sw_engine: minor refactoring

simpler logic to computes.
This commit is contained in:
Hermet Park 2025-03-11 14:16:27 +09:00
parent 852ca2a523
commit 6f9fd6ff01
2 changed files with 29 additions and 35 deletions

View file

@ -309,16 +309,10 @@ bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, S
if (yMax < pt->y) yMax = pt->y; if (yMax < pt->y) yMax = pt->y;
} }
if (fastTrack) {
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.min.x = xMin >> 6;
renderRegion.max.x = (xMax + 63) >> 6; renderRegion.max.x = (xMax + 63) >> 6;
renderRegion.min.y = yMin >> 6; renderRegion.min.y = yMin >> 6;
renderRegion.max.y = (yMax + 63) >> 6; renderRegion.max.y = (yMax + 63) >> 6;
}
return mathClipBBox(clipRegion, renderRegion); return mathClipBBox(clipRegion, renderRegion);
} }

View file

@ -258,21 +258,22 @@ static inline SwPoint UPSCALE(const SwPoint& pt)
} }
static inline SwPoint TRUNC(const SwPoint& pt)
{
return {pt.x >> PIXEL_BITS, pt.y >> PIXEL_BITS};
}
static inline SwCoord TRUNC(const SwCoord x) static inline SwCoord TRUNC(const SwCoord x)
{ {
return x >> PIXEL_BITS; return x >> PIXEL_BITS;
} }
static inline SwPoint SUBPIXELS(const SwPoint& pt) static inline SwPoint TRUNC(const SwPoint& pt)
{ {
return {SwCoord(((unsigned long) pt.x) << PIXEL_BITS), SwCoord(((unsigned long) pt.y) << PIXEL_BITS)}; return {TRUNC(pt.x), TRUNC(pt.y)};
}
static inline SwPoint FRACT(const SwPoint& pt)
{
return {pt.x & (ONE_PIXEL - 1), pt.y & (ONE_PIXEL - 1)};
} }
@ -330,7 +331,6 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor
SwCoord xOver = 0; SwCoord xOver = 0;
if (x + aCount >= rw.cellMax.x) xOver -= (x + aCount - rw.cellMax.x); if (x + aCount >= rw.cellMax.x) xOver -= (x + aCount - rw.cellMax.x);
if (x < rw.cellMin.x) xOver -= (rw.cellMin.x - x); if (x < rw.cellMin.x) xOver -= (rw.cellMin.x - x);
span->len += (aCount + xOver); span->len += (aCount + xOver);
return; return;
} }
@ -397,7 +397,7 @@ static Cell* _findCell(RleWorker& rw)
auto pcell = &rw.yCells[rw.cellPos.y]; auto pcell = &rw.yCells[rw.cellPos.y];
while(true) { while(true) {
Cell* cell = *pcell; auto cell = *pcell;
if (!cell || cell->x > x) break; if (!cell || cell->x > x) break;
if (cell->x == x) return cell; if (cell->x == x) return cell;
pcell = &cell->next; pcell = &cell->next;
@ -492,7 +492,6 @@ static bool _moveTo(RleWorker& rw, const SwPoint& to)
static bool _lineTo(RleWorker& rw, const SwPoint& to) static bool _lineTo(RleWorker& rw, const SwPoint& to)
{ {
#define SW_UDIV(a, b) (SwCoord)(((unsigned long)(a) * (unsigned long)(b)) >> (sizeof(long) * CHAR_BIT - PIXEL_BITS))
auto e1 = TRUNC(rw.pos); auto e1 = TRUNC(rw.pos);
auto e2 = TRUNC(to); auto e2 = TRUNC(to);
@ -518,7 +517,7 @@ static bool _lineTo(RleWorker& rw, const SwPoint& to)
e1 = TRUNC(line[1]); e1 = TRUNC(line[1]);
e2 = TRUNC(line[0]); e2 = TRUNC(line[0]);
auto f1 = line[1] - SUBPIXELS(e1); auto f1 = FRACT(line[1]);
SwPoint f2; SwPoint f2;
//inside one cell //inside one cell
@ -552,23 +551,25 @@ static bool _lineTo(RleWorker& rw, const SwPoint& to)
} }
//any other line //any other line
} else { } else {
#define SW_UDIV(a, b) (SwCoord)((uint64_t(a) * uint64_t(b)) >> 32)
Area prod = diff.x * f1.y - diff.y * f1.x; Area prod = diff.x * f1.y - diff.y * f1.x;
/* These macros speed up repetitive divisions by replacing them /* These macros speed up repetitive divisions by replacing them
with multiplications and right shifts. */ with multiplications and right shifts. */
auto dx_r = static_cast<long>(ULONG_MAX >> PIXEL_BITS) / (diff.x); auto dxr = (e1.x != e2.x) ? (int64_t)0xffffffff / diff.x : 0;
auto dy_r = static_cast<long>(ULONG_MAX >> PIXEL_BITS) / (diff.y); auto dyr = (e1.y != e2.y) ? (int64_t)0xffffffff / diff.y : 0;
auto px = diff.x * ONE_PIXEL;
auto py = diff.y * ONE_PIXEL;
/* 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. */
do {
auto px = diff.x * ONE_PIXEL;
auto py = diff.y * ONE_PIXEL;
do {
//left //left
if (prod <= 0 && prod - px > 0) { if (prod <= 0 && prod - px > 0) {
f2 = {0, SW_UDIV(-prod, -dx_r)}; f2 = {0, SW_UDIV(-prod, -dxr)};
prod -= py; prod -= py;
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);
@ -577,7 +578,7 @@ static bool _lineTo(RleWorker& rw, const SwPoint& to)
//up //up
} else if (prod - px <= 0 && prod - px + py > 0) { } else if (prod - px <= 0 && prod - px + py > 0) {
prod -= px; prod -= px;
f2 = {SW_UDIV(-prod, dy_r), ONE_PIXEL}; f2 = {SW_UDIV(-prod, dyr), ONE_PIXEL};
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);
f1 = {f2.x, 0}; f1 = {f2.x, 0};
@ -585,14 +586,14 @@ static bool _lineTo(RleWorker& rw, const SwPoint& to)
//right //right
} else if (prod - px + py <= 0 && prod + py >= 0) { } else if (prod - px + py <= 0 && prod + py >= 0) {
prod += py; prod += py;
f2 = {ONE_PIXEL, SW_UDIV(prod, dx_r)}; f2 = {ONE_PIXEL, SW_UDIV(prod, dxr)};
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);
f1 = {0, f2.y}; f1 = {0, f2.y};
++e1.x; ++e1.x;
//down //down
} else { } else {
f2 = {SW_UDIV(prod, -dy_r), 0}; f2 = {SW_UDIV(prod, -dyr), 0};
prod += px; prod += px;
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);
@ -605,7 +606,7 @@ static bool _lineTo(RleWorker& rw, const SwPoint& to)
} while(e1 != e2); } while(e1 != e2);
} }
f2 = line[0] - SUBPIXELS(e2); f2 = FRACT(line[0]);
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 = line[0]; rw.pos = line[0];
@ -713,8 +714,7 @@ static bool _decomposeOutline(RleWorker& rw)
types += 3; types += 3;
if (pt <= limit) { if (pt <= limit) {
if (!_cubicTo(rw, UPSCALE(pt[-2]), UPSCALE(pt[-1]), UPSCALE(pt[0]))) return false; if (!_cubicTo(rw, UPSCALE(pt[-2]), UPSCALE(pt[-1]), UPSCALE(pt[0]))) return false;
} } else if (pt - 1 == limit) {
else if (pt - 1 == limit) {
if (!_cubicTo(rw, UPSCALE(pt[-2]), UPSCALE(pt[-1]), start)) return false; if (!_cubicTo(rw, UPSCALE(pt[-2]), UPSCALE(pt[-1]), start)) return false;
} }
else goto close; else goto close;