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

#include "include/core/SkMatrix.h"
#include "include/core/SkPath.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkTypes.h"
#include "include/pathops/SkPathOps.h"
#include "src/base/SkRandom.h"
#include "src/core/SkPointPriv.h"
#include "src/core/SkRRectPriv.h"
#include "tests/Test.h"

#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>

static void test_tricky_radii(skiatest::Reporter* reporter) {
    {
        // crbug.com/458522
        SkRRect rr;
        const SkRect bounds = { 3709, 3709, 3709 + 7402, 3709 + 29825 };
        const SkScalar rad = 12814;
        const SkVector vec[] = { { rad, rad }, { 0, rad }, { rad, rad }, { 0, rad } };
        rr.setRectRadii(bounds, vec);
    }

    {
        // crbug.com//463920
        SkRect r = SkRect::MakeLTRB(0, 0, 1009, 33554432.0);
        SkVector radii[4] = {
            { 13.0f, 8.0f }, { 170.0f, 2.0 }, { 256.0f, 33554432.0 }, { 110.0f, 5.0f }
        };
        SkRRect rr;
        rr.setRectRadii(r, radii);

        REPORTER_ASSERT(reporter, (double) rr.radii(SkRRect::kUpperRight_Corner).fY +
                                  (double) rr.radii(SkRRect::kLowerRight_Corner).fY <=
                                  rr.height());
    }
}

static void test_empty_crbug_458524(skiatest::Reporter* reporter) {
    SkRRect rr;
    const SkRect bounds = { 3709, 3709, 3709 + 7402, 3709 + 29825 };
    const SkScalar rad = 40;
    rr.setRectXY(bounds, rad, rad);

    SkRRect other;
    SkMatrix matrix;
    matrix.setScale(0, 1);
    rr.transform(matrix, &other);
    REPORTER_ASSERT(reporter, SkRRect::kEmpty_Type == other.getType());
}

// Test that all the SkRRect entry points correctly handle un-sorted and
// zero-sized input rects
static void test_empty(skiatest::Reporter* reporter) {
    static const SkRect oooRects[] = {  // out of order
        { 100, 0, 0, 100 },  // ooo horizontal
        { 0, 100, 100, 0 },  // ooo vertical
        { 100, 100, 0, 0 },  // ooo both
    };

    static const SkRect emptyRects[] = {
        { 100, 100, 100, 200 }, // empty horizontal
        { 100, 100, 200, 100 }, // empty vertical
        { 100, 100, 100, 100 }, // empty both
        { 0, 0, 0, 0 }          // setEmpty-empty
    };

    static const SkVector radii[4] = { { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 } };

    SkRRect r;

    for (size_t i = 0; i < std::size(oooRects); ++i) {
        r.setRect(oooRects[i]);
        REPORTER_ASSERT(reporter, !r.isEmpty());
        REPORTER_ASSERT(reporter, r.rect() == oooRects[i].makeSorted());

        r.setOval(oooRects[i]);
        REPORTER_ASSERT(reporter, !r.isEmpty());
        REPORTER_ASSERT(reporter, r.rect() == oooRects[i].makeSorted());

        r.setRectXY(oooRects[i], 1, 2);
        REPORTER_ASSERT(reporter, !r.isEmpty());
        REPORTER_ASSERT(reporter, r.rect() == oooRects[i].makeSorted());

        r.setNinePatch(oooRects[i], 0, 1, 2, 3);
        REPORTER_ASSERT(reporter, !r.isEmpty());
        REPORTER_ASSERT(reporter, r.rect() == oooRects[i].makeSorted());

        r.setRectRadii(oooRects[i], radii);
        REPORTER_ASSERT(reporter, !r.isEmpty());
        REPORTER_ASSERT(reporter, r.rect() == oooRects[i].makeSorted());
    }

    for (size_t i = 0; i < std::size(emptyRects); ++i) {
        r.setRect(emptyRects[i]);
        REPORTER_ASSERT(reporter, r.isEmpty());
        REPORTER_ASSERT(reporter, r.rect() == emptyRects[i]);

        r.setOval(emptyRects[i]);
        REPORTER_ASSERT(reporter, r.isEmpty());
        REPORTER_ASSERT(reporter, r.rect() == emptyRects[i]);

        r.setRectXY(emptyRects[i], 1, 2);
        REPORTER_ASSERT(reporter, r.isEmpty());
        REPORTER_ASSERT(reporter, r.rect() == emptyRects[i]);

        r.setNinePatch(emptyRects[i], 0, 1, 2, 3);
        REPORTER_ASSERT(reporter, r.isEmpty());
        REPORTER_ASSERT(reporter, r.rect() == emptyRects[i]);

        r.setRectRadii(emptyRects[i], radii);
        REPORTER_ASSERT(reporter, r.isEmpty());
        REPORTER_ASSERT(reporter, r.rect() == emptyRects[i]);
    }

    r.setRect({SK_ScalarNaN, 10, 10, 20});
    REPORTER_ASSERT(reporter, r == SkRRect::MakeEmpty());
    r.setRect({0, 10, 10, SK_ScalarInfinity});
    REPORTER_ASSERT(reporter, r == SkRRect::MakeEmpty());
}

static const SkScalar kWidth = 100.0f;
static const SkScalar kHeight = 100.0f;

static void test_inset(skiatest::Reporter* reporter) {
    SkRRect rr, rr2;
    SkRect r = { 0, 0, 100, 100 };

    rr.setRect(r);
    rr.inset(-20, -20, &rr2);
    REPORTER_ASSERT(reporter, rr2.isRect());

    rr.inset(20, 20, &rr2);
    REPORTER_ASSERT(reporter, rr2.isRect());

    rr.inset(r.width()/2, r.height()/2, &rr2);
    REPORTER_ASSERT(reporter, rr2.isEmpty());

    rr.setRectXY(r, 20, 20);
    rr.inset(19, 19, &rr2);
    REPORTER_ASSERT(reporter, rr2.isSimple());
    rr.inset(20, 20, &rr2);
    REPORTER_ASSERT(reporter, rr2.isRect());
}


static void test_9patch_rrect(skiatest::Reporter* reporter,
                              const SkRect& rect,
                              SkScalar l, SkScalar t, SkScalar r, SkScalar b,
                              bool checkRadii) {
    SkRRect rr;
    rr.setNinePatch(rect, l, t, r, b);

    REPORTER_ASSERT(reporter, SkRRect::kNinePatch_Type == rr.type());
    REPORTER_ASSERT(reporter, rr.rect() == rect);

    if (checkRadii) {
        // This test doesn't hold if the radii will be rescaled by SkRRect
        SkRect ninePatchRadii = { l, t, r, b };
        SkPoint rquad[4];
        ninePatchRadii.toQuad(rquad);
        for (int i = 0; i < 4; ++i) {
            REPORTER_ASSERT(reporter, rquad[i] == rr.radii((SkRRect::Corner) i));
        }
    }
    SkRRect rr2; // construct the same RR using the most general set function
    SkVector radii[4] = { { l, t }, { r, t }, { r, b }, { l, b } };
    rr2.setRectRadii(rect, radii);
    REPORTER_ASSERT(reporter, rr2 == rr && rr2.getType() == rr.getType());
}

