Commit 6d8489a0 authored by Brendan McGrath's avatar Brendan McGrath Committed by Alexandre Julliard

d2d1: Use 24-bit FP precision for triangulate.

This fixes a rendering issue (and ultimately a crash) in PowerPoint when compiling with GCC 8. GCC8 doesn't support the `excess-precision=standard` option under the `#pragma GCC optimize` directive. This results in unpredictable floating point rounding leading to errors when inserting segments (with missing edges and/or triangles). Using 24-bit precision ensures we don't have any excess precision.
parent eb5993a7
...@@ -16,10 +16,6 @@ ...@@ -16,10 +16,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC optimize "O2,no-strict-aliasing,excess-precision=standard"
#endif
#include "d2d1_private.h" #include "d2d1_private.h"
#include <float.h> #include <float.h>
...@@ -1539,7 +1535,7 @@ static BOOL d2d_cdt_triangulate(struct d2d_cdt *cdt, size_t start_vertex, size_t ...@@ -1539,7 +1535,7 @@ static BOOL d2d_cdt_triangulate(struct d2d_cdt *cdt, size_t start_vertex, size_t
return TRUE; return TRUE;
} }
/* More than tree vertices, divide. */ /* More than three vertices, divide. */
cut = vertex_count / 2; cut = vertex_count / 2;
if (!d2d_cdt_triangulate(cdt, start_vertex, cut, &left_outer, &left_inner)) if (!d2d_cdt_triangulate(cdt, start_vertex, cut, &left_outer, &left_inner))
return FALSE; return FALSE;
...@@ -2289,6 +2285,9 @@ static HRESULT d2d_path_geometry_triangulate(struct d2d_geometry *geometry) ...@@ -2289,6 +2285,9 @@ static HRESULT d2d_path_geometry_triangulate(struct d2d_geometry *geometry)
size_t vertex_count, i, j; size_t vertex_count, i, j;
struct d2d_cdt cdt = {0}; struct d2d_cdt cdt = {0};
D2D1_POINT_2F *vertices; D2D1_POINT_2F *vertices;
#ifdef __i386__
unsigned int control_word_x87, mask = 0;
#endif
for (i = 0, vertex_count = 0; i < geometry->u.path.figure_count; ++i) for (i = 0, vertex_count = 0; i < geometry->u.path.figure_count; ++i)
{ {
...@@ -2339,10 +2338,20 @@ static HRESULT d2d_path_geometry_triangulate(struct d2d_geometry *geometry) ...@@ -2339,10 +2338,20 @@ static HRESULT d2d_path_geometry_triangulate(struct d2d_geometry *geometry)
cdt.free_edge = ~0u; cdt.free_edge = ~0u;
cdt.vertices = vertices; cdt.vertices = vertices;
#ifdef __i386__
control_word_x87 = _controlfp(0, 0);
_controlfp(_PC_24, mask = _MCW_PC);
#endif
if (!d2d_cdt_triangulate(&cdt, 0, vertex_count, &left_edge, &right_edge)) if (!d2d_cdt_triangulate(&cdt, 0, vertex_count, &left_edge, &right_edge))
goto fail; goto fail;
if (!d2d_cdt_insert_segments(&cdt, geometry)) if (!d2d_cdt_insert_segments(&cdt, geometry))
goto fail; goto fail;
#ifdef __i386__
_controlfp(control_word_x87, _MCW_PC);
mask = 0;
#endif
if (!d2d_cdt_generate_faces(&cdt, geometry)) if (!d2d_cdt_generate_faces(&cdt, geometry))
goto fail; goto fail;
...@@ -2354,6 +2363,9 @@ fail: ...@@ -2354,6 +2363,9 @@ fail:
geometry->fill.vertex_count = 0; geometry->fill.vertex_count = 0;
free(vertices); free(vertices);
free(cdt.edges); free(cdt.edges);
#ifdef __i386__
if (mask) _controlfp(control_word_x87, mask);
#endif
return E_FAIL; return E_FAIL;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment