aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-01-03 18:35:39 +0000
committerGravatar vandebo@chromium.org <vandebo@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-01-03 18:35:39 +0000
commit9ad3599a3a17f124a96979ad5dcba8ad4a107160 (patch)
tree2cd6cf533d926e5c2fb030d048b79ceb0414053a
parent2d6ef528e57928160aba6b628b2d84180ced97c3 (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.cpp52
-rw-r--r--tests/ToUnicode.cpp43
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"