Hi Laurent,

I'm just reading through the code now to get a handle on the nature of the 
changes...(and starting with the 2D version)...

[D]Dasher.java - why the changes from (firstSegIdx > 0) to (firstSegIdx != 0)?
[D]Dasher.java - why is there a new goto_starting() which is only used from one place? To be able to add final to the parameters?
[D]Dasher.java, line 268ish - why move the call to out.moveto() down a line?

[D]Stroker.java, line 170ish - you added final to the float params, but not the 
double
[D]Stroker.java, line 196ish - why are ROUND treated differently.  You have a 
question on that as well in a comment.
[D]Stroker.java, line 196ish - CAP_SQUARE would require more than lw/2 padding. 
 I think it needs lw*sqrt(2)/2 padding.

I would think the padding would be (max of the CAP/JOIN values below):
CAP_BUTT - lw/2
CAP_ROUND - lw/2
CAP_SQUARE - lw/2 * sqrt(2)
JOIN_BEVEL - lw/2
JOIN_ROUND - lw/2
JOIN_MITER - max(lw/2, miter_limit * lw)

In other words:
- lw/2 by default
- if CAP_SQUARE then multiply that by sqrt(2)
- if JOIN_MITER then max it with limit

I'm still looking through the management of the closed path detection coordinates, but I thought I'd get at least these questions out first before the weekend...

                                ...jim

On 8/25/17 1:09 PM, Laurent Bourgès wrote:
Hi,

Please review Marlin/FX upgrades that provide an efficient path clipper in
Stroker (float / double variants) fixing the bug JDK-8184429
<https://bugs.openjdk.java.net/browse/JDK-8184429>

Marlin2D patch (jdk10):
http://cr.openjdk.java.net/~lbourges/marlin/marlin-080.0/
MarlinFX patch (openjfx10):
http://cr.openjdk.java.net/~lbourges/marlinFX/marlin-080.0/

Path Clipper in (D)Stroker:
- it uses outcode computation (cohen - sutherland) for segment edges (2 for
lines, 3 for quads, 4 for cubics)
- it opens the path when a segment is invisible ie special moveTo() and
ignore invisible joins; it does not compute any intersection (line /
curve), it just skips useless segment for better performance and accuracy
- the ClosedPathDetector is needed to infer if the path is closed or not
(call to closePath) to produce caps when appropriate. It reuses the former
PolyStack (moved into Helper classes) to store the forward segments
- the clip rectangle is adjusted either in Stroker but also in
Transformer2D to take into account the mitter limit, stroker width and also
the Renderer offset

That's why it can not be applied to closed paths (fill operations) as the
path must remain closed in such case (concave polygon).
This could be implemented later as it needs to insert corner points when
needed to avoid artefacts; so the algorithm seem more complicated to me.

Marlin2D / FX Patches are slightly different to handle the Renderer offsets.

I tested these patches against my MapBench test with a small clip and
several affine transforms: it does not produce any artefact (0 pixel
difference between clip=true/false)

PS: I also improved the accuracy of Renderer's AFD by using the kaham
compensated-sum approach (later patch)

Cheers,
Laurent Bourgès

Reply via email to