Compare commits

..

No commits in common. "main" and "v0.8.0" have entirely different histories.
main ... v0.8.0

3 changed files with 27 additions and 51 deletions

View File

@ -5,4 +5,4 @@
Typeset provides utilities for text layout, wrapping, and rendering.
The state of a text layout is stored in a TypeSetter, and it can be drawn to any
draw.Image using a Drawer which "extends" TypeSetter.
image.Image using a Drawer which "extends" TypeSetter.

View File

@ -116,10 +116,12 @@ type LineLayout struct {
func DoLine (text []rune, face font.Face, wrap bool, width fixed.Int26_6) (line LineLayout, remaining []rune) {
remaining = text
x := fixed.Int26_6(0)
lastWord := WordLayout { }
isFirstWord := true
for {
// process one word
word, remainingFromWord := DoWord(remaining, face)
word.X = x
x += word.Width
// if we have gone over the preferred width, stop processing
@ -133,6 +135,7 @@ func DoLine (text []rune, face font.Face, wrap bool, width fixed.Int26_6) (line
// if the word actually has contents, add it
if word.Runes != nil {
lastWord = word
line.Words = append(line.Words, word)
}
@ -148,12 +151,9 @@ func DoLine (text []rune, face font.Face, wrap bool, width fixed.Int26_6) (line
}
// set the width of the line's content.
line.ContentWidth = lastWord.X + lastWord.Width
line.Width = width
if len(line.Words) > 0 {
lastWord := line.Words[len(line.Words) - 1]
line.ContentWidth = x - lastWord.SpaceAfter
line.SpaceAfter = lastWord.SpaceAfter
}
line.SpaceAfter = lastWord.SpaceAfter
return
}
@ -170,45 +170,30 @@ func (line *LineLayout) Length () int {
// Align aligns the text in the line according to the specified alignment
// method.
func (line *LineLayout) Align (align Align, tabWidth fixed.Int26_6) {
func (line *LineLayout) Align (align Align) {
if len(line.Words) == 0 { return }
if align == AlignEven {
line.justify(tabWidth)
} else {
line.contract(tabWidth)
var leftOffset fixed.Int26_6
if align == AlignMiddle {
leftOffset = (line.Width - line.ContentWidth) / 2
} else if align == AlignEnd {
leftOffset = line.Width - line.ContentWidth
}
line.justify()
return
}
for index := range line.Words {
line.Words[index].X += leftOffset
}
leftOffset := -line.Words[0].X
if align == AlignMiddle {
leftOffset += (line.Width - line.ContentWidth) / 2
} else if align == AlignEnd {
leftOffset += line.Width - line.ContentWidth
}
for index := range line.Words {
line.Words[index].X += leftOffset
}
}
// assume line has content > 0
func (line *LineLayout) contract (tabWidth fixed.Int26_6) {
x := fixed.Int26_6(0)
for index, word := range line.Words {
word.X = x
x += word.Width
x += word.SpaceAfter
line.Words[index] = word
}
lastWord := line.Words[len(line.Words) - 1]
line.ContentWidth = lastWord.X + lastWord.Width
line.SpaceAfter = lastWord.SpaceAfter
}
// assume line has content > 0
func (line *LineLayout) justify (tabWidth fixed.Int26_6) {
if len(line.Words) <= 1 {
line.Align(AlignStart, tabWidth)
func (line *LineLayout) justify () {
if len(line.Words) < 2 {
line.Align(AlignStart)
return
}

View File

@ -18,7 +18,6 @@ type TypeSetter struct {
face font.Face
width, height int
wrap bool
tabWidth fixed.Int26_6
minWidth fixed.Int26_6
layoutBounds image.Rectangle
@ -118,7 +117,7 @@ func (setter *TypeSetter) alignHorizontally () {
}
// align line
setter.lines[index].Align(align, setter.tabWidth)
setter.lines[index].Align(align)
}
}
@ -216,14 +215,6 @@ func (setter *TypeSetter) SetHeight (heignt int) {
setter.height = heignt
}
// SetTabWidth sets the distance between tab stops.
func (setter *TypeSetter) SetTabWidth (tabWidth fixed.Int26_6) {
if setter.tabWidth == tabWidth { return }
setter.layoutClean = false
setter.alignClean = false
setter.tabWidth = tabWidth
}
// Em returns the width of one emspace according to the typesetter's font, which
// is the width of the capital letter 'M'.
func (setter *TypeSetter) Em () (width fixed.Int26_6) {
@ -395,10 +386,10 @@ func (setter *TypeSetter) MinimumSize () image.Point {
return image.Pt(width.Round(), height.Round())
}
// RecommendedHeight returns the reccomended max height if the text were to have
// its maximum width set to the given width. This does not alter the
// ReccomendedHeightFor returns the reccomended max height if the text were to
// have its maximum width set to the given width. This does not alter the
// typesetter's state.
func (setter *TypeSetter) RecommendedHeight (width int) (height int) {
func (setter *TypeSetter) ReccomendedHeightFor (width int) (height int) {
setter.needLayout()
if setter.lines == nil { return }