/*
 * Copyright 2019 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/core/SkEnumerate.h"
#include "src/core/SkGlyphBuffer.h"
#include "src/core/SkGlyphRunPainter.h"
#include "src/core/SkScalerContext.h"
#include "tests/Test.h"

DEF_TEST(SkPackedGlyphIDCtor, reporter) {
    using PG = SkPackedGlyphID;
    // x and y are in one quarter the sub-pixel sampling frequency.
    // Number of steps on the interval [0, 1)
    const int perUnit = 1u << (PG::kSubPixelPosLen + 2);
    const float step = 1.f / perUnit;
    const int testLimit = 2 * perUnit;
    auto freqRound = [](uint32_t x) -> uint32_t {
        return ((x + 2) >> 2) & PG::kSubPixelPosMask;
    };

    {
        // Normal sub-pixel with y-axis snapping.
        auto roundingSpec = SkGlyphPositionRoundingSpec(true, kX_SkAxisAlignment);
        SkIPoint mask = roundingSpec.ignorePositionFieldMask;
        for (int x = -testLimit; x < testLimit; x++) {
            float fx = x * step;
            SkPoint roundedPos = SkPoint{fx, 0} + roundingSpec.halfAxisSampleFreq;
            SkPackedGlyphID packedID{3, roundedPos, mask};
            uint32_t subX = freqRound(x);
            uint32_t subY = 0;
            SkPackedGlyphID correctID(3, subX, subY);
            SkASSERT(packedID == correctID);
            REPORTER_ASSERT(reporter, packedID == correctID);
        }
    }

    {
        // No subpixel positioning.
        auto roundingSpec = SkGlyphPositionRoundingSpec(false, kNone_SkAxisAlignment);
        SkIPoint mask = roundingSpec.ignorePositionFieldMask;
        for (int y = -testLimit; y < testLimit; y++) {
            for (int x = -testLimit; x < testLimit; x++) {
                float fx = x * step, fy = y * step;
                SkPoint roundedPos = SkPoint{fx, fy} + roundingSpec.halfAxisSampleFreq;
                SkPackedGlyphID packedID{3, roundedPos, mask};
                uint32_t subX = 0;
                uint32_t subY = 0;
                SkPackedGlyphID correctID(3, subX, subY);
                REPORTER_ASSERT(reporter, packedID == correctID);
            }
        }
    }

    {
        // Subpixel with no axis snapping.
        auto roundingSpec = SkGlyphPositionRoundingSpec(true, kNone_SkAxisAlignment);
        SkIPoint mask = roundingSpec.ignorePositionFieldMask;
        for (int y = -testLimit; y < testLimit; y++) {
            for (int x = -testLimit; x < testLimit; x++) {
                float fx = x * step, fy = y * step;
                SkPoint roundedPos = SkPoint{fx, fy} + roundingSpec.halfAxisSampleFreq;
                SkPackedGlyphID packedID{3, roundedPos, mask};
                uint32_t subX = freqRound(x);
                uint32_t subY = freqRound(y);
                SkPackedGlyphID correctID(3, subX, subY);
                REPORTER_ASSERT(reporter, packedID == correctID);
            }
        }
    }

    {
        // Test dynamic range by transposing a large distance.
        // Floating point numbers have 24 bits of precision. The largest distance is 24 - 2 (for
        // sub-pixel) - 1 (for truncation to floor trick in the code). This leaves 21 bits. Large
        // Distance is 2^21 - 2 (because the test is on the interval [-2, 2).
        const uint32_t kLogLargeDistance = 24 - PG::kSubPixelPosLen - 1;
        const int64_t kLargeDistance = (1ull << kLogLargeDistance) - 2;
        auto roundingSpec = SkGlyphPositionRoundingSpec(true, kNone_SkAxisAlignment);
        SkIPoint mask = roundingSpec.ignorePositionFieldMask;
        for (int y = -32; y < 33; y++) {
            for (int x = -32; x < 33; x++) {
                float fx = x * step + kLargeDistance, fy = y * step + kLargeDistance;
                SkPoint roundedPos = SkPoint{fx, fy} + roundingSpec.halfAxisSampleFreq;
                SkPackedGlyphID packedID{3, roundedPos, mask};
                uint32_t subX = freqRound(x);
                uint32_t subY = freqRound(y);
                SkPackedGlyphID correctID(3, subX, subY);
                REPORTER_ASSERT(reporter, packedID == correctID);
            }
        }
    }
}

DEF_TEST(SkSourceGlyphBufferBasic, reporter) {
    SkSourceGlyphBuffer rejects;
    // Positions are picked to avoid precision problems.
    const SkPoint positions[] = {{10.25,10.25}, {20.5,10.25}, {30.75,10.25}, {40,10.25}};
    const SkGlyphID glyphIDs[] = {1, 2, 3, 4};
    auto source = SkMakeZip(glyphIDs, positions);

    rejects.setSource(source);
    for (auto [i, glyphID, pos] : SkMakeEnumerate(rejects.source())) {
        REPORTER_ASSERT(reporter, glyphID == std::get<0>(source[i]));
        REPORTER_ASSERT(reporter, pos == std::get<1>(source[i]));
    }
    // Reject a couple of glyphs.
    rejects.reject(1);
    rejects.reject(2, 100);
    rejects.flipRejectsToSource();
    REPORTER_ASSERT(reporter, rejects.rejectedMaxDimension() == 100);
    for (auto [i, glyphID, pos] : SkMakeEnumerate(rejects.source())) {
        // This will index 1 and 2 from the original source.
        size_t j = i + 1;
        REPORTER_ASSERT(reporter, glyphID == std::get<0>(source[j]));
        REPORTER_ASSERT(reporter, pos == std::get<1>(source[j]));
    }

    // Reject an additional glyph
    rejects.reject(0, 10);
    rejects.flipRejectsToSource();
    REPORTER_ASSERT(reporter, rejects.rejectedMaxDimension() == 10);
    for (auto [i, glyphID, pos] : SkMakeEnumerate(rejects.source())) {
        // This will index 1 from the original source.
        size_t j = i + 1;
        REPORTER_ASSERT(reporter, glyphID == std::get<0>(source[j]));
        REPORTER_ASSERT(reporter, pos == std::get<1>(source[j]));
    }

    // Start all over
    rejects.setSource(source);
    for (auto [i, glyphID, pos] : SkMakeEnumerate(rejects.source())) {
        REPORTER_ASSERT(reporter, glyphID == std::get<0>(source[i]));
        REPORTER_ASSERT(reporter, pos == std::get<1>(source[i]));
    }

    // Check that everything is working after calling setSource.
    rejects.reject(1);
    rejects.reject(2, 100);
    rejects.flipRejectsToSource();
    REPORTER_ASSERT(reporter, rejects.rejectedMaxDimension() == 100);
    for (auto [i, glyphID, pos] : SkMakeEnumerate(rejects.source())) {
        // This will index 1 and 2 from the original source.
        size_t j = i + 1;
        REPORTER_ASSERT(reporter, glyphID == std::get<0>(source[j]));
        REPORTER_ASSERT(reporter, pos == std::get<1>(source[j]));
    }
}

DEF_TEST(SkDrawableGlyphBufferBasic, reporter) {
    // Positions are picked to avoid precision problems.
    const SkPoint positions[] = {{10.25,10.25}, {20.5,10.25}, {30.75,10.25}, {40,10.25}};
    const SkGlyphID glyphIDs[] = {1, 2, 3, 4};
    SkGlyph glyphs[100];
    auto source = SkMakeZip(glyphIDs, positions);

    {
        SkDrawableGlyphBuffer drawable;
        drawable.ensureSize(100);
        drawable.startSource(source);
        for (auto [i, packedID, pos] : SkMakeEnumerate(drawable.input())) {
            REPORTER_ASSERT(reporter, packedID.packedID().glyphID() == glyphIDs[i]);
            REPORTER_ASSERT(reporter, pos == positions[i]);
        }
    }

    {
        SkDrawableGlyphBuffer drawable;
        drawable.ensureSize(100);
        SkMatrix matrix = SkMatrix::Scale(0.5, 0.5);
        SkGlyphPositionRoundingSpec rounding{true, kX_SkAxisAlignment};
        drawable.startBitmapDevice(source, {100, 100}, matrix, rounding);
        for (auto [i, packedID, pos] : SkMakeEnumerate(drawable.input())) {
            REPORTER_ASSERT(reporter, glyphIDs[i] == packedID.packedID().glyphID());
            REPORTER_ASSERT(reporter,
                    pos.x() == positions[i].x() * 0.5 + 50 + SkPackedGlyphID::kSubpixelRound);
            REPORTER_ASSERT(reporter, pos.y() == positions[i].y() * 0.5 + 50 + 0.5);
        }
    }

    {
        SkDrawableGlyphBuffer drawable;
        drawable.ensureSize(100);
        drawable.startSource(source);
        for (auto [i, packedID, pos] : SkMakeEnumerate(drawable.input())) {
            drawable.push_back(&glyphs[i], i);
        }
        for (auto [i, glyph, pos] : SkMakeEnumerate(drawable.drawable())) {
            REPORTER_ASSERT(reporter, glyph.glyph() == &glyphs[i]);
        }
    }
}
