{
SwCoord x, y;
- SwPoint& operator+=(const SwPoint& rhs) {
+ SwPoint& operator+=(const SwPoint& rhs)
+ {
x += rhs.x;
y += rhs.y;
return *this;
}
- SwPoint operator+(const SwPoint& rhs) const {
+ SwPoint operator+(const SwPoint& rhs) const
+ {
return {x + rhs.x, y + rhs.y};
}
- SwPoint operator-(const SwPoint& rhs) const {
+ SwPoint operator-(const SwPoint& rhs) const
+ {
return {x - rhs.x, y - rhs.y};
}
- bool operator==(const SwPoint& rhs ) const {
+ bool operator==(const SwPoint& rhs ) const
+ {
return (x == rhs.x && y == rhs.y);
}
- bool operator!=(const SwPoint& rhs) const {
+ bool operator!=(const SwPoint& rhs) const
+ {
return (x != rhs.x || y != rhs.y);
}
struct SwBBox
{
SwPoint min, max;
+
+ void reset()
+ {
+ min.x = min.y = max.x = max.y = 0;
+ }
};
struct SwFill
bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
SwFixed mathMean(SwFixed angle1, SwFixed angle2);
SwPoint mathTransform(const Point* to, const Matrix* transform);
+bool mathUpdateOutlineBBox(const SwOutline* outline, SwBBox& bbox, const SwSize& clip);
void shapeReset(SwShape* shape);
bool shapeGenOutline(SwShape* shape, const Shape* sdata, unsigned tid, const Matrix* transform);
bool shapePrepare(SwShape* shape, const Shape* sdata, unsigned tid, const SwSize& clip, const Matrix* transform, SwBBox& bbox);
bool shapePrepared(const SwShape* shape);
-bool shapeGenRle(SwShape* shape, const Shape* sdata, const SwSize& clip, bool antiAlias, bool hasComposite);
+bool shapeGenRle(SwShape* shape, const Shape* sdata, bool antiAlias, bool hasComposite);
void shapeDelOutline(SwShape* shape, uint32_t tid);
void shapeResetStroke(SwShape* shape, const Shape* sdata, const Matrix* transform);
bool shapeGenStrokeRle(SwShape* shape, const Shape* sdata, unsigned tid, const Matrix* transform, const SwSize& clip, SwBBox& bbox);
bool imagePrepare(SwImage* image, const Picture* pdata, unsigned tid, const SwSize& clip, const Matrix* transform, SwBBox& bbox);
bool imagePrepared(const SwImage* image);
-bool imageGenRle(SwImage* image, TVG_UNUSED const Picture* pdata, const SwSize& clip, const SwBBox& bbox, bool antiAlias, bool hasComposite);
+bool imageGenRle(SwImage* image, TVG_UNUSED const Picture* pdata, const SwBBox& bbox, bool antiAlias, bool hasComposite);
void imageDelOutline(SwImage* image, uint32_t tid);
void imageReset(SwImage* image);
bool imageGenOutline(SwImage* image, const Picture* pdata, unsigned tid, const Matrix* transform);
void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t offset, uint32_t len);
void fillFetchRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len);
-SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& bbox, const SwSize& clip, bool antiAlias);
+SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& bbox, bool antiAlias);
void rleFree(SwRleData* rle);
void rleReset(SwRleData* rle);
void rleClipPath(SwRleData *rle, const SwRleData *clip);
/************************************************************************/
-static void _initBBox(SwBBox& bbox)
-{
- bbox.min.x = bbox.min.y = 0;
- bbox.max.x = bbox.max.y = 0;
-}
-
-
-static bool _updateBBox(const SwOutline* outline, SwBBox& bbox, const SwSize& clip)
-{
- if (!outline) return false;
-
- auto pt = outline->pts;
-
- if (outline->ptsCnt <= 0) {
- _initBBox(bbox);
- return false;
- }
-
- auto xMin = pt->x;
- auto xMax = pt->x;
- auto yMin = pt->y;
- auto yMax = pt->y;
-
- ++pt;
-
- for(uint32_t i = 1; i < outline->ptsCnt; ++i, ++pt) {
- if (xMin > pt->x) xMin = pt->x;
- if (xMax < pt->x) xMax = pt->x;
- if (yMin > pt->y) yMin = pt->y;
- if (yMax < pt->y) yMax = pt->y;
- }
- bbox.min.x = xMin >> 6;
- bbox.max.x = (xMax + 63) >> 6;
- bbox.min.y = yMin >> 6;
- bbox.max.y = (yMax + 63) >> 6;
-
- bbox.min.x = max(bbox.min.x, TO_SWCOORD(0));
- bbox.min.y = max(bbox.min.y, TO_SWCOORD(0));
- bbox.max.x = min(bbox.max.x, clip.w);
- bbox.max.y = min(bbox.max.y, clip.h);
-
- if (xMax - xMin < 1 && yMax - yMin < 1) return false;
-
- return true;
-}
-
-
-static bool _checkValid(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip)
-{
- if (outline->ptsCnt == 0 || outline->cntrsCnt <= 0) return false;
-
- //Check boundary
- if (bbox.min.x >= clip.w || bbox.min.y >= clip.h || bbox.max.x <= 0 || bbox.max.y <= 0) return false;
-
- return true;
-}
-
/************************************************************************/
/* External Class Implementation */
bool imagePrepare(SwImage* image, const Picture* pdata, unsigned tid, const SwSize& clip, const Matrix* transform, SwBBox& bbox)
{
if (!imageGenOutline(image, pdata, tid, transform)) return false;
+ if (!mathUpdateOutlineBBox(image->outline, bbox, clip)) return false;
- if (!_updateBBox(image->outline, bbox, clip)) return false;
-
- if (!_checkValid(image->outline, bbox, clip)) return false;
+ //Guarantee boundary from mathUpdateOutlineBBox()
+ bbox.min.x = max(bbox.min.x, TO_SWCOORD(0));
+ bbox.min.y = max(bbox.min.y, TO_SWCOORD(0));
return true;
}
}
-bool imageGenRle(SwImage* image, TVG_UNUSED const Picture* pdata, const SwSize& clip, const SwBBox& bbox, bool antiAlias, TVG_UNUSED bool hasComposite)
+bool imageGenRle(SwImage* image, TVG_UNUSED const Picture* pdata, const SwBBox& bbox, bool antiAlias, TVG_UNUSED bool hasComposite)
{
- if ((image->rle = rleRender(image->rle, image->outline, bbox, clip, antiAlias))) return true;
+ if ((image->rle = rleRender(image->rle, image->outline, bbox, antiAlias))) return true;
return false;
}
return {TO_SWCOORD(tx), TO_SWCOORD(ty)};
}
+
+
+bool mathUpdateOutlineBBox(const SwOutline* outline, SwBBox& bbox, const SwSize& clip)
+{
+ if (!outline) return false;
+
+ auto pt = outline->pts;
+
+ if (outline->ptsCnt == 0 || outline->cntrsCnt <= 0) {
+ bbox.reset();
+ return false;
+ }
+
+ auto xMin = pt->x;
+ auto xMax = pt->x;
+ auto yMin = pt->y;
+ auto yMax = pt->y;
+
+ ++pt;
+
+ for(uint32_t i = 1; i < outline->ptsCnt; ++i, ++pt) {
+ if (xMin > pt->x) xMin = pt->x;
+ if (xMax < pt->x) xMax = pt->x;
+ if (yMin > pt->y) yMin = pt->y;
+ if (yMax < pt->y) yMax = pt->y;
+ }
+ bbox.min.x = xMin >> 6;
+ bbox.max.x = (xMax + 63) >> 6;
+ bbox.min.y = yMin >> 6;
+ bbox.max.y = (yMax + 63) >> 6;
+
+ //Guarantee surface boundary
+ bbox.max.x = min(bbox.max.x, clip.w);
+ bbox.max.y = min(bbox.max.y, clip.h);
+
+ //Check valid region
+ if (bbox.max.x - bbox.min.x < 1 && bbox.max.y - bbox.min.y < 1) return false;
+
+ //Check boundary
+ if (bbox.min.x >= clip.w || bbox.min.y >= clip.h || bbox.max.x <= 0 || bbox.max.y <= 0) return false;
+
+ return true;
+}
\ No newline at end of file
shape outline below stroke could be full covered by stroke drawing.
Thus it turns off antialising in that condition. */
auto antiAlias = (strokeAlpha == 255 && strokeWidth > 2) ? false : true;
- if (!shapeGenRle(&shape, sdata, clip, antiAlias, clips.count > 0 ? true : false)) goto err;
+ if (!shapeGenRle(&shape, sdata, antiAlias, clips.count > 0 ? true : false)) goto err;
++addStroking;
}
}
//Clip Path?
if (clips.count > 0) {
- if (!imageGenRle(&image, pdata, clip, bbox, false, true)) goto end;
+ if (!imageGenRle(&image, pdata, bbox, false, true)) goto end;
if (image.rle) {
for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) {
auto clipper = &static_cast<SwShapeTask*>(*clip)->shape;
Cell** yCells;
SwCoord yCnt;
- SwSize clip;
-
bool invalid;
bool antiAlias;
};
y += rw.cellMin.y;
//Clip Y range
- if (y < 0) return;
- if (y >= rw.clip.h) return;
+ if (y < 0 || y >= rw.cellMax.y) return;
/* compute the coverage line's coverage, depending on the outline fill rule */
/* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */
//Clip x range
SwCoord xOver = 0;
- if (x + acount >= rw.clip.w) xOver -= (x + acount - rw.clip.w);
+ if (x + acount >= rw.cellMax.x) xOver -= (x + acount - rw.cellMax.x);
if (x < 0) xOver += x;
//span->len += (acount + xOver) - 1;
//Clip x range
SwCoord xOver = 0;
- if (x + acount >= rw.clip.w) xOver -= (x + acount - rw.clip.w);
+ if (x + acount >= rw.cellMax.x) xOver -= (x + acount - rw.cellMax.x);
if (x < 0) {
xOver += x;
x = 0;
/* External Class Implementation */
/************************************************************************/
-SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& bbox, const SwSize& clip, bool antiAlias)
+SwRleData* rleRender(SwRleData* rle, const SwOutline* outline, const SwBBox& bbox, bool antiAlias)
{
constexpr auto RENDER_POOL_SIZE = 16384L;
constexpr auto BAND_SIZE = 40;
rw.outline = const_cast<SwOutline*>(outline);
rw.bandSize = rw.bufferSize / (sizeof(Cell) * 8); //bandSize: 64
rw.bandShoot = 0;
- rw.clip = clip;
rw.antiAlias = antiAlias;
if (!rle) rw.rle = reinterpret_cast<SwRleData*>(calloc(1, sizeof(SwRleData)));
}
-static void _initBBox(SwBBox& bbox)
-{
- bbox.min.x = bbox.min.y = 0;
- bbox.max.x = bbox.max.y = 0;
-}
-
-
-static bool _updateBBox(const SwOutline* outline, SwBBox& bbox)
-{
- if (!outline) return false;
-
- auto pt = outline->pts;
-
- if (outline->ptsCnt <= 0) {
- _initBBox(bbox);
- return false;
- }
-
- auto xMin = pt->x;
- auto xMax = pt->x;
- auto yMin = pt->y;
- auto yMax = pt->y;
-
- ++pt;
-
- for(uint32_t i = 1; i < outline->ptsCnt; ++i, ++pt) {
- if (xMin > pt->x) xMin = pt->x;
- if (xMax < pt->x) xMax = pt->x;
- if (yMin > pt->y) yMin = pt->y;
- if (yMax < pt->y) yMax = pt->y;
- }
- bbox.min.x = xMin >> 6;
- bbox.max.x = (xMax + 63) >> 6;
- bbox.min.y = yMin >> 6;
- bbox.max.y = (yMax + 63) >> 6;
-
- if (xMax - xMin < 1 && yMax - yMin < 1) return false;
-
- return true;
-}
-
-
-static bool _checkValid(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip)
-{
- if (outline->ptsCnt == 0 || outline->cntrsCnt <= 0) return false;
-
- //Check boundary
- if (bbox.min.x >= clip.w || bbox.min.y >= clip.h || bbox.max.x <= 0 || bbox.max.y <= 0) return false;
-
- return true;
-}
-
-
static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* transform)
{
_growOutlinePoint(*dash.outline, dash.outline->ptsCnt >> 1);
bool shapePrepare(SwShape* shape, const Shape* sdata, unsigned tid, const SwSize& clip, const Matrix* transform, SwBBox& bbox)
{
if (!shapeGenOutline(shape, sdata, tid, transform)) return false;
-
- if (!_updateBBox(shape->outline, shape->bbox)) return false;
-
- if (!_checkValid(shape->outline, shape->bbox, clip)) return false;
+ if (!mathUpdateOutlineBBox(shape->outline, shape->bbox, clip)) return false;
bbox = shape->bbox;
}
-bool shapeGenRle(SwShape* shape, TVG_UNUSED const Shape* sdata, const SwSize& clip, bool antiAlias, bool hasComposite)
+bool shapeGenRle(SwShape* shape, TVG_UNUSED const Shape* sdata, bool antiAlias, bool hasComposite)
{
//FIXME: Should we draw it?
//Case: Stroke Line
//Case A: Fast Track Rectangle Drawing
if (!hasComposite && (shape->rect = _fastTrack(shape->outline))) return true;
//Case B: Normale Shape RLE Drawing
- if ((shape->rle = rleRender(shape->rle, shape->outline, shape->bbox, clip, antiAlias))) return true;
+ if ((shape->rle = rleRender(shape->rle, shape->outline, shape->bbox, antiAlias))) return true;
return false;
}
rleReset(shape->rle);
rleReset(shape->strokeRle);
shape->rect = false;
- _initBBox(shape->bbox);
+ shape->bbox.reset();
}
goto fail;
}
- _updateBBox(strokeOutline, bbox);
-
- if (!_checkValid(strokeOutline, bbox, clip)) {
+ if (!mathUpdateOutlineBBox(strokeOutline, bbox, clip)) {
ret = false;
goto fail;
}
- shape->strokeRle = rleRender(shape->strokeRle, strokeOutline, bbox, clip, true);
+ shape->strokeRle = rleRender(shape->strokeRle, strokeOutline, bbox, true);
fail:
if (freeOutline) {
if (!shape->stroke->fill) return;
fillFree(shape->stroke->fill);
shape->stroke->fill = nullptr;
-}
-
+}
\ No newline at end of file