mirror of
https://github.com/thorvg/thorvg.git
synced 2025-07-28 09:05:52 +00:00
common shape: memory optimization
All shapes will have path data, avoid unnecesary dynamic memory allocation internally. @Issues: 75
This commit is contained in:
parent
8d03f131a3
commit
c6013536ec
2 changed files with 49 additions and 51 deletions
|
@ -61,9 +61,9 @@ uint32_t Shape::pathCommands(const PathCommand** cmds) const noexcept
|
||||||
{
|
{
|
||||||
if (!cmds) return 0;
|
if (!cmds) return 0;
|
||||||
|
|
||||||
*cmds = pImpl->path->cmds;
|
*cmds = pImpl->path.cmds;
|
||||||
|
|
||||||
return pImpl->path->cmdCnt;
|
return pImpl->path.cmdCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,9 +71,9 @@ uint32_t Shape::pathCoords(const Point** pts) const noexcept
|
||||||
{
|
{
|
||||||
if (!pts) return 0;
|
if (!pts) return 0;
|
||||||
|
|
||||||
*pts = pImpl->path->pts;
|
*pts = pImpl->path.pts;
|
||||||
|
|
||||||
return pImpl->path->ptsCnt;
|
return pImpl->path.ptsCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,8 +81,8 @@ Result Shape::appendPath(const PathCommand *cmds, uint32_t cmdCnt, const Point*
|
||||||
{
|
{
|
||||||
if (cmdCnt == 0 || ptsCnt == 0 || !pts || !ptsCnt) return Result::InvalidArguments;
|
if (cmdCnt == 0 || ptsCnt == 0 || !pts || !ptsCnt) return Result::InvalidArguments;
|
||||||
|
|
||||||
pImpl->path->grow(cmdCnt, ptsCnt);
|
pImpl->path.grow(cmdCnt, ptsCnt);
|
||||||
pImpl->path->append(cmds, cmdCnt, pts, ptsCnt);
|
pImpl->path.append(cmds, cmdCnt, pts, ptsCnt);
|
||||||
|
|
||||||
pImpl->flag |= RenderUpdateFlag::Path;
|
pImpl->flag |= RenderUpdateFlag::Path;
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ Result Shape::appendPath(const PathCommand *cmds, uint32_t cmdCnt, const Point*
|
||||||
|
|
||||||
Result Shape::moveTo(float x, float y) noexcept
|
Result Shape::moveTo(float x, float y) noexcept
|
||||||
{
|
{
|
||||||
pImpl->path->moveTo(x, y);
|
pImpl->path.moveTo(x, y);
|
||||||
|
|
||||||
pImpl->flag |= RenderUpdateFlag::Path;
|
pImpl->flag |= RenderUpdateFlag::Path;
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ Result Shape::moveTo(float x, float y) noexcept
|
||||||
|
|
||||||
Result Shape::lineTo(float x, float y) noexcept
|
Result Shape::lineTo(float x, float y) noexcept
|
||||||
{
|
{
|
||||||
pImpl->path->lineTo(x, y);
|
pImpl->path.lineTo(x, y);
|
||||||
|
|
||||||
pImpl->flag |= RenderUpdateFlag::Path;
|
pImpl->flag |= RenderUpdateFlag::Path;
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ Result Shape::lineTo(float x, float y) noexcept
|
||||||
|
|
||||||
Result Shape::cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y) noexcept
|
Result Shape::cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y) noexcept
|
||||||
{
|
{
|
||||||
pImpl->path->cubicTo(cx1, cy1, cx2, cy2, x, y);
|
pImpl->path.cubicTo(cx1, cy1, cx2, cy2, x, y);
|
||||||
|
|
||||||
pImpl->flag |= RenderUpdateFlag::Path;
|
pImpl->flag |= RenderUpdateFlag::Path;
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ Result Shape::cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float
|
||||||
|
|
||||||
Result Shape::close() noexcept
|
Result Shape::close() noexcept
|
||||||
{
|
{
|
||||||
pImpl->path->close();
|
pImpl->path.close();
|
||||||
|
|
||||||
pImpl->flag |= RenderUpdateFlag::Path;
|
pImpl->flag |= RenderUpdateFlag::Path;
|
||||||
|
|
||||||
|
@ -135,13 +135,13 @@ Result Shape::appendCircle(float cx, float cy, float rx, float ry) noexcept
|
||||||
auto rxKappa = rx * PATH_KAPPA;
|
auto rxKappa = rx * PATH_KAPPA;
|
||||||
auto ryKappa = ry * PATH_KAPPA;
|
auto ryKappa = ry * PATH_KAPPA;
|
||||||
|
|
||||||
pImpl->path->grow(6, 13);
|
pImpl->path.grow(6, 13);
|
||||||
pImpl->path->moveTo(cx, cy - ry);
|
pImpl->path.moveTo(cx, cy - ry);
|
||||||
pImpl->path->cubicTo(cx + rxKappa, cy - ry, cx + rx, cy - ryKappa, cx + rx, cy);
|
pImpl->path.cubicTo(cx + rxKappa, cy - ry, cx + rx, cy - ryKappa, cx + rx, cy);
|
||||||
pImpl->path->cubicTo(cx + rx, cy + ryKappa, cx + rxKappa, cy + ry, cx, cy + ry);
|
pImpl->path.cubicTo(cx + rx, cy + ryKappa, cx + rxKappa, cy + ry, cx, cy + ry);
|
||||||
pImpl->path->cubicTo(cx - rxKappa, cy + ry, cx - rx, cy + ryKappa, cx - rx, cy);
|
pImpl->path.cubicTo(cx - rxKappa, cy + ry, cx - rx, cy + ryKappa, cx - rx, cy);
|
||||||
pImpl->path->cubicTo(cx - rx, cy - ryKappa, cx - rxKappa, cy - ry, cx, cy - ry);
|
pImpl->path.cubicTo(cx - rx, cy - ryKappa, cx - rxKappa, cy - ry, cx, cy - ry);
|
||||||
pImpl->path->close();
|
pImpl->path.close();
|
||||||
|
|
||||||
pImpl->flag |= RenderUpdateFlag::Path;
|
pImpl->flag |= RenderUpdateFlag::Path;
|
||||||
|
|
||||||
|
@ -166,10 +166,10 @@ Result Shape::appendArc(float cx, float cy, float radius, float startAngle, floa
|
||||||
Point start = {radius * cos(startAngle), radius * sin(startAngle)};
|
Point start = {radius * cos(startAngle), radius * sin(startAngle)};
|
||||||
|
|
||||||
if (pie) {
|
if (pie) {
|
||||||
pImpl->path->moveTo(cx, cy);
|
pImpl->path.moveTo(cx, cy);
|
||||||
pImpl->path->lineTo(start.x + cx, start.y + cy);
|
pImpl->path.lineTo(start.x + cx, start.y + cy);
|
||||||
} else {
|
} else {
|
||||||
pImpl->path->moveTo(start.x + cx, start.y + cy);
|
pImpl->path.moveTo(start.x + cx, start.y + cy);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < nCurves; ++i) {
|
for (int i = 0; i < nCurves; ++i) {
|
||||||
|
@ -197,12 +197,12 @@ Result Shape::appendArc(float cx, float cy, float radius, float startAngle, floa
|
||||||
Point ctrl1 = {ax - k2 * ay + cx, ay + k2 * ax + cy};
|
Point ctrl1 = {ax - k2 * ay + cx, ay + k2 * ax + cy};
|
||||||
Point ctrl2 = {bx + k2 * by + cx, by - k2 * bx + cy};
|
Point ctrl2 = {bx + k2 * by + cx, by - k2 * bx + cy};
|
||||||
|
|
||||||
pImpl->path->cubicTo(ctrl1.x, ctrl1.y, ctrl2.x, ctrl2.y, end.x, end.y);
|
pImpl->path.cubicTo(ctrl1.x, ctrl1.y, ctrl2.x, ctrl2.y, end.x, end.y);
|
||||||
|
|
||||||
startAngle = endAngle;
|
startAngle = endAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pie) pImpl->path->close();
|
if (pie) pImpl->path.close();
|
||||||
|
|
||||||
pImpl->flag |= RenderUpdateFlag::Path;
|
pImpl->flag |= RenderUpdateFlag::Path;
|
||||||
|
|
||||||
|
@ -221,29 +221,29 @@ Result Shape::appendRect(float x, float y, float w, float h, float rx, float ry)
|
||||||
|
|
||||||
//rectangle
|
//rectangle
|
||||||
if (rx == 0 && ry == 0) {
|
if (rx == 0 && ry == 0) {
|
||||||
pImpl->path->grow(5, 4);
|
pImpl->path.grow(5, 4);
|
||||||
pImpl->path->moveTo(x, y);
|
pImpl->path.moveTo(x, y);
|
||||||
pImpl->path->lineTo(x + w, y);
|
pImpl->path.lineTo(x + w, y);
|
||||||
pImpl->path->lineTo(x + w, y + h);
|
pImpl->path.lineTo(x + w, y + h);
|
||||||
pImpl->path->lineTo(x, y + h);
|
pImpl->path.lineTo(x, y + h);
|
||||||
pImpl->path->close();
|
pImpl->path.close();
|
||||||
//circle
|
//circle
|
||||||
} else if (fabsf(rx - halfW) < FLT_EPSILON && fabsf(ry - halfH) < FLT_EPSILON) {
|
} else if (fabsf(rx - halfW) < FLT_EPSILON && fabsf(ry - halfH) < FLT_EPSILON) {
|
||||||
return appendCircle(x + (w * 0.5f), y + (h * 0.5f), rx, ry);
|
return appendCircle(x + (w * 0.5f), y + (h * 0.5f), rx, ry);
|
||||||
} else {
|
} else {
|
||||||
auto hrx = rx * 0.5f;
|
auto hrx = rx * 0.5f;
|
||||||
auto hry = ry * 0.5f;
|
auto hry = ry * 0.5f;
|
||||||
pImpl->path->grow(10, 17);
|
pImpl->path.grow(10, 17);
|
||||||
pImpl->path->moveTo(x + rx, y);
|
pImpl->path.moveTo(x + rx, y);
|
||||||
pImpl->path->lineTo(x + w - rx, y);
|
pImpl->path.lineTo(x + w - rx, y);
|
||||||
pImpl->path->cubicTo(x + w - rx + hrx, y, x + w, y + ry - hry, x + w, y + ry);
|
pImpl->path.cubicTo(x + w - rx + hrx, y, x + w, y + ry - hry, x + w, y + ry);
|
||||||
pImpl->path->lineTo(x + w, y + h - ry);
|
pImpl->path.lineTo(x + w, y + h - ry);
|
||||||
pImpl->path->cubicTo(x + w, y + h - ry + hry, x + w - rx + hrx, y + h, x + w - rx, y + h);
|
pImpl->path.cubicTo(x + w, y + h - ry + hry, x + w - rx + hrx, y + h, x + w - rx, y + h);
|
||||||
pImpl->path->lineTo(x + rx, y + h);
|
pImpl->path.lineTo(x + rx, y + h);
|
||||||
pImpl->path->cubicTo(x + rx - hrx, y + h, x, y + h - ry + hry, x, y + h - ry);
|
pImpl->path.cubicTo(x + rx - hrx, y + h, x, y + h - ry + hry, x, y + h - ry);
|
||||||
pImpl->path->lineTo(x, y + ry);
|
pImpl->path.lineTo(x, y + ry);
|
||||||
pImpl->path->cubicTo(x, y + ry - hry, x + rx - hrx, y, x + rx, y);
|
pImpl->path.cubicTo(x, y + ry - hry, x + rx - hrx, y, x + rx, y);
|
||||||
pImpl->path->close();
|
pImpl->path.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
pImpl->flag |= RenderUpdateFlag::Path;
|
pImpl->flag |= RenderUpdateFlag::Path;
|
||||||
|
|
|
@ -74,9 +74,11 @@ struct ShapePath
|
||||||
if (pts) free(pts);
|
if (pts) free(pts);
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapePath() {}
|
ShapePath()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ShapePath(const ShapePath* src)
|
void duplicate(const ShapePath* src)
|
||||||
{
|
{
|
||||||
cmdCnt = src->cmdCnt;
|
cmdCnt = src->cmdCnt;
|
||||||
reservedCmdCnt = src->reservedCmdCnt;
|
reservedCmdCnt = src->reservedCmdCnt;
|
||||||
|
@ -192,7 +194,7 @@ struct ShapePath
|
||||||
|
|
||||||
struct Shape::Impl
|
struct Shape::Impl
|
||||||
{
|
{
|
||||||
ShapePath *path = nullptr;
|
ShapePath path;
|
||||||
Fill *fill = nullptr;
|
Fill *fill = nullptr;
|
||||||
ShapeStroke *stroke = nullptr;
|
ShapeStroke *stroke = nullptr;
|
||||||
uint8_t color[4] = {0, 0, 0, 0}; //r, g, b, a
|
uint8_t color[4] = {0, 0, 0, 0}; //r, g, b, a
|
||||||
|
@ -201,13 +203,12 @@ struct Shape::Impl
|
||||||
Shape *shape = nullptr;
|
Shape *shape = nullptr;
|
||||||
uint32_t flag = RenderUpdateFlag::None;
|
uint32_t flag = RenderUpdateFlag::None;
|
||||||
|
|
||||||
Impl(Shape* s) : path(new ShapePath), shape(s)
|
Impl(Shape* s) : shape(s)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~Impl()
|
~Impl()
|
||||||
{
|
{
|
||||||
if (path) delete(path);
|
|
||||||
if (fill) delete(fill);
|
if (fill) delete(fill);
|
||||||
if (stroke) delete(stroke);
|
if (stroke) delete(stroke);
|
||||||
}
|
}
|
||||||
|
@ -231,8 +232,7 @@ struct Shape::Impl
|
||||||
|
|
||||||
bool bounds(float* x, float* y, float* w, float* h)
|
bool bounds(float* x, float* y, float* w, float* h)
|
||||||
{
|
{
|
||||||
if (!path) return false;
|
return path.bounds(x, y, w, h);
|
||||||
return path->bounds(x, y, w, h);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool strokeWidth(float width)
|
bool strokeWidth(float width)
|
||||||
|
@ -308,7 +308,7 @@ struct Shape::Impl
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
path->reset();
|
path.reset();
|
||||||
|
|
||||||
if (fill) {
|
if (fill) {
|
||||||
delete(fill);
|
delete(fill);
|
||||||
|
@ -337,10 +337,8 @@ struct Shape::Impl
|
||||||
dup->flag = RenderUpdateFlag::Color;
|
dup->flag = RenderUpdateFlag::Color;
|
||||||
|
|
||||||
//Path
|
//Path
|
||||||
if (path) {
|
dup->path.duplicate(&path);
|
||||||
dup->path = new ShapePath(path);
|
dup->flag |= RenderUpdateFlag::Path;
|
||||||
dup->flag |= RenderUpdateFlag::Path;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Stroke
|
//Stroke
|
||||||
if (stroke) {
|
if (stroke) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue