Rework the panel onto SI figures, labelled chips and one spacing scale

This commit is contained in:
flamingcow
2026-08-01 16:07:44 -07:00
parent de2ff13eb6
commit 726c4c2445
4 changed files with 280 additions and 146 deletions
+30 -2
View File
@@ -26,6 +26,30 @@ type textFace struct {
cellH int
ascent int
cache map[rune]*glyph
// Where a line of text starts and stops as far as the eye is concerned: the
// top of a digit or capital, down to the baseline. The cell is taller at
// both ends, reserving space above for accents nothing here uses and below
// for descenders, which hang past the line without being read as part of
// it. Laying out by the cell therefore puts visibly more air around text
// than around a bordered box the same distance away.
capTop int
lineH int
}
// Digits carry no ascender or descender, so the first row one marks is the top
// of the line and the baseline is the bottom.
func (t *textFace) measureLine() error {
g := t.glyph('0')
for y := 0; y < g.h; y++ {
for x := 0; x < g.w; x++ {
if g.cov[y*g.w+x] != 0 {
t.capTop, t.lineH = y, t.ascent-y
return nil
}
}
}
return fmt.Errorf("font rasterised no ink for a digit")
}
func loadFace(bold bool, sizePx float64) (*textFace, error) {
@@ -54,13 +78,17 @@ func loadFace(bold bool, sizePx float64) (*textFace, error) {
if !ok {
return nil, fmt.Errorf("font has no digit glyphs")
}
return &textFace{
t := &textFace{
face: face,
cellW: adv.Ceil(),
cellH: (m.Ascent + m.Descent).Ceil(),
ascent: m.Ascent.Ceil(),
cache: make(map[rune]*glyph),
}, nil
}
if err := t.measureLine(); err != nil {
return nil, err
}
return t, nil
}
// Rasterises once per rune and keeps the coverage mask, since the same few