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 |