+++
title = "Graphite progress report (Q4 2024)"
date = 2025-03-31
[extra]
banner = "https://static.graphite.rs/content/blog/2025-03-31-graphite-progress-report-q4-2024.avif"
banner_png = "https://static.graphite.rs/content/blog/2025-03-31-graphite-progress-report-q4-2024.png"
author = "Keavon Chambers & Hypercube"
summary = "Graphite's Q4 2024 update introduces quality of life features across drawing tools and procedural editing."
css = ["/component/demo-artwork.css"]
reddit = "https://www.reddit.com/r/graphite/comments/1jpjqcs/blog_post_graphite_progress_report_q4_2024/"
twitter = "https://x.com/GraphiteEditor/status/1907350199414206604"
bluesky = "https://bsky.app/profile/graphiteeditor.bsky.social/post/3llsxykppjs2c"
+++
[Graphite](/), a new open source 2D procedural graphics editor, has [wrapped up 2024](../year-in-review-2024-highlights-and-a-peek-at-2025) with a fourth quarter (October-December) focused on introducing **quality of life features** for both Graphite's interactive **tools-driven and procedural editing workflows**.
All Q4 2024 commits may be [viewed in this list](https://github.com/GraphiteEditor/Graphite/commits/master/?since=2024-10-01&until=2024-12-31) and all noteworthy changes are detailed below.
This is the fourth in our 2024 series of quarterly progress reports. If you missed [the previous post](../graphite-progress-report-q3-2024), be sure to check it out as well. If you'd like to help speed up future progress, please consider [getting involved](/volunteer) with code, QA/bug testing, or art/marketing projects. [Donations](/donate) are also valued, as are [stars on GitHub](https://github.com/GraphiteEditor/Graphite). Follow along and partake in our [Discord community](https://discord.graphite.rs), too.
At the time of publication, there is **one week left to apply for a summer 2025 internship with us through Google Summer of Code.** [Learn more here](../internships-for-a-rust-graphics-engine-gsoc-2025) and apply before [April 8 at 18:00 UTC](https://www.wolframalpha.com/input?i=April+8%2C+18%3A00+UTC).
To showcase the newly introduced feature of converting selected nodes into conveniently reusable subgraphs, the new *Parametric Dunescape* artwork is presented below. Every dune layer is generated just by its custom parameters for color, height, and random seed.
## Additions
- Node graph support for making a custom node by merging the selected nodes into a subgraph with the node context menu's "Merge Selected Nodes" option, or the shortcut CtrlM (macOS: ⌘M) ([#2097](https://github.com/GraphiteEditor/Graphite/pull/2097))
- Text controls for line height, character spacing, and wrappable box areas that can be dragged with the Text tool ([#2016](https://github.com/GraphiteEditor/Graphite/pull/2016), [#2118](https://github.com/GraphiteEditor/Graphite/pull/2118))
- Pinnable node sections in the Properties panel ([commit e6d8c47](https://github.com/GraphiteEditor/Graphite/commit/e6d8c4743d2aff15985c929df2cc7381a61908a0))
- New demo artwork, [*Changing Seasons*](https://editor.graphite.rs/#demo/changing-seasons), featured in the [previous progress report](../graphite-progress-report-q3-2024) ([commit fa6b5f2](https://github.com/GraphiteEditor/Graphite/commit/fa6b5f298adf395362e1aaa2c07be89fa89eaee2))
- *Offset Path* node that expands or contracts a vector shape ([#2030](https://github.com/GraphiteEditor/Graphite/pull/2030))
- *Flatten Vector Elements* node that turns multiple layers of vector paths into a single combined path; and changes to the *Copy to Points*, *Repeat*, and *Circular Repeat* nodes so they output group data instead of a single vector path, allowing each separate layer to be modified by nodes which operate on groups (like *Assign Colors*), or flattened with *Flatten Vector Elements* to have the prior behavior ([#2011](https://github.com/GraphiteEditor/Graphite/pull/2011), [#2045](https://github.com/GraphiteEditor/Graphite/pull/2045))
- Support for *Fill* and *Stroke* nodes with groups, applying to each vector layer within ([#2046](https://github.com/GraphiteEditor/Graphite/pull/2046))
- *Switch* node that routes one of two data connections based on a true or false value ([#2064](https://github.com/GraphiteEditor/Graphite/pull/2064))
- *Bevel* node that flattens the corners of vector shapes ([#2067](https://github.com/GraphiteEditor/Graphite/pull/2067), [#2096](https://github.com/GraphiteEditor/Graphite/pull/2096))
- *Jitter Points* node that randomly offsets each point in a vector path ([commit 7d86bf4](https://github.com/GraphiteEditor/Graphite/commit/7d86bf4abf7edfe6a5d021075e050614bee07c13))
- Node insertion button, and layer renaming, directly from the Properties panel ([#2072](https://github.com/GraphiteEditor/Graphite/pull/2072), [#2081](https://github.com/GraphiteEditor/Graphite/pull/2081))
- Path tool feature where pressing Space while dragging a handle makes the anchor be dragged as well ([#2065](https://github.com/GraphiteEditor/Graphite/pull/2065))
- Path tool feature where pressing Tab while dragging a handle makes it swap to the opposite handle ([#2058](https://github.com/GraphiteEditor/Graphite/pull/2058))
- Pen tool feature allowing the connection of layers by their endpoints so they both get merged into a single layer ([#2076](https://github.com/GraphiteEditor/Graphite/pull/2076))
- *Clamp* node that limits an input number between a minimum and maximum range ([#2087](https://github.com/GraphiteEditor/Graphite/pull/2087))
- *To U32* and *To U64* nodes that convert numbers to a positive integer type required by a few nodes, as a workaround for automatic type conversion not being fully supported yet ([#2087](https://github.com/GraphiteEditor/Graphite/pull/2087))
- *Dot Product* node that calculates the mathematical dot product between two numerical vectors ([#2126](https://github.com/GraphiteEditor/Graphite/pull/2126))
- *Math* node that calculates a custom math expression with variables "A" and "B" ([#2121](https://github.com/GraphiteEditor/Graphite/pull/2121))
- Degrees/radians option in the trig-related math nodes and "Always Positive" option in the *Modulo* node for more convenient usage of the math nodes ([commit d649052](https://github.com/GraphiteEditor/Graphite/commit/d649052255c10c15754c3a3707f2edf996d2468d))
- Node graph control bar revamp ([#2093](https://github.com/GraphiteEditor/Graphite/pull/2093))
- Freehand tool feature for drawing new subpaths on an existing vector layer by holding Shift ([commit ed119ad](https://github.com/GraphiteEditor/Graphite/commit/ed119ad3d799030dbc488ccfc8ca9ad057eeff2c))
- Proper automatic placement of layers into the artboard they're drawn inside of ([#2110](https://github.com/GraphiteEditor/Graphite/pull/2110))
- Menu bar additions of *Layer* > *New*, *Layer* > *Group Selected*, and *Layer* > *Delete Selected* ([commit feba874](https://github.com/GraphiteEditor/Graphite/commit/feba87449bb490e47df6f267576bec5ab4238dc3))
- Select tool box selection feature for subtracting the targetted layers from the active selection with a modifier key as shown in the contextual input hints at the bottom of the editor ([#2162](https://github.com/GraphiteEditor/Graphite/pull/2162))
- Path tool feature for snapping to 15° increments and locking the angles of dragged handles when Shift and Ctrl modifier keys are pressed ([#2160](https://github.com/GraphiteEditor/Graphite/pull/2160))
- Support for multiple top output wires extending from the same layer stack ([#2049](https://github.com/GraphiteEditor/Graphite/pull/2049))
- Style improvements to the Layers panel UI to clarify which layers contain selected children, even if hidden within a collapsed layer which previously obscured where selected layers were within the hierarchy ([commit 1264ea8](https://github.com/GraphiteEditor/Graphite/commit/1264ea8246cbb06e0602a93be983762ab17adf30))
- Revamped quick measurement overlays now supporting every layer arrangement scenario ([#2147](https://github.com/GraphiteEditor/Graphite/pull/2147), [#2155](https://github.com/GraphiteEditor/Graphite/pull/2155))
## Fixes
- Fix for viewport tools no longer remaining active in the background when the node graph is open ([#2093](https://github.com/GraphiteEditor/Graphite/pull/2093))
- Fix to boolean operations so open subpaths are automatically closed ([#2014](https://github.com/GraphiteEditor/Graphite/pull/2014))
- Fix for a problem with double clicking an anchor for converting it between smooth and sharp ([#2023](https://github.com/GraphiteEditor/Graphite/pull/2023))
- Fix for a *Scatter Points* node breakage ([commit 7a56af0](https://github.com/GraphiteEditor/Graphite/commit/7a56af01efc82460e780c78b008a52487972a7eb))
- Fix for properly considering artboard clipping when calculating click targets ([#2028](https://github.com/GraphiteEditor/Graphite/pull/2028), [#2036](https://github.com/GraphiteEditor/Graphite/pull/2036))
- Fix for CtrlH layer hiding and CtrlL layer locking only working with the graph open ([#2029](https://github.com/GraphiteEditor/Graphite/pull/2029))
- Fix to artboard label positioning and styling of text overlays ([#2032](https://github.com/GraphiteEditor/Graphite/pull/2032))
- Fix for an assortment of crashes and bugs ([#2075](https://github.com/GraphiteEditor/Graphite/pull/2075))
- Fix for broken gradient transforms with the Vello renderer ([#2059](https://github.com/GraphiteEditor/Graphite/pull/2059))
- Fix for alignment snapping not preserving aspect ratio when Shift is held ([#2062](https://github.com/GraphiteEditor/Graphite/pull/2062))
- Fix for the Text tool clearing the text when hitting Esc ([#2052](https://github.com/GraphiteEditor/Graphite/pull/2052))
- Fix for allowing the Path tool to edit an upstream vector path even if there's a type conversion midway ([#2055](https://github.com/GraphiteEditor/Graphite/pull/2055))
- Fix for the number input widget not updating its unit symbol when changing to show another input field ([#2080](https://github.com/GraphiteEditor/Graphite/pull/2080))
- Fix to make the *Sample Points*, *Scatter Points*, and *Splines from Points* nodes generate segments (not just invisible points) and work with subpaths ([#2085](https://github.com/GraphiteEditor/Graphite/pull/2085))
- Fix for sometimes breaking the selected layer upon switching away from the Select tool ([commit 8d3da83](https://github.com/GraphiteEditor/Graphite/commit/8d3da83606c23366d2688602afbc0917e7224e68))
- Fix to remove a visual cutout from the left border of a layer in the node graph when a wire doesn't entering through the cutout ([commit 12ca060](https://github.com/GraphiteEditor/Graphite/commit/12ca06035cd7463ed895671ff7eebe53fde655c6))
- Fix to make point nudging with the Path tool work in document space ([#2095](https://github.com/GraphiteEditor/Graphite/pull/2095))
- Fix to make the *Spline* node algorithm be continuous across start/end points ([#2092](https://github.com/GraphiteEditor/Graphite/pull/2092))
- Fix to properly support layer nudging when the view is tilted and make nudge resizing work in the Artboard tool ([#2098](https://github.com/GraphiteEditor/Graphite/pull/2098))
- Fix to disable menu bar entries when no layer is selected ([#2098](https://github.com/GraphiteEditor/Graphite/pull/2098))
- Fix for clarifying the present state of the Brush tool with a warning message ([commit de366f9](https://github.com/GraphiteEditor/Graphite/commit/de366f951424fcdf4463a419db3fa659910fabfd))
- Fix to load the editor faster by moving font catalog loading to document creation time ([commit de366f9](https://github.com/GraphiteEditor/Graphite/commit/de366f951424fcdf4463a419db3fa659910fabfd))
- Fix to make the Pen tool only append new paths when Shift is held ([#2102](https://github.com/GraphiteEditor/Graphite/pull/2102))
- Fix to make the Pen tool always snap to endpoint anchors, even when snapping is off ([#2107](https://github.com/GraphiteEditor/Graphite/pull/2107))
- Fix crash when upgrading a document with a *Modulo* node from 3 commits ago ([commit 4c4d559](https://github.com/GraphiteEditor/Graphite/commit/4c4d559d97b4d131d2777c0aab19590531ae47a9))
- Fix to clean up the consistency of the editor preferences dialog ([commit 99cf8f0](https://github.com/GraphiteEditor/Graphite/commit/99cf8f0c4f91a051b59fc2c9e5cc6c7417bdd74b))
- Fix to remove the inconsistently functioning double-click behavior of switching to the Path tool on vector layers, which previously worked only on layers with a Path node ([#2116](https://github.com/GraphiteEditor/Graphite/pull/2116))
- Fix for dragging a pair of colinear handles to break the colinearity so they can move without their anchor ([#2120](https://github.com/GraphiteEditor/Graphite/pull/2120))
- Fix for the broken bounding box of image layers, which also impacted their layer thumbnails ([#2122](https://github.com/GraphiteEditor/Graphite/pull/2122))
- Fix to restore the keyboard shortcut label in the menu bar's *File* > *Close* menu item ([#2135](https://github.com/GraphiteEditor/Graphite/pull/2135))
- Fix to the syntax of exported SVG files that minorly deviated from spec and may have impact some strict SVG viewers ([#2131](https://github.com/GraphiteEditor/Graphite/pull/2131))
- Fix for the UI by removing most "coming soon" elements left over from earlier times when placeholders were necessary ([commit 1264ea8](https://github.com/GraphiteEditor/Graphite/commit/1264ea8246cbb06e0602a93be983762ab17adf30))
- Fix for issues with selection history ([#2138](https://github.com/GraphiteEditor/Graphite/pull/2138))
- Fix for a cancellation of a transform cage rotation causing broken state upon the next transformation ([#2149](https://github.com/GraphiteEditor/Graphite/pull/2149))
- Fix to make the Path tool deselect all of a filled shape's points when single-clicked, and select all when double-clicked ([#2148](https://github.com/GraphiteEditor/Graphite/pull/2148))
- Fix for the Select tool's box selection not being able to extend a selection with Shift ([#2157](https://github.com/GraphiteEditor/Graphite/pull/2157))
- Fix for several bugs in vector-related nodes ([commit b81f483](https://github.com/GraphiteEditor/Graphite/commit/b81f48385afc8c9c27820ffe8d5953529f89b7bd))
- Fix for the Text tool making it easier to select existing text layers with more forgiving click targets ([#2145](https://github.com/GraphiteEditor/Graphite/pull/2145))
- Fix for text layers getting deselected after clicking out of Text tool's interactive editing mode ([#2144](https://github.com/GraphiteEditor/Graphite/pull/2144))
- Fix to make the Artboard tool shift its contents if resizing from the top/left so artwork remains stationary ([#2166](https://github.com/GraphiteEditor/Graphite/pull/2166))
## Internal
- Change to make the *Upload Texture* node resolution-aware ([#2018](https://github.com/GraphiteEditor/Graphite/pull/2018))
- Fix for faulty contravariance checking in the type system ([#2025](https://github.com/GraphiteEditor/Graphite/pull/2025))
- Update of Wasm dependencies to fix a crash in Firefox with Vello due to a WebGPU spec change ([#2027](https://github.com/GraphiteEditor/Graphite/pull/2027))
- Simplification of the Bezier-rs interactive web demo code ([#2020](https://github.com/GraphiteEditor/Graphite/pull/2020), [commit 4df7803](https://github.com/GraphiteEditor/Graphite/commit/4df780391c0cbb87b12812d0249ed9b62e2740e4))
- Fix for Clippy code warnings ([commit a395fbf](https://github.com/GraphiteEditor/Graphite/commit/a395fbf0637c23b8b05a7c451ff7b8421587b655), [#2119](https://github.com/GraphiteEditor/Graphite/pull/2119))
- Refactor of assorted parts of the RawKit crate ([#1972](https://github.com/GraphiteEditor/Graphite/pull/1972), [#2071](https://github.com/GraphiteEditor/Graphite/pull/2071), [#2066](https://github.com/GraphiteEditor/Graphite/pull/2066), [#2082](https://github.com/GraphiteEditor/Graphite/pull/2082), [#2088](https://github.com/GraphiteEditor/Graphite/pull/2088))
- Code tidyness cleanup for node ID generation ([#2009](https://github.com/GraphiteEditor/Graphite/pull/2009))
- Refactor collection of snap targets ([#2114](https://github.com/GraphiteEditor/Graphite/pull/2114))
- System for parsing node and parameter descriptions from doc comments, enabling better node tooltips going forward ([#2089](https://github.com/GraphiteEditor/Graphite/pull/2089), [#2163](https://github.com/GraphiteEditor/Graphite/pull/2163), [commit d649052](https://github.com/GraphiteEditor/Graphite/commit/d649052255c10c15754c3a3707f2edf996d2468d))
- Fix for the rectangle constructor in the Bezier-rs library to produce linear segments ([#2109](https://github.com/GraphiteEditor/Graphite/pull/2109))
- Math-Parser library for reading and evaluating math expressions ([#2033](https://github.com/GraphiteEditor/Graphite/pull/2033))
- Simplifications to the implementation of buffered message passing within the editor architecture ([#2123](https://github.com/GraphiteEditor/Graphite/pull/2123))
- Updates to dependencies ([#2134](https://github.com/GraphiteEditor/Graphite/pull/2134))
## Website
- Publication of the previous blog post, [*Graphite progress report (Q3 2024)*](../graphite-progress-report-q3-2024) ([#2013](https://github.com/GraphiteEditor/Graphite/pull/2013))
- Updates to the screenshots on the home page carousel ([commit f892687](https://github.com/GraphiteEditor/Graphite/commit/f89268757614bda5f949144f84ccc79bd33ddec2))
- Updates to the website roadmap and other details ([commit d7a271f](https://github.com/GraphiteEditor/Graphite/commit/d7a271f67595863835e80e58636fead9b1fe0a1d), [commit ce0cd39](https://github.com/GraphiteEditor/Graphite/commit/ce0cd39c9b4291e76d59d5b7c427afd39702aed6), [commit 740fcb7](https://github.com/GraphiteEditor/Graphite/commit/740fcb73cc1202d89107a08f3dfccd88dd17a6a3), [commit 54926d5](https://github.com/GraphiteEditor/Graphite/commit/54926d5474f3bcaffd54d0fd0d2509e989cfa425))