25 Apr 2025
Planet GNOME
Christian Hergert: Manuals on libfoundry
I finally got around this past week to getting Manuals ported to libfoundry.
That was something I wanted to do early so that I can rapidly get away from 3 versions of the documentation engine and Flatpak SDK management code. Currently it existed in Manuals, Builder, and Foundry, and soon we'll get it to just Foundry.
That also makes Manuals the first application to use libfoundry which resulted in lots of tree-shaking and things are looking bright! I very much look forward to getting Builder rebased on libfoundry.
While I was at it, I ticked off a number of requested design issues as part of the Incubator submission. This afternoon it also got support for narrow views meaning you can run it on a GNOME-enabled phone.
Probably not how most people will use it, but hey, maybe you have actually good public transportation where you are and some free time.
25 Apr 2025 11:35pm GMT
Planet KDE | English
This Week in Plasma: multiple major Wayland and UI features
Welcome to a new issue of "This Week in Plasma"! Every week we cover the highlights of what's happening in the world of KDE Plasma and its associated apps like Discover, System Monitor, and more.
This week many KDE contributors gathered in the devastatingly sensible Austrian city of Graz for a long-awaited Plasma development sprint. This was both a "planning sprint" and a "working sprint," so quite a lot of great work got done there, including some major features. And of course those not in attendance were still busy too! Check out all the good news:
Notable new Features
Plasma 6.4.0
Newly-installed applications are now visually highlighted in the Kickoff application launcher! (Kai Uwe Broulik, link)

The accessibility feature to use numberpad buttons to move the pointer now works on Wayland! (Nicolas Fella, link)
Implemented Wayland support for "relative mode" when using a drawing tablet stylus, which allows it to behave more like a mouse you hold like a pencil. (Nicolas Fella, link)
When your microphone is muted and an application tries to use it, Plasma will now display an OSD reminding you that it's muted, so you don't confusingly wonder why no one can hear you. (Kai Uwe Broulik, link)

KMenuEdit now lets you configure apps to always run on the system's discrete GPU, just like the old properties-dialog-based UI for this did. (Oliver Beard, link)

Notable UI Improvements
Plasma 6.4.0
System Settings now has a new "Animations" page that allows easy configuration of the various animated movement effects throughout the system, and these are no longer shown in on Desktop Effects page. (Oliver Beard, link 1, link 2, link 3, and link 4)

The current Desktop Effects page still contains various functional effects that are more than just animated transitions between states, but expect for more and more of them to be progressively removed from that page over time as we find better places for them.
You can now switch tabs/sources in the Media Controller widget with the Ctrl+Tab and Alt+[number] shortcuts. (Christoph Wolk, link)
When finalizing a screen recording in Spectacle is taking a long time for some reason, it now notifies you about this instead of just hanging until completed. (Arjen Hiemstra and Noah Davis, link 1, link 2, and link 3)
How notifications interact with full screen applications has been improved. Previously non-critical notifications were simply suppressed while any full-screen apps were open; now, instead, Do Not Disturb mode is automatically enabled while a full-screen app is focused. This allows re-using existing behaviors around Do Not Disturb mode, including the "you missed some notifications" message. And this behavior can be disabled if desired. (Kristen McWilliam, link)

The very nice Weather Report widget is now, by default, shown in an un-configured state in the System Tray, inviting you to set it up! This reveals it in a more obvious way, so more people find out about it. Of course, if you don't want to see a weather report, you're welcome to disable it. (Nate Graham, link)

In the panel configuration dialog, the two upper toolbar buttons have been combined into a menu so that the dialog doesn't become absurdly wide in languages like German. (Nate Graham, link)

Deleting a logged-in user now shows an appropriate warning dialog, and no longer lets you try to futilely delete their files while they're still logged in. (Nate Graham, link)
You're now also shown a warning if you try to disable the system's clipboard functionality. (Nate Graham, link)

In the Digital Clock widget's calendar popup, the dots signifying the number of events on each day are now located above the day numerals so they don't overlap with other UI elements also present, such as alternate calendar labels. Additionally, their color more closely reflects the color of the event they symbolize. (Tobias Fella, link 1 and link 2)
Did some modernization of the config dialogs for the Digital Clock, Dictionary, Timer, and Media Frame widgets. (Christoph Wolk and Tobias Fella, link 1, link 2, link 3, link 4, link 5)
There's still more consistency work to do here, as the above screenshots will indicate. But we're on the case, working on bringing these old widgets up to par for modern times!
The Configure and Pin buttons in the Digital Clock widget's popup are no longer so crunched together. (Tobias Fella, link)

After closing the Kickoff Application Launcher while viewing search results or the Places tab, opening it again no longer briefly shows a weird sliding animation for the contents. (Jin Liu, link)
Rephrased Discover's "reboot to finish this offline update" message so it isn't so pushy about rebooting immediately. (Nate Graham, link)

