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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « src/pdf/SkPDFFont.h ('k') | src/pdf/SkPDFMakeCIDGlyphWidthsArray.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkData.h" 8 #include "SkData.h"
9 #include "SkGlyphCache.h" 9 #include "SkGlyphCache.h"
10 #include "SkPaint.h" 10 #include "SkPaint.h"
11 #include "SkPDFCanon.h" 11 #include "SkPDFCanon.h"
12 #include "SkPDFConvertType1FontStream.h" 12 #include "SkPDFConvertType1FontStream.h"
13 #include "SkPDFDevice.h" 13 #include "SkPDFDevice.h"
14 #include "SkPDFMakeCIDGlyphWidthsArray.h"
14 #include "SkPDFMakeToUnicodeCmap.h" 15 #include "SkPDFMakeToUnicodeCmap.h"
15 #include "SkPDFFont.h" 16 #include "SkPDFFont.h"
16 #include "SkPDFUtils.h" 17 #include "SkPDFUtils.h"
17 #include "SkRefCnt.h" 18 #include "SkRefCnt.h"
18 #include "SkScalar.h" 19 #include "SkScalar.h"
19 #include "SkStream.h" 20 #include "SkStream.h"
20 #include "SkTypefacePriv.h" 21 #include "SkTypefacePriv.h"
21 #include "SkTypes.h" 22 #include "SkTypes.h"
22 #include "SkUtils.h" 23 #include "SkUtils.h"
23 24
24 #if defined (SK_SFNTLY_SUBSETTER) 25 #if defined (SK_SFNTLY_SUBSETTER)
25 #if defined (GOOGLE3) 26 #if defined (GOOGLE3)
26 // #including #defines doesn't work with this build system. 27 // #including #defines doesn't work with this build system.
27 #include "typography/font/sfntly/src/sample/chromium/font_subsetter.h" 28 #include "typography/font/sfntly/src/sample/chromium/font_subsetter.h"
28 #else 29 #else
29 #include SK_SFNTLY_SUBSETTER 30 #include SK_SFNTLY_SUBSETTER
30 #endif 31 #endif
31 #endif 32 #endif
32 33
33 namespace { 34 namespace {
34
35 // PDF's notion of symbolic vs non-symbolic is related to the character set, not 35 // PDF's notion of symbolic vs non-symbolic is related to the character set, not
36 // symbols vs. characters. Rarely is a font the right character set to call it 36 // symbols vs. characters. Rarely is a font the right character set to call it
37 // non-symbolic, so always call it symbolic. (PDF 1.4 spec, section 5.7.1) 37 // non-symbolic, so always call it symbolic. (PDF 1.4 spec, section 5.7.1)
38 static const int kPdfSymbolic = 4; 38 static const int kPdfSymbolic = 4;
39 39
40 struct AdvanceMetric {
41 enum MetricType {
42 kDefault, // Default advance: fAdvance.count = 1
43 kRange, // Advances for a range: fAdvance.count = fEndID-fStartID
44 kRun // fStartID-fEndID have same advance: fAdvance.count = 1
45 };
46 MetricType fType;
47 uint16_t fStartId;
48 uint16_t fEndId;
49 SkTDArray<int16_t> fAdvance;
50 AdvanceMetric(uint16_t startId) : fStartId(startId) {}
51 AdvanceMetric(AdvanceMetric&&) = default;
52 AdvanceMetric& operator=(AdvanceMetric&& other) = default;
53 AdvanceMetric(const AdvanceMetric&) = delete;
54 AdvanceMetric& operator=(const AdvanceMetric&) = delete;
55 };
56
57 class SkPDFType0Font final : public SkPDFFont { 40 class SkPDFType0Font final : public SkPDFFont {
58 public: 41 public:
59 SkPDFType0Font(sk_sp<const SkAdvancedTypefaceMetrics> info, 42 SkPDFType0Font(sk_sp<const SkAdvancedTypefaceMetrics> info,
60 sk_sp<SkTypeface> typeface, 43 sk_sp<SkTypeface> typeface,
61 SkAdvancedTypefaceMetrics::FontType type); 44 SkAdvancedTypefaceMetrics::FontType type);
62 virtual ~SkPDFType0Font(); 45 virtual ~SkPDFType0Font();
63 sk_sp<SkPDFObject> getFontSubset(const SkPDFGlyphSet* usage) override; 46 sk_sp<SkPDFObject> getFontSubset(const SkPDFGlyphSet* usage) override;
64 #ifdef SK_DEBUG 47 #ifdef SK_DEBUG
65 void emitObject(SkWStream*, 48 void emitObject(SkWStream*,
66 const SkPDFObjNumMap&, 49 const SkPDFObjNumMap&,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 const SkPDFSubstituteMap&) const override { 83 const SkPDFSubstituteMap&) const override {
101 SkDEBUGFAIL("should call getFontSubset!"); 84 SkDEBUGFAIL("should call getFontSubset!");
102 } 85 }
103 sk_sp<SkPDFObject> getFontSubset(const SkPDFGlyphSet* usage) override; 86 sk_sp<SkPDFObject> getFontSubset(const SkPDFGlyphSet* usage) override;
104 }; 87 };
105 88
106 /////////////////////////////////////////////////////////////////////////////// 89 ///////////////////////////////////////////////////////////////////////////////
107 // File-Local Functions 90 // File-Local Functions
108 /////////////////////////////////////////////////////////////////////////////// 91 ///////////////////////////////////////////////////////////////////////////////
109 92
110 const int16_t kInvalidAdvance = SK_MinS16; 93 static SkAutoGlyphCache vector_cache(SkTypeface* face, SkScalar size = 0) {
111 const int16_t kDontCareAdvance = SK_MinS16 + 1;
112
113 static void stripUninterestingTrailingAdvancesFromRange(
114 AdvanceMetric* range) {
115 SkASSERT(range);
116
117 int expectedAdvanceCount = range->fEndId - range->fStartId + 1;
118 if (range->fAdvance.count() < expectedAdvanceCount) {
119 return;
120 }
121
122 for (int i = expectedAdvanceCount - 1; i >= 0; --i) {
123 if (range->fAdvance[i] != kDontCareAdvance &&
124 range->fAdvance[i] != kInvalidAdvance &&
125 range->fAdvance[i] != 0) {
126 range->fEndId = range->fStartId + i;
127 break;
128 }
129 }
130 }
131
132 static void zeroWildcardsInRange(AdvanceMetric* range) {
133 SkASSERT(range);
134 if (range->fType != AdvanceMetric::kRange) {
135 return;
136 }
137 SkASSERT(range->fAdvance.count() == range->fEndId - range->fStartId + 1);
138
139 // Zero out wildcards.
140 for (int i = 0; i < range->fAdvance.count(); ++i) {
141 if (range->fAdvance[i] == kDontCareAdvance) {
142 range->fAdvance[i] = 0;
143 }
144 }
145 }
146
147 static void FinishRange(
148 AdvanceMetric* range,
149 int endId,
150 AdvanceMetric::MetricType type) {
151 range->fEndId = endId;
152 range->fType = type;
153 stripUninterestingTrailingAdvancesFromRange(range);
154 int newLength;
155 if (type == AdvanceMetric::kRange) {
156 newLength = range->fEndId - range->fStartId + 1;
157 } else {
158 if (range->fEndId == range->fStartId) {
159 range->fType = AdvanceMetric::kRange;
160 }
161 newLength = 1;
162 }
163 SkASSERT(range->fAdvance.count() >= newLength);
164 range->fAdvance.setCount(newLength);
165 zeroWildcardsInRange(range);
166 }
167
168 /** Retrieve advance data for glyphs. Used by the PDF backend. */
169 // TODO(halcanary): this function is complex enough to need its logic
170 // tested with unit tests. On the other hand, I want to do another
171 // round of re-factoring before figuring out how to mock this.
172 // TODO(halcanary): this function should be combined with
173 // composeAdvanceData() so that we don't need to produce a linked list
174 // of intermediate values. Or we could make the intermediate value
175 // something other than a linked list.
176 static void set_glyph_widths(SkTypeface* typeface,
177 const SkPDFGlyphSet* subset,
178 SkSinglyLinkedList<AdvanceMetric>* glyphWidths) {
179 SkPaint tmpPaint; 94 SkPaint tmpPaint;
180 tmpPaint.setHinting(SkPaint::kNo_Hinting); 95 tmpPaint.setHinting(SkPaint::kNo_Hinting);
181 tmpPaint.setTypeface(sk_ref_sp(typeface)); 96 tmpPaint.setTypeface(sk_ref_sp(face));
182 tmpPaint.setTextSize((SkScalar)typeface->getUnitsPerEm()); 97 if (0 == size) {
98 SkASSERT(face);
99 tmpPaint.setTextSize((SkScalar)face->getUnitsPerEm());
100 } else {
101 tmpPaint.setTextSize(size);
102 }
183 const SkSurfaceProps props(0, kUnknown_SkPixelGeometry); 103 const SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
184 SkAutoGlyphCache glyphCache(tmpPaint, &props, nullptr); 104 SkAutoGlyphCache glyphCache(tmpPaint, &props, nullptr);
185 SkASSERT(glyphCache.get()); 105 SkASSERT(glyphCache.get());
186 106 return glyphCache;
187 // Assuming that on average, the ASCII representation of an advance plus
188 // a space is 8 characters and the ASCII representation of a glyph id is 3
189 // characters, then the following cut offs for using different range types
190 // apply:
191 // The cost of stopping and starting the range is 7 characers
192 // a. Removing 4 0's or don't care's is a win
193 // The cost of stopping and starting the range plus a run is 22
194 // characters
195 // b. Removing 3 repeating advances is a win
196 // c. Removing 2 repeating advances and 3 don't cares is a win
197 // When not currently in a range the cost of a run over a range is 16
198 // characaters, so:
199 // d. Removing a leading 0/don't cares is a win because it is omitted
200 // e. Removing 2 repeating advances is a win
201
202 int num_glyphs = typeface->countGlyphs();
203
204 AdvanceMetric* prevRange = nullptr;
205 int16_t lastAdvance = kInvalidAdvance;
206 int repeatedAdvances = 0;
207 int wildCardsInRun = 0;
208 int trailingWildCards = 0;
209
210 // Limit the loop count to glyph id ranges provided.
211 int lastIndex = num_glyphs;
212 if (subset) {
213 while (!subset->has(lastIndex - 1) && lastIndex > 0) {
214 --lastIndex;
215 }
216 }
217 AdvanceMetric curRange(0);
218
219 for (int gId = 0; gId <= lastIndex; gId++) {
220 int16_t advance = kInvalidAdvance;
221 if (gId < lastIndex) {
222 if (!subset || 0 == gId || subset->has(gId)) {
223 advance = (int16_t)glyphCache->getGlyphIDAdvance(gId).fAdvanceX;
224 } else {
225 advance = kDontCareAdvance;
226 }
227 }
228 if (advance == lastAdvance) {
229 repeatedAdvances++;
230 trailingWildCards = 0;
231 } else if (advance == kDontCareAdvance) {
232 wildCardsInRun++;
233 trailingWildCards++;
234 } else if (curRange.fAdvance.count() ==
235 repeatedAdvances + 1 + wildCardsInRun) { // All in run.
236 if (lastAdvance == 0) {
237 curRange.fStartId = gId; // reset
238 curRange.fAdvance.setCount(0);
239 trailingWildCards = 0;
240 } else if (repeatedAdvances + 1 >= 2 || trailingWildCards >= 4) {
241 FinishRange(&curRange, gId - 1, AdvanceMetric::kRun);
242 prevRange = glyphWidths->emplace_back(std::move(curRange));
243 curRange = AdvanceMetric(gId);
244 trailingWildCards = 0;
245 }
246 repeatedAdvances = 0;
247 wildCardsInRun = trailingWildCards;
248 trailingWildCards = 0;
249 } else {
250 if (lastAdvance == 0 &&
251 repeatedAdvances + 1 + wildCardsInRun >= 4) {
252 FinishRange(&curRange,
253 gId - repeatedAdvances - wildCardsInRun - 2,
254 AdvanceMetric::kRange);
255 prevRange = glyphWidths->emplace_back(std::move(curRange));
256 curRange = AdvanceMetric(gId);
257 trailingWildCards = 0;
258 } else if (trailingWildCards >= 4 && repeatedAdvances + 1 < 2) {
259 FinishRange(&curRange, gId - trailingWildCards - 1,
260 AdvanceMetric::kRange);
261 prevRange = glyphWidths->emplace_back(std::move(curRange));
262 curRange = AdvanceMetric(gId);
263 trailingWildCards = 0;
264 } else if (lastAdvance != 0 &&
265 (repeatedAdvances + 1 >= 3 ||
266 (repeatedAdvances + 1 >= 2 && wildCardsInRun >= 3))) {
267 FinishRange(&curRange,
268 gId - repeatedAdvances - wildCardsInRun - 2,
269 AdvanceMetric::kRange);
270 (void)glyphWidths->emplace_back(std::move(curRange));
271 curRange =
272 AdvanceMetric(gId - repeatedAdvances - wildCardsInRun - 1);
273 curRange.fAdvance.append(1, &lastAdvance);
274 FinishRange(&curRange, gId - 1, AdvanceMetric::kRun);
275 prevRange = glyphWidths->emplace_back(std::move(curRange));
276 curRange = AdvanceMetric(gId);
277 trailingWildCards = 0;
278 }
279 repeatedAdvances = 0;
280 wildCardsInRun = trailingWildCards;
281 trailingWildCards = 0;
282 }
283 curRange.fAdvance.append(1, &advance);
284 if (advance != kDontCareAdvance) {
285 lastAdvance = advance;
286 }
287 }
288 if (curRange.fStartId == lastIndex) {
289 if (!prevRange) {
290 glyphWidths->reset();
291 return; // https://crbug.com/567031
292 }
293 } else {
294 FinishRange(&curRange, lastIndex - 1, AdvanceMetric::kRange);
295 glyphWidths->emplace_back(std::move(curRange));
296 }
297 } 107 }
298 108
299 ////////////////////////////////////////////////////////////////////////////////
300
301 // scale from em-units to base-1000, returning as a SkScalar 109 // scale from em-units to base-1000, returning as a SkScalar
302 SkScalar from_font_units(SkScalar scaled, uint16_t emSize) { 110 SkScalar from_font_units(SkScalar scaled, uint16_t emSize) {
303 if (emSize == 1000) { 111 if (emSize == 1000) {
304 return scaled; 112 return scaled;
305 } else { 113 } else {
306 return SkScalarMulDiv(scaled, 1000, emSize); 114 return SkScalarMulDiv(scaled, 1000, emSize);
307 } 115 }
308 } 116 }
309 117
310 SkScalar scaleFromFontUnits(int16_t val, uint16_t emSize) { 118 SkScalar scaleFromFontUnits(int16_t val, uint16_t emSize) {
(...skipping 18 matching lines...) Expand all
329 137
330 static sk_sp<SkPDFArray> makeFontBBox(SkIRect glyphBBox, uint16_t emSize) { 138 static sk_sp<SkPDFArray> makeFontBBox(SkIRect glyphBBox, uint16_t emSize) {
331 auto bbox = sk_make_sp<SkPDFArray>(); 139 auto bbox = sk_make_sp<SkPDFArray>();
332 bbox->reserve(4); 140 bbox->reserve(4);
333 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fLeft, emSize)); 141 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fLeft, emSize));
334 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fBottom, emSize)); 142 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fBottom, emSize));
335 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fRight, emSize)); 143 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fRight, emSize));
336 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fTop, emSize)); 144 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fTop, emSize));
337 return bbox; 145 return bbox;
338 } 146 }
339
340 sk_sp<SkPDFArray> composeAdvanceData(
341 const SkSinglyLinkedList<AdvanceMetric>& advanceInfo,
342 uint16_t emSize,
343 int16_t* defaultAdvance) {
344 auto result = sk_make_sp<SkPDFArray>();
345 for (const AdvanceMetric& range : advanceInfo) {
346 switch (range.fType) {
347 case AdvanceMetric::kDefault: {
348 SkASSERT(range.fAdvance.count() == 1);
349 *defaultAdvance = range.fAdvance[0];
350 break;
351 }
352 case AdvanceMetric::kRange: {
353 auto advanceArray = sk_make_sp<SkPDFArray>();
354 for (int j = 0; j < range.fAdvance.count(); j++)
355 advanceArray->appendScalar(
356 scaleFromFontUnits(range.fAdvance[j], emSize));
357 result->appendInt(range.fStartId);
358 result->appendObject(std::move(advanceArray));
359 break;
360 }
361 case AdvanceMetric::kRun: {
362 SkASSERT(range.fAdvance.count() == 1);
363 result->appendInt(range.fStartId);
364 result->appendInt(range.fEndId);
365 result->appendScalar(
366 scaleFromFontUnits(range.fAdvance[0], emSize));
367 break;
368 }
369 }
370 }
371 return result;
372 }
373
374 } // namespace 147 } // namespace
375 148
376 149
377 /////////////////////////////////////////////////////////////////////////////// 150 ///////////////////////////////////////////////////////////////////////////////
378 // class SkPDFGlyphSet 151 // class SkPDFGlyphSet
379 /////////////////////////////////////////////////////////////////////////////// 152 ///////////////////////////////////////////////////////////////////////////////
380 153
381 SkPDFGlyphSet::SkPDFGlyphSet() : fBitSet(SK_MaxU16 + 1) { 154 SkPDFGlyphSet::SkPDFGlyphSet() : fBitSet(SK_MaxU16 + 1) {
382 } 155 }
383 156
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 } else { 600 } else {
828 SkASSERT(false); 601 SkASSERT(false);
829 } 602 }
830 603
831 auto sysInfo = sk_make_sp<SkPDFDict>(); 604 auto sysInfo = sk_make_sp<SkPDFDict>();
832 sysInfo->insertString("Registry", "Adobe"); 605 sysInfo->insertString("Registry", "Adobe");
833 sysInfo->insertString("Ordering", "Identity"); 606 sysInfo->insertString("Ordering", "Identity");
834 sysInfo->insertInt("Supplement", 0); 607 sysInfo->insertInt("Supplement", 0);
835 newCIDFont->insertObject("CIDSystemInfo", std::move(sysInfo)); 608 newCIDFont->insertObject("CIDSystemInfo", std::move(sysInfo));
836 609
837 SkSinglyLinkedList<AdvanceMetric> tmpMetrics; 610 uint16_t emSize = this->getFontInfo()->fEmSize;
838 set_glyph_widths(face, subset, &tmpMetrics);
839 int16_t defaultWidth = 0; 611 int16_t defaultWidth = 0;
840 uint16_t emSize = (uint16_t)this->getFontInfo()->fEmSize; 612 const SkBitSet* bitSet = subset ? &subset->bitSet() : nullptr;
841 sk_sp<SkPDFArray> widths = composeAdvanceData(tmpMetrics, emSize, &defaultWi dth); 613 {
842 if (widths->size()) { 614 SkAutoGlyphCache glyphCache = vector_cache(face);
843 newCIDFont->insertObject("W", std::move(widths)); 615 sk_sp<SkPDFArray> widths = SkPDFMakeCIDGlyphWidthsArray(
616 glyphCache.get(), bitSet, emSize, &defaultWidth);
617 if (widths && widths->size() > 0) {
618 newCIDFont->insertObject("W", std::move(widths));
619 }
620 newCIDFont->insertScalar(
621 "DW", scaleFromFontUnits(defaultWidth, emSize));
844 } 622 }
845 623
846 newCIDFont->insertScalar(
847 "DW", scaleFromFontUnits(defaultWidth, emSize));
848
849
850 //////////////////////////////////////////////////////////////////////////// 624 ////////////////////////////////////////////////////////////////////////////
851 625
852 this->insertName("Subtype", "Type0"); 626 this->insertName("Subtype", "Type0");
853 this->insertName("BaseFont", metrics.fFontName); 627 this->insertName("BaseFont", metrics.fFontName);
854 this->insertName("Encoding", "Identity-H"); 628 this->insertName("Encoding", "Identity-H");
855 auto descendantFonts = sk_make_sp<SkPDFArray>(); 629 auto descendantFonts = sk_make_sp<SkPDFArray>();
856 descendantFonts->appendObjRef(std::move(newCIDFont)); 630 descendantFonts->appendObjRef(std::move(newCIDFont));
857 this->insertObject("DescendantFonts", std::move(descendantFonts)); 631 this->insertObject("DescendantFonts", std::move(descendantFonts));
858 this->populateToUnicodeTable(subset); 632 this->populateToUnicodeTable(subset);
859 SkDEBUGCODE(fPopulated = true); 633 SkDEBUGCODE(fPopulated = true);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
926 adjustGlyphRangeForSingleByteEncoding(glyphID); 700 adjustGlyphRangeForSingleByteEncoding(glyphID);
927 SkGlyphID firstGlyphID = this->firstGlyphID(); 701 SkGlyphID firstGlyphID = this->firstGlyphID();
928 SkGlyphID lastGlyphID = this->lastGlyphID(); 702 SkGlyphID lastGlyphID = this->lastGlyphID();
929 703
930 // glyphCount not including glyph 0 704 // glyphCount not including glyph 0
931 unsigned glyphCount = 1 + lastGlyphID - firstGlyphID; 705 unsigned glyphCount = 1 + lastGlyphID - firstGlyphID;
932 SkASSERT(glyphCount > 0 && glyphCount <= 255); 706 SkASSERT(glyphCount > 0 && glyphCount <= 255);
933 this->insertInt("FirstChar", (size_t)0); 707 this->insertInt("FirstChar", (size_t)0);
934 this->insertInt("LastChar", (size_t)glyphCount); 708 this->insertInt("LastChar", (size_t)glyphCount);
935 { 709 {
936 SkPaint tmpPaint; 710 SkAutoGlyphCache glyphCache = vector_cache(this->typeface());
937 tmpPaint.setHinting(SkPaint::kNo_Hinting);
938 tmpPaint.setTypeface(sk_ref_sp(this->typeface()));
939 tmpPaint.setTextSize((SkScalar)this->typeface()->getUnitsPerEm());
940 const SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
941 SkAutoGlyphCache glyphCache(tmpPaint, &props, nullptr);
942 auto widths = sk_make_sp<SkPDFArray>(); 711 auto widths = sk_make_sp<SkPDFArray>();
943 SkScalar advance = glyphCache->getGlyphIDAdvance(0).fAdvanceX; 712 SkScalar advance = glyphCache->getGlyphIDAdvance(0).fAdvanceX;
944 const uint16_t emSize = this->getFontInfo()->fEmSize; 713 const uint16_t emSize = this->getFontInfo()->fEmSize;
945 widths->appendScalar(from_font_units(advance, emSize)); 714 widths->appendScalar(from_font_units(advance, emSize));
946 for (unsigned gID = firstGlyphID; gID <= lastGlyphID; gID++) { 715 for (unsigned gID = firstGlyphID; gID <= lastGlyphID; gID++) {
947 advance = glyphCache->getGlyphIDAdvance(gID).fAdvanceX; 716 advance = glyphCache->getGlyphIDAdvance(gID).fAdvanceX;
948 widths->appendScalar(from_font_units(advance, emSize)); 717 widths->appendScalar(from_font_units(advance, emSize));
949 } 718 }
950 this->insertObject("Widths", std::move(widths)); 719 this->insertObject("Widths", std::move(widths));
951 } 720 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 }; 774 };
1006 } 775 }
1007 776
1008 static void add_type3_font_info(SkPDFDict* font, 777 static void add_type3_font_info(SkPDFDict* font,
1009 SkTypeface* typeface, 778 SkTypeface* typeface,
1010 SkScalar emSize, 779 SkScalar emSize,
1011 const SkPDFGlyphSet* subset, 780 const SkPDFGlyphSet* subset,
1012 SkGlyphID firstGlyphID, 781 SkGlyphID firstGlyphID,
1013 SkGlyphID lastGlyphID) { 782 SkGlyphID lastGlyphID) {
1014 SkASSERT(lastGlyphID >= firstGlyphID); 783 SkASSERT(lastGlyphID >= firstGlyphID);
1015 SkPaint paint; 784 SkASSERT(emSize > 0.0f);
1016 paint.setHinting(SkPaint::kNo_Hinting); 785 SkAutoGlyphCache cache = vector_cache(typeface, emSize);
1017 paint.setTypeface(sk_ref_sp(typeface));
1018 paint.setTextSize(emSize);
1019 const SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
1020 SkAutoGlyphCache cache(paint, &props, nullptr);
1021
1022 font->insertName("Subtype", "Type3"); 786 font->insertName("Subtype", "Type3");
1023 // Flip about the x-axis and scale by 1/emSize. 787 // Flip about the x-axis and scale by 1/emSize.
1024 SkMatrix fontMatrix; 788 SkMatrix fontMatrix;
1025 fontMatrix.setScale(SkScalarInvert(emSize), -SkScalarInvert(emSize)); 789 fontMatrix.setScale(SkScalarInvert(emSize), -SkScalarInvert(emSize));
1026 font->insertObject("FontMatrix", SkPDFUtils::MatrixToArray(fontMatrix)); 790 font->insertObject("FontMatrix", SkPDFUtils::MatrixToArray(fontMatrix));
1027 791
1028 auto charProcs = sk_make_sp<SkPDFDict>(); 792 auto charProcs = sk_make_sp<SkPDFDict>();
1029 auto encoding = sk_make_sp<SkPDFDict>("Encoding"); 793 auto encoding = sk_make_sp<SkPDFDict>("Encoding");
1030 794
1031 auto encDiffs = sk_make_sp<SkPDFArray>(); 795 auto encDiffs = sk_make_sp<SkPDFArray>();
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1189 } 953 }
1190 return *canon->fCanEmbedTypeface.set(id, canEmbed); 954 return *canon->fCanEmbedTypeface.set(id, canEmbed);
1191 } 955 }
1192 956
1193 void SkPDFFont::drop() { 957 void SkPDFFont::drop() {
1194 fTypeface = nullptr; 958 fTypeface = nullptr;
1195 fFontInfo = nullptr; 959 fFontInfo = nullptr;
1196 fDescriptor = nullptr; 960 fDescriptor = nullptr;
1197 this->SkPDFDict::drop(); 961 this->SkPDFDict::drop();
1198 } 962 }
OLDNEW
« 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