| Index: src/pdf/SkPDFFont.cpp
|
| diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp
|
| index 0481963029f81781c71129a6b3b9431c5f1359df..db687fba5f7942400e4fab0b35e0d4ce94c4ffc3 100644
|
| --- a/src/pdf/SkPDFFont.cpp
|
| +++ b/src/pdf/SkPDFFont.cpp
|
| @@ -301,51 +301,33 @@ static sk_sp<SkPDFArray> makeFontBBox(SkIRect glyphBBox, uint16_t emSize) {
|
| return bbox;
|
| }
|
|
|
| -static void appendWidth(const int16_t& width, uint16_t emSize,
|
| - SkPDFArray* array) {
|
| - array->appendScalar(scaleFromFontUnits(width, emSize));
|
| -}
|
| -
|
| -static void appendVerticalAdvance(
|
| - const SkAdvancedTypefaceMetrics::VerticalMetric& advance,
|
| - uint16_t emSize, SkPDFArray* array) {
|
| - appendWidth(advance.fVerticalAdvance, emSize, array);
|
| - appendWidth(advance.fOriginXDisp, emSize, array);
|
| - appendWidth(advance.fOriginYDisp, emSize, array);
|
| -}
|
| -
|
| -template <typename Data>
|
| -SkPDFArray* composeAdvanceData(
|
| - const SkSinglyLinkedList<
|
| - SkAdvancedTypefaceMetrics::AdvanceMetric<Data>>& advanceInfo,
|
| +sk_sp<SkPDFArray> composeAdvanceData(
|
| + const SkSinglyLinkedList<SkAdvancedTypefaceMetrics::WidthRange>& advanceInfo,
|
| uint16_t emSize,
|
| - void (*appendAdvance)(const Data& advance,
|
| - uint16_t emSize,
|
| - SkPDFArray* array),
|
| - Data* defaultAdvance) {
|
| - SkPDFArray* result = new SkPDFArray();
|
| - for (const SkAdvancedTypefaceMetrics::AdvanceMetric<Data>& range :
|
| - advanceInfo) {
|
| + int16_t* defaultAdvance) {
|
| + auto result = sk_make_sp<SkPDFArray>();
|
| + for (const SkAdvancedTypefaceMetrics::WidthRange& range : advanceInfo) {
|
| switch (range.fType) {
|
| - case SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kDefault: {
|
| + case SkAdvancedTypefaceMetrics::WidthRange::kDefault: {
|
| SkASSERT(range.fAdvance.count() == 1);
|
| *defaultAdvance = range.fAdvance[0];
|
| break;
|
| }
|
| - case SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange: {
|
| + case SkAdvancedTypefaceMetrics::WidthRange::kRange: {
|
| auto advanceArray = sk_make_sp<SkPDFArray>();
|
| for (int j = 0; j < range.fAdvance.count(); j++)
|
| - appendAdvance(range.fAdvance[j], emSize,
|
| - advanceArray.get());
|
| + advanceArray->appendScalar(
|
| + scaleFromFontUnits(range.fAdvance[j], emSize));
|
| result->appendInt(range.fStartId);
|
| result->appendObject(std::move(advanceArray));
|
| break;
|
| }
|
| - case SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRun: {
|
| + case SkAdvancedTypefaceMetrics::WidthRange::kRun: {
|
| SkASSERT(range.fAdvance.count() == 1);
|
| result->appendInt(range.fStartId);
|
| result->appendInt(range.fEndId);
|
| - appendAdvance(range.fAdvance[0], emSize, result);
|
| + result->appendScalar(
|
| + scaleFromFontUnits(range.fAdvance[0], emSize));
|
| break;
|
| }
|
| }
|
| @@ -493,7 +475,7 @@ static void append_bfrange_section(const SkTDArray<BFRange>& bfrange,
|
| // one of them), the possible savings by aggressive optimization is 416KB
|
| // pre-compressed and does not provide enough motivation for implementation.
|
|
|
| -// FIXME: this should be in a header so that it is separately testable
|
| +// TODO(halcanary): this should be in a header so that it is separately testable
|
| // ( see caller in tests/ToUnicode.cpp )
|
| void append_cmap_sections(const SkTDArray<SkUnichar>& glyphToUnicode,
|
| const SkPDFGlyphSet* subset,
|
| @@ -733,26 +715,11 @@ SkPDFFont* SkPDFFont::GetFontResource(SkPDFCanon* canon,
|
| return SkRef(relatedFont);
|
| }
|
| } else {
|
| - SkTypeface::PerGlyphInfo info;
|
| - info = SkTypeface::kGlyphNames_PerGlyphInfo;
|
| - info = SkTBitOr<SkTypeface::PerGlyphInfo>(
|
| - info, SkTypeface::kToUnicode_PerGlyphInfo);
|
| -#if !defined (SK_SFNTLY_SUBSETTER)
|
| - info = SkTBitOr<SkTypeface::PerGlyphInfo>(
|
| - info, SkTypeface::kHAdvance_PerGlyphInfo);
|
| -#endif
|
| + SkTypeface::PerGlyphInfo info =
|
| + SkTBitOr(SkTypeface::kGlyphNames_PerGlyphInfo,
|
| + SkTypeface::kToUnicode_PerGlyphInfo);
|
| fontMetrics.reset(
|
| typeface->getAdvancedTypefaceMetrics(info, nullptr, 0));
|
| -#if defined (SK_SFNTLY_SUBSETTER)
|
| - if (fontMetrics.get() &&
|
| - fontMetrics->fType != SkAdvancedTypefaceMetrics::kTrueType_Font) {
|
| - // Font does not support subsetting, get new info with advance.
|
| - info = SkTBitOr<SkTypeface::PerGlyphInfo>(
|
| - info, SkTypeface::kHAdvance_PerGlyphInfo);
|
| - fontMetrics.reset(
|
| - typeface->getAdvancedTypefaceMetrics(info, nullptr, 0));
|
| - }
|
| -#endif
|
| }
|
|
|
| SkPDFFont* font = SkPDFFont::Create(canon, fontMetrics.get(), typeface,
|
| @@ -1073,23 +1040,41 @@ bool SkPDFCIDFont::addFontDescriptor(int16_t defaultWidth,
|
| return true;
|
| }
|
|
|
| +void set_glyph_widths(SkTypeface* tf,
|
| + const SkTDArray<uint32_t>* glyphIDs,
|
| + SkAdvancedTypefaceMetrics* dst) {
|
| + SkPaint tmpPaint;
|
| + tmpPaint.setHinting(SkPaint::kNo_Hinting);
|
| + tmpPaint.setTypeface(sk_ref_sp(tf));
|
| + tmpPaint.setTextSize((SkScalar)tf->getUnitsPerEm());
|
| + SkAutoGlyphCache autoGlyphCache(tmpPaint, nullptr, nullptr);
|
| + SkGlyphCache* glyphCache = autoGlyphCache.get();
|
| + SkAdvancedTypefaceMetrics::GetAdvance advanceFn =
|
| + [glyphCache](int gid, int16_t* advance) {
|
| + *advance = (int16_t)glyphCache->getGlyphIDAdvance(gid).fAdvanceX;
|
| + return true;
|
| + };
|
| + if (!glyphIDs || glyphIDs->isEmpty()) {
|
| + dst->setGlyphWidths(tf->countGlyphs(), nullptr, 0, advanceFn);
|
| + } else {
|
| + dst->setGlyphWidths(tf->countGlyphs(),
|
| + glyphIDs->begin(),
|
| + glyphIDs->count(), advanceFn);
|
| + }
|
| +}
|
| +
|
| bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) {
|
| // Generate new font metrics with advance info for true type fonts.
|
| - if (fontInfo()->fType == SkAdvancedTypefaceMetrics::kTrueType_Font) {
|
| - // Generate glyph id array.
|
| - SkTDArray<uint32_t> glyphIDs;
|
| - if (subset) {
|
| - // Always include glyph 0.
|
| - if (!subset->has(0)) {
|
| - glyphIDs.push(0);
|
| - }
|
| - subset->exportTo(&glyphIDs);
|
| + // Generate glyph id array.
|
| + SkTDArray<uint32_t> glyphIDs;
|
| + if (subset) {
|
| + if (!subset->has(0)) {
|
| + glyphIDs.push(0); // Always include glyph 0.
|
| }
|
| -
|
| - SkTypeface::PerGlyphInfo info;
|
| - info = SkTypeface::kGlyphNames_PerGlyphInfo;
|
| - info = SkTBitOr<SkTypeface::PerGlyphInfo>(
|
| - info, SkTypeface::kHAdvance_PerGlyphInfo);
|
| + subset->exportTo(&glyphIDs);
|
| + }
|
| + if (fontInfo()->fType == SkAdvancedTypefaceMetrics::kTrueType_Font) {
|
| + SkTypeface::PerGlyphInfo info = SkTypeface::kGlyphNames_PerGlyphInfo;
|
| uint32_t* glyphs = (glyphIDs.count() == 0) ? nullptr : glyphIDs.begin();
|
| uint32_t glyphsCount = glyphs ? glyphIDs.count() : 0;
|
| sk_sp<const SkAdvancedTypefaceMetrics> fontMetrics(
|
| @@ -1118,38 +1103,18 @@ bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) {
|
| sysInfo->insertInt("Supplement", 0);
|
| this->insertObject("CIDSystemInfo", std::move(sysInfo));
|
|
|
| - if (!fontInfo()->fGlyphWidths.empty()) {
|
| - int16_t defaultWidth = 0;
|
| - sk_sp<SkPDFArray> widths(composeAdvanceData(
|
| - fontInfo()->fGlyphWidths, fontInfo()->fEmSize, &appendWidth,
|
| - &defaultWidth));
|
| - if (widths->size()) {
|
| - this->insertObject("W", std::move(widths));
|
| - }
|
| - this->insertScalar(
|
| - "DW", scaleFromFontUnits(defaultWidth, fontInfo()->fEmSize));
|
| - }
|
| - if (!fontInfo()->fVerticalMetrics.empty()) {
|
| - struct SkAdvancedTypefaceMetrics::VerticalMetric defaultAdvance;
|
| - defaultAdvance.fVerticalAdvance = 0;
|
| - defaultAdvance.fOriginXDisp = 0;
|
| - defaultAdvance.fOriginYDisp = 0;
|
| - sk_sp<SkPDFArray> advances(composeAdvanceData(
|
| - fontInfo()->fVerticalMetrics, fontInfo()->fEmSize,
|
| - &appendVerticalAdvance, &defaultAdvance));
|
| - if (advances->size())
|
| - this->insertObject("W2", std::move(advances));
|
| - if (defaultAdvance.fVerticalAdvance ||
|
| - defaultAdvance.fOriginXDisp ||
|
| - defaultAdvance.fOriginYDisp) {
|
| - auto array = sk_make_sp<SkPDFArray>();
|
| - appendVerticalAdvance(defaultAdvance,
|
| - fontInfo()->fEmSize,
|
| - array.get());
|
| - this->insertObject("DW2", std::move(array));
|
| - }
|
| + SkAdvancedTypefaceMetrics tmpMetrics;
|
| + set_glyph_widths(this->typeface(), &glyphIDs, &tmpMetrics);
|
| + int16_t defaultWidth = 0;
|
| + uint16_t emSize = (uint16_t)this->fontInfo()->fEmSize;
|
| + sk_sp<SkPDFArray> widths = composeAdvanceData(
|
| + tmpMetrics.fGlyphWidths, emSize, &defaultWidth);
|
| + if (widths->size()) {
|
| + this->insertObject("W", std::move(widths));
|
| }
|
|
|
| + this->insertScalar(
|
| + "DW", scaleFromFontUnits(defaultWidth, emSize));
|
| return true;
|
| }
|
|
|
| @@ -1205,24 +1170,28 @@ bool SkPDFType1Font::addFontDescriptor(int16_t defaultWidth) {
|
|
|
| bool SkPDFType1Font::populate(int16_t glyphID) {
|
| SkASSERT(fontInfo()->fVerticalMetrics.empty());
|
| - SkASSERT(!fontInfo()->fGlyphWidths.empty());
|
| + SkASSERT(fontInfo()->fGlyphWidths.empty());
|
|
|
| adjustGlyphRangeForSingleByteEncoding(glyphID);
|
|
|
| int16_t defaultWidth = 0;
|
| const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry = nullptr;
|
| - for (const auto& widthEntry : fontInfo()->fGlyphWidths) {
|
| - switch (widthEntry.fType) {
|
| - case SkAdvancedTypefaceMetrics::WidthRange::kDefault:
|
| - defaultWidth = widthEntry.fAdvance[0];
|
| - break;
|
| - case SkAdvancedTypefaceMetrics::WidthRange::kRun:
|
| - SkASSERT(false);
|
| - break;
|
| - case SkAdvancedTypefaceMetrics::WidthRange::kRange:
|
| - SkASSERT(widthRangeEntry == nullptr);
|
| - widthRangeEntry = &widthEntry;
|
| - break;
|
| + {
|
| + SkAdvancedTypefaceMetrics tmpMetrics;
|
| + set_glyph_widths(this->typeface(), nullptr, &tmpMetrics);
|
| + for (const auto& widthEntry : tmpMetrics.fGlyphWidths) {
|
| + switch (widthEntry.fType) {
|
| + case SkAdvancedTypefaceMetrics::WidthRange::kDefault:
|
| + defaultWidth = widthEntry.fAdvance[0];
|
| + break;
|
| + case SkAdvancedTypefaceMetrics::WidthRange::kRun:
|
| + SkASSERT(false);
|
| + break;
|
| + case SkAdvancedTypefaceMetrics::WidthRange::kRange:
|
| + SkASSERT(widthRangeEntry == nullptr);
|
| + widthRangeEntry = &widthEntry;
|
| + break;
|
| + }
|
| }
|
| }
|
|
|
| @@ -1234,8 +1203,6 @@ bool SkPDFType1Font::populate(int16_t glyphID) {
|
| insertName("BaseFont", fontInfo()->fFontName);
|
|
|
| addWidthInfoFromRange(defaultWidth, widthRangeEntry);
|
| -
|
| -
|
| auto encDiffs = sk_make_sp<SkPDFArray>();
|
| encDiffs->reserve(lastGlyphID() - firstGlyphID() + 2);
|
| encDiffs->appendInt(1);
|
| @@ -1263,15 +1230,18 @@ void SkPDFType1Font::addWidthInfoFromRange(
|
| if (endIndex > widthRangeEntry->fAdvance.count())
|
| endIndex = widthRangeEntry->fAdvance.count();
|
| if (widthRangeEntry->fStartId == 0) {
|
| - appendWidth(widthRangeEntry->fAdvance[0], emSize, widthArray.get());
|
| + widthArray->appendScalar(
|
| + scaleFromFontUnits(widthRangeEntry->fAdvance[0], emSize));
|
| } else {
|
| firstChar = startIndex + widthRangeEntry->fStartId;
|
| }
|
| for (int i = startIndex; i < endIndex; i++) {
|
| - appendWidth(widthRangeEntry->fAdvance[i], emSize, widthArray.get());
|
| + widthArray->appendScalar(
|
| + scaleFromFontUnits(widthRangeEntry->fAdvance[i], emSize));
|
| }
|
| } else {
|
| - appendWidth(defaultWidth, 1000, widthArray.get());
|
| + widthArray->appendScalar(
|
| + scaleFromFontUnits(defaultWidth, 1000));
|
| }
|
| this->insertInt("FirstChar", firstChar);
|
| this->insertInt("LastChar", firstChar + widthArray->size() - 1);
|
|
|