/*
 * Copyright 2011 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/core/SkScan.h"

#include "include/private/SkColorData.h"
#include "include/private/SkTo.h"
#include "src/core/SkBlitter.h"
#include "src/core/SkFDot6.h"
#include "src/core/SkLineClipper.h"
#include "src/core/SkRasterClip.h"

#include <utility>

/*  Our attempt to compute the worst case "bounds" for the horizontal and
    vertical cases has some numerical bug in it, and we sometimes undervalue
    our extends. The bug is that when this happens, we will set the clip to
    nullptr (for speed), and thus draw outside of the clip by a pixel, which might
    only look bad, but it might also access memory outside of the valid range
    allcoated for the device bitmap.

    This define enables our fix to outset our "bounds" by 1, thus avoiding the
    chance of the bug, but at the cost of sometimes taking the rectblitter
    case (i.e. not setting the clip to nullptr) when we might not actually need
    to. If we can improve/fix the actual calculations, then we can remove this
    step.
 */
#define OUTSET_BEFORE_CLIP_TEST     true

#define HLINE_STACK_BUFFER      100

static inline int SmallDot6Scale(int value, int dot6) {
    SkASSERT((int16_t)value == value);
    SkASSERT((unsigned)dot6 <= 64);
    return (value * dot6) >> 6;
}

//#define TEST_GAMMA

#ifdef TEST_GAMMA
    static uint8_t gGammaTable[256];
    #define ApplyGamma(table, alpha)    (table)[alpha]

    static void build_gamma_table() {
        static bool gInit = false;

        if (gInit == false) {
            for (int i = 0; i < 256; i++) {
                SkFixed n = i * 257;
                n += n >> 15;
                SkASSERT(n >= 0 && n <= SK_Fixed1);
                n = SkFixedSqrt(n);
                n = n * 255 >> 16;
            //  SkDebugf("morph %d -> %d\n", i, n);
                gGammaTable[i] = SkToU8(n);
            }
            gInit = true;
        }
    }
#else
    #define ApplyGamma(table, alpha)    SkToU8(alpha)
#endif

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

static void call_hline_blitter(SkBlitter* blitter, int x, int y, int count,
                               U8CPU alpha) {
    SkASSERT(count > 0);

    int16_t runs[HLINE_STACK_BUFFER + 1];
    uint8_t  aa[HLINE_STACK_BUFFER];

    aa[0] = ApplyGamma(gGammaTable, alpha);
    do {
        int n = count;
        if (n > HLINE_STACK_BUFFER) {
            n = HLINE_STACK_BUFFER;
        }
        runs[0] = SkToS16(n);
        runs[n] = 0;
        blitter->blitAntiH(x, y, aa, runs);
        x += n;
        count -= n;
    } while (count > 0);
}

class SkAntiHairBlitter {
public:
    SkAntiHairBlitter() : fBlitter(nullptr) {}
    virtual ~SkAntiHairBlitter() {}

    SkBlitter* getBlitter() const { return fBlitter; }

    void setup(SkBlitter* blitter) {
        fBlitter = blitter;
    }

    virtual SkFixed drawCap(int x, SkFixed fy, SkFixed slope, int mod64) = 0;
    virtual SkFixed drawLine(int x, int stopx, SkFixed fy, SkFixed slope) = 0;

private:
    SkBlitter*  fBlitter;
};

class HLine_SkAntiHairBlitter : public SkAntiHairBlitter {
public:
    SkFixed drawCap(int x, SkFixed fy, SkFixed slope, int mod64) override {
        fy += SK_Fixed1/2;

        int y = fy >> 16;
        uint8_t  a = (uint8_t)((fy >> 8) & 0xFF);

        // lower line
        unsigned ma = SmallDot6Scale(a, mod64);
        if (ma) {
            call_hline_blitter(this->getBlitter(), x, y, 1, ma);
        }

        // upper line
        ma = SmallDot6Scale(255 - a, mod64);
        if (ma) {
            call_hline_blitter(this->getBlitter(), x, y - 1, 1, ma);
        }

        return fy - SK_Fixed1/2;
    }

