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

#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkData.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkImage.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSerialProcs.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTextBlob.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/private/SkTArray.h"
#include "include/private/SkTemplates.h"
#include "include/private/SkTo.h"
#include "src/core/SkTextBlobPriv.h"
#include "tests/Test.h"
#include "tools/ToolUtils.h"

#include <algorithm>
#include <cstdint>
#include <cstring>
#include <string>

class TextBlobTester {
public:
    // This unit test feeds an SkTextBlobBuilder various runs then checks to see if
    // the result contains the provided data and merges runs when appropriate.
    static void TestBuilder(skiatest::Reporter* reporter) {
        SkTextBlobBuilder builder;

        // empty run set
        RunBuilderTest(reporter, builder, nullptr, 0, nullptr, 0);

        RunDef set1[] = {
            { 128, SkTextBlobRunIterator::kDefault_Positioning, 100, 100 },
        };
        RunBuilderTest(reporter, builder, set1, std::size(set1), set1, std::size(set1));

        RunDef set2[] = {
            { 128, SkTextBlobRunIterator::kHorizontal_Positioning, 100, 100 },
        };
        RunBuilderTest(reporter, builder, set2, std::size(set2), set2, std::size(set2));

        RunDef set3[] = {
            { 128, SkTextBlobRunIterator::kFull_Positioning, 100, 100 },
        };
        RunBuilderTest(reporter, builder, set3, std::size(set3), set3, std::size(set3));

        RunDef set4[] = {
            { 128, SkTextBlobRunIterator::kDefault_Positioning, 100, 150 },
            { 128, SkTextBlobRunIterator::kDefault_Positioning, 100, 150 },
            { 128, SkTextBlobRunIterator::kDefault_Positioning, 100, 150 },
        };
        RunBuilderTest(reporter, builder, set4, std::size(set4), set4, std::size(set4));

        RunDef set5[] = {
            { 128, SkTextBlobRunIterator::kHorizontal_Positioning, 100, 150 },
            { 128, SkTextBlobRunIterator::kHorizontal_Positioning, 200, 150 },
            { 128, SkTextBlobRunIterator::kHorizontal_Positioning, 300, 250 },
        };
        RunDef mergedSet5[] = {
            { 256, SkTextBlobRunIterator::kHorizontal_Positioning, 0, 150 },
            { 128, SkTextBlobRunIterator::kHorizontal_Positioning, 0, 250 },
        };
        RunBuilderTest(reporter, builder, set5, std::size(set5), mergedSet5,
                       std::size(mergedSet5));

        RunDef set6[] = {
            { 128, SkTextBlobRunIterator::kFull_Positioning, 100, 100 },
            { 128, SkTextBlobRunIterator::kFull_Positioning, 200, 200 },
            { 128, SkTextBlobRunIterator::kFull_Positioning, 300, 300 },
        };
        RunDef mergedSet6[] = {
            { 384, SkTextBlobRunIterator::kFull_Positioning, 0, 0 },
        };
        RunBuilderTest(reporter, builder, set6, std::size(set6), mergedSet6,
                       std::size(mergedSet6));

        RunDef set7[] = {
            { 128, SkTextBlobRunIterator::kDefault_Positioning, 100, 150 },
            { 128, SkTextBlobRunIterator::kDefault_Positioning, 100, 150 },
            { 128, SkTextBlobRunIterator::kHorizontal_Positioning, 100, 150 },
            { 128, SkTextBlobRunIterator::kHorizontal_Positioning, 200, 150 },
            { 128, SkTextBlobRunIterator::kFull_Positioning, 400, 350 },
            { 128, SkTextBlobRunIterator::kFull_Positioning, 400, 350 },
            { 128, SkTextBlobRunIterator::kDefault_Positioning, 100, 450 },
            { 128, SkTextBlobRunIterator::kDefault_Positioning, 100, 450 },
            { 128, SkTextBlobRunIterator::kHorizontal_Positioning, 100, 550 },
            { 128, SkTextBlobRunIterator::kHorizontal_Positioning, 200, 650 },
            { 128, SkTextBlobRunIterator::kFull_Positioning, 400, 750 },
            { 128, SkTextBlobRunIterator::kFull_Positioning, 400, 850 },
        };
        RunDef mergedSet7[] = {
            { 128, SkTextBlobRunIterator::kDefault_Positioning, 100, 150 },
            { 128, SkTextBlobRunIterator::kDefault_Positioning, 100, 150 },
            { 256, SkTextBlobRunIterator::kHorizontal_Positioning, 0, 150 },
            { 256, SkTextBlobRunIterator::kFull_Positioning, 0, 0 },
            { 128, SkTextBlobRunIterator::kDefault_Positioning, 100, 450 },
            { 128, SkTextBlobRunIterator::kDefault_Positioning, 100, 450 },
            { 128, SkTextBlobRunIterator::kHorizontal_Positioning, 0, 550 },
            { 128, SkTextBlobRunIterator::kHorizontal_Positioning, 0, 650 },
            { 256, SkTextBlobRunIterator::kFull_Positioning, 0, 0 },
        };
        RunBuilderTest(reporter, builder, set7, std::size(set7), mergedSet7,
                       std::size(mergedSet7));
    }

