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