128be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
328be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
628be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org */
728be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
82a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org#include <ctype.h>
92a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
108a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com#include "SkData.h"
119db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org#include "SkGlyphCache.h"
1228be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org#include "SkPaint.h"
13fb62b3d423fa34c672df42f47017dbef087d19e9halcanary#include "SkPDFCanon.h"
149db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org#include "SkPDFDevice.h"
1528be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org#include "SkPDFFont.h"
169859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org#include "SkPDFFontImpl.h"
172a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org#include "SkPDFStream.h"
182a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org#include "SkPDFTypes.h"
199db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org#include "SkPDFUtils.h"
20f77e27deb95ff6fd6e6e30dcd3f6bf1862c394e1vandebo@chromium.org#include "SkRefCnt.h"
219db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org#include "SkScalar.h"
222a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org#include "SkStream.h"
23fed86bdb8b9f037439bbfa7cdbd53a581dbc5985reed@google.com#include "SkTypefacePriv.h"
24325cb9aa17b94258b362082eb3a799524f4345f3vandebo@chromium.org#include "SkTypes.h"
2528be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org#include "SkUtils.h"
2628be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
271f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org#if defined (SK_SFNTLY_SUBSETTER)
28d1371a6019189820653aaf20f72ee8f5d0ee3fefmtklein    #include SK_SFNTLY_SUBSETTER
29d1371a6019189820653aaf20f72ee8f5d0ee3fefmtklein#endif
30d1371a6019189820653aaf20f72ee8f5d0ee3fefmtklein
31d1371a6019189820653aaf20f72ee8f5d0ee3fefmtklein#if defined (GOOGLE3)
32d1371a6019189820653aaf20f72ee8f5d0ee3fefmtklein    // #including #defines doesn't work in with this build system.
33d1371a6019189820653aaf20f72ee8f5d0ee3fefmtklein    #include "typography/font/sfntly/src/sample/chromium/font_subsetter.h"
34d1371a6019189820653aaf20f72ee8f5d0ee3fefmtklein    #define SK_SFNTLY_SUBSETTER  // For the benefit of #ifdefs below.
351f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org#endif
361f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org
37dcf9c19d38d366a9f27ad0d8b5bda327c5edb164vandebo@chromium.org// PDF's notion of symbolic vs non-symbolic is related to the character set, not
38dcf9c19d38d366a9f27ad0d8b5bda327c5edb164vandebo@chromium.org// symbols vs. characters.  Rarely is a font the right character set to call it
39dcf9c19d38d366a9f27ad0d8b5bda327c5edb164vandebo@chromium.org// non-symbolic, so always call it symbolic.  (PDF 1.4 spec, section 5.7.1)
40dcf9c19d38d366a9f27ad0d8b5bda327c5edb164vandebo@chromium.orgstatic const int kPdfSymbolic = 4;
41dcf9c19d38d366a9f27ad0d8b5bda327c5edb164vandebo@chromium.org
4228be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.orgnamespace {
4328be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
449859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org///////////////////////////////////////////////////////////////////////////////
459859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org// File-Local Functions
469859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org///////////////////////////////////////////////////////////////////////////////
479859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
482a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.orgbool parsePFBSection(const uint8_t** src, size_t* len, int sectionType,
492a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                     size_t* size) {
502a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    // PFB sections have a two or six bytes header. 0x80 and a one byte
512a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    // section type followed by a four byte section length.  Type one is
522a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    // an ASCII section (includes a length), type two is a binary section
532a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    // (includes a length) and type three is an EOF marker with no length.
542a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    const uint8_t* buf = *src;
55769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    if (*len < 2 || buf[0] != 0x80 || buf[1] != sectionType) {
562a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        return false;
57769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    } else if (buf[1] == 3) {
582a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        return true;
59769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    } else if (*len < 6) {
602a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        return false;
61769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    }
622a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
6373322074658e19ff14591236d9b5485910a2c7b7vandebo@chromium.org    *size = (size_t)buf[2] | ((size_t)buf[3] << 8) | ((size_t)buf[4] << 16) |
6473322074658e19ff14591236d9b5485910a2c7b7vandebo@chromium.org            ((size_t)buf[5] << 24);
652a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    size_t consumed = *size + 6;
66769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    if (consumed > *len) {
672a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        return false;
68769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    }
692a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    *src = *src + consumed;
702a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    *len = *len - consumed;
712a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    return true;
722a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org}
732a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
742a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.orgbool parsePFB(const uint8_t* src, size_t size, size_t* headerLen,
752a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org              size_t* dataLen, size_t* trailerLen) {
762a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    const uint8_t* srcPtr = src;
772a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    size_t remaining = size;
782a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
792a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    return parsePFBSection(&srcPtr, &remaining, 1, headerLen) &&
802a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org           parsePFBSection(&srcPtr, &remaining, 2, dataLen) &&
812a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org           parsePFBSection(&srcPtr, &remaining, 1, trailerLen) &&
822a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org           parsePFBSection(&srcPtr, &remaining, 3, NULL);
832a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org}
842a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
852a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org/* The sections of a PFA file are implicitly defined.  The body starts
862a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org * after the line containing "eexec," and the trailer starts with 512
872a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org * literal 0's followed by "cleartomark" (plus arbitrary white space).
882a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org *
892a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org * This function assumes that src is NUL terminated, but the NUL
902a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org * termination is not included in size.
912a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org *
922a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org */
932a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.orgbool parsePFA(const char* src, size_t size, size_t* headerLen,
942a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org              size_t* hexDataLen, size_t* dataLen, size_t* trailerLen) {
952a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    const char* end = src + size;
962a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
972a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    const char* dataPos = strstr(src, "eexec");
98769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    if (!dataPos) {
992a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        return false;
100769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    }
1012a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    dataPos += strlen("eexec");
1022a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    while ((*dataPos == '\n' || *dataPos == '\r' || *dataPos == ' ') &&
103769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org            dataPos < end) {
1042a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        dataPos++;
105769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    }
1062a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    *headerLen = dataPos - src;
1072a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
1082a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    const char* trailerPos = strstr(dataPos, "cleartomark");
109769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    if (!trailerPos) {
1102a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        return false;
111769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    }
1122a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    int zeroCount = 0;
1132a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    for (trailerPos--; trailerPos > dataPos && zeroCount < 512; trailerPos--) {
1142a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        if (*trailerPos == '\n' || *trailerPos == '\r' || *trailerPos == ' ') {
1152a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org            continue;
1162a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        } else if (*trailerPos == '0') {
1172a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org            zeroCount++;
1182a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        } else {
1192a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org            return false;
1202a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        }
1212a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    }
122769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    if (zeroCount != 512) {
1232a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        return false;
124769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    }
1252a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
1262a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    *hexDataLen = trailerPos - src - *headerLen;
1272a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    *trailerLen = size - *headerLen - *hexDataLen;
1282a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
1292a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    // Verify that the data section is hex encoded and count the bytes.
1302a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    int nibbles = 0;
1312a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    for (; dataPos < trailerPos; dataPos++) {
132769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org        if (isspace(*dataPos)) {
1332a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org            continue;
134769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org        }
135769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org        if (!isxdigit(*dataPos)) {
1362a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org            return false;
137769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org        }
1382a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        nibbles++;
1392a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    }
1402a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    *dataLen = (nibbles + 1) / 2;
1412a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
1422a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    return true;
1432a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org}
1442a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
1452a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.orgint8_t hexToBin(uint8_t c) {
146769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    if (!isxdigit(c)) {
1472a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        return -1;
148769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    } else if (c <= '9') {
149769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org        return c - '0';
150769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    } else if (c <= 'F') {
151769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org        return c - 'A' + 10;
152769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    } else if (c <= 'f') {
153769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org        return c - 'a' + 10;
154769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    }
1552a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    return -1;
1562a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org}
1572a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
15867ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanarystatic SkData* handle_type1_stream(SkStream* srcStream, size_t* headerLen,
15967ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary                                   size_t* dataLen, size_t* trailerLen) {
1609859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    // srcStream may be backed by a file or a unseekable fd, so we may not be
1612a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    // able to use skip(), rewind(), or getMemoryBase().  read()ing through
1622a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    // the input only once is doable, but very ugly. Furthermore, it'd be nice
1632a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    // if the data was NUL terminated so that we can use strstr() to search it.
1642a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    // Make as few copies as possible given these constraints.
1652a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    SkDynamicMemoryWStream dynamicStream;
166a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo    SkAutoTDelete<SkMemoryStream> staticStream;
1678a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    SkData* data = NULL;
1682a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    const uint8_t* src;
1692a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    size_t srcLen;
1702a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    if ((srcLen = srcStream->getLength()) > 0) {
171d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org        staticStream.reset(new SkMemoryStream(srcLen + 1));
1722a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        src = (const uint8_t*)staticStream->getMemoryBase();
1732a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        if (srcStream->getMemoryBase() != NULL) {
1742a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org            memcpy((void *)src, srcStream->getMemoryBase(), srcLen);
1752a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        } else {
1762a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org            size_t read = 0;
1772a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org            while (read < srcLen) {
1782a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                size_t got = srcStream->read((void *)staticStream->getAtPos(),
1792a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                                             srcLen - read);
180769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org                if (got == 0) {
1812a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                    return NULL;
182769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org                }
1832a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                read += got;
1842a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                staticStream->seek(read);
1852a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org            }
1862a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        }
1872a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        ((uint8_t *)src)[srcLen] = 0;
1882a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    } else {
189a5c7234e81748f76cbeede40e619351146e5286actguil@chromium.org        static const size_t kBufSize = 4096;
190a5c7234e81748f76cbeede40e619351146e5286actguil@chromium.org        uint8_t buf[kBufSize];
1912a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        size_t amount;
192769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org        while ((amount = srcStream->read(buf, kBufSize)) > 0) {
1932a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org            dynamicStream.write(buf, amount);
194769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org        }
1952a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        amount = 0;
1962a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        dynamicStream.write(&amount, 1);  // NULL terminator.
1978a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        data = dynamicStream.copyToData();
1988a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        src = data->bytes();
1998a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        srcLen = data->size() - 1;
2002a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    }
2012a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
2028a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    // this handles releasing the data we may have gotten from dynamicStream.
2038a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    // if data is null, it is a no-op
2048a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com    SkAutoDataUnref aud(data);
2058a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com
2062a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    if (parsePFB(src, srcLen, headerLen, dataLen, trailerLen)) {
20767ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        static const int kPFBSectionHeaderLength = 6;
20867ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        const size_t length = *headerLen + *dataLen + *trailerLen;
20967ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        SkASSERT(length > 0);
21067ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        SkASSERT(length + (2 * kPFBSectionHeaderLength) <= srcLen);
21167ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary
21233a30503d76fdd989358cedd78445ba96bb809ddreed        SkData* data = SkData::NewUninitialized(length);
21367ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary
21467ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        const uint8_t* const srcHeader = src + kPFBSectionHeaderLength;
21567ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        // There is a six-byte section header before header and data
21667ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        // (but not trailer) that we're not going to copy.
21733a30503d76fdd989358cedd78445ba96bb809ddreed        const uint8_t* const srcData = srcHeader + *headerLen + kPFBSectionHeaderLength;
21867ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        const uint8_t* const srcTrailer = srcData + *headerLen;
21967ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary
22033a30503d76fdd989358cedd78445ba96bb809ddreed        uint8_t* const resultHeader = (uint8_t*)data->writable_data();
22167ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        uint8_t* const resultData = resultHeader + *headerLen;
22267ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        uint8_t* const resultTrailer = resultData + *dataLen;
22367ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary
22467ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        SkASSERT(resultTrailer + *trailerLen == resultHeader + length);
22567ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary
22667ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        memcpy(resultHeader,  srcHeader,  *headerLen);
22767ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        memcpy(resultData,    srcData,    *dataLen);
22867ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        memcpy(resultTrailer, srcTrailer, *trailerLen);
22967ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary
23033a30503d76fdd989358cedd78445ba96bb809ddreed        return data;
2312a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    }
2322a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
2332a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    // A PFA has to be converted for PDF.
2342a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    size_t hexDataLen;
2352a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    if (parsePFA((const char*)src, srcLen, headerLen, &hexDataLen, dataLen,
2362a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                 trailerLen)) {
23767ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        const size_t length = *headerLen + *dataLen + *trailerLen;
23867ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        SkASSERT(length > 0);
23967ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        SkAutoTMalloc<uint8_t> buffer(length);
24067ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary
24167ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        memcpy(buffer.get(), src, *headerLen);
2429880607151ca7c2dc6b1a4b9756938bd71913ab5bsalomon        uint8_t* const resultData = &(buffer[SkToInt(*headerLen)]);
2432a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
2442a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        const uint8_t* hexData = src + *headerLen;
2452a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        const uint8_t* trailer = hexData + hexDataLen;
2462a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        size_t outputOffset = 0;
2475b073680ecba631da68e33d0d2f28f10a07110cevandebo@chromium.org        uint8_t dataByte = 0;  // To hush compiler.
2482a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        bool highNibble = true;
2492a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        for (; hexData < trailer; hexData++) {
2503720fda4ebfc5a77cd1601992cae416d72e244b1commit-bot@chromium.org            int8_t curNibble = hexToBin(*hexData);
251769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org            if (curNibble < 0) {
2522a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                continue;
253769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org            }
2542a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org            if (highNibble) {
2552a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                dataByte = curNibble << 4;
2562a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                highNibble = false;
2572a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org            } else {
2582a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                dataByte |= curNibble;
2592a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                highNibble = true;
26067ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary                resultData[outputOffset++] = dataByte;
2612a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org            }
2622a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        }
263769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org        if (!highNibble) {
26467ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary            resultData[outputOffset++] = dataByte;
265769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org        }
2662a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        SkASSERT(outputOffset == *dataLen);
2672a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
2689880607151ca7c2dc6b1a4b9756938bd71913ab5bsalomon        uint8_t* const resultTrailer = &(buffer[SkToInt(*headerLen + outputOffset)]);
26967ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        memcpy(resultTrailer, src + *headerLen + hexDataLen, *trailerLen);
270e1c55869f37bf7c5f365fddc38207dc3ec336b6crmistry
27167ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary        return SkData::NewFromMalloc(buffer.detach(), length);
27267ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary    }
2732a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    return NULL;
2742a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org}
2752a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
2763f0dcf96c332b1b0cb9b63043d16607e8702259breed@google.com// scale from em-units to base-1000, returning as a SkScalar
277c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.orgSkScalar scaleFromFontUnits(int16_t val, uint16_t emSize) {
2783f0dcf96c332b1b0cb9b63043d16607e8702259breed@google.com    SkScalar scaled = SkIntToScalar(val);
2793f0dcf96c332b1b0cb9b63043d16607e8702259breed@google.com    if (emSize == 1000) {
2803f0dcf96c332b1b0cb9b63043d16607e8702259breed@google.com        return scaled;
2813f0dcf96c332b1b0cb9b63043d16607e8702259breed@google.com    } else {
2823f0dcf96c332b1b0cb9b63043d16607e8702259breed@google.com        return SkScalarMulDiv(scaled, 1000, emSize);
2833f0dcf96c332b1b0cb9b63043d16607e8702259breed@google.com    }
284c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org}
285c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org
2869db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.orgvoid setGlyphWidthAndBoundingBox(SkScalar width, SkIRect box,
287cae5fba82e687d674b076b10cdc8aba46e1ac3b3vandebo@chromium.org                                 SkWStream* content) {
2889db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org    // Specify width and bounding box for the glyph.
289bc4696b9176e05940a7c2d6778276cdbc55ccd61halcanary    SkPDFUtils::AppendScalar(width, content);
290cae5fba82e687d674b076b10cdc8aba46e1ac3b3vandebo@chromium.org    content->writeText(" 0 ");
291cae5fba82e687d674b076b10cdc8aba46e1ac3b3vandebo@chromium.org    content->writeDecAsText(box.fLeft);
292cae5fba82e687d674b076b10cdc8aba46e1ac3b3vandebo@chromium.org    content->writeText(" ");
293cae5fba82e687d674b076b10cdc8aba46e1ac3b3vandebo@chromium.org    content->writeDecAsText(box.fTop);
294cae5fba82e687d674b076b10cdc8aba46e1ac3b3vandebo@chromium.org    content->writeText(" ");
295cae5fba82e687d674b076b10cdc8aba46e1ac3b3vandebo@chromium.org    content->writeDecAsText(box.fRight);
296cae5fba82e687d674b076b10cdc8aba46e1ac3b3vandebo@chromium.org    content->writeText(" ");
297cae5fba82e687d674b076b10cdc8aba46e1ac3b3vandebo@chromium.org    content->writeDecAsText(box.fBottom);
298cae5fba82e687d674b076b10cdc8aba46e1ac3b3vandebo@chromium.org    content->writeText(" d1\n");
2999db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org}
3009db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org
30175f97e452e8f2ee55cd2b283df7d7734f48bc2bfvandebo@chromium.orgSkPDFArray* makeFontBBox(SkIRect glyphBBox, uint16_t emSize) {
3029db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org    SkPDFArray* bbox = new SkPDFArray;
3039db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org    bbox->reserve(4);
304c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com    bbox->appendScalar(scaleFromFontUnits(glyphBBox.fLeft, emSize));
305c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com    bbox->appendScalar(scaleFromFontUnits(glyphBBox.fBottom, emSize));
306c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com    bbox->appendScalar(scaleFromFontUnits(glyphBBox.fRight, emSize));
307c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com    bbox->appendScalar(scaleFromFontUnits(glyphBBox.fTop, emSize));
3089db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org    return bbox;
3099db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org}
3109db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org
311c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.orgSkPDFArray* appendWidth(const int16_t& width, uint16_t emSize,
312c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org                        SkPDFArray* array) {
313c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com    array->appendScalar(scaleFromFontUnits(width, emSize));
314f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org    return array;
3152a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org}
3162a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
317f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.orgSkPDFArray* appendVerticalAdvance(
318c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org        const SkAdvancedTypefaceMetrics::VerticalMetric& advance,
319c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org        uint16_t emSize, SkPDFArray* array) {
320c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org    appendWidth(advance.fVerticalAdvance, emSize, array);
321c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org    appendWidth(advance.fOriginXDisp, emSize, array);
322c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org    appendWidth(advance.fOriginYDisp, emSize, array);
323f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org    return array;
32428be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org}
32528be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
3262a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.orgtemplate <typename Data>
3272a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.orgSkPDFArray* composeAdvanceData(
328c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org        SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* advanceInfo,
329c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org        uint16_t emSize,
330c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org        SkPDFArray* (*appendAdvance)(const Data& advance, uint16_t emSize,
331c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org                                     SkPDFArray* array),
3322a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        Data* defaultAdvance) {
3332a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    SkPDFArray* result = new SkPDFArray();
3342a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    for (; advanceInfo != NULL; advanceInfo = advanceInfo->fNext.get()) {
3352a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        switch (advanceInfo->fType) {
336c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org            case SkAdvancedTypefaceMetrics::WidthRange::kDefault: {
3372a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                SkASSERT(advanceInfo->fAdvance.count() == 1);
3382a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                *defaultAdvance = advanceInfo->fAdvance[0];
3392a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                break;
3402a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org            }
341c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org            case SkAdvancedTypefaceMetrics::WidthRange::kRange: {
342d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org                SkAutoTUnref<SkPDFArray> advanceArray(new SkPDFArray());
3432a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                for (int j = 0; j < advanceInfo->fAdvance.count(); j++)
344c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org                    appendAdvance(advanceInfo->fAdvance[j], emSize,
345c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org                                  advanceArray.get());
346c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com                result->appendInt(advanceInfo->fStartId);
347bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary                result->appendObject(advanceArray.detach());
3482a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                break;
3492a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org            }
350c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org            case SkAdvancedTypefaceMetrics::WidthRange::kRun: {
3512a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                SkASSERT(advanceInfo->fAdvance.count() == 1);
352c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com                result->appendInt(advanceInfo->fStartId);
353c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com                result->appendInt(advanceInfo->fEndId);
354c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org                appendAdvance(advanceInfo->fAdvance[0], emSize, result);
3552a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                break;
3562a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org            }
3572a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        }
3582a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    }
3592a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    return result;
36028be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org}
36128be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
3622a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org}  // namespace
3632a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
36426d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.comstatic void append_tounicode_header(SkDynamicMemoryWStream* cmap,
36526d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com                                    uint16_t firstGlyphID,
36626d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com                                    uint16_t lastGlyphID) {
3676744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org    // 12 dict begin: 12 is an Adobe-suggested value. Shall not change.
3686744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org    // It's there to prevent old version Adobe Readers from malfunctioning.
3696744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org    const char* kHeader =
3706744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org        "/CIDInit /ProcSet findresource begin\n"
3716744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org        "12 dict begin\n"
3726744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org        "begincmap\n";
3736744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org    cmap->writeText(kHeader);
3746744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org
3756744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org    // The /CIDSystemInfo must be consistent to the one in
3766744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org    // SkPDFFont::populateCIDFont().
3776744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org    // We can not pass over the system info object here because the format is
3786744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org    // different. This is not a reference object.
3796744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org    const char* kSysInfo =
3806744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org        "/CIDSystemInfo\n"
3816744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org        "<<  /Registry (Adobe)\n"
3826744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org        "/Ordering (UCS)\n"
3836744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org        "/Supplement 0\n"
3846744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org        ">> def\n";
3856744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org    cmap->writeText(kSysInfo);
3866744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org
3876744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org    // The CMapName must be consistent to /CIDSystemInfo above.
3886744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org    // /CMapType 2 means ToUnicode.
38926d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    // Codespace range just tells the PDF processor the valid range.
39026d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    const char* kTypeInfoHeader =
3916744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org        "/CMapName /Adobe-Identity-UCS def\n"
3926744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org        "/CMapType 2 def\n"
39326d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com        "1 begincodespacerange\n";
39426d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    cmap->writeText(kTypeInfoHeader);
3952262c588023f1641d2bf1ee8a38f6055973b1a17skia.committer@gmail.com
39626d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    // e.g.     "<0000> <FFFF>\n"
39726d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    SkString range;
39826d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    range.appendf("<%04X> <%04X>\n", firstGlyphID, lastGlyphID);
39926d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    cmap->writeText(range.c_str());
4002262c588023f1641d2bf1ee8a38f6055973b1a17skia.committer@gmail.com
40126d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    const char* kTypeInfoFooter = "endcodespacerange\n";
40226d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    cmap->writeText(kTypeInfoFooter);
4036744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org}
4046744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org
4056744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.orgstatic void append_cmap_footer(SkDynamicMemoryWStream* cmap) {
4066744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org    const char* kFooter =
4076744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org        "endcmap\n"
4086744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org        "CMapName currentdict /CMap defineresource pop\n"
4096744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org        "end\n"
4106744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org        "end";
4116744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org    cmap->writeText(kFooter);
4126744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org}
4136744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org
41404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.orgstruct BFChar {
41504c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    uint16_t fGlyphId;
41604c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    SkUnichar fUnicode;
41704c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org};
41804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org
41904c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.orgstruct BFRange {
42004c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    uint16_t fStart;
42104c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    uint16_t fEnd;
42204c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    SkUnichar fUnicode;
42304c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org};
42404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org
42504c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.orgstatic void append_bfchar_section(const SkTDArray<BFChar>& bfchar,
42604c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org                                  SkDynamicMemoryWStream* cmap) {
4276744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org    // PDF spec defines that every bf* list can have at most 100 entries.
42804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    for (int i = 0; i < bfchar.count(); i += 100) {
42904c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org        int count = bfchar.count() - i;
43004c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org        count = SkMin32(count, 100);
43104c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org        cmap->writeDecAsText(count);
43204c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org        cmap->writeText(" beginbfchar\n");
43304c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org        for (int j = 0; j < count; ++j) {
43404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org            cmap->writeText("<");
43504c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org            cmap->writeHexAsText(bfchar[i + j].fGlyphId, 4);
43604c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org            cmap->writeText("> <");
43704c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org            cmap->writeHexAsText(bfchar[i + j].fUnicode, 4);
43804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org            cmap->writeText(">\n");
4396744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org        }
44004c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org        cmap->writeText("endbfchar\n");
44104c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    }
44204c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org}
44304c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org
44404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.orgstatic void append_bfrange_section(const SkTDArray<BFRange>& bfrange,
44504c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org                                   SkDynamicMemoryWStream* cmap) {
44604c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    // PDF spec defines that every bf* list can have at most 100 entries.
44704c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    for (int i = 0; i < bfrange.count(); i += 100) {
44804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org        int count = bfrange.count() - i;
44904c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org        count = SkMin32(count, 100);
45004c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org        cmap->writeDecAsText(count);
45104c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org        cmap->writeText(" beginbfrange\n");
45204c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org        for (int j = 0; j < count; ++j) {
45304c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org            cmap->writeText("<");
45404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org            cmap->writeHexAsText(bfrange[i + j].fStart, 4);
45504c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org            cmap->writeText("> <");
45604c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org            cmap->writeHexAsText(bfrange[i + j].fEnd, 4);
45704c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org            cmap->writeText("> <");
45804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org            cmap->writeHexAsText(bfrange[i + j].fUnicode, 4);
45904c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org            cmap->writeText(">\n");
4606744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org        }
46104c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org        cmap->writeText("endbfrange\n");
4626744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org    }
46304c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org}
46404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org
46504c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// Generate <bfchar> and <bfrange> table according to PDF spec 1.4 and Adobe
46604c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// Technote 5014.
46704c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// The function is not static so we can test it in unit tests.
46804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org//
46904c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// Current implementation guarantees bfchar and bfrange entries do not overlap.
47004c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org//
47104c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// Current implementation does not attempt aggresive optimizations against
47204c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// following case because the specification is not clear.
47304c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org//
47404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// 4 beginbfchar          1 beginbfchar
47504c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// <0003> <0013>          <0020> <0014>
47604c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// <0005> <0015>    to    endbfchar
47704c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// <0007> <0017>          1 beginbfrange
47804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// <0020> <0014>          <0003> <0007> <0013>
47904c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// endbfchar              endbfrange
48004c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org//
48104c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// Adobe Technote 5014 said: "Code mappings (unlike codespace ranges) may
4821236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org// overlap, but succeeding maps supersede preceding maps."
48304c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org//
48404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// In case of searching text in PDF, bfrange will have higher precedence so
48504c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// typing char id 0x0014 in search box will get glyph id 0x0004 first.  However,
48604c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// the spec does not mention how will this kind of conflict being resolved.
48704c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org//
48804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// For the worst case (having 65536 continuous unicode and we use every other
48904c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// one of them), the possible savings by aggressive optimization is 416KB
49004c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org// pre-compressed and does not provide enough motivation for implementation.
4911445a0d53b0793a2cc05c20e4ba74528f028cd8ecaryclark@google.com
4921445a0d53b0793a2cc05c20e4ba74528f028cd8ecaryclark@google.com// FIXME: this should be in a header so that it is separately testable
4931445a0d53b0793a2cc05c20e4ba74528f028cd8ecaryclark@google.com// ( see caller in tests/ToUnicode.cpp )
4941445a0d53b0793a2cc05c20e4ba74528f028cd8ecaryclark@google.comvoid append_cmap_sections(const SkTDArray<SkUnichar>& glyphToUnicode,
4951445a0d53b0793a2cc05c20e4ba74528f028cd8ecaryclark@google.com                          const SkPDFGlyphSet* subset,
49626d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com                          SkDynamicMemoryWStream* cmap,
4971236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org                          bool multiByteGlyphs,
49826d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com                          uint16_t firstGlyphID,
49926d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com                          uint16_t lastGlyphID);
500d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
50104c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.orgvoid append_cmap_sections(const SkTDArray<SkUnichar>& glyphToUnicode,
50204c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org                          const SkPDFGlyphSet* subset,
50326d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com                          SkDynamicMemoryWStream* cmap,
5041236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org                          bool multiByteGlyphs,
50526d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com                          uint16_t firstGlyphID,
50626d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com                          uint16_t lastGlyphID) {
507769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    if (glyphToUnicode.isEmpty()) {
508769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org        return;
509769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    }
5101236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org    int glyphOffset = 0;
5111236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org    if (!multiByteGlyphs) {
5121236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org        glyphOffset = firstGlyphID - 1;
5131236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org    }
51404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org
51504c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    SkTDArray<BFChar> bfcharEntries;
51604c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    SkTDArray<BFRange> bfrangeEntries;
51704c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org
518cadbcb8e536f89babb4e165bfdca18384e97d582bsalomon@google.com    BFRange currentRangeEntry = {0, 0, 0};
5199ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    bool rangeEmpty = true;
5201236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org    const int limit =
5211236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org            SkMin32(lastGlyphID + 1, glyphToUnicode.count()) - glyphOffset;
52204c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org
5231236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org    for (int i = firstGlyphID - glyphOffset; i < limit + 1; ++i) {
52426d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com        bool inSubset = i < limit &&
5251236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org                        (subset == NULL || subset->has(i + glyphOffset));
5269ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org        if (!rangeEmpty) {
52704c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org            // PDF spec requires bfrange not changing the higher byte,
52804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org            // e.g. <1035> <10FF> <2222> is ok, but
52904c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org            //      <1035> <1100> <2222> is no good
5309ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org            bool inRange =
5319ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org                i == currentRangeEntry.fEnd + 1 &&
5329ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org                i >> 8 == currentRangeEntry.fStart >> 8 &&
53326d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com                i < limit &&
5341236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org                glyphToUnicode[i + glyphOffset] ==
5351236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org                    currentRangeEntry.fUnicode + i - currentRangeEntry.fStart;
5369ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org            if (!inSubset || !inRange) {
5379ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org                if (currentRangeEntry.fEnd > currentRangeEntry.fStart) {
53804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org                    bfrangeEntries.push(currentRangeEntry);
53904c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org                } else {
54004c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org                    BFChar* entry = bfcharEntries.append();
54104c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org                    entry->fGlyphId = currentRangeEntry.fStart;
54204c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org                    entry->fUnicode = currentRangeEntry.fUnicode;
54304c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org                }
5449ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org                rangeEmpty = true;
54504c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org            }
5469ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org        }
5479ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org        if (inSubset) {
5489ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org            currentRangeEntry.fEnd = i;
5499ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org            if (rangeEmpty) {
5509ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org              currentRangeEntry.fStart = i;
5511236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org              currentRangeEntry.fUnicode = glyphToUnicode[i + glyphOffset];
5529ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org              rangeEmpty = false;
55304c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org            }
55404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org        }
5556744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org    }
55604c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org
55704c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    // The spec requires all bfchar entries for a font must come before bfrange
55804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    // entries.
55904c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    append_bfchar_section(bfcharEntries, cmap);
56004c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    append_bfrange_section(bfrangeEntries, cmap);
5616744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org}
5626744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org
5639859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgstatic SkPDFStream* generate_tounicode_cmap(
56404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org        const SkTDArray<SkUnichar>& glyphToUnicode,
56526d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com        const SkPDFGlyphSet* subset,
5661236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org        bool multiByteGlyphs,
56726d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com        uint16_t firstGlyphID,
56826d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com        uint16_t lastGlyphID) {
5699859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    SkDynamicMemoryWStream cmap;
5701236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org    if (multiByteGlyphs) {
5711236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org        append_tounicode_header(&cmap, firstGlyphID, lastGlyphID);
5721236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org    } else {
5731236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org        append_tounicode_header(&cmap, 1, lastGlyphID - firstGlyphID + 1);
5741236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org    }
5751236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org    append_cmap_sections(glyphToUnicode, subset, &cmap, multiByteGlyphs,
57626d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com                         firstGlyphID, lastGlyphID);
5779859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    append_cmap_footer(&cmap);
57867ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary    SkAutoTUnref<SkData> cmapData(cmap.copyToData());
57967ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary    return new SkPDFStream(cmapData.get());
5809859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
5819859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
5821445a0d53b0793a2cc05c20e4ba74528f028cd8ecaryclark@google.com#if defined (SK_SFNTLY_SUBSETTER)
5831f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.orgstatic void sk_delete_array(const void* ptr, size_t, void*) {
5841f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org    // Use C-style cast to cast away const and cast type simultaneously.
5851f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org    delete[] (unsigned char*)ptr;
5861f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org}
5871445a0d53b0793a2cc05c20e4ba74528f028cd8ecaryclark@google.com#endif
5881f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org
589aec406650cbfa4ef65d83db5ff4f82572e8e098freed@google.comstatic size_t get_subset_font_stream(const char* fontName,
590aec406650cbfa4ef65d83db5ff4f82572e8e098freed@google.com                                     const SkTypeface* typeface,
591aec406650cbfa4ef65d83db5ff4f82572e8e098freed@google.com                                     const SkTDArray<uint32_t>& subset,
592aec406650cbfa4ef65d83db5ff4f82572e8e098freed@google.com                                     SkPDFStream** fontStream) {
593fed86bdb8b9f037439bbfa7cdbd53a581dbc5985reed@google.com    int ttcIndex;
594a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo    SkAutoTDelete<SkStream> fontData(typeface->openStream(&ttcIndex));
59567ec1f8eecfb48bc0a6ba04c0057f103c1c9696fhalcanary    SkASSERT(fontData.get());
5961f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org
597aec406650cbfa4ef65d83db5ff4f82572e8e098freed@google.com    size_t fontSize = fontData->getLength();
5981f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org
5991f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org#if defined (SK_SFNTLY_SUBSETTER)
6001f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org    // Read font into buffer.
6011f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org    SkPDFStream* subsetFontStream = NULL;
6021f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org    SkTDArray<unsigned char> originalFont;
603aec406650cbfa4ef65d83db5ff4f82572e8e098freed@google.com    originalFont.setCount(SkToInt(fontSize));
604aec406650cbfa4ef65d83db5ff4f82572e8e098freed@google.com    if (fontData->read(originalFont.begin(), fontSize) == fontSize) {
6051f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org        unsigned char* subsetFont = NULL;
60617e66e2d341ab684eec7841fd383af85bb4aa625vandebo@chromium.org        // sfntly requires unsigned int* to be passed in, as far as we know,
60717e66e2d341ab684eec7841fd383af85bb4aa625vandebo@chromium.org        // unsigned int is equivalent to uint32_t on all platforms.
60817e66e2d341ab684eec7841fd383af85bb4aa625vandebo@chromium.org        SK_COMPILE_ASSERT(sizeof(unsigned int) == sizeof(uint32_t),
60917e66e2d341ab684eec7841fd383af85bb4aa625vandebo@chromium.org                          unsigned_int_not_32_bits);
6101f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org        int subsetFontSize = SfntlyWrapper::SubsetFont(fontName,
6111f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org                                                       originalFont.begin(),
6121f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org                                                       fontSize,
61337ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org                                                       subset.begin(),
61437ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org                                                       subset.count(),
6151f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org                                                       &subsetFont);
6161f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org        if (subsetFontSize > 0 && subsetFont != NULL) {
61793225ff5d5872faada54a073423e802e8e721323vandebo@chromium.org            SkAutoDataUnref data(SkData::NewWithProc(subsetFont,
61893225ff5d5872faada54a073423e802e8e721323vandebo@chromium.org                                                     subsetFontSize,
61993225ff5d5872faada54a073423e802e8e721323vandebo@chromium.org                                                     sk_delete_array,
62093225ff5d5872faada54a073423e802e8e721323vandebo@chromium.org                                                     NULL));
62193225ff5d5872faada54a073423e802e8e721323vandebo@chromium.org            subsetFontStream = new SkPDFStream(data.get());
6221f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org            fontSize = subsetFontSize;
6231f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org        }
6241f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org    }
6251f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org    if (subsetFontStream) {
6261f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org        *fontStream = subsetFontStream;
6271f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org        return fontSize;
6281f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org    }
629938ea62176f435a1d5899499d414d1c1e6705482vandebo@chromium.org    fontData->rewind();
630e2e8113baa69b5d1a0bae9652a095c1eb44b3a53sugoi@google.com#else
631e2e8113baa69b5d1a0bae9652a095c1eb44b3a53sugoi@google.com    sk_ignore_unused_variable(fontName);
632e2e8113baa69b5d1a0bae9652a095c1eb44b3a53sugoi@google.com    sk_ignore_unused_variable(subset);
6331f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org#endif
6341f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org
6351f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org    // Fail over: just embed the whole font.
6361f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org    *fontStream = new SkPDFStream(fontData.get());
6371f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org    return fontSize;
6381f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org}
6391f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org
6409859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org///////////////////////////////////////////////////////////////////////////////
6419859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org// class SkPDFGlyphSet
6429859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org///////////////////////////////////////////////////////////////////////////////
6439859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
6449859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgSkPDFGlyphSet::SkPDFGlyphSet() : fBitSet(SK_MaxU16 + 1) {
6459859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
6469859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
6479859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgvoid SkPDFGlyphSet::set(const uint16_t* glyphIDs, int numGlyphs) {
6489859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    for (int i = 0; i < numGlyphs; ++i) {
6499859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        fBitSet.setBit(glyphIDs[i], true);
6509859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    }
6519859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
6529859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
6539859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgbool SkPDFGlyphSet::has(uint16_t glyphID) const {
6549859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    return fBitSet.isBitSet(glyphID);
6559859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
6569859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
6579859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgvoid SkPDFGlyphSet::merge(const SkPDFGlyphSet& usage) {
6589859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    fBitSet.orBits(usage.fBitSet);
6599859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
6609859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
66117e66e2d341ab684eec7841fd383af85bb4aa625vandebo@chromium.orgvoid SkPDFGlyphSet::exportTo(SkTDArray<unsigned int>* glyphIDs) const {
66217e66e2d341ab684eec7841fd383af85bb4aa625vandebo@chromium.org    fBitSet.exportTo(glyphIDs);
66317e66e2d341ab684eec7841fd383af85bb4aa625vandebo@chromium.org}
66417e66e2d341ab684eec7841fd383af85bb4aa625vandebo@chromium.org
6659859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org///////////////////////////////////////////////////////////////////////////////
6669859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org// class SkPDFGlyphSetMap
6679859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org///////////////////////////////////////////////////////////////////////////////
6689859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgSkPDFGlyphSetMap::FontGlyphSetPair::FontGlyphSetPair(SkPDFFont* font,
6699859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org                                                     SkPDFGlyphSet* glyphSet)
6709859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        : fFont(font),
6719859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org          fGlyphSet(glyphSet) {
6729859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
6739859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
6749859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgSkPDFGlyphSetMap::F2BIter::F2BIter(const SkPDFGlyphSetMap& map) {
6759859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    reset(map);
6769859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
6779859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
678aa537d4bdb2384cdcd0644a02a2ab7fb0ecdd3b3commit-bot@chromium.orgconst SkPDFGlyphSetMap::FontGlyphSetPair* SkPDFGlyphSetMap::F2BIter::next() const {
6799859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    if (fIndex >= fMap->count()) {
6809859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        return NULL;
6819859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    }
6829859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    return &((*fMap)[fIndex++]);
6839859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
6849859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
6859859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgvoid SkPDFGlyphSetMap::F2BIter::reset(const SkPDFGlyphSetMap& map) {
6869859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    fMap = &(map.fMap);
6879859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    fIndex = 0;
6889859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
6899859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
6909859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgSkPDFGlyphSetMap::SkPDFGlyphSetMap() {
6919859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
6929859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
6939859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgSkPDFGlyphSetMap::~SkPDFGlyphSetMap() {
6949859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    reset();
6959859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
6969859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
6979859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgvoid SkPDFGlyphSetMap::merge(const SkPDFGlyphSetMap& usage) {
6989859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    for (int i = 0; i < usage.fMap.count(); ++i) {
6999859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        SkPDFGlyphSet* myUsage = getGlyphSetForFont(usage.fMap[i].fFont);
7009859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        myUsage->merge(*(usage.fMap[i].fGlyphSet));
7019859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    }
7029859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
7039859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
7049859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgvoid SkPDFGlyphSetMap::reset() {
7059859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    for (int i = 0; i < fMap.count(); ++i) {
7069859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        delete fMap[i].fGlyphSet;  // Should not be NULL.
7079859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    }
7089859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    fMap.reset();
7099859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
7109859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
7119859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgvoid SkPDFGlyphSetMap::noteGlyphUsage(SkPDFFont* font, const uint16_t* glyphIDs,
7129859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org                                      int numGlyphs) {
7139859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    SkPDFGlyphSet* subset = getGlyphSetForFont(font);
7149859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    if (subset) {
7159859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        subset->set(glyphIDs, numGlyphs);
7169859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    }
7179859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
7189859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
7199859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgSkPDFGlyphSet* SkPDFGlyphSetMap::getGlyphSetForFont(SkPDFFont* font) {
7209859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    int index = fMap.count();
7219859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    for (int i = 0; i < index; ++i) {
7229859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        if (fMap[i].fFont == font) {
7239859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org            return fMap[i].fGlyphSet;
7249859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        }
7259859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    }
7269859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    fMap.append();
7279859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    index = fMap.count() - 1;
7289859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    fMap[index].fFont = font;
7299859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    fMap[index].fGlyphSet = new SkPDFGlyphSet();
7309859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    return fMap[index].fGlyphSet;
7319859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
7329859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
7339859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org///////////////////////////////////////////////////////////////////////////////
7349859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org// class SkPDFFont
7359859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org///////////////////////////////////////////////////////////////////////////////
7369859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
7372a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org/* Font subset design: It would be nice to be able to subset fonts
7382a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org * (particularly type 3 fonts), but it's a lot of work and not a priority.
7392a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org *
7402a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org * Resources are canonicalized and uniqueified by pointer so there has to be
7412a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org * some additional state indicating which subset of the font is used.  It
7422a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org * must be maintained at the page granularity and then combined at the document
7432a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org * granularity. a) change SkPDFFont to fill in its state on demand, kind of
7442a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org * like SkPDFGraphicState.  b) maintain a per font glyph usage class in each
7452a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org * page/pdf device. c) in the document, retrieve the per font glyph usage
7462a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org * from each page and combine it and ask for a resource with that subset.
7472a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org */
7482a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
7492e3f9d8a9309686eeb4c76ccfde5800da87a68b3halcanarySkPDFFont::~SkPDFFont() {}
75028be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
7519db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.orgSkTypeface* SkPDFFont::typeface() {
7529db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org    return fTypeface.get();
75328be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org}
75428be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
755f0ec2666d9a3f0f1662f0d63b5147628c49648aavandebo@chromium.orgSkAdvancedTypefaceMetrics::FontType SkPDFFont::getType() {
7569859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    return fFontType;
757f0ec2666d9a3f0f1662f0d63b5147628c49648aavandebo@chromium.org}
758f0ec2666d9a3f0f1662f0d63b5147628c49648aavandebo@chromium.org
7590f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebobool SkPDFFont::canEmbed() const {
7600f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    if (!fFontInfo.get()) {
7610f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo        SkASSERT(fFontType == SkAdvancedTypefaceMetrics::kOther_Font);
7620f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo        return true;
7630f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    }
7640f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    return (fFontInfo->fFlags &
7650f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo            SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag) == 0;
7660f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo}
7670f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo
7680f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebobool SkPDFFont::canSubset() const {
7690f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    if (!fFontInfo.get()) {
7700f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo        SkASSERT(fFontType == SkAdvancedTypefaceMetrics::kOther_Font);
7710f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo        return true;
7720f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    }
7730f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    return (fFontInfo->fFlags &
7740f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo            SkAdvancedTypefaceMetrics::kNotSubsettable_FontFlag) == 0;
7750f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo}
7760f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo
7772a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.orgbool SkPDFFont::hasGlyph(uint16_t id) {
7782a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    return (id >= fFirstGlyphID && id <= fLastGlyphID) || id == 0;
7792a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org}
7802a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
781aec406650cbfa4ef65d83db5ff4f82572e8e098freed@google.comint SkPDFFont::glyphsToPDFFontEncoding(uint16_t* glyphIDs, int numGlyphs) {
7820129410fbe4b88a0632fb7aa5185610b30e69852vandebo@chromium.org    // A font with multibyte glyphs will support all glyph IDs in a single font.
7839859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    if (this->multiByteGlyphs()) {
7840129410fbe4b88a0632fb7aa5185610b30e69852vandebo@chromium.org        return numGlyphs;
7850129410fbe4b88a0632fb7aa5185610b30e69852vandebo@chromium.org    }
7860129410fbe4b88a0632fb7aa5185610b30e69852vandebo@chromium.org
787aec406650cbfa4ef65d83db5ff4f82572e8e098freed@google.com    for (int i = 0; i < numGlyphs; i++) {
7880129410fbe4b88a0632fb7aa5185610b30e69852vandebo@chromium.org        if (glyphIDs[i] == 0) {
7890129410fbe4b88a0632fb7aa5185610b30e69852vandebo@chromium.org            continue;
7900129410fbe4b88a0632fb7aa5185610b30e69852vandebo@chromium.org        }
7910129410fbe4b88a0632fb7aa5185610b30e69852vandebo@chromium.org        if (glyphIDs[i] < fFirstGlyphID || glyphIDs[i] > fLastGlyphID) {
7920129410fbe4b88a0632fb7aa5185610b30e69852vandebo@chromium.org            return i;
7932a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        }
7940129410fbe4b88a0632fb7aa5185610b30e69852vandebo@chromium.org        glyphIDs[i] -= (fFirstGlyphID - 1);
79528be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    }
7962a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
7972a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    return numGlyphs;
79828be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org}
79928be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
80028be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org// static
801792c80f5a7b66e75d42664ccb298f31962c6654chalcanarySkPDFFont* SkPDFFont::GetFontResource(SkPDFCanon* canon,
802792c80f5a7b66e75d42664ccb298f31962c6654chalcanary                                      SkTypeface* typeface,
803792c80f5a7b66e75d42664ccb298f31962c6654chalcanary                                      uint16_t glyphID) {
804792c80f5a7b66e75d42664ccb298f31962c6654chalcanary    SkASSERT(canon);
805fed86bdb8b9f037439bbfa7cdbd53a581dbc5985reed@google.com    SkAutoResolveDefaultTypeface autoResolve(typeface);
806fed86bdb8b9f037439bbfa7cdbd53a581dbc5985reed@google.com    typeface = autoResolve.get();
807fed86bdb8b9f037439bbfa7cdbd53a581dbc5985reed@google.com    const uint32_t fontID = typeface->uniqueID();
808fb62b3d423fa34c672df42f47017dbef087d19e9halcanary
809fb62b3d423fa34c672df42f47017dbef087d19e9halcanary    SkPDFFont* relatedFont;
810792c80f5a7b66e75d42664ccb298f31962c6654chalcanary    if (SkPDFFont* pdfFont = canon->findFont(fontID, glyphID, &relatedFont)) {
811fb62b3d423fa34c672df42f47017dbef087d19e9halcanary        return SkRef(pdfFont);
81228be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    }
81328be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
814fb747e2c745896dd94425ff690483ae3838e88fehalcanary    SkAutoTUnref<const SkAdvancedTypefaceMetrics> fontMetrics;
8159859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    SkPDFDict* relatedFontDescriptor = NULL;
816fb62b3d423fa34c672df42f47017dbef087d19e9halcanary    if (relatedFont) {
817fb62b3d423fa34c672df42f47017dbef087d19e9halcanary        fontMetrics.reset(SkSafeRef(relatedFont->fontInfo()));
8189859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        relatedFontDescriptor = relatedFont->getFontDescriptor();
819022e857abc84a43dba0ab93be8680af9dd6f8bf7edisonn@google.com
820022e857abc84a43dba0ab93be8680af9dd6f8bf7edisonn@google.com        // This only is to catch callers who pass invalid glyph ids.
821022e857abc84a43dba0ab93be8680af9dd6f8bf7edisonn@google.com        // If glyph id is invalid, then we will create duplicate entries
8220f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo        // for TrueType fonts.
8231e34ff7030c95a96c3cd5940de9b4dda4e1cef86skia.committer@gmail.com        SkAdvancedTypefaceMetrics::FontType fontType =
824022e857abc84a43dba0ab93be8680af9dd6f8bf7edisonn@google.com            fontMetrics.get() ? fontMetrics.get()->fType :
825022e857abc84a43dba0ab93be8680af9dd6f8bf7edisonn@google.com                                SkAdvancedTypefaceMetrics::kOther_Font;
826022e857abc84a43dba0ab93be8680af9dd6f8bf7edisonn@google.com
827022e857abc84a43dba0ab93be8680af9dd6f8bf7edisonn@google.com        if (fontType == SkAdvancedTypefaceMetrics::kType1CID_Font ||
828022e857abc84a43dba0ab93be8680af9dd6f8bf7edisonn@google.com            fontType == SkAdvancedTypefaceMetrics::kTrueType_Font) {
829fb62b3d423fa34c672df42f47017dbef087d19e9halcanary            return SkRef(relatedFont);
8301e34ff7030c95a96c3cd5940de9b4dda4e1cef86skia.committer@gmail.com        }
8312a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    } else {
83239a9a5069b25aa8b9529118cfd0ece5f412fb56breed        SkTypeface::PerGlyphInfo info;
83339a9a5069b25aa8b9529118cfd0ece5f412fb56breed        info = SkTypeface::kGlyphNames_PerGlyphInfo;
83439a9a5069b25aa8b9529118cfd0ece5f412fb56breed        info = SkTBitOr<SkTypeface::PerGlyphInfo>(
83539a9a5069b25aa8b9529118cfd0ece5f412fb56breed                  info, SkTypeface::kToUnicode_PerGlyphInfo);
83637ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org#if !defined (SK_SFNTLY_SUBSETTER)
83739a9a5069b25aa8b9529118cfd0ece5f412fb56breed        info = SkTBitOr<SkTypeface::PerGlyphInfo>(
83839a9a5069b25aa8b9529118cfd0ece5f412fb56breed                  info, SkTypeface::kHAdvance_PerGlyphInfo);
83937ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org#endif
840d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org        fontMetrics.reset(
841fed86bdb8b9f037439bbfa7cdbd53a581dbc5985reed@google.com            typeface->getAdvancedTypefaceMetrics(info, NULL, 0));
842610f716b00f214e4899a102c1bbc1d6a323e114evandebo@chromium.org#if defined (SK_SFNTLY_SUBSETTER)
843d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org        if (fontMetrics.get() &&
844b3b465567db95e4ffa70aa5b5b06a6aa43b379a8vandebo@chromium.org            fontMetrics->fType != SkAdvancedTypefaceMetrics::kTrueType_Font) {
84537ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org            // Font does not support subsetting, get new info with advance.
846d9950091efab9083692b728a45d84f42fa66e5f2reed            info = SkTBitOr<SkTypeface::PerGlyphInfo>(
847d9950091efab9083692b728a45d84f42fa66e5f2reed                      info, SkTypeface::kHAdvance_PerGlyphInfo);
848d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org            fontMetrics.reset(
849fed86bdb8b9f037439bbfa7cdbd53a581dbc5985reed@google.com                typeface->getAdvancedTypefaceMetrics(info, NULL, 0));
85037ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org        }
85137ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org#endif
8522a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    }
85328be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
854792c80f5a7b66e75d42664ccb298f31962c6654chalcanary    SkPDFFont* font = SkPDFFont::Create(canon, fontMetrics.get(), typeface,
855792c80f5a7b66e75d42664ccb298f31962c6654chalcanary                                        glyphID, relatedFontDescriptor);
856792c80f5a7b66e75d42664ccb298f31962c6654chalcanary    canon->addFont(font, fontID, font->fFirstGlyphID);
857792c80f5a7b66e75d42664ccb298f31962c6654chalcanary    return font;
85828be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org}
85928be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
860e2e8113baa69b5d1a0bae9652a095c1eb44b3a53sugoi@google.comSkPDFFont* SkPDFFont::getFontSubset(const SkPDFGlyphSet*) {
8619859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    return NULL;  // Default: no support.
8629859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
8639859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
8642e3f9d8a9309686eeb4c76ccfde5800da87a68b3halcanarySkPDFFont::SkPDFFont(const SkAdvancedTypefaceMetrics* info,
865fb747e2c745896dd94425ff690483ae3838e88fehalcanary                     SkTypeface* typeface,
866e2e8113baa69b5d1a0bae9652a095c1eb44b3a53sugoi@google.com                     SkPDFDict* relatedFontDescriptor)
867792c80f5a7b66e75d42664ccb298f31962c6654chalcanary    : SkPDFDict("Font")
868792c80f5a7b66e75d42664ccb298f31962c6654chalcanary    , fTypeface(ref_or_default(typeface))
869792c80f5a7b66e75d42664ccb298f31962c6654chalcanary    , fFirstGlyphID(1)
870792c80f5a7b66e75d42664ccb298f31962c6654chalcanary    , fLastGlyphID(info ? info->fLastGlyphID : 0)
871792c80f5a7b66e75d42664ccb298f31962c6654chalcanary    , fFontInfo(SkSafeRef(info))
872792c80f5a7b66e75d42664ccb298f31962c6654chalcanary    , fDescriptor(SkSafeRef(relatedFontDescriptor)) {
8730f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    if (info == NULL ||
8740f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo            info->fFlags & SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag) {
8759859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        fFontType = SkAdvancedTypefaceMetrics::kOther_Font;
8769859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    } else {
8779859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        fFontType = info->fType;
8789859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    }
8799859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
8809859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
8819859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org// static
882792c80f5a7b66e75d42664ccb298f31962c6654chalcanarySkPDFFont* SkPDFFont::Create(SkPDFCanon* canon,
883792c80f5a7b66e75d42664ccb298f31962c6654chalcanary                             const SkAdvancedTypefaceMetrics* info,
884792c80f5a7b66e75d42664ccb298f31962c6654chalcanary                             SkTypeface* typeface,
885792c80f5a7b66e75d42664ccb298f31962c6654chalcanary                             uint16_t glyphID,
8869859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org                             SkPDFDict* relatedFontDescriptor) {
8879859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    SkAdvancedTypefaceMetrics::FontType type =
8880f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo        info ? info->fType : SkAdvancedTypefaceMetrics::kOther_Font;
8899859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
890465706820d0d373f76ab4831c286115ee0d86b7arobertphillips    if (info &&
891465706820d0d373f76ab4831c286115ee0d86b7arobertphillips            (info->fFlags & SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag)) {
892465706820d0d373f76ab4831c286115ee0d86b7arobertphillips        NOT_IMPLEMENTED(true, true);
8932e3f9d8a9309686eeb4c76ccfde5800da87a68b3halcanary        return new SkPDFType3Font(info, typeface, glyphID);
8946504cfdfc035f0a2cb854be9df352159873b9d62vandebo@chromium.org    }
8959859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    if (type == SkAdvancedTypefaceMetrics::kType1CID_Font ||
8969859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        type == SkAdvancedTypefaceMetrics::kTrueType_Font) {
8979859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        SkASSERT(relatedFontDescriptor == NULL);
8982e3f9d8a9309686eeb4c76ccfde5800da87a68b3halcanary        return new SkPDFType0Font(info, typeface);
8999859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    }
9009859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    if (type == SkAdvancedTypefaceMetrics::kType1_Font) {
9012e3f9d8a9309686eeb4c76ccfde5800da87a68b3halcanary        return new SkPDFType1Font(info, typeface, glyphID,
9029859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org                                  relatedFontDescriptor);
9039859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    }
9049859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
9059859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    SkASSERT(type == SkAdvancedTypefaceMetrics::kCFF_Font ||
9060f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo             type == SkAdvancedTypefaceMetrics::kOther_Font);
9079859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
9082e3f9d8a9309686eeb4c76ccfde5800da87a68b3halcanary    return new SkPDFType3Font(info, typeface, glyphID);
9099859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
9109859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
911fb747e2c745896dd94425ff690483ae3838e88fehalcanaryconst SkAdvancedTypefaceMetrics* SkPDFFont::fontInfo() {
9129859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    return fFontInfo.get();
9139859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
9149859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
915fb747e2c745896dd94425ff690483ae3838e88fehalcanaryvoid SkPDFFont::setFontInfo(const SkAdvancedTypefaceMetrics* info) {
91637ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org    if (info == NULL || info == fFontInfo.get()) {
91737ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org        return;
91837ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org    }
919d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org    fFontInfo.reset(info);
920d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org    SkSafeRef(info);
92137ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org}
92237ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org
9239859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orguint16_t SkPDFFont::firstGlyphID() const {
9249859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    return fFirstGlyphID;
9259859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
9269859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
9279859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orguint16_t SkPDFFont::lastGlyphID() const {
9289859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    return fLastGlyphID;
9299859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
9309859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
9319859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgvoid SkPDFFont::setLastGlyphID(uint16_t glyphID) {
9329859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    fLastGlyphID = glyphID;
9339859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
9349859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
9359859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgSkPDFDict* SkPDFFont::getFontDescriptor() {
9369859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    return fDescriptor.get();
9379859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
9389859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
9399859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgvoid SkPDFFont::setFontDescriptor(SkPDFDict* descriptor) {
940d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org    fDescriptor.reset(descriptor);
941d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org    SkSafeRef(descriptor);
9429859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
9439859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
9449859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgbool SkPDFFont::addCommonFontDescriptorEntries(int16_t defaultWidth) {
9459859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    if (fDescriptor.get() == NULL) {
9469859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        return false;
9479859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    }
9489859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
9499859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    const uint16_t emSize = fFontInfo->fEmSize;
9509859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
9519859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    fDescriptor->insertName("FontName", fFontInfo->fFontName);
952dcf9c19d38d366a9f27ad0d8b5bda327c5edb164vandebo@chromium.org    fDescriptor->insertInt("Flags", fFontInfo->fStyle | kPdfSymbolic);
9539859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    fDescriptor->insertScalar("Ascent",
9549859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org            scaleFromFontUnits(fFontInfo->fAscent, emSize));
9559859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    fDescriptor->insertScalar("Descent",
9569859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org            scaleFromFontUnits(fFontInfo->fDescent, emSize));
9579859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    fDescriptor->insertScalar("StemV",
9589859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org            scaleFromFontUnits(fFontInfo->fStemV, emSize));
959fb747e2c745896dd94425ff690483ae3838e88fehalcanary
9609859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    fDescriptor->insertScalar("CapHeight",
9619859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org            scaleFromFontUnits(fFontInfo->fCapHeight, emSize));
9629859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    fDescriptor->insertInt("ItalicAngle", fFontInfo->fItalicAngle);
963bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    fDescriptor->insertObject(
964bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary            "FontBBox", makeFontBBox(fFontInfo->fBBox, fFontInfo->fEmSize));
9659859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
9669859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    if (defaultWidth > 0) {
9679859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        fDescriptor->insertScalar("MissingWidth",
9689859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org                scaleFromFontUnits(defaultWidth, emSize));
9699859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    }
9709859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    return true;
9719859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
9729859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
97322edc8310cd57ab02155bfa6b2ddaf830556bcafbungemanvoid SkPDFFont::adjustGlyphRangeForSingleByteEncoding(uint16_t glyphID) {
9749859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    // Single byte glyph encoding supports a max of 255 glyphs.
9759859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    fFirstGlyphID = glyphID - (glyphID - 1) % 255;
9769859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    if (fLastGlyphID > fFirstGlyphID + 255 - 1) {
9779859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        fLastGlyphID = fFirstGlyphID + 255 - 1;
9789859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    }
9799859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
9809859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
9819859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgvoid SkPDFFont::populateToUnicodeTable(const SkPDFGlyphSet* subset) {
9829859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    if (fFontInfo == NULL || fFontInfo->fGlyphToUnicode.begin() == NULL) {
9839db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org        return;
9849db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org    }
985bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    this->insertObjRef("ToUnicode",
986bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary                       generate_tounicode_cmap(fFontInfo->fGlyphToUnicode,
987bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary                                               subset,
988bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary                                               multiByteGlyphs(),
989bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary                                               firstGlyphID(),
990bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary                                               lastGlyphID()));
9919859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
9929859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
9939859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org///////////////////////////////////////////////////////////////////////////////
9949859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org// class SkPDFType0Font
9959859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org///////////////////////////////////////////////////////////////////////////////
9969db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org
9972e3f9d8a9309686eeb4c76ccfde5800da87a68b3halcanarySkPDFType0Font::SkPDFType0Font(const SkAdvancedTypefaceMetrics* info,
9989859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org                               SkTypeface* typeface)
9992e3f9d8a9309686eeb4c76ccfde5800da87a68b3halcanary    : SkPDFFont(info, typeface, NULL) {
10009859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    SkDEBUGCODE(fPopulated = false);
10010f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    if (!canSubset()) {
10020f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo        populate(NULL);
10030f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    }
10042a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org}
10052a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
10069859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgSkPDFType0Font::~SkPDFType0Font() {}
10072a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
10089859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgSkPDFFont* SkPDFType0Font::getFontSubset(const SkPDFGlyphSet* subset) {
10090f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    if (!canSubset()) {
10100f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo        return NULL;
10110f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    }
1012792c80f5a7b66e75d42664ccb298f31962c6654chalcanary    SkPDFType0Font* newSubset =
10132e3f9d8a9309686eeb4c76ccfde5800da87a68b3halcanary            new SkPDFType0Font(fontInfo(), typeface());
10149859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    newSubset->populate(subset);
10159859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    return newSubset;
10169859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
10179859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
10189859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org#ifdef SK_DEBUG
101937c46cad21632cfc1411b08d73af37a1fffe2944halcanaryvoid SkPDFType0Font::emitObject(SkWStream* stream,
102037c46cad21632cfc1411b08d73af37a1fffe2944halcanary                                const SkPDFObjNumMap& objNumMap,
102137c46cad21632cfc1411b08d73af37a1fffe2944halcanary                                const SkPDFSubstituteMap& substitutes) {
10229859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    SkASSERT(fPopulated);
102337c46cad21632cfc1411b08d73af37a1fffe2944halcanary    return INHERITED::emitObject(stream, objNumMap, substitutes);
10249859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
10259859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org#endif
10269859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
10279859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgbool SkPDFType0Font::populate(const SkPDFGlyphSet* subset) {
1028c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com    insertName("Subtype", "Type0");
10299859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    insertName("BaseFont", fontInfo()->fFontName);
1030c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com    insertName("Encoding", "Identity-H");
10312a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
1032d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org    SkAutoTUnref<SkPDFCIDFont> newCIDFont(
10332e3f9d8a9309686eeb4c76ccfde5800da87a68b3halcanary            new SkPDFCIDFont(fontInfo(), typeface(), subset));
1034d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org    SkAutoTUnref<SkPDFArray> descendantFonts(new SkPDFArray());
1035bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    descendantFonts->appendObjRef(newCIDFont.detach());
1036bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    this->insertObject("DescendantFonts", descendantFonts.detach());
10376504cfdfc035f0a2cb854be9df352159873b9d62vandebo@chromium.org
10389859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    populateToUnicodeTable(subset);
10399859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
10409859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    SkDEBUGCODE(fPopulated = true);
10419859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    return true;
10426504cfdfc035f0a2cb854be9df352159873b9d62vandebo@chromium.org}
10436504cfdfc035f0a2cb854be9df352159873b9d62vandebo@chromium.org
10449859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org///////////////////////////////////////////////////////////////////////////////
10459859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org// class SkPDFCIDFont
10469859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org///////////////////////////////////////////////////////////////////////////////
10479859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
10482e3f9d8a9309686eeb4c76ccfde5800da87a68b3halcanarySkPDFCIDFont::SkPDFCIDFont(const SkAdvancedTypefaceMetrics* info,
1049792c80f5a7b66e75d42664ccb298f31962c6654chalcanary                           SkTypeface* typeface,
1050792c80f5a7b66e75d42664ccb298f31962c6654chalcanary                           const SkPDFGlyphSet* subset)
10512e3f9d8a9309686eeb4c76ccfde5800da87a68b3halcanary    : SkPDFFont(info, typeface, NULL) {
10529859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    populate(subset);
10539859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
10549859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
10559859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgSkPDFCIDFont::~SkPDFCIDFont() {}
10569859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
10579859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgbool SkPDFCIDFont::addFontDescriptor(int16_t defaultWidth,
105837ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org                                     const SkTDArray<uint32_t>* subset) {
1059d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org    SkAutoTUnref<SkPDFDict> descriptor(new SkPDFDict("FontDescriptor"));
10609859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    setFontDescriptor(descriptor.get());
10610f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    if (!addCommonFontDescriptorEntries(defaultWidth)) {
1062bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary        this->insertObjRef("FontDescriptor", descriptor.detach());
10630f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo        return false;
10640f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    }
10650f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    if (!canEmbed()) {
1066bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary        this->insertObjRef("FontDescriptor", descriptor.detach());
10670f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo        return true;
10680f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    }
10699859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
10709859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    switch (getType()) {
10719859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        case SkAdvancedTypefaceMetrics::kTrueType_Font: {
10720f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo            SkAutoTUnref<SkPDFStream> fontStream;
10730f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo            size_t fontSize = 0;
10740f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo            if (canSubset()) {
10750f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo                SkPDFStream* rawStream = NULL;
10760f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo                fontSize = get_subset_font_stream(fontInfo()->fFontName.c_str(),
10770f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo                                                  typeface(),
10780f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo                                                  *subset,
10790f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo                                                  &rawStream);
10800f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo                fontStream.reset(rawStream);
10810f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo            } else {
10820f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo                int ttcIndex;
1083a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo                SkAutoTDelete<SkStream> fontData(
10840f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo                        typeface()->openStream(&ttcIndex));
10850f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo                fontStream.reset(new SkPDFStream(fontData.get()));
10860f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo                fontSize = fontData->getLength();
10870f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo            }
10881f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org            SkASSERT(fontSize);
10890f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo            SkASSERT(fontStream.get());
10909859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
10911f1658985586b30c913dbc935f17ce1aabcdf7b5vandebo@chromium.org            fontStream->insertInt("Length1", fontSize);
1092bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary            descriptor->insertObjRef("FontFile2", fontStream.detach());
10939859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org            break;
10949859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        }
10959859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        case SkAdvancedTypefaceMetrics::kCFF_Font:
10969859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        case SkAdvancedTypefaceMetrics::kType1CID_Font: {
1097fed86bdb8b9f037439bbfa7cdbd53a581dbc5985reed@google.com            int ttcIndex;
1098a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo            SkAutoTDelete<SkStream> fontData(typeface()->openStream(&ttcIndex));
1099d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org            SkAutoTUnref<SkPDFStream> fontStream(
1100d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org                new SkPDFStream(fontData.get()));
11019859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
11029859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org            if (getType() == SkAdvancedTypefaceMetrics::kCFF_Font) {
11039859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org                fontStream->insertName("Subtype", "Type1C");
11049859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org            } else {
11059859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org                fontStream->insertName("Subtype", "CIDFontType0c");
11069859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org            }
1107bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary            descriptor->insertObjRef("FontFile3", fontStream.detach());
11089859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org            break;
11099859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        }
11109859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        default:
11119859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org            SkASSERT(false);
11126744d498fcbbbcf503ec80c4d43dd8f118a88597vandebo@chromium.org    }
1113bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    this->insertObjRef("FontDescriptor", descriptor.detach());
11140f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    return true;
11152a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org}
11162a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
11179859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgbool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) {
111837ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org    // Generate new font metrics with advance info for true type fonts.
111937ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org    if (fontInfo()->fType == SkAdvancedTypefaceMetrics::kTrueType_Font) {
112037ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org        // Generate glyph id array.
112137ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org        SkTDArray<uint32_t> glyphIDs;
112237ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org        if (subset) {
11234da3bfc5b2a44a4904286683d772c584bfa09787commit-bot@chromium.org            // Always include glyph 0.
11244da3bfc5b2a44a4904286683d772c584bfa09787commit-bot@chromium.org            if (!subset->has(0)) {
11254da3bfc5b2a44a4904286683d772c584bfa09787commit-bot@chromium.org                glyphIDs.push(0);
11264da3bfc5b2a44a4904286683d772c584bfa09787commit-bot@chromium.org            }
112737ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org            subset->exportTo(&glyphIDs);
112837ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org        }
112937ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org
113039a9a5069b25aa8b9529118cfd0ece5f412fb56breed        SkTypeface::PerGlyphInfo info;
113139a9a5069b25aa8b9529118cfd0ece5f412fb56breed        info = SkTypeface::kGlyphNames_PerGlyphInfo;
113239a9a5069b25aa8b9529118cfd0ece5f412fb56breed        info = SkTBitOr<SkTypeface::PerGlyphInfo>(
113339a9a5069b25aa8b9529118cfd0ece5f412fb56breed                  info, SkTypeface::kHAdvance_PerGlyphInfo);
11344da3bfc5b2a44a4904286683d772c584bfa09787commit-bot@chromium.org        uint32_t* glyphs = (glyphIDs.count() == 0) ? NULL : glyphIDs.begin();
113537ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org        uint32_t glyphsCount = glyphs ? glyphIDs.count() : 0;
1136fb747e2c745896dd94425ff690483ae3838e88fehalcanary        SkAutoTUnref<const SkAdvancedTypefaceMetrics> fontMetrics(
1137fed86bdb8b9f037439bbfa7cdbd53a581dbc5985reed@google.com            typeface()->getAdvancedTypefaceMetrics(info, glyphs, glyphsCount));
113837ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org        setFontInfo(fontMetrics.get());
113937ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org        addFontDescriptor(0, &glyphIDs);
114037ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org    } else {
114137ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org        // Other CID fonts
114237ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org        addFontDescriptor(0, NULL);
114337ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org    }
114437ad8fb72ff1b3faac93b01ead2c79e1a06fc172vandebo@chromium.org
11459859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    insertName("BaseFont", fontInfo()->fFontName);
1146f7c157610ff85f7323f5e213b62478dcc66edbecvandebo@chromium.org
11479859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    if (getType() == SkAdvancedTypefaceMetrics::kType1CID_Font) {
1148c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com        insertName("Subtype", "CIDFontType0");
11499859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    } else if (getType() == SkAdvancedTypefaceMetrics::kTrueType_Font) {
1150c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com        insertName("Subtype", "CIDFontType2");
1151c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com        insertName("CIDToGIDMap", "Identity");
1152c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org    } else {
11532a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        SkASSERT(false);
1154c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org    }
11552a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
1156d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org    SkAutoTUnref<SkPDFDict> sysInfo(new SkPDFDict);
1157bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    sysInfo->insertString("Registry", "Adobe");
1158bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    sysInfo->insertString("Ordering", "Identity");
1159c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com    sysInfo->insertInt("Supplement", 0);
1160bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    this->insertObject("CIDSystemInfo", sysInfo.detach());
11612a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
11629859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    if (fontInfo()->fGlyphWidths.get()) {
1163c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org        int16_t defaultWidth = 0;
1164d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org        SkAutoTUnref<SkPDFArray> widths(
11659859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org            composeAdvanceData(fontInfo()->fGlyphWidths.get(),
11669859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org                               fontInfo()->fEmSize, &appendWidth,
1167d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org                               &defaultWidth));
11682a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        if (widths->size())
1169bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary            this->insertObject("W", widths.detach());
11702a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        if (defaultWidth != 0) {
1171bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary            this->insertScalar(
1172bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary                    "DW",
1173bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary                    scaleFromFontUnits(defaultWidth, fontInfo()->fEmSize));
11742a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        }
11752a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    }
11769859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    if (fontInfo()->fVerticalMetrics.get()) {
1177c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org        struct SkAdvancedTypefaceMetrics::VerticalMetric defaultAdvance;
11782a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        defaultAdvance.fVerticalAdvance = 0;
11792a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        defaultAdvance.fOriginXDisp = 0;
11802a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        defaultAdvance.fOriginYDisp = 0;
1181d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org        SkAutoTUnref<SkPDFArray> advances(
11829859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org            composeAdvanceData(fontInfo()->fVerticalMetrics.get(),
11839859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org                               fontInfo()->fEmSize, &appendVerticalAdvance,
1184d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org                               &defaultAdvance));
11852a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        if (advances->size())
1186bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary            this->insertObject("W2", advances.detach());
11872a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        if (defaultAdvance.fVerticalAdvance ||
11882a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                defaultAdvance.fOriginXDisp ||
11892a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                defaultAdvance.fOriginYDisp) {
1190bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary            this->insertObject("DW2",
1191bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary                               appendVerticalAdvance(defaultAdvance,
1192bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary                                                     fontInfo()->fEmSize,
1193bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary                                                     new SkPDFArray));
11942a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        }
11952a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    }
11969859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
11979859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    return true;
11982a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org}
11992a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
12009859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org///////////////////////////////////////////////////////////////////////////////
12019859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org// class SkPDFType1Font
12029859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org///////////////////////////////////////////////////////////////////////////////
12039859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
12042e3f9d8a9309686eeb4c76ccfde5800da87a68b3halcanarySkPDFType1Font::SkPDFType1Font(const SkAdvancedTypefaceMetrics* info,
12059859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org                               SkTypeface* typeface,
12069859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org                               uint16_t glyphID,
12079859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org                               SkPDFDict* relatedFontDescriptor)
12082e3f9d8a9309686eeb4c76ccfde5800da87a68b3halcanary    : SkPDFFont(info, typeface, relatedFontDescriptor) {
12099859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    populate(glyphID);
12109859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
12119859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
12129859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgSkPDFType1Font::~SkPDFType1Font() {}
12139859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
12149859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgbool SkPDFType1Font::addFontDescriptor(int16_t defaultWidth) {
1215bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    if (SkPDFDict* descriptor = getFontDescriptor()) {
1216bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary        this->insertObjRef("FontDescriptor", SkRef(descriptor));
12179859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        return true;
12189859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    }
12199859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
1220d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org    SkAutoTUnref<SkPDFDict> descriptor(new SkPDFDict("FontDescriptor"));
12219859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    setFontDescriptor(descriptor.get());
12229859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
1223fed86bdb8b9f037439bbfa7cdbd53a581dbc5985reed@google.com    int ttcIndex;
12249859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    size_t header SK_INIT_TO_AVOID_WARNING;
12259859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    size_t data SK_INIT_TO_AVOID_WARNING;
12269859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    size_t trailer SK_INIT_TO_AVOID_WARNING;
1227a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo    SkAutoTDelete<SkStream> rawFontData(typeface()->openStream(&ttcIndex));
12287ba2828aa6687f9d12f4fa0b0a2ef9a9dc2efa68djsollen    SkAutoTUnref<SkData> fontData(handle_type1_stream(rawFontData.get(), &header,
12297ba2828aa6687f9d12f4fa0b0a2ef9a9dc2efa68djsollen                                                      &data, &trailer));
12307ba2828aa6687f9d12f4fa0b0a2ef9a9dc2efa68djsollen    if (fontData.get() == NULL) {
12319859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        return false;
12329859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    }
12330f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    if (canEmbed()) {
12347ba2828aa6687f9d12f4fa0b0a2ef9a9dc2efa68djsollen        SkAutoTUnref<SkPDFStream> fontStream(new SkPDFStream(fontData.get()));
12350f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo        fontStream->insertInt("Length1", header);
12360f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo        fontStream->insertInt("Length2", data);
12370f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo        fontStream->insertInt("Length3", trailer);
1238bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary        descriptor->insertObjRef("FontFile", fontStream.detach());
12390f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    }
12409859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
1241bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    this->insertObjRef("FontDescriptor", descriptor.detach());
12429859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
12439859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    return addCommonFontDescriptorEntries(defaultWidth);
12449859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
12459859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
12469859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgbool SkPDFType1Font::populate(int16_t glyphID) {
12479859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    SkASSERT(!fontInfo()->fVerticalMetrics.get());
12489859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    SkASSERT(fontInfo()->fGlyphWidths.get());
12492a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
1250f77e27deb95ff6fd6e6e30dcd3f6bf1862c394e1vandebo@chromium.org    adjustGlyphRangeForSingleByteEncoding(glyphID);
1251f77e27deb95ff6fd6e6e30dcd3f6bf1862c394e1vandebo@chromium.org
1252c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org    int16_t defaultWidth = 0;
1253c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org    const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry = NULL;
1254c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org    const SkAdvancedTypefaceMetrics::WidthRange* widthEntry;
12559859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    for (widthEntry = fontInfo()->fGlyphWidths.get();
12562a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org            widthEntry != NULL;
12572a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org            widthEntry = widthEntry->fNext.get()) {
12582a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        switch (widthEntry->fType) {
1259c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org            case SkAdvancedTypefaceMetrics::WidthRange::kDefault:
12602a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                defaultWidth = widthEntry->fAdvance[0];
12612a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                break;
1262c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org            case SkAdvancedTypefaceMetrics::WidthRange::kRun:
12632a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                SkASSERT(false);
12642a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                break;
1265c48b2b330f8bf0e01381e27ca36f48ef5c7d8d5fvandebo@chromium.org            case SkAdvancedTypefaceMetrics::WidthRange::kRange:
12662a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                SkASSERT(widthRangeEntry == NULL);
12672a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                widthRangeEntry = widthEntry;
12682a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org                break;
12692a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        }
12702a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    }
12712a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
1272769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    if (!addFontDescriptor(defaultWidth)) {
12732a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org        return false;
1274769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org    }
12752a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
1276c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com    insertName("Subtype", "Type1");
12779859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    insertName("BaseFont", fontInfo()->fFontName);
127828be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
12799db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org    addWidthInfoFromRange(defaultWidth, widthRangeEntry);
12802a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
12812a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
1282d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org    SkAutoTUnref<SkPDFArray> encDiffs(new SkPDFArray);
12839859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    encDiffs->reserve(lastGlyphID() - firstGlyphID() + 2);
1284c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com    encDiffs->appendInt(1);
12859859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    for (int gID = firstGlyphID(); gID <= lastGlyphID(); gID++) {
12869859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        encDiffs->appendName(fontInfo()->fGlyphNames->get()[gID].c_str());
12872a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    }
12882a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
1289bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    SkAutoTUnref<SkPDFDict> encoding(new SkPDFDict("Encoding"));
1290bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    encoding->insertObject("Differences", encDiffs.detach());
1291bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    this->insertObject("Encoding", encoding.detach());
12922a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    return true;
129328be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org}
129428be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
12959859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgvoid SkPDFType1Font::addWidthInfoFromRange(
12969859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        int16_t defaultWidth,
12979859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry) {
1298d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org    SkAutoTUnref<SkPDFArray> widthArray(new SkPDFArray());
12999859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    int firstChar = 0;
13009859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    if (widthRangeEntry) {
13019859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        const uint16_t emSize = fontInfo()->fEmSize;
13029859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        int startIndex = firstGlyphID() - widthRangeEntry->fStartId;
13039859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        int endIndex = startIndex + lastGlyphID() - firstGlyphID() + 1;
13049859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        if (startIndex < 0)
13059859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org            startIndex = 0;
13069859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        if (endIndex > widthRangeEntry->fAdvance.count())
13079859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org            endIndex = widthRangeEntry->fAdvance.count();
13089859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        if (widthRangeEntry->fStartId == 0) {
13099859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org            appendWidth(widthRangeEntry->fAdvance[0], emSize, widthArray.get());
13109859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        } else {
13119859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org            firstChar = startIndex + widthRangeEntry->fStartId;
13129859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        }
1313769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org        for (int i = startIndex; i < endIndex; i++) {
13149859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org            appendWidth(widthRangeEntry->fAdvance[i], emSize, widthArray.get());
1315769fa6a013baca6d7404e2bf096a34a7e3635fa5ctguil@chromium.org        }
13169859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    } else {
13179859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        appendWidth(defaultWidth, 1000, widthArray.get());
13189859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    }
1319bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    this->insertInt("FirstChar", firstChar);
1320bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    this->insertInt("LastChar", firstChar + widthArray->size() - 1);
1321bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    this->insertObject("Widths", widthArray.detach());
13229859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
13239859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
13249859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org///////////////////////////////////////////////////////////////////////////////
13259859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org// class SkPDFType3Font
13269859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org///////////////////////////////////////////////////////////////////////////////
13279859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
13282e3f9d8a9309686eeb4c76ccfde5800da87a68b3halcanarySkPDFType3Font::SkPDFType3Font(const SkAdvancedTypefaceMetrics* info,
13299859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org                               SkTypeface* typeface,
1330e2e8113baa69b5d1a0bae9652a095c1eb44b3a53sugoi@google.com                               uint16_t glyphID)
13312e3f9d8a9309686eeb4c76ccfde5800da87a68b3halcanary    : SkPDFFont(info, typeface, NULL) {
13329859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    populate(glyphID);
13339859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org}
13349859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
13359859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgSkPDFType3Font::~SkPDFType3Font() {}
13369859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
133722edc8310cd57ab02155bfa6b2ddaf830556bcafbungemanbool SkPDFType3Font::populate(uint16_t glyphID) {
1338f77e27deb95ff6fd6e6e30dcd3f6bf1862c394e1vandebo@chromium.org    SkPaint paint;
13399859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    paint.setTypeface(typeface());
1340f77e27deb95ff6fd6e6e30dcd3f6bf1862c394e1vandebo@chromium.org    paint.setTextSize(1000);
1341532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com    SkAutoGlyphCache autoCache(paint, NULL, NULL);
1342f77e27deb95ff6fd6e6e30dcd3f6bf1862c394e1vandebo@chromium.org    SkGlyphCache* cache = autoCache.getCache();
1343f77e27deb95ff6fd6e6e30dcd3f6bf1862c394e1vandebo@chromium.org    // If fLastGlyphID isn't set (because there is not fFontInfo), look it up.
13449859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    if (lastGlyphID() == 0) {
13459859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org        setLastGlyphID(cache->getGlyphCount() - 1);
1346f77e27deb95ff6fd6e6e30dcd3f6bf1862c394e1vandebo@chromium.org    }
1347f77e27deb95ff6fd6e6e30dcd3f6bf1862c394e1vandebo@chromium.org
1348f77e27deb95ff6fd6e6e30dcd3f6bf1862c394e1vandebo@chromium.org    adjustGlyphRangeForSingleByteEncoding(glyphID);
1349f77e27deb95ff6fd6e6e30dcd3f6bf1862c394e1vandebo@chromium.org
1350c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com    insertName("Subtype", "Type3");
13519db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org    // Flip about the x-axis and scale by 1/1000.
13529db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org    SkMatrix fontMatrix;
13539db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org    fontMatrix.setScale(SkScalarInvert(1000), -SkScalarInvert(1000));
1354bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    this->insertObject("FontMatrix", SkPDFUtils::MatrixToArray(fontMatrix));
13559db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org
1356d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org    SkAutoTUnref<SkPDFDict> charProcs(new SkPDFDict);
1357d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org    SkAutoTUnref<SkPDFDict> encoding(new SkPDFDict("Encoding"));
13589db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org
1359d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org    SkAutoTUnref<SkPDFArray> encDiffs(new SkPDFArray);
13609859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    encDiffs->reserve(lastGlyphID() - firstGlyphID() + 2);
1361c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com    encDiffs->appendInt(1);
13629db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org
1363d96d17b9c113ac694138224249ff2ce643e961ddvandebo@chromium.org    SkAutoTUnref<SkPDFArray> widthArray(new SkPDFArray());
13649db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org
13659db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org    SkIRect bbox = SkIRect::MakeEmpty();
13669859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    for (int gID = firstGlyphID(); gID <= lastGlyphID(); gID++) {
13679db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org        SkString characterName;
13689db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org        characterName.printf("gid%d", gID);
1369c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com        encDiffs->appendName(characterName.c_str());
13709db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org
1371ce11b26e828cef680928a68ac3fc6df5e81263c4reed@google.com        const SkGlyph& glyph = cache->getGlyphIDMetrics(gID);
1372c789cf1c6f3947283aeb34acb5a22e6204f8f6f5reed@google.com        widthArray->appendScalar(SkFixedToScalar(glyph.fAdvanceX));
13739db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org        SkIRect glyphBBox = SkIRect::MakeXYWH(glyph.fLeft, glyph.fTop,
13749db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org                                              glyph.fWidth, glyph.fHeight);
13759db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org        bbox.join(glyphBBox);
13769db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org
1377cae5fba82e687d674b076b10cdc8aba46e1ac3b3vandebo@chromium.org        SkDynamicMemoryWStream content;
13789db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org        setGlyphWidthAndBoundingBox(SkFixedToScalar(glyph.fAdvanceX), glyphBBox,
13799db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org                                    &content);
13809db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org        const SkPath* path = cache->findPath(glyph);
13819db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org        if (path) {
1382683001ce0de70c859ea5e5353245b18cadbefc45vandebo@chromium.org            SkPDFUtils::EmitPath(*path, paint.getStyle(), &content);
13839db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org            SkPDFUtils::PaintPath(paint.getStyle(), path->getFillType(),
13849db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org                                  &content);
13859db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org        }
1386a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo        SkAutoTDelete<SkMemoryStream> glyphStream(new SkMemoryStream());
13878a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com        glyphStream->setData(content.copyToData())->unref();
1388cae5fba82e687d674b076b10cdc8aba46e1ac3b3vandebo@chromium.org
1389130444fdaf737c5931a934018ab50b0c91a3499ehalcanary        charProcs->insertObjRef(characterName,
1390130444fdaf737c5931a934018ab50b0c91a3499ehalcanary                                new SkPDFStream(glyphStream.get()));
13919db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org    }
13929db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org
1393bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    encoding->insertObject("Differences", encDiffs.detach());
1394bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary
1395bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    this->insertObject("CharProcs", charProcs.detach());
1396bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    this->insertObject("Encoding", encoding.detach());
1397bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary
1398bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    this->insertObject("FontBBox", makeFontBBox(bbox, 1000));
1399bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    this->insertInt("FirstChar", 1);
1400bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    this->insertInt("LastChar", lastGlyphID() - firstGlyphID() + 1);
1401bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    this->insertObject("Widths", widthArray.detach());
1402bf51cfdbd9e41a2e9e2d16dc8d97ac74d9dd84dahalcanary    this->insertName("CIDToGIDMap", "Identity");
14039db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org
14049859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    populateToUnicodeTable(NULL);
14052a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org    return true;
14062a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org}
1407fb62b3d423fa34c672df42f47017dbef087d19e9halcanary
1408fb62b3d423fa34c672df42f47017dbef087d19e9halcanarySkPDFFont::Match SkPDFFont::IsMatch(SkPDFFont* existingFont,
1409fb62b3d423fa34c672df42f47017dbef087d19e9halcanary                                    uint32_t existingFontID,
1410fb62b3d423fa34c672df42f47017dbef087d19e9halcanary                                    uint16_t existingGlyphID,
1411fb62b3d423fa34c672df42f47017dbef087d19e9halcanary                                    uint32_t searchFontID,
1412fb62b3d423fa34c672df42f47017dbef087d19e9halcanary                                    uint16_t searchGlyphID) {
1413fb62b3d423fa34c672df42f47017dbef087d19e9halcanary    if (existingFontID != searchFontID) {
1414fb62b3d423fa34c672df42f47017dbef087d19e9halcanary        return SkPDFFont::kNot_Match;
1415fb62b3d423fa34c672df42f47017dbef087d19e9halcanary    }
1416fb62b3d423fa34c672df42f47017dbef087d19e9halcanary    if (existingGlyphID == 0 || searchGlyphID == 0) {
1417fb62b3d423fa34c672df42f47017dbef087d19e9halcanary        return SkPDFFont::kExact_Match;
1418fb62b3d423fa34c672df42f47017dbef087d19e9halcanary    }
1419fb62b3d423fa34c672df42f47017dbef087d19e9halcanary    if (existingFont != NULL) {
1420fb62b3d423fa34c672df42f47017dbef087d19e9halcanary        return (existingFont->fFirstGlyphID <= searchGlyphID &&
1421fb62b3d423fa34c672df42f47017dbef087d19e9halcanary                searchGlyphID <= existingFont->fLastGlyphID)
1422fb62b3d423fa34c672df42f47017dbef087d19e9halcanary                       ? SkPDFFont::kExact_Match
1423fb62b3d423fa34c672df42f47017dbef087d19e9halcanary                       : SkPDFFont::kRelated_Match;
1424fb62b3d423fa34c672df42f47017dbef087d19e9halcanary    }
1425fb62b3d423fa34c672df42f47017dbef087d19e9halcanary    return (existingGlyphID == searchGlyphID) ? SkPDFFont::kExact_Match
1426fb62b3d423fa34c672df42f47017dbef087d19e9halcanary                                              : SkPDFFont::kRelated_Match;
1427fb62b3d423fa34c672df42f47017dbef087d19e9halcanary}
1428