On Sun, 6 Sep 2026 22:27:53 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: > > Optimized dirty rect handling (benefits more than just SWDraingContext) Here is the next batch of comments... modules/javafx.graphics/src/main/java/com/sun/prism/sw/SWDrawingContext.java line 238: > 236: } > 237: > 238: throw new IllegalStateException("image buffer is neither heap > array-backed nor direct"); Will `ByteBuffer.allocate().asIntBuffer()` be rejected? modules/javafx.graphics/src/main/java/com/sun/prism/sw/SWDrawingContext.java line 980: > 978: } > 979: > 980: path.setWindingRule(fillRule == FillRule.EVEN_ODD ? > Path2D.WIND_EVEN_ODD : Path2D.WIND_NON_ZERO); this overwrites the current winding rule - it it compatible with the API spec in `DrawingContext` ? modules/javafx.graphics/src/main/java/com/sun/prism/sw/SWDrawingContext.java line 982: > 980: path.setWindingRule(fillRule == FillRule.EVEN_ODD ? > Path2D.WIND_EVEN_ODD : Path2D.WIND_NON_ZERO); > 981: > 982: graphics.setTransform(BaseTransform.IDENTITY_TRANSFORM); will that work with non-uniform transform scaling or shear? also, what would happen if an absolute gradient or image patterns are used? can we add these cases to the test? modules/javafx.graphics/src/main/java/com/sun/prism/sw/SWDrawingContext.java line 1005: > 1003: */ > 1004: > 1005: double scale = Math.sqrt(transform.getMxx() * > transform.getMxx() + transform.getMyx() * transform.getMyx()); will it work correctly with a non-uniform scale? modules/javafx.graphics/src/main/java/com/sun/prism/sw/SWDrawingContext.java line 1097: > 1095: > 1096: @Override > 1097: public void fillText(String text, double x, double y, double > maxWidth) { what's the behavior of `fillText()` when `maxWidth` <= 0? modules/javafx.graphics/src/main/java/com/sun/prism/sw/SWDrawingContext.java line 1206: > 1204: > 1205: // Ensure it's a Prism image > 1206: if (!(platformImage instanceof com.sun.prism.Image prismImage)) > { `GraphicsContext::drawImage()` silently ignores a `null` image, should this method simply return instead of throwing an exception? modules/javafx.graphics/src/main/java/javafx/scene/image/DrawingContext.java line 226: > 224: * <td class="colLast"> > 225: * The method used to determine the interior of paths for a > path fill or > 226: * clip operation. minor: bad indent modules/javafx.graphics/src/main/java/javafx/scene/image/WritableImage.java line 175: > 173: public final DrawingContext getDrawingContext() { > 174: if (drawingContext == null) { > 175: drawingContext = > Toolkit.getToolkit().createDrawingContext(getWritablePlatformImage(), > this::notifyDrawingContextDirty); `setPlatformImage()` L1086 can replace the platform image (as a result of `snapshot`, for instance). this will disassociate the cached `drawingContext` from the platform image. ------------- PR Review: https://git.openjdk.org/jfx/pull/1969#pullrequestreview-5283695099 PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4076550428 PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4076697519 PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4076519801 PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4076530789 PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4076648763 PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4076742281 PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4076702229 PR Review Comment: https://git.openjdk.org/jfx/pull/1969#discussion_r4076428807
