summaryrefslogtreecommitdiffstats
path: root/thirdparty/thorvg/src/renderer/sw_engine
diff options
context:
space:
mode:
authorMartin Capitanio <capnm@capitanio.org>2024-07-12 12:12:13 +0200
committerMartin Capitanio <capnm@capitanio.org>2024-07-12 12:37:42 +0200
commitbf444545be6ea9f4303757a643296a1a0dbbb2c8 (patch)
tree2a1bb17525ad74ca1aaaecca571f50081780d017 /thirdparty/thorvg/src/renderer/sw_engine
parent97b8ad1af0f2b4a216f6f1263bef4fbc69e56c7b (diff)
downloadredot-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')
-rw-r--r--thirdparty/thorvg/src/renderer/sw_engine/tvgSwImage.cpp4
-rw-r--r--thirdparty/thorvg/src/renderer/sw_engine/tvgSwMath.cpp14
-rw-r--r--thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp5
-rw-r--r--thirdparty/thorvg/src/renderer/sw_engine/tvgSwRle.cpp103
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;
}