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