| 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 |