mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
sw_engine: split long lines to avoid overflow
@Issue: https://github.com/thorvg/thorvg/issues/2651
This commit is contained in:
parent
43cdd4c7ec
commit
cb2a15528d
3 changed files with 114 additions and 90 deletions
|
@ -488,6 +488,7 @@ SwFixed mathAtan(const SwPoint& pt);
|
||||||
SwFixed mathCos(SwFixed angle);
|
SwFixed mathCos(SwFixed angle);
|
||||||
SwFixed mathSin(SwFixed angle);
|
SwFixed mathSin(SwFixed angle);
|
||||||
void mathSplitCubic(SwPoint* base);
|
void mathSplitCubic(SwPoint* base);
|
||||||
|
void mathSplitLine(SwPoint* base);
|
||||||
SwFixed mathDiff(SwFixed angle1, SwFixed angle2);
|
SwFixed mathDiff(SwFixed angle1, SwFixed angle2);
|
||||||
SwFixed mathLength(const SwPoint& pt);
|
SwFixed mathLength(const SwPoint& pt);
|
||||||
int mathCubicAngle(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
|
int mathCubicAngle(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
|
||||||
|
|
|
@ -242,6 +242,15 @@ void mathSplitCubic(SwPoint* base)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mathSplitLine(SwPoint* base)
|
||||||
|
{
|
||||||
|
base[2] = base[1];
|
||||||
|
|
||||||
|
base[1].x = (base[0].x + base[1].x) >> 1;
|
||||||
|
base[1].y = (base[0].y + base[1].y) >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SwFixed mathDiff(SwFixed angle1, SwFixed angle2)
|
SwFixed mathDiff(SwFixed angle1, SwFixed angle2)
|
||||||
{
|
{
|
||||||
auto delta = angle2 - angle1;
|
auto delta = angle2 - angle1;
|
||||||
|
|
|
@ -235,6 +235,7 @@ struct RleWorker
|
||||||
SwPoint pos;
|
SwPoint pos;
|
||||||
|
|
||||||
SwPoint bezStack[32 * 3 + 1];
|
SwPoint bezStack[32 * 3 + 1];
|
||||||
|
SwPoint lineStack[32 + 1];
|
||||||
int levStack[32];
|
int levStack[32];
|
||||||
|
|
||||||
SwOutline* outline;
|
SwOutline* outline;
|
||||||
|
@ -513,8 +514,23 @@ static void _lineTo(RleWorker& rw, const SwPoint& to)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto diff = to - rw.pos;
|
auto line = rw.lineStack;
|
||||||
auto f1 = rw.pos - SUBPIXELS(e1);
|
line[0] = to;
|
||||||
|
line[1] = rw.pos;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
auto diff = line[0] - line[1];
|
||||||
|
auto L = HYPOT(diff);
|
||||||
|
|
||||||
|
if (L > SHRT_MAX) {
|
||||||
|
mathSplitLine(line);
|
||||||
|
++line;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
e1 = TRUNC(line[1]);
|
||||||
|
e2 = TRUNC(line[0]);
|
||||||
|
|
||||||
|
auto f1 = line[1] - SUBPIXELS(e1);
|
||||||
SwPoint f2;
|
SwPoint f2;
|
||||||
|
|
||||||
//inside one cell
|
//inside one cell
|
||||||
|
@ -558,12 +574,7 @@ static void _lineTo(RleWorker& rw, const SwPoint& to)
|
||||||
/* The fundamental value `prod' determines which side and the */
|
/* The fundamental value `prod' determines which side and the */
|
||||||
/* exact coordinate where the line exits current cell. It is */
|
/* exact coordinate where the line exits current cell. It is */
|
||||||
/* also easily updated when moving from one cell to the next. */
|
/* also easily updated when moving from one cell to the next. */
|
||||||
size_t idx = 0;
|
|
||||||
do {
|
do {
|
||||||
if (++idx > 1000000000) {
|
|
||||||
TVGERR("SW_ENGINE", "Iteration limit reached during RLE generation. The resulting render may be incorrect.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
auto px = diff.x * ONE_PIXEL;
|
auto px = diff.x * ONE_PIXEL;
|
||||||
auto py = diff.y * ONE_PIXEL;
|
auto py = diff.y * ONE_PIXEL;
|
||||||
|
|
||||||
|
@ -606,10 +617,13 @@ static void _lineTo(RleWorker& rw, const SwPoint& to)
|
||||||
} while(e1 != e2);
|
} while(e1 != e2);
|
||||||
}
|
}
|
||||||
|
|
||||||
f2 = {to.x - SUBPIXELS(e2.x), to.y - SUBPIXELS(e2.y)};
|
f2 = {line[0].x - SUBPIXELS(e2.x), line[0].y - SUBPIXELS(e2.y)};
|
||||||
rw.cover += (f2.y - f1.y);
|
rw.cover += (f2.y - f1.y);
|
||||||
rw.area += (f2.y - f1.y) * (f1.x + f2.x);
|
rw.area += (f2.y - f1.y) * (f1.x + f2.x);
|
||||||
rw.pos = to;
|
rw.pos = line[0];
|
||||||
|
|
||||||
|
if (line-- == rw.lineStack) return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue