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