Discover now respects your globally-configured web search provider rather than always using DuckDuckGo. (Nate Graham, link)
Notable Bug Fixes
Plasma 6.3.5
Fixed a case where KWin could crash when disconnecting a laptop from certain docking stations. (Xaver Hugl, link)
Fixed a semi-common yet random-seeming crash in Discover. (Aleix Pol Gonzalez, link)
Fixed a bug that could cause the relevant numbers in a newly-created Weather widget to show the wrong values until restarting. (Ismael Asensio, link)
Fixed a case where tooltip text in Plasma could be unreadable when using certain non-default color schemes. (Bogdan Cvetanovski Pašalić, link)
Fixed a case with Discover's "Still looking…" message could be displayed un-centered. (Nate Graham, link)
Plasma 6.4.0
Fixed the size of the Meta+V clipboard popup in mixed-DPI multi-monitor setups on Wayland too. (Fushan Wen, link)
Fixed a bug that caused the Global Menu widget to sometimes display menus from the wrong app. (Vlad Zahorodnii, link)
Navigating away from the desktop shortcuts configuration page after reverting changes manually no longer inappropriately prompts you to save or discard changes that don't exist. (Christoph Wolk, link)
Clicking on a Trash widget in a panel or System Tray to open Dolphin showing the trash now focuses the Dolphin window if it was already open. (Kai Uwe Broulik, link)
Frameworks 6.14
Fixed a remaining issue in the common Kirigami.ScrollablePage
component that could make pages in Discover unnecessarily horizontally scrollable. (Aleix Pol Gonzalez, link)
The common Kirigami.Separator
item no longer flickers between 1px thick and 2px thick when moving or resizing a window while using fractional scale factor. (David Edmundson, link)
Other bug information of note:
- 1 very high priority Plasma bug (same as last week). Current list of bugs
- 19 15-minute Plasma bugs (down from 21 last week). Current list of bugs
Notable in Performance & Technical
Plasma 6.3.5
Fixed an issue that would cause KWin to schedule constant screen repaints while the screen was dimmed, wasting resources and power. (Xaver Hugl, link)
Plasma 6.4.0
KWin has switched to using the stable version of the ext-data-control
protocol. (Neal Gompa, link)
How You Can Help
KDE has become important in the world, and your time and contributions have helped us get there. As we grow, we need your support to keep KDE sustainable.
You can help KDE by becoming an active community member and getting involved somehow. Each contributor makes a huge difference in KDE - you are not a number or a cog in a machine!
You don't have to be a programmer, either. Many other opportunities exist:
- Triage and confirm bug reports, maybe even identify their root cause
- Contribute designs for wallpapers, icons, and app interfaces
- Design and maintain websites
- Translate user interface text items into your own language
- Promote KDE in your local community
- …And a ton more things!
You can also help us by making a donation! Any monetary contribution - however small - will help us cover operational costs, salaries, travel expenses for contributors, and in general just keep KDE bringing Free Software to the world.
To get a new Plasma feature or a bugfix mentioned here, feel free to push a commit to the relevant merge request on invent.kde.org.
25 Apr 2025 8:00pm GMT
Web Review, Week 2025-17
Let's go for my web review for the week 2025-17.
Privacy is power
Tags: tech, privacy, philosophy, politics
Reminder of why privacy matter and why we shouldn't collectively give in to the data vultures.
https://aeon.co/essays/privacy-matters-because-it-empowers-us-all
Librarians are dangerous
Tags: book, culture, learning
Very nice praise to an underrated and underpaid job. Can we have more librarians please?
https://bradmontague.substack.com/p/librarians-are-dangerous
I wrote to the address in the GPLv2 license notice and received the GPLv3 license
Tags: tech, licensing, foss, funny
OK, that's a funny experiment. I don't think many people post such requests anymore.
https://code.mendhak.com/gpl-v2-address-letter/
How decentralized is the fediverse really?
Tags: tech, fediverse, infrastructure, decentralized
Nice experiment. When looking at the actual infrastructure used, the servers are indeed nicely decentralized. For the users the picture would be different though.
https://discuss.systems/@ricci/114396317436420669
Government censorship comes to Bluesky, but not its third-party apps … yet
Tags: tech, social-media, bluesky, censorship
That happened fast, censorship demands already reached Bluesky and got applied. Third-party apps are not affected for now, likely due to their limited audience.
Getting Forked by Microsoft
Tags: tech, foss, microsoft
Such a nice and responsible citizen… FOSS is about extraction for them, not giving back.
https://philiplaine.com/posts/getting-forked-by-microsoft/
Former Google CEO Tells Congress That 99 Percent of All Electricity Will Be Used to Power Superintelligent AI
Tags: tech, ai, machine-learning, surveillance, politics, energy
Are they really believing their own lies now? More likely they're trying to manipulate clueless lawmakers at this point. They can't afford to let the circus end.
https://futurism.com/google-ceo-congress-electricity-ai-superintelligence
Coding as Craft: Going Back to the Old Gym
Tags: tech, ai, machine-learning, copilot, craftsmanship, learning
The metaphors are… funny. But still I think there's good lesson in there. If you use generative AI tools for development purposes, don't loose sight of the struggle needed to learn and improve. Otherwise you won't be able to properly drive those tools after a while.
https://cekrem.github.io/posts/coding-as-craft-going-back-to-the-old-gym/
AI Horseless Carriages
Tags: tech, ai, machine-learning, gpt, ux
Clearly to really benefit from LLMs there's quite some thinking around UX design to be had. This can't be only chat bots all the way.
https://koomen.dev/essays/horseless-carriages/
The Gruen Transfer is consuming the internet
Tags: tech, web, social-media, attention-economy, psychology
If you wonder why more websites become confusing… It's not exactly an accident.
https://sebs.website/blog/the%20gruen-transfer-is-consuming-the-internet
Understanding the Origins and the Evolution of Vi & Vim
Tags: tech, unix, editor, vim, emacs, history
Very nice account of the history behind vi and vim. Also some special mentions of Emacs and why it has such a different lineage.
https://pikuma.com/blog/origins-of-vim-text-editor
Beej's Guide to Git
Tags: tech, version-control, git
Looks like a very comprehensive resource about Git.
Store and manage dotfile configs in a bare repository
Tags: tech, version-control, git, config
Cool tip showing what can be done with got bare repositories.
https://alexalex.dev/posts/dotfiles-bare-repo/
Python's new t-strings
Tags: tech, programming, python
A new type of strings to keep an eye on in the upcoming Python release.
https://davepeck.org/2025/04/11/pythons-new-t-strings/
14 Advanced Python Features
Tags: tech, programming, python, type-systems
Good list of interesting features in Python. Some are tied to the gradual typing system but not all of them. Definitely tricks to keep in your bag.
https://blog.edward-li.com/tech/advanced-python-features/
C++26: more constexpr in the core language
Tags: tech, c++, metaprogramming, optimization
On the ever expanding domain of applicability for constexpr
, more is coming to C++26. This is definitely welcome, should keep making it easier to use.
https://www.sandordargo.com/blog/2025/04/23/cpp26-constexpr-language-changes
Does using Rust really make your software safer?
Tags: tech, programming, rust, memory, safety, fuzzing, tests
This is a nice little experiment. Not statistically relevant (there are other papers for that), but shows in the details how introducing Rust can impact the way people work. This is interesting because it means the safety gains are not only strictly coming from the (now infamous) borrow checker. We can't rely on everyone applying all the techniques necessary but for sure they're cheaper to put in place than with C.
https://tweedegolf.nl/en/blog/152/does-using-rust-really-make-your-software-safer
Zig -> allocators -> Rust ergonomics
Tags: tech, programming, memory, rust, zig
The concept of allocators in general and arena allocators in particular is too little know. Here is a little article which rediscover the motives behind them. It's a good introduction to the topic.
https://www.capturedlambda.dev/blog/zig-allocators-rust_ergo/
pahole: Analysing Memory Layout of Complex Data Structures With Ease
Tags: tech, memory, performance
This is indeed a nice tool to explore and check the memory layout of data structures.
https://pramodkumbhar.com/2023/11/pahole-to-analyz-data-structure-memory-layouts-with-ease/
Linux syscall table
Tags: tech, linux, kernel, system
Nice table of the Linux syscalls. You can search for them based on ABI and version. It even points to their definition.
Marching Events: What does iCalendar have to do with ray marching?
Tags: tech, date, time
Interesting way to look at solving recurrence rules in iCal.
https://pwy.io/posts/marching-events/
Defold - Cross platform game engine
Tags: tech, 3d, game, foss
Looks like an interesting game engine. Didn't know about its existence.
Feature Toggles (aka Feature Flags)
Tags: tech, architecture
A good post covering the feature flags concept and the different type of toggles you might have in a project.
https://martinfowler.com/articles/feature-toggles.html
YAGRI: You are gonna read it
Tags: tech, databases, debugging
Indeed, more metadata in your database can be a life saver.
https://www.scottantipa.com/yagri
Give it time
Tags: tech, architecture, design, time, ddd
Interesting food for thought. It's important to also approach domain models based on their workflows and events, not just their static relationship graphs.
https://ismaelcelis.com/posts/2025-04-give-it-time/
Design in TDD - by Kent Beck
Tags: tech, tdd, design
Yes, there's plenty of room for design in a TDD cycle. This is a good explanation of when it happens and the challenges you can have doing so.
https://tidyfirst.substack.com/p/design-in-tdd
When TDD doesn't work
Tags: tech, tests, tdd
Indeed a good reminder that TDD might not be possible to properly apply at the physical boundaries of the system.
https://blog.cleancoder.com/uncle-bob/2014/04/30/When-tdd-does-not-work.html
Implementation-Inspired Tests
Tags: tech, tests, tdd
Struggling with TDD? Really feel like you need to write the implementation first? This is a fine approach. One caveat though, you have to be very disciplined in the way you uncomment the code, otherwise you'll quickly loose the benefits.
https://arne-mertz.de/2017/02/implementation-inspired-tests/
Extreme Programming is as relevant now as before
Tags: tech, agile, xp
This is funny how this article written a long while ago now is still relevant… These are all good reasons for reading Kent Beck's book about XP.
https://f3yourmind.net/2014/01/06/the-relevance-of-xp/
The perils of estimation
Tags: tech, project-management, estimates
If you're asked a broad project estimate, building a very fine grained user story list is likely not the best approach.
https://dannorth.net/the-perils-of-estimation/
Advice for time management as a manager
Tags: tech, management, leadership
Good tips for time management indeed. I apply some of those but think I will borrow some extras from this article.
How to manage a team of remote employees
Tags: tech, management, remote-working
A bit shallow, but there's good advice to get started. Very often the quality of the communication medium is underestimated.
https://qz.com/230998/how-to-run-a-team-of-people-who-never-see-each-other
Good engineering managers aren't just hard to find - they don't exist
Tags: tech, engineering, management, leadership
This is indeed almost always leadership you need in your organization. An engineer who want to manage, maybe be careful about their skills and motives.
https://venturebeat.com/business/good-engineering-managers-arent-just-hard-to-find-they-dont-exit/
Argument Cultures and Unregulated Aggression
Tags: tech, organization, communication, decision-making, diversity
Indeed, arguments have a function. If they're used they need to be regulated, otherwise you won't get the best ideas possible in your organization due to competition.
https://www.kateheddleston.com/blog/argument-cultures-and-unregulated-aggression
Tools for better thinking
Tags: decision-making, problem-solving
Nice list of tools and models to use for better decision making and problem solving. Can all be done on paper of whiteboard. This is a good reference.
The raccoons who made computer magazine ads great - Technologizer by Harry McCracken
Tags: tech, history, art, culture
Ever realized raccoons had something to do with the history of computing? And children illustrations? Work of art if you ask me… we have to get back to the time of the computer magazines.
https://technologizer.com/home/2025/04/22/pc-connection-ads-raccoons/
Bye for now!
25 Apr 2025 5:48pm GMT
Planet GNOME
Allan Day: On Elephants
This post is a response to what Tobias posted yesterday on his blog. I would really prefer not be writing it. There are many other things that I would prefer to be doing, and I do not enjoy engaging in public disagreements. I honestly find all of this very stressful and unpleasant, but here we are.
For context, I joined the board in July last year, having previously been on the board from 2015 to 2021. This means that I wasn't on the board during some of the events and decisions described in Tobias's post. I am assuming that I am not one of the unnamed individuals he is calling on to resign, though I would be significantly impacted if that were to happen.
The post here is a personal view, based on my close involvement with the issues described in Tobias's post. As such, it is not an official board position, and other directors may disagree with me on some points. It's possible that the board may produce its own official statement in the future, but boards are inherently slow-moving beasts, and I wanted to get something posted sooner rather than later.
I want to start by saying that it is difficult to respond to Tobias's post. The Foundation has a policy that we don't comment on specific code of conduct cases, in order to protect the privacy of those involved. And, when you get down to it, this is mostly about the particulars of one specific case. Without being able to discuss those particulars, it is hard to say very much at all. That, in my opinion, is the elephant in the room.
The other reason that it is difficult to respond is there are just so many broad brush accusations in the blog post. It presents power conflicts and financial mismanagement and reckless behaviour and so on and so forth. It's impossible to address every point. Instead, what I will do is provide a fairly high-level view of each of the two main themes in the post, while calling out what I consider to be the main inaccuracies. The first of those themes is the code of conduct decision, and the second relates to the performance of the Foundation.
The big elephant
In the blog post, Tobias throws around a lot of accusations and suggestions about the code of conduct decision to suspend Sonny Piers from the GNOME project. His description of the chain of events is both misleading and a misrepresentation of what happened. Then there's an accusation of recklessness, as well as an accusation that the code of conduct decision was somehow politically motivated. All of this is clearly intended to question and undermine the code of conduct decision, and to present a picture of mismanagement at the foundation.
My view is that, despite the various twists and turns involved in the decision making process for this case, and all the questions and complexities involved, it basically boils down to one simple question: was the decision to suspend Sonny the correct one? My view, as someone who has spent a significant amount of time looking at the evidence, talking to the people involved, and considering it from different perspectives, is that it was. And this is not just my personal view. The board has looked at this issue over and over, and we have had other parties come in to look at it, and we have always come to the conclusion that some kind of suspension was appropriate. Our code of conduct committee came to this conclusion. Multiple boards came to this conclusion. At least one third party who looked at the case came to this conclusion.
I understand why people have concerns and questions about the decision. I'm sympathetic to the experiences of those individuals, and I understand why they have doubts. I understand that some of them have been badly affected. However, ultimately, the board needs to stand up for the code of conduct. The code of conduct is what provides safety for our community. We do not get to set it aside when it becomes inconvenient.
The argument that the code of conduct decision was somehow politically motivated is false. We even had an external reviewer come in and look at the case, who confirmed this. Their report was provided to Tobias already. He continues to make this accusation despite it standing in opposition to the information that we have provided him with.
Tobias seems to think that Sonny's importance to the GNOME project should have been taken into account in our decision for the code of conduct case. To me, this would imply that project leaders would operate according to a different, less stringent, set of conduct rules from other contributors. I believe that this would be wrong. The code of conduct has to apply to everyone equally. We need to protect our community from leaders just as much as we need to protect them from anyone else.
No one is suggesting that the management of the code of conduct decision was good. Communication and management should have been better. Community members were significantly impacted. We have sincerely apologised to those involved, and are more than willing to admit our failings. We've also been working to ensure that these problems don't happen again, and that's something that I personally continue to spend time and energy on.
However, to understand those failings, you also have to look back at the situation we faced last year: we had just lost an ED, board members were burned out, and our processes were being tested in a way that they never had been before. We still had all the usual board and foundation work that needed taking care of. In the middle of it all, elections happened and the board membership changed. It was a complex, shifting, and demanding situation, which looks rather different in retrospect to how it was experienced at the time. We learned a lot of lessons, that's for sure.
The other elephant
The other part of Tobias's post addresses the performance of the Foundation.
He points out various problems and challenges, some of which are real. Unfortunately, while being convenient, the theory that all of these challenges are the result of the incompetence of a few individuals is, like most convenient answers, incorrect. The reality is more complex.
One of the major factors for the Foundation's current situation is our recent history with Executive Directors. Neil left as ED in November 2022. It took us about a year to hire Holly, who was ED for seven months, during which time she had to take a non-trivial amount of time off. And the Foundation is a small organisation - there aren't lots of people around to pick up the slack when someone leaves. Given these circumstances, it's unsurprising that the Foundation's plans have changed, or that they didn't happen in the way we'd hoped.
This is why the current board has been focusing on and expending considerable effort in recruiting a new executive director, who will be joining us very soon. Hurrah!
Tobias's proposition that anyone who tries to change the Foundation gets burned out or banned is not true. I am living proof of this. I have changed the Foundation in the past, and continue to change it as part of my role as director. The Foundation today is radically different from the one I first joined in 2015, and continues to evolve and change. A lot of this is due to the interventions of previous and current directors over time.
Amid all this, it's also important not to forget all the things that the Foundation has been successfully doing in recent years! I went into some of this in my recent blog post, which provides more details than I can here. It is worth stressing that the ongoing successes of the Foundation are mostly thanks to the dedication of its staff. We've run successful conferences. We've supported Flathub during which time it has experienced extraordinary growth. We've supported development programs. And the organisation has kept running, sailing through our taxes and registrations and all those other bureaucratic requirements.
On resignations
From the outside the GNOME Foundation can seem a little opaque. Part of the reason for that is that, as a board, we have to deal with sensitive and confidential matters, so much of the work we do happens behind closed doors. However, when you are on the board you quickly learn that it is really much like any other community-based open source team: there's usually more work to do than we have capacity for, and the majority of the work gets done by a small minority of contributors.
Speaking as part of that minority, I don't think that it would be beneficial for members of the board to resign. It would just mean fewer people being available to do the work, and we are already stretched for resources. I'm also of the view that no one should be asked to resign in response to upholding the code of conduct. Conduct work is difficult and important. It requires tough decisions. As a community we need to support the people doing it.
And if people think we should have different directors, well, that's what the elections are for.
Closing
Readers might wonder why the Foundation has not spoken publicly about this topic before. The main reasons were confidentiality and legal concerns. We have also tried very hard to respect the wishes of those who have been involved and affected. Now with Tobias's post it is harder to avoid saying things in public. I'm personally skeptical of how useful this is: with opaque and complex issues like these, public discussions tend to generate more questions than they do answers. Contributor relationships are unfortunately likely going to get damaged. But again, here we are.
It should be said that while the foundation hasn't spoken publicly about these issues, we have expended significant effort engaging with community members behind the scenes. We've had meetings where we've explained as much of what has happened as we can. We even went so far as to commission an external report which we made available to those individuals. We continue to work on improving our processes in response to the, ahem, feedback we've received. I personally remain committed to this. I know that progress in some areas has been slow, but the work continues and is meaningful.
Finally: I am sure that there are contributors who will disagree with what I've written here. If you are one of those people, I'm sorry that you feel that way. I still appreciate you, and I understand how difficult it is. It is difficult for all of us.
25 Apr 2025 4:28pm GMT
Jiri Eischmann: Hiring for Flatpak Automation
The desktop team in Red Hat has another open position. We're looking for someone to work on Flatpak automation, for someone who enjoys working on infrastructure. Although the job description states 2+ years of experience, it's suitable for juniors. Formal experience can be replaced by relevant open source contributions. Being onsite in Brno, Czech Republic is preferred, but not required. We're open to hiring good candidates elsewhere, too.
If you'd like to know more about the job before formally applying, don't hesitate to contact me on Mastodon, Signal, Matrix (@eischmann at fedora.im), or email.
25 Apr 2025 3:26pm GMT
Planet KDE | English
Going in depth on Font Metrics.
After tackling fonts and opentype features thoroughly, I decided to continue on with taking care of font metrics. This covered font size, line height, baseline alignment and shift, as well as text underlines and carets.
What are font metrics.
If a font is a designed collection of glyphs, then font metrics are the specifications to which those glyphs are designed. Well, some of them at the least. While there are ways to store stem thickness metadata into the font, in practice the font metrics that are most used are those used to lay out lines of text, and to determine the font size.
The main one of these is the EM size. This defines the coordinate system in which the glyphs are drawn. When setting a font size, you end up scaling the em-size to the font size value.
To place the origin of that coordinate system, the ascender and descender are defined. Usually, ascender plus descender equals em-size, but as we'll discuss later, that's not self-evident.
Beyond that, there's often extra metrics stored like the x-height, cap-height, and super- and subscript positions.

