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