/*
 * Copyright 2014 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 "SkCanvas.h"
#include "SkGradientShader.h"
#include "SkPoint.h"
#include "SkShader.h"
#include "SkTextBlob.h"
#include "SkTDArray.h"
#include "SkTypeface.h"

// This GM exercises drawTextBlob offset vs. shader space behavior.
class TextBlobShaderGM : public skiagm::GM {
public:
    TextBlobShaderGM(const char* txt) {
        SkPaint p;
        size_t txtLen = strlen(txt);
        fGlyphs.append(p.textToGlyphs(txt, txtLen, NULL));
        p.textToGlyphs(txt, txtLen, fGlyphs.begin());
    }

protected:

    virtual void onOnceBeforeDraw() SK_OVERRIDE {
        SkPaint p;
        p.setAntiAlias(true);
        p.setSubpixelText(true);
        p.setTextSize(30);
        p.setTextEncoding(SkPaint::kGlyphID_TextEncoding);

        SkTextBlobBuilder builder;
        int glyphCount = fGlyphs.count();
        const SkTextBlobBuilder::RunBuffer* run;

        run = &builder.allocRun(p, glyphCount, 10, 10, NULL);
        memcpy(run->glyphs, fGlyphs.begin(), glyphCount * sizeof(uint16_t));

        run = &builder.allocRunPosH(p, glyphCount,  80, NULL);
        memcpy(run->glyphs, fGlyphs.begin(), glyphCount * sizeof(uint16_t));
        for (int i = 0; i < glyphCount; ++i) {
            run->pos[i] = p.getTextSize() * i * .75f;
        }

        run = &builder.allocRunPos(p, glyphCount, NULL);
        memcpy(run->glyphs, fGlyphs.begin(), glyphCount * sizeof(uint16_t));
        for (int i = 0; i < glyphCount; ++i) {
            run->pos[i * 2] = p.getTextSize() * i * .75f;
            run->pos[i * 2 + 1] = 150 + 5 * sinf((float)i * 8 / glyphCount);
        }

        fBlob.reset(builder.build());

        SkColor  colors[2];
        colors[0] = SK_ColorRED;
        colors[1] = SK_ColorGREEN;

        SkScalar pos[SK_ARRAY_COUNT(colors)];
        for (unsigned i = 0; i < SK_ARRAY_COUNT(pos); ++i) {
            pos[i] = (float)i / (SK_ARRAY_COUNT(pos) - 1);
        }

        SkISize sz = this->onISize();
        fShader.reset(SkGradientShader::CreateRadial(SkPoint::Make(SkIntToScalar(sz.width() / 2),
                                                                   SkIntToScalar(sz.height() / 2)),
                                                     sz.width() * .66f, colors, pos,
                                                     SK_ARRAY_COUNT(colors),
                                                     SkShader::kRepeat_TileMode));
    }

    virtual uint32_t onGetFlags() const SK_OVERRIDE {
        return kSkip565_Flag;
    }

    virtual SkString onShortName() SK_OVERRIDE {
        return SkString("textblobshader");
    }

    virtual SkISize onISize() SK_OVERRIDE {
        return SkISize::Make(640, 480);
    }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        SkPaint p;
        p.setStyle(SkPaint::kFill_Style);
        p.setShader(fShader);

        SkISize sz = this->onISize();
        static const int kXCount = 4;
        static const int kYCount = 3;
        for (int i = 0; i < kXCount; ++i) {
            for (int j = 0; j < kYCount; ++j) {
                canvas->drawTextBlob(fBlob,
                                     SkIntToScalar(i * sz.width() / kXCount),
                                     SkIntToScalar(j * sz.height() / kYCount),
                                     p);
            }
        }
    }

private:
    SkTDArray<uint16_t>            fGlyphs;
    SkAutoTUnref<const SkTextBlob> fBlob;
    SkAutoTUnref<SkShader>         fShader;

    typedef skiagm::GM INHERITED;
};

DEF_GM( return SkNEW_ARGS(TextBlobShaderGM, ("Blobber")); )
