[OpenJDK 2D-Dev] X11 uniform scaled wide lines and dashed lines; STROKE_CONTROL in Pisces
james.graham at oracle.com
Mon Oct 18 17:48:26 PDT 2010
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
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...)
More information about the 2d-dev