|
| 1 | ++++ |
| 2 | +title = "Linebender in August 2025" |
| 3 | +authors = ["Daniel McNab"] |
| 4 | ++++ |
| 5 | + |
| 6 | +Linebender is an informal open-source organization working on various projects to advance the state of the art in GUI for [the Rust programming language](https://rust-lang.org). |
| 7 | + |
| 8 | +## Parley |
| 9 | + |
| 10 | +Parley is a text layout library. |
| 11 | +It handles text layout, mostly at the level of line breaking and resolving glyph positions. |
| 12 | + |
| 13 | +- [parley#400][]: Migrates Parley to [HarfRust](https://github.com/harfbuzz/harfrust) for shaping, which is a Rust port of HarfBuzz. |
| 14 | +- [parley#405][]: Adds a selection of benchmarks. |
| 15 | +- [parley#406][], [parley#413][]: Adds internal caching, improving performance significantly. |
| 16 | + |
| 17 | +## Vello |
| 18 | + |
| 19 | +Vello is our GPU vector renderer. |
| 20 | +It can draw large 2D scenes with high performance, using GPU compute shaders for most of the work. |
| 21 | + |
| 22 | +- [vello#1096][]: Updated to Wgpu version 26. |
| 23 | +- [vello#1161][]: Simplifies the API for rendering a wgpu `Texture` into a Vello `Scene`. |
| 24 | +- [vello#1169][]: Increased the Skrifa version to v0.35.0. This was backported as [Vello v0.5.1](https://github.com/linebender/vello/releases/tag/v0.5.1). |
| 25 | +- [vello#1182][]: Fixed a longstanding issue with our examples, where they would crash if the window was minimised on windows. |
| 26 | + |
| 27 | +The biggest updates to the sparse strip renderers this month are the support for blending and caching in Vello Hybrid. |
| 28 | +We have also had continued SIMD improvements, including x86 support. |
| 29 | + |
| 30 | +- [vello#1136][]: Allows disabling anti-aliasing. |
| 31 | +- [vello#1137][], [vello#1153][]: Add support for caching sparse strips. |
| 32 | +- [vello#1149][]: Support for SSE4.2 and AVX2 SIMD (i.e. on x86 and x86_64). |
| 33 | + The [benchmark results viewer](https://laurenzv.github.io/vello_chart/) has been updated to include some x86_64 results. |
| 34 | +- [vello#1177][]: Move to the new v0.2.0 release of Fearless SIMD. |
| 35 | +- [vello#1155][], [vello#1178][]: Add full support for blending to Vello Hybrid. |
| 36 | + |
| 37 | +<!-- TODO: This roadmap is a bit out of date. |
| 38 | +Our [working roadmap](https://docs.google.com/document/d/1ZquH-53j2OedTbgEKCJBKTh4WLE11UveM10mNdnVARY/edit?tab=t.0#heading=h.j3duh9pgdm94) outlines the planned timeline for work on the renderers into next year. --> |
| 39 | + |
| 40 | +<img style="height: auto; width: 50%; margin-left: 25%;" width="666" height="673" src="hybrid-blending.png" alt="A series of overlapping shapes of various colours, variously composited."> |
| 41 | + |
| 42 | +<figcaption> |
| 43 | + |
| 44 | +Blending is now supported by Vello Hybrid. |
| 45 | + |
| 46 | +</figcaption> |
| 47 | +</figure> |
| 48 | + |
| 49 | +We have additionally been doing further work on Vello's imaging model. |
| 50 | +This is partly in service of the integrations of Vello in [Graphite](https://graphite.rs/) and [Servo](https://servo.org/). |
| 51 | + |
| 52 | +- [color#191][], [peniko#115][] (in progress): Add support for interpolating gradients in unpremultiplied space. |
| 53 | + This is provided for web compatibility, and shouldn't be used by most users. |
| 54 | +- [peniko#117][]: Split Image into the sampler and data. |
| 55 | +- [peniko#120][], [peniko#121][]: Add `Brga` and premultiplied image formats. |
| 56 | +- [vello#1183][] (in progress): Support luminance masks. |
| 57 | + |
| 58 | +As of [servo#38962][], Vello and Vello CPU are the only canvas backends used in Servo. |
| 59 | + |
| 60 | +### Fearless SIMD |
| 61 | + |
| 62 | +Fearless SIMD is our SIMD infrastructure library. |
| 63 | +We are developing it in concert with the Vello sparse strips renderers, particularly `vello_cpu`. |
| 64 | +We released [Fearless SIMD v0.2.0](https://github.com/linebender/fearless_simd/releases/tag/v0.2.0), the first Fearless SIMD release since 2018. |
| 65 | +This included the following changes from August: |
| 66 | + |
| 67 | +- [fearless_simd#50][], [fearless_simd#52][]: Add SSE4.2 support. |
| 68 | +- [fearless_simd#58][]: Add some initial docs. |
| 69 | +- [fearless_simd#59][]: Add basic AVX2 support. |
| 70 | +- [fearless_simd#61][]: Removes `f16` support to prepare for release. |
| 71 | +- [fearless_simd#69][]: Fixes a soundness issue with unsafe SIMD functions. |
| 72 | + |
| 73 | +With this release, Fearless SIMD is now ready for experimental use outside of Linebender. |
| 74 | +It now provides a solid way for writing portable SIMD operations across WASM, Aarch64, x86, and x86_64. |
| 75 | +Note however that the library is still in a quite early state - in particular, our documentation is currently only cursory. |
| 76 | +Contributions to improve this would be welcome! |
| 77 | + |
| 78 | +## Masonry |
| 79 | + |
| 80 | +Masonry is the widget system developed by Linebender. |
| 81 | +It provides a non-opinionated retained widget tree, designed as a base layer for high-level GUI frameworks. |
| 82 | + |
| 83 | +- [xilem#1207][]: Make `ObjectFit`, `Linebreaking` and `SpinnerColor` properties. |
| 84 | +- [xilem#1212][]: Add `Widget::Action`, which indicates the action type widgets return. |
| 85 | +- [xilem#1226][]: Refactor tab focus. |
| 86 | +- [xilem#1228][]: Add placeholder text to text input. |
| 87 | +- [xilem#1250][]: Move widgets to use a `Length` type, which represents a number of logical pixels. |
| 88 | +- [xilem#1269][]: Introduce "focus fallback" mechanism. |
| 89 | +- [xilem#1273][]: Update to Anymore v1.0. |
| 90 | +- [xilem#1282][], many others: Add unit tests for passes. |
| 91 | +- [xilem#1295][]: Merge `TextColor` and `SpinnerColor` into `ContentColor`. |
| 92 | +- [xilem#1310][]: Cleans up how the event loop handles being suspended, by Nixon. |
| 93 | +- [xilem#1312][]: Remove the generic on VirtualScroll. |
| 94 | +- [xilem#1314][]: Makes the focused indicator for checkboxes larger, by tannal. |
| 95 | +- [xilem#1320][]: Add `NewWindow` struct to encapsulate attributes needed to create a window. |
| 96 | +- [xilem#1321][]: When a new font is loaded, relayout everything. |
| 97 | +- [xilem#1332][]: Restore base colour customisation. |
| 98 | +- [xilem#1349][]: Move Masonry's examples from "Masonry Winit" to "Masonry". |
| 99 | +- [xilem#1353][]: Limit the size of screenshot tests to 8KiB by default. |
| 100 | +- [xilem#1366][]: Make the `Checkbox`'s checked state be controlled only by the driver. |
| 101 | +- [xilem#1371][]: Fix and optimise window resizing and minimising. |
| 102 | + |
| 103 | +## Xilem |
| 104 | + |
| 105 | +Xilem is our flagship GUI project, inspired by SwiftUI, which uses Masonry for its widgets. |
| 106 | +It lets you build user interfaces declaratively by composing lightweight views together, and will diff them to provide minimal updates to a retained layer. |
| 107 | + |
| 108 | +- [xilem#1260][]: Make the virtual scroll implementation much saner. |
| 109 | +- [xilem#1273][]: Update to Anymore v1.0. |
| 110 | +- [xilem#1363][]: Fix the `declare_property_tuple` macro, by Alex Moon. |
| 111 | +- [xilem#1278][]: Add `Prop`, which changes how Masonry `Properties` are applied to more closely match Xilem Web. |
| 112 | +- [xilem#1318][]: Fix initial font loading in easy cases. |
| 113 | +- [xilem#1333][]: Add docs about precise capturing, by Nils Martel. |
| 114 | +- [xilem#1348][]: Add `flex_row` and `flex_col` as convenience functions, by Paul Xu. |
| 115 | +- [xilem#1352][]: Add error handling to virtual cats example, by Nils Martel. |
| 116 | +- [xilem#1357][]: Fix how the `disabled` property is handled for text input. |
| 117 | +- [xilem#1364][]: Remove the `app_state` parameter from teardown, by Alex Moon. |
| 118 | + |
| 119 | +Placehero: |
| 120 | + |
| 121 | +- [xilem#1323][]: Use an Action for navigation (rather than directly setting fields on the app state). |
| 122 | +- [xilem#1337][]: Use virtual scrolling for timelines. |
| 123 | +- [xilem#1370][]: Show the blurhash based preview of media attachments. |
| 124 | + |
| 125 | +<figure> |
| 126 | + |
| 127 | +<img style="height: auto" width="1991" height="891" src="placehero-progress.png" alt="Two screenshots of a Mastodon app. Left shows the post announcing Matt Campbell's RustWeek 2025 talk, including a very low detail image with alt text shown below. The right screen shows posts from googlefonts@typo.social, which was entered in a box in the left sidebar of the app."> |
| 128 | + |
| 129 | +<figcaption> |
| 130 | + |
| 131 | +Placehero can now load content from anywhere in a user's timeline, and preview images (left). |
| 132 | +It can also jump directly to a specific user's timeline by username (right). |
| 133 | +Note that full image loading is not yet supported, only the preview based on the blurhash. |
| 134 | + |
| 135 | +</figcaption> |
| 136 | +</figure> |
| 137 | + |
| 138 | +## Anymore |
| 139 | + |
| 140 | +On 4 August, we released [Anymore v1.0.0](https://github.com/linebender/anymore/releases/tag/v1.0.0). |
| 141 | +This is our crate for the fundamental `AnyDebug` trait, which greatly aids debugging when using dynamically typed values. |
| 142 | +Anymore is designed to be used in public APIs; it has a minimal API surface so that it can be extremely stable. |
| 143 | +We recommend considering it for use cases where you would otherwise be returning (potentially wrapped) `Box<dyn Any>` values from your libraries. |
| 144 | + |
| 145 | +## Kurbo |
| 146 | + |
| 147 | +Kurbo provides data structures and algorithms for curves and vector paths. |
| 148 | +We've been preparing for the 0.12 release: |
| 149 | + |
| 150 | +- [kurbo#476][]: Adds an `Axis` type taken from Masonry. |
| 151 | +- [kurbo#483][]: Document Kurbo's feature flags. |
| 152 | +- [kurbo#485][]: Better handle edge cases in cubic_to_quadratic, by Cosimo Lupo. |
| 153 | +- [kurbo#486][]: Deprecate and replace existing `aspect_ratio` methods, which used a non-standard definition of aspect ratio. |
| 154 | +- [kurbo#487][], [kurbo#488][], [kurbo#489][]: Remove many long-deprecated items. |
| 155 | +- [kurbo#490][]: Fix miter join in dashed strokes. |
| 156 | +- [kurbo#493][] (in progress): Convert `CubicBez::nearest` to the `poly-cool` quintic solver. |
| 157 | + |
| 158 | +## Get Involved |
| 159 | + |
| 160 | +We welcome collaboration on any of our crates. |
| 161 | +This can include improving the documentation, implementing new features, improving our test coverage, or using them within your own code. |
| 162 | + |
| 163 | +We host an hour long office hours meeting each week where we discuss what's going on in our projects. |
| 164 | +See [#office hours in Zulip](https://xi.zulipchat.com/#narrow/channel/359642-office-hours) for details. |
| 165 | +We're also running a separate office hours time dedicated to the renderer collaboration, details also available at that link. |
| 166 | + |
| 167 | +If you wish to discuss the Linebender project individually, Daniel is offering ["office hours" appointments](https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ32eQYJ9DtZ_wJaYNtT36YioETiloZDIdImFpBFRo5-XsqGzpikgkg47LPsiHhpiwiQ1orOwwW2), which are free to book. |
| 168 | +It really helps us to learn what aspects our users care about the most. |
| 169 | + |
| 170 | +[servo#38962]: https://github.com/servo/servo/pull/38962 |
| 171 | + |
| 172 | +[color#191]: https://github.com/linebender/color/pull/191 |
| 173 | + |
| 174 | +[fearless_simd#50]: https://github.com/linebender/fearless_simd/pull/50 |
| 175 | +[fearless_simd#52]: https://github.com/linebender/fearless_simd/pull/52 |
| 176 | +[fearless_simd#58]: https://github.com/linebender/fearless_simd/pull/58 |
| 177 | +[fearless_simd#59]: https://github.com/linebender/fearless_simd/pull/59 |
| 178 | +[fearless_simd#61]: https://github.com/linebender/fearless_simd/pull/61 |
| 179 | +[fearless_simd#69]: https://github.com/linebender/fearless_simd/pull/69 |
| 180 | + |
| 181 | +[kurbo#476]: https://github.com/linebender/kurbo/pull/476 |
| 182 | +[kurbo#483]: https://github.com/linebender/kurbo/pull/483 |
| 183 | +[kurbo#485]: https://github.com/linebender/kurbo/pull/485 |
| 184 | +[kurbo#486]: https://github.com/linebender/kurbo/pull/486 |
| 185 | +[kurbo#487]: https://github.com/linebender/kurbo/pull/487 |
| 186 | +[kurbo#488]: https://github.com/linebender/kurbo/pull/488 |
| 187 | +[kurbo#489]: https://github.com/linebender/kurbo/pull/489 |
| 188 | +[kurbo#490]: https://github.com/linebender/kurbo/pull/490 |
| 189 | +[kurbo#493]: https://github.com/linebender/kurbo/pull/493 |
| 190 | + |
| 191 | +[parley#400]: https://github.com/linebender/parley/pull/400 |
| 192 | +[parley#405]: https://github.com/linebender/parley/pull/405 |
| 193 | +[parley#406]: https://github.com/linebender/parley/pull/406 |
| 194 | +[parley#413]: https://github.com/linebender/parley/pull/413 |
| 195 | +[peniko#115]: https://github.com/linebender/peniko/pull/115 |
| 196 | +[peniko#117]: https://github.com/linebender/peniko/pull/117 |
| 197 | +[peniko#120]: https://github.com/linebender/peniko/pull/120 |
| 198 | +[peniko#121]: https://github.com/linebender/peniko/pull/121 |
| 199 | + |
| 200 | +[vello#1096]: https://github.com/linebender/vello/pull/1096 |
| 201 | +[vello#1136]: https://github.com/linebender/vello/pull/1136 |
| 202 | +[vello#1137]: https://github.com/linebender/vello/pull/1137 |
| 203 | +[vello#1149]: https://github.com/linebender/vello/pull/1149 |
| 204 | +[vello#1153]: https://github.com/linebender/vello/pull/1153 |
| 205 | +[vello#1155]: https://github.com/linebender/vello/pull/1155 |
| 206 | +[vello#1161]: https://github.com/linebender/vello/pull/1161 |
| 207 | +[vello#1169]: https://github.com/linebender/vello/pull/1169 |
| 208 | +[vello#1177]: https://github.com/linebender/vello/pull/1177 |
| 209 | +[vello#1178]: https://github.com/linebender/vello/pull/1178 |
| 210 | +[vello#1182]: https://github.com/linebender/vello/pull/1182 |
| 211 | +[vello#1183]: https://github.com/linebender/vello/pull/1183 |
| 212 | + |
| 213 | +[xilem#1207]: https://github.com/linebender/xilem/pull/1207 |
| 214 | +[xilem#1212]: https://github.com/linebender/xilem/pull/1212 |
| 215 | +[xilem#1226]: https://github.com/linebender/xilem/pull/1226 |
| 216 | +[xilem#1228]: https://github.com/linebender/xilem/pull/1228 |
| 217 | +[xilem#1250]: https://github.com/linebender/xilem/pull/1250 |
| 218 | +[xilem#1260]: https://github.com/linebender/xilem/pull/1260 |
| 219 | +[xilem#1269]: https://github.com/linebender/xilem/pull/1269 |
| 220 | +[xilem#1273]: https://github.com/linebender/xilem/pull/1273 |
| 221 | +[xilem#1278]: https://github.com/linebender/xilem/pull/1278 |
| 222 | +[xilem#1282]: https://github.com/linebender/xilem/pull/1282 |
| 223 | +[xilem#1295]: https://github.com/linebender/xilem/pull/1295 |
| 224 | +[xilem#1310]: https://github.com/linebender/xilem/pull/1310 |
| 225 | +[xilem#1312]: https://github.com/linebender/xilem/pull/1312 |
| 226 | +[xilem#1314]: https://github.com/linebender/xilem/pull/1314 |
| 227 | +[xilem#1318]: https://github.com/linebender/xilem/pull/1318 |
| 228 | +[xilem#1320]: https://github.com/linebender/xilem/pull/1320 |
| 229 | +[xilem#1321]: https://github.com/linebender/xilem/pull/1321 |
| 230 | +[xilem#1323]: https://github.com/linebender/xilem/pull/1323 |
| 231 | +[xilem#1332]: https://github.com/linebender/xilem/pull/1332 |
| 232 | +[xilem#1333]: https://github.com/linebender/xilem/pull/1333 |
| 233 | +[xilem#1337]: https://github.com/linebender/xilem/pull/1337 |
| 234 | +[xilem#1348]: https://github.com/linebender/xilem/pull/1348 |
| 235 | +[xilem#1349]: https://github.com/linebender/xilem/pull/1349 |
| 236 | +[xilem#1352]: https://github.com/linebender/xilem/pull/1352 |
| 237 | +[xilem#1353]: https://github.com/linebender/xilem/pull/1353 |
| 238 | +[xilem#1357]: https://github.com/linebender/xilem/pull/1357 |
| 239 | +[xilem#1363]: https://github.com/linebender/xilem/pull/1363 |
| 240 | +[xilem#1364]: https://github.com/linebender/xilem/pull/1364 |
| 241 | +[xilem#1366]: https://github.com/linebender/xilem/pull/1366 |
| 242 | +[xilem#1370]: https://github.com/linebender/xilem/pull/1370 |
| 243 | +[xilem#1371]: https://github.com/linebender/xilem/pull/1371 |
0 commit comments