// Test out the basic API entry points
static void test_round_rect_basic(skiatest::Reporter* reporter) {
    // Test out initialization methods
    SkPoint zeroPt = { 0, 0 };
    SkRRect empty;

    empty.setEmpty();

    REPORTER_ASSERT(reporter, SkRRect::kEmpty_Type == empty.type());
    REPORTER_ASSERT(reporter, empty.rect().isEmpty());

    for (int i = 0; i < 4; ++i) {
        REPORTER_ASSERT(reporter, zeroPt == empty.radii((SkRRect::Corner) i));
    }

    //----
    SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight);

    SkRRect rr1;
    rr1.setRect(rect);

    REPORTER_ASSERT(reporter, SkRRect::kRect_Type == rr1.type());
    REPORTER_ASSERT(reporter, rr1.rect() == rect);

    for (int i = 0; i < 4; ++i) {
        REPORTER_ASSERT(reporter, zeroPt == rr1.radii((SkRRect::Corner) i));
    }
    SkRRect rr1_2; // construct the same RR using the most general set function
    SkVector rr1_2_radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } };
    rr1_2.setRectRadii(rect, rr1_2_radii);
    REPORTER_ASSERT(reporter, rr1_2 == rr1 && rr1_2.getType() == rr1.getType());
    SkRRect rr1_3;  // construct the same RR using the nine patch set function
    rr1_3.setNinePatch(rect, 0, 0, 0, 0);
    REPORTER_ASSERT(reporter, rr1_3 == rr1 && rr1_3.getType() == rr1.getType());

    //----
    SkPoint halfPoint = { SkScalarHalf(kWidth), SkScalarHalf(kHeight) };
    SkRRect rr2;
    rr2.setOval(rect);

    REPORTER_ASSERT(reporter, SkRRect::kOval_Type == rr2.type());
    REPORTER_ASSERT(reporter, rr2.rect() == rect);

    for (int i = 0; i < 4; ++i) {
        REPORTER_ASSERT(reporter,
                        SkPointPriv::EqualsWithinTolerance(rr2.radii((SkRRect::Corner) i),
                        halfPoint));
    }
    SkRRect rr2_2;  // construct the same RR using the most general set function
    SkVector rr2_2_radii[4] = { { halfPoint.fX, halfPoint.fY }, { halfPoint.fX, halfPoint.fY },
                                { halfPoint.fX, halfPoint.fY }, { halfPoint.fX, halfPoint.fY } };
    rr2_2.setRectRadii(rect, rr2_2_radii);
    REPORTER_ASSERT(reporter, rr2_2 == rr2 && rr2_2.getType() == rr2.getType());
    SkRRect rr2_3;  // construct the same RR using the nine patch set function
    rr2_3.setNinePatch(rect, halfPoint.fX, halfPoint.fY, halfPoint.fX, halfPoint.fY);
    REPORTER_ASSERT(reporter, rr2_3 == rr2 && rr2_3.getType() == rr2.getType());

    //----
    SkPoint p = { 5, 5 };
    SkRRect rr3;
    rr3.setRectXY(rect, p.fX, p.fY);

    REPORTER_ASSERT(reporter, SkRRect::kSimple_Type == rr3.type());
    REPORTER_ASSERT(reporter, rr3.rect() == rect);

    for (int i = 0; i < 4; ++i) {
        REPORTER_ASSERT(reporter, p == rr3.radii((SkRRect::Corner) i));
    }
    SkRRect rr3_2; // construct the same RR using the most general set function
    SkVector rr3_2_radii[4] = { { 5, 5 }, { 5, 5 }, { 5, 5 }, { 5, 5 } };
    rr3_2.setRectRadii(rect, rr3_2_radii);
    REPORTER_ASSERT(reporter, rr3_2 == rr3 && rr3_2.getType() == rr3.getType());
    SkRRect rr3_3;  // construct the same RR using the nine patch set function
    rr3_3.setNinePatch(rect, 5, 5, 5, 5);
    REPORTER_ASSERT(reporter, rr3_3 == rr3 && rr3_3.getType() == rr3.getType());

    //----
    test_9patch_rrect(reporter, rect, 10, 9, 8, 7, true);

    {
        // Test out the rrect from skia:3466
        SkRect rect2 = SkRect::MakeLTRB(0.358211994f, 0.755430222f, 0.872866154f, 0.806214333f);

        test_9patch_rrect(reporter,
                          rect2,
                          0.926942348f, 0.642850280f, 0.529063463f, 0.587844372f,
                          false);
    }

    //----
    SkPoint radii2[4] = { { 0, 0 }, { 0, 0 }, { 50, 50 }, { 20, 50 } };

    SkRRect rr5;
    rr5.setRectRadii(rect, radii2);

    REPORTER_ASSERT(reporter, SkRRect::kComplex_Type == rr5.type());
    REPORTER_ASSERT(reporter, rr5.rect() == rect);

    for (int i = 0; i < 4; ++i) {
        REPORTER_ASSERT(reporter, radii2[i] == rr5.radii((SkRRect::Corner) i));
    }

    // Test out == & !=
    REPORTER_ASSERT(reporter, empty != rr3);
    REPORTER_ASSERT(reporter, rr3 != rr5);
}

// Test out the cases when the RR degenerates to a rect
static void test_round_rect_rects(skiatest::Reporter* reporter) {
    SkRect r;

    //----
    SkRRect empty;

    empty.setEmpty();

    REPORTER_ASSERT(reporter, SkRRect::kEmpty_Type == empty.type());
    r = empty.rect();
    REPORTER_ASSERT(reporter, 0 == r.fLeft && 0 == r.fTop && 0 == r.fRight && 0 == r.fBottom);

    //----
    SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight);
    SkRRect rr1;
    rr1.setRectXY(rect, 0, 0);

    REPORTER_ASSERT(reporter, SkRRect::kRect_Type == rr1.type());
    r = rr1.rect();
    REPORTER_ASSERT(reporter, rect == r);

    //----
    SkPoint radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } };

    SkRRect rr2;
    rr2.setRectRadii(rect, radii);

    REPORTER_ASSERT(reporter, SkRRect::kRect_Type == rr2.type());
    r = rr2.rect();
    REPORTER_ASSERT(reporter, rect == r);

    //----
    SkPoint radii2[4] = { { 0, 0 }, { 20, 20 }, { 50, 50 }, { 20, 50 } };

    SkRRect rr3;
    rr3.setRectRadii(rect, radii2);
    REPORTER_ASSERT(reporter, SkRRect::kComplex_Type == rr3.type());
}

// Test out the cases when the RR degenerates to an oval
static void test_round_rect_ovals(skiatest::Reporter* reporter) {
    //----
    SkRect oval;
    SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight);
    SkRRect rr1;
    rr1.setRectXY(rect, SkScalarHalf(kWidth), SkScalarHalf(kHeight));

    REPORTER_ASSERT(reporter, SkRRect::kOval_Type == rr1.type());
    oval = rr1.rect();
    REPORTER_ASSERT(reporter, oval == rect);
}

// Test out the non-degenerate RR cases
static void test_round_rect_general(skiatest::Reporter* reporter) {
    //----
    SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight);
    SkRRect rr1;
    rr1.setRectXY(rect, 20, 20);

    REPORTER_ASSERT(reporter, SkRRect::kSimple_Type == rr1.type());

    //----
    SkPoint radii[4] = { { 0, 0 }, { 20, 20 }, { 50, 50 }, { 20, 50 } };

    SkRRect rr2;
    rr2.setRectRadii(rect, radii);

    REPORTER_ASSERT(reporter, SkRRect::kComplex_Type == rr2.type());
}

