SkTypeface.cpp revision 7ed98df9ba14bdb58e381508eb0505c963a4b6db
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 14SK_DEFINE_INST_COUNT(SkTypeface) 15 16//#define TRACE_LIFECYCLE 17 18#ifdef TRACE_LIFECYCLE 19 static int32_t gTypefaceCounter; 20#endif 21 22SkTypeface::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 30SkTypeface::~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 39class SkEmptyTypeface : public SkTypeface { 40public: 41 SkEmptyTypeface() : SkTypeface(SkTypeface::kNormal, 0, true) { } 42protected: 43 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE { return NULL; } 44 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK_OVERRIDE { 45 return NULL; 46 } 47 virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE { } 48 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( 49 SkAdvancedTypefaceMetrics::PerGlyphInfo, 50 const uint32_t*, uint32_t) const SK_OVERRIDE { return NULL; } 51 virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE { } 52 virtual int onCharsToGlyphs(const void* chars, Encoding encoding, 53 uint16_t glyphs[], int glyphCount) const SK_OVERRIDE { 54 if (glyphs && glyphCount > 0) { 55 sk_bzero(glyphs, glyphCount * sizeof(glyphs[0])); 56 } 57 return 0; 58 } 59 virtual int onCountGlyphs() const SK_OVERRIDE { return 0; }; 60 virtual int onGetUPEM() const SK_OVERRIDE { return 0; }; 61 class EmptyLocalizedStrings : public SkTypeface::LocalizedStrings { 62 public: 63 virtual bool next(SkTypeface::LocalizedString*) SK_OVERRIDE { return false; } 64 }; 65 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE { 66 return SkNEW(EmptyLocalizedStrings); 67 }; 68 virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE { return 0; } 69 virtual size_t onGetTableData(SkFontTableTag, size_t, size_t, void*) const SK_OVERRIDE { 70 return 0; 71 } 72 virtual SkTypeface* onRefMatchingStyle(Style) const SK_OVERRIDE { return NULL; } 73}; 74 75SkTypeface* SkTypeface::GetDefaultTypeface(Style style) { 76 // we keep a reference to this guy for all time, since if we return its 77 // fontID, the font cache may later on ask to resolve that back into a 78 // typeface object. 79 static const uint32_t FONT_STYLE_COUNT = 4; 80 static SkTypeface* gDefaultTypefaces[FONT_STYLE_COUNT]; 81 SkASSERT((unsigned)style < FONT_STYLE_COUNT); 82 83 // mask off any other bits to avoid a crash in SK_RELEASE 84 style = (Style)(style & 0x03); 85 86 if (NULL == gDefaultTypefaces[style]) { 87 gDefaultTypefaces[style] = SkFontHost::CreateTypeface(NULL, NULL, style); 88 } 89 if (NULL == gDefaultTypefaces[style]) { 90 gDefaultTypefaces[style] = SkNEW(SkEmptyTypeface); 91 } 92 93 return gDefaultTypefaces[style]; 94} 95 96SkTypeface* SkTypeface::RefDefault(Style style) { 97 return SkRef(GetDefaultTypeface(style)); 98} 99 100uint32_t SkTypeface::UniqueID(const SkTypeface* face) { 101 if (NULL == face) { 102 face = GetDefaultTypeface(); 103 } 104 return face->uniqueID(); 105} 106 107bool SkTypeface::Equal(const SkTypeface* facea, const SkTypeface* faceb) { 108 return SkTypeface::UniqueID(facea) == SkTypeface::UniqueID(faceb); 109} 110 111/////////////////////////////////////////////////////////////////////////////// 112 113SkTypeface* SkTypeface::CreateFromName(const char name[], Style style) { 114 if (NULL == name) { 115 return RefDefault(style); 116 } 117 return SkFontHost::CreateTypeface(NULL, name, style); 118} 119 120SkTypeface* SkTypeface::CreateFromTypeface(const SkTypeface* family, Style s) { 121 if (family && family->style() == s) { 122 family->ref(); 123 return const_cast<SkTypeface*>(family); 124 } 125 return SkFontHost::CreateTypeface(family, NULL, s); 126} 127 128SkTypeface* SkTypeface::CreateFromStream(SkStream* stream) { 129 return SkFontHost::CreateTypefaceFromStream(stream); 130} 131 132SkTypeface* SkTypeface::CreateFromFile(const char path[]) { 133 return SkFontHost::CreateTypefaceFromFile(path); 134} 135 136/////////////////////////////////////////////////////////////////////////////// 137 138void SkTypeface::serialize(SkWStream* wstream) const { 139 bool isLocal = false; 140 SkFontDescriptor desc(this->style()); 141 this->onGetFontDescriptor(&desc, &isLocal); 142 143 desc.serialize(wstream); 144 if (isLocal) { 145 int ttcIndex; // TODO: write this to the stream? 146 SkAutoTUnref<SkStream> rstream(this->openStream(&ttcIndex)); 147 if (rstream.get()) { 148 size_t length = rstream->getLength(); 149 wstream->writePackedUInt(length); 150 wstream->writeStream(rstream, length); 151 } else { 152 wstream->writePackedUInt(0); 153 } 154 } else { 155 wstream->writePackedUInt(0); 156 } 157} 158 159SkTypeface* SkTypeface::Deserialize(SkStream* stream) { 160 SkFontDescriptor desc(stream); 161 size_t length = stream->readPackedUInt(); 162 if (length > 0) { 163 void* addr = sk_malloc_flags(length, 0); 164 if (addr) { 165 SkAutoTUnref<SkMemoryStream> localStream(SkNEW(SkMemoryStream)); 166 localStream->setMemoryOwned(addr, length); 167 168 if (stream->read(addr, length) == length) { 169 return SkTypeface::CreateFromStream(localStream.get()); 170 } else { 171 // Failed to read the full font data, so fall through and try to create from name. 172 // If this is because of EOF, all subsequent reads from the stream will be EOF. 173 // If this is because of a stream error, the stream is in an error state, 174 // do not attempt to skip any remaining bytes. 175 } 176 } else { 177 // failed to allocate, so just skip and create-from-name 178 stream->skip(length); 179 } 180 } 181 182 return SkTypeface::CreateFromName(desc.getFamilyName(), desc.getStyle()); 183} 184 185/////////////////////////////////////////////////////////////////////////////// 186 187int SkTypeface::countTables() const { 188 return this->onGetTableTags(NULL); 189} 190 191int SkTypeface::getTableTags(SkFontTableTag tags[]) const { 192 return this->onGetTableTags(tags); 193} 194 195size_t SkTypeface::getTableSize(SkFontTableTag tag) const { 196 return this->onGetTableData(tag, 0, ~0U, NULL); 197} 198 199size_t SkTypeface::getTableData(SkFontTableTag tag, size_t offset, size_t length, 200 void* data) const { 201 return this->onGetTableData(tag, offset, length, data); 202} 203 204SkStream* SkTypeface::openStream(int* ttcIndex) const { 205 int ttcIndexStorage; 206 if (NULL == ttcIndex) { 207 // So our subclasses don't need to check for null param 208 ttcIndex = &ttcIndexStorage; 209 } 210 return this->onOpenStream(ttcIndex); 211} 212 213int SkTypeface::charsToGlyphs(const void* chars, Encoding encoding, 214 uint16_t glyphs[], int glyphCount) const { 215 if (glyphCount <= 0) { 216 return 0; 217 } 218 if (NULL == chars || (unsigned)encoding > kUTF32_Encoding) { 219 if (glyphs) { 220 sk_bzero(glyphs, glyphCount * sizeof(glyphs[0])); 221 } 222 return 0; 223 } 224 return this->onCharsToGlyphs(chars, encoding, glyphs, glyphCount); 225} 226 227int SkTypeface::countGlyphs() const { 228 return this->onCountGlyphs(); 229} 230 231int SkTypeface::getUnitsPerEm() const { 232 // should we try to cache this in the base-class? 233 return this->onGetUPEM(); 234} 235 236bool SkTypeface::getKerningPairAdjustments(const uint16_t glyphs[], int count, 237 int32_t adjustments[]) const { 238 SkASSERT(count >= 0); 239 // check for the only legal way to pass a NULL.. everything is 0 240 // in which case they just want to know if this face can possibly support 241 // kerning (true) or never (false). 242 if (NULL == glyphs || NULL == adjustments) { 243 SkASSERT(NULL == glyphs); 244 SkASSERT(0 == count); 245 SkASSERT(NULL == adjustments); 246 } 247 return this->onGetKerningPairAdjustments(glyphs, count, adjustments); 248} 249 250SkTypeface::LocalizedStrings* SkTypeface::createFamilyNameIterator() const { 251 return this->onCreateFamilyNameIterator(); 252} 253 254void SkTypeface::getFamilyName(SkString* name) const { 255 bool isLocal = false; 256 SkFontDescriptor desc(this->style()); 257 this->onGetFontDescriptor(&desc, &isLocal); 258 name->set(desc.getFamilyName()); 259} 260 261SkAdvancedTypefaceMetrics* SkTypeface::getAdvancedTypefaceMetrics( 262 SkAdvancedTypefaceMetrics::PerGlyphInfo info, 263 const uint32_t* glyphIDs, 264 uint32_t glyphIDsCount) const { 265 return this->onGetAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount); 266} 267 268SkTypeface* SkTypeface::refMatchingStyle(Style style) const { 269 return this->onRefMatchingStyle(style); 270} 271 272/////////////////////////////////////////////////////////////////////////////// 273 274bool SkTypeface::onGetKerningPairAdjustments(const uint16_t glyphs[], int count, 275 int32_t adjustments[]) const { 276 return false; 277} 278