text: handle shaping string containing only newline

This commit ensures that we properly handle the case in which an input string is only
a newline character. We now make a run of text by shaping a space rune and then
drop the glyph/rune data from the space (keeping the line height and such).
The prior behavior would shape zero runes, resulting in no output runs, and thus our
logic for synthesizing a glyph for the newline would never execute while iterating the
runs.

I tried to restructure to instead catch whether there were zero runs after the iteration,
but it came out much uglier and harder to understand that way.

Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
This commit is contained in:
Chris Waldon
2023-07-20 14:46:49 -04:00
committed by Elias Naur
parent d62057a62e
commit 36a39f7d38
+13
View File
@@ -525,10 +525,23 @@ func calculateYOffsets(lines []line) {
// LayoutRunes shapes and wraps the text, and returns the result in Gio's shaped text format.
func (s *shaperImpl) LayoutRunes(params Parameters, txt []rune) document {
hasNewline := len(txt) > 0 && txt[len(txt)-1] == '\n'
justNewline := false
if hasNewline {
txt = txt[:len(txt)-1]
if len(txt) == 0 {
// If we only have a newline, shape a space to get line metrics.
txt = []rune{' '}
justNewline = true
}
}
ls, truncated := s.shapeAndWrapText(params, replaceControlCharacters(txt))
if justNewline {
// We shaped a space to get proper line metrics, but we need to drop
// the rune/glyph info since it isn't actually part of the text.
ls[0][0].Glyphs = ls[0][0].Glyphs[:0]
ls[0][0].Runes.Count = 0
ls[0][0].Advance = 0
}
didTruncate := truncated > 0 || (params.forceTruncate && params.MaxLines == len(ls))