• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef GRAPHIC_LITE_CLIP_UTILS_H
17 #define GRAPHIC_LITE_CLIP_UTILS_H
18 
19 #include "gfx_utils/geometry2d.h"
20 #include "gfx_utils/image_info.h"
21 #include "gfx_utils/list.h"
22 #include "gfx_utils/vector.h"
23 
24 namespace OHOS {
25 /* Indicates an interval with the same transparency */
26 struct Span : public HeapBase {
27     int16_t left;
28     int16_t right;
29     uint8_t opa;
30 };
31 
32 /* Indicates a point in float */
33 struct PointF {
34     float x;
35     float y;
36 };
37 
38 /* Indicates a rectangle in flaot */
39 struct RectF {
40     float left;
41     float top;
42     float right;
43     float bottom;
44 };
45 
46 /* Indicates an edge */
47 struct Edge : public HeapBase {
48     /* The maximum y coordinate of the edge */
49     int16_t ymax;
50     /* The minimum y coordinate of the edge */
51     int16_t ymin;
52     /* The x-coordinate of the intersection with the current row */
53     float x;
54     /* Increment of x-coordinate when y-coordinate increases by 1 */
55     float dx;
56 };
57 
58 /* Indicates an edge that to be antialiased */
59 struct AAEdge : public HeapBase {
60     /* The y-coordinate of current integer x-coordinate */
61     float y;
62     /* Increment of y-coordinate when x-coordinate step by sx */
63     float dy;
64     /* Current integer x-coordinate */
65     int16_t x;
66     /* Step of x, 1 or -1 */
67     int16_t sx;
68     /* Upper limit of steps */
69     int16_t xIndex;
70 };
71 
72 /* Indicates a cubic Bezier curve */
73 struct Spline : public HeapBase {
74     /* Start point */
75     PointF a;
76     /* First control point */
77     PointF b;
78     /* Second control point */
79     PointF c;
80     /* End point */
81     PointF d;
82 };
83 
84 enum ClipPathCmd {
85     CMD_MOVE_TO,
86     CMD_LINE_TO,
87     CMD_CURVE_TO,
88 };
89 
90 class ClipPolygon : public HeapBase {
91 public:
ClipPolygon()92     ClipPolygon() {}
~ClipPolygon()93     ~ClipPolygon()
94     {
95         Clear();
96     }
97 
Clear()98     void Clear()
99     {
100         points_.Clear();
101         bound_ = {0, 0, 0, 0};
102     }
103 
AddPoint(const PointF & p)104     void AddPoint(const PointF& p)
105     {
106         if (points_.IsEmpty()) {
107             bound_.left = p.x;
108             bound_.right = p.x;
109             bound_.top = p.y;
110             bound_.bottom = p.y;
111             points_.PushBack(p);
112         } else if (!MATH_FLT_EQUAL(points_.Back().x, p.x) || !MATH_FLT_EQUAL(points_.Back().y, p.y)) {
113             bound_.left = (p.x < bound_.left) ? p.x : bound_.left;
114             bound_.top = (p.y < bound_.top) ? p.y : bound_.top;
115             bound_.right = (p.x > bound_.right) ? p.x : bound_.right;
116             bound_.bottom = (p.y > bound_.bottom) ? p.y : bound_.bottom;
117             points_.PushBack(p);
118         }
119     }
120 
121     Graphic::Vector<PointF> points_;
122     RectF bound_ = {0, 0, 0, 0};
123 };
124 
125 /*
126  * Indicates a path to be cliped.
127  * Note: The path will be automatically closed. Only non-self-intersecting path are supported.
128  */
129 class ClipPath : public HeapBase {
130 public:
ClipPath()131     ClipPath() {}
~ClipPath()132     ~ClipPath()
133     {
134         points_.Clear();
135         cmd_.Clear();
136     }
137     void GeneratePolygon(ClipPolygon& polygon) const;
138 
139     ClipPath& MoveTo(const PointF& point);
140     ClipPath& LineTo(const PointF& point);
141     ClipPath& CurveTo(const PointF& control1, const PointF& control2, const PointF& end);
142     ClipPath& Arc(const PointF& center, float radius, int16_t startAngle, int16_t endAngle);
143     ClipPath& Circle(const PointF& center, float radius);
144 
145 private:
146     bool CheckoutSplineError(const Spline& spline) const;
147     void MidPointOfLine(const PointF& a, const PointF& b, PointF& mid) const;
148     void SplitSpline(Spline& s1, Spline& s2) const;
149     void SplineDecompose(Spline& s, ClipPolygon& polygon) const;
150 
151     void ArcInner(const PointF& center, float radius, int16_t startAngle, int16_t endAngle);
152 
153     List<PointF> points_;
154     List<ClipPathCmd> cmd_;
155     PointF startPos_ = {0, 0};
156 };
157 
158 /*
159  * Blitter and its subclasses are responible for handling the span list and actually draws the pixels
160  */
161 class Blitter : public HeapBase {
162 public:
Blitter()163     Blitter() {}
~Blitter()164     virtual ~Blitter() {}
165 
DrawHorSpan(const List<Span> & span,int16_t yCur)166     virtual void DrawHorSpan(const List<Span>& span, int16_t yCur) {}
Finish()167     virtual void Finish() {}
168 };
169 
170 /* Clipimageblitter will clip the image on its original memory */
171 class ClipImageBlitter : public Blitter {
172 public:
ClipImageBlitter(const ImageInfo * src)173     explicit ClipImageBlitter(const ImageInfo* src) : src_(src) {}
~ClipImageBlitter()174     virtual ~ClipImageBlitter() {}
175 
176     void DrawHorSpan(const List<Span>& span, int16_t yCur) override;
177     void Finish() override;
178 private:
179     void DrawPixel(int16_t x, int16_t y, uint8_t opa);
180     void DrawHorLine(int16_t x, int16_t y, int16_t width, uint8_t opa);
181 
182     const ImageInfo* src_ = nullptr;
183     int16_t iy_ = 0;
184 };
185 
186 class ClipUtils : public HeapBase {
187 public:
ClipUtils()188     ClipUtils() {}
~ClipUtils()189     ~ClipUtils() {}
190 
191     void PerformScan(const ClipPath& path, Blitter& blitter);
192 private:
193     void ClearSpanTable();
194 
195     void CreateNewSpan(List<Span>& list, ListNode<Span>* node, int16_t left, int16_t right, uint8_t opa);
196     void InsertSpan(List<Span>& curList, int16_t left, int16_t right, uint8_t opa);
197     void MergeSpan(List<Span>& s);
198 
199     void CreateEdgeList(const ClipPath& path);
200     void DrawAntiAliasedPoints(int16_t yCur);
201 
202     /* Save the lines that needs to be scanned vertically */
203     List<Edge> edgeList_;
204     /* Save the non steep lines that need to be antialiased */
205     List<AAEdge> aaList_;
206     /* Pointer to the span of the current row */
207     List<Span>* span0_ = nullptr;
208     /* Pointer to the span of the next row */
209     List<Span>* span1_ = nullptr;
210 
211     int16_t minY_ = INT16_MAX;
212     int16_t maxY_ = INT16_MIN;
213 };
214 };
215 #endif