text: ensure runereader behaves same as string

This commit fixes a subtle discrepancy in the handling of text input
within the shaper. Text provided as an io.RuneReader with a trailing
newline would generate an extra (empty) line of text, whereas the
same input provided as a string would not.

Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
This commit is contained in:
Chris Waldon
2022-12-15 08:50:02 -05:00
committed by Elias Naur
parent 2db1a7bfb9
commit bfb47538aa
2 changed files with 34 additions and 5 deletions
+7 -5
View File
@@ -223,11 +223,13 @@ func (l *Shaper) layoutText(params Parameters, minWidth, maxWidth int, lc system
}
done = endByte == len(str)
}
l.txt.append(l.layoutParagraph(params, minWidth, maxWidth, lc, str[startByte:endByte], l.paragraph))
if truncating {
params.MaxLines = maxLines - len(l.txt.lines)
if params.MaxLines == 0 {
done = true
if startByte != endByte || len(l.paragraph) > 0 {
l.txt.append(l.layoutParagraph(params, minWidth, maxWidth, lc, str[startByte:endByte], l.paragraph))
if truncating {
params.MaxLines = maxLines - len(l.txt.lines)
if params.MaxLines == 0 {
done = true
}
}
}
if done {
+27
View File
@@ -1,6 +1,7 @@
package text
import (
"strings"
"testing"
nsareg "eliasnaur.com/font/noto/sans/arabic/regular"
@@ -40,6 +41,32 @@ func TestWrappingTruncation(t *testing.T) {
}
}
// TestShapingNewlineHandling checks that the shaper's newline splitting behaves
// consistently and does not create spurious lines of text.
func TestShapingNewlineHandling(t *testing.T) {
// Use a test string containing multiple newlines to ensure that they are shaped
// as separate paragraphs.
textInput := "\n"
ltrFace, _ := opentype.Parse(goregular.TTF)
collection := []FontFace{{Face: ltrFace}}
cache := NewShaper(collection)
cache.LayoutString(Parameters{
Alignment: Middle,
PxPerEm: fixed.I(10),
}, 200, 200, english, textInput)
if lineCount := len(cache.txt.lines); lineCount > 1 {
t.Errorf("shaping string %q created %d lines", textInput, lineCount)
}
cache.Layout(Parameters{
Alignment: Middle,
PxPerEm: fixed.I(10),
}, 200, 200, english, strings.NewReader(textInput))
if lineCount := len(cache.txt.lines); lineCount > 1 {
t.Errorf("shaping reader %q created %d lines", textInput, lineCount)
}
}
// TestCacheEmptyString ensures that shaping the empty string returns a
// single synthetic glyph with ascent/descent info.
func TestCacheEmptyString(t *testing.T) {