[OpenJDK 2D-Dev] X11 uniform scaled wide lines and dashed lines; STROKE_CONTROL in Pisces
Jim Graham
james.graham at oracle.com
Tue Sep 14 21:12:53 UTC 2010
On 9/14/2010 10:48 AM, Denis Lila wrote:
> Hello Jim.
>
>> sx1,sy1 have lost their way along the way somewhere.
>
> I think that was my fault:
Not entirely - see below.
>> I don't think you actually need sx1, sy1 - instead you need to buffer
>> and save aside the first set of dashes and I don't see that buffer
>> anywhere...
>
> sx1, sy1 were the buffer themselves, because we used to do flattening
> so there were no curves, and no need for an array. I did not see what
Actually then they were already buggy. It isn't enough to save 2
values. If the first "on" dash length is fairly long, and there are,
say, 50 segments of various types (though even when we were flattening
there could be multiple segments in the first "dash", they'd just all be
lines) then you need to save *all* of them aside and then spit them back
out connected to the final set of dash segments. If the old code was
only saving 2 coordinates then it wasn't doing it right.
So, a buffer should have always been provided/used and sx1,sy1 should
never have been sufficient (though they may have been a "broken" attempt
to achieve the same goal).
> they were used for, so I did not implement a buffer to replace them.
> I have now. I also fixed a couple of bugs (one related to drawing square
> caps and the other related to drawing joins), and I have tried to
> fix the whitespace (please tell me if I missed anything).
> The link is the same:
> http://icedtea.classpath.org/~dlila/webrevs/noflatten/webrev/
I'll take a look at this if I can, but last minute JavaOne issues (like
a rewrite of my slides - gulp) are starting to take over my life for the
next couple of weeks.
> There are a few smallish issues I wanted to discuss:
> 1. To subdivide at arbitrary t, I use equations like (1-t)*p1 + t*p2.
> Should I use the more intuitive p1+t*(p2-p1)? It's clearer and should be
> faster since it has 1 fewer multiplication.
I like that other equation. Both are find and equally understandable so
use whatever makes the code flow or perform better for your cases.
> 2. When computing offset curves, I check for degenerate curves (i.e. equal
> control and end points). I don't use == for comparisons. I use a function
> that returns true if 2 floats are close to each other, for fear of
> catastrophic cancellation. Is this really a good idea? If so, how close
> should the numbers be before I return true?
That's a great question. In device space I think a very small
difference (like 1/256 of a pixel) could be enough to ignore the curve,
but in user space it's harder to make a judgment call without knowing
how much they'll be scaled up. In cases like that I've sometimes used
the Math.ulp() method to figure out how many "bits of error" we have.
That method gives you the smallest increment for a given float or double
so what it is telling you is the magnitude of an "off by 1 bit" error.
If you allow differences less than 3*ulp(one of the values) then that is
allowing 1 or 2 bits of precision error. I'd use more than 2*ulp
because the numbers you are comparing might be close to a cutoff where
the binary exponent is increased. You can also choose the largest
(magnitude) of the values you are comparing and the ulp() of that value
gives you a safer estimate of being "off by a bit or two", but that
requires you to do a max() (and possibly an abs()) test just to find out
how big of a difference to allow so I usually use a multiplier of at
least 3 or so.
> 3. Should line 862 in Stroker be enabled (I give some reasons for wanting to
> in a comment below it).
That'll take me a day or two just to understand and figure out...
<crosseyed smiley>
...jim
More information about the 2d-dev
mailing list