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