SkPDF: Subset Type3 (fallback) font
Motivation: significant file-size reduction.
Also: SkPDFFont::subsetFont() returns a sk_sp<SkPDFObject>
rather than a SkPDFFont*.
SkPDFType3Font constructor no longer populates font info;
relies on subsetting.
SkPDFFont::Create is easier to read
Also: SkPDFType3Font are scaled by emSize rather than 1000.
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2231483002
Committed: https://skia.googlesource.com/skia/+/88b138da99328b04cae9a8ee19c3882b8847a550
Review-Url: https://codereview.chromium.org/2231483002
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index b9e1f3b..f3ede35 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -1206,7 +1206,11 @@
SkPDFGlyphSetMap* fontGlyphUsage = fDocument->getGlyphUsage();
while (numGlyphs > consumedGlyphCount) {
- this->updateFont(textPaint, glyphIDs[consumedGlyphCount], content.entry());
+ if (!this->updateFont(textPaint, glyphIDs[consumedGlyphCount], content.entry())) {
+ SkDebugf("SkPDF: Font error.");
+ content.entry()->fContent.writeText("ET\n%SkPDF: Font error.\n");
+ return;
+ }
SkPDFFont* font = content.entry()->fState.fFont;
int availableGlyphs = font->glyphsToPDFFontEncoding(
@@ -1273,7 +1277,11 @@
SkAutoGlyphCache autoGlyphCache(textPaint, nullptr, nullptr);
content.entry()->fContent.writeText("BT\n");
- this->updateFont(textPaint, glyphIDs[0], content.entry());
+ if (!this->updateFont(textPaint, glyphIDs[0], content.entry())) {
+ SkDebugf("SkPDF: Font error.");
+ content.entry()->fContent.writeText("ET\n%SkPDF: Font error.\n");
+ return;
+ }
GlyphPositioner glyphPositioner(&content.entry()->fContent,
textPaint.getTextSkewX(),
content.entry()->fState.fFont->multiByteGlyphs());
@@ -1286,7 +1294,11 @@
// The current pdf font cannot encode the current glyph.
// Try to get a pdf font which can encode the current glyph.
glyphPositioner.flush();
- this->updateFont(textPaint, glyphIDs[i], content.entry());
+ if (!this->updateFont(textPaint, glyphIDs[i], content.entry())) {
+ SkDebugf("SkPDF: Font error.");
+ content.entry()->fContent.writeText("ET\n%SkPDF: Font error.\n");
+ return;
+ }
font = content.entry()->fState.fFont;
glyphPositioner.setWideChars(font->multiByteGlyphs());
if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) {
@@ -1997,13 +2009,16 @@
return result;
}
-void SkPDFDevice::updateFont(const SkPaint& paint, uint16_t glyphID,
+bool SkPDFDevice::updateFont(const SkPaint& paint, uint16_t glyphID,
SkPDFDevice::ContentEntry* contentEntry) {
SkTypeface* typeface = paint.getTypeface();
if (contentEntry->fState.fFont == nullptr ||
contentEntry->fState.fTextSize != paint.getTextSize() ||
!contentEntry->fState.fFont->hasGlyph(glyphID)) {
int fontIndex = getFontResourceIndex(typeface, glyphID);
+ if (fontIndex < 0) {
+ return false;
+ }
contentEntry->fContent.writeText("/");
contentEntry->fContent.writeText(SkPDFResourceDict::getResourceName(
SkPDFResourceDict::kFont_ResourceType,
@@ -2013,11 +2028,15 @@
contentEntry->fContent.writeText(" Tf\n");
contentEntry->fState.fFont = fFontResources[fontIndex];
}
+ return true;
}
int SkPDFDevice::getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID) {
sk_sp<SkPDFFont> newFont(
SkPDFFont::GetFontResource(fDocument->canon(), typeface, glyphID));
+ if (!newFont) {
+ return -1;
+ }
int resourceIndex = fFontResources.find(newFont.get());
if (resourceIndex < 0) {
resourceIndex = fFontResources.count();