|
| 1 | ++++ |
| 2 | +title = "Linebender in January 2025" |
| 3 | +authors = ["Kaur Kuut", "Daniel McNab", "Tom Churchman", "Raph Levien"] |
| 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 | +## Xilem |
| 9 | + |
| 10 | +Xilem is our flagship GUI project, inspired by SwiftUI. |
| 11 | +It lets you build user interfaces declaratively by composing lightweight views together, and will diff them to provide minimal updates to a retained layer. |
| 12 | + |
| 13 | +Xilem saw decent direct progress in January and of course Xilem also benefits from all the progress in the rest of our stack which is detailed in later sections. |
| 14 | + |
| 15 | +- [xilem#420][], [xilem#833][]: Added emoji picker example. |
| 16 | +- [xilem#753][], [xilem#828][]: Added support for transforming widgets with `kurbo::Affine`. |
| 17 | +- [xilem#806][]: Made `Pod` more flexible to allow creating a wider variety of wrapper widgets. |
| 18 | +- [xilem#840][]: Updated to `vello` 0.4.0. |
| 19 | + |
| 20 | +<figure> |
| 21 | +<img style="height: auto" src="emoji_picker.png" alt="A screenshot of a Xilem example app. It shows sixteen different facial expression emoji with a cat face with a wry smile being selected." width="864" height="1121"> |
| 22 | +<figcaption> |
| 23 | +Xilem emoji picker example app, showing various emoji options. |
| 24 | +</figcaption> |
| 25 | +</figure> |
| 26 | + |
| 27 | +We also improved documentation, see e.g. [xilem#818][]. |
| 28 | + |
| 29 | +## Masonry |
| 30 | + |
| 31 | +Masonry is the widget system used by Xilem. |
| 32 | +It provides a non-opinionated retained widget tree, designed as a base layer for high-level GUI frameworks. |
| 33 | + |
| 34 | +January was quite a busy month for Masonry with lots of significant changes landing, including both new features and improved old ones. |
| 35 | +Most notable are the following highlights: |
| 36 | + |
| 37 | +- [xilem#737][]: Added `zstack` widget for composing widgets on top of each other. |
| 38 | +- [xilem#753][]: Added support for transforming widgets with `kurbo::Affine`. |
| 39 | +- [xilem#808][]: `AppDriver` now takes a reference to `RenderRoot` for more flexibility. |
| 40 | +- [xilem#820][]: Added a basic widget inspector for debugging. |
| 41 | +- [xilem#822][]: Now widget focus is cleared when a user clicks outside of that focused widget. |
| 42 | +- [xilem#823][]: When text of a text area is changed the cursor now gets moved to the end. |
| 43 | +- [xilem#827][]: Refactored `TreeArena`. |
| 44 | +- [xilem#830][]: Improved handling of window focus. |
| 45 | +- [xilem#831][]: Applied `is`/`has` naming convention more consistently across context method names. |
| 46 | +- [xilem#834][]: Fixed crashing in `run_single_update_pass`. |
| 47 | +- [xilem#837][]: Removed a bunch of redundant `Box` usage around `Widget`. |
| 48 | +- [xilem#841][]: Added features to help test `Textbox`. |
| 49 | +- [xilem#848][]: Reorganized modules. |
| 50 | + |
| 51 | +We also improved documentation a lot, see e.g. [xilem#787][], [xilem#809][], [xilem#811][], [xilem#813][], [xilem#815][], [xilem#824][], [xilem#826][], [xilem#829][], [xilem#832][], and [xilem#835][]. |
| 52 | +Additionally a bunch of stale code got cleaned up. |
| 53 | + |
| 54 | +## Vello |
| 55 | + |
| 56 | +Vello is our GPU vector renderer. |
| 57 | +It can draw large 2D scenes with high performance, using GPU compute shaders for most of the work. |
| 58 | + |
| 59 | +We released [Vello 0.4.0][] which has a bunch of improvements and fixes from the preceding four months. |
| 60 | +Among the improvements is the change from December that Vello now uses our own [Color][] library. |
| 61 | +Highlights from the additions in January include [image extend modes, alpha, and nearest neighbor sampling][vello#766] and [correct rendering of Apple Color Emoji][vello#792]. |
| 62 | + |
| 63 | +<figure> |
| 64 | +<img style="height: auto" src="neighbor.png" alt="A screenshot of a Vello demo app. It shows four different variations of an image extended with nearest neighbor filtering." width="1570" height="1247"> |
| 65 | +<figcaption> |
| 66 | +Vello demo, showing image extend modes with nearest neighbor filtering. |
| 67 | +</figcaption> |
| 68 | +</figure> |
| 69 | + |
| 70 | +Of course work didn't stop with this release. |
| 71 | +In preparation for the next release we have already [upgraded Vello to use wgpu 0.24.0][vello#791]. |
| 72 | + |
| 73 | +## Kurbo |
| 74 | + |
| 75 | +Kurbo provides data structures and algorithms for curves and vector paths. |
| 76 | + |
| 77 | +- [kurbo#409][]: Added `turn_90` / `rotate_scale` methods to `Vec2`, and fixed the docs of `Vec2::cross`. |
| 78 | + |
| 79 | +## Parley |
| 80 | + |
| 81 | +Parley is a text layout library. |
| 82 | +It handles text layout, mostly at the level of line breaking and resolving glyph positions. |
| 83 | + |
| 84 | +In January, a variety of layout edge cases have been fixed, support for bidirectional text was expanded, and testing of text layout and selection has improved. |
| 85 | + |
| 86 | +- [parley#238][]: Updated to `swash` 0.2.0, which paves the way for future `no_std` support. |
| 87 | +- [parley#239][]: Took another step towards supporting `no_std` by enabling further testing in CI. |
| 88 | +- [parley#241][]: Allows configuring the behavior of alignment for lines that overflow the container width. |
| 89 | +- [parley#244][]: Added screenshots to selection area and cursor positioning tests. |
| 90 | +- [parley#245][]: Enabled detection of the base direction of text layouts (left-to-right or right-to-left). |
| 91 | +- [parley#249][]: Fixed issues related to line breaking around inline boxes, by new Linebender member Wim de With. |
| 92 | +- [parley#254][]: Now adhering to the [CSS white space model][] in stripping leading white space following a new line in white space collapsing mode. |
| 93 | +- [parley#256][]: Corrected the calculation of trailing white space, also by Wim de With. |
| 94 | + |
| 95 | +## Peniko |
| 96 | + |
| 97 | +Peniko provides a set of shared types for concepts that are important for drawing/stroking paths, but excluding the path geometry itself (which can be found in Kurbo). |
| 98 | +It includes types for brush styles (including gradient) and color. |
| 99 | + |
| 100 | +We released [Peniko 0.3.1][] which was a simple maintenance release with tweaked docs and updated dependencies. |
| 101 | + |
| 102 | +## Color |
| 103 | + |
| 104 | +[Color][] provides functionality for representing, converting, parsing, serializing, and manipulating colors in a variety of color spaces. |
| 105 | +It closely follows the [CSS Color Module Level 4][] draft spec. |
| 106 | + |
| 107 | +We released [Color 0.2.2][], soon followed by [Color 0.2.3][], the latter of which added easier methods to convert 8-bit colors from byte streams (for use with GPUs) and to other color representations in [color#135][] and [color#136][]. |
| 108 | +This release also saw the addition of the ACES2065-1 color space in [color#124][]. |
| 109 | + |
| 110 | +## Velato |
| 111 | + |
| 112 | +- [velato#49][]: Updated to `vello` 0.4.0. |
| 113 | + |
| 114 | +## Vello SVG |
| 115 | + |
| 116 | +We released [Vello SVG 0.6.0][] which most notably includes: |
| 117 | +- [vello_svg#50][]: Added support for raster images to be completely disabled via a feature flag. |
| 118 | +- [vello_svg#53][]: Updated to `vello` 0.4.0. |
| 119 | + |
| 120 | +## Kompari |
| 121 | + |
| 122 | +[Kompari][] is a tool for visual inspection of snapshot tests. |
| 123 | + |
| 124 | +- [kompari#13][]: Interactive review (in HTML). |
| 125 | +- [kompari#14][]: Rework of repository layout. |
| 126 | +- [kompari#16][]: Alternative diff views. |
| 127 | + |
| 128 | +## Resvg |
| 129 | + |
| 130 | +- [resvg#873][]: Added the stylesheet option to the C API. |
| 131 | +- [resvg#878][]: Updated to `svgtypes` 0.15.3. |
| 132 | + |
| 133 | +## SVG Types |
| 134 | + |
| 135 | +We released [SVG Types 0.15.3][] with a few minor fixes. |
| 136 | +This is also the first release under the stewardship of Linebender. |
| 137 | + |
| 138 | +## Tiny Skia |
| 139 | + |
| 140 | +- [tiny-skia#146][]: Added `scale_by` / `scale_to` methods to `Size`. |
| 141 | + |
| 142 | +## SimpleCSS |
| 143 | + |
| 144 | +We released [SimpleCSS 0.2.2][] with `no_std` support, updated docs clarifying Linebender involvement, and to test run the publishing workflow. |
| 145 | + |
| 146 | +## Research and Future Directions |
| 147 | + |
| 148 | +Linebender has an origin story in being a very research oriented group, looking to break new ground. |
| 149 | +While we are focused on shipping code today, we still have an eye on the future and how to be prepared for the new opportunities and technologies that are coming. |
| 150 | + |
| 151 | +While Vello has unmatched rendering speed thanks to its GPU-driven architecture, there are two practical tradeoffs: it can require unpredictable amounts of memory, and it doesn't work on downlevel GPUs with weak or nonexistent support for compute shaders. |
| 152 | +Raph Levien has been exploring a possible hybrid CPU/GPU direction for Vello to address these issues. |
| 153 | +Read the [design doc][Potato design doc], follow the [Zulip thread][Potato zulip thread], or stay tuned for more developments. |
| 154 | + |
| 155 | +## Get Involved |
| 156 | + |
| 157 | +We welcome collaboration on any of our crates. |
| 158 | +This can include improving the documentation, implementing new features, improving our test coverage, or using them within your own code. |
| 159 | + |
| 160 | +We host an hour long office hours meeting each week where we discuss what's going on in our projects. |
| 161 | +See [#office hours in Zulip](https://xi.zulipchat.com/#narrow/channel/359642-office-hours) for details. |
| 162 | + |
| 163 | +* Daniel and Olivier's "office hours" appointments can still be booked by anyone for open-ended discussion of the ecosystem. |
| 164 | + * [See Daniel's schedule here](https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ32eQYJ9DtZ_wJaYNtT36YioETiloZDIdImFpBFRo5-XsqGzpikgkg47LPsiHhpiwiQ1orOwwW2). |
| 165 | + * [See Olivier's schedule here](https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ2t767ZRETD_TkRI_VxK2ZTG0VrO9OZ4l7HvTxefhtJcg85iK0ZN7zWNnAEZtH0Dn7C1GKxrmYM). |
| 166 | + |
| 167 | +[xilem#420]: https://github.com/linebender/xilem/pull/420 |
| 168 | +[xilem#737]: https://github.com/linebender/xilem/pull/737 |
| 169 | +[xilem#753]: https://github.com/linebender/xilem/pull/753 |
| 170 | +[xilem#787]: https://github.com/linebender/xilem/pull/787 |
| 171 | +[xilem#806]: https://github.com/linebender/xilem/pull/806 |
| 172 | +[xilem#808]: https://github.com/linebender/xilem/pull/808 |
| 173 | +[xilem#809]: https://github.com/linebender/xilem/pull/809 |
| 174 | +[xilem#811]: https://github.com/linebender/xilem/pull/811 |
| 175 | +[xilem#813]: https://github.com/linebender/xilem/pull/813 |
| 176 | +[xilem#815]: https://github.com/linebender/xilem/pull/815 |
| 177 | +[xilem#818]: https://github.com/linebender/xilem/pull/818 |
| 178 | +[xilem#820]: https://github.com/linebender/xilem/pull/820 |
| 179 | +[xilem#822]: https://github.com/linebender/xilem/pull/822 |
| 180 | +[xilem#823]: https://github.com/linebender/xilem/pull/823 |
| 181 | +[xilem#824]: https://github.com/linebender/xilem/pull/824 |
| 182 | +[xilem#826]: https://github.com/linebender/xilem/pull/826 |
| 183 | +[xilem#827]: https://github.com/linebender/xilem/pull/827 |
| 184 | +[xilem#828]: https://github.com/linebender/xilem/pull/828 |
| 185 | +[xilem#829]: https://github.com/linebender/xilem/pull/829 |
| 186 | +[xilem#830]: https://github.com/linebender/xilem/pull/830 |
| 187 | +[xilem#831]: https://github.com/linebender/xilem/pull/831 |
| 188 | +[xilem#832]: https://github.com/linebender/xilem/pull/832 |
| 189 | +[xilem#833]: https://github.com/linebender/xilem/pull/833 |
| 190 | +[xilem#834]: https://github.com/linebender/xilem/pull/834 |
| 191 | +[xilem#835]: https://github.com/linebender/xilem/pull/835 |
| 192 | +[xilem#837]: https://github.com/linebender/xilem/pull/837 |
| 193 | +[xilem#840]: https://github.com/linebender/xilem/pull/840 |
| 194 | +[xilem#841]: https://github.com/linebender/xilem/pull/841 |
| 195 | +[xilem#848]: https://github.com/linebender/xilem/pull/848 |
| 196 | + |
| 197 | +[Vello 0.4.0]: https://github.com/linebender/vello/releases/tag/v0.4.0 |
| 198 | +[vello#766]: https://github.com/linebender/vello/pull/766 |
| 199 | +[vello#791]: https://github.com/linebender/vello/pull/791 |
| 200 | +[vello#792]: https://github.com/linebender/vello/pull/792 |
| 201 | + |
| 202 | +[kurbo#409]: https://github.com/linebender/kurbo/pull/409 |
| 203 | + |
| 204 | +[parley#238]: https://github.com/linebender/parley/pull/238 |
| 205 | +[parley#239]: https://github.com/linebender/parley/pull/239 |
| 206 | +[parley#241]: https://github.com/linebender/parley/pull/241 |
| 207 | +[parley#244]: https://github.com/linebender/parley/pull/244 |
| 208 | +[parley#245]: https://github.com/linebender/parley/pull/245 |
| 209 | +[parley#249]: https://github.com/linebender/parley/pull/249 |
| 210 | +[parley#254]: https://github.com/linebender/parley/pull/254 |
| 211 | +[parley#256]: https://github.com/linebender/parley/pull/256 |
| 212 | +[CSS white space model]: https://www.w3.org/TR/CSS2/text.html#white-space-model |
| 213 | + |
| 214 | +[Peniko 0.3.1]: https://github.com/linebender/peniko/releases/tag/v0.3.1 |
| 215 | + |
| 216 | +[Color]: https://docs.rs/color/ |
| 217 | +[CSS Color Module Level 4]: https://www.w3.org/TR/css-color-4/ |
| 218 | +[Color 0.2.2]: https://github.com/linebender/color/releases/tag/v0.2.2 |
| 219 | +[Color 0.2.3]: https://github.com/linebender/color/releases/tag/v0.2.3 |
| 220 | +[color#124]: https://github.com/linebender/color/pull/124 |
| 221 | +[color#135]: https://github.com/linebender/color/pull/135 |
| 222 | +[color#136]: https://github.com/linebender/color/pull/136 |
| 223 | + |
| 224 | +[velato#49]: https://github.com/linebender/velato/pull/49 |
| 225 | + |
| 226 | +[Vello SVG 0.6.0]: https://github.com/linebender/vello_svg/releases/tag/v0.6.0 |
| 227 | +[vello_svg#50]: https://github.com/linebender/vello_svg/pull/50 |
| 228 | +[vello_svg#53]: https://github.com/linebender/vello_svg/pull/53 |
| 229 | + |
| 230 | +[Kompari]: https://github.com/linebender/kompari |
| 231 | +[kompari#13]: https://github.com/linebender/kompari/pull/13 |
| 232 | +[kompari#14]: https://github.com/linebender/kompari/pull/14 |
| 233 | +[kompari#16]: https://github.com/linebender/kompari/pull/16 |
| 234 | + |
| 235 | +[resvg#873]: https://github.com/linebender/resvg/pull/873 |
| 236 | +[resvg#878]: https://github.com/linebender/resvg/pull/878 |
| 237 | + |
| 238 | +[SVG Types 0.15.3]: https://github.com/linebender/svgtypes/releases/tag/v0.15.3 |
| 239 | + |
| 240 | +[tiny-skia#146]: https://github.com/linebender/tiny-skia/pull/146 |
| 241 | + |
| 242 | +[SimpleCSS 0.2.2]: https://github.com/linebender/simplecss/releases/tag/v0.2.2 |
| 243 | + |
| 244 | +[Potato design doc]: https://docs.google.com/document/d/1gEqf7ehTzd89Djf_VpkL0B_Fb15e0w5fuv_UzyacAPU/edit?usp=sharing |
| 245 | +[Potato zulip thread]: https://xi.zulipchat.com/#narrow/channel/197075-gpu/topic/Potato.20-.20a.20paper.20design.20for.20a.20CPU.2FGPU.20hybrid.20renderer |
0 commit comments