    virtual SkFixed drawLine(int x, int stopx, SkFixed fy,
                             SkFixed slope) override {
        SkASSERT(x < stopx);
        int count = stopx - x;
        fy += SK_Fixed1/2;

        int y = fy >> 16;
        uint8_t  a = (uint8_t)((fy >> 8) & 0xFF);

        // lower line
        if (a) {
            call_hline_blitter(this->getBlitter(), x, y, count, a);
        }

        // upper line
        a = 255 - a;
        if (a) {
            call_hline_blitter(this->getBlitter(), x, y - 1, count, a);
        }

        return fy - SK_Fixed1/2;
    }
};

class Horish_SkAntiHairBlitter : public SkAntiHairBlitter {
public:
    SkFixed drawCap(int x, SkFixed fy, SkFixed dy, int mod64) override {
        fy += SK_Fixed1/2;

        int lower_y = fy >> 16;
        uint8_t  a = (uint8_t)((fy >> 8) & 0xFF);
        unsigned a0 = SmallDot6Scale(255 - a, mod64);
        unsigned a1 = SmallDot6Scale(a, mod64);
        this->getBlitter()->blitAntiV2(x, lower_y - 1, a0, a1);

        return fy + dy - SK_Fixed1/2;
    }

    SkFixed drawLine(int x, int stopx, SkFixed fy, SkFixed dy) override {
        SkASSERT(x < stopx);

        fy += SK_Fixed1/2;
        SkBlitter* blitter = this->getBlitter();
        do {
            int lower_y = fy >> 16;
            uint8_t  a = (uint8_t)((fy >> 8) & 0xFF);
            blitter->blitAntiV2(x, lower_y - 1, 255 - a, a);
            fy += dy;
        } while (++x < stopx);

        return fy - SK_Fixed1/2;
    }
};

class VLine_SkAntiHairBlitter : public SkAntiHairBlitter {
public:
    SkFixed drawCap(int y, SkFixed fx, SkFixed dx, int mod64) override {
        SkASSERT(0 == dx);
        fx += SK_Fixed1/2;

        int x = fx >> 16;
        int a = (uint8_t)((fx >> 8) & 0xFF);

        unsigned ma = SmallDot6Scale(a, mod64);
        if (ma) {
            this->getBlitter()->blitV(x, y, 1, ma);
        }
        ma = SmallDot6Scale(255 - a, mod64);
        if (ma) {
            this->getBlitter()->blitV(x - 1, y, 1, ma);
        }

        return fx - SK_Fixed1/2;
    }

    SkFixed drawLine(int y, int stopy, SkFixed fx, SkFixed dx) override {
        SkASSERT(y < stopy);
        SkASSERT(0 == dx);
        fx += SK_Fixed1/2;

        int x = fx >> 16;
        int a = (uint8_t)((fx >> 8) & 0xFF);

        if (a) {
            this->getBlitter()->blitV(x, y, stopy - y, a);
        }
        a = 255 - a;
        if (a) {
            this->getBlitter()->blitV(x - 1, y, stopy - y, a);
        }

        return fx - SK_Fixed1/2;
    }
};

class Vertish_SkAntiHairBlitter : public SkAntiHairBlitter {
public:
    SkFixed drawCap(int y, SkFixed fx, SkFixed dx, int mod64) override {
        fx += SK_Fixed1/2;

        int x = fx >> 16;
        uint8_t a = (uint8_t)((fx >> 8) & 0xFF);
        this->getBlitter()->blitAntiH2(x - 1, y,
                                       SmallDot6Scale(255 - a, mod64), SmallDot6Scale(a, mod64));

        return fx + dx - SK_Fixed1/2;
    }

    SkFixed drawLine(int y, int stopy, SkFixed fx, SkFixed dx) override {
        SkASSERT(y < stopy);
        fx += SK_Fixed1/2;
        do {
            int x = fx >> 16;
            uint8_t a = (uint8_t)((fx >> 8) & 0xFF);
            this->getBlitter()->blitAntiH2(x - 1, y, 255 - a, a);
            fx += dx;
        } while (++y < stopy);

        return fx - SK_Fixed1/2;
    }
};

static inline SkFixed fastfixdiv(SkFDot6 a, SkFDot6 b) {
    SkASSERT((SkLeftShift(a, 16) >> 16) == a);
    SkASSERT(b != 0);
    return SkLeftShift(a, 16) / b;
}

#define SkBITCOUNT(x)   (sizeof(x) << 3)

#if 1
// returns high-bit set iff x==0x8000...
static inline int bad_int(int x) {
    return x & -x;
}

