Skip to content

Commit

Permalink
[shaping] cleanup and adjust tests
Browse files Browse the repository at this point in the history
  • Loading branch information
benoitkugler committed Nov 1, 2023
1 parent f491679 commit d06f064
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 58 deletions.
4 changes: 2 additions & 2 deletions shaping/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ func (o *Output) RecomputeAdvance() {
}

// advanceSpaceAware adjust the value in [Advance]
// if a white space character end the run.
// TODO: should be take into account multiple spaces ?
// if a white space character ends the run.
// TODO: should we take into account multiple spaces ?
func (o *Output) advanceSpaceAware() fixed.Int26_6 {
L := len(o.Glyphs)
if L == 0 {
Expand Down
93 changes: 52 additions & 41 deletions shaping/wrapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,55 @@ type lineConfig struct {
truncatedMaxWidth int
}

func (l *LineWrapper) postProcessLine(finalLine Line, done bool) (Line, int, bool) {
if len(finalLine) > 0 {
finalRun := finalLine[len(finalLine)-1]

// zero trailing whitespace advance,
// to be coherent with Output.advanceSpaceAware
if L := len(finalRun.Glyphs); L != 0 {
if finalRun.Direction.IsVertical() {
if g := &finalRun.Glyphs[L-1]; g.Height == 0 {
g.YAdvance = 0
}
} else { // horizontal
if g := finalRun.Glyphs[L-1]; g.Width == 0 {
g.XAdvance = 0
}
}
finalRun.RecomputeAdvance()
}

// Update the start position of the next line.
l.lineStartRune = finalRun.Runes.Count + finalRun.Runes.Offset
}

// Check whether we've exhausted the text.
done = done || l.lineStartRune >= l.breaker.totalRunes

// Implement truncation if needed.
truncated := 0
if l.truncating {
l.config.TruncateAfterLines--
insertTruncator := false
if l.config.TruncateAfterLines == 0 {
done = true
truncated = l.breaker.totalRunes - l.lineStartRune
insertTruncator = truncated > 0 || l.config.TextContinues
}
if insertTruncator {
finalLine = append(finalLine, l.config.Truncator)
}
}

// Mark the paragraph as complete if needed.
if done {
l.more = false
}

return finalLine, truncated, done
}

// WrapNextLine wraps the shaped glyphs of a paragraph to a particular max width.
// It is meant to be called iteratively to wrap each line, allowing lines to
// be wrapped to different widths within the same paragraph. When done is true,
Expand All @@ -828,49 +877,11 @@ func (l *LineWrapper) WrapNextLine(maxWidth int) (finalLine Line, truncated int,
if !l.more {
return nil, 0, true
}
defer func() {
if len(finalLine) > 0 {
finalRun := finalLine[len(finalLine)-1]

// Zero trailing whitespace advance, to make room for the truncator
if L := len(finalRun.Glyphs); l.truncating && L != 0 {
if finalRun.Direction.IsVertical() {
if g := &finalRun.Glyphs[L-1]; g.Height == 0 {
g.YAdvance = 0
}
} else { // horizontal
if g := finalRun.Glyphs[L-1]; g.Width == 0 {
g.XAdvance = 0
}
}
finalRun.RecomputeAdvance()
}

// Update the start position of the next line.
l.lineStartRune = finalRun.Runes.Count + finalRun.Runes.Offset

}

// Check whether we've exhausted the text.
done = done || l.lineStartRune >= l.breaker.totalRunes
// Implement truncation if needed.
if l.truncating {
l.config.TruncateAfterLines--
insertTruncator := false
if l.config.TruncateAfterLines == 0 {
done = true
truncated = l.breaker.totalRunes - l.lineStartRune
insertTruncator = truncated > 0 || l.config.TextContinues
}
if insertTruncator {
finalLine = append(finalLine, l.config.Truncator)
}
}
// Mark the paragraph as complete if needed.
if done {
l.more = false
}
defer func() {
finalLine, truncated, done = l.postProcessLine(finalLine, done)
}()

// If the iterator is empty, return early.
_, firstRun, hasFirst := l.glyphRuns.Peek()
if !hasFirst {
Expand Down
30 changes: 15 additions & 15 deletions shaping/wrapping_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2772,14 +2772,14 @@ func TestLineWrapperBreakSpecific(t *testing.T) {
{
name: "Always-Truncate",
config: WrapConfig{BreakPolicy: Always, TruncateAfterLines: 1},
runeCounts: []int{6},
truncatedCount: 6,
runeCounts: []int{7},
truncatedCount: 5,
},
{
name: "Never-Truncate",
config: WrapConfig{BreakPolicy: Never, TruncateAfterLines: 1},
runeCounts: []int{},
truncatedCount: 12,
runeCounts: []int{7},
truncatedCount: 5,
},
},
},
Expand All @@ -2790,24 +2790,24 @@ func TestLineWrapperBreakSpecific(t *testing.T) {
{
name: "WhenNecessary",
config: WrapConfig{BreakPolicy: WhenNecessary},
runeCounts: []int{6, 6},
runeCounts: []int{7, 5},
},
{
name: "WhenNecessary-Truncate",
config: WrapConfig{BreakPolicy: WhenNecessary, TruncateAfterLines: 1},
runeCounts: []int{6},
truncatedCount: 6,
runeCounts: []int{7},
truncatedCount: 5,
},
{
name: "Always",
config: WrapConfig{BreakPolicy: Always},
runeCounts: []int{6, 6},
runeCounts: []int{7, 5},
},
{
name: "Always-Truncate",
config: WrapConfig{BreakPolicy: Always, TruncateAfterLines: 1},
runeCounts: []int{6},
truncatedCount: 6,
runeCounts: []int{7},
truncatedCount: 5,
},
{
name: "Never",
Expand All @@ -2817,8 +2817,8 @@ func TestLineWrapperBreakSpecific(t *testing.T) {
{
name: "Never-Truncate",
config: WrapConfig{BreakPolicy: Never, TruncateAfterLines: 1},
runeCounts: []int{},
truncatedCount: 12,
runeCounts: []int{7},
truncatedCount: 5,
},
},
},
Expand Down Expand Up @@ -2886,12 +2886,12 @@ func TestLineWrapperBreakSpecific(t *testing.T) {
{
name: "WhenNecessary",
config: WrapConfig{BreakPolicy: WhenNecessary},
runeCounts: []int{1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1},
runeCounts: []int{1, 1, 2, 1, 2, 1, 1, 1, 1, 1},
},
{
name: "Always",
config: WrapConfig{BreakPolicy: Always},
runeCounts: []int{1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1},
runeCounts: []int{1, 1, 2, 1, 2, 1, 1, 1, 1, 1},
},
{
name: "Never",
Expand Down Expand Up @@ -3209,7 +3209,7 @@ var regressionRuns = []Output{
},
}

func TestSpace(t *testing.T) {
func TestTrailingSpace(t *testing.T) {
// assume single run, 1 to 1 rune <-> glyph mapping
shapedText := func(text []rune, line Line) string {
tu.Assert(t, len(line) == 1)
Expand Down

0 comments on commit d06f064

Please sign in to comment.