common: code refactoring

Replace the math functions with operator overloading.
This should potentially reduce the code size.
This commit is contained in:
Hermet Park 2024-05-23 21:48:59 +09:00 committed by Hermet Park
parent a95d5667eb
commit a1818cf62b
14 changed files with 173 additions and 126 deletions

View file

@ -47,23 +47,14 @@ bool mathInverse(const Matrix* m, Matrix* out)
} }
Matrix mathMultiply(const Matrix* lhs, const Matrix* rhs) bool mathIdentity(const Matrix* m)
{ {
Matrix m; if (m->e11 != 1.0f || m->e12 != 0.0f || m->e13 != 0.0f ||
m->e21 != 0.0f || m->e22 != 1.0f || m->e23 != 0.0f ||
m.e11 = lhs->e11 * rhs->e11 + lhs->e12 * rhs->e21 + lhs->e13 * rhs->e31; m->e31 != 0.0f || m->e32 != 0.0f || m->e33 != 1.0f) {
m.e12 = lhs->e11 * rhs->e12 + lhs->e12 * rhs->e22 + lhs->e13 * rhs->e32; return false;
m.e13 = lhs->e11 * rhs->e13 + lhs->e12 * rhs->e23 + lhs->e13 * rhs->e33; }
return true;
m.e21 = lhs->e21 * rhs->e11 + lhs->e22 * rhs->e21 + lhs->e23 * rhs->e31;
m.e22 = lhs->e21 * rhs->e12 + lhs->e22 * rhs->e22 + lhs->e23 * rhs->e32;
m.e23 = lhs->e21 * rhs->e13 + lhs->e22 * rhs->e23 + lhs->e23 * rhs->e33;
m.e31 = lhs->e31 * rhs->e11 + lhs->e32 * rhs->e21 + lhs->e33 * rhs->e31;
m.e32 = lhs->e31 * rhs->e12 + lhs->e32 * rhs->e22 + lhs->e33 * rhs->e32;
m.e33 = lhs->e31 * rhs->e13 + lhs->e32 * rhs->e23 + lhs->e33 * rhs->e33;
return m;
} }
@ -82,21 +73,41 @@ void mathRotate(Matrix* m, float degree)
} }
bool mathIdentity(const Matrix* m) Matrix operator*(const Matrix& lhs, const Matrix& rhs)
{ {
if (m->e11 != 1.0f || m->e12 != 0.0f || m->e13 != 0.0f || Matrix m;
m->e21 != 0.0f || m->e22 != 1.0f || m->e23 != 0.0f ||
m->e31 != 0.0f || m->e32 != 0.0f || m->e33 != 1.0f) { m.e11 = lhs.e11 * rhs.e11 + lhs.e12 * rhs.e21 + lhs.e13 * rhs.e31;
m.e12 = lhs.e11 * rhs.e12 + lhs.e12 * rhs.e22 + lhs.e13 * rhs.e32;
m.e13 = lhs.e11 * rhs.e13 + lhs.e12 * rhs.e23 + lhs.e13 * rhs.e33;
m.e21 = lhs.e21 * rhs.e11 + lhs.e22 * rhs.e21 + lhs.e23 * rhs.e31;
m.e22 = lhs.e21 * rhs.e12 + lhs.e22 * rhs.e22 + lhs.e23 * rhs.e32;
m.e23 = lhs.e21 * rhs.e13 + lhs.e22 * rhs.e23 + lhs.e23 * rhs.e33;
m.e31 = lhs.e31 * rhs.e11 + lhs.e32 * rhs.e21 + lhs.e33 * rhs.e31;
m.e32 = lhs.e31 * rhs.e12 + lhs.e32 * rhs.e22 + lhs.e33 * rhs.e32;
m.e33 = lhs.e31 * rhs.e13 + lhs.e32 * rhs.e23 + lhs.e33 * rhs.e33;
return m;
}
bool operator==(const Matrix& lhs, const Matrix& rhs)
{
if (!mathEqual(lhs.e11, rhs.e11) || !mathEqual(lhs.e12, rhs.e12) || !mathEqual(lhs.e13, rhs.e13) ||
!mathEqual(lhs.e21, rhs.e21) || !mathEqual(lhs.e22, rhs.e22) || !mathEqual(lhs.e23, rhs.e23) ||
!mathEqual(lhs.e31, rhs.e31) || !mathEqual(lhs.e32, rhs.e32) || !mathEqual(lhs.e33, rhs.e33)) {
return false; return false;
} }
return true; return true;
} }
void mathMultiply(Point* pt, const Matrix* transform) void operator*=(Point& pt, const Matrix& m)
{ {
auto tx = pt->x * transform->e11 + pt->y * transform->e12 + transform->e13; auto tx = pt.x * m.e11 + pt.y * m.e12 + m.e13;
auto ty = pt->x * transform->e21 + pt->y * transform->e22 + transform->e23; auto ty = pt.x * m.e21 + pt.y * m.e22 + m.e23;
pt->x = tx; pt.x = tx;
pt->y = ty; pt.y = ty;
} }

View file

