Files
wehub-resource-sync ead81af521
Deploy to GitHub Pages / deploy (push) Failing after 0s
CI / go (push) Has been cancelled
CI / build (darwin, macos-14) (push) Has been cancelled
CI / build (windows, windows-2025) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:31:13 +08:00

89 lines
2.1 KiB
Go
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package ui
import "strings"
// brailleGrid is a 4×2 dot-per-cell rasteriser shared by visualizers that draw
// to a fine subgrid (sand, speaker, lightning, crack, quake, geyser, strings).
// Each cell stores a tier (1..3 = low/mid/high colour, 0 = empty) and the
// renderer composes one Braille glyph per character cell.
type brailleGrid struct {
cells []int8
dotRows int
dotCols int
}
func (g *brailleGrid) ensure(rows, cols int) {
if rows == g.dotRows && cols == g.dotCols && len(g.cells) == rows*cols {
for i := range g.cells {
g.cells[i] = 0
}
return
}
g.cells = make([]int8, rows*cols)
g.dotRows = rows
g.dotCols = cols
}
func (g *brailleGrid) clear() {
for i := range g.cells {
g.cells[i] = 0
}
}
func (g *brailleGrid) set(x, y int, tier int8) {
if x < 0 || x >= g.dotCols || y < 0 || y >= g.dotRows {
return
}
if tier > g.cells[y*g.dotCols+x] {
g.cells[y*g.dotCols+x] = tier
}
}
// render flattens the dot grid to len(rows) lines, packing 4×2 dot blocks into
// Braille glyphs and emitting tier-coloured runs.
func (g *brailleGrid) render(rows int) string {
if g.dotRows < rows*4 || g.dotCols < PanelWidth*2 {
return strings.Repeat("\n", max(0, rows-1))
}
lines := make([]string, rows)
for row := 0; row < rows; row++ {
var sb, run strings.Builder
tag := -1
for col := 0; col < PanelWidth; col++ {
var braille rune = ''
cellTag := -1
for dr := 0; dr < 4; dr++ {
for dc := 0; dc < 2; dc++ {
y := row*4 + dr
x := col*2 + dc
t := g.cells[y*g.dotCols+x]
if t == 0 {
continue
}
braille |= brailleBit[dr][dc]
if int(t)-1 > cellTag {
cellTag = int(t) - 1
}
}
}
if cellTag < 0 {
cellTag = 0
}
if cellTag != tag {
flushStyleRun(&sb, &run, tag)
tag = cellTag
}
run.WriteRune(braille)
}
flushStyleRun(&sb, &run, tag)
lines[row] = sb.String()
}
return strings.Join(lines, "\n")
}
// rng64 advances a 64-bit LCG and returns a [0,1) double.
func rng64(state *uint64) float64 {
*state = *state*6364136223846793005 + 1442695040888963407
return float64((*state>>33)%1000) / 1000.0
}