summaryrefslogtreecommitdiff
path: root/drawinglayer
diff options
context:
space:
mode:
authorBartosz Kosiorek <gang65@poczta.onet.pl>2023-06-10 18:13:50 +0200
committerBartosz Kosiorek <gang65@poczta.onet.pl>2023-06-13 12:59:33 +0200
commitcbb215aa20783523555185c83875ea5d5b94535b (patch)
tree68d31593174fe0c52557312d0fa9e0b5827a6890 /drawinglayer
parent3e3d6aeec92a7252d92243e2de34b424cf5f7cdf (diff)
tdf#143877 Fix failing tests caused by floating point precision
Due to different imlementation of floating-point unit (FPU), on different CPU platforms, the floating point numbers could could be different. https://stackoverflow.com/questions/64036879/differing-floating-point-calculation-results-between-x86-64-and-armv8-2-a https://mcuoneclipse.com/2019/03/29/be-aware-floating-point-operations-on-arm-cortex-m4f/ With this path I have changed the tested images, to use floating point numbers which are easily represented by floating numbers (multiplied/divided by 2), like: - change tension to values: 0.125, 0.25, 0.5, 1.0, 1.5 ... - change position of curve to of control points to 256.0, 384.0 512.0 Previous values was hard to represent by floating numbers, for example tension: - 0.4 has been written as 0.399999976158142 - 0.1 has been written as 0.099999994039535 More information: https://observablehq.com/@benaubin/floating-point Additionally the precision of numbers were increased to double. Change-Id: I5725c1f2f474d0c00821edaa9bb2102cb172093f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152838 Reviewed-by: Stephan Bergmann <sbergman@redhat.com> Tested-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
Diffstat (limited to 'drawinglayer')
-rw-r--r--drawinglayer/source/tools/emfppath.cxx42
1 files changed, 19 insertions, 23 deletions
diff --git a/drawinglayer/source/tools/emfppath.cxx b/drawinglayer/source/tools/emfppath.cxx
index bd5b2d357b0f..e7c4a5512c76 100644
--- a/drawinglayer/source/tools/emfppath.cxx
+++ b/drawinglayer/source/tools/emfppath.cxx
@@ -34,7 +34,12 @@ namespace
namespace emfplushelper
{
- typedef float matrix [4][4];
+ typedef double matrix [4][4];
+
+ constexpr sal_uInt32 nDetails = 8;
+ constexpr double alpha[nDetails]
+ = { 1. / nDetails, 2. / nDetails, 3. / nDetails, 4. / nDetails,
+ 5. / nDetails, 6. / nDetails, 7. / nDetails, 8. / nDetails };
// see 2.2.2.21 EmfPlusInteger7
// 2.2.2.22 EmfPlusInteger15
@@ -232,21 +237,20 @@ namespace emfplushelper
m[0][2] = tension - 2.;
m[1][0] = 2. * tension;
m[1][1] = tension - 3.;
- m[1][2] = 3. - 2 * tension;
+ m[1][2] = 3. - 2. * tension;
m[3][1] = 1.;
m[0][3] = m[2][2] = tension;
m[0][0] = m[1][3] = m[2][0] = -tension;
m[2][1] = m[2][3] = m[3][0] = m[3][2] = m[3][3] = 0.;
}
- static float calculateSplineCoefficients(float p0, float p1, float p2, float p3, float alpha, matrix m)
+ static double calculateSplineCoefficients(float p0, float p1, float p2, float p3, sal_uInt32 step, matrix m)
{
- float a, b, c, d;
- a = m[0][0] * p0 + m[0][1] * p1 + m[0][2] * p2 + m[0][3] * p3;
- b = m[1][0] * p0 + m[1][1] * p1 + m[1][2] * p2 + m[1][3] * p3;
- c = m[2][0] * p0 + m[2][2] * p2;
- d = p1;
- return (d + alpha * (c + alpha * (b + alpha * a)));
+ double a = m[0][0] * p0 + m[0][1] * p1 + m[0][2] * p2 + m[0][3] * p3;
+ double b = m[1][0] * p0 + m[1][1] * p1 + m[1][2] * p2 + m[1][3] * p3;
+ double c = m[2][0] * p0 + m[2][2] * p2;
+ double d = p1;
+ return (d + alpha[step] * (c + alpha[step] * (b + alpha[step] * a)));
}
::basegfx::B2DPolyPolygon& EMFPPath::GetCardinalSpline(EmfPlusHelperData const& rR, float fTension,
@@ -254,11 +258,7 @@ namespace emfplushelper
{
::basegfx::B2DPolygon polygon;
matrix mat;
- float x, y;
- constexpr sal_uInt32 nDetails = 8;
- constexpr float alpha[nDetails]
- = { 1. / nDetails, 2. / nDetails, 3. / nDetails, 4. / nDetails,
- 5. / nDetails, 6. / nDetails, 7. / nDetails, 8. / nDetails };
+ double x, y;
if (aNumSegments >= nPoints)
aNumSegments = nPoints - 1;
GetCardinalMatrix(fTension, mat);
@@ -274,9 +274,9 @@ namespace emfplushelper
for (sal_uInt32 s = 0; s < nDetails; s++)
{
x = calculateSplineCoefficients(xPoints[i - 3], xPoints[i - 2], xPoints[i - 1],
- xPoints[i], alpha[s], mat);
+ xPoints[i], s, mat);
y = calculateSplineCoefficients(yPoints[i - 3], yPoints[i - 2], yPoints[i - 1],
- yPoints[i], alpha[s], mat);
+ yPoints[i], s, mat);
polygon.append(rR.Map(x, y));
}
}
@@ -289,11 +289,7 @@ namespace emfplushelper
{
::basegfx::B2DPolygon polygon;
matrix mat;
- float x, y;
- constexpr sal_uInt32 nDetails = 8;
- constexpr float alpha[nDetails]
- = { 1. / nDetails, 2. / nDetails, 3. / nDetails, 4. / nDetails,
- 5. / nDetails, 6. / nDetails, 7. / nDetails, 8. / nDetails };
+ double x, y;
GetCardinalMatrix(fTension, mat);
// add three first points at the end
xPoints.push_back(xPoints[0]);
@@ -308,9 +304,9 @@ namespace emfplushelper
for (sal_uInt32 s = 0; s < nDetails; s++)
{
x = calculateSplineCoefficients(xPoints[i - 3], xPoints[i - 2], xPoints[i - 1],
- xPoints[i], alpha[s], mat);
+ xPoints[i], s, mat);
y = calculateSplineCoefficients(yPoints[i - 3], yPoints[i - 2], yPoints[i - 1],
- yPoints[i], alpha[s], mat);
+ yPoints[i], s, mat);
polygon.append(rR.Map(x, y));
}
}