// Test out questionable-parameter handling
static void test_round_rect_iffy_parameters(skiatest::Reporter* reporter) {

    // When the radii exceed the base rect they are proportionally scaled down
    // to fit
    SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight);
    SkPoint radii[4] = { { 50, 100 }, { 100, 50 }, { 50, 100 }, { 100, 50 } };

    SkRRect rr1;
    rr1.setRectRadii(rect, radii);

    REPORTER_ASSERT(reporter, SkRRect::kComplex_Type == rr1.type());

    const SkPoint& p = rr1.radii(SkRRect::kUpperLeft_Corner);

    REPORTER_ASSERT(reporter, SkScalarNearlyEqual(p.fX, 33.33333f));
    REPORTER_ASSERT(reporter, SkScalarNearlyEqual(p.fY, 66.66666f));

    // Negative radii should be capped at zero
    SkRRect rr2;
    rr2.setRectXY(rect, -10, -20);

    REPORTER_ASSERT(reporter, SkRRect::kRect_Type == rr2.type());

    const SkPoint& p2 = rr2.radii(SkRRect::kUpperLeft_Corner);

    REPORTER_ASSERT(reporter, 0.0f == p2.fX);
    REPORTER_ASSERT(reporter, 0.0f == p2.fY);
}

// Move a small box from the start position by (stepX, stepY) 'numSteps' times
// testing for containment in 'rr' at each step.
static void test_direction(skiatest::Reporter* reporter, const SkRRect &rr,
                           SkScalar initX, int stepX, SkScalar initY, int stepY,
                           int numSteps, const bool* contains) {
    SkScalar x = initX, y = initY;
    for (int i = 0; i < numSteps; ++i) {
        SkRect test = SkRect::MakeXYWH(x, y,
                                       stepX ? SkIntToScalar(stepX) : SK_Scalar1,
                                       stepY ? SkIntToScalar(stepY) : SK_Scalar1);
        test.sort();

        REPORTER_ASSERT(reporter, contains[i] == rr.contains(test));

        x += stepX;
        y += stepY;
    }
}

