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

#include "SkAAClip.h"
#include "SkCanvas.h"
#include "SkMask.h"
#include "SkPath.h"
#include "SkRandom.h"
#include "SkRasterClip.h"
#include "SkRRect.h"
#include "Test.h"

static bool operator==(const SkMask& a, const SkMask& b) {
    if (a.fFormat != b.fFormat || a.fBounds != b.fBounds) {
        return false;
    }
    if (!a.fImage && !b.fImage) {
        return true;
    }
    if (!a.fImage || !b.fImage) {
        return false;
    }

    size_t wbytes = a.fBounds.width();
    switch (a.fFormat) {
        case SkMask::kBW_Format:
            wbytes = (wbytes + 7) >> 3;
            break;
        case SkMask::kA8_Format:
        case SkMask::k3D_Format:
            break;
        case SkMask::kLCD16_Format:
            wbytes <<= 1;
            break;
        case SkMask::kARGB32_Format:
            wbytes <<= 2;
            break;
        default:
            SkDEBUGFAIL("unknown mask format");
            return false;
    }

    const int h = a.fBounds.height();
    const char* aptr = (const char*)a.fImage;
    const char* bptr = (const char*)b.fImage;
    for (int y = 0; y < h; ++y) {
        if (memcmp(aptr, bptr, wbytes)) {
            return false;
        }
        aptr += wbytes;
        bptr += wbytes;
    }
    return true;
}

static void copyToMask(const SkRegion& rgn, SkMask* mask) {
    mask->fFormat = SkMask::kA8_Format;

    if (rgn.isEmpty()) {
        mask->fBounds.setEmpty();
        mask->fRowBytes = 0;
        mask->fImage = nullptr;
        return;
    }

    mask->fBounds = rgn.getBounds();
    mask->fRowBytes = mask->fBounds.width();
    mask->fImage = SkMask::AllocImage(mask->computeImageSize());
    sk_bzero(mask->fImage, mask->computeImageSize());

    SkImageInfo info = SkImageInfo::Make(mask->fBounds.width(),
                                         mask->fBounds.height(),
                                         kAlpha_8_SkColorType,
                                         kPremul_SkAlphaType);
    SkBitmap bitmap;
    bitmap.installPixels(info, mask->fImage, mask->fRowBytes);

    // canvas expects its coordinate system to always be 0,0 in the top/left
    // so we translate the rgn to match that before drawing into the mask.
    //
    SkRegion tmpRgn(rgn);
    tmpRgn.translate(-rgn.getBounds().fLeft, -rgn.getBounds().fTop);

    SkCanvas canvas(bitmap);
    canvas.clipRegion(tmpRgn);
    canvas.drawColor(SK_ColorBLACK);
}

static SkIRect rand_rect(SkRandom& rand, int n) {
    int x = rand.nextS() % n;
    int y = rand.nextS() % n;
    int w = rand.nextU() % n;
    int h = rand.nextU() % n;
    return SkIRect::MakeXYWH(x, y, w, h);
}

static void make_rand_rgn(SkRegion* rgn, SkRandom& rand) {
    int count = rand.nextU() % 20;
    for (int i = 0; i < count; ++i) {
        rgn->op(rand_rect(rand, 100), SkRegion::kXOR_Op);
    }
}

static bool operator==(const SkRegion& rgn, const SkAAClip& aaclip) {
    SkMask mask0, mask1;

    copyToMask(rgn, &mask0);
    aaclip.copyToMask(&mask1);
    bool eq = (mask0 == mask1);

    SkMask::FreeImage(mask0.fImage);
    SkMask::FreeImage(mask1.fImage);
    return eq;
}

static bool equalsAAClip(const SkRegion& rgn) {
    SkAAClip aaclip;
    aaclip.setRegion(rgn);
    return rgn == aaclip;
}

static void setRgnToPath(SkRegion* rgn, const SkPath& path) {
    SkIRect ir;
    path.getBounds().round(&ir);
    rgn->setPath(path, SkRegion(ir));
}

