diff --git a/src/common/tvgLines.cpp b/src/common/tvgLines.cpp index 48914dd5..3c62b74e 100644 --- a/src/common/tvgLines.cpp +++ b/src/common/tvgLines.cpp @@ -238,7 +238,7 @@ float bezAngleAt(const Bezier& bz, float t) pt.x *= 3; pt.y *= 3; - return mathRad2Deg(mathAtan2(pt.y, pt.x)); + return rad2deg(tvg::atan2(pt.y, pt.x)); } diff --git a/src/common/tvgMath.cpp b/src/common/tvgMath.cpp index 5d583721..24af3d45 100644 --- a/src/common/tvgMath.cpp +++ b/src/common/tvgMath.cpp @@ -22,11 +22,10 @@ #include "tvgMath.h" -//see: https://en.wikipedia.org/wiki/Remez_algorithm -float mathAtan2(float y, float x) -{ - if (y == 0.0f) return 0.0f; +namespace tvg { +float atan2(float y, float x) +{ auto a = std::min(fabsf(x), fabsf(y)) / std::max(fabsf(x), fabsf(y)); auto s = a * a; auto r = ((-0.0464964749f * s + 0.15931422f) * s - 0.327622764f) * s * a + a; @@ -37,13 +36,13 @@ float mathAtan2(float y, float x) } -bool mathInverse(const Matrix* m, Matrix* out) +bool inverse(const Matrix* m, Matrix* out) { auto det = m->e11 * (m->e22 * m->e33 - m->e32 * m->e23) - m->e12 * (m->e21 * m->e33 - m->e23 * m->e31) + m->e13 * (m->e21 * m->e32 - m->e22 * m->e31); - if (mathZero(det)) return false; + if (tvg::zero(det)) return false; auto invDet = 1 / det; @@ -61,7 +60,7 @@ bool mathInverse(const Matrix* m, Matrix* out) } -bool mathIdentity(const Matrix* m) +bool identity(const 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 || @@ -72,7 +71,7 @@ bool mathIdentity(const Matrix* m) } -void mathRotate(Matrix* m, float degree) +void rotate(Matrix* m, float degree) { if (degree == 0.0f) return; @@ -109,9 +108,9 @@ Matrix operator*(const Matrix& lhs, const Matrix& rhs) 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)) { + if (!tvg::equal(lhs.e11, rhs.e11) || !tvg::equal(lhs.e12, rhs.e12) || !tvg::equal(lhs.e13, rhs.e13) || + !tvg::equal(lhs.e21, rhs.e21) || !tvg::equal(lhs.e22, rhs.e22) || !tvg::equal(lhs.e23, rhs.e23) || + !tvg::equal(lhs.e31, rhs.e31) || !tvg::equal(lhs.e32, rhs.e32) || !tvg::equal(lhs.e33, rhs.e33)) { return false; } return true; @@ -132,4 +131,6 @@ Point operator*(const Point& pt, const Matrix& m) auto tx = pt.x * m.e11 + pt.y * m.e12 + m.e13; auto ty = pt.x * m.e21 + pt.y * m.e22 + m.e23; return {tx, ty}; +} + } \ No newline at end of file diff --git a/src/common/tvgMath.h b/src/common/tvgMath.h index cf66183b..68344fee 100644 --- a/src/common/tvgMath.h +++ b/src/common/tvgMath.h @@ -29,39 +29,42 @@ #include #include "tvgCommon.h" +namespace tvg +{ + #define MATH_PI 3.14159265358979323846f #define MATH_PI2 1.57079632679489661923f #define FLOAT_EPSILON 1.0e-06f //1.192092896e-07f #define PATH_KAPPA 0.552284f - /************************************************************************/ /* General functions */ /************************************************************************/ -float mathAtan2(float y, float x); +float atan2(float y, float x); -static inline float mathDeg2Rad(float degree) + +static inline float deg2rad(float degree) { return degree * (MATH_PI / 180.0f); } -static inline float mathRad2Deg(float radian) +static inline float rad2deg(float radian) { return radian * (180.0f / MATH_PI); } -static inline bool mathZero(float a) +static inline bool zero(float a) { return (fabsf(a) <= FLOAT_EPSILON) ? true : false; } -static inline bool mathEqual(float a, float b) +static inline bool equal(float a, float b) { - return mathZero(a - b); + return tvg::zero(a - b); } @@ -69,27 +72,27 @@ static inline bool mathEqual(float a, float b) /* Matrix functions */ /************************************************************************/ -void mathRotate(Matrix* m, float degree); -bool mathInverse(const Matrix* m, Matrix* out); -bool mathIdentity(const Matrix* m); +void rotate(Matrix* m, float degree); +bool inverse(const Matrix* m, Matrix* out); +bool identity(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 rightAngle(const Matrix* m) { - auto radian = fabsf(mathAtan2(m->e21, m->e11)); - if (radian < FLOAT_EPSILON || mathEqual(radian, MATH_PI2) || mathEqual(radian, MATH_PI)) return true; + auto radian = fabsf(tvg::atan2(m->e21, m->e11)); + if (radian < FLOAT_EPSILON || tvg::equal(radian, MATH_PI2) || tvg::equal(radian, MATH_PI)) return true; return false; } -static inline bool mathSkewed(const Matrix* m) +static inline bool skewed(const Matrix* m) { - return !mathZero(m->e21 + m->e12); + return !tvg::zero(m->e21 + m->e12); } -static inline void mathIdentity(Matrix* m) +static inline void identity(Matrix* m) { m->e11 = 1.0f; m->e12 = 0.0f; @@ -103,14 +106,14 @@ static inline void mathIdentity(Matrix* m) } -static inline void mathScale(Matrix* m, float sx, float sy) +static inline void scale(Matrix* m, float sx, float sy) { m->e11 *= sx; m->e22 *= sy; } -static inline void mathScaleR(Matrix* m, float x, float y) +static inline void scaleR(Matrix* m, float x, float y) { if (x != 1.0f) { m->e11 *= x; @@ -123,14 +126,14 @@ static inline void mathScaleR(Matrix* m, float x, float y) } -static inline void mathTranslate(Matrix* m, float x, float y) +static inline void translate(Matrix* m, float x, float y) { m->e13 += x; m->e23 += y; } -static inline void mathTranslateR(Matrix* m, float x, float y) +static inline void translateR(Matrix* m, float x, float y) { if (x == 0.0f && y == 0.0f) return; m->e13 += (x * m->e11 + y * m->e12); @@ -150,7 +153,7 @@ static inline void operator*=(Matrix& lhs, const Matrix& rhs) } -static inline void mathLog(const Matrix& m) +static inline void log(const Matrix& m) { TVGLOG("COMMON", "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); } @@ -164,13 +167,13 @@ void operator*=(Point& pt, const Matrix& m); Point operator*(const Point& pt, const Matrix& m); -static inline bool mathZero(const Point& p) +static inline bool zero(const Point& p) { - return mathZero(p.x) && mathZero(p.y); + return tvg::zero(p.x) && tvg::zero(p.y); } -static inline float mathLength(const Point* a, const Point* b) +static inline float length(const Point* a, const Point* b) { auto x = b->x - a->x; auto y = b->y - a->y; @@ -182,7 +185,7 @@ static inline float mathLength(const Point* a, const Point* b) } -static inline float mathLength(const Point& a) +static inline float length(const Point& a) { return sqrtf(a.x * a.x + a.y * a.y); } @@ -190,7 +193,7 @@ 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); + return tvg::equal(lhs.x, rhs.x) && tvg::equal(lhs.y, rhs.y); } @@ -230,7 +233,7 @@ static inline Point operator/(const Point& lhs, const float rhs) } -static inline void mathLog(const Point& pt) +static inline void log(const Point& pt) { TVGLOG("COMMON", "Point: [%f %f]", pt.x, pt.y); } @@ -240,10 +243,11 @@ static inline void mathLog(const Point& pt) /************************************************************************/ template -static inline T mathLerp(const T &start, const T &end, float t) +static inline T lerp(const T &start, const T &end, float t) { return static_cast(start + (end - start) * t); } +} #endif //_TVG_MATH_H_ diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index 1028034a..f2a8f33e 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -105,7 +105,7 @@ static bool _draw(LottieGroup* parent, RenderContext* ctx); static void _rotateX(Matrix* m, float degree) { if (degree == 0.0f) return; - auto radian = mathDeg2Rad(degree); + auto radian = deg2rad(degree); m->e22 *= cosf(radian); } @@ -113,7 +113,7 @@ static void _rotateX(Matrix* m, float degree) static void _rotateY(Matrix* m, float degree) { if (degree == 0.0f) return; - auto radian = mathDeg2Rad(degree); + auto radian = deg2rad(degree); m->e11 *= cosf(radian); } @@ -121,7 +121,7 @@ static void _rotateY(Matrix* m, float degree) static void _rotationZ(Matrix* m, float degree) { if (degree == 0.0f) return; - auto radian = mathDeg2Rad(degree); + auto radian = deg2rad(degree); m->e11 = cosf(radian); m->e12 = -sinf(radian); m->e21 = sinf(radian); @@ -131,25 +131,25 @@ static void _rotationZ(Matrix* m, float degree) static void _skew(Matrix* m, float angleDeg, float axisDeg) { - auto angle = -mathDeg2Rad(angleDeg); + auto angle = -deg2rad(angleDeg); float tanVal = tanf(angle); axisDeg = fmod(axisDeg, 180.0f); if (fabsf(axisDeg) < 0.01f || fabsf(axisDeg - 180.0f) < 0.01f || fabsf(axisDeg + 180.0f) < 0.01f) { - float cosVal = cosf(mathDeg2Rad(axisDeg)); + float cosVal = cosf(deg2rad(axisDeg)); auto B = cosVal * cosVal * tanVal; m->e12 += B * m->e11; m->e22 += B * m->e21; return; } else if (fabsf(axisDeg - 90.0f) < 0.01f || fabsf(axisDeg + 90.0f) < 0.01f) { - float sinVal = -sinf(mathDeg2Rad(axisDeg)); + float sinVal = -sinf(deg2rad(axisDeg)); auto C = sinVal * sinVal * tanVal; m->e11 -= C * m->e12; m->e21 -= C * m->e22; return; } - auto axis = -mathDeg2Rad(axisDeg); + auto axis = -deg2rad(axisDeg); float cosVal = cosf(axis); float sinVal = sinf(axis); auto A = sinVal * cosVal * tanVal; @@ -167,7 +167,7 @@ static void _skew(Matrix* m, float angleDeg, float axisDeg) static bool _updateTransform(LottieTransform* transform, float frameNo, bool autoOrient, Matrix& matrix, uint8_t& opacity, LottieExpressions* exps) { - mathIdentity(&matrix); + identity(&matrix); if (!transform) { opacity = 255; @@ -175,10 +175,10 @@ static bool _updateTransform(LottieTransform* transform, float frameNo, bool aut } if (transform->coords) { - mathTranslate(&matrix, transform->coords->x(frameNo), transform->coords->y(frameNo)); + translate(&matrix, transform->coords->x(frameNo), transform->coords->y(frameNo)); } else { auto position = transform->position(frameNo, exps); - mathTranslate(&matrix, position.x, position.y); + translate(&matrix, position.x, position.y); } auto angle = 0.0f; @@ -200,11 +200,11 @@ static bool _updateTransform(LottieTransform* transform, float frameNo, bool aut } auto scale = transform->scale(frameNo, exps); - mathScaleR(&matrix, scale.x * 0.01f, scale.y * 0.01f); + scaleR(&matrix, scale.x * 0.01f, scale.y * 0.01f); //Lottie specific anchor transform. auto anchor = transform->anchor(frameNo, exps); - mathTranslateR(&matrix, -anchor.x, -anchor.y); + translateR(&matrix, -anchor.x, -anchor.y); //invisible just in case. if (scale.x == 0.0f || scale.y == 0.0f) opacity = 0; @@ -216,7 +216,7 @@ static bool _updateTransform(LottieTransform* transform, float frameNo, bool aut static void _updateTransform(LottieLayer* layer, float frameNo, LottieExpressions* exps) { - if (!layer || mathEqual(layer->cache.frameNo, frameNo)) return; + if (!layer || tvg::equal(layer->cache.frameNo, frameNo)) return; auto transform = layer->transform; auto parent = layer->parent; @@ -228,8 +228,8 @@ static void _updateTransform(LottieLayer* layer, float frameNo, LottieExpression _updateTransform(transform, frameNo, layer->autoOrient, matrix, layer->cache.opacity, exps); if (parent) { - if (!mathIdentity((const Matrix*) &parent->cache.matrix)) { - if (mathIdentity((const Matrix*) &matrix)) layer->cache.matrix = parent->cache.matrix; + if (!identity((const Matrix*) &parent->cache.matrix)) { + if (identity((const Matrix*) &matrix)) layer->cache.matrix = parent->cache.matrix; else layer->cache.matrix = parent->cache.matrix * matrix; } } @@ -406,22 +406,22 @@ static void _repeat(LottieGroup* parent, unique_ptr path, RenderContext* auto shape = static_cast((*propagator)->duplicate()); P(shape)->rs.path = P(path.get())->rs.path; - auto opacity = repeater->interpOpacity ? mathLerp(repeater->startOpacity, repeater->endOpacity, static_cast(i + 1) / repeater->cnt) : repeater->startOpacity; + auto opacity = repeater->interpOpacity ? lerp(repeater->startOpacity, repeater->endOpacity, static_cast(i + 1) / repeater->cnt) : repeater->startOpacity; shape->opacity(opacity); Matrix m; - mathIdentity(&m); - mathTranslate(&m, repeater->position.x * multiplier + repeater->anchor.x, repeater->position.y * multiplier + repeater->anchor.y); - mathScale(&m, powf(repeater->scale.x * 0.01f, multiplier), powf(repeater->scale.y * 0.01f, multiplier)); - mathRotate(&m, repeater->rotation * multiplier); - mathTranslateR(&m, -repeater->anchor.x, -repeater->anchor.y); + identity(&m); + translate(&m, repeater->position.x * multiplier + repeater->anchor.x, repeater->position.y * multiplier + repeater->anchor.y); + scale(&m, powf(repeater->scale.x * 0.01f, multiplier), powf(repeater->scale.y * 0.01f, multiplier)); + rotate(&m, repeater->rotation * multiplier); + translateR(&m, -repeater->anchor.x, -repeater->anchor.y); m = repeater->transform * m; auto pm = PP(shape)->transform(); if (pm) { - Matrix inverse; - mathInverse(&repeater->transform, &inverse); - *pm = inverse * *pm; + Matrix m; + inverse(&repeater->transform, &m); + *pm = m * *pm; } shape->transform(pm ? m * *pm : m); @@ -452,7 +452,7 @@ static void _repeat(LottieGroup* parent, unique_ptr path, RenderContext* static void _appendRect(Shape* shape, float x, float y, float w, float h, float r, Matrix* transform) { //sharp rect - if (mathZero(r)) { + if (tvg::zero(r)) { PathCommand commands[] = { PathCommand::MoveTo, PathCommand::LineTo, PathCommand::LineTo, PathCommand::LineTo, PathCommand::Close @@ -601,14 +601,14 @@ static void _applyRoundedCorner(Shape* star, Shape* merging, float outerRoundnes const Point *pts = nullptr; auto ptsCnt = star->pathCoords(&pts); - auto len = mathLength(pts[1] - pts[2]); + auto len = length(pts[1] - pts[2]); auto r = len > 0.0f ? ROUNDED_POLYSTAR_MAGIC_NUMBER * std::min(len * 0.5f, roundness) / len : 0.0f; if (hasRoundness) { P(merging)->rs.path.cmds.grow((uint32_t)(1.5 * cmdCnt)); P(merging)->rs.path.pts.grow((uint32_t)(4.5 * cmdCnt)); - int start = 3 * mathZero(outerRoundness); + int start = 3 * tvg::zero(outerRoundness); merging->moveTo(pts[start].x, pts[start].y); for (uint32_t i = 1 + start; i < ptsCnt; i += 6) { @@ -666,7 +666,7 @@ static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* trans auto innerRoundness = star->innerRoundness(frameNo, exps) * 0.01f; auto outerRoundness = star->outerRoundness(frameNo, exps) * 0.01f; - auto angle = mathDeg2Rad(-90.0f); + auto angle = deg2rad(-90.0f); auto partialPointRadius = 0.0f; auto anglePerPoint = (2.0f * MATH_PI / ptsCnt); auto halfAnglePerPoint = anglePerPoint * 0.5f; @@ -675,17 +675,17 @@ static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* trans auto numPoints = size_t(ceilf(ptsCnt) * 2); auto direction = (star->direction == 0) ? 1.0f : -1.0f; auto hasRoundness = false; - bool roundedCorner = (roundness > ROUNDNESS_EPSILON) && (mathZero(innerRoundness) || mathZero(outerRoundness)); + bool roundedCorner = (roundness > ROUNDNESS_EPSILON) && (tvg::zero(innerRoundness) || tvg::zero(outerRoundness)); //TODO: we can use PathCommand / PathCoord directly. auto shape = roundedCorner ? Shape::gen().release() : merging; float x, y; - if (!mathZero(partialPointAmount)) { + if (!tvg::zero(partialPointAmount)) { angle += halfAnglePerPoint * (1.0f - partialPointAmount) * direction; } - if (!mathZero(partialPointAmount)) { + if (!tvg::zero(partialPointAmount)) { partialPointRadius = innerRadius + partialPointAmount * (outerRadius - innerRadius); x = partialPointRadius * cosf(angle); y = partialPointRadius * sinf(angle); @@ -696,7 +696,7 @@ static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* trans angle += halfAnglePerPoint * direction; } - if (mathZero(innerRoundness) && mathZero(outerRoundness)) { + if (tvg::zero(innerRoundness) && tvg::zero(outerRoundness)) { P(shape)->rs.path.pts.reserve(numPoints + 2); P(shape)->rs.path.cmds.reserve(numPoints + 3); } else { @@ -712,10 +712,10 @@ static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* trans for (size_t i = 0; i < numPoints; i++) { auto radius = longSegment ? outerRadius : innerRadius; auto dTheta = halfAnglePerPoint; - if (!mathZero(partialPointRadius) && i == numPoints - 2) { + if (!tvg::zero(partialPointRadius) && i == numPoints - 2) { dTheta = anglePerPoint * partialPointAmount * 0.5f; } - if (!mathZero(partialPointRadius) && i == numPoints - 1) { + if (!tvg::zero(partialPointRadius) && i == numPoints - 1) { radius = partialPointRadius; } auto previousX = x; @@ -724,10 +724,10 @@ static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* trans y = radius * sinf(angle); if (hasRoundness) { - auto cp1Theta = (mathAtan2(previousY, previousX) - MATH_PI2 * direction); + auto cp1Theta = (tvg::atan2(previousY, previousX) - MATH_PI2 * direction); auto cp1Dx = cosf(cp1Theta); auto cp1Dy = sinf(cp1Theta); - auto cp2Theta = (mathAtan2(y, x) - MATH_PI2 * direction); + auto cp2Theta = (tvg::atan2(y, x) - MATH_PI2 * direction); auto cp2Dx = cosf(cp2Theta); auto cp2Dy = sinf(cp2Theta); @@ -741,7 +741,7 @@ static void _updateStar(LottieGroup* parent, LottiePolyStar* star, Matrix* trans auto cp2x = cp2Radius * cp2Roundness * POLYSTAR_MAGIC_NUMBER * cp2Dx / ptsCnt; auto cp2y = cp2Radius * cp2Roundness * POLYSTAR_MAGIC_NUMBER * cp2Dy / ptsCnt; - if (!mathZero(partialPointAmount) && ((i == 0) || (i == numPoints - 1))) { + if (!tvg::zero(partialPointAmount) && ((i == 0) || (i == numPoints - 1))) { cp1x *= partialPointAmount; cp1y *= partialPointAmount; cp2x *= partialPointAmount; @@ -781,7 +781,7 @@ static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* tr auto radius = star->outerRadius(frameNo, exps); auto roundness = star->outerRoundness(frameNo, exps) * 0.01f; - auto angle = mathDeg2Rad(-90.0f); + auto angle = deg2rad(-90.0f); auto anglePerPoint = 2.0f * MATH_PI / float(ptsCnt); auto direction = (star->direction == 0) ? 1.0f : -1.0f; auto hasRoundness = false; @@ -790,7 +790,7 @@ static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* tr angle += anglePerPoint * direction; - if (mathZero(roundness)) { + if (tvg::zero(roundness)) { P(merging)->rs.path.pts.reserve(ptsCnt + 2); P(merging)->rs.path.cmds.reserve(ptsCnt + 3); } else { @@ -810,10 +810,10 @@ static void _updatePolygon(LottieGroup* parent, LottiePolyStar* star, Matrix* tr y = (radius * sinf(angle)); if (hasRoundness) { - auto cp1Theta = mathAtan2(previousY, previousX) - MATH_PI2 * direction; + auto cp1Theta = tvg::atan2(previousY, previousX) - MATH_PI2 * direction; auto cp1Dx = cosf(cp1Theta); auto cp1Dy = sinf(cp1Theta); - auto cp2Theta = mathAtan2(y, x) - MATH_PI2 * direction; + auto cp2Theta = tvg::atan2(y, x) - MATH_PI2 * direction; auto cp2Dx = cosf(cp2Theta); auto cp2Dy = sinf(cp2Theta); @@ -848,14 +848,14 @@ static void _updatePolystar(LottieGroup* parent, LottieObject** child, float fra //Optimize: Can we skip the individual coords transform? Matrix matrix; - mathIdentity(&matrix); + identity(&matrix); auto position = star->position(frameNo, exps); - mathTranslate(&matrix, position.x, position.y); - mathRotate(&matrix, star->rotation(frameNo, exps)); + translate(&matrix, position.x, position.y); + rotate(&matrix, star->rotation(frameNo, exps)); if (ctx->transform) matrix = *ctx->transform * matrix; - auto identity = mathIdentity((const Matrix*)&matrix); + auto identity = tvg::identity((const Matrix*)&matrix); if (!ctx->repeaters.empty()) { auto p = Shape::gen(); @@ -886,7 +886,7 @@ static void _updateRepeater(TVG_UNUSED LottieGroup* parent, LottieObject** child RenderRepeater r; r.cnt = static_cast(repeater->copies(frameNo, exps)); if (auto tr = PP(ctx->propagator)->transform()) r.transform = *tr; - else mathIdentity(&r.transform); + else identity(&r.transform); r.offset = repeater->offset(frameNo, exps); r.position = repeater->position(frameNo, exps); r.anchor = repeater->anchor(frameNo, exps); diff --git a/src/loaders/lottie/tvgLottieExpressions.cpp b/src/loaders/lottie/tvgLottieExpressions.cpp index 4fa90ea2..879dcf79 100644 --- a/src/loaders/lottie/tvgLottieExpressions.cpp +++ b/src/loaders/lottie/tvgLottieExpressions.cpp @@ -358,7 +358,7 @@ static jerry_value_t _interp(float t, const jerry_value_t args[], int argsCnt) Point ret; if (t <= tMin) ret = pt1; else if (t >= tMax) ret = pt2; - else ret = mathLerp(pt1, pt2, t); + else ret = lerp(pt1, pt2, t); jerry_value_free(val1); jerry_value_free(val2); @@ -381,7 +381,7 @@ static jerry_value_t _interp(float t, const jerry_value_t args[], int argsCnt) if (t <= tMin) jerry_number(val1); auto val2 = (float) jerry_value_as_number(args[idx + 2]); if (t >= tMax) jerry_number(val2); - return jerry_number(mathLerp(val1, val2, t)); + return jerry_number(lerp(val1, val2, t)); } @@ -519,13 +519,13 @@ static jerry_value_t _random(const jerry_call_info_t* info, const jerry_value_t static jerry_value_t _deg2rad(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) { - return jerry_number(mathDeg2Rad((float)jerry_value_as_number(args[0]))); + return jerry_number(deg2rad((float)jerry_value_as_number(args[0]))); } static jerry_value_t _rad2deg(const jerry_call_info_t* info, const jerry_value_t args[], const jerry_length_t argsCnt) { - return jerry_number(mathRad2Deg((float)jerry_value_as_number(args[0]))); + return jerry_number(rad2deg((float)jerry_value_as_number(args[0]))); } diff --git a/src/loaders/lottie/tvgLottieModel.cpp b/src/loaders/lottie/tvgLottieModel.cpp index 80f312e8..08865e1b 100644 --- a/src/loaders/lottie/tvgLottieModel.cpp +++ b/src/loaders/lottie/tvgLottieModel.cpp @@ -126,12 +126,12 @@ void LottieTrimpath::segment(float frameNo, float& start, float& end, LottieExpr auto o = fmodf(this->offset(frameNo, exps), 360.0f) / 360.0f; //0 ~ 1 auto diff = fabs(start - end); - if (mathZero(diff)) { + if (tvg::zero(diff)) { start = 0.0f; end = 0.0f; return; } - if (mathEqual(diff, 1.0f) || mathEqual(diff, 2.0f)) { + if (tvg::equal(diff, 1.0f) || tvg::equal(diff, 2.0f)) { start = 0.0f; end = 1.0f; return; @@ -174,7 +174,7 @@ uint32_t LottieGradient::populate(ColorStop& color) //generate alpha value if (output.count > 0) { auto p = ((*color.input)[cidx] - output.last().offset) / ((*color.input)[aidx] - output.last().offset); - cs.a = mathLerp(output.last().a, lroundf((*color.input)[aidx + 1] * 255.0f), p); + cs.a = lerp(output.last().a, lroundf((*color.input)[aidx + 1] * 255.0f), p); } else cs.a = 255; cidx += 4; } else { @@ -183,9 +183,9 @@ uint32_t LottieGradient::populate(ColorStop& color) //generate color value if (output.count > 0) { auto p = ((*color.input)[aidx] - output.last().offset) / ((*color.input)[cidx] - output.last().offset); - cs.r = mathLerp(output.last().r, lroundf((*color.input)[cidx + 1] * 255.0f), p); - cs.g = mathLerp(output.last().g, lroundf((*color.input)[cidx + 2] * 255.0f), p); - cs.b = mathLerp(output.last().b, lroundf((*color.input)[cidx + 3] * 255.0f), p); + cs.r = lerp(output.last().r, lroundf((*color.input)[cidx + 1] * 255.0f), p); + cs.g = lerp(output.last().g, lroundf((*color.input)[cidx + 2] * 255.0f), p); + cs.b = lerp(output.last().b, lroundf((*color.input)[cidx + 3] * 255.0f), p); } else cs.r = cs.g = cs.b = 255; aidx += 2; } @@ -246,12 +246,12 @@ Fill* LottieGradient::fill(float frameNo, LottieExpressions* exps) auto r = (w > h) ? (w + 0.375f * h) : (h + 0.375f * w); auto progress = this->height(frameNo, exps) * 0.01f; - if (mathZero(progress)) { + if (tvg::zero(progress)) { P(static_cast(fill))->radial(s.x, s.y, r, s.x, s.y, 0.0f); } else { - if (mathEqual(progress, 1.0f)) progress = 0.99f; - auto startAngle = mathRad2Deg(mathAtan2(e.y - s.y, e.x - s.x)); - auto angle = mathDeg2Rad((startAngle + this->angle(frameNo, exps))); + if (tvg::equal(progress, 1.0f)) progress = 0.99f; + auto startAngle = rad2deg(tvg::atan2(e.y - s.y, e.x - s.x)); + auto angle = deg2rad((startAngle + this->angle(frameNo, exps))); auto fx = s.x + cos(angle) * progress * r; auto fy = s.y + sin(angle) * progress * r; // Lottie doesn't have any focal radius concept diff --git a/src/loaders/lottie/tvgLottieProperty.h b/src/loaders/lottie/tvgLottieProperty.h index f77549b3..13deb18f 100644 --- a/src/loaders/lottie/tvgLottieProperty.h +++ b/src/loaders/lottie/tvgLottieProperty.h @@ -117,7 +117,7 @@ struct LottieScalarFrame if (t < 1.0f) return value; else return next->value; } - return mathLerp(value, next->value, t); + return lerp(value, next->value, t); } }; @@ -148,7 +148,7 @@ struct LottieVectorFrame t = bezAtApprox(bz, t * length, length); return bezPointAt(bz, t); } else { - return mathLerp(value, next->value, t); + return lerp(value, next->value, t); } } @@ -156,7 +156,7 @@ struct LottieVectorFrame { if (!hasTangent) { Point dp = next->value - value; - return mathRad2Deg(mathAtan2(dp.y, dp.x)); + return rad2deg(tvg::atan2(dp.y, dp.x)); } auto t = (frameNo - no) / (next->no - no); @@ -246,9 +246,9 @@ static void _copy(PathSet* pathset, Array& outCmds) static void _roundCorner(Array& cmds, Array& pts, const Point& prev, const Point& curr, const Point& next, float roundness) { - auto lenPrev = mathLength(prev - curr); + auto lenPrev = length(prev - curr); auto rPrev = lenPrev > 0.0f ? 0.5f * std::min(lenPrev * 0.5f, roundness) / lenPrev : 0.0f; - auto lenNext = mathLength(next - curr); + auto lenNext = length(next - curr); auto rNext = lenNext > 0.0f ? 0.5f * std::min(lenNext * 0.5f, roundness) / lenNext : 0.0f; auto dPrev = rPrev * (curr - prev); @@ -282,11 +282,11 @@ static bool _modifier(Point* inPts, uint32_t inPtsCnt, PathCommand* inCmds, uint auto& prev = inPts[iPts - 1]; auto& curr = inPts[iPts + 2]; if (iCmds < inCmdsCnt - 1 && - mathZero(inPts[iPts - 1] - inPts[iPts]) && - mathZero(inPts[iPts + 1] - inPts[iPts + 2])) { + tvg::zero(inPts[iPts - 1] - inPts[iPts]) && + tvg::zero(inPts[iPts + 1] - inPts[iPts + 2])) { if (inCmds[iCmds + 1] == PathCommand::CubicTo && - mathZero(inPts[iPts + 2] - inPts[iPts + 3]) && - mathZero(inPts[iPts + 4] - inPts[iPts + 5])) { + tvg::zero(inPts[iPts + 2] - inPts[iPts + 3]) && + tvg::zero(inPts[iPts + 4] - inPts[iPts + 5])) { _roundCorner(cmds, pts, prev, curr, inPts[iPts + 5], roundness); iPts += 3; break; @@ -443,7 +443,7 @@ struct LottieGenericProperty : LottieProperty if (frameNo >= frames->last().no) return frames->last().value; auto frame = frames->data + _bsearch(frames, frameNo); - if (mathEqual(frame->no, frameNo)) return frame->value; + if (tvg::equal(frame->no, frameNo)) return frame->value; return frame->interpolate(frame + 1, frameNo); } @@ -548,7 +548,7 @@ struct LottiePathSet : LottieProperty else if (frameNo >= frames->last().no) path = &frames->last().value; else { frame = frames->data + _bsearch(frames, frameNo); - if (mathEqual(frame->no, frameNo)) path = &frame->value; + if (tvg::equal(frame->no, frameNo)) path = &frame->value; else if (frame->value.ptsCnt != (frame + 1)->value.ptsCnt) { path = &frame->value; TVGLOG("LOTTIE", "Different numbers of points in consecutive frames - interpolation omitted."); @@ -574,7 +574,7 @@ struct LottiePathSet : LottieProperty auto interpPts = (Point*)malloc(frame->value.ptsCnt * sizeof(Point)); auto p = interpPts; for (auto i = 0; i < frame->value.ptsCnt; ++i, ++s, ++e, ++p) { - *p = mathLerp(*s, *e, t); + *p = lerp(*s, *e, t); if (transform) *p *= *transform; } _modifier(interpPts, frame->value.ptsCnt, frame->value.cmds, frame->value.cmdsCnt, cmds, pts, nullptr, roundness); @@ -582,7 +582,7 @@ struct LottiePathSet : LottieProperty return true; } else { for (auto i = 0; i < frame->value.ptsCnt; ++i, ++s, ++e) { - auto pt = mathLerp(*s, *e, t); + auto pt = lerp(*s, *e, t); if (transform) pt *= *transform; pts.push(pt); } @@ -689,7 +689,7 @@ struct LottieColorStop : LottieProperty if (frameNo >= frames->last().no) return fill->colorStops(frames->last().value.data, count); auto frame = frames->data + _bsearch(frames, frameNo); - if (mathEqual(frame->no, frameNo)) return fill->colorStops(frame->value.data, count); + if (tvg::equal(frame->no, frameNo)) return fill->colorStops(frame->value.data, count); //interpolate auto t = (frameNo - frame->no) / ((frame + 1)->no - frame->no); @@ -706,11 +706,11 @@ struct LottieColorStop : LottieProperty Array result; for (auto i = 0; i < count; ++i, ++s, ++e) { - auto offset = mathLerp(s->offset, e->offset, t); - auto r = mathLerp(s->r, e->r, t); - auto g = mathLerp(s->g, e->g, t); - auto b = mathLerp(s->b, e->b, t); - auto a = mathLerp(s->a, e->a, t); + auto offset = lerp(s->offset, e->offset, t); + auto r = lerp(s->r, e->r, t); + auto g = lerp(s->g, e->g, t); + auto b = lerp(s->b, e->b, t); + auto a = lerp(s->a, e->a, t); result.push({offset, r, g, b, a}); } return fill->colorStops(result.data, count); @@ -800,7 +800,7 @@ struct LottiePosition : LottieProperty if (frameNo >= frames->last().no) return frames->last().value; auto frame = frames->data + _bsearch(frames, frameNo); - if (mathEqual(frame->no, frameNo)) return frame->value; + if (tvg::equal(frame->no, frameNo)) return frame->value; return frame->interpolate(frame + 1, frameNo); } diff --git a/src/loaders/svg/tvgSvgLoader.cpp b/src/loaders/svg/tvgSvgLoader.cpp index b610feb3..cf632b05 100644 --- a/src/loaders/svg/tvgSvgLoader.cpp +++ b/src/loaders/svg/tvgSvgLoader.cpp @@ -588,15 +588,15 @@ static bool _hslToRgb(float hue, float saturation, float brightness, uint8_t* re float _red = 0, _green = 0, _blue = 0; uint32_t i = 0; - if (mathZero(saturation)) _red = _green = _blue = brightness; + if (tvg::zero(saturation)) _red = _green = _blue = brightness; else { - if (mathEqual(hue, 360.0)) hue = 0.0f; + if (tvg::equal(hue, 360.0)) hue = 0.0f; hue /= 60.0f; v = (brightness <= 0.5f) ? (brightness * (1.0f + saturation)) : (brightness + saturation - (brightness * saturation)); p = brightness + brightness - v; - if (!mathZero(v)) sv = (v - p) / v; + if (!tvg::zero(v)) sv = (v - p) / v; else sv = 0; i = static_cast(hue); @@ -853,8 +853,8 @@ static Matrix* _parseTransformationMatrix(const char* value) //Transform to signed. points[0] = fmodf(points[0], 360.0f); if (points[0] < 0) points[0] += 360.0f; - auto c = cosf(mathDeg2Rad(points[0])); - auto s = sinf(mathDeg2Rad(points[0])); + auto c = cosf(deg2rad(points[0])); + auto s = sinf(deg2rad(points[0])); if (ptCount == 1) { Matrix tmp = { c, -s, 0, s, c, 0, 0, 0, 1 }; *matrix *= tmp; @@ -877,12 +877,12 @@ static Matrix* _parseTransformationMatrix(const char* value) *matrix *= tmp; } else if (state == MatrixState::SkewX) { if (ptCount != 1) goto error; - auto deg = tanf(mathDeg2Rad(points[0])); + auto deg = tanf(deg2rad(points[0])); Matrix tmp = { 1, deg, 0, 0, 1, 0, 0, 0, 1 }; *matrix *= tmp; } else if (state == MatrixState::SkewY) { if (ptCount != 1) goto error; - auto deg = tanf(mathDeg2Rad(points[0])); + auto deg = tanf(deg2rad(points[0])); Matrix tmp = { 1, 0, 0, deg, 1, 0, 0, 0, 1 }; *matrix *= tmp; } diff --git a/src/loaders/svg/tvgSvgPath.cpp b/src/loaders/svg/tvgSvgPath.cpp index c6ed978d..57442139 100644 --- a/src/loaders/svg/tvgSvgPath.cpp +++ b/src/loaders/svg/tvgSvgPath.cpp @@ -126,7 +126,7 @@ void _pathAppendArcTo(Array* cmds, Array* pts, Point* cur, P rx = fabsf(rx); ry = fabsf(ry); - angle = mathDeg2Rad(angle); + angle = deg2rad(angle); cosPhi = cosf(angle); sinPhi = sinf(angle); dx2 = (sx - x) / 2.0f; @@ -194,10 +194,10 @@ void _pathAppendArcTo(Array* cmds, Array* pts, Point* cur, P //We dont' use arccos (as per w3c doc), see //http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm //Note: atan2 (0.0, 1.0) == 0.0 - at = mathAtan2(((y1p - cyp) / ry), ((x1p - cxp) / rx)); + at = tvg::atan2(((y1p - cyp) / ry), ((x1p - cxp) / rx)); theta1 = (at < 0.0f) ? 2.0f * MATH_PI + at : at; - nat = mathAtan2(((-y1p - cyp) / ry), ((-x1p - cxp) / rx)); + nat = tvg::atan2(((-y1p - cyp) / ry), ((-x1p - cxp) / rx)); deltaTheta = (nat < at) ? 2.0f * MATH_PI - at + nat : nat - at; if (sweep) { @@ -469,12 +469,12 @@ static bool _processCommand(Array* cmds, Array* pts, char cm } case 'a': case 'A': { - if (mathZero(arr[0]) || mathZero(arr[1])) { + if (tvg::zero(arr[0]) || tvg::zero(arr[1])) { Point p = {arr[5], arr[6]}; cmds->push(PathCommand::LineTo); pts->push(p); *cur = {arr[5], arr[6]}; - } else if (!mathEqual(cur->x, arr[5]) || !mathEqual(cur->y, arr[6])) { + } else if (!tvg::equal(cur->x, arr[5]) || !tvg::equal(cur->y, arr[6])) { _pathAppendArcTo(cmds, pts, cur, curCtl, arr[5], arr[6], fabsf(arr[0]), fabsf(arr[1]), arr[2], arr[3], arr[4]); *cur = *curCtl = {arr[5], arr[6]}; *isQuadratic = false; diff --git a/src/loaders/svg/tvgSvgSceneBuilder.cpp b/src/loaders/svg/tvgSvgSceneBuilder.cpp index c25ae833..e95090cf 100644 --- a/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -215,7 +215,7 @@ static bool _appendClipUseNode(SvgLoaderData& loaderData, SvgNode* node, Shape* } 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, identity((const Matrix*)(&finalTransform)) ? nullptr : &finalTransform); } @@ -736,10 +736,10 @@ static unique_ptr _useBuildHelper(SvgLoaderData& loaderData, const SvgNod auto vh = (symbol.hasViewBox ? symbol.vh : height); Matrix mViewBox = {1, 0, 0, 0, 1, 0, 0, 0, 1}; - if ((!mathEqual(width, vw) || !mathEqual(height, vh)) && vw > 0 && vh > 0) { + if ((!tvg::equal(width, vw) || !tvg::equal(height, vh)) && vw > 0 && vh > 0) { Box box = {symbol.vx, symbol.vy, vw, vh}; mViewBox = _calculateAspectRatioMatrix(symbol.align, symbol.meetOrSlice, width, height, box); - } else if (!mathZero(symbol.vx) || !mathZero(symbol.vy)) { + } else if (!tvg::zero(symbol.vx) || !tvg::zero(symbol.vy)) { mViewBox = {1, 0, -symbol.vx, 0, 1, -symbol.vy, 0, 0, 1}; } @@ -821,7 +821,7 @@ static unique_ptr _textBuildHelper(SvgLoaderData& loaderData, const SvgNod Matrix textTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1}; if (node->transform) textTransform = *node->transform; - mathTranslateR(&textTransform, node->node.text.x, node->node.text.y - textNode->fontSize); + translateR(&textTransform, node->node.text.x, node->node.text.y - textNode->fontSize); text->transform(textTransform); //TODO: handle def values of font and size as used in a system? @@ -926,10 +926,10 @@ Scene* svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, float h, Aspe if (!(viewFlag & SvgViewFlag::Viewbox)) _updateInvalidViewSize(docNode.get(), vBox, w, h, viewFlag); - if (!mathEqual(w, vBox.w) || !mathEqual(h, vBox.h)) { + if (!tvg::equal(w, vBox.w) || !tvg::equal(h, vBox.h)) { Matrix m = _calculateAspectRatioMatrix(align, meetOrSlice, w, h, vBox); docNode->transform(m); - } else if (!mathZero(vBox.x) || !mathZero(vBox.y)) { + } else if (!tvg::zero(vBox.x) || !tvg::zero(vBox.y)) { docNode->translate(-vBox.x, -vBox.y); } diff --git a/src/renderer/gl_engine/tvgGlGeometry.cpp b/src/renderer/gl_engine/tvgGlGeometry.cpp index fc6d1a09..09ff35d5 100644 --- a/src/renderer/gl_engine/tvgGlGeometry.cpp +++ b/src/renderer/gl_engine/tvgGlGeometry.cpp @@ -253,7 +253,7 @@ GlStencilMode GlGeometry::getStencilMode(RenderUpdateFlag flag) RenderRegion GlGeometry::getBounds() const { - if (mathIdentity(&mMatrix)) { + if (identity(&mMatrix)) { return mBounds; } else { Point lt{static_cast(mBounds.x), static_cast(mBounds.y)}; diff --git a/src/renderer/gl_engine/tvgGlRenderPass.cpp b/src/renderer/gl_engine/tvgGlRenderPass.cpp index 934cbffb..2ed90719 100644 --- a/src/renderer/gl_engine/tvgGlRenderPass.cpp +++ b/src/renderer/gl_engine/tvgGlRenderPass.cpp @@ -58,8 +58,8 @@ void GlRenderPass::getMatrix(float *dst, const Matrix &matrix) const const auto& vp = getViewport(); Matrix postMatrix{}; - mathIdentity(&postMatrix); - mathTranslate(&postMatrix, -vp.x, -vp.y); + identity(&postMatrix); + translate(&postMatrix, -vp.x, -vp.y); auto m = postMatrix * matrix; diff --git a/src/renderer/gl_engine/tvgGlRenderer.cpp b/src/renderer/gl_engine/tvgGlRenderer.cpp index 433213f7..66fef3d5 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.cpp +++ b/src/renderer/gl_engine/tvgGlRenderer.cpp @@ -253,9 +253,9 @@ void GlRenderer::drawPrimitive(GlShape& sdata, const Fill* fill, RenderUpdateFla auto gradientTransform = fill->transform(); float invMat4[16]; - if (!mathIdentity(const_cast(&gradientTransform))) { + if (!identity(const_cast(&gradientTransform))) { Matrix inv{}; - mathInverse(&gradientTransform , &inv); + inverse(&gradientTransform , &inv); GET_MATRIX44(inv, invMat4); } else { diff --git a/src/renderer/gl_engine/tvgGlTessellator.cpp b/src/renderer/gl_engine/tvgGlTessellator.cpp index 7069ab0d..92df1af2 100644 --- a/src/renderer/gl_engine/tvgGlTessellator.cpp +++ b/src/renderer/gl_engine/tvgGlTessellator.cpp @@ -781,7 +781,7 @@ static int32_t _bezierCurveCount(const Bezier &curve) static Bezier _bezFromArc(const GlPoint& start, const GlPoint& end, float radius) { // Calculate the angle between the start and end points - float angle = mathAtan2(end.y - start.y, end.x - start.x); + float angle = tvg::atan2(end.y - start.y, end.x - start.x); // Calculate the control points of the cubic bezier curve float c = radius * 0.552284749831; // c = radius * (4/3) * tan(pi/8) diff --git a/src/renderer/sw_engine/tvgSwFill.cpp b/src/renderer/sw_engine/tvgSwFill.cpp index a11a9dfa..485b7144 100644 --- a/src/renderer/sw_engine/tvgSwFill.cpp +++ b/src/renderer/sw_engine/tvgSwFill.cpp @@ -68,13 +68,13 @@ static uint32_t _estimateAAMargin(const Fill* fdata) constexpr float marginScalingFactor = 800.0f; if (fdata->type() == Type::RadialGradient) { auto radius = P(static_cast(fdata))->r; - return mathZero(radius) ? 0 : static_cast(marginScalingFactor / radius); + return tvg::zero(radius) ? 0 : static_cast(marginScalingFactor / radius); } auto grad = P(static_cast(fdata)); Point p1 {grad->x1, grad->y1}; Point p2 {grad->x2, grad->y2}; - auto length = mathLength(&p1, &p2); - return mathZero(length) ? 0 : static_cast(marginScalingFactor / length); + auto len = length(&p1, &p2); + return tvg::zero(len) ? 0 : static_cast(marginScalingFactor / len); } @@ -221,7 +221,7 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* tr fill->linear.offset = -fill->linear.dx * x1 - fill->linear.dy * y1; auto gradTransform = linear->transform(); - bool isTransformation = !mathIdentity((const Matrix*)(&gradTransform)); + bool isTransformation = !identity((const Matrix*)(&gradTransform)); if (isTransformation) { if (transform) gradTransform = *transform * gradTransform; @@ -232,7 +232,7 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* tr if (isTransformation) { Matrix invTransform; - if (!mathInverse(&gradTransform, &invTransform)) return false; + if (!inverse(&gradTransform, &invTransform)) return false; fill->linear.offset += fill->linear.dx * invTransform.e13 + fill->linear.dy * invTransform.e23; @@ -287,7 +287,7 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* tr if (fill->radial.a > 0) fill->radial.invA = 1.0f / fill->radial.a; auto gradTransform = radial->transform(); - bool isTransformation = !mathIdentity((const Matrix*)(&gradTransform)); + bool isTransformation = !identity((const Matrix*)(&gradTransform)); if (transform) { if (isTransformation) gradTransform = *transform * gradTransform; @@ -299,7 +299,7 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* tr if (isTransformation) { Matrix invTransform; - if (!mathInverse(&gradTransform, &invTransform)) return false; + if (!inverse(&gradTransform, &invTransform)) return false; fill->radial.a11 = invTransform.e11; fill->radial.a12 = invTransform.e12; fill->radial.a13 = invTransform.e13; @@ -547,7 +547,7 @@ void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3 float inc = (fill->linear.dx) * (GRADIENT_STOP_SIZE - 1); if (opacity == 255) { - if (mathZero(inc)) { + if (tvg::zero(inc)) { auto color = _fixedPixel(fill, static_cast(t * FIXPT_SIZE)); for (uint32_t i = 0; i < len; ++i, ++dst, cmp += csize) { *dst = opBlendNormal(color, *dst, alpha(cmp)); @@ -578,7 +578,7 @@ void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3 } } } else { - if (mathZero(inc)) { + if (tvg::zero(inc)) { auto color = _fixedPixel(fill, static_cast(t * FIXPT_SIZE)); for (uint32_t i = 0; i < len; ++i, ++dst, cmp += csize) { *dst = opBlendNormal(color, *dst, MULTIPLY(alpha(cmp), opacity)); @@ -620,7 +620,7 @@ void fillLinear(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32 float t = (fill->linear.dx * rx + fill->linear.dy * ry + fill->linear.offset) * (GRADIENT_STOP_SIZE - 1); float inc = (fill->linear.dx) * (GRADIENT_STOP_SIZE - 1); - if (mathZero(inc)) { + if (tvg::zero(inc)) { auto src = MULTIPLY(a, A(_fixedPixel(fill, static_cast(t * FIXPT_SIZE)))); for (uint32_t i = 0; i < len; ++i, ++dst) { *dst = maskOp(src, *dst, ~src); @@ -662,7 +662,7 @@ void fillLinear(const SwFill* fill, uint8_t* dst, uint32_t y, uint32_t x, uint32 float t = (fill->linear.dx * rx + fill->linear.dy * ry + fill->linear.offset) * (GRADIENT_STOP_SIZE - 1); float inc = (fill->linear.dx) * (GRADIENT_STOP_SIZE - 1); - if (mathZero(inc)) { + if (tvg::zero(inc)) { auto src = A(_fixedPixel(fill, static_cast(t * FIXPT_SIZE))); src = MULTIPLY(src, a); for (uint32_t i = 0; i < len; ++i, ++dst, ++cmp) { @@ -709,7 +709,7 @@ void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3 float t = (fill->linear.dx * rx + fill->linear.dy * ry + fill->linear.offset) * (GRADIENT_STOP_SIZE - 1); float inc = (fill->linear.dx) * (GRADIENT_STOP_SIZE - 1); - if (mathZero(inc)) { + if (tvg::zero(inc)) { auto color = _fixedPixel(fill, static_cast(t * FIXPT_SIZE)); for (uint32_t i = 0; i < len; ++i, ++dst) { *dst = op(color, *dst, a); @@ -749,7 +749,7 @@ void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3 float t = (fill->linear.dx * rx + fill->linear.dy * ry + fill->linear.offset) * (GRADIENT_STOP_SIZE - 1); float inc = (fill->linear.dx) * (GRADIENT_STOP_SIZE - 1); - if (mathZero(inc)) { + if (tvg::zero(inc)) { auto color = _fixedPixel(fill, static_cast(t * FIXPT_SIZE)); if (a == 255) { for (uint32_t i = 0; i < len; ++i, ++dst) { diff --git a/src/renderer/sw_engine/tvgSwImage.cpp b/src/renderer/sw_engine/tvgSwImage.cpp index c1629455..9290172d 100644 --- a/src/renderer/sw_engine/tvgSwImage.cpp +++ b/src/renderer/sw_engine/tvgSwImage.cpp @@ -29,7 +29,7 @@ static inline bool _onlyShifted(const Matrix* m) { - if (mathEqual(m->e11, 1.0f) && mathEqual(m->e22, 1.0f) && mathZero(m->e12) && mathZero(m->e21)) return true; + if (tvg::equal(m->e11, 1.0f) && tvg::equal(m->e22, 1.0f) && tvg::zero(m->e12) && tvg::zero(m->e21)) return true; return false; } @@ -122,7 +122,7 @@ bool imagePrepare(SwImage* image, const RenderMesh* mesh, const Matrix* transfor auto scaleY = sqrtf((transform->e22 * transform->e22) + (transform->e12 * transform->e12)); image->scale = (fabsf(scaleX - scaleY) > 0.01f) ? 1.0f : scaleX; - if (mathZero(transform->e12) && mathZero(transform->e21)) image->scaled = true; + if (tvg::zero(transform->e12) && tvg::zero(transform->e21)) image->scaled = true; else image->scaled = false; } diff --git a/src/renderer/sw_engine/tvgSwMath.cpp b/src/renderer/sw_engine/tvgSwMath.cpp index b48be7a7..eef0d850 100644 --- a/src/renderer/sw_engine/tvgSwMath.cpp +++ b/src/renderer/sw_engine/tvgSwMath.cpp @@ -179,7 +179,7 @@ SwFixed mathTan(SwFixed angle) SwFixed mathAtan(const SwPoint& pt) { if (pt.zero()) return 0; - return SwFixed(mathAtan2(TO_FLOAT(pt.y), TO_FLOAT(pt.x)) * (180.0f / MATH_PI) * 65536.0f); + return SwFixed(tvg::atan2(TO_FLOAT(pt.y), TO_FLOAT(pt.x)) * (180.0f / MATH_PI) * 65536.0f); } diff --git a/src/renderer/sw_engine/tvgSwRaster.cpp b/src/renderer/sw_engine/tvgSwRaster.cpp index b5bd2005..863e3616 100644 --- a/src/renderer/sw_engine/tvgSwRaster.cpp +++ b/src/renderer/sw_engine/tvgSwRaster.cpp @@ -841,8 +841,8 @@ static bool _scaledRleImage(SwSurface* surface, const SwImage* image, const Matr Matrix itransform; if (transform) { - if (!mathInverse(transform, &itransform)) return false; - } else mathIdentity(&itransform); + if (!inverse(transform, &itransform)) return false; + } else identity(&itransform); if (_compositing(surface)) { if (_matting(surface)) return _rasterScaledMattedRleImage(surface, image, &itransform, region, opacity); @@ -1201,8 +1201,8 @@ static bool _scaledImage(SwSurface* surface, const SwImage* image, const Matrix* Matrix itransform; if (transform) { - if (!mathInverse(transform, &itransform)) return false; - } else mathIdentity(&itransform); + if (!inverse(transform, &itransform)) return false; + } else identity(&itransform); if (_compositing(surface)) { if (_matting(surface)) return _rasterScaledMattedImage(surface, image, &itransform, region, opacity); diff --git a/src/renderer/sw_engine/tvgSwRasterTexmap.h b/src/renderer/sw_engine/tvgSwRasterTexmap.h index cfce7785..23cf4ef1 100644 --- a/src/renderer/sw_engine/tvgSwRasterTexmap.h +++ b/src/renderer/sw_engine/tvgSwRasterTexmap.h @@ -675,7 +675,7 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const auto denom = ((x[2] - x[0]) * (y[1] - y[0]) - (x[1] - x[0]) * (y[2] - y[0])); //Skip poly if it's an infinitely thin line - if (mathZero(denom)) return; + if (tvg::zero(denom)) return; denom = 1 / denom; //Reciprocal for speeding up dudx = ((u[2] - u[0]) * (y[1] - y[0]) - (u[1] - u[0]) * (y[2] - y[0])) * denom; @@ -691,8 +691,8 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const //Determine which side of the polygon the longer edge is on auto side = (dxdy[1] > dxdy[0]) ? true : false; - if (mathEqual(y[0], y[1])) side = x[0] > x[1]; - if (mathEqual(y[1], y[2])) side = x[2] > x[1]; + if (tvg::equal(y[0], y[1])) side = x[0] > x[1]; + if (tvg::equal(y[1], y[2])) side = x[2] > x[1]; auto regionTop = region ? region->min.y : image->rle->spans->y; //Normal Image or Rle Image? auto compositing = _compositing(surface); //Composition required diff --git a/src/renderer/sw_engine/tvgSwRenderer.cpp b/src/renderer/sw_engine/tvgSwRenderer.cpp index 3d8b5529..a945b655 100644 --- a/src/renderer/sw_engine/tvgSwRenderer.cpp +++ b/src/renderer/sw_engine/tvgSwRenderer.cpp @@ -95,10 +95,10 @@ struct SwShapeTask : SwTask if (!rshape->stroke) return 0.0f; auto width = rshape->stroke->width; - if (mathZero(width)) return 0.0f; + if (tvg::zero(width)) return 0.0f; if (!rshape->stroke->fill && (MULTIPLY(rshape->stroke->color[3], opacity) == 0)) return 0.0f; - if (mathZero(rshape->stroke->trim.begin - rshape->stroke->trim.end)) return 0.0f; + if (tvg::zero(rshape->stroke->trim.begin - rshape->stroke->trim.end)) return 0.0f; if (transform) return (width * sqrt(transform->e11 * transform->e11 + transform->e12 * transform->e12)); else return width; diff --git a/src/renderer/sw_engine/tvgSwShape.cpp b/src/renderer/sw_engine/tvgSwShape.cpp index 4f069ece..87b99aa0 100644 --- a/src/renderer/sw_engine/tvgSwShape.cpp +++ b/src/renderer/sw_engine/tvgSwShape.cpp @@ -104,7 +104,7 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* trans Line cur = {dash.ptCur, *to}; auto len = lineLength(cur.pt1, cur.pt2); - if (mathZero(len)) { + if (tvg::zero(len)) { _outlineMoveTo(*dash.outline, &dash.ptCur, transform); //draw the current line fully } else if (len <= dash.curLen) { @@ -166,7 +166,7 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct auto len = bezLength(cur); //draw the current line fully - if (mathZero(len)) { + if (tvg::zero(len)) { _outlineMoveTo(*dash.outline, &dash.ptCur, transform); } else if (len <= dash.curLen) { dash.curLen -= len; @@ -284,7 +284,7 @@ static float _outlineLength(const RenderShape* rshape, uint32_t shiftPts, uint32 if (cmdCnt <= 0 || ptsCnt <= 0) return 0.0f; const Point* close = nullptr; - auto length = 0.0f; + auto len = 0.0f; //must begin with moveTo if (cmds[0] == PathCommand::MoveTo) { @@ -297,30 +297,30 @@ static float _outlineLength(const RenderShape* rshape, uint32_t shiftPts, uint32 while (cmdCnt-- > 0) { switch (*cmds) { case PathCommand::Close: { - length += mathLength(pts - 1, close); - if (subpath) return length; + len += length(pts - 1, close); + if (subpath) return len; break; } case PathCommand::MoveTo: { - if (subpath) return length; + if (subpath) return len; close = pts; ++pts; break; } case PathCommand::LineTo: { - length += mathLength(pts - 1, pts); + len += length(pts - 1, pts); ++pts; break; } case PathCommand::CubicTo: { - length += bezLength({*(pts - 1), *pts, *(pts + 1), *(pts + 2)}); + len += bezLength({*(pts - 1), *pts, *(pts + 1), *(pts + 2)}); pts += 3; break; } } ++cmds; } - return length; + return len; } @@ -353,7 +353,7 @@ static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* trans //offset auto patternLength = 0.0f; uint32_t offIdx = 0; - if (!mathZero(offset)) { + if (!tvg::zero(offset)) { for (size_t i = 0; i < dash.cnt; ++i) patternLength += dash.pattern[i]; bool isOdd = dash.cnt % 2; if (isOdd) patternLength *= 2; diff --git a/src/renderer/tvgPaint.cpp b/src/renderer/tvgPaint.cpp index fe69283e..57d7fccb 100644 --- a/src/renderer/tvgPaint.cpp +++ b/src/renderer/tvgPaint.cpp @@ -92,8 +92,8 @@ static Result _compFastTrack(RenderMethod* renderer, Paint* cmpTarget, const Ren //No rotation and no skewing, still can try out clipping the rect region. auto tryClip = false; - if (pTransform && (!mathRightAngle(&pTransform->m) || mathSkewed(&pTransform->m))) tryClip = true; - if (rTransform && (!mathRightAngle(&rTransform->m) || mathSkewed(&rTransform->m))) tryClip = true; + if (pTransform && (!rightAngle(&pTransform->m) || skewed(&pTransform->m))) tryClip = true; + if (rTransform && (!rightAngle(&rTransform->m) || skewed(&rTransform->m))) tryClip = true; if (tryClip) return _clipRect(renderer, pts, pTransform, rTransform, before); @@ -103,8 +103,8 @@ static Result _compFastTrack(RenderMethod* renderer, Paint* cmpTarget, const Ren auto pt3 = pts + 2; auto pt4 = pts + 3; - if ((mathEqual(pt1->x, pt2->x) && mathEqual(pt2->y, pt3->y) && mathEqual(pt3->x, pt4->x) && mathEqual(pt1->y, pt4->y)) || - (mathEqual(pt2->x, pt3->x) && mathEqual(pt1->y, pt2->y) && mathEqual(pt1->x, pt4->x) && mathEqual(pt3->y, pt4->y))) { + if ((tvg::equal(pt1->x, pt2->x) && tvg::equal(pt2->y, pt3->y) && tvg::equal(pt3->x, pt4->x) && tvg::equal(pt1->y, pt4->y)) || + (tvg::equal(pt2->x, pt3->x) && tvg::equal(pt1->y, pt2->y) && tvg::equal(pt1->x, pt4->x) && tvg::equal(pt3->y, pt4->y))) { RenderRegion after; @@ -182,9 +182,9 @@ bool Paint::Impl::rotate(float degree) { if (rTransform) { if (rTransform->overriding) return false; - if (mathEqual(degree, rTransform->degree)) return true; + if (tvg::equal(degree, rTransform->degree)) return true; } else { - if (mathZero(degree)) return true; + if (tvg::zero(degree)) return true; rTransform = new RenderTransform(); } rTransform->degree = degree; @@ -198,9 +198,9 @@ bool Paint::Impl::scale(float factor) { if (rTransform) { if (rTransform->overriding) return false; - if (mathEqual(factor, rTransform->scale)) return true; + if (tvg::equal(factor, rTransform->scale)) return true; } else { - if (mathEqual(factor, 1.0f)) return true; + if (tvg::equal(factor, 1.0f)) return true; rTransform = new RenderTransform(); } rTransform->scale = factor; @@ -214,9 +214,9 @@ bool Paint::Impl::translate(float x, float y) { if (rTransform) { if (rTransform->overriding) return false; - if (mathEqual(x, rTransform->m.e13) && mathEqual(y, rTransform->m.e23)) return true; + if (tvg::equal(x, rTransform->m.e13) && tvg::equal(y, rTransform->m.e23)) return true; } else { - if (mathZero(x) && mathZero(y)) return true; + if (tvg::zero(x) && tvg::zero(y)) return true; rTransform = new RenderTransform(); } rTransform->m.e13 = x; diff --git a/src/renderer/tvgPaint.h b/src/renderer/tvgPaint.h index 73df3dbd..42abdb1c 100644 --- a/src/renderer/tvgPaint.h +++ b/src/renderer/tvgPaint.h @@ -84,7 +84,7 @@ namespace tvg bool transform(const Matrix& m) { if (!rTransform) { - if (mathIdentity(&m)) return true; + if (identity(&m)) return true; rTransform = new RenderTransform(); } rTransform->override(m); diff --git a/src/renderer/tvgRender.cpp b/src/renderer/tvgRender.cpp index 6ecaf77b..f3fa419c 100644 --- a/src/renderer/tvgRender.cpp +++ b/src/renderer/tvgRender.cpp @@ -67,8 +67,8 @@ void RenderTransform::update() m.e32 = 0.0f; m.e33 = 1.0f; - mathScale(&m, scale, scale); - mathRotate(&m, degree); + tvg::scale(&m, scale, scale); + rotate(&m, degree); } @@ -77,7 +77,7 @@ RenderTransform::RenderTransform(const RenderTransform* lhs, const RenderTransfo if (lhs && rhs) m = lhs->m * rhs->m; else if (lhs) m = lhs->m; else if (rhs) m = rhs->m; - else mathIdentity(&m); + else identity(&m); } diff --git a/src/renderer/tvgSaver.cpp b/src/renderer/tvgSaver.cpp index bd604d25..825eae27 100644 --- a/src/renderer/tvgSaver.cpp +++ b/src/renderer/tvgSaver.cpp @@ -160,7 +160,7 @@ Result Saver::save(unique_ptr animation, const string& path, uint32_t //animation holds the picture, it must be 1 at the bottom. auto remove = PP(a->picture())->refCnt <= 1 ? true : false; - if (mathZero(a->totalFrame())) { + if (tvg::zero(a->totalFrame())) { if (remove) delete(a); return Result::InsufficientCondition; } diff --git a/src/renderer/tvgShape.cpp b/src/renderer/tvgShape.cpp index b8193354..640b1de1 100644 --- a/src/renderer/tvgShape.cpp +++ b/src/renderer/tvgShape.cpp @@ -162,8 +162,8 @@ Result Shape::appendArc(float cx, float cy, float radius, float startAngle, floa if (sweep >= 360.0f || sweep <= -360.0f) return appendCircle(cx, cy, radius, radius); const float arcPrecision = 1e-5f; - startAngle = mathDeg2Rad(startAngle); - sweep = mathDeg2Rad(sweep); + startAngle = deg2rad(startAngle); + sweep = deg2rad(sweep); auto nCurves = static_cast(fabsf(sweep / MATH_PI2)); if (fabsf(sweep / MATH_PI2) - nCurves > arcPrecision) ++nCurves; diff --git a/src/renderer/tvgShape.h b/src/renderer/tvgShape.h index 37f338ed..c4bd5df0 100644 --- a/src/renderer/tvgShape.h +++ b/src/renderer/tvgShape.h @@ -213,7 +213,7 @@ struct Shape::Impl rs.stroke = new RenderStroke(); } - if (mathEqual(rs.stroke->trim.begin, begin) && mathEqual(rs.stroke->trim.end, end) && + if (tvg::equal(rs.stroke->trim.begin, begin) && tvg::equal(rs.stroke->trim.end, end) && rs.stroke->trim.simultaneous == simultaneous) return; auto loop = true; diff --git a/src/renderer/wg_engine/tvgWgGeometry.cpp b/src/renderer/wg_engine/tvgWgGeometry.cpp index 06cc79f2..1bd8a9e9 100644 --- a/src/renderer/wg_engine/tvgWgGeometry.cpp +++ b/src/renderer/wg_engine/tvgWgGeometry.cpp @@ -362,7 +362,7 @@ void WgGeometryData::appendStrokeJoin(const WgPoint& v0, const WgPoint& v1, cons appendRect(v1 - offset0, v1 + offset0, v1 - offset1, v1 + offset1); } else if (join == StrokeJoin::Miter) { WgPoint nrm = (nrm0 + nrm1); - if (!mathZero(dir0.x * dir1.y - dir0.y * dir1.x)) { + if (!tvg::zero(dir0.x * dir1.y - dir0.y * dir1.x)) { nrm.normalize(); float cosine = nrm.dot(nrm0); float angle = std::acos(dir0.dot(dir1.negative())); diff --git a/src/renderer/wg_engine/tvgWgGeometry.h b/src/renderer/wg_engine/tvgWgGeometry.h index d9ff4c39..a97c2849 100644 --- a/src/renderer/wg_engine/tvgWgGeometry.h +++ b/src/renderer/wg_engine/tvgWgGeometry.h @@ -55,7 +55,7 @@ public: inline float dot(const WgPoint& p) const { return x * p.x + y * p.y; } inline float dist(const WgPoint& p) const { return sqrt(dist2(p)); } inline float dist2(const WgPoint& p) const { return ((p.x - x)*(p.x - x) + (p.y - y)*(p.y - y)); } - inline bool equal(const WgPoint& p) const { return mathEqual(x, p.x) && mathEqual(y, p.y); } + inline bool equal(const WgPoint& p) const { return tvg::equal(x, p.x) && tvg::equal(y, p.y); } inline void normalize() { float rlen = 1.0f / length(); x *= rlen; y *= rlen; } inline WgPoint normal() const { float rlen = 1.0f / length(); return { x * rlen, y * rlen }; } inline WgPoint lerp(const WgPoint& p, float t) const { return { x + (p.x - x) * t, y + (p.y - y) * t }; }; diff --git a/src/savers/gif/tvgGifSaver.cpp b/src/savers/gif/tvgGifSaver.cpp index 7e0d5cf7..83ac711d 100644 --- a/src/savers/gif/tvgGifSaver.cpp +++ b/src/savers/gif/tvgGifSaver.cpp @@ -49,7 +49,7 @@ void GifSaver::run(unsigned tid) //use the default fps if (fps > 60.0f) fps = 60.0f; // just in case - else if (mathZero(fps) || fps < 0.0f) { + else if (tvg::zero(fps) || fps < 0.0f) { fps = (animation->totalFrame() / animation->duration()); } diff --git a/src/savers/tvg/tvgTvgSaver.cpp b/src/savers/tvg/tvgTvgSaver.cpp index f764b36b..cafaaefe 100644 --- a/src/savers/tvg/tvgTvgSaver.cpp +++ b/src/savers/tvg/tvgTvgSaver.cpp @@ -303,7 +303,7 @@ TvgBinCounter TvgSaver::writeTagProperty(TvgBinTag tag, TvgBinCounter cnt, const TvgBinCounter TvgSaver::writeTransform(const Matrix* transform, TvgBinTag tag) { - if (!mathIdentity(transform)) return writeTagProperty(tag, SIZE(Matrix), transform); + if (!identity(transform)) return writeTagProperty(tag, SIZE(Matrix), transform); return 0; } @@ -408,7 +408,7 @@ TvgBinCounter TvgSaver::serializeFill(const Fill* fill, TvgBinTag tag, const Mat radial->radial(args, args + 1, args + 2); cnt += writeTagProperty(TVG_TAG_FILL_RADIAL_GRADIENT, SIZE(args), args); //focal - if (!mathZero(P(radial)->fx)|| !mathZero(P(radial)->fy) || P(radial)->fr > 0.0f) { + if (!tvg::zero(P(radial)->fx)|| !tvg::zero(P(radial)->fy) || P(radial)->fr > 0.0f) { args[0] = P(radial)->fx; args[1] = P(radial)->fy; args[2] = P(radial)->fr; @@ -489,7 +489,7 @@ TvgBinCounter TvgSaver::serializeStroke(const Shape* shape, const Matrix* pTrans } //dash offset - if (!mathZero(offset)) { + if (!tvg::zero(offset)) { cnt += writeTagProperty(TVG_TAG_SHAPE_STROKE_DASH_OFFSET, SIZE(offset), &offset); } @@ -524,9 +524,9 @@ TvgBinCounter TvgSaver::serializePath(const Shape* shape, const Matrix* transfor //transform? if (preTransform) { - if (!mathEqual(transform->e11, 1.0f) || !mathZero(transform->e12) || !mathZero(transform->e13) || - !mathZero(transform->e21) || !mathEqual(transform->e22, 1.0f) || !mathZero(transform->e23) || - !mathZero(transform->e31) || !mathZero(transform->e32) || !mathEqual(transform->e33, 1.0f)) { + if (!tvg::equal(transform->e11, 1.0f) || !tvg::zero(transform->e12) || !tvg::zero(transform->e13) || + !tvg::zero(transform->e21) || !tvg::equal(transform->e22, 1.0f) || !tvg::zero(transform->e23) || + !tvg::zero(transform->e31) || !tvg::zero(transform->e32) || !tvg::equal(transform->e33, 1.0f)) { auto p = const_cast(pts); for (uint32_t i = 0; i < ptsCnt; ++i) { *p *= *transform; @@ -563,7 +563,7 @@ TvgBinCounter TvgSaver::serializeShape(const Shape* shape, const Matrix* pTransf shape->strokeFill(color, color + 1, color + 2, color + 3); auto fill = shape->strokeFill(); if (fill || color[3] > 0) { - if (!mathEqual(cTransform->e11, cTransform->e22) || (mathZero(cTransform->e11) && !mathEqual(cTransform->e12, cTransform->e21)) || shape->strokeDash(nullptr) > 0) preTransform = false; + if (!tvg::equal(cTransform->e11, cTransform->e22) || (tvg::zero(cTransform->e11) && !tvg::equal(cTransform->e12, cTransform->e21)) || shape->strokeDash(nullptr) > 0) preTransform = false; cnt += serializeStroke(shape, cTransform, preTransform); } }