On Mon, 5 Oct 2026 22:06:19 GMT, Andy Goryachev <[email protected]> wrote:

>> John Hendrikx has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Add implNote about known snapshot issue
>
> modules/javafx.graphics/src/main/java/com/sun/prism/sw/SWDrawingContext.java 
> line 1052:
> 
>> 1050:             return inversePath;
>> 1051:         }
>> 1052:         catch (NoninvertibleTransformException e) {
> 
> when this happens, the path will be unchanged.  graphics.fill() or .draw() 
> will then apply the same non-invertable transform again, which contradicts 
> DrawingContext:1414

This is a bit of an unusual case (and is a new bug introduced by fixing the 
non-uniform transform problem from last round); we now get correctly 
transformed strokes and gradients, but pay for it by having to keep the path in 
device space (which requires inverting before it can be rendered).

Since this deviation from the specification (derived from `GraphicsContext`) 
can only occur for degenerate transforms (where an axis is collapsed to zero), 
something which is unlikely to ever be something the user would do or want, and 
since it would require quite a bit of plumbing to make this work the same way 
as `GraphicsContext`, I think it would be best to simply document this as 
"unspecified" and render nothing at all.

In other words, if you construct a path, then just before calling `fill` or 
`stroke` you set a transform that collapses an axis, `SWDrawingContext` would 
render nothing at all; `GraphicsContext` would do the same for `stroke` (since 
the stroke itself would end up being 0 width so nothing will be drawn), but for 
`fill` it would still render the original shape (but any image pattern or 
gradient would be flattened/broken) -- mimicking this questionable behavior 
takes more effort than it is worth IMHO.

Comparison with `GraphicsContext`, only one case differs:

| op, singular transform | GraphicsContext | SWDrawingContext |
|---|---|---|
| `fill()` (path built *before* the collapse) | fills the frozen geometry 
(renders) | **nothing** |
| `fill()` (path built *under* the collapse) | nothing (geometry already 
degenerate) | nothing |
| `stroke()` (either order) | nothing | nothing |

TLDR; I made this unspecified in the `DrawingContext` interface, making both 
implementations compliant.

> modules/javafx.graphics/src/main/java/javafx/scene/image/DrawingContext.java 
> line 1602:
> 
>> 1600:      * @param x position on the x axis.
>> 1601:      * @param y position on the y axis.
>> 1602:      * @param maxWidth the maximum width of the string; a value of 
>> zero or
> 
> simply explaining away maxWidth<0 won't help, I think:
> SWDrawingContext:1294 honors the rule and draws text, while 
> GraphicsContext:1294 returns without drw=awing.

I misremembered what `GraphicsContext` did (it actually this time did the more 
sensible thing :))

-------------

PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4216364847
PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4216377011

Reply via email to