The join corners are drawn with: the element's outline, or the selected text's when the rich text
editor has focus.
It used to be one value for both, and the comment here used to explain why — a run carried no
join of its own, so the frame's border join served its glyphs as well. Text now has its own, at
both levels, so this follows the same selection-first, frame-second rule setStrokeAlignment does:
a selection writes stroke_join onto the runs it covers, a bare caret writes the frame's
text_stroke_join, and only outside the text editor does this touch the border's line_join.
A frame whose text_stroke_join is null still follows its border, which is what every document
written before the field does — so nothing changes for text nobody has given a join to.
The canvas reads the join at draw time, which is why a redraw is enough and no relayout is needed.
The join corners are drawn with: the element's outline, or the selected text's when the rich text editor has focus.
It used to be one value for both, and the comment here used to explain why — a run carried no join of its own, so the frame's border join served its glyphs as well. Text now has its own, at both levels, so this follows the same selection-first, frame-second rule setStrokeAlignment does: a selection writes stroke_join onto the runs it covers, a bare caret writes the frame's text_stroke_join, and only outside the text editor does this touch the border's line_join.
A frame whose text_stroke_join is null still follows its border, which is what every document written before the field does — so nothing changes for text nobody has given a join to.
The canvas reads the join at draw time, which is why a redraw is enough and no relayout is needed.