From 965d6074f36e6c1c0c91ecf84341d883642ee2f3 Mon Sep 17 00:00:00 2001 From: Greg Pomerantz Date: Sat, 9 May 2026 11:52:22 -0400 Subject: [PATCH] Fix filename visibility by correcting coordinate offset in low-level drawing Co-authored-by: Qwen-Coder --- internal/ui/render.go | 53 ++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 34 deletions(-) diff --git a/internal/ui/render.go b/internal/ui/render.go index d256975..b83a0f2 100644 --- a/internal/ui/render.go +++ b/internal/ui/render.go @@ -4,7 +4,6 @@ import ( "image" "image/color" - "gioui.org/f32" "gioui.org/layout" "gioui.org/op" "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 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 - //th.Shaper.LayoutString(text.Parameters{PxPerEm: fixed.I(gtx.Sp(r.theme.FontSize))}, "...") - //var ellipsisWidths []int - //for { - // g, ok := th.Shaper.NextGlyph() - // if !ok { - // break - // } - // if len(ellipsisWidths) == 0 { - // ellipsisWidths = append(ellipsisWidths, int(g.Advance>>6)) - // } else { - // ellipsisWidths = append(ellipsisWidths, ellipsisWidths[len(ellipsisWidths)-1]+int(g.Advance>>6)) - // } - //} - //ellipsisWidth := ellipsisWidths[len(ellipsisWidths)-1] + th.Shaper.LayoutString(text.Parameters{PxPerEm: fixed.I(gtx.Sp(r.theme.FontSize))}, "...") + var ellipsisWidth int + for { + g, ok := th.Shaper.NextGlyph() + if !ok { + break + } + ellipsisWidth = int((g.X + g.Advance) >> 6) + } // 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 - //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}) + 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}) // Line 2: Icons 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) var glyphs [32]text.Glyph line := glyphs[:0] - var firstGlyph text.Glyph - first := true for g, ok := shp.NextGlyph(); ok; g, ok = shp.NextGlyph() { - if first { - firstGlyph = g - first = false - } line = append(line, g) 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] } } 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.Add(gtx.Ops) } // 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) { - // Derive offset from first glyph position + desired position - // Gio's textView: lineOff = glyphPos - viewportMin - // We want: offset = (x, y) - firstGlyphPos - firstPos := f32.Point{X: float32(firstGlyph.X) / 64.0, Y: float32(firstGlyph.Y)} - off := f32.Point{X: float32(x), Y: float32(y)}.Sub(firstPos) - t := op.Affine(f32.Affine2D{}.Offset(off)).Push(gtx.Ops) +func (r *Renderer) drawLine(gtx layout.Context, shp *text.Shaper, line []text.Glyph, x, y unit.Dp, col color.NRGBA) { + // Offset coordinate system to (x, y). + // The shaper's glyph positions (g.X, g.Y) are absolute within the text block. + // g.Y for the first line is the ascent, so the top of the text will be at y. + t := op.Offset(image.Pt(gtx.Dp(x), gtx.Dp(y))).Push(gtx.Ops) // Draw vector glyphs path := shp.Shape(line)