1 /*
2 * Copyright (c) 2020-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 #include "draw/draw_rect.h"
17 #include "draw/draw_utils.h"
18 #include "engines/gfx/gfx_engine_manager.h"
19 #include "gfx_utils/graphic_log.h"
20 #include "gfx_utils/graphic_math.h"
21 #include "gfx_utils/style.h"
22
23 namespace OHOS {
Draw(BufferInfo & gfxDstBuffer,const Rect & rect,const Rect & dirtyRect,const Style & style,OpacityType opaScale)24 void DrawRect::Draw(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& dirtyRect,
25 const Style& style, OpacityType opaScale)
26 {
27 if ((rect.GetWidth() <= 0) || (rect.GetHeight() <= 0)) {
28 GRAPHIC_LOGD("DrawRect::Draw width or height is zero\n");
29 return;
30 }
31
32 /**
33 * no border
34 * radius = 0 (1/4)
35 * radius > 0 (2/4)
36 * rect width > rect height
37 * radius >= rect height / 2
38 * radius < rect height / 2
39 * rect width <= rect height
40 * radius >= rect width / 2
41 * radius < rect width / 2
42 * have border
43 * radius = 0 (3/4)
44 * radius > 0 (4/4)
45 * radius < border width (4.1/4)
46 * radius = border width (4.2/4)
47 * radius > border width (4.3/4)
48 * rect width <= rect height
49 * radius >= border width + rect height / 2
50 * radius < border width + rect height / 2
51 * rect width > rect height
52 * radius >= border width + rect height / 2
53 * radius < border width + rect height / 2
54 */
55 if (style.borderWidth_ == 0) {
56 if (style.borderRadius_ == 0) {
57 /* no border no radius (1/4) */
58 OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_);
59 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, rect, dirtyRect, style.bgColor_, opa);
60 return;
61 } else {
62 /* [2/4] no border with radius (2/4) */
63 DrawRectRadiusWithoutBorder(gfxDstBuffer, rect, dirtyRect, style, opaScale);
64 }
65 } else {
66 if (style.borderRadius_ == 0) {
67 /* [3/4] border without radius (3/4) */
68 DrawRectBorderWithoutRadius(gfxDstBuffer, rect, dirtyRect, style, opaScale);
69 } else if (style.borderRadius_ < style.borderWidth_) {
70 /* [4.1/4] radius < border width */
71 DrawRectRadiusSmallThanBorder(gfxDstBuffer, rect, dirtyRect, style, opaScale);
72 } else if (style.borderRadius_ == style.borderWidth_) {
73 /* [4.2/4] radius = border width */
74 DrawRectRadiusEqualBorder(gfxDstBuffer, rect, dirtyRect, style, opaScale);
75 } else {
76 /* [4.3/4] radius >= border width + rect height_or_width / 2 */
77 DrawRectRadiusBiggerThanBorder(gfxDstBuffer, rect, dirtyRect, style, opaScale);
78 }
79 }
80 }
81
DrawRectRadiusWithoutBorder(BufferInfo & gfxDstBuffer,const Rect & rect,const Rect & dirtyRect,const Style & style,OpacityType opaScale)82 void DrawRect::DrawRectRadiusWithoutBorder(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& dirtyRect,
83 const Style& style, OpacityType opaScale)
84 {
85 // 2 : half
86 if ((rect.GetWidth() > rect.GetHeight()) && (style.borderRadius_ >= rect.GetHeight() / 2)) {
87 DrawRectRadiusWithoutBorderCon1(gfxDstBuffer, rect, dirtyRect, style, opaScale);
88 } else if ((rect.GetWidth() < rect.GetHeight()) && (style.borderRadius_ >= rect.GetWidth() / 2)) {
89 DrawRectRadiusWithoutBorderCon2(gfxDstBuffer, rect, dirtyRect, style, opaScale);
90 } else if ((rect.GetWidth() == rect.GetHeight()) && (style.borderRadius_ >= rect.GetWidth() / 2)) {
91 DrawRectRadiusWithoutBorderCon3(gfxDstBuffer, rect, dirtyRect, style, opaScale);
92 } else {
93 DrawRectRadiusWithoutBorderCon4(gfxDstBuffer, rect, dirtyRect, style, opaScale);
94 }
95 }
96
DrawRectRadiusWithoutBorderCon1(BufferInfo & gfxDstBuffer,const Rect & rect,const Rect & dirtyRect,const Style & style,OpacityType opaScale)97 void DrawRect::DrawRectRadiusWithoutBorderCon1(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& dirtyRect,
98 const Style& style, OpacityType opaScale)
99 {
100 int16_t radius = rect.GetHeight() / 2;
101 int16_t col2X = rect.GetLeft() + radius - 1;
102 int16_t col3X = rect.GetRight() - radius + 1;
103
104 int16_t row1Y = rect.GetTop();
105 int16_t row2Y = rect.GetTop() + radius - 1;
106 int16_t row3Y = rect.GetBottom();
107
108 Style arcStyle = style;
109 arcStyle.lineWidth_ = radius;
110 arcStyle.lineColor_ = style.bgColor_;
111 arcStyle.lineOpa_ = style.bgOpa_;
112 // draw left sector
113 ArcInfo arcInfo;
114 arcInfo.center = {col2X, row2Y};
115 arcInfo.radius = radius;
116 arcInfo.startAngle = SEMICIRCLE_IN_DEGREE;
117 arcInfo.endAngle = CIRCLE_IN_DEGREE;
118 arcInfo.imgPos = {0, 0};
119 arcInfo.imgSrc = nullptr;
120 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
121
122 // draw right sector
123 arcInfo.center = {col3X, row2Y};
124 arcInfo.startAngle = 0;
125 arcInfo.endAngle = SEMICIRCLE_IN_DEGREE;
126 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
127
128 // draw top rectangle
129 Rect topRect(col2X, row1Y, col3X - 1, row2Y - 1);
130 OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_);
131 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, topRect, dirtyRect, style.bgColor_, opa);
132
133 // draw bottom rectangle
134 Rect bottomRect(col2X + 1, row2Y, col3X - 1, row3Y);
135 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, bottomRect, dirtyRect, style.bgColor_, opa);
136 }
137
DrawRectRadiusWithoutBorderCon2(BufferInfo & gfxDstBuffer,const Rect & rect,const Rect & dirtyRect,const Style & style,OpacityType opaScale)138 void DrawRect::DrawRectRadiusWithoutBorderCon2(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& dirtyRect,
139 const Style& style, OpacityType opaScale)
140 {
141 int16_t radius = rect.GetWidth() / 2;
142 int16_t col1X = rect.GetLeft();
143 int16_t col2X = rect.GetLeft() + radius - 1;
144 int16_t col3X = rect.GetRight();
145
146 int16_t row2Y = rect.GetTop() + radius - 1;
147 int16_t row3Y = rect.GetBottom() - radius + 1;
148
149 Style arcStyle = style;
150 arcStyle.lineWidth_ = radius;
151 arcStyle.lineColor_ = style.bgColor_;
152 arcStyle.lineOpa_ = style.bgOpa_;
153 // draw top sector
154 ArcInfo arcInfo;
155 arcInfo.center = {col2X, row2Y};
156 arcInfo.startAngle = THREE_QUARTER_IN_DEGREE;
157 arcInfo.endAngle = QUARTER_IN_DEGREE;
158 arcInfo.radius = radius;
159 arcInfo.imgPos = {0, 0};
160 arcInfo.imgSrc = nullptr;
161 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
162
163 // draw bottom sector
164 arcInfo.center = {col2X, row3Y};
165 arcInfo.startAngle = QUARTER_IN_DEGREE;
166 arcInfo.endAngle = THREE_QUARTER_IN_DEGREE;
167 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
168
169 // draw middle rectangle
170 Rect middleRect(col1X, row2Y + 1, col3X, row3Y - 1);
171 OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_);
172 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, middleRect, dirtyRect, style.bgColor_, opa);
173 }
174
DrawRectRadiusWithoutBorderCon3(BufferInfo & gfxDstBuffer,const Rect & rect,const Rect & dirtyRect,const Style & style,OpacityType opaScale)175 void DrawRect::DrawRectRadiusWithoutBorderCon3(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& dirtyRect,
176 const Style& style, OpacityType opaScale)
177 {
178 int16_t radius = rect.GetWidth() / 2;
179 int16_t col1X = rect.GetLeft() + radius - 1;
180 int16_t row1Y = rect.GetTop() + radius - 1;
181
182 Style arcStyle = style;
183 arcStyle.lineWidth_ = radius;
184 arcStyle.lineColor_ = style.bgColor_;
185 arcStyle.lineOpa_ = style.bgOpa_;
186 // draw circle
187 ArcInfo arcInfo;
188 arcInfo.center = {col1X, row1Y};
189 arcInfo.startAngle = 0;
190 arcInfo.endAngle = CIRCLE_IN_DEGREE;
191 arcInfo.radius = radius;
192 arcInfo.imgPos = {0, 0};
193 arcInfo.imgSrc = nullptr;
194 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
195 }
196
DrawRectRadiusWithoutBorderCon4(BufferInfo & gfxDstBuffer,const Rect & rect,const Rect & dirtyRect,const Style & style,OpacityType opaScale)197 void DrawRect::DrawRectRadiusWithoutBorderCon4(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& dirtyRect,
198 const Style& style, OpacityType opaScale)
199 {
200 int16_t radius = style.borderRadius_;
201 int16_t col1X = rect.GetLeft();
202 int16_t col2X = rect.GetLeft() + radius - 1;
203 int16_t col3X = rect.GetRight() - radius + 1;
204 int16_t col4X = rect.GetRight();
205
206 int16_t row1Y = rect.GetTop();
207 int16_t row2Y = rect.GetTop() + radius - 1;
208 int16_t row3Y = rect.GetBottom() - radius + 1;
209 int16_t row4Y = rect.GetBottom();
210
211 OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_);
212 // draw top rectangle
213 Rect topRect(col2X, row1Y, col3X - 1, row2Y);
214 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, topRect, dirtyRect, style.bgColor_, opa);
215
216 // draw middle rectangle
217 Rect middleRect(col1X, row2Y + 1, col4X, row3Y - 1);
218 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, middleRect, dirtyRect, style.bgColor_, opa);
219
220 // draw bottom rectangle
221 Rect bottomRect(col2X + 1, row3Y, col3X - 1, row4Y);
222 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, bottomRect, dirtyRect, style.bgColor_, opa);
223
224 Style arcStyle = style;
225 arcStyle.lineWidth_ = radius;
226 arcStyle.lineColor_ = style.bgColor_;
227 arcStyle.lineOpa_ = style.bgOpa_;
228 // top left sector
229 ArcInfo arcInfo;
230 arcInfo.center = {col2X, row2Y};
231 arcInfo.startAngle = THREE_QUARTER_IN_DEGREE;
232 arcInfo.endAngle = CIRCLE_IN_DEGREE;
233 arcInfo.radius = radius;
234 arcInfo.imgPos = {0, 0};
235 arcInfo.imgSrc = nullptr;
236 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
237
238 // top right sector
239 arcInfo.center = {col3X, row2Y};
240 arcInfo.startAngle = 0;
241 arcInfo.endAngle = QUARTER_IN_DEGREE;
242 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
243
244 // bottom left sector
245 arcInfo.center = {col2X, row3Y};
246 arcInfo.startAngle = SEMICIRCLE_IN_DEGREE;
247 arcInfo.endAngle = THREE_QUARTER_IN_DEGREE;
248 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
249
250 // bottom right sector
251 arcInfo.center = {col3X, row3Y};
252 arcInfo.startAngle = QUARTER_IN_DEGREE;
253 arcInfo.endAngle = SEMICIRCLE_IN_DEGREE;
254 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
255 }
256
DrawRectBorderWithoutRadius(BufferInfo & gfxDstBuffer,const Rect & rect,const Rect & dirtyRect,const Style & style,OpacityType opaScale)257 void DrawRect::DrawRectBorderWithoutRadius(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& dirtyRect,
258 const Style& style, OpacityType opaScale)
259 {
260 int16_t col1X = rect.GetLeft();
261 int16_t col2X = rect.GetLeft() + style.borderWidth_ - 1;
262 int16_t col3X = rect.GetRight() - style.borderWidth_ + 1;
263 int16_t col4X = rect.GetRight();
264
265 int16_t row1Y = rect.GetTop();
266 int16_t row2Y = rect.GetTop() + style.borderWidth_ - 1;
267 int16_t row3Y = rect.GetBottom() - style.borderWidth_ + 1;
268 int16_t row4Y = rect.GetBottom();
269
270 OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.borderOpa_);
271 // draw top border
272 Rect topRect(col1X, row1Y, col4X, row2Y);
273 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, topRect, dirtyRect, style.borderColor_, opa);
274
275 // draw left border
276 Rect leftRect(col1X, row2Y + 1, col2X, row3Y - 1);
277 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, leftRect, dirtyRect, style.borderColor_, opa);
278
279 OpacityType opaBg = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_);
280 // draw middle rectangle
281 Rect middleRect(col2X + 1, row2Y + 1, col3X - 1, row3Y - 1);
282 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, middleRect, dirtyRect, style.bgColor_, opaBg);
283
284 // draw right border
285 Rect rightRect(col3X, row2Y + 1, col4X, row3Y - 1);
286 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, rightRect, dirtyRect, style.borderColor_, opa);
287
288 // draw bottom border
289 Rect bottomRect(col1X, row3Y, col4X, row4Y);
290 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, bottomRect, dirtyRect, style.borderColor_, opa);
291 }
292
DrawRectRadiusEqualBorder(BufferInfo & gfxDstBuffer,const Rect & rect,const Rect & dirtyRect,const Style & style,OpacityType opaScale)293 void DrawRect::DrawRectRadiusEqualBorder(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& dirtyRect,
294 const Style& style, OpacityType opaScale)
295 {
296 int16_t col1X = rect.GetLeft();
297 int16_t col2X = rect.GetLeft() + style.borderRadius_ - 1;
298 int16_t col3X = rect.GetRight() - style.borderRadius_ + 1;
299 int16_t col4X = rect.GetRight();
300
301 int16_t row1Y = rect.GetTop();
302 int16_t row2Y = rect.GetTop() + style.borderRadius_ - 1;
303 int16_t row3Y = rect.GetBottom() - style.borderRadius_ + 1;
304 int16_t row4Y = rect.GetBottom();
305
306 Style arcStyle = style;
307 arcStyle.lineWidth_ = style.borderWidth_;
308 arcStyle.lineColor_ = style.borderColor_;
309 arcStyle.lineOpa_ = style.borderOpa_;
310 // draw top left sector in border
311 ArcInfo arcInfo;
312 arcInfo.center = {col2X, row2Y};
313 arcInfo.startAngle = THREE_QUARTER_IN_DEGREE;
314 arcInfo.endAngle = CIRCLE_IN_DEGREE;
315 arcInfo.radius = style.borderRadius_;
316 arcInfo.imgPos = {0, 0};
317 arcInfo.imgSrc = nullptr;
318 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
319
320 // draw top right sector in border
321 arcInfo.center = {col3X, row2Y};
322 arcInfo.startAngle = 0;
323 arcInfo.endAngle = QUARTER_IN_DEGREE;
324 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
325
326 // draw bottom left sector in border
327 arcInfo.center = {col2X, row3Y};
328 arcInfo.startAngle = SEMICIRCLE_IN_DEGREE;
329 arcInfo.endAngle = THREE_QUARTER_IN_DEGREE;
330 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
331
332 // draw bottom right sector in border
333 arcInfo.center = {col3X, row3Y};
334 arcInfo.startAngle = QUARTER_IN_DEGREE;
335 arcInfo.endAngle = SEMICIRCLE_IN_DEGREE;
336 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
337
338 OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.borderOpa_);
339 // draw top rectangle in border
340 Rect topRect(col2X, row1Y, col3X - 1, row2Y);
341 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, topRect, dirtyRect, style.borderColor_, opa);
342
343 // draw left rectangle in border
344 Rect leftRect(col1X, row2Y + 1, col2X, row3Y - 1);
345 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, leftRect, dirtyRect, style.borderColor_, opa);
346
347 OpacityType opaBg = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_);
348 // draw middle rectangle
349 Rect middleRect(col2X + 1, row2Y + 1, col3X - 1, row3Y - 1);
350 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, middleRect, dirtyRect, style.bgColor_, opaBg);
351
352 // draw right rectangle in border
353 Rect rightRect(col3X, row2Y + 1, col4X, row3Y - 1);
354 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, rightRect, dirtyRect, style.borderColor_, opa);
355
356 // draw bottom rectangle in border
357 Rect bottomRect(col2X + 1, row3Y, col3X - 1, row4Y);
358 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, bottomRect, dirtyRect, style.borderColor_, opa);
359 }
360
DrawRectRadiusSmallThanBorder(BufferInfo & gfxDstBuffer,const Rect & rect,const Rect & dirtyRect,const Style & style,OpacityType opaScale)361 void DrawRect::DrawRectRadiusSmallThanBorder(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& dirtyRect,
362 const Style& style, OpacityType opaScale)
363 {
364 int16_t radiusCol1X = rect.GetLeft();
365 int16_t radiusCol2X = rect.GetLeft() + style.borderRadius_ - 1;
366 int16_t radiusCol3X = rect.GetRight() - style.borderRadius_ + 1;
367 int16_t radiusCol4X = rect.GetRight();
368
369 int16_t radiusRow1Y = rect.GetTop();
370 int16_t radiusRow2Y = rect.GetTop() + style.borderRadius_ - 1;
371 int16_t radiusRow3Y = rect.GetBottom() - style.borderRadius_ + 1;
372 int16_t radiusRow4Y = rect.GetBottom();
373
374 int16_t rectCol1X = radiusCol1X;
375 int16_t rectCol2X = rect.GetLeft() + style.borderWidth_ - 1;
376 int16_t rectCol3X = rect.GetRight() - style.borderWidth_ + 1;
377 int16_t rectCol4X = radiusCol4X;
378
379 int16_t rectRow1Y = radiusRow2Y;
380 int16_t rectRow2Y = rect.GetTop() + style.borderWidth_ - 1;
381 int16_t rectRow3Y = rect.GetBottom() - style.borderWidth_ + 1;
382
383 Style arcStyle = style;
384 arcStyle.lineWidth_ = style.borderWidth_;
385 arcStyle.lineColor_ = style.borderColor_;
386 arcStyle.lineOpa_ = style.borderOpa_;
387 // draw top left sector in border
388 ArcInfo arcInfo;
389 arcInfo.center = {radiusCol2X, radiusRow2Y};
390 arcInfo.startAngle = THREE_QUARTER_IN_DEGREE;
391 arcInfo.endAngle = CIRCLE_IN_DEGREE;
392 arcInfo.radius = style.borderRadius_;
393 arcInfo.imgPos = {0, 0};
394 arcInfo.imgSrc = nullptr;
395 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
396
397 // draw top right sector in border
398 arcInfo.center = {radiusCol3X, radiusRow2Y};
399 arcInfo.startAngle = 0;
400 arcInfo.endAngle = QUARTER_IN_DEGREE;
401 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
402
403 // draw bottom left sector in border
404 arcInfo.center = {radiusCol2X, radiusRow3Y};
405 arcInfo.startAngle = SEMICIRCLE_IN_DEGREE;
406 arcInfo.endAngle = THREE_QUARTER_IN_DEGREE;
407 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
408
409 // draw bottom right sector in border
410 arcInfo.center = {radiusCol3X, radiusRow3Y};
411 arcInfo.startAngle = QUARTER_IN_DEGREE;
412 arcInfo.endAngle = SEMICIRCLE_IN_DEGREE;
413 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
414
415 OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.borderOpa_);
416 // draw top rectangle in border
417 Rect topRect(radiusCol2X, radiusRow1Y, radiusCol3X - 1, radiusRow2Y);
418 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, topRect, dirtyRect, style.borderColor_, opa);
419 Rect topRect2(rectCol1X, rectRow1Y + 1, rectCol4X, rectRow2Y);
420 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, topRect2, dirtyRect, style.borderColor_, opa);
421
422 // draw left rectangle in border
423 Rect leftRect(rectCol1X, rectRow2Y + 1, rectCol2X, rectRow3Y - 1);
424 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, leftRect, dirtyRect, style.borderColor_, opa);
425
426 OpacityType opaBg = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_);
427 // draw middle rectangle
428 Rect middleRect(rectCol2X + 1, rectRow2Y + 1, rectCol3X - 1, rectRow3Y - 1);
429 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, middleRect, dirtyRect, style.bgColor_, opaBg);
430
431 // draw right rectangle in border
432 Rect rightRect(rectCol3X, rectRow2Y + 1, rectCol4X, rectRow3Y - 1);
433 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, rightRect, dirtyRect, style.borderColor_, opa);
434
435 // draw bottom rectangle in border
436 Rect bottomRect(radiusCol2X + 1, radiusRow3Y, radiusCol3X - 1, radiusRow4Y);
437 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, bottomRect, dirtyRect, style.borderColor_, opa);
438 Rect bottomRect2(rectCol1X, rectRow3Y, rectCol4X, radiusRow3Y - 1);
439 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, bottomRect2, dirtyRect, style.borderColor_, opa);
440 }
441
DrawRectRadiusBiggerThanBorder(BufferInfo & gfxDstBuffer,const Rect & rect,const Rect & dirtyRect,const Style & style,OpacityType opaScale)442 void DrawRect::DrawRectRadiusBiggerThanBorder(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& dirtyRect,
443 const Style& style, OpacityType opaScale)
444 {
445 // 2 : half
446 if ((rect.GetWidth() > rect.GetHeight()) && (style.borderRadius_ >= rect.GetHeight() / 2)) {
447 DrawRectRadiusBiggerThanBorderCon1(gfxDstBuffer, rect, dirtyRect, style, opaScale);
448 } else if ((rect.GetWidth() < rect.GetHeight()) && (style.borderRadius_ >= rect.GetWidth() / 2)) {
449 DrawRectRadiusBiggerThanBorderCon2(gfxDstBuffer, rect, dirtyRect, style, opaScale);
450 } else if ((rect.GetWidth() == rect.GetHeight()) && (style.borderRadius_ >= rect.GetWidth() / 2)) {
451 DrawRectRadiusBiggerThanBorderCon3(gfxDstBuffer, rect, dirtyRect, style, opaScale);
452 } else {
453 DrawRectRadiusBiggerThanBorderCon4(gfxDstBuffer, rect, dirtyRect, style, opaScale);
454 }
455 }
456
DrawRectRadiusBiggerThanBorderCon1(BufferInfo & gfxDstBuffer,const Rect & rect,const Rect & dirtyRect,const Style & style,OpacityType opaScale)457 void DrawRect::DrawRectRadiusBiggerThanBorderCon1(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& dirtyRect,
458 const Style& style, OpacityType opaScale)
459 {
460 int16_t radius = rect.GetHeight() / 2;
461 int16_t borderWidth = style.borderWidth_;
462 int16_t col2X = rect.GetLeft() + radius - 1;
463 int16_t col3X = rect.GetRight() - radius + 1;
464
465 int16_t row1Y = rect.GetTop();
466 int16_t row2Y = rect.GetTop() + borderWidth - 1;
467 int16_t row3Y = rect.GetTop() + radius - 1;
468 int16_t row4Y = rect.GetBottom() - borderWidth + 1;
469 int16_t row5Y = rect.GetBottom();
470
471 Style arcStyle = style;
472 arcStyle.lineWidth_ = borderWidth;
473 arcStyle.lineColor_ = style.borderColor_;
474 arcStyle.lineOpa_ = style.borderOpa_;
475 // draw left arc in border
476 ArcInfo arcInfo;
477 arcInfo.center = {col2X, row3Y};
478 arcInfo.startAngle = SEMICIRCLE_IN_DEGREE;
479 arcInfo.endAngle = CIRCLE_IN_DEGREE;
480 arcInfo.radius = radius;
481 arcInfo.imgPos = {0, 0};
482 arcInfo.imgSrc = nullptr;
483 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
484 // draw right arc in border
485 arcInfo.center = {col3X, row3Y};
486 arcInfo.startAngle = 0;
487 arcInfo.endAngle = SEMICIRCLE_IN_DEGREE;
488 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
489
490 radius = radius - borderWidth;
491 arcStyle.lineWidth_ = radius;
492 arcStyle.lineColor_ = style.bgColor_;
493 arcStyle.lineOpa_ = style.bgOpa_;
494
495 // draw left sector in rectangle
496 arcInfo.center = {col2X, row3Y};
497 arcInfo.startAngle = SEMICIRCLE_IN_DEGREE;
498 arcInfo.endAngle = CIRCLE_IN_DEGREE;
499 arcInfo.radius = radius;
500 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
501 // draw right sector in rectangle
502 arcInfo.center = {col3X, row3Y};
503 arcInfo.startAngle = 0;
504 arcInfo.endAngle = SEMICIRCLE_IN_DEGREE;
505 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
506
507 OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.borderOpa_);
508 // top rectangle in border
509 Rect topBorderRect(col2X, row1Y, col3X - 1, row2Y);
510 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, topBorderRect, dirtyRect, style.borderColor_, opa);
511 OpacityType opaBg = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_);
512 // middle rectangle inner
513 Rect middleInnerRect(col2X, row2Y + 1, col3X - 1, row3Y);
514 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, middleInnerRect, dirtyRect, style.bgColor_, opaBg);
515 Rect middleInnerRect2(col2X + 1, row3Y + 1, col3X - 1, row4Y - 1);
516 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, middleInnerRect2, dirtyRect, style.bgColor_, opaBg);
517
518 // bottom rectangle in border
519 Rect bottomBorderRect(col2X + 1, row4Y, col3X - 1, row5Y);
520 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, bottomBorderRect, dirtyRect, style.borderColor_, opa);
521 }
522
DrawRectRadiusBiggerThanBorderCon2(BufferInfo & gfxDstBuffer,const Rect & rect,const Rect & dirtyRect,const Style & style,OpacityType opaScale)523 void DrawRect::DrawRectRadiusBiggerThanBorderCon2(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& dirtyRect,
524 const Style& style, OpacityType opaScale)
525 {
526 int16_t radius = rect.GetWidth() / 2;
527 int16_t borderWidth = style.borderWidth_;
528 int16_t col1X = rect.GetLeft();
529 int16_t col2X = rect.GetLeft() + borderWidth - 1;
530 int16_t col3X = rect.GetLeft() + radius - 1;
531 int16_t col4X = rect.GetRight() - borderWidth + 1;
532 int16_t col5X = rect.GetRight();
533
534 int16_t row2Y = rect.GetTop() + radius - 1;
535 int16_t row3Y = rect.GetBottom() - radius + 1;
536
537 Style arcStyle = style;
538 arcStyle.lineWidth_ = borderWidth;
539 arcStyle.lineColor_ = style.borderColor_;
540 arcStyle.lineOpa_ = style.borderOpa_;
541 // draw top arc in border
542 ArcInfo arcInfo;
543 arcInfo.center = {col3X, row2Y};
544 arcInfo.startAngle = THREE_QUARTER_IN_DEGREE;
545 arcInfo.endAngle = QUARTER_IN_DEGREE;
546 arcInfo.radius = radius;
547 arcInfo.imgPos = {0, 0};
548 arcInfo.imgSrc = nullptr;
549 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
550 // draw bottom arc in border
551 arcInfo.center = {col3X, row3Y};
552 arcInfo.startAngle = QUARTER_IN_DEGREE;
553 arcInfo.endAngle = THREE_QUARTER_IN_DEGREE;
554 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
555
556 radius = radius - borderWidth;
557 arcStyle.lineWidth_ = radius;
558 arcStyle.lineColor_ = style.bgColor_;
559 arcStyle.lineOpa_ = style.bgOpa_;
560
561 // draw top sector in rectangle
562 arcInfo.center = {col3X, row2Y};
563 arcInfo.startAngle = THREE_QUARTER_IN_DEGREE;
564 arcInfo.endAngle = QUARTER_IN_DEGREE;
565 arcInfo.radius = radius;
566 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
567 // draw bottom sector in rectangle
568 arcInfo.center = {col3X, row3Y};
569 arcInfo.startAngle = QUARTER_IN_DEGREE;
570 arcInfo.endAngle = THREE_QUARTER_IN_DEGREE;
571 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
572
573 OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.borderOpa_);
574 // left rectangle in border
575 Rect topBorderRect(col1X, row2Y + 1, col2X, row3Y - 1);
576 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, topBorderRect, dirtyRect, style.borderColor_, opa);
577
578 OpacityType opaBg = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_);
579 // middle rectangle inner
580 Rect middleInnerRect(col2X + 1, row2Y + 1, col4X - 1, row3Y - 1);
581 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, middleInnerRect, dirtyRect, style.bgColor_, opaBg);
582
583 // right rectangle in border
584 Rect bottomBorderRect(col4X, row2Y + 1, col5X, row3Y - 1);
585 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, bottomBorderRect, dirtyRect, style.borderColor_, opa);
586 }
587
DrawRectRadiusBiggerThanBorderCon3(BufferInfo & gfxDstBuffer,const Rect & rect,const Rect & dirtyRect,const Style & style,OpacityType opaScale)588 void DrawRect::DrawRectRadiusBiggerThanBorderCon3(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& dirtyRect,
589 const Style& style, OpacityType opaScale)
590 {
591 int16_t radius = rect.GetWidth() / 2;
592 int16_t borderWidth = style.borderWidth_;
593 int16_t col2X = rect.GetLeft() + radius - 1;
594 int16_t row2Y = rect.GetTop() + radius - 1;
595
596 Style arcStyle = style;
597 arcStyle.lineWidth_ = borderWidth;
598 arcStyle.lineColor_ = style.borderColor_;
599 arcStyle.lineOpa_ = style.borderOpa_;
600 // draw circle in border
601 ArcInfo arcInfo;
602 arcInfo.center = {col2X, row2Y};
603 arcInfo.startAngle = 0;
604 arcInfo.endAngle = CIRCLE_IN_DEGREE;
605 arcInfo.radius = radius;
606 arcInfo.imgPos = {0, 0};
607 arcInfo.imgSrc = nullptr;
608 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
609
610 radius = radius - borderWidth;
611 arcStyle.lineWidth_ = radius;
612 arcStyle.lineColor_ = style.bgColor_;
613 arcStyle.lineOpa_ = style.bgOpa_;
614
615 // draw circle in rectangle
616 arcInfo.center = {col2X, row2Y};
617 arcInfo.startAngle = 0;
618 arcInfo.endAngle = CIRCLE_IN_DEGREE;
619 arcInfo.radius = radius;
620 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
621 }
622
DrawRectRadiusBiggerThanBorderCon4(BufferInfo & gfxDstBuffer,const Rect & rect,const Rect & dirtyRect,const Style & style,OpacityType opaScale)623 void DrawRect::DrawRectRadiusBiggerThanBorderCon4(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& dirtyRect,
624 const Style& style, OpacityType opaScale)
625 {
626 int16_t radius = style.borderRadius_;
627 int16_t borderWidth = style.borderWidth_;
628 int16_t col1X = rect.GetLeft();
629 int16_t col2X = rect.GetLeft() + borderWidth - 1;
630 int16_t col3X = rect.GetLeft() + radius - 1;
631 int16_t col4X = rect.GetRight() - radius + 1;
632 int16_t col5X = rect.GetRight() - borderWidth + 1;
633 int16_t col6X = rect.GetRight();
634
635 int16_t row1Y = rect.GetTop();
636 int16_t row2Y = rect.GetTop() + borderWidth - 1;
637 int16_t row3Y = rect.GetTop() + radius - 1;
638 int16_t row4Y = rect.GetBottom() - radius + 1;
639 int16_t row5Y = rect.GetBottom() - borderWidth + 1;
640 int16_t row6Y = rect.GetBottom();
641
642 Style arcStyle = style;
643 arcStyle.lineWidth_ = borderWidth;
644 arcStyle.lineColor_ = style.borderColor_;
645 arcStyle.lineOpa_ = style.borderOpa_;
646
647 // draw top left arc in border
648 ArcInfo arcInfo;
649 arcInfo.center = {col3X, row3Y};
650 arcInfo.startAngle = THREE_QUARTER_IN_DEGREE;
651 arcInfo.endAngle = CIRCLE_IN_DEGREE;
652 arcInfo.radius = radius;
653 arcInfo.imgPos = {0, 0};
654 arcInfo.imgSrc = nullptr;
655 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
656 // draw top right arc in border
657 arcInfo.center = {col4X, row3Y};
658 arcInfo.startAngle = 0;
659 arcInfo.endAngle = QUARTER_IN_DEGREE;
660 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
661 // draw bottom left arc in border
662 arcInfo.center = {col3X, row4Y};
663 arcInfo.startAngle = SEMICIRCLE_IN_DEGREE;
664 arcInfo.endAngle = THREE_QUARTER_IN_DEGREE;
665 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
666 // draw bottom right arc in border
667 arcInfo.center = {col4X, row4Y};
668 arcInfo.startAngle = QUARTER_IN_DEGREE;
669 arcInfo.endAngle = SEMICIRCLE_IN_DEGREE;
670 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
671
672 radius = radius - borderWidth;
673 arcStyle.lineWidth_ = radius;
674 arcStyle.lineColor_ = style.bgColor_;
675 arcStyle.lineOpa_ = style.bgOpa_;
676
677 // draw top left sector in rectangle
678 arcInfo.center = {col3X, row3Y};
679 arcInfo.startAngle = THREE_QUARTER_IN_DEGREE;
680 arcInfo.endAngle = CIRCLE_IN_DEGREE;
681 arcInfo.radius = radius;
682 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
683 // draw top right sector in rectangle
684 arcInfo.center = {col4X, row3Y};
685 arcInfo.startAngle = 0;
686 arcInfo.endAngle = QUARTER_IN_DEGREE;
687 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
688 // draw bottom left sector in rectangle
689 arcInfo.center = {col3X, row4Y};
690 arcInfo.startAngle = SEMICIRCLE_IN_DEGREE;
691 arcInfo.endAngle = THREE_QUARTER_IN_DEGREE;
692 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
693 // draw bottom right sector in rectangle
694 arcInfo.center = {col4X, row4Y};
695 arcInfo.startAngle = QUARTER_IN_DEGREE;
696 arcInfo.endAngle = SEMICIRCLE_IN_DEGREE;
697 BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfo, dirtyRect, arcStyle, opaScale, CapType::CAP_NONE);
698
699 OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.borderOpa_);
700 // top rectangle in border
701 Rect topBorderRect(col3X, row1Y, col4X - 1, row2Y);
702 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, topBorderRect, dirtyRect, style.borderColor_, opa);
703
704 OpacityType opaBg = DrawUtils::GetMixOpacity(opaScale, style.bgOpa_);
705 // top rectangle inner
706 Rect topInnerRect(col3X, row2Y + 1, col4X - 1, row3Y);
707 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, topInnerRect, dirtyRect, style.bgColor_, opaBg);
708
709 // left rectangle in border
710 Rect leftBorderRect(col1X, row3Y + 1, col2X, row4Y - 1);
711 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, leftBorderRect, dirtyRect, style.borderColor_, opa);
712
713 // middle rectangle inner
714 Rect middleInnerRect(col2X + 1, row3Y + 1, col5X - 1, row4Y - 1);
715 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, middleInnerRect, dirtyRect, style.bgColor_, opaBg);
716
717 // right rectangle in border
718 Rect rightBorderRect(col5X, row3Y + 1, col6X, row4Y - 1);
719 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, rightBorderRect, dirtyRect, style.borderColor_, opa);
720
721 // bottom rectangle inner
722 Rect bottomInnerRect(col3X + 1, row4Y, col4X - 1, row5Y - 1);
723 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, bottomInnerRect, dirtyRect, style.bgColor_, opaBg);
724
725 // bottom rectangle in border
726 Rect bottomBorderRect(col3X + 1, row5Y, col4X - 1, row6Y);
727 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, bottomBorderRect, dirtyRect, style.borderColor_, opa);
728 }
729 } // namespace OHOS