• 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* 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