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 39SkTypeface* 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 57SkTypeface* SkTypeface::RefDefault(Style style) { 58 return SkRef(GetDefaultTypeface(style)); 59} 60 61uint32_t SkTypeface::UniqueID(const SkTypeface* face) { 62 if (NULL == face) { 63 face = GetDefaultTypeface(); 64 } 65 return face->uniqueID(); 66} 67 68bool SkTypeface::Equal(const SkTypeface* facea, const SkTypeface* faceb) { 69 return SkTypeface::UniqueID(facea) == SkTypeface::UniqueID(faceb); 70} 71 72/////////////////////////////////////////////////////////////////////////////// 73 74SkTypeface* 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 81SkTypeface* 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 89SkTypeface* SkTypeface::CreateFromStream(SkStream* stream) { 90 return SkFontHost::CreateTypefaceFromStream(stream); 91} 92 93SkTypeface* SkTypeface::CreateFromFile(const char path[]) { 94 return SkFontHost::CreateTypefaceFromFile(path); 95} 96 97/////////////////////////////////////////////////////////////////////////////// 98 99void 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 120SkTypeface* 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 148int SkTypeface::countTables() const { 149 return this->onGetTableTags(NULL); 150} 151 152int SkTypeface::getTableTags(SkFontTableTag tags[]) const { 153 return this->onGetTableTags(tags); 154} 155 156size_t SkTypeface::getTableSize(SkFontTableTag tag) const { 157 return this->onGetTableData(tag, 0, ~0U, NULL); 158} 159 160size_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 165SkStream* 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 174int 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 188int SkTypeface::countGlyphs() const { 189 return this->onCountGlyphs(); 190} 191 192int SkTypeface::getUnitsPerEm() const { 193 // should we try to cache this in the base-class? 194 return this->onGetUPEM(); 195} 196 197SkTypeface::LocalizedStrings* SkTypeface::createFamilyNameIterator() const { 198 return this->onCreateFamilyNameIterator(); 199} 200 201void 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 208SkAdvancedTypefaceMetrics* 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 215SkTypeface* SkTypeface::refMatchingStyle(Style style) const { 216 return this->onRefMatchingStyle(style); 217} 218 219/////////////////////////////////////////////////////////////////////////////// 220/////////////////////////////////////////////////////////////////////////////// 221 222int 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