On Thu, 22 Oct 2026 23:25:45 GMT, John Hendrikx <[email protected]> wrote:

>> This PR adds a `getDrawingContext` method to `WritableImage`, which works 
>> similar to `Canvas::getGraphicsContext` and shares the same signatures. Key 
>> features include:
>> 
>> - **Shape rendering**: `strokeRect`, `fillRect`, `strokeOval`, `fillOval`, 
>> `strokeArc`, `fillArc`, `strokePolyline`, `fillPolygon`, etc.
>> - **Stroke and fill attributes**: `lineWidth`, `lineCap`, `lineJoin`, 
>> `miterLimit`, `fillRule`, `stroke` and `fill` paints.
>> - **Global graphics settings**: `globalAlpha` and `globalBlendMode`.
>> - **Image drawing**: draw other `Image` instances with scaling and 
>> source/destination rectangles.
>> - **Text rendering**: render text
>> - **Save/Restore**: store current stroke, font, dashes, etc and restore them 
>> later
>> - **Paths**: begin a path, with lines, curves, etc, then stroke or fill it
>> - **Clips**: support rectangular clips in the SW renderer
>> 
>> This feature enables direct software rendering to `WritableImage` without 
>> requiring a `Canvas` + snapshot.
>> 
>> **New API for `GraphicsContext`**
>> 
>> Because `GraphicsContext` was never designed to support a more generic API 
>> when it was conceived, it has gained a few new methods that were a better 
>> fit for the reusable `DrawingContext` interface:
>> 
>> - `clipRect(x, y, w, h)` -- convenience equivalent to `rect(...)` + `clip()`
>> - `getEffect()` -- no arg getter for the `Effect`
>> - `getTextDirection()` and `setTextDirection(NodeOrientation)` -- takes 
>> precedence over `Canvas.getNodeOrientation()` when not set to `INHERIT` (the 
>> default)
>> 
>> **Additional notes**:
>> 
>> - The implementation leverages the software stack consisting of the Marlin 
>> rasterizer and Pisces compositor/painter.
>> 
>> **Example usage**:
>> 
>> 
>> WritableImage img = new WritableImage(400, 400);
>> DrawingContext ctx = img.getDrawingContext();
>> ctx.setFill(Color.RED);
>> ctx.fillRect(50, 50, 100, 100);
>> 
>> 
>> See the sample program `RandomShapesDemo` to see a `WritableImage` and 
>> `Canvas` side by side performing the same operations:
>> 
>> <img width="1249" height="741" alt="image" 
>> src="https://github.com/user-attachments/assets/4a0b9dcc-8f96-4faa-99cf-83c66d2c851e";
>>  />
>> 
>> Newer version:
>> 
>> <img width="1249" height="741" alt="image" 
>> src="https://github.com/user-attachments/assets/c0502620-3d02-4fbd-8c33-43bd5138b42c";
>>  />
>> 
>> ---------
>> - [x] I confirm that I make this contribution in accordance with the 
>> [OpenJDK Interim AI Policy](https://openjdk.org/legal/ai).
>
> John Hendrikx has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Allow INT_ARGB_PRE format for icons

(For some reason I can't reply to this directly)

> another scenario is an attempt to fillRect with coordinates that overflow, 
> such as (-50000, 0, 50001, 1). in theory, this should fill its pixel. This is 
> pre-existing, and a bit contrived - I don't know whether we should even 
> address it (although I do like your idea of using wider numbers in 
> computations prior to rendering)

I think there will be similar problems also with `GraphicsContext`, especially 
when the software pipeline is active. So even though we may want to address 
this at some point, it could be a rather large change that is a bit out of 
scope for this PR, and also shouldn't block a genuinely useful feature 
especially when the problem is pre-existing and already can cause similar 
problems with Canvas + SW pipeline.

You're also fairly unlikely to run into these issues in practice; you'd either 
need huge images, or set a ridiculously small or large scale transform (small 
transforms may overflow in the other direction). Transforms are something that 
is AFAIK rarely used when using a rendering context.

Taking a closer look at Pisces, and I think it isn't trivial to change this. 
We're basically talking about a partial rewrite of native Pisces code to get 
this to work (having it use floats or use a different trade-off, like 32.32 
fixed point math). At that point you can also consider other options like 
retiring Pisces as there are more modern rasterizers out there that do use 
floating point that I think are license compatible with JavaFX.

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

PR Comment: https://git.openjdk.org/jfx/pull/1969#issuecomment-6373918575

Reply via email to