// aaclip.setRegion should create idential masks to the region
static void test_rgn(skiatest::Reporter* reporter) {
    SkRandom rand;
    for (int i = 0; i < 1000; i++) {
        SkRegion rgn;
        make_rand_rgn(&rgn, rand);
        REPORTER_ASSERT(reporter, equalsAAClip(rgn));
    }

    {
        SkRegion rgn;
        SkPath path;
        path.addCircle(0, 0, SkIntToScalar(30));
        setRgnToPath(&rgn, path);
        REPORTER_ASSERT(reporter, equalsAAClip(rgn));

        path.reset();
        path.moveTo(0, 0);
        path.lineTo(SkIntToScalar(100), 0);
        path.lineTo(SkIntToScalar(100 - 20), SkIntToScalar(20));
        path.lineTo(SkIntToScalar(20), SkIntToScalar(20));
        setRgnToPath(&rgn, path);
        REPORTER_ASSERT(reporter, equalsAAClip(rgn));
    }
}

static const SkRegion::Op gRgnOps[] = {
    SkRegion::kDifference_Op,
    SkRegion::kIntersect_Op,
    SkRegion::kUnion_Op,
    SkRegion::kXOR_Op,
    SkRegion::kReverseDifference_Op,
    SkRegion::kReplace_Op
};

static const char* gRgnOpNames[] = {
    "DIFF", "INTERSECT", "UNION", "XOR", "REVERSE_DIFF", "REPLACE"
};

static void imoveTo(SkPath& path, int x, int y) {
    path.moveTo(SkIntToScalar(x), SkIntToScalar(y));
}

static void icubicTo(SkPath& path, int x0, int y0, int x1, int y1, int x2, int y2) {
    path.cubicTo(SkIntToScalar(x0), SkIntToScalar(y0),
                 SkIntToScalar(x1), SkIntToScalar(y1),
                 SkIntToScalar(x2), SkIntToScalar(y2));
}

static void test_path_bounds(skiatest::Reporter* reporter) {
    SkPath path;
    SkAAClip clip;
    const int height = 40;
    const SkScalar sheight = SkIntToScalar(height);

    path.addOval(SkRect::MakeWH(sheight, sheight));
    REPORTER_ASSERT(reporter, sheight == path.getBounds().height());
    clip.setPath(path, nullptr, true);
    REPORTER_ASSERT(reporter, height == clip.getBounds().height());

    // this is the trimmed height of this cubic (with aa). The critical thing
    // for this test is that it is less than height, which represents just
    // the bounds of the path's control-points.
    //
    // This used to fail until we tracked the MinY in the BuilderBlitter.
    //
    const int teardrop_height = 12;
    path.reset();
    imoveTo(path, 0, 20);
    icubicTo(path, 40, 40, 40, 0, 0, 20);
    REPORTER_ASSERT(reporter, sheight == path.getBounds().height());
    clip.setPath(path, nullptr, true);
    REPORTER_ASSERT(reporter, teardrop_height == clip.getBounds().height());
}

static void test_empty(skiatest::Reporter* reporter) {
    SkAAClip clip0, clip1;

    REPORTER_ASSERT(reporter, clip0.isEmpty());
    REPORTER_ASSERT(reporter, clip0.getBounds().isEmpty());
    REPORTER_ASSERT(reporter, clip1 == clip0);

    clip0.translate(10, 10);    // should have no effect on empty
    REPORTER_ASSERT(reporter, clip0.isEmpty());
    REPORTER_ASSERT(reporter, clip0.getBounds().isEmpty());
    REPORTER_ASSERT(reporter, clip1 == clip0);

    SkIRect r = { 10, 10, 40, 50 };
    clip0.setRect(r);
    REPORTER_ASSERT(reporter, !clip0.isEmpty());
    REPORTER_ASSERT(reporter, !clip0.getBounds().isEmpty());
    REPORTER_ASSERT(reporter, clip0 != clip1);
    REPORTER_ASSERT(reporter, clip0.getBounds() == r);

    clip0.setEmpty();
    REPORTER_ASSERT(reporter, clip0.isEmpty());
    REPORTER_ASSERT(reporter, clip0.getBounds().isEmpty());
    REPORTER_ASSERT(reporter, clip1 == clip0);

    SkMask mask;
    clip0.copyToMask(&mask);
    REPORTER_ASSERT(reporter, nullptr == mask.fImage);
    REPORTER_ASSERT(reporter, mask.fBounds.isEmpty());
}

