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

#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkRSXform.h"
#include "include/core/SkShader.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTextBlob.h"
#include "tools/ToolUtils.h"

// Exercises RSX text blobs + shader with various local matrix combinations.
// Yellow grid should stay aligned for text vs. background.
class RSXShaderGM : public skiagm::GM {
public:
private:
    SkString onShortName() override {
        return SkString("rsx_blob_shader");
    }

    SkISize onISize() override {
        return SkISize::Make(kSZ*kScale*2.1f, kSZ*kScale*2.1f);
    }

    void onOnceBeforeDraw() override {
        const SkFontStyle style(SkFontStyle::kExtraBlack_Weight,
                                SkFontStyle::kNormal_Width,
                                SkFontStyle::kUpright_Slant);
        SkFont font(ToolUtils::create_portable_typeface(nullptr, style), kFontSZ);
        font.setEdging(SkFont::Edging::kAntiAlias);

        static constexpr char txt[] = "TEST";
        SkGlyphID glyphs[16];
        float     widths[16];
        const auto glyph_count = font.textToGlyphs(txt, strlen(txt), SkTextEncoding::kUTF8,
                                                   glyphs, std::size(glyphs));
        font.getWidths(glyphs, glyph_count, widths);

        SkTextBlobBuilder builder;
        const auto& buf = builder.allocRunRSXform(font, glyph_count);
        std::copy(glyphs, glyphs + glyph_count, buf.glyphs);

        float x = 0;
        for (int i = 0; i < glyph_count; ++i) {
            buf.xforms()[i] = {
                1, 0,
                x, 0,
            };
            x += widths[i];
        }

        fBlob = builder.make();
    }

    void onDraw(SkCanvas* canvas) override {
        canvas->scale(kScale, kScale);
        this->draw_one(canvas,
            {0, 0}, SkMatrix::I(), SkMatrix::I());
        this->draw_one(canvas,
            {kSZ*1.1f, 0}, SkMatrix::Scale(2, 2), SkMatrix::I());
        this->draw_one(canvas,
            {0, kSZ*1.1f}, SkMatrix::I(), SkMatrix::RotateDeg(45));
        this->draw_one(canvas,
            {kSZ*1.1f, kSZ*1.1f}, SkMatrix::Scale(2, 2), SkMatrix::RotateDeg(45));
    }

    void draw_one(SkCanvas* canvas, SkPoint pos, const SkMatrix& lm,
                  const SkMatrix& outer_lm) const {
        SkAutoCanvasRestore acr(canvas, true);
        canvas->translate(pos.fX, pos.fY);

        SkPaint p;
        p.setShader(make_shader(lm, outer_lm));
        p.setAlphaf(0.75f);
        canvas->drawRect(SkRect::MakeWH(kSZ, kSZ), p);

        p.setAlphaf(1);
        canvas->drawTextBlob(fBlob, 0, kFontSZ*1, p);
        canvas->drawTextBlob(fBlob, 0, kFontSZ*2, p);
    }

    static sk_sp<SkShader> make_shader(const SkMatrix& lm, const SkMatrix& outer_lm) {
        static constexpr SkISize kTileSize = { 30, 30 };
        auto surface = SkSurface::MakeRasterN32Premul(kTileSize.width(), kTileSize.height());

        SkPaint p;
        p.setColor(0xffffff00);
        surface->getCanvas()->drawPaint(p);
        p.setColor(0xff008000);
        surface->getCanvas()
               ->drawRect({0, 0, kTileSize.width()*0.9f, kTileSize.height()*0.9f}, p);

        return surface->makeImageSnapshot()
                ->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
                             SkSamplingOptions(SkFilterMode::kLinear), &lm)
                ->makeWithLocalMatrix(outer_lm);
    }

    inline static constexpr float kSZ     = 300,
                                  kFontSZ = kSZ * 0.38,
                                  kScale  = 1.4f;

    sk_sp<SkTextBlob> fBlob;
};

DEF_GM(return new RSXShaderGM;)
