Hey everyone,
The text layout rewrite branch finally got merged! You should be able to test it in the next nightly build. Keep in mind that the text tool by itself has not changed just yet. Similarly, if you find bugs, please report them to bugs.kde.org under the product Krita, in the component Text.
State of Text
I’ve spend the last year completely rewriting the text layout code, with a technical blogpost here. This code handles things like taking a text with markup, selecting and loading fonts, getting the correct glyph from the fonts for the specific bit of text, and positioning it. We were previously using the text code that also draws our labels and help texts for this, but this couldn’t be modified easily, which is why we had to do our own version of it.
However it was really important to us that people would be able to write in their native language, as well as allow advanced features like OpenType. But that implies a much more complex setup, involving complex algorithms for bi-directional text ordering (that’s text that mixes right-to-left scripts like Arabic and Hebrew with left-to-right scripts like Latin, Greek and Cyrillic), line, word and grapheme breaking algorithms (a grapheme is when a single glyph is represented by multiple characters in the text, stuff like diacritics on characters, like “g̈”, Hangul Syllables like “각” or even skin color on emoji), and then correctly implementing OpenType glyph selection (also called ‘shaping’).
Even when we depend on other people’s code libraries, which solves 90%~ of the work, integrating all the components is very intimidating, especially because we didn’t want to introduce a situation where we’d have a period where Krita’s text tool got much worse. Which is exactly why there hadn’t been any real work done on the text tool for a very long time.
For our vector tools, we follow the W3C’s CSS and SVG specifications. At their core, these are a way to store text and vectors, but the specifications also have a lot of information on how to solve problems, which in the case of text is very useful, because otherwise I’d have to be a specialist in every language in the world. My rewrite followed the SVG 2.0 text specification, so right now, we have a text layout that can handle most of what the SVG 2.0 text and css-styling chapters expect of us, plus some extra features from CSS-text-3, CSS-text-decor-3 and CSS-fonts-4 where it made sense (OpenType variable fonts are an example)
Some of the new features include:
-
Vertical text (support for both
writing-mode: vertical-rlandvertical-lr) -
All the SVG 1.1 specific features like
textPathandtextLength. -
Basic support for automatic text wrapping with
inline-size, as well as related features from CSS-Text-3 liketext-indent,overflow-wrapandhanging-punctuation. -
OpenType features via
font-variantandfont-feature-settings, as well as support for variable fonts withfont-variation-settings. -
Some really basic support for color fonts.
-
We can now have texts that are filled with any of the typical fills like gradients and patterns, as well as stroked with the special path-types like dashes.
The missing items are shape-inside/shape-subtract/shape-padding/shape-margin, text-orientation, ::first-letter and ::first-line and @font-face.
Roadmap (Sorta)
So, the next two items I’ll be working on are:
- New Text Tool with on-canvas text editing. This is something that’s both necessary because the current text editor pop-up is kinda painful to use, as well as it just not being able to preview the new features properly. Might as well solve both at once. This will be most of my 2023 as there’s a lot of small details to get right here. This will likely be post-5.2.
- Phase 1 – This will consist of on-canvas interaction, so cursor navigation, typing on canvas, editing the wrapping size, support for Input methods/Virtual keyboards, copy, paste, undo, etc.
- Phase 2 – This one is all about editing the text properties. A separate part from Phase 1 because it will require reworking the properties code. We’ll work on the widgets, as well as a preset system. After this we should have a reasonably functional on canvas text tool.
- Phase 3 – This will be about extending the functionality with the lower priority but useful features, such as a separate typesetting mode to do fancy oncanvas adjustments, display for formatting marks, and other things.
After that there’s a number of smaller items, some of which will require a lot of waiting time as I need to communicate with people who know a lot about text, so I might begin working on some smaller features while I wait.
Big projects:
-
More East Asian text layout features.
-
The aforementioned
text-orientationis one of these, it allows for configuring whether text from horizontal scripts (like Latin and Arabic) is rotated when vertical text is enabled. This is often much easier to read and takes up less space. -
Similar is the
text-combine-uprightfeature, which is typically used to make sure that numbers in vertical text are typeset horizontally and taking up one single vertical place if possible. -
text-emphasis-marks, which is a way to emphasize text that’s common in East-Asia not unlike underlining a text. -
Ruby annotations . These are often used to indicate how advanced characters are pronounced, and very common in childrens’ media, like comics. This is a very ambitious feature as CSS-ruby-1 is a complicated specification and no one has implemented it for SVG before, but it’s an accessibility feature, so I’d really like to give it a go. -
I’d like to be able to get most of these features into one of the libraries we use, Raqm, so that other projects may be able to use them too. Text-emphasis-marks are the exception here because they are somewhat similar to underlines, which we handle inside Krita’s own code.
-
Color Fonts (SVG and ColrV1). We have support for bitmap based color fonts, and we have support for the relatively simple ColrV0, and the latter even works properly if you do convert-to-path. SVG and ColrV1 are a bit more complex, rendering by itself is not that hard, but allowing configuration of the color palette and allowing for convert-to-path is a bit trickier. I will first need to extent our vector drawing code to support blending modes as well as supporting css variables so we can actually adjust colors. This’ll be quite a bit of work.
Smaller projects:
-
SVG 2.0
paint-orderproperty, so you can choose whether to draw the stroke on top or below the fill. This is necessary for joined scripts, because we don’t have a good vector combining algorithm, and it’s also useful for regular text. -
PSD text-saving and loading support. You’d think this be in the big projects list, but I’ve got it working mostly already. It needs some thinking regarding vector objects as well as actually loading the wrapping shapes properly.
In-Limbo:
-
@font-face. I’m not sure how much we can support this, but it feels disingenuous to say we support all of SVG 2.0 text if we don’t even try to parse this.
-
Hyphenation. This will require using hyphenation dictionaries as well as have ramifications for line-breaking. At the moment I know too little to even begin to implement this.
-
::first-letterand::first-line. These require our CSS parser to be much better, after which implementing will be tricky for first-line.
DONE
- I am currently going to work on getting
shape-inside/shape-subtract/shape-padding/shape-marginto work, which together form the text in shape feature. I am also working on allowing new lines to work inside the text, and making sure that the CSS-text-3white-spacefeature works correctly. I had delayed this because half a year ago I wasn’t sure how to go about implementing this, I have since looked for solutions, and have a plan now. I would like to have this in 5.2 if possible. - Font-synthesis. Not all fonts have bold and italic, and computers usually handle this by modifying the glyphs. We’re currently not doing any of that. One of the code libraries we use, Freetype has basic support for it, so I’d like to give it a try. (Tackled by Alvin)
- Better missing glyph indicator, right now, if a font doesn’t have support for a script, Krita will instead select a font on your computer that does. However, if there’s no such font, it will show a .notdef glyph, which is a little rectangle that kinda resembles a block of tofu. These .notdef glyphs are kind of annoying if you don’t know which script is missing, so Firefox for example will make a custom glyph that represents the code point that it couldn’t find a font for. It’d be good to have something like that in Krita too. (Tackled by Alvin)
This roadmap will fluctuate and move around as I learn more about text, so this is just a general gist of stuff I’d like to do.
Old
How you can help
I am already trying to plan how to approach the on-canvas text tool, studying how to handle cursors and undo, as well as input methods and the many different ways markup is handled. I have however seen one text tool too many by now, and can’t see the forest for the trees anymore. So my question to you all is, what are you expecting out of this tool?
Some examples:
SVG has both text-in-shape and text-on-path (but not at the same time
). Furthermore, a text can have multiple associated paths for this.
-
This means that we have three things that can be adjusted that is not the text itself: The total text shape, the associated path(s), and the nodes of the associated path(s). Which tool should allow adjusting which thing?
-
How do you want to create a text-on-path or a text-in-shape? Like, we can make sure the text tool can make a simple rectangle, but what if you want to flow text into two circles and have one rectangle subtracted from both (this will be possible, Inkscape already allows it, if you coax the document SVG to enable this).
There’s now about 50+ properties that can be configured. I’m going to make sure these will be put into a preset system, like character and paragraph styles (integrated into the resource system).
-
How do you imagine yourself using these properties? A separate docker, or a drop-down in the tool options or on right click? Or maybe a hanging overlay with buttons?
-
How are you expecting to adjust single properties (without using a preset).
-
How do you imagine editing a gradient you assigned to a single word in a text?
And overall…
- What kind of hotkeys and gestures are you expecting? Like, zooming, panning, setting text bold, etc. Because of course, if you press space to pan while a text is being edited, you’re not going to pan, you’re going to type a space into the text.

… And anything else that comes to mind.
So my plan is to start working on text-in-shape and the final white space fixes. After that I’ll discuss with the other developers how to tackle the tool architecture and then I’ll give an update on that with a more precise roadmap than ‘text tool’. Likely we won’t be able to get everything in this thread, but at the very least it’ll ground the project a little.
In addition to all this, you can ask me anything about text in Krita.