static int any_bad_ints(int a, int b, int c, int d) {
    return (bad_int(a) | bad_int(b) | bad_int(c) | bad_int(d)) >> (SkBITCOUNT(int) - 1);
}
#else
static inline int good_int(int x) {
    return x ^ (1 << (SkBITCOUNT(x) - 1));
}

static int any_bad_ints(int a, int b, int c, int d) {
    return !(good_int(a) & good_int(b) & good_int(c) & good_int(d));
}
#endif

#ifdef SK_DEBUG
static bool canConvertFDot6ToFixed(SkFDot6 x) {
    const int maxDot6 = SK_MaxS32 >> (16 - 6);
    return SkAbs32(x) <= maxDot6;
}
#endif

/*
 *  We want the fractional part of ordinate, but we want multiples of 64 to
 *  return 64, not 0, so we can't just say (ordinate & 63).
 *  We basically want to compute those bits, and if they're 0, return 64.
 *  We can do that w/o a branch with an extra sub and add.
 */
static int contribution_64(SkFDot6 ordinate) {
#if 0
    int result = ordinate & 63;
    if (0 == result) {
        result = 64;
    }
#else
    int result = ((ordinate - 1) & 63) + 1;
#endif
    SkASSERT(result > 0 && result <= 64);
    return result;
}

