SkTypeface.cpp revision 5526ede94a2fc58bcf6b578b12a29f6addad776d
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 "SkFontStream.h" 12#include "SkStream.h" 13#include "SkTypeface.h" 14 15SK_DEFINE_INST_COUNT(SkTypeface) 16 17//#define TRACE_LIFECYCLE 18 19#ifdef TRACE_LIFECYCLE 20 static int32_t gTypefaceCounter; 21#endif 22 23SkTypeface::SkTypeface(Style style, SkFontID fontID, bool isFixedWidth) 24 : fUniqueID(fontID), fStyle(style), fIsFixedWidth(isFixedWidth) { 25#ifdef TRACE_LIFECYCLE 26 SkDebugf("SkTypeface: create %p fontID %d total %d\n", 27 this, fontID, ++gTypefaceCounter); 28#endif 29} 30 31SkTypeface::~SkTypeface() { 32#ifdef TRACE_LIFECYCLE 33 SkDebugf("SkTypeface: destroy %p fontID %d total %d\n", 34 this, fUniqueID, --gTypefaceCounter); 35#endif 36} 37 38/////////////////////////////////////////////////////////////////////////////// 39 40SkTypeface* SkTypeface::GetDefaultTypeface() { 41 // we keep a reference to this guy for all time, since if we return its 42 // fontID, the font cache may later on ask to resolve that back into a 43 // typeface object. 44 static SkTypeface* gDefaultTypeface; 45 46 if (NULL == gDefaultTypeface) { 47 gDefaultTypeface = 48 SkFontHost::CreateTypeface(NULL, NULL, SkTypeface::kNormal); 49 } 50 return gDefaultTypeface; 51} 52 53SkTypeface* SkTypeface::RefDefault() { 54 return SkRef(GetDefaultTypeface()); 55} 56 57uint32_t SkTypeface::UniqueID(const SkTypeface* face) { 58 if (NULL == face) { 59 face = GetDefaultTypeface(); 60 } 61 return face->uniqueID(); 62} 63 64bool SkTypeface::Equal(const SkTypeface* facea, const SkTypeface* faceb) { 65 return SkTypeface::UniqueID(facea) == SkTypeface::UniqueID(faceb); 66} 67 68/////////////////////////////////////////////////////////////////////////////// 69 70SkTypeface* SkTypeface::CreateFromName(const char name[], Style style) { 71 return SkFontHost::CreateTypeface(NULL, name, style); 72} 73 74SkTypeface* SkTypeface::CreateFromTypeface(const SkTypeface* family, Style s) { 75 if (family && family->style() == s) { 76 family->ref(); 77 return const_cast<SkTypeface*>(family); 78 } 79 return SkFontHost::CreateTypeface(family, NULL, s); 80} 81 82SkTypeface* SkTypeface::CreateFromStream(SkStream* stream) { 83 return SkFontHost::CreateTypefaceFromStream(stream); 84} 85 86SkTypeface* SkTypeface::CreateFromFile(const char path[]) { 87 return SkFontHost::CreateTypefaceFromFile(path); 88} 89 90/////////////////////////////////////////////////////////////////////////////// 91 92void SkTypeface::serialize(SkWStream* wstream) const { 93 bool isLocal = false; 94 SkFontDescriptor desc(this->style()); 95 this->onGetFontDescriptor(&desc, &isLocal); 96 97 desc.serialize(wstream); 98 if (isLocal) { 99 int ttcIndex; // TODO: write this to the stream? 100 SkAutoTUnref<SkStream> rstream(this->openStream(&ttcIndex)); 101 if (rstream.get()) { 102 size_t length = rstream->getLength(); 103 wstream->writePackedUInt(length); 104 wstream->writeStream(rstream, length); 105 } else { 106 wstream->writePackedUInt(0); 107 } 108 } else { 109 wstream->writePackedUInt(0); 110 } 111} 112 113SkTypeface* SkTypeface::Deserialize(SkStream* stream) { 114 SkFontDescriptor desc(stream); 115 size_t length = stream->readPackedUInt(); 116 if (length > 0) { 117 void* addr = sk_malloc_flags(length, 0); 118 if (addr) { 119 SkAutoTUnref<SkStream> localStream(SkNEW_ARGS(SkMemoryStream, 120 (addr, length, false))); 121 return SkTypeface::CreateFromStream(localStream.get()); 122 } 123 // failed to allocate, so just skip and create-from-name 124 stream->skip(length); 125 } 126 127 return SkTypeface::CreateFromName(desc.getFamilyName(), desc.getStyle()); 128} 129 130/////////////////////////////////////////////////////////////////////////////// 131 132int SkTypeface::countTables() const { 133 return this->onGetTableTags(NULL); 134} 135 136int SkTypeface::getTableTags(SkFontTableTag tags[]) const { 137 return this->onGetTableTags(tags); 138} 139 140size_t SkTypeface::getTableSize(SkFontTableTag tag) const { 141 return this->onGetTableData(tag, 0, ~0U, NULL); 142} 143 144size_t SkTypeface::getTableData(SkFontTableTag tag, size_t offset, size_t length, 145 void* data) const { 146 return this->onGetTableData(tag, offset, length, data); 147} 148 149SkStream* SkTypeface::openStream(int* ttcIndex) const { 150 int ttcIndexStorage; 151 if (NULL == ttcIndex) { 152 // So our subclasses don't need to check for null param 153 ttcIndex = &ttcIndexStorage; 154 } 155 return this->onOpenStream(ttcIndex); 156} 157 158int SkTypeface::getUnitsPerEm() const { 159 // should we try to cache this in the base-class? 160 return this->onGetUPEM(); 161} 162 163SkAdvancedTypefaceMetrics* SkTypeface::getAdvancedTypefaceMetrics( 164 SkAdvancedTypefaceMetrics::PerGlyphInfo info, 165 const uint32_t* glyphIDs, 166 uint32_t glyphIDsCount) const { 167 return this->onGetAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount); 168} 169 170/////////////////////////////////////////////////////////////////////////////// 171/////////////////////////////////////////////////////////////////////////////// 172 173int SkTypeface::onGetUPEM() const { 174 int upem = 0; 175 176 SkAdvancedTypefaceMetrics* metrics; 177 metrics = this->getAdvancedTypefaceMetrics( 178 SkAdvancedTypefaceMetrics::kNo_PerGlyphInfo, 179 NULL, 0); 180 if (metrics) { 181 upem = metrics->fEmSize; 182 metrics->unref(); 183 } 184 return upem; 185} 186 187int SkTypeface::onGetTableTags(SkFontTableTag tags[]) const { 188 int ttcIndex; 189 SkAutoTUnref<SkStream> stream(this->openStream(&ttcIndex)); 190 return stream.get() ? SkFontStream::GetTableTags(stream, ttcIndex, tags) : 0; 191} 192 193size_t SkTypeface::onGetTableData(SkFontTableTag tag, size_t offset, 194 size_t length, void* data) const { 195 int ttcIndex; 196 SkAutoTUnref<SkStream> stream(this->openStream(&ttcIndex)); 197 return stream.get() 198 ? SkFontStream::GetTableData(stream, ttcIndex, tag, offset, length, data) 199 : 0; 200} 201 202