Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/pdf/SkPDFFont.cpp

Issue 2251813006: Revert of SkPDF: cache metrics once. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pdf/SkPDFFont.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « src/pdf/SkPDFFont.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698