diff --git a/src/common/tvgMath.cpp b/src/common/tvgMath.cpp index 37a8879c..e6b5d470 100644 --- a/src/common/tvgMath.cpp +++ b/src/common/tvgMath.cpp @@ -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; - - 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; + 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->e31 != 0.0f || m->e32 != 0.0f || m->e33 != 1.0f) { + return false; + } + return true; } @@ -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 || - m->e21 != 0.0f || m->e22 != 1.0f || m->e23 != 0.0f || - m->e31 != 0.0f || m->e32 != 0.0f || m->e33 != 1.0f) { - return false; + Matrix m; + + 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 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 ty = pt->x * transform->e21 + pt->y * transform->e22 + transform->e23; - pt->x = tx; - pt->y = ty; + auto tx = pt.x * m.e11 + pt.y * m.e12 + m.e13; + auto ty = pt.x * m.e21 + pt.y * m.e22 + m.e23; + pt.x = tx; + pt.y = ty; } diff --git a/src/common/tvgMath.h b/src/common/tvgMath.h index 5c296695..0f877d91 100644 --- a/src/common/tvgMath.h +++ b/src/common/tvgMath.h @@ -38,11 +38,9 @@ #define mathMax(x, y) (((x) > (y)) ? (x) : (y)) -bool mathInverse(const Matrix* m, Matrix* out); -Matrix mathMultiply(const Matrix* lhs, const Matrix* rhs); -void mathRotate(Matrix* m, float degree); -bool mathIdentity(const Matrix* m); -void mathMultiply(Point* pt, const Matrix* transform); +/************************************************************************/ +/* General functions */ +/************************************************************************/ 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) { return mathZero(a - b); } -static inline bool mathEqual(const Matrix& a, const Matrix& b) -{ - 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; -} +/************************************************************************/ +/* Matrix functions */ +/************************************************************************/ +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) { @@ -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) { 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) { 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) { 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) { 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 static inline T mathLerp(const T &start, const T &end, float t) { diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index 2315740f..924769a8 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -230,7 +230,7 @@ static void _updateTransform(LottieLayer* layer, float frameNo, LottieExpression if (parent) { if (!mathIdentity((const 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; @@ -256,7 +256,7 @@ static void _updateTransform(LottieGroup* parent, LottieObject** child, float fr if (!_updateTransform(transform, frameNo, false, matrix, opacity, exps)) return; 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)); //FIXME: preserve the stroke width. too workaround, need a better design. @@ -413,7 +413,7 @@ static void _repeat(LottieGroup* parent, unique_ptr path, RenderContext* mathTranslateR(&m, -repeater->anchor.x, -repeater->anchor.y); 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) { 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}}; 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); //round rect @@ -480,7 +482,9 @@ static void _appendRect(Shape* shape, float x, float y, float w, float h, float }; 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); } @@ -532,7 +536,9 @@ static void _appendCircle(Shape* shape, float cx, float cy, float rx, float ry, }; 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); @@ -766,7 +772,7 @@ static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* trans } Point in = {x, y}; - if (transform) mathTransform(transform, &in); + if (transform) in *= *transform; shape->moveTo(in.x, in.y); 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 in4 = {x, y}; if (transform) { - mathTransform(transform, &in2); - mathTransform(transform, &in3); - mathTransform(transform, &in4); + in2 *= *transform; + in3 *= *transform; + in4 *= *transform; } shape->cubicTo(in2.x, in2.y, in3.x, in3.y, in4.x, in4.y); } else { Point in = {x, y}; - if (transform) mathTransform(transform, &in); + if (transform) in *= *transform; shape->lineTo(in.x, in.y); } angle += dTheta * direction; @@ -860,7 +866,7 @@ static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* tr } Point in = {x, y}; - if (transform) mathTransform(transform, &in); + if (transform) in *= *transform; merging->moveTo(in.x, in.y); 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 in4 = {x, y}; if (transform) { - mathTransform(transform, &in2); - mathTransform(transform, &in3); - mathTransform(transform, &in4); + in2 *= *transform; + in3 *= *transform; + in4 *= *transform; } merging->cubicTo(in2.x, in2.y, in3.x, in3.y, in4.x, in4.y); } else { Point in = {x, y}; - if (transform) mathTransform(transform, &in); + if (transform) in *= *transform; merging->lineTo(in.x, in.y); } angle += anglePerPoint * direction; @@ -913,7 +919,7 @@ static void _updatePolystar(LottieGroup* parent, LottieObject** child, float fra mathTranslate(&matrix, position.x, position.y); 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); diff --git a/src/loaders/lottie/tvgLottieProperty.h b/src/loaders/lottie/tvgLottieProperty.h index 31e07c54..635f5c40 100644 --- a/src/loaders/lottie/tvgLottieProperty.h +++ b/src/loaders/lottie/tvgLottieProperty.h @@ -217,7 +217,7 @@ static void _copy(PathSet* pathset, Array& outPts, Matrix* transform) if (transform) { for (int i = 0; i < pathset->ptsCnt; ++i) { Point pt = pathset->pts[i]; - mathMultiply(&pt, transform); + pt *= *transform; outPts.push(pt); } } else { @@ -306,8 +306,9 @@ static bool _modifier(Point* inputPts, uint32_t inputPtsCnt, PathCommand* inputC } } if (transform) { - for (auto i = ptsCnt; i < pts.count; ++i) - mathTransform(transform, &pts[i]); + for (auto i = ptsCnt; i < pts.count; ++i) { + pts[i] *= *transform; + } } return true; } @@ -566,7 +567,7 @@ struct LottiePathSet : LottieProperty auto p = interpPts; for (auto i = 0; i < frame->value.ptsCnt; ++i, ++s, ++e, ++p) { *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); free(interpPts); @@ -574,7 +575,7 @@ struct LottiePathSet : LottieProperty } else { for (auto i = 0; i < frame->value.ptsCnt; ++i, ++s, ++e) { auto pt = mathLerp(*s, *e, t); - if (transform) mathMultiply(&pt, transform); + if (transform) pt *= *transform; pts.push(pt); } _copy(&frame->value, cmds); diff --git a/src/loaders/svg/tvgSvgLoader.cpp b/src/loaders/svg/tvgSvgLoader.cpp index e829524e..50f39356 100644 --- a/src/loaders/svg/tvgSvgLoader.cpp +++ b/src/loaders/svg/tvgSvgLoader.cpp @@ -840,14 +840,14 @@ static Matrix* _parseTransformationMatrix(const char* value) if (state == MatrixState::Matrix) { if (ptCount != 6) goto error; 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) { if (ptCount == 1) { Matrix tmp = {1, 0, points[0], 0, 1, 0, 0, 0, 1}; - *matrix = mathMultiply(matrix, &tmp); + *matrix *= tmp; } else if (ptCount == 2) { Matrix tmp = {1, 0, points[0], 0, 1, points[1], 0, 0, 1}; - *matrix = mathMultiply(matrix, &tmp); + *matrix *= tmp; } else goto error; } else if (state == MatrixState::Rotate) { //Transform to signed. @@ -857,14 +857,14 @@ static Matrix* _parseTransformationMatrix(const char* value) auto s = sinf(mathDeg2Rad(points[0])); if (ptCount == 1) { Matrix tmp = { c, -s, 0, s, c, 0, 0, 0, 1 }; - *matrix = mathMultiply(matrix, &tmp); + *matrix *= tmp; } else if (ptCount == 3) { 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 }; - *matrix = mathMultiply(matrix, &tmp); + *matrix *= tmp; tmp = { 1, 0, -points[1], 0, 1, -points[2], 0, 0, 1 }; - *matrix = mathMultiply(matrix, &tmp); + *matrix *= tmp; } else { goto error; } @@ -874,17 +874,17 @@ static Matrix* _parseTransformationMatrix(const char* value) auto sy = sx; if (ptCount == 2) sy = points[1]; Matrix tmp = { sx, 0, 0, 0, sy, 0, 0, 0, 1 }; - *matrix = mathMultiply(matrix, &tmp); + *matrix *= tmp; } else if (state == MatrixState::SkewX) { if (ptCount != 1) goto error; auto deg = tanf(mathDeg2Rad(points[0])); Matrix tmp = { 1, deg, 0, 0, 1, 0, 0, 0, 1 }; - *matrix = mathMultiply(matrix, &tmp); + *matrix *= tmp; } else if (state == MatrixState::SkewY) { if (ptCount != 1) goto error; auto deg = tanf(mathDeg2Rad(points[0])); Matrix tmp = { 1, 0, 0, deg, 1, 0, 0, 0, 1 }; - *matrix = mathMultiply(matrix, &tmp); + *matrix *= tmp; } } return matrix; diff --git a/src/loaders/svg/tvgSvgSceneBuilder.cpp b/src/loaders/svg/tvgSvgSceneBuilder.cpp index b48b9c57..e8b13faf 100644 --- a/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -203,9 +203,9 @@ static bool _appendClipUseNode(SvgLoaderData& loaderData, SvgNode* node, Shape* if (node->transform) finalTransform = *node->transform; 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}; - 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); } @@ -228,13 +228,13 @@ static Matrix _compositionTransform(Paint* paint, const SvgNode* node, const Svg m = *node->transform; } if (compNode->transform) { - m = mathMultiply(&m, compNode->transform); + m *= *compNode->transform; } if (!compNode->node.clip.userSpace) { float x, y, w, h; P(paint)->bounds(&x, &y, &w, &h, false, false); Matrix mBBox = {w, 0, x, 0, h, y, 0, 0, 1}; - m = mathMultiply(&m, &mBBox); + m *= mBBox; } return m; } @@ -474,7 +474,10 @@ static bool _appendClipShape(SvgLoaderData& loaderData, SvgNode* node, Shape* sh auto ptsCnt = shape->pathCoords(&pts); auto p = const_cast(pts) + currentPtsCnt; - while (currentPtsCnt++ < ptsCnt) mathMultiply(p++, m); + while (currentPtsCnt++ < ptsCnt) { + *p *= *m; + ++p; + } } _applyProperty(loaderData, node, shape, vBox, svgPath, true); @@ -615,7 +618,7 @@ static unique_ptr _imageBuildHelper(SvgLoaderData& loaderData, SvgNode* auto sy = node->node.image.h / h; 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); _applyComposition(loaderData, picture.get(), node, vBox, svgPath); @@ -708,7 +711,7 @@ static unique_ptr _useBuildHelper(SvgLoaderData& loaderData, const SvgNod if (node->transform) mUseTransform = *node->transform; 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}; - mUseTransform = mathMultiply(&mUseTransform, &mTranslate); + mUseTransform *= mTranslate; } if (node->node.use.symbol) { @@ -732,9 +735,9 @@ static unique_ptr _useBuildHelper(SvgLoaderData& loaderData, const SvgNod // mSceneTransform = mUseTransform * mSymbolTransform * mViewBox Matrix mSceneTransform = mViewBox; 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); if (node->node.use.symbol->node.symbol.overflowVisible) { @@ -746,7 +749,7 @@ static unique_ptr _useBuildHelper(SvgLoaderData& loaderData, const SvgNod // mClipTransform = mUseTransform * mSymbolTransform Matrix mClipTransform = mUseTransform; if (node->node.use.symbol->transform) { - mClipTransform = mathMultiply(&mUseTransform, node->node.use.symbol->transform); + mClipTransform = mUseTransform * *node->node.use.symbol->transform; } viewBoxClip->transform(mClipTransform); diff --git a/src/renderer/gl_engine/tvgGlGeometry.cpp b/src/renderer/gl_engine/tvgGlGeometry.cpp index 5a0a35a5..13069df1 100644 --- a/src/renderer/gl_engine/tvgGlGeometry.cpp +++ b/src/renderer/gl_engine/tvgGlGeometry.cpp @@ -268,10 +268,10 @@ RenderRegion GlGeometry::getBounds() const Point rt{static_cast(mBounds.x + mBounds.w), static_cast(mBounds.y)}; Point rb{static_cast(mBounds.x + mBounds.w), static_cast(mBounds.y + mBounds.h)}; - mathMultiply(<, &mMatrix); - mathMultiply(&lb, &mMatrix); - mathMultiply(&rt, &mMatrix); - mathMultiply(&rb, &mMatrix); + lt *= mMatrix; + lb *= mMatrix; + rt *= mMatrix; + rb *= mMatrix; 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)); diff --git a/src/renderer/gl_engine/tvgGlTessellator.cpp b/src/renderer/gl_engine/tvgGlTessellator.cpp index c1bd92d0..89379975 100644 --- a/src/renderer/gl_engine/tvgGlTessellator.cpp +++ b/src/renderer/gl_engine/tvgGlTessellator.cpp @@ -1804,10 +1804,10 @@ void Stroker::strokeCubicTo(const GlPoint &cnt1, const GlPoint &cnt2, const GlPo curve.end = Point{end.x, end.y}; Bezier relCurve {curve.start, curve.ctrl1, curve.ctrl2, curve.end}; - mathMultiply(&relCurve.start, &mMatrix); - mathMultiply(&relCurve.ctrl1, &mMatrix); - mathMultiply(&relCurve.ctrl2, &mMatrix); - mathMultiply(&relCurve.end, &mMatrix); + relCurve.start *= mMatrix; + relCurve.ctrl1 *= mMatrix; + relCurve.ctrl2 *= mMatrix; + relCurve.end *= mMatrix; 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 relCurve {pts[-1], pts[0], pts[1], pts[2]}; - mathMultiply(&relCurve.start, &matrix); - mathMultiply(&relCurve.ctrl1, &matrix); - mathMultiply(&relCurve.ctrl2, &matrix); - mathMultiply(&relCurve.end, &matrix); + relCurve.start *= matrix; + relCurve.ctrl1 *= matrix; + relCurve.ctrl2 *= matrix; + relCurve.end *= matrix; auto stepCount = detail::_bezierCurveCount(relCurve); diff --git a/src/renderer/sw_engine/tvgSwFill.cpp b/src/renderer/sw_engine/tvgSwFill.cpp index 3d582d29..be1662da 100644 --- a/src/renderer/sw_engine/tvgSwFill.cpp +++ b/src/renderer/sw_engine/tvgSwFill.cpp @@ -150,7 +150,7 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* tr bool isTransformation = !mathIdentity((const Matrix*)(&gradTransform)); if (isTransformation) { - if (transform) gradTransform = mathMultiply(transform, &gradTransform); + if (transform) gradTransform = *transform * gradTransform; } else if (transform) { gradTransform = *transform; isTransformation = true; @@ -216,7 +216,7 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* tr bool isTransformation = !mathIdentity((const Matrix*)(&gradTransform)); if (transform) { - if (isTransformation) gradTransform = mathMultiply(transform, &gradTransform); + if (isTransformation) gradTransform = *transform * gradTransform; else { gradTransform = *transform; isTransformation = true; diff --git a/src/renderer/sw_engine/tvgSwRasterTexmap.h b/src/renderer/sw_engine/tvgSwRasterTexmap.h index 6d584300..71474404 100644 --- a/src/renderer/sw_engine/tvgSwRasterTexmap.h +++ b/src/renderer/sw_engine/tvgSwRasterTexmap.h @@ -1110,7 +1110,7 @@ static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const float ys = FLT_MAX, ye = -1.0f; 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 > 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; for (uint32_t i = 0; i < mesh->triangleCnt; i++) { transformedTris[i] = mesh->triangles[i]; - mathMultiply(&transformedTris[i].vertex[0].pt, transform); - mathMultiply(&transformedTris[i].vertex[1].pt, transform); - mathMultiply(&transformedTris[i].vertex[2].pt, transform); + transformedTris[i].vertex[0].pt *= *transform; + transformedTris[i].vertex[1].pt *= *transform; + transformedTris[i].vertex[2].pt *= *transform; 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; diff --git a/src/renderer/tvgPaint.cpp b/src/renderer/tvgPaint.cpp index 95d481c3..a71652c5 100644 --- a/src/renderer/tvgPaint.cpp +++ b/src/renderer/tvgPaint.cpp @@ -75,13 +75,13 @@ static Result _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform auto v2 = *pt3; if (rTransform) { - mathMultiply(&v1, &rTransform->m); - mathMultiply(&v2, &rTransform->m); + v1 *= rTransform->m; + v2 *= rTransform->m; } if (pTransform) { - mathMultiply(&v1, &pTransform->m); - mathMultiply(&v2, &pTransform->m); + v1 *= pTransform->m; + v2 *= pTransform->m; } //sorting @@ -327,7 +327,7 @@ bool Paint::Impl::bounds(float* x, float* y, float* w, float* h, bool transforme //Compute the AABB after transformation 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 > x2) x2 = pt[i].x; diff --git a/src/renderer/tvgRender.cpp b/src/renderer/tvgRender.cpp index 3b638c23..05dcde6c 100644 --- a/src/renderer/tvgRender.cpp +++ b/src/renderer/tvgRender.cpp @@ -47,7 +47,7 @@ void RenderTransform::update() mathScale(&m, scale, scale); - if (!mathZero(degree)) mathRotate(&m, degree); + mathRotate(&m, degree); mathTranslate(&m, x, y); } @@ -55,7 +55,7 @@ void RenderTransform::update() 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 (rhs) m = rhs->m; else mathIdentity(&m); diff --git a/src/savers/tvg/tvgTvgSaver.cpp b/src/savers/tvg/tvgTvgSaver.cpp index 40ab208d..96c285e0 100644 --- a/src/savers/tvg/tvgTvgSaver.cpp +++ b/src/savers/tvg/tvgTvgSaver.cpp @@ -93,7 +93,7 @@ static bool _merge(Shape* from, Shape* to) auto t1 = from->transform(); auto t2 = to->transform(); - if (!mathEqual(t1, t2)) return false; + if (t1 != t2) return false; //stroke 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); auto gTransform = fill->transform(); - if (pTransform) gTransform = mathMultiply(pTransform, &gTransform); + if (pTransform) gTransform = *pTransform * gTransform; 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->e31) || !mathZero(transform->e32) || !mathEqual(transform->e33, 1.0f)) { auto p = const_cast(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; auto transform = const_cast(paint)->transform(); - if (pTransform) transform = mathMultiply(pTransform, &transform); + if (pTransform) transform = *pTransform * transform; switch (paint->identifier()) { case TVG_CLASS_ID_SHAPE: return serializeShape(static_cast(paint), pTransform, &transform); diff --git a/test/resources/tag.tvg b/test/resources/tag.tvg index 7a934bdb..f99c6e6f 100644 Binary files a/test/resources/tag.tvg and b/test/resources/tag.tvg differ