1 /*
2  * Copyright (c) 2022 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 /**
17  * @file rasterizer_cells_antialias.h
18  * @brief Defines Grating cell (anti aliasing)
19  * @since 1.0
20  * @version 1.0
21  */
22 
23 #ifndef GRAPHIC_LITE_RASTERIZER_CELLS_ANTIALIAS_H
24 #define GRAPHIC_LITE_RASTERIZER_CELLS_ANTIALIAS_H
25 
26 #include "gfx_utils/diagram/common/common_math.h"
27 #include "gfx_utils/vector.h"
28 
29 namespace OHOS {
30 // There is no constructor defined for pixel cells,
31 // which is to avoid the additional overhead of allocating cell arrays
32 struct CellBuildAntiAlias {
33     int32_t x;
34     int32_t y;
35     int32_t cover;
36     int32_t area;
37 
InitialCellBuildAntiAlias38     void Initial()
39     {
40         x = INT32_MAX;
41         y = INT32_MAX;
42         cover = 0;
43         area = 0;
44     }
45 
StyleCellBuildAntiAlias46     void Style(const CellBuildAntiAlias&) {}
47 
NotEqualCellBuildAntiAlias48     int32_t NotEqual(int32_t ex, int32_t ey, const CellBuildAntiAlias&) const
49     {
50         return (static_cast<uint32_t>(ex) - static_cast<uint32_t>(x))
51                 | (static_cast<uint32_t>(ey) - static_cast<uint32_t>(y));
52     }
53 };
54 
55 class RasterizerCellsAntiAlias {
56     struct SortedYLevel {
57         uint32_t start;
58         uint32_t num;
59     };
60 
61     /**
62      * @brief Build the offset of 'cell unit', mask mask, cell pool capacity, etc
63      * @since 1.0
64      * @version 1.0
65      */
66     enum CellBlockScale {
67         CELL_BLOCK_SHIFT = 5,
68         CELL_BLOCK_SIZE = 1 << CELL_BLOCK_SHIFT,
69         CELL_BLOCK_MASK = CELL_BLOCK_SIZE - 1,
70         CELL_BLOCK_POOL = 256
71     };
72 
73     enum DxLimit {
74         DX_LIMIT = CONSTITUTION << POLY_SUBPIXEL_SHIFT
75     };
76 
77 public:
78     ~RasterizerCellsAntiAlias();
79 
80     /**
81      * @brief RasterizerCellsAntiAlias Class constructor
82      * initialization numBlocks_,maxBlocks_,currBlock_ etc
83      * @since 1.0
84      * @version 1.0
85      */
86     RasterizerCellsAntiAlias(uint32_t cellBlockLimit = 1024);
87 
88     /**
89      * Reinitialize settings numBlocks_,maxBlocks_,currBlock_ etc。
90      * @since 1.0
91      * @version 1.0
92      */
93     void Reset();
94     void SetStyle(const CellBuildAntiAlias& styleCell);
95 
96     /**
97      * @brief According to the incoming 2 coordinate points (both with sub pixels),
98      * The process of constructing rasterized cell points is from y to X.
99      * @since 1.0
100      * @version 1.0
101      */
102     void LineOperate(int32_t x1, int32_t y1, int32_t x2, int32_t y2);
103 
104     void LineOperateVerticalLine();
105 
106     /**
107      * @brief The rasterization process builds the coordinate range of the entity.
108      * @since 1.0
109      * @version 1.0
110      */
GetMinX()111     int32_t GetMinX() const
112     {
113         return minX_;
114     }
GetMinY()115     int32_t GetMinY() const
116     {
117         return minY_;
118     }
GetMaxX()119     int32_t GetMaxX() const
120     {
121         return maxX_;
122     }
GetMaxY()123     int32_t GetMaxY() const
124     {
125         return maxY_;
126     }
127 
128     /**
129      * @brief In the rasterization process, all cells are rasterized according to
130      * Sort from left to right and from top to bottom.
131      * @since 1.0
132      * @version 1.0
133      */
134     void SortAllCells();
135 
GetTotalCells()136     uint32_t GetTotalCells() const
137     {
138         return numCells_;
139     }
140 
141     /**
142      * @brief In the process of rasterization, it is calculated according to the coordinate height of Y
143      * Total number of cells.
144      * @since 1.0
145      * @version 1.0
146      */
GetScanlineNumCells(uint32_t yLevel)147     uint32_t GetScanlineNumCells(uint32_t yLevel)
148     {
149         uint32_t MaxSize = maxY_ - minY_ + 1 + CELLS_SIZE;
150         if ((yLevel - minY_) > MaxSize) {
151             return 0;
152         }
153 
154         return sortedY_[yLevel - minY_].num;
155     }
156 
157     /**
158      * @brief In the process of rasterization, it is calculated according to the coordinate height of Y
159      * The first address of the sorted cells array.
160      * @since 1.0
161      * @version 1.0
162      */
GetScanlineCells(uint32_t yLevel)163     const CellBuildAntiAlias * const *GetScanlineCells(uint32_t yLevel)
164     {
165         uint32_t MaxSize = maxY_ - minY_ + 1 + CELLS_SIZE;
166         if ((yLevel - minY_) > MaxSize) {
167             return sortedCells_;
168         }
169 
170         return sortedCells_ + sortedY_[yLevel - minY_].start;
171     }
172 
GetSorted()173     bool GetSorted() const
174     {
175         return sorted_;
176     }
177 
178 private:
179     RasterizerCellsAntiAlias(const CellBuildAntiAlias&);
180     const CellBuildAntiAlias& operator=(const CellBuildAntiAlias&);
181 
182     /**
183      * @brief Set the current cell during rasterization.
184      * @since 1.0
185      * @version 1.0
186      */
187     void SetCurrentCell(int32_t x, int32_t y);
188 
189     void OutLineLegal(int32_t x1, int32_t y1, int32_t x2, int32_t y2);
190 
191     /**
192      * @brief Add the current cell during rasterization.
193      * @since 1.0
194      * @version 1.0
195      */
196     void AddCurrentCell();
197 
198     /**
199      * @brief n the rasterization process, the horizontal direction is
200      * from x1 to x2 according to the coordinate height value of ey,
201      * The filling process of cell cells longitudinally from sub-pixel mask y1 to sub-pixel mask y2.
202      * @since 1.0
203      * @version 1.0
204      */
205     void RenderHorizonline(int32_t ey, int32_t x1, int32_t submaskFlagsY1, int32_t x2, int32_t submaskFlagsY2);
206 
207     void RenderVerticalLine(int32_t& x1, int32_t& ex1, int64_t& dy, int32_t& first,
208                             int32_t& increase, int32_t& xFrom, int32_t& submaskFlagsY1,
209                             int32_t& submaskFlagsY2, int32_t& ey1, int32_t& ey2, int32_t& delta);
210 
211     void RenderObliqueLine(int64_t& dx, int64_t& dy, int32_t& first,
212                            int32_t& increase, int32_t& xFrom, int64_t& deltaxMask,
213                            int32_t& ey1, int32_t& ey2, int32_t& delta);
214 
215     /**
216      * @brief Allocate array space for cells during rasterization.
217      * @since 1.0
218      * @version 1.0
219      */
220     void AllocateBlock();
221 
222 private:
223     uint32_t numBlocks_;
224     uint32_t maxBlocks_;
225     uint32_t currBlock_;
226     uint32_t numCells_;
227     uint32_t cellBlockLimit_;
228     CellBuildAntiAlias** cells_;
229     CellBuildAntiAlias* currCellPtr_;
230     CellBuildAntiAlias** sortedCells_;
231     SortedYLevel* sortedY_;
232     CellBuildAntiAlias currCell_;
233     CellBuildAntiAlias styleCell_;
234     int32_t minX_;
235     int32_t minY_;
236     int32_t maxX_;
237     int32_t maxY_;
238     bool sorted_;
239 };
240 
241 class ScanlineHitRegionMeasure {
242 public:
ScanlineHitRegionMeasure(int32_t x)243     ScanlineHitRegionMeasure(int32_t x) : xCoordinate_(x), hitMeasureFlags_(false) {}
244 
AddCellInContainer(int32_t x,int32_t)245     void AddCellInContainer(int32_t x, int32_t)
246     {
247         if (xCoordinate_ == x) {
248             hitMeasureFlags_ = true;
249         }
250     }
AddSpanInContainer(int32_t x,int32_t len,int32_t)251     void AddSpanInContainer(int32_t x, int32_t len, int32_t)
252     {
253         if (xCoordinate_ >= x && xCoordinate_ < x + len) {
254             hitMeasureFlags_ = true;
255         }
256     }
GetNumberSpans()257     uint32_t GetNumberSpans() const
258     {
259         return 1;
260     }
GetHitMeasure()261     bool GetHitMeasure() const
262     {
263         return hitMeasureFlags_;
264     }
265 
266 private:
267     int32_t xCoordinate_;
268     bool hitMeasureFlags_;
269 };
270 
271 /**
272  * @brief The exchange of cells in the rasterization process.
273  * @since 1.0
274  * @version 1.0
275  */
276 template <class T>
SwapCells(T * oneCells,T * twoCells)277 inline void SwapCells(T* oneCells, T* twoCells)
278 {
279     T tempCells = *oneCells;
280     *oneCells = *twoCells;
281     *twoCells = tempCells;
282 }
283 
284 void QsortCellsSweep(CellBuildAntiAlias*** base, CellBuildAntiAlias*** iIndex, CellBuildAntiAlias*** jIndex);
285 
286 /**
287  * @brief In the rasterization process, all cells are sorted quickly.
288  * @since 1.0
289  * @version 1.0
290  */
291 void QsortCells(CellBuildAntiAlias** start, uint32_t num);
292 
293 void QsortCellsFor(CellBuildAntiAlias*** iIndex, CellBuildAntiAlias*** jIndex,
294                    CellBuildAntiAlias*** limit, CellBuildAntiAlias*** base);
295 } // namespace OHOS
296 #endif
297