/*
 * 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.h"
#include "SkPathPriv.h"

static void create_ngon(int n, SkPoint* pts, SkScalar width, SkScalar height) {
    float angleStep = 360.0f / n, angle = 0.0f, sin, cos;
    if ((n % 2) == 1) {
        angle = angleStep/2.0f;
    }

    for (int i = 0; i < n; ++i) {
        sin = SkScalarSinCos(SkDegreesToRadians(angle), &cos);
        pts[i].fX = -sin * width;
        pts[i].fY = cos * height;
        angle += angleStep;
    }
}

namespace skiagm {

// This GM is intended to exercise Ganesh's handling of convex line-only
// paths
class ConvexLineOnlyPathsGM : public GM {
public:
    ConvexLineOnlyPathsGM(bool doStrokeAndFill) : fDoStrokeAndFill(doStrokeAndFill) {
        this->setBGColor(0xFFFFFFFF);
    }

protected:
    SkString onShortName() override {
        if (fDoStrokeAndFill) {
            return SkString("convex-lineonly-paths-stroke-and-fill");
        }
        return SkString("convex-lineonly-paths");
    }
    SkISize onISize() override { return SkISize::Make(kGMWidth, kGMHeight); }
    bool runAsBench() const override { return true; }

    static SkPath GetPath(int index, int offset, SkPath::Direction dir) {
        // narrow rect
        const SkPoint gPoints0[] = {
            { -1.5f, -50.0f },
            {  1.5f, -50.0f },
            {  1.5f,  50.0f },
            { -1.5f,  50.0f }
        };
        // narrow rect on an angle
        const SkPoint gPoints1[] = {
            { -50.0f, -49.0f },
            { -49.0f, -50.0f },
            {  50.0f,  49.0f },
            {  49.0f,  50.0f }
        };
        // trap - narrow on top - wide on bottom
        const SkPoint gPoints2[] = {
            { -10.0f, -50.0f },
            {  10.0f, -50.0f },
            {  50.0f,  50.0f },
            { -50.0f,  50.0f }
        };
        // wide skewed rect
        const SkPoint gPoints3[] = {
            { -50.0f, -50.0f },
            {   0.0f, -50.0f },
            {  50.0f,  50.0f },
            {   0.0f,  50.0f }
        };
        // thin rect with colinear-ish lines
        const SkPoint gPoints4[] = {
            { -6.0f, -50.0f },
            {  4.0f, -50.0f },
            {  5.0f, -25.0f },
            {  6.0f,   0.0f },
            {  5.0f,  25.0f },
            {  4.0f,  50.0f },
            { -4.0f,  50.0f }
        };
        // degenerate
        const SkPoint gPoints5[] = {
            { -0.025f, -0.025f  },
            {  0.025f, -0.025f  },
            {  0.025f,  0.025f },
            { -0.025f,  0.025f }
        };
        // Triangle in which the first point should fuse with last
        const SkPoint gPoints6[] = {
            { -20.0f, -13.0f },
            { -20.0f, -13.05f },
            {  20.0f, -13.0f },
            {  20.0f,  27.0f }
        };
        // thin rect with colinear lines
        const SkPoint gPoints7[] = {
            { -10.0f, -50.0f },
            {  10.0f, -50.0f },
            {  10.0f, -25.0f },
            {  10.0f,   0.0f },
            {  10.0f,  25.0f },
            {  10.0f,  50.0f },
            { -10.0f,  50.0f }
        };
        // capped teardrop
        const SkPoint gPoints8[] = {
            {  50.00f,  50.00f },
            {   0.00f,  50.00f },
            { -15.45f,  47.55f },
            { -29.39f,  40.45f },
            { -40.45f,  29.39f },
            { -47.55f,  15.45f },
            { -50.00f,   0.00f },
            { -47.55f, -15.45f },
            { -40.45f, -29.39f },
            { -29.39f, -40.45f },
            { -15.45f, -47.55f },
            {   0.00f, -50.00f },
            {  50.00f, -50.00f }
        };
        // teardrop
        const SkPoint gPoints9[] = {
            {   4.39f,  40.45f },
            {  -9.55f,  47.55f },
            { -25.00f,  50.00f },
            { -40.45f,  47.55f },
            { -54.39f,  40.45f },
            { -65.45f,  29.39f },
            { -72.55f,  15.45f },
            { -75.00f,   0.00f },
            { -72.55f, -15.45f },
            { -65.45f, -29.39f },
            { -54.39f, -40.45f },
            { -40.45f, -47.55f },
            { -25.0f,  -50.0f },
            {  -9.55f, -47.55f },
            {   4.39f, -40.45f },
            {  75.00f,   0.00f }
        };
        // clipped triangle
        const SkPoint gPoints10[] = {
            { -10.0f, -50.0f },
            {  10.0f, -50.0f },
            {  50.0f,  31.0f },
            {  40.0f,  50.0f },
            { -40.0f,  50.0f },
            { -50.0f,  31.0f },
        };

        const SkPoint* gPoints[] = {
            gPoints0, gPoints1, gPoints2, gPoints3, gPoints4, gPoints5, gPoints6,
            gPoints7, gPoints8, gPoints9, gPoints10,
        };

        const size_t gSizes[] = {
            SK_ARRAY_COUNT(gPoints0),
            SK_ARRAY_COUNT(gPoints1),
            SK_ARRAY_COUNT(gPoints2),
            SK_ARRAY_COUNT(gPoints3),
            SK_ARRAY_COUNT(gPoints4),
            SK_ARRAY_COUNT(gPoints5),
            SK_ARRAY_COUNT(gPoints6),
            SK_ARRAY_COUNT(gPoints7),
            SK_ARRAY_COUNT(gPoints8),
            SK_ARRAY_COUNT(gPoints9),
            SK_ARRAY_COUNT(gPoints10),
        };
        static_assert(SK_ARRAY_COUNT(gSizes) == SK_ARRAY_COUNT(gPoints), "array_mismatch");

        std::unique_ptr<SkPoint[]> data(nullptr);
        const SkPoint* points;
        int numPts;
        if (index < (int) SK_ARRAY_COUNT(gPoints)) {
            // manually specified
            points = gPoints[index];
            numPts = (int) gSizes[index];
        } else {
            // procedurally generated
            SkScalar width = kMaxPathHeight/2;
            SkScalar height = kMaxPathHeight/2;
            switch (index-SK_ARRAY_COUNT(gPoints)) {
            case 0:
                numPts = 3;
                break;
            case 1:
                numPts = 4;
                break;
            case 2:
                numPts = 5;
                break;
            case 3:             // squashed pentagon
                numPts = 5;
                width = kMaxPathHeight/5;
                break;
            case 4:
                numPts = 6;
                break;
            case 5:
                numPts = 8;
                break;
            case 6:              // squashed octogon
                numPts = 8;
                width = kMaxPathHeight/5;
                break;
            case 7:
                numPts = 20;
                break;
            case 8:
                numPts = 100;
                break;
            default:
                numPts = 3;
                break;
            }

            data.reset(new SkPoint[numPts]);

            create_ngon(numPts, data.get(), width, height);
            points = data.get();
        }

        SkPath path;

        if (SkPath::kCW_Direction == dir) {
            path.moveTo(points[0]);
            for (int i = 1; i < numPts; ++i) {
                path.lineTo(points[i]);
            }
        } else {
            path.moveTo(points[numPts-1]);
            for (int i = numPts-2; i >= 0; --i) {
                path.lineTo(points[i]);
            }
        }

        path.close();
#ifdef SK_DEBUG
        // Each path this method returns should be convex, only composed of
        // lines, wound the right direction, and short enough to fit in one
        // of the GMs rows.
        SkASSERT(path.isConvex());
        SkASSERT(SkPath::kLine_SegmentMask == path.getSegmentMasks());
        SkPathPriv::FirstDirection actualDir;
        SkASSERT(SkPathPriv::CheapComputeFirstDirection(path, &actualDir));
        SkASSERT(SkPathPriv::AsFirstDirection(dir) == actualDir);
        SkRect bounds = path.getBounds();
        SkASSERT(SkScalarNearlyEqual(bounds.centerX(), 0.0f));
        SkASSERT(bounds.height() <= kMaxPathHeight);
#endif
        return path;
    }

    // Draw a single path several times, shrinking it, flipping its direction
    // and changing its start vertex each time.
    void drawPath(SkCanvas* canvas, int index, SkPoint* offset) {

        SkPoint center;
        {
            SkPath path = GetPath(index, 0, SkPath::kCW_Direction);
            if (offset->fX+path.getBounds().width() > kGMWidth) {
                offset->fX = 0;
                offset->fY += kMaxPathHeight;
                if (fDoStrokeAndFill) {
                    offset->fX += kStrokeWidth / 2.0f;
                    offset->fY += kStrokeWidth / 2.0f;
                }
            }
            center = { offset->fX + SkScalarHalf(path.getBounds().width()), offset->fY};
            offset->fX += path.getBounds().width();
            if (fDoStrokeAndFill) {
                offset->fX += kStrokeWidth;
            }
        }

        const SkColor colors[2] = { SK_ColorBLACK, SK_ColorWHITE };
        const SkPath::Direction dirs[2] = { SkPath::kCW_Direction, SkPath::kCCW_Direction };
        const float scales[] = { 1.0f, 0.75f, 0.5f, 0.25f, 0.1f, 0.01f, 0.001f };
        const SkPaint::Join joins[3] = { SkPaint::kRound_Join,
                                         SkPaint::kBevel_Join,
                                         SkPaint::kMiter_Join };

        SkPaint paint;
        paint.setAntiAlias(true);

        for (size_t i = 0; i < SK_ARRAY_COUNT(scales); ++i) {
            SkPath path = GetPath(index, (int) i, dirs[i%2]);
            if (fDoStrokeAndFill) {
                paint.setStyle(SkPaint::kStrokeAndFill_Style);
                paint.setStrokeJoin(joins[i%3]);
                paint.setStrokeWidth(SkIntToScalar(kStrokeWidth));
            }

            canvas->save();
                canvas->translate(center.fX, center.fY);
                canvas->scale(scales[i], scales[i]);
                paint.setColor(colors[i%2]);
                canvas->drawPath(path, paint);
            canvas->restore();
        }
    }

    void onDraw(SkCanvas* canvas) override {
        // the right edge of the last drawn path
        SkPoint offset = { 0, SkScalarHalf(kMaxPathHeight) };
        if (fDoStrokeAndFill) {
            offset.fX += kStrokeWidth / 2.0f;
            offset.fY += kStrokeWidth / 2.0f;
        }

        for (int i = 0; i < kNumPaths; ++i) {
            this->drawPath(canvas, i, &offset);
        }

        // Repro for crbug.com/472723 (Missing AA on portions of graphic with GPU rasterization)
        {
            canvas->translate(356.0f, 50.0f);

            SkPaint p;
            p.setAntiAlias(true);
            if (fDoStrokeAndFill) {
                p.setStyle(SkPaint::kStrokeAndFill_Style);
                p.setStrokeJoin(SkPaint::kMiter_Join);
                p.setStrokeWidth(SkIntToScalar(kStrokeWidth));
            }

            SkPath p1;
            p1.moveTo(60.8522949f, 364.671021f);
            p1.lineTo(59.4380493f, 364.671021f);
            p1.lineTo(385.414276f, 690.647217f);
            p1.lineTo(386.121399f, 689.940125f);
            canvas->drawPath(p1, p);
        }
    }

private:
    static constexpr int kStrokeWidth   = 10;
    static constexpr int kNumPaths      = 20;
    static constexpr int kMaxPathHeight = 100;
    static constexpr int kGMWidth       = 512;
    static constexpr int kGMHeight      = 512;

    bool fDoStrokeAndFill;

    typedef GM INHERITED;
};

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

DEF_GM(return new ConvexLineOnlyPathsGM(false);)
DEF_GM(return new ConvexLineOnlyPathsGM(true);)
}
