From 26d2e046cd3e11cb61d1b0b3ace304a6dc8c995b Mon Sep 17 00:00:00 2001 From: "edisonn@google.com" Date: Wed, 18 Sep 2013 19:29:08 +0000 Subject: pdf: write only ToUnicode mappings needed by the font, trimming anything out of [firstChar, lastChar] interval. R=vandebo@chromium.org Review URL: https://codereview.chromium.org/23519006 git-svn-id: http://skia.googlecode.com/svn/trunk@11360 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/pdf/SkPDFFont.cpp | 54 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 20 deletions(-) (limited to 'src/pdf') diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp index 7d8c286e2e..4184e87f05 100644 --- a/src/pdf/SkPDFFont.cpp +++ b/src/pdf/SkPDFFont.cpp @@ -342,7 +342,9 @@ SkPDFArray* composeAdvanceData( } // namespace -static void append_tounicode_header(SkDynamicMemoryWStream* cmap) { +static void append_tounicode_header(SkDynamicMemoryWStream* cmap, + uint16_t firstGlyphID, + uint16_t lastGlyphID) { // 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 = @@ -365,17 +367,20 @@ static void append_tounicode_header(SkDynamicMemoryWStream* cmap) { // The CMapName must be consistent to /CIDSystemInfo above. // /CMapType 2 means ToUnicode. - // We specify codespacerange from 0x0000 to 0xFFFF because we convert our - // code table from unsigned short (16-bits). Codespace range just tells the - // PDF processor the valid range. It does not matter whether a complete - // mapping is provided or not. - const char* kTypeInfo = + // Codespace range just tells the PDF processor the valid range. + const char* kTypeInfoHeader = "/CMapName /Adobe-Identity-UCS def\n" "/CMapType 2 def\n" - "1 begincodespacerange\n" - "<0000> \n" - "endcodespacerange\n"; - cmap->writeText(kTypeInfo); + "1 begincodespacerange\n"; + cmap->writeText(kTypeInfoHeader); + + // e.g. "<0000> \n" + SkString range; + range.appendf("<%04X> <%04X>\n", firstGlyphID, lastGlyphID); + cmap->writeText(range.c_str()); + + const char* kTypeInfoFooter = "endcodespacerange\n"; + cmap->writeText(kTypeInfoFooter); } static void append_cmap_footer(SkDynamicMemoryWStream* cmap) { @@ -469,11 +474,15 @@ static void append_bfrange_section(const SkTDArray& bfrange, // ( see caller in tests/ToUnicode.cpp ) void append_cmap_sections(const SkTDArray& glyphToUnicode, const SkPDFGlyphSet* subset, - SkDynamicMemoryWStream* cmap); + SkDynamicMemoryWStream* cmap, + uint16_t firstGlyphID, + uint16_t lastGlyphID); void append_cmap_sections(const SkTDArray& glyphToUnicode, const SkPDFGlyphSet* subset, - SkDynamicMemoryWStream* cmap) { + SkDynamicMemoryWStream* cmap, + uint16_t firstGlyphID, + uint16_t lastGlyphID) { if (glyphToUnicode.isEmpty()) { return; } @@ -483,10 +492,11 @@ void append_cmap_sections(const SkTDArray& glyphToUnicode, BFRange currentRangeEntry = {0, 0, 0}; bool rangeEmpty = true; - const int count = glyphToUnicode.count(); + const int limit = SkMin32(lastGlyphID + 1, glyphToUnicode.count()); - for (int i = 0; i < count + 1; ++i) { - bool inSubset = i < count && (subset == NULL || subset->has(i)); + for (int i = firstGlyphID; i < limit + 1; ++i) { + bool inSubset = i < limit && + (subset == NULL || subset->has(i)); if (!rangeEmpty) { // PDF spec requires bfrange not changing the higher byte, // e.g. <1035> <10FF> <2222> is ok, but @@ -494,7 +504,7 @@ void append_cmap_sections(const SkTDArray& glyphToUnicode, bool inRange = i == currentRangeEntry.fEnd + 1 && i >> 8 == currentRangeEntry.fStart >> 8 && - i < count && + i < limit && glyphToUnicode[i] == currentRangeEntry.fUnicode + i - currentRangeEntry.fStart; if (!inSubset || !inRange) { @@ -526,10 +536,13 @@ void append_cmap_sections(const SkTDArray& glyphToUnicode, static SkPDFStream* generate_tounicode_cmap( const SkTDArray& glyphToUnicode, - const SkPDFGlyphSet* subset) { + const SkPDFGlyphSet* subset, + uint16_t firstGlyphID, + uint16_t lastGlyphID) { SkDynamicMemoryWStream cmap; - append_tounicode_header(&cmap); - append_cmap_sections(glyphToUnicode, subset, &cmap); + append_tounicode_header(&cmap, firstGlyphID, lastGlyphID); + append_cmap_sections(glyphToUnicode, subset, &cmap, + firstGlyphID, lastGlyphID); append_cmap_footer(&cmap); SkAutoTUnref cmapStream(new SkMemoryStream()); cmapStream->setData(cmap.copyToData())->unref(); @@ -1015,7 +1028,8 @@ void SkPDFFont::populateToUnicodeTable(const SkPDFGlyphSet* subset) { return; } SkAutoTUnref pdfCmap( - generate_tounicode_cmap(fFontInfo->fGlyphToUnicode, subset)); + generate_tounicode_cmap(fFontInfo->fGlyphToUnicode, subset, + firstGlyphID(), lastGlyphID())); addResource(pdfCmap.get()); insert("ToUnicode", new SkPDFObjRef(pdfCmap.get()))->unref(); } -- cgit v1.2.3