@ -38,11 +38,9 @@
#define mathMax(x, y) (((x) > (y)) ? (x) : (y)) #define mathMax(x, y) (((x) > (y)) ? (x) : (y))
bool mathInverse(const Matrix* m, Matrix* out); /************************************************************************/
Matrix mathMultiply(const Matrix* lhs, const Matrix* rhs); /* General functions */
void mathRotate(Matrix* m, float degree); /************************************************************************/
bool mathIdentity(const Matrix* m);
void mathMultiply(Point* pt, const Matrix* transform);
static inline float mathDeg2Rad(float degree) static inline float mathDeg2Rad(float degree)
@ -63,28 +61,21 @@ static inline bool mathZero(float a)
} }
static inline bool mathZero(const Point& p)
{
return mathZero(p.x) && mathZero(p.y);
}
static inline bool mathEqual(float a, float b) static inline bool mathEqual(float a, float b)
{ {
return mathZero(a - b); return mathZero(a - b);
} }
static inline bool mathEqual(const Matrix& a, const Matrix& b) /************************************************************************/
{ /* Matrix functions */
if (!mathEqual(a.e11, b.e11) || !mathEqual(a.e12, b.e12) || !mathEqual(a.e13, b.e13) || /************************************************************************/
!mathEqual(a.e21, b.e21) || !mathEqual(a.e22, b.e22) || !mathEqual(a.e23, b.e23) ||
!mathEqual(a.e31, b.e31) || !mathEqual(a.e32, b.e32) || !mathEqual(a.e33, b.e33)) {
return false;
}
return true;
}
void mathRotate(Matrix* m, float degree);
bool mathInverse(const Matrix* m, Matrix* out);
bool mathIdentity(const Matrix* m);
Matrix operator*(const Matrix& lhs, const Matrix& rhs);
bool operator==(const Matrix& lhs, const Matrix& rhs);
static inline bool mathRightAngle(const Matrix* m) static inline bool mathRightAngle(const Matrix* m)
{ {
@ -114,15 +105,6 @@ static inline void mathIdentity(Matrix* m)
} }
static inline void mathTransform(Matrix* transform, Point* coord)
{
auto x = coord->x;
auto y = coord->y;
coord->x = x * transform->e11 + y * transform->e12 + transform->e13;
coord->y = x * transform->e21 + y * transform->e22 + transform->e23;
}
static inline void mathScale(Matrix* m, float sx, float sy) static inline void mathScale(Matrix* m, float sx, float sy)
{ {
m->e11 *= sx; m->e11 *= sx;
@ -158,12 +140,37 @@ static inline void mathTranslateR(Matrix* m, float x, float y)
} }
static inline bool operator!=(const Matrix& lhs, const Matrix& rhs)
{
return !(lhs == rhs);
}
static inline void operator*=(Matrix& lhs, const Matrix& rhs)
{
lhs = lhs * rhs;
}
static inline void mathLog(Matrix* m) static inline void mathLog(Matrix* m)
{ {
TVGLOG("MATH", "Matrix: [%f %f %f] [%f %f %f] [%f %f %f]", m->e11, m->e12, m->e13, m->e21, m->e22, m->e23, m->e31, m->e32, m->e33); TVGLOG("MATH", "Matrix: [%f %f %f] [%f %f %f] [%f %f %f]", m->e11, m->e12, m->e13, m->e21, m->e22, m->e23, m->e31, m->e32, m->e33);
} }
/************************************************************************/
/* Point functions */
/************************************************************************/
void operator*=(Point& pt, const Matrix& m);
static inline bool mathZero(const Point& p)
{
return mathZero(p.x) && mathZero(p.y);
}
static inline float mathLength(const Point* a, const Point* b) static inline float mathLength(const Point* a, const Point* b)
{ {
auto x = b->x - a->x; auto x = b->x - a->x;
@ -182,6 +189,18 @@ static inline float mathLength(const Point& a)
} }
static inline bool operator==(const Point& lhs, const Point& rhs)
{
return mathEqual(lhs.x, rhs.x) && mathEqual(lhs.y, rhs.y);
}
static inline bool operator!=(const Point& lhs, const Point& rhs)
{
return !(lhs == rhs);
}
static inline Point operator-(const Point& lhs, const Point& rhs) static inline Point operator-(const Point& lhs, const Point& rhs)
{ {
return {lhs.x - rhs.x, lhs.y - rhs.y}; return {lhs.x - rhs.x, lhs.y - rhs.y};
@ -212,6 +231,10 @@ static inline Point operator/(const Point& lhs, const float rhs)
} }
/************************************************************************/
/* Interpolation functions */
/************************************************************************/
template <typename T> template <typename T>
static inline T mathLerp(const T &start, const T &end, float t) static inline T mathLerp(const T &start, const T &end, float t)
{ {

View file

@ -230,7 +230,7 @@ static void _updateTransform(LottieLayer* layer, float frameNo, LottieExpression
if (parent) { if (parent) {
if (!mathIdentity((const Matrix*) &parent->cache.matrix)) { if (!mathIdentity((const Matrix*) &parent->cache.matrix)) {
if (mathIdentity((const Matrix*) &matrix)) layer->cache.matrix = parent->cache.matrix; if (mathIdentity((const Matrix*) &matrix)) layer->cache.matrix = parent->cache.matrix;
else layer->cache.matrix = mathMultiply(&parent->cache.matrix, &matrix); else layer->cache.matrix = parent->cache.matrix * matrix;
} }
} }
layer->cache.frameNo = frameNo; layer->cache.frameNo = frameNo;
@ -256,7 +256,7 @@ static void _updateTransform(LottieGroup* parent, LottieObject** child, float fr
if (!_updateTransform(transform, frameNo, false, matrix, opacity, exps)) return; if (!_updateTransform(transform, frameNo, false, matrix, opacity, exps)) return;
auto pmatrix = PP(ctx->propagator)->transform(); auto pmatrix = PP(ctx->propagator)->transform();
ctx->propagator->transform(pmatrix ? mathMultiply(pmatrix, &matrix) : matrix); ctx->propagator->transform(pmatrix ? (*pmatrix * matrix) : matrix);
ctx->propagator->opacity(MULTIPLY(opacity, PP(ctx->propagator)->opacity)); ctx->propagator->opacity(MULTIPLY(opacity, PP(ctx->propagator)->opacity));
//FIXME: preserve the stroke width. too workaround, need a better design. //FIXME: preserve the stroke width. too workaround, need a better design.
@ -413,7 +413,7 @@ static void _repeat(LottieGroup* parent, unique_ptr<Shape> path, RenderContext*
mathTranslateR(&m, -repeater->anchor.x, -repeater->anchor.y); mathTranslateR(&m, -repeater->anchor.x, -repeater->anchor.y);
auto pm = PP(shape)->transform(); auto pm = PP(shape)->transform();
shape->transform(pm ? mathMultiply(&m, pm) : m); shape->transform(pm ? (m * *pm) : m);
if (ctx->roundness > 1.0f && P(shape)->rs.stroke) { if (ctx->roundness > 1.0f && P(shape)->rs.stroke) {
TVGERR("LOTTIE", "FIXME: Path roundesss should be applied properly!"); TVGERR("LOTTIE", "FIXME: Path roundesss should be applied properly!");
@ -447,7 +447,9 @@ static void _appendRect(Shape* shape, float x, float y, float w, float h, float
Point points[] = {{x + w, y}, {x + w, y + h}, {x, y + h}, {x, y}}; Point points[] = {{x + w, y}, {x + w, y + h}, {x, y + h}, {x, y}};
if (transform) { if (transform) {
for (int i = 0; i < 4; i++) mathTransform(transform, &points[i]); for (int i = 0; i < 4; i++) {
points[i] *= *transform;
}
} }
shape->appendPath(commands, 5, points, 4); shape->appendPath(commands, 5, points, 4);
//round rect //round rect
@ -480,7 +482,9 @@ static void _appendRect(Shape* shape, float x, float y, float w, float h, float
}; };
if (transform) { if (transform) {
for (int i = 0; i < ptsCnt; i++) mathTransform(transform, &points[i]); for (int i = 0; i < ptsCnt; i++) {
points[i] *= *transform;
}
} }
shape->appendPath(commands, 10, points, ptsCnt); shape->appendPath(commands, 10, points, ptsCnt);
} }
@ -532,7 +536,9 @@ static void _appendCircle(Shape* shape, float cx, float cy, float rx, float ry,
}; };
if (transform) { if (transform) {
for (int i = 0; i < ptsCnt; ++i) mathTransform(transform, &points[i]); for (int i = 0; i < ptsCnt; ++i) {
points[i] *= *transform;
}
} }
shape->appendPath(commands, cmdsCnt, points, ptsCnt); shape->appendPath(commands, cmdsCnt, points, ptsCnt);
@ -766,7 +772,7 @@ static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* trans
} }
Point in = {x, y}; Point in = {x, y};
if (transform) mathTransform(transform, &in); if (transform) in *= *transform;
shape->moveTo(in.x, in.y); shape->moveTo(in.x, in.y);
for (size_t i = 0; i < numPoints; i++) { for (size_t i = 0; i < numPoints; i++) {
@ -811,14 +817,14 @@ static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* trans
Point in3 = {x + cp2x, y + cp2y}; Point in3 = {x + cp2x, y + cp2y};
Point in4 = {x, y}; Point in4 = {x, y};
if (transform) { if (transform) {
mathTransform(transform, &in2); in2 *= *transform;
mathTransform(transform, &in3); in3 *= *transform;
mathTransform(transform, &in4); in4 *= *transform;
} }
shape->cubicTo(in2.x, in2.y, in3.x, in3.y, in4.x, in4.y); shape->cubicTo(in2.x, in2.y, in3.x, in3.y, in4.x, in4.y);
} else { } else {
Point in = {x, y}; Point in = {x, y};
if (transform) mathTransform(transform, &in); if (transform) in *= *transform;
shape->lineTo(in.x, in.y); shape->lineTo(in.x, in.y);
} }
angle += dTheta * direction; angle += dTheta * direction;
@ -860,7 +866,7 @@ static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* tr
} }
Point in = {x, y}; Point in = {x, y};
if (transform) mathTransform(transform, &in); if (transform) in *= *transform;
merging->moveTo(in.x, in.y); merging->moveTo(in.x, in.y);
for (size_t i = 0; i < ptsCnt; i++) { for (size_t i = 0; i < ptsCnt; i++) {
@ -886,14 +892,14 @@ static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* tr
Point in3 = {x + cp2x, y + cp2y}; Point in3 = {x + cp2x, y + cp2y};
Point in4 = {x, y}; Point in4 = {x, y};
if (transform) { if (transform) {
mathTransform(transform, &in2); in2 *= *transform;
mathTransform(transform, &in3); in3 *= *transform;
mathTransform(transform, &in4); in4 *= *transform;
} }
merging->cubicTo(in2.x, in2.y, in3.x, in3.y, in4.x, in4.y); merging->cubicTo(in2.x, in2.y, in3.x, in3.y, in4.x, in4.y);
} else { } else {
Point in = {x, y}; Point in = {x, y};
if (transform) mathTransform(transform, &in); if (transform) in *= *transform;
merging->lineTo(in.x, in.y); merging->lineTo(in.x, in.y);
} }
angle += anglePerPoint * direction; angle += anglePerPoint * direction;
@ -913,7 +919,7 @@ static void _updatePolystar(LottieGroup* parent, LottieObject** child, float fra
mathTranslate(&matrix, position.x, position.y); mathTranslate(&matrix, position.x, position.y);
mathRotate(&matrix, star->rotation(frameNo, exps)); mathRotate(&matrix, star->rotation(frameNo, exps));
if (ctx->transform) matrix = mathMultiply(ctx->transform, &matrix); if (ctx->transform) matrix = *ctx->transform * matrix;
auto identity = mathIdentity((const Matrix*)&matrix); auto identity = mathIdentity((const Matrix*)&matrix);

View file

@ -217,7 +217,7 @@ static void _copy(PathSet* pathset, Array<Point>& outPts, Matrix* transform)
if (transform) { if (transform) {
for (int i = 0; i < pathset->ptsCnt; ++i) { for (int i = 0; i < pathset->ptsCnt; ++i) {
Point pt = pathset->pts[i]; Point pt = pathset->pts[i];
mathMultiply(&pt, transform); pt *= *transform;
outPts.push(pt); outPts.push(pt);
} }
} else { } else {
@ -306,8 +306,9 @@ static bool _modifier(Point* inputPts, uint32_t inputPtsCnt, PathCommand* inputC
} }
} }
if (transform) { if (transform) {
for (auto i = ptsCnt; i < pts.count; ++i) for (auto i = ptsCnt; i < pts.count; ++i) {
mathTransform(transform, &pts[i]); pts[i] *= *transform;
}
} }
return true; return true;
} }
@ -566,7 +567,7 @@ struct LottiePathSet : LottieProperty
auto p = interpPts; auto p = interpPts;
for (auto i = 0; i < frame->value.ptsCnt; ++i, ++s, ++e, ++p) { for (auto i = 0; i < frame->value.ptsCnt; ++i, ++s, ++e, ++p) {
*p = mathLerp(*s, *e, t); *p = mathLerp(*s, *e, t);
if (transform) mathMultiply(p, transform); if (transform) *p *= *transform;
} }
_modifier(interpPts, frame->value.ptsCnt, frame->value.cmds, frame->value.cmdsCnt, cmds, pts, nullptr, roundness); _modifier(interpPts, frame->value.ptsCnt, frame->value.cmds, frame->value.cmdsCnt, cmds, pts, nullptr, roundness);
free(interpPts); free(interpPts);
@ -574,7 +575,7 @@ struct LottiePathSet : LottieProperty
} else { } else {
for (auto i = 0; i < frame->value.ptsCnt; ++i, ++s, ++e) { for (auto i = 0; i < frame->value.ptsCnt; ++i, ++s, ++e) {
auto pt = mathLerp(*s, *e, t); auto pt = mathLerp(*s, *e, t);
if (transform) mathMultiply(&pt, transform); if (transform) pt *= *transform;
pts.push(pt); pts.push(pt);
} }
_copy(&frame->value, cmds); _copy(&frame->value, cmds);

View file

@ -840,14 +840,14 @@ static Matrix* _parseTransformationMatrix(const char* value)
if (state == MatrixState::Matrix) { if (state == MatrixState::Matrix) {
if (ptCount != 6) goto error; if (ptCount != 6) goto error;
Matrix tmp = {points[0], points[2], points[4], points[1], points[3], points[5], 0, 0, 1}; Matrix tmp = {points[0], points[2], points[4], points[1], points[3], points[5], 0, 0, 1};
*matrix = mathMultiply(matrix, &tmp); *matrix *= tmp;
} else if (state == MatrixState::Translate) { } else if (state == MatrixState::Translate) {
if (ptCount == 1) { if (ptCount == 1) {
Matrix tmp = {1, 0, points[0], 0, 1, 0, 0, 0, 1}; Matrix tmp = {1, 0, points[0], 0, 1, 0, 0, 0, 1};
*matrix = mathMultiply(matrix, &tmp); *matrix *= tmp;
} else if (ptCount == 2) { } else if (ptCount == 2) {
Matrix tmp = {1, 0, points[0], 0, 1, points[1], 0, 0, 1}; Matrix tmp = {1, 0, points[0], 0, 1, points[1], 0, 0, 1};
*matrix = mathMultiply(matrix, &tmp); *matrix *= tmp;
} else goto error; } else goto error;
} else if (state == MatrixState::Rotate) { } else if (state == MatrixState::Rotate) {
//Transform to signed. //Transform to signed.
@ -857,14 +857,14 @@ static Matrix* _parseTransformationMatrix(const char* value)
auto s = sinf(mathDeg2Rad(points[0])); auto s = sinf(mathDeg2Rad(points[0]));
if (ptCount == 1) { if (ptCount == 1) {
Matrix tmp = { c, -s, 0, s, c, 0, 0, 0, 1 }; Matrix tmp = { c, -s, 0, s, c, 0, 0, 0, 1 };
*matrix = mathMultiply(matrix, &tmp); *matrix *= tmp;
} else if (ptCount == 3) { } else if (ptCount == 3) {
Matrix tmp = { 1, 0, points[1], 0, 1, points[2], 0, 0, 1 }; Matrix tmp = { 1, 0, points[1], 0, 1, points[2], 0, 0, 1 };
*matrix = mathMultiply(matrix, &tmp); *matrix *= tmp;
tmp = { c, -s, 0, s, c, 0, 0, 0, 1 }; tmp = { c, -s, 0, s, c, 0, 0, 0, 1 };
*matrix = mathMultiply(matrix, &tmp); *matrix *= tmp;
tmp = { 1, 0, -points[1], 0, 1, -points[2], 0, 0, 1 }; tmp = { 1, 0, -points[1], 0, 1, -points[2], 0, 0, 1 };
*matrix = mathMultiply(matrix, &tmp); *matrix *= tmp;
} else { } else {
goto error; goto error;
} }
@ -874,17 +874,17 @@ static Matrix* _parseTransformationMatrix(const char* value)
auto sy = sx; auto sy = sx;
if (ptCount == 2) sy = points[1]; if (ptCount == 2) sy = points[1];
Matrix tmp = { sx, 0, 0, 0, sy, 0, 0, 0, 1 }; Matrix tmp = { sx, 0, 0, 0, sy, 0, 0, 0, 1 };
*matrix = mathMultiply(matrix, &tmp); *matrix *= tmp;
} else if (state == MatrixState::SkewX) { } else if (state == MatrixState::SkewX) {
if (ptCount != 1) goto error; if (ptCount != 1) goto error;
auto deg = tanf(mathDeg2Rad(points[0])); auto deg = tanf(mathDeg2Rad(points[0]));
Matrix tmp = { 1, deg, 0, 0, 1, 0, 0, 0, 1 }; Matrix tmp = { 1, deg, 0, 0, 1, 0, 0, 0, 1 };
*matrix = mathMultiply(matrix, &tmp); *matrix *= tmp;
} else if (state == MatrixState::SkewY) { } else if (state == MatrixState::SkewY) {
if (ptCount != 1) goto error; if (ptCount != 1) goto error;
auto deg = tanf(mathDeg2Rad(points[0])); auto deg = tanf(mathDeg2Rad(points[0]));
Matrix tmp = { 1, 0, 0, deg, 1, 0, 0, 0, 1 }; Matrix tmp = { 1, 0, 0, deg, 1, 0, 0, 0, 1 };
*matrix = mathMultiply(matrix, &tmp); *matrix *= tmp;
} }
} }
return matrix; return matrix;