But up till now, we've only discussed metrics that are mainly common in European scripts. Other writing systems have other metrics, and while some of these metrics can map to the European metrics, others, like em-box center and hanging baseline are unique to those writing systems.

North Brahmic scripts like Devanagari have a headstroke that glyphs of different sizes are aligned at.

Meanwhile, CJK ideographs are designed inside an Em-box, which itself contains a character face-square. The latter is usually used for a sort of optical alignment of CJK ideographs. The embox is used to calculate the centers, which in turn is used to align the character vertically. Horizontally, each of these points, plus the Latin baseline, could be used to align the text.

These too, can be stored inside the font, and need special attention how to use them within text layout.
Finally, text underlines and strike-throughs, as well as slanted carets have extra metrics. We'll touch upon these at the end.
Font size and line height.
So, as mentioned before, the font size is the value that the em value the font was designed at is scaled to. So if a font has an em size of 1000, then that means all glyphs in that font are designed in a coordinate system relative to 1000. If you want to scale them to, say, 12px, you are effectively scaling all the glyphs's coordinates by 12/1000 and then rendering the result to a raster bitmap. Bitmap fonts work a little different, and there you will need to see which of the available bitmap sizes ('strikes') is closest to the requested size. In the case of bitmap emoji fonts, it is typical to find the closest size and then scale them to the required size, but for non-color bitmap fonts I made Krita follow Qt; and apply no scaling.
Now, there's a bit of a problem here: Freetype doesn't allow setting the point size below 1, so you need to scale the resulting glyphs if you want to be able to have it below 1pt. However, while said scaling of color emoji is done via FreeType transforms, and Raqm handles and applies those transforms, I can't get it to work for the below 1pt transforms. My suspicion here is that the scaling messes too much with the freetype coordinates which are stored in integers (64x the pixel size), so I had to apply that transform separately once we go from Freetype coordinates into floating point land. Not very happy about that, because that means two separate transforms for basically the same thing (getting proper font size).
Line height
So, line height is the height of the lines. Those of us that have done word processing before will know that it is not unusual for a manuscript style guide to say: "Double spacing", meaning there's a full line's worth of white space between lines (useful to write all those editorial notes into!), while final texts often are at 1.2 to 1.8 spacing.
But then, what should the line height be? Is it a multiple of the font-size? Or whatever the ascender and descender add up to? Because those two things are not the same thing!
But actually what is the ascender and descender? Is it the same as the maximum and minimum extend? It seems that early text layout programmers thought so, because for the longest time, the OpenType values called "WinAscent" and "WinDescent" both served as the ascender, descender and the clipping region on Windows. Apple instead used the values ascent and descent from the hhea
and vhea
OpenType tables.
Now, thankfully, the CSS specs define the metric we need to use: sTypoAscender and sTypoDescender from the OS/2 table (the fifth way of selecting these values, for those keeping count!), regardless of whether any related bits are set. This is what most implementations use… Except Apple, which uses hhea and vhea still, even within their web browser.
Now then, we've got the ascent and descent for horizontal. But what should we use for vertical? The vhea table values? CSS-inline-3 says nothing about the vertical line-height, but thankfully, the SVG 2.0 spec does:
Within an OpenType font, for horizontal writing-modes, the ascent and descent are given by the sTypoAscender and sTypoDescender entries in the OS/2 table. For vertical writing-modes, the descent (the distance, in this case from the (0,0) point to the left edge of the glyph) is normally zero because the (0,0) point is on the left edge. The ascent for vertical writing-modes is either 1 em or is specified by the ideographic top baseline value in the OpenType Base table for vertical writing-modes.
That's right, a sixth way of selecting ascender and descender!
Still, it is coherent with the way that the OpenType specs want us to calculate the em box (more on that later), where the height of the box should use sTypo values (if the baseline values are missing) and the width should use the baseline values.
There is a small annoying thing here with that vertical-writing modes tends to mean writing-mode: vertical-lr and vertical-rl, regardless of text-orientation, but I suspect that this is intended for the situation of text-orientation: upright, or mixed resolved to upright, because otherwise vertical but rotated text is not going to lay out correctly (For vertically oriented upright text this makes perfect sense).
Units
Another thing that needed tackling was the unit to set CSS lengths with. Many properties inside CSS text can use other units besides the default. Most interesting here are the percentages, but for something like tab size, you can choose to use a multiple of spaces.
Now, within Krita, all vector coordinates are in points, not pixels (see the appendix for their difference), and we keep track of a per document DPI to calculate conversions between the two. This is pretty standard for image editing applications like ours.
SVG mostly facilitates this: An SVG user-unit is explicitly not defined as anything particular, and the difference between the coordinate system set to the viewbox and the width and height set on the top level SVG element is what defines the scaling it'll experience when used in an HTML context.
Except, CSS length values as used by SVG text do have explicit units. And the default user unit for those is CSS pixels. This is throughout all of CSS, so if the specs say "you can use an SVG path here", then the coordinates of that SVG path are assumed to be pixels (especially relevant because SVG path definition does not allow units to be defined).
For us, that means we cannot actually store any of the absolute CSS values, that is, mm, inch, pixel, but instead convert everything to point under the hood and then store that as SVG units, and set the viewport and width/height accordingly. This mostly works, except with the line-height and tab-size values, which allow a number in addition to a length with unit. Which means those need to be set to px explicitly in those cases.
Ideally, we'd have a way to define the default CSS unit for unit-less situations like SVG, so that for our case, we could write line-height: 12pt; font-size:12;
, and the parser would be able to understand that font-size is the same value as line-height here.
However, because we are converting everything to points, we can afford to offer pixels to be actual document pixels, and not the hard-coded-to-96ppi css pixels. This is useful because a number of our users don't understand the difference between points and pixels, or PPI in itself. In the latter case, those tend to set the PPI to the pixel width, meaning that the document is exactly one Postscript point wide, and we get a bug report that the text is too large. For those artists, being able to divert them to use pixels might be a good solution (and to point out that their PPI value is useless). Then there's of course the artists that want to use retro-style fonts for aesthetic purposes, and yes, pixels is useful there, but admittedly that also needs a little bit more work beyond the scope of this particular blog post.
Relative units.
There's more to CSS values than absolute units. It has relative units. In particular, font-relative units. These units use metrics from inside the font to determine their resolved value. Think of the height of a small x, or the capital height. I in particular wanted to get these to work because eventually the idea is to have style presets, and being able to store something like "font-size: 0.5em" as a preset seems mighty useful.
For these (and the baselines later), I collect them inside a metrics struct. These are then used before text layout begins proper to handle inheritance and convert all such units to points.
Percentages are a separate thing from font-relative units, and are a bit weird. In SVG 1.1, percentages were largely relative to the root viewport, which is somewhat odd, but it is what the spec requires. In SVG 2.0, most of them are now linked to their CSS reference values. In the case of text-indent in particular, the inline-size of the wrapping area needs to be used to determine the percentage value, so that one is resolved during line layout.
Font Size Adjust
So, because the font-size is linked to a somewhat arbitrary value that is part of the design of the font, it can be useful to set the font-size by a more tangible metric.
Font size adjust allows just this, and is meant in particular to ensure that the given metric is at a decent size. CSS font-3 and 4 only allow setting the proportion of the x-height, which in turn is valuable because that can great affect the readability of the text. The idea is that you want to ensure that the x-height for all fonts is, say, 60% of the font-size. Then, you take font-size-adjust and set it to 0.6. Then during text layout, when the font-size is set, the x-height within the font is used to adjust the total font size. Setting font-size-adjust to 1.0 should then scale the font so that the x-height is the specified css font-size.
CSS-Fonts-5 has a proposal for more of these metrics, but is still very much in draft, so I've avoided it for now.
One thing I do want to mention is a bit of a problem: All of the proposed metrics can be adjusted by variable font's parameters. That is to say, you can have an optical axis on a variable font, that sets the x-height higher on small sizes and lower on big sizes. Then, changing the font-size will change the x-height. This means that you could end up in some kind of cycle trying to get the right font size for the given font-size-adjust.
I don't know how to fix this. For now, what I do is that I set the size (but not the axes), test against the default x-height, set the adjusted x-height and then set the axes, which will mean that something like optical size is at the very least the size the font is set at, but that may not be the size which was intended by font-size-adjust.
Baseline alignment and friends.
Baseline alignment is all about aligning glyphs to one another perpendicular to the line width. By default, most fonts are set up to align to the same baseline as that of Latin, because this gives the least trouble in mixed-script situations. However, when in single-script situations, especially those with font-fallback, it can look a little messy. Baseline alignment can reduce this messiness:

