| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2011 Google Inc. | 2  * Copyright 2011 Google Inc. | 
| 3  * | 3  * | 
| 4  * Use of this source code is governed by a BSD-style license that can be | 4  * Use of this source code is governed by a BSD-style license that can be | 
| 5  * found in the LICENSE file. | 5  * found in the LICENSE file. | 
| 6  */ | 6  */ | 
| 7 | 7 | 
| 8 #include <ctype.h> | 8 #include <ctype.h> | 
| 9 | 9 | 
| 10 #include "SkData.h" | 10 #include "SkData.h" | 
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 453 // following case because the specification is not clear. | 453 // following case because the specification is not clear. | 
| 454 // | 454 // | 
| 455 // 4 beginbfchar          1 beginbfchar | 455 // 4 beginbfchar          1 beginbfchar | 
| 456 // <0003> <0013>          <0020> <0014> | 456 // <0003> <0013>          <0020> <0014> | 
| 457 // <0005> <0015>    to    endbfchar | 457 // <0005> <0015>    to    endbfchar | 
| 458 // <0007> <0017>          1 beginbfrange | 458 // <0007> <0017>          1 beginbfrange | 
| 459 // <0020> <0014>          <0003> <0007> <0013> | 459 // <0020> <0014>          <0003> <0007> <0013> | 
| 460 // endbfchar              endbfrange | 460 // endbfchar              endbfrange | 
| 461 // | 461 // | 
| 462 // Adobe Technote 5014 said: "Code mappings (unlike codespace ranges) may | 462 // Adobe Technote 5014 said: "Code mappings (unlike codespace ranges) may | 
| 463 // overlap, but succeeding maps superceded preceding maps." | 463 // overlap, but succeeding maps supersede preceding maps." | 
| 464 // | 464 // | 
| 465 // In case of searching text in PDF, bfrange will have higher precedence so | 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, | 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. | 467 // the spec does not mention how will this kind of conflict being resolved. | 
| 468 // | 468 // | 
| 469 // For the worst case (having 65536 continuous unicode and we use every other | 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 | 470 // one of them), the possible savings by aggressive optimization is 416KB | 
| 471 // pre-compressed and does not provide enough motivation for implementation. | 471 // pre-compressed and does not provide enough motivation for implementation. | 
| 472 | 472 | 
| 473 // FIXME: this should be in a header so that it is separately testable | 473 // FIXME: this should be in a header so that it is separately testable | 
| 474 // ( see caller in tests/ToUnicode.cpp ) | 474 // ( see caller in tests/ToUnicode.cpp ) | 
| 475 void append_cmap_sections(const SkTDArray<SkUnichar>& glyphToUnicode, | 475 void append_cmap_sections(const SkTDArray<SkUnichar>& glyphToUnicode, | 
| 476                           const SkPDFGlyphSet* subset, | 476                           const SkPDFGlyphSet* subset, | 
| 477                           SkDynamicMemoryWStream* cmap, | 477                           SkDynamicMemoryWStream* cmap, | 
|  | 478                           bool multiByteGlyphs, | 
| 478                           uint16_t firstGlyphID, | 479                           uint16_t firstGlyphID, | 
| 479                           uint16_t lastGlyphID); | 480                           uint16_t lastGlyphID); | 
| 480 | 481 | 
| 481 void append_cmap_sections(const SkTDArray<SkUnichar>& glyphToUnicode, | 482 void append_cmap_sections(const SkTDArray<SkUnichar>& glyphToUnicode, | 
| 482                           const SkPDFGlyphSet* subset, | 483                           const SkPDFGlyphSet* subset, | 
| 483                           SkDynamicMemoryWStream* cmap, | 484                           SkDynamicMemoryWStream* cmap, | 
|  | 485                           bool multiByteGlyphs, | 
| 484                           uint16_t firstGlyphID, | 486                           uint16_t firstGlyphID, | 
| 485                           uint16_t lastGlyphID) { | 487                           uint16_t lastGlyphID) { | 
| 486     if (glyphToUnicode.isEmpty()) { | 488     if (glyphToUnicode.isEmpty()) { | 
| 487         return; | 489         return; | 
| 488     } | 490     } | 
|  | 491     int glyphOffset = 0; | 
|  | 492     if (!multiByteGlyphs) { | 
|  | 493         glyphOffset = firstGlyphID - 1; | 
|  | 494     } | 
| 489 | 495 | 
| 490     SkTDArray<BFChar> bfcharEntries; | 496     SkTDArray<BFChar> bfcharEntries; | 
| 491     SkTDArray<BFRange> bfrangeEntries; | 497     SkTDArray<BFRange> bfrangeEntries; | 
| 492 | 498 | 
| 493     BFRange currentRangeEntry = {0, 0, 0}; | 499     BFRange currentRangeEntry = {0, 0, 0}; | 
| 494     bool rangeEmpty = true; | 500     bool rangeEmpty = true; | 
| 495     const int limit = SkMin32(lastGlyphID + 1, glyphToUnicode.count()); | 501     const int limit = | 
|  | 502             SkMin32(lastGlyphID + 1, glyphToUnicode.count()) - glyphOffset; | 
| 496 | 503 | 
| 497     for (int i = firstGlyphID; i < limit + 1; ++i) { | 504     for (int i = firstGlyphID - glyphOffset; i < limit + 1; ++i) { | 
| 498         bool inSubset = i < limit && | 505         bool inSubset = i < limit && | 
| 499                         (subset == NULL || subset->has(i)); | 506                         (subset == NULL || subset->has(i + glyphOffset)); | 
| 500         if (!rangeEmpty) { | 507         if (!rangeEmpty) { | 
| 501             // PDF spec requires bfrange not changing the higher byte, | 508             // PDF spec requires bfrange not changing the higher byte, | 
| 502             // e.g. <1035> <10FF> <2222> is ok, but | 509             // e.g. <1035> <10FF> <2222> is ok, but | 
| 503             //      <1035> <1100> <2222> is no good | 510             //      <1035> <1100> <2222> is no good | 
| 504             bool inRange = | 511             bool inRange = | 
| 505                 i == currentRangeEntry.fEnd + 1 && | 512                 i == currentRangeEntry.fEnd + 1 && | 
| 506                 i >> 8 == currentRangeEntry.fStart >> 8 && | 513                 i >> 8 == currentRangeEntry.fStart >> 8 && | 
| 507                 i < limit && | 514                 i < limit && | 
| 508                 glyphToUnicode[i] == currentRangeEntry.fUnicode + i - | 515                 glyphToUnicode[i + glyphOffset] == | 
| 509                                          currentRangeEntry.fStart; | 516                     currentRangeEntry.fUnicode + i - currentRangeEntry.fStart; | 
| 510             if (!inSubset || !inRange) { | 517             if (!inSubset || !inRange) { | 
| 511                 if (currentRangeEntry.fEnd > currentRangeEntry.fStart) { | 518                 if (currentRangeEntry.fEnd > currentRangeEntry.fStart) { | 
| 512                     bfrangeEntries.push(currentRangeEntry); | 519                     bfrangeEntries.push(currentRangeEntry); | 
| 513                 } else { | 520                 } else { | 
| 514                     BFChar* entry = bfcharEntries.append(); | 521                     BFChar* entry = bfcharEntries.append(); | 
| 515                     entry->fGlyphId = currentRangeEntry.fStart; | 522                     entry->fGlyphId = currentRangeEntry.fStart; | 
| 516                     entry->fUnicode = currentRangeEntry.fUnicode; | 523                     entry->fUnicode = currentRangeEntry.fUnicode; | 
| 517                 } | 524                 } | 
| 518                 rangeEmpty = true; | 525                 rangeEmpty = true; | 
| 519             } | 526             } | 
| 520         } | 527         } | 
| 521         if (inSubset) { | 528         if (inSubset) { | 
| 522             currentRangeEntry.fEnd = i; | 529             currentRangeEntry.fEnd = i; | 
| 523             if (rangeEmpty) { | 530             if (rangeEmpty) { | 
| 524               currentRangeEntry.fStart = i; | 531               currentRangeEntry.fStart = i; | 
| 525               currentRangeEntry.fUnicode = glyphToUnicode[i]; | 532               currentRangeEntry.fUnicode = glyphToUnicode[i + glyphOffset]; | 
| 526               rangeEmpty = false; | 533               rangeEmpty = false; | 
| 527             } | 534             } | 
| 528         } | 535         } | 
| 529     } | 536     } | 
| 530 | 537 | 
| 531     // The spec requires all bfchar entries for a font must come before bfrange | 538     // The spec requires all bfchar entries for a font must come before bfrange | 
| 532     // entries. | 539     // entries. | 
| 533     append_bfchar_section(bfcharEntries, cmap); | 540     append_bfchar_section(bfcharEntries, cmap); | 
| 534     append_bfrange_section(bfrangeEntries, cmap); | 541     append_bfrange_section(bfrangeEntries, cmap); | 
| 535 } | 542 } | 
| 536 | 543 | 
| 537 static SkPDFStream* generate_tounicode_cmap( | 544 static SkPDFStream* generate_tounicode_cmap( | 
| 538         const SkTDArray<SkUnichar>& glyphToUnicode, | 545         const SkTDArray<SkUnichar>& glyphToUnicode, | 
| 539         const SkPDFGlyphSet* subset, | 546         const SkPDFGlyphSet* subset, | 
|  | 547         bool multiByteGlyphs, | 
| 540         uint16_t firstGlyphID, | 548         uint16_t firstGlyphID, | 
| 541         uint16_t lastGlyphID) { | 549         uint16_t lastGlyphID) { | 
| 542     SkDynamicMemoryWStream cmap; | 550     SkDynamicMemoryWStream cmap; | 
| 543     append_tounicode_header(&cmap, firstGlyphID, lastGlyphID); | 551     if (multiByteGlyphs) { | 
| 544     append_cmap_sections(glyphToUnicode, subset, &cmap, | 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, | 
| 545                          firstGlyphID, lastGlyphID); | 557                          firstGlyphID, lastGlyphID); | 
| 546     append_cmap_footer(&cmap); | 558     append_cmap_footer(&cmap); | 
| 547     SkAutoTUnref<SkMemoryStream> cmapStream(new SkMemoryStream()); | 559     SkAutoTUnref<SkMemoryStream> cmapStream(new SkMemoryStream()); | 
| 548     cmapStream->setData(cmap.copyToData())->unref(); | 560     cmapStream->setData(cmap.copyToData())->unref(); | 
| 549     return new SkPDFStream(cmapStream.get()); | 561     return new SkPDFStream(cmapStream.get()); | 
| 550 } | 562 } | 
| 551 | 563 | 
| 552 #if defined (SK_SFNTLY_SUBSETTER) | 564 #if defined (SK_SFNTLY_SUBSETTER) | 
| 553 static void sk_delete_array(const void* ptr, size_t, void*) { | 565 static void sk_delete_array(const void* ptr, size_t, void*) { | 
| 554     // Use C-style cast to cast away const and cast type simultaneously. | 566     // Use C-style cast to cast away const and cast type simultaneously. | 
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1037       fFontID(fontID), | 1049       fFontID(fontID), | 
| 1038       fGlyphID(glyphID) { | 1050       fGlyphID(glyphID) { | 
| 1039 } | 1051 } | 
| 1040 | 1052 | 
| 1041 void SkPDFFont::populateToUnicodeTable(const SkPDFGlyphSet* subset) { | 1053 void SkPDFFont::populateToUnicodeTable(const SkPDFGlyphSet* subset) { | 
| 1042     if (fFontInfo == NULL || fFontInfo->fGlyphToUnicode.begin() == NULL) { | 1054     if (fFontInfo == NULL || fFontInfo->fGlyphToUnicode.begin() == NULL) { | 
| 1043         return; | 1055         return; | 
| 1044     } | 1056     } | 
| 1045     SkAutoTUnref<SkPDFStream> pdfCmap( | 1057     SkAutoTUnref<SkPDFStream> pdfCmap( | 
| 1046         generate_tounicode_cmap(fFontInfo->fGlyphToUnicode, subset, | 1058         generate_tounicode_cmap(fFontInfo->fGlyphToUnicode, subset, | 
| 1047                                 firstGlyphID(), lastGlyphID())); | 1059                                 multiByteGlyphs(), firstGlyphID(), | 
|  | 1060                                 lastGlyphID())); | 
| 1048     addResource(pdfCmap.get()); | 1061     addResource(pdfCmap.get()); | 
| 1049     insert("ToUnicode", new SkPDFObjRef(pdfCmap.get()))->unref(); | 1062     insert("ToUnicode", new SkPDFObjRef(pdfCmap.get()))->unref(); | 
| 1050 } | 1063 } | 
| 1051 | 1064 | 
| 1052 /////////////////////////////////////////////////////////////////////////////// | 1065 /////////////////////////////////////////////////////////////////////////////// | 
| 1053 // class SkPDFType0Font | 1066 // class SkPDFType0Font | 
| 1054 /////////////////////////////////////////////////////////////////////////////// | 1067 /////////////////////////////////////////////////////////////////////////////// | 
| 1055 | 1068 | 
| 1056 SkPDFType0Font::SkPDFType0Font(SkAdvancedTypefaceMetrics* info, | 1069 SkPDFType0Font::SkPDFType0Font(SkAdvancedTypefaceMetrics* info, | 
| 1057                                SkTypeface* typeface) | 1070                                SkTypeface* typeface) | 
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1452         glyphStream->setData(content.copyToData())->unref(); | 1465         glyphStream->setData(content.copyToData())->unref(); | 
| 1453 | 1466 | 
| 1454         SkAutoTUnref<SkPDFStream> glyphDescription( | 1467         SkAutoTUnref<SkPDFStream> glyphDescription( | 
| 1455             new SkPDFStream(glyphStream.get())); | 1468             new SkPDFStream(glyphStream.get())); | 
| 1456         addResource(glyphDescription.get()); | 1469         addResource(glyphDescription.get()); | 
| 1457         charProcs->insert(characterName.c_str(), | 1470         charProcs->insert(characterName.c_str(), | 
| 1458                           new SkPDFObjRef(glyphDescription.get()))->unref(); | 1471                           new SkPDFObjRef(glyphDescription.get()))->unref(); | 
| 1459     } | 1472     } | 
| 1460 | 1473 | 
| 1461     insert("FontBBox", makeFontBBox(bbox, 1000))->unref(); | 1474     insert("FontBBox", makeFontBBox(bbox, 1000))->unref(); | 
| 1462     insertInt("FirstChar", firstGlyphID()); | 1475     insertInt("FirstChar", 1); | 
| 1463     insertInt("LastChar", lastGlyphID()); | 1476     insertInt("LastChar", lastGlyphID() - firstGlyphID() + 1); | 
| 1464     insert("Widths", widthArray.get()); | 1477     insert("Widths", widthArray.get()); | 
| 1465     insertName("CIDToGIDMap", "Identity"); | 1478     insertName("CIDToGIDMap", "Identity"); | 
| 1466 | 1479 | 
| 1467     populateToUnicodeTable(NULL); | 1480     populateToUnicodeTable(NULL); | 
| 1468     return true; | 1481     return true; | 
| 1469 } | 1482 } | 
| OLD | NEW | 
|---|