OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
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 | 8 |
9 #include "SkAdvancedTypefaceMetrics.h" | 9 #include "SkAdvancedTypefaceMetrics.h" |
10 #include "SkTypes.h" | 10 #include "SkTypes.h" |
11 | 11 |
12 #if defined(SK_BUILD_FOR_WIN) | |
13 #include <dwrite.h> | |
14 #endif | |
15 | |
16 // forward declare structs needed for getAdvanceData() template for freetype | |
17 struct FT_FaceRec_; | |
18 typedef struct FT_FaceRec_* FT_Face; | |
19 | |
20 #ifdef SK_BUILD_FOR_MAC | |
21 #import <ApplicationServices/ApplicationServices.h> | |
22 #endif | |
23 | |
24 #ifdef SK_BUILD_FOR_IOS | |
25 #include <CoreText/CoreText.h> | |
26 #include <CoreGraphics/CoreGraphics.h> | |
27 #include <CoreFoundation/CoreFoundation.h> | |
28 #endif | |
29 | |
30 SkAdvancedTypefaceMetrics::~SkAdvancedTypefaceMetrics() {} | 12 SkAdvancedTypefaceMetrics::~SkAdvancedTypefaceMetrics() {} |
31 | 13 |
32 const int16_t kInvalidAdvance = SK_MinS16; | 14 const int16_t kInvalidAdvance = SK_MinS16; |
33 const int16_t kDontCareAdvance = SK_MinS16 + 1; | 15 const int16_t kDontCareAdvance = SK_MinS16 + 1; |
34 | 16 |
35 static void stripUninterestingTrailingAdvancesFromRange( | 17 static void stripUninterestingTrailingAdvancesFromRange( |
36 SkAdvancedTypefaceMetrics::WidthRange* range) { | 18 SkAdvancedTypefaceMetrics::WidthRange* range) { |
37 SkASSERT(range); | 19 SkASSERT(range); |
38 | 20 |
39 int expectedAdvanceCount = range->fEndId - range->fStartId + 1; | 21 int expectedAdvanceCount = range->fEndId - range->fStartId + 1; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 if (range->fEndId == range->fStartId) { | 62 if (range->fEndId == range->fStartId) { |
81 range->fType = SkAdvancedTypefaceMetrics::WidthRange::kRange; | 63 range->fType = SkAdvancedTypefaceMetrics::WidthRange::kRange; |
82 } | 64 } |
83 newLength = 1; | 65 newLength = 1; |
84 } | 66 } |
85 SkASSERT(range->fAdvance.count() >= newLength); | 67 SkASSERT(range->fAdvance.count() >= newLength); |
86 range->fAdvance.setCount(newLength); | 68 range->fAdvance.setCount(newLength); |
87 zeroWildcardsInRange(range); | 69 zeroWildcardsInRange(range); |
88 } | 70 } |
89 | 71 |
90 template <typename FontHandle> | |
91 void SkAdvancedTypefaceMetrics::setGlyphWidths( | 72 void SkAdvancedTypefaceMetrics::setGlyphWidths( |
92 FontHandle fontHandle, | |
93 int num_glyphs, | 73 int num_glyphs, |
94 const uint32_t* subsetGlyphIDs, | 74 const uint32_t* subsetGlyphIDs, |
95 uint32_t subsetGlyphIDsLength, | 75 uint32_t subsetGlyphIDsLength, |
96 bool (*getAdvance)(FontHandle fontHandle, int gId, int16_t* data)) { | 76 SkAdvancedTypefaceMetrics::GetAdvance getAdvance) { |
97 // Assuming that on average, the ASCII representation of an advance plus | 77 // Assuming that on average, the ASCII representation of an advance plus |
98 // a space is 8 characters and the ASCII representation of a glyph id is 3 | 78 // a space is 8 characters and the ASCII representation of a glyph id is 3 |
99 // characters, then the following cut offs for using different range types | 79 // characters, then the following cut offs for using different range types |
100 // apply: | 80 // apply: |
101 // The cost of stopping and starting the range is 7 characers | 81 // The cost of stopping and starting the range is 7 characers |
102 // a. Removing 4 0's or don't care's is a win | 82 // a. Removing 4 0's or don't care's is a win |
103 // The cost of stopping and starting the range plus a run is 22 | 83 // The cost of stopping and starting the range plus a run is 22 |
104 // characters | 84 // characters |
105 // b. Removing 3 repeating advances is a win | 85 // b. Removing 3 repeating advances is a win |
106 // c. Removing 2 repeating advances and 3 don't cares is a win | 86 // c. Removing 2 repeating advances and 3 don't cares is a win |
(...skipping 21 matching lines...) Expand all Loading... |
128 | 108 |
129 for (int gId = firstIndex; gId <= lastIndex; gId++) { | 109 for (int gId = firstIndex; gId <= lastIndex; gId++) { |
130 int16_t advance = kInvalidAdvance; | 110 int16_t advance = kInvalidAdvance; |
131 if (gId < lastIndex) { | 111 if (gId < lastIndex) { |
132 // Get glyph id only when subset is nullptr, or the id is in subset. | 112 // Get glyph id only when subset is nullptr, or the id is in subset. |
133 SkASSERT(!subsetGlyphIDs || (subsetIndex < subsetGlyphIDsLength && | 113 SkASSERT(!subsetGlyphIDs || (subsetIndex < subsetGlyphIDsLength && |
134 static_cast<uint32_t>(gId) <= subsetGlyphIDs[subsetIndex])); | 114 static_cast<uint32_t>(gId) <= subsetGlyphIDs[subsetIndex])); |
135 if (!subsetGlyphIDs || | 115 if (!subsetGlyphIDs || |
136 (subsetIndex < subsetGlyphIDsLength && | 116 (subsetIndex < subsetGlyphIDsLength && |
137 static_cast<uint32_t>(gId) == subsetGlyphIDs[subsetIndex])) { | 117 static_cast<uint32_t>(gId) == subsetGlyphIDs[subsetIndex])) { |
138 SkAssertResult(getAdvance(fontHandle, gId, &advance)); | 118 SkAssertResult(getAdvance(gId, &advance)); |
139 ++subsetIndex; | 119 ++subsetIndex; |
140 } else { | 120 } else { |
141 advance = kDontCareAdvance; | 121 advance = kDontCareAdvance; |
142 } | 122 } |
143 } | 123 } |
144 if (advance == lastAdvance) { | 124 if (advance == lastAdvance) { |
145 repeatedAdvances++; | 125 repeatedAdvances++; |
146 trailingWildCards = 0; | 126 trailingWildCards = 0; |
147 } else if (advance == kDontCareAdvance) { | 127 } else if (advance == kDontCareAdvance) { |
148 wildCardsInRun++; | 128 wildCardsInRun++; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 SkASSERT(prevRange); | 185 SkASSERT(prevRange); |
206 if (!prevRange) { | 186 if (!prevRange) { |
207 fGlyphWidths.reset(); | 187 fGlyphWidths.reset(); |
208 return; // https://crbug.com/567031 | 188 return; // https://crbug.com/567031 |
209 } | 189 } |
210 } else { | 190 } else { |
211 FinishRange(&curRange, lastIndex - 1, WidthRange::kRange); | 191 FinishRange(&curRange, lastIndex - 1, WidthRange::kRange); |
212 fGlyphWidths.emplace_back(std::move(curRange)); | 192 fGlyphWidths.emplace_back(std::move(curRange)); |
213 } | 193 } |
214 } | 194 } |
215 | |
216 // Make AdvanceMetric template functions available for linking with typename | |
217 // WidthRange and VerticalAdvanceRange. | |
218 template void SkAdvancedTypefaceMetrics::setGlyphWidths( | |
219 FT_Face face, | |
220 int num_glyphs, | |
221 const uint32_t* subsetGlyphIDs, | |
222 uint32_t subsetGlyphIDsLength, | |
223 bool (*getAdvance)(FT_Face face, int gId, int16_t* data)); | |
224 | |
225 #if defined(SK_BUILD_FOR_WIN) | |
226 template void SkAdvancedTypefaceMetrics::setGlyphWidths( | |
227 HDC hdc, | |
228 int num_glyphs, | |
229 const uint32_t* subsetGlyphIDs, | |
230 uint32_t subsetGlyphIDsLength, | |
231 bool (*getAdvance)(HDC hdc, int gId, int16_t* data)); | |
232 template void SkAdvancedTypefaceMetrics::setGlyphWidths( | |
233 IDWriteFontFace* fontFace, | |
234 int num_glyphs, | |
235 const uint32_t* subsetGlyphIDs, | |
236 uint32_t subsetGlyphIDsLength, | |
237 bool (*getAdvance)(IDWriteFontFace* fontFace, int gId, int16_t* data)); | |
238 #elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) | |
239 template void SkAdvancedTypefaceMetrics::setGlyphWidths( | |
240 CTFontRef ctFont, | |
241 int num_glyphs, | |
242 const uint32_t* subsetGlyphIDs, | |
243 uint32_t subsetGlyphIDsLength, | |
244 bool (*getAdvance)(CTFontRef ctFont, int gId, int16_t* data)); | |
245 #endif | |
246 // additional declaration needed for testing with a face of an unknown type | |
247 template void SkAdvancedTypefaceMetrics::setGlyphWidths( | |
248 void* fontData, | |
249 int num_glyphs, | |
250 const uint32_t* subsetGlyphIDs, | |
251 uint32_t subsetGlyphIDsLength, | |
252 bool (*getAdvance)(void* fontData, int gId, int16_t* data)); | |
OLD | NEW |