Now, of course, it is rather hard to find these baselines, and trickier still to synthesize them right. The Sharad76 font above, for example, is a handwriting font, so it is hard to synthesize a hanging baseline for it. So, OpenType has a place to store these: The BASE table.
According to that spec, the base table is supposed to make it so that glyphs of different scripts and fonts can align correctly. And to do so, it allows for defining, per script and run direction (vertical or horizontal), values for different baseline tags, as well as the preferred baseline for that script, and min-max extents.
Unfortunately, the spec doesn't specify how the base table is supposed to see the OS/2 and hhea/vhea tables in this system, like, which baseline those are aligned to… This is a bit of a problem for the spec, because it imagines it to be able to have script to be defined by a more natural origin for their glyphs, but without ascender or descender being aligned to anything, it becomes hard to imagine how you'd make an editable text layout with a font like that.
Still, it exists, the font development recommendations suggest that fonts are by default build for Latin baseline. The only implementation I personally know of is Adobe products' CJK composer, where the ideographic em-box and character face can be aligned against.
Then, there's four different W3C baseline alignment specifications. The oldest of these is from XSL 1.1, which was then adapted by SVG 1.1, which in turn was then adapted by CSS-inline-3. SVG 2.0 also has some details, but like how SVG 1.1 adapts XSL, SVG 2.0 adapts CSS-inline. The last one is significantly different from the other two, but all of them are rather confusing. So confusing in fact, that I actually wrote this part before finishing up the implementation, just to get a grasp on what I'm actually supossed to implement.
Lets start with the oldest. The main thing XSL's spec wants, is that there's a core baseline table for the whole paragraph, and each glyph aligns to its prefered baseline on that root baseline table:
The glyphs determined by the fo:characters that are in the content of the two formatting objects are aligned based on the script to which the glyph belongs.