    // This unit test verifies blob bounds computation.
    static void TestBounds(skiatest::Reporter* reporter) {
        SkTextBlobBuilder builder;
        SkFont font;

        // Explicit bounds.
        {
            sk_sp<SkTextBlob> blob(builder.make());
            REPORTER_ASSERT(reporter, !blob);
        }

        {
            SkRect r1 = SkRect::MakeXYWH(10, 10, 20, 20);
            builder.allocRun(font, 16, 0, 0, &r1);
            sk_sp<SkTextBlob> blob(builder.make());
            REPORTER_ASSERT(reporter, blob->bounds() == r1);
        }

        {
            SkRect r1 = SkRect::MakeXYWH(10, 10, 20, 20);
            builder.allocRunPosH(font, 16, 0, &r1);
            sk_sp<SkTextBlob> blob(builder.make());
            REPORTER_ASSERT(reporter, blob->bounds() == r1);
        }

        {
            SkRect r1 = SkRect::MakeXYWH(10, 10, 20, 20);
            builder.allocRunPos(font, 16, &r1);
            sk_sp<SkTextBlob> blob(builder.make());
            REPORTER_ASSERT(reporter, blob->bounds() == r1);
        }

        {
            SkRect r1 = SkRect::MakeXYWH(10, 10, 20, 20);
            SkRect r2 = SkRect::MakeXYWH(15, 20, 50, 50);
            SkRect r3 = SkRect::MakeXYWH(0, 5, 10, 5);

            builder.allocRun(font, 16, 0, 0, &r1);
            builder.allocRunPosH(font, 16, 0, &r2);
            builder.allocRunPos(font, 16, &r3);

            sk_sp<SkTextBlob> blob(builder.make());
            REPORTER_ASSERT(reporter, blob->bounds() == SkRect::MakeXYWH(0, 5, 65, 65));
        }

        {
            sk_sp<SkTextBlob> blob(builder.make());
            REPORTER_ASSERT(reporter, !blob);
        }

        // Implicit bounds

        {
            // Exercise the empty bounds path, and ensure that RunRecord-aligned pos buffers
            // don't trigger asserts (http://crbug.com/542643).
            font.setSize(0);

            const char* txt = "BOOO";
            const size_t txtLen = strlen(txt);
            const int glyphCount = font.countText(txt, txtLen, SkTextEncoding::kUTF8);
            const SkTextBlobBuilder::RunBuffer& buffer = builder.allocRunPos(font, glyphCount);

            font.textToGlyphs(txt, txtLen, SkTextEncoding::kUTF8, buffer.glyphs, glyphCount);

            memset(buffer.pos, 0, sizeof(SkScalar) * glyphCount * 2);
            sk_sp<SkTextBlob> blob(builder.make());
            REPORTER_ASSERT(reporter, blob->bounds().isEmpty());
        }
    }

