/* libs/graphics/sgl/SkScan_Path.cpp
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License"); 
** you may not use this file except in compliance with the License. 
** You may obtain a copy of the License at 
**
**     http://www.apache.org/licenses/LICENSE-2.0 
**
** Unless required by applicable law or agreed to in writing, software 
** distributed under the License is distributed on an "AS IS" BASIS, 
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
** See the License for the specific language governing permissions and 
** limitations under the License.
*/

#include "SkScanPriv.h"
#include "SkBlitter.h"
#include "SkEdge.h"
#include "SkGeometry.h"
#include "SkPath.h"
#include "SkQuadClipper.h"
#include "SkRegion.h"
#include "SkTemplates.h"

#define USE_NEW_BUILDER

#define kEDGE_HEAD_Y    SK_MinS32
#define kEDGE_TAIL_Y    SK_MaxS32

#ifdef SK_DEBUG
    static void validate_sort(const SkEdge* edge)
    {
        int y = kEDGE_HEAD_Y;

        while (edge->fFirstY != SK_MaxS32)
        {
            edge->validate();
            SkASSERT(y <= edge->fFirstY);

            y = edge->fFirstY;
            edge = edge->fNext;
        }
    }
#else
    #define validate_sort(edge)
#endif

static inline void remove_edge(SkEdge* edge)
{
    edge->fPrev->fNext = edge->fNext;
    edge->fNext->fPrev = edge->fPrev;
}

static inline void swap_edges(SkEdge* prev, SkEdge* next)
{
    SkASSERT(prev->fNext == next && next->fPrev == prev);

    // remove prev from the list
    prev->fPrev->fNext = next;
    next->fPrev = prev->fPrev;

    // insert prev after next
    prev->fNext = next->fNext;
    next->fNext->fPrev = prev;
    next->fNext = prev;
    prev->fPrev = next;
}

static void backward_insert_edge_based_on_x(SkEdge* edge SkDECLAREPARAM(int, curr_y))
{
    SkFixed x = edge->fX;

    for (;;)
    {
        SkEdge* prev = edge->fPrev;
        
        // add 1 to curr_y since we may have added new edges (built from curves)
        // that start on the next scanline
        SkASSERT(prev && prev->fFirstY <= curr_y + 1);

        if (prev->fX <= x)
            break;

        swap_edges(prev, edge);
    }
}

static void insert_new_edges(SkEdge* newEdge, int curr_y)
{
    SkASSERT(newEdge->fFirstY >= curr_y);

    while (newEdge->fFirstY == curr_y)
    {
        SkEdge* next = newEdge->fNext;
        backward_insert_edge_based_on_x(newEdge  SkPARAM(curr_y));
        newEdge = next;
    }
}

#ifdef SK_DEBUG
static void validate_edges_for_y(const SkEdge* edge, int curr_y)
{
    while (edge->fFirstY <= curr_y)
    {
        SkASSERT(edge->fPrev && edge->fNext);
        SkASSERT(edge->fPrev->fNext == edge);
        SkASSERT(edge->fNext->fPrev == edge);
        SkASSERT(edge->fFirstY <= edge->fLastY);

        SkASSERT(edge->fPrev->fX <= edge->fX);
        edge = edge->fNext;
    }
}
#else
    #define validate_edges_for_y(edge, curr_y)
#endif

#if defined _WIN32 && _MSC_VER >= 1300  // disable warning : local variable used without having been initialized
#pragma warning ( push )
#pragma warning ( disable : 4701 )
#endif

typedef void (*PrePostProc)(SkBlitter* blitter, int y, bool isStartOfScanline);
#define PREPOST_START   true
#define PREPOST_END     false

