lottie/vector: move line related api to its own class . 45/187845/1
authorsubhransu mohanty <sub.mohanty@samsung.com>
Wed, 29 Aug 2018 02:36:10 +0000 (11:36 +0900)
committersubhransu mohanty <sub.mohanty@samsung.com>
Wed, 29 Aug 2018 02:46:49 +0000 (11:46 +0900)
Change-Id: Ib9072653cf534e558eedd88242535bc9a8e028fe

src/lottie/lottiemodel.cpp
src/vector/vbezier.cpp
src/vector/vdasher.cpp
src/vector/vglobal.h
src/vector/vline.h [new file with mode: 0644]
src/vector/vpath.cpp

index 2e48fac..5d4145f 100644 (file)
@@ -1,4 +1,5 @@
 #include "lottiemodel.h"
+#include "vline.h"
 #include <cassert>
 #include <stack>
 
@@ -242,7 +243,7 @@ void LOTGradient::update(std::unique_ptr<VGradient> &grad, int frameNo)
         grad->radial.cx = start.x();
         grad->radial.cy = start.y();
         grad->radial.cradius =
-            vLineLength(start.x(), start.y(), end.x(), end.y());
+            VLine::length(start.x(), start.y(), end.x(), end.y());
         /*
          * Focal point is the point lives in highlight length distance from
          * center along the line (start, end)  and rotated by highlight angle.
index 3651bc7..bc31fa2 100644 (file)
@@ -1,23 +1,9 @@
 #include "vbezier.h"
-
+#include "vline.h"
 #include <cmath>
 
 V_BEGIN_NAMESPACE
 
-// Approximate sqrt(x*x + y*y) using the alpha max plus beta min algorithm.
-// This uses alpha = 1, beta = 3/8, which results in a maximum error of less
-// than 7% compared to the correct value.
-static inline float lineLength(float x1, float y1, float x2, float y2)
-{
-    float x = x2 - x1;
-    float y = y2 - y1;
-
-    x = x < 0 ? -x : x;
-    y = y < 0 ? -y : y;
-
-    return (x > y ? x + 0.375 * y : y + 0.375 * x);
-}
-
 VBezier VBezier::fromPoints(const VPointF &p1, const VPointF &p2,
                             const VPointF &p3, const VPointF &p4)
 {
@@ -40,11 +26,11 @@ float VBezier::length() const
     float   chord;       /* chord length */
     float   length;
 
-    len = len + lineLength(x1, y1, x2, y2);
-    len = len + lineLength(x2, y2, x3, y3);
-    len = len + lineLength(x3, y3, x4, y4);
+    len = len + VLine::length(x1, y1, x2, y2);
+    len = len + VLine::length(x2, y2, x3, y3);
+    len = len + VLine::length(x3, y3, x4, y4);
 
-    chord = lineLength(x1, y1, x4, y4);
+    chord = VLine::length(x1, y1, x4, y4);
 
     if (!vCompare(len, chord)) {
         split(&left, &right);    /* split in two */
index b3782ff..eedae3a 100644 (file)
@@ -1,60 +1,9 @@
 #include "vdasher.h"
 #include "vbezier.h"
+#include "vline.h"
 
 V_BEGIN_NAMESPACE
 
-class VLine {
-public:
-    VLine() : mX1(0), mY1(0), mX2(0), mY2(0) {}
-    VLine(float x1, float y1, float x2, float y2)
-        : mX1(x1), mY1(y1), mX2(x2), mY2(y2)
-    {
-    }
-    VLine(const VPointF &p1, const VPointF &p2)
-        : mX1(p1.x()), mY1(p1.y()), mX2(p2.x()), mY2(p2.y())
-    {
-    }
-    float   length() const;
-    void    splitAtLength(float length, VLine &left, VLine &right) const;
-    VPointF p1() const { return VPointF(mX1, mY1); }
-    VPointF p2() const { return VPointF(mX2, mY2); }
-
-private:
-    float mX1;
-    float mY1;
-    float mX2;
-    float mY2;
-};
-
-// approximate sqrt(x*x + y*y) using alpha max plus beta min algorithm.
-// With alpha = 1, beta = 3/8, giving results with the largest error less
-// than 7% compared to the exact value.
-float VLine::length() const
-{
-    float x = mX2 - mX1;
-    float y = mY2 - mY1;
-    x = x < 0 ? -x : x;
-    y = y < 0 ? -y : y;
-    return (x > y ? x + 0.375 * y : y + 0.375 * x);
-}
-
-void VLine::splitAtLength(float lengthAt, VLine &left, VLine &right) const
-{
-    float  len = length();
-    double dx = ((mX2 - mX1) / len) * lengthAt;
-    double dy = ((mY2 - mY1) / len) * lengthAt;
-
-    left.mX1 = mX1;
-    left.mY1 = mY1;
-    left.mX2 = left.mX1 + dx;
-    left.mY2 = left.mY1 + dy;
-
-    right.mX1 = left.mX2;
-    right.mY1 = left.mY2;
-    right.mX2 = mX2;
-    right.mY2 = mY2;
-}
-
 VDasher::VDasher(const float *dashArray, int size)
 {
     if (!(size % 2)) vCritical << "invalid dashArray format";
@@ -104,6 +53,7 @@ void VDasher::moveTo(const VPointF &p)
     } else {
         mCurrentLength = mDashArray[mIndex].length;
     }
+    if (vIsZero(mCurrentLength)) updateActiveSegment();
 }
 
 void VDasher::addLine(const VPointF &p)
