mirror of
https://github.com/mineracks/seedhammer-v1-companion.git
synced 2026-06-26 22:01:05 +10:00
Twelve packages lifted from seedhammer/seedhammer @ v1.3.0
(commit 2f071c1d8f23eb7fd39b15fc0acb8874113f801e):
address/ — bitcoin address parsing
backup/ — v1 plate dimensions + UR-coded multi-plate backup
bc/ — Blockchain Commons: ur, fountain, bytewords, urtypes,
xoshiro256 (5 subpkgs)
bip32/ — HD-key derivation
bip39/ — mnemonic seed phrases + 2048-word wordlist
engrave/ — text/QR → MoveTo/LineTo command stream conversion
seedqr/ — SeedQR / CompactSeedQR encoders
image/ — paletted, rgb565, alpha4, ninepatch image formats
nonstandard/ — bitcoin descriptor + script parsing
font/ — bitmap + vector font runtime
font/{comfortaa,poppins,constant,bitmap,vector}/ — actual fonts
driver/mjolnir/ — MarkingWay USB-serial engraver driver
Plus an earlier-aside backup_test.go restored (its deps are now lifted).
Import paths globally rewritten seedhammer.com → mineracks namespace
via single sed pass; verified no orphan refs remain. go.mod adopts
upstream's full dep set plus the replace-directive for the patched
kortschak/qr fork.
go build ./... clean (all 27 packages)
go test ./... clean (12 packages with tests, all passing)
NOT lifted in this commit:
- driver/{wshat,drm,libcamera} (hardware-specific GPIO/LCD/camera —
will be platform-v1/-shaped abstractions instead)
- gui/ (depends on the above; lifts in Phase 2)
- cmd/{controller,...} (Pi binary entrypoints — not needed for the
companion repo)
- zbar/ (QR scanner — needs libcamera)
Next:
- Write the SH1E reference encoder/decoder in engrave/wire/sh1e/
- Lift Gangleri42's cmd/webnfc/ shell + retune to v1 plates
- First buildable composer WASM with a working preview
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
93 lines
1.6 KiB
Go
93 lines
1.6 KiB
Go
// package font converts an OpenType font into a form usable for engraving.
|
|
package vector
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"image"
|
|
"unicode"
|
|
)
|
|
|
|
type Face struct {
|
|
data []byte
|
|
}
|
|
|
|
func NewFace(data []byte) *Face {
|
|
return &Face{data}
|
|
}
|
|
|
|
type Glyph struct {
|
|
Advance int8
|
|
Start, End uint16
|
|
}
|
|
|
|
// Segments is an iterator over a glyph's segments
|
|
type Segments struct {
|
|
segs []byte
|
|
}
|
|
|
|
func (s *Segments) Next() (Segment, bool) {
|
|
if len(s.segs) == 0 {
|
|
return Segment{}, false
|
|
}
|
|
seg := Segment{
|
|
Op: SegmentOp(s.segs[0]),
|
|
Arg: image.Point{
|
|
X: int(int8(s.segs[1])),
|
|
Y: int(int8(s.segs[2])),
|
|
},
|
|
}
|
|
s.segs = s.segs[3:]
|
|
return seg, true
|
|
}
|
|
|
|
// Segment is like sfnt.Segment but with integer coordinates.
|
|
type Segment struct {
|
|
Op SegmentOp
|
|
Arg image.Point
|
|
}
|
|
|
|
type Metrics struct {
|
|
Ascent, Height int8
|
|
}
|
|
|
|
type SegmentOp uint32
|
|
|
|
const (
|
|
SegmentOpMoveTo SegmentOp = iota
|
|
SegmentOpLineTo
|
|
)
|
|
|
|
const (
|
|
indexLen = unicode.MaxASCII
|
|
IndexElemSize = 1 + 2 + 2
|
|
|
|
offAscent = 0
|
|
offHeight = offAscent + 1
|
|
offIndex = offHeight + 1
|
|
OffSegments = offIndex + indexLen*IndexElemSize
|
|
)
|
|
|
|
var bo = binary.LittleEndian
|
|
|
|
func (f *Face) Metrics() Metrics {
|
|
return Metrics{
|
|
Ascent: int8(f.data[offAscent]),
|
|
Height: int8(f.data[offHeight]),
|
|
}
|
|
}
|
|
|
|
func (f *Face) Decode(ch rune) (int, Segments, bool) {
|
|
if int(ch) >= indexLen {
|
|
return 0, Segments{}, false
|
|
}
|
|
index := f.data[offIndex:OffSegments]
|
|
gdata := index[ch*IndexElemSize : (ch+1)*IndexElemSize]
|
|
g := Glyph{
|
|
Advance: int8(gdata[0]),
|
|
Start: bo.Uint16(gdata[1:]),
|
|
End: bo.Uint16(gdata[1+2:]),
|
|
}
|
|
segs := f.data[g.Start:g.End]
|
|
return int(g.Advance), Segments{segs: segs}, g.Advance > 0
|
|
}
|