View file

@ -203,9 +203,9 @@ static bool _appendClipUseNode(SvgLoaderData& loaderData, SvgNode* node, Shape*
if (node->transform) finalTransform = *node->transform; if (node->transform) finalTransform = *node->transform;
if (node->node.use.x != 0.0f || node->node.use.y != 0.0f) { if (node->node.use.x != 0.0f || node->node.use.y != 0.0f) {
Matrix m = {1, 0, node->node.use.x, 0, 1, node->node.use.y, 0, 0, 1}; Matrix m = {1, 0, node->node.use.x, 0, 1, node->node.use.y, 0, 0, 1};
finalTransform = mathMultiply(&finalTransform, &m); finalTransform *= m;
} }
if (child->transform) finalTransform = mathMultiply(child->transform, &finalTransform); if (child->transform) finalTransform = *child->transform * finalTransform;
return _appendClipShape(loaderData, child, shape, vBox, svgPath, mathIdentity((const Matrix*)(&finalTransform)) ? nullptr : &finalTransform); return _appendClipShape(loaderData, child, shape, vBox, svgPath, mathIdentity((const Matrix*)(&finalTransform)) ? nullptr : &finalTransform);
} }
@ -228,13 +228,13 @@ static Matrix _compositionTransform(Paint* paint, const SvgNode* node, const Svg
m = *node->transform; m = *node->transform;
} }
if (compNode->transform) { if (compNode->transform) {
m = mathMultiply(&m, compNode->transform); m *= *compNode->transform;
} }
if (!compNode->node.clip.userSpace) { if (!compNode->node.clip.userSpace) {
float x, y, w, h; float x, y, w, h;
P(paint)->bounds(&x, &y, &w, &h, false, false); P(paint)->bounds(&x, &y, &w, &h, false, false);
Matrix mBBox = {w, 0, x, 0, h, y, 0, 0, 1}; Matrix mBBox = {w, 0, x, 0, h, y, 0, 0, 1};
m = mathMultiply(&m, &mBBox); m *= mBBox;
} }
return m; return m;
} }
@ -474,7 +474,10 @@ static bool _appendClipShape(SvgLoaderData& loaderData, SvgNode* node, Shape* sh
auto ptsCnt = shape->pathCoords(&pts); auto ptsCnt = shape->pathCoords(&pts);
auto p = const_cast<Point*>(pts) + currentPtsCnt; auto p = const_cast<Point*>(pts) + currentPtsCnt;
while (currentPtsCnt++ < ptsCnt) mathMultiply(p++, m); while (currentPtsCnt++ < ptsCnt) {
*p *= *m;
++p;
}
} }
_applyProperty(loaderData, node, shape, vBox, svgPath, true); _applyProperty(loaderData, node, shape, vBox, svgPath, true);
@ -615,7 +618,7 @@ static unique_ptr<Picture> _imageBuildHelper(SvgLoaderData& loaderData, SvgNode*
auto sy = node->node.image.h / h; auto sy = node->node.image.h / h;
m = {sx, 0, node->node.image.x, 0, sy, node->node.image.y, 0, 0, 1}; m = {sx, 0, node->node.image.x, 0, sy, node->node.image.y, 0, 0, 1};
} }
if (node->transform) m = mathMultiply(node->transform, &m); if (node->transform) m = *node->transform * m;
picture->transform(m); picture->transform(m);
_applyComposition(loaderData, picture.get(), node, vBox, svgPath); _applyComposition(loaderData, picture.get(), node, vBox, svgPath);
@ -708,7 +711,7 @@ static unique_ptr<Scene> _useBuildHelper(SvgLoaderData& loaderData, const SvgNod
if (node->transform) mUseTransform = *node->transform; if (node->transform) mUseTransform = *node->transform;
if (node->node.use.x != 0.0f || node->node.use.y != 0.0f) { if (node->node.use.x != 0.0f || node->node.use.y != 0.0f) {
Matrix mTranslate = {1, 0, node->node.use.x, 0, 1, node->node.use.y, 0, 0, 1}; Matrix mTranslate = {1, 0, node->node.use.x, 0, 1, node->node.use.y, 0, 0, 1};
mUseTransform = mathMultiply(&mUseTransform, &mTranslate); mUseTransform *= mTranslate;
} }
if (node->node.use.symbol) { if (node->node.use.symbol) {
@ -732,9 +735,9 @@ static unique_ptr<Scene> _useBuildHelper(SvgLoaderData& loaderData, const SvgNod
// mSceneTransform = mUseTransform * mSymbolTransform * mViewBox // mSceneTransform = mUseTransform * mSymbolTransform * mViewBox
Matrix mSceneTransform = mViewBox; Matrix mSceneTransform = mViewBox;
if (node->node.use.symbol->transform) { if (node->node.use.symbol->transform) {
mSceneTransform = mathMultiply(node->node.use.symbol->transform, &mViewBox); mSceneTransform = *node->node.use.symbol->transform * mViewBox;
} }
mSceneTransform = mathMultiply(&mUseTransform, &mSceneTransform); mSceneTransform = mUseTransform * mSceneTransform;
scene->transform(mSceneTransform); scene->transform(mSceneTransform);
if (node->node.use.symbol->node.symbol.overflowVisible) { if (node->node.use.symbol->node.symbol.overflowVisible) {
@ -746,7 +749,7 @@ static unique_ptr<Scene> _useBuildHelper(SvgLoaderData& loaderData, const SvgNod
// mClipTransform = mUseTransform * mSymbolTransform // mClipTransform = mUseTransform * mSymbolTransform
Matrix mClipTransform = mUseTransform; Matrix mClipTransform = mUseTransform;
if (node->node.use.symbol->transform) { if (node->node.use.symbol->transform) {
mClipTransform = mathMultiply(&mUseTransform, node->node.use.symbol->transform); mClipTransform = mUseTransform * *node->node.use.symbol->transform;
} }
viewBoxClip->transform(mClipTransform); viewBoxClip->transform(mClipTransform);

View file

@ -268,10 +268,10 @@ RenderRegion GlGeometry::getBounds() const
Point rt{static_cast<float>(mBounds.x + mBounds.w), static_cast<float>(mBounds.y)}; Point rt{static_cast<float>(mBounds.x + mBounds.w), static_cast<float>(mBounds.y)};
Point rb{static_cast<float>(mBounds.x + mBounds.w), static_cast<float>(mBounds.y + mBounds.h)}; Point rb{static_cast<float>(mBounds.x + mBounds.w), static_cast<float>(mBounds.y + mBounds.h)};
mathMultiply(&lt, &mMatrix); lt *= mMatrix;
mathMultiply(&lb, &mMatrix); lb *= mMatrix;
mathMultiply(&rt, &mMatrix); rt *= mMatrix;
mathMultiply(&rb, &mMatrix); rb *= mMatrix;
float left = min(min(lt.x, lb.x), min(rt.x, rb.x)); float left = min(min(lt.x, lb.x), min(rt.x, rb.x));
float top = min(min(lt.y, lb.y), min(rt.y, rb.y)); float top = min(min(lt.y, lb.y), min(rt.y, rb.y));

View file

@ -1804,10 +1804,10 @@ void Stroker::strokeCubicTo(const GlPoint &cnt1, const GlPoint &cnt2, const GlPo
curve.end = Point{end.x, end.y}; curve.end = Point{end.x, end.y};
Bezier relCurve {curve.start, curve.ctrl1, curve.ctrl2, curve.end}; Bezier relCurve {curve.start, curve.ctrl1, curve.ctrl2, curve.end};
mathMultiply(&relCurve.start, &mMatrix); relCurve.start *= mMatrix;
mathMultiply(&relCurve.ctrl1, &mMatrix); relCurve.ctrl1 *= mMatrix;
mathMultiply(&relCurve.ctrl2, &mMatrix); relCurve.ctrl2 *= mMatrix;
mathMultiply(&relCurve.end, &mMatrix); relCurve.end *= mMatrix;
auto count = detail::_bezierCurveCount(relCurve); auto count = detail::_bezierCurveCount(relCurve);
@ -2175,10 +2175,10 @@ void BWTessellator::tessellate(const RenderShape *rshape, const Matrix& matrix)
Bezier curve{pts[-1], pts[0], pts[1], pts[2]}; Bezier curve{pts[-1], pts[0], pts[1], pts[2]};
Bezier relCurve {pts[-1], pts[0], pts[1], pts[2]}; Bezier relCurve {pts[-1], pts[0], pts[1], pts[2]};
mathMultiply(&relCurve.start, &matrix); relCurve.start *= matrix;
mathMultiply(&relCurve.ctrl1, &matrix); relCurve.ctrl1 *= matrix;
mathMultiply(&relCurve.ctrl2, &matrix); relCurve.ctrl2 *= matrix;
mathMultiply(&relCurve.end, &matrix); relCurve.end *= matrix;
auto stepCount = detail::_bezierCurveCount(relCurve); auto stepCount = detail::_bezierCurveCount(relCurve);

View file

@ -150,7 +150,7 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* tr
bool isTransformation = !mathIdentity((const Matrix*)(&gradTransform)); bool isTransformation = !mathIdentity((const Matrix*)(&gradTransform));
if (isTransformation) { if (isTransformation) {
if (transform) gradTransform = mathMultiply(transform, &gradTransform); if (transform) gradTransform = *transform * gradTransform;
} else if (transform) { } else if (transform) {
gradTransform = *transform; gradTransform = *transform;
isTransformation = true; isTransformation = true;
@ -216,7 +216,7 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* tr
bool isTransformation = !mathIdentity((const Matrix*)(&gradTransform)); bool isTransformation = !mathIdentity((const Matrix*)(&gradTransform));
if (transform) { if (transform) {
if (isTransformation) gradTransform = mathMultiply(transform, &gradTransform); if (isTransformation) gradTransform = *transform * gradTransform;
else { else {
gradTransform = *transform; gradTransform = *transform;
isTransformation = true; isTransformation = true;

View file

@ -1110,7 +1110,7 @@ static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const
float ys = FLT_MAX, ye = -1.0f; float ys = FLT_MAX, ye = -1.0f;
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
if (transform) mathMultiply(&vertices[i].pt, transform); if (transform) vertices[i].pt *= *transform;
if (vertices[i].pt.y < ys) ys = vertices[i].pt.y; if (vertices[i].pt.y < ys) ys = vertices[i].pt.y;
if (vertices[i].pt.y > ye) ye = vertices[i].pt.y; if (vertices[i].pt.y > ye) ye = vertices[i].pt.y;
} }
@ -1171,9 +1171,9 @@ static bool _rasterTexmapPolygonMesh(SwSurface* surface, const SwImage* image, c
float ys = FLT_MAX, ye = -1.0f; float ys = FLT_MAX, ye = -1.0f;
for (uint32_t i = 0; i < mesh->triangleCnt; i++) { for (uint32_t i = 0; i < mesh->triangleCnt; i++) {
transformedTris[i] = mesh->triangles[i]; transformedTris[i] = mesh->triangles[i];
mathMultiply(&transformedTris[i].vertex[0].pt, transform); transformedTris[i].vertex[0].pt *= *transform;
mathMultiply(&transformedTris[i].vertex[1].pt, transform); transformedTris[i].vertex[1].pt *= *transform;
mathMultiply(&transformedTris[i].vertex[2].pt, transform); transformedTris[i].vertex[2].pt *= *transform;
if (transformedTris[i].vertex[0].pt.y < ys) ys = transformedTris[i].vertex[0].pt.y; if (transformedTris[i].vertex[0].pt.y < ys) ys = transformedTris[i].vertex[0].pt.y;
else if (transformedTris[i].vertex[0].pt.y > ye) ye = transformedTris[i].vertex[0].pt.y; else if (transformedTris[i].vertex[0].pt.y > ye) ye = transformedTris[i].vertex[0].pt.y;

View file

@ -75,13 +75,13 @@ static Result _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform
auto v2 = *pt3; auto v2 = *pt3;
if (rTransform) { if (rTransform) {
mathMultiply(&v1, &rTransform->m); v1 *= rTransform->m;
mathMultiply(&v2, &rTransform->m); v2 *= rTransform->m;
} }
if (pTransform) { if (pTransform) {
mathMultiply(&v1, &pTransform->m); v1 *= pTransform->m;
mathMultiply(&v2, &pTransform->m); v2 *= pTransform->m;
} }
//sorting //sorting
@ -327,7 +327,7 @@ bool Paint::Impl::bounds(float* x, float* y, float* w, float* h, bool transforme
//Compute the AABB after transformation //Compute the AABB after transformation
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
mathMultiply(&pt[i], m); pt[i] *= *m;
if (pt[i].x < x1) x1 = pt[i].x; if (pt[i].x < x1) x1 = pt[i].x;
if (pt[i].x > x2) x2 = pt[i].x; if (pt[i].x > x2) x2 = pt[i].x;

View file

@ -47,7 +47,7 @@ void RenderTransform::update()
mathScale(&m, scale, scale); mathScale(&m, scale, scale);
if (!mathZero(degree)) mathRotate(&m, degree); mathRotate(&m, degree);
mathTranslate(&m, x, y); mathTranslate(&m, x, y);
} }
@ -55,7 +55,7 @@ void RenderTransform::update()
RenderTransform::RenderTransform(const RenderTransform* lhs, const RenderTransform* rhs) RenderTransform::RenderTransform(const RenderTransform* lhs, const RenderTransform* rhs)
{ {
if (lhs && rhs) m = mathMultiply(&lhs->m, &rhs->m); if (lhs && rhs) m = lhs->m * rhs->m;
else if (lhs) m = lhs->m; else if (lhs) m = lhs->m;
else if (rhs) m = rhs->m; else if (rhs) m = rhs->m;
else mathIdentity(&m); else mathIdentity(&m);

View file

@ -93,7 +93,7 @@ static bool _merge(Shape* from, Shape* to)
auto t1 = from->transform(); auto t1 = from->transform();
auto t2 = to->transform(); auto t2 = to->transform();
if (!mathEqual(t1, t2)) return false; if (t1 != t2) return false;
//stroke //stroke
if (P(from)->strokeFirst() != P(to)->strokeFirst()) return false; if (P(from)->strokeFirst() != P(to)->strokeFirst()) return false;
@ -426,7 +426,7 @@ TvgBinCounter TvgSaver::serializeFill(const Fill* fill, TvgBinTag tag, const Mat
cnt += writeTagProperty(TVG_TAG_FILL_COLORSTOPS, stopsCnt * SIZE(Fill::ColorStop), stops); cnt += writeTagProperty(TVG_TAG_FILL_COLORSTOPS, stopsCnt * SIZE(Fill::ColorStop), stops);
auto gTransform = fill->transform(); auto gTransform = fill->transform();
if (pTransform) gTransform = mathMultiply(pTransform, &gTransform); if (pTransform) gTransform = *pTransform * gTransform;
cnt += writeTransform(&gTransform, TVG_TAG_FILL_TRANSFORM); cnt += writeTransform(&gTransform, TVG_TAG_FILL_TRANSFORM);
@ -528,7 +528,10 @@ TvgBinCounter TvgSaver::serializePath(const Shape* shape, const Matrix* transfor
!mathZero(transform->e21) || !mathEqual(transform->e22, 1.0f) || !mathZero(transform->e23) || !mathZero(transform->e21) || !mathEqual(transform->e22, 1.0f) || !mathZero(transform->e23) ||
!mathZero(transform->e31) || !mathZero(transform->e32) || !mathEqual(transform->e33, 1.0f)) { !mathZero(transform->e31) || !mathZero(transform->e32) || !mathEqual(transform->e33, 1.0f)) {
auto p = const_cast<Point*>(pts); auto p = const_cast<Point*>(pts);
for (uint32_t i = 0; i < ptsCnt; ++i) mathMultiply(p++, transform); for (uint32_t i = 0; i < ptsCnt; ++i) {
*p *= *transform;
++p;
}
} }
} }
@ -710,7 +713,7 @@ TvgBinCounter TvgSaver::serialize(const Paint* paint, const Matrix* pTransform,
if (!compTarget && paint->opacity() == 0) return 0; if (!compTarget && paint->opacity() == 0) return 0;
auto transform = const_cast<Paint*>(paint)->transform(); auto transform = const_cast<Paint*>(paint)->transform();
if (pTransform) transform = mathMultiply(pTransform, &transform); if (pTransform) transform = *pTransform * transform;
switch (paint->identifier()) { switch (paint->identifier()) {
case TVG_CLASS_ID_SHAPE: return serializeShape(static_cast<const Shape*>(paint), pTransform, &transform); case TVG_CLASS_ID_SHAPE: return serializeShape(static_cast<const Shape*>(paint), pTransform, &transform);

Binary file not shown.