Fix charWidths to match Gio's textView PxPerEm calculation

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
Greg Pomerantz 2026-05-08 23:37:10 -04:00
parent 96b7c6dc97
commit 87992c3d99
3 changed files with 10 additions and 50 deletions

View File

@ -52,7 +52,7 @@ func EditorLayout(screenWidth, screenHeight unit.Dp) []ui.Element {
// Create StatusBar with mocked filename
statusBar := ui.NewStatusBar(
statusBarRegion,
"very_long_filename_that_does_not_fit_on_a_single_line.txt",
"very_long_filename_that_does_not_fit_on_a_single_line_and_it_just_keeps_on_going_and_going_and_going_and_going_and_going.txt",
false, // FilenameExp
true, // CutCopy
false, // Copy

View File

@ -97,15 +97,11 @@ func (r *Renderer) drawStatusBar(gtx layout.Context, sb StatusBar) {
// Measure how wide "..." is, then find how many chars fit in availableWidth - ellipsisWidth
spaceForText := availableWidth - ellipsisWidth
widths := charWidths(gtx, th.Shaper, displayFilename, r.theme.FontSize)
if len(widths) > 0 && widths[len(widths)-1] > spaceForText {
if len(widths) > 0 && widths[len(widths)-1] > availableWidth {
// Find the largest index where the width fits
for i, w := range widths {
if w <= spaceForText {
if i+1 < len(displayFilename) {
displayFilename = displayFilename[:i+1] + "..."
} else {
displayFilename = displayFilename[:i] + "..."
}
for i := len(widths)-1; i >= 0; i-- {
if widths[i] <= spaceForText {
displayFilename = displayFilename[:i] + "..."
break
}
}
@ -209,54 +205,18 @@ func boolToString(b bool) string {
return "Off"
}
// textWidth measures the total width of a string using the shaper.
func textWidth(gtx layout.Context, shp *text.Shaper, str string, size unit.Sp) int {
pixelsPerDp := gtx.Dp(unit.Dp(1))
shp.LayoutString(text.Parameters{PxPerEm: fixed.Int26_6(1024 * pixelsPerDp)}, str)
var minX, maxX fixed.Int26_6
first := true
for {
g, ok := shp.NextGlyph()
if !ok {
break
}
if first {
minX = g.X
maxX = g.X + g.Advance
first = false
} else {
if g.X < minX {
minX = g.X
}
if g.X+g.Advance > maxX {
maxX = g.X + g.Advance
}
}
}
return int(maxX - minX)
}
// charWidths returns the cumulative width after each rune in str.
func charWidths(gtx layout.Context, shp *text.Shaper, str string, size unit.Sp) []int {
pixelsPerDp := gtx.Dp(unit.Dp(1))
shp.LayoutString(text.Parameters{PxPerEm: fixed.Int26_6(1024 * pixelsPerDp)}, str)
var runeAdvances []fixed.Int26_6
var runeIdx int
// Match Gio's textView: PxPerEm = font size in device pixels
shp.LayoutString(text.Parameters{PxPerEm: fixed.I(gtx.Sp(size))}, str)
var widths []int
var cumWidth fixed.Int26_6 = 0
for {
g, ok := shp.NextGlyph()
if !ok {
break
}
if runeIdx < len(str) {
runeAdvances = append(runeAdvances, g.Advance)
runeIdx++
}
}
// Accumulate advances and convert from Int26_6 to int (divide by 64)
var widths []int
var cumWidth fixed.Int26_6
for _, adv := range runeAdvances {
cumWidth += adv
cumWidth += g.Advance
widths = append(widths, int(cumWidth>>6))
}
return widths

BIN
pad

Binary file not shown.