/*
 * 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/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/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPathEffect.h"
#include "include/core/SkPoint.h"
#include "include/core/SkScalar.h"
#include "include/core/SkTextBlob.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkDashPathEffect.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"

static void test_nulldev(SkCanvas* canvas) {
    SkBitmap bm;
    bm.setInfo(SkImageInfo::MakeN32Premul(30, 30));
    // notice: no pixels mom! be sure we don't crash
    // https://code.google.com/p/chromium/issues/detail?id=352616
    SkCanvas c(bm);

    SkBitmap src;
    src.allocN32Pixels(10, 10);
    src.eraseColor(SK_ColorRED);

    // ensure we don't crash
    c.writePixels(src, 0, 0);
}

static void draw_text_stroked(SkCanvas* canvas, const SkPaint& paint, const SkFont& font,
                              SkScalar strokeWidth) {
    SkPaint p(paint);
    SkPoint loc = { 20, 435 };

    if (strokeWidth > 0) {
        p.setStyle(SkPaint::kFill_Style);
        canvas->drawSimpleText("P", 1, SkTextEncoding::kUTF8, loc.fX, loc.fY - 225, font, p);
        canvas->drawTextBlob(SkTextBlob::MakeFromPosText("P", 1, &loc, font), 0, 0, p);
    }

    p.setColor(SK_ColorRED);
    p.setStyle(SkPaint::kStroke_Style);
    p.setStrokeWidth(strokeWidth);

    canvas->drawSimpleText("P", 1, SkTextEncoding::kUTF8, loc.fX, loc.fY - 225, font, p);
    canvas->drawTextBlob(SkTextBlob::MakeFromPosText("P", 1, &loc, font), 0, 0, p);
}

static void draw_text_set(SkCanvas* canvas, const SkPaint& paint, const SkFont& font) {
    SkAutoCanvasRestore acr(canvas, true);

    draw_text_stroked(canvas, paint, font, 10);

    canvas->translate(200, 0);
    draw_text_stroked(canvas, paint, font, 0);

    const SkScalar intervals[] = { 20, 10, 5, 10 };
    const SkScalar phase = 0;

    canvas->translate(200, 0);
    SkPaint p(paint);
    p.setPathEffect(SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), phase));
    draw_text_stroked(canvas, p, font, 10);
}

namespace {
    enum {
        kBelowThreshold_TextSize = 255,
        kAboveThreshold_TextSize = 257
    };
}

DEF_SIMPLE_GM(stroketext, canvas, 1200, 480) {
    if (true) { test_nulldev(canvas); }

    SkPaint paint;
    paint.setAntiAlias(true);

    SkFont font(ToolUtils::create_portable_typeface(), kBelowThreshold_TextSize);
    draw_text_set(canvas, paint, font);

    canvas->translate(600, 0);
    font.setSize(kAboveThreshold_TextSize);
    draw_text_set(canvas, paint, font);
}

DEF_SIMPLE_GM_CAN_FAIL(stroketext_native, canvas, msg, 650, 320) {
    sk_sp<SkTypeface> ttf = MakeResourceAsTypeface("fonts/Stroking.ttf");
    sk_sp<SkTypeface> otf = MakeResourceAsTypeface("fonts/Stroking.otf");
    if (!ttf && !otf) {
        msg->append("No support for ttf or otf.");
        return skiagm::DrawResult::kSkip;
    }

    SkPaint p;
    p.setAntiAlias(true);
    p.setStyle(SkPaint::kStroke_Style);
    p.setStrokeWidth(10);
    p.setStrokeCap(SkPaint::kRound_Cap);
    p.setStrokeJoin(SkPaint::kRound_Join);
    p.setARGB(0xff, 0xbb, 0x00, 0x00);

    if (ttf) {
        /* Stroking.ttf is structured like:
            nothing U+25CB ○ (nothing inside)
            something U+25C9 ◉ (a tiny thing inside)
            - off (point off / empty quad with implicit end) (before U+207B ⁻ / after U+208B ₋)
            + on  (point on / empty line) (before U+207A ⁺ / after U+208A ₊)
            0 off off (two implicit quads) (before U+2070 ⁰ / after U+2080 ₀)
            1 off on  (quad with implicit close around) (before U+00B9 ¹ / after U+2081 ₁)
            2 on  off (quad with implicit close) (before U+00B2 ² / after U+2082 ₂)
            3 on  on  (empty line) (before U+00B3 ³ / after U+2083 ₃)
        */
        SkFont font(ttf, 100);
        canvas->drawString("○◉  ⁻₋⁺₊", 10, 100, font, p);
        canvas->drawString("⁰₀¹₁²₂³₃", 10, 200, font, p);
    }

    if (otf) {
        /* Stroking.otf is structured like:
            nothing U+25CB ○
            something U+25C9 ◉
            0 moveto, moveto (before U+2070 ⁰) (nothing there, FreeType ignores these)
            1 moveto, empty line, moveto (before U+00B9 ¹) (degenerate lineto)
            3 moveto, empty cubic, moveto (before U+00B3 ³) (degenerate cubicto)
            f moveto, empty flex, moveto (before U+1DA0 ᶠ) (degenerate flex)
        */
        SkFont font(otf, 100);
        canvas->drawString("○◉  ⁰¹³ᶠ", 10, 300, font, p);
    }

    return skiagm::DrawResult::kOk;
}
