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 #include "gfx_utils/diagram/rasterizer/rasterizer_scanline_clip.h"
17
18 namespace OHOS {
19 /**
20 * @brief In the RASTERIZER process,Judge the mark according to the last clipping range
21 * And the cutting range judgment flag this time,
22 * add the actual sampling points and set relevant attributes
23 * @since 1.0
24 * @version 1.0
25 */
LineClipY(RasterizerCellsAntiAlias & ras,int32_t x1,int32_t y1,int32_t x2,int32_t y2,uint32_t clipFlagsOne,uint32_t clipFlagsTwo) const26 void RasterizerScanlineClip::LineClipY(RasterizerCellsAntiAlias& ras,
27 int32_t x1, int32_t y1,
28 int32_t x2, int32_t y2,
29 uint32_t clipFlagsOne, uint32_t clipFlagsTwo) const
30 {
31 clipFlagsOne &= DIRECTLY_BELOW;
32 clipFlagsTwo &= DIRECTLY_BELOW;
33 if ((clipFlagsOne | clipFlagsTwo) == 0) {
34 /**
35 * It indicates that the coordinates x1, y1, x2 and y2 are all within the range, and the line operates
36 */
37 ras.LineOperate(RasterDepictInt::GetXCoordinateValue(x1),
38 RasterDepictInt::GetYCoordinateValue(y1),
39 RasterDepictInt::GetXCoordinateValue(x2),
40 RasterDepictInt::GetYCoordinateValue(y2));
41 } else {
42 if (clipFlagsOne == clipFlagsTwo) {
43 /**
44 * It indicates that the coordinates x1, y1, x2 and y2 are all outside the range and do not operate
45 */
46 return;
47 }
48 int32_t tx1 = x1;
49 int32_t ty1 = y1;
50 int32_t tx2 = x2;
51 int32_t ty2 = y2;
52 /**
53 * Indicates that the coordinate y1 < clip.y1
54 */
55 if (clipFlagsOne & 0x08) {
56 tx1 = x1 + RasterDepictInt::MultDiv(clipBox_.GetTop() - y1, x2 - x1, y2 - y1);
57 ty1 = clipBox_.GetTop();
58 }
59
60 /**
61 * Indicates that the coordinate y1 > clip.y2
62 */
63 if (clipFlagsOne & 0x02) {
64 tx1 = x1 + RasterDepictInt::MultDiv(clipBox_.GetBottom() - y1, x2 - x1, y2 - y1);
65 ty1 = clipBox_.GetBottom();
66 }
67 /**
68 * Indicates that the coordinate y1 > clip.y2
69 */
70 if (clipFlagsTwo & 0x08) {
71 tx2 = x1 + RasterDepictInt::MultDiv(clipBox_.GetTop() - y1, x2 - x1, y2 - y1);
72 ty2 = clipBox_.GetTop();
73 }
74 /**
75 * Indicates that the coordinate y2 > clip.y2
76 */
77 if (clipFlagsTwo & 0x02) {
78 tx2 = x1 + RasterDepictInt::MultDiv(clipBox_.GetBottom() - y1, x2 - x1, y2 - y1);
79 ty2 = clipBox_.GetBottom();
80 }
81 ras.LineOperate(RasterDepictInt::GetXCoordinateValue(tx1), RasterDepictInt::GetYCoordinateValue(ty1),
82 RasterDepictInt::GetXCoordinateValue(tx2), RasterDepictInt::GetYCoordinateValue(ty2));
83 }
84 }
85
86 /**
87 * @brief Cohen–Sutherland
88 * In the RASTERIZER process, add the set sampling point,
89 * And set the sampling point, set the related cover and area attributes, etc.
90 * | |
91 * 0110 | 0010 | 0011
92 * | |
93 * -------+--------+-------- clip_box.y2
94 * | |
95 * 0100 | 0000 | 0001
96 * | |
97 * -------+--------+-------- clip_box.y1
98 * | |
99 * 1100 | 1000 | 1001
100 * | |
101 * clip_box.x1 clip_box.x2
102 * @since 1.0
103 * @version 1.0
104 */
LineTo(RasterizerCellsAntiAlias & rasterLine,int32_t x2,int32_t y2)105 void RasterizerScanlineClip::LineTo(RasterizerCellsAntiAlias& rasterLine, int32_t x2, int32_t y2)
106 {
107 if (clipping_) {
108 uint32_t cFlagsLineToPoint = ClippingFlags(x2, y2, clipBox_);
109 if ((clippingFlags_ & 0x0A) == (cFlagsLineToPoint & 0x0A) && (clippingFlags_ & 0x0A) != 0) {
110 x1_ = x2;
111 y1_ = y2;
112 clippingFlags_ = cFlagsLineToPoint;
113 return;
114 }
115
116 int32_t x1 = x1_;
117 int32_t y1 = y1_;
118 uint32_t clipFlagsMoveToPoint = clippingFlags_;
119 int32_t yPilotOne;
120 int32_t yPilotTwo;
121 uint32_t yClipFlagsOne = 0;
122 uint32_t yClipFlagsTwo = 0;
123
124 switch (((clipFlagsMoveToPoint & 0x05) << 1) | (cFlagsLineToPoint & 0x05)) {
125 /**
126 * It indicates that x1, y1, x2,and y2 are all in the clip area
127 */
128 case 0x00:
129 LineClipY(rasterLine, x1, y1, x2, y2, clipFlagsMoveToPoint, cFlagsLineToPoint);
130 break;
131 /**
132 * indicate x2 > clip.x2
133 */
134 case 0x01:
135 yPilotOne = y1 + RasterDepictInt::MultDiv(clipBox_.GetRight() - x1, y2 - y1, x2 - x1);
136 yClipFlagsOne = ClippingFlagsY(yPilotOne, clipBox_);
137 LineClipY(rasterLine, x1, y1, clipBox_.GetRight(), yPilotOne,
138 clipFlagsMoveToPoint, yClipFlagsOne);
139 LineClipY(rasterLine, clipBox_.GetRight(), yPilotOne,
140 clipBox_.GetRight(), y2, yClipFlagsOne, cFlagsLineToPoint);
141 break;
142 /**
143 * indicate x1 > clip.x2
144 */
145 case 0x02:
146 yPilotOne = y1 + RasterDepictInt::MultDiv(clipBox_.GetRight() - x1, y2 - y1, x2 - x1);
147 yClipFlagsOne = ClippingFlagsY(yPilotOne, clipBox_);
148 LineClipY(rasterLine, clipBox_.GetRight(), y1, clipBox_.GetRight(),
149 yPilotOne, clipFlagsMoveToPoint, yClipFlagsOne);
150 LineClipY(rasterLine, clipBox_.GetRight(), yPilotOne, x2, y2,
151 yClipFlagsOne, cFlagsLineToPoint);
152 break;
153 /**
154 * indicate x1 > clip.x2 && x2 > clip.x2
155 */
156 case 0x03:
157 LineClipY(rasterLine, clipBox_.GetRight(), y1, clipBox_.GetRight(), y2,
158 clipFlagsMoveToPoint, cFlagsLineToPoint);
159 break;
160 /**
161 * indicate x2 < clip.x1
162 */
163 case 0x04:
164 yPilotOne = y1 + RasterDepictInt::MultDiv(clipBox_.GetLeft() - x1, y2 - y1, x2 - x1);
165 yClipFlagsOne = ClippingFlagsY(yPilotOne, clipBox_);
166 LineClipY(rasterLine, x1, y1, clipBox_.GetLeft(), yPilotOne,
167 clipFlagsMoveToPoint, yClipFlagsOne);
168 LineClipY(rasterLine, clipBox_.GetLeft(), yPilotOne, clipBox_.GetLeft(), y2,
169 yClipFlagsOne, cFlagsLineToPoint);
170 break;
171 /**
172 * indicate x1 > clip.x2 && x2 < clip.x1
173 */
174 case 0x06:
175 yPilotOne = y1 + RasterDepictInt::MultDiv(clipBox_.GetRight() - x1, y2 - y1, x2 - x1);
176 yPilotTwo = y1 + RasterDepictInt::MultDiv(clipBox_.GetLeft() - x1, y2 - y1, x2 - x1);
177 yClipFlagsOne = ClippingFlagsY(yPilotOne, clipBox_);
178 yClipFlagsTwo = ClippingFlagsY(yPilotTwo, clipBox_);
179 LineClipY(rasterLine, clipBox_.GetRight(), y1, clipBox_.GetRight(), yPilotOne,
180 clipFlagsMoveToPoint, yClipFlagsOne);
181 LineClipY(rasterLine, clipBox_.GetRight(), yPilotOne, clipBox_.GetLeft(), yPilotTwo,
182 yClipFlagsOne, yClipFlagsTwo);
183 LineClipY(rasterLine, clipBox_.GetLeft(), yPilotTwo, clipBox_.GetLeft(), y2,
184 yClipFlagsTwo, cFlagsLineToPoint);
185 break;
186
187 /**
188 * indicate x1 < clip.x1
189 */
190 case 0x08:
191 yPilotOne = y1 + RasterDepictInt::MultDiv(clipBox_.GetLeft() - x1, y2 - y1, x2 - x1);
192 yClipFlagsOne = ClippingFlagsY(yPilotOne, clipBox_);
193 LineClipY(rasterLine, clipBox_.GetLeft(), y1, clipBox_.GetLeft(), yPilotOne,
194 clipFlagsMoveToPoint, yClipFlagsOne);
195 LineClipY(rasterLine, clipBox_.GetLeft(), yPilotOne, x2, y2,
196 yClipFlagsOne, cFlagsLineToPoint);
197 break;
198 /**
199 * indicate x1 < clip.x1 && x2 > clip.x2
200 */
201 case 0x09:
202 yPilotOne = y1 + RasterDepictInt::MultDiv(clipBox_.GetLeft() - x1, y2 - y1, x2 - x1);
203 yPilotTwo = y1 + RasterDepictInt::MultDiv(clipBox_.GetRight() - x1, y2 - y1, x2 - x1);
204 yClipFlagsOne = ClippingFlagsY(yPilotOne, clipBox_);
205 yClipFlagsTwo = ClippingFlagsY(yPilotTwo, clipBox_);
206 LineClipY(rasterLine, clipBox_.GetLeft(), y1, clipBox_.GetLeft(), yPilotOne,
207 clipFlagsMoveToPoint, yClipFlagsOne);
208 LineClipY(rasterLine, clipBox_.GetLeft(), yPilotOne, clipBox_.GetRight(), yPilotTwo,
209 yClipFlagsOne, yClipFlagsTwo);
210 LineClipY(rasterLine, clipBox_.GetRight(), yPilotTwo, clipBox_.GetRight(), y2,
211 yClipFlagsTwo, cFlagsLineToPoint);
212 break;
213 /**
214 * indicate x1 < clip.x1 && x2 < clip.x1
215 */
216 case 0x0c:
217 LineClipY(rasterLine, clipBox_.GetLeft(), y1, clipBox_.GetLeft(), y2,
218 clipFlagsMoveToPoint, cFlagsLineToPoint);
219 break;
220 }
221 clippingFlags_ = cFlagsLineToPoint;
222 } else {
223 rasterLine.LineOperate(RasterDepictInt::GetXCoordinateValue(x1_),
224 RasterDepictInt::GetYCoordinateValue(y1_),
225 RasterDepictInt::GetXCoordinateValue(x2),
226 RasterDepictInt::GetYCoordinateValue(y2));
227 }
228 x1_ = x2;
229 y1_ = y2;
230 }
231 } // namespace OHOS
232