From 0fcdba8a4b8b912f1771215ec43718bcc760fc63 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Mon, 15 Nov 2021 12:17:36 +0900 Subject: [PATCH] common math: code refactoring introduced mathZero(), mathEqual() for floating variables. --- src/lib/sw_engine/tvgSwFill.cpp | 2 +- src/lib/sw_engine/tvgSwRaster.cpp | 8 ++++---- src/lib/tvgMath.h | 23 ++++++++++++++++++----- src/lib/tvgPaint.cpp | 21 ++++++++------------- src/lib/tvgRender.cpp | 7 ++----- src/lib/tvgShape.cpp | 9 +++------ src/loaders/svg/tvgSvgLoader.cpp | 4 ++-- src/loaders/svg/tvgSvgSceneBuilder.cpp | 8 ++++---- src/savers/tvg/tvgTvgSaver.cpp | 16 ++++++++-------- 9 files changed, 50 insertions(+), 48 deletions(-) diff --git a/src/lib/sw_engine/tvgSwFill.cpp b/src/lib/sw_engine/tvgSwFill.cpp index 92352423..8afc2c03 100644 --- a/src/lib/sw_engine/tvgSwFill.cpp +++ b/src/lib/sw_engine/tvgSwFill.cpp @@ -260,7 +260,7 @@ void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, 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 (fabsf(inc) < FLT_EPSILON) { + if (mathZero(inc)) { auto color = _fixedPixel(fill, static_cast(t * FIXPT_SIZE)); rasterRGBA32(dst, color, 0, len); return; diff --git a/src/lib/sw_engine/tvgSwRaster.cpp b/src/lib/sw_engine/tvgSwRaster.cpp index 28c62350..e3640bd7 100644 --- a/src/lib/sw_engine/tvgSwRaster.cpp +++ b/src/lib/sw_engine/tvgSwRaster.cpp @@ -1555,11 +1555,11 @@ bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, co if (image->rle) { if (transformed) { if (translucent) { - if (fabsf(scale - 1.0f) <= FLT_EPSILON) return _rasterTranslucentImageRle(surface, image, opacity, &itransform); + if (mathEqual(scale, 1.0f)) return _rasterTranslucentImageRle(surface, image, opacity, &itransform); else if (scale < downScaleTolerance) return _rasterTranslucentDownScaleImageRle(surface, image, opacity, &itransform, halfScale); else return _rasterTranslucentUpScaleImageRle(surface, image, opacity, &itransform); } else { - if (fabsf(scale - 1.0f) <= FLT_EPSILON) return _rasterImageRle(surface, image, &itransform); + if (mathEqual(scale, 1.0f)) return _rasterImageRle(surface, image, &itransform); else if (scale < downScaleTolerance) return _rasterDownScaleImageRle(surface, image, &itransform, halfScale); else return _rasterUpScaleImageRle(surface, image, &itransform); } @@ -1573,11 +1573,11 @@ bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, co } else { if (transformed) { if (translucent) { - if (fabsf(scale - 1.0f) <= FLT_EPSILON) return _rasterTranslucentImage(surface, image, opacity, bbox, &itransform); + if (mathEqual(scale, 1.0f)) return _rasterTranslucentImage(surface, image, opacity, bbox, &itransform); else if (scale < downScaleTolerance) return _rasterTranslucentDownScaleImage(surface, image, opacity, bbox, &itransform, halfScale); else return _rasterTranslucentUpScaleImage(surface, image, opacity, bbox, &itransform); } else { - if (fabsf(scale - 1.0f) <= FLT_EPSILON) return _rasterImage(surface, image, bbox, &itransform); + if (mathEqual(scale, 1.0f)) return _rasterImage(surface, image, bbox, &itransform); else if (scale < downScaleTolerance) return _rasterDownScaleImage(surface, image, bbox, &itransform, halfScale); else return _rasterUpScaleImage(surface, image, bbox, &itransform); } diff --git a/src/lib/tvgMath.h b/src/lib/tvgMath.h index 2a3d40b7..9e5c915f 100644 --- a/src/lib/tvgMath.h +++ b/src/lib/tvgMath.h @@ -28,19 +28,32 @@ #include #include "tvgCommon.h" + +static inline bool mathZero(float a) +{ + return (fabsf(a) < FLT_EPSILON) ? true : false; +} + + +static inline bool mathEqual(float a, float b) +{ + return (fabsf(a - b) < FLT_EPSILON); +} + + static inline bool mathRightAngle(const Matrix* m) { auto radian = fabsf(atan2(m->e21, m->e11)); - if (radian < FLT_EPSILON || fabsf(radian - float(M_PI_2)) < FLT_EPSILON || fabsf(radian - float(M_PI)) < FLT_EPSILON) return true; + if (radian < FLT_EPSILON || mathEqual(radian, float(M_PI_2)) || mathEqual(radian, float(M_PI))) return true; return false; } static inline bool mathIdentity(const Matrix* m) { - if (fabs(m->e11 - 1) > FLT_EPSILON || fabs(m->e12) > FLT_EPSILON || fabs(m->e13) > FLT_EPSILON || - fabs(m->e21) > FLT_EPSILON || fabs(m->e22 - 1) > FLT_EPSILON || fabs(m->e23) > FLT_EPSILON || - fabs(m->e31) > FLT_EPSILON || fabs(m->e32) > FLT_EPSILON || fabs(m->e33 - 1) > FLT_EPSILON) { + if (!mathEqual(m->e11, 1.0f) || !mathZero(m->e12) || !mathZero(m->e13) || + !mathZero(m->e21) || !mathEqual(m->e22, 1.0f) || !mathZero(m->e23) || + !mathZero(m->e31) || !mathZero(m->e32) || !mathEqual(m->e33, 1.0f)) { return false; } return true; @@ -53,7 +66,7 @@ static inline bool mathInverse(const Matrix* m, Matrix* out) m->e12 * (m->e21 * m->e33 - m->e23 * m->e31) + m->e13 * (m->e21 * m->e32 - m->e22 * m->e31); - if (fabsf(det) < FLT_EPSILON) return false; + if (mathZero(det)) return false; auto invDet = 1 / det; diff --git a/src/lib/tvgPaint.cpp b/src/lib/tvgPaint.cpp index 16e9ab0e..e3d2342e 100644 --- a/src/lib/tvgPaint.cpp +++ b/src/lib/tvgPaint.cpp @@ -28,11 +28,6 @@ /* Internal Class Implementation */ /************************************************************************/ -static inline bool FLT_SAME(float a, float b) -{ - return (fabsf(a - b) < FLT_EPSILON); -} - static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform, RenderTransform* rTransform, RenderRegion& viewport) { @@ -55,8 +50,8 @@ static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform, auto pt3 = pts + 2; auto pt4 = pts + 3; - if ((FLT_SAME(pt1->x, pt2->x) && FLT_SAME(pt2->y, pt3->y) && FLT_SAME(pt3->x, pt4->x) && FLT_SAME(pt1->y, pt4->y)) || - (FLT_SAME(pt2->x, pt3->x) && FLT_SAME(pt1->y, pt2->y) && FLT_SAME(pt1->x, pt4->x) && FLT_SAME(pt3->y, pt4->y))) { + 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))) { auto x1 = pt1->x; auto y1 = pt1->y; @@ -117,9 +112,9 @@ Paint* Paint::Impl::duplicate() bool Paint::Impl::rotate(float degree) { if (rTransform) { - if (fabsf(degree - rTransform->degree) <= FLT_EPSILON) return true; + if (mathEqual(degree, rTransform->degree)) return true; } else { - if (fabsf(degree) <= FLT_EPSILON) return true; + if (mathZero(degree)) return true; rTransform = new RenderTransform(); } rTransform->degree = degree; @@ -132,9 +127,9 @@ bool Paint::Impl::rotate(float degree) bool Paint::Impl::scale(float factor) { if (rTransform) { - if (fabsf(factor - rTransform->scale) <= FLT_EPSILON) return true; + if (mathEqual(factor, rTransform->scale)) return true; } else { - if (fabsf(factor) <= FLT_EPSILON) return true; + if (mathZero(factor)) return true; rTransform = new RenderTransform(); } rTransform->scale = factor; @@ -147,9 +142,9 @@ bool Paint::Impl::scale(float factor) bool Paint::Impl::translate(float x, float y) { if (rTransform) { - if (fabsf(x - rTransform->x) <= FLT_EPSILON && fabsf(y - rTransform->y) <= FLT_EPSILON) return true; + if (mathEqual(x, rTransform->x) && mathEqual(y, rTransform->y)) return true; } else { - if (fabsf(x) <= FLT_EPSILON && fabsf(y) <= FLT_EPSILON) return true; + if (mathZero(x) && mathZero(y)) return true; rTransform = new RenderTransform(); } rTransform->x = x; diff --git a/src/lib/tvgRender.cpp b/src/lib/tvgRender.cpp index fbae2caa..a48075dd 100644 --- a/src/lib/tvgRender.cpp +++ b/src/lib/tvgRender.cpp @@ -48,16 +48,13 @@ bool RenderTransform::update() if (overriding) return true; //Init Status - if (fabsf(x) <= FLT_EPSILON && fabsf(y) <= FLT_EPSILON && - fabsf(degree) <= FLT_EPSILON && fabsf(scale - 1) <= FLT_EPSILON) { - return false; - } + if (mathZero(x) && mathZero(y) && mathZero(degree) && mathEqual(scale, 1)) return false; mathIdentity(&m); mathScale(&m, scale); - if (fabsf(degree) > FLT_EPSILON) mathRotate(&m, degree); + if (!mathZero(degree)) mathRotate(&m, degree); mathTranslate(&m, x, y); diff --git a/src/lib/tvgShape.cpp b/src/lib/tvgShape.cpp index afaf2679..42b2c0db 100644 --- a/src/lib/tvgShape.cpp +++ b/src/lib/tvgShape.cpp @@ -20,10 +20,7 @@ * SOFTWARE. */ -#define _USE_MATH_DEFINES //Math Constants are not defined in Standard C/C++. - -#include -#include +#include "tvgMath.h" #include "tvgShapeImpl.h" /************************************************************************/ @@ -171,7 +168,7 @@ Result Shape::appendArc(float cx, float cy, float radius, float startAngle, floa auto nCurves = ceil(fabsf(sweep / float(M_PI_2))); auto sweepSign = (sweep < 0 ? -1 : 1); auto fract = fmodf(sweep, float(M_PI_2)); - fract = (fabsf(fract) < FLT_EPSILON) ? float(M_PI_2) * sweepSign : fract; + fract = (mathZero(fract)) ? float(M_PI_2) * sweepSign : fract; //Start from here Point start = {radius * cosf(startAngle), radius * sinf(startAngle)}; @@ -238,7 +235,7 @@ Result Shape::appendRect(float x, float y, float w, float h, float rx, float ry) pImpl->path.lineTo(x, y + h); pImpl->path.close(); //circle - } else if (fabsf(rx - halfW) < FLT_EPSILON && fabsf(ry - halfH) < FLT_EPSILON) { + } else if (mathEqual(rx, halfW) && mathEqual(ry, halfH)) { return appendCircle(x + (w * 0.5f), y + (h * 0.5f), rx, ry); } else { auto hrx = rx * 0.5f; diff --git a/src/loaders/svg/tvgSvgLoader.cpp b/src/loaders/svg/tvgSvgLoader.cpp index a7403d94..0b5c120b 100644 --- a/src/loaders/svg/tvgSvgLoader.cpp +++ b/src/loaders/svg/tvgSvgLoader.cpp @@ -1472,8 +1472,8 @@ static bool _attrParseRectNode(void* data, const char* key, const char* value) if (!strncmp(rectTags[i].tag, "rx", sz)) rect->hasRx = true; if (!strncmp(rectTags[i].tag, "ry", sz)) rect->hasRy = true; - if ((rect->rx > FLT_EPSILON) && (rect->ry <= FLT_EPSILON) && rect->hasRx && !rect->hasRy) rect->ry = rect->rx; - if ((rect->ry > FLT_EPSILON) && (rect->rx <= FLT_EPSILON) && !rect->hasRx && rect->hasRy) rect->rx = rect->ry; + if ((rect->rx >= FLT_EPSILON) && (rect->ry < FLT_EPSILON) && rect->hasRx && !rect->hasRy) rect->ry = rect->rx; + if ((rect->ry >= FLT_EPSILON) && (rect->rx < FLT_EPSILON) && !rect->hasRx && rect->hasRy) rect->rx = rect->ry; return ret; } } diff --git a/src/loaders/svg/tvgSvgSceneBuilder.cpp b/src/loaders/svg/tvgSvgSceneBuilder.cpp index 7363a71c..6737053e 100644 --- a/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -48,13 +48,13 @@ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include + #include +#include "tvgMath.h" #include "tvgSvgLoaderCommon.h" #include "tvgSvgSceneBuilder.h" #include "tvgSvgPath.h" #include "tvgSvgUtil.h" -#include static bool _appendShape(SvgNode* node, Shape* shape, float vx, float vy, float vw, float vh, const string& svgPath); static unique_ptr _sceneBuildHelper(const SvgNode* node, float vx, float vy, float vw, float vh, const string& svgPath, bool mask); @@ -598,7 +598,7 @@ unique_ptr svgSceneBuild(SvgNode* node, float vx, float vy, float vw, flo auto docNode = _sceneBuildHelper(node, vx, vy, vw, vh, svgPath, false); - if (fabsf(w - vw) > FLT_EPSILON || fabsf(h - vh) > FLT_EPSILON) { + if (!mathEqual(w, vw) || !mathEqual(h, vh)) { auto sx = w / vw; auto sy = h / vh; @@ -625,7 +625,7 @@ unique_ptr svgSceneBuild(SvgNode* node, float vx, float vy, float vw, flo Matrix m = {sx, 0, -tvx, 0, sy, -tvy, 0, 0, 1}; docNode->transform(m); } - } else if (fabs(vx) > FLT_EPSILON || fabs(vy) > FLT_EPSILON) { + } else if (!mathZero(vx) || !mathZero(vy)) { docNode->translate(-vx, -vy); } diff --git a/src/savers/tvg/tvgTvgSaver.cpp b/src/savers/tvg/tvgTvgSaver.cpp index f1648fb8..46ad28e2 100644 --- a/src/savers/tvg/tvgTvgSaver.cpp +++ b/src/savers/tvg/tvgTvgSaver.cpp @@ -83,9 +83,9 @@ static bool _merge(Shape* from, Shape* to) auto t1 = from->transform(); auto t2 = to->transform(); - if (fabs(t1.e11 - t2.e11) > FLT_EPSILON || fabs(t1.e12 - t2.e12) > FLT_EPSILON || fabs(t1.e13 - t2.e13) > FLT_EPSILON || - fabs(t1.e21 - t2.e21) > FLT_EPSILON || fabs(t1.e22 - t2.e22) > FLT_EPSILON || fabs(t1.e23 - t2.e23) > FLT_EPSILON || - fabs(t1.e31 - t2.e31) > FLT_EPSILON || fabs(t1.e32 - t2.e32) > FLT_EPSILON || fabs(t1.e33 - t2.e33) > FLT_EPSILON) { + if (!mathEqual(t1.e11, t2.e11) || !mathEqual(t1.e12, t2.e12) || !mathEqual(t1.e13, t2.e13) || + !mathEqual(t1.e21, t2.e21) || !mathEqual(t1.e22, t2.e22) || !mathEqual(t1.e23, t2.e23) || + !mathEqual(t1.e31, t2.e31) || !mathEqual(t1.e32, t2.e32) || !mathEqual(t1.e33, t2.e33)) { return false; } @@ -499,9 +499,9 @@ TvgBinCounter TvgSaver::serializePath(const Shape* shape, const Matrix* transfor //transform? if (preTransform) { - if (fabs(transform->e11 - 1) > FLT_EPSILON || fabs(transform->e12) > FLT_EPSILON || fabs(transform->e13) > FLT_EPSILON || - fabs(transform->e21) > FLT_EPSILON || fabs(transform->e22 - 1) > FLT_EPSILON || fabs(transform->e23) > FLT_EPSILON || - fabs(transform->e31) > FLT_EPSILON || fabs(transform->e32) > FLT_EPSILON || fabs(transform->e33 - 1) > FLT_EPSILON) { + 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)) { auto p = const_cast(pts); for (uint32_t i = 0; i < ptsCnt; ++i) mathMultiply(p++, transform); } @@ -535,7 +535,7 @@ TvgBinCounter TvgSaver::serializeShape(const Shape* shape, const Matrix* pTransf shape->strokeColor(color, color + 1, color + 2, color + 3); auto fill = shape->strokeFill(); if (fill || color[3] > 0) { - if (fabsf(cTransform->e11 - cTransform->e22) > FLT_EPSILON || (fabsf(cTransform->e11) < FLT_EPSILON && fabsf(cTransform->e12 - cTransform->e21) > FLT_EPSILON) || shape->strokeDash(nullptr) > 0) preTransform = false; + if (!mathEqual(cTransform->e11, cTransform->e22) || (mathZero(cTransform->e11) && !mathEqual(cTransform->e12, cTransform->e21)) || shape->strokeDash(nullptr) > 0) preTransform = false; cnt += serializeStroke(shape, cTransform, preTransform); } } @@ -756,7 +756,7 @@ bool TvgSaver::save(Paint* paint, const string& path, bool compress) if (x < 0) vsize[0] += x; if (y < 0) vsize[1] += y; - if (vsize[0] <= FLT_EPSILON || vsize[1] <= FLT_EPSILON) { + if (vsize[0] < FLT_EPSILON || vsize[1] < FLT_EPSILON) { TVGLOG("TVG_SAVER", "Saving paint(%p) has zero view size.", paint); return false; }