static void rand_irect(SkIRect* r, int N, SkRandom& rand) {
    r->setXYWH(0, 0, rand.nextU() % N, rand.nextU() % N);
    int dx = rand.nextU() % (2*N);
    int dy = rand.nextU() % (2*N);
    // use int dx,dy to make the subtract be signed
    r->offset(N - dx, N - dy);
}

static void test_irect(skiatest::Reporter* reporter) {
    SkRandom rand;

    for (int i = 0; i < 10000; i++) {
        SkAAClip clip0, clip1;
        SkRegion rgn0, rgn1;
        SkIRect r0, r1;

        rand_irect(&r0, 10, rand);
        rand_irect(&r1, 10, rand);
        clip0.setRect(r0);
        clip1.setRect(r1);
        rgn0.setRect(r0);
        rgn1.setRect(r1);
        for (size_t j = 0; j < SK_ARRAY_COUNT(gRgnOps); ++j) {
            SkRegion::Op op = gRgnOps[j];
            SkAAClip clip2;
            SkRegion rgn2;
            bool nonEmptyAA = clip2.op(clip0, clip1, op);
            bool nonEmptyBW = rgn2.op(rgn0, rgn1, op);
            if (nonEmptyAA != nonEmptyBW || clip2.getBounds() != rgn2.getBounds()) {
                ERRORF(reporter, "%s %s "
                       "[%d %d %d %d] %s [%d %d %d %d] = BW:[%d %d %d %d] AA:[%d %d %d %d]\n",
                       nonEmptyAA == nonEmptyBW ? "true" : "false",
                       clip2.getBounds() == rgn2.getBounds() ? "true" : "false",
                       r0.fLeft, r0.fTop, r0.right(), r0.bottom(),
                       gRgnOpNames[j],
                       r1.fLeft, r1.fTop, r1.right(), r1.bottom(),
                       rgn2.getBounds().fLeft, rgn2.getBounds().fTop,
                       rgn2.getBounds().right(), rgn2.getBounds().bottom(),
                       clip2.getBounds().fLeft, clip2.getBounds().fTop,
                       clip2.getBounds().right(), clip2.getBounds().bottom());
            }

            SkMask maskBW, maskAA;
            copyToMask(rgn2, &maskBW);
            clip2.copyToMask(&maskAA);
            SkAutoMaskFreeImage freeBW(maskBW.fImage);
            SkAutoMaskFreeImage freeAA(maskAA.fImage);
            REPORTER_ASSERT(reporter, maskBW == maskAA);
        }
    }
}

static void test_path_with_hole(skiatest::Reporter* reporter) {
    static const uint8_t gExpectedImage[] = {
        0xFF, 0xFF, 0xFF, 0xFF,
        0xFF, 0xFF, 0xFF, 0xFF,
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF,
        0xFF, 0xFF, 0xFF, 0xFF,
    };
    SkMask expected;
    expected.fBounds.set(0, 0, 4, 6);
    expected.fRowBytes = 4;
    expected.fFormat = SkMask::kA8_Format;
    expected.fImage = (uint8_t*)gExpectedImage;

    SkPath path;
    path.addRect(SkRect::MakeXYWH(0, 0,
                                  SkIntToScalar(4), SkIntToScalar(2)));
    path.addRect(SkRect::MakeXYWH(0, SkIntToScalar(4),
                                  SkIntToScalar(4), SkIntToScalar(2)));

    for (int i = 0; i < 2; ++i) {
        SkAAClip clip;
        clip.setPath(path, nullptr, 1 == i);

        SkMask mask;
        clip.copyToMask(&mask);
        SkAutoMaskFreeImage freeM(mask.fImage);

        REPORTER_ASSERT(reporter, expected == mask);
    }
}

