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) | 12 #if defined(SK_BUILD_FOR_WIN) |
13 #include <dwrite.h> | 13 #include <dwrite.h> |
14 #endif | 14 #endif |
15 | 15 |
16 // forward declare structs needed for getAdvanceData() template for freetype | 16 // forward declare structs needed for getAdvanceData() template for freetype |
17 struct FT_FaceRec_; | 17 struct FT_FaceRec_; |
18 typedef struct FT_FaceRec_* FT_Face; | 18 typedef struct FT_FaceRec_* FT_Face; |
19 | 19 |
20 #ifdef SK_BUILD_FOR_MAC | 20 #ifdef SK_BUILD_FOR_MAC |
21 #import <ApplicationServices/ApplicationServices.h> | 21 #import <ApplicationServices/ApplicationServices.h> |
22 #endif | 22 #endif |
23 | 23 |
24 #ifdef SK_BUILD_FOR_IOS | 24 #ifdef SK_BUILD_FOR_IOS |
25 #include <CoreText/CoreText.h> | 25 #include <CoreText/CoreText.h> |
26 #include <CoreGraphics/CoreGraphics.h> | 26 #include <CoreGraphics/CoreGraphics.h> |
27 #include <CoreFoundation/CoreFoundation.h> | 27 #include <CoreFoundation/CoreFoundation.h> |
28 #endif | 28 #endif |
29 | 29 |
30 template <typename Data> | 30 SkAdvancedTypefaceMetrics::~SkAdvancedTypefaceMetrics() {} |
31 static void unwind(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* ptr) { | |
32 while (ptr) { | |
33 SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* next = ptr->fNext.releas
e(); | |
34 delete ptr; | |
35 ptr = next; | |
36 } | |
37 } | |
38 | |
39 SkAdvancedTypefaceMetrics::~SkAdvancedTypefaceMetrics() { | |
40 // If the stacks are too deep we could get stack overflow, | |
41 // so we manually destruct the linked lists. | |
42 unwind(fGlyphWidths.release()); | |
43 unwind(fVerticalMetrics.release()); | |
44 } | |
45 | |
46 namespace skia_advanced_typeface_metrics_utils { | |
47 | 31 |
48 const int16_t kInvalidAdvance = SK_MinS16; | 32 const int16_t kInvalidAdvance = SK_MinS16; |
49 const int16_t kDontCareAdvance = SK_MinS16 + 1; | 33 const int16_t kDontCareAdvance = SK_MinS16 + 1; |
50 | 34 |
51 template <typename Data> | 35 static void stripUninterestingTrailingAdvancesFromRange( |
52 void stripUninterestingTrailingAdvancesFromRange( | 36 SkAdvancedTypefaceMetrics::WidthRange* range) { |
53 SkAdvancedTypefaceMetrics::Adva
nceMetric<Data>* range) { | |
54 SkASSERT(false); | |
55 } | |
56 | |
57 template <> | |
58 void stripUninterestingTrailingAdvancesFromRange<int16_t>( | |
59 SkAdvancedTypefaceMetr
ics::AdvanceMetric<int16_t>* range) { | |
60 SkASSERT(range); | 37 SkASSERT(range); |
61 | 38 |
62 int expectedAdvanceCount = range->fEndId - range->fStartId + 1; | 39 int expectedAdvanceCount = range->fEndId - range->fStartId + 1; |
63 if (range->fAdvance.count() < expectedAdvanceCount) { | 40 if (range->fAdvance.count() < expectedAdvanceCount) { |
64 return; | 41 return; |
65 } | 42 } |
66 | 43 |
67 for (int i = expectedAdvanceCount - 1; i >= 0; --i) { | 44 for (int i = expectedAdvanceCount - 1; i >= 0; --i) { |
68 if (range->fAdvance[i] != kDontCareAdvance && | 45 if (range->fAdvance[i] != kDontCareAdvance && |
69 range->fAdvance[i] != kInvalidAdvance && | 46 range->fAdvance[i] != kInvalidAdvance && |
70 range->fAdvance[i] != 0) { | 47 range->fAdvance[i] != 0) { |
71 range->fEndId = range->fStartId + i; | 48 range->fEndId = range->fStartId + i; |
72 break; | 49 break; |
73 } | 50 } |
74 } | 51 } |
75 } | 52 } |
76 | 53 |
77 template <typename Data> | 54 static void zeroWildcardsInRange(SkAdvancedTypefaceMetrics::WidthRange* range) { |
78 void resetRange(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range, | |
79 int startId) { | |
80 range->fStartId = startId; | |
81 range->fAdvance.setCount(0); | |
82 } | |
83 | |
84 template <typename Data, template<typename> class AutoTDelete> | |
85 SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* appendRange( | |
86 AutoTDelete<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> >* nextSlot, | |
87 int startId) { | |
88 nextSlot->reset(new SkAdvancedTypefaceMetrics::AdvanceMetric<Data>); | |
89 resetRange(nextSlot->get(), startId); | |
90 return nextSlot->get(); | |
91 } | |
92 | |
93 template <typename Data> | |
94 void zeroWildcardsInRange( | |
95 SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range)
{ | |
96 SkASSERT(false); | |
97 } | |
98 | |
99 template <> | |
100 void zeroWildcardsInRange<int16_t>( | |
101 SkAdvancedTypefaceMetrics::AdvanceMetric<int1
6_t>* range) { | |
102 SkASSERT(range); | 55 SkASSERT(range); |
103 if (range->fType != SkAdvancedTypefaceMetrics::WidthRange::kRange) { | 56 if (range->fType != SkAdvancedTypefaceMetrics::WidthRange::kRange) { |
104 return; | 57 return; |
105 } | 58 } |
106 SkASSERT(range->fAdvance.count() == range->fEndId - range->fStartId + 1); | 59 SkASSERT(range->fAdvance.count() == range->fEndId - range->fStartId + 1); |
107 | 60 |
108 // Zero out wildcards. | 61 // Zero out wildcards. |
109 for (int i = 0; i < range->fAdvance.count(); ++i) { | 62 for (int i = 0; i < range->fAdvance.count(); ++i) { |
110 if (range->fAdvance[i] == kDontCareAdvance) { | 63 if (range->fAdvance[i] == kDontCareAdvance) { |
111 range->fAdvance[i] = 0; | 64 range->fAdvance[i] = 0; |
112 } | 65 } |
113 } | 66 } |
114 } | 67 } |
115 | 68 |
116 template <typename Data> | 69 void SkAdvancedTypefaceMetrics::FinishRange( |
117 void finishRange( | 70 SkAdvancedTypefaceMetrics::WidthRange* range, |
118 SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range, | |
119 int endId, | 71 int endId, |
120 typename SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::MetricType | 72 SkAdvancedTypefaceMetrics::WidthRange::MetricType type) { |
121 type) { | |
122 range->fEndId = endId; | 73 range->fEndId = endId; |
123 range->fType = type; | 74 range->fType = type; |
124 stripUninterestingTrailingAdvancesFromRange(range); | 75 stripUninterestingTrailingAdvancesFromRange(range); |
125 int newLength; | 76 int newLength; |
126 if (type == SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange) { | 77 if (type == SkAdvancedTypefaceMetrics::WidthRange::kRange) { |
127 newLength = range->fEndId - range->fStartId + 1; | 78 newLength = range->fEndId - range->fStartId + 1; |
128 } else { | 79 } else { |
129 if (range->fEndId == range->fStartId) { | 80 if (range->fEndId == range->fStartId) { |
130 range->fType = | 81 range->fType = SkAdvancedTypefaceMetrics::WidthRange::kRange; |
131 SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange; | |
132 } | 82 } |
133 newLength = 1; | 83 newLength = 1; |
134 } | 84 } |
135 SkASSERT(range->fAdvance.count() >= newLength); | 85 SkASSERT(range->fAdvance.count() >= newLength); |
136 range->fAdvance.setCount(newLength); | 86 range->fAdvance.setCount(newLength); |
137 zeroWildcardsInRange(range); | 87 zeroWildcardsInRange(range); |
138 } | 88 } |
139 | 89 |
140 template <typename Data, typename FontHandle> | 90 template <typename FontHandle> |
141 SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData( | 91 void SkAdvancedTypefaceMetrics::setGlyphWidths( |
142 FontHandle fontHandle, | 92 FontHandle fontHandle, |
143 int num_glyphs, | 93 int num_glyphs, |
144 const uint32_t* subsetGlyphIDs, | 94 const uint32_t* subsetGlyphIDs, |
145 uint32_t subsetGlyphIDsLength, | 95 uint32_t subsetGlyphIDsLength, |
146 bool (*getAdvance)(FontHandle fontHandle, int gId, Data* data)) { | 96 bool (*getAdvance)(FontHandle fontHandle, int gId, int16_t* data)) { |
147 // Assuming that on average, the ASCII representation of an advance plus | 97 // Assuming that on average, the ASCII representation of an advance plus |
148 // a space is 8 characters and the ASCII representation of a glyph id is 3 | 98 // a space is 8 characters and the ASCII representation of a glyph id is 3 |
149 // characters, then the following cut offs for using different range types | 99 // characters, then the following cut offs for using different range types |
150 // apply: | 100 // apply: |
151 // The cost of stopping and starting the range is 7 characers | 101 // The cost of stopping and starting the range is 7 characers |
152 // a. Removing 4 0's or don't care's is a win | 102 // a. Removing 4 0's or don't care's is a win |
153 // The cost of stopping and starting the range plus a run is 22 | 103 // The cost of stopping and starting the range plus a run is 22 |
154 // characters | 104 // characters |
155 // b. Removing 3 repeating advances is a win | 105 // b. Removing 3 repeating advances is a win |
156 // c. Removing 2 repeating advances and 3 don't cares is a win | 106 // c. Removing 2 repeating advances and 3 don't cares is a win |
157 // When not currently in a range the cost of a run over a range is 16 | 107 // When not currently in a range the cost of a run over a range is 16 |
158 // characaters, so: | 108 // characaters, so: |
159 // d. Removing a leading 0/don't cares is a win because it is omitted | 109 // d. Removing a leading 0/don't cares is a win because it is omitted |
160 // e. Removing 2 repeating advances is a win | 110 // e. Removing 2 repeating advances is a win |
161 | 111 |
162 SkAutoTDelete<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> > result; | 112 WidthRange* prevRange = nullptr; |
163 SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* curRange; | 113 int16_t lastAdvance = kInvalidAdvance; |
164 SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* prevRange = nullptr; | |
165 Data lastAdvance = kInvalidAdvance; | |
166 int repeatedAdvances = 0; | 114 int repeatedAdvances = 0; |
167 int wildCardsInRun = 0; | 115 int wildCardsInRun = 0; |
168 int trailingWildCards = 0; | 116 int trailingWildCards = 0; |
169 uint32_t subsetIndex = 0; | 117 uint32_t subsetIndex = 0; |
170 | 118 |
171 // Limit the loop count to glyph id ranges provided. | 119 // Limit the loop count to glyph id ranges provided. |
172 int firstIndex = 0; | 120 int firstIndex = 0; |
173 int lastIndex = num_glyphs; | 121 int lastIndex = num_glyphs; |
174 if (subsetGlyphIDs) { | 122 if (subsetGlyphIDs) { |
175 firstIndex = static_cast<int>(subsetGlyphIDs[0]); | 123 firstIndex = static_cast<int>(subsetGlyphIDs[0]); |
176 lastIndex = | 124 lastIndex = |
177 static_cast<int>(subsetGlyphIDs[subsetGlyphIDsLength - 1]) + 1; | 125 static_cast<int>(subsetGlyphIDs[subsetGlyphIDsLength - 1]) + 1; |
178 } | 126 } |
179 curRange = appendRange(&result, firstIndex); | 127 WidthRange curRange(firstIndex); |
180 | 128 |
181 for (int gId = firstIndex; gId <= lastIndex; gId++) { | 129 for (int gId = firstIndex; gId <= lastIndex; gId++) { |
182 Data advance = kInvalidAdvance; | 130 int16_t advance = kInvalidAdvance; |
183 if (gId < lastIndex) { | 131 if (gId < lastIndex) { |
184 // Get glyph id only when subset is nullptr, or the id is in subset. | 132 // Get glyph id only when subset is nullptr, or the id is in subset. |
185 SkASSERT(!subsetGlyphIDs || (subsetIndex < subsetGlyphIDsLength && | 133 SkASSERT(!subsetGlyphIDs || (subsetIndex < subsetGlyphIDsLength && |
186 static_cast<uint32_t>(gId) <= subsetGlyphIDs[subsetIndex])); | 134 static_cast<uint32_t>(gId) <= subsetGlyphIDs[subsetIndex])); |
187 if (!subsetGlyphIDs || | 135 if (!subsetGlyphIDs || |
188 (subsetIndex < subsetGlyphIDsLength && | 136 (subsetIndex < subsetGlyphIDsLength && |
189 static_cast<uint32_t>(gId) == subsetGlyphIDs[subsetIndex])) { | 137 static_cast<uint32_t>(gId) == subsetGlyphIDs[subsetIndex])) { |
190 SkAssertResult(getAdvance(fontHandle, gId, &advance)); | 138 SkAssertResult(getAdvance(fontHandle, gId, &advance)); |
191 ++subsetIndex; | 139 ++subsetIndex; |
192 } else { | 140 } else { |
193 advance = kDontCareAdvance; | 141 advance = kDontCareAdvance; |
194 } | 142 } |
195 } | 143 } |
196 if (advance == lastAdvance) { | 144 if (advance == lastAdvance) { |
197 repeatedAdvances++; | 145 repeatedAdvances++; |
198 trailingWildCards = 0; | 146 trailingWildCards = 0; |
199 } else if (advance == kDontCareAdvance) { | 147 } else if (advance == kDontCareAdvance) { |
200 wildCardsInRun++; | 148 wildCardsInRun++; |
201 trailingWildCards++; | 149 trailingWildCards++; |
202 } else if (curRange->fAdvance.count() == | 150 } else if (curRange.fAdvance.count() == |
203 repeatedAdvances + 1 + wildCardsInRun) { // All in run. | 151 repeatedAdvances + 1 + wildCardsInRun) { // All in run. |
204 if (lastAdvance == 0) { | 152 if (lastAdvance == 0) { |
205 resetRange(curRange, gId); | 153 curRange.fStartId = gId; // reset |
| 154 curRange.fAdvance.setCount(0); |
206 trailingWildCards = 0; | 155 trailingWildCards = 0; |
207 } else if (repeatedAdvances + 1 >= 2 || trailingWildCards >= 4) { | 156 } else if (repeatedAdvances + 1 >= 2 || trailingWildCards >= 4) { |
208 finishRange(curRange, gId - 1, | 157 FinishRange(&curRange, gId - 1, WidthRange::kRun); |
209 SkAdvancedTypefaceMetrics::WidthRange::kRun); | 158 prevRange = fGlyphWidths.emplace_back(std::move(curRange)); |
210 prevRange = curRange; | 159 curRange = WidthRange(gId); |
211 curRange = appendRange(&curRange->fNext, gId); | |
212 trailingWildCards = 0; | 160 trailingWildCards = 0; |
213 } | 161 } |
214 repeatedAdvances = 0; | 162 repeatedAdvances = 0; |
215 wildCardsInRun = trailingWildCards; | 163 wildCardsInRun = trailingWildCards; |
216 trailingWildCards = 0; | 164 trailingWildCards = 0; |
217 } else { | 165 } else { |
218 if (lastAdvance == 0 && | 166 if (lastAdvance == 0 && |
219 repeatedAdvances + 1 + wildCardsInRun >= 4) { | 167 repeatedAdvances + 1 + wildCardsInRun >= 4) { |
220 finishRange(curRange, | 168 FinishRange(&curRange, |
221 gId - repeatedAdvances - wildCardsInRun - 2, | 169 gId - repeatedAdvances - wildCardsInRun - 2, |
222 SkAdvancedTypefaceMetrics::WidthRange::kRange); | 170 WidthRange::kRange); |
223 prevRange = curRange; | 171 prevRange = fGlyphWidths.emplace_back(std::move(curRange)); |
224 curRange = appendRange(&curRange->fNext, gId); | 172 curRange = WidthRange(gId); |
225 trailingWildCards = 0; | 173 trailingWildCards = 0; |
226 } else if (trailingWildCards >= 4 && repeatedAdvances + 1 < 2) { | 174 } else if (trailingWildCards >= 4 && repeatedAdvances + 1 < 2) { |
227 finishRange(curRange, | 175 FinishRange(&curRange, gId - trailingWildCards - 1, |
228 gId - trailingWildCards - 1, | 176 WidthRange::kRange); |
229 SkAdvancedTypefaceMetrics::WidthRange::kRange); | 177 prevRange = fGlyphWidths.emplace_back(std::move(curRange)); |
230 prevRange = curRange; | 178 curRange = WidthRange(gId); |
231 curRange = appendRange(&curRange->fNext, gId); | |
232 trailingWildCards = 0; | 179 trailingWildCards = 0; |
233 } else if (lastAdvance != 0 && | 180 } else if (lastAdvance != 0 && |
234 (repeatedAdvances + 1 >= 3 || | 181 (repeatedAdvances + 1 >= 3 || |
235 (repeatedAdvances + 1 >= 2 && wildCardsInRun >= 3))) { | 182 (repeatedAdvances + 1 >= 2 && wildCardsInRun >= 3))) { |
236 finishRange(curRange, | 183 FinishRange(&curRange, |
237 gId - repeatedAdvances - wildCardsInRun - 2, | 184 gId - repeatedAdvances - wildCardsInRun - 2, |
238 SkAdvancedTypefaceMetrics::WidthRange::kRange); | 185 WidthRange::kRange); |
| 186 (void)fGlyphWidths.emplace_back(std::move(curRange)); |
239 curRange = | 187 curRange = |
240 appendRange(&curRange->fNext, | 188 WidthRange(gId - repeatedAdvances - wildCardsInRun - 1); |
241 gId - repeatedAdvances - wildCardsInRun - 1); | 189 curRange.fAdvance.append(1, &lastAdvance); |
242 curRange->fAdvance.append(1, &lastAdvance); | 190 FinishRange(&curRange, gId - 1, WidthRange::kRun); |
243 finishRange(curRange, gId - 1, | 191 prevRange = fGlyphWidths.emplace_back(std::move(curRange)); |
244 SkAdvancedTypefaceMetrics::WidthRange::kRun); | 192 curRange = WidthRange(gId); |
245 prevRange = curRange; | |
246 curRange = appendRange(&curRange->fNext, gId); | |
247 trailingWildCards = 0; | 193 trailingWildCards = 0; |
248 } | 194 } |
249 repeatedAdvances = 0; | 195 repeatedAdvances = 0; |
250 wildCardsInRun = trailingWildCards; | 196 wildCardsInRun = trailingWildCards; |
251 trailingWildCards = 0; | 197 trailingWildCards = 0; |
252 } | 198 } |
253 curRange->fAdvance.append(1, &advance); | 199 curRange.fAdvance.append(1, &advance); |
254 if (advance != kDontCareAdvance) { | 200 if (advance != kDontCareAdvance) { |
255 lastAdvance = advance; | 201 lastAdvance = advance; |
256 } | 202 } |
257 } | 203 } |
258 if (curRange->fStartId == lastIndex) { | 204 if (curRange.fStartId == lastIndex) { |
259 SkASSERT(prevRange); | 205 SkASSERT(prevRange); |
260 if (!prevRange) { | 206 if (!prevRange) { |
261 return nullptr; // https://crbug.com/567031 | 207 fGlyphWidths.reset(); |
| 208 return; // https://crbug.com/567031 |
262 } | 209 } |
263 SkASSERT(prevRange->fNext->fStartId == lastIndex); | |
264 prevRange->fNext.reset(); | |
265 } else { | 210 } else { |
266 finishRange(curRange, lastIndex - 1, | 211 FinishRange(&curRange, lastIndex - 1, WidthRange::kRange); |
267 SkAdvancedTypefaceMetrics::WidthRange::kRange); | 212 fGlyphWidths.emplace_back(std::move(curRange)); |
268 } | 213 } |
269 return result.release(); | |
270 } | 214 } |
271 | 215 |
272 // Make AdvanceMetric template functions available for linking with typename | 216 // Make AdvanceMetric template functions available for linking with typename |
273 // WidthRange and VerticalAdvanceRange. | 217 // WidthRange and VerticalAdvanceRange. |
274 template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData( | 218 template void SkAdvancedTypefaceMetrics::setGlyphWidths( |
275 FT_Face face, | 219 FT_Face face, |
276 int num_glyphs, | 220 int num_glyphs, |
277 const uint32_t* subsetGlyphIDs, | 221 const uint32_t* subsetGlyphIDs, |
278 uint32_t subsetGlyphIDsLength, | 222 uint32_t subsetGlyphIDsLength, |
279 bool (*getAdvance)(FT_Face face, int gId, int16_t* data)); | 223 bool (*getAdvance)(FT_Face face, int gId, int16_t* data)); |
280 | 224 |
281 #if defined(SK_BUILD_FOR_WIN) | 225 #if defined(SK_BUILD_FOR_WIN) |
282 template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData( | 226 template void SkAdvancedTypefaceMetrics::setGlyphWidths( |
283 HDC hdc, | 227 HDC hdc, |
284 int num_glyphs, | 228 int num_glyphs, |
285 const uint32_t* subsetGlyphIDs, | 229 const uint32_t* subsetGlyphIDs, |
286 uint32_t subsetGlyphIDsLength, | 230 uint32_t subsetGlyphIDsLength, |
287 bool (*getAdvance)(HDC hdc, int gId, int16_t* data)); | 231 bool (*getAdvance)(HDC hdc, int gId, int16_t* data)); |
288 template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData( | 232 template void SkAdvancedTypefaceMetrics::setGlyphWidths( |
289 IDWriteFontFace* fontFace, | 233 IDWriteFontFace* fontFace, |
290 int num_glyphs, | 234 int num_glyphs, |
291 const uint32_t* subsetGlyphIDs, | 235 const uint32_t* subsetGlyphIDs, |
292 uint32_t subsetGlyphIDsLength, | 236 uint32_t subsetGlyphIDsLength, |
293 bool (*getAdvance)(IDWriteFontFace* fontFace, int gId, int16_t* data)); | 237 bool (*getAdvance)(IDWriteFontFace* fontFace, int gId, int16_t* data)); |
294 #elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) | 238 #elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) |
295 template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData( | 239 template void SkAdvancedTypefaceMetrics::setGlyphWidths( |
296 CTFontRef ctFont, | 240 CTFontRef ctFont, |
297 int num_glyphs, | 241 int num_glyphs, |
298 const uint32_t* subsetGlyphIDs, | 242 const uint32_t* subsetGlyphIDs, |
299 uint32_t subsetGlyphIDsLength, | 243 uint32_t subsetGlyphIDsLength, |
300 bool (*getAdvance)(CTFontRef ctFont, int gId, int16_t* data)); | 244 bool (*getAdvance)(CTFontRef ctFont, int gId, int16_t* data)); |
301 #endif | 245 #endif |
302 template void resetRange( | |
303 SkAdvancedTypefaceMetrics::WidthRange* range, | |
304 int startId); | |
305 template SkAdvancedTypefaceMetrics::WidthRange* appendRange( | |
306 SkAutoTDelete<SkAdvancedTypefaceMetrics::WidthRange >* nextSlot, | |
307 int startId); | |
308 template void finishRange<int16_t>( | |
309 SkAdvancedTypefaceMetrics::WidthRange* range, | |
310 int endId, | |
311 SkAdvancedTypefaceMetrics::WidthRange::MetricType type); | |
312 | |
313 template void resetRange( | |
314 SkAdvancedTypefaceMetrics::VerticalAdvanceRange* range, | |
315 int startId); | |
316 template SkAdvancedTypefaceMetrics::VerticalAdvanceRange* appendRange( | |
317 SkAutoTDelete<SkAdvancedTypefaceMetrics::VerticalAdvanceRange >* | |
318 nextSlot, | |
319 int startId); | |
320 template void finishRange<SkAdvancedTypefaceMetrics::VerticalMetric>( | |
321 SkAdvancedTypefaceMetrics::VerticalAdvanceRange* range, | |
322 int endId, | |
323 SkAdvancedTypefaceMetrics::VerticalAdvanceRange::MetricType type); | |
324 | |
325 // additional declaration needed for testing with a face of an unknown type | 246 // additional declaration needed for testing with a face of an unknown type |
326 template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData( | 247 template void SkAdvancedTypefaceMetrics::setGlyphWidths( |
327 void* fontData, | 248 void* fontData, |
328 int num_glyphs, | 249 int num_glyphs, |
329 const uint32_t* subsetGlyphIDs, | 250 const uint32_t* subsetGlyphIDs, |
330 uint32_t subsetGlyphIDsLength, | 251 uint32_t subsetGlyphIDsLength, |
331 bool (*getAdvance)(void* fontData, int gId, int16_t* data)); | 252 bool (*getAdvance)(void* fontData, int gId, int16_t* data)); |
332 | |
333 } // namespace skia_advanced_typeface_metrics_utils | |
OLD | NEW |