Closed nununoisy closed 6 months ago
Yes, I think that makes sense. I'd start with stroke
and stroke-width
first, and leave out stroke-style
for a second step.
Implementation wise, it might be worth adding a TextWithOutline
or TextWithStroke
in builtins.slint
so that regular Text
elements don't pay the price of the additional properties.
Regarding the software renderer, yeah, I think swash is the way to go. Perhaps this could also be done separately, i.e. stroke
first for the other renderers, then we worry about swash, and then implement it for the software renderer - i.e. separate PRs.
Olivier, what do yo think?
Right. I've already begun implementing this according to the earlier spec and I have functioning implementations with support for stroke styles working on FemtoVG, Skia, and Qt. Besides an extra if
statement, they don't incur any additional overhead if stroking is disabled. Right now I'm checking the stroke width to see if it's non-zero, but it might make more sense to instead check the stroke brush to see if it's transparent
so that a zero stroke width can correspond to a hairline stroke.
Is there any particular reason you want to push out stroke-style
to a next step? It's not complicated at all to implement, but I could see the syntax being undesirable. Perhaps it could make more sense to generalize the TextStrokeStyle
struct so we can extend the syntax to Rectangle
s and Path
s also by implementing outside strokes for those elements. In fact, it would be nice also to be able to control other aspects of the stroke, like the cap, bevels, miter limit, etc.; that's probably in the territory of a separate issue.
Along those lines, in the meantime, should it be a center or outside stroke? Center strokes are the default in most illustration programs, but outside strokes are much more popular in UI design because they don't mess up the proportions of the font. In fact, there are CSS properties for center text strokes, but most web designers prefer to use box-shadows in a hacky way because it's the only way to get outside strokes.
Is there any particular reason you want to push out stroke-style to a next step?
I was just thinking in terms of complexity, but if you’re confident about it then no problem.
I would also lean to outside stroke as default for text.
Text strokes are super useful for boosting text contrast in certain situations, especially when drawing on dynamic content. It doesn't seem like it would be that hard to add them since some of the rendering backends already support them:
PaintStyle::Stroke
style set on the foreground paintfemtovg
: draw the text withCanvas::stroke_text()
The only difficulty here would be the software renderer:
fontdue
doesn't support stroking at all, and it doesn't seem like that support is coming anytime soon. However, it's been mentioned in #3742 thatswash
is being considered as an alternative;swash
also supports text stroking with theswash::zeno::Stroke
style.For those reasons, I think it makes sense to just leave text stroking unsupported in the software renderer for now.
As for the markup, we could borrow the syntax from the stroke properties for
Rectangle
:stroke
(in brush)stroke-width
(in length)In addition, by varying the draw order, we could also allow the selection of outline styles/insets:
stroke-style
(inTextStrokeStyle
)TextStrokeStyle.outside
: inside edge of stroke is at the outer edge of the text. (blit outline at double width, blit fill)TextStrokeStyle.center
: centerline of stroke is at the outer edge of the text, like in Adobe Illustrator. (blit fill, blit outline)If this syntax is acceptable, I'd be happy to author a PR to get this support in.