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/** 17a3e0fd82Sopenharmony_ci* @brief Defines scanline renderer 18a3e0fd82Sopenharmony_ci* @since 1.0 19a3e0fd82Sopenharmony_ci* @version 1.0 20a3e0fd82Sopenharmony_ci*/ 21a3e0fd82Sopenharmony_ci 22a3e0fd82Sopenharmony_ci#include "render_scanline.h" 23a3e0fd82Sopenharmony_ci 24a3e0fd82Sopenharmony_cinamespace OHOS { 25a3e0fd82Sopenharmony_civoid RenderScanlinesAntiAliasSolid(RasterizerScanlineAntialias& raster, GeometryScanline& scanline, 26a3e0fd82Sopenharmony_ci RenderBase& renBase, const Rgba8T& color) 27a3e0fd82Sopenharmony_ci{ 28a3e0fd82Sopenharmony_ci if (!raster.RewindScanlines()) { 29a3e0fd82Sopenharmony_ci return; 30a3e0fd82Sopenharmony_ci } 31a3e0fd82Sopenharmony_ci scanline.Reset(raster.GetMinX(), raster.GetMaxX()); 32a3e0fd82Sopenharmony_ci while (raster.SweepScanline(scanline)) { 33a3e0fd82Sopenharmony_ci int32_t y = scanline.GetYLevel(); 34a3e0fd82Sopenharmony_ci uint32_t numSpans = scanline.NumSpans(); 35a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span = scanline.Begin(); 36a3e0fd82Sopenharmony_ci while (true) { 37a3e0fd82Sopenharmony_ci int32_t x = span->x; 38a3e0fd82Sopenharmony_ci if (span->spanLength > 0) { 39a3e0fd82Sopenharmony_ci renBase.BlendSolidHSpan(x, y, static_cast<uint32_t>(span->spanLength), 40a3e0fd82Sopenharmony_ci color, span->covers); 41a3e0fd82Sopenharmony_ci } else { 42a3e0fd82Sopenharmony_ci renBase.BlendHLine(x, y, static_cast<uint32_t>(x - span->spanLength - 1), 43a3e0fd82Sopenharmony_ci color, *(span->covers)); 44a3e0fd82Sopenharmony_ci } 45a3e0fd82Sopenharmony_ci if (--numSpans == 0) { 46a3e0fd82Sopenharmony_ci break; 47a3e0fd82Sopenharmony_ci } 48a3e0fd82Sopenharmony_ci ++span; 49a3e0fd82Sopenharmony_ci } 50a3e0fd82Sopenharmony_ci } 51a3e0fd82Sopenharmony_ci} 52a3e0fd82Sopenharmony_ci 53a3e0fd82Sopenharmony_civoid RenderScanlinesAntiAlias(RasterizerScanlineAntialias& raster, GeometryScanline& scanline, 54a3e0fd82Sopenharmony_ci RenderBase& renBase, FillBase& alloc, SpanBase& spanGen) 55a3e0fd82Sopenharmony_ci{ 56a3e0fd82Sopenharmony_ci if (!raster.RewindScanlines()) { 57a3e0fd82Sopenharmony_ci return; 58a3e0fd82Sopenharmony_ci } 59a3e0fd82Sopenharmony_ci scanline.Reset(raster.GetMinX(), raster.GetMaxX()); 60a3e0fd82Sopenharmony_ci spanGen.Prepare(); // Segment generator preparation 61a3e0fd82Sopenharmony_ci alloc.Resize(raster.GetMaxX()-raster.GetMinX()); 62a3e0fd82Sopenharmony_ci while (raster.SweepScanline(scanline)) { 63a3e0fd82Sopenharmony_ci int32_t y = scanline.GetYLevel(); 64a3e0fd82Sopenharmony_ci uint32_t numSpans = scanline.NumSpans(); 65a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span = scanline.Begin(); 66a3e0fd82Sopenharmony_ci while (true) { 67a3e0fd82Sopenharmony_ci int32_t x = span->x; 68a3e0fd82Sopenharmony_ci int32_t len = span->spanLength; 69a3e0fd82Sopenharmony_ci const uint8_t* covers = span->covers; 70a3e0fd82Sopenharmony_ci 71a3e0fd82Sopenharmony_ci if (len < 0) { 72a3e0fd82Sopenharmony_ci len = -len; 73a3e0fd82Sopenharmony_ci } 74a3e0fd82Sopenharmony_ci 75a3e0fd82Sopenharmony_ci spanGen.Generate(alloc.GetSpanPtr(), x, y, len); 76a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x, y, len, alloc.GetSpanPtr(), 77a3e0fd82Sopenharmony_ci (span->spanLength < 0) ? 0 : covers, *covers); 78a3e0fd82Sopenharmony_ci 79a3e0fd82Sopenharmony_ci if (--numSpans == 0) { 80a3e0fd82Sopenharmony_ci break; 81a3e0fd82Sopenharmony_ci } 82a3e0fd82Sopenharmony_ci ++span; 83a3e0fd82Sopenharmony_ci } 84a3e0fd82Sopenharmony_ci } 85a3e0fd82Sopenharmony_ci} 86a3e0fd82Sopenharmony_ci 87a3e0fd82Sopenharmony_civoid BlendScanLine(GlobalCompositeOperation op, RasterizerScanlineAntialias& raster1, 88a3e0fd82Sopenharmony_ci RasterizerScanlineAntialias& raster2, GeometryScanline& sl1, GeometryScanline& sl2, 89a3e0fd82Sopenharmony_ci RenderBase& renBase, FillBase& alloc, SpanBase& spanGen1, SpanBase& spanGen2) 90a3e0fd82Sopenharmony_ci{ 91a3e0fd82Sopenharmony_ci switch (op) { 92a3e0fd82Sopenharmony_ci case SOURCE_OVER: 93a3e0fd82Sopenharmony_ci BlendSourceOver(raster2, raster1, sl2, sl1, renBase, alloc, spanGen2, spanGen1); 94a3e0fd82Sopenharmony_ci break; 95a3e0fd82Sopenharmony_ci case SOURCE_ATOP: 96a3e0fd82Sopenharmony_ci BlendSourceAtop(raster1, raster2, sl1, sl2, renBase, alloc, spanGen1, spanGen2); 97a3e0fd82Sopenharmony_ci break; 98a3e0fd82Sopenharmony_ci case SOURCE_IN: 99a3e0fd82Sopenharmony_ci BlendSourceIn(raster1, raster2, sl1, sl2, renBase, alloc, spanGen1); 100a3e0fd82Sopenharmony_ci break; 101a3e0fd82Sopenharmony_ci case SOURCE_OUT: 102a3e0fd82Sopenharmony_ci BlendSourceOut(raster1, raster2, sl1, sl2, renBase, alloc, spanGen1); 103a3e0fd82Sopenharmony_ci break; 104a3e0fd82Sopenharmony_ci case DESTINATION_OVER: 105a3e0fd82Sopenharmony_ci BlendSourceOver(raster1, raster2, sl1, sl2, renBase, alloc, spanGen1, spanGen2); 106a3e0fd82Sopenharmony_ci break; 107a3e0fd82Sopenharmony_ci case DESTINATION_ATOP: 108a3e0fd82Sopenharmony_ci BlendSourceAtop(raster2, raster1, sl2, sl1, renBase, alloc, spanGen2, spanGen1); 109a3e0fd82Sopenharmony_ci break; 110a3e0fd82Sopenharmony_ci case DESTINATION_IN: 111a3e0fd82Sopenharmony_ci BlendSourceIn(raster2, raster1, sl2, sl1, renBase, alloc, spanGen2); 112a3e0fd82Sopenharmony_ci break; 113a3e0fd82Sopenharmony_ci case DESTINATION_OUT: 114a3e0fd82Sopenharmony_ci BlendSourceOut(raster2, raster1, sl2, sl1, renBase, alloc, spanGen2); 115a3e0fd82Sopenharmony_ci break; 116a3e0fd82Sopenharmony_ci case LIGHTER: 117a3e0fd82Sopenharmony_ci BlendLIGHTER(raster1, raster2, sl1, sl2, renBase, alloc, spanGen1, spanGen2); 118a3e0fd82Sopenharmony_ci break; 119a3e0fd82Sopenharmony_ci case COPY: 120a3e0fd82Sopenharmony_ci RenderScanlinesAntiAlias(raster1, sl1, renBase, alloc, spanGen1); 121a3e0fd82Sopenharmony_ci break; 122a3e0fd82Sopenharmony_ci case XOR: 123a3e0fd82Sopenharmony_ci BlendXOR(raster1, raster2, sl1, sl2, renBase, alloc, spanGen1, spanGen2); 124a3e0fd82Sopenharmony_ci break; 125a3e0fd82Sopenharmony_ci default: 126a3e0fd82Sopenharmony_ci break; 127a3e0fd82Sopenharmony_ci } 128a3e0fd82Sopenharmony_ci} 129a3e0fd82Sopenharmony_ci 130a3e0fd82Sopenharmony_civoid BlendSourceAtop(RasterizerScanlineAntialias& raster1, RasterizerScanlineAntialias& raster2, 131a3e0fd82Sopenharmony_ci GeometryScanline& scanline1, GeometryScanline& scanline2, RenderBase& renBase, 132a3e0fd82Sopenharmony_ci FillBase& alloc, SpanBase& spanGen1, SpanBase& spanGen2) 133a3e0fd82Sopenharmony_ci{ 134a3e0fd82Sopenharmony_ci if ((!raster1.RewindScanlines()) || (!raster2.RewindScanlines())) { 135a3e0fd82Sopenharmony_ci return; 136a3e0fd82Sopenharmony_ci } 137a3e0fd82Sopenharmony_ci scanline1.Reset(raster1.GetMinX(), raster1.GetMaxX()); 138a3e0fd82Sopenharmony_ci scanline2.Reset(raster2.GetMinX(), raster2.GetMaxX()); 139a3e0fd82Sopenharmony_ci int16_t allocMinx = (raster1.GetMinX() > raster2.GetMinX()) ? raster2.GetMinX() : raster1.GetMinX(); 140a3e0fd82Sopenharmony_ci int16_t allocMaxX = (raster1.GetMaxX() > raster2.GetMaxX()) ? raster1.GetMaxX() : raster2.GetMaxX(); 141a3e0fd82Sopenharmony_ci alloc.Resize(allocMaxX - allocMinx); 142a3e0fd82Sopenharmony_ci int32_t y1 = 0; 143a3e0fd82Sopenharmony_ci if (raster1.SweepScanline(scanline1)) { 144a3e0fd82Sopenharmony_ci y1 = scanline1.GetYLevel(); 145a3e0fd82Sopenharmony_ci spanGen1.Prepare(); // Segment generator preparation 146a3e0fd82Sopenharmony_ci } 147a3e0fd82Sopenharmony_ci while (raster2.SweepScanline(scanline2)) { 148a3e0fd82Sopenharmony_ci spanGen2.Prepare(); 149a3e0fd82Sopenharmony_ci int32_t y2 = scanline2.GetYLevel(); 150a3e0fd82Sopenharmony_ci uint32_t numSpans2 = scanline2.NumSpans(); 151a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span2 = scanline2.Begin(); 152a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span1 = scanline1.Begin(); 153a3e0fd82Sopenharmony_ci if (y2 > y1) { 154a3e0fd82Sopenharmony_ci while (raster1.SweepScanline(scanline1)) { 155a3e0fd82Sopenharmony_ci y1 = scanline1.GetYLevel(); 156a3e0fd82Sopenharmony_ci if (y1 == y2) { 157a3e0fd82Sopenharmony_ci span1 = scanline1.Begin(); 158a3e0fd82Sopenharmony_ci break; 159a3e0fd82Sopenharmony_ci } 160a3e0fd82Sopenharmony_ci } 161a3e0fd82Sopenharmony_ci } 162a3e0fd82Sopenharmony_ci while (true) { 163a3e0fd82Sopenharmony_ci int32_t x2 = span2->x; 164a3e0fd82Sopenharmony_ci if (y1 == y2) { 165a3e0fd82Sopenharmony_ci int32_t x1 = span1->x; 166a3e0fd82Sopenharmony_ci if (span2->spanLength > 0) { 167a3e0fd82Sopenharmony_ci if (span1->spanLength > 0) { 168a3e0fd82Sopenharmony_ci spanGen2.Generate(alloc.GetSpanPtr(), x2, y2, span2->spanLength); 169a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x2, y2, (uint32_t)span2->spanLength, 170a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), span2->covers); 171a3e0fd82Sopenharmony_ci if ((x1 <= x2) && ((x2 + span2->spanLength) < (x1 + span1->spanLength))) { 172a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x2, y2, span2->spanLength); 173a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x2, y2, (uint32_t)span2->spanLength, 174a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), 175a3e0fd82Sopenharmony_ci span2->covers); 176a3e0fd82Sopenharmony_ci } else if ((x1 >= x2) && ((x1 + span1->spanLength) <= (x2 + span2->spanLength))) { 177a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x1, y2, span1->spanLength); 178a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x1, y2, (uint32_t)span1->spanLength, 179a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), 180a3e0fd82Sopenharmony_ci span1->covers); 181a3e0fd82Sopenharmony_ci } else if ((x1 > x2) && (x1 < (x2 + span2->spanLength)) && 182a3e0fd82Sopenharmony_ci ((x1 + span1->spanLength) >= (x2 + span2->spanLength))) { 183a3e0fd82Sopenharmony_ci GeometryScanline scanline3; 184a3e0fd82Sopenharmony_ci CalcinterScanline(scanline3, x1, x2, span1, span2); 185a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span3 = scanline3.Begin(); 186a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x1, y2, span3->spanLength); 187a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x1, y2, (uint32_t)span3->spanLength, 188a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), 189a3e0fd82Sopenharmony_ci span3->covers); 190a3e0fd82Sopenharmony_ci } else if ((x1 < x2) && ((x1 + span1->spanLength) > x2) && 191a3e0fd82Sopenharmony_ci ((x1 + span1->spanLength) <= (x2 + span2->spanLength))) { 192a3e0fd82Sopenharmony_ci GeometryScanline scanline3; 193a3e0fd82Sopenharmony_ci CalcinterScanline(scanline3, x2, x1, span2, span1); 194a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span3 = scanline3.Begin(); 195a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x2, y2, span3->spanLength); 196a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x2, y2, (uint32_t)span3->spanLength, 197a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), 198a3e0fd82Sopenharmony_ci span3->covers); 199a3e0fd82Sopenharmony_ci } 200a3e0fd82Sopenharmony_ci } 201a3e0fd82Sopenharmony_ci } 202a3e0fd82Sopenharmony_ci ++span1; 203a3e0fd82Sopenharmony_ci } else { 204a3e0fd82Sopenharmony_ci if (span2->spanLength > 0) { 205a3e0fd82Sopenharmony_ci spanGen2.Generate(alloc.GetSpanPtr(), x2, y2, span2->spanLength); 206a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x2, y2, (uint32_t)span2->spanLength, 207a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), 208a3e0fd82Sopenharmony_ci span2->covers); 209a3e0fd82Sopenharmony_ci } 210a3e0fd82Sopenharmony_ci } 211a3e0fd82Sopenharmony_ci if (--numSpans2 == 0) { 212a3e0fd82Sopenharmony_ci break; 213a3e0fd82Sopenharmony_ci } 214a3e0fd82Sopenharmony_ci ++span2; 215a3e0fd82Sopenharmony_ci } 216a3e0fd82Sopenharmony_ci if (y1 == y2) { 217a3e0fd82Sopenharmony_ci raster1.SweepScanline(scanline1); 218a3e0fd82Sopenharmony_ci y1 = scanline1.GetYLevel(); 219a3e0fd82Sopenharmony_ci } 220a3e0fd82Sopenharmony_ci } 221a3e0fd82Sopenharmony_ci} 222a3e0fd82Sopenharmony_ci 223a3e0fd82Sopenharmony_civoid BlendSourceIn(RasterizerScanlineAntialias& raster1, RasterizerScanlineAntialias& raster2, 224a3e0fd82Sopenharmony_ci GeometryScanline& scanline1, GeometryScanline& scanline2, RenderBase& renBase, 225a3e0fd82Sopenharmony_ci FillBase& alloc, SpanBase& spanGen1) 226a3e0fd82Sopenharmony_ci{ 227a3e0fd82Sopenharmony_ci if (!raster1.RewindScanlines() || !raster2.RewindScanlines()) { 228a3e0fd82Sopenharmony_ci return; 229a3e0fd82Sopenharmony_ci } 230a3e0fd82Sopenharmony_ci 231a3e0fd82Sopenharmony_ci scanline1.Reset(raster1.GetMinX(), raster1.GetMaxX()); 232a3e0fd82Sopenharmony_ci scanline2.Reset(raster2.GetMinX(), raster2.GetMaxX()); 233a3e0fd82Sopenharmony_ci 234a3e0fd82Sopenharmony_ci int16_t allocMinx = (raster1.GetMinX() > raster2.GetMinX()) ? raster2.GetMinX() : raster1.GetMinX(); 235a3e0fd82Sopenharmony_ci int16_t allocMaxX = (raster1.GetMaxX() > raster2.GetMaxX()) ? raster1.GetMaxX() : raster2.GetMaxX(); 236a3e0fd82Sopenharmony_ci alloc.Resize(allocMaxX-allocMinx); 237a3e0fd82Sopenharmony_ci int32_t y1 = 0; 238a3e0fd82Sopenharmony_ci if (raster1.SweepScanline(scanline1)) { 239a3e0fd82Sopenharmony_ci y1 = scanline1.GetYLevel(); 240a3e0fd82Sopenharmony_ci spanGen1.Prepare(); 241a3e0fd82Sopenharmony_ci } 242a3e0fd82Sopenharmony_ci while (raster2.SweepScanline(scanline2)) { 243a3e0fd82Sopenharmony_ci BlendSourceInLoop(raster1, scanline1, scanline2, spanGen1, renBase, alloc, y1); 244a3e0fd82Sopenharmony_ci } 245a3e0fd82Sopenharmony_ci} 246a3e0fd82Sopenharmony_ci 247a3e0fd82Sopenharmony_civoid BlendSourceOut(RasterizerScanlineAntialias& raster1, RasterizerScanlineAntialias& raster2, 248a3e0fd82Sopenharmony_ci GeometryScanline& scanline1, GeometryScanline& scanline2, 249a3e0fd82Sopenharmony_ci RenderBase& renBase, FillBase& alloc, SpanBase& spanGen1) 250a3e0fd82Sopenharmony_ci{ 251a3e0fd82Sopenharmony_ci if (!raster1.RewindScanlines() || !raster2.RewindScanlines()) { 252a3e0fd82Sopenharmony_ci return; 253a3e0fd82Sopenharmony_ci } 254a3e0fd82Sopenharmony_ci scanline1.Reset(raster1.GetMinX(), raster1.GetMaxX()); 255a3e0fd82Sopenharmony_ci scanline2.Reset(raster2.GetMinX(), raster2.GetMaxX()); 256a3e0fd82Sopenharmony_ci int16_t allocMinx = (raster1.GetMinX() > raster2.GetMinX()) ? raster2.GetMinX() : raster1.GetMinX(); 257a3e0fd82Sopenharmony_ci int16_t allocMaxX = (raster1.GetMaxX() > raster2.GetMaxX()) ? raster1.GetMaxX() : raster2.GetMaxX(); 258a3e0fd82Sopenharmony_ci alloc.Resize(allocMaxX-allocMinx); 259a3e0fd82Sopenharmony_ci int32_t y1 = 0; 260a3e0fd82Sopenharmony_ci if (raster1.SweepScanline(scanline1)) { 261a3e0fd82Sopenharmony_ci y1 = scanline1.GetYLevel(); 262a3e0fd82Sopenharmony_ci spanGen1.Prepare(); 263a3e0fd82Sopenharmony_ci } 264a3e0fd82Sopenharmony_ci if (raster1.GetMinY() < raster2.GetMinY()) { 265a3e0fd82Sopenharmony_ci do { 266a3e0fd82Sopenharmony_ci y1 = scanline1.GetYLevel(); 267a3e0fd82Sopenharmony_ci if (y1 == raster2.GetMinY()) { 268a3e0fd82Sopenharmony_ci break; 269a3e0fd82Sopenharmony_ci } 270a3e0fd82Sopenharmony_ci BlendSourceOutWhile(y1, scanline1, renBase, alloc, spanGen1); 271a3e0fd82Sopenharmony_ci } while (raster1.SweepScanline(scanline1)); 272a3e0fd82Sopenharmony_ci } 273a3e0fd82Sopenharmony_ci while (raster2.SweepScanline(scanline2)) { 274a3e0fd82Sopenharmony_ci int32_t y2 = scanline2.GetYLevel(); 275a3e0fd82Sopenharmony_ci uint32_t numSpans2 = scanline2.NumSpans(); 276a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span2 = scanline2.Begin(); 277a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span1 = scanline1.Begin(); 278a3e0fd82Sopenharmony_ci while (true) { 279a3e0fd82Sopenharmony_ci int32_t x2 = span2->x; 280a3e0fd82Sopenharmony_ci if (y1 == y2) { 281a3e0fd82Sopenharmony_ci int32_t x1 = span1->x; 282a3e0fd82Sopenharmony_ci if (span2->spanLength > 0) { 283a3e0fd82Sopenharmony_ci if (span1->spanLength > 0) { 284a3e0fd82Sopenharmony_ci if ((x1 < x2) && (x2 + span2->spanLength) < (x1 + span1->spanLength)) { 285a3e0fd82Sopenharmony_ci GeometryScanline scanline3; 286a3e0fd82Sopenharmony_ci CalcOutScanlineAll(scanline3, x2, x1, span2, span1); 287a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span3 = scanline3.Begin(); 288a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x1, y2, span3->spanLength); 289a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x1, y2, (uint32_t)span3->spanLength, 290a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), 291a3e0fd82Sopenharmony_ci span3->covers); 292a3e0fd82Sopenharmony_ci } else if ((x1 >= x2) && x1 < x2 + span2->spanLength && 293a3e0fd82Sopenharmony_ci ((x1 + span1->spanLength) >= (x2 + span2->spanLength))) { 294a3e0fd82Sopenharmony_ci GeometryScanline scanline4; 295a3e0fd82Sopenharmony_ci CalcOutScanlineLeft(scanline4, x1, x2, span1, span2); 296a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span4 = scanline4.Begin(); 297a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x1, y2, span4->spanLength); 298a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x1, y2, (uint32_t)span4->spanLength, 299a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), 300a3e0fd82Sopenharmony_ci span4->covers); 301a3e0fd82Sopenharmony_ci } else if ((x1 <= x2) && (x1 + span1->spanLength) >= x2 && 302a3e0fd82Sopenharmony_ci ((x1 + span1->spanLength) <= (x2 + span2->spanLength))) { 303a3e0fd82Sopenharmony_ci GeometryScanline scanline3; 304a3e0fd82Sopenharmony_ci CalcOutScanlineRight(scanline3, x2, x1, span2, span1); 305a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span3 = scanline3.Begin(); 306a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x1, y2, span3->spanLength); 307a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x1, y2, (uint32_t)span3->spanLength, 308a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), span3->covers); 309a3e0fd82Sopenharmony_ci } else if (((x1 + span1->spanLength) < x2) || ((x2 + span2->spanLength) < x1)) { 310a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x1, y2, span1->spanLength); 311a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x1, y2, (uint32_t)span1->spanLength, 312a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), 313a3e0fd82Sopenharmony_ci span1->covers); 314a3e0fd82Sopenharmony_ci } 315a3e0fd82Sopenharmony_ci } 316a3e0fd82Sopenharmony_ci } 317a3e0fd82Sopenharmony_ci ++span1; 318a3e0fd82Sopenharmony_ci } 319a3e0fd82Sopenharmony_ci if (--numSpans2 == 0) { 320a3e0fd82Sopenharmony_ci break; 321a3e0fd82Sopenharmony_ci } 322a3e0fd82Sopenharmony_ci ++span2; 323a3e0fd82Sopenharmony_ci } 324a3e0fd82Sopenharmony_ci if (y1 == y2 && y1 < raster2.GetMaxY() - 1) { 325a3e0fd82Sopenharmony_ci if (raster1.SweepScanline(scanline1)) { 326a3e0fd82Sopenharmony_ci y1 = scanline1.GetYLevel(); 327a3e0fd82Sopenharmony_ci } 328a3e0fd82Sopenharmony_ci } 329a3e0fd82Sopenharmony_ci } 330a3e0fd82Sopenharmony_ci BlendSourceOutDrawResetRaster(raster1, scanline1, renBase, alloc, spanGen1); 331a3e0fd82Sopenharmony_ci} 332a3e0fd82Sopenharmony_ci 333a3e0fd82Sopenharmony_civoid BlendSourceOutWhile(int32_t y1, GeometryScanline& scanline1, RenderBase& renBase, 334a3e0fd82Sopenharmony_ci FillBase& alloc, SpanBase& spanGen1) 335a3e0fd82Sopenharmony_ci{ 336a3e0fd82Sopenharmony_ci uint32_t numSpans = scanline1.NumSpans(); 337a3e0fd82Sopenharmony_ci typename GeometryScanline::ConstIterator span = scanline1.Begin(); 338a3e0fd82Sopenharmony_ci while (true) { 339a3e0fd82Sopenharmony_ci int32_t x = span->x; 340a3e0fd82Sopenharmony_ci if (span->spanLength > 0) { 341a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x, y1, span->spanLength); 342a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x, y1, (uint32_t)span->spanLength, 343a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), 344a3e0fd82Sopenharmony_ci span->covers); 345a3e0fd82Sopenharmony_ci } 346a3e0fd82Sopenharmony_ci if (--numSpans == 0) { 347a3e0fd82Sopenharmony_ci break; 348a3e0fd82Sopenharmony_ci } 349a3e0fd82Sopenharmony_ci ++span; 350a3e0fd82Sopenharmony_ci } 351a3e0fd82Sopenharmony_ci} 352a3e0fd82Sopenharmony_ci 353a3e0fd82Sopenharmony_civoid BlendSourceOutDrawResetRaster(RasterizerScanlineAntialias& raster1, GeometryScanline& scanline1, 354a3e0fd82Sopenharmony_ci RenderBase& renBase, FillBase& alloc, SpanBase& spanGen1) 355a3e0fd82Sopenharmony_ci{ 356a3e0fd82Sopenharmony_ci while (raster1.SweepScanline(scanline1)) { 357a3e0fd82Sopenharmony_ci int32_t y = scanline1.GetYLevel(); 358a3e0fd82Sopenharmony_ci uint32_t numSpans = scanline1.NumSpans(); 359a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span = scanline1.Begin(); 360a3e0fd82Sopenharmony_ci while (true) { 361a3e0fd82Sopenharmony_ci int32_t x = span->x; 362a3e0fd82Sopenharmony_ci if (span->spanLength > 0) { 363a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x, y, span->spanLength); 364a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x, y, (uint32_t)span->spanLength, 365a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), 366a3e0fd82Sopenharmony_ci span->covers); 367a3e0fd82Sopenharmony_ci } 368a3e0fd82Sopenharmony_ci if (--numSpans == 0) { 369a3e0fd82Sopenharmony_ci break; 370a3e0fd82Sopenharmony_ci } 371a3e0fd82Sopenharmony_ci ++span; 372a3e0fd82Sopenharmony_ci } 373a3e0fd82Sopenharmony_ci } 374a3e0fd82Sopenharmony_ci} 375a3e0fd82Sopenharmony_ci 376a3e0fd82Sopenharmony_civoid BlendSourceOver(RasterizerScanlineAntialias &raster1, 377a3e0fd82Sopenharmony_ci RasterizerScanlineAntialias &raster2, 378a3e0fd82Sopenharmony_ci GeometryScanline &scanline1, 379a3e0fd82Sopenharmony_ci GeometryScanline &scanline2, 380a3e0fd82Sopenharmony_ci RenderBase &renBase, 381a3e0fd82Sopenharmony_ci FillBase &alloc, 382a3e0fd82Sopenharmony_ci SpanBase&&spanGen1, 383a3e0fd82Sopenharmony_ci SpanBase &spanGen2) 384a3e0fd82Sopenharmony_ci{ 385a3e0fd82Sopenharmony_ci RenderScanlinesAntiAlias(raster1, scanline1, renBase, alloc, spanGen1); 386a3e0fd82Sopenharmony_ci RenderScanlinesAntiAlias(raster2, scanline2, renBase, alloc, spanGen2); 387a3e0fd82Sopenharmony_ci} 388a3e0fd82Sopenharmony_ci 389a3e0fd82Sopenharmony_civoid BlendXOR(RasterizerScanlineAntialias& raster1, RasterizerScanlineAntialias& raster2, 390a3e0fd82Sopenharmony_ci GeometryScanline& scanline1, GeometryScanline& scanline2, 391a3e0fd82Sopenharmony_ci RenderBase& renBase, FillBase& alloc, SpanBase& spanGen1, SpanBase& spanGen2) 392a3e0fd82Sopenharmony_ci{ 393a3e0fd82Sopenharmony_ci if (!raster1.RewindScanlines() || !raster2.RewindScanlines()) { 394a3e0fd82Sopenharmony_ci return; 395a3e0fd82Sopenharmony_ci } 396a3e0fd82Sopenharmony_ci scanline1.Reset(raster1.GetMinX(), raster1.GetMaxX()); 397a3e0fd82Sopenharmony_ci scanline2.Reset(raster2.GetMinX(), raster2.GetMaxX()); 398a3e0fd82Sopenharmony_ci int16_t allocMinx = raster1.GetMinX() > raster2.GetMinX() ? raster2.GetMinX() : raster1.GetMinX(); 399a3e0fd82Sopenharmony_ci int16_t allocMaxX = raster1.GetMaxX() > raster2.GetMaxX() ? raster1.GetMaxX() : raster2.GetMaxX(); 400a3e0fd82Sopenharmony_ci alloc.Resize(allocMaxX-allocMinx); 401a3e0fd82Sopenharmony_ci int32_t y1 = 0; 402a3e0fd82Sopenharmony_ci if (raster1.SweepScanline(scanline1)) { 403a3e0fd82Sopenharmony_ci y1 = scanline1.GetYLevel(); 404a3e0fd82Sopenharmony_ci spanGen1.Prepare(); 405a3e0fd82Sopenharmony_ci } 406a3e0fd82Sopenharmony_ci BlendXORColorHspan(y1, raster1, raster2, scanline1, renBase, alloc, spanGen1); 407a3e0fd82Sopenharmony_ci while (raster2.SweepScanline(scanline2)) { 408a3e0fd82Sopenharmony_ci int32_t y2 = scanline2.GetYLevel(); 409a3e0fd82Sopenharmony_ci spanGen2.Prepare(); 410a3e0fd82Sopenharmony_ci uint32_t numSpans2 = scanline2.NumSpans(); 411a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span2 = scanline2.Begin(); 412a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span1 = scanline1.Begin(); 413a3e0fd82Sopenharmony_ci while (true) { 414a3e0fd82Sopenharmony_ci int32_t x2 = span2->x; 415a3e0fd82Sopenharmony_ci if (y1 == y2) { 416a3e0fd82Sopenharmony_ci { 417a3e0fd82Sopenharmony_ci int32_t x1 = span1->x; 418a3e0fd82Sopenharmony_ci if (span2->spanLength > 0) { 419a3e0fd82Sopenharmony_ci if (span1->spanLength > 0) { 420a3e0fd82Sopenharmony_ci if ((x1 >= x2) && ((x1 + span1->spanLength) <= (x2 + span2->spanLength))) { 421a3e0fd82Sopenharmony_ci GeometryScanline scanline3; 422a3e0fd82Sopenharmony_ci CalcOutScanlineAll(scanline3, x1, x2, span1, span2); 423a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span3 = scanline3.Begin(); 424a3e0fd82Sopenharmony_ci spanGen2.Generate(alloc.GetSpanPtr(), x2, y2, span3->spanLength); 425a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x2, y2, (uint32_t)span3->spanLength, 426a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), 427a3e0fd82Sopenharmony_ci span3->covers); 428a3e0fd82Sopenharmony_ci } else if (((x1 < x2) && ((x2 + span2->spanLength) < (x1 + span1->spanLength)))) { 429a3e0fd82Sopenharmony_ci GeometryScanline scanline3; 430a3e0fd82Sopenharmony_ci CalcOutScanlineAll(scanline3, x2, x1, span2, span1); 431a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span3 = scanline3.Begin(); 432a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x1, y2, span3->spanLength); 433a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x1, y2, (uint32_t)span3->spanLength, 434a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), 435a3e0fd82Sopenharmony_ci span3->covers); 436a3e0fd82Sopenharmony_ci } else if ((x1 >= x2) && (x1 < x2 + span2->spanLength) && 437a3e0fd82Sopenharmony_ci (x1 + span1->spanLength >= x2 + span2->spanLength)) { 438a3e0fd82Sopenharmony_ci GeometryScanline scanline3; 439a3e0fd82Sopenharmony_ci CalcOutScanlineRight(scanline3, x1, x2, span1, span2); 440a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span3 = scanline3.Begin(); 441a3e0fd82Sopenharmony_ci spanGen2.Generate(alloc.GetSpanPtr(), x2, y2, span3->spanLength); 442a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x2, y2, (uint32_t)span3->spanLength, 443a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), 444a3e0fd82Sopenharmony_ci span3->covers); 445a3e0fd82Sopenharmony_ci GeometryScanline scanline4; 446a3e0fd82Sopenharmony_ci CalcOutScanlineLeft(scanline4, x1, x2, span1, span2); 447a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span4 = scanline4.Begin(); 448a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x1, y2, span4->spanLength); 449a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x1, y2, (uint32_t)span4->spanLength, 450a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), 451a3e0fd82Sopenharmony_ci span4->covers); 452a3e0fd82Sopenharmony_ci } else if ((x1 <= x2) && (x1 + span1->spanLength >= x2) && 453a3e0fd82Sopenharmony_ci (x1 + span1->spanLength <= x2 + span2->spanLength)) { 454a3e0fd82Sopenharmony_ci GeometryScanline scanline3; 455a3e0fd82Sopenharmony_ci CalcOutScanlineRight(scanline3, x2, x1, span2, span1); 456a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span3 = scanline3.Begin(); 457a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x1, y2, span3->spanLength); 458a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x1, y2, (uint32_t)span3->spanLength, 459a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), span3->covers); 460a3e0fd82Sopenharmony_ci GeometryScanline scanline4; 461a3e0fd82Sopenharmony_ci CalcOutScanlineLeft(scanline4, x2, x1, span2, span1); 462a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span4 = scanline4.Begin(); 463a3e0fd82Sopenharmony_ci spanGen2.Generate(alloc.GetSpanPtr(), x2, y2, span4->spanLength); 464a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x2, y2, (uint32_t)span4->spanLength, 465a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), span4->covers); 466a3e0fd82Sopenharmony_ci } else if ((x1 + span1->spanLength < x2)|| (x2+span2->spanLength < x1)) { 467a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x1, y2, span1->spanLength); 468a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x1, y2, (uint32_t)span1->spanLength, 469a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), span1->covers); 470a3e0fd82Sopenharmony_ci spanGen2.Generate(alloc.GetSpanPtr(), x2, y2, span2->spanLength); 471a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x2, y2, (uint32_t)span2->spanLength, 472a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), span2->covers); 473a3e0fd82Sopenharmony_ci } 474a3e0fd82Sopenharmony_ci } 475a3e0fd82Sopenharmony_ci } 476a3e0fd82Sopenharmony_ci ++span1; 477a3e0fd82Sopenharmony_ci } 478a3e0fd82Sopenharmony_ci } else if (span2->spanLength > 0) { 479a3e0fd82Sopenharmony_ci spanGen2.Generate(alloc.GetSpanPtr(), x2, y2, span2->spanLength); 480a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x2, y2, (uint32_t)span2->spanLength, alloc.GetSpanPtr(), span2->covers); 481a3e0fd82Sopenharmony_ci } 482a3e0fd82Sopenharmony_ci if (--numSpans2 == 0) { 483a3e0fd82Sopenharmony_ci break; 484a3e0fd82Sopenharmony_ci } 485a3e0fd82Sopenharmony_ci ++span2; 486a3e0fd82Sopenharmony_ci } 487a3e0fd82Sopenharmony_ci if (y1 == y2 && y1 < raster2.GetMaxY() - 1) { 488a3e0fd82Sopenharmony_ci if (raster1.SweepScanline(scanline1)) { 489a3e0fd82Sopenharmony_ci y1 = scanline1.GetYLevel(); 490a3e0fd82Sopenharmony_ci } 491a3e0fd82Sopenharmony_ci } 492a3e0fd82Sopenharmony_ci } 493a3e0fd82Sopenharmony_ci // Draw the rest of raster1 494a3e0fd82Sopenharmony_ci BlendXORDrawResetRaster(raster1, scanline1, renBase, alloc, spanGen1); 495a3e0fd82Sopenharmony_ci} 496a3e0fd82Sopenharmony_ci 497a3e0fd82Sopenharmony_civoid BlendXORDrawResetRaster(RasterizerScanlineAntialias& raster1, GeometryScanline& scanline1, 498a3e0fd82Sopenharmony_ci RenderBase& renBase, FillBase& alloc, SpanBase& spanGen1) 499a3e0fd82Sopenharmony_ci 500a3e0fd82Sopenharmony_ci{ 501a3e0fd82Sopenharmony_ci while (raster1.SweepScanline(scanline1)) { 502a3e0fd82Sopenharmony_ci int32_t y = scanline1.GetYLevel(); 503a3e0fd82Sopenharmony_ci uint32_t numSpans = scanline1.NumSpans(); 504a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span = scanline1.Begin(); 505a3e0fd82Sopenharmony_ci while (true) { 506a3e0fd82Sopenharmony_ci int32_t x = span->x; 507a3e0fd82Sopenharmony_ci if (span->spanLength > 0) { 508a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x, y, span->spanLength); 509a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x, y, (uint32_t)span->spanLength, alloc.GetSpanPtr(), span->covers); 510a3e0fd82Sopenharmony_ci } 511a3e0fd82Sopenharmony_ci if (--numSpans == 0) { 512a3e0fd82Sopenharmony_ci break; 513a3e0fd82Sopenharmony_ci } 514a3e0fd82Sopenharmony_ci ++span; 515a3e0fd82Sopenharmony_ci } 516a3e0fd82Sopenharmony_ci } 517a3e0fd82Sopenharmony_ci} 518a3e0fd82Sopenharmony_ci 519a3e0fd82Sopenharmony_civoid BlendXORColorHspan(int32_t& y1, RasterizerScanlineAntialias& raster1, RasterizerScanlineAntialias& raster2, 520a3e0fd82Sopenharmony_ci GeometryScanline& scanline1, RenderBase& renBase, FillBase& alloc, SpanBase& spanGen1) 521a3e0fd82Sopenharmony_ci{ 522a3e0fd82Sopenharmony_ci if (raster1.GetMinY() > raster2.GetMinY()) { 523a3e0fd82Sopenharmony_ci return; 524a3e0fd82Sopenharmony_ci } 525a3e0fd82Sopenharmony_ci do { 526a3e0fd82Sopenharmony_ci y1 = scanline1.GetYLevel(); 527a3e0fd82Sopenharmony_ci if (y1 == raster2.GetMinY()) { 528a3e0fd82Sopenharmony_ci break; 529a3e0fd82Sopenharmony_ci } 530a3e0fd82Sopenharmony_ci uint32_t numSpans = scanline1.NumSpans(); 531a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span = scanline1.Begin(); 532a3e0fd82Sopenharmony_ci while (true) { 533a3e0fd82Sopenharmony_ci int32_t x = span->x; 534a3e0fd82Sopenharmony_ci if (span->spanLength > 0) { 535a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x, y1, span->spanLength); 536a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x, y1, (uint32_t)span->spanLength, 537a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), span->covers); 538a3e0fd82Sopenharmony_ci } 539a3e0fd82Sopenharmony_ci if (--numSpans == 0) { 540a3e0fd82Sopenharmony_ci break; 541a3e0fd82Sopenharmony_ci } 542a3e0fd82Sopenharmony_ci ++span; 543a3e0fd82Sopenharmony_ci } 544a3e0fd82Sopenharmony_ci } while (raster1.SweepScanline(scanline1)); 545a3e0fd82Sopenharmony_ci} 546a3e0fd82Sopenharmony_ci 547a3e0fd82Sopenharmony_civoid BlendLIGHTER(RasterizerScanlineAntialias& raster1, RasterizerScanlineAntialias& raster2, 548a3e0fd82Sopenharmony_ci GeometryScanline& scanline1, GeometryScanline& scanline2, 549a3e0fd82Sopenharmony_ci RenderBase& renBase, FillBase& alloc, SpanBase& spanGen1, SpanBase& spanGen2) 550a3e0fd82Sopenharmony_ci{ 551a3e0fd82Sopenharmony_ci BlendXOR(raster1, raster2, scanline1, scanline2, renBase, alloc, spanGen1, spanGen2); 552a3e0fd82Sopenharmony_ci SpanBlendColor spanBlendColor(spanGen1, spanGen2); 553a3e0fd82Sopenharmony_ci BlendSourceIn(raster1, raster2, scanline1, scanline2, renBase, alloc, spanBlendColor); 554a3e0fd82Sopenharmony_ci} 555a3e0fd82Sopenharmony_ci 556a3e0fd82Sopenharmony_civoid BlendSourceInLoop(RasterizerScanlineAntialias& raster1, GeometryScanline& scanline1, GeometryScanline& scanline2, 557a3e0fd82Sopenharmony_ci SpanBase& spanGen1, RenderBase& renBase, FillBase& alloc, int32_t& y1) 558a3e0fd82Sopenharmony_ci{ 559a3e0fd82Sopenharmony_ci int32_t y2 = scanline2.GetYLevel(); 560a3e0fd82Sopenharmony_ci uint32_t numSpans2 = scanline2.NumSpans(); 561a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span2 = scanline2.Begin(); 562a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span1 = scanline1.Begin(); 563a3e0fd82Sopenharmony_ci 564a3e0fd82Sopenharmony_ci if (y2 > y1) { 565a3e0fd82Sopenharmony_ci while (raster1.SweepScanline(scanline1)) { 566a3e0fd82Sopenharmony_ci y1 = scanline1.GetYLevel(); 567a3e0fd82Sopenharmony_ci if (y1 == y2) { 568a3e0fd82Sopenharmony_ci span1 = scanline1.Begin(); 569a3e0fd82Sopenharmony_ci break; 570a3e0fd82Sopenharmony_ci } 571a3e0fd82Sopenharmony_ci } 572a3e0fd82Sopenharmony_ci } 573a3e0fd82Sopenharmony_ci while (true) { 574a3e0fd82Sopenharmony_ci int32_t x2 = span2->x; 575a3e0fd82Sopenharmony_ci if (y1 == y2) { 576a3e0fd82Sopenharmony_ci int32_t x1 = span1->x; 577a3e0fd82Sopenharmony_ci if (span2->spanLength > 0) { 578a3e0fd82Sopenharmony_ci if (span1->spanLength > 0) { 579a3e0fd82Sopenharmony_ci if (x1<=x2 && x2+span2->spanLength < x1+span1->spanLength) { 580a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x2, y2, span2->spanLength); 581a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x2, y2, (uint32_t)span2->spanLength, 582a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), span2->covers); 583a3e0fd82Sopenharmony_ci } else if ((x1 >= x2) && (x1 + span1->spanLength <= x2+span2->spanLength)) { 584a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x1, y2, span1->spanLength); 585a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x1, y2, (uint32_t)span1->spanLength, 586a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), span1->covers); 587a3e0fd82Sopenharmony_ci } else if ((x1 > x2) && (x1 < x2 + span2->spanLength) && 588a3e0fd82Sopenharmony_ci (x1 + span1->spanLength >= x2 + span2->spanLength)) { 589a3e0fd82Sopenharmony_ci GeometryScanline scanline3; 590a3e0fd82Sopenharmony_ci CalcinterScanline(scanline3, x1, x2, span1, span2); 591a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span3 = scanline3.Begin(); 592a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x1, y2, span3->spanLength); 593a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x1, y2, (uint32_t)span3->spanLength, 594a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), span3->covers); 595a3e0fd82Sopenharmony_ci } else if ((x1 < x2) && (x1 + span1->spanLength > x2) && 596a3e0fd82Sopenharmony_ci (x1 + span1->spanLength <= x2 + span2->spanLength)) { 597a3e0fd82Sopenharmony_ci GeometryScanline scanline3; 598a3e0fd82Sopenharmony_ci CalcinterScanline(scanline3, x2, x1, span2, span1); 599a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span3 = scanline3.Begin(); 600a3e0fd82Sopenharmony_ci spanGen1.Generate(alloc.GetSpanPtr(), x2, y2, span3->spanLength); 601a3e0fd82Sopenharmony_ci renBase.BlendColorHSpan(x2, y2, (uint32_t)span3->spanLength, 602a3e0fd82Sopenharmony_ci alloc.GetSpanPtr(), span3->covers); 603a3e0fd82Sopenharmony_ci } 604a3e0fd82Sopenharmony_ci } 605a3e0fd82Sopenharmony_ci } 606a3e0fd82Sopenharmony_ci ++span1; 607a3e0fd82Sopenharmony_ci } 608a3e0fd82Sopenharmony_ci if (--numSpans2 == 0) { 609a3e0fd82Sopenharmony_ci break; 610a3e0fd82Sopenharmony_ci } 611a3e0fd82Sopenharmony_ci ++span2; 612a3e0fd82Sopenharmony_ci } 613a3e0fd82Sopenharmony_ci if (y1 == y2) { 614a3e0fd82Sopenharmony_ci raster1.SweepScanline(scanline1); 615a3e0fd82Sopenharmony_ci y1 = scanline1.GetYLevel(); 616a3e0fd82Sopenharmony_ci } 617a3e0fd82Sopenharmony_ci} 618a3e0fd82Sopenharmony_ci 619a3e0fd82Sopenharmony_civoid BlendSourceOver(RasterizerScanlineAntialias& raster1, RasterizerScanlineAntialias& raster2, 620a3e0fd82Sopenharmony_ci GeometryScanline& scanline1, GeometryScanline& scanline2, 621a3e0fd82Sopenharmony_ci RenderBase& renBase, FillBase& alloc, SpanBase& spanGen1, SpanBase& spanGen2) 622a3e0fd82Sopenharmony_ci{ 623a3e0fd82Sopenharmony_ci RenderScanlinesAntiAlias(raster1, scanline1, renBase, alloc, spanGen1); 624a3e0fd82Sopenharmony_ci RenderScanlinesAntiAlias(raster2, scanline2, renBase, alloc, spanGen2); 625a3e0fd82Sopenharmony_ci} 626a3e0fd82Sopenharmony_ci 627a3e0fd82Sopenharmony_civoid CalcinterScanline(GeometryScanline& scanline3, int32_t x1, int32_t x2, 628a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span1, GeometryScanline::ConstIterator span2) 629a3e0fd82Sopenharmony_ci{ 630a3e0fd82Sopenharmony_ci scanline3.Reset(x1, x2 + span2->spanLength); 631a3e0fd82Sopenharmony_ci uint32_t len3 = x2 + span2->spanLength - x1; 632a3e0fd82Sopenharmony_ci uint8_t* cover1 = span1->covers; 633a3e0fd82Sopenharmony_ci uint8_t* cover2 = span2->covers + (x1 - x2); 634a3e0fd82Sopenharmony_ci int32_t x3 = x1; 635a3e0fd82Sopenharmony_ci for (uint32_t i = 0; i < len3; i++, cover1++, cover2++) { 636a3e0fd82Sopenharmony_ci if (*(cover1) != COVER_FULL) { 637a3e0fd82Sopenharmony_ci scanline3.AddCell(x3++, *cover1); 638a3e0fd82Sopenharmony_ci } else { 639a3e0fd82Sopenharmony_ci scanline3.AddCell(x3++, *cover2); 640a3e0fd82Sopenharmony_ci } 641a3e0fd82Sopenharmony_ci } 642a3e0fd82Sopenharmony_ci} 643a3e0fd82Sopenharmony_ci 644a3e0fd82Sopenharmony_civoid CalcOutScanlineRight(GeometryScanline& scanline, int32_t x1, int32_t x2, 645a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span1, GeometryScanline::ConstIterator span2) 646a3e0fd82Sopenharmony_ci{ 647a3e0fd82Sopenharmony_ci uint8_t* cover1 = span1->covers; 648a3e0fd82Sopenharmony_ci uint8_t* cover2 = span2->covers; 649a3e0fd82Sopenharmony_ci scanline.Reset(x2, x2 + span2->spanLength); 650a3e0fd82Sopenharmony_ci for (int32_t i = 1; i <= span2->spanLength; i++, cover2++) { 651a3e0fd82Sopenharmony_ci if (x1 == x2) { 652a3e0fd82Sopenharmony_ci scanline.AddCell(x2++, COVER_FULL - (*cover1)); 653a3e0fd82Sopenharmony_ci x1++; 654a3e0fd82Sopenharmony_ci cover1++; 655a3e0fd82Sopenharmony_ci } else { 656a3e0fd82Sopenharmony_ci scanline.AddCell(x2++, *cover2); 657a3e0fd82Sopenharmony_ci } 658a3e0fd82Sopenharmony_ci } 659a3e0fd82Sopenharmony_ci} 660a3e0fd82Sopenharmony_ci 661a3e0fd82Sopenharmony_civoid CalcOutScanlineLeft(GeometryScanline& scanline, int32_t x1, int32_t x2, 662a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span1, GeometryScanline::ConstIterator span2) 663a3e0fd82Sopenharmony_ci{ 664a3e0fd82Sopenharmony_ci uint8_t* cover2 = span2->covers + (x1 - x2); 665a3e0fd82Sopenharmony_ci scanline.Reset(x1, x1 + span1->spanLength); 666a3e0fd82Sopenharmony_ci int32_t len1 = span2->spanLength - (x1 - x2); // Length of intersection 667a3e0fd82Sopenharmony_ci int32_t len2 = span1->spanLength - len1; // Length of intersection 668a3e0fd82Sopenharmony_ci uint8_t* cover1 = span1->covers + len1; 669a3e0fd82Sopenharmony_ci for (int32_t i = 0; i < len1; i++, cover2++) { 670a3e0fd82Sopenharmony_ci scanline.AddCell(x1++, COVER_FULL - (*cover2)); 671a3e0fd82Sopenharmony_ci } 672a3e0fd82Sopenharmony_ci 673a3e0fd82Sopenharmony_ci for (int32_t i = 0; i < len2; i++, cover1++) { 674a3e0fd82Sopenharmony_ci scanline.AddCell(x1++, *cover1); 675a3e0fd82Sopenharmony_ci } 676a3e0fd82Sopenharmony_ci} 677a3e0fd82Sopenharmony_ci 678a3e0fd82Sopenharmony_civoid CalcOutScanlineAll(GeometryScanline& scanline, int32_t x1, int32_t x2, 679a3e0fd82Sopenharmony_ci GeometryScanline::ConstIterator span1, GeometryScanline::ConstIterator span2) 680a3e0fd82Sopenharmony_ci{ 681a3e0fd82Sopenharmony_ci uint8_t* cover1 = span1->covers; 682a3e0fd82Sopenharmony_ci uint8_t* cover2 = span2->covers; 683a3e0fd82Sopenharmony_ci int32_t x3 = x1; 684a3e0fd82Sopenharmony_ci scanline.Reset(x2, x2 + span2->spanLength); 685a3e0fd82Sopenharmony_ci for (int32_t i = 0; i < span2->spanLength; i++, cover2++) { 686a3e0fd82Sopenharmony_ci if (x3 == x2 && x3 <= x1 + span1->spanLength - 1) { 687a3e0fd82Sopenharmony_ci scanline.AddCell(x2++, COVER_FULL - (*cover1)); 688a3e0fd82Sopenharmony_ci x3++; 689a3e0fd82Sopenharmony_ci cover1++; 690a3e0fd82Sopenharmony_ci } else { 691a3e0fd82Sopenharmony_ci scanline.AddCell(x2++, *cover2); 692a3e0fd82Sopenharmony_ci } 693a3e0fd82Sopenharmony_ci } 694a3e0fd82Sopenharmony_ci} 695a3e0fd82Sopenharmony_ci} // namespace OHOS 696