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 static SkData* handle_type1_stream(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 static const int kPFBSectionHeaderLength = 6; 203 const size_t length = *headerLen + *dataLen + *trailerLen; 204 SkASSERT(length > 0); 205 SkASSERT(length + (2 * kPFBSectionHeaderLength) <= srcLen); 206 207 SkData* data = SkData::NewUninitialized(length); 208 209 const uint8_t* const srcHeader = src + kPFBSectionHeaderLength; 210 // There is a six-byte section header before header and data 211 // (but not trailer) that we're not going to copy. 212 const uint8_t* const srcData = srcHeader + *headerLen + kPFBSectionHeaderLength; 213 const uint8_t* const srcTrailer = srcData + *headerLen; 214 215 uint8_t* const resultHeader = (uint8_t*)data->writable_data(); 216 uint8_t* const resultData = resultHeader + *headerLen; 217 uint8_t* const resultTrailer = resultData + *dataLen; 218 219 SkASSERT(resultTrailer + *trailerLen == resultHeader + length); 220 221 memcpy(resultHeader, srcHeader, *headerLen); 222 memcpy(resultData, srcData, *dataLen); 223 memcpy(resultTrailer, srcTrailer, *trailerLen); 224 225 return data; 226 } 227 228 // A PFA has to be converted for PDF. 229 size_t hexDataLen; 230 if (parsePFA((const char*)src, srcLen, headerLen, &hexDataLen, dataLen, 231 trailerLen)) { 232 const size_t length = *headerLen + *dataLen + *trailerLen; 233 SkASSERT(length > 0); 234 SkAutoTMalloc<uint8_t> buffer(length); 235 236 memcpy(buffer.get(), src, *headerLen); 237 uint8_t* const resultData = &(buffer[*headerLen]); 238 239 const uint8_t* hexData = src + *headerLen; 240 const uint8_t* trailer = hexData + hexDataLen; 241 size_t outputOffset = 0; 242 uint8_t dataByte = 0; // To hush compiler. 243 bool highNibble = true; 244 for (; hexData < trailer; hexData++) { 245 int8_t curNibble = hexToBin(*hexData); 246 if (curNibble < 0) { 247 continue; 248 } 249 if (highNibble) { 250 dataByte = curNibble << 4; 251 highNibble = false; 252 } else { 253 dataByte |= curNibble; 254 highNibble = true; 255 resultData[outputOffset++] = dataByte; 256 } 257 } 258 if (!highNibble) { 259 resultData[outputOffset++] = dataByte; 260 } 261 SkASSERT(outputOffset == *dataLen); 262 263 uint8_t* const resultTrailer = &(buffer[*headerLen + outputOffset]); 264 memcpy(resultTrailer, src + *headerLen + hexDataLen, *trailerLen); 265 266 return SkData::NewFromMalloc(buffer.detach(), length); 267 } 268 return NULL; 269 } 270 271 // scale from em-units to base-1000, returning as a SkScalar 272 SkScalar scaleFromFontUnits(int16_t val, uint16_t emSize) { 273 SkScalar scaled = SkIntToScalar(val); 274 if (emSize == 1000) { 275 return scaled; 276 } else { 277 return SkScalarMulDiv(scaled, 1000, emSize); 278 } 279 } 280 281 void setGlyphWidthAndBoundingBox(SkScalar width, SkIRect box, 282 SkWStream* content) { 283 // Specify width and bounding box for the glyph. 284 SkPDFScalar::Append(width, content); 285 content->writeText(" 0 "); 286 content->writeDecAsText(box.fLeft); 287 content->writeText(" "); 288 content->writeDecAsText(box.fTop); 289 content->writeText(" "); 290 content->writeDecAsText(box.fRight); 291 content->writeText(" "); 292 content->writeDecAsText(box.fBottom); 293 content->writeText(" d1\n"); 294 } 295 296 SkPDFArray* makeFontBBox(SkIRect glyphBBox, uint16_t emSize) { 297 SkPDFArray* bbox = new SkPDFArray; 298 bbox->reserve(4); 299 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fLeft, emSize)); 300 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fBottom, emSize)); 301 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fRight, emSize)); 302 bbox->appendScalar(scaleFromFontUnits(glyphBBox.fTop, emSize)); 303 return bbox; 304 } 305 306 SkPDFArray* appendWidth(const int16_t& width, uint16_t emSize, 307 SkPDFArray* array) { 308 array->appendScalar(scaleFromFontUnits(width, emSize)); 309 return array; 310 } 311 312 SkPDFArray* appendVerticalAdvance( 313 const SkAdvancedTypefaceMetrics::VerticalMetric& advance, 314 uint16_t emSize, SkPDFArray* array) { 315 appendWidth(advance.fVerticalAdvance, emSize, array); 316 appendWidth(advance.fOriginXDisp, emSize, array); 317 appendWidth(advance.fOriginYDisp, emSize, array); 318 return array; 319 } 320 321 template <typename Data> 322 SkPDFArray* composeAdvanceData( 323 SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* advanceInfo, 324 uint16_t emSize, 325 SkPDFArray* (*appendAdvance)(const Data& advance, uint16_t emSize, 326 SkPDFArray* array), 327 Data* defaultAdvance) { 328 SkPDFArray* result = new SkPDFArray(); 329 for (; advanceInfo != NULL; advanceInfo = advanceInfo->fNext.get()) { 330 switch (advanceInfo->fType) { 331 case SkAdvancedTypefaceMetrics::WidthRange::kDefault: { 332 SkASSERT(advanceInfo->fAdvance.count() == 1); 333 *defaultAdvance = advanceInfo->fAdvance[0]; 334 break; 335 } 336 case SkAdvancedTypefaceMetrics::WidthRange::kRange: { 337 SkAutoTUnref<SkPDFArray> advanceArray(new SkPDFArray()); 338 for (int j = 0; j < advanceInfo->fAdvance.count(); j++) 339 appendAdvance(advanceInfo->fAdvance[j], emSize, 340 advanceArray.get()); 341 result->appendInt(advanceInfo->fStartId); 342 result->append(advanceArray.get()); 343 break; 344 } 345 case SkAdvancedTypefaceMetrics::WidthRange::kRun: { 346 SkASSERT(advanceInfo->fAdvance.count() == 1); 347 result->appendInt(advanceInfo->fStartId); 348 result->appendInt(advanceInfo->fEndId); 349 appendAdvance(advanceInfo->fAdvance[0], emSize, result); 350 break; 351 } 352 } 353 } 354 return result; 355 } 356 357 } // namespace 358 359 static void append_tounicode_header(SkDynamicMemoryWStream* cmap, 360 uint16_t firstGlyphID, 361 uint16_t lastGlyphID) { 362 // 12 dict begin: 12 is an Adobe-suggested value. Shall not change. 363 // It's there to prevent old version Adobe Readers from malfunctioning. 364 const char* kHeader = 365 "/CIDInit /ProcSet findresource begin\n" 366 "12 dict begin\n" 367 "begincmap\n"; 368 cmap->writeText(kHeader); 369 370 // The /CIDSystemInfo must be consistent to the one in 371 // SkPDFFont::populateCIDFont(). 372 // We can not pass over the system info object here because the format is 373 // different. This is not a reference object. 374 const char* kSysInfo = 375 "/CIDSystemInfo\n" 376 "<< /Registry (Adobe)\n" 377 "/Ordering (UCS)\n" 378 "/Supplement 0\n" 379 ">> def\n"; 380 cmap->writeText(kSysInfo); 381 382 // The CMapName must be consistent to /CIDSystemInfo above. 383 // /CMapType 2 means ToUnicode. 384 // Codespace range just tells the PDF processor the valid range. 385 const char* kTypeInfoHeader = 386 "/CMapName /Adobe-Identity-UCS def\n" 387 "/CMapType 2 def\n" 388 "1 begincodespacerange\n"; 389 cmap->writeText(kTypeInfoHeader); 390 391 // e.g. "<0000> <FFFF>\n" 392 SkString range; 393 range.appendf("<%04X> <%04X>\n", firstGlyphID, lastGlyphID); 394 cmap->writeText(range.c_str()); 395 396 const char* kTypeInfoFooter = "endcodespacerange\n"; 397 cmap->writeText(kTypeInfoFooter); 398 } 399 400 static void append_cmap_footer(SkDynamicMemoryWStream* cmap) { 401 const char* kFooter = 402 "endcmap\n" 403 "CMapName currentdict /CMap defineresource pop\n" 404 "end\n" 405 "end"; 406 cmap->writeText(kFooter); 407 } 408 409 struct BFChar { 410 uint16_t fGlyphId; 411 SkUnichar fUnicode; 412 }; 413 414 struct BFRange { 415 uint16_t fStart; 416 uint16_t fEnd; 417 SkUnichar fUnicode; 418 }; 419 420 static void append_bfchar_section(const SkTDArray<BFChar>& bfchar, 421 SkDynamicMemoryWStream* cmap) { 422 // PDF spec defines that every bf* list can have at most 100 entries. 423 for (int i = 0; i < bfchar.count(); i += 100) { 424 int count = bfchar.count() - i; 425 count = SkMin32(count, 100); 426 cmap->writeDecAsText(count); 427 cmap->writeText(" beginbfchar\n"); 428 for (int j = 0; j < count; ++j) { 429 cmap->writeText("<"); 430 cmap->writeHexAsText(bfchar[i + j].fGlyphId, 4); 431 cmap->writeText("> <"); 432 cmap->writeHexAsText(bfchar[i + j].fUnicode, 4); 433 cmap->writeText(">\n"); 434 } 435 cmap->writeText("endbfchar\n"); 436 } 437 } 438 439 static void append_bfrange_section(const SkTDArray<BFRange>& bfrange, 440 SkDynamicMemoryWStream* cmap) { 441 // PDF spec defines that every bf* list can have at most 100 entries. 442 for (int i = 0; i < bfrange.count(); i += 100) { 443 int count = bfrange.count() - i; 444 count = SkMin32(count, 100); 445 cmap->writeDecAsText(count); 446 cmap->writeText(" beginbfrange\n"); 447 for (int j = 0; j < count; ++j) { 448 cmap->writeText("<"); 449 cmap->writeHexAsText(bfrange[i + j].fStart, 4); 450 cmap->writeText("> <"); 451 cmap->writeHexAsText(bfrange[i + j].fEnd, 4); 452 cmap->writeText("> <"); 453 cmap->writeHexAsText(bfrange[i + j].fUnicode, 4); 454 cmap->writeText(">\n"); 455 } 456 cmap->writeText("endbfrange\n"); 457 } 458 } 459 460 // Generate <bfchar> and <bfrange> table according to PDF spec 1.4 and Adobe 461 // Technote 5014. 462 // The function is not static so we can test it in unit tests. 463 // 464 // Current implementation guarantees bfchar and bfrange entries do not overlap. 465 // 466 // Current implementation does not attempt aggresive optimizations against 467 // following case because the specification is not clear. 468 // 469 // 4 beginbfchar 1 beginbfchar 470 // <0003> <0013> <0020> <0014> 471 // <0005> <0015> to endbfchar 472 // <0007> <0017> 1 beginbfrange 473 // <0020> <0014> <0003> <0007> <0013> 474 // endbfchar endbfrange 475 // 476 // Adobe Technote 5014 said: "Code mappings (unlike codespace ranges) may 477 // overlap, but succeeding maps supersede preceding maps." 478 // 479 // In case of searching text in PDF, bfrange will have higher precedence so 480 // typing char id 0x0014 in search box will get glyph id 0x0004 first. However, 481 // the spec does not mention how will this kind of conflict being resolved. 482 // 483 // For the worst case (having 65536 continuous unicode and we use every other 484 // one of them), the possible savings by aggressive optimization is 416KB 485 // pre-compressed and does not provide enough motivation for implementation. 486 487 // FIXME: this should be in a header so that it is separately testable 488 // ( see caller in tests/ToUnicode.cpp ) 489 void append_cmap_sections(const SkTDArray<SkUnichar>& glyphToUnicode, 490 const SkPDFGlyphSet* subset, 491 SkDynamicMemoryWStream* cmap, 492 bool multiByteGlyphs, 493 uint16_t firstGlyphID, 494 uint16_t lastGlyphID); 495 496 void append_cmap_sections(const SkTDArray<SkUnichar>& glyphToUnicode, 497 const SkPDFGlyphSet* subset, 498 SkDynamicMemoryWStream* cmap, 499 bool multiByteGlyphs, 500 uint16_t firstGlyphID, 501 uint16_t lastGlyphID) { 502 if (glyphToUnicode.isEmpty()) { 503 return; 504 } 505 int glyphOffset = 0; 506 if (!multiByteGlyphs) { 507 glyphOffset = firstGlyphID - 1; 508 } 509 510 SkTDArray<BFChar> bfcharEntries; 511 SkTDArray<BFRange> bfrangeEntries; 512 513 BFRange currentRangeEntry = {0, 0, 0}; 514 bool rangeEmpty = true; 515 const int limit = 516 SkMin32(lastGlyphID + 1, glyphToUnicode.count()) - glyphOffset; 517 518 for (int i = firstGlyphID - glyphOffset; i < limit + 1; ++i) { 519 bool inSubset = i < limit && 520 (subset == NULL || subset->has(i + glyphOffset)); 521 if (!rangeEmpty) { 522 // PDF spec requires bfrange not changing the higher byte, 523 // e.g. <1035> <10FF> <2222> is ok, but 524 // <1035> <1100> <2222> is no good 525 bool inRange = 526 i == currentRangeEntry.fEnd + 1 && 527 i >> 8 == currentRangeEntry.fStart >> 8 && 528 i < limit && 529 glyphToUnicode[i + glyphOffset] == 530 currentRangeEntry.fUnicode + i - currentRangeEntry.fStart; 531 if (!inSubset || !inRange) { 532 if (currentRangeEntry.fEnd > currentRangeEntry.fStart) { 533 bfrangeEntries.push(currentRangeEntry); 534 } else { 535 BFChar* entry = bfcharEntries.append(); 536 entry->fGlyphId = currentRangeEntry.fStart; 537 entry->fUnicode = currentRangeEntry.fUnicode; 538 } 539 rangeEmpty = true; 540 } 541 } 542 if (inSubset) { 543 currentRangeEntry.fEnd = i; 544 if (rangeEmpty) { 545 currentRangeEntry.fStart = i; 546 currentRangeEntry.fUnicode = glyphToUnicode[i + glyphOffset]; 547 rangeEmpty = false; 548 } 549 } 550 } 551 552 // The spec requires all bfchar entries for a font must come before bfrange 553 // entries. 554 append_bfchar_section(bfcharEntries, cmap); 555 append_bfrange_section(bfrangeEntries, cmap); 556 } 557 558 static SkPDFStream* generate_tounicode_cmap( 559 const SkTDArray<SkUnichar>& glyphToUnicode, 560 const SkPDFGlyphSet* subset, 561 bool multiByteGlyphs, 562 uint16_t firstGlyphID, 563 uint16_t lastGlyphID) { 564 SkDynamicMemoryWStream cmap; 565 if (multiByteGlyphs) { 566 append_tounicode_header(&cmap, firstGlyphID, lastGlyphID); 567 } else { 568 append_tounicode_header(&cmap, 1, lastGlyphID - firstGlyphID + 1); 569 } 570 append_cmap_sections(glyphToUnicode, subset, &cmap, multiByteGlyphs, 571 firstGlyphID, lastGlyphID); 572 append_cmap_footer(&cmap); 573 SkAutoTUnref<SkData> cmapData(cmap.copyToData()); 574 return new SkPDFStream(cmapData.get()); 575 } 576 577 #if defined (SK_SFNTLY_SUBSETTER) 578 static void sk_delete_array(const void* ptr, size_t, void*) { 579 // Use C-style cast to cast away const and cast type simultaneously. 580 delete[] (unsigned char*)ptr; 581 } 582 #endif 583 584 static size_t get_subset_font_stream(const char* fontName, 585 const SkTypeface* typeface, 586 const SkTDArray<uint32_t>& subset, 587 SkPDFStream** fontStream) { 588 int ttcIndex; 589 SkAutoTUnref<SkStream> fontData(typeface->openStream(&ttcIndex)); 590 SkASSERT(fontData.get()); 591 592 size_t fontSize = fontData->getLength(); 593 594 #if defined (SK_SFNTLY_SUBSETTER) 595 // Read font into buffer. 596 SkPDFStream* subsetFontStream = NULL; 597 SkTDArray<unsigned char> originalFont; 598 originalFont.setCount(SkToInt(fontSize)); 599 if (fontData->read(originalFont.begin(), fontSize) == fontSize) { 600 unsigned char* subsetFont = NULL; 601 // sfntly requires unsigned int* to be passed in, as far as we know, 602 // unsigned int is equivalent to uint32_t on all platforms. 603 SK_COMPILE_ASSERT(sizeof(unsigned int) == sizeof(uint32_t), 604 unsigned_int_not_32_bits); 605 int subsetFontSize = SfntlyWrapper::SubsetFont(fontName, 606 originalFont.begin(), 607 fontSize, 608 subset.begin(), 609 subset.count(), 610 &subsetFont); 611 if (subsetFontSize > 0 && subsetFont != NULL) { 612 SkAutoDataUnref data(SkData::NewWithProc(subsetFont, 613 subsetFontSize, 614 sk_delete_array, 615 NULL)); 616 subsetFontStream = new SkPDFStream(data.get()); 617 fontSize = subsetFontSize; 618 } 619 } 620 if (subsetFontStream) { 621 *fontStream = subsetFontStream; 622 return fontSize; 623 } 624 fontData->rewind(); 625 #else 626 sk_ignore_unused_variable(fontName); 627 sk_ignore_unused_variable(subset); 628 #endif 629 630 // Fail over: just embed the whole font. 631 *fontStream = new SkPDFStream(fontData.get()); 632 return fontSize; 633 } 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 NULL; 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 NULL. 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 SkAutoMutexAcquire lock(CanonicalFontsMutex()); 746 int index = -1; 747 for (int i = 0 ; i < CanonicalFonts().count() ; i++) { 748 if (CanonicalFonts()[i].fFont == this) { 749 index = i; 750 } 751 } 752 753 SkDEBUGCODE(int indexFound;) 754 SkASSERT(index == -1 || 755 (Find(fTypeface->uniqueID(), 756 fFirstGlyphID, 757 &indexFound) && 758 index == indexFound)); 759 if (index >= 0) { 760 CanonicalFonts().removeShuffle(index); 761 } 762 fResources.unrefAll(); 763 } 764 765 void SkPDFFont::getResources(const SkTSet<SkPDFObject*>& knownResourceObjects, 766 SkTSet<SkPDFObject*>* newResourceObjects) { 767 GetResourcesHelper(&fResources, knownResourceObjects, newResourceObjects); 768 } 769 770 SkTypeface* SkPDFFont::typeface() { 771 return fTypeface.get(); 772 } 773 774 SkAdvancedTypefaceMetrics::FontType SkPDFFont::getType() { 775 return fFontType; 776 } 777 778 bool SkPDFFont::canEmbed() const { 779 if (!fFontInfo.get()) { 780 SkASSERT(fFontType == SkAdvancedTypefaceMetrics::kOther_Font); 781 return true; 782 } 783 return (fFontInfo->fFlags & 784 SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag) == 0; 785 } 786 787 bool SkPDFFont::canSubset() const { 788 if (!fFontInfo.get()) { 789 SkASSERT(fFontType == SkAdvancedTypefaceMetrics::kOther_Font); 790 return true; 791 } 792 return (fFontInfo->fFlags & 793 SkAdvancedTypefaceMetrics::kNotSubsettable_FontFlag) == 0; 794 } 795 796 bool SkPDFFont::hasGlyph(uint16_t id) { 797 return (id >= fFirstGlyphID && id <= fLastGlyphID) || id == 0; 798 } 799 800 int SkPDFFont::glyphsToPDFFontEncoding(uint16_t* glyphIDs, int numGlyphs) { 801 // A font with multibyte glyphs will support all glyph IDs in a single font. 802 if (this->multiByteGlyphs()) { 803 return numGlyphs; 804 } 805 806 for (int i = 0; i < numGlyphs; i++) { 807 if (glyphIDs[i] == 0) { 808 continue; 809 } 810 if (glyphIDs[i] < fFirstGlyphID || glyphIDs[i] > fLastGlyphID) { 811 return i; 812 } 813 glyphIDs[i] -= (fFirstGlyphID - 1); 814 } 815 816 return numGlyphs; 817 } 818 819 // static 820 SkPDFFont* SkPDFFont::GetFontResource(SkTypeface* typeface, uint16_t glyphID) { 821 SkAutoMutexAcquire lock(CanonicalFontsMutex()); 822 823 SkAutoResolveDefaultTypeface autoResolve(typeface); 824 typeface = autoResolve.get(); 825 826 const uint32_t fontID = typeface->uniqueID(); 827 int relatedFontIndex; 828 if (Find(fontID, glyphID, &relatedFontIndex)) { 829 CanonicalFonts()[relatedFontIndex].fFont->ref(); 830 return CanonicalFonts()[relatedFontIndex].fFont; 831 } 832 833 SkAutoTUnref<const SkAdvancedTypefaceMetrics> fontMetrics; 834 SkPDFDict* relatedFontDescriptor = NULL; 835 if (relatedFontIndex >= 0) { 836 SkPDFFont* relatedFont = CanonicalFonts()[relatedFontIndex].fFont; 837 fontMetrics.reset(relatedFont->fontInfo()); 838 SkSafeRef(fontMetrics.get()); 839 relatedFontDescriptor = relatedFont->getFontDescriptor(); 840 841 // This only is to catch callers who pass invalid glyph ids. 842 // If glyph id is invalid, then we will create duplicate entries 843 // for TrueType fonts. 844 SkAdvancedTypefaceMetrics::FontType fontType = 845 fontMetrics.get() ? fontMetrics.get()->fType : 846 SkAdvancedTypefaceMetrics::kOther_Font; 847 848 if (fontType == SkAdvancedTypefaceMetrics::kType1CID_Font || 849 fontType == SkAdvancedTypefaceMetrics::kTrueType_Font) { 850 CanonicalFonts()[relatedFontIndex].fFont->ref(); 851 return CanonicalFonts()[relatedFontIndex].fFont; 852 } 853 } else { 854 SkAdvancedTypefaceMetrics::PerGlyphInfo info; 855 info = SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo; 856 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( 857 info, SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo); 858 #if !defined (SK_SFNTLY_SUBSETTER) 859 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( 860 info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo); 861 #endif 862 fontMetrics.reset( 863 typeface->getAdvancedTypefaceMetrics(info, NULL, 0)); 864 #if defined (SK_SFNTLY_SUBSETTER) 865 if (fontMetrics.get() && 866 fontMetrics->fType != SkAdvancedTypefaceMetrics::kTrueType_Font) { 867 // Font does not support subsetting, get new info with advance. 868 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( 869 info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo); 870 fontMetrics.reset( 871 typeface->getAdvancedTypefaceMetrics(info, NULL, 0)); 872 } 873 #endif 874 } 875 876 SkPDFFont* font = Create(fontMetrics.get(), typeface, glyphID, 877 relatedFontDescriptor); 878 FontRec newEntry(font, fontID, font->fFirstGlyphID); 879 CanonicalFonts().push(newEntry); 880 return font; // Return the reference new SkPDFFont() created. 881 } 882 883 SkPDFFont* SkPDFFont::getFontSubset(const SkPDFGlyphSet*) { 884 return NULL; // Default: no support. 885 } 886 887 // static 888 SkTDArray<SkPDFFont::FontRec>& SkPDFFont::CanonicalFonts() { 889 SkPDFFont::CanonicalFontsMutex().assertHeld(); 890 static SkTDArray<FontRec> gCanonicalFonts; 891 return gCanonicalFonts; 892 } 893 894 SK_DECLARE_STATIC_MUTEX(gCanonicalFontsMutex); 895 // static 896 SkBaseMutex& SkPDFFont::CanonicalFontsMutex() { 897 return gCanonicalFontsMutex; 898 } 899 900 // static 901 bool SkPDFFont::Find(uint32_t fontID, uint16_t glyphID, int* index) { 902 // TODO(vandebo): Optimize this, do only one search? 903 FontRec search(NULL, fontID, glyphID); 904 *index = CanonicalFonts().find(search); 905 if (*index >= 0) { 906 return true; 907 } 908 search.fGlyphID = 0; 909 *index = CanonicalFonts().find(search); 910 return false; 911 } 912 913 SkPDFFont::SkPDFFont(const SkAdvancedTypefaceMetrics* info, 914 SkTypeface* typeface, 915 SkPDFDict* relatedFontDescriptor) 916 : SkPDFDict("Font"), 917 fTypeface(ref_or_default(typeface)), 918 fFirstGlyphID(1), 919 fLastGlyphID(info ? info->fLastGlyphID : 0), 920 fFontInfo(SkSafeRef(info)), 921 fDescriptor(SkSafeRef(relatedFontDescriptor)) { 922 if (info == NULL || 923 info->fFlags & SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag) { 924 fFontType = SkAdvancedTypefaceMetrics::kOther_Font; 925 } else { 926 fFontType = info->fType; 927 } 928 } 929 930 // static 931 SkPDFFont* SkPDFFont::Create(const SkAdvancedTypefaceMetrics* info, 932 SkTypeface* typeface, uint16_t glyphID, 933 SkPDFDict* relatedFontDescriptor) { 934 SkAdvancedTypefaceMetrics::FontType type = 935 info ? info->fType : SkAdvancedTypefaceMetrics::kOther_Font; 936 937 if (info && 938 (info->fFlags & SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag)) { 939 NOT_IMPLEMENTED(true, true); 940 return new SkPDFType3Font(info, 941 typeface, 942 glyphID); 943 } 944 if (type == SkAdvancedTypefaceMetrics::kType1CID_Font || 945 type == SkAdvancedTypefaceMetrics::kTrueType_Font) { 946 SkASSERT(relatedFontDescriptor == NULL); 947 return new SkPDFType0Font(info, typeface); 948 } 949 if (type == SkAdvancedTypefaceMetrics::kType1_Font) { 950 return new SkPDFType1Font(info, 951 typeface, 952 glyphID, 953 relatedFontDescriptor); 954 } 955 956 SkASSERT(type == SkAdvancedTypefaceMetrics::kCFF_Font || 957 type == SkAdvancedTypefaceMetrics::kOther_Font); 958 959 return new SkPDFType3Font(info, typeface, glyphID); 960 } 961 962 const SkAdvancedTypefaceMetrics* SkPDFFont::fontInfo() { 963 return fFontInfo.get(); 964 } 965 966 void SkPDFFont::setFontInfo(const SkAdvancedTypefaceMetrics* info) { 967 if (info == NULL || info == fFontInfo.get()) { 968 return; 969 } 970 fFontInfo.reset(info); 971 SkSafeRef(info); 972 } 973 974 uint16_t SkPDFFont::firstGlyphID() const { 975 return fFirstGlyphID; 976 } 977 978 uint16_t SkPDFFont::lastGlyphID() const { 979 return fLastGlyphID; 980 } 981 982 void SkPDFFont::setLastGlyphID(uint16_t glyphID) { 983 fLastGlyphID = glyphID; 984 } 985 986 void SkPDFFont::addResource(SkPDFObject* object) { 987 SkASSERT(object != NULL); 988 fResources.push(object); 989 object->ref(); 990 } 991 992 SkPDFDict* SkPDFFont::getFontDescriptor() { 993 return fDescriptor.get(); 994 } 995 996 void SkPDFFont::setFontDescriptor(SkPDFDict* descriptor) { 997 fDescriptor.reset(descriptor); 998 SkSafeRef(descriptor); 999 } 1000 1001 bool SkPDFFont::addCommonFontDescriptorEntries(int16_t defaultWidth) { 1002 if (fDescriptor.get() == NULL) { 1003 return false; 1004 } 1005 1006 const uint16_t emSize = fFontInfo->fEmSize; 1007 1008 fDescriptor->insertName("FontName", fFontInfo->fFontName); 1009 fDescriptor->insertInt("Flags", fFontInfo->fStyle | kPdfSymbolic); 1010 fDescriptor->insertScalar("Ascent", 1011 scaleFromFontUnits(fFontInfo->fAscent, emSize)); 1012 fDescriptor->insertScalar("Descent", 1013 scaleFromFontUnits(fFontInfo->fDescent, emSize)); 1014 fDescriptor->insertScalar("StemV", 1015 scaleFromFontUnits(fFontInfo->fStemV, emSize)); 1016 1017 fDescriptor->insertScalar("CapHeight", 1018 scaleFromFontUnits(fFontInfo->fCapHeight, emSize)); 1019 fDescriptor->insertInt("ItalicAngle", fFontInfo->fItalicAngle); 1020 fDescriptor->insert("FontBBox", makeFontBBox(fFontInfo->fBBox, 1021 fFontInfo->fEmSize))->unref(); 1022 1023 if (defaultWidth > 0) { 1024 fDescriptor->insertScalar("MissingWidth", 1025 scaleFromFontUnits(defaultWidth, emSize)); 1026 } 1027 return true; 1028 } 1029 1030 void SkPDFFont::adjustGlyphRangeForSingleByteEncoding(uint16_t glyphID) { 1031 // Single byte glyph encoding supports a max of 255 glyphs. 1032 fFirstGlyphID = glyphID - (glyphID - 1) % 255; 1033 if (fLastGlyphID > fFirstGlyphID + 255 - 1) { 1034 fLastGlyphID = fFirstGlyphID + 255 - 1; 1035 } 1036 } 1037 1038 bool SkPDFFont::FontRec::operator==(const SkPDFFont::FontRec& b) const { 1039 if (fFontID != b.fFontID) { 1040 return false; 1041 } 1042 if (fFont != NULL && b.fFont != NULL) { 1043 return fFont->fFirstGlyphID == b.fFont->fFirstGlyphID && 1044 fFont->fLastGlyphID == b.fFont->fLastGlyphID; 1045 } 1046 if (fGlyphID == 0 || b.fGlyphID == 0) { 1047 return true; 1048 } 1049 1050 if (fFont != NULL) { 1051 return fFont->fFirstGlyphID <= b.fGlyphID && 1052 b.fGlyphID <= fFont->fLastGlyphID; 1053 } else if (b.fFont != NULL) { 1054 return b.fFont->fFirstGlyphID <= fGlyphID && 1055 fGlyphID <= b.fFont->fLastGlyphID; 1056 } 1057 return fGlyphID == b.fGlyphID; 1058 } 1059 1060 SkPDFFont::FontRec::FontRec(SkPDFFont* font, uint32_t fontID, uint16_t glyphID) 1061 : fFont(font), 1062 fFontID(fontID), 1063 fGlyphID(glyphID) { 1064 } 1065 1066 void SkPDFFont::populateToUnicodeTable(const SkPDFGlyphSet* subset) { 1067 if (fFontInfo == NULL || fFontInfo->fGlyphToUnicode.begin() == NULL) { 1068 return; 1069 } 1070 SkAutoTUnref<SkPDFStream> pdfCmap( 1071 generate_tounicode_cmap(fFontInfo->fGlyphToUnicode, subset, 1072 multiByteGlyphs(), firstGlyphID(), 1073 lastGlyphID())); 1074 addResource(pdfCmap.get()); 1075 insert("ToUnicode", new SkPDFObjRef(pdfCmap.get()))->unref(); 1076 } 1077 1078 /////////////////////////////////////////////////////////////////////////////// 1079 // class SkPDFType0Font 1080 /////////////////////////////////////////////////////////////////////////////// 1081 1082 SkPDFType0Font::SkPDFType0Font(const SkAdvancedTypefaceMetrics* info, 1083 SkTypeface* typeface) 1084 : SkPDFFont(info, typeface, NULL) { 1085 SkDEBUGCODE(fPopulated = false); 1086 if (!canSubset()) { 1087 populate(NULL); 1088 } 1089 } 1090 1091 SkPDFType0Font::~SkPDFType0Font() {} 1092 1093 SkPDFFont* SkPDFType0Font::getFontSubset(const SkPDFGlyphSet* subset) { 1094 if (!canSubset()) { 1095 return NULL; 1096 } 1097 SkPDFType0Font* newSubset = new SkPDFType0Font(fontInfo(), typeface()); 1098 newSubset->populate(subset); 1099 return newSubset; 1100 } 1101 1102 #ifdef SK_DEBUG 1103 void SkPDFType0Font::emitObject(SkWStream* stream, SkPDFCatalog* catalog, 1104 bool indirect) { 1105 SkASSERT(fPopulated); 1106 return INHERITED::emitObject(stream, catalog, indirect); 1107 } 1108 #endif 1109 1110 bool SkPDFType0Font::populate(const SkPDFGlyphSet* subset) { 1111 insertName("Subtype", "Type0"); 1112 insertName("BaseFont", fontInfo()->fFontName); 1113 insertName("Encoding", "Identity-H"); 1114 1115 SkAutoTUnref<SkPDFCIDFont> newCIDFont( 1116 new SkPDFCIDFont(fontInfo(), typeface(), subset)); 1117 addResource(newCIDFont.get()); 1118 SkAutoTUnref<SkPDFArray> descendantFonts(new SkPDFArray()); 1119 descendantFonts->append(new SkPDFObjRef(newCIDFont.get()))->unref(); 1120 insert("DescendantFonts", descendantFonts.get()); 1121 1122 populateToUnicodeTable(subset); 1123 1124 SkDEBUGCODE(fPopulated = true); 1125 return true; 1126 } 1127 1128 /////////////////////////////////////////////////////////////////////////////// 1129 // class SkPDFCIDFont 1130 /////////////////////////////////////////////////////////////////////////////// 1131 1132 SkPDFCIDFont::SkPDFCIDFont(const SkAdvancedTypefaceMetrics* info, 1133 SkTypeface* typeface, const SkPDFGlyphSet* subset) 1134 : SkPDFFont(info, typeface, NULL) { 1135 populate(subset); 1136 } 1137 1138 SkPDFCIDFont::~SkPDFCIDFont() {} 1139 1140 bool SkPDFCIDFont::addFontDescriptor(int16_t defaultWidth, 1141 const SkTDArray<uint32_t>* subset) { 1142 SkAutoTUnref<SkPDFDict> descriptor(new SkPDFDict("FontDescriptor")); 1143 setFontDescriptor(descriptor.get()); 1144 addResource(descriptor.get()); 1145 insert("FontDescriptor", new SkPDFObjRef(descriptor.get()))->unref(); 1146 if (!addCommonFontDescriptorEntries(defaultWidth)) { 1147 return false; 1148 } 1149 if (!canEmbed()) { 1150 return true; 1151 } 1152 1153 switch (getType()) { 1154 case SkAdvancedTypefaceMetrics::kTrueType_Font: { 1155 SkAutoTUnref<SkPDFStream> fontStream; 1156 size_t fontSize = 0; 1157 if (canSubset()) { 1158 SkPDFStream* rawStream = NULL; 1159 fontSize = get_subset_font_stream(fontInfo()->fFontName.c_str(), 1160 typeface(), 1161 *subset, 1162 &rawStream); 1163 fontStream.reset(rawStream); 1164 } else { 1165 int ttcIndex; 1166 SkAutoTUnref<SkStream> fontData( 1167 typeface()->openStream(&ttcIndex)); 1168 fontStream.reset(new SkPDFStream(fontData.get())); 1169 fontSize = fontData->getLength(); 1170 } 1171 SkASSERT(fontSize); 1172 SkASSERT(fontStream.get()); 1173 addResource(fontStream.get()); 1174 1175 fontStream->insertInt("Length1", fontSize); 1176 descriptor->insert("FontFile2", 1177 new SkPDFObjRef(fontStream.get()))->unref(); 1178 break; 1179 } 1180 case SkAdvancedTypefaceMetrics::kCFF_Font: 1181 case SkAdvancedTypefaceMetrics::kType1CID_Font: { 1182 int ttcIndex; 1183 SkAutoTUnref<SkStream> fontData(typeface()->openStream(&ttcIndex)); 1184 SkAutoTUnref<SkPDFStream> fontStream( 1185 new SkPDFStream(fontData.get())); 1186 addResource(fontStream.get()); 1187 1188 if (getType() == SkAdvancedTypefaceMetrics::kCFF_Font) { 1189 fontStream->insertName("Subtype", "Type1C"); 1190 } else { 1191 fontStream->insertName("Subtype", "CIDFontType0c"); 1192 } 1193 descriptor->insert("FontFile3", 1194 new SkPDFObjRef(fontStream.get()))->unref(); 1195 break; 1196 } 1197 default: 1198 SkASSERT(false); 1199 } 1200 return true; 1201 } 1202 1203 bool SkPDFCIDFont::populate(const SkPDFGlyphSet* subset) { 1204 // Generate new font metrics with advance info for true type fonts. 1205 if (fontInfo()->fType == SkAdvancedTypefaceMetrics::kTrueType_Font) { 1206 // Generate glyph id array. 1207 SkTDArray<uint32_t> glyphIDs; 1208 if (subset) { 1209 // Always include glyph 0. 1210 if (!subset->has(0)) { 1211 glyphIDs.push(0); 1212 } 1213 subset->exportTo(&glyphIDs); 1214 } 1215 1216 SkAdvancedTypefaceMetrics::PerGlyphInfo info; 1217 info = SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo; 1218 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( 1219 info, SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo); 1220 uint32_t* glyphs = (glyphIDs.count() == 0) ? NULL : glyphIDs.begin(); 1221 uint32_t glyphsCount = glyphs ? glyphIDs.count() : 0; 1222 SkAutoTUnref<const SkAdvancedTypefaceMetrics> fontMetrics( 1223 typeface()->getAdvancedTypefaceMetrics(info, glyphs, glyphsCount)); 1224 setFontInfo(fontMetrics.get()); 1225 addFontDescriptor(0, &glyphIDs); 1226 } else { 1227 // Other CID fonts 1228 addFontDescriptor(0, NULL); 1229 } 1230 1231 insertName("BaseFont", fontInfo()->fFontName); 1232 1233 if (getType() == SkAdvancedTypefaceMetrics::kType1CID_Font) { 1234 insertName("Subtype", "CIDFontType0"); 1235 } else if (getType() == SkAdvancedTypefaceMetrics::kTrueType_Font) { 1236 insertName("Subtype", "CIDFontType2"); 1237 insertName("CIDToGIDMap", "Identity"); 1238 } else { 1239 SkASSERT(false); 1240 } 1241 1242 SkAutoTUnref<SkPDFDict> sysInfo(new SkPDFDict); 1243 sysInfo->insert("Registry", new SkPDFString("Adobe"))->unref(); 1244 sysInfo->insert("Ordering", new SkPDFString("Identity"))->unref(); 1245 sysInfo->insertInt("Supplement", 0); 1246 insert("CIDSystemInfo", sysInfo.get()); 1247 1248 if (fontInfo()->fGlyphWidths.get()) { 1249 int16_t defaultWidth = 0; 1250 SkAutoTUnref<SkPDFArray> widths( 1251 composeAdvanceData(fontInfo()->fGlyphWidths.get(), 1252 fontInfo()->fEmSize, &appendWidth, 1253 &defaultWidth)); 1254 if (widths->size()) 1255 insert("W", widths.get()); 1256 if (defaultWidth != 0) { 1257 insertScalar("DW", scaleFromFontUnits(defaultWidth, 1258 fontInfo()->fEmSize)); 1259 } 1260 } 1261 if (fontInfo()->fVerticalMetrics.get()) { 1262 struct SkAdvancedTypefaceMetrics::VerticalMetric defaultAdvance; 1263 defaultAdvance.fVerticalAdvance = 0; 1264 defaultAdvance.fOriginXDisp = 0; 1265 defaultAdvance.fOriginYDisp = 0; 1266 SkAutoTUnref<SkPDFArray> advances( 1267 composeAdvanceData(fontInfo()->fVerticalMetrics.get(), 1268 fontInfo()->fEmSize, &appendVerticalAdvance, 1269 &defaultAdvance)); 1270 if (advances->size()) 1271 insert("W2", advances.get()); 1272 if (defaultAdvance.fVerticalAdvance || 1273 defaultAdvance.fOriginXDisp || 1274 defaultAdvance.fOriginYDisp) { 1275 insert("DW2", appendVerticalAdvance(defaultAdvance, 1276 fontInfo()->fEmSize, 1277 new SkPDFArray))->unref(); 1278 } 1279 } 1280 1281 return true; 1282 } 1283 1284 /////////////////////////////////////////////////////////////////////////////// 1285 // class SkPDFType1Font 1286 /////////////////////////////////////////////////////////////////////////////// 1287 1288 SkPDFType1Font::SkPDFType1Font(const SkAdvancedTypefaceMetrics* info, 1289 SkTypeface* typeface, 1290 uint16_t glyphID, 1291 SkPDFDict* relatedFontDescriptor) 1292 : SkPDFFont(info, typeface, relatedFontDescriptor) { 1293 populate(glyphID); 1294 } 1295 1296 SkPDFType1Font::~SkPDFType1Font() {} 1297 1298 bool SkPDFType1Font::addFontDescriptor(int16_t defaultWidth) { 1299 if (getFontDescriptor() != NULL) { 1300 SkPDFDict* descriptor = getFontDescriptor(); 1301 addResource(descriptor); 1302 insert("FontDescriptor", new SkPDFObjRef(descriptor))->unref(); 1303 return true; 1304 } 1305 1306 SkAutoTUnref<SkPDFDict> descriptor(new SkPDFDict("FontDescriptor")); 1307 setFontDescriptor(descriptor.get()); 1308 1309 int ttcIndex; 1310 size_t header SK_INIT_TO_AVOID_WARNING; 1311 size_t data SK_INIT_TO_AVOID_WARNING; 1312 size_t trailer SK_INIT_TO_AVOID_WARNING; 1313 SkAutoTUnref<SkStream> rawFontData(typeface()->openStream(&ttcIndex)); 1314 SkAutoTUnref<SkData> fontData(handle_type1_stream(rawFontData.get(), &header, 1315 &data, &trailer)); 1316 if (fontData.get() == NULL) { 1317 return false; 1318 } 1319 if (canEmbed()) { 1320 SkAutoTUnref<SkPDFStream> fontStream(new SkPDFStream(fontData.get())); 1321 addResource(fontStream.get()); 1322 fontStream->insertInt("Length1", header); 1323 fontStream->insertInt("Length2", data); 1324 fontStream->insertInt("Length3", trailer); 1325 descriptor->insert("FontFile", 1326 new SkPDFObjRef(fontStream.get()))->unref(); 1327 } 1328 1329 addResource(descriptor.get()); 1330 insert("FontDescriptor", new SkPDFObjRef(descriptor.get()))->unref(); 1331 1332 return addCommonFontDescriptorEntries(defaultWidth); 1333 } 1334 1335 bool SkPDFType1Font::populate(int16_t glyphID) { 1336 SkASSERT(!fontInfo()->fVerticalMetrics.get()); 1337 SkASSERT(fontInfo()->fGlyphWidths.get()); 1338 1339 adjustGlyphRangeForSingleByteEncoding(glyphID); 1340 1341 int16_t defaultWidth = 0; 1342 const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry = NULL; 1343 const SkAdvancedTypefaceMetrics::WidthRange* widthEntry; 1344 for (widthEntry = fontInfo()->fGlyphWidths.get(); 1345 widthEntry != NULL; 1346 widthEntry = widthEntry->fNext.get()) { 1347 switch (widthEntry->fType) { 1348 case SkAdvancedTypefaceMetrics::WidthRange::kDefault: 1349 defaultWidth = widthEntry->fAdvance[0]; 1350 break; 1351 case SkAdvancedTypefaceMetrics::WidthRange::kRun: 1352 SkASSERT(false); 1353 break; 1354 case SkAdvancedTypefaceMetrics::WidthRange::kRange: 1355 SkASSERT(widthRangeEntry == NULL); 1356 widthRangeEntry = widthEntry; 1357 break; 1358 } 1359 } 1360 1361 if (!addFontDescriptor(defaultWidth)) { 1362 return false; 1363 } 1364 1365 insertName("Subtype", "Type1"); 1366 insertName("BaseFont", fontInfo()->fFontName); 1367 1368 addWidthInfoFromRange(defaultWidth, widthRangeEntry); 1369 1370 SkAutoTUnref<SkPDFDict> encoding(new SkPDFDict("Encoding")); 1371 insert("Encoding", encoding.get()); 1372 1373 SkAutoTUnref<SkPDFArray> encDiffs(new SkPDFArray); 1374 encoding->insert("Differences", encDiffs.get()); 1375 1376 encDiffs->reserve(lastGlyphID() - firstGlyphID() + 2); 1377 encDiffs->appendInt(1); 1378 for (int gID = firstGlyphID(); gID <= lastGlyphID(); gID++) { 1379 encDiffs->appendName(fontInfo()->fGlyphNames->get()[gID].c_str()); 1380 } 1381 1382 return true; 1383 } 1384 1385 void SkPDFType1Font::addWidthInfoFromRange( 1386 int16_t defaultWidth, 1387 const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry) { 1388 SkAutoTUnref<SkPDFArray> widthArray(new SkPDFArray()); 1389 int firstChar = 0; 1390 if (widthRangeEntry) { 1391 const uint16_t emSize = fontInfo()->fEmSize; 1392 int startIndex = firstGlyphID() - widthRangeEntry->fStartId; 1393 int endIndex = startIndex + lastGlyphID() - firstGlyphID() + 1; 1394 if (startIndex < 0) 1395 startIndex = 0; 1396 if (endIndex > widthRangeEntry->fAdvance.count()) 1397 endIndex = widthRangeEntry->fAdvance.count(); 1398 if (widthRangeEntry->fStartId == 0) { 1399 appendWidth(widthRangeEntry->fAdvance[0], emSize, widthArray.get()); 1400 } else { 1401 firstChar = startIndex + widthRangeEntry->fStartId; 1402 } 1403 for (int i = startIndex; i < endIndex; i++) { 1404 appendWidth(widthRangeEntry->fAdvance[i], emSize, widthArray.get()); 1405 } 1406 } else { 1407 appendWidth(defaultWidth, 1000, widthArray.get()); 1408 } 1409 insertInt("FirstChar", firstChar); 1410 insertInt("LastChar", firstChar + widthArray->size() - 1); 1411 insert("Widths", widthArray.get()); 1412 } 1413 1414 /////////////////////////////////////////////////////////////////////////////// 1415 // class SkPDFType3Font 1416 /////////////////////////////////////////////////////////////////////////////// 1417 1418 SkPDFType3Font::SkPDFType3Font(const SkAdvancedTypefaceMetrics* info, 1419 SkTypeface* typeface, 1420 uint16_t glyphID) 1421 : SkPDFFont(info, typeface, NULL) { 1422 populate(glyphID); 1423 } 1424 1425 SkPDFType3Font::~SkPDFType3Font() {} 1426 1427 bool SkPDFType3Font::populate(uint16_t glyphID) { 1428 SkPaint paint; 1429 paint.setTypeface(typeface()); 1430 paint.setTextSize(1000); 1431 SkAutoGlyphCache autoCache(paint, NULL, NULL); 1432 SkGlyphCache* cache = autoCache.getCache(); 1433 // If fLastGlyphID isn't set (because there is not fFontInfo), look it up. 1434 if (lastGlyphID() == 0) { 1435 setLastGlyphID(cache->getGlyphCount() - 1); 1436 } 1437 1438 adjustGlyphRangeForSingleByteEncoding(glyphID); 1439 1440 insertName("Subtype", "Type3"); 1441 // Flip about the x-axis and scale by 1/1000. 1442 SkMatrix fontMatrix; 1443 fontMatrix.setScale(SkScalarInvert(1000), -SkScalarInvert(1000)); 1444 insert("FontMatrix", SkPDFUtils::MatrixToArray(fontMatrix))->unref(); 1445 1446 SkAutoTUnref<SkPDFDict> charProcs(new SkPDFDict); 1447 insert("CharProcs", charProcs.get()); 1448 1449 SkAutoTUnref<SkPDFDict> encoding(new SkPDFDict("Encoding")); 1450 insert("Encoding", encoding.get()); 1451 1452 SkAutoTUnref<SkPDFArray> encDiffs(new SkPDFArray); 1453 encoding->insert("Differences", encDiffs.get()); 1454 encDiffs->reserve(lastGlyphID() - firstGlyphID() + 2); 1455 encDiffs->appendInt(1); 1456 1457 SkAutoTUnref<SkPDFArray> widthArray(new SkPDFArray()); 1458 1459 SkIRect bbox = SkIRect::MakeEmpty(); 1460 for (int gID = firstGlyphID(); gID <= lastGlyphID(); gID++) { 1461 SkString characterName; 1462 characterName.printf("gid%d", gID); 1463 encDiffs->appendName(characterName.c_str()); 1464 1465 const SkGlyph& glyph = cache->getGlyphIDMetrics(gID); 1466 widthArray->appendScalar(SkFixedToScalar(glyph.fAdvanceX)); 1467 SkIRect glyphBBox = SkIRect::MakeXYWH(glyph.fLeft, glyph.fTop, 1468 glyph.fWidth, glyph.fHeight); 1469 bbox.join(glyphBBox); 1470 1471 SkDynamicMemoryWStream content; 1472 setGlyphWidthAndBoundingBox(SkFixedToScalar(glyph.fAdvanceX), glyphBBox, 1473 &content); 1474 const SkPath* path = cache->findPath(glyph); 1475 if (path) { 1476 SkPDFUtils::EmitPath(*path, paint.getStyle(), &content); 1477 SkPDFUtils::PaintPath(paint.getStyle(), path->getFillType(), 1478 &content); 1479 } 1480 SkAutoTUnref<SkMemoryStream> glyphStream(new SkMemoryStream()); 1481 glyphStream->setData(content.copyToData())->unref(); 1482 1483 SkAutoTUnref<SkPDFStream> glyphDescription( 1484 new SkPDFStream(glyphStream.get())); 1485 addResource(glyphDescription.get()); 1486 charProcs->insert(characterName.c_str(), 1487 new SkPDFObjRef(glyphDescription.get()))->unref(); 1488 } 1489 1490 insert("FontBBox", makeFontBBox(bbox, 1000))->unref(); 1491 insertInt("FirstChar", 1); 1492 insertInt("LastChar", lastGlyphID() - firstGlyphID() + 1); 1493 insert("Widths", widthArray.get()); 1494 insertName("CIDToGIDMap", "Identity"); 1495 1496 populateToUnicodeTable(NULL); 1497 return true; 1498 } 1499