/*
 * 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/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/utils/SkCustomTypeface.h"
#include "tools/Resources.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;
    const float upem = font.getTypefaceOrDefault()->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.getTypefaceOrDefault()->fontStyle());

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

        SkScalar width;
        font.getWidths(&glyph, 1, &width);
        SkPath path;
        font.getPath(glyph, &path);
        path.transform(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();
}

#include "include/core/SkTextBlob.h"

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

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

public:
    UserFontGM() {}

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

    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 onShortName() override { return SkString("user_typeface"); }

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

    void onDraw(SkCanvas* canvas) override {
        auto waterfall = [&](sk_sp<SkTypeface> tf) {
            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 (tf == nullptr) {
                    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(nullptr);
        canvas->translate(400, 0);
        waterfall(fTF);
    }
};
DEF_GM(return new UserFontGM;)
