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