static void walk_edges(SkEdge* prevHead, SkPath::FillType fillType,
                       SkBlitter* blitter, int start_y, int stop_y,
                       PrePostProc proc)
{
    validate_sort(prevHead->fNext);

    int curr_y = start_y;
    // returns 1 for evenodd, -1 for winding, regardless of inverse-ness
    int windingMask = (fillType & 1) ? 1 : -1;

    for (;;)
    {
        int     w = 0;
        int     left SK_INIT_TO_AVOID_WARNING;
        bool    in_interval = false;
        SkEdge* currE = prevHead->fNext;
        SkFixed prevX = prevHead->fX;

        validate_edges_for_y(currE, curr_y);
        
        if (proc) {
            proc(blitter, curr_y, PREPOST_START);    // pre-proc
        }
        
        while (currE->fFirstY <= curr_y)
        {
            SkASSERT(currE->fLastY >= curr_y);

            int x = (currE->fX + SK_Fixed1/2) >> 16;
            w += currE->fWinding;
            if ((w & windingMask) == 0) // we finished an interval
            {
                SkASSERT(in_interval);
                int width = x - left;
                SkASSERT(width >= 0);
                if (width)
                    blitter->blitH(left, curr_y, width);
                in_interval = false;
            }
            else if (!in_interval)
            {
                left = x;
                in_interval = true;
            }

            SkEdge* next = currE->fNext;
            SkFixed newX;

            if (currE->fLastY == curr_y)    // are we done with this edge?
            {
                if (currE->fCurveCount < 0)
                {
                    if (((SkCubicEdge*)currE)->updateCubic())
                    {
                        SkASSERT(currE->fFirstY == curr_y + 1);
                        
                        newX = currE->fX;
                        goto NEXT_X;
                    }
                }
                else if (currE->fCurveCount > 0)
                {
                    if (((SkQuadraticEdge*)currE)->updateQuadratic())
                    {
                        newX = currE->fX;
                        goto NEXT_X;
                    }
                }
                remove_edge(currE);
            }
            else
            {
                SkASSERT(currE->fLastY > curr_y);
                newX = currE->fX + currE->fDX;
                currE->fX = newX;
            NEXT_X:
                if (newX < prevX)   // ripple currE backwards until it is x-sorted
                    backward_insert_edge_based_on_x(currE  SkPARAM(curr_y));
                else
                    prevX = newX;
            }
            currE = next;
            SkASSERT(currE);
        }
        
        if (proc) {
            proc(blitter, curr_y, PREPOST_END);    // post-proc
        }

        curr_y += 1;
        if (curr_y >= stop_y)
            break;

        // now currE points to the first edge with a Yint larger than curr_y
        insert_new_edges(currE, curr_y);
    }
}

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

// this guy overrides blitH, and will call its proxy blitter with the inverse
// of the spans it is given (clipped to the left/right of the cliprect)
//
// used to implement inverse filltypes on paths
//
class InverseBlitter : public SkBlitter {
public:
    void setBlitter(SkBlitter* blitter, const SkIRect& clip, int shift) {
        fBlitter = blitter;
        fFirstX = clip.fLeft << shift;
        fLastX = clip.fRight << shift;
    }
    void prepost(int y, bool isStart) {
        if (isStart) {
            fPrevX = fFirstX;
        } else {
            int invWidth = fLastX - fPrevX;
            if (invWidth > 0) {
                fBlitter->blitH(fPrevX, y, invWidth);
            }
        }
    }

    // overrides
    virtual void blitH(int x, int y, int width) {
        int invWidth = x - fPrevX;
        if (invWidth > 0) {
            fBlitter->blitH(fPrevX, y, invWidth);
        }
        fPrevX = x + width;
    }
    
    // we do not expect to get called with these entrypoints
    virtual void blitAntiH(int, int, const SkAlpha[], const int16_t runs[]) {
        SkASSERT(!"blitAntiH unexpected");
    }
    virtual void blitV(int x, int y, int height, SkAlpha alpha) {
        SkASSERT(!"blitV unexpected");
    }
    virtual void blitRect(int x, int y, int width, int height) {
        SkASSERT(!"blitRect unexpected");
    }
    virtual void blitMask(const SkMask&, const SkIRect& clip) {
        SkASSERT(!"blitMask unexpected");
    }
    virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) {
        SkASSERT(!"justAnOpaqueColor unexpected");
        return NULL;
    }
    
private:
    SkBlitter*  fBlitter;
    int         fFirstX, fLastX, fPrevX;
};

static void PrePostInverseBlitterProc(SkBlitter* blitter, int y, bool isStart) {
    ((InverseBlitter*)blitter)->prepost(y, isStart);
}

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

#if defined _WIN32 && _MSC_VER >= 1300
#pragma warning ( pop )
#endif

/*  Our line edge relies on the maximum span being <= 512, so that it can
    use FDot6 and keep the dx,dy in 16bits (for much faster slope divide).
    This function returns true if the specified line is too big.
*/
static inline bool line_too_big(const SkPoint pts[2])
{
    SkScalar dx = pts[1].fX - pts[0].fX;
    SkScalar dy = pts[1].fY - pts[0].fY;

    return  SkScalarAbs(dx) > SkIntToScalar(511) ||
            SkScalarAbs(dy) > SkIntToScalar(511);
}

