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 23namespace OHOS { 24void 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 82void 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 97void 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 140void 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 178void 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 200void 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 262void 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 299void 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 369void 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 452void 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 467void 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 536void 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 603void 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 639void 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