Fix font baseline issue

main v1.0.3
Trevor Slocum 2023-06-08 20:26:48 -07:00
parent 3fb1571641
commit c6af3330a7
1 changed files with 42 additions and 32 deletions

View File

@ -86,6 +86,9 @@ type TextField struct {
// overrideLineHeight is the custom height for a line of text, or 0 to disable.
overrideLineHeight int
// lineOffset is the offset of the baseline current font.
lineOffset int
// textColor is the color of the text within the field.
textColor color.Color
@ -151,7 +154,7 @@ func NewTextField(face font.Face) *TextField {
scrollAutoHide: true,
visible: true,
}
f.setDefaultLineHeight()
f.fontUpdated()
return f
}
@ -298,7 +301,7 @@ func (f *TextField) SetFont(face font.Face) {
defer f.Unlock()
f.face = face
f.setDefaultLineHeight()
f.fontUpdated()
}
// Padding returns the amount of padding around the text within the field.
@ -510,9 +513,10 @@ func (f *TextField) Draw(screen *ebiten.Image) {
screen.DrawImage(f.img, op)
}
func (f *TextField) setDefaultLineHeight() {
lineBounds := text.BoundString(f.face, "ATZgpq.")
f.lineHeight = lineBounds.Dy() + 5
func (f *TextField) fontUpdated() {
m := f.face.Metrics()
f.lineHeight = m.Height.Round()
f.lineOffset = m.Ascent.Round()
}
func (f *TextField) wrapContent(withScrollBar bool) {
@ -542,6 +546,7 @@ func (f *TextField) wrapContent(withScrollBar bool) {
}
l := len(line)
availableWidth := w - (f.padding * 2)
var start int
var end int
var initialEnd int
@ -550,29 +555,29 @@ func (f *TextField) wrapContent(withScrollBar bool) {
initialEnd = end
bounds := text.BoundString(f.face, line[start:end])
if bounds.Dx() <= w-(f.padding*2) {
if f.wordWrap {
if end < l && !unicode.IsSpace(rune(line[end])) {
for endOffset := 0; endOffset < end-start; endOffset++ {
if unicode.IsSpace(rune(line[end-endOffset])) {
end = end - endOffset
if end < l-1 {
end++
}
break
}
if bounds.Dx() > availableWidth {
continue
}
if f.wordWrap && end < l && !unicode.IsSpace(rune(line[end])) {
for endOffset := 0; endOffset < end-start; endOffset++ {
if unicode.IsSpace(rune(line[end-endOffset])) {
end = end - endOffset
if end < l-1 {
end++
}
break
}
}
if end != initialEnd && f.horizontal != AlignStart {
bounds = text.BoundString(f.face, line[start:end])
}
f.bufferWrapped = append(f.bufferWrapped, line[start:end])
f.lineWidths = append(f.lineWidths, bounds.Dx())
break
}
if end != initialEnd && f.horizontal != AlignStart {
bounds = text.BoundString(f.face, line[start:end])
}
f.bufferWrapped = append(f.bufferWrapped, line[start:end])
f.lineWidths = append(f.lineWidths, bounds.Dx())
break
}
start = end
}
@ -595,22 +600,23 @@ func (f *TextField) drawContent() (overflow bool) {
if lineHeight == 0 {
lineHeight = f.lineHeight
}
lineOffset := lineHeight / 3
f.bufferSize = 0
for i, line := range f.bufferWrapped {
lineX := f.padding
lineY := f.padding
lineY += lineHeight*(i+1) - lineOffset
lineY := f.lineOffset + lineHeight*i
// Calculate buffer size (width or height).
if f.singleLine {
bounds := text.BoundString(f.face, line)
f.bufferSize = bounds.Dx() + f.padding*4
f.bufferSize = bounds.Dx() + f.padding*2
} else {
f.bufferSize = lineY + lineOffset + f.padding
f.bufferSize = lineY + f.padding*2
}
if lineY < 0 || lineY >= h-(f.padding*2) {
// Calculate whether the line overflows the visible area.
lineOverflows := lineY < 0 || lineY >= h-(f.padding*2)
if lineOverflows {
overflow = true
}
@ -619,24 +625,28 @@ func (f *TextField) drawContent() (overflow bool) {
continue
}
// Apply scrolling transformation.
if f.singleLine {
lineX -= f.offset
} else {
lineY -= f.offset
}
// Align horizontally.
if f.horizontal == AlignCenter {
lineX = (fieldWidth - f.lineWidths[i]) / 2
} else if f.horizontal == AlignEnd {
lineX = (fieldWidth - f.lineWidths[i]) - f.padding*2
}
// Align vertically.
if f.vertical == AlignCenter && lineHeight*lines <= h {
lineY = (fieldHeight-(lineHeight*lines))/2 + lineHeight*(i+1) - lineOffset
lineY = (fieldHeight-(lineHeight*lines))/2 + lineHeight*(i+1) - f.lineOffset
} else if f.vertical == AlignEnd && lineHeight*lines <= h {
lineY = (fieldHeight - lineHeight*i) - f.padding*2
}
// Draw line.
text.Draw(f.img, line, f.face, lineX, lineY, f.textColor)
}