#ifdef USE_NEW_BUILDER
#include "SkEdgeBuilder.h"
#else
static int build_edges(SkEdge edge[], const SkPath& path,
                       const SkIRect* clipRect, SkEdge* list[], int shiftUp) {
    SkEdge**        start = list;
    SkPath::Iter    iter(path, true);
    SkPoint         pts[4];
    SkPath::Verb    verb;
    
    SkQuadClipper qclipper;
    if (clipRect) {
        SkIRect r;
        r.set(clipRect->fLeft >> shiftUp, clipRect->fTop >> shiftUp,
              clipRect->fRight >> shiftUp, clipRect->fBottom >> shiftUp);
        qclipper.setClip(r);
    }

    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
        switch (verb) {
            case SkPath::kLine_Verb:
                if (edge->setLine(pts[0], pts[1], clipRect, shiftUp)) {
                    *list++ = edge;
                    edge = (SkEdge*)((char*)edge + sizeof(SkEdge));
                }
                break;
            case SkPath::kQuad_Verb: {
                SkPoint tmp[5], clippedPts[3];
                SkPoint* p = tmp;
                int     count = SkChopQuadAtYExtrema(pts, tmp);

                do {
                    const SkPoint* qpts = p;
                    if (clipRect) {
                        if (!qclipper.clipQuad(p, clippedPts)) {
                            goto NEXT_CHOPPED_QUAD;
                        }
                        qpts = clippedPts;
                    }
                    if (((SkQuadraticEdge*)edge)->setQuadratic(qpts, shiftUp)) {
                        *list++ = edge;
                        edge = (SkEdge*)((char*)edge + sizeof(SkQuadraticEdge));
                    }
                NEXT_CHOPPED_QUAD:
                    p += 2;
                } while (--count >= 0);
                break;
            }
            case SkPath::kCubic_Verb: {
                SkPoint tmp[10];
                SkPoint* p = tmp;
                int     count = SkChopCubicAtYExtrema(pts, tmp);                
                SkASSERT(count >= 0 && count <= 2);

                do {
                    if (((SkCubicEdge*)edge)->setCubic(p, clipRect, shiftUp))
                    {
                        *list++ = edge;
                        edge = (SkEdge*)((char*)edge + sizeof(SkCubicEdge));
                    }
                    p += 3;
                } while (--count >= 0);
                break;
            }
        default:
            break;
        }
    }
    return (int)(list - start);
}

#ifdef SK_DEBUG
/* 'quick' computation of the max sized needed to allocated for
    our edgelist.
*/
static int worst_case_edge_count(const SkPath& path, size_t* storage)
{
    size_t  size = 0;
    int     edgeCount = 0;

    SkPath::Iter    iter(path, true);
    SkPath::Verb    verb;

    while ((verb = iter.next(NULL)) != SkPath::kDone_Verb)
    {
        switch (verb) {
        case SkPath::kLine_Verb:
            edgeCount += 1;
            size += sizeof(SkQuadraticEdge);    // treat line like Quad (in case its > 512)
            break;
        case SkPath::kQuad_Verb:
            edgeCount += 2;                     // might need 2 edges when we chop on Y extrema
            size += 2 * sizeof(SkQuadraticEdge);
            break;
        case SkPath::kCubic_Verb:
            edgeCount += 3;                     // might need 3 edges when we chop on Y extrema
            size += 3 * sizeof(SkCubicEdge);
            break;
        default:
            break;
        }
    }

    SkASSERT(storage);
    *storage = size;
    return edgeCount;
}
#endif

/* Much faster than worst_case_edge_count, but over estimates even more
*/
static int cheap_worst_case_edge_count(const SkPath& path, size_t* storage) {
    int ptCount = path.getPoints(NULL, 0);
    // worst case is curve, close, curve, close, as that is 
    //     2 lines per pt, or             : pts * 2
    //     2 quads + 1 line per 2 pts, or : pts * 3 / 2
    //     3 cubics + 1 line per 3 pts    : pts * 4 / 3
    int edgeCount = ptCount << 1;
    // worst storage, due to relative size of different edge types, is
    // quads * 3 / 2
    size_t quadSize = (ptCount * 3 >> 1) * sizeof(SkQuadraticEdge);
#if 0
    size_t lineSize = (ptCount << 1) * sizeof(SkEdge);
    size_t cubicSize = (ptCount * 3 / 4) * sizeof(SkCubicEdge);
    SkASSERT(lineSize <= quadSize);
    SkASSERT(cubicSize <= quadSize);
#endif
    *storage = quadSize;
    return edgeCount;
}
#endif

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