static void do_anti_hairline(SkFDot6 x0, SkFDot6 y0, SkFDot6 x1, SkFDot6 y1,
                             const SkIRect* clip, SkBlitter* blitter) {
    // check for integer NaN (0x80000000) which we can't handle (can't negate it)
    // It appears typically from a huge float (inf or nan) being converted to int.
    // If we see it, just don't draw.
    if (any_bad_ints(x0, y0, x1, y1)) {
        return;
    }

    // The caller must clip the line to [-32767.0 ... 32767.0] ahead of time
    // (in dot6 format)
    SkASSERT(canConvertFDot6ToFixed(x0));
    SkASSERT(canConvertFDot6ToFixed(y0));
    SkASSERT(canConvertFDot6ToFixed(x1));
    SkASSERT(canConvertFDot6ToFixed(y1));

    if (SkAbs32(x1 - x0) > SkIntToFDot6(511) || SkAbs32(y1 - y0) > SkIntToFDot6(511)) {
        /*  instead of (x0 + x1) >> 1, we shift each separately. This is less
            precise, but avoids overflowing the intermediate result if the
            values are huge. A better fix might be to clip the original pts
            directly (i.e. do the divide), so we don't spend time subdividing
            huge lines at all.
         */
        int hx = (x0 >> 1) + (x1 >> 1);
        int hy = (y0 >> 1) + (y1 >> 1);
        do_anti_hairline(x0, y0, hx, hy, clip, blitter);
        do_anti_hairline(hx, hy, x1, y1, clip, blitter);
        return;
    }

    int         scaleStart, scaleStop;
    int         istart, istop;
    SkFixed     fstart, slope;

    HLine_SkAntiHairBlitter     hline_blitter;
    Horish_SkAntiHairBlitter    horish_blitter;
    VLine_SkAntiHairBlitter     vline_blitter;
    Vertish_SkAntiHairBlitter   vertish_blitter;
    SkAntiHairBlitter*          hairBlitter = nullptr;

    if (SkAbs32(x1 - x0) > SkAbs32(y1 - y0)) {   // mostly horizontal
        if (x0 > x1) {    // we want to go left-to-right
            using std::swap;
            swap(x0, x1);
            swap(y0, y1);
        }

        istart = SkFDot6Floor(x0);
        istop = SkFDot6Ceil(x1);
        fstart = SkFDot6ToFixed(y0);
        if (y0 == y1) {   // completely horizontal, take fast case
            slope = 0;
            hairBlitter = &hline_blitter;
        } else {
            slope = fastfixdiv(y1 - y0, x1 - x0);
            SkASSERT(slope >= -SK_Fixed1 && slope <= SK_Fixed1);
            fstart += (slope * (32 - (x0 & 63)) + 32) >> 6;
            hairBlitter = &horish_blitter;
        }

        SkASSERT(istop > istart);
        if (istop - istart == 1) {
            // we are within a single pixel
            scaleStart = x1 - x0;
            SkASSERT(scaleStart >= 0 && scaleStart <= 64);
            scaleStop = 0;
        } else {
            scaleStart = 64 - (x0 & 63);
            scaleStop = x1 & 63;
        }

        if (clip){
            if (istart >= clip->fRight || istop <= clip->fLeft) {
                return;
            }
            if (istart < clip->fLeft) {
                fstart += slope * (clip->fLeft - istart);
                istart = clip->fLeft;
                scaleStart = 64;
                if (istop - istart == 1) {
                    // we are within a single pixel
                    scaleStart = contribution_64(x1);
                    scaleStop = 0;
                }
            }
            if (istop > clip->fRight) {
                istop = clip->fRight;
                scaleStop = 0;  // so we don't draw this last column
            }

            SkASSERT(istart <= istop);
            if (istart == istop) {
                return;
            }
            // now test if our Y values are completely inside the clip
            int top, bottom;
            if (slope >= 0) { // T2B
                top = SkFixedFloorToInt(fstart - SK_FixedHalf);
                bottom = SkFixedCeilToInt(fstart + (istop - istart - 1) * slope + SK_FixedHalf);
            } else {           // B2T
                bottom = SkFixedCeilToInt(fstart + SK_FixedHalf);
                top = SkFixedFloorToInt(fstart + (istop - istart - 1) * slope - SK_FixedHalf);
            }
#ifdef OUTSET_BEFORE_CLIP_TEST
            top -= 1;
            bottom += 1;
#endif
            if (top >= clip->fBottom || bottom <= clip->fTop) {
                return;
            }
            if (clip->fTop <= top && clip->fBottom >= bottom) {
                clip = nullptr;
            }
        }
    } else {   // mostly vertical
        if (y0 > y1) {  // we want to go top-to-bottom
            using std::swap;
            swap(x0, x1);
            swap(y0, y1);
        }

        istart = SkFDot6Floor(y0);
        istop = SkFDot6Ceil(y1);
        fstart = SkFDot6ToFixed(x0);
        if (x0 == x1) {
            if (y0 == y1) { // are we zero length?
                return;     // nothing to do
            }
            slope = 0;
            hairBlitter = &vline_blitter;
        } else {
            slope = fastfixdiv(x1 - x0, y1 - y0);
            SkASSERT(slope <= SK_Fixed1 && slope >= -SK_Fixed1);
            fstart += (slope * (32 - (y0 & 63)) + 32) >> 6;
            hairBlitter = &vertish_blitter;
        }

        SkASSERT(istop > istart);
        if (istop - istart == 1) {
            // we are within a single pixel
            scaleStart = y1 - y0;
            SkASSERT(scaleStart >= 0 && scaleStart <= 64);
            scaleStop = 0;
        } else {
            scaleStart = 64 - (y0 & 63);
            scaleStop = y1 & 63;
        }

        if (clip) {
            if (istart >= clip->fBottom || istop <= clip->fTop) {
                return;
            }
            if (istart < clip->fTop) {
                fstart += slope * (clip->fTop - istart);
                istart = clip->fTop;
                scaleStart = 64;
                if (istop - istart == 1) {
                    // we are within a single pixel
                    scaleStart = contribution_64(y1);
                    scaleStop = 0;
                }
            }
            if (istop > clip->fBottom) {
                istop = clip->fBottom;
                scaleStop = 0;  // so we don't draw this last row
            }

            SkASSERT(istart <= istop);
            if (istart == istop)
                return;

            // now test if our X values are completely inside the clip
            int left, right;
            if (slope >= 0) { // L2R
                left = SkFixedFloorToInt(fstart - SK_FixedHalf);
                right = SkFixedCeilToInt(fstart + (istop - istart - 1) * slope + SK_FixedHalf);
            } else {           // R2L
                right = SkFixedCeilToInt(fstart + SK_FixedHalf);
                left = SkFixedFloorToInt(fstart + (istop - istart - 1) * slope - SK_FixedHalf);
            }
#ifdef OUTSET_BEFORE_CLIP_TEST
            left -= 1;
            right += 1;
#endif
            if (left >= clip->fRight || right <= clip->fLeft) {
                return;
            }
            if (clip->fLeft <= left && clip->fRight >= right) {
                clip = nullptr;
            }
        }
    }

    SkRectClipBlitter   rectClipper;
    if (clip) {
        rectClipper.init(blitter, *clip);
        blitter = &rectClipper;
    }

    SkASSERT(hairBlitter);
    hairBlitter->setup(blitter);

#ifdef SK_DEBUG
    if (scaleStart > 0 && scaleStop > 0) {
        // be sure we don't draw twice in the same pixel
        SkASSERT(istart < istop - 1);
    }
#endif

    fstart = hairBlitter->drawCap(istart, fstart, slope, scaleStart);
    istart += 1;
    int fullSpans = istop - istart - (scaleStop > 0);
    if (fullSpans > 0) {
        fstart = hairBlitter->drawLine(istart, istart + fullSpans, fstart, slope);
    }
    if (scaleStop > 0) {
        hairBlitter->drawCap(istop - 1, fstart, slope, scaleStop);
    }
}

