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 21 matching lines...) Expand all Loading... |
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 class SkPDFType0Font final : public SkPDFFont { |
41 public: | 41 public: |
42 SkPDFType0Font(const SkAdvancedTypefaceMetrics* info, | 42 SkPDFType0Font(sk_sp<const SkAdvancedTypefaceMetrics> info, |
43 sk_sp<SkTypeface> typeface, | 43 sk_sp<SkTypeface> typeface, |
44 SkAdvancedTypefaceMetrics::FontType type); | 44 SkAdvancedTypefaceMetrics::FontType type); |
45 virtual ~SkPDFType0Font(); | 45 virtual ~SkPDFType0Font(); |
46 sk_sp<SkPDFObject> getFontSubset(SkPDFCanon*, const SkPDFGlyphSet*) override
; | 46 sk_sp<SkPDFObject> getFontSubset(const SkPDFGlyphSet* usage) override; |
47 #ifdef SK_DEBUG | 47 #ifdef SK_DEBUG |
48 void emitObject(SkWStream*, | 48 void emitObject(SkWStream*, |
49 const SkPDFObjNumMap&, | 49 const SkPDFObjNumMap&, |
50 const SkPDFSubstituteMap&) const override; | 50 const SkPDFSubstituteMap&) const override; |
51 #endif | 51 #endif |
52 | 52 |
53 private: | 53 private: |
54 #ifdef SK_DEBUG | 54 #ifdef SK_DEBUG |
55 bool fPopulated; | 55 bool fPopulated; |
56 #endif | 56 #endif |
57 bool populate(const SkPDFGlyphSet* subset, | 57 bool populate(const SkPDFGlyphSet* subset); |
58 const SkAdvancedTypefaceMetrics& metrics); | |
59 typedef SkPDFDict INHERITED; | 58 typedef SkPDFDict INHERITED; |
60 }; | 59 }; |
61 | 60 |
62 class SkPDFType1Font final : public SkPDFFont { | 61 class SkPDFType1Font final : public SkPDFFont { |
63 public: | 62 public: |
64 SkPDFType1Font(const SkAdvancedTypefaceMetrics* info, | 63 SkPDFType1Font(sk_sp<const SkAdvancedTypefaceMetrics> info, |
65 sk_sp<SkTypeface> typeface, | 64 sk_sp<SkTypeface> typeface, |
66 uint16_t glyphID, | 65 uint16_t glyphID, |
67 SkPDFCanon* canon); | 66 sk_sp<SkPDFDict> relatedFontDescriptor); |
68 virtual ~SkPDFType1Font() {} | 67 virtual ~SkPDFType1Font(); |
| 68 |
| 69 private: |
| 70 bool populate(int16_t glyphID); |
| 71 bool addFontDescriptor(int16_t defaultWidth); |
69 }; | 72 }; |
70 | 73 |
71 class SkPDFType3Font final : public SkPDFFont { | 74 class SkPDFType3Font final : public SkPDFFont { |
72 public: | 75 public: |
73 SkPDFType3Font(const SkAdvancedTypefaceMetrics* info, | 76 SkPDFType3Font(sk_sp<const SkAdvancedTypefaceMetrics> info, |
74 sk_sp<SkTypeface> typeface, | 77 sk_sp<SkTypeface> typeface, |
75 SkAdvancedTypefaceMetrics::FontType fontType, | 78 SkAdvancedTypefaceMetrics::FontType fontType, |
76 uint16_t glyphID); | 79 uint16_t glyphID); |
77 virtual ~SkPDFType3Font() {} | 80 virtual ~SkPDFType3Font() {} |
78 void emitObject(SkWStream*, | 81 void emitObject(SkWStream*, |
79 const SkPDFObjNumMap&, | 82 const SkPDFObjNumMap&, |
80 const SkPDFSubstituteMap&) const override { | 83 const SkPDFSubstituteMap&) const override { |
81 SkDEBUGFAIL("should call getFontSubset!"); | 84 SkDEBUGFAIL("should call getFontSubset!"); |
82 } | 85 } |
83 sk_sp<SkPDFObject> getFontSubset(SkPDFCanon*, const SkPDFGlyphSet*) override
; | 86 sk_sp<SkPDFObject> getFontSubset(const SkPDFGlyphSet* usage) override; |
84 }; | 87 }; |
85 | 88 |
86 /////////////////////////////////////////////////////////////////////////////// | 89 /////////////////////////////////////////////////////////////////////////////// |
87 // File-Local Functions | 90 // File-Local Functions |
88 /////////////////////////////////////////////////////////////////////////////// | 91 /////////////////////////////////////////////////////////////////////////////// |
89 | 92 |
90 static SkAutoGlyphCache vector_cache(SkTypeface* face, SkScalar size = 0) { | 93 static SkAutoGlyphCache vector_cache(SkTypeface* face, SkScalar size = 0) { |
91 SkPaint tmpPaint; | 94 SkPaint tmpPaint; |
92 tmpPaint.setHinting(SkPaint::kNo_Hinting); | 95 tmpPaint.setHinting(SkPaint::kNo_Hinting); |
93 tmpPaint.setTypeface(sk_ref_sp(face)); | 96 tmpPaint.setTypeface(sk_ref_sp(face)); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 * some additional state indicating which subset of the font is used. It | 209 * 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 | 210 * must be maintained at the page granularity and then combined at the document |
208 * granularity. a) change SkPDFFont to fill in its state on demand, kind of | 211 * granularity. a) change SkPDFFont to fill in its state on demand, kind of |
209 * like SkPDFGraphicState. b) maintain a per font glyph usage class in each | 212 * like SkPDFGraphicState. b) maintain a per font glyph usage class in each |
210 * page/pdf device. c) in the document, retrieve the per font glyph usage | 213 * page/pdf device. c) in the document, retrieve the per font glyph usage |
211 * from each page and combine it and ask for a resource with that subset. | 214 * from each page and combine it and ask for a resource with that subset. |
212 */ | 215 */ |
213 | 216 |
214 SkPDFFont::~SkPDFFont() {} | 217 SkPDFFont::~SkPDFFont() {} |
215 | 218 |
216 static bool can_embed(const SkAdvancedTypefaceMetrics* metrics) { | 219 bool SkPDFFont::canEmbed() const { |
217 return !metrics || | 220 if (!fFontInfo.get()) { |
218 !SkToBool(metrics->fFlags & SkAdvancedTypefaceMetrics::kNotEmbeddable
_FontFlag); | 221 SkASSERT(fFontType == SkAdvancedTypefaceMetrics::kOther_Font); |
| 222 return true; |
| 223 } |
| 224 return (fFontInfo->fFlags & |
| 225 SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag) == 0; |
219 } | 226 } |
220 | 227 |
221 static bool can_subset(const SkAdvancedTypefaceMetrics* metrics) { | 228 bool SkPDFFont::canSubset() const { |
222 return !metrics || | 229 if (!fFontInfo.get()) { |
223 !SkToBool(metrics->fFlags & SkAdvancedTypefaceMetrics::kNotSubsettabl
e_FontFlag); | 230 SkASSERT(fFontType == SkAdvancedTypefaceMetrics::kOther_Font); |
| 231 return true; |
| 232 } |
| 233 return (fFontInfo->fFlags & |
| 234 SkAdvancedTypefaceMetrics::kNotSubsettable_FontFlag) == 0; |
| 235 } |
| 236 |
| 237 bool SkPDFFont::hasGlyph(uint16_t id) { |
| 238 return (id >= fFirstGlyphID && id <= fLastGlyphID) || id == 0; |
224 } | 239 } |
225 | 240 |
226 int SkPDFFont::glyphsToPDFFontEncoding(SkGlyphID* glyphIDs, int numGlyphs) const
{ | 241 int SkPDFFont::glyphsToPDFFontEncoding(SkGlyphID* glyphIDs, int numGlyphs) const
{ |
227 // A font with multibyte glyphs will support all glyph IDs in a single font. | 242 // A font with multibyte glyphs will support all glyph IDs in a single font. |
228 if (this->multiByteGlyphs()) { | 243 if (this->multiByteGlyphs()) { |
229 return numGlyphs; | 244 return numGlyphs; |
230 } | 245 } |
231 | 246 |
232 for (int i = 0; i < numGlyphs; i++) { | 247 for (int i = 0; i < numGlyphs; i++) { |
233 if (glyphIDs[i] == 0) { | 248 if (glyphIDs[i] == 0) { |
(...skipping 15 matching lines...) Expand all Loading... |
249 } | 264 } |
250 for (int i = 0; i < numGlyphs; i++) { | 265 for (int i = 0; i < numGlyphs; i++) { |
251 if (glyphIDs[i] != 0 && | 266 if (glyphIDs[i] != 0 && |
252 (glyphIDs[i] < fFirstGlyphID || glyphIDs[i] > fLastGlyphID)) { | 267 (glyphIDs[i] < fFirstGlyphID || glyphIDs[i] > fLastGlyphID)) { |
253 return i; | 268 return i; |
254 } | 269 } |
255 } | 270 } |
256 return numGlyphs; | 271 return numGlyphs; |
257 } | 272 } |
258 | 273 |
259 | 274 // static |
260 const SkAdvancedTypefaceMetrics* SkPDFFont::GetMetrics(SkTypeface* typeface, | |
261 SkPDFCanon* canon) { | |
262 SkFontID id = SkTypeface::UniqueID(typeface); | |
263 if (SkAdvancedTypefaceMetrics** ptr = canon->fTypefaceMetrics.find(id)) { | |
264 return *ptr; | |
265 } | |
266 sk_sp<SkTypeface> defaultFace; | |
267 if (!typeface) { | |
268 defaultFace = SkTypeface::MakeDefault(); | |
269 typeface = defaultFace.get(); | |
270 } | |
271 sk_sp<SkAdvancedTypefaceMetrics> metrics( | |
272 typeface->getAdvancedTypefaceMetrics( | |
273 SkTypeface::kGlyphNames_PerGlyphInfo | SkTypeface::kToUnicod
e_PerGlyphInfo, | |
274 nullptr, 0)); | |
275 return *canon->fTypefaceMetrics.set(id, metrics.release()); | |
276 } | |
277 | |
278 SkAdvancedTypefaceMetrics::FontType font_type(const SkAdvancedTypefaceMetrics* m
etrics) { | |
279 if (!metrics || SkToBool(metrics->fFlags & | |
280 SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag))
{ | |
281 // force Type3 fallback. | |
282 return SkAdvancedTypefaceMetrics::kOther_Font; | |
283 } | |
284 return metrics->fType; | |
285 } | |
286 | |
287 static SkGlyphID first_glyph_for_single_byte_encoding(SkGlyphID gid) { | |
288 return gid != 0 ? gid - (gid - 1) % 255 : 1; | |
289 } | |
290 | |
291 SkPDFFont* SkPDFFont::GetFontResource(SkPDFCanon* canon, | 275 SkPDFFont* SkPDFFont::GetFontResource(SkPDFCanon* canon, |
292 SkTypeface* face, | 276 SkTypeface* face, |
293 SkGlyphID glyphID) { | 277 uint16_t glyphID) { |
294 SkASSERT(canon); | 278 SkASSERT(canon); |
295 const SkAdvancedTypefaceMetrics* fontMetrics = SkPDFFont::GetMetrics(face, c
anon); | 279 const uint32_t fontID = SkTypeface::UniqueID(face); |
296 SkAdvancedTypefaceMetrics::FontType type = font_type(fontMetrics); | 280 SkPDFFont* relatedFont; |
297 bool multibyte = SkPDFFont::IsMultiByte(type); | 281 if (SkPDFFont* pdfFont = canon->findFont(fontID, glyphID, &relatedFont)) { |
298 SkGlyphID firstGlyph = multibyte ? 0 : first_glyph_for_single_byte_encoding(
glyphID); | 282 return SkRef(pdfFont); |
299 uint64_t fontID = (SkTypeface::UniqueID(face) << 16) | firstGlyph; | |
300 | |
301 if (SkPDFFont** found = canon->fFontMap.find(fontID)) { | |
302 SkASSERT(multibyte == (*found)->multiByteGlyphs()); | |
303 return SkRef(*found); | |
304 } | 283 } |
305 | |
306 sk_sp<SkTypeface> typeface(face ? sk_ref_sp(face) : SkTypeface::MakeDefault(
)); | 284 sk_sp<SkTypeface> typeface(face ? sk_ref_sp(face) : SkTypeface::MakeDefault(
)); |
307 SkASSERT(typeface); | 285 SkASSERT(typeface); |
308 int glyphCount = typeface->countGlyphs(); | 286 int glyphCount = typeface->countGlyphs(); |
309 // Validate typeface + glyph; | |
310 if (glyphCount < 1 || // typeface lacks even a NOTDEF glyph. | 287 if (glyphCount < 1 || // typeface lacks even a NOTDEF glyph. |
311 glyphCount > 1 + SK_MaxU16 || // invalid glyphCount | 288 glyphCount > 1 + SK_MaxU16 || // invalid glyphCount |
312 glyphID >= glyphCount) { // invalid glyph | 289 glyphID >= glyphCount) { // invalid glyph |
313 return nullptr; | 290 return nullptr; |
314 } | 291 } |
| 292 sk_sp<const SkAdvancedTypefaceMetrics> fontMetrics; |
| 293 sk_sp<SkPDFDict> relatedFontDescriptor; |
| 294 if (relatedFont) { |
| 295 fontMetrics = relatedFont->refFontInfo(); |
| 296 relatedFontDescriptor = relatedFont->refFontDescriptor(); |
| 297 |
| 298 // This only is to catch callers who pass invalid glyph ids. |
| 299 // If glyph id is invalid, then we will create duplicate entries |
| 300 // for TrueType fonts. |
| 301 SkDEBUGCODE(SkAdvancedTypefaceMetrics::FontType fontType = relatedFont->
getType()); |
| 302 SkASSERT(fontType != SkAdvancedTypefaceMetrics::kType1CID_Font); |
| 303 SkASSERT(fontType != SkAdvancedTypefaceMetrics::kTrueType_Font); |
| 304 } else { |
| 305 SkTypeface::PerGlyphInfo info = SkTypeface::kGlyphNames_PerGlyphInfo | |
| 306 SkTypeface::kToUnicode_PerGlyphInfo; |
| 307 fontMetrics.reset( |
| 308 typeface->getAdvancedTypefaceMetrics(info, nullptr, 0)); |
| 309 } |
| 310 |
| 311 SkAdvancedTypefaceMetrics::FontType type = |
| 312 fontMetrics ? fontMetrics->fType : SkAdvancedTypefaceMetrics::kOther_Fon
t; |
| 313 if (fontMetrics && |
| 314 SkToBool(fontMetrics->fFlags & |
| 315 SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag)) { |
| 316 // force Type3 fallback. |
| 317 type = SkAdvancedTypefaceMetrics::kOther_Font; |
| 318 } |
315 | 319 |
316 sk_sp<SkPDFFont> font; | 320 sk_sp<SkPDFFont> font; |
317 switch (type) { | 321 switch (type) { |
318 case SkAdvancedTypefaceMetrics::kType1CID_Font: | 322 case SkAdvancedTypefaceMetrics::kType1CID_Font: |
319 case SkAdvancedTypefaceMetrics::kTrueType_Font: | 323 case SkAdvancedTypefaceMetrics::kTrueType_Font: |
320 SkASSERT(multibyte); | 324 SkASSERT(relatedFontDescriptor == nullptr); |
321 SkASSERT(fontMetrics != nullptr); | 325 SkASSERT(fontMetrics != nullptr); |
322 font = sk_make_sp<SkPDFType0Font>(fontMetrics, | 326 font = sk_make_sp<SkPDFType0Font>(std::move(fontMetrics), |
323 std::move(typeface), | 327 std::move(typeface), |
324 type); | 328 type); |
325 break; | 329 break; |
326 case SkAdvancedTypefaceMetrics::kType1_Font: | 330 case SkAdvancedTypefaceMetrics::kType1_Font: |
327 SkASSERT(!multibyte); | |
328 SkASSERT(fontMetrics != nullptr); | 331 SkASSERT(fontMetrics != nullptr); |
329 font = sk_make_sp<SkPDFType1Font>(fontMetrics, | 332 font = sk_make_sp<SkPDFType1Font>(std::move(fontMetrics), |
330 std::move(typeface), | 333 std::move(typeface), |
331 glyphID, | 334 glyphID, |
332 canon); | 335 std::move(relatedFontDescriptor)); |
333 break; | 336 break; |
334 default: | 337 case SkAdvancedTypefaceMetrics::kCFF_Font: |
335 SkASSERT(!multibyte); | 338 SkASSERT(fontMetrics != nullptr); |
336 font = sk_make_sp<SkPDFType3Font>(fontMetrics, | 339 // fallthrough |
| 340 case SkAdvancedTypefaceMetrics::kOther_Font: |
| 341 font = sk_make_sp<SkPDFType3Font>(std::move(fontMetrics), |
337 std::move(typeface), | 342 std::move(typeface), |
338 type, | 343 type, |
339 glyphID); | 344 glyphID); |
340 break; | 345 break; |
| 346 default: |
| 347 SkDEBUGFAIL("invalid SkAdvancedTypefaceMetrics::FontType"); |
| 348 return nullptr; |
341 } | 349 } |
342 canon->fFontMap.set(fontID, SkRef(font.get())); | 350 // When firstGlyphID==0, SkFont::IsMatch() matches all glyphs in font. |
| 351 SkGlyphID firstGlyphID = font->multiByteGlyphs() ? 0 : font->fFirstGlyphID; |
| 352 // TODO(halcanary) Make SkCanon::addFont take sk_sp<SkPDFFont>. |
| 353 canon->addFont(font.get(), fontID, firstGlyphID); |
343 return font.release(); // TODO(halcanary) return sk_sp<SkPDFFont>. | 354 return font.release(); // TODO(halcanary) return sk_sp<SkPDFFont>. |
344 } | 355 } |
345 | 356 |
346 sk_sp<SkPDFObject> SkPDFFont::getFontSubset(SkPDFCanon*, const SkPDFGlyphSet*) { | 357 sk_sp<SkPDFObject> SkPDFFont::getFontSubset(const SkPDFGlyphSet*) { |
347 return nullptr; // Default: no support. | 358 return nullptr; // Default: no support. |
348 } | 359 } |
349 | 360 |
350 SkPDFFont::SkPDFFont(sk_sp<SkTypeface> typeface, | 361 // TODO: take a sk_sp<SkAdvancedTypefaceMetrics> and sk_sp<SkTypeface> |
351 SkAdvancedTypefaceMetrics::FontType fontType) | 362 SkPDFFont::SkPDFFont(sk_sp<const SkAdvancedTypefaceMetrics> info, |
| 363 sk_sp<SkTypeface> typeface, |
| 364 sk_sp<SkPDFDict> relatedFontDescriptor, |
| 365 SkAdvancedTypefaceMetrics::FontType fontType, |
| 366 bool multiByteGlyphs) |
352 : SkPDFDict("Font") | 367 : SkPDFDict("Font") |
353 , fTypeface(std::move(typeface)) | 368 , fTypeface(std::move(typeface)) |
| 369 , fFontInfo(std::move(info)) |
| 370 , fDescriptor(std::move(relatedFontDescriptor)) |
354 , fFirstGlyphID(1) | 371 , fFirstGlyphID(1) |
355 , fFontType(fontType) { | 372 , fFontType(fontType) |
| 373 , fMultiByteGlyphs(multiByteGlyphs) { |
356 SkASSERT(fTypeface); | 374 SkASSERT(fTypeface); |
357 fLastGlyphID = SkToU16(fTypeface->countGlyphs() - 1); | 375 fLastGlyphID = fFontInfo ? fFontInfo->fLastGlyphID : 0; |
| 376 if (0 == fLastGlyphID) { |
| 377 fLastGlyphID = SkToU16(fTypeface->countGlyphs() - 1); |
| 378 } |
| 379 } |
| 380 |
| 381 void SkPDFFont::setFontInfo(sk_sp<const SkAdvancedTypefaceMetrics> info) { |
| 382 if (info) { |
| 383 fFontInfo = std::move(info); |
| 384 } |
| 385 } |
| 386 |
| 387 void SkPDFFont::setLastGlyphID(uint16_t glyphID) { |
| 388 fLastGlyphID = glyphID; |
| 389 } |
| 390 |
| 391 void SkPDFFont::setFontDescriptor(sk_sp<SkPDFDict> descriptor) { |
| 392 fDescriptor = std::move(descriptor); |
358 } | 393 } |
359 | 394 |
360 static void add_common_font_descriptor_entries(SkPDFDict* descriptor, | 395 static void add_common_font_descriptor_entries(SkPDFDict* descriptor, |
361 const SkAdvancedTypefaceMetrics&
metrics, | 396 const SkAdvancedTypefaceMetrics&
metrics, |
362 int16_t defaultWidth) { | 397 int16_t defaultWidth) { |
363 const uint16_t emSize = metrics.fEmSize; | 398 const uint16_t emSize = metrics.fEmSize; |
364 descriptor->insertName("FontName", metrics.fFontName); | 399 descriptor->insertName("FontName", metrics.fFontName); |
365 descriptor->insertInt("Flags", (size_t)(metrics.fStyle | kPdfSymbolic)); | 400 descriptor->insertInt("Flags", (size_t)(metrics.fStyle | kPdfSymbolic)); |
366 descriptor->insertScalar("Ascent", | 401 descriptor->insertScalar("Ascent", |
367 scaleFromFontUnits(metrics.fAscent, emSize)); | 402 scaleFromFontUnits(metrics.fAscent, emSize)); |
368 descriptor->insertScalar("Descent", | 403 descriptor->insertScalar("Descent", |
369 scaleFromFontUnits(metrics.fDescent, emSize)); | 404 scaleFromFontUnits(metrics.fDescent, emSize)); |
370 descriptor->insertScalar("StemV", | 405 descriptor->insertScalar("StemV", |
371 scaleFromFontUnits(metrics.fStemV, emSize)); | 406 scaleFromFontUnits(metrics.fStemV, emSize)); |
372 descriptor->insertScalar("CapHeight", | 407 descriptor->insertScalar("CapHeight", |
373 scaleFromFontUnits(metrics.fCapHeight, emSize)); | 408 scaleFromFontUnits(metrics.fCapHeight, emSize)); |
374 descriptor->insertInt("ItalicAngle", metrics.fItalicAngle); | 409 descriptor->insertInt("ItalicAngle", metrics.fItalicAngle); |
375 descriptor->insertObject( | 410 descriptor->insertObject( |
376 "FontBBox", makeFontBBox(metrics.fBBox, metrics.fEmSize)); | 411 "FontBBox", makeFontBBox(metrics.fBBox, metrics.fEmSize)); |
377 if (defaultWidth > 0) { | 412 if (defaultWidth > 0) { |
378 descriptor->insertScalar("MissingWidth", | 413 descriptor->insertScalar("MissingWidth", |
379 scaleFromFontUnits(defaultWidth, emSize)); | 414 scaleFromFontUnits(defaultWidth, emSize)); |
380 } | 415 } |
381 } | 416 } |
382 | 417 |
383 void SkPDFFont::adjustGlyphRangeForSingleByteEncoding(SkGlyphID glyphID) { | 418 void SkPDFFont::adjustGlyphRangeForSingleByteEncoding(uint16_t glyphID) { |
384 // Single byte glyph encoding supports a max of 255 glyphs. | 419 // Single byte glyph encoding supports a max of 255 glyphs. |
385 fFirstGlyphID = first_glyph_for_single_byte_encoding(glyphID); | 420 fFirstGlyphID = glyphID - (glyphID - 1) % 255; |
386 if (fLastGlyphID > fFirstGlyphID + 255 - 1) { | 421 if (fLastGlyphID > fFirstGlyphID + 255 - 1) { |
387 fLastGlyphID = fFirstGlyphID + 255 - 1; | 422 fLastGlyphID = fFirstGlyphID + 255 - 1; |
388 } | 423 } |
389 } | 424 } |
390 | 425 |
| 426 void SkPDFFont::populateToUnicodeTable(const SkPDFGlyphSet* subset) { |
| 427 if (fFontInfo == nullptr || fFontInfo->fGlyphToUnicode.begin() == nullptr) { |
| 428 return; |
| 429 } |
| 430 this->insertObjRef("ToUnicode", |
| 431 SkPDFMakeToUnicodeCmap(fFontInfo->fGlyphToUnicode, |
| 432 subset, |
| 433 multiByteGlyphs(), |
| 434 firstGlyphID(), |
| 435 lastGlyphID())); |
| 436 } |
| 437 |
391 /////////////////////////////////////////////////////////////////////////////// | 438 /////////////////////////////////////////////////////////////////////////////// |
392 // class SkPDFType0Font | 439 // class SkPDFType0Font |
393 /////////////////////////////////////////////////////////////////////////////// | 440 /////////////////////////////////////////////////////////////////////////////// |
394 | 441 |
395 SkPDFType0Font::SkPDFType0Font(const SkAdvancedTypefaceMetrics* info, | 442 SkPDFType0Font::SkPDFType0Font(sk_sp<const SkAdvancedTypefaceMetrics> info, |
396 sk_sp<SkTypeface> typeface, | 443 sk_sp<SkTypeface> typeface, |
397 SkAdvancedTypefaceMetrics::FontType fontType) | 444 SkAdvancedTypefaceMetrics::FontType fontType) |
398 : SkPDFFont(std::move(typeface), fontType) { | 445 : SkPDFFont(std::move(info), std::move(typeface), nullptr, fontType, true) { |
399 SkDEBUGCODE(fPopulated = false); | 446 SkDEBUGCODE(fPopulated = false); |
400 if (!can_subset(info)) { | 447 if (!canSubset()) { |
401 this->populate(nullptr, *info); | 448 this->populate(nullptr); |
402 } | 449 } |
403 } | 450 } |
404 | 451 |
405 SkPDFType0Font::~SkPDFType0Font() {} | 452 SkPDFType0Font::~SkPDFType0Font() {} |
406 | 453 |
407 sk_sp<SkPDFObject> SkPDFType0Font::getFontSubset(SkPDFCanon* canon, | 454 sk_sp<SkPDFObject> SkPDFType0Font::getFontSubset(const SkPDFGlyphSet* subset) { |
408 const SkPDFGlyphSet* subset) { | 455 if (!canSubset()) { |
409 const SkAdvancedTypefaceMetrics* metrics = | |
410 SkPDFFont::GetMetrics(this->typeface(), canon); | |
411 SkASSERT(metrics); | |
412 if (!can_subset(metrics)) { | |
413 return nullptr; | 456 return nullptr; |
414 } | 457 } |
415 auto newSubset = sk_make_sp<SkPDFType0Font>( | 458 auto newSubset = sk_make_sp<SkPDFType0Font>(refFontInfo(), refTypeface(), ge
tType()); |
416 metrics, this->refTypeface(), this->getType()); | 459 newSubset->populate(subset); |
417 newSubset->populate(subset, *metrics); | |
418 return newSubset; | 460 return newSubset; |
419 } | 461 } |
420 | 462 |
421 #ifdef SK_DEBUG | 463 #ifdef SK_DEBUG |
422 void SkPDFType0Font::emitObject(SkWStream* stream, | 464 void SkPDFType0Font::emitObject(SkWStream* stream, |
423 const SkPDFObjNumMap& objNumMap, | 465 const SkPDFObjNumMap& objNumMap, |
424 const SkPDFSubstituteMap& substitutes) const { | 466 const SkPDFSubstituteMap& substitutes) const { |
425 SkASSERT(fPopulated); | 467 SkASSERT(fPopulated); |
426 return INHERITED::emitObject(stream, objNumMap, substitutes); | 468 return INHERITED::emitObject(stream, objNumMap, substitutes); |
427 } | 469 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 auto subsetStream = sk_make_sp<SkPDFStream>( | 515 auto subsetStream = sk_make_sp<SkPDFStream>( |
474 SkData::MakeWithProc( | 516 SkData::MakeWithProc( |
475 subsetFont, subsetFontSize, | 517 subsetFont, subsetFontSize, |
476 [](const void* p, void*) { delete[] (unsigned char*)p; }, | 518 [](const void* p, void*) { delete[] (unsigned char*)p; }, |
477 nullptr)); | 519 nullptr)); |
478 subsetStream->dict()->insertInt("Length1", subsetFontSize); | 520 subsetStream->dict()->insertInt("Length1", subsetFontSize); |
479 return subsetStream; | 521 return subsetStream; |
480 } | 522 } |
481 #endif // SK_SFNTLY_SUBSETTER | 523 #endif // SK_SFNTLY_SUBSETTER |
482 | 524 |
483 bool SkPDFType0Font::populate(const SkPDFGlyphSet* subset, | 525 bool SkPDFType0Font::populate(const SkPDFGlyphSet* subset) { |
484 const SkAdvancedTypefaceMetrics& metrics) { | 526 SkASSERT(this->canEmbed()); |
485 SkASSERT(can_embed(&metrics)); | 527 SkASSERT(this->getFontInfo()); |
| 528 const SkAdvancedTypefaceMetrics& metrics = *(this->getFontInfo()); |
486 SkAdvancedTypefaceMetrics::FontType type = this->getType(); | 529 SkAdvancedTypefaceMetrics::FontType type = this->getType(); |
487 SkTypeface* face = this->typeface(); | 530 SkTypeface* face = this->typeface(); |
488 SkASSERT(face); | 531 SkASSERT(face); |
489 const SkString& name = metrics.fFontName; | 532 const SkString& name = metrics.fFontName; |
490 | 533 |
491 auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor"); | 534 auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor"); |
492 add_common_font_descriptor_entries(descriptor.get(), metrics, 0); | 535 add_common_font_descriptor_entries(descriptor.get(), metrics, 0); |
493 switch (type) { | 536 switch (type) { |
494 case SkAdvancedTypefaceMetrics::kTrueType_Font: { | 537 case SkAdvancedTypefaceMetrics::kTrueType_Font: { |
495 int ttcIndex; | 538 int ttcIndex; |
496 std::unique_ptr<SkStreamAsset> fontAsset(face->openStream(&ttcIndex)
); | 539 std::unique_ptr<SkStreamAsset> fontAsset(face->openStream(&ttcIndex)
); |
497 SkASSERT(fontAsset); | 540 SkASSERT(fontAsset); |
498 if (!fontAsset) { | 541 if (!fontAsset) { |
499 return false; | 542 return false; |
500 } | 543 } |
501 size_t fontSize = fontAsset->getLength(); | 544 size_t fontSize = fontAsset->getLength(); |
502 SkASSERT(fontSize > 0); | 545 SkASSERT(fontSize > 0); |
503 if (fontSize == 0) { | 546 if (fontSize == 0) { |
504 return false; | 547 return false; |
505 } | 548 } |
506 | 549 |
507 #ifdef SK_SFNTLY_SUBSETTER | 550 #ifdef SK_SFNTLY_SUBSETTER |
508 if (can_subset(&metrics) && subset) { | 551 if (this->canSubset() && subset) { |
509 // Generate glyph id array. in format needed by sfntly | 552 // Generate glyph id array. in format needed by sfntly |
510 SkTDArray<uint32_t> glyphIDs; | 553 SkTDArray<uint32_t> glyphIDs; |
511 if (subset) { | 554 if (subset) { |
512 if (!subset->has(0)) { | 555 if (!subset->has(0)) { |
513 glyphIDs.push(0); // Always include glyph 0. | 556 glyphIDs.push(0); // Always include glyph 0. |
514 } | 557 } |
515 subset->exportTo(&glyphIDs); | 558 subset->exportTo(&glyphIDs); |
516 } | 559 } |
517 sk_sp<SkPDFObject> subsetStream = get_subset_font_stream( | 560 sk_sp<SkPDFObject> subsetStream = get_subset_font_stream( |
518 std::move(fontAsset), glyphIDs, name.c_str()); | 561 std::move(fontAsset), glyphIDs, name.c_str()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 } else { | 600 } else { |
558 SkASSERT(false); | 601 SkASSERT(false); |
559 } | 602 } |
560 | 603 |
561 auto sysInfo = sk_make_sp<SkPDFDict>(); | 604 auto sysInfo = sk_make_sp<SkPDFDict>(); |
562 sysInfo->insertString("Registry", "Adobe"); | 605 sysInfo->insertString("Registry", "Adobe"); |
563 sysInfo->insertString("Ordering", "Identity"); | 606 sysInfo->insertString("Ordering", "Identity"); |
564 sysInfo->insertInt("Supplement", 0); | 607 sysInfo->insertInt("Supplement", 0); |
565 newCIDFont->insertObject("CIDSystemInfo", std::move(sysInfo)); | 608 newCIDFont->insertObject("CIDSystemInfo", std::move(sysInfo)); |
566 | 609 |
567 uint16_t emSize = metrics.fEmSize; | 610 uint16_t emSize = this->getFontInfo()->fEmSize; |
568 int16_t defaultWidth = 0; | 611 int16_t defaultWidth = 0; |
569 const SkBitSet* bitSet = subset ? &subset->bitSet() : nullptr; | 612 const SkBitSet* bitSet = subset ? &subset->bitSet() : nullptr; |
570 { | 613 { |
571 SkAutoGlyphCache glyphCache = vector_cache(face); | 614 SkAutoGlyphCache glyphCache = vector_cache(face); |
572 sk_sp<SkPDFArray> widths = SkPDFMakeCIDGlyphWidthsArray( | 615 sk_sp<SkPDFArray> widths = SkPDFMakeCIDGlyphWidthsArray( |
573 glyphCache.get(), bitSet, emSize, &defaultWidth); | 616 glyphCache.get(), bitSet, emSize, &defaultWidth); |
574 if (widths && widths->size() > 0) { | 617 if (widths && widths->size() > 0) { |
575 newCIDFont->insertObject("W", std::move(widths)); | 618 newCIDFont->insertObject("W", std::move(widths)); |
576 } | 619 } |
577 newCIDFont->insertScalar( | 620 newCIDFont->insertScalar( |
578 "DW", scaleFromFontUnits(defaultWidth, emSize)); | 621 "DW", scaleFromFontUnits(defaultWidth, emSize)); |
579 } | 622 } |
580 | 623 |
581 //////////////////////////////////////////////////////////////////////////// | 624 //////////////////////////////////////////////////////////////////////////// |
582 | 625 |
583 this->insertName("Subtype", "Type0"); | 626 this->insertName("Subtype", "Type0"); |
584 this->insertName("BaseFont", metrics.fFontName); | 627 this->insertName("BaseFont", metrics.fFontName); |
585 this->insertName("Encoding", "Identity-H"); | 628 this->insertName("Encoding", "Identity-H"); |
586 auto descendantFonts = sk_make_sp<SkPDFArray>(); | 629 auto descendantFonts = sk_make_sp<SkPDFArray>(); |
587 descendantFonts->appendObjRef(std::move(newCIDFont)); | 630 descendantFonts->appendObjRef(std::move(newCIDFont)); |
588 this->insertObject("DescendantFonts", std::move(descendantFonts)); | 631 this->insertObject("DescendantFonts", std::move(descendantFonts)); |
589 | 632 this->populateToUnicodeTable(subset); |
590 if (metrics.fGlyphToUnicode.count() > 0) { | |
591 this->insertObjRef("ToUnicode", | |
592 SkPDFMakeToUnicodeCmap(metrics.fGlyphToUnicode, | |
593 subset, | |
594 multiByteGlyphs(), | |
595 firstGlyphID(), | |
596 lastGlyphID())); | |
597 } | |
598 SkDEBUGCODE(fPopulated = true); | 633 SkDEBUGCODE(fPopulated = true); |
599 return true; | 634 return true; |
600 } | 635 } |
601 | 636 |
| 637 sk_sp<const SkAdvancedTypefaceMetrics> SkPDFFont::GetFontMetricsWithToUnicode( |
| 638 SkTypeface* typeface, uint32_t* glyphs, uint32_t glyphsCount) { |
| 639 return sk_sp<const SkAdvancedTypefaceMetrics>( |
| 640 typeface->getAdvancedTypefaceMetrics( |
| 641 SkTypeface::kToUnicode_PerGlyphInfo, glyphs, glyphsCount)); |
| 642 } |
| 643 |
| 644 |
602 /////////////////////////////////////////////////////////////////////////////// | 645 /////////////////////////////////////////////////////////////////////////////// |
603 // class SkPDFType1Font | 646 // class SkPDFType1Font |
604 /////////////////////////////////////////////////////////////////////////////// | 647 /////////////////////////////////////////////////////////////////////////////// |
605 | 648 |
606 static sk_sp<SkPDFDict> make_type1_font_descriptor( | 649 SkPDFType1Font::SkPDFType1Font(sk_sp<const SkAdvancedTypefaceMetrics> info, |
607 SkTypeface* typeface, | 650 sk_sp<SkTypeface> typeface, |
608 const SkAdvancedTypefaceMetrics* info) { | 651 uint16_t glyphID, |
| 652 sk_sp<SkPDFDict> relatedFontDescriptor) |
| 653 : SkPDFFont(std::move(info), |
| 654 std::move(typeface), |
| 655 std::move(relatedFontDescriptor), |
| 656 SkAdvancedTypefaceMetrics::kType1_Font, |
| 657 /* multiByteGlyphs = */ false) { |
| 658 this->populate(glyphID); // TODO(halcanary): subset this. |
| 659 } |
| 660 |
| 661 SkPDFType1Font::~SkPDFType1Font() {} |
| 662 |
| 663 bool SkPDFType1Font::addFontDescriptor(int16_t defaultWidth) { |
| 664 if (sk_sp<SkPDFDict> descriptor = this->refFontDescriptor()) { |
| 665 this->insertObjRef("FontDescriptor", std::move(descriptor)); |
| 666 return true; |
| 667 } |
| 668 |
609 auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor"); | 669 auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor"); |
610 SkASSERT(info); | 670 setFontDescriptor(descriptor); |
611 add_common_font_descriptor_entries(descriptor.get(), *info, 0); | |
612 | 671 |
613 int ttcIndex; | 672 int ttcIndex; |
614 size_t header SK_INIT_TO_AVOID_WARNING; | 673 size_t header SK_INIT_TO_AVOID_WARNING; |
615 size_t data SK_INIT_TO_AVOID_WARNING; | 674 size_t data SK_INIT_TO_AVOID_WARNING; |
616 size_t trailer SK_INIT_TO_AVOID_WARNING; | 675 size_t trailer SK_INIT_TO_AVOID_WARNING; |
617 std::unique_ptr<SkStreamAsset> rawFontData(typeface->openStream(&ttcIndex)); | 676 std::unique_ptr<SkStreamAsset> rawFontData(typeface()->openStream(&ttcIndex)
); |
618 sk_sp<SkData> fontData = SkPDFConvertType1FontStream(std::move(rawFontData), | 677 sk_sp<SkData> fontData = SkPDFConvertType1FontStream(std::move(rawFontData), |
619 &header, &data, &traile
r); | 678 &header, &data, &traile
r); |
620 if (fontData && can_embed(info)) { | 679 if (!fontData) { |
621 auto fontStream = sk_make_sp<SkPDFStream>(std::move(fontData)); | 680 return false; |
622 fontStream->dict()->insertInt("Length1", header); | |
623 fontStream->dict()->insertInt("Length2", data); | |
624 fontStream->dict()->insertInt("Length3", trailer); | |
625 descriptor->insertObjRef("FontFile", std::move(fontStream)); | |
626 } | 681 } |
627 return descriptor; | 682 SkASSERT(this->canEmbed()); |
| 683 auto fontStream = sk_make_sp<SkPDFStream>(std::move(fontData)); |
| 684 fontStream->dict()->insertInt("Length1", header); |
| 685 fontStream->dict()->insertInt("Length2", data); |
| 686 fontStream->dict()->insertInt("Length3", trailer); |
| 687 descriptor->insertObjRef("FontFile", std::move(fontStream)); |
| 688 |
| 689 SkASSERT(this->getFontInfo()); |
| 690 add_common_font_descriptor_entries(descriptor.get(), |
| 691 *this->getFontInfo(), |
| 692 defaultWidth); |
| 693 this->insertObjRef("FontDescriptor", std::move(descriptor)); |
| 694 return true; |
628 } | 695 } |
629 | 696 |
630 static void populate_type_1_font(SkPDFDict* font, | 697 bool SkPDFType1Font::populate(int16_t glyphID) { |
631 const SkAdvancedTypefaceMetrics* info, | 698 this->insertName("Subtype", "Type1"); |
632 SkTypeface* typeface, | 699 this->insertName("BaseFont", this->getFontInfo()->fFontName); |
633 SkGlyphID firstGlyphID, | 700 adjustGlyphRangeForSingleByteEncoding(glyphID); |
634 SkGlyphID lastGlyphID) { | 701 SkGlyphID firstGlyphID = this->firstGlyphID(); |
635 SkASSERT(info); | 702 SkGlyphID lastGlyphID = this->lastGlyphID(); |
636 font->insertName("Subtype", "Type1"); | |
637 font->insertName("BaseFont", info->fFontName); | |
638 | 703 |
639 // glyphCount not including glyph 0 | 704 // glyphCount not including glyph 0 |
640 unsigned glyphCount = 1 + lastGlyphID - firstGlyphID; | 705 unsigned glyphCount = 1 + lastGlyphID - firstGlyphID; |
641 SkASSERT(glyphCount > 0 && glyphCount <= 255); | 706 SkASSERT(glyphCount > 0 && glyphCount <= 255); |
642 font->insertInt("FirstChar", (size_t)0); | 707 this->insertInt("FirstChar", (size_t)0); |
643 font->insertInt("LastChar", (size_t)glyphCount); | 708 this->insertInt("LastChar", (size_t)glyphCount); |
644 { | 709 { |
645 SkAutoGlyphCache glyphCache = vector_cache(typeface); | 710 SkAutoGlyphCache glyphCache = vector_cache(this->typeface()); |
646 auto widths = sk_make_sp<SkPDFArray>(); | 711 auto widths = sk_make_sp<SkPDFArray>(); |
647 SkScalar advance = glyphCache->getGlyphIDAdvance(0).fAdvanceX; | 712 SkScalar advance = glyphCache->getGlyphIDAdvance(0).fAdvanceX; |
648 const uint16_t emSize = info->fEmSize; | 713 const uint16_t emSize = this->getFontInfo()->fEmSize; |
649 widths->appendScalar(from_font_units(advance, emSize)); | 714 widths->appendScalar(from_font_units(advance, emSize)); |
650 for (unsigned gID = firstGlyphID; gID <= lastGlyphID; gID++) { | 715 for (unsigned gID = firstGlyphID; gID <= lastGlyphID; gID++) { |
651 advance = glyphCache->getGlyphIDAdvance(gID).fAdvanceX; | 716 advance = glyphCache->getGlyphIDAdvance(gID).fAdvanceX; |
652 widths->appendScalar(from_font_units(advance, emSize)); | 717 widths->appendScalar(from_font_units(advance, emSize)); |
653 } | 718 } |
654 font->insertObject("Widths", std::move(widths)); | 719 this->insertObject("Widths", std::move(widths)); |
| 720 } |
| 721 if (!addFontDescriptor(0)) { |
| 722 return false; |
655 } | 723 } |
656 auto encDiffs = sk_make_sp<SkPDFArray>(); | 724 auto encDiffs = sk_make_sp<SkPDFArray>(); |
657 encDiffs->reserve(lastGlyphID - firstGlyphID + 3); | 725 encDiffs->reserve(lastGlyphID - firstGlyphID + 3); |
658 encDiffs->appendInt(0); | 726 encDiffs->appendInt(0); |
659 const SkTArray<SkString>& glyphNames = info->fGlyphNames; | 727 const SkTArray<SkString>& glyphNames = this->getFontInfo()->fGlyphNames; |
660 SkASSERT(glyphNames.count() > lastGlyphID); | 728 SkASSERT(glyphNames.count() > lastGlyphID); |
661 encDiffs->appendName(glyphNames[0].c_str()); | 729 encDiffs->appendName(glyphNames[0].c_str()); |
662 const SkString unknown("UNKNOWN"); | 730 const SkString unknown("UNKNOWN"); |
663 for (int gID = firstGlyphID; gID <= lastGlyphID; gID++) { | 731 for (int gID = firstGlyphID; gID <= lastGlyphID; gID++) { |
664 const bool valid = gID < glyphNames.count() && !glyphNames[gID].isEmpty(
); | 732 const bool valid = gID < glyphNames.count() && !glyphNames[gID].isEmpty(
); |
665 const SkString& name = valid ? glyphNames[gID] : unknown; | 733 const SkString& name = valid ? glyphNames[gID] : unknown; |
666 encDiffs->appendName(name); | 734 encDiffs->appendName(name); |
667 } | 735 } |
668 | 736 |
669 auto encoding = sk_make_sp<SkPDFDict>("Encoding"); | 737 auto encoding = sk_make_sp<SkPDFDict>("Encoding"); |
670 encoding->insertObject("Differences", std::move(encDiffs)); | 738 encoding->insertObject("Differences", std::move(encDiffs)); |
671 font->insertObject("Encoding", std::move(encoding)); | 739 this->insertObject("Encoding", std::move(encoding)); |
672 } | 740 return true; |
673 | |
674 SkPDFType1Font::SkPDFType1Font(const SkAdvancedTypefaceMetrics* info, | |
675 sk_sp<SkTypeface> typeface, | |
676 uint16_t glyphID, | |
677 SkPDFCanon* canon) | |
678 : SkPDFFont(std::move(typeface), SkAdvancedTypefaceMetrics::kType1_Font) | |
679 { | |
680 SkFontID fontID = this->typeface()->uniqueID(); | |
681 sk_sp<SkPDFDict> fontDescriptor; | |
682 if (SkPDFDict** ptr = canon->fFontDescriptors.find(fontID)) { | |
683 fontDescriptor = sk_ref_sp(*ptr); | |
684 } else { | |
685 fontDescriptor = make_type1_font_descriptor(this->typeface(), info); | |
686 canon->fFontDescriptors.set(fontID, SkRef(fontDescriptor.get())); | |
687 } | |
688 this->insertObjRef("FontDescriptor", std::move(fontDescriptor)); | |
689 this->adjustGlyphRangeForSingleByteEncoding(glyphID); | |
690 // TODO(halcanary): subset this (advances and names). | |
691 populate_type_1_font(this, info, this->typeface(), | |
692 this->firstGlyphID(), this->lastGlyphID()); | |
693 } | 741 } |
694 | 742 |
695 /////////////////////////////////////////////////////////////////////////////// | 743 /////////////////////////////////////////////////////////////////////////////// |
696 // class SkPDFType3Font | 744 // class SkPDFType3Font |
697 /////////////////////////////////////////////////////////////////////////////// | 745 /////////////////////////////////////////////////////////////////////////////// |
698 | 746 |
699 namespace { | 747 namespace { |
700 // returns [0, first, first+1, ... last-1, last] | 748 // returns [0, first, first+1, ... last-1, last] |
701 struct SingleByteGlyphIdIterator { | 749 struct SingleByteGlyphIdIterator { |
702 SingleByteGlyphIdIterator(SkGlyphID first, SkGlyphID last) | 750 SingleByteGlyphIdIterator(SkGlyphID first, SkGlyphID last) |
(...skipping 16 matching lines...) Expand all Loading... |
719 int fCurrent; // must be int to make fLast+1 to fit | 767 int fCurrent; // must be int to make fLast+1 to fit |
720 }; | 768 }; |
721 Iter begin() const { return Iter(fFirst, 0); } | 769 Iter begin() const { return Iter(fFirst, 0); } |
722 Iter end() const { return Iter(fFirst, (int)fLast + 1); } | 770 Iter end() const { return Iter(fFirst, (int)fLast + 1); } |
723 private: | 771 private: |
724 const SkGlyphID fFirst; | 772 const SkGlyphID fFirst; |
725 const SkGlyphID fLast; | 773 const SkGlyphID fLast; |
726 }; | 774 }; |
727 } | 775 } |
728 | 776 |
729 static void add_type3_font_info(SkPDFCanon* canon, | 777 static void add_type3_font_info(SkPDFDict* font, |
730 SkPDFDict* font, | |
731 SkTypeface* typeface, | 778 SkTypeface* typeface, |
732 SkScalar emSize, | 779 SkScalar emSize, |
733 const SkPDFGlyphSet* subset, | 780 const SkPDFGlyphSet* subset, |
734 SkGlyphID firstGlyphID, | 781 SkGlyphID firstGlyphID, |
735 SkGlyphID lastGlyphID) { | 782 SkGlyphID lastGlyphID) { |
736 SkASSERT(lastGlyphID >= firstGlyphID); | 783 SkASSERT(lastGlyphID >= firstGlyphID); |
737 SkASSERT(emSize > 0.0f); | 784 SkASSERT(emSize > 0.0f); |
738 SkAutoGlyphCache cache = vector_cache(typeface, emSize); | 785 SkAutoGlyphCache cache = vector_cache(typeface, emSize); |
739 font->insertName("Subtype", "Type3"); | 786 font->insertName("Subtype", "Type3"); |
740 // Flip about the x-axis and scale by 1/emSize. | 787 // Flip about the x-axis and scale by 1/emSize. |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 glyphs of the font were placed with their origins coincident and | 855 glyphs of the font were placed with their origins coincident and |
809 then filled." */ | 856 then filled." */ |
810 auto fontBBox = sk_make_sp<SkPDFArray>(); | 857 auto fontBBox = sk_make_sp<SkPDFArray>(); |
811 fontBBox->reserve(4); | 858 fontBBox->reserve(4); |
812 fontBBox->appendInt(bbox.left()); | 859 fontBBox->appendInt(bbox.left()); |
813 fontBBox->appendInt(bbox.bottom()); | 860 fontBBox->appendInt(bbox.bottom()); |
814 fontBBox->appendInt(bbox.right()); | 861 fontBBox->appendInt(bbox.right()); |
815 fontBBox->appendInt(bbox.top()); | 862 fontBBox->appendInt(bbox.top()); |
816 font->insertObject("FontBBox", std::move(fontBBox)); | 863 font->insertObject("FontBBox", std::move(fontBBox)); |
817 font->insertName("CIDToGIDMap", "Identity"); | 864 font->insertName("CIDToGIDMap", "Identity"); |
818 const SkAdvancedTypefaceMetrics* metrics = SkPDFFont::GetMetrics(typeface, c
anon); | 865 sk_sp<const SkAdvancedTypefaceMetrics> metrics; |
819 if (metrics /* && metrics->fGlyphToUnicode.count() > 0 */) { | 866 if (subset) { |
| 867 SkTDArray<uint32_t> subsetList; |
| 868 for (SkGlyphID gID : SingleByteGlyphIdIterator(firstGlyphID, lastGlyphID
)) { |
| 869 if (gID == 0 || subset->has(gID)) { // Always include glyph 0. |
| 870 subsetList.push(0); |
| 871 } |
| 872 } |
| 873 subset->exportTo(&subsetList); |
| 874 metrics = SkPDFFont::GetFontMetricsWithToUnicode(typeface, subsetList.be
gin(), |
| 875 subsetList.count()); |
| 876 } else { |
| 877 metrics = SkPDFFont::GetFontMetricsWithToUnicode(typeface, nullptr, 0); |
| 878 } |
| 879 if (metrics) { |
820 font->insertObjRef("ToUnicode", | 880 font->insertObjRef("ToUnicode", |
821 SkPDFMakeToUnicodeCmap(metrics->fGlyphToUnicode, | 881 SkPDFMakeToUnicodeCmap(metrics->fGlyphToUnicode, |
822 subset, | 882 subset, |
823 false, | 883 false, |
824 firstGlyphID, | 884 firstGlyphID, |
825 lastGlyphID)); | 885 lastGlyphID)); |
826 } | 886 } |
827 font->insertObject("Widths", std::move(widthArray)); | 887 font->insertObject("Widths", std::move(widthArray)); |
828 font->insertObject("Encoding", std::move(encoding)); | 888 font->insertObject("Encoding", std::move(encoding)); |
829 font->insertObject("CharProcs", std::move(charProcs)); | 889 font->insertObject("CharProcs", std::move(charProcs)); |
830 } | 890 } |
831 | 891 |
832 SkPDFType3Font::SkPDFType3Font(const SkAdvancedTypefaceMetrics* info, | 892 SkPDFType3Font::SkPDFType3Font(sk_sp<const SkAdvancedTypefaceMetrics> info, |
833 sk_sp<SkTypeface> typeface, | 893 sk_sp<SkTypeface> typeface, |
834 SkAdvancedTypefaceMetrics::FontType fontType, | 894 SkAdvancedTypefaceMetrics::FontType fontType, |
835 uint16_t glyphID) | 895 uint16_t glyphID) |
836 : SkPDFFont(std::move(typeface), fontType) { | 896 : SkPDFFont(std::move(info), std::move(typeface), nullptr, |
| 897 fontType, /* multiByteGlyphs = */ false) { |
| 898 // If fLastGlyphID isn't set (because there is not fFontInfo), look it up. |
| 899 this->setLastGlyphID(SkToU16(this->typeface()->countGlyphs() - 1)); |
837 this->adjustGlyphRangeForSingleByteEncoding(glyphID); | 900 this->adjustGlyphRangeForSingleByteEncoding(glyphID); |
838 } | 901 } |
839 | 902 |
840 sk_sp<SkPDFObject> SkPDFType3Font::getFontSubset(SkPDFCanon* canon, | 903 sk_sp<SkPDFObject> SkPDFType3Font::getFontSubset(const SkPDFGlyphSet* usage) { |
841 const SkPDFGlyphSet* usage) { | |
842 // All fonts are subset before serialization. | 904 // All fonts are subset before serialization. |
843 // TODO(halcanary): all fonts should follow this pattern. | 905 // TODO(halcanary): all fonts should follow this pattern. |
844 const SkAdvancedTypefaceMetrics* info = | 906 auto font = sk_make_sp<SkPDFDict>("Font"); |
845 SkPDFFont::GetMetrics(this->typeface(), canon); | 907 const SkAdvancedTypefaceMetrics* info = this->getFontInfo(); |
846 uint16_t emSize = info && info->fEmSize > 0 ? info->fEmSize : 1000; | 908 uint16_t emSize = info && info->fEmSize > 0 ? info->fEmSize : 1000; |
847 auto font = sk_make_sp<SkPDFDict>("Font"); | 909 add_type3_font_info(font.get(), this->typeface(), (SkScalar)emSize, usage, |
848 add_type3_font_info(canon, font.get(), this->typeface(), (SkScalar)emSize, u
sage, | |
849 this->firstGlyphID(), this->lastGlyphID()); | 910 this->firstGlyphID(), this->lastGlyphID()); |
850 return font; | 911 return font; |
851 } | 912 } |
852 | 913 |
853 | 914 |
854 //////////////////////////////////////////////////////////////////////////////// | 915 //////////////////////////////////////////////////////////////////////////////// |
855 | 916 |
| 917 SkPDFFont::Match SkPDFFont::IsMatch(SkPDFFont* existingFont, |
| 918 uint32_t existingFontID, |
| 919 uint16_t existingGlyphID, |
| 920 uint32_t searchFontID, |
| 921 uint16_t searchGlyphID) { |
| 922 if (existingFontID != searchFontID) { |
| 923 return SkPDFFont::kNot_Match; |
| 924 } |
| 925 if (existingGlyphID == 0 || searchGlyphID == 0) { |
| 926 return SkPDFFont::kExact_Match; |
| 927 } |
| 928 if (existingFont != nullptr) { |
| 929 return (existingFont->fFirstGlyphID <= searchGlyphID && |
| 930 searchGlyphID <= existingFont->fLastGlyphID) |
| 931 ? SkPDFFont::kExact_Match |
| 932 : SkPDFFont::kRelated_Match; |
| 933 } |
| 934 return (existingGlyphID == searchGlyphID) ? SkPDFFont::kExact_Match |
| 935 : SkPDFFont::kRelated_Match; |
| 936 } |
| 937 |
| 938 // Since getAdvancedTypefaceMetrics is expensive, cache the result. |
856 bool SkPDFFont::CanEmbedTypeface(SkTypeface* typeface, SkPDFCanon* canon) { | 939 bool SkPDFFont::CanEmbedTypeface(SkTypeface* typeface, SkPDFCanon* canon) { |
857 return can_embed(SkPDFFont::GetMetrics(typeface, canon)); | 940 SkFontID id = SkTypeface::UniqueID(typeface); |
| 941 if (bool* value = canon->fCanEmbedTypeface.find(id)) { |
| 942 return *value; |
| 943 } |
| 944 SkAutoResolveDefaultTypeface face(typeface); |
| 945 bool canEmbed = true; |
| 946 sk_sp<const SkAdvancedTypefaceMetrics> fontMetrics( |
| 947 face->getAdvancedTypefaceMetrics( |
| 948 SkTypeface::kNo_PerGlyphInfo, nullptr, 0)); |
| 949 if (fontMetrics) { |
| 950 canEmbed = !SkToBool( |
| 951 fontMetrics->fFlags & |
| 952 SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag); |
| 953 } |
| 954 return *canon->fCanEmbedTypeface.set(id, canEmbed); |
858 } | 955 } |
859 | 956 |
860 void SkPDFFont::drop() { | 957 void SkPDFFont::drop() { |
861 fTypeface = nullptr; | 958 fTypeface = nullptr; |
| 959 fFontInfo = nullptr; |
| 960 fDescriptor = nullptr; |
862 this->SkPDFDict::drop(); | 961 this->SkPDFDict::drop(); |
863 } | 962 } |
OLD | NEW |