static void test_really_a_rect(skiatest::Reporter* reporter) {
    SkRRect rrect;
    rrect.setRectXY(SkRect::MakeWH(100, 100), 5, 5);

    SkPath path;
    path.addRRect(rrect);

    SkAAClip clip;
    clip.setPath(path);

    REPORTER_ASSERT(reporter, clip.getBounds() == SkIRect::MakeWH(100, 100));
    REPORTER_ASSERT(reporter, !clip.isRect());

    // This rect should intersect the clip, but slice-out all of the "soft" parts,
    // leaving just a rect.
    const SkIRect ir = SkIRect::MakeLTRB(10, -10, 50, 90);

    clip.op(ir, SkRegion::kIntersect_Op);

    REPORTER_ASSERT(reporter, clip.getBounds() == SkIRect::MakeLTRB(10, 0, 50, 90));
    // the clip recognized that that it is just a rect!
    REPORTER_ASSERT(reporter, clip.isRect());
}

static void did_dx_affect(skiatest::Reporter* reporter, const SkScalar dx[],
                          size_t count, bool changed) {
    const SkIRect baseBounds = SkIRect::MakeXYWH(0, 0, 10, 10);
    SkIRect ir = { 0, 0, 10, 10 };

    for (size_t i = 0; i < count; ++i) {
        SkRect r;
        r.set(ir);

        SkRasterClip rc0(ir);
        SkRasterClip rc1(ir);
        SkRasterClip rc2(ir);

        rc0.op(r, SkMatrix::I(), baseBounds, SkRegion::kIntersect_Op, false);
        r.offset(dx[i], 0);
        rc1.op(r, SkMatrix::I(), baseBounds, SkRegion::kIntersect_Op, true);
        r.offset(-2*dx[i], 0);
        rc2.op(r, SkMatrix::I(), baseBounds, SkRegion::kIntersect_Op, true);

        REPORTER_ASSERT(reporter, changed != (rc0 == rc1));
        REPORTER_ASSERT(reporter, changed != (rc0 == rc2));
    }
}

static void test_nearly_integral(skiatest::Reporter* reporter) {
    // All of these should generate equivalent rasterclips

    static const SkScalar gSafeX[] = {
        0, SK_Scalar1/1000, SK_Scalar1/100, SK_Scalar1/10,
    };
    did_dx_affect(reporter, gSafeX, SK_ARRAY_COUNT(gSafeX), false);

    static const SkScalar gUnsafeX[] = {
        SK_Scalar1/4, SK_Scalar1/3,
    };
    did_dx_affect(reporter, gUnsafeX, SK_ARRAY_COUNT(gUnsafeX), true);
}

static void test_regressions() {
    // these should not assert in the debug build
    // bug was introduced in rev. 3209
    {
        SkAAClip clip;
        SkRect r;
        r.fLeft = 129.892181f;
        r.fTop = 10.3999996f;
        r.fRight = 130.892181f;
        r.fBottom = 20.3999996f;
        clip.setRect(r, true);
    }
}

// Building aaclip meant aa-scan-convert a path into a huge clip.
// the old algorithm sized the supersampler to the size of the clip, which overflowed
// its internal 16bit coordinates. The fix was to intersect the clip+path_bounds before
// sizing the supersampler.
//
// Before the fix, the following code would assert in debug builds.
//
static void test_crbug_422693(skiatest::Reporter* reporter) {
    SkRasterClip rc(SkIRect::MakeLTRB(-25000, -25000, 25000, 25000));
    SkPath path;
    path.addCircle(50, 50, 50);
    rc.op(path, SkMatrix::I(), rc.getBounds(), SkRegion::kIntersect_Op, true);
}

DEF_TEST(AAClip, reporter) {
    test_empty(reporter);
    test_path_bounds(reporter);
    test_irect(reporter);
    test_rgn(reporter);
    test_path_with_hole(reporter);
    test_regressions();
    test_nearly_integral(reporter);
    test_really_a_rect(reporter);
    test_crbug_422693(reporter);
}