    // Verify that text-related properties are captured in run paints.
    static void TestPaintProps(skiatest::Reporter* reporter) {
        SkFont font;
        // Kitchen sink font.
        font.setSize(42);
        font.setScaleX(4.2f);
        font.setTypeface(ToolUtils::create_portable_typeface());
        font.setSkewX(0.42f);
        font.setHinting(SkFontHinting::kFull);
        font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
        font.setEmbolden(true);
        font.setLinearMetrics(true);
        font.setSubpixel(true);
        font.setEmbeddedBitmaps(true);
        font.setForceAutoHinting(true);

        // Ensure we didn't pick default values by mistake.
        SkFont defaultFont;
        REPORTER_ASSERT(reporter, defaultFont.getSize() != font.getSize());
        REPORTER_ASSERT(reporter, defaultFont.getScaleX() != font.getScaleX());
        REPORTER_ASSERT(reporter, defaultFont.getTypefaceOrDefault() != font.getTypefaceOrDefault());
        REPORTER_ASSERT(reporter, defaultFont.getSkewX() != font.getSkewX());
        REPORTER_ASSERT(reporter, defaultFont.getHinting() != font.getHinting());
        REPORTER_ASSERT(reporter, defaultFont.getEdging() != font.getEdging());
        REPORTER_ASSERT(reporter, defaultFont.isEmbolden() != font.isEmbolden());
        REPORTER_ASSERT(reporter, defaultFont.isLinearMetrics() != font.isLinearMetrics());
        REPORTER_ASSERT(reporter, defaultFont.isSubpixel() != font.isSubpixel());
        REPORTER_ASSERT(reporter,
                        defaultFont.isEmbeddedBitmaps() != font.isEmbeddedBitmaps());
        REPORTER_ASSERT(reporter, defaultFont.isForceAutoHinting() != font.isForceAutoHinting());

        SkTextBlobBuilder builder;
        AddRun(font, 1, SkTextBlobRunIterator::kDefault_Positioning, SkPoint::Make(0, 0), builder);
        AddRun(font, 1, SkTextBlobRunIterator::kHorizontal_Positioning, SkPoint::Make(0, 0),
               builder);
        AddRun(font, 1, SkTextBlobRunIterator::kFull_Positioning, SkPoint::Make(0, 0), builder);
        sk_sp<SkTextBlob> blob(builder.make());

        SkTextBlobRunIterator it(blob.get());
        while (!it.done()) {
            REPORTER_ASSERT(reporter, it.font() == font);
            it.next();
        }

    }

private:
    struct RunDef {
        unsigned                                count;
        SkTextBlobRunIterator::GlyphPositioning pos;
        SkScalar                                x, y;
    };

    static void RunBuilderTest(skiatest::Reporter* reporter, SkTextBlobBuilder& builder,
                               const RunDef in[], unsigned inCount,
                               const RunDef out[], unsigned outCount) {
        SkFont font;

        for (unsigned i = 0; i < inCount; ++i) {
            AddRun(font, in[i].count, in[i].pos, SkPoint::Make(in[i].x, in[i].y), builder);
        }

        sk_sp<SkTextBlob> blob(builder.make());
        REPORTER_ASSERT(reporter, (inCount > 0) == SkToBool(blob));
        if (!blob) {
            return;
        }

        SkTextBlobRunIterator it(blob.get());
        for (unsigned i = 0; i < outCount; ++i) {
            REPORTER_ASSERT(reporter, !it.done());
            REPORTER_ASSERT(reporter, out[i].pos == it.positioning());
            REPORTER_ASSERT(reporter, out[i].count == it.glyphCount());
            if (SkTextBlobRunIterator::kDefault_Positioning == out[i].pos) {
                REPORTER_ASSERT(reporter, out[i].x == it.offset().x());
                REPORTER_ASSERT(reporter, out[i].y == it.offset().y());
            } else if (SkTextBlobRunIterator::kHorizontal_Positioning == out[i].pos) {
                REPORTER_ASSERT(reporter, out[i].y == it.offset().y());
            }

            for (unsigned k = 0; k < it.glyphCount(); ++k) {
                REPORTER_ASSERT(reporter, k % 128 == it.glyphs()[k]);
                if (SkTextBlobRunIterator::kHorizontal_Positioning == it.positioning()) {
                    REPORTER_ASSERT(reporter, SkIntToScalar(k % 128) == it.pos()[k]);
                } else if (SkTextBlobRunIterator::kFull_Positioning == it.positioning()) {
                    REPORTER_ASSERT(reporter, SkIntToScalar(k % 128) == it.pos()[k * 2]);
                    REPORTER_ASSERT(reporter, -SkIntToScalar(k % 128) == it.pos()[k * 2 + 1]);
                }
            }

            it.next();
        }

        REPORTER_ASSERT(reporter, it.done());
    }