extern "C" {
    static int edge_compare(const void* a, const void* b) {
        const SkEdge* edgea = *(const SkEdge**)a;
        const SkEdge* edgeb = *(const SkEdge**)b;
        
        int valuea = edgea->fFirstY;
        int valueb = edgeb->fFirstY;
        
        if (valuea == valueb) {
            valuea = edgea->fX;
            valueb = edgeb->fX;
        }
        
        // this overflows if valuea >>> valueb or vice-versa
        //     return valuea - valueb;
        // do perform the slower but safe compares
        return (valuea < valueb) ? -1 : (valuea > valueb);
    }
}

static SkEdge* sort_edges(SkEdge* list[], int count, SkEdge** last) {
    qsort(list, count, sizeof(SkEdge*), edge_compare);
    
    // now make the edges linked in sorted order
    for (int i = 1; i < count; i++) {
        list[i - 1]->fNext = list[i];
        list[i]->fPrev = list[i - 1];
    }
    
    *last = list[count - 1];
    return list[0];
}

// clipRect may be null, even though we always have a clip. This indicates that
// the path is contained in the clip, and so we can ignore it during the blit
//
// clipRect (if no null) has already been shifted up
//
void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitter,
                  int start_y, int stop_y, int shiftEdgesUp, const SkRegion& clipRgn)
{
    SkASSERT(&path && blitter);

#ifdef USE_NEW_BUILDER
    SkEdgeBuilder   builder;
    
    int count = builder.build(path, clipRect, shiftEdgesUp);
    SkEdge**    list = builder.edgeList();
#else
    size_t  size;
    int     maxCount = cheap_worst_case_edge_count(path, &size);

#ifdef SK_DEBUG
    {
        size_t  size2;
        int     maxCount2 = worst_case_edge_count(path, &size2);
        
        SkASSERT(maxCount >= maxCount2 && size >= size2);
    }
#endif

    SkAutoMalloc    memory(maxCount * sizeof(SkEdge*) + size);
    SkEdge**        list = (SkEdge**)memory.get();
    SkEdge*         initialEdge = (SkEdge*)(list + maxCount);
    int             count = build_edges(initialEdge, path, clipRect, list,
                                        shiftEdgesUp);
    SkASSERT(count <= maxCount);
#endif

    if (count < 2) {
        if (path.isInverseFillType()) {
            const SkIRect& clipRect = clipRgn.getBounds();
            blitter->blitRect(clipRect.fLeft << shiftEdgesUp,
                              clipRect.fTop << shiftEdgesUp,
                              clipRect.width() << shiftEdgesUp,
                              clipRect.height() << shiftEdgesUp);
        }

        return;
    }

    SkEdge headEdge, tailEdge, *last;
    // this returns the first and last edge after they're sorted into a dlink list
    SkEdge* edge = sort_edges(list, count, &last);

    headEdge.fPrev = NULL;
    headEdge.fNext = edge;
    headEdge.fFirstY = kEDGE_HEAD_Y;
    headEdge.fX = SK_MinS32;
    edge->fPrev = &headEdge;

    tailEdge.fPrev = last;
    tailEdge.fNext = NULL;
    tailEdge.fFirstY = kEDGE_TAIL_Y;
    last->fNext = &tailEdge;

    // now edge is the head of the sorted linklist

    start_y <<= shiftEdgesUp;
    stop_y <<= shiftEdgesUp;
    if (clipRect && start_y < clipRect->fTop) {
        start_y = clipRect->fTop;
    }
    if (clipRect && stop_y > clipRect->fBottom) {
        stop_y = clipRect->fBottom;
    }

    InverseBlitter  ib;
    PrePostProc     proc = NULL;

    if (path.isInverseFillType()) {
        ib.setBlitter(blitter, clipRgn.getBounds(), shiftEdgesUp);
        blitter = &ib;
        proc = PrePostInverseBlitterProc;
    }

    walk_edges(&headEdge, path.getFillType(), blitter, start_y, stop_y, proc);
}

void sk_blit_above_and_below(SkBlitter* blitter, const SkIRect& ir,
                             const SkRegion& clip) {
    const SkIRect& cr = clip.getBounds();
    SkIRect tmp;
    
    tmp.fLeft = cr.fLeft;
    tmp.fRight = cr.fRight;

    tmp.fTop = cr.fTop;
    tmp.fBottom = ir.fTop;
    if (!tmp.isEmpty()) {
        blitter->blitRectRegion(tmp, clip);
    }

    tmp.fTop = ir.fBottom;
    tmp.fBottom = cr.fBottom;
    if (!tmp.isEmpty()) {
        blitter->blitRectRegion(tmp, clip);
    }
}

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