void SkScan::AntiHairLineRgn(const SkPoint array[], int arrayCount, const SkRegion* clip,
                             SkBlitter* blitter) {
    if (clip && clip->isEmpty()) {
        return;
    }

    SkASSERT(clip == nullptr || !clip->getBounds().isEmpty());

#ifdef TEST_GAMMA
    build_gamma_table();
#endif

    const SkScalar max = SkIntToScalar(32767);
    const SkRect fixedBounds = SkRect::MakeLTRB(-max, -max, max, max);

    SkRect clipBounds;
    if (clip) {
        clipBounds.set(clip->getBounds());
        /*  We perform integral clipping later on, but we do a scalar clip first
         to ensure that our coordinates are expressible in fixed/integers.

         antialiased hairlines can draw up to 1/2 of a pixel outside of
         their bounds, so we need to outset the clip before calling the
         clipper. To make the numerics safer, we outset by a whole pixel,
         since the 1/2 pixel boundary is important to the antihair blitter,
         we don't want to risk numerical fate by chopping on that edge.
         */
        clipBounds.outset(SK_Scalar1, SK_Scalar1);
    }

    for (int i = 0; i < arrayCount - 1; ++i) {
        SkPoint pts[2];

        // We have to pre-clip the line to fit in a SkFixed, so we just chop
        // the line. TODO find a way to actually draw beyond that range.
        if (!SkLineClipper::IntersectLine(&array[i], fixedBounds, pts)) {
            continue;
        }

        if (clip && !SkLineClipper::IntersectLine(pts, clipBounds, pts)) {
            continue;
        }

        SkFDot6 x0 = SkScalarToFDot6(pts[0].fX);
        SkFDot6 y0 = SkScalarToFDot6(pts[0].fY);
        SkFDot6 x1 = SkScalarToFDot6(pts[1].fX);
        SkFDot6 y1 = SkScalarToFDot6(pts[1].fY);

        if (clip) {
            SkFDot6 left = SkMin32(x0, x1);
            SkFDot6 top = SkMin32(y0, y1);
            SkFDot6 right = SkMax32(x0, x1);
            SkFDot6 bottom = SkMax32(y0, y1);
            SkIRect ir;

            ir.set( SkFDot6Floor(left) - 1,
                    SkFDot6Floor(top) - 1,
                    SkFDot6Ceil(right) + 1,
                    SkFDot6Ceil(bottom) + 1);

            if (clip->quickReject(ir)) {
                continue;
            }
            if (!clip->quickContains(ir)) {
                SkRegion::Cliperator iter(*clip, ir);
                const SkIRect*       r = &iter.rect();

                while (!iter.done()) {
                    do_anti_hairline(x0, y0, x1, y1, r, blitter);
                    iter.next();
                }
                continue;
            }
            // fall through to no-clip case
        }
        do_anti_hairline(x0, y0, x1, y1, nullptr, blitter);
    }
}

void SkScan::AntiHairRect(const SkRect& rect, const SkRasterClip& clip,
                          SkBlitter* blitter) {
    SkPoint pts[5];

    pts[0].set(rect.fLeft, rect.fTop);
    pts[1].set(rect.fRight, rect.fTop);
    pts[2].set(rect.fRight, rect.fBottom);
    pts[3].set(rect.fLeft, rect.fBottom);
    pts[4] = pts[0];
    SkScan::AntiHairLine(pts, 5, clip, blitter);
}

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

typedef int FDot8;  // 24.8 integer fixed point

static inline FDot8 SkFixedToFDot8(SkFixed x) {
    return (x + 0x80) >> 8;
}

