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

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: metrics can be null 2016-08-18 (Thursday) 10:59:37 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 nu ll.");
bungeman-skia 2016/08/18 15:17:28 This should be SkDEBUGF so we're not spewing this
hal.canary 2016/08/18 15:37:35 Done.
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) { return nullptr; }
421 if (!can_subset(*metrics)) {
bungeman-skia 2016/08/18 15:17:28 if (!metrics || !can_subset(*metrics)) { or (to m
hal.canary 2016/08/18 15:37:35 Done.
456 return nullptr; 422 return nullptr;
457 } 423 }
458 auto newSubset = sk_make_sp<SkPDFType0Font>(refFontInfo(), refTypeface(), ge tType()); 424 auto newSubset = sk_make_sp<SkPDFType0Font>(
459 newSubset->populate(subset); 425 *metrics, this->refTypeface(), this->getType());
426 newSubset->populate(subset, *metrics);
460 return newSubset; 427 return newSubset;
461 } 428 }
462 429
463 #ifdef SK_DEBUG 430 #ifdef SK_DEBUG
464 void SkPDFType0Font::emitObject(SkWStream* stream, 431 void SkPDFType0Font::emitObject(SkWStream* stream,
465 const SkPDFObjNumMap& objNumMap, 432 const SkPDFObjNumMap& objNumMap,
466 const SkPDFSubstituteMap& substitutes) const { 433 const SkPDFSubstituteMap& substitutes) const {
467 SkASSERT(fPopulated); 434 SkASSERT(fPopulated);
468 return INHERITED::emitObject(stream, objNumMap, substitutes); 435 return INHERITED::emitObject(stream, objNumMap, substitutes);
469 } 436 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 auto subsetStream = sk_make_sp<SkPDFStream>( 482 auto subsetStream = sk_make_sp<SkPDFStream>(
516 SkData::MakeWithProc( 483 SkData::MakeWithProc(
517 subsetFont, subsetFontSize, 484 subsetFont, subsetFontSize,
518 [](const void* p, void*) { delete[] (unsigned char*)p; }, 485 [](const void* p, void*) { delete[] (unsigned char*)p; },
519 nullptr)); 486 nullptr));
520 subsetStream->dict()->insertInt("Length1", subsetFontSize); 487 subsetStream->dict()->insertInt("Length1", subsetFontSize);
521 return subsetStream; 488 return subsetStream;
522 } 489 }
523 #endif // SK_SFNTLY_SUBSETTER 490 #endif // SK_SFNTLY_SUBSETTER
524 491
525 bool SkPDFType0Font::populate(const SkPDFGlyphSet* subset) { 492 bool SkPDFType0Font::populate(const SkPDFGlyphSet* subset,
526 SkASSERT(this->canEmbed()); 493 const SkAdvancedTypefaceMetrics& metrics) {
527 SkASSERT(this->getFontInfo()); 494 SkASSERT(can_embed(metrics));
528 const SkAdvancedTypefaceMetrics& metrics = *(this->getFontInfo());
529 SkAdvancedTypefaceMetrics::FontType type = this->getType(); 495 SkAdvancedTypefaceMetrics::FontType type = this->getType();
530 SkTypeface* face = this->typeface(); 496 SkTypeface* face = this->typeface();
531 SkASSERT(face); 497 SkASSERT(face);
532 const SkString& name = metrics.fFontName; 498 const SkString& name = metrics.fFontName;
533 499
534 auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor"); 500 auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor");
535 add_common_font_descriptor_entries(descriptor.get(), metrics, 0); 501 add_common_font_descriptor_entries(descriptor.get(), metrics, 0);
536 switch (type) { 502 switch (type) {
537 case SkAdvancedTypefaceMetrics::kTrueType_Font: { 503 case SkAdvancedTypefaceMetrics::kTrueType_Font: {
538 int ttcIndex; 504 int ttcIndex;
539 std::unique_ptr<SkStreamAsset> fontAsset(face->openStream(&ttcIndex) ); 505 std::unique_ptr<SkStreamAsset> fontAsset(face->openStream(&ttcIndex) );
540 SkASSERT(fontAsset); 506 SkASSERT(fontAsset);
541 if (!fontAsset) { 507 if (!fontAsset) {
542 return false; 508 return false;
543 } 509 }
544 size_t fontSize = fontAsset->getLength(); 510 size_t fontSize = fontAsset->getLength();
545 SkASSERT(fontSize > 0); 511 SkASSERT(fontSize > 0);
546 if (fontSize == 0) { 512 if (fontSize == 0) {
547 return false; 513 return false;
548 } 514 }
549 515
550 #ifdef SK_SFNTLY_SUBSETTER 516 #ifdef SK_SFNTLY_SUBSETTER
551 if (this->canSubset() && subset) { 517 if (can_subset(metrics) && subset) {
552 // Generate glyph id array. in format needed by sfntly 518 // Generate glyph id array. in format needed by sfntly
553 SkTDArray<uint32_t> glyphIDs; 519 SkTDArray<uint32_t> glyphIDs;
554 if (subset) { 520 if (subset) {
555 if (!subset->has(0)) { 521 if (!subset->has(0)) {
556 glyphIDs.push(0); // Always include glyph 0. 522 glyphIDs.push(0); // Always include glyph 0.
557 } 523 }
558 subset->exportTo(&glyphIDs); 524 subset->exportTo(&glyphIDs);
559 } 525 }
560 sk_sp<SkPDFObject> subsetStream = get_subset_font_stream( 526 sk_sp<SkPDFObject> subsetStream = get_subset_font_stream(
561 std::move(fontAsset), glyphIDs, name.c_str()); 527 std::move(fontAsset), glyphIDs, name.c_str());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 } else { 566 } else {
601 SkASSERT(false); 567 SkASSERT(false);
602 } 568 }
603 569
604 auto sysInfo = sk_make_sp<SkPDFDict>(); 570 auto sysInfo = sk_make_sp<SkPDFDict>();
605 sysInfo->insertString("Registry", "Adobe"); 571 sysInfo->insertString("Registry", "Adobe");
606 sysInfo->insertString("Ordering", "Identity"); 572 sysInfo->insertString("Ordering", "Identity");
607 sysInfo->insertInt("Supplement", 0); 573 sysInfo->insertInt("Supplement", 0);
608 newCIDFont->insertObject("CIDSystemInfo", std::move(sysInfo)); 574 newCIDFont->insertObject("CIDSystemInfo", std::move(sysInfo));
609 575
610 uint16_t emSize = this->getFontInfo()->fEmSize; 576 uint16_t emSize = metrics.fEmSize;
611 int16_t defaultWidth = 0; 577 int16_t defaultWidth = 0;
612 const SkBitSet* bitSet = subset ? &subset->bitSet() : nullptr; 578 const SkBitSet* bitSet = subset ? &subset->bitSet() : nullptr;
613 { 579 {
614 SkAutoGlyphCache glyphCache = vector_cache(face); 580 SkAutoGlyphCache glyphCache = vector_cache(face);
615 sk_sp<SkPDFArray> widths = SkPDFMakeCIDGlyphWidthsArray( 581 sk_sp<SkPDFArray> widths = SkPDFMakeCIDGlyphWidthsArray(
616 glyphCache.get(), bitSet, emSize, &defaultWidth); 582 glyphCache.get(), bitSet, emSize, &defaultWidth);
617 if (widths && widths->size() > 0) { 583 if (widths && widths->size() > 0) {
618 newCIDFont->insertObject("W", std::move(widths)); 584 newCIDFont->insertObject("W", std::move(widths));
619 } 585 }
620 newCIDFont->insertScalar( 586 newCIDFont->insertScalar(
621 "DW", scaleFromFontUnits(defaultWidth, emSize)); 587 "DW", scaleFromFontUnits(defaultWidth, emSize));
622 } 588 }
623 589
624 //////////////////////////////////////////////////////////////////////////// 590 ////////////////////////////////////////////////////////////////////////////
625 591
626 this->insertName("Subtype", "Type0"); 592 this->insertName("Subtype", "Type0");
627 this->insertName("BaseFont", metrics.fFontName); 593 this->insertName("BaseFont", metrics.fFontName);
628 this->insertName("Encoding", "Identity-H"); 594 this->insertName("Encoding", "Identity-H");
629 auto descendantFonts = sk_make_sp<SkPDFArray>(); 595 auto descendantFonts = sk_make_sp<SkPDFArray>();
630 descendantFonts->appendObjRef(std::move(newCIDFont)); 596 descendantFonts->appendObjRef(std::move(newCIDFont));
631 this->insertObject("DescendantFonts", std::move(descendantFonts)); 597 this->insertObject("DescendantFonts", std::move(descendantFonts));
632 this->populateToUnicodeTable(subset); 598
599 if (metrics.fGlyphToUnicode.count() > 0) {
600 this->insertObjRef("ToUnicode",
601 SkPDFMakeToUnicodeCmap(metrics.fGlyphToUnicode,
602 subset,
603 multiByteGlyphs(),
604 firstGlyphID(),
605 lastGlyphID()));
606 }
633 SkDEBUGCODE(fPopulated = true); 607 SkDEBUGCODE(fPopulated = true);
634 return true; 608 return true;
635 } 609 }
636 610
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 /////////////////////////////////////////////////////////////////////////////// 611 ///////////////////////////////////////////////////////////////////////////////
646 // class SkPDFType1Font 612 // class SkPDFType1Font
647 /////////////////////////////////////////////////////////////////////////////// 613 ///////////////////////////////////////////////////////////////////////////////
648 614
649 SkPDFType1Font::SkPDFType1Font(sk_sp<const SkAdvancedTypefaceMetrics> info, 615 static sk_sp<SkPDFDict> make_type1_font_descriptor(
650 sk_sp<SkTypeface> typeface, 616 SkTypeface* typeface,
651 uint16_t glyphID, 617 const SkAdvancedTypefaceMetrics& info) {
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
669 auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor"); 618 auto descriptor = sk_make_sp<SkPDFDict>("FontDescriptor");
670 setFontDescriptor(descriptor); 619 add_common_font_descriptor_entries(descriptor.get(), info, 0);
671 620
672 int ttcIndex; 621 int ttcIndex;
673 size_t header SK_INIT_TO_AVOID_WARNING; 622 size_t header SK_INIT_TO_AVOID_WARNING;
674 size_t data SK_INIT_TO_AVOID_WARNING; 623 size_t data SK_INIT_TO_AVOID_WARNING;
675 size_t trailer SK_INIT_TO_AVOID_WARNING; 624 size_t trailer SK_INIT_TO_AVOID_WARNING;
676 std::unique_ptr<SkStreamAsset> rawFontData(typeface()->openStream(&ttcIndex) ); 625 std::unique_ptr<SkStreamAsset> rawFontData(typeface->openStream(&ttcIndex));
677 sk_sp<SkData> fontData = SkPDFConvertType1FontStream(std::move(rawFontData), 626 sk_sp<SkData> fontData = SkPDFConvertType1FontStream(std::move(rawFontData),
678 &header, &data, &traile r); 627 &header, &data, &traile r);
679 if (!fontData) { 628 if (fontData && can_embed(info)) {
680 return false; 629 auto fontStream = sk_make_sp<SkPDFStream>(std::move(fontData));
630 fontStream->dict()->insertInt("Length1", header);
631 fontStream->dict()->insertInt("Length2", data);
632 fontStream->dict()->insertInt("Length3", trailer);
633 descriptor->insertObjRef("FontFile", std::move(fontStream));
681 } 634 }
682 SkASSERT(this->canEmbed()); 635 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 } 636 }
696 637
697 bool SkPDFType1Font::populate(int16_t glyphID) { 638 static void populate_type_1_font(SkPDFDict* font,
698 this->insertName("Subtype", "Type1"); 639 const SkAdvancedTypefaceMetrics& info,
699 this->insertName("BaseFont", this->getFontInfo()->fFontName); 640 SkTypeface* typeface,
700 adjustGlyphRangeForSingleByteEncoding(glyphID); 641 SkGlyphID firstGlyphID,
701 SkGlyphID firstGlyphID = this->firstGlyphID(); 642 SkGlyphID lastGlyphID) {
702 SkGlyphID lastGlyphID = this->lastGlyphID(); 643 font->insertName("Subtype", "Type1");
644 font->insertName("BaseFont", info.fFontName);
703 645
704 // glyphCount not including glyph 0 646 // glyphCount not including glyph 0
705 unsigned glyphCount = 1 + lastGlyphID - firstGlyphID; 647 unsigned glyphCount = 1 + lastGlyphID - firstGlyphID;
706 SkASSERT(glyphCount > 0 && glyphCount <= 255); 648 SkASSERT(glyphCount > 0 && glyphCount <= 255);
707 this->insertInt("FirstChar", (size_t)0); 649 font->insertInt("FirstChar", (size_t)0);
708 this->insertInt("LastChar", (size_t)glyphCount); 650 font->insertInt("LastChar", (size_t)glyphCount);
709 { 651 {
710 SkAutoGlyphCache glyphCache = vector_cache(this->typeface()); 652 SkAutoGlyphCache glyphCache = vector_cache(typeface);
711 auto widths = sk_make_sp<SkPDFArray>(); 653 auto widths = sk_make_sp<SkPDFArray>();
712 SkScalar advance = glyphCache->getGlyphIDAdvance(0).fAdvanceX; 654 SkScalar advance = glyphCache->getGlyphIDAdvance(0).fAdvanceX;
713 const uint16_t emSize = this->getFontInfo()->fEmSize; 655 const uint16_t emSize = info.fEmSize;
714 widths->appendScalar(from_font_units(advance, emSize)); 656 widths->appendScalar(from_font_units(advance, emSize));
715 for (unsigned gID = firstGlyphID; gID <= lastGlyphID; gID++) { 657 for (unsigned gID = firstGlyphID; gID <= lastGlyphID; gID++) {
716 advance = glyphCache->getGlyphIDAdvance(gID).fAdvanceX; 658 advance = glyphCache->getGlyphIDAdvance(gID).fAdvanceX;
717 widths->appendScalar(from_font_units(advance, emSize)); 659 widths->appendScalar(from_font_units(advance, emSize));
718 } 660 }
719 this->insertObject("Widths", std::move(widths)); 661 font->insertObject("Widths", std::move(widths));
720 }
721 if (!addFontDescriptor(0)) {
722 return false;
723 } 662 }
724 auto encDiffs = sk_make_sp<SkPDFArray>(); 663 auto encDiffs = sk_make_sp<SkPDFArray>();
725 encDiffs->reserve(lastGlyphID - firstGlyphID + 3); 664 encDiffs->reserve(lastGlyphID - firstGlyphID + 3);
726 encDiffs->appendInt(0); 665 encDiffs->appendInt(0);
727 const SkTArray<SkString>& glyphNames = this->getFontInfo()->fGlyphNames; 666 const SkTArray<SkString>& glyphNames = info.fGlyphNames;
728 SkASSERT(glyphNames.count() > lastGlyphID); 667 SkASSERT(glyphNames.count() > lastGlyphID);
729 encDiffs->appendName(glyphNames[0].c_str()); 668 encDiffs->appendName(glyphNames[0].c_str());
730 const SkString unknown("UNKNOWN"); 669 const SkString unknown("UNKNOWN");
731 for (int gID = firstGlyphID; gID <= lastGlyphID; gID++) { 670 for (int gID = firstGlyphID; gID <= lastGlyphID; gID++) {
732 const bool valid = gID < glyphNames.count() && !glyphNames[gID].isEmpty( ); 671 const bool valid = gID < glyphNames.count() && !glyphNames[gID].isEmpty( );
733 const SkString& name = valid ? glyphNames[gID] : unknown; 672 const SkString& name = valid ? glyphNames[gID] : unknown;
734 encDiffs->appendName(name); 673 encDiffs->appendName(name);
735 } 674 }
736 675
737 auto encoding = sk_make_sp<SkPDFDict>("Encoding"); 676 auto encoding = sk_make_sp<SkPDFDict>("Encoding");
738 encoding->insertObject("Differences", std::move(encDiffs)); 677 encoding->insertObject("Differences", std::move(encDiffs));
739 this->insertObject("Encoding", std::move(encoding)); 678 font->insertObject("Encoding", std::move(encoding));
740 return true; 679 }
680
681 SkPDFType1Font::SkPDFType1Font(const SkAdvancedTypefaceMetrics& info,
682 sk_sp<SkTypeface> typeface,
683 uint16_t glyphID,
684 SkPDFCanon* canon)
685 : SkPDFFont(std::move(typeface), SkAdvancedTypefaceMetrics::kType1_Font)
686 {
687 SkFontID fontID = this->typeface()->uniqueID();
688 sk_sp<SkPDFDict> fontDescriptor;
689 if (SkPDFDict** ptr = canon->fFontDescriptors.find(fontID)) {
690 fontDescriptor = sk_ref_sp(*ptr);
691 } else {
692 fontDescriptor = make_type1_font_descriptor(this->typeface(), info);
693 canon->fFontDescriptors.set(fontID, SkRef(fontDescriptor.get()));
694 }
695 this->insertObjRef("FontDescriptor", std::move(fontDescriptor));
696 this->adjustGlyphRangeForSingleByteEncoding(glyphID);
697 // TODO(halcanary): subset this (advances and names).
698 populate_type_1_font(this, info, this->typeface(),
699 this->firstGlyphID(), this->lastGlyphID());
741 } 700 }
742 701
743 /////////////////////////////////////////////////////////////////////////////// 702 ///////////////////////////////////////////////////////////////////////////////
744 // class SkPDFType3Font 703 // class SkPDFType3Font
745 /////////////////////////////////////////////////////////////////////////////// 704 ///////////////////////////////////////////////////////////////////////////////
746 705
747 namespace { 706 namespace {
748 // returns [0, first, first+1, ... last-1, last] 707 // returns [0, first, first+1, ... last-1, last]
749 struct SingleByteGlyphIdIterator { 708 struct SingleByteGlyphIdIterator {
750 SingleByteGlyphIdIterator(SkGlyphID first, SkGlyphID last) 709 SingleByteGlyphIdIterator(SkGlyphID first, SkGlyphID last)
(...skipping 16 matching lines...) Expand all
767 int fCurrent; // must be int to make fLast+1 to fit 726 int fCurrent; // must be int to make fLast+1 to fit
768 }; 727 };
769 Iter begin() const { return Iter(fFirst, 0); } 728 Iter begin() const { return Iter(fFirst, 0); }
770 Iter end() const { return Iter(fFirst, (int)fLast + 1); } 729 Iter end() const { return Iter(fFirst, (int)fLast + 1); }
771 private: 730 private:
772 const SkGlyphID fFirst; 731 const SkGlyphID fFirst;
773 const SkGlyphID fLast; 732 const SkGlyphID fLast;
774 }; 733 };
775 } 734 }
776 735
777 static void add_type3_font_info(SkPDFDict* font, 736 static void add_type3_font_info(SkPDFCanon* canon,
737 SkPDFDict* font,
778 SkTypeface* typeface, 738 SkTypeface* typeface,
779 SkScalar emSize, 739 SkScalar emSize,
780 const SkPDFGlyphSet* subset, 740 const SkPDFGlyphSet* subset,
781 SkGlyphID firstGlyphID, 741 SkGlyphID firstGlyphID,
782 SkGlyphID lastGlyphID) { 742 SkGlyphID lastGlyphID) {
783 SkASSERT(lastGlyphID >= firstGlyphID); 743 SkASSERT(lastGlyphID >= firstGlyphID);
784 SkASSERT(emSize > 0.0f); 744 SkASSERT(emSize > 0.0f);
785 SkAutoGlyphCache cache = vector_cache(typeface, emSize); 745 SkAutoGlyphCache cache = vector_cache(typeface, emSize);
786 font->insertName("Subtype", "Type3"); 746 font->insertName("Subtype", "Type3");
787 // Flip about the x-axis and scale by 1/emSize. 747 // 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 815 glyphs of the font were placed with their origins coincident and
856 then filled." */ 816 then filled." */
857 auto fontBBox = sk_make_sp<SkPDFArray>(); 817 auto fontBBox = sk_make_sp<SkPDFArray>();
858 fontBBox->reserve(4); 818 fontBBox->reserve(4);
859 fontBBox->appendInt(bbox.left()); 819 fontBBox->appendInt(bbox.left());
860 fontBBox->appendInt(bbox.bottom()); 820 fontBBox->appendInt(bbox.bottom());
861 fontBBox->appendInt(bbox.right()); 821 fontBBox->appendInt(bbox.right());
862 fontBBox->appendInt(bbox.top()); 822 fontBBox->appendInt(bbox.top());
863 font->insertObject("FontBBox", std::move(fontBBox)); 823 font->insertObject("FontBBox", std::move(fontBBox));
864 font->insertName("CIDToGIDMap", "Identity"); 824 font->insertName("CIDToGIDMap", "Identity");
865 sk_sp<const SkAdvancedTypefaceMetrics> metrics; 825 const SkAdvancedTypefaceMetrics* metrics = SkPDFFont::GetMetrics(typeface, c anon);
866 if (subset) { 826 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", 827 font->insertObjRef("ToUnicode",
881 SkPDFMakeToUnicodeCmap(metrics->fGlyphToUnicode, 828 SkPDFMakeToUnicodeCmap(metrics->fGlyphToUnicode,
882 subset, 829 subset,
883 false, 830 false,
884 firstGlyphID, 831 firstGlyphID,
885 lastGlyphID)); 832 lastGlyphID));
886 } 833 }
887 font->insertObject("Widths", std::move(widthArray)); 834 font->insertObject("Widths", std::move(widthArray));
888 font->insertObject("Encoding", std::move(encoding)); 835 font->insertObject("Encoding", std::move(encoding));
889 font->insertObject("CharProcs", std::move(charProcs)); 836 font->insertObject("CharProcs", std::move(charProcs));
890 } 837 }
891 838
892 SkPDFType3Font::SkPDFType3Font(sk_sp<const SkAdvancedTypefaceMetrics> info, 839 SkPDFType3Font::SkPDFType3Font(const SkAdvancedTypefaceMetrics& info,
893 sk_sp<SkTypeface> typeface, 840 sk_sp<SkTypeface> typeface,
894 SkAdvancedTypefaceMetrics::FontType fontType, 841 SkAdvancedTypefaceMetrics::FontType fontType,
895 uint16_t glyphID) 842 uint16_t glyphID)
896 : SkPDFFont(std::move(info), std::move(typeface), nullptr, 843 : 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); 844 this->adjustGlyphRangeForSingleByteEncoding(glyphID);
901 } 845 }
902 846
903 sk_sp<SkPDFObject> SkPDFType3Font::getFontSubset(const SkPDFGlyphSet* usage) { 847 sk_sp<SkPDFObject> SkPDFType3Font::getFontSubset(SkPDFCanon* canon,
848 const SkPDFGlyphSet* usage) {
904 // All fonts are subset before serialization. 849 // All fonts are subset before serialization.
905 // TODO(halcanary): all fonts should follow this pattern. 850 // TODO(halcanary): all fonts should follow this pattern.
851 const SkAdvancedTypefaceMetrics* info =
852 SkPDFFont::GetMetrics(this->typeface(), canon);
853 SkASSERT(info);
854 uint16_t emSize = info->fEmSize > 0 ? info->fEmSize : 1000;
906 auto font = sk_make_sp<SkPDFDict>("Font"); 855 auto font = sk_make_sp<SkPDFDict>("Font");
907 const SkAdvancedTypefaceMetrics* info = this->getFontInfo(); 856 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()); 857 this->firstGlyphID(), this->lastGlyphID());
911 return font; 858 return font;
912 } 859 }
913 860
914 861
915 //////////////////////////////////////////////////////////////////////////////// 862 ////////////////////////////////////////////////////////////////////////////////
916 863
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) { 864 bool SkPDFFont::CanEmbedTypeface(SkTypeface* typeface, SkPDFCanon* canon) {
940 SkFontID id = SkTypeface::UniqueID(typeface); 865 const SkAdvancedTypefaceMetrics* metrics = SkPDFFont::GetMetrics(typeface, c anon);
941 if (bool* value = canon->fCanEmbedTypeface.find(id)) { 866 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 } 867 }
956 868
957 void SkPDFFont::drop() { 869 void SkPDFFont::drop() {
958 fTypeface = nullptr; 870 fTypeface = nullptr;
959 fFontInfo = nullptr;
960 fDescriptor = nullptr;
961 this->SkPDFDict::drop(); 871 this->SkPDFDict::drop();
962 } 872 }
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