 Chromium Code Reviews
 Chromium Code Reviews Issue 2292303004:
  SkPDF: Fix Type3 ToUnicode table.  (Closed)
    
  
    Issue 2292303004:
  SkPDF: Fix Type3 ToUnicode table.  (Closed) 
  | Index: src/pdf/SkPDFMakeToUnicodeCmap.cpp | 
| diff --git a/src/pdf/SkPDFMakeToUnicodeCmap.cpp b/src/pdf/SkPDFMakeToUnicodeCmap.cpp | 
| index 5186cbbda1955dbda41fcc25ed5600c5d41cb875..7fc5c59be35fcaddffb07522ecd6c1a411821496 100644 | 
| --- a/src/pdf/SkPDFMakeToUnicodeCmap.cpp | 
| +++ b/src/pdf/SkPDFMakeToUnicodeCmap.cpp | 
| @@ -10,8 +10,7 @@ | 
| #include "SkUtils.h" | 
| static void append_tounicode_header(SkDynamicMemoryWStream* cmap, | 
| - SkGlyphID firstGlyphID, | 
| - SkGlyphID lastGlyphID) { | 
| + bool multibyte) { | 
| // 12 dict begin: 12 is an Adobe-suggested value. Shall not change. | 
| // It's there to prevent old version Adobe Readers from malfunctioning. | 
| const char* kHeader = | 
| @@ -26,8 +25,8 @@ static void append_tounicode_header(SkDynamicMemoryWStream* cmap, | 
| // different. This is not a reference object. | 
| const char* kSysInfo = | 
| "/CIDSystemInfo\n" | 
| - "<< /Registry (Adobe)\n" | 
| - "/Ordering (UCS)\n" | 
| + "<< /Registry (Skia)\n" | 
| + "/Ordering (SkiaOrdering)\n" | 
| 
Rik
2016/09/01 17:41:21
Please leave this as-is
 | 
| "/Supplement 0\n" | 
| ">> def\n"; | 
| cmap->writeText(kSysInfo); | 
| @@ -36,18 +35,16 @@ static void append_tounicode_header(SkDynamicMemoryWStream* cmap, | 
| // /CMapType 2 means ToUnicode. | 
| // Codespace range just tells the PDF processor the valid range. | 
| const char* kTypeInfoHeader = | 
| - "/CMapName /Adobe-Identity-UCS def\n" | 
| + "/CMapName /Skia-Identity-SkiaOrdering def\n" | 
| "/CMapType 2 def\n" | 
| "1 begincodespacerange\n"; | 
| cmap->writeText(kTypeInfoHeader); | 
| - | 
| - // e.g. "<0000> <FFFF>\n" | 
| - SkString range; | 
| - range.appendf("<%04X> <%04X>\n", firstGlyphID, lastGlyphID); | 
| - cmap->writeText(range.c_str()); | 
| - | 
| - const char* kTypeInfoFooter = "endcodespacerange\n"; | 
| - cmap->writeText(kTypeInfoFooter); | 
| + if (multibyte) { | 
| + cmap->writeText("<0000> <FFFF>\n"); | 
| + } else { | 
| + cmap->writeText("<00> <FF>\n"); | 
| + } | 
| + cmap->writeText("endcodespacerange\n"); | 
| } | 
| static void append_cmap_footer(SkDynamicMemoryWStream* cmap) { | 
| @@ -82,7 +79,18 @@ static void write_utf16be(SkDynamicMemoryWStream* wStream, SkUnichar utf32) { | 
| } | 
| } | 
| +static void write_glyph(SkDynamicMemoryWStream* cmap, | 
| + bool multiByte, | 
| + SkGlyphID gid) { | 
| + if (multiByte) { | 
| + SkPDFUtils::WriteUInt16BE(cmap, gid); | 
| + } else { | 
| + SkPDFUtils::WriteUInt8(cmap, SkToU8(gid)); | 
| + } | 
| +} | 
| + | 
| static void append_bfchar_section(const SkTDArray<BFChar>& bfchar, | 
| + bool multiByte, | 
| SkDynamicMemoryWStream* cmap) { | 
| // PDF spec defines that every bf* list can have at most 100 entries. | 
| for (int i = 0; i < bfchar.count(); i += 100) { | 
| @@ -92,7 +100,7 @@ static void append_bfchar_section(const SkTDArray<BFChar>& bfchar, | 
| cmap->writeText(" beginbfchar\n"); | 
| for (int j = 0; j < count; ++j) { | 
| cmap->writeText("<"); | 
| - SkPDFUtils::WriteUInt16BE(cmap, bfchar[i + j].fGlyphId); | 
| + write_glyph(cmap, multiByte, bfchar[i + j].fGlyphId); | 
| cmap->writeText("> <"); | 
| write_utf16be(cmap, bfchar[i + j].fUnicode); | 
| cmap->writeText(">\n"); | 
| @@ -102,6 +110,7 @@ static void append_bfchar_section(const SkTDArray<BFChar>& bfchar, | 
| } | 
| static void append_bfrange_section(const SkTDArray<BFRange>& bfrange, | 
| + bool multiByte, | 
| SkDynamicMemoryWStream* cmap) { | 
| // PDF spec defines that every bf* list can have at most 100 entries. | 
| for (int i = 0; i < bfrange.count(); i += 100) { | 
| @@ -111,9 +120,9 @@ static void append_bfrange_section(const SkTDArray<BFRange>& bfrange, | 
| cmap->writeText(" beginbfrange\n"); | 
| for (int j = 0; j < count; ++j) { | 
| cmap->writeText("<"); | 
| - SkPDFUtils::WriteUInt16BE(cmap, bfrange[i + j].fStart); | 
| + write_glyph(cmap, multiByte, bfrange[i + j].fStart); | 
| cmap->writeText("> <"); | 
| - SkPDFUtils::WriteUInt16BE(cmap, bfrange[i + j].fEnd); | 
| + write_glyph(cmap, multiByte, bfrange[i + j].fEnd); | 
| cmap->writeText("> <"); | 
| write_utf16be(cmap, bfrange[i + j].fUnicode); | 
| cmap->writeText(">\n"); | 
| @@ -206,8 +215,8 @@ void SkPDFAppendCmapSections(const SkTDArray<SkUnichar>& glyphToUnicode, | 
| // The spec requires all bfchar entries for a font must come before bfrange | 
| // entries. | 
| - append_bfchar_section(bfcharEntries, cmap); | 
| - append_bfrange_section(bfrangeEntries, cmap); | 
| + append_bfchar_section(bfcharEntries, multiByteGlyphs, cmap); | 
| + append_bfrange_section(bfrangeEntries, multiByteGlyphs, cmap); | 
| } | 
| sk_sp<SkPDFStream> SkPDFMakeToUnicodeCmap( | 
| @@ -217,11 +226,7 @@ sk_sp<SkPDFStream> SkPDFMakeToUnicodeCmap( | 
| SkGlyphID firstGlyphID, | 
| SkGlyphID lastGlyphID) { | 
| SkDynamicMemoryWStream cmap; | 
| - if (multiByteGlyphs) { | 
| - append_tounicode_header(&cmap, firstGlyphID, lastGlyphID); | 
| - } else { | 
| - append_tounicode_header(&cmap, 1, lastGlyphID - firstGlyphID + 1); | 
| - } | 
| + append_tounicode_header(&cmap, multiByteGlyphs); | 
| SkPDFAppendCmapSections(glyphToUnicode, subset, &cmap, multiByteGlyphs, | 
| firstGlyphID, lastGlyphID); | 
| append_cmap_footer(&cmap); |