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