SkScanClipper::SkScanClipper(SkBlitter* blitter, const SkRegion* clip, const SkIRect& ir)
{
    fBlitter = NULL;     // null means blit nothing
    fClipRect = NULL;

    if (clip)
    {
        fClipRect = &clip->getBounds();
        if (!SkIRect::Intersects(*fClipRect, ir))  // completely clipped out
            return;

        if (clip->isRect())
        {
            if (fClipRect->contains(ir))
                fClipRect = NULL;
            else
            {
                // only need a wrapper blitter if we're horizontally clipped
                if (fClipRect->fLeft > ir.fLeft || fClipRect->fRight < ir.fRight)
                {
                    fRectBlitter.init(blitter, *fClipRect);
                    blitter = &fRectBlitter;
                }
            }
        }
        else
        {
            fRgnBlitter.init(blitter, clip);
            blitter = &fRgnBlitter;
        }
    }
    fBlitter = blitter;
}

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

void SkScan::FillPath(const SkPath& path, const SkRegion& clip,
                      SkBlitter* blitter) {
    if (clip.isEmpty()) {
        return;
    }

    SkIRect ir;
    path.getBounds().round(&ir);
    if (ir.isEmpty()) {
        if (path.isInverseFillType()) {
            blitter->blitRegion(clip);
        }
        return;
    }

    SkScanClipper   clipper(blitter, &clip, ir);

    blitter = clipper.getBlitter();
    if (blitter) {
        if (path.isInverseFillType()) {
            sk_blit_above_and_below(blitter, ir, clip);
        }
        sk_fill_path(path, clipper.getClipRect(), blitter, ir.fTop, ir.fBottom, 0, clip);
    } else {
        // what does it mean to not have a blitter if path.isInverseFillType???
    }
}

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

static int build_tri_edges(SkEdge edge[], const SkPoint pts[],
                           const SkIRect* clipRect, SkEdge* list[]) {
    SkEdge** start = list;
    
    if (edge->setLine(pts[0], pts[1], clipRect, 0)) {
        *list++ = edge;
        edge = (SkEdge*)((char*)edge + sizeof(SkEdge));
    }
    if (edge->setLine(pts[1], pts[2], clipRect, 0)) {
        *list++ = edge;
        edge = (SkEdge*)((char*)edge + sizeof(SkEdge));
    }
    if (edge->setLine(pts[2], pts[0], clipRect, 0)) {
        *list++ = edge;
    }
    return (int)(list - start);
}


static void sk_fill_triangle(const SkPoint pts[], const SkIRect* clipRect,
                             SkBlitter* blitter, const SkIRect& ir) {
    SkASSERT(pts && blitter);
    
    SkEdge edgeStorage[3];
    SkEdge* list[3];

    int count = build_tri_edges(edgeStorage, pts, clipRect, list);
    if (count < 2) {
        return;
    }

    SkEdge headEdge, tailEdge, *last;

    // this returns the first and last edge after they're sorted into a dlink list
    SkEdge* edge = sort_edges(list, count, &last);
    
    headEdge.fPrev = NULL;
    headEdge.fNext = edge;
    headEdge.fFirstY = kEDGE_HEAD_Y;
    headEdge.fX = SK_MinS32;
    edge->fPrev = &headEdge;
    
    tailEdge.fPrev = last;
    tailEdge.fNext = NULL;
    tailEdge.fFirstY = kEDGE_TAIL_Y;
    last->fNext = &tailEdge;
    
    // now edge is the head of the sorted linklist
    int stop_y = ir.fBottom;
    if (clipRect && stop_y > clipRect->fBottom) {
        stop_y = clipRect->fBottom;
    }
    int start_y = ir.fTop;
    if (clipRect && start_y < clipRect->fTop) {
        start_y = clipRect->fTop;
    }
    walk_edges(&headEdge, SkPath::kEvenOdd_FillType, blitter, start_y, stop_y, NULL);
}

void SkScan::FillTriangle(const SkPoint pts[], const SkRegion* clip,
                          SkBlitter* blitter) {
    if (clip && clip->isEmpty()) {
        return;
    }
    
    SkRect  r;
    SkIRect ir;
    r.set(pts, 3);
    r.round(&ir);
    if (ir.isEmpty()) {
        return;
    }
    
    SkScanClipper   clipper(blitter, clip, ir);
    
    blitter = clipper.getBlitter();
    if (NULL != blitter) {
        sk_fill_triangle(pts, clipper.getClipRect(), blitter, ir);
    }
}

