1 // Copyright 2019 Google LLC.
2 // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
3
4 #include "src/pdf/SkPDFType1Font.h"
5
6 #include "include/core/SkData.h"
7 #include "include/core/SkRefCnt.h"
8 #include "include/core/SkScalar.h"
9 #include "include/core/SkStream.h"
10 #include "include/core/SkString.h"
11 #include "include/core/SkTypeface.h"
12 #include "include/core/SkTypes.h"
13 #include "include/private/base/SkMacros.h"
14 #include "include/private/base/SkSpan_impl.h"
15 #include "include/private/base/SkTemplates.h"
16 #include "include/private/base/SkTo.h"
17 #include "src/base/SkBitmaskEnum.h"
18 #include "src/core/SkAdvancedTypefaceMetrics.h"
19 #include "src/core/SkGlyph.h"
20 #include "src/core/SkStrikeSpec.h"
21 #include "src/core/SkTHash.h"
22 #include "src/pdf/SkPDFDocumentPriv.h"
23 #include "src/pdf/SkPDFFont.h"
24 #include "src/pdf/SkPDFTypes.h"
25
26 #include <ctype.h>
27 #include <cstdint>
28 #include <cstring>
29 #include <memory>
30 #include <utility>
31 #include <vector>
32
33 using namespace skia_private;
34
35 /*
36 "A standard Type 1 font program, as described in the Adobe Type 1
37 Font Format specification, consists of three parts: a clear-text
38 portion (written using PostScript syntax), an encrypted portion, and
39 a fixed-content portion. The fixed-content portion contains 512
40 ASCII zeros followed by a cleartomark operator, and perhaps followed
41 by additional data. Although the encrypted portion of a standard
42 Type 1 font may be in binary or ASCII hexadecimal format, PDF
43 supports only the binary format."
44 */
parsePFBSection(const uint8_t ** src,size_t * len,int sectionType,size_t * size)45 static bool parsePFBSection(const uint8_t** src, size_t* len, int sectionType,
46 size_t* size) {
47 // 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
49 // 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.
51 const uint8_t* buf = *src;
52 if (*len < 2 || buf[0] != 0x80 || buf[1] != sectionType) {
53 return false;
54 } else if (buf[1] == 3) {
55 return true;
56 } else if (*len < 6) {
57 return false;
58 }
59
60 *size = (size_t)buf[2] | ((size_t)buf[3] << 8) | ((size_t)buf[4] << 16) |
61 ((size_t)buf[5] << 24);
62 size_t consumed = *size + 6;
63 if (consumed > *len) {
64 return false;
65 }
66 *src = *src + consumed;
67 *len = *len - consumed;
68 return true;
69 }
70
parsePFB(const uint8_t * src,size_t size,size_t * headerLen,size_t * dataLen,size_t * trailerLen)71 static bool parsePFB(const uint8_t* src, size_t size, size_t* headerLen,
72 size_t* dataLen, size_t* trailerLen) {
73 const uint8_t* srcPtr = src;
74 size_t remaining = size;
75
76 return parsePFBSection(&srcPtr, &remaining, 1, headerLen) &&
77 parsePFBSection(&srcPtr, &remaining, 2, dataLen) &&
78 parsePFBSection(&srcPtr, &remaining, 1, trailerLen) &&
79 parsePFBSection(&srcPtr, &remaining, 3, nullptr);
80 }
81
82 /* The sections of a PFA file are implicitly defined. The body starts
83 * after the line containing "eexec," and the trailer starts with 512
84 * literal 0's followed by "cleartomark" (plus arbitrary white space).
85 *
86 * This function assumes that src is NUL terminated, but the NUL
87 * termination is not included in size.
88 *
89 */
parsePFA(const char * src,size_t size,size_t * headerLen,size_t * hexDataLen,size_t * dataLen,size_t * trailerLen)90 static bool parsePFA(const char* src, size_t size, size_t* headerLen,
91 size_t* hexDataLen, size_t* dataLen, size_t* trailerLen) {
92 const char* end = src + size;
93
94 const char* dataPos = strstr(src, "eexec");
95 if (!dataPos) {
96 return false;
97 }
98 dataPos += strlen("eexec");
99 while ((*dataPos == '\n' || *dataPos == '\r' || *dataPos == ' ') &&
100 dataPos < end) {
101 dataPos++;
102 }
103 *headerLen = dataPos - src;
104
105 const char* trailerPos = strstr(dataPos, "cleartomark");
106 if (!trailerPos) {
107 return false;
108 }
109 int zeroCount = 0;
110 for (trailerPos--; trailerPos > dataPos && zeroCount < 512; trailerPos--) {
111 if (*trailerPos == '\n' || *trailerPos == '\r' || *trailerPos == ' ') {
112 continue;
113 } else if (*trailerPos == '0') {
114 zeroCount++;
115 } else {
116 return false;
117 }
118 }
119 if (zeroCount != 512) {
120 return false;
121 }
122
123 *hexDataLen = trailerPos - src - *headerLen;
124 *trailerLen = size - *headerLen - *hexDataLen;
125
126 // Verify that the data section is hex encoded and count the bytes.
127 int nibbles = 0;
128 for (; dataPos < trailerPos; dataPos++) {
129 if (isspace(*dataPos)) {
130 continue;
131 }
132 // isxdigit() is locale-sensitive https://bugs.skia.org/8285
133 if (nullptr == strchr("0123456789abcdefABCDEF", *dataPos)) {
134 return false;
135 }
136 nibbles++;
137 }
138 *dataLen = (nibbles + 1) / 2;
139
140 return true;
141 }
142
hexToBin(uint8_t c)143 static int8_t hexToBin(uint8_t c) {
144 if (!isxdigit(c)) {
145 return -1;
146 } else if (c <= '9') {
147 return c - '0';
148 } else if (c <= 'F') {
149 return c - 'A' + 10;
150 } else if (c <= 'f') {
151 return c - 'a' + 10;
152 }
153 return -1;
154 }
155
convert_type1_font_stream(std::unique_ptr<SkStreamAsset> srcStream,size_t * headerLen,size_t * dataLen,size_t * trailerLen)156 static sk_sp<SkData> convert_type1_font_stream(std::unique_ptr<SkStreamAsset> srcStream,
157 size_t* headerLen,
158 size_t* dataLen,
159 size_t* trailerLen) {
160 size_t srcLen = srcStream ? srcStream->getLength() : 0;
161 SkASSERT(srcLen);
162 if (!srcLen) {
163 return nullptr;
164 }
165 // Flatten and Nul-terminate the source stream so that we can use
166 // strstr() to search it.
167 AutoTMalloc<uint8_t> sourceBuffer(SkToInt(srcLen + 1));
168 (void)srcStream->read(sourceBuffer.get(), srcLen);
169 sourceBuffer[SkToInt(srcLen)] = 0;
170 const uint8_t* src = sourceBuffer.get();
171
172 if (parsePFB(src, srcLen, headerLen, dataLen, trailerLen)) {
173 static const int kPFBSectionHeaderLength = 6;
174 const size_t length = *headerLen + *dataLen + *trailerLen;
175 SkASSERT(length > 0);
176 SkASSERT(length + (2 * kPFBSectionHeaderLength) <= srcLen);
177
178 sk_sp<SkData> data(SkData::MakeUninitialized(length));
179
180 const uint8_t* const srcHeader = src + kPFBSectionHeaderLength;
181 // There is a six-byte section header before header and data
182 // (but not trailer) that we're not going to copy.
183 const uint8_t* const srcData = srcHeader + *headerLen + kPFBSectionHeaderLength;
184 const uint8_t* const srcTrailer = srcData + *headerLen;
185
186 uint8_t* const resultHeader = (uint8_t*)data->writable_data();
187 uint8_t* const resultData = resultHeader + *headerLen;
188 uint8_t* const resultTrailer = resultData + *dataLen;
189
190 SkASSERT(resultTrailer + *trailerLen == resultHeader + length);
191
192 memcpy(resultHeader, srcHeader, *headerLen);
193 memcpy(resultData, srcData, *dataLen);
194 memcpy(resultTrailer, srcTrailer, *trailerLen);
195
196 return data;
197 }
198
199 // A PFA has to be converted for PDF.
200 size_t hexDataLen;
201 if (!parsePFA((const char*)src, srcLen, headerLen, &hexDataLen, dataLen,
202 trailerLen)) {
203 return nullptr;
204 }
205 const size_t length = *headerLen + *dataLen + *trailerLen;
206 SkASSERT(length > 0);
207 auto data = SkData::MakeUninitialized(length);
208 uint8_t* buffer = (uint8_t*)data->writable_data();
209
210 memcpy(buffer, src, *headerLen);
211 uint8_t* const resultData = &(buffer[*headerLen]);
212
213 const uint8_t* hexData = src + *headerLen;
214 const uint8_t* trailer = hexData + hexDataLen;
215 size_t outputOffset = 0;
216 uint8_t dataByte = 0; // To hush compiler.
217 bool highNibble = true;
218 for (; hexData < trailer; hexData++) {
219 int8_t curNibble = hexToBin(*hexData);
220 if (curNibble < 0) {
221 continue;
222 }
223 if (highNibble) {
224 dataByte = curNibble << 4;
225 highNibble = false;
226 } else {
227 dataByte |= curNibble;
228 highNibble = true;
229 resultData[outputOffset++] = dataByte;
230 }
231 }
232 if (!highNibble) {
233 resultData[outputOffset++] = dataByte;
234 }
235 SkASSERT(outputOffset == *dataLen);
236
237 uint8_t* const resultTrailer = &(buffer[SkToInt(*headerLen + outputOffset)]);
238 memcpy(resultTrailer, src + *headerLen + hexDataLen, *trailerLen);
239 return data;
240 }
241
can_embed(const SkAdvancedTypefaceMetrics & metrics)242 inline static bool can_embed(const SkAdvancedTypefaceMetrics& metrics) {
243 return !SkToBool(metrics.fFlags & SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag);
244 }
245
from_font_units(SkScalar scaled,uint16_t emSize)246 inline static SkScalar from_font_units(SkScalar scaled, uint16_t emSize) {
247 return emSize == 1000 ? scaled : scaled * 1000 / emSize;
248 }
249
make_type1_font_descriptor(SkPDFDocument * doc,const SkPDFStrikeSpec & pdfStrikeSpec,const SkAdvancedTypefaceMetrics * info)250 static SkPDFIndirectReference make_type1_font_descriptor(SkPDFDocument* doc,
251 const SkPDFStrikeSpec& pdfStrikeSpec,
252 const SkAdvancedTypefaceMetrics* info) {
253 SkPDFDict descriptor("FontDescriptor");
254 uint16_t emSize = SkToU16(SkScalarRoundToInt(pdfStrikeSpec.fUnitsPerEM));
255 if (info) {
256 SkPDFFont::PopulateCommonFontDescriptor(&descriptor, *info, emSize, 0);
257 if (can_embed(*info)) {
258 int ttcIndex;
259 size_t header SK_INIT_TO_AVOID_WARNING;
260 size_t data SK_INIT_TO_AVOID_WARNING;
261 size_t trailer SK_INIT_TO_AVOID_WARNING;
262 const SkTypeface& typeface = pdfStrikeSpec.fStrikeSpec.typeface();
263 std::unique_ptr<SkStreamAsset> rawFontData = typeface.openStream(&ttcIndex);
264 sk_sp<SkData> fontData = convert_type1_font_stream(std::move(rawFontData),
265 &header, &data, &trailer);
266 if (fontData) {
267 std::unique_ptr<SkPDFDict> dict = SkPDFMakeDict();
268 dict->insertInt("Length1", header);
269 dict->insertInt("Length2", data);
270 dict->insertInt("Length3", trailer);
271 auto fontStream = SkMemoryStream::Make(std::move(fontData));
272 descriptor.insertRef("FontFile",
273 SkPDFStreamOut(std::move(dict), std::move(fontStream),
274 doc, SkPDFSteamCompressionEnabled::Yes));
275 }
276 }
277 }
278 return doc->emit(descriptor);
279 }
280
281
type_1_glyphnames(SkPDFDocument * canon,const SkTypeface & typeface)282 static const std::vector<SkString>& type_1_glyphnames(SkPDFDocument* canon,
283 const SkTypeface& typeface) {
284 SkTypefaceID typefaceID = typeface.uniqueID();
285 const std::vector<SkString>* glyphNames = canon->fType1GlyphNames.find(typefaceID);
286 if (!glyphNames) {
287 std::vector<SkString> names(typeface.countGlyphs());
288 SkPDFFont::GetType1GlyphNames(typeface, names.data());
289 glyphNames = canon->fType1GlyphNames.set(typefaceID, std::move(names));
290 }
291 SkASSERT(glyphNames);
292 return *glyphNames;
293 }
294
type1_font_descriptor(SkPDFDocument * doc,const SkPDFStrikeSpec & pdfStrikeSpec)295 static SkPDFIndirectReference type1_font_descriptor(SkPDFDocument* doc,
296 const SkPDFStrikeSpec& pdfStrikeSpec) {
297 const SkTypeface& typeface = pdfStrikeSpec.fStrikeSpec.typeface();
298 SkTypefaceID typefaceID = typeface.uniqueID();
299 if (SkPDFIndirectReference* ptr = doc->fFontDescriptors.find(typefaceID)) {
300 return *ptr;
301 }
302 const SkAdvancedTypefaceMetrics* info = SkPDFFont::GetMetrics(typeface, doc);
303 auto fontDescriptor = make_type1_font_descriptor(doc, pdfStrikeSpec, info);
304 doc->fFontDescriptors.set(typefaceID, fontDescriptor);
305 return fontDescriptor;
306 }
307
308
SkPDFEmitType1Font(const SkPDFFont & pdfFont,SkPDFDocument * doc)309 void SkPDFEmitType1Font(const SkPDFFont& pdfFont, SkPDFDocument* doc) {
310 const SkTypeface& typeface = pdfFont.strike().fPath.fStrikeSpec.typeface();
311 const std::vector<SkString>& glyphNames = type_1_glyphnames(doc, typeface);
312 SkGlyphID firstGlyphID = pdfFont.firstGlyphID();
313 SkGlyphID lastGlyphID = pdfFont.lastGlyphID();
314
315 SkPDFDict font("Font");
316 font.insertRef("FontDescriptor", type1_font_descriptor(doc, pdfFont.strike().fPath));
317 font.insertName("Subtype", "Type1");
318 if (const SkAdvancedTypefaceMetrics* info = SkPDFFont::GetMetrics(typeface, doc)) {
319 font.insertName("BaseFont", info->fPostScriptName);
320 }
321
322 // glyphCount not including glyph 0
323 unsigned glyphCount = 1 + lastGlyphID - firstGlyphID;
324 SkASSERT(glyphCount > 0 && glyphCount <= 255);
325 font.insertInt("FirstChar", (size_t)0);
326 font.insertInt("LastChar", (size_t)glyphCount);
327 {
328 int emSize = pdfFont.strike().fPath.fUnitsPerEM;
329 auto widths = SkPDFMakeArray();
330
331 int glyphRangeSize = lastGlyphID - firstGlyphID + 2;
332 AutoTArray<SkGlyphID> glyphIDs{glyphRangeSize};
333 glyphIDs[0] = 0;
334 for (unsigned gId = firstGlyphID; gId <= lastGlyphID; gId++) {
335 glyphIDs[gId - firstGlyphID + 1] = gId;
336 }
337 SkBulkGlyphMetrics metrics{pdfFont.strike().fPath.fStrikeSpec};
338 auto glyphs = metrics.glyphs(SkSpan(glyphIDs.get(), glyphRangeSize));
339 for (int i = 0; i < glyphRangeSize; ++i) {
340 widths->appendScalar(from_font_units(glyphs[i]->advanceX(), SkToU16(emSize)));
341 }
342 font.insertObject("Widths", std::move(widths));
343 }
344 auto encDiffs = SkPDFMakeArray();
345 encDiffs->reserve(lastGlyphID - firstGlyphID + 3);
346 encDiffs->appendInt(0);
347
348 SkASSERT(glyphNames.size() > lastGlyphID);
349 const SkString unknown("UNKNOWN");
350 encDiffs->appendName(glyphNames[0].isEmpty() ? unknown : glyphNames[0]);
351 for (int gID = firstGlyphID; gID <= lastGlyphID; gID++) {
352 encDiffs->appendName(glyphNames[gID].isEmpty() ? unknown : glyphNames[gID]);
353 }
354
355 auto encoding = SkPDFMakeDict("Encoding");
356 encoding->insertObject("Differences", std::move(encDiffs));
357 font.insertObject("Encoding", std::move(encoding));
358
359 doc->emit(font, pdfFont.indirectReference());
360 }
361