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

#include "Benchmark.h"
#include "Resources.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkRandom.h"
#include "SkStream.h"
#include "SkString.h"
#include "SkTemplates.h"
#include "SkTypeface.h"

enum FontQuality {
    kBW,
    kAA,
    kLCD,
};

static const char* fontQualityName(const SkPaint& paint) {
    if (!paint.isAntiAlias()) {
        return "BW";
    }
    if (paint.isLCDRenderText()) {
        return "LCD";
    }
    return "AA";
}

/*  Some considerations for performance:
        short -vs- long strings (measuring overhead)
        tiny -vs- large pointsize (measure blit -vs- overhead)
        1 -vs- many point sizes (measure cache lookup)
        normal -vs- subpixel -vs- lineartext (minor)
        force purge after each draw to measure scaler
        textencoding?
        text -vs- postext - pathtext
 */
class TextBench : public Benchmark {
    SkPaint     fPaint;
    SkString    fText;
    SkString    fName;
    FontQuality fFQ;
    bool        fDoPos;
    bool        fDoColorEmoji;
    SkAutoTUnref<SkTypeface> fColorEmojiTypeface;
    SkPoint*    fPos;
public:
    TextBench(const char text[], int ps,
              SkColor color, FontQuality fq, bool doColorEmoji = false, bool doPos = false)
        : fText(text)
        , fFQ(fq)
        , fDoPos(doPos)
        , fDoColorEmoji(doColorEmoji)
        , fPos(nullptr) {
        fPaint.setAntiAlias(kBW != fq);
        fPaint.setLCDRenderText(kLCD == fq);
        fPaint.setTextSize(SkIntToScalar(ps));
        fPaint.setColor(color);
    }

    virtual ~TextBench() {
        delete[] fPos;
    }

protected:
    void onDelayedSetup() override {
        if (fDoColorEmoji) {
            SkASSERT(kBW == fFQ);
            fColorEmojiTypeface.reset(GetResourceAsTypeface("/fonts/Funkster.ttf"));
        }

        if (fDoPos) {
            size_t len = fText.size();
            SkScalar* adv = new SkScalar[len];
            fPaint.getTextWidths(fText.c_str(), len, adv);
            fPos = new SkPoint[len];
            SkScalar x = 0;
            for (size_t i = 0; i < len; ++i) {
                fPos[i].set(x, SkIntToScalar(50));
                x += adv[i];
            }
            delete[] adv;
        }
    }


    const char* onGetName() override {
        fName.printf("text_%g", SkScalarToFloat(fPaint.getTextSize()));
        if (fDoPos) {
            fName.append("_pos");
        }
        fName.appendf("_%s", fontQualityName(fPaint));
        if (SK_ColorBLACK == fPaint.getColor()) {
            fName.append("_BK");
        } else if (SK_ColorWHITE == fPaint.getColor()) {
            fName.append("_WT");
        } else {
            fName.appendf("_%02X", fPaint.getAlpha());
        }

        if (fDoColorEmoji) {
            fName.append("_ColorEmoji");
        }

        return fName.c_str();
    }

    void onDraw(int loops, SkCanvas* canvas) override {
        const SkIPoint dim = this->getSize();
        SkRandom rand;

        SkPaint paint(fPaint);
        this->setupPaint(&paint);
        // explicitly need these
        paint.setColor(fPaint.getColor());
        paint.setAntiAlias(kBW != fFQ);
        paint.setLCDRenderText(kLCD == fFQ);

        if (fDoColorEmoji && fColorEmojiTypeface) {
            paint.setTypeface(fColorEmojiTypeface);
        }

        const SkScalar x0 = SkIntToScalar(-10);
        const SkScalar y0 = SkIntToScalar(-10);

        if (fDoPos) {
            // realistically, the matrix is often at least translated, so we
            // do that since it exercises different code in drawPosText.
            canvas->translate(SK_Scalar1, SK_Scalar1);
        }

        for (int i = 0; i < loops; i++) {
            if (fDoPos) {
                canvas->drawPosText(fText.c_str(), fText.size(), fPos, paint);
            } else {
                SkScalar x = x0 + rand.nextUScalar1() * dim.fX;
                SkScalar y = y0 + rand.nextUScalar1() * dim.fY;
                canvas->drawText(fText.c_str(), fText.size(), x, y, paint);
            }
        }
    }

private:
    typedef Benchmark INHERITED;
};

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

#define STR     "Hamburgefons"

DEF_BENCH( return new TextBench(STR, 16, 0xFFFFFFFF, kBW); )
DEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kBW); )
DEF_BENCH( return new TextBench(STR, 16, 0xFFFF0000, kBW); )
DEF_BENCH( return new TextBench(STR, 16, 0x88FF0000, kBW); )

DEF_BENCH( return new TextBench(STR, 16, 0xFFFFFFFF, kAA); )
DEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kAA); )
DEF_BENCH( return new TextBench(STR, 16, 0xFFFF0000, kAA); )
DEF_BENCH( return new TextBench(STR, 16, 0x88FF0000, kAA); )

DEF_BENCH( return new TextBench(STR, 16, 0xFFFFFFFF, kLCD); )
DEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kLCD); )
DEF_BENCH( return new TextBench(STR, 16, 0xFFFF0000, kLCD); )
DEF_BENCH( return new TextBench(STR, 16, 0x88FF0000, kLCD); )

DEF_BENCH( return new TextBench(STR, 16, 0xFFFFFFFF, kBW, true); )
DEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kBW, true); )
DEF_BENCH( return new TextBench(STR, 16, 0xFFFF0000, kBW, true); )
DEF_BENCH( return new TextBench(STR, 16, 0x88FF0000, kBW, true); )

DEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kBW, true, true); )
DEF_BENCH( return new TextBench(STR, 16, 0xFF000000, kAA, false, true); )