This is why "dominant baseline" doesn't inherit; every time the dominant baseline is defined, a new table is calculated, and if it is not, the old baseline table is inherited. It's alignment baseline that allows manual alignment of glyphs.
SVG 1.1 is similar, except that "before-edge" and "after-edge", which are basically line-relative alignments (lines, which SVG 1.1 doesn't have), get interpreted to be the equivelant of ascent/descent.
The description of alignment-baseline: auto, however, shows why it is important to read the XSL spec, as the definition in SVG 1.1 is rather confusing, it says literally two different things:
The value is the dominant-baseline of the script to which the character belongs - i.e., use the dominant-baseline of the parent.
While XSL is much clearer here:
The computed value depends on the kind of object on which it is being used. For fo:character, the value is the dominant-baseline of the script to which the character belongs. If the value of the "script" property on the parent formatting object is other than "auto" then use the baseline for that script; otherwise, use the dominant-baseline of the parent. For all other objects, the value is computed as for the "baseline" value.
So basically, align glyphs to the inherited baseline table with their preferred baseline, everything non-glyph is aligned using the dominant baseline.
CSS-inline-3 however, gets rid of this inherited baseline table, and instead says 'any inline-box is always aligned to its parent', 'any glyph is aligned to its parent inline-box'… I think. The actual text says, for dominant-baseline:
For inline boxes, the dominant baseline is used to align the box's text (and, unless otherwise specified by vertical-align, any inline-level child boxes) by aligning each glyph/box's corresponding baseline to the box's own dominant baseline.
For alignment-baseline:
When performing baseline alignment, these values specify which baseline of the box is aligned to the corresponding baseline of its alignment context. (In an inline formatting context, inline-level box fragments and glyphs share an alignment context established by their parent inline box fragment along its inline axis. …)
And finally, a little earlier, in the Baseline Alignment intro text:
For a glyph, the alignment baseline is always determined by the parent's dominant baseline.
What trips me up here is "parent inline box fragment", which refers to a box that due layout is split over multiple lines, columns or shapes. But that isn't really relevant for alignment baseline, because that only has font-derived alignment points. If there were line-derived alignment points, (like, before-edge/after-edge), then this would make sense. But instead those (renamed "top" and "bottom", and joined by "middle") are now part of baseline-shift, with a note saying "maybe these should be part of alignment baseline"…
Then there's this weird note under dominant-baseline:
In SVG text layout, these values instead specify the baseline that is aligned to the SVG current text position.
Which is very confusing to read when you're trying to write SVG 2 text layout with automated wrapping, because it makes it sound like alignment-baseline will have no effect, in which case, why would it be in the SVG 2 spec? (SVG 2 also doesn't help here, it kinda glosses over the fact that the implementation details are completely different between CSS-inline-3 and SVG 1.1. Might be because the spec is still not finished…)
Another thing that is different between all the specs, is that in XSL, "use-script" should use the script defined inside the script property (that is, XSL has a property named "script", not the unicode property script), and then use the default baseline for that script as defined in the font. SVG 1.1 has no script property, so it should guess the dominant script inside the text.
CSS-inline-3 removed the "use-script" property, because the SVG 1.1 definition was too vague, and it seems they don't know that fonts themselves are supossed to define the default baseline for a script. In theory it can be resurrected, but then using the BCP47 tag, as CSS-text does, and using the default baseline-for-script defined in the font.
Finally, all the specs also define baseline-shift. In CSS-inline-3, it wants to see baseline-shift and alignment-baseline as longhands of vertical-align (XSL wanted to do something similar, by the way).
It then defines the baseline-shift as a post-alignment shift, implying the baseline alignment needs to be done beforehand.
However, XSL and SVG 1.1 have an important note here, with regards to the baseline shift super and sub properties:
The dominant-baseline is shifted to the default position for superscripts. The offset to this position is determined using the font data for the nominal font. Because in most fonts the superscript position is normally given relative to the "alphabetic" baseline, the user agent may compute the effective position for superscripts when some other baseline is dominant. The suggested computation is to subtract the difference between the position of the dominant baseline and the position of the "alphabetic" baseline from the position of the superscript. The resulting offset is determined by multiplying the effective superscript position by the dominant baseline-table font-size. If there is no applicable font data the user agent may use heuristics to determine the offset.
There's another oddity in the SVG spec, regarding the percentage:
The computed value of the property is this percentage multiplied by the computed "line-height" of the 'text' element. The dominant-baseline is shifted in the shift direction (positive value) or opposite to the shift direction (negative value) of the parent text content element by the computed value. A value of "0%" is equivalent to "baseline".
But SVG 1.1 doesn't have a line-height, and the spec says to interpret it as font-size. Meaning this property behaves differently between SVG 1.1 and SVG 2 (which does have line-height).
Finally, SVG 2 has some notes as well:
When a different font (or change in font size) is specified in the middle of a run of text, the dominant baseline determines the baseline used to align glyphs in the new font (new size) to those in the previous font. The dominant-baseline property is used to set the dominant baseline.
So then, how should we implement this.
Let's go back to that SVG note.
In SVG text layout, these values instead specify the baseline that is aligned to the SVG current text position.
SVG 2.0 has a similar note:
SVG uses the value of the dominant-baseline property to align glyphs relative to the 'x' and 'y' attributes. For the text-orientation value sideways, the auto value for dominant-baseline is alphabetic; however, for backwards compatibility, the glyphs should be aligned to the 'x' and 'y' attributes using the value central.
So, the "current text position" or "x and y" properties here refer to SVG's per-character positioning and rotation. One frustration here is that while text-position and x and y refer to similar things, the latter is only a part of the former, with dX, dY and rotation being the remainder.
However, lets assume there's no dx, dy and rotation, can we then tell what this is trying to do?
Yes, its trying to align the text in question so that its dominant-baseline can align with a path in text-on-path layout. This makes sense and we want this.

