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