OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 The Android Open Source Project | 2 * Copyright 2011 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkAdvancedTypefaceMetrics.h" | 8 #include "SkAdvancedTypefaceMetrics.h" |
9 #include "SkFontDescriptor.h" | 9 #include "SkFontDescriptor.h" |
10 #include "SkFontHost.h" | 10 #include "SkFontHost.h" |
11 #include "SkOnce.h" | 11 #include "SkLazyPtr.h" |
12 #include "SkStream.h" | 12 #include "SkStream.h" |
13 #include "SkTypeface.h" | 13 #include "SkTypeface.h" |
14 | 14 |
15 //#define TRACE_LIFECYCLE | 15 //#define TRACE_LIFECYCLE |
16 | 16 |
17 #ifdef TRACE_LIFECYCLE | 17 #ifdef TRACE_LIFECYCLE |
18 static int32_t gTypefaceCounter; | 18 static int32_t gTypefaceCounter; |
19 #endif | 19 #endif |
20 | 20 |
21 SkTypeface::SkTypeface(Style style, SkFontID fontID, bool isFixedPitch) | 21 SkTypeface::SkTypeface(Style style, SkFontID fontID, bool isFixedPitch) |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 }; | 67 }; |
68 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_
OVERRIDE { | 68 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_
OVERRIDE { |
69 return SkNEW(EmptyLocalizedStrings); | 69 return SkNEW(EmptyLocalizedStrings); |
70 }; | 70 }; |
71 virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE { return
0; } | 71 virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE { return
0; } |
72 virtual size_t onGetTableData(SkFontTableTag, size_t, size_t, void*) const S
K_OVERRIDE { | 72 virtual size_t onGetTableData(SkFontTableTag, size_t, size_t, void*) const S
K_OVERRIDE { |
73 return 0; | 73 return 0; |
74 } | 74 } |
75 }; | 75 }; |
76 | 76 |
77 static SkTypeface* gDefaultTypefaces[] = { NULL, NULL, NULL, NULL }; | 77 SkTypeface* SkTypeface::CreateDefault(int style) { |
78 static const size_t FONT_STYLE_COUNT = SK_ARRAY_COUNT(gDefaultTypefaces); | 78 // If backed by fontconfig, it's not safe to call SkFontHost::CreateTypeface
concurrently. |
79 static SkOnceFlag gDefaultTypefaceOnce[FONT_STYLE_COUNT] = { | 79 // To be safe, we serialize here with a mutex so only one call to |
80 SK_ONCE_INIT, SK_ONCE_INIT, SK_ONCE_INIT, SK_ONCE_INIT | 80 // CreateTypeface is happening at any given time. |
81 }; | 81 // TODO(bungeman, mtklein): This is sad. Make our fontconfig code safe? |
82 template <uintmax_t N> struct SkTIsPow2 { | 82 SK_DECLARE_STATIC_MUTEX(mutex); |
83 static const bool value = (N & (N - 1)) == 0; | 83 SkAutoMutexAcquire lock(&mutex); |
84 }; | |
85 SK_COMPILE_ASSERT(SkTIsPow2<FONT_STYLE_COUNT>::value, FONT_STYLE_COUNT_not_power
_of_2); | |
86 | 84 |
87 void SkTypeface::create_default_typeface(Style style) { | 85 SkTypeface* t = SkFontHost::CreateTypeface(NULL, NULL, (Style)style); |
88 if (NULL == gDefaultTypefaces[style]) { | 86 return t ? t : SkEmptyTypeface::Create(); |
89 gDefaultTypefaces[style] = SkFontHost::CreateTypeface(NULL, NULL, style)
; | 87 } |
90 } | 88 |
91 if (NULL == gDefaultTypefaces[style]) { | 89 void SkTypeface::DeleteDefault(SkTypeface* t) { |
92 // FIXME: Use a singleton for SkEmptyTypeface. | 90 // The SkTypeface returned by SkFontHost::CreateTypeface may _itself_ be a |
93 gDefaultTypefaces[style] = SkEmptyTypeface::Create(); | 91 // cleverly-shared singleton. This is less than ideal. This means we |
94 } | 92 // cannot just assert our ownership and SkDELETE(t) like we'd want to. |
| 93 SkSafeUnref(t); |
95 } | 94 } |
96 | 95 |
97 SkTypeface* SkTypeface::GetDefaultTypeface(Style style) { | 96 SkTypeface* SkTypeface::GetDefaultTypeface(Style style) { |
98 SkASSERT((size_t)style < FONT_STYLE_COUNT); | 97 SK_DECLARE_STATIC_LAZY_PTR_ARRAY(SkTypeface, defaults, 4, CreateDefault, Del
eteDefault); |
99 | 98 |
100 // mask off any other bits to avoid a crash in SK_RELEASE | 99 SkASSERT((int)style < 4); |
101 style = (Style)(style & (FONT_STYLE_COUNT - 1)); | 100 return defaults[style]; |
102 | |
103 SkOnce(&gDefaultTypefaceOnce[style], SkTypeface::create_default_typeface, st
yle); | |
104 return gDefaultTypefaces[style]; | |
105 } | 101 } |
106 | 102 |
107 SkTypeface* SkTypeface::RefDefault(Style style) { | 103 SkTypeface* SkTypeface::RefDefault(Style style) { |
108 return SkRef(GetDefaultTypeface(style)); | 104 return SkRef(GetDefaultTypeface(style)); |
109 } | 105 } |
110 | 106 |
111 uint32_t SkTypeface::UniqueID(const SkTypeface* face) { | 107 uint32_t SkTypeface::UniqueID(const SkTypeface* face) { |
112 if (NULL == face) { | 108 if (NULL == face) { |
113 face = GetDefaultTypeface(); | 109 face = GetDefaultTypeface(); |
114 } | 110 } |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 uint32_t glyphIDsCount) const { | 271 uint32_t glyphIDsCount) const { |
276 return this->onGetAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount); | 272 return this->onGetAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount); |
277 } | 273 } |
278 | 274 |
279 /////////////////////////////////////////////////////////////////////////////// | 275 /////////////////////////////////////////////////////////////////////////////// |
280 | 276 |
281 bool SkTypeface::onGetKerningPairAdjustments(const uint16_t glyphs[], int count, | 277 bool SkTypeface::onGetKerningPairAdjustments(const uint16_t glyphs[], int count, |
282 int32_t adjustments[]) const { | 278 int32_t adjustments[]) const { |
283 return false; | 279 return false; |
284 } | 280 } |
OLD | NEW |