Then, it stands to reason that dx, dy and rotation should probably use this new point as well. Which means CSS-inline is correct here; it affects the current text position.
So what we can, in effect, do for dominant-baseline, if it is aligning glyphs, is to have it not specifically align, but rather, have it shift the origin of the glyph's coordinate system. That's the glyph path coordinates, bitmap rectangles, as well as all the metrics.
(Now, both the SVG 2 and CSS inline spec caution that for dominant-baseline:auto, the resulting vertical dominant baseline is always central in SVG, but that is largely in regards to text-orientation, and Krita doesn't support text-orientation right now, so it is not relevant for me yet.)
For CSS text layout (important for wrapping), there's no difference between aligning the glyphs via dominant baseline or shifting their origin.
Then there's the question of, how do alignment-baseline and baseline-shift get involved with this?
Firstly, both are non-inheritable. And baseline-shift, or at the least super and sub script positioning can nest. So alignment-baseline, now part of vertical align, then also stacks. Similarly, because vertical-align: super affects the line-height, so will alignment-baseline, now part of vertical-align.
That in turn means that baseline alignment needs to happen before wrapping. Especially as, when wrapping in a shape for SVG 2.0, the line-height will affect how much inline space is available.
Now… there's a bit of a problem here. The default SVG 2 layout algorithm does this thing to ensure that the initial position aligns with the absolute transforms. Which mean that you can't start a text with a super-script, as the layout will reset that initial position. Most implementations I've checked don't do this, so the vertical-align probably should be taken into account. However, I can't really find anything in the SVG 2 spec that confirms this, beyond the following sentence:
As glyphs are sequentially placed along a baseline, the alignment point of a glyph is typically positioned at the current text position (some properties such as vertical-align may alter the positioning).
In addition to no implementation doing this: if you don't take vertical-align into account, then certain layouts could have the whole text move by removing the first character, which can't be the intention.
Beyond that, alignment baseline should probably also work from a moved origin, because it needs to compute to "0" when defaulting to the dominant baseline.
Finally, there's whether or not super and subscript should be adjusted to alignment or dominant baseline. As noted before, XSL and SVG 1.1 say it probably should be aligned to the alphabetic baseline, but there alignment-baseline was the positioning, while dominant-baseline defined the baseline table, while in CSS they're both a type of positioning behaviour.
In any case something needs to be done, because especially with "hanging", the behaviour can can change radically whether dominant-baseline is set or not.

Eventually I decided to have alignment-baseline affect the strength of super and sub, because even in a situation like CSS, where the alignment-baseline and baseline-shift are both part of vertical-align, alignment-baseline is always active and aligns to the dominant baseline. Which means that if you have CSS inheriting from two different classes, dominant-baseline can affect super and subscript in unexpected ways.
Finally there's the line-relative modes. That is baseline-shift: top, centre, bottom ("center" being an absolute terrible name: it means that vertical-align now has "middle", "central" and "center" meaning three distinct things). I accidentally implemented top and bottom, because I had misread the spec. And I could just parse the baseline-shift: top/bottom and use those instead, but I'm kind of stuck having to decide where to stick them in the UI. The spec itself is saying "well, this is just draft for now".
What I actually implemented.
Let me run through what Krita is doing now, with some ugly pixel art examples, where each inline-box also has a different text color:

Firstly, we have our set of glyphs and their baselines. Each of them has an alphabetic baseline at 0, and a hanging baseline at various points.

To start with, we translate the coordinate system and all related metrics so that the dominant baseline is the 0 in the coordinate system. When doing this, you will want to adjust the baseline metrics you are storing per-typographic character in the same manner, as that will be useful when calculating the text-decoration later.

Then, as the second part of handling dominant baseline alignment, we align all glyphs to their parent inline box by the dominant baseline. Because we aligned all glyphs so that the dominant baseline is 0, we now have that second alignment as an offset onto each glyph. These two adjustments are only applied when aligning glyphs, not when aligning inline boxes to their parents.

As that is the next step. Here, we have the alignment-baseline align portion. By default, this is the same as dominant baseline, but if it were any other value, it'd use that instead.

Finally, we have baseline-shift. If baseline-shift is super or sub, we subtract the shift from alphabetic to alignment point caused by alignment baseline from the super or subscript value. If it turns out to be a line-relative value (top/bottom), these will not be processed during the regular alignment process, but instead done after line-breaking.
This approach has some benefits. Firstly, the coordinate system shift makes using the dominant baseline as the point to which align the current text position trivial. The second, which is a little bit more odd, is that when having done that coordinate system shift, the total shift needed for alignment and dominant baseline together will be constant over the whole text as long as alignment baseline defaults to dominant.
This is useful, because later, you will need to know whether vertical align (that's baseline-shift and alignment-baseline) changes if you want to know whether the strike-through for text-decoration needs to be split into a new chunk. This way, you don't need to test whether the css property is set, but can instead test whether this offset is changing.
Then, for the current text position problem I had, I subtract the shift caused by dominant+alignment baseline from the first text transform. This means that if an absolute SVG text transform is applied to a text with dominant or alignment baseline applied, it will still move the origin of the glyph to that position.

For baseline-shift however, that offset is stored separately. According to the SVG spec, we first need to apply the relative transform, then text-length, and then the absolute transform. The spec says to take the relative offset, subtract the current character position, and then add the absolute offset to that for the total shift. I'm not 100% sure why it does that, but for my purposes, the baseline-shift is added to the relative offset. This means that an absolute transform will always have the baseline-shift (if any) added in addition, which in turn should make it possible for pieces of SVG text to start with a superscript without moving the whole text position if that superscript is removed.
That means that for me, line-relative values like vertical-align: top
don't necessarily need to be mapped to baseline-shift or alignment-baseline for whether they count as alignment or not, but rather for how they interact with SVGs absolute character transforms. Its kind of why I have decided to not show these options in the UI for now, because I don't know what makes sense here…
Em box calculation.
Because base table is not that widely used, CSS-inline-3 has a number of fallback calculations, and Harfbuzz implements a number of these. I am somewhat sceptical of the ideographic em-box calculation, however:

Here we have script samples in, left to right, Latin, Simplified Chinese, Tibetan, Korean and Devanagari, all aligned by their "ideographic" baseline (pink). All glyphs are from Noto Sans and -Serif fonts. Blue square uses the font-size used by the text for its width and height.
What is going on here is that if we look at the official way to calculate the ideographic em box, we end up with a rectangle that uses the em size for the width, and the sTypographic ascender+descender for the height… but only if the font is evidently a CJK font.
Noto Serif Tibetan is not a CJK font, and has a large descender to reserve enough room for the clusters that Tibetan produces. That means that the ideographic bottom is far lower than anyone would expect it to be.
So I decided to adjust the em-box calculation a little. For vertical, upright, glyphs, it defaults to the em-size in width if there's no Base table ideographic values.
For horizontal, it uses sTypo ascender + descender when the font either has a CJK script in its design scripts metadata, or, more likely, has '水' (U+6C34) as a character, which I needed to test anyway as it is used for the ic
font-relative value.
If neither is the case, then it scales the ascender as per CSS-inline-3 em-over. Then compares that to, first, the hanging baseline (if present), or otherwise the cap-height. If one of these is larger than the scaled ascender, it will use that as the em-box top. Then, the em-box bottom is 1 em below the em-box top.

This is by no means perfect, a bit messy honestly, but it does look a lot less like something broke.
Before I forget, there's another oddity with the baseline properties, and that is that it only allows alignment to ideographic-bottom and central, but not ideographic-top. Arguably, because of the way the em-box is calculated, the ideographic top can be the same as 'text-top', but if you look at non-CJK fonts, that isn't necessarily the case. Similarly, character face metrics are not defined at all. I guess part of them problem is figuring out what exactly is being used in real life and for what purposes, but it is a little odd.
Text decoration
When I did a talk at the last Libre Graphics Meeting, one of the questions afterwards was "so, how are you calculating the text-decorations, are you using css-text-decor-4?" The answer was "no", largely because I only realized that had a different way of calculating after I'd finished my initial text layout work.
However, after reworking the baseline alignment stuff, text decoration also needed overhauling, and I figured to take into account decor-4's new specifications would make sense.
The biggest difference between decor-3 and decor-4 is that for decor-4, the strike-through is split when the font-size changes in without vertical-align changes.
Beyond that, decor-4 suggests that the underline position, when not using alphabetic underline, should use the em-box lower edge… Which I don't quite understand, as the em-box is never defined anywhere in decor-4, and if it is the em-box meant by the opentype specs, then that is going to be too high up for a Tibetan fonts that does have ideographic edges defined.. So I am ignoring mentioned of 'em-box' in decor-4, and assuming it means the ascent+descent instead.
So to tackle these differences, I first calculate the ranges the text-decor needs to be applied to. To keep consistency, decorating boxes need to be derived, and a span of decorated text can have multiple decoration boxes in case there's a line break for whatever reason. Because I am working in SVG, I've, in the past, also decided that it would make most sense if the decorating boxes got split whenever there's an anchored chunk, as these, within svg, are caused by both line starts as well as absolute positioning changes.
So what I end up doing is that every time an anchored chunk start is encountered, a new decorating box is created for that range. Then, said range is "trimmed" to remove the hidden/collapsed/unaddressable/white spaces from the start and end of the range, as per §2 of the spec:
Underlines, overlines, and line-throughs are drawn only for non-replaced inline boxes, and are drawn across all text (including white space, letter spacing, and word spacing) except spacing (white space, letter spacing, and word spacing) at the beginning and end of a line.
After getting the ranges, the decorating boxes proper are calculated by going over each range. For under and overlines, the layout bounds (a box of the advance and ascent+descent in line-height direction) are used to create the decorating box. When dealing with "auto" or "alphabetic" positioned underlines, the layout box instead uses the ascent+offset to alphabetic baseline as the line-height. Because back in the dominant baseline section, all metrics got adjusted to the dominant baseline, you don't need to know what the dominant baseline is, just how much distance there is between the alphabetic and origin.
For line-through, the start of each range creates a new line-through, but also whenever the font-size changes (but not when the font-size and total baseline offset change). Because of the way I calculate the baseline alignment, the total offset only changes when alignment baseline is doing something else than dominant baseline, or the baseline-shift changes, both of which are what constitute a vertical-align shift. By checking the value difference, we don't need to know whether vertical-align is actually set in the CSS.
EDIT: I might change this again in the future, as I just realized that if you change the dominant baseline halfway in a decorated span, the alignment baseline will ensure it stays in the same place, but it does change the offset, meaning the line-through changes. Maybe I am entirely overthinking this and the decor-4 spec writer was thinking "avoid super-script problems" without any regard for inline-3.

The spec also states:
To prevent superscripts and subscripts from throwing this [underline offset] position off-kilter, an inline with a non-initial computed vertical-align is treated as having the ideal underline position of its parent.
I'll freely admit I'm just not counting the metrics for these offset sections, and only making the decoration box/line through larger, because that prevents me from having to know what the ideal value of the parent is, simplifying the algorithm. In the end, the underline offset, line-through offset, and line thicknesses are averaged by the amount of samples I have, which does not include these ignored sections.
Cursor stuff
The last bit is the slanted cursor line metrics. This is mostly idle musing, as the metrics involved themselves are rather trivial.
When you have a piece of text that is slanted, like in an italics face, this slant might be stored inside the font metrics, so that the cursor, or caret, can be slanted as well.
Because slant ratios are floating point, and the OpenType metrics (from hhea and vhea respectively) are integers, the value is stored as a rational number derived from a caret "run" and "rise". These by default are 0 and 1 for horizontal, and 1 and 0 for vertical. Then, there's an offset, because if you slant a line as long as the line height, that line will not go through the origin of the glyph anymore. This extra offset corrects that.
I had initially added this to the font metrics in a thought of avoiding extra calculations when retrieving glyph data, but when I started to move it I came to the conclusion I was checking the font anyhow to get the ligature caret offsets.
So instead some musings:
In particular, most of this blog was about baseline-alignment, and offsets in the line-height direction (called box-direction by the CSS specs). If a glyph is slanted somehow, shouldn't that be taken into account here? Like, there isn't actually a self-evident answer here:
When slanting an italic, some fonts have it so that the slanted glyphs are fully encompassed by the advance, and then use kerning to reduce the advance to what is strictly necessary. Because kerning doesn't happen across itemization runs, and having a different slant counts as a different run, this means that there's a little space before and after slanted glyphs, so they don't knock into non-slanted glyphs.
But not all fonts do that. Nor do all fonts have slant carets despite being visually slanted, or have extra x and y data to allow shifting the super and subscripts slanted (I'm making Krita use this data right now, because "why not?", but it is not require by the spec).
And while we're at it, if a script is being synthetically slanted… should that happen across its dominant baseline origin?
Maybe the spacing issue, at the very least could be resolved with having a "spaces before/after italics" for the new auto spacing properties in css-text-4, but that in itself will not provide answers for how to handle baseline offsets.
Final thoughts
When I had finished font file handling, I wanted to do something slightly less heavy, and I thus chose to work on OpenType features. This was because I could already tell that fine-tuning the handling of font metrics was going to be quite a big task, and I was correct.
Reworking baseline alignment to shift from XSL/SVG 1.1 to CSS-inline-3 in itself was 4 days for reading the specs, and then another 4 days for untangling all the whole system. Text decorations too required multiple days to get right, to the point where, now I am writing these final thoughts, I am still building some changes to get past an edge case.
For the baseline alignment stuff, I was somewhat… Confused? Disappointed? In the way how people talked about the feature, saying things like "Alignment of glyphs of different font-sizes is not an important feature", while any understanding of the scripts involved makes it clear it must look mighty strange to a native user. Meanwhile, Latin text has support for ligatures and hyphenation and the like, which I can't say is any more or less important than proper baseline alignment.
That said, the feature itself is weirdly… uninteresting once it is implemented. Because the metrics largely align to the parent baseline, it is only really interesting when you start nesting text, meaning that in most cases you only really want to set the dominant-baseline. Because alignment-baseline takes over dominant-baseline of the parent, I am having a hard time imagining situations where you'd set it by itself. I've had situations where it seemed like it wasn't working, until I realized that I was comparing the glyphs in question to the line they were in, and not the top-level font metrics.
This is one place where I'd like to have some better UI so this becomes a little less abstract. I don't regret implementing the feature, in any case: Because for Krita the text tool's current main goal is to be able to type set comics, we need to ensure it can be used in situations where otherwise people would resort to calligraphy/hand lettering. Proper baseline alignment, as well as font-size differences seem to me like they'd be common in that kind of type setting.
Other than that, these properties are peculiar in that many of them don't inherit: Baseline-shift doesn't inherit, nor does alignment-baseline or the main text-decoration properties. This is because they can nest: You can have a baseline-shift inside a baseline-shift, a text-decoration that paints over another. Beyond these properties, there's one other important SVG text related CSS property that also nests: Unicode-bidi, meant to assist in managing the handling of bidirectional text layout.
Because the majority of WYSIWYG text tools don't support editing text-layout as a tree of nested items, there is no common way to handle this. Which means I probably spend way too much time on getting this text layout to handle stuff most artists won't ever see, which is a little unsatisfactory. I think it'll remain that way for a while though, until I can figure out a way of manipulating these nestable properties that doesn't result into extensive tree management.
My next text layout blog will be about some remaining line breaking related stuff, mostly because I am already done with the work for that…
Appendix
Pixels versus Points
For those not aware, there is a difference between pixels and points. In particular, pixels are the amount of samples on your screen, while points refers to "PostScript points" and are 1/72th of an Inch, a rounding of actual typographic American point, which is used by TeX as 1/72.27. There's a ton of variations on typographic points, but for the purposes of computer graphics, we largely use the 1/72 PostScript style points whenever we talk about Points.
Now, to convert between pixels and points, you then need to know how many pixels should go in an inch. This is what we refer to as PPI or DPI, pixels per inch or dots per inch respectively.
Now, according to the wikipedia article about typographic points, the original idea behind a point was to measure the stem-width of a glyph. So it makes sense that when choosing a standard PPI for their displays, Apple decided to use 72, as that would mean a glyph's stem would be big enough to be covered by a single pixel. Following that, at Microsoft, folks thought that was too small, a screen would be much farther away than a piece of paper on a desk. So they went with 96 dpi instead. Meaning that the pixel size is 4/3rd that of the point size.
At one point, the W3C decided to make that the official ppi for the internet, by including it in the CSS specs. There was an attempt to change this in the 2000nds when the first hidpi screens were available on smart phones, but apparantly using actual DPI didn't work out here, and it was much easier to allow for a pixel scaling factor to have x amount of design pixels map to x amount of device pixels. Which is annoying, but workable.
Except Apple doesn't follow the CSS spec. On Apple's Safari web browser, pixels are 72 ppi, meaning they're the same as points. But points are not PostScript points either. In fact, if you look at Apple's developer docs, it seems they use points to talk about design pixels.
That means that web development wise, all the absolute CSS values besides pixels are completely pointless (pun not intended, but, 'eh'), because you have no idea what the viewer is going to see at all.
This also explains why Apple-first software like the Adobe products seem to confuse points and pixels (like, PSDs storing text in points while it clearly meant to use pixels), even though you'd think this is the one place where that would not happen. I even recall a post by an Adobe engineer on their forums lamenting that they tried for years to get their user base to understand what DPI is and failing. And honestly, if those designers were all on Apple products, yeah, I'm not surprised.
SVG defaults
So, CSS typically is supposed to be applied to a whole document, and also cascade over that whole document. Unfortunately, while I can make CSS cascade over a whole text-object, Krita is not set up to handle cascading over a whole document. This means we right now have two problems:
- What is the default font-size? If whole document cascading were possible, you'd set the font size on the document css properties. However, it is not, so right now we just default to 12 pt. The best I can do here, probably, is to always save
root{font-size:12;}
in all Krita svg files so that this is resolved upon loading. - Setting a whole text-object to baseline-shift:super makes no coherent sense without a root level font that cascades in. However, arguably just setting baseline-shift:super on a whole text object makes no sense in SVG overall, as unlike HTML, absolute positioning is the normal way to use SVG objects. There's no coherent sense of what baseline-shift even does in this context, and I don't really know how I am supposed to treat it due that.
Ascender and descender
Gonna ramble on about ascender and descender a bit more:
I already mentioned that ascender and descender don't really mean much. Frequently, ascender+descender is much bigger than the em-size.

Now, traditionally, the ascender is the metric corresponding to the thing that sticks out on b
, h
, k
, which are often higher than the size of the capitals, and descender is the lower part of g
, j
and q
. Arguably that is also where the digital fonts' ascender and descender should be, especially now that we don't use bitmap-based fonts anymore, and don't need to confuse the ascender and descender with the maximum bitmap extends.
However, most Latin using languages make heavy use of diacritics, many of which hang above or below the main glyph. English is one of the few that doesn´t really need them, and unfortunately, it seems a lot of text layout styling is done by english speakers. In addition, not all software anticipates that the line-height needs to be a little bigger for those diacritics (think terminal emulators). so if you want to guarantee that diacritics will be automatically fitted, it is better to add a little bit extra ascender and descender to ensure that the diacritics will not overflow into the next or previous line.
Sample SVG
Throughout this blog I've been showing samples of text with baselines. I made these by taking the writing system samples in QFontDatabase, and then generating SVGs for those in the script specific Noto fonts, at size 12, and aligning some metrics lines to the various metrics retrieved from Harfbuzz (with fallbacks that Harfbuzz calculates based on CSS-inline-3). Then in inkscape I made all those texts into paths, turned everything into svg symbols, and finally I handedited them so all metrics are colored with CSS classes.
The QFontDatabase samples aren't the greatest as showcasing the different scripts' typographic qualities (Latin shows AaÃáZz, which, sure, shows diacritics, but AaÃábg would've shown the descenders and ascenders, and Devanagari and Tibetan would've both benefited from their conjuncts and clusters), but I can only read Latin, so this was better than trying to desperately come up with something myself. Script samples are a bit of a problem UI wise, and sometimes I wished there was a good repository for them. Technically fonts themselves have the ability to store a "preview", but this is hardly ever used.
Anyway, I'm telling you all this, because I've uploaded the SVG file so that people can play with it.
25 Apr 2025 10:33am GMT
22 Apr 2025
planet.freedesktop.org
Melissa Wen: 2025 FOSDEM: Don't let your motivation go, save time with kworkflow
2025 was my first year at FOSDEM, and I can say it was an incredible experience where I met many colleagues from Igalia who live around the world, and also many friends from the Linux display stack who are part of my daily work and contributions to DRM/KMS. In addition, I met new faces and recognized others with whom I had interacted on some online forums and we had good and long conversations.
During FOSDEM 2025 I had the opportunity to present about kworkflow in the kernel devroom. Kworkflow is a set of tools that help kernel developers with their routine tasks and it is the tool I use for my development tasks. In short, every contribution I make to the Linux kernel is assisted by kworkflow.
The goal of my presentation was to spread the word about kworkflow. I aimed to show how the suite consolidates good practices and recommendations of the kernel workflow in short commands. These commands are easily configurable and memorized for your current work setup, or for your multiple setups.
For me, Kworkflow is a tool that accommodates the needs of different agents in the Linux kernel community. Active developers and maintainers are the main target audience for kworkflow, but it is also inviting for users and user-space developers who just want to report a problem and validate a solution without needing to know every detail of the kernel development workflow.
Something I didn't emphasize during the presentation but would like to correct this flaw here is that the main author and developer of kworkflow is my colleague at Igalia, Rodrigo Siqueira. Being honest, my contributions are mostly on requesting and validating new features, fixing bugs, and sharing scripts to increase feature coverage.
So, the video and slide deck of my FOSDEM presentation are available for download here.
And, as usual, you will find in this blog post the script of this presentation and more detailed explanation of the demo presented there.
Kworkflow at FOSDEM 2025: Speaker Notes and Demo
Hi, I'm Melissa, a GPU kernel driver developer at Igalia and today I'll be giving a very inclusive talk to not let your motivation go by saving time with kworkflow.
So, you're a kernel developer, or you want to be a kernel developer, or you don't want to be a kernel developer. But you're all united by a single need: you need to validate a custom kernel with just one change, and you need to verify that it fixes or improves something in the kernel.
And that's a given change for a given distribution, or for a given device, or for a given subsystem…
Look to this diagram and try to figure out the number of subsystems and related work trees you can handle in the kernel.
So, whether you are a kernel developer or not, at some point you may come across this type of situation:
There is a userspace developer who wants to report a kernel issue and says:
- Oh, there is a problem in your driver that can only be reproduced by running this specific distribution. And the kernel developer asks:
- Oh, have you checked if this issue is still present in the latest kernel version of this branch?
But the userspace developer has never compiled and installed a custom kernel before. So they have to read a lot of tutorials and kernel documentation to create a kernel compilation and deployment script. Finally, the reporter managed to compile and deploy a custom kernel and reports:
- Sorry for the delay, this is the first time I have installed a custom kernel. I am not sure if I did it right, but the issue is still present in the kernel of the branch you pointed out.
And then, the kernel developer needs to reproduce this issue on their side, but they have never worked with this distribution, so they just created a new script, but the same script created by the reporter.
What's the problem of this situation? The problem is that you keep creating new scripts!
Every time you change distribution, change architecture, change hardware, change project - even in the same company - the development setup may change when you switch to a different project, you create another script for your new kernel development workflow!
You know, you have a lot of babies, you have a collection of "my precious scripts", like Sméagol (Lord of the Rings) with the precious ring.
Instead of creating and accumulating scripts, save yourself time with kworkflow. Here is a typical script that many of you may have. This is a Raspberry Pi 4 script and contains everything you need to memorize to compile and deploy a kernel on your Raspberry Pi 4.
With kworkflow, you only need to memorize two commands, and those commands are not specific to Raspberry Pi. They are the same commands to different architecture, kernel configuration, target device.
What is kworkflow?
Kworkflow is a collection of tools and software combined to:
- Optimize Linux kernel development workflow.
- Reduce time spent on repetitive tasks, since we are spending our lives compiling kernels.
- Standardize best practices.
- Ensure reliable data exchange across kernel workflow. For example: two people describe the same setup, but they are not seeing the same thing, kworkflow can ensure both are actually with the same kernel, modules and options enabled.
I don't know if you will get this analogy, but kworkflow is for me a megazord of scripts. You are combining all of your scripts to create a very powerful tool.
What is the main feature of kworflow?
There are many, but these are the most important for me:
- Build & deploy custom kernels across devices & distros.
- Handle cross-compilation seamlessly.
- Manage multiple architecture, settings and target devices in the same work tree.
- Organize kernel configuration files.
- Facilitate remote debugging & code inspection.
- Standardize Linux kernel patch submission guidelines. You don't need to double check documentantion neither Greg needs to tell you that you are not following Linux kernel guidelines.
- Upcoming: Interface to bookmark, apply and "reviewed-by" patches from mailing lists (lore.kernel.org).
This is the list of commands you can run with kworkflow. The first subset is to configure your tool for various situations you may face in your daily tasks.
# Manage kw and kw configurations
kw init - Initialize kw config file
kw self-update (u) - Update kw
kw config (g) - Manage kernel .config files
The second subset is to build and deploy custom kernels.
# Build & Deploy custom kernels
kw kernel-config-manager (k) - Manage kernel .config files
kw build (b) - Build kernel
kw deploy (d) - Deploy kernel image (local/remote)
kw bd - Build and deploy kernel
We have some tools to manage and interact with target machines.
# Manage and interact with target machines
kw ssh (s) - SSH support
kw remote (r) - Manage machines available via ssh
kw vm - QEMU support
To inspect and debug a kernel.
# Inspect and debug
kw device - Show basic hardware information
kw explore (e) - Explore string patterns in the work tree and git logs
kw debug - Linux kernel debug utilities
kw drm - Set of commands to work with DRM drivers
To automatize best practices for patch submission like codestyle, maintainers and the correct list of recipients and mailing lists of this change, to ensure we are sending the patch to who is interested in it.
# Automatize best practices for patch submission
kw codestyle (c) - Check code style
kw maintainers (m) - Get maintainers/mailing list
kw send-patch - Send patches via email
And the last one, the upcoming patch hub.
# Upcoming
kw patch-hub - Interact with patches (lore.kernel.org)
How can you save time with Kworkflow?
So how can you save time building and deploying a custom kernel?
First, you need a .config file.
- Without kworkflow: You may be manually extracting and managing .config files from different targets and saving them with different suffixes to link the kernel to the target device or distribution, or any descriptive suffix to help identify which is which. Or even copying and pasting from somewhere.
- With kworkflow: you can use the kernel-config-manager command, or simply
kw k
, to store, describe and retrieve a specific .config file very easily, according to your current needs.
Then you want to build the kernel:
- Without kworkflow: You are probably now memorizing a combination of commands and options.
- With kworkflow: you just need
kw b
(kw build) to build the kernel with the correct settings for cross-compilation, compilation warnings, cflags, etc. It also shows some information about the kernel, like number of modules.
Finally, to deploy the kernel in a target machine.
- Without kworkflow: You might be doing things like: SSH connecting to the remote machine, copying and removing files according to distributions and architecture, and manually updating the bootloader for the target distribution.
- With kworkflow: you just need
kw d
which does a lot of things for you, like: deploying the kernel, preparing the target machine for the new installation, listing available kernels and uninstall them, creating a tarball, rebooting the machine after deploying the kernel, etc.
You can also save time on debugging kernels locally or remotely.
- Without kworkflow: you do: ssh, manual setup and traces enablement, copy&paste logs.
- With kworkflow: more straighforward access to debug utilities: events, trace, dmesg.
You can save time on managing multiple kernel images in the same work tree.
- Without kworkflow: now you can be cloning multiple times the same repository so you don't lose compiled files when changing kernel configuration or compilation options and manually managing build and deployment scripts.
- With kworkflow: you can use
kw env
to isolate multiple contexts in the same worktree as environments, so you can keep different configurations in the same worktree and switch between them easily without losing anything from the last time you worked in a specific context.
Finally, you can save time when submitting kernel patches. In kworkflow, you can find everything you need to wrap your changes in patch format and submit them to the right list of recipients, those who can review, comment on, and accept your changes.
This is a demo that the lead developer of the kw patch-hub feature sent me. With this feature, you will be able to check out a series on a specific mailing list, bookmark those patches in the kernel for validation, and when you are satisfied with the proposed changes, you can automatically submit a reviewed-by for that whole series to the mailing list.
Demo
Now a demo of how to use kw environment to deal with different devices, architectures and distributions in the same work tree without losing compiled files, build and deploy settings, .config file, remote access configuration and other settings specific for those three devices that I have.
Setup
- Three devices:
-
laptop (debian x86 intel local) -
SteamDeck (steamos x86 amd remote) -
RaspberryPi 4 (raspbian arm64 broadcomm remote)
-
- Goal: To validate a change on DRM/VKMS using a single kernel tree.
- Kworkflow commands:
- kw env
- kw d
- kw bd
- kw device
- kw debug
- kw drm
Demo script
In the same terminal and worktree.
First target device: Laptop (debian|x86|intel|local)
$ kw env --list # list environments available in this work tree
$ kw env --use LOCAL # select the environment of local machine (laptop) to use: loading pre-compiled files, kernel and kworkflow settings.
$ kw device # show device information
$ sudo modinfo vkms # show VKMS module information before applying kernel changes.
$ <open VKMS file and change module info>
$ kw bd # compile and install kernel with the given change
$ sudo modinfo vkms # show VKMS module information after kernel changes.
$ git checkout -- drivers
Second target device: RaspberryPi 4 (raspbian|arm64|broadcomm|remote)
$ kw env --use RPI_64 # move to the environment for a different target device.
$ kw device # show device information and kernel image name
$ kw drm --gui-off-after-reboot # set the system to not load graphical layer after reboot
$ kw b # build the kernel with the VKMS change
$ kw d --reboot # deploy the custom kernel in a Raspberry Pi 4 with Raspbian 64, and reboot
$ kw s # connect with the target machine via ssh and check the kernel image name
$ exit
Third target device: SteamDeck (steamos|x86|amd|remote)
$ kw env --use STEAMDECK # move to the environment for a different target device
$ kw device # show device information
$ kw debug --dmesg --follow --history --cmd="modprobe vkms" # run a command and show the related dmesg output
$ kw debug --dmesg --follow --history --cmd="modprobe -r vkms" # run a command and show the related dmesg output
$ <add a printk with a random msg to appear on dmesg log>
$ kw bd # deploy and install custom kernel to the target device
$ kw debug --dmesg --follow --history --cmd="modprobe vkms" # run a command and show the related dmesg output after build and deploy the kernel change
Q&A
Most of the questions raised at the end of the presentation were actually suggestions and additions of new features to kworkflow.
The first participant, that is also a kernel maintainer, asked about two features: (1) automatize getting patches from patchwork (or lore) and triggering the process of building, deploying and validating them using the existing workflow, (2) bisecting support. They are both very interesting features. The first one fits well the patch-hub subproject, that is under-development, and I've actually made a similar request a couple of weeks before the talk. The second is an already existing request in kworkflow github project.
Another request was to use kexec and avoid rebooting the kernel for testing. Reviewing my presentation I realized I wasn't very clear that kworkflow doesn't support kexec. As I replied, what it does is to install the modules and you can load/unload them for validations, but for built-in parts, you need to reboot the kernel.
Another two questions: one about Android Debug Bridge (ADB) support instead of SSH and another about support to alternative ways of booting when the custom kernel ended up broken but you only have one kernel image there. Kworkflow doesn't manage it yet, but I agree this is a very useful feature for embedded devices. On Raspberry Pi 4, kworkflow mitigates this issue by preserving the distro kernel image and using config.txt file to set a custom kernel for booting. For ADB, there is no support too, and as I don't see currently users of KW working with Android, I don't think we will have this support any time soon, except if we find new volunteers and increase the pool of contributors.
The last two questions were regarding the status of b4 integration, that is under development, and other debugging features that the tool doesn't support yet.
Finally, when Andrea and I were changing turn on the stage, he suggested to add support for virtme-ng to kworkflow. So I opened an issue for tracking this feature request in the project github.
With all these questions and requests, I could see the general need for a tool that integrates the variety of kernel developer workflows, as proposed by kworflow. Also, there are still many cases to be covered by kworkflow.
Despite the high demand, this is a completely voluntary project and it is unlikely that we will be able to meet these needs given the limited resources. We will keep trying our best in the hope we can increase the pool of users and contributors too.
22 Apr 2025 7:30pm GMT
16 Apr 2025
planet.freedesktop.org
Simon Ser: Status update, April 2025
Hi!
Last week wlroots 0.19.0-rc1 has been released! It includes the new color management protocol, however it doesn't include HDR10 support because the renderer and backend bits haven't yet been merged. Also worth noting is full explicit synchronization support as well as the new screen capture protocols. I plan to release new release candidates weekly until we're happy with the stability. Please test!
Sway is also getting close to its first release candidate. I plan to publish version 1.11.0-rc1 this week-end. Thanks to Ferdinand Bachmann, Sway no longer aborts on shutdown due to dangling signal listeners. I've also updated my HDR10 patch to add an output hdr
command (but it's Sway 1.12 material).
I've spent a bit of time on libicc, my C library to manipulate ICC profiles. I've introduced an encoder to make it easy to write new ICC profiles, and used that to write a small program to create an ICC profile which inverts colors. The encoder doesn't support as many ICC elements as the decoder yet (patches welcome!), but does support many interesting bits for display profiles: basic matrices and curves, lut16Type
elements and more advanced lutAToBType
elements. New APIs have been introduced to apply ICC profile transforms to a color value. I've also added tests which compare the results given by libicc and by LittleCMS. For some reason lut16Type
and lutAToBType
results are multiplied by 2 by LittleCMS, I haven't yet understood why that is, even after reading the spec in depth and staring at LittleCMS source code for a few hours (if you have a guess please ping me). In the future I'd like to add a small tool to convert ICC profiles to and from JSON files to make it easy to create new files or adjust exist ones.
Version 0.9.0 of the soju IRC bouncer has been released. Among the most notable changes, the database is used by default to store messages, pinned/muted channels and buffers can be synchronized across devices, and database queries have been optimized. I've continued working on the Goguma mobile IRC client, fixing a few bugs such as dangling Firebase push subscriptions and message notifications being dismissed too eagerly.
Max Ehrlich has contributed a mako patch to introduce a Notifications
property to the mako-specific D-Bus API, so that external programs can monitor active notifications (e.g. display a count in a status bar, or display a list on a lockscreen).
That's all I have in store, see you next month!
16 Apr 2025 10:00pm GMT
Mike Blumenkrantz: Another Milestone
16 Apr 2025 12:00am GMT