SkPDFFont.cpp revision 6b7f34e34cc0ce397ce5e4ddc0c244f372b4f840
1/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include <ctype.h>
9
10#include "SkData.h"
11#include "SkGlyphCache.h"
12#include "SkPaint.h"
13#include "SkPDFCanon.h"
14#include "SkPDFDevice.h"
15#include "SkPDFFont.h"
16#include "SkPDFFontImpl.h"
17#include "SkPDFStream.h"
18#include "SkPDFTypes.h"
19#include "SkPDFUtils.h"
20#include "SkRefCnt.h"
21#include "SkScalar.h"
22#include "SkStream.h"
23#include "SkTypefacePriv.h"
24#include "SkTypes.h"
25#include "SkUtils.h"
26
27#if defined (GOOGLE3)
28    // #including #defines doesn't work in with this build system.
29    #include "typography/font/sfntly/src/sample/chromium/font_subsetter.h"
30    #define SK_SFNTLY_SUBSETTER  // For the benefit of #ifdefs below.
31#elif defined (SK_SFNTLY_SUBSETTER)
32    #include SK_SFNTLY_SUBSETTER
33#endif
34
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
37// non-symbolic, so always call it symbolic.  (PDF 1.4 spec, section 5.7.1)
38static const int kPdfSymbolic = 4;
39
40namespace {
41
42///////////////////////////////////////////////////////////////////////////////
43// File-Local Functions
44///////////////////////////////////////////////////////////////////////////////
45
46bool parsePFBSection(const uint8_t** src, size_t* len, int sectionType,
47                     size_t* size) {
48    // PFB sections have a two or six bytes header. 0x80 and a one byte
49    // section type followed by a four byte section length.  Type one is
50    // an ASCII section (includes a length), type two is a binary section
51    // (includes a length) and type three is an EOF marker with no length.
52    const uint8_t* buf = *src;
53    if (*len < 2 || buf[0] != 0x80 || buf[1] != sectionType) {
54        return false;
55    } else if (buf[1] == 3) {
56        return true;
57    } else if (*len < 6) {
58        return false;
59    }
60
61    *size = (size_t)buf[2] | ((size_t)buf[3] << 8) | ((size_t)buf[4] << 16) |
62            ((size_t)buf[5] << 24);
63    size_t consumed = *size + 6;
64    if (consumed > *len) {
65        return false;
66    }
67    *src = *src + consumed;
68    *len = *len - consumed;
69    return true;
70}
71
72bool parsePFB(const uint8_t* src, size_t size, size_t* headerLen,
73              size_t* dataLen, size_t* trailerLen) {
74    const uint8_t* srcPtr = src;
75    size_t remaining = size;
76
77    return parsePFBSection(&srcPtr, &remaining, 1, headerLen) &&
78           parsePFBSection(&srcPtr, &remaining, 2, dataLen) &&
79           parsePFBSection(&srcPtr, &remaining, 1, trailerLen) &&
80           parsePFBSection(&srcPtr, &remaining, 3, NULL);
81}
82
83/* The sections of a PFA file are implicitly defined.  The body starts
84 * after the line containing "eexec," and the trailer starts with 512
85 * literal 0's followed by "cleartomark" (plus arbitrary white space).
86 *
87 * This function assumes that src is NUL terminated, but the NUL
88 * termination is not included in size.
89 *
90 */
91bool parsePFA(const char* src, size_t size, size_t* headerLen,
92              size_t* hexDataLen, size_t* dataLen, size_t* trailerLen) {
93    const char* end = src + size;
94
95    const char* dataPos = strstr(src, "eexec");
96    if (!dataPos) {
97        return false;
98    }
99    dataPos += strlen("eexec");
100    while ((*dataPos == '\n' || *dataPos == '\r' || *dataPos == ' ') &&
101            dataPos < end) {
102        dataPos++;
103    }
104    *headerLen = dataPos - src;
105
106    const char* trailerPos = strstr(dataPos, "cleartomark");
107    if (!trailerPos) {
108        return false;
109    }
110    int zeroCount = 0;
111    for (trailerPos--; trailerPos > dataPos && zeroCount < 512; trailerPos--) {
112        if (*trailerPos == '\n' || *trailerPos == '\r' || *trailerPos == ' ') {
113            continue;
114        } else if (*trailerPos == '0') {
115            zeroCount++;
116        } else {
117            return false;
118        }
119    }
120    if (zeroCount != 512) {
121        return false;
122    }
123
124    *hexDataLen = trailerPos - src - *headerLen;
125    *trailerLen = size - *headerLen - *hexDataLen;
126
127    // Verify that the data section is hex encoded and count the bytes.
128    int nibbles = 0;
129    for (; dataPos < trailerPos; dataPos++) {
130        if (isspace(*dataPos)) {
131            continue;
132        }
133        if (!isxdigit(*dataPos)) {
134            return false;
135        }
136        nibbles++;
137    }
138    *dataLen = (nibbles + 1) / 2;
139
140    return true;
141}
142
143int8_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
156static SkData* handle_type1_stream(SkStream* srcStream, size_t* headerLen,
157                                   size_t* dataLen, size_t* trailerLen) {
158    // srcStream may be backed by a file or a unseekable fd, so we may not be
159    // able to use skip(), rewind(), or getMemoryBase().  read()ing through
160    // the input only once is doable, but very ugly. Furthermore, it'd be nice
161    // if the data was NUL terminated so that we can use strstr() to search it.
162    // Make as few copies as possible given these constraints.
163    SkDynamicMemoryWStream dynamicStream;
164    SkAutoTDelete<SkMemoryStream> staticStream;
165    SkData* data = NULL;
166    const uint8_t* src;
167    size_t srcLen;
168    if ((srcLen = srcStream->getLength()) > 0) {
169        staticStream.reset(new SkMemoryStream(srcLen + 1));
170        src = (const uint8_t*)staticStream->getMemoryBase();
171        if (srcStream->getMemoryBase() != NULL) {
172            memcpy((void *)src, srcStream->getMemoryBase(), srcLen);
173        } else {
174            size_t read = 0;
175            while (read < srcLen) {
176                size_t got = srcStream->read((void *)staticStream->getAtPos(),
177                                             srcLen - read);
178                if (got == 0) {
179                    return NULL;
180                }
181                read += got;
182                staticStream->seek(read);
183            }
184        }
185        ((uint8_t *)src)[srcLen] = 0;
186    } else {
187        static const size_t kBufSize = 4096;
188        uint8_t buf[kBufSize];
189        size_t amount;
190        while ((amount = srcStream->read(buf, kBufSize)) > 0) {
191            dynamicStream.write(buf, amount);
192        }
193        amount = 0;
194        dynamicStream.write(&amount, 1);  // NULL terminator.
195        data = dynamicStream.copyToData();
196        src = data->bytes();
197        srcLen = data->size() - 1;
198    }
199
200    // this handles releasing the data we may have gotten from dynamicStream.
201    // if data is null, it is a no-op
202    SkAutoDataUnref aud(data);
203
204    if (parsePFB(src, srcLen, headerLen, dataLen, trailerLen)) {
205        static const int kPFBSectionHeaderLength = 6;
206        const size_t length = *headerLen + *dataLen + *trailerLen;
207        SkASSERT(length > 0);
208        SkASSERT(length + (2 * kPFBSectionHeaderLength) <= srcLen);
209
210        SkData* data = SkData::NewUninitialized(length);
211
212        const uint8_t* const srcHeader = src + kPFBSectionHeaderLength;
213        // There is a six-byte section header before header and data
214        // (but not trailer) that we're not going to copy.
215        const uint8_t* const srcData = srcHeader + *headerLen + kPFBSectionHeaderLength;
216        const uint8_t* const srcTrailer = srcData + *headerLen;
217
218        uint8_t* const resultHeader = (uint8_t*)data->writable_data();
219        uint8_t* const resultData = resultHeader + *headerLen;
220        uint8_t* const resultTrailer = resultData + *dataLen;
221
222        SkASSERT(resultTrailer + *trailerLen == resultHeader + length);
223
224        memcpy(resultHeader,  srcHeader,  *headerLen);
225        memcpy(resultData,    srcData,    *dataLen);
226        memcpy(resultTrailer, srcTrailer, *trailerLen);
227
228        return data;
229    }
230
231    // A PFA has to be converted for PDF.
232    size_t hexDataLen;
233    if (parsePFA((const char*)src, srcLen, headerLen, &hexDataLen, dataLen,
234                 trailerLen)) {
235        const size_t length = *headerLen + *dataLen + *trailerLen;
236        SkASSERT(length > 0);
237        SkAutoTMalloc<uint8_t> buffer(length);
238
239        memcpy(buffer.get(), src, *headerLen);
240        uint8_t* const resultData = &(buffer[SkToInt(*headerLen)]);
241
242        const uint8_t* hexData = src + *headerLen;
243        const uint8_t* trailer = hexData + hexDataLen;
244        size_t outputOffset = 0;
245        uint8_t dataByte = 0;  // To hush compiler.
246        bool highNibble = true;
247        for (; hexData < trailer; hexData++) {
248            int8_t curNibble = hexToBin(*hexData);
249            if (curNibble < 0) {
250                continue;
251            }
252            if (highNibble) {
253                dataByte = curNibble << 4;
254                highNibble = false;
255            } else {
256                dataByte |= curNibble;
257                highNibble = true;
258                resultData[outputOffset++] = dataByte;
259            }
260        }
261        if (!highNibble) {
262            resultData[outputOffset++] = dataByte;
263        }
264        SkASSERT(outputOffset == *dataLen);
265
266        uint8_t* const resultTrailer = &(buffer[SkToInt(*headerLen + outputOffset)]);
267        memcpy(resultTrailer, src + *headerLen + hexDataLen, *trailerLen);
268
269        return SkData::NewFromMalloc(buffer.detach(), length);
270    }
271    return NULL;
272}
273
274// scale from em-units to base-1000, returning as a SkScalar
275SkScalar scaleFromFontUnits(int16_t val, uint16_t emSize) {
276    SkScalar scaled = SkIntToScalar(val);
277    if (emSize == 1000) {
278        return scaled;
279    } else {
280        return SkScalarMulDiv(scaled, 1000, emSize);
281    }
282}
283
284void setGlyphWidthAndBoundingBox(SkScalar width, SkIRect box,
285                                 SkWStream* content) {
286    // Specify width and bounding box for the glyph.
287    SkPDFUtils::AppendScalar(width, content);
288    content->writeText(" 0 ");
289    content->writeDecAsText(box.fLeft);
290    content->writeText(" ");
291    content->writeDecAsText(box.fTop);
292    content->writeText(" ");
293    content->writeDecAsText(box.fRight);
294    content->writeText(" ");
295    content->writeDecAsText(box.fBottom);
296    content->writeText(" d1\n");
297}
298
299SkPDFArray* makeFontBBox(SkIRect glyphBBox, uint16_t emSize) {
300    SkPDFArray* bbox = new SkPDFArray;
301    bbox->reserve(4);
302    bbox->appendScalar(scaleFromFontUnits(glyphBBox.fLeft, emSize));
303    bbox->appendScalar(scaleFromFontUnits(glyphBBox.fBottom, emSize));
304    bbox->appendScalar(scaleFromFontUnits(glyphBBox.fRight, emSize));
305    bbox->appendScalar(scaleFromFontUnits(glyphBBox.fTop, emSize));
306    return bbox;
307}
308
309SkPDFArray* appendWidth(const int16_t& width, uint16_t emSize,
310                        SkPDFArray* array) {
311    array->appendScalar(scaleFromFontUnits(width, emSize));
312    return array;
313}
314
315SkPDFArray* appendVerticalAdvance(
316        const SkAdvancedTypefaceMetrics::VerticalMetric& advance,
317        uint16_t emSize, SkPDFArray* array) {
318    appendWidth(advance.fVerticalAdvance, emSize, array);
319    appendWidth(advance.fOriginXDisp, emSize, array);
320    appendWidth(advance.fOriginYDisp, emSize, array);
321    return array;
322}
323
324template <typename Data>
325SkPDFArray* composeAdvanceData(
326        SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* advanceInfo,
327        uint16_t emSize,
328        SkPDFArray* (*appendAdvance)(const Data& advance, uint16_t emSize,
329                                     SkPDFArray* array),
330        Data* defaultAdvance) {
331    SkPDFArray* result = new SkPDFArray();
332    for (; advanceInfo != NULL; advanceInfo = advanceInfo->fNext.get()) {
333        switch (advanceInfo->fType) {
334            case SkAdvancedTypefaceMetrics::WidthRange::kDefault: {
335                SkASSERT(advanceInfo->fAdvance.count() == 1);
336                *defaultAdvance = advanceInfo->fAdvance[0];
337                break;
338            }
339            case SkAdvancedTypefaceMetrics::WidthRange::kRange: {
340                SkAutoTUnref<SkPDFArray> advanceArray(new SkPDFArray());
341                for (int j = 0; j < advanceInfo->fAdvance.count(); j++)
342                    appendAdvance(advanceInfo->fAdvance[j], emSize,
343                                  advanceArray.get());
344                result->appendInt(advanceInfo->fStartId);
345                result->appendObject(advanceArray.detach());
346                break;
347            }
348            case SkAdvancedTypefaceMetrics::WidthRange::kRun: {
349                SkASSERT(advanceInfo->fAdvance.count() == 1);
350                result->appendInt(advanceInfo->fStartId);
351                result->appendInt(advanceInfo->fEndId);
352                appendAdvance(advanceInfo->fAdvance[0], emSize, result);
353                break;
354            }
355        }
356    }
357    return result;
358}
359
360}  // namespace
361
362static void append_tounicode_header(SkDynamicMemoryWStream* cmap,
363                                    uint16_t firstGlyphID,
364                                    uint16_t lastGlyphID) {
365    // 12 dict begin: 12 is an Adobe-suggested value. Shall not change.
366    // It's there to prevent old version Adobe Readers from malfunctioning.
367    const char* kHeader =
368        "/CIDInit /ProcSet findresource begin\n"
369        "12 dict begin\n"
370        "begincmap\n";
371    cmap->writeText(kHeader);
372
373    // The /CIDSystemInfo must be consistent to the one in
374    // SkPDFFont::populateCIDFont().
375    // We can not pass over the system info object here because the format is
376    // different. This is not a reference object.
377    const char* kSysInfo =
378        "/CIDSystemInfo\n"
379        "<<  /Registry (Adobe)\n"
380        "/Ordering (UCS)\n"
381        "/Supplement 0\n"
382        ">> def\n";
383    cmap->writeText(kSysInfo);
384
385    // The CMapName must be consistent to /CIDSystemInfo above.
386    // /CMapType 2 means ToUnicode.
387    // Codespace range just tells the PDF processor the valid range.
388    const char* kTypeInfoHeader =
389        "/CMapName /Adobe-Identity-UCS def\n"
390        "/CMapType 2 def\n"
391        "1 begincodespacerange\n";
392    cmap->writeText(kTypeInfoHeader);
393
394    // e.g.     "<0000> <FFFF>\n"
395    SkString range;
396    range.appendf("<%04X> <%04X>\n", firstGlyphID, lastGlyphID);
397    cmap->writeText(range.c_str());
398
399    const char* kTypeInfoFooter = "endcodespacerange\n";
400    cmap->writeText(kTypeInfoFooter);
401}
402
403static void append_cmap_footer(SkDynamicMemoryWStream* cmap) {
404    const char* kFooter =
405        "endcmap\n"
406        "CMapName currentdict /CMap defineresource pop\n"
407        "end\n"
408        "end";
409    cmap->writeText(kFooter);
410}
411
412struct BFChar {
413    uint16_t fGlyphId;
414    SkUnichar fUnicode;
415};
416
417struct BFRange {
418    uint16_t fStart;
419    uint16_t fEnd;
420    SkUnichar fUnicode;
421};
422
423static void append_bfchar_section(const SkTDArray<BFChar>& bfchar,
424                                  SkDynamicMemoryWStream* cmap) {
425    // PDF spec defines that every bf* list can have at most 100 entries.
426    for (int i = 0; i < bfchar.count(); i += 100) {
427        int count = bfchar.count() - i;
428        count = SkMin32(count, 100);
429        cmap->writeDecAsText(count);
430        cmap->writeText(" beginbfchar\n");
431        for (int j = 0; j < count; ++j) {
432            cmap->writeText("<");
433            cmap->writeHexAsText(bfchar[i + j].fGlyphId, 4);
434            cmap->writeText("> <");
435            cmap->writeHexAsText(bfchar[i + j].fUnicode, 4);
436            cmap->writeText(">\n");
437        }
438        cmap->writeText("endbfchar\n");
439    }
440}
441
442static void append_bfrange_section(const SkTDArray<BFRange>& bfrange,
443                                   SkDynamicMemoryWStream* cmap) {
444    // PDF spec defines that every bf* list can have at most 100 entries.
445    for (int i = 0; i < bfrange.count(); i += 100) {
446        int count = bfrange.count() - i;
447        count = SkMin32(count, 100);
448        cmap->writeDecAsText(count);
449        cmap->writeText(" beginbfrange\n");
450        for (int j = 0; j < count; ++j) {
451            cmap->writeText("<");
452            cmap->writeHexAsText(bfrange[i + j].fStart, 4);
453            cmap->writeText("> <");
454            cmap->writeHexAsText(bfrange[i + j].fEnd, 4);
455            cmap->writeText("> <");
456            cmap->writeHexAsText(bfrange[i + j].fUnicode, 4);
457            cmap->writeText(">\n");
458        }
459        cmap->writeText("endbfrange\n");
460    }
461}
462
463// Generate <bfchar> and <bfrange> table according to PDF spec 1.4 and Adobe
464// Technote 5014.
465// The function is not static so we can test it in unit tests.
466//
467// Current implementation guarantees bfchar and bfrange entries do not overlap.
468//
469// Current implementation does not attempt aggresive optimizations against
470// following case because the specification is not clear.
471//
472// 4 beginbfchar          1 beginbfchar
473// <0003> <0013>          <0020> <0014>
474// <0005> <0015>    to    endbfchar
475// <0007> <0017>          1 beginbfrange
476// <0020> <0014>          <0003> <0007> <0013>
477// endbfchar              endbfrange
478//
479// Adobe Technote 5014 said: "Code mappings (unlike codespace ranges) may
480// overlap, but succeeding maps supersede preceding maps."
481//
482// In case of searching text in PDF, bfrange will have higher precedence so
483// typing char id 0x0014 in search box will get glyph id 0x0004 first.  However,
484// the spec does not mention how will this kind of conflict being resolved.
485//
486// For the worst case (having 65536 continuous unicode and we use every other
487// one of them), the possible savings by aggressive optimization is 416KB
488// pre-compressed and does not provide enough motivation for implementation.
489
490// FIXME: this should be in a header so that it is separately testable
491// ( see caller in tests/ToUnicode.cpp )
492void append_cmap_sections(const SkTDArray<SkUnichar>& glyphToUnicode,
493                          const SkPDFGlyphSet* subset,
494                          SkDynamicMemoryWStream* cmap,
495                          bool multiByteGlyphs,
496                          uint16_t firstGlyphID,
497                          uint16_t lastGlyphID);
498
499void append_cmap_sections(const SkTDArray<SkUnichar>& glyphToUnicode,
500                          const SkPDFGlyphSet* subset,
501                          SkDynamicMemoryWStream* cmap,
502                          bool multiByteGlyphs,
503                          uint16_t firstGlyphID,
504                          uint16_t lastGlyphID) {
505    if (glyphToUnicode.isEmpty()) {
506        return;
507    }
508    int glyphOffset = 0;
509    if (!multiByteGlyphs) {
510        glyphOffset = firstGlyphID - 1;
511    }
512
513    SkTDArray<BFChar> bfcharEntries;
514    SkTDArray<BFRange> bfrangeEntries;
515
516    BFRange currentRangeEntry = {0, 0, 0};
517    bool rangeEmpty = true;
518    const int limit =
519            SkMin32(lastGlyphID + 1, glyphToUnicode.count()) - glyphOffset;
520
521    for (int i = firstGlyphID - glyphOffset; i < limit + 1; ++i) {
522        bool inSubset = i < limit &&
523                        (subset == NULL || subset->has(i + glyphOffset));
524        if (!rangeEmpty) {
525            // PDF spec requires bfrange not changing the higher byte,
526            // e.g. <1035> <10FF> <2222> is ok, but
527            //      <1035> <1100> <2222> is no good
528            bool inRange =
529                i == currentRangeEntry.fEnd + 1 &&
530                i >> 8 == currentRangeEntry.fStart >> 8 &&
531                i < limit &&
532                glyphToUnicode[i + glyphOffset] ==
533                    currentRangeEntry.fUnicode + i - currentRangeEntry.fStart;
534            if (!inSubset || !inRange) {
535                if (currentRangeEntry.fEnd > currentRangeEntry.fStart) {
536                    bfrangeEntries.push(currentRangeEntry);
537                } else {
538                    BFChar* entry = bfcharEntries.append();
539                    entry->fGlyphId = currentRangeEntry.fStart;
540                    entry->fUnicode = currentRangeEntry.fUnicode;
541                }
542                rangeEmpty = true;
543            }
544        }
545        if (inSubset) {
546            currentRangeEntry.fEnd = i;
547            if (rangeEmpty) {
548              currentRangeEntry.fStart = i;
549              currentRangeEntry.fUnicode = glyphToUnicode[i + glyphOffset];
550              rangeEmpty = false;
551            }
552        }
553    }
554
555    // The spec requires all bfchar entries for a font must come before bfrange
556    // entries.
557    append_bfchar_section(bfcharEntries, cmap);
558    append_bfrange_section(bfrangeEntries, cmap);
559}
560
561static SkPDFStream* generate_tounicode_cmap(
562        const SkTDArray<SkUnichar>& glyphToUnicode,
563        const SkPDFGlyphSet* subset,
564        bool multiByteGlyphs,
565        uint16_t firstGlyphID,
566        uint16_t lastGlyphID) {
567    SkDynamicMemoryWStream cmap;
568    if (multiByteGlyphs) {
569        append_tounicode_header(&cmap, firstGlyphID, lastGlyphID);
570    } else {
571        append_tounicode_header(&cmap, 1, lastGlyphID - firstGlyphID + 1);
572    }
573    append_cmap_sections(glyphToUnicode, subset, &cmap, multiByteGlyphs,
574                         firstGlyphID, lastGlyphID);
575    append_cmap_footer(&cmap);
576    SkAutoTUnref<SkData> cmapData(cmap.copyToData());
577    return new SkPDFStream(cmapData.get());
578}
579
580#if defined (SK_SFNTLY_SUBSETTER)
581static void sk_delete_array(const void* ptr, void*) {
582    // Use C-style cast to cast away const and cast type simultaneously.
583    delete[] (unsigned char*)ptr;
584}
585#endif
586
587static size_t get_subset_font_stream(const char* fontName,
588                                     const SkTypeface* typeface,
589                                     const SkTDArray<uint32_t>& subset,
590                                     SkPDFStream** fontStream) {
591    int ttcIndex;
592    SkAutoTDelete<SkStream> fontData(typeface->openStream(&ttcIndex));
593    SkASSERT(fontData.get());
594
595    size_t fontSize = fontData->getLength();
596
597#if defined (SK_SFNTLY_SUBSETTER)
598    // Read font into buffer.
599    SkPDFStream* subsetFontStream = NULL;
600    SkTDArray<unsigned char> originalFont;
601    originalFont.setCount(SkToInt(fontSize));
602    if (fontData->read(originalFont.begin(), fontSize) == fontSize) {
603        unsigned char* subsetFont = NULL;
604        // sfntly requires unsigned int* to be passed in, as far as we know,
605        // unsigned int is equivalent to uint32_t on all platforms.
606        SK_COMPILE_ASSERT(sizeof(unsigned int) == sizeof(uint32_t),
607                          unsigned_int_not_32_bits);
608        int subsetFontSize = SfntlyWrapper::SubsetFont(fontName,
609                                                       originalFont.begin(),
610                                                       fontSize,
611                                                       subset.begin(),
612                                                       subset.count(),
613                                                       &subsetFont);
614        if (subsetFontSize > 0 && subsetFont != NULL) {
615            SkAutoDataUnref data(SkData::NewWithProc(subsetFont,
616                                                     subsetFontSize,
617                                                     sk_delete_array,
618                                                     NULL));
619            subsetFontStream = new SkPDFStream(data.get());
620            fontSize = subsetFontSize;
621        }
622    }
623    if (subsetFontStream) {
624        *fontStream = subsetFontStream;
625        return fontSize;
626    }
627    fontData->rewind();
628#else
629    sk_ignore_unused_variable(fontName);
630    sk_ignore_unused_variable(subset);
631#endif
632
633    // Fail over: just embed the whole font.
634    *fontStream = new SkPDFStream(fontData.get());
635    return fontSize;
636}
637
638///////////////////////////////////////////////////////////////////////////////
639// class SkPDFGlyphSet
640///////////////////////////////////////////////////////////////////////////////
641
642SkPDFGlyphSet::SkPDFGlyphSet() : fBitSet(SK_MaxU16 + 1) {
643}
644
645void SkPDFGlyphSet::set(const uint16_t* glyphIDs, int numGlyphs) {
646    for (int i = 0; i < numGlyphs; ++i) {
647        fBitSet.setBit(glyphIDs[i], true);
648    }
649}
650
651bool SkPDFGlyphSet::has(uint16_t glyphID) const {
652    return fBitSet.isBitSet(glyphID);
653}
654
655void SkPDFGlyphSet::merge(const SkPDFGlyphSet& usage) {
656    fBitSet.orBits(usage.fBitSet);
657}
658
659void SkPDFGlyphSet::exportTo(SkTDArray<unsigned int>* glyphIDs) const {
660    fBitSet.exportTo(glyphIDs);
661}
662
663///////////////////////////////////////////////////////////////////////////////
664// class SkPDFGlyphSetMap
665///////////////////////////////////////////////////////////////////////////////
666SkPDFGlyphSetMap::FontGlyphSetPair::FontGlyphSetPair(SkPDFFont* font,
667                                                     SkPDFGlyphSet* glyphSet)
668        : fFont(font),
669          fGlyphSet(glyphSet) {
670}
671
672SkPDFGlyphSetMap::F2BIter::F2BIter(const SkPDFGlyphSetMap& map) {
673    reset(map);
674}
675
676const SkPDFGlyphSetMap::FontGlyphSetPair* SkPDFGlyphSetMap::F2BIter::next() const {
677    if (fIndex >= fMap->count()) {
678        return NULL;
679    }
680    return &((*fMap)[fIndex++]);
681}
682
683void SkPDFGlyphSetMap::F2BIter::reset(const SkPDFGlyphSetMap& map) {
684    fMap = &(map.fMap);
685    fIndex = 0;
686}
687
688SkPDFGlyphSetMap::SkPDFGlyphSetMap() {
689}
690
691SkPDFGlyphSetMap::~SkPDFGlyphSetMap() {
692    reset();
693}
694
695void SkPDFGlyphSetMap::merge(const SkPDFGlyphSetMap& usage) {
696    for (int i = 0; i < usage.fMap.count(); ++i) {
697        SkPDFGlyphSet* myUsage = getGlyphSetForFont(usage.fMap[i].fFont);
698        myUsage->merge(*(usage.fMap[i].fGlyphSet));
699    }
700}
701
702void SkPDFGlyphSetMap::reset() {
703    for (int i = 0; i < fMap.count(); ++i) {
704        delete fMap[i].fGlyphSet;  // Should not be NULL.
705    }
706    fMap.reset();
707}
708
709void SkPDFGlyphSetMap::noteGlyphUsage(SkPDFFont* font, const uint16_t* glyphIDs,
710                                      int numGlyphs) {
711    SkPDFGlyphSet* subset = getGlyphSetForFont(font);
712    if (subset) {
713        subset->set(glyphIDs, numGlyphs);
714    }
715}
716
717SkPDFGlyphSet* SkPDFGlyphSetMap::getGlyphSetForFont(SkPDFFont* font) {
718    int index = fMap.count();
719    for (int i = 0; i < index; ++i) {
720        if (fMap[i].fFont == font) {
721            return fMap[i].fGlyphSet;
722        }
723    }
724    fMap.append();
725    index = fMap.count() - 1;
726    fMap[index].fFont = font;
727    fMap[index].fGlyphSet = new SkPDFGlyphSet();
728    return fMap[index].fGlyphSet;
729}
730
731///////////////////////////////////////////////////////////////////////////////
732// class SkPDFFont
733///////////////////////////////////////////////////////////////////////////////
734
735/* Font subset design: It would be nice to be able to subset fonts
736 * (particularly type 3 fonts), but it's a lot of work and not a priority.
737 *
738 * Resources are canonicalized and uniqueified by pointer so there has to be
739 * some additional state indicating which subset of the font is used.  It
740 * must be maintained at the page granularity and then combined at the document
741 * granularity. a) change SkPDFFont to fill in its state on demand, kind of
742 * like SkPDFGraphicState.  b) maintain a per font glyph usage class in each
743 * page/pdf device. c) in the document, retrieve the per font glyph usage
744 * from each page and combine it and ask for a resource with that subset.
745 */
746
747SkPDFFont::~SkPDFFont() {}
748
749SkTypeface* SkPDFFont::typeface() {
750    return fTypeface.get();
751}
752
753SkAdvancedTypefaceMetrics::FontType SkPDFFont::getType() {
754    return fFontType;
755}
756
757bool SkPDFFont::canEmbed() const {
758    if (!fFontInfo.get()) {
759        SkASSERT(fFontType == SkAdvancedTypefaceMetrics::kOther_Font);
760        return true;
761    }
762    return (fFontInfo->fFlags &
763            SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag) == 0;
764}
765
766bool SkPDFFont::canSubset() const {
767    if (!fFontInfo.get()) {
768        SkASSERT(fFontType == SkAdvancedTypefaceMetrics::kOther_Font);
769        return true;
770    }
771    return (fFontInfo->fFlags &
772            SkAdvancedTypefaceMetrics::kNotSubsettable_FontFlag) == 0;
773}
774
775bool SkPDFFont::hasGlyph(uint16_t id) {
776    return (id >= fFirstGlyphID && id <= fLastGlyphID) || id == 0;
777}
778
779int SkPDFFont::glyphsToPDFFontEncoding(uint16_t* glyphIDs, int numGlyphs) {
780    // A font with multibyte glyphs will support all glyph IDs in a single font.
781    if (this->multiByteGlyphs()) {
782        return numGlyphs;
783    }
784
785    for (int i = 0; i < numGlyphs; i++) {
786        if (glyphIDs[i] == 0) {
787            continue;
788        }
789        if (glyphIDs[i] < fFirstGlyphID || glyphIDs[i] > fLastGlyphID) {
790            return i;
791        }
792        glyphIDs[i] -= (fFirstGlyphID - 1);
793    }
794
795    return numGlyphs;
796}
797
798// static
799SkPDFFont* SkPDFFont::GetFontResource(SkPDFCanon* canon,
800                                      SkTypeface* typeface,
801                                      uint16_t glyphID) {
802    SkASSERT(canon);
803    SkAutoResolveDefaultTypeface autoResolve(typeface);
804    typeface = autoResolve.get();
805    const uint32_t fontID = typeface->uniqueID();
806
807    SkPDFFont* relatedFont;
808    if (SkPDFFont* pdfFont = canon->findFont(fontID, glyphID, &relatedFont)) {
809        return SkRef(pdfFont);
810    }
811
812    SkAutoTUnref<const SkAdvancedTypefaceMetrics> fontMetrics;
813    SkPDFDict* relatedFontDescriptor = NULL;
814    if (relatedFont) {
815        fontMetrics.reset(SkSafeRef(relatedFont->fontInfo()));
816        relatedFontDescriptor = relatedFont->getFontDescriptor();
817
818        // This only is to catch callers who pass invalid glyph ids.
819        // If glyph id is invalid, then we will create duplicate entries
820        // for TrueType fonts.
821        SkAdvancedTypefaceMetrics::FontType fontType =
822            fontMetrics.get() ? fontMetrics.get()->fType :
823                                SkAdvancedTypefaceMetrics::kOther_Font;
824
825        if (fontType == SkAdvancedTypefaceMetrics::kType1CID_Font ||
826            fontType == SkAdvancedTypefaceMetrics::kTrueType_Font) {
827            return SkRef(relatedFont);
828        }
829    } else {
830        SkTypeface::PerGlyphInfo info;
831        info = SkTypeface::kGlyphNames_PerGlyphInfo;
832        info = SkTBitOr<SkTypeface::PerGlyphInfo>(
833                  info, SkTypeface::kToUnicode_PerGlyphInfo);
834#if !defined (SK_SFNTLY_SUBSETTER)
835        info = SkTBitOr<SkTypeface::PerGlyphInfo>(
836                  info, SkTypeface::kHAdvance_PerGlyphInfo);
837#endif
838        fontMetrics.reset(
839            typeface->getAdvancedTypefaceMetrics(info, NULL, 0));
840#if defined (SK_SFNTLY_SUBSETTER)
841        if (fontMetrics.get() &&
842            fontMetrics->fType != SkAdvancedTypefaceMetrics::kTrueType_Font) {
843            // Font does not support subsetting, get new info with advance.
844            info = SkTBitOr<SkTypeface::PerGlyphInfo>(
845                      info, SkTypeface::kHAdvance_PerGlyphInfo);
846            fontMetrics.reset(
847                typeface->getAdvancedTypefaceMetrics(info, NULL, 0));
848        }
849#endif
850    }
851
852    SkPDFFont* font = SkPDFFont::Create(canon, fontMetrics.get(), typeface,
853                                        glyphID, relatedFontDescriptor);
854    canon->addFont(font, fontID, font->fFirstGlyphID);
855    return font;
856}
857
858SkPDFFont* SkPDFFont::getFontSubset(const SkPDFGlyphSet*) {
859    return NULL;  // Default: no support.
860}
861
862SkPDFFont::SkPDFFont(const SkAdvancedTypefaceMetrics* info,
863                     SkTypeface* typeface,
864                     SkPDFDict* relatedFontDescriptor)
865    : SkPDFDict("Font")
866    , fTypeface(ref_or_default(typeface))
867    , fFirstGlyphID(1)
868    , fLastGlyphID(info ? info->fLastGlyphID : 0)
869    , fFontInfo(SkSafeRef(info))
870    , fDescriptor(SkSafeRef(relatedFontDescriptor)) {
871    if (info == NULL ||
872            info->fFlags & SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag) {
873        fFontType = SkAdvancedTypefaceMetrics::kOther_Font;
874    } else {
875        fFontType = info->fType;
876    }
877}
878
879// static
880SkPDFFont* SkPDFFont::Create(SkPDFCanon* canon,
881                             const SkAdvancedTypefaceMetrics* info,
882                             SkTypeface* typeface,
883                             uint16_t glyphID,
884                             SkPDFDict* relatedFontDescriptor) {
885    SkAdvancedTypefaceMetrics::FontType type =
886        info ? info->fType : SkAdvancedTypefaceMetrics::kOther_Font;
887
888    if (info && (info->fFlags & SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag)) {
889        return new SkPDFType3Font(info, typeface, glyphID);
890    }
891    if (type == SkAdvancedTypefaceMetrics::kType1CID_Font ||
892        type == SkAdvancedTypefaceMetrics::kTrueType_Font) {
893        SkASSERT(relatedFontDescriptor == NULL);
894        return new SkPDFType0Font(info, typeface);
895    }
896    if (type == SkAdvancedTypefaceMetrics::kType1_Font) {
897        return new SkPDFType1Font(info, typeface, glyphID,
898                                  relatedFontDescriptor);
899    }
900
901    SkASSERT(type == SkAdvancedTypefaceMetrics::kCFF_Font ||
902             type == SkAdvancedTypefaceMetrics::kOther_Font);
903
904    return new SkPDFType3Font(info, typeface, glyphID);
905}
906
907const SkAdvancedTypefaceMetrics* SkPDFFont::fontInfo() {
908    return fFontInfo.get();
909}
910
911void SkPDFFont::setFontInfo(const SkAdvancedTypefaceMetrics* info) {
912    if (info == NULL || info == fFontInfo.get()) {
913        return;
914    }
915    fFontInfo.reset(info);
916    SkSafeRef(info);
917}
918
919uint16_t SkPDFFont::firstGlyphID() const {
920    return fFirstGlyphID;
921}
922
923uint16_t SkPDFFont::lastGlyphID() const {
924    return fLastGlyphID;
925}
926
927void SkPDFFont::setLastGlyphID(uint16_t glyphID) {
928    fLastGlyphID = glyphID;
929}
930
931SkPDFDict* SkPDFFont::getFontDescriptor() {
932    return fDescriptor.get();
933}
934
935void SkPDFFont::setFontDescriptor(SkPDFDict* descriptor) {
936    fDescriptor.reset(descriptor);
937    SkSafeRef(descriptor);
938}
939
940bool SkPDFFont::addCommonFontDescriptorEntries(int16_t defaultWidth) {
941    if (fDescriptor.get() == NULL) {
942        return false;
943    }
944
945    const uint16_t emSize = fFontInfo->fEmSize;
946
947    fDescriptor->insertName("FontName", fFontInfo->fFontName);
948    fDescriptor->insertInt("Flags", fFontInfo->fStyle | kPdfSymbolic);
949    fDescriptor->insertScalar("Ascent",
950            scaleFromFontUnits(fFontInfo->fAscent, emSize));
951    fDescriptor->insertScalar("Descent",
952            scaleFromFontUnits(fFontInfo->fDescent, emSize));
953    fDescriptor->insertScalar("StemV",
954            scaleFromFontUnits(fFontInfo->fStemV, emSize));
955
956    fDescriptor->insertScalar("CapHeight",
957            scaleFromFontUnits(fFontInfo->fCapHeight, emSize));
958    fDescriptor->insertInt("ItalicAngle", fFontInfo->fItalicAngle);
959    fDescriptor->insertObject(
960            "FontBBox", makeFontBBox(fFontInfo->fBBox, fFontInfo->fEmSize));
961
962    if (defaultWidth > 0) {
963        fDescriptor->insertScalar("MissingWidth",
964                scaleFromFontUnits(defaultWidth, emSize));
965    }
966    return true;
967}
968
969void SkPDFFont::adjustGlyphRangeForSingleByteEncoding(uint16_t glyphID) {
970    // Single byte glyph encoding supports a max of 255 glyphs.
971    fFirstGlyphID = glyphID - (glyphID - 1) % 255;
972    if (fLastGlyphID > fFirstGlyphID + 255 - 1) {
973        fLastGlyphID = fFirstGlyphID + 255 - 1;
974    }
975}
976
977void SkPDFFont::populateToUnicodeTable(const SkPDFGlyphSet* subset) {
978    if (fFontInfo == NULL || fFontInfo->fGlyphToUnicode.begin() == NULL) {
979        return;
980    }
981    this->insertObjRef("ToUnicode",
982                       generate_tounicode_cmap(fFontInfo->fGlyphToUnicode,
983                                               subset,
984                                               multiByteGlyphs(),
985                                               firstGlyphID(),
986                                               lastGlyphID()));
987}
988
989///////////////////////////////////////////////////////////////////////////////
990// class SkPDFType0Font
991///////////////////////////////////////////////////////////////////////////////
992
993SkPDFType0Font::SkPDFType0Font(const SkAdvancedTypefaceMetrics* info,
994                               SkTypeface* typeface)
995    : SkPDFFont(info, typeface, NULL) {
996    SkDEBUGCODE(fPopulated = false);
997    if (!canSubset()) {
998        populate(NULL);
999    }
1000}
1001
1002SkPDFType0Font::~SkPDFType0Font() {}
1003
1004SkPDFFont* SkPDFType0Font::getFontSubset(const SkPDFGlyphSet* subset) {
1005    if (!canSubset()) {
1006        return NULL;
1007    }
1008    SkPDFType0Font* newSubset =
1009            new SkPDFType0Font(fontInfo(), typeface());
1010    newSubset->populate(subset);
1011    return newSubset;
1012}
1013
1014#ifdef SK_DEBUG
1015void SkPDFType0Font::emitObject(SkWStream* stream,
1016                                const SkPDFObjNumMap& objNumMap,
1017                                const SkPDFSubstituteMap& substitutes) {
1018    SkASSERT(fPopulated);
1019    return INHERITED::emitObject(stream, objNumMap, substitutes);
1020}
1021#endif
1022
1023bool SkPDFType0Font::populate(const SkPDFGlyphSet* subset) {
1024    insertName("Subtype", "Type0");
1025    insertName("BaseFont", fontInfo()->fFontName);
1026    insertName("Encoding", "Identity-H");
1027
1028    SkAutoTUnref<SkPDFCIDFont> newCIDFont(
1029            new SkPDFCIDFont(fontInfo(), typeface(), subset));
1030    SkAutoTUnref<SkPDFArray> descendantFonts(new SkPDFArray());
1031    descendantFonts->appendObjRef(newCIDFont.detach());
1032    this->insertObject("DescendantFonts", descendantFonts.detach());
1033
1034    populateToUnicodeTable(subset);
1035
1036    SkDEBUGCODE(fPopulated = true);
1037    return true;
1038}
1039
1040///////////////////////////////////////////////////////////////////////////////
1041// class SkPDFCIDFont
1042///////////////////////////////////////////////////////////////////////////////
1043
1044SkPDFCIDFont::SkPDFCIDFont(const SkAdvancedTypefaceMetrics* info,
1045                           SkTypeface* typeface,
1046                           const SkPDFGlyphSet* subset)
1047    : SkPDFFont(info, typeface, NULL) {
1048    populate(subset);
1049}
1050
1051SkPDFCIDFont::~SkPDFCIDFont() {}
1052
1053bool SkPDFCIDFont::addFontDescriptor(int16_t defaultWidth,
1054                                     const SkTDArray<uint32_t>* subset) {
1055    SkAutoTUnref<SkPDFDict> descriptor(new SkPDFDict("FontDescriptor"));
1056    setFontDescriptor(descriptor.get());
1057    if (!addCommonFontDescriptorEntries(defaultWidth)) {
1058        this->insertObjRef("FontDescriptor", descriptor.detach());
1059        return false;
1060    }
1061    if (!canEmbed()) {
1062        this->insertObjRef("FontDescriptor", descriptor.detach());
1063        return true;
1064    }
1065
1066    switch (getType()) {
1067        case SkAdvancedTypefaceMetrics::kTrueType_Font: {
1068            SkAutoTUnref<SkPDFStream> fontStream;
1069            size_t fontSize = 0;
1070            if (canSubset()) {
1071                SkPDFStream* rawStream = NULL;
1072                fontSize = get_subset_font_stream(fontInfo()->fFontName.c_str(),
1073                                                  typeface(),
1074                                                  *subset,
1075                                                  &rawStream);
1076                fontStream.reset(rawStream);
1077            } else {
1078                int ttcIndex;
1079                SkAutoTDelete<SkStream> fontData(
1080                        typeface()->openStream(&ttcIndex));
1081                fontStream.reset(new SkPDFStream(fontData.get()));
1082                fontSize = fontData->getLength();
1083            }
1084            SkASSERT(fontSize);
1085            SkASSERT(fontStream.get());
1086
1087            fontStream->insertInt("Length1", fontSize);
1088            descriptor->insertObjRef("FontFile2", fontStream.detach());
1089            break;
1090        }
1091        case SkAdvancedTypefaceMetrics::kCFF_Font:
1092        case SkAdvancedTypefaceMetrics::kType1CID_Font: {
1093            int ttcIndex;
1094            SkAutoTDelete<SkStream> fontData(typeface()->openStream(&ttcIndex));
1095            SkAutoTUnref<SkPDFStream> fontStream(
1096                new SkPDFStream(fontData.get()));
1097
1098            if (getType() == SkAdvancedTypefaceMetrics::kCFF_Font) {
1099                fontStream->insertName("Subtype", "Type1C");
1100            } else {
1101                fontStream->insertName("Subtype", "CIDFontType0c");
1102            }
1103            descriptor->insertObjRef("FontFile3", fontStream.detach());
1104            break;
1105        }
1106        default:
1107            SkASSERT(false);
1108    }
1109    this->insertObjRef("FontDescriptor", descriptor.detach());
1110    return true;
1111}
1112
1113bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) {
1114    // Generate new font metrics with advance info for true type fonts.
1115    if (fontInfo()->fType == SkAdvancedTypefaceMetrics::kTrueType_Font) {
1116        // Generate glyph id array.
1117        SkTDArray<uint32_t> glyphIDs;
1118        if (subset) {
1119            // Always include glyph 0.
1120            if (!subset->has(0)) {
1121                glyphIDs.push(0);
1122            }
1123            subset->exportTo(&glyphIDs);
1124        }
1125
1126        SkTypeface::PerGlyphInfo info;
1127        info = SkTypeface::kGlyphNames_PerGlyphInfo;
1128        info = SkTBitOr<SkTypeface::PerGlyphInfo>(
1129                  info, SkTypeface::kHAdvance_PerGlyphInfo);
1130        uint32_t* glyphs = (glyphIDs.count() == 0) ? NULL : glyphIDs.begin();
1131        uint32_t glyphsCount = glyphs ? glyphIDs.count() : 0;
1132        SkAutoTUnref<const SkAdvancedTypefaceMetrics> fontMetrics(
1133            typeface()->getAdvancedTypefaceMetrics(info, glyphs, glyphsCount));
1134        setFontInfo(fontMetrics.get());
1135        addFontDescriptor(0, &glyphIDs);
1136    } else {
1137        // Other CID fonts
1138        addFontDescriptor(0, NULL);
1139    }
1140
1141    insertName("BaseFont", fontInfo()->fFontName);
1142
1143    if (getType() == SkAdvancedTypefaceMetrics::kType1CID_Font) {
1144        insertName("Subtype", "CIDFontType0");
1145    } else if (getType() == SkAdvancedTypefaceMetrics::kTrueType_Font) {
1146        insertName("Subtype", "CIDFontType2");
1147        insertName("CIDToGIDMap", "Identity");
1148    } else {
1149        SkASSERT(false);
1150    }
1151
1152    SkAutoTUnref<SkPDFDict> sysInfo(new SkPDFDict);
1153    sysInfo->insertString("Registry", "Adobe");
1154    sysInfo->insertString("Ordering", "Identity");
1155    sysInfo->insertInt("Supplement", 0);
1156    this->insertObject("CIDSystemInfo", sysInfo.detach());
1157
1158    if (fontInfo()->fGlyphWidths.get()) {
1159        int16_t defaultWidth = 0;
1160        SkAutoTUnref<SkPDFArray> widths(
1161            composeAdvanceData(fontInfo()->fGlyphWidths.get(),
1162                               fontInfo()->fEmSize, &appendWidth,
1163                               &defaultWidth));
1164        if (widths->size())
1165            this->insertObject("W", widths.detach());
1166        if (defaultWidth != 0) {
1167            this->insertScalar(
1168                    "DW",
1169                    scaleFromFontUnits(defaultWidth, fontInfo()->fEmSize));
1170        }
1171    }
1172    if (fontInfo()->fVerticalMetrics.get()) {
1173        struct SkAdvancedTypefaceMetrics::VerticalMetric defaultAdvance;
1174        defaultAdvance.fVerticalAdvance = 0;
1175        defaultAdvance.fOriginXDisp = 0;
1176        defaultAdvance.fOriginYDisp = 0;
1177        SkAutoTUnref<SkPDFArray> advances(
1178            composeAdvanceData(fontInfo()->fVerticalMetrics.get(),
1179                               fontInfo()->fEmSize, &appendVerticalAdvance,
1180                               &defaultAdvance));
1181        if (advances->size())
1182            this->insertObject("W2", advances.detach());
1183        if (defaultAdvance.fVerticalAdvance ||
1184                defaultAdvance.fOriginXDisp ||
1185                defaultAdvance.fOriginYDisp) {
1186            this->insertObject("DW2",
1187                               appendVerticalAdvance(defaultAdvance,
1188                                                     fontInfo()->fEmSize,
1189                                                     new SkPDFArray));
1190        }
1191    }
1192
1193    return true;
1194}
1195
1196///////////////////////////////////////////////////////////////////////////////
1197// class SkPDFType1Font
1198///////////////////////////////////////////////////////////////////////////////
1199
1200SkPDFType1Font::SkPDFType1Font(const SkAdvancedTypefaceMetrics* info,
1201                               SkTypeface* typeface,
1202                               uint16_t glyphID,
1203                               SkPDFDict* relatedFontDescriptor)
1204    : SkPDFFont(info, typeface, relatedFontDescriptor) {
1205    populate(glyphID);
1206}
1207
1208SkPDFType1Font::~SkPDFType1Font() {}
1209
1210bool SkPDFType1Font::addFontDescriptor(int16_t defaultWidth) {
1211    if (SkPDFDict* descriptor = getFontDescriptor()) {
1212        this->insertObjRef("FontDescriptor", SkRef(descriptor));
1213        return true;
1214    }
1215
1216    SkAutoTUnref<SkPDFDict> descriptor(new SkPDFDict("FontDescriptor"));
1217    setFontDescriptor(descriptor.get());
1218
1219    int ttcIndex;
1220    size_t header SK_INIT_TO_AVOID_WARNING;
1221    size_t data SK_INIT_TO_AVOID_WARNING;
1222    size_t trailer SK_INIT_TO_AVOID_WARNING;
1223    SkAutoTDelete<SkStream> rawFontData(typeface()->openStream(&ttcIndex));
1224    SkAutoTUnref<SkData> fontData(handle_type1_stream(rawFontData.get(), &header,
1225                                                      &data, &trailer));
1226    if (fontData.get() == NULL) {
1227        return false;
1228    }
1229    if (canEmbed()) {
1230        SkAutoTUnref<SkPDFStream> fontStream(new SkPDFStream(fontData.get()));
1231        fontStream->insertInt("Length1", header);
1232        fontStream->insertInt("Length2", data);
1233        fontStream->insertInt("Length3", trailer);
1234        descriptor->insertObjRef("FontFile", fontStream.detach());
1235    }
1236
1237    this->insertObjRef("FontDescriptor", descriptor.detach());
1238
1239    return addCommonFontDescriptorEntries(defaultWidth);
1240}
1241
1242bool SkPDFType1Font::populate(int16_t glyphID) {
1243    SkASSERT(!fontInfo()->fVerticalMetrics.get());
1244    SkASSERT(fontInfo()->fGlyphWidths.get());
1245
1246    adjustGlyphRangeForSingleByteEncoding(glyphID);
1247
1248    int16_t defaultWidth = 0;
1249    const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry = NULL;
1250    const SkAdvancedTypefaceMetrics::WidthRange* widthEntry;
1251    for (widthEntry = fontInfo()->fGlyphWidths.get();
1252            widthEntry != NULL;
1253            widthEntry = widthEntry->fNext.get()) {
1254        switch (widthEntry->fType) {
1255            case SkAdvancedTypefaceMetrics::WidthRange::kDefault:
1256                defaultWidth = widthEntry->fAdvance[0];
1257                break;
1258            case SkAdvancedTypefaceMetrics::WidthRange::kRun:
1259                SkASSERT(false);
1260                break;
1261            case SkAdvancedTypefaceMetrics::WidthRange::kRange:
1262                SkASSERT(widthRangeEntry == NULL);
1263                widthRangeEntry = widthEntry;
1264                break;
1265        }
1266    }
1267
1268    if (!addFontDescriptor(defaultWidth)) {
1269        return false;
1270    }
1271
1272    insertName("Subtype", "Type1");
1273    insertName("BaseFont", fontInfo()->fFontName);
1274
1275    addWidthInfoFromRange(defaultWidth, widthRangeEntry);
1276
1277
1278    SkAutoTUnref<SkPDFArray> encDiffs(new SkPDFArray);
1279    encDiffs->reserve(lastGlyphID() - firstGlyphID() + 2);
1280    encDiffs->appendInt(1);
1281    for (int gID = firstGlyphID(); gID <= lastGlyphID(); gID++) {
1282        encDiffs->appendName(fontInfo()->fGlyphNames->get()[gID].c_str());
1283    }
1284
1285    SkAutoTUnref<SkPDFDict> encoding(new SkPDFDict("Encoding"));
1286    encoding->insertObject("Differences", encDiffs.detach());
1287    this->insertObject("Encoding", encoding.detach());
1288    return true;
1289}
1290
1291void SkPDFType1Font::addWidthInfoFromRange(
1292        int16_t defaultWidth,
1293        const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry) {
1294    SkAutoTUnref<SkPDFArray> widthArray(new SkPDFArray());
1295    int firstChar = 0;
1296    if (widthRangeEntry) {
1297        const uint16_t emSize = fontInfo()->fEmSize;
1298        int startIndex = firstGlyphID() - widthRangeEntry->fStartId;
1299        int endIndex = startIndex + lastGlyphID() - firstGlyphID() + 1;
1300        if (startIndex < 0)
1301            startIndex = 0;
1302        if (endIndex > widthRangeEntry->fAdvance.count())
1303            endIndex = widthRangeEntry->fAdvance.count();
1304        if (widthRangeEntry->fStartId == 0) {
1305            appendWidth(widthRangeEntry->fAdvance[0], emSize, widthArray.get());
1306        } else {
1307            firstChar = startIndex + widthRangeEntry->fStartId;
1308        }
1309        for (int i = startIndex; i < endIndex; i++) {
1310            appendWidth(widthRangeEntry->fAdvance[i], emSize, widthArray.get());
1311        }
1312    } else {
1313        appendWidth(defaultWidth, 1000, widthArray.get());
1314    }
1315    this->insertInt("FirstChar", firstChar);
1316    this->insertInt("LastChar", firstChar + widthArray->size() - 1);
1317    this->insertObject("Widths", widthArray.detach());
1318}
1319
1320///////////////////////////////////////////////////////////////////////////////
1321// class SkPDFType3Font
1322///////////////////////////////////////////////////////////////////////////////
1323
1324SkPDFType3Font::SkPDFType3Font(const SkAdvancedTypefaceMetrics* info,
1325                               SkTypeface* typeface,
1326                               uint16_t glyphID)
1327    : SkPDFFont(info, typeface, NULL) {
1328    populate(glyphID);
1329}
1330
1331SkPDFType3Font::~SkPDFType3Font() {}
1332
1333bool SkPDFType3Font::populate(uint16_t glyphID) {
1334    SkPaint paint;
1335    paint.setTypeface(typeface());
1336    paint.setTextSize(1000);
1337    SkAutoGlyphCache autoCache(paint, NULL, NULL);
1338    SkGlyphCache* cache = autoCache.getCache();
1339    // If fLastGlyphID isn't set (because there is not fFontInfo), look it up.
1340    if (lastGlyphID() == 0) {
1341        setLastGlyphID(cache->getGlyphCount() - 1);
1342    }
1343
1344    adjustGlyphRangeForSingleByteEncoding(glyphID);
1345
1346    insertName("Subtype", "Type3");
1347    // Flip about the x-axis and scale by 1/1000.
1348    SkMatrix fontMatrix;
1349    fontMatrix.setScale(SkScalarInvert(1000), -SkScalarInvert(1000));
1350    this->insertObject("FontMatrix", SkPDFUtils::MatrixToArray(fontMatrix));
1351
1352    SkAutoTUnref<SkPDFDict> charProcs(new SkPDFDict);
1353    SkAutoTUnref<SkPDFDict> encoding(new SkPDFDict("Encoding"));
1354
1355    SkAutoTUnref<SkPDFArray> encDiffs(new SkPDFArray);
1356    encDiffs->reserve(lastGlyphID() - firstGlyphID() + 2);
1357    encDiffs->appendInt(1);
1358
1359    SkAutoTUnref<SkPDFArray> widthArray(new SkPDFArray());
1360
1361    SkIRect bbox = SkIRect::MakeEmpty();
1362    for (int gID = firstGlyphID(); gID <= lastGlyphID(); gID++) {
1363        SkString characterName;
1364        characterName.printf("gid%d", gID);
1365        encDiffs->appendName(characterName.c_str());
1366
1367        const SkGlyph& glyph = cache->getGlyphIDMetrics(gID);
1368        widthArray->appendScalar(SkFixedToScalar(glyph.fAdvanceX));
1369        SkIRect glyphBBox = SkIRect::MakeXYWH(glyph.fLeft, glyph.fTop,
1370                                              glyph.fWidth, glyph.fHeight);
1371        bbox.join(glyphBBox);
1372
1373        SkDynamicMemoryWStream content;
1374        setGlyphWidthAndBoundingBox(SkFixedToScalar(glyph.fAdvanceX), glyphBBox,
1375                                    &content);
1376        const SkPath* path = cache->findPath(glyph);
1377        if (path) {
1378            SkPDFUtils::EmitPath(*path, paint.getStyle(), &content);
1379            SkPDFUtils::PaintPath(paint.getStyle(), path->getFillType(),
1380                                  &content);
1381        }
1382        SkAutoTDelete<SkMemoryStream> glyphStream(new SkMemoryStream());
1383        glyphStream->setData(content.copyToData())->unref();
1384
1385        charProcs->insertObjRef(characterName,
1386                                new SkPDFStream(glyphStream.get()));
1387    }
1388
1389    encoding->insertObject("Differences", encDiffs.detach());
1390
1391    this->insertObject("CharProcs", charProcs.detach());
1392    this->insertObject("Encoding", encoding.detach());
1393
1394    this->insertObject("FontBBox", makeFontBBox(bbox, 1000));
1395    this->insertInt("FirstChar", 1);
1396    this->insertInt("LastChar", lastGlyphID() - firstGlyphID() + 1);
1397    this->insertObject("Widths", widthArray.detach());
1398    this->insertName("CIDToGIDMap", "Identity");
1399
1400    populateToUnicodeTable(NULL);
1401    return true;
1402}
1403
1404SkPDFFont::Match SkPDFFont::IsMatch(SkPDFFont* existingFont,
1405                                    uint32_t existingFontID,
1406                                    uint16_t existingGlyphID,
1407                                    uint32_t searchFontID,
1408                                    uint16_t searchGlyphID) {
1409    if (existingFontID != searchFontID) {
1410        return SkPDFFont::kNot_Match;
1411    }
1412    if (existingGlyphID == 0 || searchGlyphID == 0) {
1413        return SkPDFFont::kExact_Match;
1414    }
1415    if (existingFont != NULL) {
1416        return (existingFont->fFirstGlyphID <= searchGlyphID &&
1417                searchGlyphID <= existingFont->fLastGlyphID)
1418                       ? SkPDFFont::kExact_Match
1419                       : SkPDFFont::kRelated_Match;
1420    }
1421    return (existingGlyphID == searchGlyphID) ? SkPDFFont::kExact_Match
1422                                              : SkPDFFont::kRelated_Match;
1423}
1424