[OpenJDK 2D-Dev] X11 uniform scaled wide lines and dashed lines; STROKE_CONTROL in Pisces

Jim Graham james.graham at oracle.com
Tue Oct 19 00:48:26 UTC 2010


Hi Denis,

On 10/18/2010 2:21 PM, Denis Lila wrote:
>> Are you happy with the current variable names?
>
> Not really. The names you suggested are much better. I'm using them now.
> As for making a vector class, I think we should push this and then decide.
> It's absence has already done most of the damage it could possibly do, so
> it's not an urgent matter. And besides, pushing a good version of this first
> will make it easier to determine the performance impact of the vector class.

Woohoo!  Note comment needs updating at line 90.

> I introduced a drawRoundCap method. This eliminated the side argument from
> the round join drawing, which made it easier to eliminate the trig function
> calls. I did this by using dot products to compute cosines (which was possible
> because now Stroker takes only untransformed paths, and all lineWidths are the
> same), and I used the double angle identities to compute any sines.
> I came up with my own ways of detecting acute/obtuse angles and finding the centres
> of angles ("my own" meaning I didn't look at any websites), and they consist of:
> 1. if (omx * mx + omy * my)>= 0 then the angle is acute (line 200).
> 2. I explain this in a comment in the file (line 208).

Yay.  And I can't believe you got that much mileage out of that one 
change.  Cool!  I'll verify the math tomorrow (it doesn't look hard, but 
I'm almost out of here).

> I was tempted to do this. I didn't because the boolean versions will need
> absolute coordinates, while the non boolean ones require relative ones. So
> if the non boolean versions need to be called and all we have are the boolean
> ones, 2 dummy arguments need to be supplied. However, I've looked at the code
> more closesly, and it turns out that we only use the non boolean versions
> from inside the boolean versions, so I've followed your suggestion (except
> on emitLineTo, since the non boolean version of that is used quite a bit).

OK, no problem.

>> line 374 - why is this moveto here?  Doesn't this break the joined
>> path into 2 separate paths?  Should this be a lineto?
>
> It does break it into 2 separate paths, but that's the correct behaviour
> in this case. Mathematically speaking, the 2 offset curves are spearate
> curves (despite any intersections). This changes when we use caps, but
> when using closePath(), caps aren't drawn so we<i>should</i>  have 2 separate
> paths. This is also the behaviour of oracle's closed source java (which
> can be seen in one of the Java2Ddemo demos - the one that draws the offset
> curves of a star with a vertical slider controlling the line width).

Oh, duh!  I get it.  I had been looking at Dasher all day before that 
and so I was thinking of this in terms of "connecting the last dash to 
the first" which would, of course, be one continuous path, but this is 
Stroker so if you get a close then it has an inner and outer path. 
Sorry for the distraction.

>> line 389 - The test here is different from closePath.  What if they
>> were both "prev == DRAWING_OP_TO"?
>
> I am now using prev!=DRAWING_OP_TO (not ==, since it is supposed to execute
> finish() if no nonzero length lines have been fed to Stroker yet). In fact
> I have removed the "started" variable since it's equivalent to prev==DRAWING_OP_TO.

Interesting.  I'll have to trace this later, but it sounds good.

>> line 337 - shouldn't this just return?  I don't think that empty lines
>> should modify the path at all.  If this is a case of "moveto(x,y);
>> lineto(x,y)" then the finish() code should deal with the "path that
>> never went anywhere - i.e. drawing a dot", shouldn't it?  The only
>> problem is that moveTo never set up omx,omy so finish will likely draw
>> something random.  Perhaps if moveto (and closepath) simply set up
>> omx,omy to w,0 (or 0,-w if you prefer) then finish would do a
>> reasonable thing for empty paths?
>
> The reason I made it the way it is is to match what proprietary java
> does. If one tries to draw a path like moveTo(0,0);lineTo(100,-100);
> lineTo(100,-100);lineTo(0,-200); instead of ignoring the second lineTo(100,-100)
> it will instead behave as if it were something like lineTo(100.00001,-100.00001),
> and it will draw the join. Of course, just because proprietary java does it, it
> doesn't mean it's the right thing to do. So, should I still make it ignore segments
> of 0 length?

No, let me think about this some more.  Compatible is a good default for 
now until we understand it fully so let's not derail for that.

>> line 283 - doesn't this simplify to?:
>>      t = x10p*(y0-y0p) - y10p*(x0-x0p)
>> (source: http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/)
>> then calculating:
>>      t = (...)/den;
>> can amortize the dividend from the following 2 calculations.
>
> I am using this t calculation now. I don't see how what I had simplified
> into this though. This is makes me think we were using a wrong equation, which is
> puzzling since I didn't notice any problems with drawing miters or quadratic beziers.
> Well, maybe I just made some mistake in trying to show they're equivalent. It doesn't
> matter.

No, actually they are identical.  If you expand it out, they are the 
same value - one just does more calculations.  The only reason I noted 
it was that I googled for the formula and found this form and had to 
verify that the one that was there was the same - at which point I noted 
that the google version had fewer operations.

>> My head started spinning when evaluating the parallel curve methods so
>> I'll stop here for now...
>
> Sorry about that. Is there anything I can do to make it easier?

No, I eventually muddled through it (in later emails...)

			...jim



More information about the 2d-dev mailing list