| 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 "SkData.h" | 8 #include "SkData.h" |
| 9 #include "SkGlyphCache.h" | 9 #include "SkGlyphCache.h" |
| 10 #include "SkPaint.h" | 10 #include "SkPaint.h" |
| 11 #include "SkPDFCanon.h" | 11 #include "SkPDFCanon.h" |
| 12 #include "SkPDFConvertType1FontStream.h" | 12 #include "SkPDFConvertType1FontStream.h" |
| 13 #include "SkPDFDevice.h" | 13 #include "SkPDFDevice.h" |
| 14 #include "SkPDFMakeCIDGlyphWidthsArray.h" |
| 14 #include "SkPDFMakeToUnicodeCmap.h" | 15 #include "SkPDFMakeToUnicodeCmap.h" |
| 15 #include "SkPDFFont.h" | 16 #include "SkPDFFont.h" |
| 16 #include "SkPDFUtils.h" | 17 #include "SkPDFUtils.h" |
| 17 #include "SkRefCnt.h" | 18 #include "SkRefCnt.h" |
| 18 #include "SkScalar.h" | 19 #include "SkScalar.h" |
| 19 #include "SkStream.h" | 20 #include "SkStream.h" |
| 20 #include "SkTypefacePriv.h" | 21 #include "SkTypefacePriv.h" |
| 21 #include "SkTypes.h" | 22 #include "SkTypes.h" |
| 22 #include "SkUtils.h" | 23 #include "SkUtils.h" |
| 23 | 24 |
| 24 #if defined (SK_SFNTLY_SUBSETTER) | 25 #if defined (SK_SFNTLY_SUBSETTER) |
| 25 #if defined (GOOGLE3) | 26 #if defined (GOOGLE3) |
| 26 // #including #defines doesn't work with this build system. | 27 // #including #defines doesn't work with this build system. |
| 27 #include "typography/font/sfntly/src/sample/chromium/font_subsetter.h" | 28 #include "typography/font/sfntly/src/sample/chromium/font_subsetter.h" |
| 28 #else | 29 #else |
| 29 #include SK_SFNTLY_SUBSETTER | 30 #include SK_SFNTLY_SUBSETTER |
| 30 #endif | 31 #endif |
| 31 #endif | 32 #endif |
| 32 | 33 |
| 33 namespace { | 34 namespace { |
| 34 | |
| 35 // PDF's notion of symbolic vs non-symbolic is related to the character set, not | 35 // PDF's notion of symbolic vs non-symbolic is related to the character set, not |
| 36 // symbols vs. characters. Rarely is a font the right character set to call it | 36 // symbols vs. characters. Rarely is a font the right character set to call it |
| 37 // non-symbolic, so always call it symbolic. (PDF 1.4 spec, section 5.7.1) | 37 // non-symbolic, so always call it symbolic. (PDF 1.4 spec, section 5.7.1) |
| 38 static const int kPdfSymbolic = 4; | 38 static const int kPdfSymbolic = 4; |
| 39 | 39 |
| 40 struct AdvanceMetric { | |
| 41 enum MetricType { | |
| 42 kDefault, // Default advance: fAdvance.count = 1 | |
| 43 kRange, // Advances for a range: fAdvance.count = fEndID-fStartID | |
| 44 kRun // fStartID-fEndID have same advance: fAdvance.count = 1 | |
| 45 }; | |
| 46 MetricType fType; | |
| 47 uint16_t fStartId; | |
| 48 uint16_t fEndId; | |
| 49 SkTDArray<int16_t> fAdvance; | |
| 50 AdvanceMetric(uint16_t startId) : fStartId(startId) {} | |
| 51 AdvanceMetric(AdvanceMetric&&) = default; | |
| 52 AdvanceMetric& operator=(AdvanceMetric&& other) = default; | |
| 53 AdvanceMetric(const AdvanceMetric&) = delete; | |
| 54 AdvanceMetric& operator=(const AdvanceMetric&) = delete; | |
| 55 }; | |
| 56 | |
| 57 class SkPDFType0Font final : public SkPDFFont { | 40 class SkPDFType0Font final : public SkPDFFont { |
| 58 public: | 41 public: |
| 59 SkPDFType0Font(sk_sp<const SkAdvancedTypefaceMetrics> info, | 42 SkPDFType0Font(sk_sp<const SkAdvancedTypefaceMetrics> info, |
| 60 sk_sp<SkTypeface> typeface, | 43 sk_sp<SkTypeface> typeface, |
| 61 SkAdvancedTypefaceMetrics::FontType type); | 44 SkAdvancedTypefaceMetrics::FontType type); |
| 62 virtual ~SkPDFType0Font(); | 45 virtual ~SkPDFType0Font(); |
| 63 sk_sp<SkPDFObject> getFontSubset(const SkPDFGlyphSet* usage) override; | 46 sk_sp<SkPDFObject> getFontSubset(const SkPDFGlyphSet* usage) override; |
| 64 #ifdef SK_DEBUG | 47 #ifdef SK_DEBUG |
| 65 void emitObject(SkWStream*, | 48 void emitObject(SkWStream*, |
| 66 const SkPDFObjNumMap&, | 49 const SkPDFObjNumMap&, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 const SkPDFSubstituteMap&) const override { | 83 const SkPDFSubstituteMap&) const override { |
| 101 SkDEBUGFAIL("should call getFontSubset!"); | 84 SkDEBUGFAIL("should call getFontSubset!"); |
| 102 } | 85 } |
| 103 sk_sp<SkPDFObject> getFontSubset(const SkPDFGlyphSet* usage) override; | 86 sk_sp<SkPDFObject> getFontSubset(const SkPDFGlyphSet* usage) override; |
| 104 }; | 87 }; |
| 105 | 88 |
| 106 /////////////////////////////////////////////////////////////////////////////// | 89 /////////////////////////////////////////////////////////////////////////////// |
| 107 // File-Local Functions | 90 // File-Local Functions |
| 108 /////////////////////////////////////////////////////////////////////////////// | 91 /////////////////////////////////////////////////////////////////////////////// |
| 109 | 92 |
| 110 const int16_t kInvalidAdvance = SK_MinS16; | 93 static SkAutoGlyphCache vector_cache(SkTypeface* face, SkScalar size = 0) { |
| 111 const int16_t kDontCareAdvance = SK_MinS16 + 1; | |
| 112 | |
| 113 static void stripUninterestingTrailingAdvancesFromRange( | |
| 114 AdvanceMetric* range) { | |
| 115 SkASSERT(range); | |
| 116 | |
| 117 int expectedAdvanceCount = range->fEndId - range->fStartId + 1; | |
| 118 if (range->fAdvance.count() < expectedAdvanceCount) { | |
| 119 return; | |
| 120 } | |
| 121 | |
| 122 for (int i = expectedAdvanceCount - 1; i >= 0; --i) { | |
| 123 if (range->fAdvance[i] != kDontCareAdvance && | |
| 124 range->fAdvance[i] != kInvalidAdvance && | |
| 125 range->fAdvance[i] != 0) { | |
| 126 range->fEndId = range->fStartId + i; | |
| 127 break; | |
| 128 } | |
| 129 } | |
| 130 } | |
| 131 | |
| 132 static void zeroWildcardsInRange(AdvanceMetric* range) { | |
| 133 SkASSERT(range); | |
| 134 if (range->fType != AdvanceMetric::kRange) { | |
| 135 return; | |
| 136 } | |
| 137 SkASSERT(range->fAdvance.count() == range->fEndId - range->fStartId + 1); | |
| 138 | |
| 139 // Zero out wildcards. | |
| 140 for (int i = 0; i < range->fAdvance.count(); ++i) { | |
| 141 if (range->fAdvance[i] == kDontCareAdvance) { | |
| 142 range->fAdvance[i] = 0; | |
| 143 } | |
| 144 } | |
| 145 } | |
| 146 | |
| 147 static void FinishRange( | |
| 148 AdvanceMetric* range, | |
| 149 int endId, | |
| 150 AdvanceMetric::MetricType type) { | |
| 151 range->fEndId = endId; | |
| 152 range->fType = type; | |
| 153 stripUninterestingTrailingAdvancesFromRange(range); | |
| 154 int newLength; | |
| 155 if (type == AdvanceMetric::kRange) { | |
| 156 newLength = range->fEndId - range->fStartId + 1; | |
| 157 } else { | |
| 158 if (range->fEndId == range->fStartId) { | |
| 159 range->fType = AdvanceMetric::kRange; | |
| 160 } | |
| 161 newLength = 1; | |
| 162 } | |
| 163 SkASSERT(range->fAdvance.count() >= newLength); | |
| 164 range->fAdvance.setCount(newLength); | |
| 165 zeroWildcardsInRange(range); | |
| 166 } | |
| 167 | |
| 168 /** Retrieve advance data for glyphs. Used by the PDF backend. */ | |
| 169 // TODO(halcanary): this function is complex enough to need its logic | |
| 170 // tested with unit tests. On the other hand, I want to do another | |
| 171 // round of re-factoring before figuring out how to mock this. | |
| 172 // TODO(halcanary): this function should be combined with | |
| 173 // composeAdvanceData() so that we don't need to produce a linked list | |
| 174 // of intermediate values. Or we could make the intermediate value | |
| 175 // something other than a linked list. | |
| 176 static void set_glyph_widths(SkTypeface* typeface, | |
| 177 const SkPDFGlyphSet* subset, | |
| 178 SkSinglyLinkedList<AdvanceMetric>* glyphWidths) { | |
| 179 SkPaint tmpPaint; | 94 SkPaint tmpPaint; |
| 180 tmpPaint.setHinting(SkPaint::kNo_Hinting); | 95 tmpPaint.setHinting(SkPaint::kNo_Hinting); |
| 181 tmpPaint.setTypeface(sk_ref_sp(typeface)); | 96 tmpPaint.setTypeface(sk_ref_sp(face)); |
| 182 tmpPaint.setTextSize((SkScalar)typeface->getUnitsPerEm()); | 97 if (0 == size) { |
| 98 SkASSERT(face); |
| 99 tmpPaint.setTextSize((SkScalar)face->getUnitsPerEm()); |
| 100 } else { |
| 101 tmpPaint.setTextSize(size); |
| 102 } |
| 183 const SkSurfaceProps props(0, kUnknown_SkPixelGeometry); | 103 const SkSurfaceProps props(0, kUnknown_SkPixelGeometry); |
| 184 SkAutoGlyphCache glyphCache(tmpPaint, &props, nullptr); | 104 SkAutoGlyphCache glyphCache(tmpPaint, &props, nullptr); |
| 185 SkASSERT(glyphCache.get()); | 105 SkASSERT(glyphCache.get()); |
| 186 | 106 return glyphCache; |
| 187 // Assuming that on average, the ASCII representation of an advance plus | |
| 188 // a space is 8 characters and the ASCII representation of a glyph id is 3 | |
| 189 // characters, then the following cut offs for using different range types | |
| 190 // apply: | |
| 191 // The cost of stopping and starting the range is 7 characers | |
| 192 // a. Removing 4 0's or don't care's is a win | |
| 193 // The cost of stopping and starting the range plus a run is 22 | |
| 194 // characters | |
| 195 // b. Removing 3 repeating advances is a win | |
| 196 // c. Removing 2 repeating advances and 3 don't cares is a win | |
| 197 // When not currently in a range the cost of a run over a range is 16 | |
| 198 // characaters, so: | |
| 199 // d. Removing a leading 0/don't cares is a win because it is omitted | |
| 200 // e. Removing 2 repeating advances is a win | |
| 201 | |
| 202 int num_glyphs = typeface->countGlyphs(); | |
| 203 | |
| 204 AdvanceMetric* prevRange = nullptr; | |
| 205 int16_t lastAdvance = kInvalidAdvance; | |
| 206 int repeatedAdvances = 0; | |
| 207 int wildCardsInRun = 0; | |
| 208 int trailingWildCards = 0; | |
| 209 | |
| 210 // Limit the loop count to glyph id ranges provided. | |
| 211 int lastIndex = num_glyphs; | |
| 212 if (subset) { | |
| 213 while (!subset->has(lastIndex - 1) && lastIndex > 0) { | |
| 214 --lastIndex; | |
| 215 } | |
| 216 } | |
| 217 AdvanceMetric curRange(0); | |
| 218 | |
| 219 for (int gId = 0; gId <= lastIndex; gId++) { | |
| 220 int16_t advance = kInvalidAdvance; | |
| 221 if (gId < lastIndex) { | |
| 222 if (!subset || 0 == gId || subset->has(gId)) { | |
| 223 advance = (int16_t)glyphCache->getGlyphIDAdvance(gId).fAdvanceX; | |
| 224 } else { | |
| 225 advance = kDontCareAdvance; | |
| 226 } | |
| 227 } | |
| 228 if (advance == lastAdvance) { | |
| 229 repeatedAdvances++; | |
| 230 trailingWildCards = 0; | |
| 231 } else if (advance == kDontCareAdvance) { | |
| 232 wildCardsInRun++; | |
| 233 trailingWildCards++; | |
| 234 } else if (curRange.fAdvance.count() == | |
| 235 repeatedAdvances + 1 + wildCardsInRun) { // All in run. | |
| 236 if (lastAdvance == 0) { | |
| 237 curRange.fStartId = gId; // reset | |
| 238 curRange.fAdvance.setCount(0); | |
| 239 trailingWildCards = 0; | |
| 240 } else if (repeatedAdvances + 1 >= 2 || trailingWildCards >= 4) { | |
| 241 FinishRange(&curRange, gId - 1, AdvanceMetric::kRun); | |
| 242 prevRange = glyphWidths->emplace_back(std::move(curRange)); | |
| 243 curRange = AdvanceMetric(gId); | |
| 244 trailingWildCards = 0; | |
| 245 } | |
| 246 repeatedAdvances = 0; | |
| 247 wildCardsInRun = trailingWildCards; | |
| 248 trailingWildCards = 0; | |
| 249 } else { | |
| 250 if (lastAdvance == 0 && | |
| 251 repeatedAdvances + 1 + wildCardsInRun >= 4) { | |
| 252 FinishRange(&curRange, | |
| 253 gId - repeatedAdvances - wildCardsInRun - 2, | |
| 254 AdvanceMetric::kRange); | |
| 255 prevRange = glyphWidths->emplace_back(std::move(curRange)); | |
| 256 curRange = AdvanceMetric(gId); | |
| 257 trailingWildCards = 0; | |
| 258 } else if (trailingWildCards >= 4 && repeatedAdvances + 1 < 2) { | |
| 259 FinishRange(&curRange, gId - trailingWildCards - 1, | |
| 260 AdvanceMetric::kRange); | |
| 261 prevRange = glyphWidths->emplace_back(std::move(curRange)); | |
| 262 curRange = AdvanceMetric(gId); | |
| 263 trailingWildCards = 0; | |
| 264 } else if (lastAdvance != 0 && | |
| 265 (repeatedAdvances + 1 >= 3 || | |
| 266 (repeatedAdvances + 1 >= 2 && wildCardsInRun >= 3))) { | |
| 267 FinishRange(&curRange, | |
| 268 gId - repeatedAdvances - wildCardsInRun - 2, | |
| 269 AdvanceMetric::kRange); | |
| 270 (void)glyphWidths->emplace_back(std::move(curRange)); | |
| 271 curRange = | |
| 272 AdvanceMetric(gId - repeatedAdvances - wildCardsInRun -
1); | |
| 273 curRange.fAdvance.append(1, &lastAdvance); | |
| 274 FinishRange(&curRange, gId - 1, AdvanceMetric::kRun); | |
| 275 prevRange = glyphWidths->emplace_back(std::move(curRange)); | |
| 276 curRange = AdvanceMetric(gId); | |
| 277 trailingWildCards = 0; | |
| 278 } | |
| 279 repeatedAdvances = 0; | |
| 280 wildCardsInRun = trailingWildCards; | |
| 281 trailingWildCards = 0; | |
| 282 } | |
| 283 curRange.fAdvance.append(1, &advance); | |
| 284 if (advance != kDontCareAdvance) { | |
| 285 lastAdvance = advance; | |
| 286 } | |
| 287 } | |
| 288 if (curRange.fStartId == lastIndex) { | |
| 289 if (!prevRange) { | |
| 290 glyphWidths->reset(); | |
| 291 return; // https://crbug.com/567031 | |
| 292 } | |
| 293 } else { | |
| 294 FinishRange(&curRange, lastIndex - 1, AdvanceMetric::kRange); | |
| 295 glyphWidths->emplace_back(std::move(curRange)); | |
| 296 } | |
| 297 } | 107 } |
| 298 | 108 |
| 299 //////////////////////////////////////////////////////////////////////////////// | |
| 300 | |
| 301 // scale from em-units to base-1000, returning as a SkScalar | 109 // scale from em-units to base-1000, returning as a SkScalar |
| 302 SkScalar from_font_units(SkScalar scaled, uint16_t emSize) { | 110 SkScalar from_font_units(SkScalar scaled, uint16_t emSize) { |
| 303 if (emSize == 1000) { | 111 if (emSize == 1000) { |
| 304 return scaled; | 112 return scaled; |
| 305 } else { | 113 } else { |
| 306 return SkScalarMulDiv(scaled, 1000, emSize); | 114 return SkScalarMulDiv(scaled, 1000, emSize); |
| 307 } | 115 } |
| 308 } | 116 } |
| 309 | 117 |
| 310 SkScalar scaleFromFontUnits(int16_t val, uint16_t emSize) { | 118 SkScalar scaleFromFontUnits(int16_t val, uint16_t emSize) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 329 | 137 |
| 330 static sk_sp<SkPDFArray> makeFontBBox(SkIRect glyphBBox, uint16_t emSize) { | 138 static sk_sp<SkPDFArray> makeFontBBox(SkIRect glyphBBox, uint16_t emSize) { |
| 331 auto bbox = sk_make_sp<SkPDFArray>(); | 139 auto bbox = sk_make_sp<SkPDFArray>(); |
| 332 bbox->reserve(4); | 140 bbox->reserve(4); |
| 333 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fLeft, emSize)); | 141 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fLeft, emSize)); |
| 334 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fBottom, emSize)); | 142 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fBottom, emSize)); |
| 335 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fRight, emSize)); | 143 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fRight, emSize)); |
| 336 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fTop, emSize)); | 144 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fTop, emSize)); |
| 337 return bbox; | 145 return bbox; |
| 338 } | 146 } |
| 339 | |
| 340 sk_sp<SkPDFArray> composeAdvanceData( | |
| 341 const SkSinglyLinkedList<AdvanceMetric>& advanceInfo, | |
| 342 uint16_t emSize, | |
| 343 int16_t* defaultAdvance) { | |
| 344 auto result = sk_make_sp<SkPDFArray>(); | |
| 345 for (const AdvanceMetric& range : advanceInfo) { | |
| 346 switch (range.fType) { | |
| 347 case AdvanceMetric::kDefault: { | |
| 348 SkASSERT(range.fAdvance.count() == 1); | |
| 349 *defaultAdvance = range.fAdvance[0]; | |
| 350 break; | |
| 351 } | |
| 352 case AdvanceMetric::kRange: { | |
| 353 auto advanceArray = sk_make_sp<SkPDFArray>(); | |
| 354 for (int j = 0; j < range.fAdvance.count(); j++) | |
| 355 advanceArray->appendScalar( | |
| 356 scaleFromFontUnits(range.fAdvance[j], emSize)); | |
| 357 result->appendInt(range.fStartId); | |
| 358 result->appendObject(std::move(advanceArray)); | |
| 359 break; | |
| 360 } | |
| 361 case AdvanceMetric::kRun: { | |
| 362 SkASSERT(range.fAdvance.count() == 1); | |
| 363 result->appendInt(range.fStartId); | |
| 364 result->appendInt(range.fEndId); | |
| 365 result->appendScalar( | |
| 366 scaleFromFontUnits(range.fAdvance[0], emSize)); | |
| 367 break; | |
| 368 } | |
| 369 } | |
| 370 } | |
| 371 return result; | |
| 372 } | |
| 373 | |
| 374 } // namespace | 147 } // namespace |
| 375 | 148 |
| 376 | 149 |
| 377 /////////////////////////////////////////////////////////////////////////////// | 150 /////////////////////////////////////////////////////////////////////////////// |
| 378 // class SkPDFGlyphSet | 151 // class SkPDFGlyphSet |
| 379 /////////////////////////////////////////////////////////////////////////////// | 152 /////////////////////////////////////////////////////////////////////////////// |
| 380 | 153 |
| 381 SkPDFGlyphSet::SkPDFGlyphSet() : fBitSet(SK_MaxU16 + 1) { | 154 SkPDFGlyphSet::SkPDFGlyphSet() : fBitSet(SK_MaxU16 + 1) { |
| 382 } | 155 } |
| 383 | 156 |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 827 } else { | 600 } else { |
| 828 SkASSERT(false); | 601 SkASSERT(false); |
| 829 } | 602 } |
| 830 | 603 |
| 831 auto sysInfo = sk_make_sp<SkPDFDict>(); | 604 auto sysInfo = sk_make_sp<SkPDFDict>(); |
| 832 sysInfo->insertString("Registry", "Adobe"); | 605 sysInfo->insertString("Registry", "Adobe"); |
| 833 sysInfo->insertString("Ordering", "Identity"); | 606 sysInfo->insertString("Ordering", "Identity"); |
| 834 sysInfo->insertInt("Supplement", 0); | 607 sysInfo->insertInt("Supplement", 0); |
| 835 newCIDFont->insertObject("CIDSystemInfo", std::move(sysInfo)); | 608 newCIDFont->insertObject("CIDSystemInfo", std::move(sysInfo)); |
| 836 | 609 |
| 837 SkSinglyLinkedList<AdvanceMetric> tmpMetrics; | 610 uint16_t emSize = this->getFontInfo()->fEmSize; |
| 838 set_glyph_widths(face, subset, &tmpMetrics); | |
| 839 int16_t defaultWidth = 0; | 611 int16_t defaultWidth = 0; |
| 840 uint16_t emSize = (uint16_t)this->getFontInfo()->fEmSize; | 612 const SkBitSet* bitSet = subset ? &subset->bitSet() : nullptr; |
| 841 sk_sp<SkPDFArray> widths = composeAdvanceData(tmpMetrics, emSize, &defaultWi
dth); | 613 { |
| 842 if (widths->size()) { | 614 SkAutoGlyphCache glyphCache = vector_cache(face); |
| 843 newCIDFont->insertObject("W", std::move(widths)); | 615 sk_sp<SkPDFArray> widths = SkPDFMakeCIDGlyphWidthsArray( |
| 616 glyphCache.get(), bitSet, emSize, &defaultWidth); |
| 617 if (widths && widths->size() > 0) { |
| 618 newCIDFont->insertObject("W", std::move(widths)); |
| 619 } |
| 620 newCIDFont->insertScalar( |
| 621 "DW", scaleFromFontUnits(defaultWidth, emSize)); |
| 844 } | 622 } |
| 845 | 623 |
| 846 newCIDFont->insertScalar( | |
| 847 "DW", scaleFromFontUnits(defaultWidth, emSize)); | |
| 848 | |
| 849 | |
| 850 //////////////////////////////////////////////////////////////////////////// | 624 //////////////////////////////////////////////////////////////////////////// |
| 851 | 625 |
| 852 this->insertName("Subtype", "Type0"); | 626 this->insertName("Subtype", "Type0"); |
| 853 this->insertName("BaseFont", metrics.fFontName); | 627 this->insertName("BaseFont", metrics.fFontName); |
| 854 this->insertName("Encoding", "Identity-H"); | 628 this->insertName("Encoding", "Identity-H"); |
| 855 auto descendantFonts = sk_make_sp<SkPDFArray>(); | 629 auto descendantFonts = sk_make_sp<SkPDFArray>(); |
| 856 descendantFonts->appendObjRef(std::move(newCIDFont)); | 630 descendantFonts->appendObjRef(std::move(newCIDFont)); |
| 857 this->insertObject("DescendantFonts", std::move(descendantFonts)); | 631 this->insertObject("DescendantFonts", std::move(descendantFonts)); |
| 858 this->populateToUnicodeTable(subset); | 632 this->populateToUnicodeTable(subset); |
| 859 SkDEBUGCODE(fPopulated = true); | 633 SkDEBUGCODE(fPopulated = true); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 926 adjustGlyphRangeForSingleByteEncoding(glyphID); | 700 adjustGlyphRangeForSingleByteEncoding(glyphID); |
| 927 SkGlyphID firstGlyphID = this->firstGlyphID(); | 701 SkGlyphID firstGlyphID = this->firstGlyphID(); |
| 928 SkGlyphID lastGlyphID = this->lastGlyphID(); | 702 SkGlyphID lastGlyphID = this->lastGlyphID(); |
| 929 | 703 |
| 930 // glyphCount not including glyph 0 | 704 // glyphCount not including glyph 0 |
| 931 unsigned glyphCount = 1 + lastGlyphID - firstGlyphID; | 705 unsigned glyphCount = 1 + lastGlyphID - firstGlyphID; |
| 932 SkASSERT(glyphCount > 0 && glyphCount <= 255); | 706 SkASSERT(glyphCount > 0 && glyphCount <= 255); |
| 933 this->insertInt("FirstChar", (size_t)0); | 707 this->insertInt("FirstChar", (size_t)0); |
| 934 this->insertInt("LastChar", (size_t)glyphCount); | 708 this->insertInt("LastChar", (size_t)glyphCount); |
| 935 { | 709 { |
| 936 SkPaint tmpPaint; | 710 SkAutoGlyphCache glyphCache = vector_cache(this->typeface()); |
| 937 tmpPaint.setHinting(SkPaint::kNo_Hinting); | |
| 938 tmpPaint.setTypeface(sk_ref_sp(this->typeface())); | |
| 939 tmpPaint.setTextSize((SkScalar)this->typeface()->getUnitsPerEm()); | |
| 940 const SkSurfaceProps props(0, kUnknown_SkPixelGeometry); | |
| 941 SkAutoGlyphCache glyphCache(tmpPaint, &props, nullptr); | |
| 942 auto widths = sk_make_sp<SkPDFArray>(); | 711 auto widths = sk_make_sp<SkPDFArray>(); |
| 943 SkScalar advance = glyphCache->getGlyphIDAdvance(0).fAdvanceX; | 712 SkScalar advance = glyphCache->getGlyphIDAdvance(0).fAdvanceX; |
| 944 const uint16_t emSize = this->getFontInfo()->fEmSize; | 713 const uint16_t emSize = this->getFontInfo()->fEmSize; |
| 945 widths->appendScalar(from_font_units(advance, emSize)); | 714 widths->appendScalar(from_font_units(advance, emSize)); |
| 946 for (unsigned gID = firstGlyphID; gID <= lastGlyphID; gID++) { | 715 for (unsigned gID = firstGlyphID; gID <= lastGlyphID; gID++) { |
| 947 advance = glyphCache->getGlyphIDAdvance(gID).fAdvanceX; | 716 advance = glyphCache->getGlyphIDAdvance(gID).fAdvanceX; |
| 948 widths->appendScalar(from_font_units(advance, emSize)); | 717 widths->appendScalar(from_font_units(advance, emSize)); |
| 949 } | 718 } |
| 950 this->insertObject("Widths", std::move(widths)); | 719 this->insertObject("Widths", std::move(widths)); |
| 951 } | 720 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1005 }; | 774 }; |
| 1006 } | 775 } |
| 1007 | 776 |
| 1008 static void add_type3_font_info(SkPDFDict* font, | 777 static void add_type3_font_info(SkPDFDict* font, |
| 1009 SkTypeface* typeface, | 778 SkTypeface* typeface, |
| 1010 SkScalar emSize, | 779 SkScalar emSize, |
| 1011 const SkPDFGlyphSet* subset, | 780 const SkPDFGlyphSet* subset, |
| 1012 SkGlyphID firstGlyphID, | 781 SkGlyphID firstGlyphID, |
| 1013 SkGlyphID lastGlyphID) { | 782 SkGlyphID lastGlyphID) { |
| 1014 SkASSERT(lastGlyphID >= firstGlyphID); | 783 SkASSERT(lastGlyphID >= firstGlyphID); |
| 1015 SkPaint paint; | 784 SkASSERT(emSize > 0.0f); |
| 1016 paint.setHinting(SkPaint::kNo_Hinting); | 785 SkAutoGlyphCache cache = vector_cache(typeface, emSize); |
| 1017 paint.setTypeface(sk_ref_sp(typeface)); | |
| 1018 paint.setTextSize(emSize); | |
| 1019 const SkSurfaceProps props(0, kUnknown_SkPixelGeometry); | |
| 1020 SkAutoGlyphCache cache(paint, &props, nullptr); | |
| 1021 | |
| 1022 font->insertName("Subtype", "Type3"); | 786 font->insertName("Subtype", "Type3"); |
| 1023 // Flip about the x-axis and scale by 1/emSize. | 787 // Flip about the x-axis and scale by 1/emSize. |
| 1024 SkMatrix fontMatrix; | 788 SkMatrix fontMatrix; |
| 1025 fontMatrix.setScale(SkScalarInvert(emSize), -SkScalarInvert(emSize)); | 789 fontMatrix.setScale(SkScalarInvert(emSize), -SkScalarInvert(emSize)); |
| 1026 font->insertObject("FontMatrix", SkPDFUtils::MatrixToArray(fontMatrix)); | 790 font->insertObject("FontMatrix", SkPDFUtils::MatrixToArray(fontMatrix)); |
| 1027 | 791 |
| 1028 auto charProcs = sk_make_sp<SkPDFDict>(); | 792 auto charProcs = sk_make_sp<SkPDFDict>(); |
| 1029 auto encoding = sk_make_sp<SkPDFDict>("Encoding"); | 793 auto encoding = sk_make_sp<SkPDFDict>("Encoding"); |
| 1030 | 794 |
| 1031 auto encDiffs = sk_make_sp<SkPDFArray>(); | 795 auto encDiffs = sk_make_sp<SkPDFArray>(); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1189 } | 953 } |
| 1190 return *canon->fCanEmbedTypeface.set(id, canEmbed); | 954 return *canon->fCanEmbedTypeface.set(id, canEmbed); |
| 1191 } | 955 } |
| 1192 | 956 |
| 1193 void SkPDFFont::drop() { | 957 void SkPDFFont::drop() { |
| 1194 fTypeface = nullptr; | 958 fTypeface = nullptr; |
| 1195 fFontInfo = nullptr; | 959 fFontInfo = nullptr; |
| 1196 fDescriptor = nullptr; | 960 fDescriptor = nullptr; |
| 1197 this->SkPDFDict::drop(); | 961 this->SkPDFDict::drop(); |
| 1198 } | 962 } |
| OLD | NEW |