104c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org/*
204c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org * Copyright 2010 The Android Open Source Project
304c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org *
404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org * Use of this source code is governed by a BSD-style license that can be
504c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org * found in the LICENSE file.
604c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org */
704c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org
804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org#include "SkData.h"
904c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org#include "SkPDFFont.h"
108f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "SkPDFTypes.h"
1104c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org#include "SkStream.h"
128f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "Test.h"
1304c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org
1404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.orgstatic bool stream_equals(const SkDynamicMemoryWStream& stream, size_t offset,
159ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org                          const char* buffer, size_t len) {
1604c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    SkAutoDataUnref data(stream.copyToData());
1759f46b81f8bdd1b524f5cc43bc27603f9604c71arobertphillips@google.com    if (offset + len > data->size()) {
1804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org        return false;
1904c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    }
209ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    if (len != strlen(buffer)) {
219ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org        return false;
229ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    }
2359f46b81f8bdd1b524f5cc43bc27603f9604c71arobertphillips@google.com    return memcmp(data->bytes() + offset, buffer, len) == 0;
2404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org}
2504c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org
2604c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.orgvoid append_cmap_sections(const SkTDArray<SkUnichar>& glyphToUnicode,
2704c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org                          const SkPDFGlyphSet* subset,
2826d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com                          SkDynamicMemoryWStream* cmap,
291236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org                          bool multiByteGlyphs,
3026d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com                          uint16_t firstGlypthID,
3126d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com                          uint16_t lastGlypthID);
329ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org
33e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.orgDEF_TEST(ToUnicode, reporter) {
3404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    SkTDArray<SkUnichar> glyphToUnicode;
3504c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    SkTDArray<uint16_t> glyphsInSubset;
3604c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    SkPDFGlyphSet subset;
3704c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org
3804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphToUnicode.push(0);  // 0
3904c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphToUnicode.push(0);  // 1
4004c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphToUnicode.push(0);  // 2
4104c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphsInSubset.push(3);
4204c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphToUnicode.push(0x20);  // 3
4304c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphsInSubset.push(4);
4404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphToUnicode.push(0x25);  // 4
4504c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphsInSubset.push(5);
4604c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphToUnicode.push(0x27);  // 5
4704c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphsInSubset.push(6);
4804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphToUnicode.push(0x28);  // 6
4904c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphsInSubset.push(7);
5004c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphToUnicode.push(0x29);  // 7
5104c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphsInSubset.push(8);
5204c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphToUnicode.push(0x2F);  // 8
5304c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphsInSubset.push(9);
5404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphToUnicode.push(0x33);  // 9
5504c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphToUnicode.push(0);  // 10
5604c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphsInSubset.push(11);
5704c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphToUnicode.push(0x35);  // 11
5804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphsInSubset.push(12);
5904c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphToUnicode.push(0x36);  // 12
6026d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    glyphsInSubset.push(13);
6126d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    glyphToUnicode.push(0x37);  // 13
6226d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    for (uint16_t i = 14; i < 0xFE; ++i) {
6304c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org        glyphToUnicode.push(0);  // Zero from index 0x9 to 0xFD
6404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    }
6504c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphsInSubset.push(0xFE);
6604c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphToUnicode.push(0x1010);
6704c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphsInSubset.push(0xFF);
6804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphToUnicode.push(0x1011);
6904c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphsInSubset.push(0x100);
7004c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphToUnicode.push(0x1012);
7104c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphsInSubset.push(0x101);
7204c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    glyphToUnicode.push(0x1013);
7304c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org
7404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    SkDynamicMemoryWStream buffer;
7504c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    subset.set(glyphsInSubset.begin(), glyphsInSubset.count());
761236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org    append_cmap_sections(glyphToUnicode, &subset, &buffer, true, 0, 0xFFFF);
7704c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org
7804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    char expectedResult[] =
7904c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org"4 beginbfchar\n\
8004c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org<0003> <0020>\n\
8104c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org<0004> <0025>\n\
8204c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org<0008> <002F>\n\
8304c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org<0009> <0033>\n\
8404c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.orgendbfchar\n\
8504c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org4 beginbfrange\n\
8604c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org<0005> <0007> <0027>\n\
8726d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com<000B> <000D> <0035>\n\
8804c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org<00FE> <00FF> <1010>\n\
8904c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org<0100> <0101> <1012>\n\
9004c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.orgendbfrange\n";
9104c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org
9204c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org    REPORTER_ASSERT(reporter, stream_equals(buffer, 0, expectedResult,
9304c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org                                            buffer.getOffset()));
949ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org
9526d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    // Remove characters and ranges.
9626d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    buffer.reset();
9726d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com
981236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org    append_cmap_sections(glyphToUnicode, &subset, &buffer, true, 8, 0x00FF);
9926d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com
10026d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    char expectedResultChop1[] =
10126d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com"2 beginbfchar\n\
10226d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com<0008> <002F>\n\
10326d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com<0009> <0033>\n\
10426d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.comendbfchar\n\
10526d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com2 beginbfrange\n\
10626d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com<000B> <000D> <0035>\n\
10726d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com<00FE> <00FF> <1010>\n\
10826d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.comendbfrange\n";
10926d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com
11026d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    REPORTER_ASSERT(reporter, stream_equals(buffer, 0, expectedResultChop1,
11126d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com                                            buffer.getOffset()));
11226d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com
11326d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    // Remove characters from range to downdrade it to one char.
11426d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    buffer.reset();
11526d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com
1161236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org    append_cmap_sections(glyphToUnicode, &subset, &buffer, true, 0x00D, 0x00FE);
11726d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com
11826d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    char expectedResultChop2[] =
11926d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com"2 beginbfchar\n\
12026d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com<000D> <0037>\n\
12126d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com<00FE> <1010>\n\
12226d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.comendbfchar\n";
12326d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com
12426d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com    REPORTER_ASSERT(reporter, stream_equals(buffer, 0, expectedResultChop2,
12526d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com                                            buffer.getOffset()));
12626d2e046cd3e11cb61d1b0b3ace304a6dc8c995bedisonn@google.com
1271236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org    buffer.reset();
1281236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org
1292880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    append_cmap_sections(glyphToUnicode, nullptr, &buffer, false, 0xFC, 0x110);
1301236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org
1311236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org    char expectedResultSingleBytes[] =
1321236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org"2 beginbfchar\n\
1331236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org<0001> <0000>\n\
1341236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org<0002> <0000>\n\
1351236d8e37c96339865832ceef569340283201e37commit-bot@chromium.orgendbfchar\n\
1361236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org1 beginbfrange\n\
1371236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org<0003> <0006> <1010>\n\
1381236d8e37c96339865832ceef569340283201e37commit-bot@chromium.orgendbfrange\n";
1391236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org
1401236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org    REPORTER_ASSERT(reporter, stream_equals(buffer, 0,
1411236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org                                            expectedResultSingleBytes,
1421236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org                                            buffer.getOffset()));
1431236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org
1449ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    glyphToUnicode.reset();
1459ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    glyphsInSubset.reset();
1469ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    SkPDFGlyphSet subset2;
1479ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org
1489ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    // Test mapping:
1499ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    //           I  n  s  t  a  l
1509ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    // Glyph id 2c 51 56 57 44 4f
1519ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    // Unicode  49 6e 73 74 61 6c
1529880607151ca7c2dc6b1a4b9756938bd71913ab5bsalomon    for (SkUnichar i = 0; i < 100; ++i) {
1539ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org      glyphToUnicode.push(i + 29);
1549ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    }
1559ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org
1569ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    glyphsInSubset.push(0x2C);
1579ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    glyphsInSubset.push(0x44);
1589ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    glyphsInSubset.push(0x4F);
1599ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    glyphsInSubset.push(0x51);
1609ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    glyphsInSubset.push(0x56);
1619ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    glyphsInSubset.push(0x57);
1629ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org
1639ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    SkDynamicMemoryWStream buffer2;
1649ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    subset2.set(glyphsInSubset.begin(), glyphsInSubset.count());
1651236d8e37c96339865832ceef569340283201e37commit-bot@chromium.org    append_cmap_sections(glyphToUnicode, &subset2, &buffer2, true, 0, 0xffff);
1669ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org
1679ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    char expectedResult2[] =
1689ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org"4 beginbfchar\n\
1699ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org<002C> <0049>\n\
1709ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org<0044> <0061>\n\
1719ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org<004F> <006C>\n\
1729ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org<0051> <006E>\n\
1739ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.orgendbfchar\n\
1749ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org1 beginbfrange\n\
1759ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org<0056> <0057> <0073>\n\
1769ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.orgendbfrange\n";
1779ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org
1789ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org    REPORTER_ASSERT(reporter, stream_equals(buffer2, 0, expectedResult2,
1799ad3599a3a17f124a96979ad5dcba8ad4a107160vandebo@chromium.org                                            buffer2.getOffset()));
18004c643b7739cf7e618d9996c3fd1514eee4b27c0vandebo@chromium.org}
181