• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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