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

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

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