1a3e0fd82Sopenharmony_ci/* 2a3e0fd82Sopenharmony_ci * Copyright (c) 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_canvas.h" 17a3e0fd82Sopenharmony_ci#include "common/typed_text.h" 18a3e0fd82Sopenharmony_ci#include "draw/clip_utils.h" 19a3e0fd82Sopenharmony_ci#include "gfx_utils/diagram/depiction/depict_curve.h" 20a3e0fd82Sopenharmony_ci#include "gfx_utils/diagram/spancolorfill/fill_gradient.h" 21a3e0fd82Sopenharmony_ci#include "gfx_utils/diagram/spancolorfill/fill_interpolator.h" 22a3e0fd82Sopenharmony_ci 23a3e0fd82Sopenharmony_cinamespace OHOS { 24a3e0fd82Sopenharmony_ci/** 25a3e0fd82Sopenharmony_ci * Renders monochrome polygon paths and fills 26a3e0fd82Sopenharmony_ci */ 27a3e0fd82Sopenharmony_civoid RenderSolid(const Paint& paint, RasterizerScanlineAntialias& rasterizer, RenderBase& renBase, const bool& isStroke) 28a3e0fd82Sopenharmony_ci{ 29a3e0fd82Sopenharmony_ci GeometryScanline scanline; 30a3e0fd82Sopenharmony_ci Rgba8T color; 31a3e0fd82Sopenharmony_ci DrawCanvas::RenderBlendSolid(paint, color, isStroke); 32a3e0fd82Sopenharmony_ci RenderScanlinesAntiAliasSolid(rasterizer, scanline, renBase, color); 33a3e0fd82Sopenharmony_ci} 34a3e0fd82Sopenharmony_ci 35a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND 36a3e0fd82Sopenharmony_civoid DrawCanvas::DoRender(BufferInfo& gfxDstBuffer, 37a3e0fd82Sopenharmony_ci void* param, 38a3e0fd82Sopenharmony_ci const Paint& paint, 39a3e0fd82Sopenharmony_ci const Rect& rect, 40a3e0fd82Sopenharmony_ci const Rect& invalidatedArea, 41a3e0fd82Sopenharmony_ci const Style& style, 42a3e0fd82Sopenharmony_ci const bool& isStroke) 43a3e0fd82Sopenharmony_ci{ 44a3e0fd82Sopenharmony_ci if (param == nullptr) { 45a3e0fd82Sopenharmony_ci return; 46a3e0fd82Sopenharmony_ci } 47a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_SHADOW_EFFECT_FLAG) && GRAPHIC_ENABLE_SHADOW_EFFECT_FLAG 48a3e0fd82Sopenharmony_ci if (paint.HaveShadow()) { 49a3e0fd82Sopenharmony_ci DrawCanvas::DoDrawShadow(gfxDstBuffer, param, paint, rect, invalidatedArea, style, isStroke); 50a3e0fd82Sopenharmony_ci } 51a3e0fd82Sopenharmony_ci#endif 52a3e0fd82Sopenharmony_ci TransAffine transform; 53a3e0fd82Sopenharmony_ci RenderBuffer renderBuffer; 54a3e0fd82Sopenharmony_ci InitRenderAndTransform(gfxDstBuffer, renderBuffer, rect, transform, style, paint); 55a3e0fd82Sopenharmony_ci 56a3e0fd82Sopenharmony_ci RasterizerScanlineAntialias rasterizer; 57a3e0fd82Sopenharmony_ci GeometryScanline scanline; 58a3e0fd82Sopenharmony_ci 59a3e0fd82Sopenharmony_ci PathParam* pathParam = static_cast<PathParam*>(param); 60a3e0fd82Sopenharmony_ci rasterizer.ClipBox(0, 0, gfxDstBuffer.width, gfxDstBuffer.height); 61a3e0fd82Sopenharmony_ci SetRasterizer(*pathParam->vertices, paint, rasterizer, transform, isStroke); 62a3e0fd82Sopenharmony_ci 63a3e0fd82Sopenharmony_ci RenderPixfmtRgbaBlend pixFormat(renderBuffer); 64a3e0fd82Sopenharmony_ci RenderBase renBase(pixFormat); 65a3e0fd82Sopenharmony_ci FillBase allocator; 66a3e0fd82Sopenharmony_ci 67a3e0fd82Sopenharmony_ci renBase.ResetClipping(true); 68a3e0fd82Sopenharmony_ci renBase.ClipBox(invalidatedArea.GetLeft(), invalidatedArea.GetTop(), invalidatedArea.GetRight(), 69a3e0fd82Sopenharmony_ci invalidatedArea.GetBottom()); 70a3e0fd82Sopenharmony_ci 71a3e0fd82Sopenharmony_ci if (paint.GetStyle() == Paint::STROKE_STYLE || paint.GetStyle() == Paint::FILL_STYLE || 72a3e0fd82Sopenharmony_ci paint.GetStyle() == Paint::STROKE_FILL_STYLE) { 73a3e0fd82Sopenharmony_ci RenderSolid(paint, rasterizer, renBase, isStroke); 74a3e0fd82Sopenharmony_ci } 75a3e0fd82Sopenharmony_ci 76a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_GRADIENT_FILL_FLAG) && GRAPHIC_ENABLE_GRADIENT_FILL_FLAG 77a3e0fd82Sopenharmony_ci if (paint.GetStyle() == Paint::GRADIENT) { 78a3e0fd82Sopenharmony_ci RenderGradient(paint, rasterizer, transform, renBase, renderBuffer, allocator, invalidatedArea); 79a3e0fd82Sopenharmony_ci } 80a3e0fd82Sopenharmony_ci#endif 81a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_PATTERN_FILL_FLAG) && GRAPHIC_ENABLE_PATTERN_FILL_FLAG 82a3e0fd82Sopenharmony_ci if (paint.GetStyle() == Paint::PATTERN) { 83a3e0fd82Sopenharmony_ci RenderPattern(paint, pathParam->imageParam, rasterizer, renBase, allocator, rect); 84a3e0fd82Sopenharmony_ci } 85a3e0fd82Sopenharmony_ci#endif 86a3e0fd82Sopenharmony_ci} 87a3e0fd82Sopenharmony_ci 88a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_SHADOW_EFFECT_FLAG) && GRAPHIC_ENABLE_SHADOW_EFFECT_FLAG 89a3e0fd82Sopenharmony_civoid DrawCanvas::DoDrawShadow(BufferInfo& gfxDstBuffer, 90a3e0fd82Sopenharmony_ci void* param, 91a3e0fd82Sopenharmony_ci const Paint& paint, 92a3e0fd82Sopenharmony_ci const Rect& rect, 93a3e0fd82Sopenharmony_ci const Rect& invalidatedArea, 94a3e0fd82Sopenharmony_ci const Style& style, 95a3e0fd82Sopenharmony_ci const bool& isStroke) 96a3e0fd82Sopenharmony_ci{ 97a3e0fd82Sopenharmony_ci if (param == nullptr) { 98a3e0fd82Sopenharmony_ci return; 99a3e0fd82Sopenharmony_ci } 100a3e0fd82Sopenharmony_ci 101a3e0fd82Sopenharmony_ci TransAffine transform; 102a3e0fd82Sopenharmony_ci RenderBuffer renderBuffer; 103a3e0fd82Sopenharmony_ci DrawCanvas::InitRenderAndTransform(gfxDstBuffer, renderBuffer, rect, transform, style, paint); 104a3e0fd82Sopenharmony_ci 105a3e0fd82Sopenharmony_ci transform.Translate(paint.GetShadowOffsetX(), paint.GetShadowOffsetY()); 106a3e0fd82Sopenharmony_ci 107a3e0fd82Sopenharmony_ci RasterizerScanlineAntialias rasterizer; 108a3e0fd82Sopenharmony_ci GeometryScanline scanline; 109a3e0fd82Sopenharmony_ci PathParam* pathParam = static_cast<PathParam*>(param); 110a3e0fd82Sopenharmony_ci rasterizer.ClipBox(0, 0, gfxDstBuffer.width, gfxDstBuffer.height); 111a3e0fd82Sopenharmony_ci DrawCanvas::SetRasterizer(*pathParam->vertices, paint, rasterizer, transform, isStroke); 112a3e0fd82Sopenharmony_ci Rect bbox(rasterizer.GetMinX(), rasterizer.GetMinY(), rasterizer.GetMaxX(), rasterizer.GetMaxY()); 113a3e0fd82Sopenharmony_ci 114a3e0fd82Sopenharmony_ci RenderPixfmtRgbaBlend pixFormat(renderBuffer); 115a3e0fd82Sopenharmony_ci RenderBase renBase(pixFormat); 116a3e0fd82Sopenharmony_ci FillBase allocator; 117a3e0fd82Sopenharmony_ci 118a3e0fd82Sopenharmony_ci renBase.ResetClipping(true); 119a3e0fd82Sopenharmony_ci renBase.ClipBox(invalidatedArea.GetLeft(), invalidatedArea.GetTop(), invalidatedArea.GetRight(), 120a3e0fd82Sopenharmony_ci invalidatedArea.GetBottom()); 121a3e0fd82Sopenharmony_ci 122a3e0fd82Sopenharmony_ci Rgba8T shadowColor; 123a3e0fd82Sopenharmony_ci DrawCanvas::ChangeColor(shadowColor, paint.GetShadowColor(), paint.GetShadowColor().alpha * paint.GetGlobalAlpha()); 124a3e0fd82Sopenharmony_ci 125a3e0fd82Sopenharmony_ci RenderScanlinesAntiAliasSolid(rasterizer, scanline, renBase, shadowColor); 126a3e0fd82Sopenharmony_ci#if GRAPHIC_ENABLE_BLUR_EFFECT_FLAG 127a3e0fd82Sopenharmony_ci bbox.SetLeft(bbox.GetLeft() - paint.GetShadowBlur()); 128a3e0fd82Sopenharmony_ci bbox.SetTop(bbox.GetTop() - paint.GetShadowBlur()); 129a3e0fd82Sopenharmony_ci bbox.SetRight(bbox.GetRight() + paint.GetShadowBlur()); 130a3e0fd82Sopenharmony_ci bbox.SetBottom(bbox.GetBottom() + paint.GetShadowBlur()); 131a3e0fd82Sopenharmony_ci RenderBuffer shadowBuffer; 132a3e0fd82Sopenharmony_ci RenderPixfmtRgbaBlend pixf2(shadowBuffer); 133a3e0fd82Sopenharmony_ci Rect shadowRect = {int16_t(bbox.GetLeft()), int16_t(bbox.GetTop()), int16_t(bbox.GetRight()), 134a3e0fd82Sopenharmony_ci int16_t(bbox.GetBottom())}; 135a3e0fd82Sopenharmony_ci shadowRect.Intersect(shadowRect, invalidatedArea); 136a3e0fd82Sopenharmony_ci pixf2.Attach(pixFormat, shadowRect.GetLeft(), shadowRect.GetTop(), shadowRect.GetRight(), shadowRect.GetBottom()); 137a3e0fd82Sopenharmony_ci uint8_t pixelByteSize = DrawUtils::GetPxSizeByColorMode(gfxDstBuffer.mode) >> 3; // 3: Shift right 3 bits 138a3e0fd82Sopenharmony_ci 139a3e0fd82Sopenharmony_ci paint.GetDrawBoxBlur().BoxBlur(pixf2, MATH_UROUND(paint.GetShadowBlur()), pixelByteSize, gfxDstBuffer.stride); 140a3e0fd82Sopenharmony_ci 141a3e0fd82Sopenharmony_ci#endif // GRAPHIC_ENABLE_BLUR_EFFECT_FLAG 142a3e0fd82Sopenharmony_ci} 143a3e0fd82Sopenharmony_ci#endif // GRAPHIC_ENABLE_SHADOW_EFFECT_FLAG 144a3e0fd82Sopenharmony_ci#endif // ENABLE_CANVAS_EXTEND 145a3e0fd82Sopenharmony_ci 146a3e0fd82Sopenharmony_civoid DrawCanvas::InitRenderAndTransform(BufferInfo& gfxDstBuffer, 147a3e0fd82Sopenharmony_ci RenderBuffer& renderBuffer, 148a3e0fd82Sopenharmony_ci const Rect& rect, 149a3e0fd82Sopenharmony_ci TransAffine& transform, 150a3e0fd82Sopenharmony_ci const Style& style, 151a3e0fd82Sopenharmony_ci const Paint& paint) 152a3e0fd82Sopenharmony_ci{ 153a3e0fd82Sopenharmony_ci int16_t realLeft = rect.GetLeft() + style.paddingLeft_ + style.borderWidth_; 154a3e0fd82Sopenharmony_ci int16_t realTop = rect.GetTop() + style.paddingTop_ + style.borderWidth_; 155a3e0fd82Sopenharmony_ci transform.Reset(); 156a3e0fd82Sopenharmony_ci transform *= paint.GetTransAffine(); 157a3e0fd82Sopenharmony_ci transform.Translate(realLeft, realTop); 158a3e0fd82Sopenharmony_ci renderBuffer.Attach(static_cast<uint8_t*>(gfxDstBuffer.virAddr), gfxDstBuffer.width, gfxDstBuffer.height, 159a3e0fd82Sopenharmony_ci gfxDstBuffer.stride); 160a3e0fd82Sopenharmony_ci} 161a3e0fd82Sopenharmony_ci 162a3e0fd82Sopenharmony_civoid DrawCanvas::SetRasterizer(UICanvasVertices& vertices, 163a3e0fd82Sopenharmony_ci const Paint& paint, 164a3e0fd82Sopenharmony_ci RasterizerScanlineAntialias& rasterizer, 165a3e0fd82Sopenharmony_ci TransAffine& transform, 166a3e0fd82Sopenharmony_ci const bool& isStroke) 167a3e0fd82Sopenharmony_ci{ 168a3e0fd82Sopenharmony_ci DepictCurve canvasPath(vertices); 169a3e0fd82Sopenharmony_ci if (isStroke) { 170a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_DASH_GENERATE_FLAG) && GRAPHIC_ENABLE_DASH_GENERATE_FLAG 171a3e0fd82Sopenharmony_ci if (paint.IsLineDash()) { 172a3e0fd82Sopenharmony_ci using DashStyle = DepictDash; 173a3e0fd82Sopenharmony_ci using StrokeDashStyle = DepictStroke<DashStyle>; 174a3e0fd82Sopenharmony_ci using StrokeDashTransform = DepictTransform<StrokeDashStyle>; 175a3e0fd82Sopenharmony_ci DashStyle dashStyle(canvasPath); 176a3e0fd82Sopenharmony_ci LineDashStyleCalc(dashStyle, paint); 177a3e0fd82Sopenharmony_ci StrokeDashStyle strokeDashStyle(dashStyle); 178a3e0fd82Sopenharmony_ci LineStyleCalc(strokeDashStyle, paint); 179a3e0fd82Sopenharmony_ci StrokeDashTransform strokeDashTransform(strokeDashStyle, transform); 180a3e0fd82Sopenharmony_ci rasterizer.Reset(); 181a3e0fd82Sopenharmony_ci rasterizer.AddPath(strokeDashTransform); 182a3e0fd82Sopenharmony_ci return; 183a3e0fd82Sopenharmony_ci } 184a3e0fd82Sopenharmony_ci#endif 185a3e0fd82Sopenharmony_ci using StrokeLineStyle = DepictStroke<DepictCurve>; 186a3e0fd82Sopenharmony_ci StrokeLineStyle strokeLineStyle(canvasPath); 187a3e0fd82Sopenharmony_ci LineStyleCalc(strokeLineStyle, paint); 188a3e0fd82Sopenharmony_ci 189a3e0fd82Sopenharmony_ci DepictTransform<StrokeLineStyle> strokeTransform(strokeLineStyle, transform); 190a3e0fd82Sopenharmony_ci rasterizer.Reset(); 191a3e0fd82Sopenharmony_ci rasterizer.AddPath(strokeTransform); 192a3e0fd82Sopenharmony_ci } else { 193a3e0fd82Sopenharmony_ci DepictTransform<DepictCurve> pathTransform(canvasPath, transform); 194a3e0fd82Sopenharmony_ci rasterizer.Reset(); 195a3e0fd82Sopenharmony_ci rasterizer.AddPath(pathTransform); 196a3e0fd82Sopenharmony_ci } 197a3e0fd82Sopenharmony_ci} 198a3e0fd82Sopenharmony_ci 199a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_GRADIENT_FILL_FLAG) && GRAPHIC_ENABLE_GRADIENT_FILL_FLAG 200a3e0fd82Sopenharmony_civoid DrawCanvas::RenderGradient(const Paint& paint, 201a3e0fd82Sopenharmony_ci RasterizerScanlineAntialias& rasterizer, 202a3e0fd82Sopenharmony_ci TransAffine& transform, 203a3e0fd82Sopenharmony_ci RenderBase& renBase, 204a3e0fd82Sopenharmony_ci RenderBuffer& renderBuffer, 205a3e0fd82Sopenharmony_ci FillBase& allocator, 206a3e0fd82Sopenharmony_ci const Rect& invalidatedArea) 207a3e0fd82Sopenharmony_ci{ 208a3e0fd82Sopenharmony_ci GeometryScanline scanline; 209a3e0fd82Sopenharmony_ci 210a3e0fd82Sopenharmony_ci RenderPixfmtRgbaBlend pixFormatComp(renderBuffer); 211a3e0fd82Sopenharmony_ci RenderBase m_renBaseComp(pixFormatComp); 212a3e0fd82Sopenharmony_ci 213a3e0fd82Sopenharmony_ci m_renBaseComp.ResetClipping(true); 214a3e0fd82Sopenharmony_ci m_renBaseComp.ClipBox(invalidatedArea.GetLeft(), invalidatedArea.GetTop(), invalidatedArea.GetRight(), 215a3e0fd82Sopenharmony_ci invalidatedArea.GetBottom()); 216a3e0fd82Sopenharmony_ci TransAffine gradientMatrix; 217a3e0fd82Sopenharmony_ci FillInterpolator interpolatorType(gradientMatrix); 218a3e0fd82Sopenharmony_ci FillGradientLut gradientColorMode; 219a3e0fd82Sopenharmony_ci BuildGradientColor(paint, gradientColorMode); 220a3e0fd82Sopenharmony_ci if (paint.GetGradient() == Paint::Linear) { 221a3e0fd82Sopenharmony_ci float distance = 0; 222a3e0fd82Sopenharmony_ci BuildLineGradientMatrix(paint, gradientMatrix, transform, distance); 223a3e0fd82Sopenharmony_ci GradientLinearCalculate gradientLinearCalculate; 224a3e0fd82Sopenharmony_ci FillGradient span(interpolatorType, gradientLinearCalculate, gradientColorMode, 0, distance); 225a3e0fd82Sopenharmony_ci RenderScanlinesAntiAlias(rasterizer, scanline, renBase, allocator, span); 226a3e0fd82Sopenharmony_ci } 227a3e0fd82Sopenharmony_ci 228a3e0fd82Sopenharmony_ci if (paint.GetGradient() == Paint::Radial) { 229a3e0fd82Sopenharmony_ci Paint::RadialGradientPoint radialPoint = paint.GetRadialGradientPoint(); 230a3e0fd82Sopenharmony_ci float startRadius = 0; 231a3e0fd82Sopenharmony_ci float endRadius = 0; 232a3e0fd82Sopenharmony_ci BuildRadialGradientMatrix(paint, gradientMatrix, transform, startRadius, endRadius); 233a3e0fd82Sopenharmony_ci GradientRadialCalculate gradientRadialCalculate(radialPoint.r1, radialPoint.x0 - radialPoint.x1, 234a3e0fd82Sopenharmony_ci radialPoint.y0 - radialPoint.y1); 235a3e0fd82Sopenharmony_ci FillGradient span(interpolatorType, gradientRadialCalculate, gradientColorMode, startRadius, endRadius); 236a3e0fd82Sopenharmony_ci RenderScanlinesAntiAlias(rasterizer, scanline, renBase, allocator, span); 237a3e0fd82Sopenharmony_ci } 238a3e0fd82Sopenharmony_ci} 239a3e0fd82Sopenharmony_ci 240a3e0fd82Sopenharmony_civoid DrawCanvas::BuildGradientColor(const Paint& paint, FillGradientLut& gradientColorMode) 241a3e0fd82Sopenharmony_ci{ 242a3e0fd82Sopenharmony_ci gradientColorMode.RemoveAll(); 243a3e0fd82Sopenharmony_ci ListNode<Paint::StopAndColor>* iter = paint.getStopAndColor().Begin(); 244a3e0fd82Sopenharmony_ci uint16_t count = 0; 245a3e0fd82Sopenharmony_ci for (; count < paint.getStopAndColor().Size(); count++) { 246a3e0fd82Sopenharmony_ci ColorType stopColor = iter->data_.color; 247a3e0fd82Sopenharmony_ci Rgba8T sRgba8; 248a3e0fd82Sopenharmony_ci ChangeColor(sRgba8, stopColor, stopColor.alpha * paint.GetGlobalAlpha()); 249a3e0fd82Sopenharmony_ci gradientColorMode.AddColor(iter->data_.stop, sRgba8); 250a3e0fd82Sopenharmony_ci iter = iter->next_; 251a3e0fd82Sopenharmony_ci } 252a3e0fd82Sopenharmony_ci gradientColorMode.BuildLut(); 253a3e0fd82Sopenharmony_ci} 254a3e0fd82Sopenharmony_ci 255a3e0fd82Sopenharmony_civoid DrawCanvas::BuildRadialGradientMatrix(const Paint& paint, 256a3e0fd82Sopenharmony_ci TransAffine& gradientMatrix, 257a3e0fd82Sopenharmony_ci TransAffine& transform, 258a3e0fd82Sopenharmony_ci float& startRadius, 259a3e0fd82Sopenharmony_ci float& endRadius) 260a3e0fd82Sopenharmony_ci{ 261a3e0fd82Sopenharmony_ci Paint::RadialGradientPoint radialPoint = paint.GetRadialGradientPoint(); 262a3e0fd82Sopenharmony_ci gradientMatrix.Reset(); 263a3e0fd82Sopenharmony_ci gradientMatrix *= TransAffine::TransAffineTranslation(radialPoint.x1, radialPoint.y1); 264a3e0fd82Sopenharmony_ci gradientMatrix *= transform; 265a3e0fd82Sopenharmony_ci gradientMatrix.Invert(); 266a3e0fd82Sopenharmony_ci startRadius = radialPoint.r0; 267a3e0fd82Sopenharmony_ci endRadius = radialPoint.r1; 268a3e0fd82Sopenharmony_ci} 269a3e0fd82Sopenharmony_ci#endif // GRAPHIC_ENABLE_GRADIENT_FILL_FLAG 270a3e0fd82Sopenharmony_ci 271a3e0fd82Sopenharmony_ci#if defined(GRAPHIC_ENABLE_PATTERN_FILL_FLAG) && GRAPHIC_ENABLE_PATTERN_FILL_FLAG 272a3e0fd82Sopenharmony_ci#if defined(ENABLE_CANVAS_EXTEND) && ENABLE_CANVAS_EXTEND 273a3e0fd82Sopenharmony_civoid DrawCanvas::RenderPattern(const Paint& paint, 274a3e0fd82Sopenharmony_ci void* param, 275a3e0fd82Sopenharmony_ci RasterizerScanlineAntialias& rasterizer, 276a3e0fd82Sopenharmony_ci RenderBase& renBase, 277a3e0fd82Sopenharmony_ci FillBase& allocator, 278a3e0fd82Sopenharmony_ci const Rect& rect) 279a3e0fd82Sopenharmony_ci{ 280a3e0fd82Sopenharmony_ci if (param == nullptr) { 281a3e0fd82Sopenharmony_ci return; 282a3e0fd82Sopenharmony_ci } 283a3e0fd82Sopenharmony_ci ImageParam* imageParam = static_cast<ImageParam*>(param); 284a3e0fd82Sopenharmony_ci if (imageParam->image == nullptr) { 285a3e0fd82Sopenharmony_ci return; 286a3e0fd82Sopenharmony_ci } 287a3e0fd82Sopenharmony_ci GeometryScanline scanline; 288a3e0fd82Sopenharmony_ci FillPatternRgba spanPattern(imageParam->image->GetImageInfo(), paint.GetPatternRepeatMode(), rect.GetLeft(), 289a3e0fd82Sopenharmony_ci rect.GetTop()); 290a3e0fd82Sopenharmony_ci RenderScanlinesAntiAlias(rasterizer, scanline, renBase, allocator, spanPattern); 291a3e0fd82Sopenharmony_ci} 292a3e0fd82Sopenharmony_ci#endif 293a3e0fd82Sopenharmony_ci#endif // GRAPHIC_ENABLE_PATTERN_FILL_FLAG 294a3e0fd82Sopenharmony_ci 295a3e0fd82Sopenharmony_ci} // namespace OHOS 296