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