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


/*
 * This GM exercises stroking of paths with large stroke lengths, which is
 * referred to as "overstroke" for brevity. In Skia as of 8/2016 we offset
 * each part of the curve the request amount even if it makes the offsets
 * overlap and create holes. There is not a really great algorithm for this
 * and several other 2D graphics engines have the same bug.
 *
 * The old Nvidia Path Renderer used to yield correct results, so a possible
 * direction of attack is to use the GPU and a completely different algorithm.
 *
 * See crbug.com/589769 skbug.com/40036571 skbug.com/40036572
 */

#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPathBuilder.h"
#include "include/core/SkPathMeasure.h"
#include "include/core/SkPathUtils.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "src/core/SkPointPriv.h"

#include <cstddef>

const SkScalar OVERSTROKE_WIDTH = 500.0f;
const SkScalar NORMALSTROKE_WIDTH = 3.0f;

//////// path and paint builders

SkPaint make_normal_paint() {
    SkPaint p;
    p.setAntiAlias(true);
    p.setStyle(SkPaint::kStroke_Style);
    p.setStrokeWidth(NORMALSTROKE_WIDTH);
    p.setColor(SK_ColorBLUE);

    return p;
}

SkPaint make_overstroke_paint() {
    SkPaint p;
    p.setAntiAlias(true);
    p.setStyle(SkPaint::kStroke_Style);
    p.setStrokeWidth(OVERSTROKE_WIDTH);

    return p;
}

SkPath quad_path() {
    return SkPathBuilder().moveTo(0, 0)
                          .lineTo(100, 0)
                          .quadTo(50, -40, 0, 0)
                          .close()
                          .detach();
}

SkPath cubic_path() {
    return SkPathBuilder()
           .moveTo(0, 0)
           .cubicTo(25, 75, 75, -50, 100, 0)
           .detach();
}

SkPath oval_path() {
    SkRect oval = SkRect::MakeXYWH(0, -25, 100, 50);

    return SkPathBuilder().arcTo(oval, 0, 359, true).close().detach();
}

SkPath ribs_path(SkPath path, SkScalar radius) {
    SkPathBuilder ribs;

    const SkScalar spacing = 5.0f;
    float accum = 0.0f;

    SkPathMeasure meas(path, false);
    SkScalar length = meas.getLength();
    SkPoint pos;
    SkVector tan;
    while (accum < length) {
        if (meas.getPosTan(accum, &pos, &tan)) {
            tan.scale(radius);
            SkPointPriv::RotateCCW(&tan);
            ribs.addLine(pos + tan, pos - tan);
        }
        accum += spacing;
    }

    return ribs.detach();
}

void draw_ribs(SkCanvas *canvas, SkPath path) {
    SkPath ribs = ribs_path(path, OVERSTROKE_WIDTH/2.0f);
    SkPaint p = make_normal_paint();
    p.setStrokeWidth(1);
    p.setColor(SK_ColorBLUE);
    p.setColor(SK_ColorGREEN);

    canvas->drawPath(ribs, p);
}

///////// quads

void draw_small_quad(SkCanvas *canvas) {
    // scaled so it's visible
    // canvas->scale(8, 8);

    SkPaint p = make_normal_paint();
    SkPath path = quad_path();

    draw_ribs(canvas, path);
    canvas->drawPath(path, p);
}

void draw_large_quad(SkCanvas *canvas) {
    SkPaint p = make_overstroke_paint();
    SkPath path = quad_path();

    canvas->drawPath(path, p);
    draw_ribs(canvas, path);
}

void draw_quad_fillpath(SkCanvas *canvas) {
    SkPath path = quad_path();
    SkPaint p = make_overstroke_paint();

    SkPaint fillp = make_normal_paint();
    fillp.setColor(SK_ColorMAGENTA);

    SkPathBuilder fillpath;
    skpathutils::FillPathWithPaint(path, p, &fillpath);

    canvas->drawPath(fillpath.detach(), fillp);
}

void draw_stroked_quad(SkCanvas *canvas) {
    canvas->translate(400, 0);
    draw_large_quad(canvas);
    draw_quad_fillpath(canvas);
}

////////// cubics

void draw_small_cubic(SkCanvas *canvas) {
    SkPaint p = make_normal_paint();
    SkPath path = cubic_path();

    draw_ribs(canvas, path);
    canvas->drawPath(path, p);
}

void draw_large_cubic(SkCanvas *canvas) {
    SkPaint p = make_overstroke_paint();
    SkPath path = cubic_path();

    canvas->drawPath(path, p);
    draw_ribs(canvas, path);
}

void draw_cubic_fillpath(SkCanvas *canvas) {
    SkPath path = cubic_path();
    SkPaint p = make_overstroke_paint();

    SkPaint fillp = make_normal_paint();
    fillp.setColor(SK_ColorMAGENTA);

    SkPathBuilder fillpath;
    skpathutils::FillPathWithPaint(path, p, &fillpath);

    canvas->drawPath(fillpath.detach(), fillp);
}

void draw_stroked_cubic(SkCanvas *canvas) {
    canvas->translate(400, 0);
    draw_large_cubic(canvas);
    draw_cubic_fillpath(canvas);
}

////////// ovals

void draw_small_oval(SkCanvas *canvas) {
    SkPaint p = make_normal_paint();

    SkPath path = oval_path();

    draw_ribs(canvas, path);
    canvas->drawPath(path, p);
}

void draw_large_oval(SkCanvas *canvas) {
    SkPaint p = make_overstroke_paint();
    SkPath path = oval_path();

    canvas->drawPath(path, p);
    draw_ribs(canvas, path);
}

void draw_oval_fillpath(SkCanvas *canvas) {
    SkPath path = oval_path();
    SkPaint p = make_overstroke_paint();

    SkPaint fillp = make_normal_paint();
    fillp.setColor(SK_ColorMAGENTA);

    SkPath fillpath = skpathutils::FillPathWithPaint(path, p);

    canvas->drawPath(fillpath, fillp);
}

void draw_stroked_oval(SkCanvas *canvas) {
    canvas->translate(400, 0);
    draw_large_oval(canvas);
    draw_oval_fillpath(canvas);
}

////////// gm

void (*examples[])(SkCanvas *canvas) = {
    draw_small_quad,    draw_stroked_quad, draw_small_cubic,
    draw_stroked_cubic, draw_small_oval,   draw_stroked_oval,
};

DEF_SIMPLE_GM(OverStroke, canvas, 500, 500) {
    const size_t length = sizeof(examples) / sizeof(examples[0]);
    const size_t width = 2;

    for (size_t i = 0; i < length; i++) {
        int x = (int)(i % width);
        int y = (int)(i / width);

        canvas->save();
        canvas->translate(150.0f * x, 150.0f * y);
        canvas->scale(0.2f, 0.2f);
        canvas->translate(300.0f, 400.0f);

        examples[i](canvas);

        canvas->restore();
    }
}
