|
@@ -197,7 +197,6 @@
|
|
/* Internal Class Implementation */
|
|
/* Internal Class Implementation */
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
|
|
|
|
-constexpr auto MAX_SPANS = 256;
|
|
|
|
constexpr auto PIXEL_BITS = 8; //must be at least 6 bits!
|
|
constexpr auto PIXEL_BITS = 8; //must be at least 6 bits!
|
|
constexpr auto ONE_PIXEL = (1L << PIXEL_BITS);
|
|
constexpr auto ONE_PIXEL = (1L << PIXEL_BITS);
|
|
|
|
|
|
@@ -240,10 +239,6 @@ struct RleWorker
|
|
|
|
|
|
SwOutline* outline;
|
|
SwOutline* outline;
|
|
|
|
|
|
- SwSpan spans[MAX_SPANS];
|
|
|
|
- int spansCnt;
|
|
|
|
- int ySpan;
|
|
|
|
-
|
|
|
|
int bandSize;
|
|
int bandSize;
|
|
int bandShoot;
|
|
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)));
|
|
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)
|
|
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 > 255) coverage = 255;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (coverage == 0) return;
|
|
|
|
+
|
|
//span has ushort coordinates. check limit overflow
|
|
//span has ushort coordinates. check limit overflow
|
|
if (x >= SHRT_MAX) {
|
|
if (x >= SHRT_MAX) {
|
|
- TVGERR("SW_ENGINE", "X-coordiante overflow!");
|
|
|
|
- x = SHRT_MAX;
|
|
|
|
|
|
+ TVGERR("SW_ENGINE", "X-coordinate overflow!");
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
if (y >= SHRT_MAX) {
|
|
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
|
|
//Clip x range
|
|
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);
|
|
@@ -372,35 +348,35 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor
|
|
span->len += (acount + xOver);
|
|
span->len += (acount + xOver);
|
|
return;
|
|
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;
|
|
if (rw.cellsCnt == 0) return;
|
|
|
|
|
|
- rw.spansCnt = 0;
|
|
|
|
- rw.ySpan = 0;
|
|
|
|
-
|
|
|
|
for (int y = 0; y < rw.yCnt; ++y) {
|
|
for (int y = 0; y < rw.yCnt; ++y) {
|
|
auto cover = 0;
|
|
auto cover = 0;
|
|
auto x = 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 (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.cellMax = renderRegion.max;
|
|
rw.cellXCnt = rw.cellMax.x - rw.cellMin.x;
|
|
rw.cellXCnt = rw.cellMax.x - rw.cellMin.x;
|
|
rw.cellYCnt = rw.cellMax.y - rw.cellMin.y;
|
|
rw.cellYCnt = rw.cellMax.y - rw.cellMin.y;
|
|
- rw.ySpan = 0;
|
|
|
|
rw.outline = const_cast<SwOutline*>(outline);
|
|
rw.outline = const_cast<SwOutline*>(outline);
|
|
rw.bandSize = rw.bufferSize / (sizeof(Cell) * 2); //bandSize: 256
|
|
rw.bandSize = rw.bufferSize / (sizeof(Cell) * 2); //bandSize: 256
|
|
rw.bandShoot = 0;
|
|
rw.bandShoot = 0;
|
|
@@ -1019,7 +989,6 @@ SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& ren
|
|
|
|
|
|
error:
|
|
error:
|
|
free(rw.rle);
|
|
free(rw.rle);
|
|
- rw.rle = nullptr;
|
|
|
|
return nullptr;
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
|