1a3e0fd82Sopenharmony_ci/* 2a3e0fd82Sopenharmony_ci * Copyright (c) 2020-2022 Huawei Device Co., Ltd. 3a3e0fd82Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4a3e0fd82Sopenharmony_ci * you may not use this file except in compliance with the License. 5a3e0fd82Sopenharmony_ci * You may obtain a copy of the License at 6a3e0fd82Sopenharmony_ci * 7a3e0fd82Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8a3e0fd82Sopenharmony_ci * 9a3e0fd82Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10a3e0fd82Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11a3e0fd82Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12a3e0fd82Sopenharmony_ci * See the License for the specific language governing permissions and 13a3e0fd82Sopenharmony_ci * limitations under the License. 14a3e0fd82Sopenharmony_ci */ 15a3e0fd82Sopenharmony_ci 16a3e0fd82Sopenharmony_ci#include "draw/draw_utils.h" 17a3e0fd82Sopenharmony_ci 18a3e0fd82Sopenharmony_ci#include "color_fill.h" 19a3e0fd82Sopenharmony_ci#include "draw/draw_triangle.h" 20a3e0fd82Sopenharmony_ci#include "engines/gfx/gfx_engine_manager.h" 21a3e0fd82Sopenharmony_ci#include "font/ui_font.h" 22a3e0fd82Sopenharmony_ci#include "gfx_utils/color.h" 23a3e0fd82Sopenharmony_ci#include "gfx_utils/graphic_log.h" 24a3e0fd82Sopenharmony_ci#include "gfx_utils/graphic_math.h" 25a3e0fd82Sopenharmony_ci#include "graphic_performance.h" 26a3e0fd82Sopenharmony_ci#include "securec.h" 27a3e0fd82Sopenharmony_ci#include "common/typed_text.h" 28a3e0fd82Sopenharmony_ci#ifdef ARM_NEON_OPT 29a3e0fd82Sopenharmony_ci#include "graphic_neon_pipeline.h" 30a3e0fd82Sopenharmony_ci#include "graphic_neon_utils.h" 31a3e0fd82Sopenharmony_ci#endif 32a3e0fd82Sopenharmony_ci 33a3e0fd82Sopenharmony_ci#if ENABLE_ARM_MATH 34a3e0fd82Sopenharmony_ci#include "arm_math.h" 35a3e0fd82Sopenharmony_ci#endif 36a3e0fd82Sopenharmony_ci 37a3e0fd82Sopenharmony_cinamespace OHOS { 38a3e0fd82Sopenharmony_ci// Preprocess operation for draw 39a3e0fd82Sopenharmony_ci#define DRAW_UTILS_PREPROCESS(gfxBufferInfo, opa) \ 40a3e0fd82Sopenharmony_ci if ((opa) == OPA_TRANSPARENT) { \ 41a3e0fd82Sopenharmony_ci return; \ 42a3e0fd82Sopenharmony_ci } \ 43a3e0fd82Sopenharmony_ci uint8_t* screenBuffer = static_cast<uint8_t*>(gfxBufferInfo.virAddr); \ 44a3e0fd82Sopenharmony_ci if (screenBuffer == nullptr) { \ 45a3e0fd82Sopenharmony_ci return; \ 46a3e0fd82Sopenharmony_ci } \ 47a3e0fd82Sopenharmony_ci ColorMode bufferMode = gfxBufferInfo.mode; \ 48a3e0fd82Sopenharmony_ci uint8_t bufferPxSize = GetByteSizeByColorMode(bufferMode); \ 49a3e0fd82Sopenharmony_ci uint16_t screenBufferWidth = gfxBufferInfo.width; 50a3e0fd82Sopenharmony_ci 51a3e0fd82Sopenharmony_cinamespace { 52a3e0fd82Sopenharmony_cistatic constexpr uint8_t OPACITY_STEP_A1 = 255; 53a3e0fd82Sopenharmony_cistatic constexpr uint8_t OPACITY_STEP_A2 = 85; 54a3e0fd82Sopenharmony_cistatic constexpr uint8_t OPACITY_STEP_A4 = 17; 55a3e0fd82Sopenharmony_ci} // namespace 56a3e0fd82Sopenharmony_ci 57a3e0fd82Sopenharmony_ciTriangleEdge::TriangleEdge(int16_t x1, int16_t y1, int16_t x2, int16_t y2) 58a3e0fd82Sopenharmony_ci{ 59a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 60a3e0fd82Sopenharmony_ci curX = FO_TRANS_INTEGER_TO_FIXED(x1); 61a3e0fd82Sopenharmony_ci curY = FO_TRANS_INTEGER_TO_FIXED(y1); 62a3e0fd82Sopenharmony_ci du = FO_TRANS_INTEGER_TO_FIXED(x2 - x1); 63a3e0fd82Sopenharmony_ci dv = FO_TRANS_INTEGER_TO_FIXED(y2 - y1); 64a3e0fd82Sopenharmony_ci#else 65a3e0fd82Sopenharmony_ci curX = static_cast<float>(x1); 66a3e0fd82Sopenharmony_ci curY = static_cast<float>(y1); 67a3e0fd82Sopenharmony_ci du = static_cast<float>(x2 - x1); 68a3e0fd82Sopenharmony_ci dv = static_cast<float>(y2 - y1); 69a3e0fd82Sopenharmony_ci#endif 70a3e0fd82Sopenharmony_ci} 71a3e0fd82Sopenharmony_ci 72a3e0fd82Sopenharmony_ciTriangleEdge::~TriangleEdge() {} 73a3e0fd82Sopenharmony_ci 74a3e0fd82Sopenharmony_ciDrawUtils* DrawUtils::GetInstance() 75a3e0fd82Sopenharmony_ci{ 76a3e0fd82Sopenharmony_ci static DrawUtils instance; 77a3e0fd82Sopenharmony_ci return &instance; 78a3e0fd82Sopenharmony_ci} 79a3e0fd82Sopenharmony_ci 80a3e0fd82Sopenharmony_civoid DrawUtils::DrawColorAreaBySides(BufferInfo& gfxDstBuffer, 81a3e0fd82Sopenharmony_ci const Rect& mask, 82a3e0fd82Sopenharmony_ci const ColorType& color, 83a3e0fd82Sopenharmony_ci OpacityType opa, 84a3e0fd82Sopenharmony_ci const EdgeSides& sides) const 85a3e0fd82Sopenharmony_ci{ 86a3e0fd82Sopenharmony_ci Rect area(sides.left, sides.top, sides.right, sides.bottom); 87a3e0fd82Sopenharmony_ci DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, area, mask, color, opa); 88a3e0fd82Sopenharmony_ci} 89a3e0fd82Sopenharmony_ci 90a3e0fd82Sopenharmony_civoid DrawUtils::DrawColorArea(BufferInfo& gfxDstBuffer, 91a3e0fd82Sopenharmony_ci const Rect& area, 92a3e0fd82Sopenharmony_ci const Rect& mask, 93a3e0fd82Sopenharmony_ci const ColorType& color, 94a3e0fd82Sopenharmony_ci OpacityType opa) const 95a3e0fd82Sopenharmony_ci{ 96a3e0fd82Sopenharmony_ci if (opa == OPA_TRANSPARENT) { 97a3e0fd82Sopenharmony_ci return; 98a3e0fd82Sopenharmony_ci } 99a3e0fd82Sopenharmony_ci 100a3e0fd82Sopenharmony_ci Rect maskedArea; 101a3e0fd82Sopenharmony_ci if (!maskedArea.Intersect(area, mask)) { 102a3e0fd82Sopenharmony_ci return; 103a3e0fd82Sopenharmony_ci } 104a3e0fd82Sopenharmony_ci 105a3e0fd82Sopenharmony_ci BaseGfxEngine::GetInstance()->Fill(gfxDstBuffer, maskedArea, color, opa); 106a3e0fd82Sopenharmony_ci} 107a3e0fd82Sopenharmony_ci 108a3e0fd82Sopenharmony_ciuint8_t DrawUtils::GetPxSizeByColorMode(uint8_t colorMode) 109a3e0fd82Sopenharmony_ci{ 110a3e0fd82Sopenharmony_ci switch (colorMode) { 111a3e0fd82Sopenharmony_ci case TSC6: 112a3e0fd82Sopenharmony_ci case TSC6A: 113a3e0fd82Sopenharmony_ci case ARGB8888: 114a3e0fd82Sopenharmony_ci case XRGB8888: 115a3e0fd82Sopenharmony_ci return 32; // 32: 32 bit 116a3e0fd82Sopenharmony_ci case RGB888: 117a3e0fd82Sopenharmony_ci return 24; // 24: 24 bit 118a3e0fd82Sopenharmony_ci case RGB565: 119a3e0fd82Sopenharmony_ci case ARGB1555: 120a3e0fd82Sopenharmony_ci case ARGB4444: 121a3e0fd82Sopenharmony_ci return 16; // 16: 16 bit 122a3e0fd82Sopenharmony_ci case L1: 123a3e0fd82Sopenharmony_ci case A1: 124a3e0fd82Sopenharmony_ci return 1; // 1: 1 bit 125a3e0fd82Sopenharmony_ci case L2: 126a3e0fd82Sopenharmony_ci case A2: 127a3e0fd82Sopenharmony_ci return 2; // 2: 2 bit 128a3e0fd82Sopenharmony_ci case L4: 129a3e0fd82Sopenharmony_ci case A4: 130a3e0fd82Sopenharmony_ci return 4; // 4: 4 bit 131a3e0fd82Sopenharmony_ci case L8: 132a3e0fd82Sopenharmony_ci case A8: 133a3e0fd82Sopenharmony_ci return 8; // 8: 8 bit 134a3e0fd82Sopenharmony_ci default: 135a3e0fd82Sopenharmony_ci return 0; 136a3e0fd82Sopenharmony_ci } 137a3e0fd82Sopenharmony_ci} 138a3e0fd82Sopenharmony_ci 139a3e0fd82Sopenharmony_ciuint8_t DrawUtils::GetByteSizeByColorMode(uint8_t colorMode) 140a3e0fd82Sopenharmony_ci{ 141a3e0fd82Sopenharmony_ci switch (colorMode) { 142a3e0fd82Sopenharmony_ci case ARGB8888: 143a3e0fd82Sopenharmony_ci case XRGB8888: 144a3e0fd82Sopenharmony_ci return 4; // 4: 4 Byte 145a3e0fd82Sopenharmony_ci case RGB888: 146a3e0fd82Sopenharmony_ci return 3; // 3: 3 Byte 147a3e0fd82Sopenharmony_ci case RGB565: 148a3e0fd82Sopenharmony_ci case ARGB1555: 149a3e0fd82Sopenharmony_ci case ARGB4444: 150a3e0fd82Sopenharmony_ci return 2; // 2: 2 Byte 151a3e0fd82Sopenharmony_ci default: 152a3e0fd82Sopenharmony_ci return 0; 153a3e0fd82Sopenharmony_ci } 154a3e0fd82Sopenharmony_ci} 155a3e0fd82Sopenharmony_ci 156a3e0fd82Sopenharmony_civoid DrawUtils::DrawPixel(BufferInfo& gfxDstBuffer, 157a3e0fd82Sopenharmony_ci int16_t x, 158a3e0fd82Sopenharmony_ci int16_t y, 159a3e0fd82Sopenharmony_ci const Rect& mask, 160a3e0fd82Sopenharmony_ci const ColorType& color, 161a3e0fd82Sopenharmony_ci OpacityType opa) const 162a3e0fd82Sopenharmony_ci{ 163a3e0fd82Sopenharmony_ci if ((x < mask.GetLeft()) || (x > mask.GetRight()) || (y < mask.GetTop()) || (y > mask.GetBottom())) { 164a3e0fd82Sopenharmony_ci return; 165a3e0fd82Sopenharmony_ci } 166a3e0fd82Sopenharmony_ci 167a3e0fd82Sopenharmony_ci DRAW_UTILS_PREPROCESS(gfxDstBuffer, opa); 168a3e0fd82Sopenharmony_ci 169a3e0fd82Sopenharmony_ci Color32 fillColor; 170a3e0fd82Sopenharmony_ci fillColor.full = Color::ColorTo32(color); 171a3e0fd82Sopenharmony_ci 172a3e0fd82Sopenharmony_ci screenBuffer += (y * screenBufferWidth + x) * bufferPxSize; 173a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &fillColor, ARGB8888, opa); 174a3e0fd82Sopenharmony_ci} 175a3e0fd82Sopenharmony_ci 176a3e0fd82Sopenharmony_civoid DrawUtils::DrawColorLetter(BufferInfo& gfxDstBuffer, 177a3e0fd82Sopenharmony_ci const LabelLetterInfo& letterInfo, 178a3e0fd82Sopenharmony_ci uint8_t* fontMap, 179a3e0fd82Sopenharmony_ci GlyphNode node, 180a3e0fd82Sopenharmony_ci int16_t lineHeight) const 181a3e0fd82Sopenharmony_ci{ 182a3e0fd82Sopenharmony_ci if (fontMap == nullptr) { 183a3e0fd82Sopenharmony_ci return; 184a3e0fd82Sopenharmony_ci } 185a3e0fd82Sopenharmony_ci UIFont* fontEngine = UIFont::GetInstance(); 186a3e0fd82Sopenharmony_ci uint16_t letterW = node.cols; 187a3e0fd82Sopenharmony_ci uint16_t letterH = node.rows; 188a3e0fd82Sopenharmony_ci int16_t posX; 189a3e0fd82Sopenharmony_ci int16_t posY; 190a3e0fd82Sopenharmony_ci if (letterInfo.baseLine) { 191a3e0fd82Sopenharmony_ci // 2:Half the size between lineHeight and node.rows of emoji 192a3e0fd82Sopenharmony_ci posY = letterInfo.pos.y + (lineHeight - letterH) / 2 + letterInfo.offsetY; 193a3e0fd82Sopenharmony_ci } else { 194a3e0fd82Sopenharmony_ci FontHeader head; 195a3e0fd82Sopenharmony_ci if (fontEngine->GetFontHeader(head, letterInfo.fontId, letterInfo.fontSize) != 0) { 196a3e0fd82Sopenharmony_ci return; 197a3e0fd82Sopenharmony_ci } 198a3e0fd82Sopenharmony_ci posY = letterInfo.pos.y + head.ascender - letterInfo.offsetY; 199a3e0fd82Sopenharmony_ci } 200a3e0fd82Sopenharmony_ci if (letterInfo.direct == TEXT_DIRECT_RTL) { 201a3e0fd82Sopenharmony_ci /* RTL */ 202a3e0fd82Sopenharmony_ci posX = letterInfo.pos.x- node.advance + letterInfo.offsetX; 203a3e0fd82Sopenharmony_ci } else { 204a3e0fd82Sopenharmony_ci /* LTR */ 205a3e0fd82Sopenharmony_ci posX = letterInfo.pos.x; 206a3e0fd82Sopenharmony_ci } 207a3e0fd82Sopenharmony_ci 208a3e0fd82Sopenharmony_ci uint16_t rowStart = (posY >= letterInfo.mask.GetTop()) ? 0 : (letterInfo.mask.GetTop() - posY); 209a3e0fd82Sopenharmony_ci uint16_t rowEnd = 210a3e0fd82Sopenharmony_ci (posY + letterH <= letterInfo.mask.GetBottom()) ? letterH : (letterInfo.mask.GetBottom() - posY + 1); 211a3e0fd82Sopenharmony_ci uint16_t colStart = (posX >= letterInfo.mask.GetLeft()) ? 0 : (letterInfo.mask.GetLeft() - posX); 212a3e0fd82Sopenharmony_ci uint16_t colEnd = 213a3e0fd82Sopenharmony_ci (posX + letterW <= letterInfo.mask.GetRight()) ? letterW : (letterInfo.mask.GetRight() - posX + 1); 214a3e0fd82Sopenharmony_ci 215a3e0fd82Sopenharmony_ci Rect srcRect(posX, posY, posX + letterW - 1, posY + letterH - 1); 216a3e0fd82Sopenharmony_ci Rect subRect(posX + colStart, posY + rowStart, colEnd - 1 + posX, rowEnd - 1 + posY); 217a3e0fd82Sopenharmony_ci 218a3e0fd82Sopenharmony_ci uint8_t pxSize = DrawUtils::GetPxSizeByColorMode(gfxDstBuffer.mode); 219a3e0fd82Sopenharmony_ci DrawImage(gfxDstBuffer, srcRect, letterInfo.mask, fontMap, letterInfo.opa, pxSize, ARGB8888); 220a3e0fd82Sopenharmony_ci} 221a3e0fd82Sopenharmony_ci 222a3e0fd82Sopenharmony_civoid DrawUtils::DrawNormalLetter(BufferInfo& gfxDstBuffer, 223a3e0fd82Sopenharmony_ci const LabelLetterInfo& letterInfo, 224a3e0fd82Sopenharmony_ci uint8_t* fontMap, 225a3e0fd82Sopenharmony_ci GlyphNode node, 226a3e0fd82Sopenharmony_ci uint8_t maxLetterSize) const 227a3e0fd82Sopenharmony_ci{ 228a3e0fd82Sopenharmony_ci if (fontMap == nullptr) { 229a3e0fd82Sopenharmony_ci return; 230a3e0fd82Sopenharmony_ci } 231a3e0fd82Sopenharmony_ci 232a3e0fd82Sopenharmony_ci UIFont* fontEngine = UIFont::GetInstance(); 233a3e0fd82Sopenharmony_ci uint16_t letterW = node.cols; 234a3e0fd82Sopenharmony_ci uint16_t letterH = node.rows; 235a3e0fd82Sopenharmony_ci int16_t posX; 236a3e0fd82Sopenharmony_ci int16_t posY; 237a3e0fd82Sopenharmony_ci 238a3e0fd82Sopenharmony_ci if (letterInfo.baseLine) { 239a3e0fd82Sopenharmony_ci posY = letterInfo.pos.y + maxLetterSize - node.top + letterInfo.offsetY; 240a3e0fd82Sopenharmony_ci } else { 241a3e0fd82Sopenharmony_ci FontHeader head; 242a3e0fd82Sopenharmony_ci if (fontEngine->GetFontHeader(head, letterInfo.fontId, letterInfo.fontSize) != 0) { 243a3e0fd82Sopenharmony_ci return; 244a3e0fd82Sopenharmony_ci } 245a3e0fd82Sopenharmony_ci posY = letterInfo.pos.y + head.ascender - node.top - letterInfo.offsetY; 246a3e0fd82Sopenharmony_ci } 247a3e0fd82Sopenharmony_ci if (letterInfo.direct == TEXT_DIRECT_RTL) { 248a3e0fd82Sopenharmony_ci /* RTL */ 249a3e0fd82Sopenharmony_ci posX = letterInfo.pos.x - node.advance + node.left + letterInfo.offsetX; 250a3e0fd82Sopenharmony_ci } else { 251a3e0fd82Sopenharmony_ci /* LTR */ 252a3e0fd82Sopenharmony_ci posX = letterInfo.pos.x + node.left + letterInfo.offsetX; 253a3e0fd82Sopenharmony_ci } 254a3e0fd82Sopenharmony_ci BaseGfxEngine* baseGfxEngine = BaseGfxEngine::GetInstance(); 255a3e0fd82Sopenharmony_ci if (letterInfo.haveLineBackgroundColor) { 256a3e0fd82Sopenharmony_ci Rect lineBackgroundRect(posX - node.left, letterInfo.mask.GetTop(), 257a3e0fd82Sopenharmony_ci posX + node.advance + letterInfo.letterSpace_ - node.left, 258a3e0fd82Sopenharmony_ci letterInfo.mask.GetBottom() - letterInfo.lineSpace_); 259a3e0fd82Sopenharmony_ci Style lineStyle; 260a3e0fd82Sopenharmony_ci lineStyle.bgColor_ = letterInfo.lineBackgroundColor; 261a3e0fd82Sopenharmony_ci baseGfxEngine->DrawRect(gfxDstBuffer, lineBackgroundRect, 262a3e0fd82Sopenharmony_ci lineBackgroundRect, lineStyle, lineStyle.bgColor_.alpha); 263a3e0fd82Sopenharmony_ci } 264a3e0fd82Sopenharmony_ci if (letterInfo.havebackgroundColor) { 265a3e0fd82Sopenharmony_ci Rect backgroundRect(posX, letterInfo.mask.GetTop(), posX + letterW + letterInfo.letterSpace_ - 1, 266a3e0fd82Sopenharmony_ci letterInfo.mask.GetBottom() - letterInfo.lineSpace_); 267a3e0fd82Sopenharmony_ci Style style; 268a3e0fd82Sopenharmony_ci style.bgColor_ = letterInfo.backgroundColor; 269a3e0fd82Sopenharmony_ci baseGfxEngine->DrawRect(gfxDstBuffer, backgroundRect, 270a3e0fd82Sopenharmony_ci backgroundRect, style, style.bgColor_.alpha); 271a3e0fd82Sopenharmony_ci } 272a3e0fd82Sopenharmony_ci 273a3e0fd82Sopenharmony_ci if ((posX + letterW < letterInfo.mask.GetLeft()) || (posX > letterInfo.mask.GetRight()) || 274a3e0fd82Sopenharmony_ci (posY + letterH < letterInfo.mask.GetTop()) || (posY > letterInfo.mask.GetBottom())) { 275a3e0fd82Sopenharmony_ci return; 276a3e0fd82Sopenharmony_ci } 277a3e0fd82Sopenharmony_ci 278a3e0fd82Sopenharmony_ci uint16_t rowStart = (posY >= letterInfo.mask.GetTop()) ? 0 : (letterInfo.mask.GetTop() - posY); 279a3e0fd82Sopenharmony_ci uint16_t rowEnd = 280a3e0fd82Sopenharmony_ci (posY + letterH <= letterInfo.mask.GetBottom()) ? letterH : (letterInfo.mask.GetBottom() - posY + 1); 281a3e0fd82Sopenharmony_ci uint16_t colStart = (posX >= letterInfo.mask.GetLeft()) ? 0 : (letterInfo.mask.GetLeft() - posX); 282a3e0fd82Sopenharmony_ci uint16_t colEnd = 283a3e0fd82Sopenharmony_ci (posX + letterW <= letterInfo.mask.GetRight()) ? letterW : (letterInfo.mask.GetRight() - posX + 1); 284a3e0fd82Sopenharmony_ci 285a3e0fd82Sopenharmony_ci Rect srcRect(posX, posY, posX + letterW - 1, posY + letterH - 1); 286a3e0fd82Sopenharmony_ci Rect subRect(posX + colStart, posY + rowStart, colEnd - 1 + posX, rowEnd - 1 + posY); 287a3e0fd82Sopenharmony_ci 288a3e0fd82Sopenharmony_ci uint8_t fontWeight = fontEngine->GetFontWeight(letterInfo.fontId); 289a3e0fd82Sopenharmony_ci baseGfxEngine->DrawLetter(gfxDstBuffer, fontMap, srcRect, subRect, 290a3e0fd82Sopenharmony_ci fontWeight, letterInfo.color, letterInfo.opa); 291a3e0fd82Sopenharmony_ci} 292a3e0fd82Sopenharmony_ci 293a3e0fd82Sopenharmony_civoid DrawUtils::DrawLetter(BufferInfo& gfxDstBuffer, 294a3e0fd82Sopenharmony_ci const uint8_t* fontMap, 295a3e0fd82Sopenharmony_ci const Rect& fontRect, 296a3e0fd82Sopenharmony_ci const Rect& subRect, 297a3e0fd82Sopenharmony_ci const uint8_t fontWeight, 298a3e0fd82Sopenharmony_ci const ColorType& color, 299a3e0fd82Sopenharmony_ci const OpacityType opa) const 300a3e0fd82Sopenharmony_ci{ 301a3e0fd82Sopenharmony_ci Color32 fillColor; 302a3e0fd82Sopenharmony_ci fillColor.full = Color::ColorTo32(color); 303a3e0fd82Sopenharmony_ci uint8_t opacityMask; 304a3e0fd82Sopenharmony_ci uint8_t opacityStep = 1; 305a3e0fd82Sopenharmony_ci switch (fontWeight) { 306a3e0fd82Sopenharmony_ci case FONT_WEIGHT_1: 307a3e0fd82Sopenharmony_ci opacityStep = OPACITY_STEP_A1; 308a3e0fd82Sopenharmony_ci opacityMask = 0x01; 309a3e0fd82Sopenharmony_ci break; 310a3e0fd82Sopenharmony_ci case FONT_WEIGHT_2: 311a3e0fd82Sopenharmony_ci opacityStep = OPACITY_STEP_A2; 312a3e0fd82Sopenharmony_ci opacityMask = 0x03; 313a3e0fd82Sopenharmony_ci break; 314a3e0fd82Sopenharmony_ci case FONT_WEIGHT_4: 315a3e0fd82Sopenharmony_ci opacityStep = OPACITY_STEP_A4; 316a3e0fd82Sopenharmony_ci opacityMask = 0x0F; 317a3e0fd82Sopenharmony_ci break; 318a3e0fd82Sopenharmony_ci case FONT_WEIGHT_8: 319a3e0fd82Sopenharmony_ci opacityMask = 0xFF; 320a3e0fd82Sopenharmony_ci break; 321a3e0fd82Sopenharmony_ci case FONT_WEIGHT_32: 322a3e0fd82Sopenharmony_ci opacityMask = 0xFF; 323a3e0fd82Sopenharmony_ci break; 324a3e0fd82Sopenharmony_ci default: 325a3e0fd82Sopenharmony_ci return; 326a3e0fd82Sopenharmony_ci } 327a3e0fd82Sopenharmony_ci 328a3e0fd82Sopenharmony_ci uint8_t letterWidthInByte = (fontRect.GetWidth() * fontWeight) >> SHIFT_3; 329a3e0fd82Sopenharmony_ci if ((fontRect.GetWidth() * fontWeight) & 0x7) { // 0x7 : less than 1 byte is counted as 1 byte 330a3e0fd82Sopenharmony_ci letterWidthInByte++; 331a3e0fd82Sopenharmony_ci } 332a3e0fd82Sopenharmony_ci int16_t rowStart = subRect.GetY() - fontRect.GetY(); 333a3e0fd82Sopenharmony_ci int16_t rowEnd = rowStart + subRect.GetHeight(); 334a3e0fd82Sopenharmony_ci int16_t colStart = subRect.GetX() - fontRect.GetX(); 335a3e0fd82Sopenharmony_ci int16_t colEnd = colStart + subRect.GetWidth(); 336a3e0fd82Sopenharmony_ci 337a3e0fd82Sopenharmony_ci DRAW_UTILS_PREPROCESS(gfxDstBuffer, opa); 338a3e0fd82Sopenharmony_ci screenBuffer += ((subRect.GetY() * screenBufferWidth) + subRect.GetX()) * bufferPxSize; 339a3e0fd82Sopenharmony_ci fontMap += (rowStart * letterWidthInByte) + ((colStart * fontWeight) >> SHIFT_3); 340a3e0fd82Sopenharmony_ci 341a3e0fd82Sopenharmony_ci uint8_t offsetInFont = (colStart * fontWeight) % FONT_WEIGHT_8; 342a3e0fd82Sopenharmony_ci int16_t temp = subRect.GetWidth() * fontWeight - FONT_WEIGHT_8 + offsetInFont; 343a3e0fd82Sopenharmony_ci if (temp < 0) { 344a3e0fd82Sopenharmony_ci temp = 0; 345a3e0fd82Sopenharmony_ci } 346a3e0fd82Sopenharmony_ci int16_t validWidthInByte = temp / FONT_WEIGHT_8 + 1; 347a3e0fd82Sopenharmony_ci if (temp % FONT_WEIGHT_8 != 0) { 348a3e0fd82Sopenharmony_ci validWidthInByte++; 349a3e0fd82Sopenharmony_ci } 350a3e0fd82Sopenharmony_ci for (int16_t i = rowStart; i < rowEnd; i++) { 351a3e0fd82Sopenharmony_ci int16_t col = colStart; 352a3e0fd82Sopenharmony_ci uint8_t tempOffset = offsetInFont; 353a3e0fd82Sopenharmony_ci uint8_t tempFontByte = (*fontMap++) >> offsetInFont; 354a3e0fd82Sopenharmony_ci while (col < colEnd) { 355a3e0fd82Sopenharmony_ci while ((tempOffset < FONT_WEIGHT_8) && (col < colEnd)) { 356a3e0fd82Sopenharmony_ci uint8_t validOpacity = tempFontByte & opacityMask; 357a3e0fd82Sopenharmony_ci if (validOpacity != 0) { 358a3e0fd82Sopenharmony_ci validOpacity *= opacityStep; 359a3e0fd82Sopenharmony_ci if (opa != OPA_OPAQUE) { 360a3e0fd82Sopenharmony_ci validOpacity = 361a3e0fd82Sopenharmony_ci static_cast<OpacityType>((static_cast<uint16_t>(validOpacity) * opa) >> FONT_WEIGHT_8); 362a3e0fd82Sopenharmony_ci } 363a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &fillColor, ARGB8888, validOpacity); 364a3e0fd82Sopenharmony_ci } 365a3e0fd82Sopenharmony_ci screenBuffer += bufferPxSize; 366a3e0fd82Sopenharmony_ci tempFontByte = tempFontByte >> fontWeight; 367a3e0fd82Sopenharmony_ci tempOffset += fontWeight; 368a3e0fd82Sopenharmony_ci col++; 369a3e0fd82Sopenharmony_ci } 370a3e0fd82Sopenharmony_ci tempOffset = 0; 371a3e0fd82Sopenharmony_ci tempFontByte = *(fontMap++); 372a3e0fd82Sopenharmony_ci } 373a3e0fd82Sopenharmony_ci fontMap += letterWidthInByte - validWidthInByte - 1; 374a3e0fd82Sopenharmony_ci screenBuffer += (screenBufferWidth - (colEnd - colStart)) * bufferPxSize; 375a3e0fd82Sopenharmony_ci } 376a3e0fd82Sopenharmony_ci} 377a3e0fd82Sopenharmony_ci 378a3e0fd82Sopenharmony_civoid DrawUtils::DrawImage(BufferInfo& gfxDstBuffer, 379a3e0fd82Sopenharmony_ci const Rect& area, 380a3e0fd82Sopenharmony_ci const Rect& mask, 381a3e0fd82Sopenharmony_ci const uint8_t* image, 382a3e0fd82Sopenharmony_ci OpacityType opa, 383a3e0fd82Sopenharmony_ci uint8_t pxBitSize, 384a3e0fd82Sopenharmony_ci ColorMode colorMode) const 385a3e0fd82Sopenharmony_ci{ 386a3e0fd82Sopenharmony_ci if (image == nullptr) { 387a3e0fd82Sopenharmony_ci return; 388a3e0fd82Sopenharmony_ci } 389a3e0fd82Sopenharmony_ci Rect maskedArea; 390a3e0fd82Sopenharmony_ci if (!maskedArea.Intersect(area, mask)) { 391a3e0fd82Sopenharmony_ci return; 392a3e0fd82Sopenharmony_ci } 393a3e0fd82Sopenharmony_ci int16_t mapWidth = area.GetWidth(); 394a3e0fd82Sopenharmony_ci int16_t imageX = maskedArea.GetLeft() - area.GetLeft(); 395a3e0fd82Sopenharmony_ci int16_t imageY = maskedArea.GetTop() - area.GetTop(); 396a3e0fd82Sopenharmony_ci uint32_t imageWidthInByte = (static_cast<uint32_t>(mapWidth) * pxBitSize) >> SHIFT_3; 397a3e0fd82Sopenharmony_ci if ((mapWidth * pxBitSize) & 0x7) { // 0x7 : less than 1 byte is counted as 1 byte 398a3e0fd82Sopenharmony_ci imageWidthInByte++; 399a3e0fd82Sopenharmony_ci } 400a3e0fd82Sopenharmony_ci 401a3e0fd82Sopenharmony_ci BufferInfo src; 402a3e0fd82Sopenharmony_ci src.rect = {imageX, imageY, static_cast<int16_t>(imageX + maskedArea.GetWidth() - 1), 403a3e0fd82Sopenharmony_ci static_cast<int16_t>(imageY + maskedArea.GetHeight() - 1)}; 404a3e0fd82Sopenharmony_ci 405a3e0fd82Sopenharmony_ci src.virAddr = static_cast<void*>(const_cast<uint8_t*>(image)); 406a3e0fd82Sopenharmony_ci src.stride = imageWidthInByte; 407a3e0fd82Sopenharmony_ci src.mode = colorMode; 408a3e0fd82Sopenharmony_ci src.color = 0; 409a3e0fd82Sopenharmony_ci 410a3e0fd82Sopenharmony_ci Point dstPos = {maskedArea.GetLeft(), maskedArea.GetTop()}; 411a3e0fd82Sopenharmony_ci BlendOption blendOption; 412a3e0fd82Sopenharmony_ci blendOption.opacity = opa; 413a3e0fd82Sopenharmony_ci blendOption.mode = BLEND_SRC_OVER; 414a3e0fd82Sopenharmony_ci BaseGfxEngine::GetInstance()->Blit(gfxDstBuffer, dstPos, src, maskedArea, blendOption); 415a3e0fd82Sopenharmony_ci} 416a3e0fd82Sopenharmony_ci 417a3e0fd82Sopenharmony_civoid DrawUtils::FillAreaWithSoftWare(BufferInfo& gfxDstBuffer, 418a3e0fd82Sopenharmony_ci const Rect& fillArea, 419a3e0fd82Sopenharmony_ci const ColorType& color, 420a3e0fd82Sopenharmony_ci const OpacityType& opa) const 421a3e0fd82Sopenharmony_ci{ 422a3e0fd82Sopenharmony_ci if (gfxDstBuffer.virAddr == nullptr) { 423a3e0fd82Sopenharmony_ci return; 424a3e0fd82Sopenharmony_ci } 425a3e0fd82Sopenharmony_ci ColorMode mode = gfxDstBuffer.mode; 426a3e0fd82Sopenharmony_ci uint8_t destByteSize = GetByteSizeByColorMode(mode); 427a3e0fd82Sopenharmony_ci int16_t destWidth = gfxDstBuffer.width; 428a3e0fd82Sopenharmony_ci int32_t halBufferDeltaByteLen = static_cast<int32_t>(destWidth) * destByteSize; 429a3e0fd82Sopenharmony_ci int16_t width = fillArea.GetWidth(); 430a3e0fd82Sopenharmony_ci int16_t height = fillArea.GetHeight(); 431a3e0fd82Sopenharmony_ci uint8_t* dest = static_cast<uint8_t*>(gfxDstBuffer.virAddr); 432a3e0fd82Sopenharmony_ci int32_t offset = static_cast<int32_t>(fillArea.GetTop()) * destWidth + fillArea.GetLeft(); 433a3e0fd82Sopenharmony_ci dest += offset * destByteSize; 434a3e0fd82Sopenharmony_ci 435a3e0fd82Sopenharmony_ci int32_t dstMaxSize = (gfxDstBuffer.width * gfxDstBuffer.height - offset) * destByteSize; 436a3e0fd82Sopenharmony_ci Color32 fillColor; 437a3e0fd82Sopenharmony_ci fillColor.full = Color::ColorTo32(color); 438a3e0fd82Sopenharmony_ci uint8_t* dstTmp = nullptr; 439a3e0fd82Sopenharmony_ci 440a3e0fd82Sopenharmony_ci if ((fillColor.alpha == OPA_TRANSPARENT) || (opa == OPA_TRANSPARENT)) { 441a3e0fd82Sopenharmony_ci return; 442a3e0fd82Sopenharmony_ci } 443a3e0fd82Sopenharmony_ci /* cover mode */ 444a3e0fd82Sopenharmony_ci if ((opa == OPA_OPAQUE) && (fillColor.alpha == OPA_OPAQUE)) { 445a3e0fd82Sopenharmony_ci for (int16_t col = 0; col < width; ++col) { 446a3e0fd82Sopenharmony_ci dstTmp = dest + (col * destByteSize); 447a3e0fd82Sopenharmony_ci COLOR_FILL_COVER(dstTmp, mode, fillColor.red, fillColor.green, fillColor.blue, ARGB8888); 448a3e0fd82Sopenharmony_ci } 449a3e0fd82Sopenharmony_ci uint8_t* memStart = dest; 450a3e0fd82Sopenharmony_ci int32_t memSize = static_cast<int32_t>(width) * destByteSize; 451a3e0fd82Sopenharmony_ci dest += halBufferDeltaByteLen; 452a3e0fd82Sopenharmony_ci dstMaxSize -= halBufferDeltaByteLen; 453a3e0fd82Sopenharmony_ci for (int16_t row = 1; row < height; ++row) { 454a3e0fd82Sopenharmony_ci#ifdef ARM_NEON_OPT 455a3e0fd82Sopenharmony_ci { 456a3e0fd82Sopenharmony_ci DEBUG_PERFORMANCE_TRACE("memcpy_neon"); 457a3e0fd82Sopenharmony_ci NeonMemcpy(dest, dstMaxSize, memStart, memSize); 458a3e0fd82Sopenharmony_ci } 459a3e0fd82Sopenharmony_ci#else 460a3e0fd82Sopenharmony_ci { 461a3e0fd82Sopenharmony_ci DEBUG_PERFORMANCE_TRACE("memcpy"); 462a3e0fd82Sopenharmony_ci if (memcpy_s(dest, dstMaxSize, memStart, memSize) != EOK) { 463a3e0fd82Sopenharmony_ci GRAPHIC_LOGE("DrawUtils::FillAreaWithSoftWare memcpy failed!\n"); 464a3e0fd82Sopenharmony_ci return; 465a3e0fd82Sopenharmony_ci } 466a3e0fd82Sopenharmony_ci } 467a3e0fd82Sopenharmony_ci#endif 468a3e0fd82Sopenharmony_ci dest += halBufferDeltaByteLen; 469a3e0fd82Sopenharmony_ci dstMaxSize -= halBufferDeltaByteLen; 470a3e0fd82Sopenharmony_ci } 471a3e0fd82Sopenharmony_ci } else { 472a3e0fd82Sopenharmony_ci#ifdef ARM_NEON_OPT 473a3e0fd82Sopenharmony_ci { 474a3e0fd82Sopenharmony_ci DEBUG_PERFORMANCE_TRACE("FillAreaWithSoftWare_neon"); 475a3e0fd82Sopenharmony_ci NeonBlendPipeLine pipeLine; 476a3e0fd82Sopenharmony_ci pipeLine.Construct(mode, ARGB8888, &fillColor, opa); 477a3e0fd82Sopenharmony_ci int16_t step = NEON_STEP_8 * GetByteSizeByColorMode(mode); 478a3e0fd82Sopenharmony_ci for (int16_t row = 0; row < height; ++row) { 479a3e0fd82Sopenharmony_ci uint8_t* buf = dest; 480a3e0fd82Sopenharmony_ci int16_t tmpWidth = width; 481a3e0fd82Sopenharmony_ci while (tmpWidth >= NEON_STEP_8) { 482a3e0fd82Sopenharmony_ci pipeLine.Invoke(buf); 483a3e0fd82Sopenharmony_ci buf += step; 484a3e0fd82Sopenharmony_ci tmpWidth -= NEON_STEP_8; 485a3e0fd82Sopenharmony_ci } 486a3e0fd82Sopenharmony_ci for (int16_t i = 0; i < tmpWidth; ++i) { 487a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(buf, mode, &fillColor, ARGB8888, opa); 488a3e0fd82Sopenharmony_ci buf += destByteSize; 489a3e0fd82Sopenharmony_ci } 490a3e0fd82Sopenharmony_ci dest += halBufferDeltaByteLen; 491a3e0fd82Sopenharmony_ci } 492a3e0fd82Sopenharmony_ci } 493a3e0fd82Sopenharmony_ci#else 494a3e0fd82Sopenharmony_ci { 495a3e0fd82Sopenharmony_ci DEBUG_PERFORMANCE_TRACE("FillAreaWithSoftWare"); 496a3e0fd82Sopenharmony_ci for (int16_t row = 0; row < height; row++) { 497a3e0fd82Sopenharmony_ci for (int16_t col = 0; col < width; col++) { 498a3e0fd82Sopenharmony_ci dstTmp = dest + (col * destByteSize); 499a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(dstTmp, mode, &fillColor, ARGB8888, opa); 500a3e0fd82Sopenharmony_ci } 501a3e0fd82Sopenharmony_ci dest += destWidth * destByteSize; 502a3e0fd82Sopenharmony_ci } 503a3e0fd82Sopenharmony_ci } 504a3e0fd82Sopenharmony_ci#endif 505a3e0fd82Sopenharmony_ci } 506a3e0fd82Sopenharmony_ci} 507a3e0fd82Sopenharmony_ci 508a3e0fd82Sopenharmony_ci#ifdef ARM_NEON_OPT 509a3e0fd82Sopenharmony_civoid DrawUtils::BlendLerpPix(uint8_t* color, uint8_t red, uint8_t green, uint8_t blue, 510a3e0fd82Sopenharmony_ci uint8_t alpha, uint8_t cover) 511a3e0fd82Sopenharmony_ci{ 512a3e0fd82Sopenharmony_ci NeonBlendPipeLine mNeonBlendPipeLine; 513a3e0fd82Sopenharmony_ci mNeonBlendPipeLine.NeonLerpARGB8888(color, red, green, blue, alpha, cover); 514a3e0fd82Sopenharmony_ci} 515a3e0fd82Sopenharmony_ci 516a3e0fd82Sopenharmony_civoid DrawUtils::BlendLerpPix(uint8_t* color, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) 517a3e0fd82Sopenharmony_ci{ 518a3e0fd82Sopenharmony_ci NeonBlendPipeLine mNeonBlendPipeLine; 519a3e0fd82Sopenharmony_ci mNeonBlendPipeLine.NeonLerpARGB8888(color, red, green, blue, alpha); 520a3e0fd82Sopenharmony_ci} 521a3e0fd82Sopenharmony_ci 522a3e0fd82Sopenharmony_civoid DrawUtils::BlendLerpPix(uint8_t* dstColors, uint8_t* srcColors, uint8_t srcCover) 523a3e0fd82Sopenharmony_ci{ 524a3e0fd82Sopenharmony_ci NeonBlendPipeLine mNeonBlendPipeLine; 525a3e0fd82Sopenharmony_ci mNeonBlendPipeLine.NeonLerpARGB8888(dstColors, srcColors, srcCover); 526a3e0fd82Sopenharmony_ci} 527a3e0fd82Sopenharmony_ci 528a3e0fd82Sopenharmony_civoid DrawUtils::BlendLerpPix(uint8_t* dstColors, uint8_t* srcColors, uint8_t* srcCovers) 529a3e0fd82Sopenharmony_ci{ 530a3e0fd82Sopenharmony_ci NeonBlendPipeLine mNeonBlendPipeLine; 531a3e0fd82Sopenharmony_ci mNeonBlendPipeLine.NeonLerpARGB8888(dstColors, srcColors, srcCovers); 532a3e0fd82Sopenharmony_ci} 533a3e0fd82Sopenharmony_ci 534a3e0fd82Sopenharmony_civoid DrawUtils::BlendLerpPix(uint8_t* color, uint8_t red, uint8_t green, uint8_t blue, 535a3e0fd82Sopenharmony_ci uint8_t alpha, uint8_t* covers) 536a3e0fd82Sopenharmony_ci{ 537a3e0fd82Sopenharmony_ci NeonBlendPipeLine mNeonBlendPipeLine; 538a3e0fd82Sopenharmony_ci mNeonBlendPipeLine.NeonLerpARGB8888(color, red, green, blue, alpha, covers); 539a3e0fd82Sopenharmony_ci} 540a3e0fd82Sopenharmony_ci 541a3e0fd82Sopenharmony_civoid DrawUtils::BlendPreLerpPix(uint8_t* color, uint8_t red, uint8_t green, uint8_t blue, 542a3e0fd82Sopenharmony_ci uint8_t alpha, uint8_t cover) 543a3e0fd82Sopenharmony_ci{ 544a3e0fd82Sopenharmony_ci NeonBlendPipeLine mNeonBlendPipeLine; 545a3e0fd82Sopenharmony_ci mNeonBlendPipeLine.NeonPrelerpARGB8888(color, red, green, blue, alpha, cover); 546a3e0fd82Sopenharmony_ci} 547a3e0fd82Sopenharmony_ci 548a3e0fd82Sopenharmony_civoid DrawUtils::BlendPreLerpPix(uint8_t* color, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) 549a3e0fd82Sopenharmony_ci{ 550a3e0fd82Sopenharmony_ci NeonBlendPipeLine mNeonBlendPipeLine; 551a3e0fd82Sopenharmony_ci mNeonBlendPipeLine.NeonPrelerpARGB8888(color, red, green, blue, alpha); 552a3e0fd82Sopenharmony_ci} 553a3e0fd82Sopenharmony_civoid DrawUtils::BlendPreLerpPix(uint8_t *dstColors, uint8_t *srcColors, uint8_t srcCover) 554a3e0fd82Sopenharmony_ci{ 555a3e0fd82Sopenharmony_ci NeonBlendPipeLine mNeonBlendPipeLine; 556a3e0fd82Sopenharmony_ci mNeonBlendPipeLine.NeonLerpARGB8888(dstColors, srcColors, srcCover); 557a3e0fd82Sopenharmony_ci} 558a3e0fd82Sopenharmony_ci 559a3e0fd82Sopenharmony_civoid DrawUtils::BlendPreLerpPix(uint8_t *dstColors, uint8_t *srcColors, uint8_t *srcCovers) 560a3e0fd82Sopenharmony_ci{ 561a3e0fd82Sopenharmony_ci NeonBlendPipeLine mNeonBlendPipeLine; 562a3e0fd82Sopenharmony_ci mNeonBlendPipeLine.NeonLerpARGB8888(dstColors, srcColors, srcCovers); 563a3e0fd82Sopenharmony_ci} 564a3e0fd82Sopenharmony_ci 565a3e0fd82Sopenharmony_civoid DrawUtils::BlendPreLerpPix(uint8_t *color, uint8_t red, uint8_t green, uint8_t blue, 566a3e0fd82Sopenharmony_ci uint8_t alpha, uint8_t *covers) 567a3e0fd82Sopenharmony_ci{ 568a3e0fd82Sopenharmony_ci NeonBlendPipeLine mNeonBlendPipeLine; 569a3e0fd82Sopenharmony_ci mNeonBlendPipeLine.NeonPreLerpARGB8888(color, red, green, blue, alpha, covers); 570a3e0fd82Sopenharmony_ci} 571a3e0fd82Sopenharmony_ci#endif 572a3e0fd82Sopenharmony_ci 573a3e0fd82Sopenharmony_civoid DrawUtils::BlendWithSoftWare(const uint8_t* src1, 574a3e0fd82Sopenharmony_ci const Rect& srcRect, 575a3e0fd82Sopenharmony_ci uint32_t srcStride, 576a3e0fd82Sopenharmony_ci uint32_t srcLineNumber, 577a3e0fd82Sopenharmony_ci ColorMode srcMode, 578a3e0fd82Sopenharmony_ci uint32_t color, 579a3e0fd82Sopenharmony_ci OpacityType opa, 580a3e0fd82Sopenharmony_ci uint8_t* dst, 581a3e0fd82Sopenharmony_ci uint32_t destStride, 582a3e0fd82Sopenharmony_ci ColorMode destMode, 583a3e0fd82Sopenharmony_ci uint32_t x, 584a3e0fd82Sopenharmony_ci uint32_t y) const 585a3e0fd82Sopenharmony_ci{ 586a3e0fd82Sopenharmony_ci if ((dst == nullptr) || (src1 == nullptr)) { 587a3e0fd82Sopenharmony_ci return; 588a3e0fd82Sopenharmony_ci } 589a3e0fd82Sopenharmony_ci uint8_t destByteSize = GetByteSizeByColorMode(destMode); 590a3e0fd82Sopenharmony_ci uint8_t srcByteSize = GetByteSizeByColorMode(srcMode); 591a3e0fd82Sopenharmony_ci 592a3e0fd82Sopenharmony_ci uint8_t* dest = dst + destStride * y; 593a3e0fd82Sopenharmony_ci dest += destByteSize * x; 594a3e0fd82Sopenharmony_ci 595a3e0fd82Sopenharmony_ci uint8_t pxByteSize = GetPxSizeByColorMode(srcMode) >> 3; // 3 : right shift 3 bits 596a3e0fd82Sopenharmony_ci uint8_t* src = const_cast<uint8_t*>(src1) + srcStride * srcRect.GetY() + pxByteSize * srcRect.GetX(); 597a3e0fd82Sopenharmony_ci uint32_t width = srcRect.GetWidth(); 598a3e0fd82Sopenharmony_ci uint32_t height = srcRect.GetHeight(); 599a3e0fd82Sopenharmony_ci#ifdef ARM_NEON_OPT 600a3e0fd82Sopenharmony_ci GetInstance()->SetDestAndSrc(srcMode, destMode, height, src, width, opa, dest, 601a3e0fd82Sopenharmony_ci destStride, srcStride, destByteSize, srcByteSize); 602a3e0fd82Sopenharmony_ci#else 603a3e0fd82Sopenharmony_ci { 604a3e0fd82Sopenharmony_ci DEBUG_PERFORMANCE_TRACE("BlendWithSoftWare"); 605a3e0fd82Sopenharmony_ci for (uint32_t row = 0; row < height; ++row) { 606a3e0fd82Sopenharmony_ci uint8_t* destTmp = dest; 607a3e0fd82Sopenharmony_ci uint8_t* srcTmp = const_cast<uint8_t*>(src); 608a3e0fd82Sopenharmony_ci for (uint32_t col = 0; col < width; ++col) { 609a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(destTmp, destMode, srcTmp, srcMode, opa); 610a3e0fd82Sopenharmony_ci destTmp += destByteSize; 611a3e0fd82Sopenharmony_ci srcTmp += srcByteSize; 612a3e0fd82Sopenharmony_ci } 613a3e0fd82Sopenharmony_ci dest += destStride; 614a3e0fd82Sopenharmony_ci src += srcStride; 615a3e0fd82Sopenharmony_ci } 616a3e0fd82Sopenharmony_ci } 617a3e0fd82Sopenharmony_ci#endif 618a3e0fd82Sopenharmony_ci} 619a3e0fd82Sopenharmony_ci 620a3e0fd82Sopenharmony_ci#ifdef ARM_NEON_OPT 621a3e0fd82Sopenharmony_civoid DrawUtils::SetDestAndSrc(ColorMode& srcMode, ColorMode& destMode, uint32_t height, uint8_t* src, 622a3e0fd82Sopenharmony_ci uint32_t width, OpacityType opa, uint8_t* dest, uint32_t destStride, 623a3e0fd82Sopenharmony_ci uint32_t srcStride, uint8_t destByteSize, uint8_t srcByteSize) const 624a3e0fd82Sopenharmony_ci{ 625a3e0fd82Sopenharmony_ci DEBUG_PERFORMANCE_TRACE("BlendWithSoftWare_neon"); 626a3e0fd82Sopenharmony_ci NeonBlendPipeLine pipeLine; 627a3e0fd82Sopenharmony_ci pipeLine.Construct(destMode, srcMode); 628a3e0fd82Sopenharmony_ci int16_t dstStep = NEON_STEP_8 * GetByteSizeByColorMode(destMode); 629a3e0fd82Sopenharmony_ci int16_t srcStep = NEON_STEP_8 * GetByteSizeByColorMode(srcMode); 630a3e0fd82Sopenharmony_ci for (uint32_t row = 0; row < height; ++row) { 631a3e0fd82Sopenharmony_ci uint8_t* dstBuf = dest; 632a3e0fd82Sopenharmony_ci uint8_t* srcBuf = const_cast<uint8_t*>(src); 633a3e0fd82Sopenharmony_ci int16_t tmpWidth = width; 634a3e0fd82Sopenharmony_ci while (tmpWidth >= NEON_STEP_8) { 635a3e0fd82Sopenharmony_ci pipeLine.Invoke(dstBuf, srcBuf, opa); 636a3e0fd82Sopenharmony_ci dstBuf += dstStep; 637a3e0fd82Sopenharmony_ci srcBuf += srcStep; 638a3e0fd82Sopenharmony_ci tmpWidth -= NEON_STEP_8; 639a3e0fd82Sopenharmony_ci } 640a3e0fd82Sopenharmony_ci for (int16_t i = 0; i < tmpWidth; ++i) { 641a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(dstBuf, destMode, srcBuf, srcMode, opa); 642a3e0fd82Sopenharmony_ci dstBuf += destByteSize; 643a3e0fd82Sopenharmony_ci srcBuf += srcByteSize; 644a3e0fd82Sopenharmony_ci } 645a3e0fd82Sopenharmony_ci dest += destStride; 646a3e0fd82Sopenharmony_ci src += srcStride; 647a3e0fd82Sopenharmony_ci } 648a3e0fd82Sopenharmony_ci} 649a3e0fd82Sopenharmony_ci#endif 650a3e0fd82Sopenharmony_ci 651a3e0fd82Sopenharmony_civoid DrawUtils::GetXAxisErrForJunctionLine(bool ignoreJunctionPoint, 652a3e0fd82Sopenharmony_ci bool isRightPart, 653a3e0fd82Sopenharmony_ci int16_t& xMinErr, 654a3e0fd82Sopenharmony_ci int16_t& xMaxErr) 655a3e0fd82Sopenharmony_ci{ 656a3e0fd82Sopenharmony_ci xMinErr = 0; 657a3e0fd82Sopenharmony_ci xMaxErr = 0; 658a3e0fd82Sopenharmony_ci if (ignoreJunctionPoint) { 659a3e0fd82Sopenharmony_ci if (isRightPart) { 660a3e0fd82Sopenharmony_ci xMinErr = 1; 661a3e0fd82Sopenharmony_ci } else { 662a3e0fd82Sopenharmony_ci xMaxErr = -1; 663a3e0fd82Sopenharmony_ci } 664a3e0fd82Sopenharmony_ci } 665a3e0fd82Sopenharmony_ci} 666a3e0fd82Sopenharmony_ci 667a3e0fd82Sopenharmony_civoid DrawUtils::GetTransformInitState(const TransformMap& transMap, 668a3e0fd82Sopenharmony_ci const Point& position, 669a3e0fd82Sopenharmony_ci const Rect& trans, 670a3e0fd82Sopenharmony_ci TransformInitState& init) 671a3e0fd82Sopenharmony_ci{ 672a3e0fd82Sopenharmony_ci int16_t x = trans.GetLeft(); 673a3e0fd82Sopenharmony_ci int16_t y = trans.GetTop(); 674a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 675a3e0fd82Sopenharmony_ci init.duHorizon = FO_TRANS_FLOAT_TO_FIXED(transMap.invMatrix_.GetData()[0]); 676a3e0fd82Sopenharmony_ci init.dvHorizon = FO_TRANS_FLOAT_TO_FIXED(transMap.invMatrix_.GetData()[1]); 677a3e0fd82Sopenharmony_ci init.duVertical = FO_TRANS_FLOAT_TO_FIXED(transMap.invMatrix_.GetData()[3]); // 3:RSxy 678a3e0fd82Sopenharmony_ci init.dvVertical = FO_TRANS_FLOAT_TO_FIXED(transMap.invMatrix_.GetData()[4]); // 4:RSyy 679a3e0fd82Sopenharmony_ci init.verticalU = (x - position.x) * init.duHorizon + (y - position.y) * init.duVertical + 680a3e0fd82Sopenharmony_ci FO_TRANS_FLOAT_TO_FIXED(transMap.invMatrix_.GetData()[6]); // 6:TRSx 681a3e0fd82Sopenharmony_ci init.verticalV = (x - position.x) * init.dvHorizon + (y - position.y) * init.dvVertical + 682a3e0fd82Sopenharmony_ci FO_TRANS_FLOAT_TO_FIXED(transMap.invMatrix_.GetData()[7]); // 7:TRSy 683a3e0fd82Sopenharmony_ci#else 684a3e0fd82Sopenharmony_ci init.duHorizon = transMap.invMatrix_.GetData()[0]; 685a3e0fd82Sopenharmony_ci init.dvHorizon = transMap.invMatrix_.GetData()[1]; 686a3e0fd82Sopenharmony_ci init.duVertical = transMap.invMatrix_.GetData()[3]; // 3:RSxy 687a3e0fd82Sopenharmony_ci init.dvVertical = transMap.invMatrix_.GetData()[4]; // 4:RSyy 688a3e0fd82Sopenharmony_ci init.verticalU = (x - position.x) * init.duHorizon + (y - position.y) * init.duVertical + 689a3e0fd82Sopenharmony_ci transMap.invMatrix_.GetData()[6]; // 6:TRSx 690a3e0fd82Sopenharmony_ci init.verticalV = (x - position.x) * init.dvHorizon + (y - position.y) * init.dvVertical + 691a3e0fd82Sopenharmony_ci transMap.invMatrix_.GetData()[7]; // 7:TRSy 692a3e0fd82Sopenharmony_ci#endif 693a3e0fd82Sopenharmony_ci} 694a3e0fd82Sopenharmony_ci 695a3e0fd82Sopenharmony_ciinline void DrawUtils::StepToNextLine(TriangleEdge& edge1, TriangleEdge& edge2) 696a3e0fd82Sopenharmony_ci{ 697a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 698a3e0fd82Sopenharmony_ci edge1.curY += FIXED_NUM_1; 699a3e0fd82Sopenharmony_ci edge2.curY += FIXED_NUM_1; 700a3e0fd82Sopenharmony_ci edge1.curX += FO_DIV(edge1.du, edge1.dv); 701a3e0fd82Sopenharmony_ci edge2.curX += FO_DIV(edge2.du, edge2.dv); 702a3e0fd82Sopenharmony_ci#else 703a3e0fd82Sopenharmony_ci edge1.curY++; 704a3e0fd82Sopenharmony_ci edge2.curY++; 705a3e0fd82Sopenharmony_ci edge1.curX += edge1.du / edge1.dv; 706a3e0fd82Sopenharmony_ci edge2.curX += edge2.du / edge2.dv; 707a3e0fd82Sopenharmony_ci#endif 708a3e0fd82Sopenharmony_ci} 709a3e0fd82Sopenharmony_ci 710a3e0fd82Sopenharmony_civoid DrawUtils::DrawTriangleAlphaBilinear(const TriangleScanInfo& in, const ColorMode bufferMode) 711a3e0fd82Sopenharmony_ci{ 712a3e0fd82Sopenharmony_ci int16_t maskLeft = in.mask.GetLeft(); 713a3e0fd82Sopenharmony_ci int16_t maskRight = in.mask.GetRight(); 714a3e0fd82Sopenharmony_ci for (int16_t y = in.yMin; y <= in.yMax; y++) { 715a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 716a3e0fd82Sopenharmony_ci int16_t tempV = FO_TO_INTEGER(in.edge1.curX); 717a3e0fd82Sopenharmony_ci int16_t xMin = MATH_MAX(tempV, maskLeft); 718a3e0fd82Sopenharmony_ci tempV = FO_TO_INTEGER(in.edge2.curX); 719a3e0fd82Sopenharmony_ci int16_t xMax = MATH_MIN(tempV, maskRight); 720a3e0fd82Sopenharmony_ci int16_t diffX = xMin - FO_TO_INTEGER(in.edge1.curX); 721a3e0fd82Sopenharmony_ci#else 722a3e0fd82Sopenharmony_ci int16_t xMin = MATH_MAX(static_cast<int16_t>(in.edge1.curX), maskLeft); 723a3e0fd82Sopenharmony_ci int16_t xMax = MATH_MIN(static_cast<int16_t>(in.edge2.curX), maskRight); 724a3e0fd82Sopenharmony_ci int16_t diffX = (xMin - static_cast<int32_t>(in.edge1.curX)); 725a3e0fd82Sopenharmony_ci#endif 726a3e0fd82Sopenharmony_ci in.init.verticalU += in.init.duHorizon * diffX; 727a3e0fd82Sopenharmony_ci in.init.verticalV += in.init.dvHorizon * diffX; 728a3e0fd82Sopenharmony_ci uint8_t* screenBuffer = in.screenBuffer + (y * in.screenBufferWidth + xMin) * in.bufferPxSize; 729a3e0fd82Sopenharmony_ci 730a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 731a3e0fd82Sopenharmony_ci // parameters below are Q15 fixed-point number 732a3e0fd82Sopenharmony_ci int64_t u = in.init.verticalU; 733a3e0fd82Sopenharmony_ci int64_t v = in.init.verticalV; 734a3e0fd82Sopenharmony_ci // parameters above are Q15 fixed-point number 735a3e0fd82Sopenharmony_ci#else 736a3e0fd82Sopenharmony_ci float u = in.init.verticalU; 737a3e0fd82Sopenharmony_ci float v = in.init.verticalV; 738a3e0fd82Sopenharmony_ci#endif 739a3e0fd82Sopenharmony_ci for (int16_t x = xMin; x <= xMax; x++) { 740a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 741a3e0fd82Sopenharmony_ci int16_t intU = FO_TO_INTEGER(u); 742a3e0fd82Sopenharmony_ci int16_t intV = FO_TO_INTEGER(v); 743a3e0fd82Sopenharmony_ci if ((u >= 0) && (intU < (in.info.header.width - 1)) && (v >= 0) && (intV < (in.info.header.height - 1))) { 744a3e0fd82Sopenharmony_ci int16_t intUPlus1 = intU + 1; 745a3e0fd82Sopenharmony_ci int16_t intVPlus1 = intV + 1; 746a3e0fd82Sopenharmony_ci#else 747a3e0fd82Sopenharmony_ci const int16_t intU = static_cast<int16_t>(u); 748a3e0fd82Sopenharmony_ci const int16_t intV = static_cast<int16_t>(v); 749a3e0fd82Sopenharmony_ci if ((u >= 0) && (intU < in.info.header.width - 1) && (v >= 0) && (intV < in.info.header.height - 1)) { 750a3e0fd82Sopenharmony_ci const int16_t intUPlus1 = intU + 1; 751a3e0fd82Sopenharmony_ci const int16_t intVPlus1 = intV + 1; 752a3e0fd82Sopenharmony_ci#endif 753a3e0fd82Sopenharmony_ci OpacityType p1 = GetPxAlphaForAlphaImg(in.info, {intU, intV}); 754a3e0fd82Sopenharmony_ci OpacityType p2 = GetPxAlphaForAlphaImg(in.info, {intUPlus1, intV}); 755a3e0fd82Sopenharmony_ci OpacityType p3 = GetPxAlphaForAlphaImg(in.info, {intU, intVPlus1}); 756a3e0fd82Sopenharmony_ci OpacityType p4 = GetPxAlphaForAlphaImg(in.info, {intUPlus1, intVPlus1}); 757a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 758a3e0fd82Sopenharmony_ci // parameters below are Q15 fixed-point number 759a3e0fd82Sopenharmony_ci int64_t decU = FO_DECIMAL(u); 760a3e0fd82Sopenharmony_ci int64_t decV = FO_DECIMAL(v); 761a3e0fd82Sopenharmony_ci int64_t decUMinus1 = FIXED_NUM_1 - decU; 762a3e0fd82Sopenharmony_ci int64_t decVMinus1 = FIXED_NUM_1 - decV; 763a3e0fd82Sopenharmony_ci int64_t w1 = FO_MUL(decUMinus1, decVMinus1); 764a3e0fd82Sopenharmony_ci int64_t w2 = FO_MUL(decU, decVMinus1); 765a3e0fd82Sopenharmony_ci int64_t w3 = FO_MUL(decUMinus1, decV); 766a3e0fd82Sopenharmony_ci int64_t w4 = FO_MUL(decU, decV); 767a3e0fd82Sopenharmony_ci // parameters above are Q15 fixed-point number 768a3e0fd82Sopenharmony_ci#else 769a3e0fd82Sopenharmony_ci const float decU = u - intU; 770a3e0fd82Sopenharmony_ci const float decV = v - intV; 771a3e0fd82Sopenharmony_ci const float decUMinus1 = 1.0f - decU; 772a3e0fd82Sopenharmony_ci const float decVMinus1 = 1.0f - decV; 773a3e0fd82Sopenharmony_ci 774a3e0fd82Sopenharmony_ci const int32_t w1 = static_cast<int32_t>(decUMinus1 * decVMinus1 * 256.0f); // 256:shift 8 bit left 775a3e0fd82Sopenharmony_ci const int32_t w2 = static_cast<int32_t>(decU * decVMinus1 * 256.0f); // 256:shift 8 bit left 776a3e0fd82Sopenharmony_ci const int32_t w3 = static_cast<int32_t>(decUMinus1 * decV * 256.0f); // 256:shift 8 bit left 777a3e0fd82Sopenharmony_ci const int32_t w4 = static_cast<int32_t>(decU * decV * 256.0f); // 256:shift 8 bit left 778a3e0fd82Sopenharmony_ci#endif 779a3e0fd82Sopenharmony_ci#if ENABLE_ARM_MATH 780a3e0fd82Sopenharmony_ci const int64_t outA = __SMUAD(p1, w1) + __SMUAD(p2, w2) + __SMUAD(p3, w3) + __SMUAD(p4, w4); 781a3e0fd82Sopenharmony_ci#else 782a3e0fd82Sopenharmony_ci const int64_t outA = p1 * w1 + p2 * w2 + p3 * w3 + p4 * w4; 783a3e0fd82Sopenharmony_ci#endif 784a3e0fd82Sopenharmony_ci Color32 result; 785a3e0fd82Sopenharmony_ci result.full = Color::ColorTo32(in.color); 786a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 787a3e0fd82Sopenharmony_ci result.alpha = FO_TO_INTEGER(outA); 788a3e0fd82Sopenharmony_ci#else 789a3e0fd82Sopenharmony_ci result.alpha = static_cast<uint8_t>(outA >> 8); // 8:shift 8 bit right 790a3e0fd82Sopenharmony_ci#endif 791a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, in.opaScale); 792a3e0fd82Sopenharmony_ci } 793a3e0fd82Sopenharmony_ci u += in.init.duHorizon; 794a3e0fd82Sopenharmony_ci v += in.init.dvHorizon; 795a3e0fd82Sopenharmony_ci screenBuffer += in.bufferPxSize; 796a3e0fd82Sopenharmony_ci } 797a3e0fd82Sopenharmony_ci StepToNextLine(in.edge1, in.edge2); 798a3e0fd82Sopenharmony_ci in.init.verticalU += in.init.duVertical; 799a3e0fd82Sopenharmony_ci in.init.verticalV += in.init.dvVertical; 800a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 801a3e0fd82Sopenharmony_ci int16_t deltaX = FO_TO_INTEGER(in.edge1.curX) - xMin; 802a3e0fd82Sopenharmony_ci#else 803a3e0fd82Sopenharmony_ci int16_t deltaX = static_cast<int16_t>(in.edge1.curX) - xMin; 804a3e0fd82Sopenharmony_ci#endif 805a3e0fd82Sopenharmony_ci in.init.verticalU += in.init.duHorizon * deltaX; 806a3e0fd82Sopenharmony_ci in.init.verticalV += in.init.dvHorizon * deltaX; 807a3e0fd82Sopenharmony_ci } 808a3e0fd82Sopenharmony_ci} 809a3e0fd82Sopenharmony_ci 810a3e0fd82Sopenharmony_civoid DrawUtils::DrawTriangleTrueColorBilinear565(const TriangleScanInfo& in, const ColorMode bufferMode) 811a3e0fd82Sopenharmony_ci{ 812a3e0fd82Sopenharmony_ci int16_t maskLeft = in.mask.GetLeft(); 813a3e0fd82Sopenharmony_ci int16_t maskRight = in.mask.GetRight(); 814a3e0fd82Sopenharmony_ci int16_t xMinErr = 0; 815a3e0fd82Sopenharmony_ci int16_t xMaxErr = 0; 816a3e0fd82Sopenharmony_ci GetXAxisErrForJunctionLine(in.ignoreJunctionPoint, in.isRightPart, xMinErr, xMaxErr); 817a3e0fd82Sopenharmony_ci for (int16_t y = in.yMin; y <= in.yMax; y++) { 818a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 819a3e0fd82Sopenharmony_ci int16_t tempV = FO_TO_INTEGER(in.edge1.curX) + xMinErr; 820a3e0fd82Sopenharmony_ci int16_t xMin = MATH_MAX(tempV, maskLeft); 821a3e0fd82Sopenharmony_ci tempV = FO_TO_INTEGER(in.edge2.curX) + xMaxErr; 822a3e0fd82Sopenharmony_ci int16_t xMax = MATH_MIN(tempV, maskRight); 823a3e0fd82Sopenharmony_ci int16_t diffX = xMin - FO_TO_INTEGER(in.edge1.curX); 824a3e0fd82Sopenharmony_ci#else 825a3e0fd82Sopenharmony_ci int16_t xMin = MATH_MAX(static_cast<int16_t>(in.edge1.curX + xMinErr), maskLeft); 826a3e0fd82Sopenharmony_ci int16_t xMax = MATH_MIN(static_cast<int16_t>(in.edge2.curX + xMaxErr), maskRight); 827a3e0fd82Sopenharmony_ci int16_t diffX = (xMin - static_cast<int32_t>(in.edge1.curX)); 828a3e0fd82Sopenharmony_ci#endif 829a3e0fd82Sopenharmony_ci in.init.verticalU += in.init.duHorizon * diffX; 830a3e0fd82Sopenharmony_ci in.init.verticalV += in.init.dvHorizon * diffX; 831a3e0fd82Sopenharmony_ci uint8_t* screenBuffer = in.screenBuffer + (y * in.screenBufferWidth + xMin) * in.bufferPxSize; 832a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 833a3e0fd82Sopenharmony_ci // parameters below are Q15 fixed-point number 834a3e0fd82Sopenharmony_ci int64_t u = in.init.verticalU; 835a3e0fd82Sopenharmony_ci int64_t v = in.init.verticalV; 836a3e0fd82Sopenharmony_ci // parameters above are Q15 fixed-point number 837a3e0fd82Sopenharmony_ci#else 838a3e0fd82Sopenharmony_ci float u = in.init.verticalU; 839a3e0fd82Sopenharmony_ci float v = in.init.verticalV; 840a3e0fd82Sopenharmony_ci#endif 841a3e0fd82Sopenharmony_ci for (int16_t x = xMin; x <= xMax; x++) { 842a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 843a3e0fd82Sopenharmony_ci int16_t intU = FO_TO_INTEGER(u); 844a3e0fd82Sopenharmony_ci int16_t intV = FO_TO_INTEGER(v); 845a3e0fd82Sopenharmony_ci if ((u >= 0) && (intU < (in.info.header.width - 1)) && (v >= 0) && (intV < (in.info.header.height - 1))) { 846a3e0fd82Sopenharmony_ci#else 847a3e0fd82Sopenharmony_ci const int16_t intU = static_cast<int16_t>(u); 848a3e0fd82Sopenharmony_ci const int16_t intV = static_cast<int16_t>(v); 849a3e0fd82Sopenharmony_ci if ((u >= 0) && (intU < in.info.header.width - 1) && (v >= 0) && (intV < in.info.header.height - 1)) { 850a3e0fd82Sopenharmony_ci#endif 851a3e0fd82Sopenharmony_ci#if ENABLE_ARM_MATH 852a3e0fd82Sopenharmony_ci uint32_t val1 = __SMUAD(intV, in.srcLineWidth); 853a3e0fd82Sopenharmony_ci uint32_t val2 = __SMUAD(intU, in.pixelSize); 854a3e0fd82Sopenharmony_ci uint32_t px1 = val1 + val2; 855a3e0fd82Sopenharmony_ci#else 856a3e0fd82Sopenharmony_ci uint32_t px1 = intV * in.srcLineWidth + intU * in.pixelSize; 857a3e0fd82Sopenharmony_ci#endif 858a3e0fd82Sopenharmony_ci uint8_t* imgHead = const_cast<uint8_t*>(in.info.data); 859a3e0fd82Sopenharmony_ci const Color16 p1 = *(reinterpret_cast<Color16*>(&imgHead[px1])); 860a3e0fd82Sopenharmony_ci const Color16 p2 = *(reinterpret_cast<Color16*>(&imgHead[px1 + in.pixelSize])); 861a3e0fd82Sopenharmony_ci const Color16 p3 = *(reinterpret_cast<Color16*>(&imgHead[px1 + in.srcLineWidth])); 862a3e0fd82Sopenharmony_ci const Color16 p4 = *(reinterpret_cast<Color16*>(&imgHead[px1 + in.srcLineWidth + in.pixelSize])); 863a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 864a3e0fd82Sopenharmony_ci // parameters below are Q15 fixed-point number 865a3e0fd82Sopenharmony_ci int64_t decU = FO_DECIMAL(u); 866a3e0fd82Sopenharmony_ci int64_t decV = FO_DECIMAL(v); 867a3e0fd82Sopenharmony_ci int64_t decUMinus1 = FIXED_NUM_1 - decU; 868a3e0fd82Sopenharmony_ci int64_t decVMinus1 = FIXED_NUM_1 - decV; 869a3e0fd82Sopenharmony_ci int64_t w1 = FO_MUL(decUMinus1, decVMinus1); 870a3e0fd82Sopenharmony_ci int64_t w2 = FO_MUL(decU, decVMinus1); 871a3e0fd82Sopenharmony_ci int64_t w3 = FO_MUL(decUMinus1, decV); 872a3e0fd82Sopenharmony_ci int64_t w4 = FO_MUL(decU, decV); 873a3e0fd82Sopenharmony_ci // parameters above are Q15 fixed-point number 874a3e0fd82Sopenharmony_ci#else 875a3e0fd82Sopenharmony_ci const float decU = u - intU; 876a3e0fd82Sopenharmony_ci const float decV = v - intV; 877a3e0fd82Sopenharmony_ci const float decUMinus1 = 1 - decU; 878a3e0fd82Sopenharmony_ci const float decVMinus1 = 1 - decV; 879a3e0fd82Sopenharmony_ci const int32_t w1 = static_cast<int32_t>(decUMinus1 * decVMinus1 * 256.0f); // 256:shift 8 bit left 880a3e0fd82Sopenharmony_ci const int32_t w2 = static_cast<int32_t>(decU * decVMinus1 * 256.0f); // 256:shift 8 bit left 881a3e0fd82Sopenharmony_ci const int32_t w3 = static_cast<int32_t>(decUMinus1 * decV * 256.0f); // 256:shift 8 bit left 882a3e0fd82Sopenharmony_ci const int32_t w4 = static_cast<int32_t>(decU * decV * 256.0f); // 256:shift 8 bit left 883a3e0fd82Sopenharmony_ci#endif 884a3e0fd82Sopenharmony_ci#if ENABLE_ARM_MATH 885a3e0fd82Sopenharmony_ci const int64_t outR = 886a3e0fd82Sopenharmony_ci __SMUAD(p1.red, w1) + __SMUAD(p2.red, w2) + __SMUAD(p3.red, w3) + __SMUAD(p4.red, w4); 887a3e0fd82Sopenharmony_ci const int64_t outG = 888a3e0fd82Sopenharmony_ci __SMUAD(p1.green, w1) + __SMUAD(p2.green, w2) + __SMUAD(p3.green, w3) + __SMUAD(p4.green, w4); 889a3e0fd82Sopenharmony_ci const int64_t outB = 890a3e0fd82Sopenharmony_ci __SMUAD(p1.blue, w1) + __SMUAD(p2.blue, w2) + __SMUAD(p3.blue, w3) + __SMUAD(p4.blue, w4); 891a3e0fd82Sopenharmony_ci#else 892a3e0fd82Sopenharmony_ci const int64_t outR = p1.red * w1 + p2.red * w2 + p3.red * w3 + p4.red * w4; 893a3e0fd82Sopenharmony_ci const int64_t outG = p1.green * w1 + p2.green * w2 + p3.green * w3 + p4.green * w4; 894a3e0fd82Sopenharmony_ci const int64_t outB = p1.blue * w1 + p2.blue * w2 + p3.blue * w3 + p4.blue * w4; 895a3e0fd82Sopenharmony_ci#endif 896a3e0fd82Sopenharmony_ci 897a3e0fd82Sopenharmony_ci Color16 result; 898a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 899a3e0fd82Sopenharmony_ci result.red = static_cast<uint8_t>(outR >> FIXED_Q_NUM); 900a3e0fd82Sopenharmony_ci result.green = static_cast<uint8_t>(outG >> FIXED_Q_NUM); 901a3e0fd82Sopenharmony_ci result.blue = static_cast<uint8_t>(outB >> FIXED_Q_NUM); 902a3e0fd82Sopenharmony_ci#else 903a3e0fd82Sopenharmony_ci result.red = static_cast<uint8_t>(outR >> 5); // 5:shift 5 bit right 904a3e0fd82Sopenharmony_ci result.green = static_cast<uint8_t>(outG >> 6); // 6:shift 6 bit right 905a3e0fd82Sopenharmony_ci result.blue = static_cast<uint8_t>(outB >> 5); // 5:shift 5 bit right 906a3e0fd82Sopenharmony_ci#endif 907a3e0fd82Sopenharmony_ci if (in.opaScale == OPA_OPAQUE) { 908a3e0fd82Sopenharmony_ci COLOR_FILL_COVER(screenBuffer, bufferMode, result.red, result.green, result.blue, RGB565); 909a3e0fd82Sopenharmony_ci } else { 910a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, RGB565, in.opaScale); 911a3e0fd82Sopenharmony_ci } 912a3e0fd82Sopenharmony_ci } 913a3e0fd82Sopenharmony_ci u += in.init.duHorizon; 914a3e0fd82Sopenharmony_ci v += in.init.dvHorizon; 915a3e0fd82Sopenharmony_ci screenBuffer += in.bufferPxSize; 916a3e0fd82Sopenharmony_ci } 917a3e0fd82Sopenharmony_ci StepToNextLine(in.edge1, in.edge2); 918a3e0fd82Sopenharmony_ci in.init.verticalU += in.init.duVertical; 919a3e0fd82Sopenharmony_ci in.init.verticalV += in.init.dvVertical; 920a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 921a3e0fd82Sopenharmony_ci int16_t deltaX = FO_TO_INTEGER(in.edge1.curX) - xMin; 922a3e0fd82Sopenharmony_ci#else 923a3e0fd82Sopenharmony_ci int16_t deltaX = static_cast<int16_t>(in.edge1.curX) - xMin; 924a3e0fd82Sopenharmony_ci#endif 925a3e0fd82Sopenharmony_ci in.init.verticalU += in.init.duHorizon * deltaX; 926a3e0fd82Sopenharmony_ci in.init.verticalV += in.init.dvHorizon * deltaX; 927a3e0fd82Sopenharmony_ci } 928a3e0fd82Sopenharmony_ci} 929a3e0fd82Sopenharmony_ci 930a3e0fd82Sopenharmony_civoid DrawUtils::DrawTriangleTrueColorBilinear888(const TriangleScanInfo& in, const ColorMode bufferMode) 931a3e0fd82Sopenharmony_ci{ 932a3e0fd82Sopenharmony_ci int16_t maskLeft = in.mask.GetLeft(); 933a3e0fd82Sopenharmony_ci int16_t maskRight = in.mask.GetRight(); 934a3e0fd82Sopenharmony_ci int16_t xMinErr = 0; 935a3e0fd82Sopenharmony_ci int16_t xMaxErr = 0; 936a3e0fd82Sopenharmony_ci GetXAxisErrForJunctionLine(in.ignoreJunctionPoint, in.isRightPart, xMinErr, xMaxErr); 937a3e0fd82Sopenharmony_ci for (int16_t y = in.yMin; y <= in.yMax; y++) { 938a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 939a3e0fd82Sopenharmony_ci int16_t tempV = FO_TO_INTEGER(in.edge1.curX) + xMinErr; 940a3e0fd82Sopenharmony_ci int16_t xMin = MATH_MAX(tempV, maskLeft); 941a3e0fd82Sopenharmony_ci tempV = FO_TO_INTEGER(in.edge2.curX) + xMaxErr; 942a3e0fd82Sopenharmony_ci int16_t xMax = MATH_MIN(tempV, maskRight); 943a3e0fd82Sopenharmony_ci int16_t diffX = xMin - FO_TO_INTEGER(in.edge1.curX); 944a3e0fd82Sopenharmony_ci#else 945a3e0fd82Sopenharmony_ci int16_t xMin = MATH_MAX(static_cast<int16_t>(in.edge1.curX + xMinErr), maskLeft); 946a3e0fd82Sopenharmony_ci int16_t xMax = MATH_MIN(static_cast<int16_t>(in.edge2.curX + xMaxErr), maskRight); 947a3e0fd82Sopenharmony_ci int16_t diffX = (xMin - static_cast<int32_t>(in.edge1.curX)); 948a3e0fd82Sopenharmony_ci#endif 949a3e0fd82Sopenharmony_ci in.init.verticalU += in.init.duHorizon * diffX; 950a3e0fd82Sopenharmony_ci in.init.verticalV += in.init.dvHorizon * diffX; 951a3e0fd82Sopenharmony_ci uint8_t* screenBuffer = in.screenBuffer + (y * in.screenBufferWidth + xMin) * in.bufferPxSize; 952a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 953a3e0fd82Sopenharmony_ci // parameters below are Q15 fixed-point number 954a3e0fd82Sopenharmony_ci int64_t u = in.init.verticalU; 955a3e0fd82Sopenharmony_ci int64_t v = in.init.verticalV; 956a3e0fd82Sopenharmony_ci // parameters above are Q15 fixed-point number 957a3e0fd82Sopenharmony_ci#else 958a3e0fd82Sopenharmony_ci float u = in.init.verticalU; 959a3e0fd82Sopenharmony_ci float v = in.init.verticalV; 960a3e0fd82Sopenharmony_ci#endif 961a3e0fd82Sopenharmony_ci for (int16_t x = xMin; x <= xMax; x++) { 962a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 963a3e0fd82Sopenharmony_ci int16_t intU = FO_TO_INTEGER(u); 964a3e0fd82Sopenharmony_ci int16_t intV = FO_TO_INTEGER(v); 965a3e0fd82Sopenharmony_ci#else 966a3e0fd82Sopenharmony_ci const int16_t intU = static_cast<int16_t>(u); 967a3e0fd82Sopenharmony_ci const int16_t intV = static_cast<int16_t>(v); 968a3e0fd82Sopenharmony_ci#endif 969a3e0fd82Sopenharmony_ci if ((u >= 0) && (intU < in.info.header.width - 1) && (v >= 0) && (intV < in.info.header.height - 1)) { 970a3e0fd82Sopenharmony_ci#if ENABLE_ARM_MATH 971a3e0fd82Sopenharmony_ci uint32_t val1 = __SMUAD(intV, in.srcLineWidth); 972a3e0fd82Sopenharmony_ci uint32_t val2 = __SMUAD(intU, in.pixelSize); 973a3e0fd82Sopenharmony_ci uint32_t px1 = val1 + val2; 974a3e0fd82Sopenharmony_ci#else 975a3e0fd82Sopenharmony_ci uint32_t px1 = intV * in.srcLineWidth + intU * in.pixelSize; 976a3e0fd82Sopenharmony_ci#endif 977a3e0fd82Sopenharmony_ci uint8_t* imgHead = const_cast<uint8_t*>(in.info.data); 978a3e0fd82Sopenharmony_ci const Color24 p1 = *(reinterpret_cast<Color24*>(&imgHead[px1])); 979a3e0fd82Sopenharmony_ci const Color24 p2 = *(reinterpret_cast<Color24*>(&imgHead[px1 + in.pixelSize])); 980a3e0fd82Sopenharmony_ci const Color24 p3 = *(reinterpret_cast<Color24*>(&imgHead[px1 + in.srcLineWidth])); 981a3e0fd82Sopenharmony_ci const Color24 p4 = *(reinterpret_cast<Color24*>(&imgHead[px1 + in.srcLineWidth + in.pixelSize])); 982a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 983a3e0fd82Sopenharmony_ci // parameters below are Q15 fixed-point number 984a3e0fd82Sopenharmony_ci int64_t decU = FO_DECIMAL(u); 985a3e0fd82Sopenharmony_ci int64_t decV = FO_DECIMAL(v); 986a3e0fd82Sopenharmony_ci int64_t decUMinus1 = FIXED_NUM_1 - decU; 987a3e0fd82Sopenharmony_ci int64_t decVMinus1 = FIXED_NUM_1 - decV; 988a3e0fd82Sopenharmony_ci int64_t w1 = FO_MUL(decUMinus1, decVMinus1); 989a3e0fd82Sopenharmony_ci int64_t w2 = FO_MUL(decU, decVMinus1); 990a3e0fd82Sopenharmony_ci int64_t w3 = FO_MUL(decUMinus1, decV); 991a3e0fd82Sopenharmony_ci int64_t w4 = FO_MUL(decU, decV); 992a3e0fd82Sopenharmony_ci // parameters above are Q15 fixed-point number 993a3e0fd82Sopenharmony_ci#else 994a3e0fd82Sopenharmony_ci const float decU = u - intU; 995a3e0fd82Sopenharmony_ci const float decV = v - intV; 996a3e0fd82Sopenharmony_ci const float decUMinus1 = 1 - decU; 997a3e0fd82Sopenharmony_ci const float decVMinus1 = 1 - decV; 998a3e0fd82Sopenharmony_ci const int32_t w1 = static_cast<int32_t>(decUMinus1 * decVMinus1 * 256.0f); // 256:shift 8 bit left 999a3e0fd82Sopenharmony_ci const int32_t w2 = static_cast<int32_t>(decU * decVMinus1 * 256.0f); // 256:shift 8 bit left 1000a3e0fd82Sopenharmony_ci const int32_t w3 = static_cast<int32_t>(decUMinus1 * decV * 256.0f); // 256:shift 8 bit left 1001a3e0fd82Sopenharmony_ci const int32_t w4 = static_cast<int32_t>(decU * decV * 256.0f); // 256:shift 8 bit left 1002a3e0fd82Sopenharmony_ci#endif 1003a3e0fd82Sopenharmony_ci 1004a3e0fd82Sopenharmony_ci#if ENABLE_ARM_MATH 1005a3e0fd82Sopenharmony_ci const int64_t outR = 1006a3e0fd82Sopenharmony_ci __SMUAD(p1.red, w1) + __SMUAD(p2.red, w2) + __SMUAD(p3.red, w3) + __SMUAD(p4.red, w4); 1007a3e0fd82Sopenharmony_ci const int64_t outG = 1008a3e0fd82Sopenharmony_ci __SMUAD(p1.green, w1) + __SMUAD(p2.green, w2) + __SMUAD(p3.green, w3) + __SMUAD(p4.green, w4); 1009a3e0fd82Sopenharmony_ci const int64_t outB = 1010a3e0fd82Sopenharmony_ci __SMUAD(p1.blue, w1) + __SMUAD(p2.blue, w2) + __SMUAD(p3.blue, w3) + __SMUAD(p4.blue, w4); 1011a3e0fd82Sopenharmony_ci#else 1012a3e0fd82Sopenharmony_ci const int64_t outR = p1.red * w1 + p2.red * w2 + p3.red * w3 + p4.red * w4; 1013a3e0fd82Sopenharmony_ci const int64_t outG = p1.green * w1 + p2.green * w2 + p3.green * w3 + p4.green * w4; 1014a3e0fd82Sopenharmony_ci const int64_t outB = p1.blue * w1 + p2.blue * w2 + p3.blue * w3 + p4.blue * w4; 1015a3e0fd82Sopenharmony_ci#endif 1016a3e0fd82Sopenharmony_ci 1017a3e0fd82Sopenharmony_ci Color24 result; 1018a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1019a3e0fd82Sopenharmony_ci result.red = static_cast<uint8_t>(outR >> FIXED_Q_NUM); 1020a3e0fd82Sopenharmony_ci result.green = static_cast<uint8_t>(outG >> FIXED_Q_NUM); 1021a3e0fd82Sopenharmony_ci result.blue = static_cast<uint8_t>(outB >> FIXED_Q_NUM); 1022a3e0fd82Sopenharmony_ci#else 1023a3e0fd82Sopenharmony_ci result.red = static_cast<uint8_t>(outR >> 8); // 8:shift 8 bit right 1024a3e0fd82Sopenharmony_ci result.green = static_cast<uint8_t>(outG >> 8); // 8:shift 8 bit right 1025a3e0fd82Sopenharmony_ci result.blue = static_cast<uint8_t>(outB >> 8); // 8:shift 8 bit right 1026a3e0fd82Sopenharmony_ci#endif 1027a3e0fd82Sopenharmony_ci if (in.opaScale == OPA_OPAQUE) { 1028a3e0fd82Sopenharmony_ci COLOR_FILL_COVER(screenBuffer, bufferMode, result.red, result.green, result.blue, RGB888); 1029a3e0fd82Sopenharmony_ci } else { 1030a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, RGB888, in.opaScale); 1031a3e0fd82Sopenharmony_ci } 1032a3e0fd82Sopenharmony_ci } 1033a3e0fd82Sopenharmony_ci u += in.init.duHorizon; 1034a3e0fd82Sopenharmony_ci v += in.init.dvHorizon; 1035a3e0fd82Sopenharmony_ci screenBuffer += in.bufferPxSize; 1036a3e0fd82Sopenharmony_ci } 1037a3e0fd82Sopenharmony_ci StepToNextLine(in.edge1, in.edge2); 1038a3e0fd82Sopenharmony_ci in.init.verticalU += in.init.duVertical; 1039a3e0fd82Sopenharmony_ci in.init.verticalV += in.init.dvVertical; 1040a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1041a3e0fd82Sopenharmony_ci int16_t deltaX = FO_TO_INTEGER(in.edge1.curX) - xMin; 1042a3e0fd82Sopenharmony_ci#else 1043a3e0fd82Sopenharmony_ci int16_t deltaX = static_cast<int16_t>(in.edge1.curX) - xMin; 1044a3e0fd82Sopenharmony_ci#endif 1045a3e0fd82Sopenharmony_ci in.init.verticalU += in.init.duHorizon * deltaX; 1046a3e0fd82Sopenharmony_ci in.init.verticalV += in.init.dvHorizon * deltaX; 1047a3e0fd82Sopenharmony_ci } 1048a3e0fd82Sopenharmony_ci} 1049a3e0fd82Sopenharmony_ci 1050a3e0fd82Sopenharmony_ci#if !ENABLE_FIXED_POINT 1051a3e0fd82Sopenharmony_cistatic void DrawTriangleTrueColorBilinear8888Inner(const TriangleScanInfo& in, 1052a3e0fd82Sopenharmony_ci uint8_t* screenBuffer, 1053a3e0fd82Sopenharmony_ci int16_t len, 1054a3e0fd82Sopenharmony_ci const ColorMode bufferMode, 1055a3e0fd82Sopenharmony_ci float u, 1056a3e0fd82Sopenharmony_ci float v) 1057a3e0fd82Sopenharmony_ci{ 1058a3e0fd82Sopenharmony_ci for (int16_t x = 0; x < len; ++x) { 1059a3e0fd82Sopenharmony_ci const int16_t intU = static_cast<int16_t>(u); 1060a3e0fd82Sopenharmony_ci const int16_t intV = static_cast<int16_t>(v); 1061a3e0fd82Sopenharmony_ci if ((u >= 0) && (intU < in.info.header.width - 1) && (v >= 0) && (intV < in.info.header.height - 1)) { 1062a3e0fd82Sopenharmony_ci#if ENABLE_ARM_MATH 1063a3e0fd82Sopenharmony_ci uint32_t val1 = __SMUAD(intV, in.srcLineWidth); 1064a3e0fd82Sopenharmony_ci uint32_t val2 = __SMUAD(intU, in.pixelSize); 1065a3e0fd82Sopenharmony_ci uint32_t px1 = val1 + val2; 1066a3e0fd82Sopenharmony_ci#else 1067a3e0fd82Sopenharmony_ci uint32_t px1 = intV * in.srcLineWidth + intU * in.pixelSize; 1068a3e0fd82Sopenharmony_ci#endif 1069a3e0fd82Sopenharmony_ci uint8_t* imgHead = const_cast<uint8_t*>(in.info.data); 1070a3e0fd82Sopenharmony_ci const ColorType p1 = *(reinterpret_cast<ColorType*>(&imgHead[px1])); 1071a3e0fd82Sopenharmony_ci const ColorType p2 = *(reinterpret_cast<ColorType*>(&imgHead[px1 + in.pixelSize])); 1072a3e0fd82Sopenharmony_ci const ColorType p3 = *(reinterpret_cast<ColorType*>(&imgHead[px1 + in.srcLineWidth])); 1073a3e0fd82Sopenharmony_ci const ColorType p4 = *(reinterpret_cast<ColorType*>(&imgHead[px1 + in.srcLineWidth + in.pixelSize])); 1074a3e0fd82Sopenharmony_ci 1075a3e0fd82Sopenharmony_ci const float decU = u - intU; 1076a3e0fd82Sopenharmony_ci const float decV = v - intV; 1077a3e0fd82Sopenharmony_ci const float decUMinus1 = 1 - decU; 1078a3e0fd82Sopenharmony_ci const float decVMinus1 = 1 - decV; 1079a3e0fd82Sopenharmony_ci 1080a3e0fd82Sopenharmony_ci const int32_t w1 = static_cast<int32_t>(decUMinus1 * decVMinus1 * 256.0f); // 256:shift 8 bit left 1081a3e0fd82Sopenharmony_ci const int32_t w2 = static_cast<int32_t>(decU * decVMinus1 * 256.0f); // 256:shift 8 bit left 1082a3e0fd82Sopenharmony_ci const int32_t w3 = static_cast<int32_t>(decUMinus1 * decV * 256.0f); // 256:shift 8 bit left 1083a3e0fd82Sopenharmony_ci const int32_t w4 = static_cast<int32_t>(decU * decV * 256.0f); // 256:shift 8 bit left 1084a3e0fd82Sopenharmony_ci 1085a3e0fd82Sopenharmony_ci#if ENABLE_ARM_MATH 1086a3e0fd82Sopenharmony_ci const int32_t outR = __SMUAD(p1.red, w1) + __SMUAD(p2.red, w2) + __SMUAD(p3.red, w3) + __SMUAD(p4.red, w4); 1087a3e0fd82Sopenharmony_ci const int32_t outG = 1088a3e0fd82Sopenharmony_ci __SMUAD(p1.green, w1) + __SMUAD(p2.green, w2) + __SMUAD(p3.green, w3) + __SMUAD(p4.green, w4); 1089a3e0fd82Sopenharmony_ci const int32_t outB = 1090a3e0fd82Sopenharmony_ci __SMUAD(p1.blue, w1) + __SMUAD(p2.blue, w2) + __SMUAD(p3.blue, w3) + __SMUAD(p4.blue, w4); 1091a3e0fd82Sopenharmony_ci const int32_t outA = 1092a3e0fd82Sopenharmony_ci __SMUAD(p1.alpha, w1) + __SMUAD(p2.alpha, w2) + __SMUAD(p3.alpha, w3) + __SMUAD(p4.alpha, w4); 1093a3e0fd82Sopenharmony_ci#else 1094a3e0fd82Sopenharmony_ci const int32_t outR = p1.red * w1 + p2.red * w2 + p3.red * w3 + p4.red * w4; 1095a3e0fd82Sopenharmony_ci const int32_t outG = p1.green * w1 + p2.green * w2 + p3.green * w3 + p4.green * w4; 1096a3e0fd82Sopenharmony_ci const int32_t outB = p1.blue * w1 + p2.blue * w2 + p3.blue * w3 + p4.blue * w4; 1097a3e0fd82Sopenharmony_ci const int32_t outA = p1.alpha * w1 + p2.alpha * w2 + p3.alpha * w3 + p4.alpha * w4; 1098a3e0fd82Sopenharmony_ci#endif 1099a3e0fd82Sopenharmony_ci 1100a3e0fd82Sopenharmony_ci Color32 result; 1101a3e0fd82Sopenharmony_ci result.red = static_cast<uint8_t>(outR >> 8); // 8:shift 8 bit right 1102a3e0fd82Sopenharmony_ci result.green = static_cast<uint8_t>(outG >> 8); // 8:shift 8 bit right 1103a3e0fd82Sopenharmony_ci result.blue = static_cast<uint8_t>(outB >> 8); // 8:shift 8 bit right 1104a3e0fd82Sopenharmony_ci result.alpha = static_cast<uint8_t>(outA >> 8); // 8:shift 8 bit right 1105a3e0fd82Sopenharmony_ci if ((in.opaScale == OPA_OPAQUE) && (result.alpha == OPA_OPAQUE)) { 1106a3e0fd82Sopenharmony_ci COLOR_FILL_COVER(screenBuffer, bufferMode, result.red, result.green, result.blue, ARGB8888); 1107a3e0fd82Sopenharmony_ci } else { 1108a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, in.opaScale); 1109a3e0fd82Sopenharmony_ci } 1110a3e0fd82Sopenharmony_ci } 1111a3e0fd82Sopenharmony_ci u += in.init.duHorizon; 1112a3e0fd82Sopenharmony_ci v += in.init.dvHorizon; 1113a3e0fd82Sopenharmony_ci screenBuffer += in.bufferPxSize; 1114a3e0fd82Sopenharmony_ci } 1115a3e0fd82Sopenharmony_ci} 1116a3e0fd82Sopenharmony_ci#endif 1117a3e0fd82Sopenharmony_ci 1118a3e0fd82Sopenharmony_ci#if defined(ENABLE_FIXED_POINT) && ENABLE_FIXED_POINT 1119a3e0fd82Sopenharmony_cistatic void DrawFixedTriangleTrueColorBilinear8888Inner(const TriangleScanInfo& in, 1120a3e0fd82Sopenharmony_ci uint8_t* screenBuffer, 1121a3e0fd82Sopenharmony_ci int16_t len, 1122a3e0fd82Sopenharmony_ci const ColorMode bufferMode, 1123a3e0fd82Sopenharmony_ci int64_t u, 1124a3e0fd82Sopenharmony_ci int64_t v) 1125a3e0fd82Sopenharmony_ci{ 1126a3e0fd82Sopenharmony_ci for (int16_t x = 0; x < len; ++x) { 1127a3e0fd82Sopenharmony_ci int16_t intU = FO_TO_INTEGER(u); 1128a3e0fd82Sopenharmony_ci int16_t intV = FO_TO_INTEGER(v); 1129a3e0fd82Sopenharmony_ci if ((u >= 0) && (intU < in.info.header.width - 1) && (v >= 0) && (intV < in.info.header.height - 1)) { 1130a3e0fd82Sopenharmony_ci#if ENABLE_ARM_MATH 1131a3e0fd82Sopenharmony_ci uint32_t val1 = __SMUAD(intV, in.srcLineWidth); 1132a3e0fd82Sopenharmony_ci uint32_t val2 = __SMUAD(intU, in.pixelSize); 1133a3e0fd82Sopenharmony_ci uint32_t px1 = val1 + val2; 1134a3e0fd82Sopenharmony_ci#else 1135a3e0fd82Sopenharmony_ci uint32_t px1 = intV * in.srcLineWidth + intU * in.pixelSize; 1136a3e0fd82Sopenharmony_ci#endif 1137a3e0fd82Sopenharmony_ci uint8_t* imgHead = const_cast<uint8_t*>(in.info.data); 1138a3e0fd82Sopenharmony_ci const ColorType p1 = *(reinterpret_cast<ColorType*>(&imgHead[px1])); 1139a3e0fd82Sopenharmony_ci const ColorType p2 = *(reinterpret_cast<ColorType*>(&imgHead[px1 + in.pixelSize])); 1140a3e0fd82Sopenharmony_ci const ColorType p3 = *(reinterpret_cast<ColorType*>(&imgHead[px1 + in.srcLineWidth])); 1141a3e0fd82Sopenharmony_ci const ColorType p4 = *(reinterpret_cast<ColorType*>(&imgHead[px1 + in.srcLineWidth + in.pixelSize])); 1142a3e0fd82Sopenharmony_ci 1143a3e0fd82Sopenharmony_ci // parameters below are Q15 fixed-point number 1144a3e0fd82Sopenharmony_ci int64_t decU = FO_DECIMAL(u); 1145a3e0fd82Sopenharmony_ci int64_t decV = FO_DECIMAL(v); 1146a3e0fd82Sopenharmony_ci int64_t decUMinus1 = FIXED_NUM_1 - decU; 1147a3e0fd82Sopenharmony_ci int64_t decVMinus1 = FIXED_NUM_1 - decV; 1148a3e0fd82Sopenharmony_ci int64_t w1 = FO_MUL(decUMinus1, decVMinus1); 1149a3e0fd82Sopenharmony_ci int64_t w2 = FO_MUL(decU, decVMinus1); 1150a3e0fd82Sopenharmony_ci int64_t w3 = FO_MUL(decUMinus1, decV); 1151a3e0fd82Sopenharmony_ci int64_t w4 = FO_MUL(decU, decV); 1152a3e0fd82Sopenharmony_ci // parameters above are Q15 fixed-point number 1153a3e0fd82Sopenharmony_ci 1154a3e0fd82Sopenharmony_ci#if ENABLE_ARM_MATH 1155a3e0fd82Sopenharmony_ci const int64_t outR = __SMUAD(p1.red, w1) + __SMUAD(p2.red, w2) + __SMUAD(p3.red, w3) + __SMUAD(p4.red, w4); 1156a3e0fd82Sopenharmony_ci const int64_t outG = 1157a3e0fd82Sopenharmony_ci __SMUAD(p1.green, w1) + __SMUAD(p2.green, w2) + __SMUAD(p3.green, w3) + __SMUAD(p4.green, w4); 1158a3e0fd82Sopenharmony_ci const int64_t outB = 1159a3e0fd82Sopenharmony_ci __SMUAD(p1.blue, w1) + __SMUAD(p2.blue, w2) + __SMUAD(p3.blue, w3) + __SMUAD(p4.blue, w4); 1160a3e0fd82Sopenharmony_ci const int64_t outA = 1161a3e0fd82Sopenharmony_ci __SMUAD(p1.alpha, w1) + __SMUAD(p2.alpha, w2) + __SMUAD(p3.alpha, w3) + __SMUAD(p4.alpha, w4); 1162a3e0fd82Sopenharmony_ci#else 1163a3e0fd82Sopenharmony_ci const int64_t outR = p1.red * w1 + p2.red * w2 + p3.red * w3 + p4.red * w4; 1164a3e0fd82Sopenharmony_ci const int64_t outG = p1.green * w1 + p2.green * w2 + p3.green * w3 + p4.green * w4; 1165a3e0fd82Sopenharmony_ci const int64_t outB = p1.blue * w1 + p2.blue * w2 + p3.blue * w3 + p4.blue * w4; 1166a3e0fd82Sopenharmony_ci const int64_t outA = p1.alpha * w1 + p2.alpha * w2 + p3.alpha * w3 + p4.alpha * w4; 1167a3e0fd82Sopenharmony_ci#endif 1168a3e0fd82Sopenharmony_ci 1169a3e0fd82Sopenharmony_ci Color32 result; 1170a3e0fd82Sopenharmony_ci result.red = static_cast<uint8_t>(outR >> FIXED_Q_NUM); 1171a3e0fd82Sopenharmony_ci result.green = static_cast<uint8_t>(outG >> FIXED_Q_NUM); 1172a3e0fd82Sopenharmony_ci result.blue = static_cast<uint8_t>(outB >> FIXED_Q_NUM); 1173a3e0fd82Sopenharmony_ci result.alpha = static_cast<uint8_t>(outA >> FIXED_Q_NUM); 1174a3e0fd82Sopenharmony_ci if ((in.opaScale == OPA_OPAQUE) && (result.alpha == OPA_OPAQUE)) { 1175a3e0fd82Sopenharmony_ci COLOR_FILL_COVER(screenBuffer, bufferMode, result.red, result.green, result.blue, ARGB8888); 1176a3e0fd82Sopenharmony_ci } else { 1177a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, in.opaScale); 1178a3e0fd82Sopenharmony_ci } 1179a3e0fd82Sopenharmony_ci } 1180a3e0fd82Sopenharmony_ci u += in.init.duHorizon; 1181a3e0fd82Sopenharmony_ci v += in.init.dvHorizon; 1182a3e0fd82Sopenharmony_ci screenBuffer += in.bufferPxSize; 1183a3e0fd82Sopenharmony_ci } 1184a3e0fd82Sopenharmony_ci} 1185a3e0fd82Sopenharmony_ci#endif 1186a3e0fd82Sopenharmony_ci 1187a3e0fd82Sopenharmony_ci#ifdef ARM_NEON_OPT 1188a3e0fd82Sopenharmony_cistatic void DrawTriangleTrueColorBilinear8888InnerNeon(const TriangleScanInfo& in, 1189a3e0fd82Sopenharmony_ci uint8_t* screenBuffer, 1190a3e0fd82Sopenharmony_ci int16_t len, 1191a3e0fd82Sopenharmony_ci float u, 1192a3e0fd82Sopenharmony_ci float v, 1193a3e0fd82Sopenharmony_ci NeonBlendPipeLine& pipeLine, 1194a3e0fd82Sopenharmony_ci const ColorMode bufferMode) 1195a3e0fd82Sopenharmony_ci{ 1196a3e0fd82Sopenharmony_ci ColorType arrayp1[NEON_STEP_8] = {}; 1197a3e0fd82Sopenharmony_ci ColorType arrayp2[NEON_STEP_8] = {}; 1198a3e0fd82Sopenharmony_ci ColorType arrayp3[NEON_STEP_8] = {}; 1199a3e0fd82Sopenharmony_ci ColorType arrayp4[NEON_STEP_8] = {}; 1200a3e0fd82Sopenharmony_ci float arrayU[NEON_STEP_8] = {0}; 1201a3e0fd82Sopenharmony_ci float arrayV[NEON_STEP_8] = {0}; 1202a3e0fd82Sopenharmony_ci int32_t arrayPx1[NEON_STEP_8] = {0}; 1203a3e0fd82Sopenharmony_ci int16_t step = in.bufferPxSize * NEON_STEP_8; 1204a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1205a3e0fd82Sopenharmony_ci float duHorizon = static_cast<float>(in.init.duHorizon) / FIXED_NUM_1; 1206a3e0fd82Sopenharmony_ci float dvHorizon = static_cast<float>(in.init.dvHorizon) / FIXED_NUM_1; 1207a3e0fd82Sopenharmony_ci#endif 1208a3e0fd82Sopenharmony_ci while (len >= NEON_STEP_8) { 1209a3e0fd82Sopenharmony_ci for (uint32_t i = 0; i < NEON_STEP_8; ++i) { 1210a3e0fd82Sopenharmony_ci arrayU[i] = u; 1211a3e0fd82Sopenharmony_ci arrayV[i] = v; 1212a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1213a3e0fd82Sopenharmony_ci u += duHorizon; 1214a3e0fd82Sopenharmony_ci v += dvHorizon; 1215a3e0fd82Sopenharmony_ci#else 1216a3e0fd82Sopenharmony_ci u += in.init.duHorizon; 1217a3e0fd82Sopenharmony_ci v += in.init.dvHorizon; 1218a3e0fd82Sopenharmony_ci#endif 1219a3e0fd82Sopenharmony_ci } 1220a3e0fd82Sopenharmony_ci // Monotonically increasing or decreasing, so only judge the beginning and end. 1221a3e0fd82Sopenharmony_ci if ((arrayU[0] >= 0) && (arrayU[0] < in.info.header.width - 1) && (arrayV[0] >= 0) && 1222a3e0fd82Sopenharmony_ci (arrayV[0] < in.info.header.height - 1) && (arrayU[NEON_STEP_8 - 1] >= 0) && 1223a3e0fd82Sopenharmony_ci (arrayU[NEON_STEP_8 - 1] < in.info.header.width - 1) && (arrayV[NEON_STEP_8 - 1] >= 0) && 1224a3e0fd82Sopenharmony_ci (arrayV[NEON_STEP_8 - 1] < in.info.header.height - 1)) { 1225a3e0fd82Sopenharmony_ci // Process the lower half of arrayU and arrayV 1226a3e0fd82Sopenharmony_ci float32x4_t vU = vld1q_f32(arrayU); 1227a3e0fd82Sopenharmony_ci float32x4_t vV = vld1q_f32(arrayV); 1228a3e0fd82Sopenharmony_ci int32x4_t vIntU = vcvtq_s32_f32(vU); 1229a3e0fd82Sopenharmony_ci int32x4_t vIntV = vcvtq_s32_f32(vV); 1230a3e0fd82Sopenharmony_ci int32x4_t vPx1 = 1231a3e0fd82Sopenharmony_ci vaddq_s32(vmulq_s32(vIntV, vdupq_n_s32(in.srcLineWidth)), vmulq_s32(vIntU, vdupq_n_s32(in.pixelSize))); 1232a3e0fd82Sopenharmony_ci vst1q_s32(arrayPx1, vPx1); 1233a3e0fd82Sopenharmony_ci float32x4_t vDecU = vsubq_f32(vU, vcvtq_f32_s32(vIntU)); 1234a3e0fd82Sopenharmony_ci float32x4_t vDecV = vsubq_f32(vV, vcvtq_f32_s32(vIntV)); 1235a3e0fd82Sopenharmony_ci float32x4_t vDecUMinus1 = vsubq_f32(vdupq_n_f32(1.0), vDecU); 1236a3e0fd82Sopenharmony_ci float32x4_t vDecVMinus1 = vsubq_f32(vdupq_n_f32(1.0), vDecV); 1237a3e0fd82Sopenharmony_ci // 256:shift 8 bit left 1238a3e0fd82Sopenharmony_ci uint32x4_t vLowW1 = vcvtq_u32_f32(vmulq_f32(vmulq_f32(vDecUMinus1, vDecVMinus1), vdupq_n_f32(256.0))); 1239a3e0fd82Sopenharmony_ci uint32x4_t vLowW2 = vcvtq_u32_f32(vmulq_f32(vmulq_f32(vDecU, vDecVMinus1), vdupq_n_f32(256.0))); 1240a3e0fd82Sopenharmony_ci uint32x4_t vLowW3 = vcvtq_u32_f32(vmulq_f32(vmulq_f32(vDecUMinus1, vDecV), vdupq_n_f32(256.0))); 1241a3e0fd82Sopenharmony_ci uint32x4_t vLowW4 = vcvtq_u32_f32(vmulq_f32(vmulq_f32(vDecU, vDecV), vdupq_n_f32(256.0))); 1242a3e0fd82Sopenharmony_ci // Process the higher half of arrayU and arrayV 1243a3e0fd82Sopenharmony_ci vU = vld1q_f32(arrayU + NEON_STEP_4); 1244a3e0fd82Sopenharmony_ci vV = vld1q_f32(arrayV + NEON_STEP_4); 1245a3e0fd82Sopenharmony_ci vIntU = vcvtq_s32_f32(vU); 1246a3e0fd82Sopenharmony_ci vIntV = vcvtq_s32_f32(vV); 1247a3e0fd82Sopenharmony_ci vPx1 = 1248a3e0fd82Sopenharmony_ci vaddq_s32(vmulq_s32(vIntV, vdupq_n_s32(in.srcLineWidth)), vmulq_s32(vIntU, vdupq_n_s32(in.pixelSize))); 1249a3e0fd82Sopenharmony_ci vst1q_s32(arrayPx1 + NEON_STEP_4, vPx1); 1250a3e0fd82Sopenharmony_ci vDecU = vsubq_f32(vU, vcvtq_f32_s32(vIntU)); 1251a3e0fd82Sopenharmony_ci vDecV = vsubq_f32(vV, vcvtq_f32_s32(vIntV)); 1252a3e0fd82Sopenharmony_ci vDecUMinus1 = vsubq_f32(vdupq_n_f32(1.0), vDecU); 1253a3e0fd82Sopenharmony_ci vDecVMinus1 = vsubq_f32(vdupq_n_f32(1.0), vDecV); 1254a3e0fd82Sopenharmony_ci // 256:shift 8 bit left 1255a3e0fd82Sopenharmony_ci uint32x4_t vHighW1 = vcvtq_u32_f32(vmulq_f32(vmulq_f32(vDecUMinus1, vDecVMinus1), vdupq_n_f32(256.0))); 1256a3e0fd82Sopenharmony_ci uint32x4_t vHighW2 = vcvtq_u32_f32(vmulq_f32(vmulq_f32(vDecU, vDecVMinus1), vdupq_n_f32(256.0))); 1257a3e0fd82Sopenharmony_ci uint32x4_t vHighW3 = vcvtq_u32_f32(vmulq_f32(vmulq_f32(vDecUMinus1, vDecV), vdupq_n_f32(256.0))); 1258a3e0fd82Sopenharmony_ci uint32x4_t vHighW4 = vcvtq_u32_f32(vmulq_f32(vmulq_f32(vDecU, vDecV), vdupq_n_f32(256.0))); 1259a3e0fd82Sopenharmony_ci 1260a3e0fd82Sopenharmony_ci // joins two uint32x4_t vectors into a uint16x8_t vector 1261a3e0fd82Sopenharmony_ci uint16x8_t vW1 = vcombine_u16(vmovn_u32(vLowW1), vmovn_u32(vHighW1)); 1262a3e0fd82Sopenharmony_ci uint16x8_t vW2 = vcombine_u16(vmovn_u32(vLowW2), vmovn_u32(vHighW2)); 1263a3e0fd82Sopenharmony_ci uint16x8_t vW3 = vcombine_u16(vmovn_u32(vLowW3), vmovn_u32(vHighW3)); 1264a3e0fd82Sopenharmony_ci uint16x8_t vW4 = vcombine_u16(vmovn_u32(vLowW4), vmovn_u32(vHighW4)); 1265a3e0fd82Sopenharmony_ci 1266a3e0fd82Sopenharmony_ci uint8_t* imgHead = const_cast<uint8_t*>(in.info.data); 1267a3e0fd82Sopenharmony_ci for (uint32_t i = 0; i < NEON_STEP_8; ++i) { 1268a3e0fd82Sopenharmony_ci int32_t px1 = arrayPx1[i]; 1269a3e0fd82Sopenharmony_ci arrayp1[i] = *(reinterpret_cast<ColorType*>(&imgHead[px1])); 1270a3e0fd82Sopenharmony_ci arrayp2[i] = *(reinterpret_cast<ColorType*>(&imgHead[px1 + in.pixelSize])); 1271a3e0fd82Sopenharmony_ci arrayp3[i] = *(reinterpret_cast<ColorType*>(&imgHead[px1 + in.srcLineWidth])); 1272a3e0fd82Sopenharmony_ci arrayp4[i] = *(reinterpret_cast<ColorType*>(&imgHead[px1 + in.srcLineWidth + in.pixelSize])); 1273a3e0fd82Sopenharmony_ci } 1274a3e0fd82Sopenharmony_ci 1275a3e0fd82Sopenharmony_ci uint8x8x4_t v4p1 = vld4_u8(reinterpret_cast<uint8_t*>(arrayp1)); 1276a3e0fd82Sopenharmony_ci uint8x8x4_t v4p2 = vld4_u8(reinterpret_cast<uint8_t*>(arrayp2)); 1277a3e0fd82Sopenharmony_ci uint8x8x4_t v4p3 = vld4_u8(reinterpret_cast<uint8_t*>(arrayp3)); 1278a3e0fd82Sopenharmony_ci uint8x8x4_t v4p4 = vld4_u8(reinterpret_cast<uint8_t*>(arrayp4)); 1279a3e0fd82Sopenharmony_ci uint8x8_t vOutB = 1280a3e0fd82Sopenharmony_ci vshrn_n_u16(vmulq_u16(vmovl_u8(v4p1.val[NEON_B]), vW1) + vmulq_u16(vmovl_u8(v4p2.val[NEON_B]), vW2) + 1281a3e0fd82Sopenharmony_ci vmulq_u16(vmovl_u8(v4p3.val[NEON_B]), vW3) + vmulq_u16(vmovl_u8(v4p4.val[NEON_B]), vW4), 1282a3e0fd82Sopenharmony_ci 8); // 8:shift 8 bit right 1283a3e0fd82Sopenharmony_ci uint8x8_t vOutG = 1284a3e0fd82Sopenharmony_ci vshrn_n_u16(vmulq_u16(vmovl_u8(v4p1.val[NEON_G]), vW1) + vmulq_u16(vmovl_u8(v4p2.val[NEON_G]), vW2) + 1285a3e0fd82Sopenharmony_ci vmulq_u16(vmovl_u8(v4p3.val[NEON_G]), vW3) + vmulq_u16(vmovl_u8(v4p4.val[NEON_G]), vW4), 1286a3e0fd82Sopenharmony_ci 8); // 8:shift 8 bit right 1287a3e0fd82Sopenharmony_ci uint8x8_t vOutR = 1288a3e0fd82Sopenharmony_ci vshrn_n_u16(vmulq_u16(vmovl_u8(v4p1.val[NEON_R]), vW1) + vmulq_u16(vmovl_u8(v4p2.val[NEON_R]), vW2) + 1289a3e0fd82Sopenharmony_ci vmulq_u16(vmovl_u8(v4p3.val[NEON_R]), vW3) + vmulq_u16(vmovl_u8(v4p4.val[NEON_R]), vW4), 1290a3e0fd82Sopenharmony_ci 8); // 8:shift 8 bit right 1291a3e0fd82Sopenharmony_ci uint8x8_t vOutA = 1292a3e0fd82Sopenharmony_ci vshrn_n_u16(vmulq_u16(vmovl_u8(v4p1.val[NEON_A]), vW1) + vmulq_u16(vmovl_u8(v4p2.val[NEON_A]), vW2) + 1293a3e0fd82Sopenharmony_ci vmulq_u16(vmovl_u8(v4p3.val[NEON_A]), vW3) + vmulq_u16(vmovl_u8(v4p4.val[NEON_A]), vW4), 1294a3e0fd82Sopenharmony_ci 8); // 8:shift 8 bit right 1295a3e0fd82Sopenharmony_ci vOutA = NeonMulDiv255(vdup_n_u8(in.opaScale), vOutA); 1296a3e0fd82Sopenharmony_ci pipeLine.Invoke(screenBuffer, vOutR, vOutG, vOutB, vOutA); 1297a3e0fd82Sopenharmony_ci } else { 1298a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1299a3e0fd82Sopenharmony_ci int64_t fixedU = FO_TRANS_FLOAT_TO_FIXED(arrayU[0]); 1300a3e0fd82Sopenharmony_ci int64_t fixedV = FO_TRANS_FLOAT_TO_FIXED(arrayV[0]); 1301a3e0fd82Sopenharmony_ci DrawFixedTriangleTrueColorBilinear8888Inner(in, screenBuffer, NEON_STEP_8, bufferMode, fixedU, fixedV); 1302a3e0fd82Sopenharmony_ci#else 1303a3e0fd82Sopenharmony_ci DrawTriangleTrueColorBilinear8888Inner(in, screenBuffer, NEON_STEP_8, bufferMode, arrayU[0], arrayV[0]); 1304a3e0fd82Sopenharmony_ci#endif 1305a3e0fd82Sopenharmony_ci } 1306a3e0fd82Sopenharmony_ci screenBuffer += step; 1307a3e0fd82Sopenharmony_ci len -= NEON_STEP_8; 1308a3e0fd82Sopenharmony_ci } 1309a3e0fd82Sopenharmony_ci if (len > 0) { 1310a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1311a3e0fd82Sopenharmony_ci int64_t fixedU = FO_TRANS_FLOAT_TO_FIXED(u); 1312a3e0fd82Sopenharmony_ci int64_t fixedV = FO_TRANS_FLOAT_TO_FIXED(v); 1313a3e0fd82Sopenharmony_ci DrawFixedTriangleTrueColorBilinear8888Inner(in, screenBuffer, len, bufferMode, fixedU, fixedV); 1314a3e0fd82Sopenharmony_ci#else 1315a3e0fd82Sopenharmony_ci DrawTriangleTrueColorBilinear8888Inner(in, screenBuffer, len, bufferMode, u, v); 1316a3e0fd82Sopenharmony_ci#endif 1317a3e0fd82Sopenharmony_ci } 1318a3e0fd82Sopenharmony_ci} 1319a3e0fd82Sopenharmony_ci#endif 1320a3e0fd82Sopenharmony_ci 1321a3e0fd82Sopenharmony_civoid DrawUtils::Draw3DTriangleTrueColorBilinear8888(const TriangleScanInfo& in, const ColorMode bufferMode) 1322a3e0fd82Sopenharmony_ci{ 1323a3e0fd82Sopenharmony_ci int16_t maskLeft = in.mask.GetLeft(); 1324a3e0fd82Sopenharmony_ci int16_t maskRight = in.mask.GetRight(); 1325a3e0fd82Sopenharmony_ci int16_t xMinErr = 0; 1326a3e0fd82Sopenharmony_ci int16_t xMaxErr = 0; 1327a3e0fd82Sopenharmony_ci GetXAxisErrForJunctionLine(in.ignoreJunctionPoint, in.isRightPart, xMinErr, xMaxErr); 1328a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1329a3e0fd82Sopenharmony_ci int64_t invMatrix00 = FO_TRANS_FLOAT_TO_FIXED(in.matrix.GetData()[0]); 1330a3e0fd82Sopenharmony_ci int64_t invMatrix01 = FO_TRANS_FLOAT_TO_FIXED(in.matrix.GetData()[1]); 1331a3e0fd82Sopenharmony_ci int64_t invMatrix02 = FO_TRANS_FLOAT_TO_FIXED(in.matrix.GetData()[2]); 1332a3e0fd82Sopenharmony_ci int64_t invMatrix20 = FO_TRANS_FLOAT_TO_FIXED(in.matrix.GetData()[3]); 1333a3e0fd82Sopenharmony_ci int64_t invMatrix21 = FO_TRANS_FLOAT_TO_FIXED(in.matrix.GetData()[4]); 1334a3e0fd82Sopenharmony_ci int64_t invMatrix22 = FO_TRANS_FLOAT_TO_FIXED(in.matrix.GetData()[5]); 1335a3e0fd82Sopenharmony_ci int64_t invMatrix30 = FO_TRANS_FLOAT_TO_FIXED(in.matrix.GetData()[6]); 1336a3e0fd82Sopenharmony_ci int64_t invMatrix31 = FO_TRANS_FLOAT_TO_FIXED(in.matrix.GetData()[7]); 1337a3e0fd82Sopenharmony_ci int64_t invMatrix32 = FO_TRANS_FLOAT_TO_FIXED(in.matrix.GetData()[8]); 1338a3e0fd82Sopenharmony_ci#else // ENABLE_FIXED_POINT 1339a3e0fd82Sopenharmony_ci float invMatrix00 = in.matrix.GetData()[0]; 1340a3e0fd82Sopenharmony_ci float invMatrix01 = in.matrix.GetData()[1]; 1341a3e0fd82Sopenharmony_ci float invMatrix02 = in.matrix.GetData()[2]; 1342a3e0fd82Sopenharmony_ci float invMatrix20 = in.matrix.GetData()[3]; 1343a3e0fd82Sopenharmony_ci float invMatrix21 = in.matrix.GetData()[4]; 1344a3e0fd82Sopenharmony_ci float invMatrix22 = in.matrix.GetData()[5]; 1345a3e0fd82Sopenharmony_ci float invMatrix30 = in.matrix.GetData()[6]; 1346a3e0fd82Sopenharmony_ci float invMatrix31 = in.matrix.GetData()[7]; 1347a3e0fd82Sopenharmony_ci float invMatrix32 = in.matrix.GetData()[8]; 1348a3e0fd82Sopenharmony_ci#endif // ENABLE_FIXED_POINT 1349a3e0fd82Sopenharmony_ci for (int16_t y = in.yMin; y <= in.yMax; ++y) { 1350a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1351a3e0fd82Sopenharmony_ci int16_t tempV = FO_TO_INTEGER(in.edge1.curX) + xMinErr; 1352a3e0fd82Sopenharmony_ci int16_t xMin = MATH_MAX(tempV, maskLeft); 1353a3e0fd82Sopenharmony_ci tempV = FO_TO_INTEGER(in.edge2.curX) + xMaxErr; 1354a3e0fd82Sopenharmony_ci int16_t xMax = MATH_MIN(tempV, maskRight); 1355a3e0fd82Sopenharmony_ci#else // ENABLE_FIXED_POINT 1356a3e0fd82Sopenharmony_ci int16_t xMin = MATH_MAX(static_cast<int16_t>(in.edge1.curX + xMinErr), maskLeft); 1357a3e0fd82Sopenharmony_ci int16_t xMax = MATH_MIN(static_cast<int16_t>(in.edge2.curX + xMaxErr), maskRight); 1358a3e0fd82Sopenharmony_ci#endif // ENABLE_FIXED_POINT 1359a3e0fd82Sopenharmony_ci uint8_t* screenBuffer = in.screenBuffer + (y * in.screenBufferWidth + xMin) * in.bufferPxSize; 1360a3e0fd82Sopenharmony_ci // move to current position 1361a3e0fd82Sopenharmony_ci for (int16_t x = xMin; x <= xMax; x++) { 1362a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1363a3e0fd82Sopenharmony_ci int64_t w = invMatrix02 * x + invMatrix22 * y + invMatrix32; 1364a3e0fd82Sopenharmony_ci int64_t u = FO_DIV((invMatrix00 * x + invMatrix20 * y + invMatrix30), w); 1365a3e0fd82Sopenharmony_ci int64_t v = FO_DIV((invMatrix01 * x + invMatrix21 * y + invMatrix31), w); 1366a3e0fd82Sopenharmony_ci int16_t intU = FO_TO_INTEGER(u); 1367a3e0fd82Sopenharmony_ci int16_t intV = FO_TO_INTEGER(v); 1368a3e0fd82Sopenharmony_ci#else // ENABLE_FIXED_POINT 1369a3e0fd82Sopenharmony_ci float w = invMatrix02 * x + invMatrix22 * y + invMatrix32; 1370a3e0fd82Sopenharmony_ci float u = (invMatrix00 * x + invMatrix20 * y + invMatrix30) / w; 1371a3e0fd82Sopenharmony_ci float v = (invMatrix01 * x + invMatrix21 * y + invMatrix31) / w; 1372a3e0fd82Sopenharmony_ci int16_t intU = static_cast<int16_t>(u); 1373a3e0fd82Sopenharmony_ci int16_t intV = static_cast<int16_t>(v); 1374a3e0fd82Sopenharmony_ci#endif // ENABLE_FIXED_POINT 1375a3e0fd82Sopenharmony_ci if ((u >= 0) && (intU < in.info.header.width - 1) && (v >= 0) && (intV < in.info.header.height - 1)) { 1376a3e0fd82Sopenharmony_ci#if ENABLE_ARM_MATH 1377a3e0fd82Sopenharmony_ci uint32_t val1 = __SMUAD(intV, in.srcLineWidth); 1378a3e0fd82Sopenharmony_ci uint32_t val2 = __SMUAD(intU, in.pixelSize); 1379a3e0fd82Sopenharmony_ci uint32_t px1 = val1 + val2; 1380a3e0fd82Sopenharmony_ci#else // ENABLE_ARM_MATH 1381a3e0fd82Sopenharmony_ci uint32_t px1 = intV * in.srcLineWidth + intU * in.pixelSize; 1382a3e0fd82Sopenharmony_ci#endif // ENABLE_ARM_MATH 1383a3e0fd82Sopenharmony_ci uint8_t* imgHead = const_cast<uint8_t*>(in.info.data); 1384a3e0fd82Sopenharmony_ci const ColorType p1 = *(reinterpret_cast<ColorType*>(&imgHead[px1])); 1385a3e0fd82Sopenharmony_ci const ColorType p2 = *(reinterpret_cast<ColorType*>(&imgHead[px1 + in.pixelSize])); 1386a3e0fd82Sopenharmony_ci const ColorType p3 = *(reinterpret_cast<ColorType*>(&imgHead[px1 + in.srcLineWidth])); 1387a3e0fd82Sopenharmony_ci const ColorType p4 = *(reinterpret_cast<ColorType*>(&imgHead[px1 + in.srcLineWidth + in.pixelSize])); 1388a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1389a3e0fd82Sopenharmony_ci int64_t decU = FO_DECIMAL(u); 1390a3e0fd82Sopenharmony_ci int64_t decV = FO_DECIMAL(v); 1391a3e0fd82Sopenharmony_ci int64_t decUMinus1 = FIXED_NUM_1 - decU; 1392a3e0fd82Sopenharmony_ci int64_t decVMinus1 = FIXED_NUM_1 - decV; 1393a3e0fd82Sopenharmony_ci int64_t w1 = FO_MUL(decUMinus1, decVMinus1); 1394a3e0fd82Sopenharmony_ci int64_t w2 = FO_MUL(decU, decVMinus1); 1395a3e0fd82Sopenharmony_ci int64_t w3 = FO_MUL(decUMinus1, decV); 1396a3e0fd82Sopenharmony_ci int64_t w4 = FO_MUL(decU, decV); 1397a3e0fd82Sopenharmony_ci#if ENABLE_ARM_MATH 1398a3e0fd82Sopenharmony_ci const int64_t outR = 1399a3e0fd82Sopenharmony_ci __SMUAD(p1.red, w1) + __SMUAD(p2.red, w2) + __SMUAD(p3.red, w3) + __SMUAD(p4.red, w4); 1400a3e0fd82Sopenharmony_ci const int64_t outG = 1401a3e0fd82Sopenharmony_ci __SMUAD(p1.green, w1) + __SMUAD(p2.green, w2) + __SMUAD(p3.green, w3) + __SMUAD(p4.green, w4); 1402a3e0fd82Sopenharmony_ci const int64_t outB = 1403a3e0fd82Sopenharmony_ci __SMUAD(p1.blue, w1) + __SMUAD(p2.blue, w2) + __SMUAD(p3.blue, w3) + __SMUAD(p4.blue, w4); 1404a3e0fd82Sopenharmony_ci const int64_t outA = 1405a3e0fd82Sopenharmony_ci __SMUAD(p1.alpha, w1) + __SMUAD(p2.alpha, w2) + __SMUAD(p3.alpha, w3) + __SMUAD(p4.alpha, w4); 1406a3e0fd82Sopenharmony_ci#else 1407a3e0fd82Sopenharmony_ci const int64_t outR = p1.red * w1 + p2.red * w2 + p3.red * w3 + p4.red * w4; 1408a3e0fd82Sopenharmony_ci const int64_t outG = p1.green * w1 + p2.green * w2 + p3.green * w3 + p4.green * w4; 1409a3e0fd82Sopenharmony_ci const int64_t outB = p1.blue * w1 + p2.blue * w2 + p3.blue * w3 + p4.blue * w4; 1410a3e0fd82Sopenharmony_ci const int64_t outA = p1.alpha * w1 + p2.alpha * w2 + p3.alpha * w3 + p4.alpha * w4; 1411a3e0fd82Sopenharmony_ci#endif 1412a3e0fd82Sopenharmony_ci Color32 result; 1413a3e0fd82Sopenharmony_ci result.red = static_cast<uint8_t>(outR >> FIXED_Q_NUM); 1414a3e0fd82Sopenharmony_ci result.green = static_cast<uint8_t>(outG >> FIXED_Q_NUM); 1415a3e0fd82Sopenharmony_ci result.blue = static_cast<uint8_t>(outB >> FIXED_Q_NUM); 1416a3e0fd82Sopenharmony_ci result.alpha = static_cast<uint8_t>(outA >> FIXED_Q_NUM); 1417a3e0fd82Sopenharmony_ci#else // ENABLE_FIXED_POINT 1418a3e0fd82Sopenharmony_ci const float decU = u - intU; 1419a3e0fd82Sopenharmony_ci const float decV = v - intV; 1420a3e0fd82Sopenharmony_ci const float decUMinus1 = 1 - decU; 1421a3e0fd82Sopenharmony_ci const float decVMinus1 = 1 - decV; 1422a3e0fd82Sopenharmony_ci const int32_t w1 = static_cast<int32_t>(decUMinus1 * decVMinus1 * 256.0f); // 256:shift 8 bit left 1423a3e0fd82Sopenharmony_ci const int32_t w2 = static_cast<int32_t>(decU * decVMinus1 * 256.0f); // 256:shift 8 bit left 1424a3e0fd82Sopenharmony_ci const int32_t w3 = static_cast<int32_t>(decUMinus1 * decV * 256.0f); // 256:shift 8 bit left 1425a3e0fd82Sopenharmony_ci const int32_t w4 = static_cast<int32_t>(decU * decV * 256.0f); 1426a3e0fd82Sopenharmony_ci#if ENABLE_ARM_MATH 1427a3e0fd82Sopenharmony_ci const int32_t outR = 1428a3e0fd82Sopenharmony_ci __SMUAD(p1.red, w1) + __SMUAD(p2.red, w2) + __SMUAD(p3.red, w3) + __SMUAD(p4.red, w4); 1429a3e0fd82Sopenharmony_ci const int32_t outG = 1430a3e0fd82Sopenharmony_ci __SMUAD(p1.green, w1) + __SMUAD(p2.green, w2) + __SMUAD(p3.green, w3) + __SMUAD(p4.green, w4); 1431a3e0fd82Sopenharmony_ci const int32_t outB = 1432a3e0fd82Sopenharmony_ci __SMUAD(p1.blue, w1) + __SMUAD(p2.blue, w2) + __SMUAD(p3.blue, w3) + __SMUAD(p4.blue, w4); 1433a3e0fd82Sopenharmony_ci const int32_t outA = 1434a3e0fd82Sopenharmony_ci __SMUAD(p1.alpha, w1) + __SMUAD(p2.alpha, w2) + __SMUAD(p3.alpha, w3) + __SMUAD(p4.alpha, w4); 1435a3e0fd82Sopenharmony_ci#else // ENABLE_ARM_MATH 1436a3e0fd82Sopenharmony_ci const int32_t outR = p1.red * w1 + p2.red * w2 + p3.red * w3 + p4.red * w4; 1437a3e0fd82Sopenharmony_ci const int32_t outG = p1.green * w1 + p2.green * w2 + p3.green * w3 + p4.green * w4; 1438a3e0fd82Sopenharmony_ci const int32_t outB = p1.blue * w1 + p2.blue * w2 + p3.blue * w3 + p4.blue * w4; 1439a3e0fd82Sopenharmony_ci const int32_t outA = p1.alpha * w1 + p2.alpha * w2 + p3.alpha * w3 + p4.alpha * w4; 1440a3e0fd82Sopenharmony_ci#endif // ENABLE_ARM_MATH 1441a3e0fd82Sopenharmony_ci Color32 result; 1442a3e0fd82Sopenharmony_ci result.red = static_cast<uint8_t>(outR >> 8); // 8:shift 8 bit right 1443a3e0fd82Sopenharmony_ci result.green = static_cast<uint8_t>(outG >> 8); // 8:shift 8 bit right 1444a3e0fd82Sopenharmony_ci result.blue = static_cast<uint8_t>(outB >> 8); // 8:shift 8 bit right 1445a3e0fd82Sopenharmony_ci result.alpha = static_cast<uint8_t>(outA >> 8); // 8:shift 8 bit right 1446a3e0fd82Sopenharmony_ci#endif // ENABLE_FIXED_POINT 1447a3e0fd82Sopenharmony_ci if ((in.opaScale == OPA_OPAQUE) && (result.alpha == OPA_OPAQUE)) { 1448a3e0fd82Sopenharmony_ci COLOR_FILL_COVER(screenBuffer, bufferMode, result.red, result.green, result.blue, ARGB8888); 1449a3e0fd82Sopenharmony_ci } else { 1450a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, in.opaScale); 1451a3e0fd82Sopenharmony_ci } 1452a3e0fd82Sopenharmony_ci } 1453a3e0fd82Sopenharmony_ci screenBuffer += in.bufferPxSize; 1454a3e0fd82Sopenharmony_ci } 1455a3e0fd82Sopenharmony_ci StepToNextLine(in.edge1, in.edge2); 1456a3e0fd82Sopenharmony_ci } 1457a3e0fd82Sopenharmony_ci} 1458a3e0fd82Sopenharmony_ci 1459a3e0fd82Sopenharmony_civoid DrawUtils::DrawTriangleTrueColorBilinear8888(const TriangleScanInfo& in, const ColorMode bufferMode) 1460a3e0fd82Sopenharmony_ci{ 1461a3e0fd82Sopenharmony_ci int16_t maskLeft = in.mask.GetLeft(); 1462a3e0fd82Sopenharmony_ci int16_t maskRight = in.mask.GetRight(); 1463a3e0fd82Sopenharmony_ci int16_t xMinErr = 0; 1464a3e0fd82Sopenharmony_ci int16_t xMaxErr = 0; 1465a3e0fd82Sopenharmony_ci GetXAxisErrForJunctionLine(in.ignoreJunctionPoint, in.isRightPart, xMinErr, xMaxErr); 1466a3e0fd82Sopenharmony_ci#ifdef ARM_NEON_OPT 1467a3e0fd82Sopenharmony_ci NeonBlendPipeLine pipeLine; 1468a3e0fd82Sopenharmony_ci pipeLine.Construct(bufferMode, ARGB8888); 1469a3e0fd82Sopenharmony_ci#endif 1470a3e0fd82Sopenharmony_ci for (int16_t y = in.yMin; y <= in.yMax; ++y) { 1471a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1472a3e0fd82Sopenharmony_ci int16_t tempV = FO_TO_INTEGER(in.edge1.curX) + xMinErr; 1473a3e0fd82Sopenharmony_ci int16_t xMin = MATH_MAX(tempV, maskLeft); 1474a3e0fd82Sopenharmony_ci tempV = FO_TO_INTEGER(in.edge2.curX) + xMaxErr; 1475a3e0fd82Sopenharmony_ci int16_t xMax = MATH_MIN(tempV, maskRight); 1476a3e0fd82Sopenharmony_ci int16_t diffX = xMin - FO_TO_INTEGER(in.edge1.curX); 1477a3e0fd82Sopenharmony_ci#else 1478a3e0fd82Sopenharmony_ci int16_t xMin = MATH_MAX(static_cast<int16_t>(in.edge1.curX + xMinErr), maskLeft); 1479a3e0fd82Sopenharmony_ci int16_t xMax = MATH_MIN(static_cast<int16_t>(in.edge2.curX + xMaxErr), maskRight); 1480a3e0fd82Sopenharmony_ci int16_t diffX = (xMin - static_cast<int32_t>(in.edge1.curX)); 1481a3e0fd82Sopenharmony_ci#endif 1482a3e0fd82Sopenharmony_ci in.init.verticalU += in.init.duHorizon * diffX; 1483a3e0fd82Sopenharmony_ci in.init.verticalV += in.init.dvHorizon * diffX; 1484a3e0fd82Sopenharmony_ci uint8_t* screenBuffer = in.screenBuffer + (y * in.screenBufferWidth + xMin) * in.bufferPxSize; 1485a3e0fd82Sopenharmony_ci#ifdef ARM_NEON_OPT 1486a3e0fd82Sopenharmony_ci { 1487a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1488a3e0fd82Sopenharmony_ci float u = static_cast<float>(in.init.verticalU) / FIXED_NUM_1; 1489a3e0fd82Sopenharmony_ci float v = static_cast<float>(in.init.verticalV) / FIXED_NUM_1; 1490a3e0fd82Sopenharmony_ci#else 1491a3e0fd82Sopenharmony_ci float u = in.init.verticalU; 1492a3e0fd82Sopenharmony_ci float v = in.init.verticalV; 1493a3e0fd82Sopenharmony_ci#endif 1494a3e0fd82Sopenharmony_ci DEBUG_PERFORMANCE_TRACE("DrawTriangleTrueColorBilinear8888_neon"); 1495a3e0fd82Sopenharmony_ci DrawTriangleTrueColorBilinear8888InnerNeon(in, screenBuffer, xMax - xMin + 1, u, v, pipeLine, bufferMode); 1496a3e0fd82Sopenharmony_ci } 1497a3e0fd82Sopenharmony_ci#else 1498a3e0fd82Sopenharmony_ci { 1499a3e0fd82Sopenharmony_ci DEBUG_PERFORMANCE_TRACE("DrawTriangleTrueColorBilinear8888"); 1500a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1501a3e0fd82Sopenharmony_ci DrawFixedTriangleTrueColorBilinear8888Inner(in, screenBuffer, xMax - xMin + 1, bufferMode, 1502a3e0fd82Sopenharmony_ci in.init.verticalU, in.init.verticalV); 1503a3e0fd82Sopenharmony_ci#else 1504a3e0fd82Sopenharmony_ci DrawTriangleTrueColorBilinear8888Inner(in, screenBuffer, xMax - xMin + 1, bufferMode, in.init.verticalU, 1505a3e0fd82Sopenharmony_ci in.init.verticalV); 1506a3e0fd82Sopenharmony_ci#endif 1507a3e0fd82Sopenharmony_ci } 1508a3e0fd82Sopenharmony_ci#endif 1509a3e0fd82Sopenharmony_ci StepToNextLine(in.edge1, in.edge2); 1510a3e0fd82Sopenharmony_ci in.init.verticalU += in.init.duVertical; 1511a3e0fd82Sopenharmony_ci in.init.verticalV += in.init.dvVertical; 1512a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1513a3e0fd82Sopenharmony_ci int16_t deltaX = FO_TO_INTEGER(in.edge1.curX) - xMin; 1514a3e0fd82Sopenharmony_ci#else 1515a3e0fd82Sopenharmony_ci int16_t deltaX = static_cast<int16_t>(in.edge1.curX) - xMin; 1516a3e0fd82Sopenharmony_ci#endif 1517a3e0fd82Sopenharmony_ci in.init.verticalU += in.init.duHorizon * deltaX; 1518a3e0fd82Sopenharmony_ci in.init.verticalV += in.init.dvHorizon * deltaX; 1519a3e0fd82Sopenharmony_ci } 1520a3e0fd82Sopenharmony_ci} 1521a3e0fd82Sopenharmony_ci 1522a3e0fd82Sopenharmony_civoid DrawUtils::DrawTriangleTrueColorNearest(const TriangleScanInfo& in, const ColorMode bufferMode) 1523a3e0fd82Sopenharmony_ci{ 1524a3e0fd82Sopenharmony_ci int16_t maskLeft = in.mask.GetLeft(); 1525a3e0fd82Sopenharmony_ci int16_t maskRight = in.mask.GetRight(); 1526a3e0fd82Sopenharmony_ci int16_t xMinErr = 0; 1527a3e0fd82Sopenharmony_ci int16_t xMaxErr = 0; 1528a3e0fd82Sopenharmony_ci GetXAxisErrForJunctionLine(in.ignoreJunctionPoint, in.isRightPart, xMinErr, xMaxErr); 1529a3e0fd82Sopenharmony_ci for (int16_t y = in.yMin; y <= in.yMax; y++) { 1530a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1531a3e0fd82Sopenharmony_ci int16_t tempV = FO_TO_INTEGER(in.edge1.curX) + xMinErr; 1532a3e0fd82Sopenharmony_ci int16_t xMin = MATH_MAX(tempV, maskLeft); 1533a3e0fd82Sopenharmony_ci tempV = FO_TO_INTEGER(in.edge2.curX) + xMaxErr; 1534a3e0fd82Sopenharmony_ci int16_t xMax = MATH_MIN(tempV, maskRight); 1535a3e0fd82Sopenharmony_ci int16_t diffX = xMin - FO_TO_INTEGER(in.edge1.curX); 1536a3e0fd82Sopenharmony_ci#else 1537a3e0fd82Sopenharmony_ci int16_t xMin = MATH_MAX(static_cast<int16_t>(in.edge1.curX + xMinErr), maskLeft); 1538a3e0fd82Sopenharmony_ci int16_t xMax = MATH_MIN(static_cast<int16_t>(in.edge2.curX + xMaxErr), maskRight); 1539a3e0fd82Sopenharmony_ci int16_t diffX = (xMin - static_cast<int32_t>(in.edge1.curX)); 1540a3e0fd82Sopenharmony_ci#endif 1541a3e0fd82Sopenharmony_ci in.init.verticalU += in.init.duHorizon * diffX; 1542a3e0fd82Sopenharmony_ci in.init.verticalV += in.init.dvHorizon * diffX; 1543a3e0fd82Sopenharmony_ci uint8_t* screenBuffer = in.screenBuffer + (y * in.screenBufferWidth + xMin) * in.bufferPxSize; 1544a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1545a3e0fd82Sopenharmony_ci // parameters below are Q15 fixed-point number 1546a3e0fd82Sopenharmony_ci int64_t u = in.init.verticalU; 1547a3e0fd82Sopenharmony_ci int64_t v = in.init.verticalV; 1548a3e0fd82Sopenharmony_ci // parameters above are Q15 fixed-point number 1549a3e0fd82Sopenharmony_ci#else 1550a3e0fd82Sopenharmony_ci float u = in.init.verticalU; 1551a3e0fd82Sopenharmony_ci float v = in.init.verticalV; 1552a3e0fd82Sopenharmony_ci#endif 1553a3e0fd82Sopenharmony_ci for (int16_t x = xMin; x <= xMax; x++) { 1554a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1555a3e0fd82Sopenharmony_ci int16_t intU = FO_TO_INTEGER(u); 1556a3e0fd82Sopenharmony_ci int16_t intV = FO_TO_INTEGER(v); 1557a3e0fd82Sopenharmony_ci if ((u >= 0) && (intU < (in.info.header.width - 1)) && (v >= 0) && (intV < (in.info.header.height - 1))) { 1558a3e0fd82Sopenharmony_ci#else 1559a3e0fd82Sopenharmony_ci const int16_t intU = static_cast<int16_t>(u); 1560a3e0fd82Sopenharmony_ci const int16_t intV = static_cast<int16_t>(v); 1561a3e0fd82Sopenharmony_ci if ((u >= 0) && (intU < in.info.header.width - 1) && (v >= 0) && (intV < in.info.header.height - 1)) { 1562a3e0fd82Sopenharmony_ci#endif 1563a3e0fd82Sopenharmony_ci#if ENABLE_ARM_MATH 1564a3e0fd82Sopenharmony_ci uint32_t val1 = __SMUAD(intV, in.srcLineWidth); 1565a3e0fd82Sopenharmony_ci uint32_t val2 = __SMUAD(intU, in.pixelSize); 1566a3e0fd82Sopenharmony_ci uint32_t px1 = val1 + val2; 1567a3e0fd82Sopenharmony_ci#else 1568a3e0fd82Sopenharmony_ci uint32_t px1 = intV * in.srcLineWidth + intU * in.pixelSize; 1569a3e0fd82Sopenharmony_ci#endif 1570a3e0fd82Sopenharmony_ci uint8_t* imgHead = const_cast<uint8_t*>(in.info.data); 1571a3e0fd82Sopenharmony_ci OpacityType opa = in.opaScale; 1572a3e0fd82Sopenharmony_ci 1573a3e0fd82Sopenharmony_ci switch (in.info.header.colorMode) { 1574a3e0fd82Sopenharmony_ci case RGB888: { 1575a3e0fd82Sopenharmony_ci Color24 p24 = *(reinterpret_cast<Color24*>(&imgHead[px1])); 1576a3e0fd82Sopenharmony_ci if (opa == OPA_OPAQUE) { 1577a3e0fd82Sopenharmony_ci COLOR_FILL_COVER(screenBuffer, bufferMode, p24.red, p24.green, p24.blue, RGB888); 1578a3e0fd82Sopenharmony_ci } else { 1579a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &p24, RGB888, opa); 1580a3e0fd82Sopenharmony_ci } 1581a3e0fd82Sopenharmony_ci break; 1582a3e0fd82Sopenharmony_ci } 1583a3e0fd82Sopenharmony_ci case RGB565: { 1584a3e0fd82Sopenharmony_ci Color16 p16 = *(reinterpret_cast<Color16*>(&imgHead[px1])); 1585a3e0fd82Sopenharmony_ci if (opa == OPA_OPAQUE) { 1586a3e0fd82Sopenharmony_ci COLOR_FILL_COVER(screenBuffer, bufferMode, p16.red, p16.green, p16.blue, RGB565); 1587a3e0fd82Sopenharmony_ci } else { 1588a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &p16, RGB565, opa); 1589a3e0fd82Sopenharmony_ci } 1590a3e0fd82Sopenharmony_ci break; 1591a3e0fd82Sopenharmony_ci } 1592a3e0fd82Sopenharmony_ci case ARGB8888: { 1593a3e0fd82Sopenharmony_ci Color32 p32 = *(reinterpret_cast<Color32*>(&imgHead[px1])); 1594a3e0fd82Sopenharmony_ci if ((in.opaScale == OPA_OPAQUE) && (p32.alpha == OPA_OPAQUE)) { 1595a3e0fd82Sopenharmony_ci COLOR_FILL_COVER(screenBuffer, bufferMode, p32.red, p32.green, p32.blue, ARGB8888); 1596a3e0fd82Sopenharmony_ci } else { 1597a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &p32, ARGB8888, in.opaScale); 1598a3e0fd82Sopenharmony_ci } 1599a3e0fd82Sopenharmony_ci break; 1600a3e0fd82Sopenharmony_ci } 1601a3e0fd82Sopenharmony_ci case XRGB8888: { 1602a3e0fd82Sopenharmony_ci Color32 p32 = *(reinterpret_cast<Color32*>(&imgHead[px1])); 1603a3e0fd82Sopenharmony_ci if ((in.opaScale == OPA_OPAQUE) && (p32.alpha == OPA_OPAQUE)) { 1604a3e0fd82Sopenharmony_ci COLOR_FILL_COVER(screenBuffer, bufferMode, p32.red, p32.green, p32.blue, XRGB8888); 1605a3e0fd82Sopenharmony_ci } else { 1606a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &p32, XRGB8888, in.opaScale); 1607a3e0fd82Sopenharmony_ci } 1608a3e0fd82Sopenharmony_ci break; 1609a3e0fd82Sopenharmony_ci } 1610a3e0fd82Sopenharmony_ci default: 1611a3e0fd82Sopenharmony_ci return; 1612a3e0fd82Sopenharmony_ci } 1613a3e0fd82Sopenharmony_ci } 1614a3e0fd82Sopenharmony_ci u += in.init.duHorizon; 1615a3e0fd82Sopenharmony_ci v += in.init.dvHorizon; 1616a3e0fd82Sopenharmony_ci screenBuffer += in.bufferPxSize; 1617a3e0fd82Sopenharmony_ci } 1618a3e0fd82Sopenharmony_ci StepToNextLine(in.edge1, in.edge2); 1619a3e0fd82Sopenharmony_ci in.init.verticalU += in.init.duVertical; 1620a3e0fd82Sopenharmony_ci in.init.verticalV += in.init.dvVertical; 1621a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1622a3e0fd82Sopenharmony_ci int16_t deltaX = FO_TO_INTEGER(in.edge1.curX) - xMin; 1623a3e0fd82Sopenharmony_ci#else 1624a3e0fd82Sopenharmony_ci int16_t deltaX = static_cast<int16_t>(in.edge1.curX) - xMin; 1625a3e0fd82Sopenharmony_ci#endif 1626a3e0fd82Sopenharmony_ci in.init.verticalU += in.init.duHorizon * deltaX; 1627a3e0fd82Sopenharmony_ci in.init.verticalV += in.init.dvHorizon * deltaX; 1628a3e0fd82Sopenharmony_ci } 1629a3e0fd82Sopenharmony_ci} 1630a3e0fd82Sopenharmony_ci 1631a3e0fd82Sopenharmony_civoid DrawUtils::DrawTriangleTransformPart(BufferInfo& gfxDstBuffer, const TrianglePartInfo& part) 1632a3e0fd82Sopenharmony_ci{ 1633a3e0fd82Sopenharmony_ci#if ENABLE_FIXED_POINT 1634a3e0fd82Sopenharmony_ci // parameters below are Q15 fixed-point number 1635a3e0fd82Sopenharmony_ci int64_t yMin = FO_TRANS_INTEGER_TO_FIXED(part.yMin); 1636a3e0fd82Sopenharmony_ci part.edge1.curX += (static_cast<int64_t>(part.edge1.du) * (yMin - part.edge1.curY) / part.edge1.dv); 1637a3e0fd82Sopenharmony_ci part.edge1.curY = yMin; 1638a3e0fd82Sopenharmony_ci part.edge2.curX += (static_cast<int64_t>(part.edge2.du) * (yMin - part.edge2.curY) / part.edge2.dv); 1639a3e0fd82Sopenharmony_ci part.edge2.curY = yMin; 1640a3e0fd82Sopenharmony_ci Rect line; 1641a3e0fd82Sopenharmony_ci line.SetLeft(FO_TO_INTEGER(part.edge1.curX)); 1642a3e0fd82Sopenharmony_ci line.SetRight(FO_TO_INTEGER(part.edge1.curX)); 1643a3e0fd82Sopenharmony_ci line.SetTop(FO_TO_INTEGER(part.edge1.curY)); 1644a3e0fd82Sopenharmony_ci line.SetBottom(FO_TO_INTEGER(part.edge1.curY)); 1645a3e0fd82Sopenharmony_ci // parameters above are Q15 fixed-point number 1646a3e0fd82Sopenharmony_ci#else 1647a3e0fd82Sopenharmony_ci part.edge1.curX += part.edge1.du * (part.yMin - part.edge1.curY) / part.edge1.dv; 1648a3e0fd82Sopenharmony_ci part.edge1.curY = part.yMin; 1649a3e0fd82Sopenharmony_ci part.edge2.curX += part.edge2.du * (part.yMin - part.edge2.curY) / part.edge2.dv; 1650a3e0fd82Sopenharmony_ci part.edge2.curY = part.yMin; 1651a3e0fd82Sopenharmony_ci Rect line; 1652a3e0fd82Sopenharmony_ci line.SetLeft(static_cast<int16_t>(part.edge1.curX)); 1653a3e0fd82Sopenharmony_ci line.SetRight(static_cast<int16_t>(part.edge1.curX)); 1654a3e0fd82Sopenharmony_ci line.SetTop(static_cast<int16_t>(part.edge1.curY)); 1655a3e0fd82Sopenharmony_ci line.SetBottom(static_cast<int16_t>(part.edge1.curY)); 1656a3e0fd82Sopenharmony_ci#endif 1657a3e0fd82Sopenharmony_ci TransformInitState init; 1658a3e0fd82Sopenharmony_ci GetTransformInitState(part.transMap, part.position, line, init); 1659a3e0fd82Sopenharmony_ci 1660a3e0fd82Sopenharmony_ci uint8_t* screenBuffer = static_cast<uint8_t*>(gfxDstBuffer.virAddr); 1661a3e0fd82Sopenharmony_ci if (screenBuffer == nullptr) { 1662a3e0fd82Sopenharmony_ci return; 1663a3e0fd82Sopenharmony_ci } 1664a3e0fd82Sopenharmony_ci GetInstance()->SetFucInfo(gfxDstBuffer, part, screenBuffer, init); 1665a3e0fd82Sopenharmony_ci} 1666a3e0fd82Sopenharmony_ci 1667a3e0fd82Sopenharmony_civoid DrawUtils::SetFucInfo(BufferInfo& gfxDstBuffer, const TrianglePartInfo& part, 1668a3e0fd82Sopenharmony_ci uint8_t* screenBuffer, TransformInitState& init) 1669a3e0fd82Sopenharmony_ci{ 1670a3e0fd82Sopenharmony_ci ColorMode bufferMode = gfxDstBuffer.mode; 1671a3e0fd82Sopenharmony_ci uint8_t bufferPxSize = GetByteSizeByColorMode(bufferMode); 1672a3e0fd82Sopenharmony_ci 1673a3e0fd82Sopenharmony_ci uint8_t pixelSize; 1674a3e0fd82Sopenharmony_ci DrawTriangleTransformFuc fuc; 1675a3e0fd82Sopenharmony_ci bool isTrueColor = (part.info.header.colorMode == ARGB8888) || (part.info.header.colorMode == RGB888) || 1676a3e0fd82Sopenharmony_ci (part.info.header.colorMode == RGB565) || (part.info.header.colorMode == XRGB8888); 1677a3e0fd82Sopenharmony_ci if (isTrueColor) { 1678a3e0fd82Sopenharmony_ci pixelSize = part.info.pxSize >> SHIFT_3; 1679a3e0fd82Sopenharmony_ci if (part.info.algorithm == TransformAlgorithm::NEAREST_NEIGHBOR) { 1680a3e0fd82Sopenharmony_ci fuc = DrawTriangleTrueColorNearest; 1681a3e0fd82Sopenharmony_ci } else if (part.info.header.colorMode == ARGB8888 || part.info.header.colorMode == XRGB8888) { 1682a3e0fd82Sopenharmony_ci if (part.transMap.Is3DTransform()) { 1683a3e0fd82Sopenharmony_ci fuc = Draw3DTriangleTrueColorBilinear8888; 1684a3e0fd82Sopenharmony_ci } else { 1685a3e0fd82Sopenharmony_ci fuc = DrawTriangleTrueColorBilinear8888; 1686a3e0fd82Sopenharmony_ci } 1687a3e0fd82Sopenharmony_ci } else if (part.info.header.colorMode == RGB888) { 1688a3e0fd82Sopenharmony_ci fuc = DrawTriangleTrueColorBilinear888; 1689a3e0fd82Sopenharmony_ci } else { 1690a3e0fd82Sopenharmony_ci fuc = DrawTriangleTrueColorBilinear565; 1691a3e0fd82Sopenharmony_ci } 1692a3e0fd82Sopenharmony_ci } else { 1693a3e0fd82Sopenharmony_ci pixelSize = part.info.pxSize; 1694a3e0fd82Sopenharmony_ci fuc = DrawTriangleAlphaBilinear; 1695a3e0fd82Sopenharmony_ci } 1696a3e0fd82Sopenharmony_ci const int32_t srcLineWidth = part.info.header.width * pixelSize; 1697a3e0fd82Sopenharmony_ci TriangleScanInfo input{part.yMin, 1698a3e0fd82Sopenharmony_ci part.yMax, 1699a3e0fd82Sopenharmony_ci part.edge1, 1700a3e0fd82Sopenharmony_ci part.edge2, 1701a3e0fd82Sopenharmony_ci screenBuffer, 1702a3e0fd82Sopenharmony_ci bufferPxSize, 1703a3e0fd82Sopenharmony_ci part.color, 1704a3e0fd82Sopenharmony_ci part.opaScale, 1705a3e0fd82Sopenharmony_ci init, 1706a3e0fd82Sopenharmony_ci gfxDstBuffer.width, 1707a3e0fd82Sopenharmony_ci pixelSize, 1708a3e0fd82Sopenharmony_ci srcLineWidth, 1709a3e0fd82Sopenharmony_ci part.info, 1710a3e0fd82Sopenharmony_ci part.mask, 1711a3e0fd82Sopenharmony_ci part.isRightPart, 1712a3e0fd82Sopenharmony_ci part.ignoreJunctionPoint, 1713a3e0fd82Sopenharmony_ci part.transMap.invMatrix_}; 1714a3e0fd82Sopenharmony_ci fuc(input, gfxDstBuffer.mode); 1715a3e0fd82Sopenharmony_ci} 1716a3e0fd82Sopenharmony_ci 1717a3e0fd82Sopenharmony_civoid DrawUtils::DrawTriangleTransform(BufferInfo& gfxDstBuffer, 1718a3e0fd82Sopenharmony_ci const Rect& mask, 1719a3e0fd82Sopenharmony_ci const Point& position, 1720a3e0fd82Sopenharmony_ci const ColorType& color, 1721a3e0fd82Sopenharmony_ci OpacityType opaScale, 1722a3e0fd82Sopenharmony_ci const TransformMap& transMap, 1723a3e0fd82Sopenharmony_ci const TriangleTransformDataInfo& triangleInfo) 1724a3e0fd82Sopenharmony_ci{ 1725a3e0fd82Sopenharmony_ci bool p3IsInRight = ((triangleInfo.p1.y - triangleInfo.p2.y) * triangleInfo.p3.x + 1726a3e0fd82Sopenharmony_ci (triangleInfo.p2.x - triangleInfo.p1.x) * triangleInfo.p3.y + 1727a3e0fd82Sopenharmony_ci triangleInfo.p1.x * triangleInfo.p2.y - triangleInfo.p2.x * triangleInfo.p1.y) < 0; 1728a3e0fd82Sopenharmony_ci TriangleEdge edge1; 1729a3e0fd82Sopenharmony_ci TriangleEdge edge2; 1730a3e0fd82Sopenharmony_ci TrianglePartInfo part{ 1731a3e0fd82Sopenharmony_ci mask, 1732a3e0fd82Sopenharmony_ci transMap, 1733a3e0fd82Sopenharmony_ci position, 1734a3e0fd82Sopenharmony_ci edge1, 1735a3e0fd82Sopenharmony_ci edge2, 1736a3e0fd82Sopenharmony_ci 0, 1737a3e0fd82Sopenharmony_ci 0, 1738a3e0fd82Sopenharmony_ci triangleInfo.info, 1739a3e0fd82Sopenharmony_ci color, 1740a3e0fd82Sopenharmony_ci opaScale, 1741a3e0fd82Sopenharmony_ci triangleInfo.isRightPart, 1742a3e0fd82Sopenharmony_ci triangleInfo.ignoreJunctionPoint, 1743a3e0fd82Sopenharmony_ci }; 1744a3e0fd82Sopenharmony_ci 1745a3e0fd82Sopenharmony_ci uint8_t yErr = 1; 1746a3e0fd82Sopenharmony_ci if (triangleInfo.p2.y == triangleInfo.p1.y) { 1747a3e0fd82Sopenharmony_ci yErr = 0; 1748a3e0fd82Sopenharmony_ci GetInstance()->SetPartEdge(gfxDstBuffer, triangleInfo, edge1, edge2, p3IsInRight, mask, yErr, part); 1749a3e0fd82Sopenharmony_ci return; 1750a3e0fd82Sopenharmony_ci } 1751a3e0fd82Sopenharmony_ci if (p3IsInRight) { 1752a3e0fd82Sopenharmony_ci edge1 = TriangleEdge(triangleInfo.p1.x, triangleInfo.p1.y, triangleInfo.p2.x, triangleInfo.p2.y); 1753a3e0fd82Sopenharmony_ci edge2 = TriangleEdge(triangleInfo.p1.x, triangleInfo.p1.y, triangleInfo.p3.x, triangleInfo.p3.y); 1754a3e0fd82Sopenharmony_ci } else { 1755a3e0fd82Sopenharmony_ci edge2 = TriangleEdge(triangleInfo.p1.x, triangleInfo.p1.y, triangleInfo.p2.x, triangleInfo.p2.y); 1756a3e0fd82Sopenharmony_ci edge1 = TriangleEdge(triangleInfo.p1.x, triangleInfo.p1.y, triangleInfo.p3.x, triangleInfo.p3.y); 1757a3e0fd82Sopenharmony_ci } 1758a3e0fd82Sopenharmony_ci 1759a3e0fd82Sopenharmony_ci part.yMin = MATH_MAX(mask.GetTop(), triangleInfo.p1.y); 1760a3e0fd82Sopenharmony_ci part.yMax = MATH_MIN(mask.GetBottom(), triangleInfo.p2.y); 1761a3e0fd82Sopenharmony_ci part.edge1 = edge1; 1762a3e0fd82Sopenharmony_ci part.edge2 = edge2; 1763a3e0fd82Sopenharmony_ci DrawTriangleTransformPart(gfxDstBuffer, part); 1764a3e0fd82Sopenharmony_ci GetInstance()->SetPartEdge(gfxDstBuffer, triangleInfo, edge1, edge2, p3IsInRight, mask, yErr, part); 1765a3e0fd82Sopenharmony_ci} 1766a3e0fd82Sopenharmony_ci 1767a3e0fd82Sopenharmony_civoid DrawUtils::SetPartEdge(BufferInfo& gfxDstBuffer, const TriangleTransformDataInfo& triangleInfo, 1768a3e0fd82Sopenharmony_ci TriangleEdge& edge1, TriangleEdge& edge2, bool p3IsInRight, 1769a3e0fd82Sopenharmony_ci const Rect& mask, uint8_t yErr, TrianglePartInfo& part) const 1770a3e0fd82Sopenharmony_ci{ 1771a3e0fd82Sopenharmony_ci if (triangleInfo.p2.y == triangleInfo.p3.y) { 1772a3e0fd82Sopenharmony_ci return; 1773a3e0fd82Sopenharmony_ci } 1774a3e0fd82Sopenharmony_ci 1775a3e0fd82Sopenharmony_ci if (triangleInfo.p2.y == triangleInfo.p1.y) { 1776a3e0fd82Sopenharmony_ci if (triangleInfo.p1.x < triangleInfo.p2.x) { 1777a3e0fd82Sopenharmony_ci edge1 = TriangleEdge(triangleInfo.p1.x, triangleInfo.p1.y, triangleInfo.p3.x, triangleInfo.p3.y); 1778a3e0fd82Sopenharmony_ci edge2 = TriangleEdge(triangleInfo.p2.x, triangleInfo.p2.y, triangleInfo.p3.x, triangleInfo.p3.y); 1779a3e0fd82Sopenharmony_ci } else { 1780a3e0fd82Sopenharmony_ci edge2 = TriangleEdge(triangleInfo.p1.x, triangleInfo.p1.y, triangleInfo.p3.x, triangleInfo.p3.y); 1781a3e0fd82Sopenharmony_ci edge1 = TriangleEdge(triangleInfo.p2.x, triangleInfo.p2.y, triangleInfo.p3.x, triangleInfo.p3.y); 1782a3e0fd82Sopenharmony_ci } 1783a3e0fd82Sopenharmony_ci } else { 1784a3e0fd82Sopenharmony_ci if (p3IsInRight) { 1785a3e0fd82Sopenharmony_ci edge1 = TriangleEdge(triangleInfo.p2.x, triangleInfo.p2.y, triangleInfo.p3.x, triangleInfo.p3.y); 1786a3e0fd82Sopenharmony_ci } else { 1787a3e0fd82Sopenharmony_ci edge2 = TriangleEdge(triangleInfo.p2.x, triangleInfo.p2.y, triangleInfo.p3.x, triangleInfo.p3.y); 1788a3e0fd82Sopenharmony_ci } 1789a3e0fd82Sopenharmony_ci } 1790a3e0fd82Sopenharmony_ci 1791a3e0fd82Sopenharmony_ci part.yMin = MATH_MAX(mask.GetTop(), triangleInfo.p2.y + yErr); 1792a3e0fd82Sopenharmony_ci part.yMax = MATH_MIN(mask.GetBottom(), triangleInfo.p3.y); 1793a3e0fd82Sopenharmony_ci part.edge1 = edge1; 1794a3e0fd82Sopenharmony_ci part.edge2 = edge2; 1795a3e0fd82Sopenharmony_ci DrawTriangleTransformPart(gfxDstBuffer, part); 1796a3e0fd82Sopenharmony_ci} 1797a3e0fd82Sopenharmony_ci 1798a3e0fd82Sopenharmony_civoid DrawUtils::AddBorderToImageData(TransformDataInfo& newDataInfo, ImageInfo& imageinfo) 1799a3e0fd82Sopenharmony_ci{ 1800a3e0fd82Sopenharmony_ci int16_t border = 1; // 1 : border width 1801a3e0fd82Sopenharmony_ci int16_t offset = border * 2; // 2 : offset 1802a3e0fd82Sopenharmony_ci uint16_t width = newDataInfo.header.width; 1803a3e0fd82Sopenharmony_ci uint16_t height = newDataInfo.header.height; 1804a3e0fd82Sopenharmony_ci int16_t diff = 0; 1805a3e0fd82Sopenharmony_ci if (newDataInfo.pxSize > FONT_WEIGHT_8) { 1806a3e0fd82Sopenharmony_ci width += offset; 1807a3e0fd82Sopenharmony_ci height += offset; 1808a3e0fd82Sopenharmony_ci diff = border * newDataInfo.pxSize / FONT_WEIGHT_8; 1809a3e0fd82Sopenharmony_ci } else { 1810a3e0fd82Sopenharmony_ci width += offset * FONT_WEIGHT_8 / newDataInfo.pxSize; 1811a3e0fd82Sopenharmony_ci height += offset; 1812a3e0fd82Sopenharmony_ci diff = border; 1813a3e0fd82Sopenharmony_ci } 1814a3e0fd82Sopenharmony_ci uint16_t widthInByte = width * newDataInfo.pxSize / FONT_WEIGHT_8; 1815a3e0fd82Sopenharmony_ci if ((width * newDataInfo.pxSize) % FONT_WEIGHT_8 != 0) { 1816a3e0fd82Sopenharmony_ci widthInByte++; 1817a3e0fd82Sopenharmony_ci } 1818a3e0fd82Sopenharmony_ci imageinfo.header.width = newDataInfo.header.width; 1819a3e0fd82Sopenharmony_ci imageinfo.header.height = newDataInfo.header.height; 1820a3e0fd82Sopenharmony_ci imageinfo.dataSize = widthInByte * height; 1821a3e0fd82Sopenharmony_ci uint8_t* newData = static_cast<uint8_t*>(ImageCacheMalloc(imageinfo)); 1822a3e0fd82Sopenharmony_ci if (newData == nullptr) { 1823a3e0fd82Sopenharmony_ci return; 1824a3e0fd82Sopenharmony_ci } 1825a3e0fd82Sopenharmony_ci imageinfo.data = newData; 1826a3e0fd82Sopenharmony_ci if (memset_s(newData, widthInByte * height, 0, widthInByte * height) != EOK) { 1827a3e0fd82Sopenharmony_ci ImageCacheFree(imageinfo); 1828a3e0fd82Sopenharmony_ci newData = nullptr; 1829a3e0fd82Sopenharmony_ci return; 1830a3e0fd82Sopenharmony_ci } 1831a3e0fd82Sopenharmony_ci uint8_t* tmp = newData; 1832a3e0fd82Sopenharmony_ci uint8_t* data = const_cast<uint8_t*>(newDataInfo.data); 1833a3e0fd82Sopenharmony_ci tmp += widthInByte * border + diff; 1834a3e0fd82Sopenharmony_ci for (int i = 0; i < newDataInfo.header.height; ++i) { 1835a3e0fd82Sopenharmony_ci // 2 : double 1836a3e0fd82Sopenharmony_ci if (memcpy_s(tmp, widthInByte - diff * 2, data, widthInByte - diff * 2) != EOK) { 1837a3e0fd82Sopenharmony_ci ImageCacheFree(imageinfo); 1838a3e0fd82Sopenharmony_ci newData = nullptr; 1839a3e0fd82Sopenharmony_ci return; 1840a3e0fd82Sopenharmony_ci } 1841a3e0fd82Sopenharmony_ci tmp += widthInByte; 1842a3e0fd82Sopenharmony_ci data += widthInByte - diff * 2; // 2 : double 1843a3e0fd82Sopenharmony_ci } 1844a3e0fd82Sopenharmony_ci newDataInfo.header.width = width; 1845a3e0fd82Sopenharmony_ci newDataInfo.header.height = height; 1846a3e0fd82Sopenharmony_ci newDataInfo.data = newData; 1847a3e0fd82Sopenharmony_ci} 1848a3e0fd82Sopenharmony_ci 1849a3e0fd82Sopenharmony_civoid DrawUtils::UpdateTransMap(int16_t width, int16_t height, TransformMap& transMap) 1850a3e0fd82Sopenharmony_ci{ 1851a3e0fd82Sopenharmony_ci Rect rect = transMap.GetTransMapRect(); 1852a3e0fd82Sopenharmony_ci Matrix4<float> matrix = transMap.GetTransformMatrix(); 1853a3e0fd82Sopenharmony_ci matrix = matrix * (Matrix4<float>::Translate(Vector3<float>(-rect.GetX(), -rect.GetY(), 0))); 1854a3e0fd82Sopenharmony_ci int16_t offsetX = (width - rect.GetWidth()) / 2; // 2 : half; 1855a3e0fd82Sopenharmony_ci int16_t offsetY = (height - rect.GetHeight()) / 2; // 2 : half; 1856a3e0fd82Sopenharmony_ci rect.SetPosition(rect.GetX() - offsetX, rect.GetY() - offsetY); 1857a3e0fd82Sopenharmony_ci rect.Resize(width, height); 1858a3e0fd82Sopenharmony_ci Polygon polygon = Polygon(rect); 1859a3e0fd82Sopenharmony_ci uint8_t vertexNum = transMap.GetPolygon().GetVertexNum(); 1860a3e0fd82Sopenharmony_ci Vector4<float> imgPoint4; 1861a3e0fd82Sopenharmony_ci for (uint8_t i = 0; i < vertexNum; i++) { 1862a3e0fd82Sopenharmony_ci Vector4<float> point(polygon[i].x_, polygon[i].y_, 0, 1); 1863a3e0fd82Sopenharmony_ci imgPoint4 = matrix * point; 1864a3e0fd82Sopenharmony_ci if (imgPoint4.x_ < COORD_MIN) { 1865a3e0fd82Sopenharmony_ci polygon[i].x_ = COORD_MIN; 1866a3e0fd82Sopenharmony_ci } else if (imgPoint4.x_ > COORD_MAX) { 1867a3e0fd82Sopenharmony_ci polygon[i].x_ = COORD_MAX; 1868a3e0fd82Sopenharmony_ci } else { 1869a3e0fd82Sopenharmony_ci polygon[i].x_ = MATH_ROUND(imgPoint4.x_); 1870a3e0fd82Sopenharmony_ci } 1871a3e0fd82Sopenharmony_ci 1872a3e0fd82Sopenharmony_ci if (imgPoint4.y_ < COORD_MIN) { 1873a3e0fd82Sopenharmony_ci polygon[i].y_ = COORD_MIN; 1874a3e0fd82Sopenharmony_ci } else if (imgPoint4.y_ > COORD_MAX) { 1875a3e0fd82Sopenharmony_ci polygon[i].y_ = COORD_MAX; 1876a3e0fd82Sopenharmony_ci } else { 1877a3e0fd82Sopenharmony_ci polygon[i].y_ = MATH_ROUND(imgPoint4.y_); 1878a3e0fd82Sopenharmony_ci } 1879a3e0fd82Sopenharmony_ci } 1880a3e0fd82Sopenharmony_ci transMap.SetPolygon(polygon); 1881a3e0fd82Sopenharmony_ci Matrix3<float> matrix3(matrix[0][0], matrix[0][1], matrix[0][3], matrix[1][0], matrix[1][1], matrix[1][3], 1882a3e0fd82Sopenharmony_ci matrix[3][0], matrix[3][1], matrix[3][3]); 1883a3e0fd82Sopenharmony_ci transMap.invMatrix_ = (matrix3 * (Matrix3<float>::Translate(Vector2<float>(rect.GetX(), rect.GetY())))).Inverse(); 1884a3e0fd82Sopenharmony_ci} 1885a3e0fd82Sopenharmony_ci 1886a3e0fd82Sopenharmony_civoid DrawUtils::DrawTransform(BufferInfo& gfxDstBuffer, 1887a3e0fd82Sopenharmony_ci const Rect& mask, 1888a3e0fd82Sopenharmony_ci const Point& position, 1889a3e0fd82Sopenharmony_ci const ColorType& color, 1890a3e0fd82Sopenharmony_ci OpacityType opaScale, 1891a3e0fd82Sopenharmony_ci const TransformMap& transMap, 1892a3e0fd82Sopenharmony_ci const TransformDataInfo& dataInfo) const 1893a3e0fd82Sopenharmony_ci{ 1894a3e0fd82Sopenharmony_ci if (opaScale == OPA_TRANSPARENT) { 1895a3e0fd82Sopenharmony_ci return; 1896a3e0fd82Sopenharmony_ci } 1897a3e0fd82Sopenharmony_ci if ((gfxDstBuffer.virAddr == nullptr) || (dataInfo.data == nullptr)) { 1898a3e0fd82Sopenharmony_ci return; 1899a3e0fd82Sopenharmony_ci } 1900a3e0fd82Sopenharmony_ci ImageInfo imageinfo; 1901a3e0fd82Sopenharmony_ci TransformDataInfo newDataInfo = dataInfo; 1902a3e0fd82Sopenharmony_ci TransformMap newTransMap = transMap; 1903a3e0fd82Sopenharmony_ci // If the width and height of the rectangle of transMap are not equal to the width and height of the ImageHeader, 1904a3e0fd82Sopenharmony_ci // a border of transparency values to the data cannot be added. 1905a3e0fd82Sopenharmony_ci if ((transMap.GetTransMapRect().GetWidth() == dataInfo.header.width) && 1906a3e0fd82Sopenharmony_ci (transMap.GetTransMapRect().GetHeight() == dataInfo.header.height)) { 1907a3e0fd82Sopenharmony_ci // Add a border of transparency values to the data 1908a3e0fd82Sopenharmony_ci AddBorderToImageData(newDataInfo, imageinfo); 1909a3e0fd82Sopenharmony_ci // Update the transMap according to new rect width and height 1910a3e0fd82Sopenharmony_ci UpdateTransMap(newDataInfo.header.width, newDataInfo.header.height, newTransMap); 1911a3e0fd82Sopenharmony_ci } 1912a3e0fd82Sopenharmony_ci 1913a3e0fd82Sopenharmony_ci Rect trans = newTransMap.GetBoxRect(); 1914a3e0fd82Sopenharmony_ci trans.SetX(trans.GetX() + position.x); 1915a3e0fd82Sopenharmony_ci trans.SetY(trans.GetY() + position.y); 1916a3e0fd82Sopenharmony_ci imageinfo.data = newDataInfo.data; 1917a3e0fd82Sopenharmony_ci if (!trans.Intersect(trans, mask)) { 1918a3e0fd82Sopenharmony_ci if (newDataInfo.data != dataInfo.data) { 1919a3e0fd82Sopenharmony_ci ImageCacheFree(imageinfo); 1920a3e0fd82Sopenharmony_ci } 1921a3e0fd82Sopenharmony_ci return; 1922a3e0fd82Sopenharmony_ci } 1923a3e0fd82Sopenharmony_ci 1924a3e0fd82Sopenharmony_ci TriangleTransformDataInfo triangleInfo{ 1925a3e0fd82Sopenharmony_ci newDataInfo, 1926a3e0fd82Sopenharmony_ci }; 1927a3e0fd82Sopenharmony_ci Polygon polygon = newTransMap.GetPolygon(); 1928a3e0fd82Sopenharmony_ci Point p1; 1929a3e0fd82Sopenharmony_ci p1.x = polygon[0].x_ + position.x; // 0:first point 1930a3e0fd82Sopenharmony_ci p1.y = polygon[0].y_ + position.y; // 0:first point 1931a3e0fd82Sopenharmony_ci Point p2; 1932a3e0fd82Sopenharmony_ci p2.x = polygon[1].x_ + position.x; // 1:second point 1933a3e0fd82Sopenharmony_ci p2.y = polygon[1].y_ + position.y; // 1:second point 1934a3e0fd82Sopenharmony_ci Point p3; 1935a3e0fd82Sopenharmony_ci p3.x = polygon[2].x_ + position.x; // 2:third point 1936a3e0fd82Sopenharmony_ci p3.y = polygon[2].y_ + position.y; // 2:third point 1937a3e0fd82Sopenharmony_ci triangleInfo.isRightPart = ((p1.y - p3.y) * p2.x + (p3.x - p1.x) * p2.y + p1.x * p3.y - p3.x * p1.y) < 0; 1938a3e0fd82Sopenharmony_ci triangleInfo.isRightPart = (p1.y < p3.y) ? triangleInfo.isRightPart : !triangleInfo.isRightPart; 1939a3e0fd82Sopenharmony_ci DrawTriangle::SortVertexs(p1, p2, p3); 1940a3e0fd82Sopenharmony_ci triangleInfo.ignoreJunctionPoint = false; 1941a3e0fd82Sopenharmony_ci triangleInfo.p1 = p1; 1942a3e0fd82Sopenharmony_ci triangleInfo.p2 = p2; 1943a3e0fd82Sopenharmony_ci triangleInfo.p3 = p3; 1944a3e0fd82Sopenharmony_ci if ((triangleInfo.p1.y <= mask.GetBottom()) && (triangleInfo.p3.y >= mask.GetTop())) { 1945a3e0fd82Sopenharmony_ci DrawTriangleTransform(gfxDstBuffer, mask, position, color, opaScale, newTransMap, triangleInfo); 1946a3e0fd82Sopenharmony_ci } 1947a3e0fd82Sopenharmony_ci 1948a3e0fd82Sopenharmony_ci triangleInfo.ignoreJunctionPoint = true; 1949a3e0fd82Sopenharmony_ci triangleInfo.isRightPart = !triangleInfo.isRightPart; 1950a3e0fd82Sopenharmony_ci p1.x = polygon[0].x_ + position.x; // 0:first point 1951a3e0fd82Sopenharmony_ci p1.y = polygon[0].y_ + position.y; // 0:first point 1952a3e0fd82Sopenharmony_ci p3.x = polygon[2].x_ + position.x; // 2:third point 1953a3e0fd82Sopenharmony_ci p3.y = polygon[2].y_ + position.y; // 2:third point 1954a3e0fd82Sopenharmony_ci Point p4; 1955a3e0fd82Sopenharmony_ci p4.x = polygon[3].x_ + position.x; // 3:fourth point 1956a3e0fd82Sopenharmony_ci p4.y = polygon[3].y_ + position.y; // 3:fourth point 1957a3e0fd82Sopenharmony_ci DrawTriangle::SortVertexs(p1, p3, p4); 1958a3e0fd82Sopenharmony_ci triangleInfo.p1 = p1; 1959a3e0fd82Sopenharmony_ci triangleInfo.p2 = p3; 1960a3e0fd82Sopenharmony_ci triangleInfo.p3 = p4; 1961a3e0fd82Sopenharmony_ci if ((triangleInfo.p1.y <= mask.GetBottom()) && (triangleInfo.p3.y >= mask.GetTop())) { 1962a3e0fd82Sopenharmony_ci DrawTriangleTransform(gfxDstBuffer, mask, position, color, opaScale, newTransMap, triangleInfo); 1963a3e0fd82Sopenharmony_ci } 1964a3e0fd82Sopenharmony_ci if (newDataInfo.data != dataInfo.data) { 1965a3e0fd82Sopenharmony_ci ImageCacheFree(imageinfo); 1966a3e0fd82Sopenharmony_ci } 1967a3e0fd82Sopenharmony_ci} 1968a3e0fd82Sopenharmony_ci 1969a3e0fd82Sopenharmony_ciOpacityType DrawUtils::GetPxAlphaForAlphaImg(const TransformDataInfo& dataInfo, const Point& point) 1970a3e0fd82Sopenharmony_ci{ 1971a3e0fd82Sopenharmony_ci Point tmpPoint = point; 1972a3e0fd82Sopenharmony_ci const uint8_t* bufU8 = const_cast<uint8_t*>(dataInfo.data); 1973a3e0fd82Sopenharmony_ci#if ENABLE_SPEC_FONT 1974a3e0fd82Sopenharmony_ci if (dataInfo.header.colorMode == A1) { 1975a3e0fd82Sopenharmony_ci uint8_t bit = tmpPoint.x & 0x7; // 0x7: 1 byte is 8 bit, 1976a3e0fd82Sopenharmony_ci tmpPoint.x = tmpPoint.x >> SHIFT_3; 1977a3e0fd82Sopenharmony_ci 1978a3e0fd82Sopenharmony_ci uint32_t px = (dataInfo.header.width >> SHIFT_3) * tmpPoint.y + tmpPoint.x; 1979a3e0fd82Sopenharmony_ci // 1: A1 means 1 bit, 7: maximum offset in bytes 1980a3e0fd82Sopenharmony_ci uint8_t pxOpa = (bufU8[px] & (1 << (7 - bit))) >> (7 - bit); 1981a3e0fd82Sopenharmony_ci return pxOpa ? OPA_TRANSPARENT : OPA_OPAQUE; 1982a3e0fd82Sopenharmony_ci } else if (dataInfo.header.colorMode == A2) { 1983a3e0fd82Sopenharmony_ci uint8_t bit = (tmpPoint.x & 0x3) * 2; // 0x3: 0b0011, 2: A2 color mode 1984a3e0fd82Sopenharmony_ci tmpPoint.x = tmpPoint.x >> SHIFT_2; 1985a3e0fd82Sopenharmony_ci 1986a3e0fd82Sopenharmony_ci uint32_t px = (dataInfo.header.width >> SHIFT_2) * tmpPoint.y + tmpPoint.x; 1987a3e0fd82Sopenharmony_ci // 3: the value of 0b0011 1988a3e0fd82Sopenharmony_ci uint8_t pxOpa = (bufU8[px] & (3 << (SHIFT_6 - bit))) >> (SHIFT_6 - bit); 1989a3e0fd82Sopenharmony_ci return pxOpa * OPACITY_STEP_A2; 1990a3e0fd82Sopenharmony_ci } else if (dataInfo.header.colorMode == A8) { 1991a3e0fd82Sopenharmony_ci uint32_t px = dataInfo.header.width * tmpPoint.y + tmpPoint.x; 1992a3e0fd82Sopenharmony_ci return bufU8[px]; 1993a3e0fd82Sopenharmony_ci } 1994a3e0fd82Sopenharmony_ci#else 1995a3e0fd82Sopenharmony_ci uint8_t letterWidthInByte = (dataInfo.header.width * dataInfo.pxSize) >> SHIFT_3; 1996a3e0fd82Sopenharmony_ci // 0x7: for rounding 1997a3e0fd82Sopenharmony_ci if ((dataInfo.header.width * dataInfo.pxSize) & 0x7) { 1998a3e0fd82Sopenharmony_ci letterWidthInByte++; 1999a3e0fd82Sopenharmony_ci } 2000a3e0fd82Sopenharmony_ci uint8_t bit = (tmpPoint.x & 0x1) << SHIFT_2; 2001a3e0fd82Sopenharmony_ci bufU8 += (tmpPoint.y * letterWidthInByte) + ((tmpPoint.x * dataInfo.pxSize) >> SHIFT_3); 2002a3e0fd82Sopenharmony_ci // 0xF: 0b1111, get the data of the A4 color mode 2003a3e0fd82Sopenharmony_ci uint8_t pxOpa = (*bufU8 & (0xF << bit)) >> (bit); 2004a3e0fd82Sopenharmony_ci return pxOpa * OPACITY_STEP_A4; 2005a3e0fd82Sopenharmony_ci#endif // ENABLE_SPEC_FONT 2006a3e0fd82Sopenharmony_ci} 2007a3e0fd82Sopenharmony_ci 2008a3e0fd82Sopenharmony_civoid DrawUtils::DrawTranspantArea(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& mask) 2009a3e0fd82Sopenharmony_ci{ 2010a3e0fd82Sopenharmony_ci FillArea(gfxDstBuffer, rect, mask, true, nullptr); 2011a3e0fd82Sopenharmony_ci} 2012a3e0fd82Sopenharmony_ci 2013a3e0fd82Sopenharmony_civoid DrawUtils::DrawWithBuffer(BufferInfo& gfxDstBuffer, const Rect& rect, const Rect& mask, const ColorType* colorBuf) 2014a3e0fd82Sopenharmony_ci{ 2015a3e0fd82Sopenharmony_ci FillArea(gfxDstBuffer, rect, mask, false, colorBuf); 2016a3e0fd82Sopenharmony_ci} 2017a3e0fd82Sopenharmony_ci 2018a3e0fd82Sopenharmony_civoid DrawUtils::FillArea(BufferInfo& gfxDstBuffer, 2019a3e0fd82Sopenharmony_ci const Rect& rect, 2020a3e0fd82Sopenharmony_ci const Rect& mask, 2021a3e0fd82Sopenharmony_ci bool isTransparent, 2022a3e0fd82Sopenharmony_ci const ColorType* colorBuf) 2023a3e0fd82Sopenharmony_ci{ 2024a3e0fd82Sopenharmony_ci Rect maskedArea; 2025a3e0fd82Sopenharmony_ci if (!maskedArea.Intersect(rect, mask)) { 2026a3e0fd82Sopenharmony_ci return; 2027a3e0fd82Sopenharmony_ci } 2028a3e0fd82Sopenharmony_ci 2029a3e0fd82Sopenharmony_ci int16_t left = maskedArea.GetLeft(); 2030a3e0fd82Sopenharmony_ci int16_t right = maskedArea.GetRight(); 2031a3e0fd82Sopenharmony_ci int16_t top = maskedArea.GetTop(); 2032a3e0fd82Sopenharmony_ci int16_t bottom = maskedArea.GetBottom(); 2033a3e0fd82Sopenharmony_ci 2034a3e0fd82Sopenharmony_ci DRAW_UTILS_PREPROCESS(gfxDstBuffer, OPA_OPAQUE); 2035a3e0fd82Sopenharmony_ci uint8_t* mem = screenBuffer; 2036a3e0fd82Sopenharmony_ci mem += top * screenBufferWidth * bufferPxSize; 2037a3e0fd82Sopenharmony_ci if (isTransparent) { 2038a3e0fd82Sopenharmony_ci uint16_t sz = (right - left + 1) * bufferPxSize; 2039a3e0fd82Sopenharmony_ci for (int16_t row = top; row <= bottom; row++) { 2040a3e0fd82Sopenharmony_ci if (memset_s(mem + (left * bufferPxSize), sz, 0, sz) != EOK) { 2041a3e0fd82Sopenharmony_ci return; 2042a3e0fd82Sopenharmony_ci } 2043a3e0fd82Sopenharmony_ci mem += screenBufferWidth * bufferPxSize; 2044a3e0fd82Sopenharmony_ci } 2045a3e0fd82Sopenharmony_ci } else { 2046a3e0fd82Sopenharmony_ci if (colorBuf == nullptr) { 2047a3e0fd82Sopenharmony_ci return; 2048a3e0fd82Sopenharmony_ci } 2049a3e0fd82Sopenharmony_ci for (int16_t row = top; row <= bottom; row++) { 2050a3e0fd82Sopenharmony_ci for (int16_t col = left; col <= right; col++) { 2051a3e0fd82Sopenharmony_ci#if COLOR_DEPTH == 32 2052a3e0fd82Sopenharmony_ci COLOR_FILL_COVER(mem[col * bufferPxSize], bufferMode, colorBuf[row * screenBufferWidth + col].red, 2053a3e0fd82Sopenharmony_ci colorBuf[row * screenBufferWidth + col].green, 2054a3e0fd82Sopenharmony_ci colorBuf[row * screenBufferWidth + col].blue, ARGB8888); 2055a3e0fd82Sopenharmony_ci#else 2056a3e0fd82Sopenharmony_ci COLOR_FILL_COVER(mem[col * bufferPxSize], bufferMode, colorBuf[row * screenBufferWidth + col].red, 2057a3e0fd82Sopenharmony_ci colorBuf[row * screenBufferWidth + col].green, 2058a3e0fd82Sopenharmony_ci colorBuf[row * screenBufferWidth + col].blue, RGB565); 2059a3e0fd82Sopenharmony_ci#endif 2060a3e0fd82Sopenharmony_ci } 2061a3e0fd82Sopenharmony_ci mem += screenBufferWidth * bufferPxSize; 2062a3e0fd82Sopenharmony_ci } 2063a3e0fd82Sopenharmony_ci } 2064a3e0fd82Sopenharmony_ci} 2065a3e0fd82Sopenharmony_ci 2066a3e0fd82Sopenharmony_civoid DrawUtils::DrawAdjPixelInLine(BufferInfo& gfxDstBuffer, 2067a3e0fd82Sopenharmony_ci int16_t x1, 2068a3e0fd82Sopenharmony_ci int16_t y1, 2069a3e0fd82Sopenharmony_ci int16_t x2, 2070a3e0fd82Sopenharmony_ci int16_t y2, 2071a3e0fd82Sopenharmony_ci const Rect& mask, 2072a3e0fd82Sopenharmony_ci const ColorType& color, 2073a3e0fd82Sopenharmony_ci OpacityType opa, 2074a3e0fd82Sopenharmony_ci uint16_t weight) const 2075a3e0fd82Sopenharmony_ci{ 2076a3e0fd82Sopenharmony_ci DRAW_UTILS_PREPROCESS(gfxDstBuffer, opa); 2077a3e0fd82Sopenharmony_ci Color32 result; 2078a3e0fd82Sopenharmony_ci result.full = Color::ColorTo32(color); 2079a3e0fd82Sopenharmony_ci if ((x1 >= mask.GetLeft()) && (x1 <= mask.GetRight()) && (y1 >= mask.GetTop()) && (y1 <= mask.GetBottom())) { 2080a3e0fd82Sopenharmony_ci screenBuffer += (y1 * screenBufferWidth + x1) * bufferPxSize; 2081a3e0fd82Sopenharmony_ci OpacityType fillOpa = (weight ^ OPA_OPAQUE) * opa / OPA_OPAQUE; 2082a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, fillOpa); 2083a3e0fd82Sopenharmony_ci } 2084a3e0fd82Sopenharmony_ci if ((x2 >= mask.GetLeft()) && (x2 <= mask.GetRight()) && (y2 >= mask.GetTop()) && (y2 <= mask.GetBottom())) { 2085a3e0fd82Sopenharmony_ci screenBuffer = static_cast<uint8_t*>(gfxDstBuffer.virAddr); 2086a3e0fd82Sopenharmony_ci screenBuffer += (y2 * screenBufferWidth + x2) * bufferPxSize; 2087a3e0fd82Sopenharmony_ci OpacityType fillOpa = weight * opa / OPA_OPAQUE; 2088a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, fillOpa); 2089a3e0fd82Sopenharmony_ci } 2090a3e0fd82Sopenharmony_ci} 2091a3e0fd82Sopenharmony_ci 2092a3e0fd82Sopenharmony_civoid DrawUtils::DrawPixelInLine(BufferInfo& gfxDstBuffer, 2093a3e0fd82Sopenharmony_ci int16_t x, 2094a3e0fd82Sopenharmony_ci int16_t y, 2095a3e0fd82Sopenharmony_ci const Rect& mask, 2096a3e0fd82Sopenharmony_ci const ColorType& color, 2097a3e0fd82Sopenharmony_ci OpacityType opa, 2098a3e0fd82Sopenharmony_ci uint16_t weight) const 2099a3e0fd82Sopenharmony_ci{ 2100a3e0fd82Sopenharmony_ci DRAW_UTILS_PREPROCESS(gfxDstBuffer, opa); 2101a3e0fd82Sopenharmony_ci Color32 result; 2102a3e0fd82Sopenharmony_ci result.full = Color::ColorTo32(color); 2103a3e0fd82Sopenharmony_ci if ((x >= mask.GetLeft()) && (x <= mask.GetRight()) && (y >= mask.GetTop()) && (y <= mask.GetBottom())) { 2104a3e0fd82Sopenharmony_ci screenBuffer += (y * screenBufferWidth + x) * bufferPxSize; 2105a3e0fd82Sopenharmony_ci OpacityType fillOpa = weight * opa / OPA_OPAQUE; 2106a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, fillOpa); 2107a3e0fd82Sopenharmony_ci } 2108a3e0fd82Sopenharmony_ci} 2109a3e0fd82Sopenharmony_ci 2110a3e0fd82Sopenharmony_civoid DrawUtils::DrawVerPixelInLine(BufferInfo& gfxDstBuffer, 2111a3e0fd82Sopenharmony_ci int16_t x, 2112a3e0fd82Sopenharmony_ci int16_t y, 2113a3e0fd82Sopenharmony_ci int8_t dir, 2114a3e0fd82Sopenharmony_ci const Rect& mask, 2115a3e0fd82Sopenharmony_ci const ColorType& color, 2116a3e0fd82Sopenharmony_ci OpacityType opa, 2117a3e0fd82Sopenharmony_ci uint16_t weight) const 2118a3e0fd82Sopenharmony_ci{ 2119a3e0fd82Sopenharmony_ci DRAW_UTILS_PREPROCESS(gfxDstBuffer, opa); 2120a3e0fd82Sopenharmony_ci if ((y < mask.GetTop()) || (y > mask.GetBottom())) { 2121a3e0fd82Sopenharmony_ci return; 2122a3e0fd82Sopenharmony_ci } 2123a3e0fd82Sopenharmony_ci Color32 result; 2124a3e0fd82Sopenharmony_ci result.full = Color::ColorTo32(color); 2125a3e0fd82Sopenharmony_ci int16_t x0 = x + dir; 2126a3e0fd82Sopenharmony_ci int16_t x1 = x - dir; 2127a3e0fd82Sopenharmony_ci if ((x0 >= mask.GetLeft()) && (x0 <= mask.GetRight())) { 2128a3e0fd82Sopenharmony_ci screenBuffer += (y * screenBufferWidth + x0) * bufferPxSize; 2129a3e0fd82Sopenharmony_ci OpacityType fillOpa = weight * opa / OPA_OPAQUE; 2130a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, fillOpa); 2131a3e0fd82Sopenharmony_ci } 2132a3e0fd82Sopenharmony_ci if ((x >= mask.GetLeft()) && (x <= mask.GetRight())) { 2133a3e0fd82Sopenharmony_ci screenBuffer = static_cast<uint8_t*>(gfxDstBuffer.virAddr); 2134a3e0fd82Sopenharmony_ci screenBuffer += (y * screenBufferWidth + x) * bufferPxSize; 2135a3e0fd82Sopenharmony_ci if (opa == OPA_OPAQUE) { 2136a3e0fd82Sopenharmony_ci COLOR_FILL_COVER(screenBuffer, bufferMode, result.red, result.green, result.blue, ARGB8888); 2137a3e0fd82Sopenharmony_ci } else { 2138a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, opa); 2139a3e0fd82Sopenharmony_ci } 2140a3e0fd82Sopenharmony_ci } 2141a3e0fd82Sopenharmony_ci if ((x1 >= mask.GetLeft()) && (x1 <= mask.GetRight())) { 2142a3e0fd82Sopenharmony_ci screenBuffer = static_cast<uint8_t*>(gfxDstBuffer.virAddr); 2143a3e0fd82Sopenharmony_ci screenBuffer += (y * screenBufferWidth + x1) * bufferPxSize; 2144a3e0fd82Sopenharmony_ci OpacityType fillOpa = (weight ^ OPA_OPAQUE) * opa / OPA_OPAQUE; 2145a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, fillOpa); 2146a3e0fd82Sopenharmony_ci } 2147a3e0fd82Sopenharmony_ci} 2148a3e0fd82Sopenharmony_ci 2149a3e0fd82Sopenharmony_civoid DrawUtils::DrawHorPixelInLine(BufferInfo& gfxDstBuffer, 2150a3e0fd82Sopenharmony_ci int16_t x, 2151a3e0fd82Sopenharmony_ci int16_t y, 2152a3e0fd82Sopenharmony_ci int8_t dir, 2153a3e0fd82Sopenharmony_ci const Rect& mask, 2154a3e0fd82Sopenharmony_ci const ColorType& color, 2155a3e0fd82Sopenharmony_ci OpacityType opa, 2156a3e0fd82Sopenharmony_ci uint16_t weight) const 2157a3e0fd82Sopenharmony_ci{ 2158a3e0fd82Sopenharmony_ci DRAW_UTILS_PREPROCESS(gfxDstBuffer, opa); 2159a3e0fd82Sopenharmony_ci if ((x < mask.GetLeft()) || (x > mask.GetRight())) { 2160a3e0fd82Sopenharmony_ci return; 2161a3e0fd82Sopenharmony_ci } 2162a3e0fd82Sopenharmony_ci Color32 result; 2163a3e0fd82Sopenharmony_ci result.full = Color::ColorTo32(color); 2164a3e0fd82Sopenharmony_ci int16_t y0 = y + dir; 2165a3e0fd82Sopenharmony_ci int16_t y1 = y - dir; 2166a3e0fd82Sopenharmony_ci if ((y0 >= mask.GetTop()) && (y0 <= mask.GetBottom())) { 2167a3e0fd82Sopenharmony_ci screenBuffer += (y0 * screenBufferWidth + x) * bufferPxSize; 2168a3e0fd82Sopenharmony_ci OpacityType fillOpa = weight * opa / OPA_OPAQUE; 2169a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, fillOpa); 2170a3e0fd82Sopenharmony_ci } 2171a3e0fd82Sopenharmony_ci if ((y >= mask.GetTop()) && (y <= mask.GetBottom())) { 2172a3e0fd82Sopenharmony_ci screenBuffer = static_cast<uint8_t*>(gfxDstBuffer.virAddr); 2173a3e0fd82Sopenharmony_ci screenBuffer += (y * screenBufferWidth + x) * bufferPxSize; 2174a3e0fd82Sopenharmony_ci if (opa == OPA_OPAQUE) { 2175a3e0fd82Sopenharmony_ci COLOR_FILL_COVER(screenBuffer, bufferMode, result.red, result.green, result.blue, ARGB8888); 2176a3e0fd82Sopenharmony_ci } else { 2177a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, opa); 2178a3e0fd82Sopenharmony_ci } 2179a3e0fd82Sopenharmony_ci } 2180a3e0fd82Sopenharmony_ci if ((y1 >= mask.GetTop()) && (y1 <= mask.GetBottom())) { 2181a3e0fd82Sopenharmony_ci screenBuffer = static_cast<uint8_t*>(gfxDstBuffer.virAddr); 2182a3e0fd82Sopenharmony_ci screenBuffer += (y1 * screenBufferWidth + x) * bufferPxSize; 2183a3e0fd82Sopenharmony_ci OpacityType fillOpa = (weight ^ OPA_OPAQUE) * opa / OPA_OPAQUE; 2184a3e0fd82Sopenharmony_ci COLOR_FILL_BLEND(screenBuffer, bufferMode, &result, ARGB8888, fillOpa); 2185a3e0fd82Sopenharmony_ci } 2186a3e0fd82Sopenharmony_ci} 2187a3e0fd82Sopenharmony_ci} // namespace OHOS 2188