    static void AddRun(const SkFont& font, int count, SkTextBlobRunIterator::GlyphPositioning pos,
                       const SkPoint& offset, SkTextBlobBuilder& builder,
                       const SkRect* bounds = nullptr) {
        switch (pos) {
        case SkTextBlobRunIterator::kDefault_Positioning: {
            const SkTextBlobBuilder::RunBuffer& rb = builder.allocRun(font, count, offset.x(),
                                                                      offset.y(), bounds);
            for (int i = 0; i < count; ++i) {
                rb.glyphs[i] = i;
            }
        } break;
        case SkTextBlobRunIterator::kHorizontal_Positioning: {
            const SkTextBlobBuilder::RunBuffer& rb = builder.allocRunPosH(font, count, offset.y(),
                                                                          bounds);
            for (int i = 0; i < count; ++i) {
                rb.glyphs[i] = i;
                rb.pos[i] = SkIntToScalar(i);
            }
        } break;
        case SkTextBlobRunIterator::kFull_Positioning: {
            const SkTextBlobBuilder::RunBuffer& rb = builder.allocRunPos(font, count, bounds);
            for (int i = 0; i < count; ++i) {
                rb.glyphs[i] = i;
                rb.pos[i * 2] = SkIntToScalar(i);
                rb.pos[i * 2 + 1] = -SkIntToScalar(i);
            }
        } break;
        default:
            SK_ABORT("unhandled positioning value");
        }
    }
};

DEF_TEST(TextBlob_builder, reporter) {
    TextBlobTester::TestBuilder(reporter);
    TextBlobTester::TestBounds(reporter);
}

DEF_TEST(TextBlob_paint, reporter) {
    TextBlobTester::TestPaintProps(reporter);
}

