[OpenJDK 2D-Dev] RFC: Fix for 7036754

Jim Graham james.graham at oracle.com
Wed Apr 20 23:52:01 UTC 2011


Hi Denis,

On 4/20/2011 2:06 PM, Denis Lila wrote:
>> One thing I just looked at and I'm wondering about is why there are
>> linetos at line 850 and 865. Shouldn't those points already be
>> interpolated either by the end of the previous segment or the end of
>> the
>> one that was just added? Does this add a lot of extra dirt into the
>> outlines?
>
> I'm not completely sure. Maybe to plug holes between curves after
> subdivision? I will think about this more and give you a better
> answer later. We should be very careful if changing this though. I vaguely
> remember inserting them when I originally wrote this code to solve
> some nasty bugs.

Yes, it would be good to keep this in mind.  Should I file a bug/rfe on it?

>> I didn't see where you had the "x1 == x2&&  y1 == y2..." block that
>> you
>> mentioned below. Did you decide against that one as well? I'm not sure
>> it will end up causing non-finite values in the computeIntersection
>> methods because computeOffset protects against divide by zero and
>> returns dummy values which may actually induce us to find finite
>> intersection points.
>
> Yes, I decided against it. I think it was redundant because if
> "(x1 == x2&&  y1 == y2 ||..." is true then computeIntersection
> is guaranteed to compute NaNs, for both the right path and the
> left path. In that case we call getLineOffsets, which is exactly
> what we would do in the "(x1 == x2&&  y1 == y2 ||..." case.

Ah, I see it now.  Either dx1,dy1 are both zero or dx3,dy3 are both zero 
in which case computeOffsets returns 0 offsets for one of the endpoints 
and computeIntersection is called to find the intersection of a line and 
a pair of identical points and that identical pair ends up generating a 
den==0 which causes Inf or NaN.  Cool.  Is that worth a comment somewhere?

Also, the comment in computeIntersection claims that it can't get 
infinities because drawMiter already eliminated them, but the quad code 
doesn't eliminate them so that is worth a mention.

> This way, that rare special case is made slower and everything
> else is made a bit faster.

Perfect!

>> Now that you have a case where you are testing "!isNot", it points out
>> that maybe the method should be renamed "isFinite" and have its return
>> value inverted so that we don't get a bunch of double negatives in the
>> code (my head is reeling a little from reviewing that line ;-). (OK,
>> so I'm about to point out that this new addition isn't needed anyway, but
>> in case we find a need to apply ! to the isNot method in the future,
>> it will look annoying when that happens.)
>
> Eh, I was hoping you wouldn't mind :-)
> I did it this way to minimize the total number of "!"s. With isNotFinite
> there are no "!" at all. With isFinite there must be at least 2.

!isFinite() is shorter than isNonFinite.  I find them about equal to 
read, but if we ever end up with another "!isNonFinite" my head might 
explode and I would not enjoy that.  ;)

I just noticed that you made this change and I was going to suggest the 
version that you just wrote so I'm doing the happy dance (not like 
that's a goal here, but thanks ;-)  Just in case I sent an internal 
message to one of our IEEE FP experts to verify that the range test is 
complete and performant.

You could actually avoid all of the "!" by swapping the code bodies 
around and using if/else:

	if (both finite) {
	    quad1 code
	} else {
	    computeIntersection2
	    if (both finite) {
	        quad2 code
	    } else {
	        line code
	    }
	}

> Updated webrev:
> http://icedtea.classpath.org/~dlila/webrevs/7036754/webrev/

Looks correct, but what do you think about the suggestions I've made above?

			...jim



More information about the 2d-dev mailing list