On Sun, 4 Oct 2026 09:31:42 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. >> >> **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 implNote about known snapshot issue Still some issues, see inline. I think the buffer endianness issue might warrant a unit test. modules/javafx.graphics/src/main/java/com/sun/javafx/util/FXCleaner.java line 1: > 1: package com.sun.javafx.util; needs copyright header modules/javafx.graphics/src/main/java/com/sun/javafx/util/FXCleaner.java line 13: > 11: * Usage example: > 12: * <pre> > 13: * FXCleaner.register(resource, () -> resource.dispose()); bad example: the lambda creates a strong reference to `resource`, so the cleaner action will never run. 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 modules/javafx.graphics/src/main/java/com/sun/prism/sw/SWDrawingContext.java line 1241: > 1239: // Ensure it's a Prism image > 1240: if (!(platformImage instanceof com.sun.prism.Image prismImage)) > { > 1241: throw new IllegalArgumentException("PlatformImage must be a > Prism Image"); a failed image (progress=1.0, platformImage=null) will throw here, but public `drawImage()` specifies not such failure. should we check isError() and ignore? 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. modules/javafx.graphics/src/main/java/javafx/scene/image/WritableImage.java line 181: > 179: * format (for example, when created from a {@code > BYTE_BGRA_PRE} {@code PixelBuffer}) > 180: */ > 181: public final DrawingContext getDrawingContext() { `@since 28` modules/javafx.graphics/src/main/native-prism-sw/JDirectBufferSurface.c line 140: > 138: } > 139: > 140: void* data = (*env)->GetDirectBufferAddress(env, > surface->dataHandle); Will this fail when byte order of the direct buffer differs from the system byte order? ------------- Changes requested by angorya (Reviewer). PR Review: https://git.openjdk.org/jfx/pull/1969#pullrequestreview-5421134500 PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4189452768 PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4189528593 PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4189336903 PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4189448801 PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4189358677 PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4189458161 PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4189310424
