Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
e8b4d8e0
Commit
e8b4d8e0
authored
Oct 06, 2015
by
Henri Verbeet
Committed by
Alexandre Julliard
Oct 07, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
d2d1: Implement d2d_point_ccw() in a more robust way.
Signed-off-by:
Henri Verbeet
<
hverbeet@codeweavers.com
>
parent
f35bfff4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
278 additions
and
4 deletions
+278
-4
configure
configure
+28
-0
configure.ac
configure.ac
+1
-0
Makefile.in
dlls/d2d1/Makefile.in
+1
-0
geometry.c
dlls/d2d1/geometry.c
+248
-4
No files found.
configure
View file @
e8b4d8e0
...
...
@@ -632,6 +632,7 @@ POLL_LIBS
DL_LIBS
TOOLSEXT
UNWINDFLAGS
EXCESS_PRECISION_CFLAGS
BUILTINFLAG
EXTRACFLAGS
PROCSTAT_LIBS
...
...
@@ -13993,6 +13994,32 @@ $as_echo "$ac_cv_cflags__fno_strict_aliasing" >&6; }
if
test
"x
$ac_cv_cflags__fno_strict_aliasing
"
=
xyes
;
then
:
EXTRACFLAGS
=
"
$EXTRACFLAGS
-fno-strict-aliasing"
fi
{
$as_echo
"
$as_me
:
${
as_lineno
-
$LINENO
}
: checking whether the compiler supports -fexcess-precision=standard"
>
&5
$as_echo_n
"checking whether the compiler supports -fexcess-precision=standard... "
>
&6
;
}
if
${
ac_cv_cflags__fexcess_precision_standard
+
:
}
false
;
then
:
$as_echo_n
"(cached) "
>
&6
else
ac_wine_try_cflags_saved
=
$CFLAGS
CFLAGS
=
"
$CFLAGS
-fexcess-precision=standard"
cat
confdefs.h -
<<
_ACEOF
>conftest.
$ac_ext
/* end confdefs.h. */
int main(int argc, char **argv) { return 0; }
_ACEOF
if
ac_fn_c_try_link
"
$LINENO
"
;
then
:
ac_cv_cflags__fexcess_precision_standard
=
yes
else
ac_cv_cflags__fexcess_precision_standard
=
no
fi
rm
-f
core conftest.err conftest.
$ac_objext
\
conftest
$ac_exeext
conftest.
$ac_ext
CFLAGS
=
$ac_wine_try_cflags_saved
fi
{
$as_echo
"
$as_me
:
${
as_lineno
-
$LINENO
}
: result:
$ac_cv_cflags__fexcess_precision_standard
"
>
&5
$as_echo
"
$ac_cv_cflags__fexcess_precision_standard
"
>
&6
;
}
if
test
"x
$ac_cv_cflags__fexcess_precision_standard
"
=
xyes
;
then
:
EXCESS_PRECISION_CFLAGS
=
"-fexcess-precision=standard"
fi
saved_CFLAGS
=
$CFLAGS
{
$as_echo
"
$as_me
:
${
as_lineno
-
$LINENO
}
: checking whether the compiler supports -Werror=unknown-warning-option"
>
&5
$as_echo_n
"checking whether the compiler supports -Werror=unknown-warning-option... "
>
&6
;
}
...
...
@@ -17111,6 +17138,7 @@ MPG123_CFLAGS = $MPG123_CFLAGS
MPG123_LIBS =
$MPG123_LIBS
KSTAT_LIBS =
$KSTAT_LIBS
PROCSTAT_LIBS =
$PROCSTAT_LIBS
EXCESS_PRECISION_CFLAGS =
$EXCESS_PRECISION_CFLAGS
DL_LIBS =
$DL_LIBS
POLL_LIBS =
$POLL_LIBS
RT_LIBS =
$RT_LIBS
...
...
configure.ac
View file @
e8b4d8e0
...
...
@@ -1820,6 +1820,7 @@ then
dnl Check for some compiler flags
WINE_TRY_CFLAGS([-fno-builtin],[AC_SUBST(BUILTINFLAG,"-fno-builtin")])
WINE_TRY_CFLAGS([-fno-strict-aliasing])
WINE_TRY_CFLAGS([-fexcess-precision=standard],[AC_SUBST(EXCESS_PRECISION_CFLAGS,"-fexcess-precision=standard")])
dnl clang needs to be told to fail on unknown options
saved_CFLAGS=$CFLAGS
WINE_TRY_CFLAGS([-Werror=unknown-warning-option],[CFLAGS="$CFLAGS -Werror=unknown-warning-option"])
...
...
dlls/d2d1/Makefile.in
View file @
e8b4d8e0
...
...
@@ -2,6 +2,7 @@ MODULE = d2d1.dll
IMPORTLIB
=
d2d1
IMPORTS
=
d3d10_1 dxguid uuid
DELAYIMPORTS
=
dwrite
CFLAGS
+=
$(EXCESS_PRECISION_CFLAGS)
C_SRCS
=
\
bitmap.c
\
...
...
dlls/d2d1/geometry.c
View file @
e8b4d8e0
...
...
@@ -20,12 +20,17 @@
#include "wine/port.h"
#include "d2d1_private.h"
#ifdef HAVE_FLOAT_H
#include <float.h>
#endif
WINE_DEFAULT_DEBUG_CHANNEL
(
d2d
);
#define D2D_CDT_EDGE_FLAG_FREED 0x80000000u
#define D2D_CDT_EDGE_FLAG_VISITED(r) (1u << (r))
#define D2D_FP_EPS (1.0f / (1 << FLT_MANT_DIG))
static
const
D2D1_MATRIX_3X2_F
identity
=
{
1
.
0
f
,
0
.
0
f
,
...
...
@@ -75,6 +80,171 @@ struct d2d_cdt
const
D2D1_POINT_2F
*
vertices
;
};
struct
d2d_fp_two_vec2
{
float
x
[
2
];
float
y
[
2
];
};
static
void
d2d_fp_two_sum
(
float
*
out
,
float
a
,
float
b
)
{
float
a_virt
,
a_round
,
b_virt
,
b_round
;
out
[
1
]
=
a
+
b
;
b_virt
=
out
[
1
]
-
a
;
a_virt
=
out
[
1
]
-
b_virt
;
b_round
=
b
-
b_virt
;
a_round
=
a
-
a_virt
;
out
[
0
]
=
a_round
+
b_round
;
}
static
void
d2d_fp_fast_two_sum
(
float
*
out
,
float
a
,
float
b
)
{
float
b_virt
;
out
[
1
]
=
a
+
b
;
b_virt
=
out
[
1
]
-
a
;
out
[
0
]
=
b
-
b_virt
;
}
static
void
d2d_fp_two_diff_tail
(
float
*
out
,
float
a
,
float
b
,
float
x
)
{
float
a_virt
,
a_round
,
b_virt
,
b_round
;
b_virt
=
a
-
x
;
a_virt
=
x
+
b_virt
;
b_round
=
b_virt
-
b
;
a_round
=
a
-
a_virt
;
*
out
=
a_round
+
b_round
;
}
static
void
d2d_fp_two_two_diff
(
float
*
out
,
const
float
*
a
,
const
float
*
b
)
{
float
sum
[
2
],
diff
;
diff
=
a
[
0
]
-
b
[
0
];
d2d_fp_two_diff_tail
(
out
,
a
[
0
],
b
[
0
],
diff
);
d2d_fp_two_sum
(
sum
,
a
[
1
],
diff
);
diff
=
sum
[
0
]
-
b
[
1
];
d2d_fp_two_diff_tail
(
&
out
[
1
],
sum
[
0
],
b
[
1
],
diff
);
d2d_fp_two_sum
(
&
out
[
2
],
sum
[
1
],
diff
);
}
static
void
d2d_fp_split
(
float
*
out
,
float
a
)
{
float
a_big
,
c
;
c
=
a
*
((
1
<<
(
FLT_MANT_DIG
/
2
))
+
1
.
0
f
);
a_big
=
c
-
a
;
out
[
1
]
=
c
-
a_big
;
out
[
0
]
=
a
-
out
[
1
];
}
static
void
d2d_fp_two_product_presplit
(
float
*
out
,
float
a
,
float
b
,
const
float
*
b_split
)
{
float
a_split
[
2
],
err1
,
err2
,
err3
;
out
[
1
]
=
a
*
b
;
d2d_fp_split
(
a_split
,
a
);
err1
=
out
[
1
]
-
(
a_split
[
1
]
*
b_split
[
1
]);
err2
=
err1
-
(
a_split
[
0
]
*
b_split
[
1
]);
err3
=
err2
-
(
a_split
[
1
]
*
b_split
[
0
]);
out
[
0
]
=
(
a_split
[
0
]
*
b_split
[
0
])
-
err3
;
}
static
void
d2d_fp_two_product
(
float
*
out
,
float
a
,
float
b
)
{
float
b_split
[
2
];
d2d_fp_split
(
b_split
,
b
);
d2d_fp_two_product_presplit
(
out
,
a
,
b
,
b_split
);
}
static
float
d2d_fp_estimate
(
float
*
a
,
size_t
len
)
{
float
out
=
a
[
0
];
size_t
idx
=
1
;
while
(
idx
<
len
)
out
+=
a
[
idx
++
];
return
out
;
}
static
void
d2d_fp_fast_expansion_sum_zeroelim
(
float
*
out
,
size_t
*
out_len
,
const
float
*
a
,
size_t
a_len
,
const
float
*
b
,
size_t
b_len
)
{
float
sum
[
2
],
q
,
a_curr
,
b_curr
;
size_t
a_idx
,
b_idx
,
out_idx
;
a_curr
=
a
[
0
];
b_curr
=
b
[
0
];
a_idx
=
b_idx
=
0
;
if
((
b_curr
>
a_curr
)
==
(
b_curr
>
-
a_curr
))
{
q
=
a_curr
;
a_curr
=
a
[
++
a_idx
];
}
else
{
q
=
b_curr
;
b_curr
=
b
[
++
b_idx
];
}
out_idx
=
0
;
if
(
a_idx
<
a_len
&&
b_idx
<
b_len
)
{
if
((
b_curr
>
a_curr
)
==
(
b_curr
>
-
a_curr
))
{
d2d_fp_fast_two_sum
(
sum
,
a_curr
,
q
);
a_curr
=
a
[
++
a_idx
];
}
else
{
d2d_fp_fast_two_sum
(
sum
,
b_curr
,
q
);
b_curr
=
b
[
++
b_idx
];
}
if
(
sum
[
0
]
!=
0
.
0
f
)
out
[
out_idx
++
]
=
sum
[
0
];
q
=
sum
[
1
];
while
(
a_idx
<
a_len
&&
b_idx
<
b_len
)
{
if
((
b_curr
>
a_curr
)
==
(
b_curr
>
-
a_curr
))
{
d2d_fp_two_sum
(
sum
,
q
,
a_curr
);
a_curr
=
a
[
++
a_idx
];
}
else
{
d2d_fp_two_sum
(
sum
,
q
,
b_curr
);
b_curr
=
b
[
++
b_idx
];
}
if
(
sum
[
0
]
!=
0
.
0
f
)
out
[
out_idx
++
]
=
sum
[
0
];
q
=
sum
[
1
];
}
}
while
(
a_idx
<
a_len
)
{
d2d_fp_two_sum
(
sum
,
q
,
a_curr
);
a_curr
=
a
[
++
a_idx
];
if
(
sum
[
0
]
!=
0
.
0
f
)
out
[
out_idx
++
]
=
sum
[
0
];
q
=
sum
[
1
];
}
while
(
b_idx
<
b_len
)
{
d2d_fp_two_sum
(
sum
,
q
,
b_curr
);
b_curr
=
b
[
++
b_idx
];
if
(
sum
[
0
]
!=
0
.
0
f
)
out
[
out_idx
++
]
=
sum
[
0
];
q
=
sum
[
1
];
}
if
(
q
!=
0
.
0
f
||
!
out_idx
)
out
[
out_idx
++
]
=
q
;
*
out_len
=
out_idx
;
}
static
void
d2d_point_subtract
(
D2D1_POINT_2F
*
out
,
const
D2D1_POINT_2F
*
a
,
const
D2D1_POINT_2F
*
b
)
{
...
...
@@ -82,14 +252,88 @@ static void d2d_point_subtract(D2D1_POINT_2F *out,
out
->
y
=
a
->
y
-
b
->
y
;
}
/* This implementation is based on the paper "Adaptive Precision
* Floating-Point Arithmetic and Fast Robust Geometric Predicates" and
* associated (Public Domain) code by Jonathan Richard Shewchuk. */
static
float
d2d_point_ccw
(
const
D2D1_POINT_2F
*
a
,
const
D2D1_POINT_2F
*
b
,
const
D2D1_POINT_2F
*
c
)
{
D2D1_POINT_2F
ab
,
ac
;
static
const
float
err_bound_result
=
(
3
.
0
f
+
8
.
0
f
*
D2D_FP_EPS
)
*
D2D_FP_EPS
;
static
const
float
err_bound_a
=
(
3
.
0
f
+
16
.
0
f
*
D2D_FP_EPS
)
*
D2D_FP_EPS
;
static
const
float
err_bound_b
=
(
2
.
0
f
+
12
.
0
f
*
D2D_FP_EPS
)
*
D2D_FP_EPS
;
static
const
float
err_bound_c
=
(
9
.
0
f
+
64
.
0
f
*
D2D_FP_EPS
)
*
D2D_FP_EPS
*
D2D_FP_EPS
;
float
det_d
[
16
],
det_c2
[
12
],
det_c1
[
8
],
det_b
[
4
],
temp4
[
4
],
temp2a
[
2
],
temp2b
[
2
],
abxacy
[
2
],
abyacx
[
2
];
size_t
det_d_len
,
det_c2_len
,
det_c1_len
;
float
det
,
det_sum
,
err_bound
;
struct
d2d_fp_two_vec2
ab
,
ac
;
ab
.
x
[
1
]
=
b
->
x
-
a
->
x
;
ab
.
y
[
1
]
=
b
->
y
-
a
->
y
;
ac
.
x
[
1
]
=
c
->
x
-
a
->
x
;
ac
.
y
[
1
]
=
c
->
y
-
a
->
y
;
abxacy
[
1
]
=
ab
.
x
[
1
]
*
ac
.
y
[
1
];
abyacx
[
1
]
=
ab
.
y
[
1
]
*
ac
.
x
[
1
];
det
=
abxacy
[
1
]
-
abyacx
[
1
];
if
(
abxacy
[
1
]
>
0
.
0
f
)
{
if
(
abyacx
[
1
]
<=
0
.
0
f
)
return
det
;
det_sum
=
abxacy
[
1
]
+
abyacx
[
1
];
}
else
if
(
abxacy
[
1
]
<
0
.
0
f
)
{
if
(
abyacx
[
1
]
>=
0
.
0
f
)
return
det
;
det_sum
=
-
abxacy
[
1
]
-
abyacx
[
1
];
}
else
{
return
det
;
}
err_bound
=
err_bound_a
*
det_sum
;
if
(
det
>=
err_bound
||
-
det
>=
err_bound
)
return
det
;
d2d_fp_two_product
(
abxacy
,
ab
.
x
[
1
],
ac
.
y
[
1
]);
d2d_fp_two_product
(
abyacx
,
ab
.
y
[
1
],
ac
.
x
[
1
]);
d2d_fp_two_two_diff
(
det_b
,
abxacy
,
abyacx
);
det
=
d2d_fp_estimate
(
det_b
,
4
);
err_bound
=
err_bound_b
*
det_sum
;
if
(
det
>=
err_bound
||
-
det
>=
err_bound
)
return
det
;
d2d_fp_two_diff_tail
(
&
ab
.
x
[
0
],
b
->
x
,
a
->
x
,
ab
.
x
[
1
]);
d2d_fp_two_diff_tail
(
&
ab
.
y
[
0
],
b
->
y
,
a
->
y
,
ab
.
y
[
1
]);
d2d_fp_two_diff_tail
(
&
ac
.
x
[
0
],
c
->
x
,
a
->
x
,
ac
.
x
[
1
]);
d2d_fp_two_diff_tail
(
&
ac
.
y
[
0
],
c
->
y
,
a
->
y
,
ac
.
y
[
1
]);
if
(
ab
.
x
[
0
]
==
0
.
0
f
&&
ab
.
y
[
0
]
==
0
.
0
f
&&
ac
.
x
[
0
]
==
0
.
0
f
&&
ac
.
y
[
0
]
==
0
.
0
f
)
return
det
;
err_bound
=
err_bound_c
*
det_sum
+
err_bound_result
*
fabsf
(
det
);
det
+=
(
ab
.
x
[
1
]
*
ac
.
y
[
0
]
+
ac
.
y
[
1
]
*
ab
.
x
[
0
])
-
(
ab
.
y
[
1
]
*
ac
.
x
[
0
]
+
ac
.
x
[
1
]
*
ab
.
y
[
0
]);
if
(
det
>=
err_bound
||
-
det
>=
err_bound
)
return
det
;
d2d_fp_two_product
(
temp2a
,
ab
.
x
[
0
],
ac
.
y
[
1
]);
d2d_fp_two_product
(
temp2b
,
ab
.
y
[
0
],
ac
.
x
[
1
]);
d2d_fp_two_two_diff
(
temp4
,
temp2a
,
temp2b
);
d2d_fp_fast_expansion_sum_zeroelim
(
det_c1
,
&
det_c1_len
,
det_b
,
4
,
temp4
,
4
);
d2d_fp_two_product
(
temp2a
,
ab
.
x
[
1
],
ac
.
y
[
0
]);
d2d_fp_two_product
(
temp2b
,
ab
.
y
[
1
],
ac
.
x
[
0
]);
d2d_fp_two_two_diff
(
temp4
,
temp2a
,
temp2b
);
d2d_fp_fast_expansion_sum_zeroelim
(
det_c2
,
&
det_c2_len
,
det_c1
,
det_c1_len
,
temp4
,
4
);
d2d_point_subtract
(
&
ab
,
b
,
a
);
d2d_point_subtract
(
&
ac
,
c
,
a
);
d2d_fp_two_product
(
temp2a
,
ab
.
x
[
0
],
ac
.
y
[
0
]);
d2d_fp_two_product
(
temp2b
,
ab
.
y
[
0
],
ac
.
x
[
0
]);
d2d_fp_two_two_diff
(
temp4
,
temp2a
,
temp2b
);
d2d_fp_fast_expansion_sum_zeroelim
(
det_d
,
&
det_d_len
,
det_c2
,
det_c2_len
,
temp4
,
4
);
return
ab
.
x
*
ac
.
y
-
ab
.
y
*
ac
.
x
;
return
det_d
[
det_d_len
-
1
]
;
}
static
BOOL
d2d_array_reserve
(
void
**
elements
,
size_t
*
capacity
,
size_t
element_count
,
size_t
element_size
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment