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