1 /* 2 * Copyright 2010 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "Test.h" 9 10 #ifdef SK_SUPPORT_PDF 11 12 #include "SkBitSet.h" 13 #include "SkData.h" 14 #include "SkPDFMakeToUnicodeCmap.h" 15 #include "SkStream.h" 16 17 static const int kMaximumGlyphCount = SK_MaxU16 + 1; 18 19 static bool stream_equals(const SkDynamicMemoryWStream& stream, size_t offset, 20 const char* buffer, size_t len) { 21 if (len != strlen(buffer)) { 22 return false; 23 } 24 25 const size_t streamSize = stream.bytesWritten(); 26 27 if (offset + len > streamSize) { 28 return false; 29 } 30 31 SkAutoTMalloc<char> data(streamSize); 32 stream.copyTo(data.get()); 33 return memcmp(data.get() + offset, buffer, len) == 0; 34 } 35 36 DEF_TEST(SkPDF_ToUnicode, reporter) { 37 SkTDArray<SkUnichar> glyphToUnicode; 38 SkTDArray<uint16_t> glyphsInSubset; 39 SkBitSet subset(kMaximumGlyphCount); 40 41 glyphToUnicode.push(0); // 0 42 glyphToUnicode.push(0); // 1 43 glyphToUnicode.push(0); // 2 44 glyphsInSubset.push(3); 45 glyphToUnicode.push(0x20); // 3 46 glyphsInSubset.push(4); 47 glyphToUnicode.push(0x25); // 4 48 glyphsInSubset.push(5); 49 glyphToUnicode.push(0x27); // 5 50 glyphsInSubset.push(6); 51 glyphToUnicode.push(0x28); // 6 52 glyphsInSubset.push(7); 53 glyphToUnicode.push(0x29); // 7 54 glyphsInSubset.push(8); 55 glyphToUnicode.push(0x2F); // 8 56 glyphsInSubset.push(9); 57 glyphToUnicode.push(0x33); // 9 58 glyphToUnicode.push(0); // 10 59 glyphsInSubset.push(11); 60 glyphToUnicode.push(0x35); // 11 61 glyphsInSubset.push(12); 62 glyphToUnicode.push(0x36); // 12 63 glyphsInSubset.push(13); 64 glyphToUnicode.push(0x37); // 13 65 for (uint16_t i = 14; i < 0xFE; ++i) { 66 glyphToUnicode.push(0); // Zero from index 0x9 to 0xFD 67 } 68 glyphsInSubset.push(0xFE); 69 glyphToUnicode.push(0x1010); 70 glyphsInSubset.push(0xFF); 71 glyphToUnicode.push(0x1011); 72 glyphsInSubset.push(0x100); 73 glyphToUnicode.push(0x1012); 74 glyphsInSubset.push(0x101); 75 glyphToUnicode.push(0x1013); 76 77 SkDynamicMemoryWStream buffer; 78 subset.setAll(glyphsInSubset.begin(), glyphsInSubset.count()); 79 SkPDFAppendCmapSections(glyphToUnicode, &subset, &buffer, true, 0, 0xFFFF); 80 81 char expectedResult[] = 82 "4 beginbfchar\n\ 83 <0003> <0020>\n\ 84 <0004> <0025>\n\ 85 <0008> <002F>\n\ 86 <0009> <0033>\n\ 87 endbfchar\n\ 88 4 beginbfrange\n\ 89 <0005> <0007> <0027>\n\ 90 <000B> <000D> <0035>\n\ 91 <00FE> <00FF> <1010>\n\ 92 <0100> <0101> <1012>\n\ 93 endbfrange\n"; 94 95 REPORTER_ASSERT(reporter, stream_equals(buffer, 0, expectedResult, 96 buffer.bytesWritten())); 97 98 // Remove characters and ranges. 99 buffer.reset(); 100 101 SkPDFAppendCmapSections(glyphToUnicode, &subset, &buffer, true, 8, 0x00FF); 102 103 char expectedResultChop1[] = 104 "2 beginbfchar\n\ 105 <0008> <002F>\n\ 106 <0009> <0033>\n\ 107 endbfchar\n\ 108 2 beginbfrange\n\ 109 <000B> <000D> <0035>\n\ 110 <00FE> <00FF> <1010>\n\ 111 endbfrange\n"; 112 113 REPORTER_ASSERT(reporter, stream_equals(buffer, 0, expectedResultChop1, 114 buffer.bytesWritten())); 115 116 // Remove characters from range to downdrade it to one char. 117 buffer.reset(); 118 119 SkPDFAppendCmapSections(glyphToUnicode, &subset, &buffer, true, 0x00D, 0x00FE); 120 121 char expectedResultChop2[] = 122 "2 beginbfchar\n\ 123 <000D> <0037>\n\ 124 <00FE> <1010>\n\ 125 endbfchar\n"; 126 127 REPORTER_ASSERT(reporter, stream_equals(buffer, 0, expectedResultChop2, 128 buffer.bytesWritten())); 129 130 buffer.reset(); 131 132 SkPDFAppendCmapSections(glyphToUnicode, nullptr, &buffer, false, 0xFC, 0x110); 133 134 char expectedResultSingleBytes[] = 135 "2 beginbfchar\n\ 136 <01> <0000>\n\ 137 <02> <0000>\n\ 138 endbfchar\n\ 139 1 beginbfrange\n\ 140 <03> <06> <1010>\n\ 141 endbfrange\n"; 142 143 REPORTER_ASSERT(reporter, stream_equals(buffer, 0, 144 expectedResultSingleBytes, 145 buffer.bytesWritten())); 146 147 glyphToUnicode.reset(); 148 glyphsInSubset.reset(); 149 SkBitSet subset2(kMaximumGlyphCount); 150 151 // Test mapping: 152 // I n s t a l 153 // Glyph id 2c 51 56 57 44 4f 154 // Unicode 49 6e 73 74 61 6c 155 for (SkUnichar i = 0; i < 100; ++i) { 156 glyphToUnicode.push(i + 29); 157 } 158 159 glyphsInSubset.push(0x2C); 160 glyphsInSubset.push(0x44); 161 glyphsInSubset.push(0x4F); 162 glyphsInSubset.push(0x51); 163 glyphsInSubset.push(0x56); 164 glyphsInSubset.push(0x57); 165 166 SkDynamicMemoryWStream buffer2; 167 subset2.setAll(glyphsInSubset.begin(), glyphsInSubset.count()); 168 SkPDFAppendCmapSections(glyphToUnicode, &subset2, &buffer2, true, 0, 0xffff); 169 170 char expectedResult2[] = 171 "4 beginbfchar\n\ 172 <002C> <0049>\n\ 173 <0044> <0061>\n\ 174 <004F> <006C>\n\ 175 <0051> <006E>\n\ 176 endbfchar\n\ 177 1 beginbfrange\n\ 178 <0056> <0057> <0073>\n\ 179 endbfrange\n"; 180 181 REPORTER_ASSERT(reporter, stream_equals(buffer2, 0, expectedResult2, 182 buffer2.bytesWritten())); 183 } 184 185 #endif 186