SkPDFFont.cpp revision 1f1658985586b30c913dbc935f17ce1aabcdf7b5
1/*
2 * Copyright (C) 2011 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <ctype.h>
18
19#include "SkData.h"
20#include "SkFontHost.h"
21#include "SkGlyphCache.h"
22#include "SkPaint.h"
23#include "SkPDFCatalog.h"
24#include "SkPDFDevice.h"
25#include "SkPDFFont.h"
26#include "SkPDFFontImpl.h"
27#include "SkPDFStream.h"
28#include "SkPDFTypes.h"
29#include "SkPDFUtils.h"
30#include "SkRefCnt.h"
31#include "SkScalar.h"
32#include "SkStream.h"
33#include "SkTypeface.h"
34#include "SkTypes.h"
35#include "SkUtils.h"
36
37#if defined (SK_SFNTLY_SUBSETTER)
38#include SK_SFNTLY_SUBSETTER
39#endif
40
41namespace {
42
43///////////////////////////////////////////////////////////////////////////////
44// File-Local Functions
45///////////////////////////////////////////////////////////////////////////////
46
47bool parsePFBSection(const uint8_t** src, size_t* len, int sectionType,
48                     size_t* size) {
49    // PFB sections have a two or six bytes header. 0x80 and a one byte
50    // section type followed by a four byte section length.  Type one is
51    // an ASCII section (includes a length), type two is a binary section
52    // (includes a length) and type three is an EOF marker with no length.
53    const uint8_t* buf = *src;
54    if (*len < 2 || buf[0] != 0x80 || buf[1] != sectionType)
55        return false;
56    if (buf[1] == 3)
57        return true;
58    if (*len < 6)
59        return false;
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    *src = *src + consumed;
67    *len = *len - consumed;
68    return true;
69}
70
71bool parsePFB(const uint8_t* src, size_t size, size_t* headerLen,
72              size_t* dataLen, size_t* trailerLen) {
73    const uint8_t* srcPtr = src;
74    size_t remaining = size;
75
76    return parsePFBSection(&srcPtr, &remaining, 1, headerLen) &&
77           parsePFBSection(&srcPtr, &remaining, 2, dataLen) &&
78           parsePFBSection(&srcPtr, &remaining, 1, trailerLen) &&
79           parsePFBSection(&srcPtr, &remaining, 3, NULL);
80}
81
82/* The sections of a PFA file are implicitly defined.  The body starts
83 * after the line containing "eexec," and the trailer starts with 512
84 * literal 0's followed by "cleartomark" (plus arbitrary white space).
85 *
86 * This function assumes that src is NUL terminated, but the NUL
87 * termination is not included in size.
88 *
89 */
90bool parsePFA(const char* src, size_t size, size_t* headerLen,
91              size_t* hexDataLen, size_t* dataLen, size_t* trailerLen) {
92    const char* end = src + size;
93
94    const char* dataPos = strstr(src, "eexec");
95    if (!dataPos)
96        return false;
97    dataPos += strlen("eexec");
98    while ((*dataPos == '\n' || *dataPos == '\r' || *dataPos == ' ') &&
99            dataPos < end)
100        dataPos++;
101    *headerLen = dataPos - src;
102
103    const char* trailerPos = strstr(dataPos, "cleartomark");
104    if (!trailerPos)
105        return false;
106    int zeroCount = 0;
107    for (trailerPos--; trailerPos > dataPos && zeroCount < 512; trailerPos--) {
108        if (*trailerPos == '\n' || *trailerPos == '\r' || *trailerPos == ' ') {
109            continue;
110        } else if (*trailerPos == '0') {
111            zeroCount++;
112        } else {
113            return false;
114        }
115    }
116    if (zeroCount != 512)
117        return false;
118
119    *hexDataLen = trailerPos - src - *headerLen;
120    *trailerLen = size - *headerLen - *hexDataLen;
121
122    // Verify that the data section is hex encoded and count the bytes.
123    int nibbles = 0;
124    for (; dataPos < trailerPos; dataPos++) {
125        if (isspace(*dataPos))
126            continue;
127        if (!isxdigit(*dataPos))
128            return false;
129        nibbles++;
130    }
131    *dataLen = (nibbles + 1) / 2;
132
133    return true;
134}
135
136int8_t hexToBin(uint8_t c) {
137    if (!isxdigit(c))
138        return -1;
139    if (c <= '9') return c - '0';
140    if (c <= 'F') return c - 'A' + 10;
141    if (c <= 'f') return c - 'a' + 10;
142    return -1;
143}
144
145SkStream* handleType1Stream(SkStream* srcStream, size_t* headerLen,
146                            size_t* dataLen, size_t* trailerLen) {
147    // srcStream may be backed by a file or a unseekable fd, so we may not be
148    // able to use skip(), rewind(), or getMemoryBase().  read()ing through
149    // the input only once is doable, but very ugly. Furthermore, it'd be nice
150    // if the data was NUL terminated so that we can use strstr() to search it.
151    // Make as few copies as possible given these constraints.
152    SkDynamicMemoryWStream dynamicStream;
153    SkRefPtr<SkMemoryStream> staticStream;
154    SkData* data = NULL;
155    const uint8_t* src;
156    size_t srcLen;
157    if ((srcLen = srcStream->getLength()) > 0) {
158        staticStream = new SkMemoryStream(srcLen + 1);
159        staticStream->unref();  // new and SkRefPtr both took a ref.
160        src = (const uint8_t*)staticStream->getMemoryBase();
161        if (srcStream->getMemoryBase() != NULL) {
162            memcpy((void *)src, srcStream->getMemoryBase(), srcLen);
163        } else {
164            size_t read = 0;
165            while (read < srcLen) {
166                size_t got = srcStream->read((void *)staticStream->getAtPos(),
167                                             srcLen - read);
168                if (got == 0)
169                    return NULL;
170                read += got;
171                staticStream->seek(read);
172            }
173        }
174        ((uint8_t *)src)[srcLen] = 0;
175    } else {
176        static const size_t bufSize = 4096;
177        uint8_t buf[bufSize];
178        size_t amount;
179        while ((amount = srcStream->read(buf, bufSize)) > 0)
180            dynamicStream.write(buf, amount);
181        amount = 0;
182        dynamicStream.write(&amount, 1);  // NULL terminator.
183        data = dynamicStream.copyToData();
184        src = data->bytes();
185        srcLen = data->size() - 1;
186    }
187
188    // this handles releasing the data we may have gotten from dynamicStream.
189    // if data is null, it is a no-op
190    SkAutoDataUnref aud(data);
191
192    if (parsePFB(src, srcLen, headerLen, dataLen, trailerLen)) {
193        SkMemoryStream* result =
194            new SkMemoryStream(*headerLen + *dataLen + *trailerLen);
195        memcpy((char*)result->getAtPos(), src + 6, *headerLen);
196        result->seek(*headerLen);
197        memcpy((char*)result->getAtPos(), src + 6 + *headerLen + 6, *dataLen);
198        result->seek(*headerLen + *dataLen);
199        memcpy((char*)result->getAtPos(), src + 6 + *headerLen + 6 + *dataLen,
200               *trailerLen);
201        result->rewind();
202        return result;
203    }
204
205    // A PFA has to be converted for PDF.
206    size_t hexDataLen;
207    if (parsePFA((const char*)src, srcLen, headerLen, &hexDataLen, dataLen,
208                 trailerLen)) {
209        SkMemoryStream* result =
210            new SkMemoryStream(*headerLen + *dataLen + *trailerLen);
211        memcpy((char*)result->getAtPos(), src, *headerLen);
212        result->seek(*headerLen);
213
214        const uint8_t* hexData = src + *headerLen;
215        const uint8_t* trailer = hexData + hexDataLen;
216        size_t outputOffset = 0;
217        uint8_t dataByte = 0;  // To hush compiler.
218        bool highNibble = true;
219        for (; hexData < trailer; hexData++) {
220            char curNibble = hexToBin(*hexData);
221            if (curNibble < 0)
222                continue;
223            if (highNibble) {
224                dataByte = curNibble << 4;
225                highNibble = false;
226            } else {
227                dataByte |= curNibble;
228                highNibble = true;
229                ((char *)result->getAtPos())[outputOffset++] = dataByte;
230            }
231        }
232        if (!highNibble)
233            ((char *)result->getAtPos())[outputOffset++] = dataByte;
234        SkASSERT(outputOffset == *dataLen);
235        result->seek(*headerLen + outputOffset);
236
237        memcpy((char *)result->getAtPos(), src + *headerLen + hexDataLen,
238               *trailerLen);
239        result->rewind();
240        return result;
241    }
242
243    return NULL;
244}
245
246// scale from em-units to base-1000, returning as a SkScalar
247SkScalar scaleFromFontUnits(int16_t val, uint16_t emSize) {
248    SkScalar scaled = SkIntToScalar(val);
249    if (emSize == 1000) {
250        return scaled;
251    } else {
252        return SkScalarMulDiv(scaled, 1000, emSize);
253    }
254}
255
256void setGlyphWidthAndBoundingBox(SkScalar width, SkIRect box,
257                                 SkWStream* content) {
258    // Specify width and bounding box for the glyph.
259    SkPDFScalar::Append(width, content);
260    content->writeText(" 0 ");
261    content->writeDecAsText(box.fLeft);
262    content->writeText(" ");
263    content->writeDecAsText(box.fTop);
264    content->writeText(" ");
265    content->writeDecAsText(box.fRight);
266    content->writeText(" ");
267    content->writeDecAsText(box.fBottom);
268    content->writeText(" d1\n");
269}
270
271SkPDFArray* makeFontBBox(SkIRect glyphBBox, uint16_t emSize) {
272    SkPDFArray* bbox = new SkPDFArray;
273    bbox->reserve(4);
274    bbox->appendScalar(scaleFromFontUnits(glyphBBox.fLeft, emSize));
275    bbox->appendScalar(scaleFromFontUnits(glyphBBox.fBottom, emSize));
276    bbox->appendScalar(scaleFromFontUnits(glyphBBox.fRight, emSize));
277    bbox->appendScalar(scaleFromFontUnits(glyphBBox.fTop, emSize));
278    return bbox;
279}
280
281SkPDFArray* appendWidth(const int16_t& width, uint16_t emSize,
282                        SkPDFArray* array) {
283    array->appendScalar(scaleFromFontUnits(width, emSize));
284    return array;
285}
286
287SkPDFArray* appendVerticalAdvance(
288        const SkAdvancedTypefaceMetrics::VerticalMetric& advance,
289        uint16_t emSize, SkPDFArray* array) {
290    appendWidth(advance.fVerticalAdvance, emSize, array);
291    appendWidth(advance.fOriginXDisp, emSize, array);
292    appendWidth(advance.fOriginYDisp, emSize, array);
293    return array;
294}
295
296template <typename Data>
297SkPDFArray* composeAdvanceData(
298        SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* advanceInfo,
299        uint16_t emSize,
300        SkPDFArray* (*appendAdvance)(const Data& advance, uint16_t emSize,
301                                     SkPDFArray* array),
302        Data* defaultAdvance) {
303    SkPDFArray* result = new SkPDFArray();
304    for (; advanceInfo != NULL; advanceInfo = advanceInfo->fNext.get()) {
305        switch (advanceInfo->fType) {
306            case SkAdvancedTypefaceMetrics::WidthRange::kDefault: {
307                SkASSERT(advanceInfo->fAdvance.count() == 1);
308                *defaultAdvance = advanceInfo->fAdvance[0];
309                break;
310            }
311            case SkAdvancedTypefaceMetrics::WidthRange::kRange: {
312                SkRefPtr<SkPDFArray> advanceArray = new SkPDFArray();
313                advanceArray->unref();  // SkRefPtr and new both took a ref.
314                for (int j = 0; j < advanceInfo->fAdvance.count(); j++)
315                    appendAdvance(advanceInfo->fAdvance[j], emSize,
316                                  advanceArray.get());
317                result->appendInt(advanceInfo->fStartId);
318                result->append(advanceArray.get());
319                break;
320            }
321            case SkAdvancedTypefaceMetrics::WidthRange::kRun: {
322                SkASSERT(advanceInfo->fAdvance.count() == 1);
323                result->appendInt(advanceInfo->fStartId);
324                result->appendInt(advanceInfo->fEndId);
325                appendAdvance(advanceInfo->fAdvance[0], emSize, result);
326                break;
327            }
328        }
329    }
330    return result;
331}
332
333}  // namespace
334
335static void append_tounicode_header(SkDynamicMemoryWStream* cmap) {
336    // 12 dict begin: 12 is an Adobe-suggested value. Shall not change.
337    // It's there to prevent old version Adobe Readers from malfunctioning.
338    const char* kHeader =
339        "/CIDInit /ProcSet findresource begin\n"
340        "12 dict begin\n"
341        "begincmap\n";
342    cmap->writeText(kHeader);
343
344    // The /CIDSystemInfo must be consistent to the one in
345    // SkPDFFont::populateCIDFont().
346    // We can not pass over the system info object here because the format is
347    // different. This is not a reference object.
348    const char* kSysInfo =
349        "/CIDSystemInfo\n"
350        "<<  /Registry (Adobe)\n"
351        "/Ordering (UCS)\n"
352        "/Supplement 0\n"
353        ">> def\n";
354    cmap->writeText(kSysInfo);
355
356    // The CMapName must be consistent to /CIDSystemInfo above.
357    // /CMapType 2 means ToUnicode.
358    // We specify codespacerange from 0x0000 to 0xFFFF because we convert our
359    // code table from unsigned short (16-bits). Codespace range just tells the
360    // PDF processor the valid range. It does not matter whether a complete
361    // mapping is provided or not.
362    const char* kTypeInfo =
363        "/CMapName /Adobe-Identity-UCS def\n"
364        "/CMapType 2 def\n"
365        "1 begincodespacerange\n"
366        "<0000> <FFFF>\n"
367        "endcodespacerange\n";
368    cmap->writeText(kTypeInfo);
369}
370
371static void append_cmap_bfchar_table(uint16_t* glyph_id, SkUnichar* unicode,
372                                     size_t count,
373                                     SkDynamicMemoryWStream* cmap) {
374    cmap->writeDecAsText(count);
375    cmap->writeText(" beginbfchar\n");
376    for (size_t i = 0; i < count; ++i) {
377        cmap->writeText("<");
378        cmap->writeHexAsText(glyph_id[i], 4);
379        cmap->writeText("> <");
380        cmap->writeHexAsText(unicode[i], 4);
381        cmap->writeText(">\n");
382    }
383    cmap->writeText("endbfchar\n");
384}
385
386static void append_cmap_footer(SkDynamicMemoryWStream* cmap) {
387    const char* kFooter =
388        "endcmap\n"
389        "CMapName currentdict /CMap defineresource pop\n"
390        "end\n"
391        "end";
392    cmap->writeText(kFooter);
393}
394
395// Generate <bfchar> table according to PDF spec 1.4 and Adobe Technote 5014.
396static void append_cmap_bfchar_sections(
397                const SkTDArray<SkUnichar>& glyphUnicode,
398                const SkPDFGlyphSet* subset, SkDynamicMemoryWStream* cmap) {
399    // PDF spec defines that every bf* list can have at most 100 entries.
400    const size_t kMaxEntries = 100;
401    uint16_t glyphId[kMaxEntries];
402    SkUnichar unicode[kMaxEntries];
403    size_t index = 0;
404    for (int i = 0; i < glyphUnicode.count(); i++) {
405        if (glyphUnicode[i] && (subset == NULL || subset->has(i))) {
406            glyphId[index] = i;
407            unicode[index] = glyphUnicode[i];
408            ++index;
409        }
410        if (index == kMaxEntries) {
411            append_cmap_bfchar_table(glyphId, unicode, index, cmap);
412            index = 0;
413        }
414    }
415
416    if (index) {
417        append_cmap_bfchar_table(glyphId, unicode, index, cmap);
418    }
419}
420
421static SkPDFStream* generate_tounicode_cmap(
422                        const SkTDArray<SkUnichar>& glyphUnicode,
423                        const SkPDFGlyphSet* subset) {
424    SkDynamicMemoryWStream cmap;
425    append_tounicode_header(&cmap);
426    append_cmap_bfchar_sections(glyphUnicode, subset, &cmap);
427    append_cmap_footer(&cmap);
428    SkRefPtr<SkMemoryStream> cmapStream = new SkMemoryStream();
429    cmapStream->unref();  // SkRefPtr and new took a reference.
430    cmapStream->setData(cmap.copyToData());
431    return new SkPDFStream(cmapStream.get());
432}
433
434static void sk_delete_array(const void* ptr, size_t, void*) {
435    // Use C-style cast to cast away const and cast type simultaneously.
436    delete[] (unsigned char*)ptr;
437}
438
439static int get_subset_font_stream(const char* fontName,
440                                  const SkTypeface* typeface,
441                                  const SkPDFGlyphSet* subset,
442                                  SkPDFStream** fontStream) {
443    SkRefPtr<SkStream> fontData =
444            SkFontHost::OpenStream(SkTypeface::UniqueID(typeface));
445    fontData->unref();  // SkRefPtr and OpenStream both took a ref.
446
447    int fontSize = fontData->getLength();
448
449#if defined (SK_SFNTLY_SUBSETTER)
450    // Generate glyph id array.
451    SkTDArray<unsigned int> glyphIDs;
452    glyphIDs.push(0);  // Always include glyph 0.
453    for (int i = 0; i <= SK_MaxU16; ++i) {
454        if (subset->has(i)) {
455            glyphIDs.push(i);
456        }
457    }
458
459    // Read font into buffer.
460    SkPDFStream* subsetFontStream = NULL;
461    SkTDArray<unsigned char> originalFont;
462    originalFont.setCount(fontSize);
463    if (fontData->read(originalFont.begin(), fontSize) == (size_t)fontSize) {
464        unsigned char* subsetFont = NULL;
465        int subsetFontSize = SfntlyWrapper::SubsetFont(fontName,
466                                                       originalFont.begin(),
467                                                       fontSize,
468                                                       glyphIDs.begin(),
469                                                       glyphIDs.count(),
470                                                       &subsetFont);
471        if (subsetFontSize > 0 && subsetFont != NULL) {
472            SkData* data = SkData::NewWithProc(subsetFont,
473                                               subsetFontSize,
474                                               sk_delete_array,
475                                               NULL);
476            subsetFontStream = new SkPDFStream(data);
477            fontSize = subsetFontSize;
478        }
479    }
480    if (subsetFontStream) {
481        *fontStream = subsetFontStream;
482        return fontSize;
483    }
484#endif
485
486    // Fail over: just embed the whole font.
487    *fontStream = new SkPDFStream(fontData.get());
488    return fontSize;
489}
490
491///////////////////////////////////////////////////////////////////////////////
492// class SkPDFGlyphSet
493///////////////////////////////////////////////////////////////////////////////
494
495SkPDFGlyphSet::SkPDFGlyphSet() : fBitSet(SK_MaxU16 + 1) {
496}
497
498void SkPDFGlyphSet::set(const uint16_t* glyphIDs, int numGlyphs) {
499    for (int i = 0; i < numGlyphs; ++i) {
500        fBitSet.setBit(glyphIDs[i], true);
501    }
502}
503
504bool SkPDFGlyphSet::has(uint16_t glyphID) const {
505    return fBitSet.isBitSet(glyphID);
506}
507
508void SkPDFGlyphSet::merge(const SkPDFGlyphSet& usage) {
509    fBitSet.orBits(usage.fBitSet);
510}
511
512///////////////////////////////////////////////////////////////////////////////
513// class SkPDFGlyphSetMap
514///////////////////////////////////////////////////////////////////////////////
515SkPDFGlyphSetMap::FontGlyphSetPair::FontGlyphSetPair(SkPDFFont* font,
516                                                     SkPDFGlyphSet* glyphSet)
517        : fFont(font),
518          fGlyphSet(glyphSet) {
519}
520
521SkPDFGlyphSetMap::F2BIter::F2BIter(const SkPDFGlyphSetMap& map) {
522    reset(map);
523}
524
525SkPDFGlyphSetMap::FontGlyphSetPair* SkPDFGlyphSetMap::F2BIter::next() const {
526    if (fIndex >= fMap->count()) {
527        return NULL;
528    }
529    return &((*fMap)[fIndex++]);
530}
531
532void SkPDFGlyphSetMap::F2BIter::reset(const SkPDFGlyphSetMap& map) {
533    fMap = &(map.fMap);
534    fIndex = 0;
535}
536
537SkPDFGlyphSetMap::SkPDFGlyphSetMap() {
538}
539
540SkPDFGlyphSetMap::~SkPDFGlyphSetMap() {
541    reset();
542}
543
544void SkPDFGlyphSetMap::merge(const SkPDFGlyphSetMap& usage) {
545    for (int i = 0; i < usage.fMap.count(); ++i) {
546        SkPDFGlyphSet* myUsage = getGlyphSetForFont(usage.fMap[i].fFont);
547        myUsage->merge(*(usage.fMap[i].fGlyphSet));
548    }
549}
550
551void SkPDFGlyphSetMap::reset() {
552    for (int i = 0; i < fMap.count(); ++i) {
553        delete fMap[i].fGlyphSet;  // Should not be NULL.
554    }
555    fMap.reset();
556}
557
558void SkPDFGlyphSetMap::noteGlyphUsage(SkPDFFont* font, const uint16_t* glyphIDs,
559                                      int numGlyphs) {
560    SkPDFGlyphSet* subset = getGlyphSetForFont(font);
561    if (subset) {
562        subset->set(glyphIDs, numGlyphs);
563    }
564}
565
566SkPDFGlyphSet* SkPDFGlyphSetMap::getGlyphSetForFont(SkPDFFont* font) {
567    int index = fMap.count();
568    for (int i = 0; i < index; ++i) {
569        if (fMap[i].fFont == font) {
570            return fMap[i].fGlyphSet;
571        }
572    }
573    fMap.append();
574    index = fMap.count() - 1;
575    fMap[index].fFont = font;
576    fMap[index].fGlyphSet = new SkPDFGlyphSet();
577    return fMap[index].fGlyphSet;
578}
579
580///////////////////////////////////////////////////////////////////////////////
581// class SkPDFFont
582///////////////////////////////////////////////////////////////////////////////
583
584/* Font subset design: It would be nice to be able to subset fonts
585 * (particularly type 3 fonts), but it's a lot of work and not a priority.
586 *
587 * Resources are canonicalized and uniqueified by pointer so there has to be
588 * some additional state indicating which subset of the font is used.  It
589 * must be maintained at the page granularity and then combined at the document
590 * granularity. a) change SkPDFFont to fill in its state on demand, kind of
591 * like SkPDFGraphicState.  b) maintain a per font glyph usage class in each
592 * page/pdf device. c) in the document, retrieve the per font glyph usage
593 * from each page and combine it and ask for a resource with that subset.
594 */
595
596SkPDFFont::~SkPDFFont() {
597    SkAutoMutexAcquire lock(CanonicalFontsMutex());
598    int index;
599    if (Find(SkTypeface::UniqueID(fTypeface.get()), fFirstGlyphID, &index)) {
600        CanonicalFonts().removeShuffle(index);
601    }
602    fResources.unrefAll();
603}
604
605void SkPDFFont::getResources(SkTDArray<SkPDFObject*>* resourceList) {
606    GetResourcesHelper(&fResources, resourceList);
607}
608
609SkTypeface* SkPDFFont::typeface() {
610    return fTypeface.get();
611}
612
613SkAdvancedTypefaceMetrics::FontType SkPDFFont::getType() {
614    return fFontType;
615}
616
617bool SkPDFFont::hasGlyph(uint16_t id) {
618    return (id >= fFirstGlyphID && id <= fLastGlyphID) || id == 0;
619}
620
621size_t SkPDFFont::glyphsToPDFFontEncoding(uint16_t* glyphIDs,
622                                          size_t numGlyphs) {
623    // A font with multibyte glyphs will support all glyph IDs in a single font.
624    if (this->multiByteGlyphs()) {
625        return numGlyphs;
626    }
627
628    for (size_t i = 0; i < numGlyphs; i++) {
629        if (glyphIDs[i] == 0) {
630            continue;
631        }
632        if (glyphIDs[i] < fFirstGlyphID || glyphIDs[i] > fLastGlyphID) {
633            return i;
634        }
635        glyphIDs[i] -= (fFirstGlyphID - 1);
636    }
637
638    return numGlyphs;
639}
640
641// static
642SkPDFFont* SkPDFFont::GetFontResource(SkTypeface* typeface, uint16_t glyphID) {
643    SkAutoMutexAcquire lock(CanonicalFontsMutex());
644    const uint32_t fontID = SkTypeface::UniqueID(typeface);
645    int relatedFontIndex;
646    if (Find(fontID, glyphID, &relatedFontIndex)) {
647        CanonicalFonts()[relatedFontIndex].fFont->ref();
648        return CanonicalFonts()[relatedFontIndex].fFont;
649    }
650
651    SkRefPtr<SkAdvancedTypefaceMetrics> fontMetrics;
652    SkPDFDict* relatedFontDescriptor = NULL;
653    if (relatedFontIndex >= 0) {
654        SkPDFFont* relatedFont = CanonicalFonts()[relatedFontIndex].fFont;
655        SkASSERT(relatedFont->fFontInfo.get());
656        fontMetrics = relatedFont->fontInfo();
657        relatedFontDescriptor = relatedFont->getFontDescriptor();
658    } else {
659        SkAdvancedTypefaceMetrics::PerGlyphInfo info;
660        info = SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo;
661        info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>(
662                  info, SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo);
663        info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>(
664                  info, SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo);
665        fontMetrics = SkFontHost::GetAdvancedTypefaceMetrics(fontID, info);
666        SkSafeUnref(fontMetrics.get());  // SkRefPtr and Get both took a ref.
667    }
668
669    SkPDFFont* font = Create(fontMetrics.get(), typeface, glyphID,
670                             relatedFontDescriptor);
671    FontRec newEntry(font, fontID, font->fFirstGlyphID);
672    CanonicalFonts().push(newEntry);
673    return font;  // Return the reference new SkPDFFont() created.
674}
675
676SkPDFFont* SkPDFFont::getFontSubset(const SkPDFGlyphSet* usage) {
677    return NULL;  // Default: no support.
678}
679
680// static
681SkTDArray<SkPDFFont::FontRec>& SkPDFFont::CanonicalFonts() {
682    // This initialization is only thread safe with gcc.
683    static SkTDArray<FontRec> gCanonicalFonts;
684    return gCanonicalFonts;
685}
686
687// static
688SkMutex& SkPDFFont::CanonicalFontsMutex() {
689    // This initialization is only thread safe with gcc.
690    static SkMutex gCanonicalFontsMutex;
691    return gCanonicalFontsMutex;
692}
693
694// static
695bool SkPDFFont::Find(uint32_t fontID, uint16_t glyphID, int* index) {
696    // TODO(vandebo) optimize this, do only one search?
697    FontRec search(NULL, fontID, glyphID);
698    *index = CanonicalFonts().find(search);
699    if (*index >= 0)
700        return true;
701    search.fGlyphID = 0;
702    *index = CanonicalFonts().find(search);
703    return false;
704}
705
706SkPDFFont::SkPDFFont(SkAdvancedTypefaceMetrics* info, SkTypeface* typeface,
707                     uint16_t glyphID, bool descendantFont)
708        : SkPDFDict("Font"),
709          fTypeface(typeface),
710          fFirstGlyphID(1),
711          fLastGlyphID(info ? info->fLastGlyphID : 0),
712          fFontInfo(info) {
713    if (info == NULL) {
714        fFontType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font;
715    } else if (info->fMultiMaster) {
716        fFontType = SkAdvancedTypefaceMetrics::kOther_Font;
717    } else {
718        fFontType = info->fType;
719    }
720}
721
722// static
723SkPDFFont* SkPDFFont::Create(SkAdvancedTypefaceMetrics* info,
724                             SkTypeface* typeface, uint16_t glyphID,
725                             SkPDFDict* relatedFontDescriptor) {
726    SkAdvancedTypefaceMetrics::FontType type =
727        info ? info->fType : SkAdvancedTypefaceMetrics::kNotEmbeddable_Font;
728
729    if (info && info->fMultiMaster) {
730        NOT_IMPLEMENTED(true, true);
731        return new SkPDFType3Font(info,
732                                  typeface,
733                                  glyphID,
734                                  relatedFontDescriptor);
735    }
736    if (type == SkAdvancedTypefaceMetrics::kType1CID_Font ||
737        type == SkAdvancedTypefaceMetrics::kTrueType_Font) {
738        SkASSERT(relatedFontDescriptor == NULL);
739        return new SkPDFType0Font(info, typeface);
740    }
741    if (type == SkAdvancedTypefaceMetrics::kType1_Font) {
742        return new SkPDFType1Font(info,
743                                  typeface,
744                                  glyphID,
745                                  relatedFontDescriptor);
746    }
747
748    SkASSERT(type == SkAdvancedTypefaceMetrics::kCFF_Font ||
749             type == SkAdvancedTypefaceMetrics::kOther_Font ||
750             type == SkAdvancedTypefaceMetrics::kNotEmbeddable_Font);
751
752    return new SkPDFType3Font(info, typeface, glyphID, relatedFontDescriptor);
753}
754
755SkAdvancedTypefaceMetrics* SkPDFFont::fontInfo() {
756    return fFontInfo.get();
757}
758
759uint16_t SkPDFFont::firstGlyphID() const {
760    return fFirstGlyphID;
761}
762
763uint16_t SkPDFFont::lastGlyphID() const {
764    return fLastGlyphID;
765}
766
767void SkPDFFont::setLastGlyphID(uint16_t glyphID) {
768    fLastGlyphID = glyphID;
769}
770
771void SkPDFFont::addResource(SkPDFObject* object) {
772    SkASSERT(object != NULL);
773    fResources.push(object);
774}
775
776SkPDFDict* SkPDFFont::getFontDescriptor() {
777    return fDescriptor.get();
778}
779
780void SkPDFFont::setFontDescriptor(SkPDFDict* descriptor) {
781    fDescriptor = descriptor;
782}
783
784bool SkPDFFont::addCommonFontDescriptorEntries(int16_t defaultWidth) {
785    if (fDescriptor.get() == NULL) {
786        return false;
787    }
788
789    const uint16_t emSize = fFontInfo->fEmSize;
790
791    fDescriptor->insertName("FontName", fFontInfo->fFontName);
792    fDescriptor->insertInt("Flags", fFontInfo->fStyle);
793    fDescriptor->insertScalar("Ascent",
794            scaleFromFontUnits(fFontInfo->fAscent, emSize));
795    fDescriptor->insertScalar("Descent",
796            scaleFromFontUnits(fFontInfo->fDescent, emSize));
797    fDescriptor->insertScalar("StemV",
798            scaleFromFontUnits(fFontInfo->fStemV, emSize));
799    fDescriptor->insertScalar("CapHeight",
800            scaleFromFontUnits(fFontInfo->fCapHeight, emSize));
801    fDescriptor->insertInt("ItalicAngle", fFontInfo->fItalicAngle);
802    fDescriptor->insert("FontBBox", makeFontBBox(fFontInfo->fBBox,
803                                                 fFontInfo->fEmSize))->unref();
804
805    if (defaultWidth > 0) {
806        fDescriptor->insertScalar("MissingWidth",
807                scaleFromFontUnits(defaultWidth, emSize));
808    }
809    return true;
810}
811
812void SkPDFFont::adjustGlyphRangeForSingleByteEncoding(int16_t glyphID) {
813    // Single byte glyph encoding supports a max of 255 glyphs.
814    fFirstGlyphID = glyphID - (glyphID - 1) % 255;
815    if (fLastGlyphID > fFirstGlyphID + 255 - 1) {
816        fLastGlyphID = fFirstGlyphID + 255 - 1;
817    }
818}
819
820bool SkPDFFont::FontRec::operator==(const SkPDFFont::FontRec& b) const {
821    if (fFontID != b.fFontID)
822        return false;
823    if (fFont != NULL && b.fFont != NULL) {
824        return fFont->fFirstGlyphID == b.fFont->fFirstGlyphID &&
825            fFont->fLastGlyphID == b.fFont->fLastGlyphID;
826    }
827    if (fGlyphID == 0 || b.fGlyphID == 0)
828        return true;
829
830    if (fFont != NULL) {
831        return fFont->fFirstGlyphID <= b.fGlyphID &&
832            b.fGlyphID <= fFont->fLastGlyphID;
833    } else if (b.fFont != NULL) {
834        return b.fFont->fFirstGlyphID <= fGlyphID &&
835            fGlyphID <= b.fFont->fLastGlyphID;
836    }
837    return fGlyphID == b.fGlyphID;
838}
839
840SkPDFFont::FontRec::FontRec(SkPDFFont* font, uint32_t fontID, uint16_t glyphID)
841    : fFont(font),
842      fFontID(fontID),
843      fGlyphID(glyphID) {
844}
845
846void SkPDFFont::populateToUnicodeTable(const SkPDFGlyphSet* subset) {
847    if (fFontInfo == NULL || fFontInfo->fGlyphToUnicode.begin() == NULL) {
848        return;
849    }
850    SkRefPtr<SkPDFStream> pdfCmap =
851        generate_tounicode_cmap(fFontInfo->fGlyphToUnicode, subset);
852    addResource(pdfCmap.get());  // Pass reference from new.
853    insert("ToUnicode", new SkPDFObjRef(pdfCmap.get()))->unref();
854}
855
856///////////////////////////////////////////////////////////////////////////////
857// class SkPDFType0Font
858///////////////////////////////////////////////////////////////////////////////
859
860SkPDFType0Font::SkPDFType0Font(SkAdvancedTypefaceMetrics* info,
861                               SkTypeface* typeface)
862        : SkPDFFont(info, typeface, 0, false) {
863    SkDEBUGCODE(fPopulated = false);
864}
865
866SkPDFType0Font::~SkPDFType0Font() {}
867
868SkPDFFont* SkPDFType0Font::getFontSubset(const SkPDFGlyphSet* subset) {
869    SkPDFType0Font* newSubset = new SkPDFType0Font(fontInfo(), typeface());
870    newSubset->populate(subset);
871    return newSubset;
872}
873
874#ifdef SK_DEBUG
875void SkPDFType0Font::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
876                                bool indirect) {
877    SkASSERT(fPopulated);
878    return INHERITED::emitObject(stream, catalog, indirect);
879}
880#endif
881
882bool SkPDFType0Font::populate(const SkPDFGlyphSet* subset) {
883    insertName("Subtype", "Type0");
884    insertName("BaseFont", fontInfo()->fFontName);
885    insertName("Encoding", "Identity-H");
886
887    // Pass ref new created to fResources.
888    SkPDFCIDFont* newCIDFont =
889        new SkPDFCIDFont(fontInfo(), typeface(), subset);
890    addResource(newCIDFont);
891    SkRefPtr<SkPDFArray> descendantFonts = new SkPDFArray();
892    descendantFonts->unref();  // SkRefPtr and new took a reference.
893    descendantFonts->append(new SkPDFObjRef(newCIDFont))->unref();
894    insert("DescendantFonts", descendantFonts.get());
895
896    populateToUnicodeTable(subset);
897
898    SkDEBUGCODE(fPopulated = true);
899    return true;
900}
901
902///////////////////////////////////////////////////////////////////////////////
903// class SkPDFCIDFont
904///////////////////////////////////////////////////////////////////////////////
905
906SkPDFCIDFont::SkPDFCIDFont(SkAdvancedTypefaceMetrics* info,
907                           SkTypeface* typeface, const SkPDFGlyphSet* subset)
908        : SkPDFFont(info, typeface, 0, true) {
909    populate(subset);
910}
911
912SkPDFCIDFont::~SkPDFCIDFont() {}
913
914bool SkPDFCIDFont::addFontDescriptor(int16_t defaultWidth,
915                                     const SkPDFGlyphSet* subset) {
916    SkRefPtr<SkPDFDict> descriptor = new SkPDFDict("FontDescriptor");
917    descriptor->unref();  // SkRefPtr and new both took a ref.
918    setFontDescriptor(descriptor.get());
919
920    switch (getType()) {
921        case SkAdvancedTypefaceMetrics::kTrueType_Font: {
922            // Font subsetting
923            SkPDFStream* rawStream = NULL;
924            int fontSize = get_subset_font_stream(fontInfo()->fFontName.c_str(),
925                                                  typeface(),
926                                                  subset,
927                                                  &rawStream);
928            SkASSERT(fontSize);
929            SkASSERT(rawStream);
930            SkRefPtr<SkPDFStream> fontStream = rawStream;
931            // SkRefPtr and new both ref()'d fontStream, pass one.
932            addResource(fontStream.get());
933
934            fontStream->insertInt("Length1", fontSize);
935            descriptor->insert("FontFile2",
936                                new SkPDFObjRef(fontStream.get()))->unref();
937            break;
938        }
939        case SkAdvancedTypefaceMetrics::kCFF_Font:
940        case SkAdvancedTypefaceMetrics::kType1CID_Font: {
941            SkRefPtr<SkStream> fontData =
942                SkFontHost::OpenStream(SkTypeface::UniqueID(typeface()));
943            fontData->unref();  // SkRefPtr and OpenStream both took a ref.
944            SkRefPtr<SkPDFStream> fontStream = new SkPDFStream(fontData.get());
945            // SkRefPtr and new both ref()'d fontStream, pass one.
946            addResource(fontStream.get());
947
948            if (getType() == SkAdvancedTypefaceMetrics::kCFF_Font) {
949                fontStream->insertName("Subtype", "Type1C");
950            } else {
951                fontStream->insertName("Subtype", "CIDFontType0c");
952            }
953            descriptor->insert("FontFile3",
954                                new SkPDFObjRef(fontStream.get()))->unref();
955            break;
956        }
957        default:
958            SkASSERT(false);
959    }
960
961    addResource(descriptor.get());
962    descriptor->ref();
963
964    insert("FontDescriptor", new SkPDFObjRef(descriptor.get()))->unref();
965    return addCommonFontDescriptorEntries(defaultWidth);
966}
967
968bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) {
969    insertName("BaseFont", fontInfo()->fFontName);
970
971    if (getType() == SkAdvancedTypefaceMetrics::kType1CID_Font) {
972        insertName("Subtype", "CIDFontType0");
973    } else if (getType() == SkAdvancedTypefaceMetrics::kTrueType_Font) {
974        insertName("Subtype", "CIDFontType2");
975        insertName("CIDToGIDMap", "Identity");
976    } else {
977        SkASSERT(false);
978    }
979
980    SkRefPtr<SkPDFDict> sysInfo = new SkPDFDict;
981    sysInfo->unref();  // SkRefPtr and new both took a reference.
982    sysInfo->insert("Registry", new SkPDFString("Adobe"))->unref();
983    sysInfo->insert("Ordering", new SkPDFString("Identity"))->unref();
984    sysInfo->insertInt("Supplement", 0);
985    insert("CIDSystemInfo", sysInfo.get());
986
987    addFontDescriptor(0, subset);
988
989    if (fontInfo()->fGlyphWidths.get()) {
990        int16_t defaultWidth = 0;
991        SkRefPtr<SkPDFArray> widths =
992            composeAdvanceData(fontInfo()->fGlyphWidths.get(),
993                               fontInfo()->fEmSize, &appendWidth,
994                               &defaultWidth);
995        widths->unref();  // SkRefPtr and compose both took a reference.
996        if (widths->size())
997            insert("W", widths.get());
998        if (defaultWidth != 0) {
999            insertScalar("DW", scaleFromFontUnits(defaultWidth,
1000                                                  fontInfo()->fEmSize));
1001        }
1002    }
1003    if (fontInfo()->fVerticalMetrics.get()) {
1004        struct SkAdvancedTypefaceMetrics::VerticalMetric defaultAdvance;
1005        defaultAdvance.fVerticalAdvance = 0;
1006        defaultAdvance.fOriginXDisp = 0;
1007        defaultAdvance.fOriginYDisp = 0;
1008        SkRefPtr<SkPDFArray> advances =
1009            composeAdvanceData(fontInfo()->fVerticalMetrics.get(),
1010                               fontInfo()->fEmSize, &appendVerticalAdvance,
1011                               &defaultAdvance);
1012        advances->unref();  // SkRefPtr and compose both took a ref.
1013        if (advances->size())
1014            insert("W2", advances.get());
1015        if (defaultAdvance.fVerticalAdvance ||
1016                defaultAdvance.fOriginXDisp ||
1017                defaultAdvance.fOriginYDisp) {
1018            insert("DW2", appendVerticalAdvance(defaultAdvance,
1019                                                fontInfo()->fEmSize,
1020                                                new SkPDFArray))->unref();
1021        }
1022    }
1023
1024    return true;
1025}
1026
1027///////////////////////////////////////////////////////////////////////////////
1028// class SkPDFType1Font
1029///////////////////////////////////////////////////////////////////////////////
1030
1031SkPDFType1Font::SkPDFType1Font(SkAdvancedTypefaceMetrics* info,
1032                               SkTypeface* typeface,
1033                               uint16_t glyphID,
1034                               SkPDFDict* relatedFontDescriptor)
1035        : SkPDFFont(info, typeface, glyphID, false) {
1036    populate(glyphID);
1037}
1038
1039SkPDFType1Font::~SkPDFType1Font() {}
1040
1041bool SkPDFType1Font::addFontDescriptor(int16_t defaultWidth) {
1042    SkRefPtr<SkPDFDict> descriptor = getFontDescriptor();
1043    if (descriptor.get() != NULL) {
1044        addResource(descriptor.get());
1045        descriptor->ref();
1046        insert("FontDescriptor", new SkPDFObjRef(descriptor.get()))->unref();
1047        return true;
1048    }
1049
1050    descriptor = new SkPDFDict("FontDescriptor");
1051    descriptor->unref();  // SkRefPtr and new both took a ref.
1052    setFontDescriptor(descriptor.get());
1053
1054    size_t header SK_INIT_TO_AVOID_WARNING;
1055    size_t data SK_INIT_TO_AVOID_WARNING;
1056    size_t trailer SK_INIT_TO_AVOID_WARNING;
1057    SkRefPtr<SkStream> rawFontData =
1058        SkFontHost::OpenStream(SkTypeface::UniqueID(typeface()));
1059    rawFontData->unref();  // SkRefPtr and OpenStream both took a ref.
1060    SkStream* fontData = handleType1Stream(rawFontData.get(), &header, &data,
1061                                           &trailer);
1062    if (fontData == NULL) {
1063        return false;
1064    }
1065    SkRefPtr<SkPDFStream> fontStream = new SkPDFStream(fontData);
1066    // SkRefPtr and new both ref()'d fontStream, pass one.
1067    addResource(fontStream.get());
1068    fontStream->insertInt("Length1", header);
1069    fontStream->insertInt("Length2", data);
1070    fontStream->insertInt("Length3", trailer);
1071    descriptor->insert("FontFile", new SkPDFObjRef(fontStream.get()))->unref();
1072
1073    addResource(descriptor.get());
1074    descriptor->ref();
1075    insert("FontDescriptor", new SkPDFObjRef(descriptor.get()))->unref();
1076
1077    return addCommonFontDescriptorEntries(defaultWidth);
1078}
1079
1080bool SkPDFType1Font::populate(int16_t glyphID) {
1081    SkASSERT(!fontInfo()->fVerticalMetrics.get());
1082    SkASSERT(fontInfo()->fGlyphWidths.get());
1083
1084    adjustGlyphRangeForSingleByteEncoding(glyphID);
1085
1086    int16_t defaultWidth = 0;
1087    const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry = NULL;
1088    const SkAdvancedTypefaceMetrics::WidthRange* widthEntry;
1089    for (widthEntry = fontInfo()->fGlyphWidths.get();
1090            widthEntry != NULL;
1091            widthEntry = widthEntry->fNext.get()) {
1092        switch (widthEntry->fType) {
1093            case SkAdvancedTypefaceMetrics::WidthRange::kDefault:
1094                defaultWidth = widthEntry->fAdvance[0];
1095                break;
1096            case SkAdvancedTypefaceMetrics::WidthRange::kRun:
1097                SkASSERT(false);
1098                break;
1099            case SkAdvancedTypefaceMetrics::WidthRange::kRange:
1100                SkASSERT(widthRangeEntry == NULL);
1101                widthRangeEntry = widthEntry;
1102                break;
1103        }
1104    }
1105
1106    if (!addFontDescriptor(defaultWidth))
1107        return false;
1108
1109    insertName("Subtype", "Type1");
1110    insertName("BaseFont", fontInfo()->fFontName);
1111
1112    addWidthInfoFromRange(defaultWidth, widthRangeEntry);
1113
1114    SkRefPtr<SkPDFDict> encoding = new SkPDFDict("Encoding");
1115    encoding->unref();  // SkRefPtr and new both took a reference.
1116    insert("Encoding", encoding.get());
1117
1118    SkRefPtr<SkPDFArray> encDiffs = new SkPDFArray;
1119    encDiffs->unref();  // SkRefPtr and new both took a reference.
1120    encoding->insert("Differences", encDiffs.get());
1121
1122    encDiffs->reserve(lastGlyphID() - firstGlyphID() + 2);
1123    encDiffs->appendInt(1);
1124    for (int gID = firstGlyphID(); gID <= lastGlyphID(); gID++) {
1125        encDiffs->appendName(fontInfo()->fGlyphNames->get()[gID].c_str());
1126    }
1127
1128    return true;
1129}
1130
1131void SkPDFType1Font::addWidthInfoFromRange(
1132        int16_t defaultWidth,
1133        const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry) {
1134    SkRefPtr<SkPDFArray> widthArray = new SkPDFArray();
1135    widthArray->unref();  // SkRefPtr and new both took a ref.
1136    int firstChar = 0;
1137    if (widthRangeEntry) {
1138        const uint16_t emSize = fontInfo()->fEmSize;
1139        int startIndex = firstGlyphID() - widthRangeEntry->fStartId;
1140        int endIndex = startIndex + lastGlyphID() - firstGlyphID() + 1;
1141        if (startIndex < 0)
1142            startIndex = 0;
1143        if (endIndex > widthRangeEntry->fAdvance.count())
1144            endIndex = widthRangeEntry->fAdvance.count();
1145        if (widthRangeEntry->fStartId == 0) {
1146            appendWidth(widthRangeEntry->fAdvance[0], emSize, widthArray.get());
1147        } else {
1148            firstChar = startIndex + widthRangeEntry->fStartId;
1149        }
1150        for (int i = startIndex; i < endIndex; i++)
1151            appendWidth(widthRangeEntry->fAdvance[i], emSize, widthArray.get());
1152    } else {
1153        appendWidth(defaultWidth, 1000, widthArray.get());
1154    }
1155    insertInt("FirstChar", firstChar);
1156    insertInt("LastChar", firstChar + widthArray->size() - 1);
1157    insert("Widths", widthArray.get());
1158}
1159
1160///////////////////////////////////////////////////////////////////////////////
1161// class SkPDFType3Font
1162///////////////////////////////////////////////////////////////////////////////
1163
1164SkPDFType3Font::SkPDFType3Font(SkAdvancedTypefaceMetrics* info,
1165                               SkTypeface* typeface,
1166                               uint16_t glyphID,
1167                               SkPDFDict* relatedFontDescriptor)
1168        : SkPDFFont(info, typeface, glyphID, false) {
1169    populate(glyphID);
1170}
1171
1172SkPDFType3Font::~SkPDFType3Font() {}
1173
1174bool SkPDFType3Font::populate(int16_t glyphID) {
1175    SkPaint paint;
1176    paint.setTypeface(typeface());
1177    paint.setTextSize(1000);
1178    SkAutoGlyphCache autoCache(paint, NULL);
1179    SkGlyphCache* cache = autoCache.getCache();
1180    // If fLastGlyphID isn't set (because there is not fFontInfo), look it up.
1181    if (lastGlyphID() == 0) {
1182        setLastGlyphID(cache->getGlyphCount() - 1);
1183    }
1184
1185    adjustGlyphRangeForSingleByteEncoding(glyphID);
1186
1187    insertName("Subtype", "Type3");
1188    // Flip about the x-axis and scale by 1/1000.
1189    SkMatrix fontMatrix;
1190    fontMatrix.setScale(SkScalarInvert(1000), -SkScalarInvert(1000));
1191    insert("FontMatrix", SkPDFUtils::MatrixToArray(fontMatrix))->unref();
1192
1193    SkRefPtr<SkPDFDict> charProcs = new SkPDFDict;
1194    charProcs->unref();  // SkRefPtr and new both took a reference.
1195    insert("CharProcs", charProcs.get());
1196
1197    SkRefPtr<SkPDFDict> encoding = new SkPDFDict("Encoding");
1198    encoding->unref();  // SkRefPtr and new both took a reference.
1199    insert("Encoding", encoding.get());
1200
1201    SkRefPtr<SkPDFArray> encDiffs = new SkPDFArray;
1202    encDiffs->unref();  // SkRefPtr and new both took a reference.
1203    encoding->insert("Differences", encDiffs.get());
1204    encDiffs->reserve(lastGlyphID() - firstGlyphID() + 2);
1205    encDiffs->appendInt(1);
1206
1207    SkRefPtr<SkPDFArray> widthArray = new SkPDFArray();
1208    widthArray->unref();  // SkRefPtr and new both took a ref.
1209
1210    SkIRect bbox = SkIRect::MakeEmpty();
1211    for (int gID = firstGlyphID(); gID <= lastGlyphID(); gID++) {
1212        SkString characterName;
1213        characterName.printf("gid%d", gID);
1214        encDiffs->appendName(characterName.c_str());
1215
1216        const SkGlyph& glyph = cache->getGlyphIDMetrics(gID);
1217        widthArray->appendScalar(SkFixedToScalar(glyph.fAdvanceX));
1218        SkIRect glyphBBox = SkIRect::MakeXYWH(glyph.fLeft, glyph.fTop,
1219                                              glyph.fWidth, glyph.fHeight);
1220        bbox.join(glyphBBox);
1221
1222        SkDynamicMemoryWStream content;
1223        setGlyphWidthAndBoundingBox(SkFixedToScalar(glyph.fAdvanceX), glyphBBox,
1224                                    &content);
1225        const SkPath* path = cache->findPath(glyph);
1226        if (path) {
1227            SkPDFUtils::EmitPath(*path, &content);
1228            SkPDFUtils::PaintPath(paint.getStyle(), path->getFillType(),
1229                                  &content);
1230        }
1231        SkRefPtr<SkMemoryStream> glyphStream = new SkMemoryStream();
1232        glyphStream->unref();  // SkRefPtr and new both took a ref.
1233        glyphStream->setData(content.copyToData())->unref();
1234
1235        SkRefPtr<SkPDFStream> glyphDescription =
1236            new SkPDFStream(glyphStream.get());
1237        // SkRefPtr and new both ref()'d charProcs, pass one.
1238        addResource(glyphDescription.get());
1239        charProcs->insert(characterName.c_str(),
1240                          new SkPDFObjRef(glyphDescription.get()))->unref();
1241    }
1242
1243    insert("FontBBox", makeFontBBox(bbox, 1000))->unref();
1244    insertInt("FirstChar", firstGlyphID());
1245    insertInt("LastChar", lastGlyphID());
1246    insert("Widths", widthArray.get());
1247    insertName("CIDToGIDMap", "Identity");
1248
1249    populateToUnicodeTable(NULL);
1250    return true;
1251}
1252