static void do_scanline(FDot8 L, int top, FDot8 R, U8CPU alpha,
                        SkBlitter* blitter) {
    SkASSERT(L < R);

    if ((L >> 8) == ((R - 1) >> 8)) {  // 1x1 pixel
        blitter->blitV(L >> 8, top, 1, SkAlphaMul(alpha, R - L));
        return;
    }

    int left = L >> 8;

    if (L & 0xFF) {
        blitter->blitV(left, top, 1, SkAlphaMul(alpha, 256 - (L & 0xFF)));
        left += 1;
    }

    int rite = R >> 8;
    int width = rite - left;
    if (width > 0) {
        call_hline_blitter(blitter, left, top, width, alpha);
    }
    if (R & 0xFF) {
        blitter->blitV(rite, top, 1, SkAlphaMul(alpha, R & 0xFF));
    }
}

static void antifilldot8(FDot8 L, FDot8 T, FDot8 R, FDot8 B, SkBlitter* blitter,
                         bool fillInner) {
    // check for empty now that we're in our reduced precision space
    if (L >= R || T >= B) {
        return;
    }
    int top = T >> 8;
    if (top == ((B - 1) >> 8)) {   // just one scanline high
        do_scanline(L, top, R, B - T - 1, blitter);
        return;
    }

    if (T & 0xFF) {
        do_scanline(L, top, R, 256 - (T & 0xFF), blitter);
        top += 1;
    }

    int bot = B >> 8;
    int height = bot - top;
    if (height > 0) {
        int left = L >> 8;
        if (left == ((R - 1) >> 8)) {   // just 1-pixel wide
            blitter->blitV(left, top, height, R - L - 1);
        } else {
            if (L & 0xFF) {
                blitter->blitV(left, top, height, 256 - (L & 0xFF));
                left += 1;
            }
            int rite = R >> 8;
            int width = rite - left;
            if (width > 0 && fillInner) {
                blitter->blitRect(left, top, width, height);
            }
            if (R & 0xFF) {
                blitter->blitV(rite, top, height, R & 0xFF);
            }
        }
    }

    if (B & 0xFF) {
        do_scanline(L, bot, R, B & 0xFF, blitter);
    }
}

static void antifillrect(const SkXRect& xr, SkBlitter* blitter) {
    antifilldot8(SkFixedToFDot8(xr.fLeft), SkFixedToFDot8(xr.fTop),
                 SkFixedToFDot8(xr.fRight), SkFixedToFDot8(xr.fBottom),
                 blitter, true);
}

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

void SkScan::AntiFillXRect(const SkXRect& xr, const SkRegion* clip,
                          SkBlitter* blitter) {
    if (nullptr == clip) {
        antifillrect(xr, blitter);
    } else {
        SkIRect outerBounds;
        XRect_roundOut(xr, &outerBounds);

        if (clip->isRect()) {
            const SkIRect& clipBounds = clip->getBounds();

            if (clipBounds.contains(outerBounds)) {
                antifillrect(xr, blitter);
            } else {
                SkXRect tmpR;
                // this keeps our original edges fractional
                XRect_set(&tmpR, clipBounds);
                if (tmpR.intersect(xr)) {
                    antifillrect(tmpR, blitter);
                }
            }
        } else {
            SkRegion::Cliperator clipper(*clip, outerBounds);
            const SkIRect&       rr = clipper.rect();

            while (!clipper.done()) {
                SkXRect  tmpR;

                // this keeps our original edges fractional
                XRect_set(&tmpR, rr);
                if (tmpR.intersect(xr)) {
                    antifillrect(tmpR, blitter);
                }
                clipper.next();
            }
        }
    }
}

void SkScan::AntiFillXRect(const SkXRect& xr, const SkRasterClip& clip,
                           SkBlitter* blitter) {
    if (clip.isBW()) {
        AntiFillXRect(xr, &clip.bwRgn(), blitter);
    } else {
        SkIRect outerBounds;
        XRect_roundOut(xr, &outerBounds);

        if (clip.quickContains(outerBounds)) {
            AntiFillXRect(xr, nullptr, blitter);
        } else {
            SkAAClipBlitterWrapper wrapper(clip, blitter);
            AntiFillXRect(xr, &wrapper.getRgn(), wrapper.getBlitter());
        }
    }
}

/*  This guy takes a float-rect, but with the key improvement that it has
    already been clipped, so we know that it is safe to convert it into a
    XRect (fixedpoint), as it won't overflow.
*/
static void antifillrect(const SkRect& r, SkBlitter* blitter) {
    SkXRect xr;

    XRect_set(&xr, r);
    antifillrect(xr, blitter);
}

