Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2011 The Android Open Source Project
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkAdvancedTypefaceMetrics.h"
      9 #include "SkFontDescriptor.h"
     10 #include "SkFontHost.h"
     11 #include "SkStream.h"
     12 #include "SkTypeface.h"
     13 
     14 SK_DEFINE_INST_COUNT(SkTypeface)
     15 
     16 //#define TRACE_LIFECYCLE
     17 
     18 #ifdef TRACE_LIFECYCLE
     19     static int32_t gTypefaceCounter;
     20 #endif
     21 
     22 SkTypeface::SkTypeface(Style style, SkFontID fontID, bool isFixedPitch)
     23     : fUniqueID(fontID), fStyle(style), fIsFixedPitch(isFixedPitch) {
     24 #ifdef TRACE_LIFECYCLE
     25     SkDebugf("SkTypeface: create  %p fontID %d total %d\n",
     26              this, fontID, ++gTypefaceCounter);
     27 #endif
     28 }
     29 
     30 SkTypeface::~SkTypeface() {
     31 #ifdef TRACE_LIFECYCLE
     32     SkDebugf("SkTypeface: destroy %p fontID %d total %d\n",
     33              this, fUniqueID, --gTypefaceCounter);
     34 #endif
     35 }
     36 
     37 ///////////////////////////////////////////////////////////////////////////////
     38 
     39 SkTypeface* SkTypeface::GetDefaultTypeface(Style style) {
     40     // we keep a reference to this guy for all time, since if we return its
     41     // fontID, the font cache may later on ask to resolve that back into a
     42     // typeface object.
     43     static const uint32_t FONT_STYLE_COUNT = 4;
     44     static SkTypeface* gDefaultTypefaces[FONT_STYLE_COUNT];
     45     SkASSERT((unsigned)style < FONT_STYLE_COUNT);
     46 
     47     // mask off any other bits to avoid a crash in SK_RELEASE
     48     style = (Style)(style & 0x03);
     49 
     50     if (NULL == gDefaultTypefaces[style]) {
     51         gDefaultTypefaces[style] =
     52         SkFontHost::CreateTypeface(NULL, NULL, style);
     53     }
     54     return gDefaultTypefaces[style];
     55 }
     56 
     57 SkTypeface* SkTypeface::RefDefault(Style style) {
     58     return SkRef(GetDefaultTypeface(style));
     59 }
     60 
     61 uint32_t SkTypeface::UniqueID(const SkTypeface* face) {
     62     if (NULL == face) {
     63         face = GetDefaultTypeface();
     64     }
     65     return face->uniqueID();
     66 }
     67 
     68 bool SkTypeface::Equal(const SkTypeface* facea, const SkTypeface* faceb) {
     69     return SkTypeface::UniqueID(facea) == SkTypeface::UniqueID(faceb);
     70 }
     71 
     72 ///////////////////////////////////////////////////////////////////////////////
     73 
     74 SkTypeface* SkTypeface::CreateFromName(const char name[], Style style) {
     75     if (NULL == name) {
     76         return RefDefault(style);
     77     }
     78     return SkFontHost::CreateTypeface(NULL, name, style);
     79 }
     80 
     81 SkTypeface* SkTypeface::CreateFromTypeface(const SkTypeface* family, Style s) {
     82     if (family && family->style() == s) {
     83         family->ref();
     84         return const_cast<SkTypeface*>(family);
     85     }
     86     return SkFontHost::CreateTypeface(family, NULL, s);
     87 }
     88 
     89 SkTypeface* SkTypeface::CreateFromStream(SkStream* stream) {
     90     return SkFontHost::CreateTypefaceFromStream(stream);
     91 }
     92 
     93 SkTypeface* SkTypeface::CreateFromFile(const char path[]) {
     94     return SkFontHost::CreateTypefaceFromFile(path);
     95 }
     96 
     97 ///////////////////////////////////////////////////////////////////////////////
     98 
     99 void SkTypeface::serialize(SkWStream* wstream) const {
    100     bool isLocal = false;
    101     SkFontDescriptor desc(this->style());
    102     this->onGetFontDescriptor(&desc, &isLocal);
    103 
    104     desc.serialize(wstream);
    105     if (isLocal) {
    106         int ttcIndex;   // TODO: write this to the stream?
    107         SkAutoTUnref<SkStream> rstream(this->openStream(&ttcIndex));
    108         if (rstream.get()) {
    109             size_t length = rstream->getLength();
    110             wstream->writePackedUInt(length);
    111             wstream->writeStream(rstream, length);
    112         } else {
    113             wstream->writePackedUInt(0);
    114         }
    115     } else {
    116         wstream->writePackedUInt(0);
    117     }
    118 }
    119 
    120 SkTypeface* SkTypeface::Deserialize(SkStream* stream) {
    121     SkFontDescriptor desc(stream);
    122     size_t length = stream->readPackedUInt();
    123     if (length > 0) {
    124         void* addr = sk_malloc_flags(length, 0);
    125         if (addr) {
    126             SkAutoTUnref<SkMemoryStream> localStream(SkNEW(SkMemoryStream));
    127             localStream->setMemoryOwned(addr, length);
    128 
    129             if (stream->read(addr, length) == length) {
    130                 return SkTypeface::CreateFromStream(localStream.get());
    131             } else {
    132                 // Failed to read the full font data, so fall through and try to create from name.
    133                 // If this is because of EOF, all subsequent reads from the stream will be EOF.
    134                 // If this is because of a stream error, the stream is in an error state,
    135                 // do not attempt to skip any remaining bytes.
    136             }
    137         } else {
    138             // failed to allocate, so just skip and create-from-name
    139             stream->skip(length);
    140         }
    141     }
    142 
    143     return SkTypeface::CreateFromName(desc.getFamilyName(), desc.getStyle());
    144 }
    145 
    146 ///////////////////////////////////////////////////////////////////////////////
    147 
    148 int SkTypeface::countTables() const {
    149     return this->onGetTableTags(NULL);
    150 }
    151 
    152 int SkTypeface::getTableTags(SkFontTableTag tags[]) const {
    153     return this->onGetTableTags(tags);
    154 }
    155 
    156 size_t SkTypeface::getTableSize(SkFontTableTag tag) const {
    157     return this->onGetTableData(tag, 0, ~0U, NULL);
    158 }
    159 
    160 size_t SkTypeface::getTableData(SkFontTableTag tag, size_t offset, size_t length,
    161                                 void* data) const {
    162     return this->onGetTableData(tag, offset, length, data);
    163 }
    164 
    165 SkStream* SkTypeface::openStream(int* ttcIndex) const {
    166     int ttcIndexStorage;
    167     if (NULL == ttcIndex) {
    168         // So our subclasses don't need to check for null param
    169         ttcIndex = &ttcIndexStorage;
    170     }
    171     return this->onOpenStream(ttcIndex);
    172 }
    173 
    174 int SkTypeface::charsToGlyphs(const void* chars, Encoding encoding,
    175                               uint16_t glyphs[], int glyphCount) const {
    176     if (glyphCount <= 0) {
    177         return 0;
    178     }
    179     if (NULL == chars || (unsigned)encoding > kUTF32_Encoding) {
    180         if (glyphs) {
    181             sk_bzero(glyphs, glyphCount * sizeof(glyphs[0]));
    182         }
    183         return 0;
    184     }
    185     return this->onCharsToGlyphs(chars, encoding, glyphs, glyphCount);
    186 }
    187 
    188 int SkTypeface::countGlyphs() const {
    189     return this->onCountGlyphs();
    190 }
    191 
    192 int SkTypeface::getUnitsPerEm() const {
    193     // should we try to cache this in the base-class?
    194     return this->onGetUPEM();
    195 }
    196 
    197 SkTypeface::LocalizedStrings* SkTypeface::createFamilyNameIterator() const {
    198     return this->onCreateFamilyNameIterator();
    199 }
    200 
    201 void SkTypeface::getFamilyName(SkString* name) const {
    202     bool isLocal = false;
    203     SkFontDescriptor desc(this->style());
    204     this->onGetFontDescriptor(&desc, &isLocal);
    205     name->set(desc.getFamilyName());
    206 }
    207 
    208 SkAdvancedTypefaceMetrics* SkTypeface::getAdvancedTypefaceMetrics(
    209                                 SkAdvancedTypefaceMetrics::PerGlyphInfo info,
    210                                 const uint32_t* glyphIDs,
    211                                 uint32_t glyphIDsCount) const {
    212     return this->onGetAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount);
    213 }
    214 
    215 SkTypeface* SkTypeface::refMatchingStyle(Style style) const {
    216     return this->onRefMatchingStyle(style);
    217 }
    218 
    219 ///////////////////////////////////////////////////////////////////////////////
    220 ///////////////////////////////////////////////////////////////////////////////
    221 
    222 int SkTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
    223                                 uint16_t glyphs[], int glyphCount) const {
    224     SkDebugf("onCharsToGlyphs unimplemented\n");
    225     if (glyphs && glyphCount > 0) {
    226         sk_bzero(glyphs, glyphCount * sizeof(glyphs[0]));
    227     }
    228     return 0;
    229 }
    230