On Sun, 18 Oct 2026 17:35:43 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:
> 
>   Add missing since tags

A few more things -

modules/javafx.graphics/src/main/java/com/sun/prism/sw/SWDrawingContext.java 
line 731:

> 729:             graphics.setPaint(prismFillPaint);
> 730:             graphics.resetPaintBounds();
> 731:             graphics.fillRect((float)x, (float)y, (float)w, (float)h);

`fillRect()` uses `PiscesRenderer.fillRect()` which will overflow with wide / 
tall images due to `<< 16`.  Should it tile or explicitly call for width/height 
limitations in the constructor?

modules/javafx.graphics/src/main/java/com/sun/prism/sw/SWDrawingContext.java 
line 775:

> 773:     public void fillOval(double x, double y, double w, double h) {
> 774:         if (w != 0 && h != 0) {
> 775:             applyStrokeParameters();

are stroke parameters needed for the fill operation?

modules/javafx.graphics/src/main/java/com/sun/prism/sw/SWDrawingContext.java 
line 1276:

> 1274:             }
> 1275:             else {
> 1276:                 graphics.drawString(run, strike, runX, runY, null, 0, 
> 0);

what happens when text with proportional gradient is drawn too far right (ganz 
rechts)?  should the gradient anchor be set at the text position?

modules/javafx.graphics/src/main/java/com/sun/prism/sw/SWDrawingContext.java 
line 1303:

> 1301: 
> 1302:         // Create a texture from the Prism image
> 1303:         Texture tex = resourceFactory.createTexture(prismImage, 
> Usage.DEFAULT, Texture.WrapMode.CLAMP_TO_EDGE);

efficiency: this copies the whole image each time, even when drawing a small 
part of it.  is it worth optimizing?

modules/javafx.graphics/src/main/java/javafx/scene/image/DrawingContext.java 
line 469:

> 467:  * WritableImage writableImage = new WritableImage(250,250);
> 468:  * ImageView root = new ImageView(writableImage);
> 469:  * Scene s = new Scene(root, 300, 300, Color.BLACK);

the example does not compile

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

PR Review: https://git.openjdk.org/jfx/pull/1969#pullrequestreview-5575754917
PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4317852634
PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4317347681
PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4317206924
PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4318036870
PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4317366761

Reply via email to