Fix charWidths to match Gio's textView PxPerEm calculation
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
parent
96b7c6dc97
commit
87992c3d99
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
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
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user