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