Fix filename visibility by correcting coordinate offset in low-level drawing

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
Greg Pomerantz 2026-05-09 11:52:22 -04:00
parent 4798e8fe3d
commit 965d6074f3

View File

@ -4,7 +4,6 @@ import (
"image" "image"
"image/color" "image/color"
"gioui.org/f32"
"gioui.org/layout" "gioui.org/layout"
"gioui.org/op" "gioui.org/op"
"gioui.org/op/clip" "gioui.org/op/clip"
@ -94,29 +93,23 @@ func (r *Renderer) drawStatusBar(gtx layout.Context, sb StatusBar) {
// Truncate filename only if it doesn't fit // Truncate filename only if it doesn't fit
displayFilename := sb.Filename displayFilename := sb.Filename
//availableWidth := int(reg.W - unit.Dp(8) - unit.Dp(40)) // left margin + right icons in DP availableWidth := int(reg.W - unit.Dp(8) - unit.Dp(40)) // left margin + right icons in DP
// Layout ellipsis once and get its width // Layout ellipsis once and get its width
//th.Shaper.LayoutString(text.Parameters{PxPerEm: fixed.I(gtx.Sp(r.theme.FontSize))}, "...") th.Shaper.LayoutString(text.Parameters{PxPerEm: fixed.I(gtx.Sp(r.theme.FontSize))}, "...")
//var ellipsisWidths []int var ellipsisWidth int
//for { for {
// g, ok := th.Shaper.NextGlyph() g, ok := th.Shaper.NextGlyph()
// if !ok { if !ok {
// break break
// } }
// if len(ellipsisWidths) == 0 { ellipsisWidth = int((g.X + g.Advance) >> 6)
// ellipsisWidths = append(ellipsisWidths, int(g.Advance>>6)) }
// } else {
// ellipsisWidths = append(ellipsisWidths, ellipsisWidths[len(ellipsisWidths)-1]+int(g.Advance>>6))
// }
//}
//ellipsisWidth := ellipsisWidths[len(ellipsisWidths)-1]
// Measure how wide "..." is, then find how many chars fit in availableWidth - ellipsisWidth // Measure how wide "..." is, then find how many chars fit in availableWidth - ellipsisWidth
//spaceForText := availableWidth - ellipsisWidth spaceForText := availableWidth - ellipsisWidth
// Layout filename, measure widths, and draw in a single pass // Layout filename, measure widths, and draw in a single pass
//r.drawTruncatedText(gtx, th.Shaper, displayFilename, r.theme.FontSize, reg.X+unit.Dp(8), filenameLineY, availableWidth, spaceForText, color.NRGBA{R: 0, G: 0, B: 0, A: 255}) r.drawTruncatedText(gtx, th.Shaper, displayFilename, r.theme.FontSize, reg.X+unit.Dp(8), filenameLineY, availableWidth, spaceForText, color.NRGBA{R: 0, G: 0, B: 0, A: 255})
r.drawText(gtx, th.Shaper, displayFilename, r.theme.FontSize, reg.X+unit.Dp(8), filenameLineY, color.NRGBA{R: 0, G: 0, B: 0, A: 255})
// Line 2: Icons // Line 2: Icons
iconsLineY := filenameLineY + filenameLineH iconsLineY := filenameLineY + filenameLineH
@ -250,34 +243,26 @@ func (r *Renderer) drawLineText(gtx layout.Context, shp *text.Shaper, x, y unit.
m := op.Record(gtx.Ops) m := op.Record(gtx.Ops)
var glyphs [32]text.Glyph var glyphs [32]text.Glyph
line := glyphs[:0] line := glyphs[:0]
var firstGlyph text.Glyph
first := true
for g, ok := shp.NextGlyph(); ok; g, ok = shp.NextGlyph() { for g, ok := shp.NextGlyph(); ok; g, ok = shp.NextGlyph() {
if first {
firstGlyph = g
first = false
}
line = append(line, g) line = append(line, g)
if g.Flags&text.FlagLineBreak != 0 || cap(line)-len(line) == 0 { if g.Flags&text.FlagLineBreak != 0 || cap(line)-len(line) == 0 {
r.drawLine(gtx, shp, line, firstGlyph, x, y, col) r.drawLine(gtx, shp, line, x, y, col)
line = line[:0] line = line[:0]
} }
} }
if len(line) > 0 { if len(line) > 0 {
r.drawLine(gtx, shp, line, firstGlyph, x, y, col) r.drawLine(gtx, shp, line, x, y, col)
} }
call := m.Stop() call := m.Stop()
call.Add(gtx.Ops) call.Add(gtx.Ops)
} }
// drawLine draws a line of glyphs using shaper.Shape() and shaper.Bitmaps(). // drawLine draws a line of glyphs using shaper.Shape() and shaper.Bitmaps().
func (r *Renderer) drawLine(gtx layout.Context, shp *text.Shaper, line []text.Glyph, firstGlyph text.Glyph, x, y unit.Dp, col color.NRGBA) { func (r *Renderer) drawLine(gtx layout.Context, shp *text.Shaper, line []text.Glyph, x, y unit.Dp, col color.NRGBA) {
// Derive offset from first glyph position + desired position // Offset coordinate system to (x, y).
// Gio's textView: lineOff = glyphPos - viewportMin // The shaper's glyph positions (g.X, g.Y) are absolute within the text block.
// We want: offset = (x, y) - firstGlyphPos // g.Y for the first line is the ascent, so the top of the text will be at y.
firstPos := f32.Point{X: float32(firstGlyph.X) / 64.0, Y: float32(firstGlyph.Y)} t := op.Offset(image.Pt(gtx.Dp(x), gtx.Dp(y))).Push(gtx.Ops)
off := f32.Point{X: float32(x), Y: float32(y)}.Sub(firstPos)
t := op.Affine(f32.Affine2D{}.Offset(off)).Push(gtx.Ops)
// Draw vector glyphs // Draw vector glyphs
path := shp.Shape(line) path := shp.Shape(line)