/*
 * Copyright 2020 Google LLC
 *
 * 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/SkFont.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkSize.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkTextBlob.h"
#include "include/utils/SkCustomTypeface.h"
#include "src/core/SkFontPriv.h"
#include "tools/Resources.h"
#include "tools/fonts/FontToolUtils.h"


static sk_sp<SkDrawable> make_drawable(const SkPath& path) {
    const auto bounds = path.computeTightBounds();

    SkPictureRecorder recorder;
    auto* canvas = recorder.beginRecording(bounds);

    SkPaint paint;
    paint.setColor(0xff008000);
    paint.setAntiAlias(true);

    canvas->drawPath(path, paint);

    return recorder.finishRecordingAsDrawable();
}

static sk_sp<SkTypeface> make_tf() {
    SkCustomTypefaceBuilder builder;
    SkFont font = ToolUtils::DefaultFont();
    SkASSERT(font.getTypeface());
    const float upem = font.getTypeface()->getUnitsPerEm();

    // request a big size, to improve precision at the fontscaler level
    font.setSize(upem);
    font.setHinting(SkFontHinting::kNone);

    // so we can scale our paths back down to 1-point
    const SkMatrix scale = SkMatrix::Scale(1.0f/upem, 1.0f/upem);

    {
        SkFontMetrics metrics;
        font.getMetrics(&metrics);
        builder.setMetrics(metrics, 1.0f/upem);
    }
    builder.setFontStyle(font.getTypeface()->fontStyle());

    // Steal the first 128 chars from the default font
    for (SkUnichar index = 0; index <= 127; ++index) {
        SkGlyphID glyph = font.unicharToGlyph(index);

        SkScalar width = font.getWidth(glyph);
        SkPath path = font.getPath(glyph).value_or(SkPath()).makeTransform(scale);

        // we use the charcode to be our glyph index, since we have no cmap table
        if (index % 2) {
            builder.setGlyph(index, width/upem, make_drawable(path), path.computeTightBounds());
        } else {
            builder.setGlyph(index, width/upem, path);
        }
    }

    return builder.detach();
}

static sk_sp<SkTypeface> round_trip(sk_sp<SkTypeface> tf) {
    auto data = tf->serialize();
    SkMemoryStream stream(data->data(), data->size());
    sk_sp<SkTypeface> face = SkTypeface::MakeDeserialize(&stream, nullptr);
    SkASSERT(face);
    return face;
}

class UserFontGM : public skiagm::GM {
    sk_sp<SkTypeface> fTF;

public:
    UserFontGM() {}

    void onOnceBeforeDraw() override {
        // test serialization
        fTF = round_trip(make_tf());
    }

    static sk_sp<SkTextBlob> make_blob(sk_sp<SkTypeface> tf, float size, float* spacing) {
        SkFont font(tf);
        font.setSize(size);
        font.setEdging(SkFont::Edging::kAntiAlias);
        *spacing = font.getMetrics(nullptr);
        return SkTextBlob::MakeFromString("Typeface", font);
    }

    bool runAsBench() const override { return true; }

    SkString getName() const override { return SkString("user_typeface"); }

    SkISize getISize() override { return {810, 452}; }

    void onDraw(SkCanvas* canvas) override {
        auto waterfall = [&](sk_sp<SkTypeface> tf, bool defaultFace) {
            SkPaint paint;
            paint.setAntiAlias(true);

            float spacing;
            float x = 20,
                  y = 16;
            for (float size = 9; size <= 100; size *= 1.25f) {
                auto blob = make_blob(tf, size, &spacing);

                // shared baseline
                if (defaultFace) {
                    paint.setColor(0xFFDDDDDD);
                    canvas->drawRect({0, y, 810, y+1}, paint);
                }

                paint.setColor(0xFFCCCCCC);
                paint.setStyle(SkPaint::kStroke_Style);
                canvas->drawRect(blob->bounds().makeOffset(x, y), paint);

                paint.setStyle(SkPaint::kFill_Style);
                paint.setColor(SK_ColorBLACK);
                canvas->drawTextBlob(blob, x, y, paint);

                y += SkScalarRoundToInt(spacing * 1.25f + 2);
            }
        };

        waterfall(ToolUtils::DefaultTypeface(), true);
        canvas->translate(400, 0);
        waterfall(fTF, false);
    }
};
DEF_GM(return new UserFontGM;)