// Exercise the RR's contains rect method
static void test_round_rect_contains_rect(skiatest::Reporter* reporter) {

    static const int kNumRRects = 4;
    static const SkVector gRadii[kNumRRects][4] = {
        { {  0,  0 }, {  0,  0 }, {  0,  0 }, {  0,  0 } },  // rect
        { { 20, 20 }, { 20, 20 }, { 20, 20 }, { 20, 20 } },  // circle
        { { 10, 10 }, { 10, 10 }, { 10, 10 }, { 10, 10 } },  // simple
        { {  0,  0 }, { 20, 20 }, { 10, 10 }, { 30, 30 } }   // complex
    };

    SkRRect rrects[kNumRRects];
    for (int i = 0; i < kNumRRects; ++i) {
        rrects[i].setRectRadii(SkRect::MakeWH(40, 40), gRadii[i]);
    }

    // First test easy outs - boxes that are obviously out on
    // each corner and edge
    static const SkRect easyOuts[] = {
        { -5, -5,  5,  5 }, // NW
        { 15, -5, 20,  5 }, // N
        { 35, -5, 45,  5 }, // NE
        { 35, 15, 45, 20 }, // E
        { 35, 45, 35, 45 }, // SE
        { 15, 35, 20, 45 }, // S
        { -5, 35,  5, 45 }, // SW
        { -5, 15,  5, 20 }  // W
    };

    for (int i = 0; i < kNumRRects; ++i) {
        for (size_t j = 0; j < std::size(easyOuts); ++j) {
            REPORTER_ASSERT(reporter, !rrects[i].contains(easyOuts[j]));
        }
    }

    // Now test non-trivial containment. For each compass
    // point walk a 1x1 rect in from the edge  of the bounding
    // rect
    static const int kNumSteps = 15;
    bool answers[kNumRRects][8][kNumSteps] = {
        // all the test rects are inside the degenerate rrect
        {
            // rect
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        },
        // for the circle we expect 6 blocks to be out on the
        // corners (then the rest in) and only the first block
        // out on the vertical and horizontal axes (then
        // the rest in)
        {
            // circle
            { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        },
        // for the simple round rect we expect 3 out on
        // the corners (then the rest in) and no blocks out
        // on the vertical and horizontal axes
        {
            // simple RR
            { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        },
        // for the complex case the answer is different for each direction
        {
            // complex RR
            // all in for NW (rect) corner (same as rect case)
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            // only first block out for N (same as circle case)
            { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            // first 6 blocks out for NE (same as circle case)
            { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            // only first block out for E (same as circle case)
            { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            // first 3 blocks out for SE (same as simple case)
            { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            // first two blocks out for S
            { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            // first 9 blocks out for SW
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
            // first two blocks out for W (same as S)
            { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
         }
    };

    for (int i = 0; i < kNumRRects; ++i) {
        test_direction(reporter, rrects[i],     0,  1,     0,  1, kNumSteps, answers[i][0]); // NW
        test_direction(reporter, rrects[i], 19.5f,  0,     0,  1, kNumSteps, answers[i][1]); // N
        test_direction(reporter, rrects[i],    40, -1,     0,  1, kNumSteps, answers[i][2]); // NE
        test_direction(reporter, rrects[i],    40, -1, 19.5f,  0, kNumSteps, answers[i][3]); // E
        test_direction(reporter, rrects[i],    40, -1,    40, -1, kNumSteps, answers[i][4]); // SE
        test_direction(reporter, rrects[i], 19.5f,  0,    40, -1, kNumSteps, answers[i][5]); // S
        test_direction(reporter, rrects[i],     0,  1,    40, -1, kNumSteps, answers[i][6]); // SW
        test_direction(reporter, rrects[i],     0,  1, 19.5f,  0, kNumSteps, answers[i][7]); // W
    }
}

// Called for a matrix that should cause SkRRect::transform to fail.
static void assert_transform_failure(skiatest::Reporter* reporter, const SkRRect& orig,
                                     const SkMatrix& matrix) {
    // The test depends on the fact that the original is not empty.
    SkASSERT(!orig.isEmpty());
    SkRRect dst;
    dst.setEmpty();

    const SkRRect copyOfDst = dst;
    const SkRRect copyOfOrig = orig;
    bool success = orig.transform(matrix, &dst);
    // This transform should fail.
    REPORTER_ASSERT(reporter, !success);
    // Since the transform failed, dst should be unchanged.
    REPORTER_ASSERT(reporter, copyOfDst == dst);
    // original should not be modified.
    REPORTER_ASSERT(reporter, copyOfOrig == orig);
    REPORTER_ASSERT(reporter, orig != dst);
}

#define GET_RADII                                                       \
    const SkVector& origUL = orig.radii(SkRRect::kUpperLeft_Corner);    \
    const SkVector& origUR = orig.radii(SkRRect::kUpperRight_Corner);   \
    const SkVector& origLR = orig.radii(SkRRect::kLowerRight_Corner);   \
    const SkVector& origLL = orig.radii(SkRRect::kLowerLeft_Corner);    \
    const SkVector& dstUL = dst.radii(SkRRect::kUpperLeft_Corner);      \
    const SkVector& dstUR = dst.radii(SkRRect::kUpperRight_Corner);     \
    const SkVector& dstLR = dst.radii(SkRRect::kLowerRight_Corner);     \
    const SkVector& dstLL = dst.radii(SkRRect::kLowerLeft_Corner)

// Called to test various transforms on a single SkRRect.
static void test_transform_helper(skiatest::Reporter* reporter, const SkRRect& orig) {
    SkRRect dst;
    dst.setEmpty();

    // The identity matrix will duplicate the rrect.
    bool success = orig.transform(SkMatrix::I(), &dst);
    REPORTER_ASSERT(reporter, success);
    REPORTER_ASSERT(reporter, orig == dst);

    // Skew and Perspective make transform fail.
    SkMatrix matrix;
    matrix.reset();
    matrix.setSkewX(SkIntToScalar(2));
    assert_transform_failure(reporter, orig, matrix);

    matrix.reset();
    matrix.setSkewY(SkIntToScalar(3));
    assert_transform_failure(reporter, orig, matrix);

    matrix.reset();
    matrix.setPerspX(4);
    assert_transform_failure(reporter, orig, matrix);

    matrix.reset();
    matrix.setPerspY(5);
    assert_transform_failure(reporter, orig, matrix);

    // Rotation fails.
    matrix.reset();
    matrix.setRotate(SkIntToScalar(37));
    assert_transform_failure(reporter, orig, matrix);

    // Translate will keep the rect moved, but otherwise the same.
    matrix.reset();
    SkScalar translateX = SkIntToScalar(32);
    SkScalar translateY = SkIntToScalar(15);
    matrix.setTranslateX(translateX);
    matrix.setTranslateY(translateY);
    dst.setEmpty();
    success = orig.transform(matrix, &dst);
    REPORTER_ASSERT(reporter, success);
    for (int i = 0; i < 4; ++i) {
        REPORTER_ASSERT(reporter,
                orig.radii((SkRRect::Corner) i) == dst.radii((SkRRect::Corner) i));
    }
    REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().width());
    REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().height());
    REPORTER_ASSERT(reporter, dst.rect().left() == orig.rect().left() + translateX);
    REPORTER_ASSERT(reporter, dst.rect().top() == orig.rect().top() + translateY);

    // Keeping the translation, but adding skew will make transform fail.
    matrix.setSkewY(SkIntToScalar(7));
    assert_transform_failure(reporter, orig, matrix);

    // Scaling in -x will flip the round rect horizontally.
    matrix.reset();
    matrix.setScaleX(SkIntToScalar(-1));
    dst.setEmpty();
    success = orig.transform(matrix, &dst);
    REPORTER_ASSERT(reporter, success);
    {
        GET_RADII;
        // Radii have swapped in x.
        REPORTER_ASSERT(reporter, origUL == dstUR);
        REPORTER_ASSERT(reporter, origUR == dstUL);
        REPORTER_ASSERT(reporter, origLR == dstLL);
        REPORTER_ASSERT(reporter, origLL == dstLR);
    }
    // Width and height remain the same.
    REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().width());
    REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().height());
    // Right and left have swapped (sort of)
    REPORTER_ASSERT(reporter, orig.rect().right() == -dst.rect().left());
    // Top has stayed the same.
    REPORTER_ASSERT(reporter, orig.rect().top() == dst.rect().top());

    // Keeping the scale, but adding a persp will make transform fail.
    matrix.setPerspX(7);
    assert_transform_failure(reporter, orig, matrix);

    // Scaling in -y will flip the round rect vertically.
    matrix.reset();
    matrix.setScaleY(SkIntToScalar(-1));
    dst.setEmpty();
    success = orig.transform(matrix, &dst);
    REPORTER_ASSERT(reporter, success);
    {
        GET_RADII;
        // Radii have swapped in y.
        REPORTER_ASSERT(reporter, origUL == dstLL);
        REPORTER_ASSERT(reporter, origUR == dstLR);
        REPORTER_ASSERT(reporter, origLR == dstUR);
        REPORTER_ASSERT(reporter, origLL == dstUL);
    }
    // Width and height remain the same.
    REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().width());
    REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().height());
    // Top and bottom have swapped (sort of)
    REPORTER_ASSERT(reporter, orig.rect().top() == -dst.rect().bottom());
    // Left has stayed the same.
    REPORTER_ASSERT(reporter, orig.rect().left() == dst.rect().left());

    // Scaling in -x and -y will swap in both directions.
    matrix.reset();
    matrix.setScaleY(SkIntToScalar(-1));
    matrix.setScaleX(SkIntToScalar(-1));
    dst.setEmpty();
    success = orig.transform(matrix, &dst);
    REPORTER_ASSERT(reporter, success);
    {
        GET_RADII;
        REPORTER_ASSERT(reporter, origUL == dstLR);
        REPORTER_ASSERT(reporter, origUR == dstLL);
        REPORTER_ASSERT(reporter, origLR == dstUL);
        REPORTER_ASSERT(reporter, origLL == dstUR);
    }
    // Width and height remain the same.
    REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().width());
    REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().height());
    REPORTER_ASSERT(reporter, orig.rect().top() == -dst.rect().bottom());
    REPORTER_ASSERT(reporter, orig.rect().right() == -dst.rect().left());

    // Scale in both directions.
    SkScalar xScale = SkIntToScalar(3);
    SkScalar yScale = 3.2f;
    matrix.reset();
    matrix.setScaleX(xScale);
    matrix.setScaleY(yScale);
    dst.setEmpty();
    success = orig.transform(matrix, &dst);
    REPORTER_ASSERT(reporter, success);
    // Radii are scaled.
    for (int i = 0; i < 4; ++i) {
        REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.radii((SkRRect::Corner) i).fX,
                                    orig.radii((SkRRect::Corner) i).fX * xScale));
        REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.radii((SkRRect::Corner) i).fY,
                                    orig.radii((SkRRect::Corner) i).fY * yScale));
    }
    REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().width(),
                                                  orig.rect().width() * xScale));
    REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().height(),
                                                  orig.rect().height() * yScale));
    REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().left(),
                                                  orig.rect().left() * xScale));
    REPORTER_ASSERT(reporter, SkScalarNearlyEqual(dst.rect().top(),
                                                  orig.rect().top() * yScale));


    //  a-----b            d-----a
    //  |     |     ->     |     |
    //  |     |  Rotate 90 |     |
    //  d-----c            c-----b
    matrix.reset();
    matrix.setRotate(SkIntToScalar(90));
    dst.setEmpty();
    success = orig.transform(matrix, &dst);
    REPORTER_ASSERT(reporter, success);
    {
        GET_RADII;
        // Radii have cycled clockwise and swapped their x and y axis.
        REPORTER_ASSERT(reporter, dstUL.x() == origLL.y());
        REPORTER_ASSERT(reporter, dstUL.y() == origLL.x());
        REPORTER_ASSERT(reporter, dstUR.x() == origUL.y());
        REPORTER_ASSERT(reporter, dstUR.y() == origUL.x());
        REPORTER_ASSERT(reporter, dstLR.x() == origUR.y());
        REPORTER_ASSERT(reporter, dstLR.y() == origUR.x());
        REPORTER_ASSERT(reporter, dstLL.x() == origLR.y());
        REPORTER_ASSERT(reporter, dstLL.y() == origLR.x());
    }
    // Width and height would get swapped.
    REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().height());
    REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().width());

    //  a-----b        b-----a           c-----b
    //  |     |   ->   |     |    ->     |     |
    //  |     | Flip X |     | Rotate 90 |     |
    //  d-----c        c-----d           d-----a
    matrix.reset();
    matrix.setRotate(SkIntToScalar(90));
    matrix.postScale(SkIntToScalar(-1), SkIntToScalar(1));
    dst.setEmpty();
    success = orig.transform(matrix, &dst);
    REPORTER_ASSERT(reporter, success);
    {
        GET_RADII;
        REPORTER_ASSERT(reporter, dstUL.x() == origLR.y());
        REPORTER_ASSERT(reporter, dstUL.y() == origLR.x());
        REPORTER_ASSERT(reporter, dstUR.x() == origUR.y());
        REPORTER_ASSERT(reporter, dstUR.y() == origUR.x());
        REPORTER_ASSERT(reporter, dstLR.x() == origUL.y());
        REPORTER_ASSERT(reporter, dstLR.y() == origUL.x());
        REPORTER_ASSERT(reporter, dstLL.x() == origLL.y());
        REPORTER_ASSERT(reporter, dstLL.y() == origLL.x());
    }
    // Width and height would get swapped.
    REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().height());
    REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().width());

    //  a-----b           d-----a        c-----b
    //  |     |    ->     |     |   ->   |     |
    //  |     | Rotate 90 |     | Flip Y |     |
    //  d-----c           c-----b        d-----a
    //
    // This is the same as Flip X and Rotate 90.
    matrix.reset();
    matrix.setScale(SkIntToScalar(1), SkIntToScalar(-1));
    matrix.postRotate(SkIntToScalar(90));
    SkRRect dst2;
    dst2.setEmpty();
    success = orig.transform(matrix, &dst2);
    REPORTER_ASSERT(reporter, success);
    REPORTER_ASSERT(reporter, dst == dst2);

    //  a-----b            b-----c        c-----b
    //  |     |     ->     |     |   ->   |     |
    //  |     | Rotate 270 |     | Flip X |     |
    //  d-----c            a-----d        d-----a
    matrix.reset();
    matrix.setScale(SkIntToScalar(-1), SkIntToScalar(1));
    matrix.postRotate(SkIntToScalar(270));
    dst2.setEmpty();
    success = orig.transform(matrix, &dst2);
    REPORTER_ASSERT(reporter, success);
    REPORTER_ASSERT(reporter, dst == dst2);

    //  a-----b        d-----c            c-----b
    //  |     |   ->   |     |     ->     |     |
    //  |     | Flip Y |     | Rotate 270 |     |
    //  d-----c        a-----b            d-----a
    matrix.reset();
    matrix.setRotate(SkIntToScalar(270));
    matrix.postScale(SkIntToScalar(1), SkIntToScalar(-1));
    dst2.setEmpty();
    success = orig.transform(matrix, &dst2);
    REPORTER_ASSERT(reporter, success);
    REPORTER_ASSERT(reporter, dst == dst2);

    //  a-----b           d-----a        a-----d
    //  |     |    ->     |     |   ->   |     |
    //  |     | Rotate 90 |     | Flip X |     |
    //  d-----c           c-----b        b-----c
    matrix.reset();
    matrix.setScale(SkIntToScalar(-1), SkIntToScalar(1));
    matrix.postRotate(SkIntToScalar(90));
    dst.setEmpty();
    success = orig.transform(matrix, &dst);
    REPORTER_ASSERT(reporter, success);
    {
        GET_RADII;
        REPORTER_ASSERT(reporter, dstUL.x() == origUL.y());
        REPORTER_ASSERT(reporter, dstUL.y() == origUL.x());
        REPORTER_ASSERT(reporter, dstUR.x() == origLL.y());
        REPORTER_ASSERT(reporter, dstUR.y() == origLL.x());
        REPORTER_ASSERT(reporter, dstLR.x() == origLR.y());
        REPORTER_ASSERT(reporter, dstLR.y() == origLR.x());
        REPORTER_ASSERT(reporter, dstLL.x() == origUR.y());
        REPORTER_ASSERT(reporter, dstLL.y() == origUR.x());
    }
    // Width and height would get swapped.
    REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().height());
    REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().width());

    //  a-----b        d-----c           a-----d
    //  |     |   ->   |     |    ->     |     |
    //  |     | Flip Y |     | Rotate 90 |     |
    //  d-----c        a-----b           b-----c
    // This is the same as rotate 90 and flip x.
    matrix.reset();
    matrix.setRotate(SkIntToScalar(90));
    matrix.postScale(SkIntToScalar(1), SkIntToScalar(-1));
    dst2.setEmpty();
    success = orig.transform(matrix, &dst2);
    REPORTER_ASSERT(reporter, success);
    REPORTER_ASSERT(reporter, dst == dst2);

    //  a-----b        b-----a            a-----d
    //  |     |   ->   |     |     ->     |     |
    //  |     | Flip X |     | Rotate 270 |     |
    //  d-----c        c-----d            b-----c
    matrix.reset();
    matrix.setRotate(SkIntToScalar(270));
    matrix.postScale(SkIntToScalar(-1), SkIntToScalar(1));
    dst2.setEmpty();
    success = orig.transform(matrix, &dst2);
    REPORTER_ASSERT(reporter, success);
    REPORTER_ASSERT(reporter, dst == dst2);

    //  a-----b            b-----c        a-----d
    //  |     |     ->     |     |   ->   |     |
    //  |     | Rotate 270 |     | Flip Y |     |
    //  d-----c            a-----d        b-----c
    matrix.reset();
    matrix.setScale(SkIntToScalar(1), SkIntToScalar(-1));
    matrix.postRotate(SkIntToScalar(270));
    dst2.setEmpty();
    success = orig.transform(matrix, &dst2);
    REPORTER_ASSERT(reporter, success);
    REPORTER_ASSERT(reporter, dst == dst2);


    //  a-----b        b-----a        c-----d            b-----c
    //  |     |   ->   |     |   ->   |     |    ->      |     |
    //  |     | Flip X |     | Flip Y |     | Rotate 90  |     |
    //  d-----c        c-----d        b-----a            a-----d
    //
    // This is the same as rotation by 270.
    matrix.reset();
    matrix.setRotate(SkIntToScalar(90));
    matrix.postScale(SkIntToScalar(-1), SkIntToScalar(-1));
    dst.setEmpty();
    success = orig.transform(matrix, &dst);
    REPORTER_ASSERT(reporter, success);
    {
        GET_RADII;
        // Radii have cycled clockwise and swapped their x and y axis.
        REPORTER_ASSERT(reporter, dstUL.x() == origUR.y());
        REPORTER_ASSERT(reporter, dstUL.y() == origUR.x());
        REPORTER_ASSERT(reporter, dstUR.x() == origLR.y());
        REPORTER_ASSERT(reporter, dstUR.y() == origLR.x());
        REPORTER_ASSERT(reporter, dstLR.x() == origLL.y());
        REPORTER_ASSERT(reporter, dstLR.y() == origLL.x());
        REPORTER_ASSERT(reporter, dstLL.x() == origUL.y());
        REPORTER_ASSERT(reporter, dstLL.y() == origUL.x());
    }
    // Width and height would get swapped.
    REPORTER_ASSERT(reporter, orig.rect().width() == dst.rect().height());
    REPORTER_ASSERT(reporter, orig.rect().height() == dst.rect().width());

    //  a-----b             b-----c
    //  |     |     ->      |     |
    //  |     | Rotate 270  |     |
    //  d-----c             a-----d
    //
    dst2.setEmpty();
    matrix.reset();
    matrix.setRotate(SkIntToScalar(270));
    success = orig.transform(matrix, &dst2);
    REPORTER_ASSERT(reporter, success);
    REPORTER_ASSERT(reporter, dst == dst2);

    //  a-----b        b-----a        c-----d             d-----a
    //  |     |   ->   |     |   ->   |     |     ->      |     |
    //  |     | Flip X |     | Flip Y |     | Rotate 270  |     |
    //  d-----c        c-----d        b-----a             c-----b
    //
    // This is the same as rotation by 90 degrees.
    matrix.reset();
    matrix.setRotate(SkIntToScalar(270));
    matrix.postScale(SkIntToScalar(-1), SkIntToScalar(-1));
    dst.setEmpty();
    success = orig.transform(matrix, &dst);
    REPORTER_ASSERT(reporter, success);

    matrix.reset();
    matrix.setRotate(SkIntToScalar(90));
    dst2.setEmpty();
    success = orig.transform(matrix, &dst2);
    REPORTER_ASSERT(reporter, dst == dst2);

}

