From 9ad3599a3a17f124a96979ad5dcba8ad4a107160 Mon Sep 17 00:00:00 2001 From: "vandebo@chromium.org" Date: Tue, 3 Jan 2012 18:35:39 +0000 Subject: [PATCH] Fix ToUnicode generation bug. Code from arthurhsu@chromium.org Original CL: http://codereview.appspot.com/5492061/ BUG=Chromium:104062 Review URL: http://codereview.appspot.com/5498064 git-svn-id: http://skia.googlecode.com/svn/trunk@2944 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/pdf/SkPDFFont.cpp | 52 +++++++++++++++++++++------------------------------ tests/ToUnicode.cpp | 43 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 32 deletions(-) diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp index 0da5698..404c762 100644 --- a/src/pdf/SkPDFFont.cpp +++ b/src/pdf/SkPDFFont.cpp @@ -474,48 +474,38 @@ void append_cmap_sections(const SkTDArray& glyphToUnicode, SkTDArray bfrangeEntries; BFRange currentRangeEntry; - bool haveBase = false; - int continuousEntries = 0; + bool rangeEmpty = true; + const int count = glyphToUnicode.count(); - for (int i = 0; i < glyphToUnicode.count(); ++i) { - if (glyphToUnicode[i] && (subset == NULL || subset->has(i))) { + for (int i = 0; i < count + 1; ++i) { + bool inSubset = i < count && (subset == NULL || subset->has(i)); + if (!rangeEmpty) { // PDF spec requires bfrange not changing the higher byte, // e.g. <1035> <10FF> <2222> is ok, but // <1035> <1100> <2222> is no good - if (haveBase) { - ++continuousEntries; - if (i == currentRangeEntry.fStart + continuousEntries && - (i >> 8) == (currentRangeEntry.fStart >> 8) && - glyphToUnicode[i] == (currentRangeEntry.fUnicode + - continuousEntries)) { - currentRangeEntry.fEnd = i; - if (i == glyphToUnicode.count() - 1) { - // Last entry is in a range. - bfrangeEntries.push(currentRangeEntry); - } - continue; - } - - // Need to have at least 2 entries to form a bfrange. - if (continuousEntries >= 2) { + bool inRange = + i == currentRangeEntry.fEnd + 1 && + i >> 8 == currentRangeEntry.fStart >> 8 && + i < count && + glyphToUnicode[i] == currentRangeEntry.fUnicode + i - + currentRangeEntry.fStart; + if (!inSubset || !inRange) { + if (currentRangeEntry.fEnd > currentRangeEntry.fStart) { bfrangeEntries.push(currentRangeEntry); } else { BFChar* entry = bfcharEntries.append(); entry->fGlyphId = currentRangeEntry.fStart; entry->fUnicode = currentRangeEntry.fUnicode; } - continuousEntries = 0; + rangeEmpty = true; } - - if (i != glyphToUnicode.count() - 1) { - currentRangeEntry.fStart = i; - currentRangeEntry.fEnd = i; - currentRangeEntry.fUnicode = glyphToUnicode[i]; - haveBase = true; - } else { - BFChar* entry = bfcharEntries.append(); - entry->fGlyphId = i; - entry->fUnicode = glyphToUnicode[i]; + } + if (inSubset) { + currentRangeEntry.fEnd = i; + if (rangeEmpty) { + currentRangeEntry.fStart = i; + currentRangeEntry.fUnicode = glyphToUnicode[i]; + rangeEmpty = false; } } } diff --git a/tests/ToUnicode.cpp b/tests/ToUnicode.cpp index ad1e0a9..c0a945a 100644 --- a/tests/ToUnicode.cpp +++ b/tests/ToUnicode.cpp @@ -16,17 +16,21 @@ #include "SkStream.h" static bool stream_equals(const SkDynamicMemoryWStream& stream, size_t offset, - const void* buffer, size_t len) { + const char* buffer, size_t len) { SkAutoDataUnref data(stream.copyToData()); if (offset + len > data.size()) { return false; } + if (len != strlen(buffer)) { + return false; + } return memcmp(data.bytes() + offset, buffer, len) == 0; } void append_cmap_sections(const SkTDArray& glyphToUnicode, const SkPDFGlyphSet* subset, SkDynamicMemoryWStream* cmap); + static void TestToUnicode(skiatest::Reporter* reporter) { SkTDArray glyphToUnicode; SkTDArray glyphsInSubset; @@ -86,6 +90,43 @@ endbfrange\n"; REPORTER_ASSERT(reporter, stream_equals(buffer, 0, expectedResult, buffer.getOffset())); + + glyphToUnicode.reset(); + glyphsInSubset.reset(); + SkPDFGlyphSet subset2; + + // Test mapping: + // I n s t a l + // Glyph id 2c 51 56 57 44 4f + // Unicode 49 6e 73 74 61 6c + for (size_t i = 0; i < 100; ++i) { + glyphToUnicode.push(i + 29); + } + + glyphsInSubset.push(0x2C); + glyphsInSubset.push(0x44); + glyphsInSubset.push(0x4F); + glyphsInSubset.push(0x51); + glyphsInSubset.push(0x56); + glyphsInSubset.push(0x57); + + SkDynamicMemoryWStream buffer2; + subset2.set(glyphsInSubset.begin(), glyphsInSubset.count()); + append_cmap_sections(glyphToUnicode, &subset2, &buffer2); + + char expectedResult2[] = +"4 beginbfchar\n\ +<002C> <0049>\n\ +<0044> <0061>\n\ +<004F> <006C>\n\ +<0051> <006E>\n\ +endbfchar\n\ +1 beginbfrange\n\ +<0056> <0057> <0073>\n\ +endbfrange\n"; + + REPORTER_ASSERT(reporter, stream_equals(buffer2, 0, expectedResult2, + buffer2.getOffset())); } #include "TestClassDef.h" -- 2.7.4