diff options
author | Martin Capitanio <capnm@capitanio.org> | 2024-07-12 12:12:13 +0200 |
---|---|---|
committer | Martin Capitanio <capnm@capitanio.org> | 2024-07-12 12:37:42 +0200 |
commit | bf444545be6ea9f4303757a643296a1a0dbbb2c8 (patch) | |
tree | 2a1bb17525ad74ca1aaaecca571f50081780d017 /thirdparty/thorvg/src/renderer/sw_engine | |
parent | 97b8ad1af0f2b4a216f6f1263bef4fbc69e56c7b (diff) | |
download | redot-engine-bf444545be6ea9f4303757a643296a1a0dbbb2c8.tar.gz |
ThorVG: Update to 0.14.2
+ Fixes SVG: Graphical objects stored in <defs> shouldn't be rendered directly.
Diffstat (limited to 'thirdparty/thorvg/src/renderer/sw_engine')
4 files changed, 48 insertions, 78 deletions
diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwImage.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwImage.cpp index c162945501..e1d41a0d52 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwImage.cpp +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwImage.cpp @@ -114,8 +114,8 @@ bool imagePrepare(SwImage* image, const RenderMesh* mesh, const Matrix* transfor //Fast track: Non-transformed image but just shifted. if (image->direct) { - image->ox = -static_cast<int32_t>(round(transform->e13)); - image->oy = -static_cast<int32_t>(round(transform->e23)); + image->ox = -static_cast<int32_t>(nearbyint(transform->e13)); + image->oy = -static_cast<int32_t>(nearbyint(transform->e23)); //Figure out the scale factor by transform matrix } else { auto scaleX = sqrtf((transform->e11 * transform->e11) + (transform->e21 * transform->e21)); diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwMath.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwMath.cpp index ad5a2b7371..ae158c836a 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwMath.cpp +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwMath.cpp @@ -164,8 +164,8 @@ void mathRotate(SwPoint& pt, SwFixed angle) auto cosv = cosf(radian); auto sinv = sinf(radian); - pt.x = SwCoord(roundf((v.x * cosv - v.y * sinv) * 64.0f)); - pt.y = SwCoord(roundf((v.x * sinv + v.y * cosv) * 64.0f)); + pt.x = SwCoord(nearbyint((v.x * cosv - v.y * sinv) * 64.0f)); + pt.y = SwCoord(nearbyint((v.x * sinv + v.y * cosv) * 64.0f)); } @@ -179,7 +179,7 @@ SwFixed mathTan(SwFixed angle) SwFixed mathAtan(const SwPoint& pt) { if (pt.zero()) return 0; - return SwFixed(atan2f(TO_FLOAT(pt.y), TO_FLOAT(pt.x)) * (180.0f / MATH_PI) * 65536.0f); + return SwFixed(mathAtan2(TO_FLOAT(pt.y), TO_FLOAT(pt.x)) * (180.0f / MATH_PI) * 65536.0f); } @@ -309,10 +309,10 @@ bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, S //the rasterization region has to be rearranged. //https://github.com/Samsung/thorvg/issues/916 if (fastTrack) { - renderRegion.min.x = static_cast<SwCoord>(round(xMin / 64.0f)); - renderRegion.max.x = static_cast<SwCoord>(round(xMax / 64.0f)); - renderRegion.min.y = static_cast<SwCoord>(round(yMin / 64.0f)); - renderRegion.max.y = static_cast<SwCoord>(round(yMax / 64.0f)); + renderRegion.min.x = static_cast<SwCoord>(nearbyint(xMin / 64.0f)); + renderRegion.max.x = static_cast<SwCoord>(nearbyint(xMax / 64.0f)); + renderRegion.min.y = static_cast<SwCoord>(nearbyint(yMin / 64.0f)); + renderRegion.max.y = static_cast<SwCoord>(nearbyint(yMax / 64.0f)); } else { renderRegion.min.x = xMin >> 6; renderRegion.max.x = (xMax + 63) >> 6; diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp index b3507acdc3..042d1e2b44 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp @@ -383,7 +383,8 @@ static bool _rasterMattedRect(SwSurface* surface, const SwBBox& region, uint8_t auto dst = &buffer[y * surface->stride]; auto cmp = &cbuffer[y * surface->compositor->image.stride * csize]; for (uint32_t x = 0; x < w; ++x, ++dst, cmp += csize) { - *dst = INTERPOLATE(color, *dst, alpha(cmp)); + auto tmp = ALPHA_BLEND(color, alpha(cmp)); + *dst = tmp + ALPHA_BLEND(*dst, IA(tmp)); } } //8bits grayscale @@ -674,7 +675,7 @@ static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g, auto sy = (y) * itransform->e22 + itransform->e23 - 0.49f; \ if (sy <= -0.5f || (uint32_t)(sy + 0.5f) >= image->h) continue; \ if (scaleMethod == _interpDownScaler) { \ - auto my = (int32_t)round(sy); \ + auto my = (int32_t)nearbyint(sy); \ miny = my - (int32_t)sampleSize; \ if (miny < 0) miny = 0; \ maxy = my + (int32_t)sampleSize; \ diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRle.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRle.cpp index 1e5c4ef409..25c6cd90b9 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRle.cpp +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRle.cpp @@ -197,7 +197,6 @@ /* Internal Class Implementation */ /************************************************************************/ -constexpr auto MAX_SPANS = 256; constexpr auto PIXEL_BITS = 8; //must be at least 6 bits! constexpr auto ONE_PIXEL = (1L << PIXEL_BITS); @@ -240,10 +239,6 @@ struct RleWorker SwOutline* outline; - SwSpan spans[MAX_SPANS]; - int spansCnt; - int ySpan; - int bandSize; int bandShoot; @@ -301,26 +296,6 @@ static inline SwCoord HYPOT(SwPoint pt) return ((pt.x > pt.y) ? (pt.x + (3 * pt.y >> 3)) : (pt.y + (3 * pt.x >> 3))); } -static void _genSpan(SwRleData* rle, const SwSpan* spans, uint32_t count) -{ - auto newSize = rle->size + count; - - /* allocate enough memory for new spans */ - /* alloc is required to prevent free and reallocation */ - /* when the rle needs to be regenerated because of attribute change. */ - if (rle->alloc < newSize) { - rle->alloc = (newSize * 2); - //OPTIMIZE: use mempool! - rle->spans = static_cast<SwSpan*>(realloc(rle->spans, rle->alloc * sizeof(SwSpan))); - } - - //copy the new spans to the allocated memory - SwSpan* lastSpan = rle->spans + rle->size; - memcpy(lastSpan, spans, count * sizeof(SwSpan)); - - rle->size = newSize; -} - static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoord acount) { @@ -344,25 +319,26 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor if (coverage > 255) coverage = 255; } + if (coverage == 0) return; + //span has ushort coordinates. check limit overflow if (x >= SHRT_MAX) { - TVGERR("SW_ENGINE", "X-coordiante overflow!"); - x = SHRT_MAX; + TVGERR("SW_ENGINE", "X-coordinate overflow!"); + return; } if (y >= SHRT_MAX) { - TVGERR("SW_ENGINE", "Y Coordiante overflow!"); - y = SHRT_MAX; + TVGERR("SW_ENGINE", "Y-coordinate overflow!"); + return; } - if (coverage > 0) { - if (!rw.antiAlias) coverage = 255; - auto count = rw.spansCnt; - auto span = rw.spans + count - 1; + auto rle = rw.rle; - //see whether we can add this span to the current list - if ((count > 0) && (rw.ySpan == y) && - (span->x + span->len == x) && (span->coverage == coverage)) { + if (!rw.antiAlias) coverage = 255; + //see whether we can add this span to the current list + if (rle->size > 0) { + auto span = rle->spans + rle->size - 1; + if ((span->coverage == coverage) && (span->y == y) && (span->x + span->len == x)) { //Clip x range SwCoord xOver = 0; if (x + acount >= rw.cellMax.x) xOver -= (x + acount - rw.cellMax.x); @@ -372,35 +348,35 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor span->len += (acount + xOver); return; } + } - if (count >= MAX_SPANS) { - _genSpan(rw.rle, rw.spans, count); - rw.spansCnt = 0; - rw.ySpan = 0; - span = rw.spans; - } else { - ++span; + //span pool is full, grow it. + if (rle->size >= rle->alloc) { + auto newSize = (rle->size > 0) ? (rle->size * 2) : 256; + if (rle->alloc < newSize) { + rle->alloc = newSize; + rle->spans = static_cast<SwSpan*>(realloc(rle->spans, rle->alloc * sizeof(SwSpan))); } + } - //Clip x range - SwCoord xOver = 0; - if (x + acount >= rw.cellMax.x) xOver -= (x + acount - rw.cellMax.x); - if (x < rw.cellMin.x) { - xOver -= (rw.cellMin.x - x); - x = rw.cellMin.x; - } + //Clip x range + SwCoord xOver = 0; + if (x + acount >= rw.cellMax.x) xOver -= (x + acount - rw.cellMax.x); + if (x < rw.cellMin.x) { + xOver -= (rw.cellMin.x - x); + x = rw.cellMin.x; + } - //Nothing to draw - if (acount + xOver <= 0) return; + //Nothing to draw + if (acount + xOver <= 0) return; - //add a span to the current list - span->x = x; - span->y = y; - span->len = (acount + xOver); - span->coverage = coverage; - ++rw.spansCnt; - rw.ySpan = y; - } + //add a span to the current list + auto span = rle->spans + rle->size; + span->x = x; + span->y = y; + span->len = (acount + xOver); + span->coverage = coverage; + rle->size++; } @@ -408,9 +384,6 @@ static void _sweep(RleWorker& rw) { if (rw.cellsCnt == 0) return; - rw.spansCnt = 0; - rw.ySpan = 0; - for (int y = 0; y < rw.yCnt; ++y) { auto cover = 0; auto x = 0; @@ -427,8 +400,6 @@ static void _sweep(RleWorker& rw) if (cover != 0) _horizLine(rw, x, y, cover * (ONE_PIXEL * 2), rw.cellXCnt - x); } - - if (rw.spansCnt > 0) _genSpan(rw.rle, rw.spans, rw.spansCnt); } @@ -926,7 +897,6 @@ SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& ren rw.cellMax = renderRegion.max; rw.cellXCnt = rw.cellMax.x - rw.cellMin.x; rw.cellYCnt = rw.cellMax.y - rw.cellMin.y; - rw.ySpan = 0; rw.outline = const_cast<SwOutline*>(outline); rw.bandSize = rw.bufferSize / (sizeof(Cell) * 2); //bandSize: 256 rw.bandShoot = 0; @@ -1019,7 +989,6 @@ SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& ren error: free(rw.rle); - rw.rle = nullptr; return nullptr; } |