1639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com/*
21304bb25aa3b0baa61fc2e2900fabcef88801b59caryclark@google.com * Copyright 2011 Google Inc.
3639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com *
41304bb25aa3b0baa61fc2e2900fabcef88801b59caryclark@google.com * Use of this source code is governed by a BSD-style license that can be
51304bb25aa3b0baa61fc2e2900fabcef88801b59caryclark@google.com * found in the LICENSE file.
6639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com */
7639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com#ifndef SkAntiEdge_DEFINED
8639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com#define SkAntiEdge_DEFINED
9639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com
10639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com#include "SkFixed.h"
11639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com#include "SkTDArray.h"
12639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com
13639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comstruct SkBitmap;
14639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comstruct SkPoint;
15639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com
16639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comstruct SkAntiEdge {
17639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkAntiEdge* fNext; // list in walking order (y, then x, then diag)
18639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkAntiEdge* fPrev; // reverse in walking order
19639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkAntiEdge* fLink; // list in connected order, top to bottom
20639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com
21639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkFixed     fFirstX; // starting X
22639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkFixed     fFirstY; // starting Y
23639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkFixed     fLastX; // ending X
24639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkFixed     fLastY; // ending Y
25639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkFixed     fX0; // computed edge current value (may be off end)
26639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkFixed     fY0;
27639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkFixed     fX; // edge current value (always on edge)
28639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkFixed     fY;
29639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkFixed     fDX; // change in X per unit step in Y
30639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkFixed     fDY; // change in Y per unit step in X
31639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkFixed     fWalkX; // unit step position (integer after initial step)
32639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkFixed     fWalkY;
33639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    uint16_t    fPartialY; // initial partial coverage in Y (0 .. SkFixed1]
34639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    int16_t     fWindingSum; // winding including contributions to the left
35639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    int8_t      fWinding; // 1 or -1 (could be 2 bits)
36639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    bool        fFinished : 1;
37639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    unsigned    fDXFlipped : 1; // used as bool and to adjust calculations (0/1)
38639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    bool        fLinkSet : 1; // set if edge has been attached to another edge
39639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com
40639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    void calcLine();
41639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    bool setLine(const SkPoint& p0, const SkPoint& p1);
42639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    uint16_t advanceX(SkFixed left);
43639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    uint16_t advanceFlippedX(SkFixed left);
44639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    void advanceY(SkFixed top);
45639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com// FIXME: mark DEBUG
46639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    void pointInLine(SkFixed x, SkFixed y);
47639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    void pointOnLine(SkFixed x, SkFixed y);
48639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    void validate();
49639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com};
50639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com
51639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comclass SkAntiEdgeBuilder {
52639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.compublic:
53639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comvoid process(const SkPoint* points, int ptCount,
54639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com        uint8_t* result, int pixelCol, int pixelRow);
55639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comprivate:
56639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    int build(const SkPoint pts[], int count);
57639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    void calc();
58639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    void link();
59639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    void sort();
60639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    void sort(SkTDArray<SkAntiEdge*>&);
61639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    void split();
62639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    void split(SkAntiEdge* edge, SkFixed y);
63639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    void walk(uint8_t* result, int rowBytes, int height);
64639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkAntiEdge fHeadEdge;
65639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkAntiEdge fTailEdge;
66639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkTDArray<SkAntiEdge> fEdges;
67639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com    SkTDArray<SkAntiEdge*> fList;
68639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com};
69639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com
70639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comvoid SkAntiEdge_Test();
71639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comvoid CreateSweep(SkBitmap* , float width);
72639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comvoid CreateHorz(SkBitmap* );
73639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comvoid CreateVert(SkBitmap* );
74639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.comvoid CreateAngle(SkBitmap* sweep, float angle);
75639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com
76639df891487e40925a4f8d9a34fd3dc0c18b40a7caryclark@google.com#endif
77