• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 geometry_scanline.h
18  *
19  * @brief When converting information from rasterizer to scanline renderer,
20  * The scanline container is used. A scanline consists of many horizontal, disjoint spans.
21  * These spans are sorted by the x-axis
22  * This means that sorting is not provided and must be handled when span is added to scanline
23  * @since 1.0
24  * @version 1.0
25  */
26 
27 #ifndef GRAPHIC_LITE_GEOMETRY_SCANLINE_H
28 #define GRAPHIC_LITE_GEOMETRY_SCANLINE_H
29 
30 #include "gfx_utils/diagram/vertexprimitive/geometry_plaindata_array.h"
31 #include "gfx_utils/graphic_log.h"
32 #include "gfx_utils/vector.h"
33 namespace OHOS {
34 /**
35  * @class ScanlineUnPackedContainer
36  * @brief 16 bit unpacked scan line container class - packed scan line container,
37  * Containers can contain de aliasing information Unpacked scanline always
38  * saves overlay values for all pixels(coverage value),
39  * Include those pixels that all cover the interior of the polygon
40  * @since 1.0
41  * @version 1.0
42  */
43 class GeometryScanline {
44 public:
45     /**
46      * Pixel coverage type
47      */
48     struct SpanBlock {
49         int16_t x;
50         int16_t spanLength;
51         uint8_t* covers;
52     };
53     using Iterator = SpanBlock* ;
54     using ConstIterator = const SpanBlock* ;
GeometryScanline()55     GeometryScanline() : minScaneLineXCoord_(0), lastScaneLineXCoord_(0x7FFFFFF0),
56                          scaneLineYCoord_(0), curSpanBlock_(0) {}
57     /**
58      * @class ScanlineUnPackedContainer
59      * @brief 16 bit unpacked scan line container class - packed scan line container,
60      * Containers can contain de aliasing information Packed scanline and unpacked scanline
61      * The difference between scanline and unpacked scanline is that
62      * unpacked scanline always saves coverage values for all pixels,
63      * Include those pixels that are all covered inside the polygon.
64      * Packed scanlines will merge pixels with the same coverage value into solid span
65      * @since 1.0
66      * @version 1.0
67      */
Reset(int32_t minX,int32_t maxX)68     void Reset(int32_t minX, int32_t maxX)
69     {
70         const int32_t liftNumber = 2;
71         uint32_t maxLen = maxX - minX + liftNumber;
72         if (maxLen > arraySpans_.GetSize()) {
73             arraySpans_.Resize(maxLen);
74             arrayCovers_.Resize(maxLen);
75         }
76         lastScaneLineXCoord_ = 0x7FFFFFF0;
77         minScaneLineXCoord_ = minX;
78         curSpanBlock_ = arraySpans_.Data();
79     }
80 
81     /**
82      * According to the position of X and the cover color, the coverage is the area of the extended call
83      * or add a cell
84      */
AddCell(int32_t x,uint32_t cover)85     void AddCell(int32_t x, uint32_t cover)
86     {
87         x -= minScaneLineXCoord_;
88         arrayCovers_[x] = (uint8_t)cover;
89         if (x == lastScaneLineXCoord_ + 1) {
90             curSpanBlock_->spanLength++;
91         } else {
92             curSpanBlock_++;
93             curSpanBlock_->x = static_cast<int16_t>(x + minScaneLineXCoord_);
94             curSpanBlock_->spanLength = 1;
95             curSpanBlock_->covers = &arrayCovers_[x];
96         }
97         lastScaneLineXCoord_ = x;
98     }
99 
100     /**
101      * According to the position of X, the span length of len and
102      * the cover color coverage are the areas where the call is extended
103      * or add a cell
104      */
AddCells(int32_t x,uint32_t cellLength,const uint8_t * covers)105     void AddCells(int32_t x, uint32_t cellLength, const uint8_t* covers)
106     {
107         x -= minScaneLineXCoord_;
108         if (memcpy_s(&arrayCovers_[x], cellLength * sizeof(uint8_t), covers, cellLength * sizeof(uint8_t)) != EOK) {
109             GRAPHIC_LOGE("AddCells fail");
110             return;
111         }
112         if (x == lastScaneLineXCoord_ + 1) {
113             curSpanBlock_->spanLength += static_cast<int16_t>(cellLength);
114         } else {
115             curSpanBlock_++;
116             curSpanBlock_->x = static_cast<int16_t>(x + minScaneLineXCoord_);
117             curSpanBlock_->spanLength = static_cast<int16_t>(cellLength);
118             curSpanBlock_->covers = &arrayCovers_[x];
119         }
120         lastScaneLineXCoord_ = x + cellLength - 1;
121     }
122 
123     /**
124      * According to the position of X, the span length of len and
125      * the cover color coverage are the areas where the call is extended
126      * Or add a span cell array.
127      * Note here that pixels with the same coverage value will be merged into solid span.
128      */
AddSpan(int32_t x,uint32_t spanLength,uint32_t cover)129     void AddSpan(int32_t x, uint32_t spanLength, uint32_t cover)
130     {
131         x -= minScaneLineXCoord_;
132         if (memset_s(&arrayCovers_[x], spanLength, cover, spanLength) != EOK) {
133             GRAPHIC_LOGE("AddSpan fail");
134             return;
135         }
136         if (x == lastScaneLineXCoord_ + 1) {
137             curSpanBlock_->spanLength += static_cast<int16_t>(spanLength);
138         } else {
139             curSpanBlock_++;
140             curSpanBlock_->x = static_cast<int16_t>(x + minScaneLineXCoord_);
141             curSpanBlock_->spanLength = static_cast<int16_t>(spanLength);
142             curSpanBlock_->covers = &arrayCovers_[x];
143         }
144         lastScaneLineXCoord_ = x + spanLength - 1;
145     }
146 
147     /**
148      * End operation
149      */
Finalize(int32_t y)150     void Finalize(int32_t y)
151     {
152         scaneLineYCoord_ = y;
153     }
ResetSpans()154     void ResetSpans()
155     {
156         lastScaneLineXCoord_ = 0x7FFFFFF0;
157         curSpanBlock_ = &arraySpans_[0];
158     }
159 
GetYLevel()160     int32_t GetYLevel() const
161     {
162         return scaneLineYCoord_;
163     }
NumSpans()164     uint32_t NumSpans() const
165     {
166         return uint32_t(curSpanBlock_ - &arraySpans_[0]);
167     }
Begin()168     ConstIterator Begin() const
169     {
170         return &arraySpans_[1];
171     }
Begin()172     Iterator Begin()
173     {
174         return &arraySpans_[1];
175     }
176 
177 private:
178     GeometryScanline(const GeometryScanline&);
179     const GeometryScanline& operator=(const GeometryScanline&);
180 
181 private:
182     int32_t minScaneLineXCoord_;
183     int32_t lastScaneLineXCoord_;
184     int32_t scaneLineYCoord_;
185     GeometryPlainDataArray<uint8_t> arrayCovers_;
186     GeometryPlainDataArray<SpanBlock> arraySpans_;
187     SpanBlock* curSpanBlock_;
188 };
189 } // namespace OHOS
190 #endif
191