Fix filename truncation with proper scaling and ellipsis width measurement
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
parent
bbd16be9f2
commit
9c1e32c52a
|
|
@ -2,6 +2,7 @@ package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
|
"log"
|
||||||
|
|
||||||
"gioui.org/layout"
|
"gioui.org/layout"
|
||||||
"gioui.org/op"
|
"gioui.org/op"
|
||||||
|
|
@ -92,11 +93,13 @@ 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
|
||||||
ellipsisWidth := textWidth(gtx, th.Shaper, "...", r.theme.FontSize)
|
ellipsisWidths := charWidths(gtx, th.Shaper, "...", r.theme.FontSize)
|
||||||
|
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
|
||||||
widths := charWidths(gtx, th.Shaper, displayFilename, r.theme.FontSize)
|
widths := charWidths(gtx, th.Shaper, displayFilename, r.theme.FontSize)
|
||||||
if len(widths) > 0 && widths[len(widths)-1] > availableWidth {
|
log.Printf("drawStatusBar: filename=%q availableWidth=%d ellipsisWidth=%d spaceForText=%d widths=%v", displayFilename, availableWidth, ellipsisWidth, spaceForText, widths)
|
||||||
|
if len(widths) > 0 && widths[len(widths)-1] > spaceForText {
|
||||||
// Find the largest index where the width fits
|
// Find the largest index where the width fits
|
||||||
for i, w := range widths {
|
for i, w := range widths {
|
||||||
if w <= spaceForText {
|
if w <= spaceForText {
|
||||||
|
|
@ -109,6 +112,7 @@ func (r *Renderer) drawStatusBar(gtx layout.Context, sb StatusBar) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
log.Printf("drawStatusBar: final filename=%q", displayFilename)
|
||||||
|
|
||||||
// Position filename at (reg.X + 8, filenameLineY)
|
// Position filename at (reg.X + 8, filenameLineY)
|
||||||
call1 := op.Offset(image.Point{X: int(reg.X + unit.Dp(8)), Y: int(filenameLineY)}).Push(gtx.Ops)
|
call1 := op.Offset(image.Point{X: int(reg.X + unit.Dp(8)), Y: int(filenameLineY)}).Push(gtx.Ops)
|
||||||
|
|
@ -210,38 +214,54 @@ func boolToString(b bool) string {
|
||||||
|
|
||||||
// textWidth measures the total width of a string using the shaper.
|
// 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 {
|
func textWidth(gtx layout.Context, shp *text.Shaper, str string, size unit.Sp) int {
|
||||||
shp.LayoutString(text.Parameters{PxPerEm: 1024}, str)
|
pixelsPerDp := gtx.Dp(unit.Dp(1))
|
||||||
var lastX fixed.Int26_6
|
shp.LayoutString(text.Parameters{PxPerEm: fixed.Int26_6(1024 * pixelsPerDp)}, str)
|
||||||
|
var minX, maxX fixed.Int26_6
|
||||||
|
first := true
|
||||||
for {
|
for {
|
||||||
g, ok := shp.NextGlyph()
|
g, ok := shp.NextGlyph()
|
||||||
if !ok {
|
if !ok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
x := g.X + g.Advance
|
if first {
|
||||||
if x > lastX {
|
minX = g.X
|
||||||
lastX = 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(lastX)
|
}
|
||||||
|
return int(maxX - minX)
|
||||||
}
|
}
|
||||||
|
|
||||||
// charWidths returns the cumulative width after each rune in str.
|
// charWidths returns the cumulative width after each rune in str.
|
||||||
func charWidths(gtx layout.Context, shp *text.Shaper, str string, size unit.Sp) []int {
|
func charWidths(gtx layout.Context, shp *text.Shaper, str string, size unit.Sp) []int {
|
||||||
shp.LayoutString(text.Parameters{PxPerEm: 1024}, str)
|
pixelsPerDp := gtx.Dp(unit.Dp(1))
|
||||||
var widths []int
|
shp.LayoutString(text.Parameters{PxPerEm: fixed.Int26_6(1024 * pixelsPerDp)}, str)
|
||||||
var cumX fixed.Int26_6
|
var runeAdvances []fixed.Int26_6
|
||||||
var runeIdx int
|
var runeIdx int
|
||||||
for {
|
for {
|
||||||
g, ok := shp.NextGlyph()
|
g, ok := shp.NextGlyph()
|
||||||
if !ok {
|
if !ok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
cumX = g.X + g.Advance
|
|
||||||
// Each glyph corresponds to one rune in our simple ASCII case
|
|
||||||
if runeIdx < len(str) {
|
if runeIdx < len(str) {
|
||||||
widths = append(widths, int(cumX))
|
runeAdvances = append(runeAdvances, g.Advance)
|
||||||
runeIdx++
|
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
|
||||||
|
widths = append(widths, int(cumWidth>>6))
|
||||||
|
}
|
||||||
|
log.Printf("charWidths: runeAdvances=%v widths=%v", runeAdvances, widths)
|
||||||
return widths
|
return widths
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user