mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 05:33:36 +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 mathSin(SwFixed angle);
|
||||
void mathSplitCubic(SwPoint* base);
|
||||
void mathSplitLine(SwPoint* base);
|
||||
SwFixed mathDiff(SwFixed angle1, SwFixed angle2);
|
||||
SwFixed mathLength(const SwPoint& pt);
|
||||
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)
|
||||
{
|
||||
auto delta = angle2 - angle1;
|
||||
|
|
|
@ -235,6 +235,7 @@ struct RleWorker
|
|||
SwPoint pos;
|
||||
|
||||
SwPoint bezStack[32 * 3 + 1];
|
||||
SwPoint lineStack[32 + 1];
|
||||
int levStack[32];
|
||||
|
||||
SwOutline* outline;
|
||||
|
@ -513,8 +514,23 @@ static void _lineTo(RleWorker& rw, const SwPoint& to)
|
|||
return;
|
||||
}
|
||||
|
||||
auto diff = to - rw.pos;
|
||||
auto f1 = rw.pos - SUBPIXELS(e1);
|
||||
auto line = rw.lineStack;
|
||||
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;
|
||||
|
||||
//inside one cell
|
||||
|
@ -558,12 +574,7 @@ static void _lineTo(RleWorker& rw, const SwPoint& to)
|
|||
/* The fundamental value `prod' determines which side and the */
|
||||
/* exact coordinate where the line exits current cell. It is */
|
||||
/* also easily updated when moving from one cell to the next. */
|
||||
size_t idx = 0;
|
||||
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 py = diff.y * ONE_PIXEL;
|
||||
|
||||
|
@ -606,10 +617,13 @@ static void _lineTo(RleWorker& rw, const SwPoint& to)
|
|||
} 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.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