2 * Copyright 2011 The Android Open Source Project
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #include "SkAdvancedTypefaceMetrics.h"
10 #include "SkFontDescriptor.h"
11 #include "SkFontMgr.h"
12 #include "SkLazyPtr.h"
13 #include "SkOTTable_OS_2.h"
15 #include "SkTypeface.h"
17 SkTypeface::SkTypeface(const SkFontStyle& style, SkFontID fontID, bool isFixedPitch)
18 : fUniqueID(fontID), fStyle(style), fIsFixedPitch(isFixedPitch) { }
20 SkTypeface::~SkTypeface() { }
22 ///////////////////////////////////////////////////////////////////////////////
24 class SkEmptyTypeface : public SkTypeface {
26 static SkEmptyTypeface* Create() {
27 return SkNEW(SkEmptyTypeface);
30 SkEmptyTypeface() : SkTypeface(SkFontStyle(), 0, true) { }
32 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE { return NULL; }
33 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK_OVERRIDE {
36 virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE { }
37 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
38 SkAdvancedTypefaceMetrics::PerGlyphInfo,
39 const uint32_t*, uint32_t) const SK_OVERRIDE { return NULL; }
40 virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE { }
41 virtual int onCharsToGlyphs(const void* chars, Encoding encoding,
42 uint16_t glyphs[], int glyphCount) const SK_OVERRIDE {
43 if (glyphs && glyphCount > 0) {
44 sk_bzero(glyphs, glyphCount * sizeof(glyphs[0]));
48 virtual int onCountGlyphs() const SK_OVERRIDE { return 0; };
49 virtual int onGetUPEM() const SK_OVERRIDE { return 0; };
50 class EmptyLocalizedStrings : public SkTypeface::LocalizedStrings {
52 virtual bool next(SkTypeface::LocalizedString*) SK_OVERRIDE { return false; }
54 virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE {
57 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE {
58 return SkNEW(EmptyLocalizedStrings);
60 virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE { return 0; }
61 virtual size_t onGetTableData(SkFontTableTag, size_t, size_t, void*) const SK_OVERRIDE {
68 SK_DECLARE_STATIC_MUTEX(gCreateDefaultMutex);
70 // As a template arguments, these must have external linkage.
71 SkTypeface* sk_create_default_typeface(int style) {
72 // If backed by fontconfig, it's not safe to call SkFontHost::CreateTypeface concurrently.
73 // To be safe, we serialize here with a mutex so only one call to
74 // CreateTypeface is happening at any given time.
75 // TODO(bungeman, mtklein): This is sad. Make our fontconfig code safe?
76 SkAutoMutexAcquire lock(&gCreateDefaultMutex);
78 SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
79 SkTypeface* t = fm->legacyCreateTypeface(NULL, style);;
80 return t ? t : SkEmptyTypeface::Create();
83 void sk_unref_typeface(SkTypeface* ptr) { SkSafeUnref(ptr); }
87 SK_DECLARE_STATIC_LAZY_PTR_ARRAY(SkTypeface, defaults, 4,
88 sk_create_default_typeface, sk_unref_typeface);
90 SkTypeface* SkTypeface::GetDefaultTypeface(Style style) {
91 SkASSERT((int)style < 4);
92 return defaults[style];
95 SkTypeface* SkTypeface::RefDefault(Style style) {
96 return SkRef(GetDefaultTypeface(style));
99 uint32_t SkTypeface::UniqueID(const SkTypeface* face) {
101 face = GetDefaultTypeface();
103 return face->uniqueID();
106 bool SkTypeface::Equal(const SkTypeface* facea, const SkTypeface* faceb) {
107 return SkTypeface::UniqueID(facea) == SkTypeface::UniqueID(faceb);
110 ///////////////////////////////////////////////////////////////////////////////
112 SkTypeface* SkTypeface::CreateFromName(const char name[], Style style) {
114 return RefDefault(style);
116 SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
117 return fm->legacyCreateTypeface(name, style);
120 SkTypeface* SkTypeface::CreateFromTypeface(const SkTypeface* family, Style s) {
122 return SkTypeface::RefDefault(s);
125 if (family->style() == s) {
127 return const_cast<SkTypeface*>(family);
130 SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
131 bool bold = s & SkTypeface::kBold;
132 bool italic = s & SkTypeface::kItalic;
133 SkFontStyle newStyle = SkFontStyle(bold ? SkFontStyle::kBold_Weight
134 : SkFontStyle::kNormal_Weight,
135 SkFontStyle::kNormal_Width,
136 italic ? SkFontStyle::kItalic_Slant
137 : SkFontStyle::kUpright_Slant);
138 return fm->matchFaceStyle(family, newStyle);
141 SkTypeface* SkTypeface::CreateFromStream(SkStream* stream, int index) {
142 SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
143 return fm->createFromStream(stream, index);
146 SkTypeface* SkTypeface::CreateFromFile(const char path[], int index) {
147 SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
148 return fm->createFromFile(path, index);
151 ///////////////////////////////////////////////////////////////////////////////
153 void SkTypeface::serialize(SkWStream* wstream) const {
154 bool isLocal = false;
155 SkFontDescriptor desc(this->style());
156 this->onGetFontDescriptor(&desc, &isLocal);
158 if (isLocal && NULL == desc.getFontData()) {
160 desc.setFontData(this->onOpenStream(&ttcIndex));
161 desc.setFontIndex(ttcIndex);
164 desc.serialize(wstream);
167 SkTypeface* SkTypeface::Deserialize(SkStream* stream) {
168 SkFontDescriptor desc(stream);
169 SkStream* data = desc.getFontData();
171 SkTypeface* typeface = SkTypeface::CreateFromStream(data, desc.getFontIndex());
176 return SkTypeface::CreateFromName(desc.getFamilyName(), desc.getStyle());
179 ///////////////////////////////////////////////////////////////////////////////
181 int SkTypeface::countTables() const {
182 return this->onGetTableTags(NULL);
185 int SkTypeface::getTableTags(SkFontTableTag tags[]) const {
186 return this->onGetTableTags(tags);
189 size_t SkTypeface::getTableSize(SkFontTableTag tag) const {
190 return this->onGetTableData(tag, 0, ~0U, NULL);
193 size_t SkTypeface::getTableData(SkFontTableTag tag, size_t offset, size_t length,
195 return this->onGetTableData(tag, offset, length, data);
198 SkStream* SkTypeface::openStream(int* ttcIndex) const {
200 if (NULL == ttcIndex) {
201 // So our subclasses don't need to check for null param
202 ttcIndex = &ttcIndexStorage;
204 return this->onOpenStream(ttcIndex);
207 int SkTypeface::charsToGlyphs(const void* chars, Encoding encoding,
208 uint16_t glyphs[], int glyphCount) const {
209 if (glyphCount <= 0) {
212 if (NULL == chars || (unsigned)encoding > kUTF32_Encoding) {
214 sk_bzero(glyphs, glyphCount * sizeof(glyphs[0]));
218 return this->onCharsToGlyphs(chars, encoding, glyphs, glyphCount);
221 int SkTypeface::countGlyphs() const {
222 return this->onCountGlyphs();
225 int SkTypeface::getUnitsPerEm() const {
226 // should we try to cache this in the base-class?
227 return this->onGetUPEM();
230 bool SkTypeface::getKerningPairAdjustments(const uint16_t glyphs[], int count,
231 int32_t adjustments[]) const {
232 SkASSERT(count >= 0);
233 // check for the only legal way to pass a NULL.. everything is 0
234 // in which case they just want to know if this face can possibly support
235 // kerning (true) or never (false).
236 if (NULL == glyphs || NULL == adjustments) {
237 SkASSERT(NULL == glyphs);
238 SkASSERT(0 == count);
239 SkASSERT(NULL == adjustments);
241 return this->onGetKerningPairAdjustments(glyphs, count, adjustments);
244 SkTypeface::LocalizedStrings* SkTypeface::createFamilyNameIterator() const {
245 return this->onCreateFamilyNameIterator();
248 void SkTypeface::getFamilyName(SkString* name) const {
250 this->onGetFamilyName(name);
253 SkAdvancedTypefaceMetrics* SkTypeface::getAdvancedTypefaceMetrics(
254 SkAdvancedTypefaceMetrics::PerGlyphInfo info,
255 const uint32_t* glyphIDs,
256 uint32_t glyphIDsCount) const {
257 SkAdvancedTypefaceMetrics* result =
258 this->onGetAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount);
259 if (result && result->fType == SkAdvancedTypefaceMetrics::kTrueType_Font) {
260 struct SkOTTableOS2 os2table;
261 if (this->getTableData(SkTEndian_SwapBE32(SkOTTableOS2::TAG), 0,
262 sizeof(os2table), &os2table) > 0) {
263 if (os2table.version.v2.fsType.field.Bitmap ||
264 (os2table.version.v2.fsType.field.Restricted &&
265 !(os2table.version.v2.fsType.field.PreviewPrint ||
266 os2table.version.v2.fsType.field.Editable))) {
267 result->fFlags = SkTBitOr<SkAdvancedTypefaceMetrics::FontFlags>(
269 SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag);
271 if (os2table.version.v2.fsType.field.NoSubsetting) {
272 result->fFlags = SkTBitOr<SkAdvancedTypefaceMetrics::FontFlags>(
274 SkAdvancedTypefaceMetrics::kNotSubsettable_FontFlag);
281 bool SkTypeface::onGetKerningPairAdjustments(const uint16_t glyphs[], int count,
282 int32_t adjustments[]) const {
286 ///////////////////////////////////////////////////////////////////////////////
288 #include "SkDescriptor.h"
291 struct SkTypeface::BoundsComputer {
292 const SkTypeface& fTypeface;
294 BoundsComputer(const SkTypeface& tf) : fTypeface(tf) {}
296 SkRect* operator()() const {
297 SkRect* rect = SkNEW(SkRect);
298 if (!fTypeface.onComputeBounds(rect)) {
305 SkRect SkTypeface::getBounds() const {
306 return *fLazyBounds.get(BoundsComputer(*this));
309 bool SkTypeface::onComputeBounds(SkRect* bounds) const {
310 // we use a big size to ensure lots of significant bits from the scalercontext.
311 // then we scale back down to return our final answer (at 1-pt)
312 const SkScalar textSize = 2048;
313 const SkScalar invTextSize = 1 / textSize;
316 paint.setTypeface(const_cast<SkTypeface*>(this));
317 paint.setTextSize(textSize);
318 paint.setLinearText(true);
320 SkScalerContext::Rec rec;
321 SkScalerContext::MakeRec(paint, NULL, NULL, &rec);
323 SkAutoDescriptor ad(sizeof(rec) + SkDescriptor::ComputeOverhead(1));
324 SkDescriptor* desc = ad.getDesc();
326 desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
328 SkAutoTDelete<SkScalerContext> ctx(this->createScalerContext(desc, true));
330 SkPaint::FontMetrics fm;
331 ctx->getFontMetrics(&fm);
332 bounds->set(fm.fXMin * invTextSize, fm.fTop * invTextSize,
333 fm.fXMax * invTextSize, fm.fBottom * invTextSize);