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