[2/3] gdiplus: fix GdipPathIterNextMarker behaviour on path without markers. fix tests.

Michael Karcher wine at mkarcher.dialup.fu-berlin.de
Sun Jul 13 12:27:57 CDT 2008


Am Sonntag, den 13.07.2008, 18:43 +0400 schrieb Nikolay Sivov:
> >> Exactly, so I plan to test this deeper on native. As I see now after 
> >> some basic tests, most probably native call does a bitwise comparison 
> >> cause the result is affected by a smallest matrix element change (e.g. 
> >> 1.0000000f -> 1.0000001f). But I'll test it more.
> > 1+FLT_EPSILON is the value to use for the "smallest matrix element
> > change". But sour test already is a very strong indication that it
> > really is strict equality test. FLT_EPSILON is in <float.h>
> This header is optional, isn't it? I've used FLT_EPSILON in call PlgBlt 
> of gdi32, but it was replaced with 1e-5 on commit (it was fabs(det) < 
> FLT_EPSILON).
To the best of my knowledge and the web pages I found on this topic,
float.h is standard ANSI C. There should be no need to avoid this
header.

On the other hand, I don't understand why you use 1e-5 or FLT_EPSILON at
that point at all. If I am not totally confused, you calculate some kind
of determinant from the nRect entries, which were directly before
initialized from the nXSrc, nYSrc, nWidth, nHeight variables, which are
integers, so rect contains integer values. The formula for det only
contains subtraction and multiplication. How do you expect that the
outcome of this calculation is non-integral?

> >  A hint how I would
> > implement that test (if it turns out that a strict comparison to 0 is
> > not the right result): Do not calculate the sum of a*d and -b*c, but
> > compare these numbers in a sensible way.   
> Here I something like FLT_EPSILON constant. So it's the same like above.
Be aware that 2+FLT_EPSILON stored into a float still is 2! You do not
want to write fabs(a*d-b*c) < FLT_EPSILON.

Try this:

<<<
#include <float.h>
#include <stdio.h>

float det(float a, float b, float c, float d)
{
  return fabs(a*b-c*d);
}

int main(void)
{
  printf("%g %g\n",det(100./3,120./7,12000./21,1), FLT_EPSILON);
}
>>>

compiled with no optimization (to avoid the compiler pre-calculating the
determinant with higher precision). You will see that the difference is
*much* bigger than FLT_EPSILON, yet the matrix was intended to be
singular (and were singular if there were no rounding errors on the
thirds). You should understand the cause of this before you try to write
a robust float comparison function.

Regards,
  Michael Karcher





More information about the wine-devel mailing list