Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(640)

Unified Diff: src/pdf/SkPDFFont.cpp

Issue 2251803002: SkPDF: pull out SkPDFMakeCIDGlyphWidthsArray.cpp (Closed) Base URL: https://skia.googlesource.com/skia.git@SkPdfEliminateSkPDFCIDfont
Patch Set: 2016-08-16 (Tuesday) 21:06:10 EDT Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/pdf/SkPDFFont.h ('k') | src/pdf/SkPDFMakeCIDGlyphWidthsArray.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pdf/SkPDFFont.cpp
diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp
index 5cc80b04ec814f34398f89d3934e1b06075cdeb1..4d114f0e1a91b72c6e5ee28269f8c9a5dd341059 100644
--- a/src/pdf/SkPDFFont.cpp
+++ b/src/pdf/SkPDFFont.cpp
@@ -11,6 +11,7 @@
#include "SkPDFCanon.h"
#include "SkPDFConvertType1FontStream.h"
#include "SkPDFDevice.h"
+#include "SkPDFMakeCIDGlyphWidthsArray.h"
#include "SkPDFMakeToUnicodeCmap.h"
#include "SkPDFFont.h"
#include "SkPDFUtils.h"
@@ -31,29 +32,11 @@
#endif
namespace {
-
// PDF's notion of symbolic vs non-symbolic is related to the character set, not
// symbols vs. characters. Rarely is a font the right character set to call it
// non-symbolic, so always call it symbolic. (PDF 1.4 spec, section 5.7.1)
static const int kPdfSymbolic = 4;
-struct AdvanceMetric {
- enum MetricType {
- kDefault, // Default advance: fAdvance.count = 1
- kRange, // Advances for a range: fAdvance.count = fEndID-fStartID
- kRun // fStartID-fEndID have same advance: fAdvance.count = 1
- };
- MetricType fType;
- uint16_t fStartId;
- uint16_t fEndId;
- SkTDArray<int16_t> fAdvance;
- AdvanceMetric(uint16_t startId) : fStartId(startId) {}
- AdvanceMetric(AdvanceMetric&&) = default;
- AdvanceMetric& operator=(AdvanceMetric&& other) = default;
- AdvanceMetric(const AdvanceMetric&) = delete;
- AdvanceMetric& operator=(const AdvanceMetric&) = delete;
-};
-
class SkPDFType0Font final : public SkPDFFont {
public:
SkPDFType0Font(sk_sp<const SkAdvancedTypefaceMetrics> info,
@@ -107,197 +90,22 @@ public:
// File-Local Functions
///////////////////////////////////////////////////////////////////////////////
-const int16_t kInvalidAdvance = SK_MinS16;
-const int16_t kDontCareAdvance = SK_MinS16 + 1;
-
-static void stripUninterestingTrailingAdvancesFromRange(
- AdvanceMetric* range) {
- SkASSERT(range);
-
- int expectedAdvanceCount = range->fEndId - range->fStartId + 1;
- if (range->fAdvance.count() < expectedAdvanceCount) {
- return;
- }
-
- for (int i = expectedAdvanceCount - 1; i >= 0; --i) {
- if (range->fAdvance[i] != kDontCareAdvance &&
- range->fAdvance[i] != kInvalidAdvance &&
- range->fAdvance[i] != 0) {
- range->fEndId = range->fStartId + i;
- break;
- }
- }
-}
-
-static void zeroWildcardsInRange(AdvanceMetric* range) {
- SkASSERT(range);
- if (range->fType != AdvanceMetric::kRange) {
- return;
- }
- SkASSERT(range->fAdvance.count() == range->fEndId - range->fStartId + 1);
-
- // Zero out wildcards.
- for (int i = 0; i < range->fAdvance.count(); ++i) {
- if (range->fAdvance[i] == kDontCareAdvance) {
- range->fAdvance[i] = 0;
- }
- }
-}
-
-static void FinishRange(
- AdvanceMetric* range,
- int endId,
- AdvanceMetric::MetricType type) {
- range->fEndId = endId;
- range->fType = type;
- stripUninterestingTrailingAdvancesFromRange(range);
- int newLength;
- if (type == AdvanceMetric::kRange) {
- newLength = range->fEndId - range->fStartId + 1;
- } else {
- if (range->fEndId == range->fStartId) {
- range->fType = AdvanceMetric::kRange;
- }
- newLength = 1;
- }
- SkASSERT(range->fAdvance.count() >= newLength);
- range->fAdvance.setCount(newLength);
- zeroWildcardsInRange(range);
-}
-
-/** Retrieve advance data for glyphs. Used by the PDF backend. */
-// TODO(halcanary): this function is complex enough to need its logic
-// tested with unit tests. On the other hand, I want to do another
-// round of re-factoring before figuring out how to mock this.
-// TODO(halcanary): this function should be combined with
-// composeAdvanceData() so that we don't need to produce a linked list
-// of intermediate values. Or we could make the intermediate value
-// something other than a linked list.
-static void set_glyph_widths(SkTypeface* typeface,
- const SkPDFGlyphSet* subset,
- SkSinglyLinkedList<AdvanceMetric>* glyphWidths) {
+static SkAutoGlyphCache vector_cache(SkTypeface* face, SkScalar size = 0) {
SkPaint tmpPaint;
tmpPaint.setHinting(SkPaint::kNo_Hinting);
- tmpPaint.setTypeface(sk_ref_sp(typeface));
- tmpPaint.setTextSize((SkScalar)typeface->getUnitsPerEm());
+ tmpPaint.setTypeface(sk_ref_sp(face));
+ if (0 == size) {
+ SkASSERT(face);
+ tmpPaint.setTextSize((SkScalar)face->getUnitsPerEm());
+ } else {
+ tmpPaint.setTextSize(size);
+ }
const SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
SkAutoGlyphCache glyphCache(tmpPaint, &props, nullptr);
SkASSERT(glyphCache.get());
-
- // Assuming that on average, the ASCII representation of an advance plus
- // a space is 8 characters and the ASCII representation of a glyph id is 3
- // characters, then the following cut offs for using different range types
- // apply:
- // The cost of stopping and starting the range is 7 characers
- // a. Removing 4 0's or don't care's is a win
- // The cost of stopping and starting the range plus a run is 22
- // characters
- // b. Removing 3 repeating advances is a win
- // c. Removing 2 repeating advances and 3 don't cares is a win
- // When not currently in a range the cost of a run over a range is 16
- // characaters, so:
- // d. Removing a leading 0/don't cares is a win because it is omitted
- // e. Removing 2 repeating advances is a win
-
- int num_glyphs = typeface->countGlyphs();
-
- AdvanceMetric* prevRange = nullptr;
- int16_t lastAdvance = kInvalidAdvance;
- int repeatedAdvances = 0;
- int wildCardsInRun = 0;
- int trailingWildCards = 0;
-
- // Limit the loop count to glyph id ranges provided.
- int lastIndex = num_glyphs;
- if (subset) {
- while (!subset->has(lastIndex - 1) && lastIndex > 0) {
- --lastIndex;
- }
- }
- AdvanceMetric curRange(0);
-
- for (int gId = 0; gId <= lastIndex; gId++) {
- int16_t advance = kInvalidAdvance;
- if (gId < lastIndex) {
- if (!subset || 0 == gId || subset->has(gId)) {
- advance = (int16_t)glyphCache->getGlyphIDAdvance(gId).fAdvanceX;
- } else {
- advance = kDontCareAdvance;
- }
- }
- if (advance == lastAdvance) {
- repeatedAdvances++;
- trailingWildCards = 0;
- } else if (advance == kDontCareAdvance) {
- wildCardsInRun++;
- trailingWildCards++;
- } else if (curRange.fAdvance.count() ==
- repeatedAdvances + 1 + wildCardsInRun) { // All in run.
- if (lastAdvance == 0) {
- curRange.fStartId = gId; // reset
- curRange.fAdvance.setCount(0);
- trailingWildCards = 0;
- } else if (repeatedAdvances + 1 >= 2 || trailingWildCards >= 4) {
- FinishRange(&curRange, gId - 1, AdvanceMetric::kRun);
- prevRange = glyphWidths->emplace_back(std::move(curRange));
- curRange = AdvanceMetric(gId);
- trailingWildCards = 0;
- }
- repeatedAdvances = 0;
- wildCardsInRun = trailingWildCards;
- trailingWildCards = 0;
- } else {
- if (lastAdvance == 0 &&
- repeatedAdvances + 1 + wildCardsInRun >= 4) {
- FinishRange(&curRange,
- gId - repeatedAdvances - wildCardsInRun - 2,
- AdvanceMetric::kRange);
- prevRange = glyphWidths->emplace_back(std::move(curRange));
- curRange = AdvanceMetric(gId);
- trailingWildCards = 0;
- } else if (trailingWildCards >= 4 && repeatedAdvances + 1 < 2) {
- FinishRange(&curRange, gId - trailingWildCards - 1,
- AdvanceMetric::kRange);
- prevRange = glyphWidths->emplace_back(std::move(curRange));
- curRange = AdvanceMetric(gId);
- trailingWildCards = 0;
- } else if (lastAdvance != 0 &&
- (repeatedAdvances + 1 >= 3 ||
- (repeatedAdvances + 1 >= 2 && wildCardsInRun >= 3))) {
- FinishRange(&curRange,
- gId - repeatedAdvances - wildCardsInRun - 2,
- AdvanceMetric::kRange);
- (void)glyphWidths->emplace_back(std::move(curRange));
- curRange =
- AdvanceMetric(gId - repeatedAdvances - wildCardsInRun - 1);
- curRange.fAdvance.append(1, &lastAdvance);
- FinishRange(&curRange, gId - 1, AdvanceMetric::kRun);
- prevRange = glyphWidths->emplace_back(std::move(curRange));
- curRange = AdvanceMetric(gId);
- trailingWildCards = 0;
- }
- repeatedAdvances = 0;
- wildCardsInRun = trailingWildCards;
- trailingWildCards = 0;
- }
- curRange.fAdvance.append(1, &advance);
- if (advance != kDontCareAdvance) {
- lastAdvance = advance;
- }
- }
- if (curRange.fStartId == lastIndex) {
- if (!prevRange) {
- glyphWidths->reset();
- return; // https://crbug.com/567031
- }
- } else {
- FinishRange(&curRange, lastIndex - 1, AdvanceMetric::kRange);
- glyphWidths->emplace_back(std::move(curRange));
- }
+ return glyphCache;
}
-////////////////////////////////////////////////////////////////////////////////
-
// scale from em-units to base-1000, returning as a SkScalar
SkScalar from_font_units(SkScalar scaled, uint16_t emSize) {
if (emSize == 1000) {
@@ -336,41 +144,6 @@ static sk_sp<SkPDFArray> makeFontBBox(SkIRect glyphBBox, uint16_t emSize) {
bbox->appendScalar(scaleFromFontUnits(glyphBBox.fTop, emSize));
return bbox;
}
-
-sk_sp<SkPDFArray> composeAdvanceData(
- const SkSinglyLinkedList<AdvanceMetric>& advanceInfo,
- uint16_t emSize,
- int16_t* defaultAdvance) {
- auto result = sk_make_sp<SkPDFArray>();
- for (const AdvanceMetric& range : advanceInfo) {
- switch (range.fType) {
- case AdvanceMetric::kDefault: {
- SkASSERT(range.fAdvance.count() == 1);
- *defaultAdvance = range.fAdvance[0];
- break;
- }
- case AdvanceMetric::kRange: {
- auto advanceArray = sk_make_sp<SkPDFArray>();
- for (int j = 0; j < range.fAdvance.count(); j++)
- advanceArray->appendScalar(
- scaleFromFontUnits(range.fAdvance[j], emSize));
- result->appendInt(range.fStartId);
- result->appendObject(std::move(advanceArray));
- break;
- }
- case AdvanceMetric::kRun: {
- SkASSERT(range.fAdvance.count() == 1);
- result->appendInt(range.fStartId);
- result->appendInt(range.fEndId);
- result->appendScalar(
- scaleFromFontUnits(range.fAdvance[0], emSize));
- break;
- }
- }
- }
- return result;
-}
-
} // namespace
@@ -834,19 +607,20 @@ bool SkPDFType0Font::populate(const SkPDFGlyphSet* subset) {
sysInfo->insertInt("Supplement", 0);
newCIDFont->insertObject("CIDSystemInfo", std::move(sysInfo));
- SkSinglyLinkedList<AdvanceMetric> tmpMetrics;
- set_glyph_widths(face, subset, &tmpMetrics);
+ uint16_t emSize = this->getFontInfo()->fEmSize;
int16_t defaultWidth = 0;
- uint16_t emSize = (uint16_t)this->getFontInfo()->fEmSize;
- sk_sp<SkPDFArray> widths = composeAdvanceData(tmpMetrics, emSize, &defaultWidth);
- if (widths->size()) {
- newCIDFont->insertObject("W", std::move(widths));
+ const SkBitSet* bitSet = subset ? &subset->bitSet() : nullptr;
+ {
+ SkAutoGlyphCache glyphCache = vector_cache(face);
+ sk_sp<SkPDFArray> widths = SkPDFMakeCIDGlyphWidthsArray(
+ glyphCache.get(), bitSet, emSize, &defaultWidth);
+ if (widths && widths->size() > 0) {
+ newCIDFont->insertObject("W", std::move(widths));
+ }
+ newCIDFont->insertScalar(
+ "DW", scaleFromFontUnits(defaultWidth, emSize));
}
- newCIDFont->insertScalar(
- "DW", scaleFromFontUnits(defaultWidth, emSize));
-
-
////////////////////////////////////////////////////////////////////////////
this->insertName("Subtype", "Type0");
@@ -933,12 +707,7 @@ bool SkPDFType1Font::populate(int16_t glyphID) {
this->insertInt("FirstChar", (size_t)0);
this->insertInt("LastChar", (size_t)glyphCount);
{
- SkPaint tmpPaint;
- tmpPaint.setHinting(SkPaint::kNo_Hinting);
- tmpPaint.setTypeface(sk_ref_sp(this->typeface()));
- tmpPaint.setTextSize((SkScalar)this->typeface()->getUnitsPerEm());
- const SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
- SkAutoGlyphCache glyphCache(tmpPaint, &props, nullptr);
+ SkAutoGlyphCache glyphCache = vector_cache(this->typeface());
auto widths = sk_make_sp<SkPDFArray>();
SkScalar advance = glyphCache->getGlyphIDAdvance(0).fAdvanceX;
const uint16_t emSize = this->getFontInfo()->fEmSize;
@@ -1012,13 +781,8 @@ static void add_type3_font_info(SkPDFDict* font,
SkGlyphID firstGlyphID,
SkGlyphID lastGlyphID) {
SkASSERT(lastGlyphID >= firstGlyphID);
- SkPaint paint;
- paint.setHinting(SkPaint::kNo_Hinting);
- paint.setTypeface(sk_ref_sp(typeface));
- paint.setTextSize(emSize);
- const SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
- SkAutoGlyphCache cache(paint, &props, nullptr);
-
+ SkASSERT(emSize > 0.0f);
+ SkAutoGlyphCache cache = vector_cache(typeface, emSize);
font->insertName("Subtype", "Type3");
// Flip about the x-axis and scale by 1/emSize.
SkMatrix fontMatrix;
« no previous file with comments | « src/pdf/SkPDFFont.h ('k') | src/pdf/SkPDFMakeCIDGlyphWidthsArray.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698