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