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