/*
 * Copyright 2010 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "Test.h"

#ifdef SK_SUPPORT_PDF

#include "SkBitSet.h"
#include "SkData.h"
#include "SkPDFMakeToUnicodeCmap.h"
#include "SkStream.h"
#include "SkTo.h"

static const int kMaximumGlyphCount = UINT16_MAX + 1;

static bool stream_equals(const SkDynamicMemoryWStream& stream, size_t offset,
                          const char* buffer, size_t len) {
    if (len != strlen(buffer)) {
        return false;
    }

    const size_t streamSize = stream.bytesWritten();

    if (offset + len > streamSize) {
        return false;
    }

    SkAutoTMalloc<char> data(streamSize);
    stream.copyTo(data.get());
    return memcmp(data.get() + offset, buffer, len) == 0;
}

DEF_TEST(SkPDF_ToUnicode, reporter) {
    SkTDArray<SkUnichar> glyphToUnicode;
    SkTDArray<uint16_t> glyphsInSubset;
    SkBitSet subset(kMaximumGlyphCount);

    glyphToUnicode.push(0);  // 0
    glyphToUnicode.push(0);  // 1
    glyphToUnicode.push(0);  // 2
    glyphsInSubset.push(3);
    glyphToUnicode.push(0x20);  // 3
    glyphsInSubset.push(4);
    glyphToUnicode.push(0x25);  // 4
    glyphsInSubset.push(5);
    glyphToUnicode.push(0x27);  // 5
    glyphsInSubset.push(6);
    glyphToUnicode.push(0x28);  // 6
    glyphsInSubset.push(7);
    glyphToUnicode.push(0x29);  // 7
    glyphsInSubset.push(8);
    glyphToUnicode.push(0x2F);  // 8
    glyphsInSubset.push(9);
    glyphToUnicode.push(0x33);  // 9
    glyphToUnicode.push(0);  // 10
    glyphsInSubset.push(11);
    glyphToUnicode.push(0x35);  // 11
    glyphsInSubset.push(12);
    glyphToUnicode.push(0x36);  // 12
    glyphsInSubset.push(13);
    glyphToUnicode.push(0x37);  // 13
    for (uint16_t i = 14; i < 0xFE; ++i) {
        glyphToUnicode.push(0);  // Zero from index 0x9 to 0xFD
    }
    glyphsInSubset.push(0xFE);
    glyphToUnicode.push(0x1010);
    glyphsInSubset.push(0xFF);
    glyphToUnicode.push(0x1011);
    glyphsInSubset.push(0x100);
    glyphToUnicode.push(0x1012);
    glyphsInSubset.push(0x101);
    glyphToUnicode.push(0x1013);

    SkGlyphID lastGlyphID = SkToU16(glyphToUnicode.count() - 1);

    SkDynamicMemoryWStream buffer;
    subset.setAll(glyphsInSubset.begin(), glyphsInSubset.count());
    SkPDFAppendCmapSections(&glyphToUnicode[0], &subset, &buffer, true, 0,
                            SkTMin<SkGlyphID>(0xFFFF,  lastGlyphID));

    char expectedResult[] =
"4 beginbfchar\n\
<0003> <0020>\n\
<0004> <0025>\n\
<0008> <002F>\n\
<0009> <0033>\n\
endbfchar\n\
4 beginbfrange\n\
<0005> <0007> <0027>\n\
<000B> <000D> <0035>\n\
<00FE> <00FF> <1010>\n\
<0100> <0101> <1012>\n\
endbfrange\n";

    REPORTER_ASSERT(reporter, stream_equals(buffer, 0, expectedResult,
                                            buffer.bytesWritten()));

    // Remove characters and ranges.
    buffer.reset();

    SkPDFAppendCmapSections(&glyphToUnicode[0], &subset, &buffer, true, 8,
                            SkTMin<SkGlyphID>(0x00FF, lastGlyphID));

    char expectedResultChop1[] =
"2 beginbfchar\n\
<0008> <002F>\n\
<0009> <0033>\n\
endbfchar\n\
2 beginbfrange\n\
<000B> <000D> <0035>\n\
<00FE> <00FF> <1010>\n\
endbfrange\n";

    REPORTER_ASSERT(reporter, stream_equals(buffer, 0, expectedResultChop1,
                                            buffer.bytesWritten()));

    // Remove characters from range to downdrade it to one char.
    buffer.reset();

    SkPDFAppendCmapSections(&glyphToUnicode[0], &subset, &buffer, true, 0x00D,
                            SkTMin<SkGlyphID>(0x00FE, lastGlyphID));

    char expectedResultChop2[] =
"2 beginbfchar\n\
<000D> <0037>\n\
<00FE> <1010>\n\
endbfchar\n";

    REPORTER_ASSERT(reporter, stream_equals(buffer, 0, expectedResultChop2,
                                            buffer.bytesWritten()));

    buffer.reset();

    SkPDFAppendCmapSections(&glyphToUnicode[0], nullptr, &buffer, false, 0xFC,
                            SkTMin<SkGlyphID>(0x110, lastGlyphID));

    char expectedResultSingleBytes[] =
"2 beginbfchar\n\
<01> <0000>\n\
<02> <0000>\n\
endbfchar\n\
1 beginbfrange\n\
<03> <06> <1010>\n\
endbfrange\n";

    REPORTER_ASSERT(reporter, stream_equals(buffer, 0,
                                            expectedResultSingleBytes,
                                            buffer.bytesWritten()));

    glyphToUnicode.reset();
    glyphsInSubset.reset();
    SkBitSet subset2(kMaximumGlyphCount);

    // Test mapping:
    //           I  n  s  t  a  l
    // Glyph id 2c 51 56 57 44 4f
    // Unicode  49 6e 73 74 61 6c
    for (SkUnichar i = 0; i < 100; ++i) {
      glyphToUnicode.push(i + 29);
    }
    lastGlyphID = SkToU16(glyphToUnicode.count() - 1);

    glyphsInSubset.push(0x2C);
    glyphsInSubset.push(0x44);
    glyphsInSubset.push(0x4F);
    glyphsInSubset.push(0x51);
    glyphsInSubset.push(0x56);
    glyphsInSubset.push(0x57);

    SkDynamicMemoryWStream buffer2;
    subset2.setAll(glyphsInSubset.begin(), glyphsInSubset.count());
    SkPDFAppendCmapSections(&glyphToUnicode[0], &subset2, &buffer2, true, 0,
                            SkTMin<SkGlyphID>(0xFFFF, lastGlyphID));

    char expectedResult2[] =
"4 beginbfchar\n\
<002C> <0049>\n\
<0044> <0061>\n\
<004F> <006C>\n\
<0051> <006E>\n\
endbfchar\n\
1 beginbfrange\n\
<0056> <0057> <0073>\n\
endbfrange\n";

    REPORTER_ASSERT(reporter, stream_equals(buffer2, 0, expectedResult2,
                                            buffer2.bytesWritten()));
}

#endif