@@ -129,6 +79,7 @@ void VDasher::updateActiveSegment()
         mDiscard = true;
         mCurrentLength = mDashArray[mIndex].gap;
     }
+    if (vIsZero(mCurrentLength)) updateActiveSegment();
 }
 
 void VDasher::lineTo(const VPointF &p)
index df6ae1d..a46742f 100644 (file)
@@ -110,20 +110,6 @@ static inline bool vIsZero(double f)
     return (std::abs(f) <= EPSILON_DOUBLE);
 }
 
-// Approximate sqrt(x*x + y*y) using the alpha max plus beta min algorithm.
-// This uses alpha = 1, beta = 3/8, which results in a maximum error of less
-// than 7% compared to the correct value.
-static inline float vLineLength(float x1, float y1, float x2, float y2)
-{
-    float x = x2 - x1;
-    float y = y2 - y1;
-
-    x = x < 0 ? -x : x;
-    y = y < 0 ? -y : y;
-
-    return (x > y ? x + 0.375 * y : y + 0.375 * x);
-}
-
 class vFlagHelper {
     int i;
 
diff --git a/src/vector/vline.h b/src/vector/vline.h
new file mode 100644 (file)
index 0000000..47ddff4
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef VLINE_H
+#define VLINE_H
+
+#include "vglobal.h"
+#include "vpoint.h"
+
+V_BEGIN_NAMESPACE
+
+class VLine {
+public:
+    VLine() = default;
+    VLine(float x1, float y1, float x2, float y2)
+        : mX1(x1), mY1(y1), mX2(x2), mY2(y2)
+    {
+    }
+    VLine(const VPointF &p1, const VPointF &p2)
+        : mX1(p1.x()), mY1(p1.y()), mX2(p2.x()), mY2(p2.y())
+    {
+    }
+    float   length() const { return length(mX1, mY1, mX2, mY2);}
+    void    splitAtLength(float length, VLine &left, VLine &right) const;
+    VPointF p1() const { return VPointF(mX1, mY1); }
+    VPointF p2() const { return VPointF(mX2, mY2); }
+
+    static float length(float x1, float y1, float x2, float y2);
+
+private:
+    float mX1{0};
+    float mY1{0};
+    float mX2{0};
+    float mY2{0};
+};
+
+// approximate sqrt(x*x + y*y) using alpha max plus beta min algorithm.
+// With alpha = 1, beta = 3/8, giving results with the largest error less
+// than 7% compared to the exact value.
+inline float VLine::length(float x1, float y1, float x2, float y2)
+{
+    float x = x2 - x1;
+    float y = y2 - y1;
+
+    x = x < 0 ? -x : x;
+    y = y < 0 ? -y : y;
+
+    return (x > y ? x + 0.375 * y : y + 0.375 * x);
+}
+
+inline void VLine::splitAtLength(float lengthAt, VLine &left, VLine &right) const
+{
+    float  len = length();
+    float dx = ((mX2 - mX1) / len) * lengthAt;
+    float dy = ((mY2 - mY1) / len) * lengthAt;
+
+    left.mX1 = mX1;
+    left.mY1 = mY1;
+    left.mX2 = left.mX1 + dx;
+    left.mY2 = left.mY1 + dy;
+
+    right.mX1 = left.mX2;
+    right.mY1 = left.mY2;
+    right.mX2 = mX2;
+    right.mY2 = mY2;
+}
+
+#endif //VLINE_H
\ No newline at end of file
index 7089d2b..5114603 100644 (file)
@@ -4,6 +4,7 @@
 #include "vbezier.h"
 #include "vdebug.h"
 #include "vrect.h"
+#include "vline.h"
 
 V_BEGIN_NAMESPACE
 
@@ -38,19 +39,14 @@ float VPath::VPathData::length() const
             i++;
             break;
         case VPath::Element::LineTo: {
-            VPointF p0 = m_points[i - 1];
-            VPointF p = m_points[i++];
-            VBezier b = VBezier::fromPoints(p0, p0, p, p);
-            len += b.length();
+            len += VLine( m_points[i-1], m_points[i]).length();
+            i++;
             break;
         }
         case VPath::Element::CubicTo: {
-            VPointF p0 = m_points[i - 1];
-            VPointF p = m_points[i++];
-            VPointF p1 = m_points[i++];
-            VPointF p2 = m_points[i++];
-            VBezier b = VBezier::fromPoints(p0, p, p1, p2);
-            len += b.length();
+            len += VBezier::fromPoints(m_points[i-1], m_points[i],
+                                       m_points[i+1], m_points[i+2]).length();
+            i += 3;
             break;
         }
         case VPath::Element::Close: