/*
 * 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/gm.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkShader.h"
#include "include/core/SkTextBlob.h"
#include "include/core/SkTileMode.h"
#include "include/core/SkTypeface.h"
#include "tools/ToolUtils.h"
#include "tools/fonts/FontToolUtils.h"

#include <string.h>

static void rotated_checkerboard_shader(SkPaint* paint,
                                        SkColor c1,
                                        SkColor c2,
                                        int size) {
    SkBitmap bm;
    bm.allocN32Pixels(2 * size, 2 * size);
    bm.eraseColor(c1);
    bm.eraseArea(SkIRect::MakeLTRB(0, 0, size, size), c2);
    bm.eraseArea(SkIRect::MakeLTRB(size, size, 2 * size, 2 * size), c2);
    SkMatrix matrix;
    matrix.setScale(0.75f, 0.75f);
    matrix.preRotate(30.0f);
    paint->setShader(bm.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
                                   SkSamplingOptions(), matrix));
}

static void exercise_draw_pos_text(SkCanvas* canvas,
                                   const char* text,
                                   SkScalar x, SkScalar y,
                                   const SkFont& font, const SkPaint& paint) {
    const int count = font.countText(text, strlen(text), SkTextEncoding::kUTF8);
    SkTextBlobBuilder builder;
    auto rec = builder.allocRunPos(font, count);
    font.textToGlyphs(text, strlen(text), SkTextEncoding::kUTF8, rec.glyphs, count);
    font.getPos(rec.glyphs, count, rec.points(), {x, y});
    canvas->drawTextBlob(builder.make(), 0, 0, paint);
}

static void exercise_draw_pos_text_h(SkCanvas* canvas,
                                     const char* text,
                                     SkScalar x, SkScalar y,
                                     const SkFont& font, const SkPaint& paint) {
    const int count = font.countText(text, strlen(text), SkTextEncoding::kUTF8);
    SkTextBlobBuilder builder;
    auto rec = builder.allocRunPosH(font, count, 0);
    font.textToGlyphs(text, strlen(text), SkTextEncoding::kUTF8, rec.glyphs, count);
    font.getXPos(rec.glyphs, count, rec.pos);
    canvas->drawTextBlob(builder.make(), x, y, paint);
}

static void test_text(SkCanvas* canvas, SkScalar size,
                      SkColor color, SkScalar Y) {
    SkFont font(ToolUtils::DefaultPortableTypeface(), 24);
    font.setEdging(SkFont::Edging::kAlias);
    SkPaint type;
    type.setColor(color);
    const char text[] = "HELLO WORLD";
    canvas->drawSimpleText(text, strlen(text), SkTextEncoding::kUTF8, 32, size / 2 + Y,
                           font, type);
    SkScalar lineSpacing = font.getSpacing();
    exercise_draw_pos_text(canvas, text, 32, size / 2 + Y + lineSpacing, font, type);
    exercise_draw_pos_text_h(canvas, text, 32,
                             size / 2 + Y + 2 * lineSpacing, font, type);
}

// If this GM works correctly, the cyan layer should be lined up with
// the objects below it.
DEF_SIMPLE_GM(skbug_257, canvas, 512, 512) {
    const SkScalar size = 256;
    SkAutoCanvasRestore autoCanvasRestore0(canvas, true);
    const SkScalar scale = 1.00168f;
    canvas->scale(scale, scale);
    {
        SkPaint checker;
        rotated_checkerboard_shader(&checker, SK_ColorWHITE, SK_ColorBLACK, 16);
        checker.setAntiAlias(true);

        SkAutoCanvasRestore autoCanvasRestore(canvas, true);
        canvas->clear(0xFFCECFCE);
        SkScalar translate = 225364.0f;
        canvas->translate(0, -translate);

        // Test rects
        SkRect rect = SkRect::MakeLTRB(8, 8 + translate, size - 8,
                                       size - 8 + translate);
        canvas->drawRect(rect, checker);

        // Test Paths
        canvas->translate(size, 0);
        SkRRect rrect;
        SkVector radii[4] = {{40, 40}, {40, 40}, {40, 40}, {40, 40}};
        rrect.setRectRadii(rect, radii);
        canvas->drawRRect(rrect, checker);

        // Test Points
        canvas->translate(-size, size);
        SkScalar delta = 1.0 / 64.0;
        SkPoint points[8] = {{size / 2, 8 + translate},
                             {size / 2, 8 + translate + delta},
                             {8, size / 2 + translate},
                             {8, size / 2 + translate + delta},
                             {size / 2, size - 8 + translate},
                             {size / 2, size - 8 + translate + delta},
                             {size - 8, size / 2 + translate},
                             {size - 8, size / 2 + translate + delta}};
        checker.setStyle(SkPaint::kStroke_Style);
        checker.setStrokeWidth(8);
        checker.setStrokeCap(SkPaint::kRound_Cap);
        canvas->drawPoints(SkCanvas::kLines_PointMode, 8, points, checker);

        // Test Text
        canvas->translate(size, 0);
        test_text(canvas, size, SK_ColorBLACK, translate);
    }
    // reference points (without the huge translations).
    SkPaint stroke;
    stroke.setStyle(SkPaint::kStroke_Style);
    stroke.setStrokeWidth(5);
    stroke.setColor(SK_ColorCYAN);
    canvas->drawCircle(size / 2, size / 2, size / 2 - 10, stroke);
    canvas->drawCircle(3 * size / 2, size / 2, size / 2 - 10, stroke);
    canvas->drawCircle(size / 2, 384, size / 2 - 10, stroke);
    canvas->translate(size, size);
    test_text(canvas, size, SK_ColorCYAN, 0.0f);
}
