1/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7#ifndef SkAntiEdge_DEFINED
8#define SkAntiEdge_DEFINED
9
10#include "SkFixed.h"
11#include "SkTDArray.h"
12
13struct SkBitmap;
14struct SkPoint;
15
16struct SkAntiEdge {
17    SkAntiEdge* fNext; // list in walking order (y, then x, then diag)
18    SkAntiEdge* fPrev; // reverse in walking order
19    SkAntiEdge* fLink; // list in connected order, top to bottom
20
21    SkFixed     fFirstX; // starting X
22    SkFixed     fFirstY; // starting Y
23    SkFixed     fLastX; // ending X
24    SkFixed     fLastY; // ending Y
25    SkFixed     fX0; // computed edge current value (may be off end)
26    SkFixed     fY0;
27    SkFixed     fX; // edge current value (always on edge)
28    SkFixed     fY;
29    SkFixed     fDX; // change in X per unit step in Y
30    SkFixed     fDY; // change in Y per unit step in X
31    SkFixed     fWalkX; // unit step position (integer after initial step)
32    SkFixed     fWalkY;
33    uint16_t    fPartialY; // initial partial coverage in Y (0 .. SkFixed1]
34    int16_t     fWindingSum; // winding including contributions to the left
35    int8_t      fWinding; // 1 or -1 (could be 2 bits)
36    bool        fFinished : 1;
37    unsigned    fDXFlipped : 1; // used as bool and to adjust calculations (0/1)
38    bool        fLinkSet : 1; // set if edge has been attached to another edge
39
40    void calcLine();
41    bool setLine(const SkPoint& p0, const SkPoint& p1);
42    uint16_t advanceX(SkFixed left);
43    uint16_t advanceFlippedX(SkFixed left);
44    void advanceY(SkFixed top);
45// FIXME: mark DEBUG
46    void pointInLine(SkFixed x, SkFixed y);
47    void pointOnLine(SkFixed x, SkFixed y);
48    void validate();
49};
50
51class SkAntiEdgeBuilder {
52public:
53void process(const SkPoint* points, int ptCount,
54        uint8_t* result, int pixelCol, int pixelRow);
55private:
56    int build(const SkPoint pts[], int count);
57    void calc();
58    void link();
59    void sort();
60    void sort(SkTDArray<SkAntiEdge*>&);
61    void split();
62    void split(SkAntiEdge* edge, SkFixed y);
63    void walk(uint8_t* result, int rowBytes, int height);
64    SkAntiEdge fHeadEdge;
65    SkAntiEdge fTailEdge;
66    SkTDArray<SkAntiEdge> fEdges;
67    SkTDArray<SkAntiEdge*> fList;
68};
69
70void SkAntiEdge_Test();
71void CreateSweep(SkBitmap* , float width);
72void CreateHorz(SkBitmap* );
73void CreateVert(SkBitmap* );
74void CreateAngle(SkBitmap* sweep, float angle);
75
76#endif
77