| 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" | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 30         #include SK_SFNTLY_SUBSETTER | 30         #include SK_SFNTLY_SUBSETTER | 
| 31     #endif | 31     #endif | 
| 32 #endif | 32 #endif | 
| 33 | 33 | 
| 34 namespace { | 34 namespace { | 
| 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 class SkPDFType0Font final : public SkPDFFont { | 40 struct SkPDFType0Font final : public SkPDFFont { | 
| 41 public: | 41     SkPDFType0Font(SkPDFFont::Info, const SkAdvancedTypefaceMetrics&); | 
| 42     SkPDFType0Font(const SkAdvancedTypefaceMetrics& info, |  | 
| 43                    sk_sp<SkTypeface> typeface, |  | 
| 44                    SkAdvancedTypefaceMetrics::FontType type); |  | 
| 45     virtual ~SkPDFType0Font(); | 42     virtual ~SkPDFType0Font(); | 
| 46     sk_sp<SkPDFObject> getFontSubset(SkPDFCanon*, const SkPDFGlyphSet*) override
     ; | 43     void getFontSubset(SkPDFCanon*) override; | 
| 47 #ifdef SK_DEBUG | 44 #ifdef SK_DEBUG | 
| 48     void emitObject(SkWStream*, | 45     void emitObject(SkWStream*, const SkPDFObjNumMap&) const override; | 
| 49                     const SkPDFObjNumMap&, |  | 
| 50                     const SkPDFSubstituteMap&) const override; |  | 
| 51 #endif |  | 
| 52 |  | 
| 53 private: |  | 
| 54 #ifdef SK_DEBUG |  | 
| 55     bool fPopulated; | 46     bool fPopulated; | 
| 56 #endif | 47 #endif | 
| 57     bool populate(const SkPDFGlyphSet* subset, |  | 
| 58                   const SkAdvancedTypefaceMetrics& metrics); |  | 
| 59     typedef SkPDFDict INHERITED; | 48     typedef SkPDFDict INHERITED; | 
| 60 }; | 49 }; | 
| 61 | 50 | 
| 62 class SkPDFType1Font final : public SkPDFFont { | 51 struct SkPDFType1Font final : public SkPDFFont { | 
| 63 public: | 52     SkPDFType1Font(SkPDFFont::Info, const SkAdvancedTypefaceMetrics&, SkPDFCanon
     *); | 
| 64     SkPDFType1Font(const SkAdvancedTypefaceMetrics& info, |  | 
| 65                    sk_sp<SkTypeface> typeface, |  | 
| 66                    uint16_t glyphID, |  | 
| 67                    SkPDFCanon* canon); |  | 
| 68     virtual ~SkPDFType1Font() {} | 53     virtual ~SkPDFType1Font() {} | 
|  | 54     void getFontSubset(SkPDFCanon*) override {} // TODO(halcanary): implement | 
| 69 }; | 55 }; | 
| 70 | 56 | 
| 71 class SkPDFType3Font final : public SkPDFFont { | 57 struct SkPDFType3Font final : public SkPDFFont { | 
| 72 public: | 58     SkPDFType3Font(SkPDFFont::Info, const SkAdvancedTypefaceMetrics&); | 
| 73     SkPDFType3Font(const SkAdvancedTypefaceMetrics& info, |  | 
| 74                    sk_sp<SkTypeface> typeface, |  | 
| 75                    SkAdvancedTypefaceMetrics::FontType fontType, |  | 
| 76                    uint16_t glyphID); |  | 
| 77     virtual ~SkPDFType3Font() {} | 59     virtual ~SkPDFType3Font() {} | 
| 78     void emitObject(SkWStream*, | 60     void getFontSubset(SkPDFCanon*) override; | 
| 79                     const SkPDFObjNumMap&, |  | 
| 80                     const SkPDFSubstituteMap&) const override { |  | 
| 81         SkDEBUGFAIL("should call getFontSubset!"); |  | 
| 82     } |  | 
| 83     sk_sp<SkPDFObject> getFontSubset(SkPDFCanon*, const SkPDFGlyphSet*) override
     ; |  | 
| 84 }; | 61 }; | 
| 85 | 62 | 
| 86 /////////////////////////////////////////////////////////////////////////////// | 63 /////////////////////////////////////////////////////////////////////////////// | 
| 87 // File-Local Functions | 64 // File-Local Functions | 
| 88 /////////////////////////////////////////////////////////////////////////////// | 65 /////////////////////////////////////////////////////////////////////////////// | 
| 89 | 66 | 
| 90 static SkAutoGlyphCache vector_cache(SkTypeface* face, SkScalar size = 0) { | 67 static SkAutoGlyphCache vector_cache(SkTypeface* face, SkScalar size = 0) { | 
| 91     SkPaint tmpPaint; | 68     SkPaint tmpPaint; | 
| 92     tmpPaint.setHinting(SkPaint::kNo_Hinting); | 69     tmpPaint.setHinting(SkPaint::kNo_Hinting); | 
| 93     tmpPaint.setTypeface(sk_ref_sp(face)); | 70     tmpPaint.setTypeface(sk_ref_sp(face)); | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 136     auto bbox = sk_make_sp<SkPDFArray>(); | 113     auto bbox = sk_make_sp<SkPDFArray>(); | 
| 137     bbox->reserve(4); | 114     bbox->reserve(4); | 
| 138     bbox->appendScalar(scaleFromFontUnits(glyphBBox.fLeft, emSize)); | 115     bbox->appendScalar(scaleFromFontUnits(glyphBBox.fLeft, emSize)); | 
| 139     bbox->appendScalar(scaleFromFontUnits(glyphBBox.fBottom, emSize)); | 116     bbox->appendScalar(scaleFromFontUnits(glyphBBox.fBottom, emSize)); | 
| 140     bbox->appendScalar(scaleFromFontUnits(glyphBBox.fRight, emSize)); | 117     bbox->appendScalar(scaleFromFontUnits(glyphBBox.fRight, emSize)); | 
| 141     bbox->appendScalar(scaleFromFontUnits(glyphBBox.fTop, emSize)); | 118     bbox->appendScalar(scaleFromFontUnits(glyphBBox.fTop, emSize)); | 
| 142     return bbox; | 119     return bbox; | 
| 143 } | 120 } | 
| 144 }  // namespace | 121 }  // namespace | 
| 145 | 122 | 
| 146 |  | 
| 147 /////////////////////////////////////////////////////////////////////////////// |  | 
| 148 // class SkPDFGlyphSet |  | 
| 149 /////////////////////////////////////////////////////////////////////////////// |  | 
| 150 |  | 
| 151 SkPDFGlyphSet::SkPDFGlyphSet() : fBitSet(SK_MaxU16 + 1) { |  | 
| 152 } |  | 
| 153 |  | 
| 154 void SkPDFGlyphSet::set(const uint16_t* glyphIDs, int numGlyphs) { |  | 
| 155     for (int i = 0; i < numGlyphs; ++i) { |  | 
| 156         fBitSet.setBit(glyphIDs[i], true); |  | 
| 157     } |  | 
| 158 } |  | 
| 159 |  | 
| 160 bool SkPDFGlyphSet::has(uint16_t glyphID) const { |  | 
| 161     return fBitSet.isBitSet(glyphID); |  | 
| 162 } |  | 
| 163 |  | 
| 164 void SkPDFGlyphSet::exportTo(SkTDArray<unsigned int>* glyphIDs) const { |  | 
| 165     fBitSet.exportTo(glyphIDs); |  | 
| 166 } |  | 
| 167 |  | 
| 168 /////////////////////////////////////////////////////////////////////////////// |  | 
| 169 // class SkPDFGlyphSetMap |  | 
| 170 /////////////////////////////////////////////////////////////////////////////// |  | 
| 171 |  | 
| 172 SkPDFGlyphSetMap::SkPDFGlyphSetMap() {} |  | 
| 173 |  | 
| 174 SkPDFGlyphSetMap::~SkPDFGlyphSetMap() { |  | 
| 175     fMap.reset(); |  | 
| 176 } |  | 
| 177 |  | 
| 178 void SkPDFGlyphSetMap::noteGlyphUsage(SkPDFFont* font, const uint16_t* glyphIDs, |  | 
| 179                                       int numGlyphs) { |  | 
| 180     SkPDFGlyphSet* subset = getGlyphSetForFont(font); |  | 
| 181     if (subset) { |  | 
| 182         subset->set(glyphIDs, numGlyphs); |  | 
| 183     } |  | 
| 184 } |  | 
| 185 |  | 
| 186 SkPDFGlyphSet* SkPDFGlyphSetMap::getGlyphSetForFont(SkPDFFont* font) { |  | 
| 187     int index = fMap.count(); |  | 
| 188     for (int i = 0; i < index; ++i) { |  | 
| 189         if (fMap[i].fFont == font) { |  | 
| 190             return &fMap[i].fGlyphSet; |  | 
| 191         } |  | 
| 192     } |  | 
| 193     FontGlyphSetPair& pair = fMap.push_back(); |  | 
| 194     pair.fFont = font; |  | 
| 195     return &pair.fGlyphSet; |  | 
| 196 } |  | 
| 197 |  | 
| 198 /////////////////////////////////////////////////////////////////////////////// | 123 /////////////////////////////////////////////////////////////////////////////// | 
| 199 // class SkPDFFont | 124 // class SkPDFFont | 
| 200 /////////////////////////////////////////////////////////////////////////////// | 125 /////////////////////////////////////////////////////////////////////////////// | 
| 201 | 126 | 
| 202 /* Font subset design: It would be nice to be able to subset fonts | 127 /* Font subset design: It would be nice to be able to subset fonts | 
| 203  * (particularly type 3 fonts), but it's a lot of work and not a priority. | 128  * (particularly type 3 fonts), but it's a lot of work and not a priority. | 
| 204  * | 129  * | 
| 205  * Resources are canonicalized and uniqueified by pointer so there has to be | 130  * Resources are canonicalized and uniqueified by pointer so there has to be | 
| 206  * some additional state indicating which subset of the font is used.  It | 131  * some additional state indicating which subset of the font is used.  It | 
| 207  * must be maintained at the page granularity and then combined at the document | 132  * must be maintained at the page granularity and then combined at the document | 
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 315     sk_sp<SkTypeface> typeface(face ? sk_ref_sp(face) : SkTypeface::MakeDefault(
     )); | 240     sk_sp<SkTypeface> typeface(face ? sk_ref_sp(face) : SkTypeface::MakeDefault(
     )); | 
| 316     SkASSERT(typeface); | 241     SkASSERT(typeface); | 
| 317     int glyphCount = typeface->countGlyphs(); | 242     int glyphCount = typeface->countGlyphs(); | 
| 318     // Validate typeface + glyph; | 243     // Validate typeface + glyph; | 
| 319     if (glyphCount < 1 ||  // typeface lacks even a NOTDEF glyph. | 244     if (glyphCount < 1 ||  // typeface lacks even a NOTDEF glyph. | 
| 320         glyphCount > 1 + SK_MaxU16 ||  // invalid glyphCount | 245         glyphCount > 1 + SK_MaxU16 ||  // invalid glyphCount | 
| 321         glyphID >= glyphCount) {  // invalid glyph | 246         glyphID >= glyphCount) {  // invalid glyph | 
| 322         return nullptr; | 247         return nullptr; | 
| 323     } | 248     } | 
| 324 | 249 | 
|  | 250     SkGlyphID firstNonZeroGlyph; | 
|  | 251     SkGlyphID lastGlyph; | 
|  | 252     if (multibyte) { | 
|  | 253         firstNonZeroGlyph = 1; | 
|  | 254         lastGlyph = SkToU16(glyphCount - 1); | 
|  | 255     } else { | 
|  | 256         firstNonZeroGlyph = firstGlyph; | 
|  | 257         lastGlyph = SkToU16(SkTMin<int>(glyphCount - 1, | 
|  | 258                                         254 + (int)firstGlyph)); | 
|  | 259     } | 
|  | 260     SkPDFFont::Info info = {std::move(typeface), firstNonZeroGlyph, lastGlyph, t
     ype}; | 
| 325     sk_sp<SkPDFFont> font; | 261     sk_sp<SkPDFFont> font; | 
| 326     switch (type) { | 262     switch (type) { | 
| 327         case SkAdvancedTypefaceMetrics::kType1CID_Font: | 263         case SkAdvancedTypefaceMetrics::kType1CID_Font: | 
| 328         case SkAdvancedTypefaceMetrics::kTrueType_Font: | 264         case SkAdvancedTypefaceMetrics::kTrueType_Font: | 
| 329             SkASSERT(multibyte); | 265             SkASSERT(multibyte); | 
| 330             font = sk_make_sp<SkPDFType0Font>(metrics, | 266             font = sk_make_sp<SkPDFType0Font>(std::move(info), metrics); | 
| 331                                               std::move(typeface), |  | 
| 332                                               type); |  | 
| 333             break; | 267             break; | 
| 334         case SkAdvancedTypefaceMetrics::kType1_Font: | 268         case SkAdvancedTypefaceMetrics::kType1_Font: | 
| 335             SkASSERT(!multibyte); | 269             SkASSERT(!multibyte); | 
| 336             font = sk_make_sp<SkPDFType1Font>(metrics, | 270             font = sk_make_sp<SkPDFType1Font>(std::move(info), metrics, canon); | 
| 337                                               std::move(typeface), |  | 
| 338                                               glyphID, |  | 
| 339                                               canon); |  | 
| 340             break; | 271             break; | 
| 341         default: | 272         default: | 
| 342             SkASSERT(!multibyte); | 273             SkASSERT(!multibyte); | 
| 343             // Type3 is our fallback font. | 274             // Type3 is our fallback font. | 
| 344             font = sk_make_sp<SkPDFType3Font>(metrics, | 275             font = sk_make_sp<SkPDFType3Font>(std::move(info), metrics); | 
| 345                                               std::move(typeface), |  | 
| 346                                               type, |  | 
| 347                                               glyphID); |  | 
| 348             break; | 276             break; | 
| 349     } | 277     } | 
| 350     canon->fFontMap.set(fontID, SkRef(font.get())); | 278     canon->fFontMap.set(fontID, SkRef(font.get())); | 
| 351     return font.release();  // TODO(halcanary) return sk_sp<SkPDFFont>. | 279     return font.release();  // TODO(halcanary) return sk_sp<SkPDFFont>. | 
| 352 } | 280 } | 
| 353 | 281 | 
| 354 sk_sp<SkPDFObject> SkPDFFont::getFontSubset(SkPDFCanon*, const SkPDFGlyphSet*) { | 282 SkPDFFont::SkPDFFont(SkPDFFont::Info info) | 
| 355     return nullptr;  // Default: no support. |  | 
| 356 } |  | 
| 357 |  | 
| 358 SkPDFFont::SkPDFFont(sk_sp<SkTypeface> typeface, |  | 
| 359                      SkAdvancedTypefaceMetrics::FontType fontType) |  | 
| 360     : SkPDFDict("Font") | 283     : SkPDFDict("Font") | 
| 361     , fTypeface(std::move(typeface)) | 284     , fTypeface(std::move(info.fTypeface)) | 
| 362     , fFirstGlyphID(1) | 285     , fGlyphUsage(info.fLastGlyphID + 1)  // TODO(halcanary): Adjust mapping? | 
| 363     , fFontType(fontType) { | 286     , fFirstGlyphID(info.fFirstGlyphID) | 
|  | 287     , fLastGlyphID(info.fLastGlyphID) | 
|  | 288     , fFontType(info.fFontType) { | 
| 364     SkASSERT(fTypeface); | 289     SkASSERT(fTypeface); | 
| 365     fLastGlyphID = SkToU16(fTypeface->countGlyphs() - 1); |  | 
| 366 } | 290 } | 
| 367 | 291 | 
| 368 static void  add_common_font_descriptor_entries(SkPDFDict* descriptor, | 292 static void  add_common_font_descriptor_entries(SkPDFDict* descriptor, | 
| 369                                                 const SkAdvancedTypefaceMetrics&
      metrics, | 293                                                 const SkAdvancedTypefaceMetrics&
      metrics, | 
| 370                                                 int16_t defaultWidth) { | 294                                                 int16_t defaultWidth) { | 
| 371     const uint16_t emSize = metrics.fEmSize; | 295     const uint16_t emSize = metrics.fEmSize; | 
| 372     descriptor->insertName("FontName", metrics.fFontName); | 296     descriptor->insertName("FontName", metrics.fFontName); | 
| 373     descriptor->insertInt("Flags", (size_t)(metrics.fStyle | kPdfSymbolic)); | 297     descriptor->insertInt("Flags", (size_t)(metrics.fStyle | kPdfSymbolic)); | 
| 374     descriptor->insertScalar("Ascent", | 298     descriptor->insertScalar("Ascent", | 
| 375             scaleFromFontUnits(metrics.fAscent, emSize)); | 299             scaleFromFontUnits(metrics.fAscent, emSize)); | 
| 376     descriptor->insertScalar("Descent", | 300     descriptor->insertScalar("Descent", | 
| 377             scaleFromFontUnits(metrics.fDescent, emSize)); | 301             scaleFromFontUnits(metrics.fDescent, emSize)); | 
| 378     descriptor->insertScalar("StemV", | 302     descriptor->insertScalar("StemV", | 
| 379             scaleFromFontUnits(metrics.fStemV, emSize)); | 303             scaleFromFontUnits(metrics.fStemV, emSize)); | 
| 380     descriptor->insertScalar("CapHeight", | 304     descriptor->insertScalar("CapHeight", | 
| 381             scaleFromFontUnits(metrics.fCapHeight, emSize)); | 305             scaleFromFontUnits(metrics.fCapHeight, emSize)); | 
| 382     descriptor->insertInt("ItalicAngle", metrics.fItalicAngle); | 306     descriptor->insertInt("ItalicAngle", metrics.fItalicAngle); | 
| 383     descriptor->insertObject( | 307     descriptor->insertObject( | 
| 384             "FontBBox", makeFontBBox(metrics.fBBox, metrics.fEmSize)); | 308             "FontBBox", makeFontBBox(metrics.fBBox, metrics.fEmSize)); | 
| 385     if (defaultWidth > 0) { | 309     if (defaultWidth > 0) { | 
| 386         descriptor->insertScalar("MissingWidth", | 310         descriptor->insertScalar("MissingWidth", | 
| 387                 scaleFromFontUnits(defaultWidth, emSize)); | 311                 scaleFromFontUnits(defaultWidth, emSize)); | 
| 388     } | 312     } | 
| 389 } | 313 } | 
| 390 | 314 | 
| 391 void SkPDFFont::adjustGlyphRangeForSingleByteEncoding(SkGlyphID glyphID) { |  | 
| 392     // Single byte glyph encoding supports a max of 255 glyphs. |  | 
| 393     fFirstGlyphID = first_glyph_for_single_byte_encoding(glyphID); |  | 
| 394     if (fLastGlyphID > fFirstGlyphID + 255 - 1) { |  | 
| 395         fLastGlyphID = fFirstGlyphID + 255 - 1; |  | 
| 396     } |  | 
| 397 } |  | 
| 398 |  | 
| 399 /////////////////////////////////////////////////////////////////////////////// | 315 /////////////////////////////////////////////////////////////////////////////// | 
| 400 // class SkPDFType0Font | 316 // class SkPDFType0Font | 
| 401 /////////////////////////////////////////////////////////////////////////////// | 317 /////////////////////////////////////////////////////////////////////////////// | 
| 402 | 318 | 
| 403 SkPDFType0Font::SkPDFType0Font(const SkAdvancedTypefaceMetrics& info, | 319 SkPDFType0Font::SkPDFType0Font( | 
| 404                                sk_sp<SkTypeface> typeface, | 320         SkPDFFont::Info info, | 
| 405                                SkAdvancedTypefaceMetrics::FontType fontType) | 321         const SkAdvancedTypefaceMetrics& metrics) | 
| 406     : SkPDFFont(std::move(typeface), fontType) { | 322     : SkPDFFont(std::move(info)) { | 
| 407     SkDEBUGCODE(fPopulated = false); | 323     SkDEBUGCODE(fPopulated = false); | 
| 408     if (!can_subset(info)) { |  | 
| 409         this->populate(nullptr, info); |  | 
| 410     } |  | 
| 411 } | 324 } | 
| 412 | 325 | 
| 413 SkPDFType0Font::~SkPDFType0Font() {} | 326 SkPDFType0Font::~SkPDFType0Font() {} | 
| 414 | 327 | 
| 415 sk_sp<SkPDFObject>  SkPDFType0Font::getFontSubset(SkPDFCanon* canon, |  | 
| 416                                                   const SkPDFGlyphSet* subset) { |  | 
| 417     const SkAdvancedTypefaceMetrics* metrics = |  | 
| 418         SkPDFFont::GetMetrics(this->typeface(), canon); |  | 
| 419     SkASSERT(metrics); |  | 
| 420     if (!metrics || !can_subset(*metrics)) { |  | 
| 421         return nullptr; |  | 
| 422     } |  | 
| 423     auto newSubset = sk_make_sp<SkPDFType0Font>( |  | 
| 424             *metrics, this->refTypeface(), this->getType()); |  | 
| 425     newSubset->populate(subset, *metrics); |  | 
| 426     return newSubset; |  | 
| 427 } |  | 
| 428 | 328 | 
| 429 #ifdef SK_DEBUG | 329 #ifdef SK_DEBUG | 
| 430 void SkPDFType0Font::emitObject(SkWStream* stream, | 330 void SkPDFType0Font::emitObject(SkWStream* stream, | 
| 431                                 const SkPDFObjNumMap& objNumMap, | 331                                 const SkPDFObjNumMap& objNumMap) const { | 
| 432                                 const SkPDFSubstituteMap& substitutes) const { |  | 
| 433     SkASSERT(fPopulated); | 332     SkASSERT(fPopulated); | 
| 434     return INHERITED::emitObject(stream, objNumMap, substitutes); | 333     return INHERITED::emitObject(stream, objNumMap); | 
| 435 } | 334 } | 
| 436 #endif | 335 #endif | 
| 437 | 336 | 
| 438 #ifdef SK_SFNTLY_SUBSETTER | 337 #ifdef SK_SFNTLY_SUBSETTER | 
| 439 // if possible, make no copy. | 338 // if possible, make no copy. | 
| 440 static sk_sp<SkData> stream_to_data(std::unique_ptr<SkStreamAsset> stream) { | 339 static sk_sp<SkData> stream_to_data(std::unique_ptr<SkStreamAsset> stream) { | 
| 441     SkASSERT(stream); | 340     SkASSERT(stream); | 
| 442     (void)stream->rewind(); | 341     (void)stream->rewind(); | 
| 443     SkASSERT(stream->hasLength()); | 342     SkASSERT(stream->hasLength()); | 
| 444     size_t size = stream->getLength(); | 343     size_t size = stream->getLength(); | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 481     auto subsetStream = sk_make_sp<SkPDFStream>( | 380     auto subsetStream = sk_make_sp<SkPDFStream>( | 
| 482             SkData::MakeWithProc( | 381             SkData::MakeWithProc( | 
| 483                     subsetFont, subsetFontSize, | 382                     subsetFont, subsetFontSize, | 
| 484                     [](const void* p, void*) { delete[] (unsigned char*)p; }, | 383                     [](const void* p, void*) { delete[] (unsigned char*)p; }, | 
| 485                     nullptr)); | 384                     nullptr)); | 
| 486     subsetStream->dict()->insertInt("Length1", subsetFontSize); | 385     subsetStream->dict()->insertInt("Length1", subsetFontSize); | 
| 487     return subsetStream; | 386     return subsetStream; | 
| 488 } | 387 } | 
| 489 #endif  // SK_SFNTLY_SUBSETTER | 388 #endif  // SK_SFNTLY_SUBSETTER | 
| 490 | 389 | 
| 491 bool SkPDFType0Font::populate(const SkPDFGlyphSet* subset, | 390 void SkPDFType0Font::getFontSubset(SkPDFCanon* canon) { | 
| 492                               const SkAdvancedTypefaceMetrics& metrics) { | 391     const SkAdvancedTypefaceMetrics* metricsPtr = | 
|  | 392         SkPDFFont::GetMetrics(this->typeface(), canon); | 
|  | 393     SkASSERT(metricsPtr); | 
|  | 394     if (!metricsPtr) { return; } | 
|  | 395     const SkAdvancedTypefaceMetrics& metrics = *metricsPtr; | 
| 493     SkASSERT(can_embed(metrics)); | 396     SkASSERT(can_embed(metrics)); | 
| 494     SkAdvancedTypefaceMetrics::FontType type = this->getType(); | 397     SkAdvancedTypefaceMetrics::FontType type = this->getType(); | 
| 495     SkTypeface* face = this->typeface(); | 398     SkTypeface* face = this->typeface(); | 
| 496     SkASSERT(face); | 399     SkASSERT(face); | 
| 497     const SkString& name = metrics.fFontName; | 400     const SkString& name = metrics.fFontName; | 
| 498 | 401 | 
| 499     auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor"); | 402     auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor"); | 
| 500     add_common_font_descriptor_entries(descriptor.get(), metrics, 0); | 403     add_common_font_descriptor_entries(descriptor.get(), metrics, 0); | 
| 501     switch (type) { | 404     switch (type) { | 
| 502         case SkAdvancedTypefaceMetrics::kTrueType_Font: { | 405         case SkAdvancedTypefaceMetrics::kTrueType_Font: { | 
| 503             int ttcIndex; | 406             int ttcIndex; | 
| 504             std::unique_ptr<SkStreamAsset> fontAsset(face->openStream(&ttcIndex)
     ); | 407             std::unique_ptr<SkStreamAsset> fontAsset(face->openStream(&ttcIndex)
     ); | 
| 505             SkASSERT(fontAsset); | 408             SkASSERT(fontAsset); | 
| 506             if (!fontAsset) { | 409             if (!fontAsset) { | 
| 507                 return false; | 410                 return; | 
| 508             } | 411             } | 
| 509             size_t fontSize = fontAsset->getLength(); | 412             size_t fontSize = fontAsset->getLength(); | 
| 510             SkASSERT(fontSize > 0); | 413             SkASSERT(fontSize > 0); | 
| 511             if (fontSize == 0) { | 414             if (fontSize == 0) { | 
| 512                 return false; | 415                 return; | 
| 513             } | 416             } | 
| 514 | 417 | 
| 515             #ifdef SK_SFNTLY_SUBSETTER | 418             #ifdef SK_SFNTLY_SUBSETTER | 
| 516             if (can_subset(metrics) && subset) { | 419             if (can_subset(metrics)) { | 
| 517                 // Generate glyph id array. in format needed by sfntly | 420                 // Generate glyph id array. in format needed by sfntly | 
| 518                 SkTDArray<uint32_t> glyphIDs; | 421                 SkTDArray<uint32_t> glyphIDs; | 
| 519                 if (subset) { | 422                 if (!this->glyphUsage().has(0)) { | 
| 520                     if (!subset->has(0)) { | 423                     glyphIDs.push(0);  // Always include glyph 0. | 
| 521                         glyphIDs.push(0);  // Always include glyph 0. |  | 
| 522                     } |  | 
| 523                     subset->exportTo(&glyphIDs); |  | 
| 524                 } | 424                 } | 
|  | 425                 this->glyphUsage().exportTo(&glyphIDs); | 
| 525                 sk_sp<SkPDFObject> subsetStream = get_subset_font_stream( | 426                 sk_sp<SkPDFObject> subsetStream = get_subset_font_stream( | 
| 526                         std::move(fontAsset), glyphIDs, name.c_str()); | 427                         std::move(fontAsset), glyphIDs, name.c_str()); | 
| 527                 if (subsetStream) { | 428                 if (subsetStream) { | 
| 528                     descriptor->insertObjRef("FontFile2", std::move(subsetStream
     )); | 429                     descriptor->insertObjRef("FontFile2", std::move(subsetStream
     )); | 
| 529                     break; | 430                     break; | 
| 530                 } | 431                 } | 
| 531                 // If subsetting fails, fall back to original font data. | 432                 // If subsetting fails, fall back to original font data. | 
| 532                 fontAsset.reset(face->openStream(&ttcIndex)); | 433                 fontAsset.reset(face->openStream(&ttcIndex)); | 
| 533             } | 434             } | 
| 534             #endif  // SK_SFNTLY_SUBSETTER | 435             #endif  // SK_SFNTLY_SUBSETTER | 
| 535             auto fontStream = sk_make_sp<SkPDFSharedStream>(std::move(fontAsset)
     ); | 436             auto fontStream = sk_make_sp<SkPDFSharedStream>(std::move(fontAsset)
     ); | 
| 536             fontStream->dict()->insertInt("Length1", fontSize); | 437             fontStream->dict()->insertInt("Length1", fontSize); | 
| 537             descriptor->insertObjRef("FontFile2", std::move(fontStream)); | 438             descriptor->insertObjRef("FontFile2", std::move(fontStream)); | 
| 538             break; | 439             break; | 
| 539         } | 440         } | 
| 540         case SkAdvancedTypefaceMetrics::kType1CID_Font: { | 441         case SkAdvancedTypefaceMetrics::kType1CID_Font: { | 
| 541             std::unique_ptr<SkStreamAsset> fontData(face->openStream(nullptr)); | 442             std::unique_ptr<SkStreamAsset> fontData(face->openStream(nullptr)); | 
| 542             SkASSERT(fontData); | 443             SkASSERT(fontData); | 
| 543             SkASSERT(fontData->getLength() > 0); | 444             SkASSERT(fontData->getLength() > 0); | 
| 544             if (!fontData || 0 == fontData->getLength()) { | 445             if (!fontData || 0 == fontData->getLength()) { | 
| 545                 return false; | 446                 return; | 
| 546             } | 447             } | 
| 547             auto fontStream = sk_make_sp<SkPDFSharedStream>(std::move(fontData))
     ; | 448             auto fontStream = sk_make_sp<SkPDFSharedStream>(std::move(fontData))
     ; | 
| 548             fontStream->dict()->insertName("Subtype", "CIDFontType0c"); | 449             fontStream->dict()->insertName("Subtype", "CIDFontType0c"); | 
| 549             descriptor->insertObjRef("FontFile3", std::move(fontStream)); | 450             descriptor->insertObjRef("FontFile3", std::move(fontStream)); | 
| 550             break; | 451             break; | 
| 551         } | 452         } | 
| 552         default: | 453         default: | 
| 553             SkASSERT(false); | 454             SkASSERT(false); | 
| 554     } | 455     } | 
| 555 | 456 | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 567     } | 468     } | 
| 568 | 469 | 
| 569     auto sysInfo = sk_make_sp<SkPDFDict>(); | 470     auto sysInfo = sk_make_sp<SkPDFDict>(); | 
| 570     sysInfo->insertString("Registry", "Adobe"); | 471     sysInfo->insertString("Registry", "Adobe"); | 
| 571     sysInfo->insertString("Ordering", "Identity"); | 472     sysInfo->insertString("Ordering", "Identity"); | 
| 572     sysInfo->insertInt("Supplement", 0); | 473     sysInfo->insertInt("Supplement", 0); | 
| 573     newCIDFont->insertObject("CIDSystemInfo", std::move(sysInfo)); | 474     newCIDFont->insertObject("CIDSystemInfo", std::move(sysInfo)); | 
| 574 | 475 | 
| 575     uint16_t emSize = metrics.fEmSize; | 476     uint16_t emSize = metrics.fEmSize; | 
| 576     int16_t defaultWidth = 0; | 477     int16_t defaultWidth = 0; | 
| 577     const SkBitSet* bitSet = subset ? &subset->bitSet() : nullptr; |  | 
| 578     { | 478     { | 
| 579         SkAutoGlyphCache glyphCache = vector_cache(face); | 479         SkAutoGlyphCache glyphCache = vector_cache(face); | 
| 580         sk_sp<SkPDFArray> widths = SkPDFMakeCIDGlyphWidthsArray( | 480         sk_sp<SkPDFArray> widths = SkPDFMakeCIDGlyphWidthsArray( | 
| 581                 glyphCache.get(), bitSet, emSize, &defaultWidth); | 481                 glyphCache.get(), &this->glyphUsage(), emSize, &defaultWidth); | 
| 582         if (widths && widths->size() > 0) { | 482         if (widths && widths->size() > 0) { | 
| 583             newCIDFont->insertObject("W", std::move(widths)); | 483             newCIDFont->insertObject("W", std::move(widths)); | 
| 584         } | 484         } | 
| 585         newCIDFont->insertScalar( | 485         newCIDFont->insertScalar( | 
| 586                 "DW", scaleFromFontUnits(defaultWidth, emSize)); | 486                 "DW", scaleFromFontUnits(defaultWidth, emSize)); | 
| 587     } | 487     } | 
| 588 | 488 | 
| 589     //////////////////////////////////////////////////////////////////////////// | 489     //////////////////////////////////////////////////////////////////////////// | 
| 590 | 490 | 
| 591     this->insertName("Subtype", "Type0"); | 491     this->insertName("Subtype", "Type0"); | 
| 592     this->insertName("BaseFont", metrics.fFontName); | 492     this->insertName("BaseFont", metrics.fFontName); | 
| 593     this->insertName("Encoding", "Identity-H"); | 493     this->insertName("Encoding", "Identity-H"); | 
| 594     auto descendantFonts = sk_make_sp<SkPDFArray>(); | 494     auto descendantFonts = sk_make_sp<SkPDFArray>(); | 
| 595     descendantFonts->appendObjRef(std::move(newCIDFont)); | 495     descendantFonts->appendObjRef(std::move(newCIDFont)); | 
| 596     this->insertObject("DescendantFonts", std::move(descendantFonts)); | 496     this->insertObject("DescendantFonts", std::move(descendantFonts)); | 
| 597 | 497 | 
| 598     if (metrics.fGlyphToUnicode.count() > 0) { | 498     if (metrics.fGlyphToUnicode.count() > 0) { | 
| 599         this->insertObjRef("ToUnicode", | 499         this->insertObjRef("ToUnicode", | 
| 600                            SkPDFMakeToUnicodeCmap(metrics.fGlyphToUnicode, | 500                            SkPDFMakeToUnicodeCmap(metrics.fGlyphToUnicode, | 
| 601                                                   subset, | 501                                                   &this->glyphUsage(), | 
| 602                                                   multiByteGlyphs(), | 502                                                   multiByteGlyphs(), | 
| 603                                                   firstGlyphID(), | 503                                                   firstGlyphID(), | 
| 604                                                   lastGlyphID())); | 504                                                   lastGlyphID())); | 
| 605     } | 505     } | 
| 606     SkDEBUGCODE(fPopulated = true); | 506     SkDEBUGCODE(fPopulated = true); | 
| 607     return true; | 507     return; | 
| 608 } | 508 } | 
| 609 | 509 | 
| 610 /////////////////////////////////////////////////////////////////////////////// | 510 /////////////////////////////////////////////////////////////////////////////// | 
| 611 // class SkPDFType1Font | 511 // class SkPDFType1Font | 
| 612 /////////////////////////////////////////////////////////////////////////////// | 512 /////////////////////////////////////////////////////////////////////////////// | 
| 613 | 513 | 
| 614 static sk_sp<SkPDFDict> make_type1_font_descriptor( | 514 static sk_sp<SkPDFDict> make_type1_font_descriptor( | 
| 615         SkTypeface* typeface, | 515         SkTypeface* typeface, | 
| 616         const SkAdvancedTypefaceMetrics& info) { | 516         const SkAdvancedTypefaceMetrics& info) { | 
| 617     auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor"); | 517     auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor"); | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 672         const bool valid = gID < glyphNames.count() && !glyphNames[gID].isEmpty(
     ); | 572         const bool valid = gID < glyphNames.count() && !glyphNames[gID].isEmpty(
     ); | 
| 673         const SkString& name = valid ? glyphNames[gID] : unknown; | 573         const SkString& name = valid ? glyphNames[gID] : unknown; | 
| 674         encDiffs->appendName(name); | 574         encDiffs->appendName(name); | 
| 675     } | 575     } | 
| 676 | 576 | 
| 677     auto encoding = sk_make_sp<SkPDFDict>("Encoding"); | 577     auto encoding = sk_make_sp<SkPDFDict>("Encoding"); | 
| 678     encoding->insertObject("Differences", std::move(encDiffs)); | 578     encoding->insertObject("Differences", std::move(encDiffs)); | 
| 679     font->insertObject("Encoding", std::move(encoding)); | 579     font->insertObject("Encoding", std::move(encoding)); | 
| 680 } | 580 } | 
| 681 | 581 | 
| 682 SkPDFType1Font::SkPDFType1Font(const SkAdvancedTypefaceMetrics& info, | 582 SkPDFType1Font::SkPDFType1Font(SkPDFFont::Info info, | 
| 683                                sk_sp<SkTypeface> typeface, | 583                                const SkAdvancedTypefaceMetrics& metrics, | 
| 684                                uint16_t glyphID, |  | 
| 685                                SkPDFCanon* canon) | 584                                SkPDFCanon* canon) | 
| 686     : SkPDFFont(std::move(typeface), SkAdvancedTypefaceMetrics::kType1_Font) | 585     : SkPDFFont(std::move(info)) | 
| 687 { | 586 { | 
| 688     SkFontID fontID = this->typeface()->uniqueID(); | 587     SkFontID fontID = this->typeface()->uniqueID(); | 
| 689     sk_sp<SkPDFDict> fontDescriptor; | 588     sk_sp<SkPDFDict> fontDescriptor; | 
| 690     if (SkPDFDict** ptr = canon->fFontDescriptors.find(fontID)) { | 589     if (SkPDFDict** ptr = canon->fFontDescriptors.find(fontID)) { | 
| 691         fontDescriptor = sk_ref_sp(*ptr); | 590         fontDescriptor = sk_ref_sp(*ptr); | 
| 692     } else { | 591     } else { | 
| 693         fontDescriptor = make_type1_font_descriptor(this->typeface(), info); | 592         fontDescriptor = make_type1_font_descriptor(this->typeface(), metrics); | 
| 694         canon->fFontDescriptors.set(fontID, SkRef(fontDescriptor.get())); | 593         canon->fFontDescriptors.set(fontID, SkRef(fontDescriptor.get())); | 
| 695     } | 594     } | 
| 696     this->insertObjRef("FontDescriptor", std::move(fontDescriptor)); | 595     this->insertObjRef("FontDescriptor", std::move(fontDescriptor)); | 
| 697     this->adjustGlyphRangeForSingleByteEncoding(glyphID); |  | 
| 698     // TODO(halcanary): subset this (advances and names). | 596     // TODO(halcanary): subset this (advances and names). | 
| 699     populate_type_1_font(this, info, this->typeface(), | 597     populate_type_1_font(this, metrics, this->typeface(), | 
| 700                          this->firstGlyphID(), this->lastGlyphID()); | 598                          this->firstGlyphID(), this->lastGlyphID()); | 
| 701 } | 599 } | 
| 702 | 600 | 
| 703 /////////////////////////////////////////////////////////////////////////////// | 601 /////////////////////////////////////////////////////////////////////////////// | 
| 704 // class SkPDFType3Font | 602 // class SkPDFType3Font | 
| 705 /////////////////////////////////////////////////////////////////////////////// | 603 /////////////////////////////////////////////////////////////////////////////// | 
| 706 | 604 | 
| 707 namespace { | 605 namespace { | 
| 708 // returns [0, first, first+1, ... last-1,  last] | 606 // returns [0, first, first+1, ... last-1,  last] | 
| 709 struct SingleByteGlyphIdIterator { | 607 struct SingleByteGlyphIdIterator { | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 731 private: | 629 private: | 
| 732     const SkGlyphID fFirst; | 630     const SkGlyphID fFirst; | 
| 733     const SkGlyphID fLast; | 631     const SkGlyphID fLast; | 
| 734 }; | 632 }; | 
| 735 } | 633 } | 
| 736 | 634 | 
| 737 static void add_type3_font_info(SkPDFCanon* canon, | 635 static void add_type3_font_info(SkPDFCanon* canon, | 
| 738                                 SkPDFDict* font, | 636                                 SkPDFDict* font, | 
| 739                                 SkTypeface* typeface, | 637                                 SkTypeface* typeface, | 
| 740                                 SkScalar emSize, | 638                                 SkScalar emSize, | 
| 741                                 const SkPDFGlyphSet* subset, | 639                                 const SkBitSet& subset, | 
| 742                                 SkGlyphID firstGlyphID, | 640                                 SkGlyphID firstGlyphID, | 
| 743                                 SkGlyphID lastGlyphID) { | 641                                 SkGlyphID lastGlyphID) { | 
| 744     SkASSERT(lastGlyphID >= firstGlyphID); | 642     SkASSERT(lastGlyphID >= firstGlyphID); | 
| 745     SkASSERT(emSize > 0.0f); | 643     SkASSERT(emSize > 0.0f); | 
| 746     SkAutoGlyphCache cache = vector_cache(typeface, emSize); | 644     SkAutoGlyphCache cache = vector_cache(typeface, emSize); | 
| 747     font->insertName("Subtype", "Type3"); | 645     font->insertName("Subtype", "Type3"); | 
| 748     // Flip about the x-axis and scale by 1/emSize. | 646     // Flip about the x-axis and scale by 1/emSize. | 
| 749     SkMatrix fontMatrix; | 647     SkMatrix fontMatrix; | 
| 750     fontMatrix.setScale(SkScalarInvert(emSize), -SkScalarInvert(emSize)); | 648     fontMatrix.setScale(SkScalarInvert(emSize), -SkScalarInvert(emSize)); | 
| 751     font->insertObject("FontMatrix", SkPDFUtils::MatrixToArray(fontMatrix)); | 649     font->insertObject("FontMatrix", SkPDFUtils::MatrixToArray(fontMatrix)); | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 763     encDiffs->reserve(glyphCount + 1); | 661     encDiffs->reserve(glyphCount + 1); | 
| 764     encDiffs->appendInt(0);  // index of first glyph | 662     encDiffs->appendInt(0);  // index of first glyph | 
| 765 | 663 | 
| 766     auto widthArray = sk_make_sp<SkPDFArray>(); | 664     auto widthArray = sk_make_sp<SkPDFArray>(); | 
| 767     widthArray->reserve(glyphCount); | 665     widthArray->reserve(glyphCount); | 
| 768 | 666 | 
| 769     SkIRect bbox = SkIRect::MakeEmpty(); | 667     SkIRect bbox = SkIRect::MakeEmpty(); | 
| 770 | 668 | 
| 771     sk_sp<SkPDFStream> emptyStream; | 669     sk_sp<SkPDFStream> emptyStream; | 
| 772     for (SkGlyphID gID : SingleByteGlyphIdIterator(firstGlyphID, lastGlyphID)) { | 670     for (SkGlyphID gID : SingleByteGlyphIdIterator(firstGlyphID, lastGlyphID)) { | 
| 773         bool skipGlyph = subset && gID != 0 && !subset->has(gID); | 671         bool skipGlyph = gID != 0 && !subset.has(gID); | 
| 774         SkString characterName; | 672         SkString characterName; | 
| 775         SkScalar advance = 0.0f; | 673         SkScalar advance = 0.0f; | 
| 776         SkIRect glyphBBox; | 674         SkIRect glyphBBox; | 
| 777         if (skipGlyph) { | 675         if (skipGlyph) { | 
| 778             characterName.set("g0"); | 676             characterName.set("g0"); | 
| 779         } else { | 677         } else { | 
| 780             characterName.printf("g%X", gID); | 678             characterName.printf("g%X", gID); | 
| 781             const SkGlyph& glyph = cache->getGlyphIDMetrics(gID); | 679             const SkGlyph& glyph = cache->getGlyphIDMetrics(gID); | 
| 782             advance = SkFloatToScalar(glyph.fAdvanceX); | 680             advance = SkFloatToScalar(glyph.fAdvanceX); | 
| 783             glyphBBox = SkIRect::MakeXYWH(glyph.fLeft, glyph.fTop, | 681             glyphBBox = SkIRect::MakeXYWH(glyph.fLeft, glyph.fTop, | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 820     fontBBox->appendInt(bbox.left()); | 718     fontBBox->appendInt(bbox.left()); | 
| 821     fontBBox->appendInt(bbox.bottom()); | 719     fontBBox->appendInt(bbox.bottom()); | 
| 822     fontBBox->appendInt(bbox.right()); | 720     fontBBox->appendInt(bbox.right()); | 
| 823     fontBBox->appendInt(bbox.top()); | 721     fontBBox->appendInt(bbox.top()); | 
| 824     font->insertObject("FontBBox", std::move(fontBBox)); | 722     font->insertObject("FontBBox", std::move(fontBBox)); | 
| 825     font->insertName("CIDToGIDMap", "Identity"); | 723     font->insertName("CIDToGIDMap", "Identity"); | 
| 826     const SkAdvancedTypefaceMetrics* metrics = SkPDFFont::GetMetrics(typeface, c
     anon); | 724     const SkAdvancedTypefaceMetrics* metrics = SkPDFFont::GetMetrics(typeface, c
     anon); | 
| 827     if (metrics /* && metrics->fGlyphToUnicode.count() > 0 */) { | 725     if (metrics /* && metrics->fGlyphToUnicode.count() > 0 */) { | 
| 828         font->insertObjRef("ToUnicode", | 726         font->insertObjRef("ToUnicode", | 
| 829                            SkPDFMakeToUnicodeCmap(metrics->fGlyphToUnicode, | 727                            SkPDFMakeToUnicodeCmap(metrics->fGlyphToUnicode, | 
| 830                                                   subset, | 728                                                   &subset, | 
| 831                                                   false, | 729                                                   false, | 
| 832                                                   firstGlyphID, | 730                                                   firstGlyphID, | 
| 833                                                   lastGlyphID)); | 731                                                   lastGlyphID)); | 
| 834     } | 732     } | 
| 835     font->insertObject("Widths", std::move(widthArray)); | 733     font->insertObject("Widths", std::move(widthArray)); | 
| 836     font->insertObject("Encoding", std::move(encoding)); | 734     font->insertObject("Encoding", std::move(encoding)); | 
| 837     font->insertObject("CharProcs", std::move(charProcs)); | 735     font->insertObject("CharProcs", std::move(charProcs)); | 
| 838 } | 736 } | 
| 839 | 737 | 
| 840 SkPDFType3Font::SkPDFType3Font(const SkAdvancedTypefaceMetrics& info, | 738 SkPDFType3Font::SkPDFType3Font(SkPDFFont::Info info, | 
| 841                                sk_sp<SkTypeface> typeface, | 739                                const SkAdvancedTypefaceMetrics& metrics) | 
| 842                                SkAdvancedTypefaceMetrics::FontType fontType, | 740     : SkPDFFont(std::move(info)) {} | 
| 843                                uint16_t glyphID) |  | 
| 844     : SkPDFFont(std::move(typeface), fontType) { |  | 
| 845     this->adjustGlyphRangeForSingleByteEncoding(glyphID); |  | 
| 846 } |  | 
| 847 | 741 | 
| 848 sk_sp<SkPDFObject> SkPDFType3Font::getFontSubset(SkPDFCanon* canon, | 742 void SkPDFType3Font::getFontSubset(SkPDFCanon* canon) { | 
| 849                                                  const SkPDFGlyphSet* usage) { |  | 
| 850     // All fonts are subset before serialization. |  | 
| 851     // TODO(halcanary): all fonts should follow this pattern. |  | 
| 852     const SkAdvancedTypefaceMetrics* info = | 743     const SkAdvancedTypefaceMetrics* info = | 
| 853         SkPDFFont::GetMetrics(this->typeface(), canon); | 744         SkPDFFont::GetMetrics(this->typeface(), canon); | 
| 854     SkASSERT(info); | 745     SkASSERT(info); | 
| 855     uint16_t emSize = info->fEmSize > 0 ? info->fEmSize : 1000; | 746     uint16_t emSize = info->fEmSize > 0 ? info->fEmSize : 1000; | 
| 856     auto font = sk_make_sp<SkPDFDict>("Font"); | 747     add_type3_font_info(canon, this, this->typeface(), (SkScalar)emSize, | 
| 857     add_type3_font_info(canon, font.get(), this->typeface(), (SkScalar)emSize, u
     sage, | 748                         this->glyphUsage(), | 
| 858                         this->firstGlyphID(), this->lastGlyphID()); | 749                         this->firstGlyphID(), this->lastGlyphID()); | 
| 859     return font; |  | 
| 860 } | 750 } | 
| 861 | 751 | 
| 862 |  | 
| 863 //////////////////////////////////////////////////////////////////////////////// | 752 //////////////////////////////////////////////////////////////////////////////// | 
| 864 | 753 | 
| 865 bool SkPDFFont::CanEmbedTypeface(SkTypeface* typeface, SkPDFCanon* canon) { | 754 bool SkPDFFont::CanEmbedTypeface(SkTypeface* typeface, SkPDFCanon* canon) { | 
| 866     const SkAdvancedTypefaceMetrics* metrics = SkPDFFont::GetMetrics(typeface, c
     anon); | 755     const SkAdvancedTypefaceMetrics* metrics = SkPDFFont::GetMetrics(typeface, c
     anon); | 
| 867     return metrics && can_embed(*metrics); | 756     return metrics && can_embed(*metrics); | 
| 868 } | 757 } | 
| 869 | 758 | 
| 870 void SkPDFFont::drop() { | 759 void SkPDFFont::drop() { | 
| 871     fTypeface = nullptr; | 760     fTypeface = nullptr; | 
| 872     this->SkPDFDict::drop(); | 761     this->SkPDFDict::drop(); | 
| 873 } | 762 } | 
| OLD | NEW | 
|---|