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 SkEdgeBuilder_DEFINED
8 #define SkEdgeBuilder_DEFINED
9 
10 #include "SkAnalyticEdge.h"
11 #include "SkArenaAlloc.h"
12 #include "SkEdge.h"
13 #include "SkRect.h"
14 #include "SkTDArray.h"
15 
16 class SkPath;
17 
18 class SkEdgeBuilder {
19 public:
20     int buildEdges(const SkPath& path,
21                    const SkIRect* shiftedClip);
22 
23 protected:
24     SkEdgeBuilder() = default;
25     virtual ~SkEdgeBuilder() = default;
26 
27     // In general mode we allocate pointers in fList and fEdgeList points to its head.
28     // In polygon mode we preallocated edges contiguously in fAlloc and fEdgeList points there.
29     void**              fEdgeList = nullptr;
30     SkTDArray<void*>    fList;
31     SkSTArenaAlloc<512> fAlloc;
32 
33     enum Combine {
34         kNo_Combine,
35         kPartial_Combine,
36         kTotal_Combine
37     };
38 
39 private:
40     int build    (const SkPath& path, const SkIRect* clip, bool clipToTheRight);
41     int buildPoly(const SkPath& path, const SkIRect* clip, bool clipToTheRight);
42 
43     virtual char* allocEdges(size_t n, size_t* sizeof_edge) = 0;
44     virtual SkRect recoverClip(const SkIRect&) const = 0;
45     virtual bool chopCubics() const = 0;
46 
47     virtual void addLine (const SkPoint pts[]) = 0;
48     virtual void addQuad (const SkPoint pts[]) = 0;
49     virtual void addCubic(const SkPoint pts[]) = 0;
50     virtual Combine addPolyLine(SkPoint pts[], char* edge, char** edgePtr) = 0;
51 };
52 
53 class SkBasicEdgeBuilder final : public SkEdgeBuilder {
54 public:
SkBasicEdgeBuilder(int clipShift)55     explicit SkBasicEdgeBuilder(int clipShift) : fClipShift(clipShift) {}
56 
edgeList()57     SkEdge** edgeList() { return (SkEdge**)fEdgeList; }
58 
59 private:
60     Combine combineVertical(const SkEdge* edge, SkEdge* last);
61 
62     char* allocEdges(size_t, size_t*) override;
63     SkRect recoverClip(const SkIRect&) const override;
chopCubics()64     bool chopCubics() const override { return true; }
65 
66     void addLine (const SkPoint pts[]) override;
67     void addQuad (const SkPoint pts[]) override;
68     void addCubic(const SkPoint pts[]) override;
69     Combine addPolyLine(SkPoint pts[], char* edge, char** edgePtr) override;
70 
71     const int fClipShift;
72 };
73 
74 class SkAnalyticEdgeBuilder final : public SkEdgeBuilder {
75 public:
SkAnalyticEdgeBuilder()76     SkAnalyticEdgeBuilder() {}
77 
analyticEdgeList()78     SkAnalyticEdge** analyticEdgeList() { return (SkAnalyticEdge**)fEdgeList; }
79 
80 private:
81     Combine combineVertical(const SkAnalyticEdge* edge, SkAnalyticEdge* last);
82 
83     char* allocEdges(size_t, size_t*) override;
84     SkRect recoverClip(const SkIRect&) const override;
chopCubics()85     bool chopCubics() const override { return true; }
86 
87     void addLine (const SkPoint pts[]) override;
88     void addQuad (const SkPoint pts[]) override;
89     void addCubic(const SkPoint pts[]) override;
90     Combine addPolyLine(SkPoint pts[], char* edge, char** edgePtr) override;
91 };
92 
93 class SkBezierEdgeBuilder final : public SkEdgeBuilder {
94 public:
SkBezierEdgeBuilder()95     SkBezierEdgeBuilder() {}
96 
bezierList()97     SkBezier** bezierList() { return (SkBezier**)fEdgeList; }
98 
99 private:
100     char* allocEdges(size_t, size_t*) override;
101     SkRect recoverClip(const SkIRect&) const override;
chopCubics()102     bool chopCubics() const override { return false; }
103 
104     void addLine (const SkPoint pts[]) override;
105     void addQuad (const SkPoint pts[]) override;
106     void addCubic(const SkPoint pts[]) override;
107     Combine addPolyLine(SkPoint pts[], char* edge, char** edgePtr) override;
108 };
109 
110 #endif
111