| Index: src/pdf/SkPDFFont.cpp
|
| diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp
|
| index 389df62fd5da133041c66a5d8f81a446ad3cabf5..d7ef8123a2b8ad1832d5b4e8d86a0253442a65d9 100644
|
| --- a/src/pdf/SkPDFFont.cpp
|
| +++ b/src/pdf/SkPDFFont.cpp
|
| @@ -18,7 +18,6 @@
|
| #include "SkRefCnt.h"
|
| #include "SkScalar.h"
|
| #include "SkStream.h"
|
| -#include "SkTypefacePriv.h"
|
| #include "SkTypes.h"
|
| #include "SkUtils.h"
|
|
|
| @@ -148,63 +147,28 @@ static bool can_subset(const SkAdvancedTypefaceMetrics& metrics) {
|
| }
|
| #endif
|
|
|
| -int SkPDFFont::glyphsToPDFFontEncoding(SkGlyphID* glyphIDs, int numGlyphs) const {
|
| - // A font with multibyte glyphs will support all glyph IDs in a single font.
|
| - if (this->multiByteGlyphs()) {
|
| - return numGlyphs;
|
| - }
|
| -
|
| - for (int i = 0; i < numGlyphs; i++) {
|
| - if (glyphIDs[i] == 0) {
|
| - continue;
|
| - }
|
| - if (glyphIDs[i] < fFirstGlyphID || glyphIDs[i] > fLastGlyphID) {
|
| - return i;
|
| - }
|
| - glyphIDs[i] -= (fFirstGlyphID - 1);
|
| - }
|
| -
|
| - return numGlyphs;
|
| -}
|
| -
|
| -int SkPDFFont::glyphsToPDFFontEncodingCount(const SkGlyphID* glyphIDs,
|
| - int numGlyphs) const {
|
| - if (this->multiByteGlyphs()) { // A font with multibyte glyphs will
|
| - return numGlyphs; // support all glyph IDs in a single font.
|
| - }
|
| - for (int i = 0; i < numGlyphs; i++) {
|
| - if (glyphIDs[i] != 0 &&
|
| - (glyphIDs[i] < fFirstGlyphID || glyphIDs[i] > fLastGlyphID)) {
|
| - return i;
|
| - }
|
| - }
|
| - return numGlyphs;
|
| -}
|
| -
|
| -
|
| const SkAdvancedTypefaceMetrics* SkPDFFont::GetMetrics(SkTypeface* typeface,
|
| SkPDFCanon* canon) {
|
| - SkFontID id = SkTypeface::UniqueID(typeface);
|
| + SkASSERT(typeface);
|
| + SkFontID id = typeface->uniqueID();
|
| if (SkAdvancedTypefaceMetrics** ptr = canon->fTypefaceMetrics.find(id)) {
|
| return *ptr;
|
| }
|
| - sk_sp<SkTypeface> defaultFace;
|
| - if (!typeface) {
|
| - defaultFace = SkTypeface::MakeDefault();
|
| - typeface = defaultFace.get();
|
| + int count = typeface->countGlyphs();
|
| + if (count <= 0 || count > 1 + SK_MaxU16) {
|
| + // Cache nullptr to skip this check. Use SkSafeUnref().
|
| + canon->fTypefaceMetrics.set(id, nullptr);
|
| + return nullptr;
|
| }
|
| sk_sp<SkAdvancedTypefaceMetrics> metrics(
|
| typeface->getAdvancedTypefaceMetrics(
|
| SkTypeface::kGlyphNames_PerGlyphInfo | SkTypeface::kToUnicode_PerGlyphInfo,
|
| nullptr, 0));
|
| if (!metrics) {
|
| - if (typeface->countGlyphs() > 0) {
|
| - metrics = sk_make_sp<SkAdvancedTypefaceMetrics>();
|
| - } else {
|
| - SkDEBUGF(("SkPDF: SkTypeface:getAdvancedTypefaceMetrics() returned null.\n"));
|
| - }
|
| - }
|
| - // May cache null to skip this check. use SkSafeUnref.
|
| + metrics = sk_make_sp<SkAdvancedTypefaceMetrics>();
|
| + metrics->fLastGlyphID = SkToU16(count - 1);
|
| + }
|
| + SkASSERT(metrics->fLastGlyphID == SkToU16(count - 1));
|
| return *canon->fTypefaceMetrics.set(id, metrics.release());
|
| }
|
|
|
| @@ -216,7 +180,7 @@ SkAdvancedTypefaceMetrics::FontType font_type(const SkAdvancedTypefaceMetrics& m
|
| return metrics.fType;
|
| }
|
|
|
| -static SkGlyphID first_glyph_for_single_byte_encoding(SkGlyphID gid) {
|
| +static SkGlyphID first_nonzero_glyph_for_single_byte_encoding(SkGlyphID gid) {
|
| return gid != 0 ? gid - (gid - 1) % 255 : 1;
|
| }
|
|
|
| @@ -224,40 +188,37 @@ SkPDFFont* SkPDFFont::GetFontResource(SkPDFCanon* canon,
|
| SkTypeface* face,
|
| SkGlyphID glyphID) {
|
| SkASSERT(canon);
|
| + SkASSERT(face); // All SkPDFDevice::internalDrawText ensures this.
|
| const SkAdvancedTypefaceMetrics* fontMetrics = SkPDFFont::GetMetrics(face, canon);
|
| - if (!fontMetrics) {
|
| - return nullptr; // bad font, return early.
|
| - }
|
| + SkASSERT(fontMetrics); // SkPDFDevice::internalDrawText ensures the typeface is good.
|
| + // GetMetrics only returns null to signify a bad typeface.
|
| const SkAdvancedTypefaceMetrics& metrics = *fontMetrics;
|
| SkAdvancedTypefaceMetrics::FontType type = font_type(metrics);
|
| bool multibyte = SkPDFFont::IsMultiByte(type);
|
| - SkGlyphID firstGlyph = multibyte ? 0 : first_glyph_for_single_byte_encoding(glyphID);
|
| - uint64_t fontID = (SkTypeface::UniqueID(face) << 16) | firstGlyph;
|
| + SkGlyphID subsetCode = multibyte ? 0 : first_nonzero_glyph_for_single_byte_encoding(glyphID);
|
| + uint64_t fontID = (SkTypeface::UniqueID(face) << 16) | subsetCode;
|
|
|
| if (SkPDFFont** found = canon->fFontMap.find(fontID)) {
|
| - SkASSERT(multibyte == (*found)->multiByteGlyphs());
|
| - return SkRef(*found);
|
| + SkPDFFont* foundFont = *found;
|
| + SkASSERT(foundFont && multibyte == foundFont->multiByteGlyphs());
|
| + return SkRef(foundFont);
|
| }
|
|
|
| - sk_sp<SkTypeface> typeface(face ? sk_ref_sp(face) : SkTypeface::MakeDefault());
|
| + sk_sp<SkTypeface> typeface(sk_ref_sp(face));
|
| SkASSERT(typeface);
|
| - int glyphCount = typeface->countGlyphs();
|
| - // Validate typeface + glyph;
|
| - if (glyphCount < 1 || // typeface lacks even a NOTDEF glyph.
|
| - glyphCount > 1 + SK_MaxU16 || // invalid glyphCount
|
| - glyphID >= glyphCount) { // invalid glyph
|
| - return nullptr;
|
| - }
|
| +
|
| + SkGlyphID lastGlyph = metrics.fLastGlyphID;
|
| + SkASSERT(typeface->countGlyphs() == SkToInt(1 + metrics.fLastGlyphID));
|
| +
|
| + // should be caught by SkPDFDevice::internalDrawText
|
| + SkASSERT(glyphID <= lastGlyph);
|
|
|
| SkGlyphID firstNonZeroGlyph;
|
| - SkGlyphID lastGlyph;
|
| if (multibyte) {
|
| firstNonZeroGlyph = 1;
|
| - lastGlyph = SkToU16(glyphCount - 1);
|
| } else {
|
| - firstNonZeroGlyph = firstGlyph;
|
| - lastGlyph = SkToU16(SkTMin<int>(glyphCount - 1,
|
| - 254 + (int)firstGlyph));
|
| + firstNonZeroGlyph = subsetCode;
|
| + lastGlyph = SkToU16(SkTMin<int>((int)lastGlyph, 254 + (int)subsetCode));
|
| }
|
| SkPDFFont::Info info = {std::move(typeface), firstNonZeroGlyph, lastGlyph, type};
|
| sk_sp<SkPDFFont> font;
|
|
|