1 /* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 /** 17 * @file geometry_scanline.h 18 * 19 * @brief When converting information from rasterizer to scanline renderer, 20 * The scanline container is used. A scanline consists of many horizontal, disjoint spans. 21 * These spans are sorted by the x-axis 22 * This means that sorting is not provided and must be handled when span is added to scanline 23 * @since 1.0 24 * @version 1.0 25 */ 26 27 #ifndef GRAPHIC_LITE_GEOMETRY_SCANLINE_H 28 #define GRAPHIC_LITE_GEOMETRY_SCANLINE_H 29 30 #include "gfx_utils/diagram/vertexprimitive/geometry_plaindata_array.h" 31 #include "gfx_utils/graphic_log.h" 32 #include "gfx_utils/vector.h" 33 namespace OHOS { 34 /** 35 * @class ScanlineUnPackedContainer 36 * @brief 16 bit unpacked scan line container class - packed scan line container, 37 * Containers can contain de aliasing information Unpacked scanline always 38 * saves overlay values for all pixels(coverage value), 39 * Include those pixels that all cover the interior of the polygon 40 * @since 1.0 41 * @version 1.0 42 */ 43 class GeometryScanline { 44 public: 45 /** 46 * Pixel coverage type 47 */ 48 struct SpanBlock { 49 int16_t x; 50 int16_t spanLength; 51 uint8_t* covers; 52 }; 53 using Iterator = SpanBlock* ; 54 using ConstIterator = const SpanBlock* ; GeometryScanline()55 GeometryScanline() : minScaneLineXCoord_(0), lastScaneLineXCoord_(0x7FFFFFF0), 56 scaneLineYCoord_(0), curSpanBlock_(0) {} 57 /** 58 * @class ScanlineUnPackedContainer 59 * @brief 16 bit unpacked scan line container class - packed scan line container, 60 * Containers can contain de aliasing information Packed scanline and unpacked scanline 61 * The difference between scanline and unpacked scanline is that 62 * unpacked scanline always saves coverage values for all pixels, 63 * Include those pixels that are all covered inside the polygon. 64 * Packed scanlines will merge pixels with the same coverage value into solid span 65 * @since 1.0 66 * @version 1.0 67 */ Reset(int32_t minX,int32_t maxX)68 void Reset(int32_t minX, int32_t maxX) 69 { 70 const int32_t liftNumber = 2; 71 uint32_t maxLen = maxX - minX + liftNumber; 72 if (maxLen > arraySpans_.GetSize()) { 73 arraySpans_.Resize(maxLen); 74 arrayCovers_.Resize(maxLen); 75 } 76 lastScaneLineXCoord_ = 0x7FFFFFF0; 77 minScaneLineXCoord_ = minX; 78 curSpanBlock_ = arraySpans_.Data(); 79 } 80 81 /** 82 * According to the position of X and the cover color, the coverage is the area of the extended call 83 * or add a cell 84 */ AddCell(int32_t x,uint32_t cover)85 void AddCell(int32_t x, uint32_t cover) 86 { 87 x -= minScaneLineXCoord_; 88 arrayCovers_[x] = (uint8_t)cover; 89 if (x == lastScaneLineXCoord_ + 1) { 90 curSpanBlock_->spanLength++; 91 } else { 92 curSpanBlock_++; 93 curSpanBlock_->x = static_cast<int16_t>(x + minScaneLineXCoord_); 94 curSpanBlock_->spanLength = 1; 95 curSpanBlock_->covers = &arrayCovers_[x]; 96 } 97 lastScaneLineXCoord_ = x; 98 } 99 100 /** 101 * According to the position of X, the span length of len and 102 * the cover color coverage are the areas where the call is extended 103 * or add a cell 104 */ AddCells(int32_t x,uint32_t cellLength,const uint8_t * covers)105 void AddCells(int32_t x, uint32_t cellLength, const uint8_t* covers) 106 { 107 x -= minScaneLineXCoord_; 108 if (memcpy_s(&arrayCovers_[x], cellLength * sizeof(uint8_t), covers, cellLength * sizeof(uint8_t)) != EOK) { 109 GRAPHIC_LOGE("AddCells fail"); 110 return; 111 } 112 if (x == lastScaneLineXCoord_ + 1) { 113 curSpanBlock_->spanLength += static_cast<int16_t>(cellLength); 114 } else { 115 curSpanBlock_++; 116 curSpanBlock_->x = static_cast<int16_t>(x + minScaneLineXCoord_); 117 curSpanBlock_->spanLength = static_cast<int16_t>(cellLength); 118 curSpanBlock_->covers = &arrayCovers_[x]; 119 } 120 lastScaneLineXCoord_ = x + cellLength - 1; 121 } 122 123 /** 124 * According to the position of X, the span length of len and 125 * the cover color coverage are the areas where the call is extended 126 * Or add a span cell array. 127 * Note here that pixels with the same coverage value will be merged into solid span. 128 */ AddSpan(int32_t x,uint32_t spanLength,uint32_t cover)129 void AddSpan(int32_t x, uint32_t spanLength, uint32_t cover) 130 { 131 x -= minScaneLineXCoord_; 132 if (memset_s(&arrayCovers_[x], spanLength, cover, spanLength) != EOK) { 133 GRAPHIC_LOGE("AddSpan fail"); 134 return; 135 } 136 if (x == lastScaneLineXCoord_ + 1) { 137 curSpanBlock_->spanLength += static_cast<int16_t>(spanLength); 138 } else { 139 curSpanBlock_++; 140 curSpanBlock_->x = static_cast<int16_t>(x + minScaneLineXCoord_); 141 curSpanBlock_->spanLength = static_cast<int16_t>(spanLength); 142 curSpanBlock_->covers = &arrayCovers_[x]; 143 } 144 lastScaneLineXCoord_ = x + spanLength - 1; 145 } 146 147 /** 148 * End operation 149 */ Finalize(int32_t y)150 void Finalize(int32_t y) 151 { 152 scaneLineYCoord_ = y; 153 } ResetSpans()154 void ResetSpans() 155 { 156 lastScaneLineXCoord_ = 0x7FFFFFF0; 157 curSpanBlock_ = &arraySpans_[0]; 158 } 159 GetYLevel()160 int32_t GetYLevel() const 161 { 162 return scaneLineYCoord_; 163 } NumSpans()164 uint32_t NumSpans() const 165 { 166 return uint32_t(curSpanBlock_ - &arraySpans_[0]); 167 } Begin()168 ConstIterator Begin() const 169 { 170 return &arraySpans_[1]; 171 } Begin()172 Iterator Begin() 173 { 174 return &arraySpans_[1]; 175 } 176 177 private: 178 GeometryScanline(const GeometryScanline&); 179 const GeometryScanline& operator=(const GeometryScanline&); 180 181 private: 182 int32_t minScaneLineXCoord_; 183 int32_t lastScaneLineXCoord_; 184 int32_t scaneLineYCoord_; 185 GeometryPlainDataArray<uint8_t> arrayCovers_; 186 GeometryPlainDataArray<SpanBlock> arraySpans_; 187 SpanBlock* curSpanBlock_; 188 }; 189 } // namespace OHOS 190 #endif 191