blob: a549e1568168d3ca19560d8bce75d5534b5322c9 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
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 */
reed@android.com909994f2009-11-18 16:09:51 +00007#ifndef SkEdgeBuilder_DEFINED
8#define SkEdgeBuilder_DEFINED
9
Herb Derby4b1b04d2017-03-01 13:44:39 -050010#include "SkArenaAlloc.h"
reed@android.com909994f2009-11-18 16:09:51 +000011#include "SkRect.h"
12#include "SkTDArray.h"
Yuqian Lidf60e362017-07-25 11:26:31 -040013#include "SkEdge.h"
14#include "SkAnalyticEdge.h"
reed@android.com909994f2009-11-18 16:09:51 +000015
senorblanco@chromium.orgb1501a32009-12-04 19:53:28 +000016struct SkEdge;
liyuqian38911a72016-10-04 11:23:22 -070017struct SkAnalyticEdge;
reed@android.com909994f2009-11-18 16:09:51 +000018class SkEdgeClipper;
19class SkPath;
20
21class SkEdgeBuilder {
22public:
Yuqian Lidf60e362017-07-25 11:26:31 -040023 enum EdgeType {
Yuqian Li5eb8fc52017-08-08 14:00:52 -040024 // Used in supersampling or non-AA scan coverter; it stores only integral y coordinates.
Yuqian Lidf60e362017-07-25 11:26:31 -040025 kEdge,
Yuqian Li5eb8fc52017-08-08 14:00:52 -040026
27 // Used in Analytic AA scan converter; it uses SkFixed to store fractional y.
Yuqian Lidf60e362017-07-25 11:26:31 -040028 kAnalyticEdge,
Yuqian Li5eb8fc52017-08-08 14:00:52 -040029
30 // Used in Delta AA scan converter; it's a super-light wrapper of SkPoint, which can then be
31 // used to construct SkAnalyticEdge (kAnalyticEdge) later. We use kBezier to save the memory
32 // allocation time (a SkBezier is much lighter than SkAnalyticEdge or SkEdge). Note that
33 // Delta AA only has to deal with one SkAnalyticEdge at a time (whereas Analytic AA has to
34 // deal with all SkAnalyticEdges at the same time). Thus for Delta AA, we only need to
35 // allocate memory for n SkBeziers and 1 SkAnalyticEdge. (Analytic AA need to allocate
36 // memory for n SkAnalyticEdges.)
Yuqian Lidf60e362017-07-25 11:26:31 -040037 kBezier
38 };
39
40 // static constexpr int kEdgeSizes[3] = {sizeof(SkEdge), sizeof(SkAnalyticEdge), sizeof(SkBezier)};
41
reed@android.com909994f2009-11-18 16:09:51 +000042 SkEdgeBuilder();
rmistry@google.comfbfcd562012-08-23 18:09:54 +000043
reed@google.comc8d640b2012-08-02 14:26:43 +000044 // returns the number of built edges. The array of those edge pointers
45 // is returned from edgeList().
liyuqian38911a72016-10-04 11:23:22 -070046 int build(const SkPath& path, const SkIRect* clip, int shiftUp, bool clipToTheRight,
Yuqian Lidf60e362017-07-25 11:26:31 -040047 EdgeType edgeType = kEdge);
rmistry@google.comfbfcd562012-08-23 18:09:54 +000048
Yuqian Li1c840882017-05-26 14:50:35 -040049 int build_edges(const SkPath& path, const SkIRect* shiftedClip,
Yuqian Lidf60e362017-07-25 11:26:31 -040050 int shiftEdgesUp, bool pathContainedInClip, EdgeType edgeType = kEdge);
Yuqian Li1c840882017-05-26 14:50:35 -040051
liyuqian38911a72016-10-04 11:23:22 -070052 SkEdge** edgeList() { return (SkEdge**)fEdgeList; }
53 SkAnalyticEdge** analyticEdgeList() { return (SkAnalyticEdge**)fEdgeList; }
Yuqian Lidf60e362017-07-25 11:26:31 -040054 SkBezier** bezierList() { return (SkBezier**)fEdgeList; }
rmistry@google.comfbfcd562012-08-23 18:09:54 +000055
reed@android.com909994f2009-11-18 16:09:51 +000056private:
caryclarkafd25f72016-01-30 14:07:20 -080057 enum Combine {
58 kNo_Combine,
59 kPartial_Combine,
60 kTotal_Combine
61 };
62
liyuqian38911a72016-10-04 11:23:22 -070063 Combine CombineVertical(const SkEdge* edge, SkEdge* last);
64 Combine CombineVertical(const SkAnalyticEdge* edge, SkAnalyticEdge* last);
caryclarkafd25f72016-01-30 14:07:20 -080065 Combine checkVertical(const SkEdge* edge, SkEdge** edgePtr);
liyuqian38911a72016-10-04 11:23:22 -070066 Combine checkVertical(const SkAnalyticEdge* edge, SkAnalyticEdge** edgePtr);
67 bool vertical_line(const SkEdge* edge);
68 bool vertical_line(const SkAnalyticEdge* edge);
caryclarkafd25f72016-01-30 14:07:20 -080069
Florin Malita14a64302017-05-24 14:53:44 -040070 SkSTArenaAlloc<512> fAlloc;
liyuqian38911a72016-10-04 11:23:22 -070071 SkTDArray<void*> fList;
rmistry@google.comfbfcd562012-08-23 18:09:54 +000072
reed@google.comc8d640b2012-08-02 14:26:43 +000073 /*
74 * If we're in general mode, we allcoate the pointers in fList, and this
75 * will point at fList.begin(). If we're in polygon mode, fList will be
76 * empty, as we will have preallocated room for the pointers in fAlloc's
77 * block, and fEdgeList will point into that.
78 */
liyuqian38911a72016-10-04 11:23:22 -070079 void** fEdgeList;
reed@android.com909994f2009-11-18 16:09:51 +000080
reed01d33192015-02-07 12:18:41 -080081 int fShiftUp;
Yuqian Lidf60e362017-07-25 11:26:31 -040082 EdgeType fEdgeType;
rmistry@google.comfbfcd562012-08-23 18:09:54 +000083
reed@google.com277c3f82013-05-31 15:17:50 +000084public:
reed@android.com909994f2009-11-18 16:09:51 +000085 void addLine(const SkPoint pts[]);
86 void addQuad(const SkPoint pts[]);
87 void addCubic(const SkPoint pts[]);
88 void addClipper(SkEdgeClipper*);
reed@google.comc8d640b2012-08-02 14:26:43 +000089
Yuqian Li5eb8fc52017-08-08 14:00:52 -040090 EdgeType edgeType() const { return fEdgeType; }
91
reed01d33192015-02-07 12:18:41 -080092 int buildPoly(const SkPath& path, const SkIRect* clip, int shiftUp, bool clipToTheRight);
Yuqian Lidf60e362017-07-25 11:26:31 -040093
94 inline void addPolyLine(SkPoint pts[], char* &edge, size_t edgeSize, char** &edgePtr,
95 int shiftUp) {
96 if (fEdgeType == kBezier) {
97 if (((SkLine*)edge)->set(pts)) {
98 *edgePtr++ = edge;
99 edge += edgeSize;
100 }
101 return;
102 }
103 bool analyticAA = fEdgeType == kAnalyticEdge;
104 bool setLineResult = analyticAA ?
105 ((SkAnalyticEdge*)edge)->setLine(pts[0], pts[1]) :
106 ((SkEdge*)edge)->setLine(pts[0], pts[1], shiftUp);
107 if (setLineResult) {
108 Combine combine = analyticAA ?
109 checkVertical((SkAnalyticEdge*)edge, (SkAnalyticEdge**)edgePtr) :
110 checkVertical((SkEdge*)edge, (SkEdge**)edgePtr);
111 if (kNo_Combine == combine) {
112 *edgePtr++ = edge;
113 edge += edgeSize;
114 } else if (kTotal_Combine == combine) {
115 --edgePtr;
116 }
117 }
118 }
reed@android.com909994f2009-11-18 16:09:51 +0000119};
120
121#endif