SkPDF: Stop using kHAdvance_PerGlyphInfo
SkPDFFont: - never request kHAdvance_PerGlyphInfo from typeface. - set_glyph_widths() fn uses a glyph cache to get advances. - stop expecting vertical advances that are never requested. - composeAdvanceData() now non-templated - appendAdvance() one-line function removed SkPDFDevice: - use a glyph cache for getting repeated advances. GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2219733004 Review-Url: https://codereview.chromium.org/2219733004
This commit is contained in:
parent
ae2964452b
commit
462d0148a5
@ -182,7 +182,6 @@ void SkAdvancedTypefaceMetrics::setGlyphWidths(
|
||||
}
|
||||
}
|
||||
if (curRange.fStartId == lastIndex) {
|
||||
SkASSERT(prevRange);
|
||||
if (!prevRange) {
|
||||
fGlyphWidths.reset();
|
||||
return; // https://crbug.com/567031
|
||||
|
@ -1270,6 +1270,7 @@ void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len,
|
||||
const uint16_t* glyphIDs = nullptr;
|
||||
size_t numGlyphs = force_glyph_encoding(paint, text, len, &storage, &glyphIDs);
|
||||
textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
||||
SkAutoGlyphCache autoGlyphCache(textPaint, nullptr, nullptr);
|
||||
|
||||
content.entry()->fContent.writeText("BT\n");
|
||||
this->updateFont(textPaint, glyphIDs[0], content.entry());
|
||||
@ -1280,6 +1281,7 @@ void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len,
|
||||
for (size_t i = 0; i < numGlyphs; i++) {
|
||||
SkPDFFont* font = content.entry()->fState.fFont;
|
||||
uint16_t encodedValue = glyphIDs[i];
|
||||
SkScalar advanceWidth = autoGlyphCache->getGlyphIDAdvance(encodedValue).fAdvanceX;
|
||||
if (font->glyphsToPDFFontEncoding(&encodedValue, 1) != 1) {
|
||||
// The current pdf font cannot encode the current glyph.
|
||||
// Try to get a pdf font which can encode the current glyph.
|
||||
@ -1292,13 +1294,11 @@ void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
fontGlyphUsage->noteGlyphUsage(font, &encodedValue, 1);
|
||||
SkScalar x = offset.x() + pos[i * scalarsPerPos];
|
||||
SkScalar y = offset.y() + (2 == scalarsPerPos ? pos[i * scalarsPerPos + 1] : 0);
|
||||
align_text(textPaint, glyphIDs + i, 1, &x, &y);
|
||||
|
||||
SkScalar advanceWidth = textPaint.measureText(&encodedValue, sizeof(uint16_t));
|
||||
glyphPositioner.writeGlyph(x, y, advanceWidth, encodedValue);
|
||||
}
|
||||
glyphPositioner.flush(); // Must flush before ending text object.
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user