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

#include "gm.h"

#include "Resources.h"
#include "SkBlurMask.h"
#include "SkBlurMaskFilter.h"
#include "SkCanvas.h"
#include "SkGradientShader.h"
#include "SkImage.h"
#include "SkRandom.h"
#include "SkStream.h"
#include "SkSurface.h"
#include "SkTextBlob.h"
#include "SkTypeface.h"

namespace skiagm {
class TextBlobMixedSizes : public GM {
public:
    // This gm tests that textblobs of mixed sizes with a large glyph will render properly
    TextBlobMixedSizes(bool useDFT) : fUseDFT(useDFT) {}

protected:
    void onOnceBeforeDraw() override {
        SkAutoTUnref<SkTypeface> typeface(GetResourceAsTypeface("/fonts/HangingS.ttf"));
        SkTextBlobBuilder builder;

        // make textblob.  To stress distance fields, we choose sizes appropriately
        SkPaint paint;
        paint.setAntiAlias(true);
        paint.setSubpixelText(true);
        paint.setLCDRenderText(true);
        paint.setTypeface(typeface);

        const char* text = "Sk";

        // extra large
        paint.setTextSize(262);

        sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, 0);

        // large
        SkRect bounds;
        paint.measureText(text, strlen(text), &bounds);
        SkScalar yOffset = bounds.height();
        paint.setTextSize(162);

        sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, yOffset);

        // Medium
        paint.measureText(text, strlen(text), &bounds);
        yOffset += bounds.height();
        paint.setTextSize(72);

        sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, yOffset);

        // Small
        paint.measureText(text, strlen(text), &bounds);
        yOffset += bounds.height();
        paint.setTextSize(32);

        sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, yOffset);

        // micro (will fall out of distance field text even if distance field text is enabled)
        paint.measureText(text, strlen(text), &bounds);
        yOffset += bounds.height();
        paint.setTextSize(14);

        sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, yOffset);

        // build
        fBlob.reset(builder.build());
    }

    SkString onShortName() override {
        SkString name("textblobmixedsizes");
        if (fUseDFT) {
            name.appendf("_df");
        }
        return name;
    }

    SkISize onISize() override {
        return SkISize::Make(kWidth, kHeight);
    }

    void onDraw(SkCanvas* inputCanvas) override {
        SkCanvas* canvas = inputCanvas;
        SkAutoTUnref<SkSurface> surface;
        if (fUseDFT) {
#if SK_SUPPORT_GPU
            // Create a new Canvas to enable DFT
            GrContext* ctx = inputCanvas->getGrContext();
            SkImageInfo info = SkImageInfo::MakeN32Premul(onISize());
            SkSurfaceProps props(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
                                 SkSurfaceProps::kLegacyFontHost_InitType);
            surface.reset(SkSurface::NewRenderTarget(ctx, SkSurface::kNo_Budgeted, info, 0,
                                                     &props));
            canvas = surface.get() ? surface->getCanvas() : inputCanvas;
            // init our new canvas with the old canvas's matrix
            canvas->setMatrix(inputCanvas->getTotalMatrix());
#endif
        }
        canvas->drawColor(sk_tool_utils::color_to_565(SK_ColorWHITE));

        SkRect bounds = fBlob->bounds();

        static const int kPadX = SkScalarFloorToInt(bounds.width() / 3);
        static const int kPadY = SkScalarFloorToInt(bounds.height() / 3);

        int rowCount = 0;
        canvas->translate(SkIntToScalar(kPadX), SkIntToScalar(kPadY));
        canvas->save();
        SkRandom random;

        SkPaint paint;
        if (!fUseDFT) {
            paint.setColor(sk_tool_utils::color_to_565(SK_ColorWHITE));
        }
        paint.setAntiAlias(false);

        static const SkScalar kSigma = SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(8));

        // setup blur paint
        SkPaint blurPaint(paint);
        blurPaint.setColor(sk_tool_utils::color_to_565(SK_ColorBLACK));
        SkAutoTUnref<SkMaskFilter> mf(SkBlurMaskFilter::Create(kNormal_SkBlurStyle, kSigma));
        blurPaint.setMaskFilter(mf);

        for (int i = 0; i < 4; i++) {
            canvas->save();
            switch (i % 2) {
                case 0:
                    canvas->rotate(random.nextF() * 45.f);
                    break;
                case 1:
                    canvas->rotate(-random.nextF() * 45.f);
                    break;
            }
            if (!fUseDFT) {
                canvas->drawTextBlob(fBlob, 0, 0, blurPaint);
            }
            canvas->drawTextBlob(fBlob, 0, 0, paint);
            canvas->restore();
            canvas->translate(bounds.width() + SK_Scalar1 * kPadX, 0);
            ++rowCount;
            if ((bounds.width() + 2 * kPadX) * rowCount > kWidth) {
                canvas->restore();
                canvas->translate(0, bounds.height() + SK_Scalar1 * kPadY);
                canvas->save();
                rowCount = 0;
            }
        }
        canvas->restore();

#if SK_SUPPORT_GPU
        // render offscreen buffer
        if (surface) {
            SkAutoCanvasRestore acr(inputCanvas, true);
            // since we prepended this matrix already, we blit using identity
            inputCanvas->resetMatrix();
            SkImage* image = surface->newImageSnapshot();
            inputCanvas->drawImage(image, 0, 0, nullptr);
            image->unref();
        }
#endif
    }

private:
    SkAutoTUnref<const SkTextBlob> fBlob;

    static const int kWidth = 2000;
    static const int kHeight = 2000;

    bool fUseDFT;

    typedef GM INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

DEF_GM( return new TextBlobMixedSizes(false); )
#if SK_SUPPORT_GPU
DEF_GM( return new TextBlobMixedSizes(true); )
#endif
}
