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

Side by Side Diff: src/pdf/SkPDFFont.cpp

Issue 2222523003: SkPDF/SkAdvancedTypefaceMetrics: simplify ATM, PDF takes over (Closed) Base URL: https://skia.googlesource.com/skia.git@SkPDF_no_kHAdvance
Patch Set: 2016-08-07 (Sunday) 08:21:11 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/core/SkAdvancedTypefaceMetrics.cpp ('k') | src/pdf/SkPDFFontImpl.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 <ctype.h> 8 #include <ctype.h>
9 9
10 #include "SkData.h" 10 #include "SkData.h"
(...skipping 18 matching lines...) Expand all
29 #else 29 #else
30 #include SK_SFNTLY_SUBSETTER 30 #include SK_SFNTLY_SUBSETTER
31 #endif 31 #endif
32 #endif 32 #endif
33 33
34 // PDF's notion of symbolic vs non-symbolic is related to the character set, not 34 // PDF's notion of symbolic vs non-symbolic is related to the character set, not
35 // symbols vs. characters. Rarely is a font the right character set to call it 35 // symbols vs. characters. Rarely is a font the right character set to call it
36 // non-symbolic, so always call it symbolic. (PDF 1.4 spec, section 5.7.1) 36 // non-symbolic, so always call it symbolic. (PDF 1.4 spec, section 5.7.1)
37 static const int kPdfSymbolic = 4; 37 static const int kPdfSymbolic = 4;
38 38
39 struct AdvanceMetric {
40 enum MetricType {
41 kDefault, // Default advance: fAdvance.count = 1
42 kRange, // Advances for a range: fAdvance.count = fEndID-fStartID
43 kRun // fStartID-fEndID have same advance: fAdvance.count = 1
44 };
45 MetricType fType;
46 uint16_t fStartId;
47 uint16_t fEndId;
48 SkTDArray<int16_t> fAdvance;
49 AdvanceMetric(uint16_t startId) : fStartId(startId) {}
50 AdvanceMetric(AdvanceMetric&& other)
51 : fType(other.fType)
52 , fStartId(other.fStartId)
53 , fEndId(other.fEndId) {
54 fAdvance.swap(other.fAdvance);
55 }
56 AdvanceMetric& operator=(AdvanceMetric&& other) {
57 fType = other.fType;
58 fStartId = other.fStartId;
59 fEndId = other.fEndId;
60 fAdvance.swap(other.fAdvance);
61 return *this;
62 }
63 AdvanceMetric(const AdvanceMetric&) = delete;
64 AdvanceMetric& operator=(const AdvanceMetric&) = delete;
65 };
66
39 namespace { 67 namespace {
40 68
41 /////////////////////////////////////////////////////////////////////////////// 69 ///////////////////////////////////////////////////////////////////////////////
42 // File-Local Functions 70 // File-Local Functions
43 /////////////////////////////////////////////////////////////////////////////// 71 ///////////////////////////////////////////////////////////////////////////////
44 72
73 const int16_t kInvalidAdvance = SK_MinS16;
74 const int16_t kDontCareAdvance = SK_MinS16 + 1;
75
76 static void stripUninterestingTrailingAdvancesFromRange(
77 AdvanceMetric* range) {
78 SkASSERT(range);
79
80 int expectedAdvanceCount = range->fEndId - range->fStartId + 1;
81 if (range->fAdvance.count() < expectedAdvanceCount) {
82 return;
83 }
84
85 for (int i = expectedAdvanceCount - 1; i >= 0; --i) {
86 if (range->fAdvance[i] != kDontCareAdvance &&
87 range->fAdvance[i] != kInvalidAdvance &&
88 range->fAdvance[i] != 0) {
89 range->fEndId = range->fStartId + i;
90 break;
91 }
92 }
93 }
94
95 static void zeroWildcardsInRange(AdvanceMetric* range) {
96 SkASSERT(range);
97 if (range->fType != AdvanceMetric::kRange) {
98 return;
99 }
100 SkASSERT(range->fAdvance.count() == range->fEndId - range->fStartId + 1);
101
102 // Zero out wildcards.
103 for (int i = 0; i < range->fAdvance.count(); ++i) {
104 if (range->fAdvance[i] == kDontCareAdvance) {
105 range->fAdvance[i] = 0;
106 }
107 }
108 }
109
110 static void FinishRange(
111 AdvanceMetric* range,
112 int endId,
113 AdvanceMetric::MetricType type) {
114 range->fEndId = endId;
115 range->fType = type;
116 stripUninterestingTrailingAdvancesFromRange(range);
117 int newLength;
118 if (type == AdvanceMetric::kRange) {
119 newLength = range->fEndId - range->fStartId + 1;
120 } else {
121 if (range->fEndId == range->fStartId) {
122 range->fType = AdvanceMetric::kRange;
123 }
124 newLength = 1;
125 }
126 SkASSERT(range->fAdvance.count() >= newLength);
127 range->fAdvance.setCount(newLength);
128 zeroWildcardsInRange(range);
129 }
130
131
132 /** Retrieve advance data for glyphs. Used by the PDF backend.
133 @param num_glyphs Total number of glyphs in the given font.
134 @param glyphIDs For per-glyph info, specify subset of the
135 font by giving glyph ids. Each integer
136 represents a glyph id. Passing nullptr
137 means all glyphs in the font.
138 @param glyphIDsCount Number of elements in subsetGlyphIds.
139 Ignored if glyphIDs is nullptr.
140 */
141 // TODO(halcanary): this function is complex enough to need its logic
142 // tested with unit tests. On the other hand, I want to do another
143 // round of re-factoring before figuring out how to mock this.
144 // TODO(halcanary): this function should be combined with
145 // composeAdvanceData() so that we don't need to produce a linked list
146 // of intermediate values. Or we could make the intermediate value
147 // something other than a linked list.
148 static void get_glyph_widths(SkSinglyLinkedList<AdvanceMetric>* glyphWidths,
149 int num_glyphs,
150 const uint32_t* subsetGlyphIDs,
151 uint32_t subsetGlyphIDsLength,
152 SkGlyphCache* glyphCache) {
153 // Assuming that on average, the ASCII representation of an advance plus
154 // a space is 8 characters and the ASCII representation of a glyph id is 3
155 // characters, then the following cut offs for using different range types
156 // apply:
157 // The cost of stopping and starting the range is 7 characers
158 // a. Removing 4 0's or don't care's is a win
159 // The cost of stopping and starting the range plus a run is 22
160 // characters
161 // b. Removing 3 repeating advances is a win
162 // c. Removing 2 repeating advances and 3 don't cares is a win
163 // When not currently in a range the cost of a run over a range is 16
164 // characaters, so:
165 // d. Removing a leading 0/don't cares is a win because it is omitted
166 // e. Removing 2 repeating advances is a win
167
168 AdvanceMetric* prevRange = nullptr;
169 int16_t lastAdvance = kInvalidAdvance;
170 int repeatedAdvances = 0;
171 int wildCardsInRun = 0;
172 int trailingWildCards = 0;
173 uint32_t subsetIndex = 0;
174
175 // Limit the loop count to glyph id ranges provided.
176 int firstIndex = 0;
177 int lastIndex = num_glyphs;
178 if (subsetGlyphIDs) {
179 firstIndex = static_cast<int>(subsetGlyphIDs[0]);
180 lastIndex =
181 static_cast<int>(subsetGlyphIDs[subsetGlyphIDsLength - 1]) + 1;
182 }
183 AdvanceMetric curRange(firstIndex);
184
185 for (int gId = firstIndex; gId <= lastIndex; gId++) {
186 int16_t advance = kInvalidAdvance;
187 if (gId < lastIndex) {
188 // Get glyph id only when subset is nullptr, or the id is in subset.
189 SkASSERT(!subsetGlyphIDs || (subsetIndex < subsetGlyphIDsLength &&
190 static_cast<uint32_t>(gId) <= subsetGlyphIDs[subsetIndex]));
191 if (!subsetGlyphIDs ||
192 (subsetIndex < subsetGlyphIDsLength &&
193 static_cast<uint32_t>(gId) == subsetGlyphIDs[subsetIndex])) {
194 advance = (int16_t)glyphCache->getGlyphIDAdvance(gId).fAdvanceX;
195 ++subsetIndex;
196 } else {
197 advance = kDontCareAdvance;
198 }
199 }
200 if (advance == lastAdvance) {
201 repeatedAdvances++;
202 trailingWildCards = 0;
203 } else if (advance == kDontCareAdvance) {
204 wildCardsInRun++;
205 trailingWildCards++;
206 } else if (curRange.fAdvance.count() ==
207 repeatedAdvances + 1 + wildCardsInRun) { // All in run.
208 if (lastAdvance == 0) {
209 curRange.fStartId = gId; // reset
210 curRange.fAdvance.setCount(0);
211 trailingWildCards = 0;
212 } else if (repeatedAdvances + 1 >= 2 || trailingWildCards >= 4) {
213 FinishRange(&curRange, gId - 1, AdvanceMetric::kRun);
214 prevRange = glyphWidths->emplace_back(std::move(curRange));
215 curRange = AdvanceMetric(gId);
216 trailingWildCards = 0;
217 }
218 repeatedAdvances = 0;
219 wildCardsInRun = trailingWildCards;
220 trailingWildCards = 0;
221 } else {
222 if (lastAdvance == 0 &&
223 repeatedAdvances + 1 + wildCardsInRun >= 4) {
224 FinishRange(&curRange,
225 gId - repeatedAdvances - wildCardsInRun - 2,
226 AdvanceMetric::kRange);
227 prevRange = glyphWidths->emplace_back(std::move(curRange));
228 curRange = AdvanceMetric(gId);
229 trailingWildCards = 0;
230 } else if (trailingWildCards >= 4 && repeatedAdvances + 1 < 2) {
231 FinishRange(&curRange, gId - trailingWildCards - 1,
232 AdvanceMetric::kRange);
233 prevRange = glyphWidths->emplace_back(std::move(curRange));
234 curRange = AdvanceMetric(gId);
235 trailingWildCards = 0;
236 } else if (lastAdvance != 0 &&
237 (repeatedAdvances + 1 >= 3 ||
238 (repeatedAdvances + 1 >= 2 && wildCardsInRun >= 3))) {
239 FinishRange(&curRange,
240 gId - repeatedAdvances - wildCardsInRun - 2,
241 AdvanceMetric::kRange);
242 (void)glyphWidths->emplace_back(std::move(curRange));
243 curRange =
244 AdvanceMetric(gId - repeatedAdvances - wildCardsInRun - 1);
245 curRange.fAdvance.append(1, &lastAdvance);
246 FinishRange(&curRange, gId - 1, AdvanceMetric::kRun);
247 prevRange = glyphWidths->emplace_back(std::move(curRange));
248 curRange = AdvanceMetric(gId);
249 trailingWildCards = 0;
250 }
251 repeatedAdvances = 0;
252 wildCardsInRun = trailingWildCards;
253 trailingWildCards = 0;
254 }
255 curRange.fAdvance.append(1, &advance);
256 if (advance != kDontCareAdvance) {
257 lastAdvance = advance;
258 }
259 }
260 if (curRange.fStartId == lastIndex) {
261 if (!prevRange) {
262 glyphWidths->reset();
263 return; // https://crbug.com/567031
264 }
265 } else {
266 FinishRange(&curRange, lastIndex - 1, AdvanceMetric::kRange);
267 glyphWidths->emplace_back(std::move(curRange));
268 }
269 }
270
271 ////////////////////////////////////////////////////////////////////////////////
272
273
45 bool parsePFBSection(const uint8_t** src, size_t* len, int sectionType, 274 bool parsePFBSection(const uint8_t** src, size_t* len, int sectionType,
46 size_t* size) { 275 size_t* size) {
47 // PFB sections have a two or six bytes header. 0x80 and a one byte 276 // PFB sections have a two or six bytes header. 0x80 and a one byte
48 // section type followed by a four byte section length. Type one is 277 // section type followed by a four byte section length. Type one is
49 // an ASCII section (includes a length), type two is a binary section 278 // an ASCII section (includes a length), type two is a binary section
50 // (includes a length) and type three is an EOF marker with no length. 279 // (includes a length) and type three is an EOF marker with no length.
51 const uint8_t* buf = *src; 280 const uint8_t* buf = *src;
52 if (*len < 2 || buf[0] != 0x80 || buf[1] != sectionType) { 281 if (*len < 2 || buf[0] != 0x80 || buf[1] != sectionType) {
53 return false; 282 return false;
54 } else if (buf[1] == 3) { 283 } else if (buf[1] == 3) {
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 auto bbox = sk_make_sp<SkPDFArray>(); 524 auto bbox = sk_make_sp<SkPDFArray>();
296 bbox->reserve(4); 525 bbox->reserve(4);
297 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fLeft, emSize)); 526 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fLeft, emSize));
298 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fBottom, emSize)); 527 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fBottom, emSize));
299 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fRight, emSize)); 528 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fRight, emSize));
300 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fTop, emSize)); 529 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fTop, emSize));
301 return bbox; 530 return bbox;
302 } 531 }
303 532
304 sk_sp<SkPDFArray> composeAdvanceData( 533 sk_sp<SkPDFArray> composeAdvanceData(
305 const SkSinglyLinkedList<SkAdvancedTypefaceMetrics::WidthRange>& advance Info, 534 const SkSinglyLinkedList<AdvanceMetric>& advanceInfo,
306 uint16_t emSize, 535 uint16_t emSize,
307 int16_t* defaultAdvance) { 536 int16_t* defaultAdvance) {
308 auto result = sk_make_sp<SkPDFArray>(); 537 auto result = sk_make_sp<SkPDFArray>();
309 for (const SkAdvancedTypefaceMetrics::WidthRange& range : advanceInfo) { 538 for (const AdvanceMetric& range : advanceInfo) {
310 switch (range.fType) { 539 switch (range.fType) {
311 case SkAdvancedTypefaceMetrics::WidthRange::kDefault: { 540 case AdvanceMetric::kDefault: {
312 SkASSERT(range.fAdvance.count() == 1); 541 SkASSERT(range.fAdvance.count() == 1);
313 *defaultAdvance = range.fAdvance[0]; 542 *defaultAdvance = range.fAdvance[0];
314 break; 543 break;
315 } 544 }
316 case SkAdvancedTypefaceMetrics::WidthRange::kRange: { 545 case AdvanceMetric::kRange: {
317 auto advanceArray = sk_make_sp<SkPDFArray>(); 546 auto advanceArray = sk_make_sp<SkPDFArray>();
318 for (int j = 0; j < range.fAdvance.count(); j++) 547 for (int j = 0; j < range.fAdvance.count(); j++)
319 advanceArray->appendScalar( 548 advanceArray->appendScalar(
320 scaleFromFontUnits(range.fAdvance[j], emSize)); 549 scaleFromFontUnits(range.fAdvance[j], emSize));
321 result->appendInt(range.fStartId); 550 result->appendInt(range.fStartId);
322 result->appendObject(std::move(advanceArray)); 551 result->appendObject(std::move(advanceArray));
323 break; 552 break;
324 } 553 }
325 case SkAdvancedTypefaceMetrics::WidthRange::kRun: { 554 case AdvanceMetric::kRun: {
326 SkASSERT(range.fAdvance.count() == 1); 555 SkASSERT(range.fAdvance.count() == 1);
327 result->appendInt(range.fStartId); 556 result->appendInt(range.fStartId);
328 result->appendInt(range.fEndId); 557 result->appendInt(range.fEndId);
329 result->appendScalar( 558 result->appendScalar(
330 scaleFromFontUnits(range.fAdvance[0], emSize)); 559 scaleFromFontUnits(range.fAdvance[0], emSize));
331 break; 560 break;
332 } 561 }
333 } 562 }
334 } 563 }
335 return result; 564 return result;
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 } 1264 }
1036 default: 1265 default:
1037 SkASSERT(false); 1266 SkASSERT(false);
1038 } 1267 }
1039 this->insertObjRef("FontDescriptor", std::move(descriptor)); 1268 this->insertObjRef("FontDescriptor", std::move(descriptor));
1040 return true; 1269 return true;
1041 } 1270 }
1042 1271
1043 void set_glyph_widths(SkTypeface* tf, 1272 void set_glyph_widths(SkTypeface* tf,
1044 const SkTDArray<uint32_t>* glyphIDs, 1273 const SkTDArray<uint32_t>* glyphIDs,
1045 SkAdvancedTypefaceMetrics* dst) { 1274 SkSinglyLinkedList<AdvanceMetric>* dst) {
1046 SkPaint tmpPaint; 1275 SkPaint tmpPaint;
1047 tmpPaint.setHinting(SkPaint::kNo_Hinting); 1276 tmpPaint.setHinting(SkPaint::kNo_Hinting);
1048 tmpPaint.setTypeface(sk_ref_sp(tf)); 1277 tmpPaint.setTypeface(sk_ref_sp(tf));
1049 tmpPaint.setTextSize((SkScalar)tf->getUnitsPerEm()); 1278 tmpPaint.setTextSize((SkScalar)tf->getUnitsPerEm());
1050 SkAutoGlyphCache autoGlyphCache(tmpPaint, nullptr, nullptr); 1279 SkAutoGlyphCache autoGlyphCache(tmpPaint, nullptr, nullptr);
1051 SkGlyphCache* glyphCache = autoGlyphCache.get();
1052 SkAdvancedTypefaceMetrics::GetAdvance advanceFn =
1053 [glyphCache](int gid, int16_t* advance) {
1054 *advance = (int16_t)glyphCache->getGlyphIDAdvance(gid).fAdvanceX;
1055 return true;
1056 };
1057 if (!glyphIDs || glyphIDs->isEmpty()) { 1280 if (!glyphIDs || glyphIDs->isEmpty()) {
1058 dst->setGlyphWidths(tf->countGlyphs(), nullptr, 0, advanceFn); 1281 get_glyph_widths(dst, tf->countGlyphs(), nullptr, 0, autoGlyphCache.get( ));
1059 } else { 1282 } else {
1060 dst->setGlyphWidths(tf->countGlyphs(), 1283 get_glyph_widths(dst, tf->countGlyphs(),
1061 glyphIDs->begin(), 1284 glyphIDs->begin(),
bungeman-skia 2016/08/08 14:06:09 nit: indentation
hal.canary 2016/08/08 15:48:19 Done.
1062 glyphIDs->count(), advanceFn); 1285 glyphIDs->count(), autoGlyphCache.get());
1063 } 1286 }
1064 } 1287 }
1065 1288
1066 bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) { 1289 bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) {
1067 // Generate new font metrics with advance info for true type fonts. 1290 // Generate new font metrics with advance info for true type fonts.
1068 // Generate glyph id array. 1291 // Generate glyph id array.
1069 SkTDArray<uint32_t> glyphIDs; 1292 SkTDArray<uint32_t> glyphIDs;
1070 if (subset) { 1293 if (subset) {
1071 if (!subset->has(0)) { 1294 if (!subset->has(0)) {
1072 glyphIDs.push(0); // Always include glyph 0. 1295 glyphIDs.push(0); // Always include glyph 0.
(...skipping 23 matching lines...) Expand all
1096 } else { 1319 } else {
1097 SkASSERT(false); 1320 SkASSERT(false);
1098 } 1321 }
1099 1322
1100 auto sysInfo = sk_make_sp<SkPDFDict>(); 1323 auto sysInfo = sk_make_sp<SkPDFDict>();
1101 sysInfo->insertString("Registry", "Adobe"); 1324 sysInfo->insertString("Registry", "Adobe");
1102 sysInfo->insertString("Ordering", "Identity"); 1325 sysInfo->insertString("Ordering", "Identity");
1103 sysInfo->insertInt("Supplement", 0); 1326 sysInfo->insertInt("Supplement", 0);
1104 this->insertObject("CIDSystemInfo", std::move(sysInfo)); 1327 this->insertObject("CIDSystemInfo", std::move(sysInfo));
1105 1328
1106 SkAdvancedTypefaceMetrics tmpMetrics; 1329 SkSinglyLinkedList<AdvanceMetric> tmpMetrics;
1107 set_glyph_widths(this->typeface(), &glyphIDs, &tmpMetrics); 1330 set_glyph_widths(this->typeface(), &glyphIDs, &tmpMetrics);
1108 int16_t defaultWidth = 0; 1331 int16_t defaultWidth = 0;
1109 uint16_t emSize = (uint16_t)this->fontInfo()->fEmSize; 1332 uint16_t emSize = (uint16_t)this->fontInfo()->fEmSize;
1110 sk_sp<SkPDFArray> widths = composeAdvanceData( 1333 sk_sp<SkPDFArray> widths = composeAdvanceData(tmpMetrics, emSize, &defaultWi dth);
1111 tmpMetrics.fGlyphWidths, emSize, &defaultWidth);
1112 if (widths->size()) { 1334 if (widths->size()) {
1113 this->insertObject("W", std::move(widths)); 1335 this->insertObject("W", std::move(widths));
1114 } 1336 }
1115 1337
1116 this->insertScalar( 1338 this->insertScalar(
1117 "DW", scaleFromFontUnits(defaultWidth, emSize)); 1339 "DW", scaleFromFontUnits(defaultWidth, emSize));
1118 return true; 1340 return true;
1119 } 1341 }
1120 1342
1121 /////////////////////////////////////////////////////////////////////////////// 1343 ///////////////////////////////////////////////////////////////////////////////
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1162 fontStream->dict()->insertInt("Length2", data); 1384 fontStream->dict()->insertInt("Length2", data);
1163 fontStream->dict()->insertInt("Length3", trailer); 1385 fontStream->dict()->insertInt("Length3", trailer);
1164 descriptor->insertObjRef("FontFile", std::move(fontStream)); 1386 descriptor->insertObjRef("FontFile", std::move(fontStream));
1165 1387
1166 this->insertObjRef("FontDescriptor", std::move(descriptor)); 1388 this->insertObjRef("FontDescriptor", std::move(descriptor));
1167 1389
1168 return addCommonFontDescriptorEntries(defaultWidth); 1390 return addCommonFontDescriptorEntries(defaultWidth);
1169 } 1391 }
1170 1392
1171 bool SkPDFType1Font::populate(int16_t glyphID) { 1393 bool SkPDFType1Font::populate(int16_t glyphID) {
1172 SkASSERT(fontInfo()->fVerticalMetrics.empty());
1173 SkASSERT(fontInfo()->fGlyphWidths.empty());
1174
1175 adjustGlyphRangeForSingleByteEncoding(glyphID); 1394 adjustGlyphRangeForSingleByteEncoding(glyphID);
1176 1395
1177 int16_t defaultWidth = 0; 1396 int16_t defaultWidth = 0;
1178 const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry = nullptr; 1397 const AdvanceMetric* widthRangeEntry = nullptr;
1179 { 1398 {
1180 SkAdvancedTypefaceMetrics tmpMetrics; 1399 SkSinglyLinkedList<AdvanceMetric> tmpMetrics;
1181 set_glyph_widths(this->typeface(), nullptr, &tmpMetrics); 1400 set_glyph_widths(this->typeface(), nullptr, &tmpMetrics);
1182 for (const auto& widthEntry : tmpMetrics.fGlyphWidths) { 1401 for (const auto& widthEntry : tmpMetrics) {
1183 switch (widthEntry.fType) { 1402 switch (widthEntry.fType) {
1184 case SkAdvancedTypefaceMetrics::WidthRange::kDefault: 1403 case AdvanceMetric::kDefault:
1185 defaultWidth = widthEntry.fAdvance[0]; 1404 defaultWidth = widthEntry.fAdvance[0];
1186 break; 1405 break;
1187 case SkAdvancedTypefaceMetrics::WidthRange::kRun: 1406 case AdvanceMetric::kRun:
1188 SkASSERT(false); 1407 SkASSERT(false);
1189 break; 1408 break;
1190 case SkAdvancedTypefaceMetrics::WidthRange::kRange: 1409 case AdvanceMetric::kRange:
1191 SkASSERT(widthRangeEntry == nullptr); 1410 SkASSERT(widthRangeEntry == nullptr);
1192 widthRangeEntry = &widthEntry; 1411 widthRangeEntry = &widthEntry;
1193 break; 1412 break;
1194 } 1413 }
1195 } 1414 }
1196 } 1415 }
1197 1416
1198 if (!addFontDescriptor(defaultWidth)) { 1417 if (!addFontDescriptor(defaultWidth)) {
1199 return false; 1418 return false;
1200 } 1419 }
1201 1420
1202 insertName("Subtype", "Type1"); 1421 insertName("Subtype", "Type1");
1203 insertName("BaseFont", fontInfo()->fFontName); 1422 insertName("BaseFont", fontInfo()->fFontName);
1204 1423
1205 addWidthInfoFromRange(defaultWidth, widthRangeEntry); 1424 addWidthInfoFromRange(defaultWidth, widthRangeEntry);
1206 auto encDiffs = sk_make_sp<SkPDFArray>(); 1425 auto encDiffs = sk_make_sp<SkPDFArray>();
1207 encDiffs->reserve(lastGlyphID() - firstGlyphID() + 2); 1426 encDiffs->reserve(lastGlyphID() - firstGlyphID() + 2);
1208 encDiffs->appendInt(1); 1427 encDiffs->appendInt(1);
1428 SkASSERT(this->fontInfo()->fGlyphNames.count() >= this->lastGlyphID());
1209 for (int gID = firstGlyphID(); gID <= lastGlyphID(); gID++) { 1429 for (int gID = firstGlyphID(); gID <= lastGlyphID(); gID++) {
1210 encDiffs->appendName(fontInfo()->fGlyphNames->get()[gID].c_str()); 1430 encDiffs->appendName(fontInfo()->fGlyphNames[gID].c_str());
1211 } 1431 }
1212 1432
1213 auto encoding = sk_make_sp<SkPDFDict>("Encoding"); 1433 auto encoding = sk_make_sp<SkPDFDict>("Encoding");
1214 encoding->insertObject("Differences", std::move(encDiffs)); 1434 encoding->insertObject("Differences", std::move(encDiffs));
1215 this->insertObject("Encoding", std::move(encoding)); 1435 this->insertObject("Encoding", std::move(encoding));
1216 return true; 1436 return true;
1217 } 1437 }
1218 1438
1219 void SkPDFType1Font::addWidthInfoFromRange( 1439 void SkPDFType1Font::addWidthInfoFromRange(
1220 int16_t defaultWidth, 1440 int16_t defaultWidth,
1221 const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry) { 1441 const AdvanceMetric* widthRangeEntry) {
1222 auto widthArray = sk_make_sp<SkPDFArray>(); 1442 auto widthArray = sk_make_sp<SkPDFArray>();
1223 int firstChar = 0; 1443 int firstChar = 0;
1224 if (widthRangeEntry) { 1444 if (widthRangeEntry) {
1225 const uint16_t emSize = fontInfo()->fEmSize; 1445 const uint16_t emSize = fontInfo()->fEmSize;
1226 int startIndex = firstGlyphID() - widthRangeEntry->fStartId; 1446 int startIndex = firstGlyphID() - widthRangeEntry->fStartId;
1227 int endIndex = startIndex + lastGlyphID() - firstGlyphID() + 1; 1447 int endIndex = startIndex + lastGlyphID() - firstGlyphID() + 1;
1228 if (startIndex < 0) 1448 if (startIndex < 0)
1229 startIndex = 0; 1449 startIndex = 0;
1230 if (endIndex > widthRangeEntry->fAdvance.count()) 1450 if (endIndex > widthRangeEntry->fAdvance.count())
1231 endIndex = widthRangeEntry->fAdvance.count(); 1451 endIndex = widthRangeEntry->fAdvance.count();
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1370 } 1590 }
1371 return *canon->fCanEmbedTypeface.set(id, canEmbed); 1591 return *canon->fCanEmbedTypeface.set(id, canEmbed);
1372 } 1592 }
1373 1593
1374 void SkPDFFont::drop() { 1594 void SkPDFFont::drop() {
1375 fTypeface = nullptr; 1595 fTypeface = nullptr;
1376 fFontInfo = nullptr; 1596 fFontInfo = nullptr;
1377 fDescriptor = nullptr; 1597 fDescriptor = nullptr;
1378 this->SkPDFDict::drop(); 1598 this->SkPDFDict::drop();
1379 } 1599 }
OLDNEW
« no previous file with comments | « src/core/SkAdvancedTypefaceMetrics.cpp ('k') | src/pdf/SkPDFFontImpl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698