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 #include <ctype.h> | 8 #include <ctype.h> |
9 | 9 |
10 #include "SkData.h" | 10 #include "SkData.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 #else | 29 #else |
30 #include SK_SFNTLY_SUBSETTER | 30 #include SK_SFNTLY_SUBSETTER |
31 #endif | 31 #endif |
32 #endif | 32 #endif |
33 | 33 |
34 // PDF's notion of symbolic vs non-symbolic is related to the character set, not | 34 // PDF's notion of symbolic vs non-symbolic is related to the character set, not |
35 // symbols vs. characters. Rarely is a font the right character set to call it | 35 // symbols vs. characters. Rarely is a font the right character set to call it |
36 // non-symbolic, so always call it symbolic. (PDF 1.4 spec, section 5.7.1) | 36 // non-symbolic, so always call it symbolic. (PDF 1.4 spec, section 5.7.1) |
37 static const int kPdfSymbolic = 4; | 37 static const int kPdfSymbolic = 4; |
38 | 38 |
| 39 struct AdvanceMetric { |
| 40 enum MetricType { |
| 41 kDefault, // Default advance: fAdvance.count = 1 |
| 42 kRange, // Advances for a range: fAdvance.count = fEndID-fStartID |
| 43 kRun // fStartID-fEndID have same advance: fAdvance.count = 1 |
| 44 }; |
| 45 MetricType fType; |
| 46 uint16_t fStartId; |
| 47 uint16_t fEndId; |
| 48 SkTDArray<int16_t> fAdvance; |
| 49 AdvanceMetric(uint16_t startId) : fStartId(startId) {} |
| 50 AdvanceMetric(AdvanceMetric&&) = default; |
| 51 AdvanceMetric& operator=(AdvanceMetric&& other) = default; |
| 52 AdvanceMetric(const AdvanceMetric&) = delete; |
| 53 AdvanceMetric& operator=(const AdvanceMetric&) = delete; |
| 54 }; |
| 55 |
39 namespace { | 56 namespace { |
40 | 57 |
41 /////////////////////////////////////////////////////////////////////////////// | 58 /////////////////////////////////////////////////////////////////////////////// |
42 // File-Local Functions | 59 // File-Local Functions |
43 /////////////////////////////////////////////////////////////////////////////// | 60 /////////////////////////////////////////////////////////////////////////////// |
44 | 61 |
| 62 const int16_t kInvalidAdvance = SK_MinS16; |
| 63 const int16_t kDontCareAdvance = SK_MinS16 + 1; |
| 64 |
| 65 static void stripUninterestingTrailingAdvancesFromRange( |
| 66 AdvanceMetric* range) { |
| 67 SkASSERT(range); |
| 68 |
| 69 int expectedAdvanceCount = range->fEndId - range->fStartId + 1; |
| 70 if (range->fAdvance.count() < expectedAdvanceCount) { |
| 71 return; |
| 72 } |
| 73 |
| 74 for (int i = expectedAdvanceCount - 1; i >= 0; --i) { |
| 75 if (range->fAdvance[i] != kDontCareAdvance && |
| 76 range->fAdvance[i] != kInvalidAdvance && |
| 77 range->fAdvance[i] != 0) { |
| 78 range->fEndId = range->fStartId + i; |
| 79 break; |
| 80 } |
| 81 } |
| 82 } |
| 83 |
| 84 static void zeroWildcardsInRange(AdvanceMetric* range) { |
| 85 SkASSERT(range); |
| 86 if (range->fType != AdvanceMetric::kRange) { |
| 87 return; |
| 88 } |
| 89 SkASSERT(range->fAdvance.count() == range->fEndId - range->fStartId + 1); |
| 90 |
| 91 // Zero out wildcards. |
| 92 for (int i = 0; i < range->fAdvance.count(); ++i) { |
| 93 if (range->fAdvance[i] == kDontCareAdvance) { |
| 94 range->fAdvance[i] = 0; |
| 95 } |
| 96 } |
| 97 } |
| 98 |
| 99 static void FinishRange( |
| 100 AdvanceMetric* range, |
| 101 int endId, |
| 102 AdvanceMetric::MetricType type) { |
| 103 range->fEndId = endId; |
| 104 range->fType = type; |
| 105 stripUninterestingTrailingAdvancesFromRange(range); |
| 106 int newLength; |
| 107 if (type == AdvanceMetric::kRange) { |
| 108 newLength = range->fEndId - range->fStartId + 1; |
| 109 } else { |
| 110 if (range->fEndId == range->fStartId) { |
| 111 range->fType = AdvanceMetric::kRange; |
| 112 } |
| 113 newLength = 1; |
| 114 } |
| 115 SkASSERT(range->fAdvance.count() >= newLength); |
| 116 range->fAdvance.setCount(newLength); |
| 117 zeroWildcardsInRange(range); |
| 118 } |
| 119 |
| 120 |
| 121 /** Retrieve advance data for glyphs. Used by the PDF backend. |
| 122 @param num_glyphs Total number of glyphs in the given font. |
| 123 @param glyphIDs For per-glyph info, specify subset of the |
| 124 font by giving glyph ids. Each integer |
| 125 represents a glyph id. Passing nullptr |
| 126 means all glyphs in the font. |
| 127 @param glyphIDsCount Number of elements in subsetGlyphIds. |
| 128 Ignored if glyphIDs is nullptr. |
| 129 */ |
| 130 // TODO(halcanary): this function is complex enough to need its logic |
| 131 // tested with unit tests. On the other hand, I want to do another |
| 132 // round of re-factoring before figuring out how to mock this. |
| 133 // TODO(halcanary): this function should be combined with |
| 134 // composeAdvanceData() so that we don't need to produce a linked list |
| 135 // of intermediate values. Or we could make the intermediate value |
| 136 // something other than a linked list. |
| 137 static void get_glyph_widths(SkSinglyLinkedList<AdvanceMetric>* glyphWidths, |
| 138 int num_glyphs, |
| 139 const uint32_t* subsetGlyphIDs, |
| 140 uint32_t subsetGlyphIDsLength, |
| 141 SkGlyphCache* glyphCache) { |
| 142 // Assuming that on average, the ASCII representation of an advance plus |
| 143 // a space is 8 characters and the ASCII representation of a glyph id is 3 |
| 144 // characters, then the following cut offs for using different range types |
| 145 // apply: |
| 146 // The cost of stopping and starting the range is 7 characers |
| 147 // a. Removing 4 0's or don't care's is a win |
| 148 // The cost of stopping and starting the range plus a run is 22 |
| 149 // characters |
| 150 // b. Removing 3 repeating advances is a win |
| 151 // c. Removing 2 repeating advances and 3 don't cares is a win |
| 152 // When not currently in a range the cost of a run over a range is 16 |
| 153 // characaters, so: |
| 154 // d. Removing a leading 0/don't cares is a win because it is omitted |
| 155 // e. Removing 2 repeating advances is a win |
| 156 |
| 157 AdvanceMetric* prevRange = nullptr; |
| 158 int16_t lastAdvance = kInvalidAdvance; |
| 159 int repeatedAdvances = 0; |
| 160 int wildCardsInRun = 0; |
| 161 int trailingWildCards = 0; |
| 162 uint32_t subsetIndex = 0; |
| 163 |
| 164 // Limit the loop count to glyph id ranges provided. |
| 165 int firstIndex = 0; |
| 166 int lastIndex = num_glyphs; |
| 167 if (subsetGlyphIDs) { |
| 168 firstIndex = static_cast<int>(subsetGlyphIDs[0]); |
| 169 lastIndex = |
| 170 static_cast<int>(subsetGlyphIDs[subsetGlyphIDsLength - 1]) + 1; |
| 171 } |
| 172 AdvanceMetric curRange(firstIndex); |
| 173 |
| 174 for (int gId = firstIndex; gId <= lastIndex; gId++) { |
| 175 int16_t advance = kInvalidAdvance; |
| 176 if (gId < lastIndex) { |
| 177 // Get glyph id only when subset is nullptr, or the id is in subset. |
| 178 SkASSERT(!subsetGlyphIDs || (subsetIndex < subsetGlyphIDsLength && |
| 179 static_cast<uint32_t>(gId) <= subsetGlyphIDs[subsetIndex])); |
| 180 if (!subsetGlyphIDs || |
| 181 (subsetIndex < subsetGlyphIDsLength && |
| 182 static_cast<uint32_t>(gId) == subsetGlyphIDs[subsetIndex])) { |
| 183 advance = (int16_t)glyphCache->getGlyphIDAdvance(gId).fAdvanceX; |
| 184 ++subsetIndex; |
| 185 } else { |
| 186 advance = kDontCareAdvance; |
| 187 } |
| 188 } |
| 189 if (advance == lastAdvance) { |
| 190 repeatedAdvances++; |
| 191 trailingWildCards = 0; |
| 192 } else if (advance == kDontCareAdvance) { |
| 193 wildCardsInRun++; |
| 194 trailingWildCards++; |
| 195 } else if (curRange.fAdvance.count() == |
| 196 repeatedAdvances + 1 + wildCardsInRun) { // All in run. |
| 197 if (lastAdvance == 0) { |
| 198 curRange.fStartId = gId; // reset |
| 199 curRange.fAdvance.setCount(0); |
| 200 trailingWildCards = 0; |
| 201 } else if (repeatedAdvances + 1 >= 2 || trailingWildCards >= 4) { |
| 202 FinishRange(&curRange, gId - 1, AdvanceMetric::kRun); |
| 203 prevRange = glyphWidths->emplace_back(std::move(curRange)); |
| 204 curRange = AdvanceMetric(gId); |
| 205 trailingWildCards = 0; |
| 206 } |
| 207 repeatedAdvances = 0; |
| 208 wildCardsInRun = trailingWildCards; |
| 209 trailingWildCards = 0; |
| 210 } else { |
| 211 if (lastAdvance == 0 && |
| 212 repeatedAdvances + 1 + wildCardsInRun >= 4) { |
| 213 FinishRange(&curRange, |
| 214 gId - repeatedAdvances - wildCardsInRun - 2, |
| 215 AdvanceMetric::kRange); |
| 216 prevRange = glyphWidths->emplace_back(std::move(curRange)); |
| 217 curRange = AdvanceMetric(gId); |
| 218 trailingWildCards = 0; |
| 219 } else if (trailingWildCards >= 4 && repeatedAdvances + 1 < 2) { |
| 220 FinishRange(&curRange, gId - trailingWildCards - 1, |
| 221 AdvanceMetric::kRange); |
| 222 prevRange = glyphWidths->emplace_back(std::move(curRange)); |
| 223 curRange = AdvanceMetric(gId); |
| 224 trailingWildCards = 0; |
| 225 } else if (lastAdvance != 0 && |
| 226 (repeatedAdvances + 1 >= 3 || |
| 227 (repeatedAdvances + 1 >= 2 && wildCardsInRun >= 3))) { |
| 228 FinishRange(&curRange, |
| 229 gId - repeatedAdvances - wildCardsInRun - 2, |
| 230 AdvanceMetric::kRange); |
| 231 (void)glyphWidths->emplace_back(std::move(curRange)); |
| 232 curRange = |
| 233 AdvanceMetric(gId - repeatedAdvances - wildCardsInRun -
1); |
| 234 curRange.fAdvance.append(1, &lastAdvance); |
| 235 FinishRange(&curRange, gId - 1, AdvanceMetric::kRun); |
| 236 prevRange = glyphWidths->emplace_back(std::move(curRange)); |
| 237 curRange = AdvanceMetric(gId); |
| 238 trailingWildCards = 0; |
| 239 } |
| 240 repeatedAdvances = 0; |
| 241 wildCardsInRun = trailingWildCards; |
| 242 trailingWildCards = 0; |
| 243 } |
| 244 curRange.fAdvance.append(1, &advance); |
| 245 if (advance != kDontCareAdvance) { |
| 246 lastAdvance = advance; |
| 247 } |
| 248 } |
| 249 if (curRange.fStartId == lastIndex) { |
| 250 if (!prevRange) { |
| 251 glyphWidths->reset(); |
| 252 return; // https://crbug.com/567031 |
| 253 } |
| 254 } else { |
| 255 FinishRange(&curRange, lastIndex - 1, AdvanceMetric::kRange); |
| 256 glyphWidths->emplace_back(std::move(curRange)); |
| 257 } |
| 258 } |
| 259 |
| 260 //////////////////////////////////////////////////////////////////////////////// |
| 261 |
| 262 |
45 bool parsePFBSection(const uint8_t** src, size_t* len, int sectionType, | 263 bool parsePFBSection(const uint8_t** src, size_t* len, int sectionType, |
46 size_t* size) { | 264 size_t* size) { |
47 // PFB sections have a two or six bytes header. 0x80 and a one byte | 265 // PFB sections have a two or six bytes header. 0x80 and a one byte |
48 // section type followed by a four byte section length. Type one is | 266 // section type followed by a four byte section length. Type one is |
49 // an ASCII section (includes a length), type two is a binary section | 267 // an ASCII section (includes a length), type two is a binary section |
50 // (includes a length) and type three is an EOF marker with no length. | 268 // (includes a length) and type three is an EOF marker with no length. |
51 const uint8_t* buf = *src; | 269 const uint8_t* buf = *src; |
52 if (*len < 2 || buf[0] != 0x80 || buf[1] != sectionType) { | 270 if (*len < 2 || buf[0] != 0x80 || buf[1] != sectionType) { |
53 return false; | 271 return false; |
54 } else if (buf[1] == 3) { | 272 } else if (buf[1] == 3) { |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 auto bbox = sk_make_sp<SkPDFArray>(); | 513 auto bbox = sk_make_sp<SkPDFArray>(); |
296 bbox->reserve(4); | 514 bbox->reserve(4); |
297 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fLeft, emSize)); | 515 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fLeft, emSize)); |
298 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fBottom, emSize)); | 516 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fBottom, emSize)); |
299 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fRight, emSize)); | 517 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fRight, emSize)); |
300 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fTop, emSize)); | 518 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fTop, emSize)); |
301 return bbox; | 519 return bbox; |
302 } | 520 } |
303 | 521 |
304 sk_sp<SkPDFArray> composeAdvanceData( | 522 sk_sp<SkPDFArray> composeAdvanceData( |
305 const SkSinglyLinkedList<SkAdvancedTypefaceMetrics::WidthRange>& advance
Info, | 523 const SkSinglyLinkedList<AdvanceMetric>& advanceInfo, |
306 uint16_t emSize, | 524 uint16_t emSize, |
307 int16_t* defaultAdvance) { | 525 int16_t* defaultAdvance) { |
308 auto result = sk_make_sp<SkPDFArray>(); | 526 auto result = sk_make_sp<SkPDFArray>(); |
309 for (const SkAdvancedTypefaceMetrics::WidthRange& range : advanceInfo) { | 527 for (const AdvanceMetric& range : advanceInfo) { |
310 switch (range.fType) { | 528 switch (range.fType) { |
311 case SkAdvancedTypefaceMetrics::WidthRange::kDefault: { | 529 case AdvanceMetric::kDefault: { |
312 SkASSERT(range.fAdvance.count() == 1); | 530 SkASSERT(range.fAdvance.count() == 1); |
313 *defaultAdvance = range.fAdvance[0]; | 531 *defaultAdvance = range.fAdvance[0]; |
314 break; | 532 break; |
315 } | 533 } |
316 case SkAdvancedTypefaceMetrics::WidthRange::kRange: { | 534 case AdvanceMetric::kRange: { |
317 auto advanceArray = sk_make_sp<SkPDFArray>(); | 535 auto advanceArray = sk_make_sp<SkPDFArray>(); |
318 for (int j = 0; j < range.fAdvance.count(); j++) | 536 for (int j = 0; j < range.fAdvance.count(); j++) |
319 advanceArray->appendScalar( | 537 advanceArray->appendScalar( |
320 scaleFromFontUnits(range.fAdvance[j], emSize)); | 538 scaleFromFontUnits(range.fAdvance[j], emSize)); |
321 result->appendInt(range.fStartId); | 539 result->appendInt(range.fStartId); |
322 result->appendObject(std::move(advanceArray)); | 540 result->appendObject(std::move(advanceArray)); |
323 break; | 541 break; |
324 } | 542 } |
325 case SkAdvancedTypefaceMetrics::WidthRange::kRun: { | 543 case AdvanceMetric::kRun: { |
326 SkASSERT(range.fAdvance.count() == 1); | 544 SkASSERT(range.fAdvance.count() == 1); |
327 result->appendInt(range.fStartId); | 545 result->appendInt(range.fStartId); |
328 result->appendInt(range.fEndId); | 546 result->appendInt(range.fEndId); |
329 result->appendScalar( | 547 result->appendScalar( |
330 scaleFromFontUnits(range.fAdvance[0], emSize)); | 548 scaleFromFontUnits(range.fAdvance[0], emSize)); |
331 break; | 549 break; |
332 } | 550 } |
333 } | 551 } |
334 } | 552 } |
335 return result; | 553 return result; |
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1035 } | 1253 } |
1036 default: | 1254 default: |
1037 SkASSERT(false); | 1255 SkASSERT(false); |
1038 } | 1256 } |
1039 this->insertObjRef("FontDescriptor", std::move(descriptor)); | 1257 this->insertObjRef("FontDescriptor", std::move(descriptor)); |
1040 return true; | 1258 return true; |
1041 } | 1259 } |
1042 | 1260 |
1043 void set_glyph_widths(SkTypeface* tf, | 1261 void set_glyph_widths(SkTypeface* tf, |
1044 const SkTDArray<uint32_t>* glyphIDs, | 1262 const SkTDArray<uint32_t>* glyphIDs, |
1045 SkAdvancedTypefaceMetrics* dst) { | 1263 SkSinglyLinkedList<AdvanceMetric>* dst) { |
1046 SkPaint tmpPaint; | 1264 SkPaint tmpPaint; |
1047 tmpPaint.setHinting(SkPaint::kNo_Hinting); | 1265 tmpPaint.setHinting(SkPaint::kNo_Hinting); |
1048 tmpPaint.setTypeface(sk_ref_sp(tf)); | 1266 tmpPaint.setTypeface(sk_ref_sp(tf)); |
1049 tmpPaint.setTextSize((SkScalar)tf->getUnitsPerEm()); | 1267 tmpPaint.setTextSize((SkScalar)tf->getUnitsPerEm()); |
1050 SkAutoGlyphCache autoGlyphCache(tmpPaint, nullptr, nullptr); | 1268 SkAutoGlyphCache autoGlyphCache(tmpPaint, nullptr, nullptr); |
1051 SkGlyphCache* glyphCache = autoGlyphCache.get(); | |
1052 SkAdvancedTypefaceMetrics::GetAdvance advanceFn = | |
1053 [glyphCache](int gid, int16_t* advance) { | |
1054 *advance = (int16_t)glyphCache->getGlyphIDAdvance(gid).fAdvanceX; | |
1055 return true; | |
1056 }; | |
1057 if (!glyphIDs || glyphIDs->isEmpty()) { | 1269 if (!glyphIDs || glyphIDs->isEmpty()) { |
1058 dst->setGlyphWidths(tf->countGlyphs(), nullptr, 0, advanceFn); | 1270 get_glyph_widths(dst, tf->countGlyphs(), nullptr, 0, autoGlyphCache.get(
)); |
1059 } else { | 1271 } else { |
1060 dst->setGlyphWidths(tf->countGlyphs(), | 1272 get_glyph_widths(dst, tf->countGlyphs(), glyphIDs->begin(), |
1061 glyphIDs->begin(), | 1273 glyphIDs->count(), autoGlyphCache.get()); |
1062 glyphIDs->count(), advanceFn); | |
1063 } | 1274 } |
1064 } | 1275 } |
1065 | 1276 |
1066 bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) { | 1277 bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) { |
1067 // Generate new font metrics with advance info for true type fonts. | 1278 // Generate new font metrics with advance info for true type fonts. |
1068 // Generate glyph id array. | 1279 // Generate glyph id array. |
1069 SkTDArray<uint32_t> glyphIDs; | 1280 SkTDArray<uint32_t> glyphIDs; |
1070 if (subset) { | 1281 if (subset) { |
1071 if (!subset->has(0)) { | 1282 if (!subset->has(0)) { |
1072 glyphIDs.push(0); // Always include glyph 0. | 1283 glyphIDs.push(0); // Always include glyph 0. |
(...skipping 23 matching lines...) Expand all Loading... |
1096 } else { | 1307 } else { |
1097 SkASSERT(false); | 1308 SkASSERT(false); |
1098 } | 1309 } |
1099 | 1310 |
1100 auto sysInfo = sk_make_sp<SkPDFDict>(); | 1311 auto sysInfo = sk_make_sp<SkPDFDict>(); |
1101 sysInfo->insertString("Registry", "Adobe"); | 1312 sysInfo->insertString("Registry", "Adobe"); |
1102 sysInfo->insertString("Ordering", "Identity"); | 1313 sysInfo->insertString("Ordering", "Identity"); |
1103 sysInfo->insertInt("Supplement", 0); | 1314 sysInfo->insertInt("Supplement", 0); |
1104 this->insertObject("CIDSystemInfo", std::move(sysInfo)); | 1315 this->insertObject("CIDSystemInfo", std::move(sysInfo)); |
1105 | 1316 |
1106 SkAdvancedTypefaceMetrics tmpMetrics; | 1317 SkSinglyLinkedList<AdvanceMetric> tmpMetrics; |
1107 set_glyph_widths(this->typeface(), &glyphIDs, &tmpMetrics); | 1318 set_glyph_widths(this->typeface(), &glyphIDs, &tmpMetrics); |
1108 int16_t defaultWidth = 0; | 1319 int16_t defaultWidth = 0; |
1109 uint16_t emSize = (uint16_t)this->fontInfo()->fEmSize; | 1320 uint16_t emSize = (uint16_t)this->fontInfo()->fEmSize; |
1110 sk_sp<SkPDFArray> widths = composeAdvanceData( | 1321 sk_sp<SkPDFArray> widths = composeAdvanceData(tmpMetrics, emSize, &defaultWi
dth); |
1111 tmpMetrics.fGlyphWidths, emSize, &defaultWidth); | |
1112 if (widths->size()) { | 1322 if (widths->size()) { |
1113 this->insertObject("W", std::move(widths)); | 1323 this->insertObject("W", std::move(widths)); |
1114 } | 1324 } |
1115 | 1325 |
1116 this->insertScalar( | 1326 this->insertScalar( |
1117 "DW", scaleFromFontUnits(defaultWidth, emSize)); | 1327 "DW", scaleFromFontUnits(defaultWidth, emSize)); |
1118 return true; | 1328 return true; |
1119 } | 1329 } |
1120 | 1330 |
1121 /////////////////////////////////////////////////////////////////////////////// | 1331 /////////////////////////////////////////////////////////////////////////////// |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1162 fontStream->dict()->insertInt("Length2", data); | 1372 fontStream->dict()->insertInt("Length2", data); |
1163 fontStream->dict()->insertInt("Length3", trailer); | 1373 fontStream->dict()->insertInt("Length3", trailer); |
1164 descriptor->insertObjRef("FontFile", std::move(fontStream)); | 1374 descriptor->insertObjRef("FontFile", std::move(fontStream)); |
1165 | 1375 |
1166 this->insertObjRef("FontDescriptor", std::move(descriptor)); | 1376 this->insertObjRef("FontDescriptor", std::move(descriptor)); |
1167 | 1377 |
1168 return addCommonFontDescriptorEntries(defaultWidth); | 1378 return addCommonFontDescriptorEntries(defaultWidth); |
1169 } | 1379 } |
1170 | 1380 |
1171 bool SkPDFType1Font::populate(int16_t glyphID) { | 1381 bool SkPDFType1Font::populate(int16_t glyphID) { |
1172 SkASSERT(fontInfo()->fVerticalMetrics.empty()); | |
1173 SkASSERT(fontInfo()->fGlyphWidths.empty()); | |
1174 | |
1175 adjustGlyphRangeForSingleByteEncoding(glyphID); | 1382 adjustGlyphRangeForSingleByteEncoding(glyphID); |
1176 | 1383 |
1177 int16_t defaultWidth = 0; | 1384 int16_t defaultWidth = 0; |
1178 const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry = nullptr; | 1385 const AdvanceMetric* widthRangeEntry = nullptr; |
1179 { | 1386 { |
1180 SkAdvancedTypefaceMetrics tmpMetrics; | 1387 SkSinglyLinkedList<AdvanceMetric> tmpMetrics; |
1181 set_glyph_widths(this->typeface(), nullptr, &tmpMetrics); | 1388 set_glyph_widths(this->typeface(), nullptr, &tmpMetrics); |
1182 for (const auto& widthEntry : tmpMetrics.fGlyphWidths) { | 1389 for (const auto& widthEntry : tmpMetrics) { |
1183 switch (widthEntry.fType) { | 1390 switch (widthEntry.fType) { |
1184 case SkAdvancedTypefaceMetrics::WidthRange::kDefault: | 1391 case AdvanceMetric::kDefault: |
1185 defaultWidth = widthEntry.fAdvance[0]; | 1392 defaultWidth = widthEntry.fAdvance[0]; |
1186 break; | 1393 break; |
1187 case SkAdvancedTypefaceMetrics::WidthRange::kRun: | 1394 case AdvanceMetric::kRun: |
1188 SkASSERT(false); | 1395 SkASSERT(false); |
1189 break; | 1396 break; |
1190 case SkAdvancedTypefaceMetrics::WidthRange::kRange: | 1397 case AdvanceMetric::kRange: |
1191 SkASSERT(widthRangeEntry == nullptr); | 1398 SkASSERT(widthRangeEntry == nullptr); |
1192 widthRangeEntry = &widthEntry; | 1399 widthRangeEntry = &widthEntry; |
1193 break; | 1400 break; |
1194 } | 1401 } |
1195 } | 1402 } |
1196 } | 1403 } |
1197 | 1404 |
1198 if (!addFontDescriptor(defaultWidth)) { | 1405 if (!addFontDescriptor(defaultWidth)) { |
1199 return false; | 1406 return false; |
1200 } | 1407 } |
1201 | 1408 |
1202 insertName("Subtype", "Type1"); | 1409 insertName("Subtype", "Type1"); |
1203 insertName("BaseFont", fontInfo()->fFontName); | 1410 insertName("BaseFont", fontInfo()->fFontName); |
1204 | 1411 |
1205 addWidthInfoFromRange(defaultWidth, widthRangeEntry); | 1412 addWidthInfoFromRange(defaultWidth, widthRangeEntry); |
1206 auto encDiffs = sk_make_sp<SkPDFArray>(); | 1413 auto encDiffs = sk_make_sp<SkPDFArray>(); |
1207 encDiffs->reserve(lastGlyphID() - firstGlyphID() + 2); | 1414 encDiffs->reserve(lastGlyphID() - firstGlyphID() + 2); |
1208 encDiffs->appendInt(1); | 1415 encDiffs->appendInt(1); |
| 1416 SkASSERT(this->fontInfo()->fGlyphNames.count() >= this->lastGlyphID()); |
1209 for (int gID = firstGlyphID(); gID <= lastGlyphID(); gID++) { | 1417 for (int gID = firstGlyphID(); gID <= lastGlyphID(); gID++) { |
1210 encDiffs->appendName(fontInfo()->fGlyphNames->get()[gID].c_str()); | 1418 encDiffs->appendName(fontInfo()->fGlyphNames[gID].c_str()); |
1211 } | 1419 } |
1212 | 1420 |
1213 auto encoding = sk_make_sp<SkPDFDict>("Encoding"); | 1421 auto encoding = sk_make_sp<SkPDFDict>("Encoding"); |
1214 encoding->insertObject("Differences", std::move(encDiffs)); | 1422 encoding->insertObject("Differences", std::move(encDiffs)); |
1215 this->insertObject("Encoding", std::move(encoding)); | 1423 this->insertObject("Encoding", std::move(encoding)); |
1216 return true; | 1424 return true; |
1217 } | 1425 } |
1218 | 1426 |
1219 void SkPDFType1Font::addWidthInfoFromRange( | 1427 void SkPDFType1Font::addWidthInfoFromRange( |
1220 int16_t defaultWidth, | 1428 int16_t defaultWidth, |
1221 const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry) { | 1429 const AdvanceMetric* widthRangeEntry) { |
1222 auto widthArray = sk_make_sp<SkPDFArray>(); | 1430 auto widthArray = sk_make_sp<SkPDFArray>(); |
1223 int firstChar = 0; | 1431 int firstChar = 0; |
1224 if (widthRangeEntry) { | 1432 if (widthRangeEntry) { |
1225 const uint16_t emSize = fontInfo()->fEmSize; | 1433 const uint16_t emSize = fontInfo()->fEmSize; |
1226 int startIndex = firstGlyphID() - widthRangeEntry->fStartId; | 1434 int startIndex = firstGlyphID() - widthRangeEntry->fStartId; |
1227 int endIndex = startIndex + lastGlyphID() - firstGlyphID() + 1; | 1435 int endIndex = startIndex + lastGlyphID() - firstGlyphID() + 1; |
1228 if (startIndex < 0) | 1436 if (startIndex < 0) |
1229 startIndex = 0; | 1437 startIndex = 0; |
1230 if (endIndex > widthRangeEntry->fAdvance.count()) | 1438 if (endIndex > widthRangeEntry->fAdvance.count()) |
1231 endIndex = widthRangeEntry->fAdvance.count(); | 1439 endIndex = widthRangeEntry->fAdvance.count(); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1370 } | 1578 } |
1371 return *canon->fCanEmbedTypeface.set(id, canEmbed); | 1579 return *canon->fCanEmbedTypeface.set(id, canEmbed); |
1372 } | 1580 } |
1373 | 1581 |
1374 void SkPDFFont::drop() { | 1582 void SkPDFFont::drop() { |
1375 fTypeface = nullptr; | 1583 fTypeface = nullptr; |
1376 fFontInfo = nullptr; | 1584 fFontInfo = nullptr; |
1377 fDescriptor = nullptr; | 1585 fDescriptor = nullptr; |
1378 this->SkPDFDict::drop(); | 1586 this->SkPDFDict::drop(); |
1379 } | 1587 } |
OLD | NEW |