static void test_round_rect_transform(skiatest::Reporter* reporter) {
    SkRRect rrect;
    {
        SkRect r = { 0, 0, kWidth, kHeight };
        rrect.setRectXY(r, SkIntToScalar(4), SkIntToScalar(7));
        test_transform_helper(reporter, rrect);
    }
    {
        SkRect r = { SkIntToScalar(5), SkIntToScalar(15),
                     SkIntToScalar(27), SkIntToScalar(34) };
        SkVector radii[4] = { { 0, SkIntToScalar(1) },
                              { SkIntToScalar(2), SkIntToScalar(3) },
                              { SkIntToScalar(4), SkIntToScalar(5) },
                              { SkIntToScalar(6), SkIntToScalar(7) } };
        rrect.setRectRadii(r, radii);
        test_transform_helper(reporter, rrect);
    }
}

// Test out the case where an oval already off in space is translated/scaled
// further off into space - yielding numerical issues when the rect & radii
// are transformed separatly
// BUG=skia:2696
static void test_issue_2696(skiatest::Reporter* reporter) {
    SkRRect rrect;
    SkRect r = { 28443.8594f, 53.1428604f, 28446.7148f, 56.0000038f };
    rrect.setOval(r);

    SkMatrix xform;
    xform.setAll(2.44f,  0.0f, 485411.7f,
                 0.0f,  2.44f,   -438.7f,
                 0.0f,   0.0f,      1.0f);
    SkRRect dst;

    bool success = rrect.transform(xform, &dst);
    REPORTER_ASSERT(reporter, success);

    SkScalar halfWidth = SkScalarHalf(dst.width());
    SkScalar halfHeight = SkScalarHalf(dst.height());

    for (int i = 0; i < 4; ++i) {
        REPORTER_ASSERT(reporter,
                        SkScalarNearlyEqual(dst.radii((SkRRect::Corner)i).fX, halfWidth));
        REPORTER_ASSERT(reporter,
                        SkScalarNearlyEqual(dst.radii((SkRRect::Corner)i).fY, halfHeight));
    }
}