/*  We repeat the clipping logic of AntiFillXRect because the float rect might
    overflow if we blindly converted it to an XRect. This sucks that we have to
    repeat the clipping logic, but I don't see how to share the code/logic.

    We clip r (as needed) into one or more (smaller) float rects, and then pass
    those to our version of antifillrect, which converts it into an XRect and
    then calls the blit.
*/
void SkScan::AntiFillRect(const SkRect& origR, const SkRegion* clip,
                          SkBlitter* blitter) {
    if (clip) {
        SkRect newR;
        newR.set(clip->getBounds());
        if (!newR.intersect(origR)) {
            return;
        }

        const SkIRect outerBounds = newR.roundOut();

        if (clip->isRect()) {
            antifillrect(newR, blitter);
        } else {
            SkRegion::Cliperator clipper(*clip, outerBounds);
            while (!clipper.done()) {
                newR.set(clipper.rect());
                if (newR.intersect(origR)) {
                    antifillrect(newR, blitter);
                }
                clipper.next();
            }
        }
    } else {
        antifillrect(origR, blitter);
    }
}

void SkScan::AntiFillRect(const SkRect& r, const SkRasterClip& clip,
                          SkBlitter* blitter) {
    if (clip.isBW()) {
        AntiFillRect(r, &clip.bwRgn(), blitter);
    } else {
        SkAAClipBlitterWrapper wrap(clip, blitter);
        AntiFillRect(r, &wrap.getRgn(), wrap.getBlitter());
    }
}

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

#define SkAlphaMulRound(a, b)   SkMulDiv255Round(a, b)

// calls blitRect() if the rectangle is non-empty
static void fillcheckrect(int L, int T, int R, int B, SkBlitter* blitter) {
    if (L < R && T < B) {
        blitter->blitRect(L, T, R - L, B - T);
    }
}

static inline FDot8 SkScalarToFDot8(SkScalar x) {
    return (int)(x * 256);
}

static inline int FDot8Floor(FDot8 x) {
    return x >> 8;
}

static inline int FDot8Ceil(FDot8 x) {
    return (x + 0xFF) >> 8;
}

// 1 - (1 - a)*(1 - b)
static inline U8CPU InvAlphaMul(U8CPU a, U8CPU b) {
    // need precise rounding (not just SkAlphaMul) so that values like
    // a=228, b=252 don't overflow the result
    return SkToU8(a + b - SkAlphaMulRound(a, b));
}

static void inner_scanline(FDot8 L, int top, FDot8 R, U8CPU alpha,
                           SkBlitter* blitter) {
    SkASSERT(L < R);

    if ((L >> 8) == ((R - 1) >> 8)) {  // 1x1 pixel
        FDot8 widClamp = R - L;
        // border case clamp 256 to 255 instead of going through call_hline_blitter
        // see skbug/4406
        widClamp = widClamp - (widClamp >> 8);
        blitter->blitV(L >> 8, top, 1, InvAlphaMul(alpha, widClamp));
        return;
    }

    int left = L >> 8;
    if (L & 0xFF) {
        blitter->blitV(left, top, 1, InvAlphaMul(alpha, L & 0xFF));
        left += 1;
    }

    int rite = R >> 8;
    int width = rite - left;
    if (width > 0) {
        call_hline_blitter(blitter, left, top, width, alpha);
    }

    if (R & 0xFF) {
        blitter->blitV(rite, top, 1, InvAlphaMul(alpha, ~R & 0xFF));
    }
}

static void innerstrokedot8(FDot8 L, FDot8 T, FDot8 R, FDot8 B,
                            SkBlitter* blitter) {
    SkASSERT(L < R && T < B);

    int top = T >> 8;
    if (top == ((B - 1) >> 8)) {   // just one scanline high
        // We want the inverse of B-T, since we're the inner-stroke
        int alpha = 256 - (B - T);
        if (alpha) {
            inner_scanline(L, top, R, alpha, blitter);
        }
        return;
    }

    if (T & 0xFF) {
        inner_scanline(L, top, R, T & 0xFF, blitter);
        top += 1;
    }

    int bot = B >> 8;
    int height = bot - top;
    if (height > 0) {
        if (L & 0xFF) {
            blitter->blitV(L >> 8, top, height, L & 0xFF);
        }
        if (R & 0xFF) {
            blitter->blitV(R >> 8, top, height, ~R & 0xFF);
        }
    }

    if (B & 0xFF) {
        inner_scanline(L, bot, R, ~B & 0xFF, blitter);
    }
}

