SkPDF: rasterize bitmap glyphs at 64pt, not em-size
Motivation: em-size is often results in huge bitmaps for each glyph
(e.g. 2556x2406 rgba pixels).
Define SK_PDF_BITMAP_GLYPH_RASTER_SIZE to 0 to get previous behaviour.
Define SK_PDF_BITMAP_GLYPH_RASTER_SIZE to a positive value to rasterize
at that font size rather than 64pt.
Bug: b/141094460
Bug: chromium:921585
Change-Id: I4523e512ec149cf02c985eb83f2e640a2c680d3a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/245160
Commit-Queue: Hal Canary <halcanary@skia.org>
Reviewed-by: Ben Wagner <bungeman@google.com>
diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp
index ba79a15..c027523 100644
--- a/src/pdf/SkPDFFont.cpp
+++ b/src/pdf/SkPDFFont.cpp
@@ -511,6 +511,22 @@
return ref;
}
+#ifdef SK_PDF_BITMAP_GLYPH_RASTER_SIZE
+static constexpr float kBitmapFontSize = SK_PDF_BITMAP_GLYPH_RASTER_SIZE;
+#else
+static constexpr float kBitmapFontSize = 64;
+#endif
+
+SkStrikeSpec make_small_strike(const SkTypeface& typeface) {
+ SkFont font(sk_ref_sp(&typeface), kBitmapFontSize);
+ font.setHinting(SkFontHinting::kNone);
+ font.setEdging(SkFont::Edging::kAlias);
+ return SkStrikeSpec::MakeMask(font,
+ SkPaint(),
+ SkSurfaceProps(0, kUnknown_SkPixelGeometry),
+ kFakeGammaAndBoostContrast,
+ SkMatrix::I());
+}
static void emit_subset_type3(const SkPDFFont& pdfFont, SkPDFDocument* doc) {
SkTypeface* typeface = pdfFont.typeface();
@@ -529,6 +545,12 @@
SkASSERT(cache);
SkScalar emSize = (SkScalar)unitsPerEm;
+ SkStrikeSpec strikeSpecSmall = kBitmapFontSize > 0 ? make_small_strike(*typeface)
+ : strikeSpec;
+ auto smallCache = strikeSpecSmall.findOrCreateExclusiveStrike();
+ SkASSERT(smallCache);
+ float bitmapScale = kBitmapFontSize > 0 ? emSize / kBitmapFontSize : 1.0f;
+
SkPDFDict font("Font");
font.insertName("Subtype", "Type3");
// Flip about the x-axis and scale by 1/emSize.
@@ -575,20 +597,22 @@
SkPDFUtils::EmitPath(*path, SkPaint::kFill_Style, &content);
SkPDFUtils::PaintPath(SkPaint::kFill_Style, path->getFillType(), &content);
} else {
- auto pimg = to_image(gID, cache.get());
+ auto pimg = to_image(gID, smallCache.get());
if (!pimg.fImage) {
setGlyphWidthAndBoundingBox(glyph->advanceX(), glyphBBox, &content);
} else {
+ using SkPDFUtils::AppendScalar;
imageGlyphs.emplace_back(gID, SkPDFSerializeImage(pimg.fImage.get(), doc));
- SkPDFUtils::AppendScalar(glyph->advanceX(), &content);
+ AppendScalar(glyph->advanceX(), &content);
content.writeText(" 0 d0\n");
- content.writeDecAsText(pimg.fImage->width());
+ AppendScalar(pimg.fImage->width() * bitmapScale, &content);
content.writeText(" 0 0 ");
- content.writeDecAsText(-pimg.fImage->height());
+ AppendScalar(-pimg.fImage->height() * bitmapScale, &content);
content.writeText(" ");
- content.writeDecAsText(pimg.fOffset.x());
+ AppendScalar(pimg.fOffset.x() * bitmapScale, &content);
content.writeText(" ");
- content.writeDecAsText(pimg.fImage->height() + pimg.fOffset.y());
+ AppendScalar((pimg.fImage->height() + pimg.fOffset.y()) * bitmapScale,
+ &content);
content.writeText(" cm\n/X");
content.write(characterName.c_str(), characterName.size());
content.writeText(" Do\n");