void test_read_rrect(skiatest::Reporter* reporter, const SkRRect& rrect, bool shouldEqualSrc) {
    // It would be cleaner to call rrect.writeToMemory into a buffer. However, writeToMemory asserts
    // that the rrect is valid and our caller may have fiddled with the internals of rrect to make
    // it invalid.
    const void* buffer = reinterpret_cast<const void*>(&rrect);
    SkRRect deserialized;
    size_t size = deserialized.readFromMemory(buffer, sizeof(SkRRect));
    REPORTER_ASSERT(reporter, size == SkRRect::kSizeInMemory);
    REPORTER_ASSERT(reporter, deserialized.isValid());
    if (shouldEqualSrc) {
       REPORTER_ASSERT(reporter, rrect == deserialized);
    }
}

static void test_read(skiatest::Reporter* reporter) {
    static const SkRect kRect = {10.f, 10.f, 20.f, 20.f};
    static const SkRect kNaNRect = {10.f, 10.f, 20.f, SK_ScalarNaN};
    static const SkRect kInfRect = {10.f, 10.f, SK_ScalarInfinity, 20.f};
    SkRRect rrect;

    test_read_rrect(reporter, SkRRect::MakeEmpty(), true);
    test_read_rrect(reporter, SkRRect::MakeRect(kRect), true);
    // These get coerced to empty.
    test_read_rrect(reporter, SkRRect::MakeRect(kInfRect), true);
    test_read_rrect(reporter, SkRRect::MakeRect(kNaNRect), true);

    rrect.setRect(kRect);
    SkRect* innerRect = reinterpret_cast<SkRect*>(&rrect);
    SkASSERT(*innerRect == kRect);
    *innerRect = kInfRect;
    test_read_rrect(reporter, rrect, false);
    *innerRect = kNaNRect;
    test_read_rrect(reporter, rrect, false);

    test_read_rrect(reporter, SkRRect::MakeOval(kRect), true);
    test_read_rrect(reporter, SkRRect::MakeOval(kInfRect), true);
    test_read_rrect(reporter, SkRRect::MakeOval(kNaNRect), true);
    rrect.setOval(kRect);
    *innerRect = kInfRect;
    test_read_rrect(reporter, rrect, false);
    *innerRect = kNaNRect;
    test_read_rrect(reporter, rrect, false);

    test_read_rrect(reporter, SkRRect::MakeRectXY(kRect, 5.f, 5.f), true);
    // rrect should scale down the radii to make this legal
    test_read_rrect(reporter, SkRRect::MakeRectXY(kRect, 5.f, 400.f), true);

    static const SkVector kRadii[4] = {{0.5f, 1.f}, {1.5f, 2.f}, {2.5f, 3.f}, {3.5f, 4.f}};
    rrect.setRectRadii(kRect, kRadii);
    test_read_rrect(reporter, rrect, true);
    SkScalar* innerRadius = reinterpret_cast<SkScalar*>(&rrect) + 6;
    SkASSERT(*innerRadius == 1.5f);
    *innerRadius = 400.f;
    test_read_rrect(reporter, rrect, false);
    *innerRadius = SK_ScalarInfinity;
    test_read_rrect(reporter, rrect, false);
    *innerRadius = SK_ScalarNaN;
    test_read_rrect(reporter, rrect, false);
    *innerRadius = -10.f;
    test_read_rrect(reporter, rrect, false);
}

