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