1 :
2 : /*
3 : * Copyright 2011 Google Inc.
4 : *
5 : * Use of this source code is governed by a BSD-style license that can be
6 : * found in the LICENSE file.
7 : */
8 :
9 :
10 : #include "SkAdvancedTypefaceMetrics.h"
11 : #include "SkTypes.h"
12 :
13 : #if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID)
14 : #include <ft2build.h>
15 : #include FT_FREETYPE_H
16 : #endif
17 :
18 : #ifdef SK_BUILD_FOR_MAC
19 : #import <ApplicationServices/ApplicationServices.h>
20 : #endif
21 :
22 : #ifdef SK_BUILD_FOR_IOS
23 : #include <CoreText/CoreText.h>
24 : #include <CoreGraphics/CoreGraphics.h>
25 : #include <CoreFoundation/CoreFoundation.h>
26 : #endif
27 :
28 : namespace skia_advanced_typeface_metrics_utils {
29 :
30 : const int16_t kInvalidAdvance = SK_MinS16;
31 : const int16_t kDontCareAdvance = SK_MinS16 + 1;
32 :
33 : template <typename Data>
34 0 : void stripUninterestingTrailingAdvancesFromRange(
35 : SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range) {
36 0 : SkASSERT(false);
37 0 : }
38 :
39 : template <>
40 0 : void stripUninterestingTrailingAdvancesFromRange<int16_t>(
41 : SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>* range) {
42 0 : SkASSERT(range);
43 :
44 0 : int expectedAdvanceCount = range->fEndId - range->fStartId + 1;
45 0 : if (range->fAdvance.count() < expectedAdvanceCount) {
46 0 : return;
47 : }
48 :
49 0 : for (int i = expectedAdvanceCount - 1; i >= 0; --i) {
50 0 : if (range->fAdvance[i] != kDontCareAdvance &&
51 0 : range->fAdvance[i] != kInvalidAdvance &&
52 0 : range->fAdvance[i] != 0) {
53 0 : range->fEndId = range->fStartId + i;
54 0 : break;
55 : }
56 : }
57 : }
58 :
59 : template <typename Data>
60 : void resetRange(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
61 0 : int startId) {
62 0 : range->fStartId = startId;
63 0 : range->fAdvance.setCount(0);
64 0 : }
65 :
66 : template <typename Data>
67 : SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* appendRange(
68 : SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> >* nextSlot,
69 0 : int startId) {
70 0 : nextSlot->reset(new SkAdvancedTypefaceMetrics::AdvanceMetric<Data>);
71 0 : resetRange(nextSlot->get(), startId);
72 0 : return nextSlot->get();
73 : }
74 :
75 : template <typename Data>
76 0 : void zeroWildcardsInRange(
77 : SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range) {
78 0 : SkASSERT(false);
79 0 : }
80 :
81 : template <>
82 0 : void zeroWildcardsInRange<int16_t>(
83 : SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>* range) {
84 0 : SkASSERT(range);
85 0 : if (range->fType != SkAdvancedTypefaceMetrics::WidthRange::kRange) {
86 0 : return;
87 : }
88 0 : SkASSERT(range->fAdvance.count() == range->fEndId - range->fStartId + 1);
89 :
90 : // Zero out wildcards.
91 0 : for (int i = 0; i < range->fAdvance.count(); ++i) {
92 0 : if (range->fAdvance[i] == kDontCareAdvance) {
93 0 : range->fAdvance[i] = 0;
94 : }
95 : }
96 : }
97 :
98 : template <typename Data>
99 : void finishRange(
100 : SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
101 : int endId,
102 : typename SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::MetricType
103 0 : type) {
104 0 : range->fEndId = endId;
105 0 : range->fType = type;
106 0 : stripUninterestingTrailingAdvancesFromRange(range);
107 : int newLength;
108 0 : if (type == SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange) {
109 0 : newLength = range->fEndId - range->fStartId + 1;
110 : } else {
111 0 : if (range->fEndId == range->fStartId) {
112 0 : range->fType =
113 : SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange;
114 : }
115 0 : newLength = 1;
116 : }
117 0 : SkASSERT(range->fAdvance.count() >= newLength);
118 0 : range->fAdvance.setCount(newLength);
119 0 : zeroWildcardsInRange(range);
120 0 : }
121 :
122 : template <typename Data, typename FontHandle>
123 : SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData(
124 : FontHandle fontHandle,
125 : int num_glyphs,
126 : const uint32_t* subsetGlyphIDs,
127 : uint32_t subsetGlyphIDsLength,
128 0 : bool (*getAdvance)(FontHandle fontHandle, int gId, Data* data)) {
129 : // Assuming that on average, the ASCII representation of an advance plus
130 : // a space is 8 characters and the ASCII representation of a glyph id is 3
131 : // characters, then the following cut offs for using different range types
132 : // apply:
133 : // The cost of stopping and starting the range is 7 characers
134 : // a. Removing 4 0's or don't care's is a win
135 : // The cost of stopping and starting the range plus a run is 22
136 : // characters
137 : // b. Removing 3 repeating advances is a win
138 : // c. Removing 2 repeating advances and 3 don't cares is a win
139 : // When not currently in a range the cost of a run over a range is 16
140 : // characaters, so:
141 : // d. Removing a leading 0/don't cares is a win because it is omitted
142 : // e. Removing 2 repeating advances is a win
143 :
144 0 : SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> > result;
145 : SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* curRange;
146 0 : SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* prevRange = NULL;
147 0 : Data lastAdvance = kInvalidAdvance;
148 0 : int repeatedAdvances = 0;
149 0 : int wildCardsInRun = 0;
150 0 : int leadingWildCards = 0;
151 0 : int trailingWildCards = 0;
152 0 : uint32_t subsetIndex = 0;
153 :
154 : // Limit the loop count to glyph id ranges provided.
155 0 : int firstIndex = 0;
156 0 : int lastIndex = num_glyphs;
157 0 : if (subsetGlyphIDs) {
158 0 : firstIndex = static_cast<int>(subsetGlyphIDs[0]);
159 0 : lastIndex =
160 : static_cast<int>(subsetGlyphIDs[subsetGlyphIDsLength - 1]) + 1;
161 : }
162 0 : curRange = appendRange(&result, firstIndex);
163 :
164 0 : for (int gId = firstIndex; gId <= lastIndex; gId++) {
165 0 : Data advance = kInvalidAdvance;
166 0 : if (gId < lastIndex) {
167 : // Get glyph id only when subset is NULL, or the id is in subset.
168 0 : if (!subsetGlyphIDs ||
169 : (subsetIndex < subsetGlyphIDsLength &&
170 : static_cast<uint32_t>(gId) == subsetGlyphIDs[subsetIndex])) {
171 0 : SkAssertResult(getAdvance(fontHandle, gId, &advance));
172 0 : ++subsetIndex;
173 : } else {
174 0 : advance = kDontCareAdvance;
175 : }
176 : }
177 0 : if (advance == lastAdvance) {
178 0 : repeatedAdvances++;
179 0 : trailingWildCards = 0;
180 0 : } else if (advance == kDontCareAdvance) {
181 0 : wildCardsInRun++;
182 0 : trailingWildCards++;
183 0 : } else if (curRange->fAdvance.count() ==
184 : repeatedAdvances + 1 + wildCardsInRun) { // All in run.
185 0 : if (lastAdvance == 0) {
186 0 : resetRange(curRange, gId);
187 0 : trailingWildCards = 0;
188 0 : } else if (repeatedAdvances + 1 >= 2 || trailingWildCards >= 4) {
189 0 : finishRange(curRange, gId - 1,
190 : SkAdvancedTypefaceMetrics::WidthRange::kRun);
191 0 : prevRange = curRange;
192 0 : curRange = appendRange(&curRange->fNext, gId);
193 0 : trailingWildCards = 0;
194 : }
195 0 : repeatedAdvances = 0;
196 0 : wildCardsInRun = trailingWildCards;
197 0 : leadingWildCards = trailingWildCards;
198 0 : trailingWildCards = 0;
199 : } else {
200 0 : if (lastAdvance == 0 &&
201 : repeatedAdvances + 1 + wildCardsInRun >= 4) {
202 0 : finishRange(curRange,
203 : gId - repeatedAdvances - wildCardsInRun - 2,
204 : SkAdvancedTypefaceMetrics::WidthRange::kRange);
205 0 : prevRange = curRange;
206 0 : curRange = appendRange(&curRange->fNext, gId);
207 0 : trailingWildCards = 0;
208 0 : } else if (trailingWildCards >= 4 && repeatedAdvances + 1 < 2) {
209 0 : finishRange(curRange,
210 : gId - trailingWildCards - 1,
211 : SkAdvancedTypefaceMetrics::WidthRange::kRange);
212 0 : prevRange = curRange;
213 0 : curRange = appendRange(&curRange->fNext, gId);
214 0 : trailingWildCards = 0;
215 0 : } else if (lastAdvance != 0 &&
216 : (repeatedAdvances + 1 >= 3 ||
217 : (repeatedAdvances + 1 >= 2 && wildCardsInRun >= 3))) {
218 0 : finishRange(curRange,
219 : gId - repeatedAdvances - wildCardsInRun - 2,
220 : SkAdvancedTypefaceMetrics::WidthRange::kRange);
221 0 : curRange =
222 : appendRange(&curRange->fNext,
223 : gId - repeatedAdvances - wildCardsInRun - 1);
224 0 : curRange->fAdvance.append(1, &lastAdvance);
225 0 : finishRange(curRange, gId - 1,
226 : SkAdvancedTypefaceMetrics::WidthRange::kRun);
227 0 : prevRange = curRange;
228 0 : curRange = appendRange(&curRange->fNext, gId);
229 0 : trailingWildCards = 0;
230 : }
231 0 : repeatedAdvances = 0;
232 0 : wildCardsInRun = trailingWildCards;
233 0 : leadingWildCards = trailingWildCards;
234 0 : trailingWildCards = 0;
235 : }
236 0 : curRange->fAdvance.append(1, &advance);
237 0 : if (advance != kDontCareAdvance) {
238 0 : lastAdvance = advance;
239 : }
240 : }
241 0 : if (curRange->fStartId == lastIndex) {
242 0 : SkASSERT(prevRange);
243 0 : SkASSERT(prevRange->fNext->fStartId == lastIndex);
244 0 : prevRange->fNext.reset();
245 : } else {
246 0 : finishRange(curRange, lastIndex - 1,
247 : SkAdvancedTypefaceMetrics::WidthRange::kRange);
248 : }
249 0 : return result.release();
250 : }
251 :
252 : // Make AdvanceMetric template functions available for linking with typename
253 : // WidthRange and VerticalAdvanceRange.
254 : #if defined(SK_BUILD_FOR_WIN)
255 : template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
256 : HDC hdc,
257 : int num_glyphs,
258 : const uint32_t* subsetGlyphIDs,
259 : uint32_t subsetGlyphIDsLength,
260 : bool (*getAdvance)(HDC hdc, int gId, int16_t* data));
261 : #elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID)
262 : template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
263 : FT_Face face,
264 : int num_glyphs,
265 : const uint32_t* subsetGlyphIDs,
266 : uint32_t subsetGlyphIDsLength,
267 : bool (*getAdvance)(FT_Face face, int gId, int16_t* data));
268 : #elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
269 : template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
270 : CTFontRef ctFont,
271 : int num_glyphs,
272 : const uint32_t* subsetGlyphIDs,
273 : uint32_t subsetGlyphIDsLength,
274 : bool (*getAdvance)(CTFontRef ctFont, int gId, int16_t* data));
275 : #endif
276 : template void resetRange(
277 : SkAdvancedTypefaceMetrics::WidthRange* range,
278 : int startId);
279 : template SkAdvancedTypefaceMetrics::WidthRange* appendRange(
280 : SkTScopedPtr<SkAdvancedTypefaceMetrics::WidthRange >* nextSlot,
281 : int startId);
282 : template void finishRange<int16_t>(
283 : SkAdvancedTypefaceMetrics::WidthRange* range,
284 : int endId,
285 : SkAdvancedTypefaceMetrics::WidthRange::MetricType type);
286 :
287 : template void resetRange(
288 : SkAdvancedTypefaceMetrics::VerticalAdvanceRange* range,
289 : int startId);
290 : template SkAdvancedTypefaceMetrics::VerticalAdvanceRange* appendRange(
291 : SkTScopedPtr<SkAdvancedTypefaceMetrics::VerticalAdvanceRange >*
292 : nextSlot,
293 : int startId);
294 : template void finishRange<SkAdvancedTypefaceMetrics::VerticalMetric>(
295 : SkAdvancedTypefaceMetrics::VerticalAdvanceRange* range,
296 : int endId,
297 : SkAdvancedTypefaceMetrics::VerticalAdvanceRange::MetricType type);
298 :
299 : } // namespace skia_advanced_typeface_metrics_utils
|