DEF_TEST(TextBlob_extended, reporter) {
    SkTextBlobBuilder textBlobBuilder;
    SkFont font;
    const char text1[] = "Foo";
    const char text2[] = "Bar";

    int glyphCount = font.countText(text1, strlen(text1), SkTextEncoding::kUTF8);
    SkAutoTMalloc<uint16_t> glyphs(glyphCount);
    (void)font.textToGlyphs(text1, strlen(text1), SkTextEncoding::kUTF8, glyphs.get(), glyphCount);

    auto run = textBlobBuilder.allocRunText(font, glyphCount, 0, 0, SkToInt(strlen(text2)));
    memcpy(run.glyphs, glyphs.get(), sizeof(uint16_t) * glyphCount);
    memcpy(run.utf8text, text2, strlen(text2));
    for (int i = 0; i < glyphCount; ++i) {
        run.clusters[i] = std::min(SkToU32(i), SkToU32(strlen(text2)));
    }
    sk_sp<SkTextBlob> blob(textBlobBuilder.make());
    REPORTER_ASSERT(reporter, blob);

    for (SkTextBlobRunIterator it(blob.get()); !it.done(); it.next()) {
        REPORTER_ASSERT(reporter, it.glyphCount() == (uint32_t)glyphCount);
        for (uint32_t i = 0; i < it.glyphCount(); ++i) {
            REPORTER_ASSERT(reporter, it.glyphs()[i] == glyphs[i]);
        }
        REPORTER_ASSERT(reporter, SkTextBlobRunIterator::kDefault_Positioning == it.positioning());
        REPORTER_ASSERT(reporter, (SkPoint{0.0f, 0.0f}) == it.offset());
        REPORTER_ASSERT(reporter, it.textSize() > 0);
        REPORTER_ASSERT(reporter, it.clusters());
        for (uint32_t i = 0; i < it.glyphCount(); ++i) {
            REPORTER_ASSERT(reporter, i == it.clusters()[i]);
        }
        REPORTER_ASSERT(reporter, 0 == strncmp(text2, it.text(), it.textSize()));
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////
static void add_run(SkTextBlobBuilder* builder, const char text[], SkScalar x, SkScalar y,
                    sk_sp<SkTypeface> tf) {
    SkFont font;
    font.setEdging(SkFont::Edging::kAntiAlias);
    font.setSubpixel(true);
    font.setSize(16);
    font.setTypeface(tf);

    int glyphCount = font.countText(text, strlen(text), SkTextEncoding::kUTF8);

    SkTextBlobBuilder::RunBuffer buffer = builder->allocRun(font, glyphCount, x, y);

    (void)font.textToGlyphs(text, strlen(text), SkTextEncoding::kUTF8, buffer.glyphs, glyphCount);
}

static sk_sp<SkImage> render(const SkTextBlob* blob) {
    auto surf = SkSurface::MakeRasterN32Premul(SkScalarRoundToInt(blob->bounds().width()),
                                               SkScalarRoundToInt(blob->bounds().height()));
    if (!surf) {
        return nullptr; // bounds are empty?
    }
    surf->getCanvas()->clear(SK_ColorWHITE);
    surf->getCanvas()->drawTextBlob(blob, -blob->bounds().left(), -blob->bounds().top(), SkPaint());
    return surf->makeImageSnapshot();
}

static sk_sp<SkData> SerializeTypeface(SkTypeface* tf, void* ctx) {
    auto array = (SkTArray<sk_sp<SkTypeface>>*)ctx;
    const size_t idx = array->size();
    array->emplace_back(sk_ref_sp(tf));
    // In this test, we are deserializing on the same machine, so we don't worry about endianness.
    return SkData::MakeWithCopy(&idx, sizeof(idx));
}

static sk_sp<SkTypeface> DeserializeTypeface(const void* data, size_t length, void* ctx) {
    auto array = (SkTArray<sk_sp<SkTypeface>>*)ctx;
    if (length != sizeof(size_t)) {
        SkASSERT(false);
        return nullptr;
    }
    size_t idx = *reinterpret_cast<const size_t*>(data);
    if (idx >= SkToSizeT(array->size())) {
        SkASSERT(false);
        return nullptr;
    }
    return (*array)[idx];
}

/*
 *  Build a blob with more than one typeface.
 *  Draw it into an offscreen,
 *  then serialize and deserialize,
 *  Then draw the new instance and assert it draws the same as the original.
 */
DEF_TEST(TextBlob_serialize, reporter) {
    sk_sp<SkTextBlob> blob0 = []() {
        sk_sp<SkTypeface> tf = SkTypeface::MakeFromName(nullptr, SkFontStyle::BoldItalic());

        SkTextBlobBuilder builder;
        add_run(&builder, "Hello", 10, 20, nullptr);    // don't flatten a typeface
        add_run(&builder, "World", 10, 40, tf);         // do flatten this typeface
        return builder.make();
    }();

    SkTArray<sk_sp<SkTypeface>> array;
    SkSerialProcs serializeProcs;
    serializeProcs.fTypefaceProc = &SerializeTypeface;
    serializeProcs.fTypefaceCtx = (void*) &array;
    sk_sp<SkData> data = blob0->serialize(serializeProcs);
    REPORTER_ASSERT(reporter, array.size() == 1);
    SkDeserialProcs deserializeProcs;
    deserializeProcs.fTypefaceProc = &DeserializeTypeface;
    deserializeProcs.fTypefaceCtx = (void*) &array;
    sk_sp<SkTextBlob> blob1 = SkTextBlob::Deserialize(data->data(), data->size(), deserializeProcs);

    sk_sp<SkImage> img0 = render(blob0.get());
    sk_sp<SkImage> img1 = render(blob1.get());
    if (img0 && img1) {
        REPORTER_ASSERT(reporter, ToolUtils::equal_pixels(img0.get(), img1.get()));
    }
}

DEF_TEST(TextBlob_MakeAsDrawText, reporter) {
    const char text[] = "Hello";
    auto blob = SkTextBlob::MakeFromString(text, SkFont(), SkTextEncoding::kUTF8);

    int runs = 0;
    for(SkTextBlobRunIterator it(blob.get()); !it.done(); it.next()) {
        REPORTER_ASSERT(reporter, it.glyphCount() == strlen(text));
        REPORTER_ASSERT(reporter, it.positioning() == SkTextBlobRunIterator::kFull_Positioning);
        runs += 1;
    }
    REPORTER_ASSERT(reporter, runs == 1);

}

DEF_TEST(TextBlob_iter, reporter) {
    sk_sp<SkTypeface> tf = SkTypeface::MakeFromName(nullptr, SkFontStyle::BoldItalic());

    SkTextBlobBuilder builder;
    add_run(&builder, "Hello", 10, 20, nullptr);
    add_run(&builder, "World", 10, 40, tf);
    auto blob = builder.make();

    SkTextBlob::Iter::Run expected[] = {
        { nullptr, 5, nullptr },
        { tf.get(), 5, nullptr },
    };

    SkTextBlob::Iter iter(*blob);
    SkTextBlob::Iter::Run run;
    for (auto exp : expected) {
        REPORTER_ASSERT(reporter, iter.next(&run));
        REPORTER_ASSERT(reporter, run.fTypeface == exp.fTypeface);
        REPORTER_ASSERT(reporter, run.fGlyphCount == exp.fGlyphCount);
        for (int i = 0; i < run.fGlyphCount; ++i) {
            REPORTER_ASSERT(reporter, run.fGlyphIndices[i] != 0);
        }
    }
    REPORTER_ASSERT(reporter, !iter.next(&run));    // we're done

    SkTextBlob::Iter iter2(*blob);
    REPORTER_ASSERT(reporter, iter2.next(&run));
    // Hello should have the same glyph repeated for the 'l'
    REPORTER_ASSERT(reporter, run.fGlyphIndices[2] == run.fGlyphIndices[3]);
}

DEF_TEST(TextBlob_getIntercepts, reporter) {
    SkFont font;
    font.setSize(16);

    SkPoint lowPos[1] = { SkPoint::Make(0, 5) };
    SkPoint highPos[1] = { SkPoint::Make(0, -8) };
    SkPoint zeroPos[1] = { SkPoint::Make(0, 0) };

    // 'x' sitting on baseline
    auto blobZeroX = SkTextBlob::MakeFromPosText("x", 1, zeroPos, font);
    // 'x' lowered to intersect baseline
    auto blobLowX = SkTextBlob::MakeFromPosText("x", 1, lowPos, font);
    // 'y' sitting on baseline
    auto blobZeroY = SkTextBlob::MakeFromPosText("y", 1, zeroPos, font);
    // 'y' raised to not intersect baseline
    auto blobHighY = SkTextBlob::MakeFromPosText("y", 1, highPos, font);

    // bounds right below baseline
    SkScalar bounds[2] = { 1, 2 };

    // 'x' on baseline should not intersect
    REPORTER_ASSERT(reporter, blobZeroX->getIntercepts(bounds, nullptr) == 0);
    // lowered 'x' should intersect
    REPORTER_ASSERT(reporter, blobLowX->getIntercepts(bounds, nullptr) == 2);
    // 'y' on baseline should intersect
    REPORTER_ASSERT(reporter, blobZeroY->getIntercepts(bounds, nullptr) == 2);
    // raised 'y' should not intersect
    REPORTER_ASSERT(reporter, blobHighY->getIntercepts(bounds, nullptr) == 0);
}