static void test_inner_bounds(skiatest::Reporter* reporter) {
    // Because InnerBounds() insets the computed bounds slightly to correct for numerical inaccuracy
    // when finding the maximum inscribed point on a curve, we use a larger epsilon for comparing
    // expected areas.
    static constexpr SkScalar kEpsilon = 0.005f;

    // Test that an empty rrect reports empty inner bounds
    REPORTER_ASSERT(reporter, SkRRectPriv::InnerBounds(SkRRect::MakeEmpty()).isEmpty());
    // Test that a rect rrect reports itself as the inner bounds
    SkRect r = SkRect::MakeLTRB(0, 1, 2, 3);
    REPORTER_ASSERT(reporter, SkRRectPriv::InnerBounds(SkRRect::MakeRect(r)) == r);
    // Test that a circle rrect has an inner bounds area equal to 2*radius^2
    float radius = 5.f;
    SkRect inner = SkRRectPriv::InnerBounds(SkRRect::MakeOval(SkRect::MakeWH(2.f * radius,
                                                                             2.f * radius)));
    REPORTER_ASSERT(reporter, SkScalarNearlyEqual(inner.width() * inner.height(),
                                                  2.f * radius * radius, kEpsilon));

    float width = 20.f;
    float height = 25.f;
    r = SkRect::MakeWH(width, height);
    // Test that a rrect with circular corners has an area equal to:
    float expectedArea =
            (2.f * radius * radius) +                      // area in the 4 circular corners
            (width-2.f*radius) * (height-2.f*radius) +     // inner area excluding corners and edges
            SK_ScalarSqrt2 * radius * (width-2.f*radius) + // two horiz. rects between corners
            SK_ScalarSqrt2 * radius * (height-2.f*radius); // two vert. rects between corners

    inner = SkRRectPriv::InnerBounds(SkRRect::MakeRectXY(r, radius, radius));
    REPORTER_ASSERT(reporter, SkScalarNearlyEqual(inner.width() * inner.height(),
                                                  expectedArea, kEpsilon));

    // Test that a rrect with a small y radius but large x radius selects the horizontal interior
    SkRRect rr = SkRRect::MakeRectXY(r, 2.f * radius, 0.1f * radius);
    REPORTER_ASSERT(reporter, SkRRectPriv::InnerBounds(rr) ==
                              SkRect::MakeLTRB(0.f, 0.1f * radius, width, height - 0.1f * radius));
    // And vice versa with large y and small x radii
    rr = SkRRect::MakeRectXY(r, 0.1f * radius, 2.f * radius);
    REPORTER_ASSERT(reporter, SkRRectPriv::InnerBounds(rr) ==
                              SkRect::MakeLTRB(0.1f * radius, 0.f, width - 0.1f * radius, height));

    // Test a variety of complex round rects produce a non-empty rect that is at least contained,
    // and larger than the inner area avoiding all corners.
    SkRandom rng;
    for (int i = 0; i < 1000; ++i) {
        float maxRadiusX = rng.nextRangeF(0.f, 40.f);
        float maxRadiusY = rng.nextRangeF(0.f, 40.f);

        float innerWidth = rng.nextRangeF(0.f, 40.f);
        float innerHeight = rng.nextRangeF(0.f, 40.f);

        SkVector radii[4] = {{rng.nextRangeF(0.f, maxRadiusX), rng.nextRangeF(0.f, maxRadiusY)},
                             {rng.nextRangeF(0.f, maxRadiusX), rng.nextRangeF(0.f, maxRadiusY)},
                             {rng.nextRangeF(0.f, maxRadiusX), rng.nextRangeF(0.f, maxRadiusY)},
                             {rng.nextRangeF(0.f, maxRadiusX), rng.nextRangeF(0.f, maxRadiusY)}};

        float maxLeft   = std::max(radii[0].fX, radii[3].fX);
        float maxTop    = std::max(radii[0].fY, radii[1].fY);
        float maxRight  = std::max(radii[1].fX, radii[2].fX);
        float maxBottom = std::max(radii[2].fY, radii[3].fY);

        SkRect outer = SkRect::MakeWH(maxLeft + maxRight + innerWidth,
                                      maxTop + maxBottom + innerHeight);
        rr.setRectRadii(outer, radii);

        SkRect maxInner = SkRRectPriv::InnerBounds(rr);
        // Test upper limit on the size of 'maxInner'
        REPORTER_ASSERT(reporter, outer.contains(maxInner));
        REPORTER_ASSERT(reporter, rr.contains(maxInner));

        // Test lower limit on the size of 'maxInner'
        inner = SkRect::MakeXYWH(maxLeft, maxTop, innerWidth, innerHeight);
        inner.inset(kEpsilon, kEpsilon);

        if (inner.isSorted()) {
            REPORTER_ASSERT(reporter, maxInner.contains(inner));
        } else {
            // Flipped from the inset, just test two points of inner
            float midX = maxLeft + 0.5f * innerWidth;
            float midY = maxTop + 0.5f * innerHeight;
            REPORTER_ASSERT(reporter, maxInner.contains(midX, maxTop));
            REPORTER_ASSERT(reporter, maxInner.contains(midX, maxTop + innerHeight));
            REPORTER_ASSERT(reporter, maxInner.contains(maxLeft, midY));
            REPORTER_ASSERT(reporter, maxInner.contains(maxLeft + innerWidth, midY));
        }
    }
}

namespace {
    // Helper to test expected intersection, relying on the fact that all round rect intersections
    // will have their bounds equal to the intersection of the bounds of the input round rects, and
    // their corner radii will be a one of A's, B's, or rectangular.
    enum CornerChoice : uint8_t {
        kA, kB, kRect
    };

    static void verify_success(skiatest::Reporter* reporter, const SkRRect& a, const SkRRect& b,
                               CornerChoice tl, CornerChoice tr, CornerChoice br, CornerChoice bl) {
        static const SkRRect kRect = SkRRect::MakeEmpty(); // has (0,0) for all corners

        // Compute expected round rect intersection given bounds of A and B, and the specified
        // corner choices for the 4 corners.
        SkRect expectedBounds;
        SkAssertResult(expectedBounds.intersect(a.rect(), b.rect()));

        SkVector radii[4] = {
            (tl == kA ? a : (tl == kB ? b : kRect)).radii(SkRRect::kUpperLeft_Corner),
            (tr == kA ? a : (tr == kB ? b : kRect)).radii(SkRRect::kUpperRight_Corner),
            (br == kA ? a : (br == kB ? b : kRect)).radii(SkRRect::kLowerRight_Corner),
            (bl == kA ? a : (bl == kB ? b : kRect)).radii(SkRRect::kLowerLeft_Corner)
        };
        SkRRect expected;
        expected.setRectRadii(expectedBounds, radii);

        SkRRect actual = SkRRectPriv::ConservativeIntersect(a, b);
        // Intersections are commutative so ba and ab should be the same
        REPORTER_ASSERT(reporter, actual == SkRRectPriv::ConservativeIntersect(b, a));

        // Intersection of the result with either A or B should remain the intersection
        REPORTER_ASSERT(reporter, actual == SkRRectPriv::ConservativeIntersect(actual, a));
        REPORTER_ASSERT(reporter, actual == SkRRectPriv::ConservativeIntersect(actual, b));

        // Bounds of intersection round rect should equal intersection of bounds of a and b
        REPORTER_ASSERT(reporter, actual.rect() == expectedBounds);

        // Use PathOps to confirm that the explicit round rect is correct.
        SkPath aPath, bPath, expectedPath;
        aPath.addRRect(a);
        bPath.addRRect(b);
        SkAssertResult(Op(aPath, bPath, kIntersect_SkPathOp, &expectedPath));

        // The isRRect() heuristics in SkPath are based on having called addRRect(), so a path from
        // path ops that is a rounded rectangle will return false. However, if test XOR expected is
        // empty, then we know that the shapes were the same.
        SkPath testPath;
        testPath.addRRect(actual);

        SkPath empty;
        SkAssertResult(Op(testPath, expectedPath, kXOR_SkPathOp, &empty));
        REPORTER_ASSERT(reporter, empty.isEmpty());
    }

    static void verify_failure(skiatest::Reporter* reporter, const SkRRect& a, const SkRRect& b) {
        SkRRect intersection = SkRRectPriv::ConservativeIntersect(a, b);
        // Expected the intersection to fail (no intersection or complex intersection is not
        // disambiguated).
        REPORTER_ASSERT(reporter, intersection.isEmpty());
        REPORTER_ASSERT(reporter, SkRRectPriv::ConservativeIntersect(b, a).isEmpty());
    }
}  // namespace

