Home | History | Annotate | Download | only in pdf
      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 "SkFontHost.h"
     20 #include "SkGlyphCache.h"
     21 #include "SkPaint.h"
     22 #include "SkPDFDevice.h"
     23 #include "SkPDFFont.h"
     24 #include "SkPDFStream.h"
     25 #include "SkPDFTypes.h"
     26 #include "SkPDFUtils.h"
     27 #include "SkRefCnt.h"
     28 #include "SkScalar.h"
     29 #include "SkStream.h"
     30 #include "SkTypeface.h"
     31 #include "SkTypes.h"
     32 #include "SkUtils.h"
     33 
     34 namespace {
     35 
     36 bool parsePFBSection(const uint8_t** src, size_t* len, int sectionType,
     37                      size_t* size) {
     38     // PFB sections have a two or six bytes header. 0x80 and a one byte
     39     // section type followed by a four byte section length.  Type one is
     40     // an ASCII section (includes a length), type two is a binary section
     41     // (includes a length) and type three is an EOF marker with no length.
     42     const uint8_t* buf = *src;
     43     if (*len < 2 || buf[0] != 0x80 || buf[1] != sectionType)
     44         return false;
     45     if (buf[1] == 3)
     46         return true;
     47     if (*len < 6)
     48         return false;
     49 
     50     *size = buf[2] | (buf[3] << 8) | (buf[4] << 16) | (buf[5] << 24);
     51     size_t consumed = *size + 6;
     52     if (consumed > *len)
     53         return false;
     54     *src = *src + consumed;
     55     *len = *len - consumed;
     56     return true;
     57 }
     58 
     59 bool parsePFB(const uint8_t* src, size_t size, size_t* headerLen,
     60               size_t* dataLen, size_t* trailerLen) {
     61     const uint8_t* srcPtr = src;
     62     size_t remaining = size;
     63 
     64     return parsePFBSection(&srcPtr, &remaining, 1, headerLen) &&
     65            parsePFBSection(&srcPtr, &remaining, 2, dataLen) &&
     66            parsePFBSection(&srcPtr, &remaining, 1, trailerLen) &&
     67            parsePFBSection(&srcPtr, &remaining, 3, NULL);
     68 }
     69 
     70 /* The sections of a PFA file are implicitly defined.  The body starts
     71  * after the line containing "eexec," and the trailer starts with 512
     72  * literal 0's followed by "cleartomark" (plus arbitrary white space).
     73  *
     74  * This function assumes that src is NUL terminated, but the NUL
     75  * termination is not included in size.
     76  *
     77  */
     78 bool parsePFA(const char* src, size_t size, size_t* headerLen,
     79               size_t* hexDataLen, size_t* dataLen, size_t* trailerLen) {
     80     const char* end = src + size;
     81 
     82     const char* dataPos = strstr(src, "eexec");
     83     if (!dataPos)
     84         return false;
     85     dataPos += strlen("eexec");
     86     while ((*dataPos == '\n' || *dataPos == '\r' || *dataPos == ' ') &&
     87             dataPos < end)
     88         dataPos++;
     89     *headerLen = dataPos - src;
     90 
     91     const char* trailerPos = strstr(dataPos, "cleartomark");
     92     if (!trailerPos)
     93         return false;
     94     int zeroCount = 0;
     95     for (trailerPos--; trailerPos > dataPos && zeroCount < 512; trailerPos--) {
     96         if (*trailerPos == '\n' || *trailerPos == '\r' || *trailerPos == ' ') {
     97             continue;
     98         } else if (*trailerPos == '0') {
     99             zeroCount++;
    100         } else {
    101             return false;
    102         }
    103     }
    104     if (zeroCount != 512)
    105         return false;
    106 
    107     *hexDataLen = trailerPos - src - *headerLen;
    108     *trailerLen = size - *headerLen - *hexDataLen;
    109 
    110     // Verify that the data section is hex encoded and count the bytes.
    111     int nibbles = 0;
    112     for (; dataPos < trailerPos; dataPos++) {
    113         if (isspace(*dataPos))
    114             continue;
    115         if (!isxdigit(*dataPos))
    116             return false;
    117         nibbles++;
    118     }
    119     *dataLen = (nibbles + 1) / 2;
    120 
    121     return true;
    122 }
    123 
    124 int8_t hexToBin(uint8_t c) {
    125     if (!isxdigit(c))
    126         return -1;
    127     if (c <= '9') return c - '0';
    128     if (c <= 'F') return c - 'A' + 10;
    129     if (c <= 'f') return c - 'a' + 10;
    130     return -1;
    131 }
    132 
    133 SkStream* handleType1Stream(SkStream* srcStream, size_t* headerLen,
    134                             size_t* dataLen, size_t* trailerLen) {
    135     // srcStream may be backed by a file or a unseekable fd, so we may not be
    136     // able to use skip(), rewind(), or getMemoryBase().  read()ing through
    137     // the input only once is doable, but very ugly. Furthermore, it'd be nice
    138     // if the data was NUL terminated so that we can use strstr() to search it.
    139     // Make as few copies as possible given these constraints.
    140     SkDynamicMemoryWStream dynamicStream;
    141     SkRefPtr<SkMemoryStream> staticStream;
    142     const uint8_t* src;
    143     size_t srcLen;
    144     if ((srcLen = srcStream->getLength()) > 0) {
    145         staticStream = new SkMemoryStream(srcLen + 1);
    146         staticStream->unref();  // new and SkRefPtr both took a ref.
    147         src = (const uint8_t*)staticStream->getMemoryBase();
    148         if (srcStream->getMemoryBase() != NULL) {
    149             memcpy((void *)src, srcStream->getMemoryBase(), srcLen);
    150         } else {
    151             size_t read = 0;
    152             while (read < srcLen) {
    153                 size_t got = srcStream->read((void *)staticStream->getAtPos(),
    154                                              srcLen - read);
    155                 if (got == 0)
    156                     return NULL;
    157                 read += got;
    158                 staticStream->seek(read);
    159             }
    160         }
    161         ((uint8_t *)src)[srcLen] = 0;
    162     } else {
    163         static const size_t bufSize = 4096;
    164         uint8_t buf[bufSize];
    165         size_t amount;
    166         while ((amount = srcStream->read(buf, bufSize)) > 0)
    167             dynamicStream.write(buf, amount);
    168         amount = 0;
    169         dynamicStream.write(&amount, 1);  // NULL terminator.
    170         // getStream makes another copy, but we couldn't do any better.
    171         src = (const uint8_t*)dynamicStream.getStream();
    172         srcLen = dynamicStream.getOffset() - 1;
    173     }
    174 
    175     if (parsePFB(src, srcLen, headerLen, dataLen, trailerLen)) {
    176         SkMemoryStream* result =
    177             new SkMemoryStream(*headerLen + *dataLen + *trailerLen);
    178         memcpy((char*)result->getAtPos(), src + 6, *headerLen);
    179         result->seek(*headerLen);
    180         memcpy((char*)result->getAtPos(), src + 6 + *headerLen + 6, *dataLen);
    181         result->seek(*headerLen + *dataLen);
    182         memcpy((char*)result->getAtPos(), src + 6 + *headerLen + 6 + *dataLen,
    183                *trailerLen);
    184         result->rewind();
    185         return result;
    186     }
    187 
    188     // A PFA has to be converted for PDF.
    189     size_t hexDataLen;
    190     if (parsePFA((const char*)src, srcLen, headerLen, &hexDataLen, dataLen,
    191                  trailerLen)) {
    192         SkMemoryStream* result =
    193             new SkMemoryStream(*headerLen + *dataLen + *trailerLen);
    194         memcpy((char*)result->getAtPos(), src, *headerLen);
    195         result->seek(*headerLen);
    196 
    197         const uint8_t* hexData = src + *headerLen;
    198         const uint8_t* trailer = hexData + hexDataLen;
    199         size_t outputOffset = 0;
    200         uint8_t dataByte = 0;  // To hush compiler.
    201         bool highNibble = true;
    202         for (; hexData < trailer; hexData++) {
    203             char curNibble = hexToBin(*hexData);
    204             if (curNibble < 0)
    205                 continue;
    206             if (highNibble) {
    207                 dataByte = curNibble << 4;
    208                 highNibble = false;
    209             } else {
    210                 dataByte |= curNibble;
    211                 highNibble = true;
    212                 ((char *)result->getAtPos())[outputOffset++] = dataByte;
    213             }
    214         }
    215         if (!highNibble)
    216             ((char *)result->getAtPos())[outputOffset++] = dataByte;
    217         SkASSERT(outputOffset == *dataLen);
    218         result->seek(*headerLen + outputOffset);
    219 
    220         memcpy((char *)result->getAtPos(), src + *headerLen + hexDataLen,
    221                *trailerLen);
    222         result->rewind();
    223         return result;
    224     }
    225 
    226     return NULL;
    227 }
    228 
    229 // scale from em-units to base-1000, returning as a SkScalar
    230 SkScalar scaleFromFontUnits(int16_t val, uint16_t emSize) {
    231     SkScalar scaled = SkIntToScalar(val);
    232     if (emSize == 1000) {
    233         return scaled;
    234     } else {
    235         return SkScalarMulDiv(scaled, 1000, emSize);
    236     }
    237 }
    238 
    239 void setGlyphWidthAndBoundingBox(SkScalar width, SkIRect box,
    240                                  SkWStream* content) {
    241     // Specify width and bounding box for the glyph.
    242     SkPDFScalar::Append(width, content);
    243     content->writeText(" 0 ");
    244     content->writeDecAsText(box.fLeft);
    245     content->writeText(" ");
    246     content->writeDecAsText(box.fTop);
    247     content->writeText(" ");
    248     content->writeDecAsText(box.fRight);
    249     content->writeText(" ");
    250     content->writeDecAsText(box.fBottom);
    251     content->writeText(" d1\n");
    252 }
    253 
    254 SkPDFArray* makeFontBBox(SkIRect glyphBBox, uint16_t emSize) {
    255     SkPDFArray* bbox = new SkPDFArray;
    256     bbox->reserve(4);
    257     bbox->append(new SkPDFScalar(scaleFromFontUnits(glyphBBox.fLeft,
    258                                                     emSize)))->unref();
    259     bbox->append(new SkPDFScalar(scaleFromFontUnits(glyphBBox.fBottom,
    260                                                     emSize)))->unref();
    261     bbox->append(new SkPDFScalar(scaleFromFontUnits(glyphBBox.fRight,
    262                                                     emSize)))->unref();
    263     bbox->append(new SkPDFScalar(scaleFromFontUnits(glyphBBox.fTop,
    264                                                     emSize)))->unref();
    265     return bbox;
    266 }
    267 
    268 SkPDFArray* appendWidth(const int16_t& width, uint16_t emSize,
    269                         SkPDFArray* array) {
    270     array->append(new SkPDFScalar(scaleFromFontUnits(width, emSize)))->unref();
    271     return array;
    272 }
    273 
    274 SkPDFArray* appendVerticalAdvance(
    275         const SkAdvancedTypefaceMetrics::VerticalMetric& advance,
    276         uint16_t emSize, SkPDFArray* array) {
    277     appendWidth(advance.fVerticalAdvance, emSize, array);
    278     appendWidth(advance.fOriginXDisp, emSize, array);
    279     appendWidth(advance.fOriginYDisp, emSize, array);
    280     return array;
    281 }
    282 
    283 template <typename Data>
    284 SkPDFArray* composeAdvanceData(
    285         SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* advanceInfo,
    286         uint16_t emSize,
    287         SkPDFArray* (*appendAdvance)(const Data& advance, uint16_t emSize,
    288                                      SkPDFArray* array),
    289         Data* defaultAdvance) {
    290     SkPDFArray* result = new SkPDFArray();
    291     for (; advanceInfo != NULL; advanceInfo = advanceInfo->fNext.get()) {
    292         switch (advanceInfo->fType) {
    293             case SkAdvancedTypefaceMetrics::WidthRange::kDefault: {
    294                 SkASSERT(advanceInfo->fAdvance.count() == 1);
    295                 *defaultAdvance = advanceInfo->fAdvance[0];
    296                 break;
    297             }
    298             case SkAdvancedTypefaceMetrics::WidthRange::kRange: {
    299                 SkRefPtr<SkPDFArray> advanceArray = new SkPDFArray();
    300                 advanceArray->unref();  // SkRefPtr and new both took a ref.
    301                 for (int j = 0; j < advanceInfo->fAdvance.count(); j++)
    302                     appendAdvance(advanceInfo->fAdvance[j], emSize,
    303                                   advanceArray.get());
    304                 result->append(new SkPDFInt(advanceInfo->fStartId))->unref();
    305                 result->append(advanceArray.get());
    306                 break;
    307             }
    308             case SkAdvancedTypefaceMetrics::WidthRange::kRun: {
    309                 SkASSERT(advanceInfo->fAdvance.count() == 1);
    310                 result->append(new SkPDFInt(advanceInfo->fStartId))->unref();
    311                 result->append(new SkPDFInt(advanceInfo->fEndId))->unref();
    312                 appendAdvance(advanceInfo->fAdvance[0], emSize, result);
    313                 break;
    314             }
    315         }
    316     }
    317     return result;
    318 }
    319 
    320 }  // namespace
    321 
    322 static void append_tounicode_header(SkDynamicMemoryWStream* cmap) {
    323     // 12 dict begin: 12 is an Adobe-suggested value. Shall not change.
    324     // It's there to prevent old version Adobe Readers from malfunctioning.
    325     const char* kHeader =
    326         "/CIDInit /ProcSet findresource begin\n"
    327         "12 dict begin\n"
    328         "begincmap\n";
    329     cmap->writeText(kHeader);
    330 
    331     // The /CIDSystemInfo must be consistent to the one in
    332     // SkPDFFont::populateCIDFont().
    333     // We can not pass over the system info object here because the format is
    334     // different. This is not a reference object.
    335     const char* kSysInfo =
    336         "/CIDSystemInfo\n"
    337         "<<  /Registry (Adobe)\n"
    338         "/Ordering (UCS)\n"
    339         "/Supplement 0\n"
    340         ">> def\n";
    341     cmap->writeText(kSysInfo);
    342 
    343     // The CMapName must be consistent to /CIDSystemInfo above.
    344     // /CMapType 2 means ToUnicode.
    345     // We specify codespacerange from 0x0000 to 0xFFFF because we convert our
    346     // code table from unsigned short (16-bits). Codespace range just tells the
    347     // PDF processor the valid range. It does not matter whether a complete
    348     // mapping is provided or not.
    349     const char* kTypeInfo =
    350         "/CMapName /Adobe-Identity-UCS def\n"
    351         "/CMapType 2 def\n"
    352         "1 begincodespacerange\n"
    353         "<0000> <FFFF>\n"
    354         "endcodespacerange\n";
    355     cmap->writeText(kTypeInfo);
    356 }
    357 
    358 static void append_cmap_bfchar_table(uint16_t* glyph_id, SkUnichar* unicode,
    359                                      size_t count,
    360                                      SkDynamicMemoryWStream* cmap) {
    361     cmap->writeDecAsText(count);
    362     cmap->writeText(" beginbfchar\n");
    363     for (size_t i = 0; i < count; ++i) {
    364         cmap->writeText("<");
    365         cmap->writeHexAsText(glyph_id[i], 4);
    366         cmap->writeText("> <");
    367         cmap->writeHexAsText(unicode[i], 4);
    368         cmap->writeText(">\n");
    369     }
    370     cmap->writeText("endbfchar\n");
    371 }
    372 
    373 static void append_cmap_footer(SkDynamicMemoryWStream* cmap) {
    374     const char* kFooter =
    375         "endcmap\n"
    376         "CMapName currentdict /CMap defineresource pop\n"
    377         "end\n"
    378         "end";
    379     cmap->writeText(kFooter);
    380 }
    381 
    382 // Generate <bfchar> table according to PDF spec 1.4 and Adobe Technote 5014.
    383 static void append_cmap_bfchar_sections(
    384                 const SkTDArray<SkUnichar>& glyphUnicode,
    385                 SkDynamicMemoryWStream* cmap) {
    386     // PDF spec defines that every bf* list can have at most 100 entries.
    387     const size_t kMaxEntries = 100;
    388     uint16_t glyphId[kMaxEntries];
    389     SkUnichar unicode[kMaxEntries];
    390     size_t index = 0;
    391     for (int i = 0; i < glyphUnicode.count(); i++) {
    392         if (glyphUnicode[i]) {
    393             glyphId[index] = i;
    394             unicode[index] = glyphUnicode[i];
    395             ++index;
    396         }
    397         if (index == kMaxEntries) {
    398             append_cmap_bfchar_table(glyphId, unicode, index, cmap);
    399             index = 0;
    400         }
    401     }
    402 
    403     if (index) {
    404         append_cmap_bfchar_table(glyphId, unicode, index, cmap);
    405     }
    406 }
    407 
    408 /* Font subset design: It would be nice to be able to subset fonts
    409  * (particularly type 3 fonts), but it's a lot of work and not a priority.
    410  *
    411  * Resources are canonicalized and uniqueified by pointer so there has to be
    412  * some additional state indicating which subset of the font is used.  It
    413  * must be maintained at the page granularity and then combined at the document
    414  * granularity. a) change SkPDFFont to fill in its state on demand, kind of
    415  * like SkPDFGraphicState.  b) maintain a per font glyph usage class in each
    416  * page/pdf device. c) in the document, retrieve the per font glyph usage
    417  * from each page and combine it and ask for a resource with that subset.
    418  */
    419 
    420 SkPDFFont::~SkPDFFont() {
    421     SkAutoMutexAcquire lock(canonicalFontsMutex());
    422     int index;
    423     if (find(SkTypeface::UniqueID(fTypeface.get()), fFirstGlyphID, &index)) {
    424         canonicalFonts().removeShuffle(index);
    425 #ifdef SK_DEBUG
    426         SkASSERT(!fDescendant);
    427     } else {
    428         SkASSERT(fDescendant);
    429 #endif
    430     }
    431     fResources.unrefAll();
    432 }
    433 
    434 void SkPDFFont::getResources(SkTDArray<SkPDFObject*>* resourceList) {
    435     resourceList->setReserve(resourceList->count() + fResources.count());
    436     for (int i = 0; i < fResources.count(); i++) {
    437         resourceList->push(fResources[i]);
    438         fResources[i]->ref();
    439         fResources[i]->getResources(resourceList);
    440     }
    441 }
    442 
    443 SkTypeface* SkPDFFont::typeface() {
    444     return fTypeface.get();
    445 }
    446 
    447 SkAdvancedTypefaceMetrics::FontType SkPDFFont::getType() {
    448     return fType;
    449 }
    450 
    451 bool SkPDFFont::hasGlyph(uint16_t id) {
    452     return (id >= fFirstGlyphID && id <= fLastGlyphID) || id == 0;
    453 }
    454 
    455 bool SkPDFFont::multiByteGlyphs() {
    456     return fMultiByteGlyphs;
    457 }
    458 
    459 size_t SkPDFFont::glyphsToPDFFontEncoding(uint16_t* glyphIDs,
    460                                           size_t numGlyphs) {
    461     // A font with multibyte glyphs will support all glyph IDs in a single font.
    462     if (fMultiByteGlyphs) {
    463         return numGlyphs;
    464     }
    465 
    466     for (size_t i = 0; i < numGlyphs; i++) {
    467         if (glyphIDs[i] == 0) {
    468             continue;
    469         }
    470         if (glyphIDs[i] < fFirstGlyphID || glyphIDs[i] > fLastGlyphID) {
    471             return i;
    472         }
    473         glyphIDs[i] -= (fFirstGlyphID - 1);
    474     }
    475 
    476     return numGlyphs;
    477 }
    478 
    479 // static
    480 SkPDFFont* SkPDFFont::getFontResource(SkTypeface* typeface, uint16_t glyphID) {
    481     SkAutoMutexAcquire lock(canonicalFontsMutex());
    482     const uint32_t fontID = SkTypeface::UniqueID(typeface);
    483     int index;
    484     if (find(fontID, glyphID, &index)) {
    485         canonicalFonts()[index].fFont->ref();
    486         return canonicalFonts()[index].fFont;
    487     }
    488 
    489     SkRefPtr<SkAdvancedTypefaceMetrics> fontInfo;
    490     SkPDFDict* fontDescriptor = NULL;
    491     if (index >= 0) {
    492         SkPDFFont* relatedFont = canonicalFonts()[index].fFont;
    493         SkASSERT(relatedFont->fFontInfo.get());
    494         fontInfo = relatedFont->fFontInfo;
    495         fontDescriptor = relatedFont->fDescriptor.get();
    496     } else {
    497         SkAdvancedTypefaceMetrics::PerGlyphInfo info;
    498         info = SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo;
    499         info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>(
    500                   info, SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo);
    501         info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>(
    502                   info, SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo);
    503         fontInfo = SkFontHost::GetAdvancedTypefaceMetrics(fontID, info);
    504         SkSafeUnref(fontInfo.get());  // SkRefPtr and Get both took a reference.
    505     }
    506 
    507     SkPDFFont* font = new SkPDFFont(fontInfo.get(), typeface, glyphID, false,
    508                                     fontDescriptor);
    509     FontRec newEntry(font, fontID, font->fFirstGlyphID);
    510     index = canonicalFonts().count();
    511     canonicalFonts().push(newEntry);
    512     return font;  // Return the reference new SkPDFFont() created.
    513 }
    514 
    515 // static
    516 SkTDArray<SkPDFFont::FontRec>& SkPDFFont::canonicalFonts() {
    517     // This initialization is only thread safe with gcc.
    518     static SkTDArray<FontRec> gCanonicalFonts;
    519     return gCanonicalFonts;
    520 }
    521 
    522 // static
    523 SkMutex& SkPDFFont::canonicalFontsMutex() {
    524     // This initialization is only thread safe with gcc.
    525     static SkMutex gCanonicalFontsMutex;
    526     return gCanonicalFontsMutex;
    527 }
    528 
    529 // static
    530 bool SkPDFFont::find(uint32_t fontID, uint16_t glyphID, int* index) {
    531     // TODO(vandebo) optimize this, do only one search?
    532     FontRec search(NULL, fontID, glyphID);
    533     *index = canonicalFonts().find(search);
    534     if (*index >= 0)
    535         return true;
    536     search.fGlyphID = 0;
    537     *index = canonicalFonts().find(search);
    538     return false;
    539 }
    540 
    541 SkPDFFont::SkPDFFont(class SkAdvancedTypefaceMetrics* fontInfo,
    542                      SkTypeface* typeface,
    543                      uint16_t glyphID,
    544                      bool descendantFont,
    545                      SkPDFDict* fontDescriptor)
    546         : SkPDFDict("Font"),
    547           fTypeface(typeface),
    548           fType(fontInfo ? fontInfo->fType :
    549                            SkAdvancedTypefaceMetrics::kNotEmbeddable_Font),
    550 #ifdef SK_DEBUG
    551           fDescendant(descendantFont),
    552 #endif
    553           fMultiByteGlyphs(false),
    554           fFirstGlyphID(1),
    555           fLastGlyphID(fontInfo ? fontInfo->fLastGlyphID : 0),
    556           fFontInfo(fontInfo),
    557           fDescriptor(fontDescriptor) {
    558     if (fontInfo && fontInfo->fMultiMaster) {
    559         NOT_IMPLEMENTED(true, true);
    560         fType = SkAdvancedTypefaceMetrics::kOther_Font;
    561     }
    562     if (fType == SkAdvancedTypefaceMetrics::kType1CID_Font ||
    563         fType == SkAdvancedTypefaceMetrics::kTrueType_Font) {
    564         if (descendantFont) {
    565             populateCIDFont();
    566         } else {
    567             populateType0Font();
    568         }
    569         // No need to hold onto the font info for fonts types that
    570         // support multibyte glyphs.
    571         fFontInfo = NULL;
    572         return;
    573     }
    574 
    575     if (fType == SkAdvancedTypefaceMetrics::kType1_Font &&
    576         populateType1Font(glyphID)) {
    577         return;
    578     }
    579 
    580     SkASSERT(fType == SkAdvancedTypefaceMetrics::kType1_Font ||
    581              fType == SkAdvancedTypefaceMetrics::kCFF_Font ||
    582              fType == SkAdvancedTypefaceMetrics::kOther_Font ||
    583              fType == SkAdvancedTypefaceMetrics::kNotEmbeddable_Font);
    584     populateType3Font(glyphID);
    585 }
    586 
    587 void SkPDFFont::populateType0Font() {
    588     fMultiByteGlyphs = true;
    589 
    590     insert("Subtype", new SkPDFName("Type0"))->unref();
    591     insert("BaseFont", new SkPDFName(fFontInfo->fFontName))->unref();
    592     insert("Encoding",  new SkPDFName("Identity-H"))->unref();
    593 
    594     SkRefPtr<SkPDFArray> descendantFonts = new SkPDFArray();
    595     descendantFonts->unref();  // SkRefPtr and new took a reference.
    596 
    597     // Pass ref new created to fResources.
    598     fResources.push(
    599         new SkPDFFont(fFontInfo.get(), fTypeface.get(), 1, true, NULL));
    600     descendantFonts->append(new SkPDFObjRef(fResources.top()))->unref();
    601     insert("DescendantFonts", descendantFonts.get());
    602 
    603     populateToUnicodeTable();
    604 }
    605 
    606 void SkPDFFont::populateToUnicodeTable() {
    607     if (fFontInfo.get() == NULL ||
    608         fFontInfo->fGlyphToUnicode.begin() == NULL) {
    609         return;
    610     }
    611 
    612     SkDynamicMemoryWStream cmap;
    613     append_tounicode_header(&cmap);
    614     append_cmap_bfchar_sections(fFontInfo->fGlyphToUnicode, &cmap);
    615     append_cmap_footer(&cmap);
    616     SkRefPtr<SkMemoryStream> cmapStream = new SkMemoryStream();
    617     cmapStream->unref();  // SkRefPtr and new took a reference.
    618     cmapStream->setMemoryOwned(cmap.detach(), cmap.getOffset());
    619     SkRefPtr<SkPDFStream> pdfCmap = new SkPDFStream(cmapStream.get());
    620     fResources.push(pdfCmap.get());  // Pass reference from new.
    621     insert("ToUnicode", new SkPDFObjRef(pdfCmap.get()))->unref();
    622 }
    623 
    624 void SkPDFFont::populateCIDFont() {
    625     fMultiByteGlyphs = true;
    626     insert("BaseFont", new SkPDFName(fFontInfo->fFontName))->unref();
    627 
    628     if (fFontInfo->fType == SkAdvancedTypefaceMetrics::kType1CID_Font) {
    629         insert("Subtype", new SkPDFName("CIDFontType0"))->unref();
    630     } else if (fFontInfo->fType == SkAdvancedTypefaceMetrics::kTrueType_Font) {
    631         insert("Subtype", new SkPDFName("CIDFontType2"))->unref();
    632         insert("CIDToGIDMap", new SkPDFName("Identity"))->unref();
    633     } else {
    634         SkASSERT(false);
    635     }
    636 
    637     SkRefPtr<SkPDFDict> sysInfo = new SkPDFDict;
    638     sysInfo->unref();  // SkRefPtr and new both took a reference.
    639     sysInfo->insert("Registry", new SkPDFString("Adobe"))->unref();
    640     sysInfo->insert("Ordering", new SkPDFString("Identity"))->unref();
    641     sysInfo->insert("Supplement", new SkPDFInt(0))->unref();
    642     insert("CIDSystemInfo", sysInfo.get());
    643 
    644     addFontDescriptor(0);
    645 
    646     if (fFontInfo->fGlyphWidths.get()) {
    647         int16_t defaultWidth = 0;
    648         SkRefPtr<SkPDFArray> widths =
    649             composeAdvanceData(fFontInfo->fGlyphWidths.get(),
    650                                fFontInfo->fEmSize, &appendWidth, &defaultWidth);
    651         widths->unref();  // SkRefPtr and compose both took a reference.
    652         if (widths->size())
    653             insert("W", widths.get());
    654         if (defaultWidth != 0) {
    655             insert("DW", new SkPDFScalar(scaleFromFontUnits(
    656                     defaultWidth, fFontInfo->fEmSize)))->unref();
    657         }
    658     }
    659     if (fFontInfo->fVerticalMetrics.get()) {
    660         struct SkAdvancedTypefaceMetrics::VerticalMetric defaultAdvance;
    661         defaultAdvance.fVerticalAdvance = 0;
    662         defaultAdvance.fOriginXDisp = 0;
    663         defaultAdvance.fOriginYDisp = 0;
    664         SkRefPtr<SkPDFArray> advances =
    665             composeAdvanceData(fFontInfo->fVerticalMetrics.get(),
    666                                fFontInfo->fEmSize, &appendVerticalAdvance,
    667                                &defaultAdvance);
    668         advances->unref();  // SkRefPtr and compose both took a ref.
    669         if (advances->size())
    670             insert("W2", advances.get());
    671         if (defaultAdvance.fVerticalAdvance ||
    672                 defaultAdvance.fOriginXDisp ||
    673                 defaultAdvance.fOriginYDisp) {
    674             insert("DW2", appendVerticalAdvance(defaultAdvance,
    675                                                 fFontInfo->fEmSize,
    676                                                 new SkPDFArray))->unref();
    677         }
    678     }
    679 }
    680 
    681 bool SkPDFFont::populateType1Font(int16_t glyphID) {
    682     SkASSERT(!fFontInfo->fVerticalMetrics.get());
    683     SkASSERT(fFontInfo->fGlyphWidths.get());
    684 
    685     adjustGlyphRangeForSingleByteEncoding(glyphID);
    686 
    687     int16_t defaultWidth = 0;
    688     const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry = NULL;
    689     const SkAdvancedTypefaceMetrics::WidthRange* widthEntry;
    690     for (widthEntry = fFontInfo.get()->fGlyphWidths.get();
    691             widthEntry != NULL;
    692             widthEntry = widthEntry->fNext.get()) {
    693         switch (widthEntry->fType) {
    694             case SkAdvancedTypefaceMetrics::WidthRange::kDefault:
    695                 defaultWidth = widthEntry->fAdvance[0];
    696                 break;
    697             case SkAdvancedTypefaceMetrics::WidthRange::kRun:
    698                 SkASSERT(false);
    699                 break;
    700             case SkAdvancedTypefaceMetrics::WidthRange::kRange:
    701                 SkASSERT(widthRangeEntry == NULL);
    702                 widthRangeEntry = widthEntry;
    703                 break;
    704         }
    705     }
    706 
    707     if (!addFontDescriptor(defaultWidth))
    708         return false;
    709 
    710     insert("Subtype", new SkPDFName("Type1"))->unref();
    711     insert("BaseFont", new SkPDFName(fFontInfo->fFontName))->unref();
    712 
    713     addWidthInfoFromRange(defaultWidth, widthRangeEntry);
    714 
    715     SkRefPtr<SkPDFDict> encoding = new SkPDFDict("Encoding");
    716     encoding->unref();  // SkRefPtr and new both took a reference.
    717     insert("Encoding", encoding.get());
    718 
    719     SkRefPtr<SkPDFArray> encDiffs = new SkPDFArray;
    720     encDiffs->unref();  // SkRefPtr and new both took a reference.
    721     encoding->insert("Differences", encDiffs.get());
    722 
    723     encDiffs->reserve(fLastGlyphID - fFirstGlyphID + 2);
    724     encDiffs->append(new SkPDFInt(1))->unref();
    725     for (int gID = fFirstGlyphID; gID <= fLastGlyphID; gID++) {
    726         encDiffs->append(
    727             new SkPDFName(fFontInfo->fGlyphNames->get()[gID]))->unref();
    728     }
    729 
    730     if (fFontInfo->fLastGlyphID <= 255)
    731         fFontInfo = NULL;
    732     return true;
    733 }
    734 
    735 void SkPDFFont::populateType3Font(int16_t glyphID) {
    736     SkPaint paint;
    737     paint.setTypeface(fTypeface.get());
    738     paint.setTextSize(1000);
    739     SkAutoGlyphCache autoCache(paint, NULL);
    740     SkGlyphCache* cache = autoCache.getCache();
    741     // If fLastGlyphID isn't set (because there is not fFontInfo), look it up.
    742     if (fLastGlyphID == 0) {
    743         fLastGlyphID = cache->getGlyphCount() - 1;
    744     }
    745 
    746     adjustGlyphRangeForSingleByteEncoding(glyphID);
    747 
    748     insert("Subtype", new SkPDFName("Type3"))->unref();
    749     // Flip about the x-axis and scale by 1/1000.
    750     SkMatrix fontMatrix;
    751     fontMatrix.setScale(SkScalarInvert(1000), -SkScalarInvert(1000));
    752     insert("FontMatrix", SkPDFUtils::MatrixToArray(fontMatrix))->unref();
    753 
    754     SkRefPtr<SkPDFDict> charProcs = new SkPDFDict;
    755     charProcs->unref();  // SkRefPtr and new both took a reference.
    756     insert("CharProcs", charProcs.get());
    757 
    758     SkRefPtr<SkPDFDict> encoding = new SkPDFDict("Encoding");
    759     encoding->unref();  // SkRefPtr and new both took a reference.
    760     insert("Encoding", encoding.get());
    761 
    762     SkRefPtr<SkPDFArray> encDiffs = new SkPDFArray;
    763     encDiffs->unref();  // SkRefPtr and new both took a reference.
    764     encoding->insert("Differences", encDiffs.get());
    765     encDiffs->reserve(fLastGlyphID - fFirstGlyphID + 2);
    766     encDiffs->append(new SkPDFInt(1))->unref();
    767 
    768     SkRefPtr<SkPDFArray> widthArray = new SkPDFArray();
    769     widthArray->unref();  // SkRefPtr and new both took a ref.
    770 
    771     SkIRect bbox = SkIRect::MakeEmpty();
    772     for (int gID = fFirstGlyphID; gID <= fLastGlyphID; gID++) {
    773         SkString characterName;
    774         characterName.printf("gid%d", gID);
    775         encDiffs->append(new SkPDFName(characterName))->unref();
    776 
    777         const SkGlyph& glyph = cache->getGlyphIDMetrics(gID);
    778         widthArray->append(new SkPDFScalar(SkFixedToScalar(glyph.fAdvanceX)))->unref();
    779         SkIRect glyphBBox = SkIRect::MakeXYWH(glyph.fLeft, glyph.fTop,
    780                                               glyph.fWidth, glyph.fHeight);
    781         bbox.join(glyphBBox);
    782 
    783         SkDynamicMemoryWStream content;
    784         setGlyphWidthAndBoundingBox(SkFixedToScalar(glyph.fAdvanceX), glyphBBox,
    785                                     &content);
    786         const SkPath* path = cache->findPath(glyph);
    787         if (path) {
    788             SkPDFUtils::EmitPath(*path, &content);
    789             SkPDFUtils::PaintPath(paint.getStyle(), path->getFillType(),
    790                                   &content);
    791         }
    792         SkRefPtr<SkMemoryStream> glyphStream = new SkMemoryStream();
    793         glyphStream->unref();  // SkRefPtr and new both took a ref.
    794         glyphStream->setMemoryOwned(content.detach(), content.getOffset());
    795 
    796         SkRefPtr<SkPDFStream> glyphDescription =
    797             new SkPDFStream(glyphStream.get());
    798         // SkRefPtr and new both ref()'d charProcs, pass one.
    799         fResources.push(glyphDescription.get());
    800         charProcs->insert(characterName.c_str(),
    801                           new SkPDFObjRef(glyphDescription.get()))->unref();
    802     }
    803 
    804     insert("FontBBox", makeFontBBox(bbox, 1000))->unref();
    805     insert("FirstChar", new SkPDFInt(fFirstGlyphID))->unref();
    806     insert("LastChar", new SkPDFInt(fLastGlyphID))->unref();
    807     insert("Widths", widthArray.get());
    808     insert("CIDToGIDMap", new SkPDFName("Identity"))->unref();
    809 
    810     if (fFontInfo && fFontInfo->fLastGlyphID <= 255)
    811         fFontInfo = NULL;
    812 
    813     populateToUnicodeTable();
    814 }
    815 
    816 bool SkPDFFont::addFontDescriptor(int16_t defaultWidth) {
    817     if (fDescriptor.get() != NULL) {
    818         fResources.push(fDescriptor.get());
    819         fDescriptor->ref();
    820         insert("FontDescriptor", new SkPDFObjRef(fDescriptor.get()))->unref();
    821         return true;
    822     }
    823 
    824     fDescriptor = new SkPDFDict("FontDescriptor");
    825     fDescriptor->unref();  // SkRefPtr and new both took a ref.
    826 
    827     switch (fFontInfo->fType) {
    828         case SkAdvancedTypefaceMetrics::kType1_Font: {
    829             size_t header SK_INIT_TO_AVOID_WARNING;
    830             size_t data SK_INIT_TO_AVOID_WARNING;
    831             size_t trailer SK_INIT_TO_AVOID_WARNING;
    832             SkRefPtr<SkStream> rawFontData =
    833                 SkFontHost::OpenStream(SkTypeface::UniqueID(fTypeface.get()));
    834             rawFontData->unref();  // SkRefPtr and OpenStream both took a ref.
    835             SkStream* fontData = handleType1Stream(rawFontData.get(), &header,
    836                                                    &data, &trailer);
    837             if (fontData == NULL)
    838                 return false;
    839             SkRefPtr<SkPDFStream> fontStream = new SkPDFStream(fontData);
    840             // SkRefPtr and new both ref()'d fontStream, pass one.
    841             fResources.push(fontStream.get());
    842             fontStream->insert("Length1", new SkPDFInt(header))->unref();
    843             fontStream->insert("Length2", new SkPDFInt(data))->unref();
    844             fontStream->insert("Length3", new SkPDFInt(trailer))->unref();
    845             fDescriptor->insert("FontFile",
    846                                 new SkPDFObjRef(fontStream.get()))->unref();
    847             break;
    848         }
    849         case SkAdvancedTypefaceMetrics::kTrueType_Font: {
    850             SkRefPtr<SkStream> fontData =
    851                 SkFontHost::OpenStream(SkTypeface::UniqueID(fTypeface.get()));
    852             fontData->unref();  // SkRefPtr and OpenStream both took a ref.
    853             SkRefPtr<SkPDFStream> fontStream = new SkPDFStream(fontData.get());
    854             // SkRefPtr and new both ref()'d fontStream, pass one.
    855             fResources.push(fontStream.get());
    856 
    857             fontStream->insert("Length1",
    858                                new SkPDFInt(fontData->getLength()))->unref();
    859             fDescriptor->insert("FontFile2",
    860                                 new SkPDFObjRef(fontStream.get()))->unref();
    861             break;
    862         }
    863         case SkAdvancedTypefaceMetrics::kCFF_Font:
    864         case SkAdvancedTypefaceMetrics::kType1CID_Font: {
    865             SkRefPtr<SkStream> fontData =
    866                 SkFontHost::OpenStream(SkTypeface::UniqueID(fTypeface.get()));
    867             fontData->unref();  // SkRefPtr and OpenStream both took a ref.
    868             SkRefPtr<SkPDFStream> fontStream = new SkPDFStream(fontData.get());
    869             // SkRefPtr and new both ref()'d fontStream, pass one.
    870             fResources.push(fontStream.get());
    871 
    872             if (fFontInfo->fType == SkAdvancedTypefaceMetrics::kCFF_Font) {
    873                 fontStream->insert("Subtype", new SkPDFName("Type1C"))->unref();
    874             } else {
    875                 fontStream->insert("Subtype",
    876                         new SkPDFName("CIDFontType0c"))->unref();
    877             }
    878             fDescriptor->insert("FontFile3",
    879                                 new SkPDFObjRef(fontStream.get()))->unref();
    880             break;
    881         }
    882         default:
    883             SkASSERT(false);
    884     }
    885 
    886     const uint16_t emSize = fFontInfo->fEmSize;
    887     fResources.push(fDescriptor.get());
    888     fDescriptor->ref();
    889     insert("FontDescriptor", new SkPDFObjRef(fDescriptor.get()))->unref();
    890 
    891     fDescriptor->insert("FontName", new SkPDFName(
    892             fFontInfo->fFontName))->unref();
    893     fDescriptor->insert("Flags", new SkPDFInt(fFontInfo->fStyle))->unref();
    894     fDescriptor->insert("Ascent", new SkPDFScalar(
    895             scaleFromFontUnits(fFontInfo->fAscent, emSize)))->unref();
    896     fDescriptor->insert("Descent", new SkPDFScalar(
    897             scaleFromFontUnits(fFontInfo->fDescent, emSize)))->unref();
    898     fDescriptor->insert("StemV", new SkPDFScalar(
    899             scaleFromFontUnits(fFontInfo->fStemV, emSize)))->unref();
    900     fDescriptor->insert("CapHeight", new SkPDFScalar(
    901             scaleFromFontUnits(fFontInfo->fCapHeight, emSize)))->unref();
    902     fDescriptor->insert("ItalicAngle", new SkPDFInt(
    903             fFontInfo->fItalicAngle))->unref();
    904     fDescriptor->insert("FontBBox", makeFontBBox(fFontInfo->fBBox,
    905                                                  fFontInfo->fEmSize))->unref();
    906 
    907     if (defaultWidth > 0) {
    908         fDescriptor->insert("MissingWidth", new SkPDFScalar(
    909                 scaleFromFontUnits(defaultWidth, emSize)))->unref();
    910     }
    911     return true;
    912 }
    913 void SkPDFFont::addWidthInfoFromRange(
    914         int16_t defaultWidth,
    915         const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry) {
    916     SkRefPtr<SkPDFArray> widthArray = new SkPDFArray();
    917     widthArray->unref();  // SkRefPtr and new both took a ref.
    918     int firstChar = 0;
    919     if (widthRangeEntry) {
    920         const uint16_t emSize = fFontInfo->fEmSize;
    921         int startIndex = fFirstGlyphID - widthRangeEntry->fStartId;
    922         int endIndex = startIndex + fLastGlyphID - fFirstGlyphID + 1;
    923         if (startIndex < 0)
    924             startIndex = 0;
    925         if (endIndex > widthRangeEntry->fAdvance.count())
    926             endIndex = widthRangeEntry->fAdvance.count();
    927         if (widthRangeEntry->fStartId == 0) {
    928             appendWidth(widthRangeEntry->fAdvance[0], emSize, widthArray.get());
    929         } else {
    930             firstChar = startIndex + widthRangeEntry->fStartId;
    931         }
    932         for (int i = startIndex; i < endIndex; i++)
    933             appendWidth(widthRangeEntry->fAdvance[i], emSize, widthArray.get());
    934     } else {
    935         appendWidth(defaultWidth, 1000, widthArray.get());
    936     }
    937     insert("FirstChar", new SkPDFInt(firstChar))->unref();
    938     insert("LastChar",
    939            new SkPDFInt(firstChar + widthArray->size() - 1))->unref();
    940     insert("Widths", widthArray.get());
    941 }
    942 
    943 void SkPDFFont::adjustGlyphRangeForSingleByteEncoding(int16_t glyphID) {
    944     // Single byte glyph encoding supports a max of 255 glyphs.
    945     fFirstGlyphID = glyphID - (glyphID - 1) % 255;
    946     if (fLastGlyphID > fFirstGlyphID + 255 - 1) {
    947         fLastGlyphID = fFirstGlyphID + 255 - 1;
    948     }
    949 }
    950 
    951 
    952 bool SkPDFFont::FontRec::operator==(const SkPDFFont::FontRec& b) const {
    953     if (fFontID != b.fFontID)
    954         return false;
    955     if (fFont != NULL && b.fFont != NULL) {
    956         return fFont->fFirstGlyphID == b.fFont->fFirstGlyphID &&
    957             fFont->fLastGlyphID == b.fFont->fLastGlyphID;
    958     }
    959     if (fGlyphID == 0 || b.fGlyphID == 0)
    960         return true;
    961 
    962     if (fFont != NULL) {
    963         return fFont->fFirstGlyphID <= b.fGlyphID &&
    964             b.fGlyphID <= fFont->fLastGlyphID;
    965     } else if (b.fFont != NULL) {
    966         return b.fFont->fFirstGlyphID <= fGlyphID &&
    967             fGlyphID <= b.fFont->fLastGlyphID;
    968     }
    969     return fGlyphID == b.fGlyphID;
    970 }
    971 
    972 SkPDFFont::FontRec::FontRec(SkPDFFont* font, uint32_t fontID, uint16_t glyphID)
    973     : fFont(font),
    974       fFontID(fontID),
    975       fGlyphID(glyphID) {
    976 }
    977