diff options
author | vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-01-03 18:35:39 +0000 |
---|---|---|
committer | vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-01-03 18:35:39 +0000 |
commit | 9ad3599a3a17f124a96979ad5dcba8ad4a107160 (patch) | |
tree | 2cd6cf533d926e5c2fb030d048b79ceb0414053a | |
parent | 2d6ef528e57928160aba6b628b2d84180ced97c3 (diff) |
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
-rw-r--r-- | src/pdf/SkPDFFont.cpp | 52 | ||||
-rw-r--r-- | tests/ToUnicode.cpp | 43 |
2 files changed, 63 insertions, 32 deletions
diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp index 0da5698bc9..404c762457 100644 --- a/src/pdf/SkPDFFont.cpp +++ b/src/pdf/SkPDFFont.cpp @@ -474,48 +474,38 @@ void append_cmap_sections(const SkTDArray<SkUnichar>& glyphToUnicode, SkTDArray<BFRange> 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 ad1e0a990b..c0a945a5e7 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<SkUnichar>& glyphToUnicode, const SkPDFGlyphSet* subset, SkDynamicMemoryWStream* cmap); + static void TestToUnicode(skiatest::Reporter* reporter) { SkTDArray<SkUnichar> glyphToUnicode; SkTDArray<uint16_t> 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" |