static inline void align_thin_stroke(FDot8& edge1, FDot8& edge2) {
    SkASSERT(edge1 <= edge2);

    if (FDot8Floor(edge1) == FDot8Floor(edge2)) {
        edge2 -= (edge1 & 0xFF);
        edge1 &= ~0xFF;
    }
}

void SkScan::AntiFrameRect(const SkRect& r, const SkPoint& strokeSize,
                           const SkRegion* clip, SkBlitter* blitter) {
    SkASSERT(strokeSize.fX >= 0 && strokeSize.fY >= 0);

    SkScalar rx = SkScalarHalf(strokeSize.fX);
    SkScalar ry = SkScalarHalf(strokeSize.fY);

    // outset by the radius
    FDot8 outerL = SkScalarToFDot8(r.fLeft - rx);
    FDot8 outerT = SkScalarToFDot8(r.fTop - ry);
    FDot8 outerR = SkScalarToFDot8(r.fRight + rx);
    FDot8 outerB = SkScalarToFDot8(r.fBottom + ry);

    SkIRect outer;
    // set outer to the outer rect of the outer section
    outer.set(FDot8Floor(outerL), FDot8Floor(outerT), FDot8Ceil(outerR), FDot8Ceil(outerB));

    SkBlitterClipper clipper;
    if (clip) {
        if (clip->quickReject(outer)) {
            return;
        }
        if (!clip->contains(outer)) {
            blitter = clipper.apply(blitter, clip, &outer);
        }
        // now we can ignore clip for the rest of the function
    }

    // in case we lost a bit with diameter/2
    rx = strokeSize.fX - rx;
    ry = strokeSize.fY - ry;

    // inset by the radius
    FDot8 innerL = SkScalarToFDot8(r.fLeft + rx);
    FDot8 innerT = SkScalarToFDot8(r.fTop + ry);
    FDot8 innerR = SkScalarToFDot8(r.fRight - rx);
    FDot8 innerB = SkScalarToFDot8(r.fBottom - ry);

    // For sub-unit strokes, tweak the hulls such that one of the edges coincides with the pixel
    // edge. This ensures that the general rect stroking logic below
    //   a) doesn't blit the same scanline twice
    //   b) computes the correct coverage when both edges fall within the same pixel
    if (strokeSize.fX < 1 || strokeSize.fY < 1) {
        align_thin_stroke(outerL, innerL);
        align_thin_stroke(outerT, innerT);
        align_thin_stroke(innerR, outerR);
        align_thin_stroke(innerB, outerB);
    }

    // stroke the outer hull
    antifilldot8(outerL, outerT, outerR, outerB, blitter, false);

    // set outer to the outer rect of the middle section
    outer.set(FDot8Ceil(outerL), FDot8Ceil(outerT), FDot8Floor(outerR), FDot8Floor(outerB));

    if (innerL >= innerR || innerT >= innerB) {
        fillcheckrect(outer.fLeft, outer.fTop, outer.fRight, outer.fBottom,
                      blitter);
    } else {
        SkIRect inner;
        // set inner to the inner rect of the middle section
        inner.set(FDot8Floor(innerL), FDot8Floor(innerT), FDot8Ceil(innerR), FDot8Ceil(innerB));

        // draw the frame in 4 pieces
        fillcheckrect(outer.fLeft, outer.fTop, outer.fRight, inner.fTop,
                      blitter);
        fillcheckrect(outer.fLeft, inner.fTop, inner.fLeft, inner.fBottom,
                      blitter);
        fillcheckrect(inner.fRight, inner.fTop, outer.fRight, inner.fBottom,
                      blitter);
        fillcheckrect(outer.fLeft, inner.fBottom, outer.fRight, outer.fBottom,
                      blitter);

        // now stroke the inner rect, which is similar to antifilldot8() except that
        // it treats the fractional coordinates with the inverse bias (since its
        // inner).
        innerstrokedot8(innerL, innerT, innerR, innerB, blitter);
    }
}

void SkScan::AntiFrameRect(const SkRect& r, const SkPoint& strokeSize,
                           const SkRasterClip& clip, SkBlitter* blitter) {
    if (clip.isBW()) {
        AntiFrameRect(r, strokeSize, &clip.bwRgn(), blitter);
    } else {
        SkAAClipBlitterWrapper wrap(clip, blitter);
        AntiFrameRect(r, strokeSize, &wrap.getRgn(), wrap.getBlitter());
    }
}
