1 /* 2 * Copyright (C) 2011 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <ctype.h> 18 19 #include "SkFontHost.h" 20 #include "SkGlyphCache.h" 21 #include "SkPaint.h" 22 #include "SkPDFDevice.h" 23 #include "SkPDFFont.h" 24 #include "SkPDFStream.h" 25 #include "SkPDFTypes.h" 26 #include "SkPDFUtils.h" 27 #include "SkRefCnt.h" 28 #include "SkScalar.h" 29 #include "SkStream.h" 30 #include "SkTypeface.h" 31 #include "SkTypes.h" 32 #include "SkUtils.h" 33 34 namespace { 35 36 bool parsePFBSection(const uint8_t** src, size_t* len, int sectionType, 37 size_t* size) { 38 // PFB sections have a two or six bytes header. 0x80 and a one byte 39 // section type followed by a four byte section length. Type one is 40 // an ASCII section (includes a length), type two is a binary section 41 // (includes a length) and type three is an EOF marker with no length. 42 const uint8_t* buf = *src; 43 if (*len < 2 || buf[0] != 0x80 || buf[1] != sectionType) 44 return false; 45 if (buf[1] == 3) 46 return true; 47 if (*len < 6) 48 return false; 49 50 *size = buf[2] | (buf[3] << 8) | (buf[4] << 16) | (buf[5] << 24); 51 size_t consumed = *size + 6; 52 if (consumed > *len) 53 return false; 54 *src = *src + consumed; 55 *len = *len - consumed; 56 return true; 57 } 58 59 bool parsePFB(const uint8_t* src, size_t size, size_t* headerLen, 60 size_t* dataLen, size_t* trailerLen) { 61 const uint8_t* srcPtr = src; 62 size_t remaining = size; 63 64 return parsePFBSection(&srcPtr, &remaining, 1, headerLen) && 65 parsePFBSection(&srcPtr, &remaining, 2, dataLen) && 66 parsePFBSection(&srcPtr, &remaining, 1, trailerLen) && 67 parsePFBSection(&srcPtr, &remaining, 3, NULL); 68 } 69 70 /* The sections of a PFA file are implicitly defined. The body starts 71 * after the line containing "eexec," and the trailer starts with 512 72 * literal 0's followed by "cleartomark" (plus arbitrary white space). 73 * 74 * This function assumes that src is NUL terminated, but the NUL 75 * termination is not included in size. 76 * 77 */ 78 bool parsePFA(const char* src, size_t size, size_t* headerLen, 79 size_t* hexDataLen, size_t* dataLen, size_t* trailerLen) { 80 const char* end = src + size; 81 82 const char* dataPos = strstr(src, "eexec"); 83 if (!dataPos) 84 return false; 85 dataPos += strlen("eexec"); 86 while ((*dataPos == '\n' || *dataPos == '\r' || *dataPos == ' ') && 87 dataPos < end) 88 dataPos++; 89 *headerLen = dataPos - src; 90 91 const char* trailerPos = strstr(dataPos, "cleartomark"); 92 if (!trailerPos) 93 return false; 94 int zeroCount = 0; 95 for (trailerPos--; trailerPos > dataPos && zeroCount < 512; trailerPos--) { 96 if (*trailerPos == '\n' || *trailerPos == '\r' || *trailerPos == ' ') { 97 continue; 98 } else if (*trailerPos == '0') { 99 zeroCount++; 100 } else { 101 return false; 102 } 103 } 104 if (zeroCount != 512) 105 return false; 106 107 *hexDataLen = trailerPos - src - *headerLen; 108 *trailerLen = size - *headerLen - *hexDataLen; 109 110 // Verify that the data section is hex encoded and count the bytes. 111 int nibbles = 0; 112 for (; dataPos < trailerPos; dataPos++) { 113 if (isspace(*dataPos)) 114 continue; 115 if (!isxdigit(*dataPos)) 116 return false; 117 nibbles++; 118 } 119 *dataLen = (nibbles + 1) / 2; 120 121 return true; 122 } 123 124 int8_t hexToBin(uint8_t c) { 125 if (!isxdigit(c)) 126 return -1; 127 if (c <= '9') return c - '0'; 128 if (c <= 'F') return c - 'A' + 10; 129 if (c <= 'f') return c - 'a' + 10; 130 return -1; 131 } 132 133 SkStream* handleType1Stream(SkStream* srcStream, size_t* headerLen, 134 size_t* dataLen, size_t* trailerLen) { 135 // srcStream may be backed by a file or a unseekable fd, so we may not be 136 // able to use skip(), rewind(), or getMemoryBase(). read()ing through 137 // the input only once is doable, but very ugly. Furthermore, it'd be nice 138 // if the data was NUL terminated so that we can use strstr() to search it. 139 // Make as few copies as possible given these constraints. 140 SkDynamicMemoryWStream dynamicStream; 141 SkRefPtr<SkMemoryStream> staticStream; 142 const uint8_t* src; 143 size_t srcLen; 144 if ((srcLen = srcStream->getLength()) > 0) { 145 staticStream = new SkMemoryStream(srcLen + 1); 146 staticStream->unref(); // new and SkRefPtr both took a ref. 147 src = (const uint8_t*)staticStream->getMemoryBase(); 148 if (srcStream->getMemoryBase() != NULL) { 149 memcpy((void *)src, srcStream->getMemoryBase(), srcLen); 150 } else { 151 size_t read = 0; 152 while (read < srcLen) { 153 size_t got = srcStream->read((void *)staticStream->getAtPos(), 154 srcLen - read); 155 if (got == 0) 156 return NULL; 157 read += got; 158 staticStream->seek(read); 159 } 160 } 161 ((uint8_t *)src)[srcLen] = 0; 162 } else { 163 static const size_t bufSize = 4096; 164 uint8_t buf[bufSize]; 165 size_t amount; 166 while ((amount = srcStream->read(buf, bufSize)) > 0) 167 dynamicStream.write(buf, amount); 168 amount = 0; 169 dynamicStream.write(&amount, 1); // NULL terminator. 170 // getStream makes another copy, but we couldn't do any better. 171 src = (const uint8_t*)dynamicStream.getStream(); 172 srcLen = dynamicStream.getOffset() - 1; 173 } 174 175 if (parsePFB(src, srcLen, headerLen, dataLen, trailerLen)) { 176 SkMemoryStream* result = 177 new SkMemoryStream(*headerLen + *dataLen + *trailerLen); 178 memcpy((char*)result->getAtPos(), src + 6, *headerLen); 179 result->seek(*headerLen); 180 memcpy((char*)result->getAtPos(), src + 6 + *headerLen + 6, *dataLen); 181 result->seek(*headerLen + *dataLen); 182 memcpy((char*)result->getAtPos(), src + 6 + *headerLen + 6 + *dataLen, 183 *trailerLen); 184 result->rewind(); 185 return result; 186 } 187 188 // A PFA has to be converted for PDF. 189 size_t hexDataLen; 190 if (parsePFA((const char*)src, srcLen, headerLen, &hexDataLen, dataLen, 191 trailerLen)) { 192 SkMemoryStream* result = 193 new SkMemoryStream(*headerLen + *dataLen + *trailerLen); 194 memcpy((char*)result->getAtPos(), src, *headerLen); 195 result->seek(*headerLen); 196 197 const uint8_t* hexData = src + *headerLen; 198 const uint8_t* trailer = hexData + hexDataLen; 199 size_t outputOffset = 0; 200 uint8_t dataByte = 0; // To hush compiler. 201 bool highNibble = true; 202 for (; hexData < trailer; hexData++) { 203 char curNibble = hexToBin(*hexData); 204 if (curNibble < 0) 205 continue; 206 if (highNibble) { 207 dataByte = curNibble << 4; 208 highNibble = false; 209 } else { 210 dataByte |= curNibble; 211 highNibble = true; 212 ((char *)result->getAtPos())[outputOffset++] = dataByte; 213 } 214 } 215 if (!highNibble) 216 ((char *)result->getAtPos())[outputOffset++] = dataByte; 217 SkASSERT(outputOffset == *dataLen); 218 result->seek(*headerLen + outputOffset); 219 220 memcpy((char *)result->getAtPos(), src + *headerLen + hexDataLen, 221 *trailerLen); 222 result->rewind(); 223 return result; 224 } 225 226 return NULL; 227 } 228 229 // scale from em-units to base-1000, returning as a SkScalar 230 SkScalar scaleFromFontUnits(int16_t val, uint16_t emSize) { 231 SkScalar scaled = SkIntToScalar(val); 232 if (emSize == 1000) { 233 return scaled; 234 } else { 235 return SkScalarMulDiv(scaled, 1000, emSize); 236 } 237 } 238 239 void setGlyphWidthAndBoundingBox(SkScalar width, SkIRect box, 240 SkWStream* content) { 241 // Specify width and bounding box for the glyph. 242 SkPDFScalar::Append(width, content); 243 content->writeText(" 0 "); 244 content->writeDecAsText(box.fLeft); 245 content->writeText(" "); 246 content->writeDecAsText(box.fTop); 247 content->writeText(" "); 248 content->writeDecAsText(box.fRight); 249 content->writeText(" "); 250 content->writeDecAsText(box.fBottom); 251 content->writeText(" d1\n"); 252 } 253 254 SkPDFArray* makeFontBBox(SkIRect glyphBBox, uint16_t emSize) { 255 SkPDFArray* bbox = new SkPDFArray; 256 bbox->reserve(4); 257 bbox->append(new SkPDFScalar(scaleFromFontUnits(glyphBBox.fLeft, 258 emSize)))->unref(); 259 bbox->append(new SkPDFScalar(scaleFromFontUnits(glyphBBox.fBottom, 260 emSize)))->unref(); 261 bbox->append(new SkPDFScalar(scaleFromFontUnits(glyphBBox.fRight, 262 emSize)))->unref(); 263 bbox->append(new SkPDFScalar(scaleFromFontUnits(glyphBBox.fTop, 264 emSize)))->unref(); 265 return bbox; 266 } 267 268 SkPDFArray* appendWidth(const int16_t& width, uint16_t emSize, 269 SkPDFArray* array) { 270 array->append(new SkPDFScalar(scaleFromFontUnits(width, emSize)))->unref(); 271 return array; 272 } 273 274 SkPDFArray* appendVerticalAdvance( 275 const SkAdvancedTypefaceMetrics::VerticalMetric& advance, 276 uint16_t emSize, SkPDFArray* array) { 277 appendWidth(advance.fVerticalAdvance, emSize, array); 278 appendWidth(advance.fOriginXDisp, emSize, array); 279 appendWidth(advance.fOriginYDisp, emSize, array); 280 return array; 281 } 282 283 template <typename Data> 284 SkPDFArray* composeAdvanceData( 285 SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* advanceInfo, 286 uint16_t emSize, 287 SkPDFArray* (*appendAdvance)(const Data& advance, uint16_t emSize, 288 SkPDFArray* array), 289 Data* defaultAdvance) { 290 SkPDFArray* result = new SkPDFArray(); 291 for (; advanceInfo != NULL; advanceInfo = advanceInfo->fNext.get()) { 292 switch (advanceInfo->fType) { 293 case SkAdvancedTypefaceMetrics::WidthRange::kDefault: { 294 SkASSERT(advanceInfo->fAdvance.count() == 1); 295 *defaultAdvance = advanceInfo->fAdvance[0]; 296 break; 297 } 298 case SkAdvancedTypefaceMetrics::WidthRange::kRange: { 299 SkRefPtr<SkPDFArray> advanceArray = new SkPDFArray(); 300 advanceArray->unref(); // SkRefPtr and new both took a ref. 301 for (int j = 0; j < advanceInfo->fAdvance.count(); j++) 302 appendAdvance(advanceInfo->fAdvance[j], emSize, 303 advanceArray.get()); 304 result->append(new SkPDFInt(advanceInfo->fStartId))->unref(); 305 result->append(advanceArray.get()); 306 break; 307 } 308 case SkAdvancedTypefaceMetrics::WidthRange::kRun: { 309 SkASSERT(advanceInfo->fAdvance.count() == 1); 310 result->append(new SkPDFInt(advanceInfo->fStartId))->unref(); 311 result->append(new SkPDFInt(advanceInfo->fEndId))->unref(); 312 appendAdvance(advanceInfo->fAdvance[0], emSize, result); 313 break; 314 } 315 } 316 } 317 return result; 318 } 319 320 } // namespace 321 322 static void append_tounicode_header(SkDynamicMemoryWStream* cmap) { 323 // 12 dict begin: 12 is an Adobe-suggested value. Shall not change. 324 // It's there to prevent old version Adobe Readers from malfunctioning. 325 const char* kHeader = 326 "/CIDInit /ProcSet findresource begin\n" 327 "12 dict begin\n" 328 "begincmap\n"; 329 cmap->writeText(kHeader); 330 331 // The /CIDSystemInfo must be consistent to the one in 332 // SkPDFFont::populateCIDFont(). 333 // We can not pass over the system info object here because the format is 334 // different. This is not a reference object. 335 const char* kSysInfo = 336 "/CIDSystemInfo\n" 337 "<< /Registry (Adobe)\n" 338 "/Ordering (UCS)\n" 339 "/Supplement 0\n" 340 ">> def\n"; 341 cmap->writeText(kSysInfo); 342 343 // The CMapName must be consistent to /CIDSystemInfo above. 344 // /CMapType 2 means ToUnicode. 345 // We specify codespacerange from 0x0000 to 0xFFFF because we convert our 346 // code table from unsigned short (16-bits). Codespace range just tells the 347 // PDF processor the valid range. It does not matter whether a complete 348 // mapping is provided or not. 349 const char* kTypeInfo = 350 "/CMapName /Adobe-Identity-UCS def\n" 351 "/CMapType 2 def\n" 352 "1 begincodespacerange\n" 353 "<0000> <FFFF>\n" 354 "endcodespacerange\n"; 355 cmap->writeText(kTypeInfo); 356 } 357 358 static void append_cmap_bfchar_table(uint16_t* glyph_id, SkUnichar* unicode, 359 size_t count, 360 SkDynamicMemoryWStream* cmap) { 361 cmap->writeDecAsText(count); 362 cmap->writeText(" beginbfchar\n"); 363 for (size_t i = 0; i < count; ++i) { 364 cmap->writeText("<"); 365 cmap->writeHexAsText(glyph_id[i], 4); 366 cmap->writeText("> <"); 367 cmap->writeHexAsText(unicode[i], 4); 368 cmap->writeText(">\n"); 369 } 370 cmap->writeText("endbfchar\n"); 371 } 372 373 static void append_cmap_footer(SkDynamicMemoryWStream* cmap) { 374 const char* kFooter = 375 "endcmap\n" 376 "CMapName currentdict /CMap defineresource pop\n" 377 "end\n" 378 "end"; 379 cmap->writeText(kFooter); 380 } 381 382 // Generate <bfchar> table according to PDF spec 1.4 and Adobe Technote 5014. 383 static void append_cmap_bfchar_sections( 384 const SkTDArray<SkUnichar>& glyphUnicode, 385 SkDynamicMemoryWStream* cmap) { 386 // PDF spec defines that every bf* list can have at most 100 entries. 387 const size_t kMaxEntries = 100; 388 uint16_t glyphId[kMaxEntries]; 389 SkUnichar unicode[kMaxEntries]; 390 size_t index = 0; 391 for (int i = 0; i < glyphUnicode.count(); i++) { 392 if (glyphUnicode[i]) { 393 glyphId[index] = i; 394 unicode[index] = glyphUnicode[i]; 395 ++index; 396 } 397 if (index == kMaxEntries) { 398 append_cmap_bfchar_table(glyphId, unicode, index, cmap); 399 index = 0; 400 } 401 } 402 403 if (index) { 404 append_cmap_bfchar_table(glyphId, unicode, index, cmap); 405 } 406 } 407 408 /* Font subset design: It would be nice to be able to subset fonts 409 * (particularly type 3 fonts), but it's a lot of work and not a priority. 410 * 411 * Resources are canonicalized and uniqueified by pointer so there has to be 412 * some additional state indicating which subset of the font is used. It 413 * must be maintained at the page granularity and then combined at the document 414 * granularity. a) change SkPDFFont to fill in its state on demand, kind of 415 * like SkPDFGraphicState. b) maintain a per font glyph usage class in each 416 * page/pdf device. c) in the document, retrieve the per font glyph usage 417 * from each page and combine it and ask for a resource with that subset. 418 */ 419 420 SkPDFFont::~SkPDFFont() { 421 SkAutoMutexAcquire lock(canonicalFontsMutex()); 422 int index; 423 if (find(SkTypeface::UniqueID(fTypeface.get()), fFirstGlyphID, &index)) { 424 canonicalFonts().removeShuffle(index); 425 #ifdef SK_DEBUG 426 SkASSERT(!fDescendant); 427 } else { 428 SkASSERT(fDescendant); 429 #endif 430 } 431 fResources.unrefAll(); 432 } 433 434 void SkPDFFont::getResources(SkTDArray<SkPDFObject*>* resourceList) { 435 resourceList->setReserve(resourceList->count() + fResources.count()); 436 for (int i = 0; i < fResources.count(); i++) { 437 resourceList->push(fResources[i]); 438 fResources[i]->ref(); 439 fResources[i]->getResources(resourceList); 440 } 441 } 442 443 SkTypeface* SkPDFFont::typeface() { 444 return fTypeface.get(); 445 } 446 447 SkAdvancedTypefaceMetrics::FontType SkPDFFont::getType() { 448 return fType; 449 } 450 451 bool SkPDFFont::hasGlyph(uint16_t id) { 452 return (id >= fFirstGlyphID && id <= fLastGlyphID) || id == 0; 453 } 454 455 bool SkPDFFont::multiByteGlyphs() { 456 return fMultiByteGlyphs; 457 } 458 459 size_t SkPDFFont::glyphsToPDFFontEncoding(uint16_t* glyphIDs, 460 size_t numGlyphs) { 461 // A font with multibyte glyphs will support all glyph IDs in a single font. 462 if (fMultiByteGlyphs) { 463 return numGlyphs; 464 } 465 466 for (size_t i = 0; i < numGlyphs; i++) { 467 if (glyphIDs[i] == 0) { 468 continue; 469 } 470 if (glyphIDs[i] < fFirstGlyphID || glyphIDs[i] > fLastGlyphID) { 471 return i; 472 } 473 glyphIDs[i] -= (fFirstGlyphID - 1); 474 } 475 476 return numGlyphs; 477 } 478 479 // static 480 SkPDFFont* SkPDFFont::getFontResource(SkTypeface* typeface, uint16_t glyphID) { 481 SkAutoMutexAcquire lock(canonicalFontsMutex()); 482 const uint32_t fontID = SkTypeface::UniqueID(typeface); 483 int index; 484 if (find(fontID, glyphID, &index)) { 485 canonicalFonts()[index].fFont->ref(); 486 return canonicalFonts()[index].fFont; 487 } 488 489 SkRefPtr<SkAdvancedTypefaceMetrics> fontInfo; 490 SkPDFDict* fontDescriptor = NULL; 491 if (index >= 0) { 492 SkPDFFont* relatedFont = canonicalFonts()[index].fFont; 493 SkASSERT(relatedFont->fFontInfo.get()); 494 fontInfo = relatedFont->fFontInfo; 495 fontDescriptor = relatedFont->fDescriptor.get(); 496 } else { 497 SkAdvancedTypefaceMetrics::PerGlyphInfo info; 498 info = SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo; 499 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( 500 info, SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo); 501 info = SkTBitOr<SkAdvancedTypefaceMetrics::PerGlyphInfo>( 502 info, SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo); 503 fontInfo = SkFontHost::GetAdvancedTypefaceMetrics(fontID, info); 504 SkSafeUnref(fontInfo.get()); // SkRefPtr and Get both took a reference. 505 } 506 507 SkPDFFont* font = new SkPDFFont(fontInfo.get(), typeface, glyphID, false, 508 fontDescriptor); 509 FontRec newEntry(font, fontID, font->fFirstGlyphID); 510 index = canonicalFonts().count(); 511 canonicalFonts().push(newEntry); 512 return font; // Return the reference new SkPDFFont() created. 513 } 514 515 // static 516 SkTDArray<SkPDFFont::FontRec>& SkPDFFont::canonicalFonts() { 517 // This initialization is only thread safe with gcc. 518 static SkTDArray<FontRec> gCanonicalFonts; 519 return gCanonicalFonts; 520 } 521 522 // static 523 SkMutex& SkPDFFont::canonicalFontsMutex() { 524 // This initialization is only thread safe with gcc. 525 static SkMutex gCanonicalFontsMutex; 526 return gCanonicalFontsMutex; 527 } 528 529 // static 530 bool SkPDFFont::find(uint32_t fontID, uint16_t glyphID, int* index) { 531 // TODO(vandebo) optimize this, do only one search? 532 FontRec search(NULL, fontID, glyphID); 533 *index = canonicalFonts().find(search); 534 if (*index >= 0) 535 return true; 536 search.fGlyphID = 0; 537 *index = canonicalFonts().find(search); 538 return false; 539 } 540 541 SkPDFFont::SkPDFFont(class SkAdvancedTypefaceMetrics* fontInfo, 542 SkTypeface* typeface, 543 uint16_t glyphID, 544 bool descendantFont, 545 SkPDFDict* fontDescriptor) 546 : SkPDFDict("Font"), 547 fTypeface(typeface), 548 fType(fontInfo ? fontInfo->fType : 549 SkAdvancedTypefaceMetrics::kNotEmbeddable_Font), 550 #ifdef SK_DEBUG 551 fDescendant(descendantFont), 552 #endif 553 fMultiByteGlyphs(false), 554 fFirstGlyphID(1), 555 fLastGlyphID(fontInfo ? fontInfo->fLastGlyphID : 0), 556 fFontInfo(fontInfo), 557 fDescriptor(fontDescriptor) { 558 if (fontInfo && fontInfo->fMultiMaster) { 559 NOT_IMPLEMENTED(true, true); 560 fType = SkAdvancedTypefaceMetrics::kOther_Font; 561 } 562 if (fType == SkAdvancedTypefaceMetrics::kType1CID_Font || 563 fType == SkAdvancedTypefaceMetrics::kTrueType_Font) { 564 if (descendantFont) { 565 populateCIDFont(); 566 } else { 567 populateType0Font(); 568 } 569 // No need to hold onto the font info for fonts types that 570 // support multibyte glyphs. 571 fFontInfo = NULL; 572 return; 573 } 574 575 if (fType == SkAdvancedTypefaceMetrics::kType1_Font && 576 populateType1Font(glyphID)) { 577 return; 578 } 579 580 SkASSERT(fType == SkAdvancedTypefaceMetrics::kType1_Font || 581 fType == SkAdvancedTypefaceMetrics::kCFF_Font || 582 fType == SkAdvancedTypefaceMetrics::kOther_Font || 583 fType == SkAdvancedTypefaceMetrics::kNotEmbeddable_Font); 584 populateType3Font(glyphID); 585 } 586 587 void SkPDFFont::populateType0Font() { 588 fMultiByteGlyphs = true; 589 590 insert("Subtype", new SkPDFName("Type0"))->unref(); 591 insert("BaseFont", new SkPDFName(fFontInfo->fFontName))->unref(); 592 insert("Encoding", new SkPDFName("Identity-H"))->unref(); 593 594 SkRefPtr<SkPDFArray> descendantFonts = new SkPDFArray(); 595 descendantFonts->unref(); // SkRefPtr and new took a reference. 596 597 // Pass ref new created to fResources. 598 fResources.push( 599 new SkPDFFont(fFontInfo.get(), fTypeface.get(), 1, true, NULL)); 600 descendantFonts->append(new SkPDFObjRef(fResources.top()))->unref(); 601 insert("DescendantFonts", descendantFonts.get()); 602 603 populateToUnicodeTable(); 604 } 605 606 void SkPDFFont::populateToUnicodeTable() { 607 if (fFontInfo.get() == NULL || 608 fFontInfo->fGlyphToUnicode.begin() == NULL) { 609 return; 610 } 611 612 SkDynamicMemoryWStream cmap; 613 append_tounicode_header(&cmap); 614 append_cmap_bfchar_sections(fFontInfo->fGlyphToUnicode, &cmap); 615 append_cmap_footer(&cmap); 616 SkRefPtr<SkMemoryStream> cmapStream = new SkMemoryStream(); 617 cmapStream->unref(); // SkRefPtr and new took a reference. 618 cmapStream->setMemoryOwned(cmap.detach(), cmap.getOffset()); 619 SkRefPtr<SkPDFStream> pdfCmap = new SkPDFStream(cmapStream.get()); 620 fResources.push(pdfCmap.get()); // Pass reference from new. 621 insert("ToUnicode", new SkPDFObjRef(pdfCmap.get()))->unref(); 622 } 623 624 void SkPDFFont::populateCIDFont() { 625 fMultiByteGlyphs = true; 626 insert("BaseFont", new SkPDFName(fFontInfo->fFontName))->unref(); 627 628 if (fFontInfo->fType == SkAdvancedTypefaceMetrics::kType1CID_Font) { 629 insert("Subtype", new SkPDFName("CIDFontType0"))->unref(); 630 } else if (fFontInfo->fType == SkAdvancedTypefaceMetrics::kTrueType_Font) { 631 insert("Subtype", new SkPDFName("CIDFontType2"))->unref(); 632 insert("CIDToGIDMap", new SkPDFName("Identity"))->unref(); 633 } else { 634 SkASSERT(false); 635 } 636 637 SkRefPtr<SkPDFDict> sysInfo = new SkPDFDict; 638 sysInfo->unref(); // SkRefPtr and new both took a reference. 639 sysInfo->insert("Registry", new SkPDFString("Adobe"))->unref(); 640 sysInfo->insert("Ordering", new SkPDFString("Identity"))->unref(); 641 sysInfo->insert("Supplement", new SkPDFInt(0))->unref(); 642 insert("CIDSystemInfo", sysInfo.get()); 643 644 addFontDescriptor(0); 645 646 if (fFontInfo->fGlyphWidths.get()) { 647 int16_t defaultWidth = 0; 648 SkRefPtr<SkPDFArray> widths = 649 composeAdvanceData(fFontInfo->fGlyphWidths.get(), 650 fFontInfo->fEmSize, &appendWidth, &defaultWidth); 651 widths->unref(); // SkRefPtr and compose both took a reference. 652 if (widths->size()) 653 insert("W", widths.get()); 654 if (defaultWidth != 0) { 655 insert("DW", new SkPDFScalar(scaleFromFontUnits( 656 defaultWidth, fFontInfo->fEmSize)))->unref(); 657 } 658 } 659 if (fFontInfo->fVerticalMetrics.get()) { 660 struct SkAdvancedTypefaceMetrics::VerticalMetric defaultAdvance; 661 defaultAdvance.fVerticalAdvance = 0; 662 defaultAdvance.fOriginXDisp = 0; 663 defaultAdvance.fOriginYDisp = 0; 664 SkRefPtr<SkPDFArray> advances = 665 composeAdvanceData(fFontInfo->fVerticalMetrics.get(), 666 fFontInfo->fEmSize, &appendVerticalAdvance, 667 &defaultAdvance); 668 advances->unref(); // SkRefPtr and compose both took a ref. 669 if (advances->size()) 670 insert("W2", advances.get()); 671 if (defaultAdvance.fVerticalAdvance || 672 defaultAdvance.fOriginXDisp || 673 defaultAdvance.fOriginYDisp) { 674 insert("DW2", appendVerticalAdvance(defaultAdvance, 675 fFontInfo->fEmSize, 676 new SkPDFArray))->unref(); 677 } 678 } 679 } 680 681 bool SkPDFFont::populateType1Font(int16_t glyphID) { 682 SkASSERT(!fFontInfo->fVerticalMetrics.get()); 683 SkASSERT(fFontInfo->fGlyphWidths.get()); 684 685 adjustGlyphRangeForSingleByteEncoding(glyphID); 686 687 int16_t defaultWidth = 0; 688 const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry = NULL; 689 const SkAdvancedTypefaceMetrics::WidthRange* widthEntry; 690 for (widthEntry = fFontInfo.get()->fGlyphWidths.get(); 691 widthEntry != NULL; 692 widthEntry = widthEntry->fNext.get()) { 693 switch (widthEntry->fType) { 694 case SkAdvancedTypefaceMetrics::WidthRange::kDefault: 695 defaultWidth = widthEntry->fAdvance[0]; 696 break; 697 case SkAdvancedTypefaceMetrics::WidthRange::kRun: 698 SkASSERT(false); 699 break; 700 case SkAdvancedTypefaceMetrics::WidthRange::kRange: 701 SkASSERT(widthRangeEntry == NULL); 702 widthRangeEntry = widthEntry; 703 break; 704 } 705 } 706 707 if (!addFontDescriptor(defaultWidth)) 708 return false; 709 710 insert("Subtype", new SkPDFName("Type1"))->unref(); 711 insert("BaseFont", new SkPDFName(fFontInfo->fFontName))->unref(); 712 713 addWidthInfoFromRange(defaultWidth, widthRangeEntry); 714 715 SkRefPtr<SkPDFDict> encoding = new SkPDFDict("Encoding"); 716 encoding->unref(); // SkRefPtr and new both took a reference. 717 insert("Encoding", encoding.get()); 718 719 SkRefPtr<SkPDFArray> encDiffs = new SkPDFArray; 720 encDiffs->unref(); // SkRefPtr and new both took a reference. 721 encoding->insert("Differences", encDiffs.get()); 722 723 encDiffs->reserve(fLastGlyphID - fFirstGlyphID + 2); 724 encDiffs->append(new SkPDFInt(1))->unref(); 725 for (int gID = fFirstGlyphID; gID <= fLastGlyphID; gID++) { 726 encDiffs->append( 727 new SkPDFName(fFontInfo->fGlyphNames->get()[gID]))->unref(); 728 } 729 730 if (fFontInfo->fLastGlyphID <= 255) 731 fFontInfo = NULL; 732 return true; 733 } 734 735 void SkPDFFont::populateType3Font(int16_t glyphID) { 736 SkPaint paint; 737 paint.setTypeface(fTypeface.get()); 738 paint.setTextSize(1000); 739 SkAutoGlyphCache autoCache(paint, NULL); 740 SkGlyphCache* cache = autoCache.getCache(); 741 // If fLastGlyphID isn't set (because there is not fFontInfo), look it up. 742 if (fLastGlyphID == 0) { 743 fLastGlyphID = cache->getGlyphCount() - 1; 744 } 745 746 adjustGlyphRangeForSingleByteEncoding(glyphID); 747 748 insert("Subtype", new SkPDFName("Type3"))->unref(); 749 // Flip about the x-axis and scale by 1/1000. 750 SkMatrix fontMatrix; 751 fontMatrix.setScale(SkScalarInvert(1000), -SkScalarInvert(1000)); 752 insert("FontMatrix", SkPDFUtils::MatrixToArray(fontMatrix))->unref(); 753 754 SkRefPtr<SkPDFDict> charProcs = new SkPDFDict; 755 charProcs->unref(); // SkRefPtr and new both took a reference. 756 insert("CharProcs", charProcs.get()); 757 758 SkRefPtr<SkPDFDict> encoding = new SkPDFDict("Encoding"); 759 encoding->unref(); // SkRefPtr and new both took a reference. 760 insert("Encoding", encoding.get()); 761 762 SkRefPtr<SkPDFArray> encDiffs = new SkPDFArray; 763 encDiffs->unref(); // SkRefPtr and new both took a reference. 764 encoding->insert("Differences", encDiffs.get()); 765 encDiffs->reserve(fLastGlyphID - fFirstGlyphID + 2); 766 encDiffs->append(new SkPDFInt(1))->unref(); 767 768 SkRefPtr<SkPDFArray> widthArray = new SkPDFArray(); 769 widthArray->unref(); // SkRefPtr and new both took a ref. 770 771 SkIRect bbox = SkIRect::MakeEmpty(); 772 for (int gID = fFirstGlyphID; gID <= fLastGlyphID; gID++) { 773 SkString characterName; 774 characterName.printf("gid%d", gID); 775 encDiffs->append(new SkPDFName(characterName))->unref(); 776 777 const SkGlyph& glyph = cache->getGlyphIDMetrics(gID); 778 widthArray->append(new SkPDFScalar(SkFixedToScalar(glyph.fAdvanceX)))->unref(); 779 SkIRect glyphBBox = SkIRect::MakeXYWH(glyph.fLeft, glyph.fTop, 780 glyph.fWidth, glyph.fHeight); 781 bbox.join(glyphBBox); 782 783 SkDynamicMemoryWStream content; 784 setGlyphWidthAndBoundingBox(SkFixedToScalar(glyph.fAdvanceX), glyphBBox, 785 &content); 786 const SkPath* path = cache->findPath(glyph); 787 if (path) { 788 SkPDFUtils::EmitPath(*path, &content); 789 SkPDFUtils::PaintPath(paint.getStyle(), path->getFillType(), 790 &content); 791 } 792 SkRefPtr<SkMemoryStream> glyphStream = new SkMemoryStream(); 793 glyphStream->unref(); // SkRefPtr and new both took a ref. 794 glyphStream->setMemoryOwned(content.detach(), content.getOffset()); 795 796 SkRefPtr<SkPDFStream> glyphDescription = 797 new SkPDFStream(glyphStream.get()); 798 // SkRefPtr and new both ref()'d charProcs, pass one. 799 fResources.push(glyphDescription.get()); 800 charProcs->insert(characterName.c_str(), 801 new SkPDFObjRef(glyphDescription.get()))->unref(); 802 } 803 804 insert("FontBBox", makeFontBBox(bbox, 1000))->unref(); 805 insert("FirstChar", new SkPDFInt(fFirstGlyphID))->unref(); 806 insert("LastChar", new SkPDFInt(fLastGlyphID))->unref(); 807 insert("Widths", widthArray.get()); 808 insert("CIDToGIDMap", new SkPDFName("Identity"))->unref(); 809 810 if (fFontInfo && fFontInfo->fLastGlyphID <= 255) 811 fFontInfo = NULL; 812 813 populateToUnicodeTable(); 814 } 815 816 bool SkPDFFont::addFontDescriptor(int16_t defaultWidth) { 817 if (fDescriptor.get() != NULL) { 818 fResources.push(fDescriptor.get()); 819 fDescriptor->ref(); 820 insert("FontDescriptor", new SkPDFObjRef(fDescriptor.get()))->unref(); 821 return true; 822 } 823 824 fDescriptor = new SkPDFDict("FontDescriptor"); 825 fDescriptor->unref(); // SkRefPtr and new both took a ref. 826 827 switch (fFontInfo->fType) { 828 case SkAdvancedTypefaceMetrics::kType1_Font: { 829 size_t header SK_INIT_TO_AVOID_WARNING; 830 size_t data SK_INIT_TO_AVOID_WARNING; 831 size_t trailer SK_INIT_TO_AVOID_WARNING; 832 SkRefPtr<SkStream> rawFontData = 833 SkFontHost::OpenStream(SkTypeface::UniqueID(fTypeface.get())); 834 rawFontData->unref(); // SkRefPtr and OpenStream both took a ref. 835 SkStream* fontData = handleType1Stream(rawFontData.get(), &header, 836 &data, &trailer); 837 if (fontData == NULL) 838 return false; 839 SkRefPtr<SkPDFStream> fontStream = new SkPDFStream(fontData); 840 // SkRefPtr and new both ref()'d fontStream, pass one. 841 fResources.push(fontStream.get()); 842 fontStream->insert("Length1", new SkPDFInt(header))->unref(); 843 fontStream->insert("Length2", new SkPDFInt(data))->unref(); 844 fontStream->insert("Length3", new SkPDFInt(trailer))->unref(); 845 fDescriptor->insert("FontFile", 846 new SkPDFObjRef(fontStream.get()))->unref(); 847 break; 848 } 849 case SkAdvancedTypefaceMetrics::kTrueType_Font: { 850 SkRefPtr<SkStream> fontData = 851 SkFontHost::OpenStream(SkTypeface::UniqueID(fTypeface.get())); 852 fontData->unref(); // SkRefPtr and OpenStream both took a ref. 853 SkRefPtr<SkPDFStream> fontStream = new SkPDFStream(fontData.get()); 854 // SkRefPtr and new both ref()'d fontStream, pass one. 855 fResources.push(fontStream.get()); 856 857 fontStream->insert("Length1", 858 new SkPDFInt(fontData->getLength()))->unref(); 859 fDescriptor->insert("FontFile2", 860 new SkPDFObjRef(fontStream.get()))->unref(); 861 break; 862 } 863 case SkAdvancedTypefaceMetrics::kCFF_Font: 864 case SkAdvancedTypefaceMetrics::kType1CID_Font: { 865 SkRefPtr<SkStream> fontData = 866 SkFontHost::OpenStream(SkTypeface::UniqueID(fTypeface.get())); 867 fontData->unref(); // SkRefPtr and OpenStream both took a ref. 868 SkRefPtr<SkPDFStream> fontStream = new SkPDFStream(fontData.get()); 869 // SkRefPtr and new both ref()'d fontStream, pass one. 870 fResources.push(fontStream.get()); 871 872 if (fFontInfo->fType == SkAdvancedTypefaceMetrics::kCFF_Font) { 873 fontStream->insert("Subtype", new SkPDFName("Type1C"))->unref(); 874 } else { 875 fontStream->insert("Subtype", 876 new SkPDFName("CIDFontType0c"))->unref(); 877 } 878 fDescriptor->insert("FontFile3", 879 new SkPDFObjRef(fontStream.get()))->unref(); 880 break; 881 } 882 default: 883 SkASSERT(false); 884 } 885 886 const uint16_t emSize = fFontInfo->fEmSize; 887 fResources.push(fDescriptor.get()); 888 fDescriptor->ref(); 889 insert("FontDescriptor", new SkPDFObjRef(fDescriptor.get()))->unref(); 890 891 fDescriptor->insert("FontName", new SkPDFName( 892 fFontInfo->fFontName))->unref(); 893 fDescriptor->insert("Flags", new SkPDFInt(fFontInfo->fStyle))->unref(); 894 fDescriptor->insert("Ascent", new SkPDFScalar( 895 scaleFromFontUnits(fFontInfo->fAscent, emSize)))->unref(); 896 fDescriptor->insert("Descent", new SkPDFScalar( 897 scaleFromFontUnits(fFontInfo->fDescent, emSize)))->unref(); 898 fDescriptor->insert("StemV", new SkPDFScalar( 899 scaleFromFontUnits(fFontInfo->fStemV, emSize)))->unref(); 900 fDescriptor->insert("CapHeight", new SkPDFScalar( 901 scaleFromFontUnits(fFontInfo->fCapHeight, emSize)))->unref(); 902 fDescriptor->insert("ItalicAngle", new SkPDFInt( 903 fFontInfo->fItalicAngle))->unref(); 904 fDescriptor->insert("FontBBox", makeFontBBox(fFontInfo->fBBox, 905 fFontInfo->fEmSize))->unref(); 906 907 if (defaultWidth > 0) { 908 fDescriptor->insert("MissingWidth", new SkPDFScalar( 909 scaleFromFontUnits(defaultWidth, emSize)))->unref(); 910 } 911 return true; 912 } 913 void SkPDFFont::addWidthInfoFromRange( 914 int16_t defaultWidth, 915 const SkAdvancedTypefaceMetrics::WidthRange* widthRangeEntry) { 916 SkRefPtr<SkPDFArray> widthArray = new SkPDFArray(); 917 widthArray->unref(); // SkRefPtr and new both took a ref. 918 int firstChar = 0; 919 if (widthRangeEntry) { 920 const uint16_t emSize = fFontInfo->fEmSize; 921 int startIndex = fFirstGlyphID - widthRangeEntry->fStartId; 922 int endIndex = startIndex + fLastGlyphID - fFirstGlyphID + 1; 923 if (startIndex < 0) 924 startIndex = 0; 925 if (endIndex > widthRangeEntry->fAdvance.count()) 926 endIndex = widthRangeEntry->fAdvance.count(); 927 if (widthRangeEntry->fStartId == 0) { 928 appendWidth(widthRangeEntry->fAdvance[0], emSize, widthArray.get()); 929 } else { 930 firstChar = startIndex + widthRangeEntry->fStartId; 931 } 932 for (int i = startIndex; i < endIndex; i++) 933 appendWidth(widthRangeEntry->fAdvance[i], emSize, widthArray.get()); 934 } else { 935 appendWidth(defaultWidth, 1000, widthArray.get()); 936 } 937 insert("FirstChar", new SkPDFInt(firstChar))->unref(); 938 insert("LastChar", 939 new SkPDFInt(firstChar + widthArray->size() - 1))->unref(); 940 insert("Widths", widthArray.get()); 941 } 942 943 void SkPDFFont::adjustGlyphRangeForSingleByteEncoding(int16_t glyphID) { 944 // Single byte glyph encoding supports a max of 255 glyphs. 945 fFirstGlyphID = glyphID - (glyphID - 1) % 255; 946 if (fLastGlyphID > fFirstGlyphID + 255 - 1) { 947 fLastGlyphID = fFirstGlyphID + 255 - 1; 948 } 949 } 950 951 952 bool SkPDFFont::FontRec::operator==(const SkPDFFont::FontRec& b) const { 953 if (fFontID != b.fFontID) 954 return false; 955 if (fFont != NULL && b.fFont != NULL) { 956 return fFont->fFirstGlyphID == b.fFont->fFirstGlyphID && 957 fFont->fLastGlyphID == b.fFont->fLastGlyphID; 958 } 959 if (fGlyphID == 0 || b.fGlyphID == 0) 960 return true; 961 962 if (fFont != NULL) { 963 return fFont->fFirstGlyphID <= b.fGlyphID && 964 b.fGlyphID <= fFont->fLastGlyphID; 965 } else if (b.fFont != NULL) { 966 return b.fFont->fFirstGlyphID <= fGlyphID && 967 fGlyphID <= b.fFont->fLastGlyphID; 968 } 969 return fGlyphID == b.fGlyphID; 970 } 971 972 SkPDFFont::FontRec::FontRec(SkPDFFont* font, uint32_t fontID, uint16_t glyphID) 973 : fFont(font), 974 fFontID(fontID), 975 fGlyphID(glyphID) { 976 } 977