static void test_conservative_intersection(skiatest::Reporter* reporter) {
    // Helper to inline making an inset round rect
    auto make_inset = [](const SkRRect& r, float dx, float dy) {
        SkRRect i = r;
        i.inset(dx, dy);
        return i;
    };

    // A is a wide, short round rect
    SkRRect a = SkRRect::MakeRectXY({0.f, 4.f, 16.f, 12.f}, 2.f, 2.f);
    // B is a narrow, tall round rect
    SkRRect b = SkRRect::MakeRectXY({4.f, 0.f, 12.f, 16.f}, 3.f, 3.f);
    // NOTE: As positioned by default, A and B intersect as the rectangle {4, 4, 12, 12}.
    // There is a 2 px buffer between the corner curves of A and the vertical edges of B, and
    // a 1 px buffer between the corner curves of B and the horizontal edges of A. Since the shapes
    // form a symmetric rounded cross, we can easily test edge and corner combinations by simply
    // flipping signs and/or swapping x and y offsets.

    // Successful intersection operations:
    //  - for clarity these are formed by moving A around to intersect with B in different ways.
    //  - the expected bounds of the round rect intersection is calculated automatically
    //    in check_success, so all we have to specify are the expected corner radii

    // A and B intersect as a rectangle
    verify_success(reporter, a, b, kRect, kRect, kRect, kRect);
    // Move A to intersect B on a vertical edge, preserving two corners of A inside B
    verify_success(reporter, a.makeOffset(6.f, 0.f), b, kA, kRect, kRect, kA);
    verify_success(reporter, a.makeOffset(-6.f, 0.f), b, kRect, kA, kA, kRect);
    // Move B to intersect A on a horizontal edge, preserving two corners of B inside A
    verify_success(reporter, a, b.makeOffset(0.f, 6.f), kB, kB, kRect, kRect);
    verify_success(reporter, a, b.makeOffset(0.f, -6.f), kRect, kRect, kB, kB);
    // Move A to intersect B on a corner, preserving one corner of A and one of B
    verify_success(reporter, a.makeOffset(-7.f, -8.f), b, kB, kRect, kA, kRect); // TL of B
    verify_success(reporter, a.makeOffset(7.f, -8.f), b, kRect, kB, kRect, kA);  // TR of B
    verify_success(reporter, a.makeOffset(7.f, 8.f), b, kA, kRect, kB, kRect);   // BR of B
    verify_success(reporter, a.makeOffset(-7.f, 8.f), b, kRect, kA, kRect, kB);  // BL of B
    // An inset is contained inside the original (note that SkRRect::inset modifies radii too) so
    // is returned unmodified when intersected.
    verify_success(reporter, a, make_inset(a, 1.f, 1.f), kB, kB, kB, kB);
    verify_success(reporter, make_inset(b, 2.f, 2.f), b, kA, kA, kA, kA);

    // A rectangle exactly matching the corners of the rrect bounds keeps the rrect radii,
    // regardless of whether or not it's the 1st or 2nd arg to ConservativeIntersect.
    SkRRect c = SkRRect::MakeRectXY({0.f, 0.f, 10.f, 10.f}, 2.f, 2.f);
    SkRRect cT = SkRRect::MakeRect({0.f, 0.f, 10.f, 5.f});
    verify_success(reporter, c, cT, kA, kA, kRect, kRect);
    verify_success(reporter, cT, c, kB, kB, kRect, kRect);
    SkRRect cB = SkRRect::MakeRect({0.f, 5.f, 10.f, 10.});
    verify_success(reporter, c, cB, kRect, kRect, kA, kA);
    verify_success(reporter, cB, c, kRect, kRect, kB, kB);
    SkRRect cL = SkRRect::MakeRect({0.f, 0.f, 5.f, 10.f});
    verify_success(reporter, c, cL, kA, kRect, kRect, kA);
    verify_success(reporter, cL, c, kB, kRect, kRect, kB);
    SkRRect cR = SkRRect::MakeRect({5.f, 0.f, 10.f, 10.f});
    verify_success(reporter, c, cR, kRect, kA, kA, kRect);
    verify_success(reporter, cR, c, kRect, kB, kB, kRect);

    // Failed intersection operations:

    // A and B's bounds do not intersect
    verify_failure(reporter, a.makeOffset(32.f, 0.f), b);
    // A and B's bounds intersect, but corner curves do not -> no intersection
    verify_failure(reporter, a.makeOffset(11.5f, -11.5f), b);
    // A is empty -> no intersection
    verify_failure(reporter, SkRRect::MakeEmpty(), b);
    // A is contained in B, but is too close to the corner curves for the conservative
    // approximations to construct a valid round rect intersection.
    verify_failure(reporter, make_inset(b, 0.3f, 0.3f), b);
    // A intersects a straight edge, but not far enough for B to contain A's corners
    verify_failure(reporter, a.makeOffset(2.5f, 0.f), b);
    verify_failure(reporter, a.makeOffset(-2.5f, 0.f), b);
    // And vice versa for B into A
    verify_failure(reporter, a, b.makeOffset(0.f, 1.5f));
    verify_failure(reporter, a, b.makeOffset(0.f, -1.5f));
    // A intersects a straight edge and part of B's corner
    verify_failure(reporter, a.makeOffset(5.f, -2.f), b);
    verify_failure(reporter, a.makeOffset(-5.f, -2.f), b);
    verify_failure(reporter, a.makeOffset(5.f, 2.f), b);
    verify_failure(reporter, a.makeOffset(-5.f, 2.f), b);
    // And vice versa
    verify_failure(reporter, a, b.makeOffset(3.f, -5.f));
    verify_failure(reporter, a, b.makeOffset(-3.f, -5.f));
    verify_failure(reporter, a, b.makeOffset(3.f, 5.f));
    verify_failure(reporter, a, b.makeOffset(-3.f, 5.f));
    // A intersects B on a corner, but the corner curves overlap each other
    verify_failure(reporter, a.makeOffset(8.f, 10.f), b);
    verify_failure(reporter, a.makeOffset(-8.f, 10.f), b);
    verify_failure(reporter, a.makeOffset(8.f, -10.f), b);
    verify_failure(reporter, a.makeOffset(-8.f, -10.f), b);

    // Another variant of corners overlapping, this is two circles of radius r that overlap by r
    // pixels (e.g. the leftmost point of the right circle touches the center of the left circle).
    // The key difference with the above case is that the intersection of the circle bounds have
    // corners that are contained in both circles, but because it is only r wide, can not satisfy
    // all corners having radii = r.
    float r = 100.f;
    a = SkRRect::MakeOval(SkRect::MakeWH(2*r, 2*r));
    verify_failure(reporter, a, a.makeOffset(r, 0.f));
}

DEF_TEST(RoundRect, reporter) {
    test_round_rect_basic(reporter);
    test_round_rect_rects(reporter);
    test_round_rect_ovals(reporter);
    test_round_rect_general(reporter);
    test_round_rect_iffy_parameters(reporter);
    test_inset(reporter);
    test_round_rect_contains_rect(reporter);
    test_round_rect_transform(reporter);
    test_issue_2696(reporter);
    test_tricky_radii(reporter);
    test_empty_crbug_458524(reporter);
    test_empty(reporter);
    test_read(reporter);
    test_inner_bounds(reporter);
    test_conservative_intersection(reporter);
}

DEF_TEST(RRect_fuzzer_regressions, r) {
    {
        unsigned char buf[] = {
            0x0a, 0x00, 0x00, 0xff, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
            0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
            0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
            0x7f, 0x7f, 0x7f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x02, 0x00
        };
        REPORTER_ASSERT(r, sizeof(buf) == SkRRect{}.readFromMemory(buf, sizeof(buf)));
    }

    {
        unsigned char buf[] = {
            0x5d, 0xff, 0xff, 0x5d, 0x0a, 0x60, 0x0a, 0x0a, 0x0a, 0x7e, 0x0a, 0x5a,
            0x0a, 0x12, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
            0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x00, 0x00, 0x00, 0x0a,
            0x0a, 0x0a, 0x0a, 0x26, 0x0a, 0x0a, 0x0a, 0x0a, 0xff, 0xff, 0x0a, 0x0a
        };
        REPORTER_ASSERT(r, sizeof(buf) == SkRRect{}.readFromMemory(buf, sizeof(buf)));
    }

    {
        unsigned char buf[] = {
            0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x04, 0xdd, 0xdd, 0x15,
            0xfe, 0x00, 0x00, 0x04, 0x05, 0x7e, 0x00, 0x00, 0x00, 0xff, 0x08, 0x04,
            0xff, 0xff, 0xfe, 0xfe, 0xff, 0x32, 0x32, 0x32, 0x32, 0x00, 0x32, 0x32,
            0x04, 0xdd, 0x3d, 0x1c, 0xfe, 0x89, 0x04, 0x0a, 0x0e, 0x05, 0x7e, 0x0a
        };
        REPORTER_ASSERT(r, sizeof(buf) == SkRRect{}.readFromMemory(buf, sizeof(buf)));
    }
}
