Hey @pbnjay! Sorry, this took longer than I intended thanks to wandering priorities and interests.
I've been working on a branch here that moderately overhauls font parsing in fontgen.
The core of the change revolves around the isolation of text and image parsing code into individual packages (with tests!) that offer a top-level Decode function. Decode produces a *bitfont.Font, which is...
// Font is the internal representation of an entire pixel font, as generated by the parsing packages.
type Font struct {
Width, Height int
Glyphs map[rune]Glyph
}
type Glyph struct {
Mask []uint32
// eventually: Advance? Some way to store variable glyphs; BDF has a lot of info that we may want to preserve
}
bitfont.Font wouldn't be used outside of the parsing/generating code; the internal packed representation would continue to be used in generated packages and for efficient lookup.
This would let us move the core parsing logic of bdf2pixfont into another package that just produces a *bitfont.Font. After that, fontgen becomes a thin wrapper around the parser packages -- it serves to direct commandline arguments into the right places. I cobbled together a bit of that code here (though it targets an earlier version of the code where I had named it cmd/fontgen/internal/parser instead of internal/bitfont)[1].
Right now, the API shape for image.Decode leaves a bit to be desired; I couldn't decide how to handle offsets and chops in a particularly ergonomic fashion. text.Decode and bdf.Decode are relatively sane, though.
doc for packages text, image
### text
```
package text // import "github.com/pbnjay/pixfont/internal/bitfont/text"
FUNCTIONS
func Decode(r io.Reader) (*bitfont.Font, error)
```
### image
```
package image // import "github.com/pbnjay/pixfont/internal/bitfont/image"
FUNCTIONS
func Decode(r io.Reader, alphabet string, options *Options) (*bitfont.Font, error)
TYPES
type Options struct {
Offset image.Point
Size image.Point // 0 in X or Y is treated as "max"; ew
}
```
[1] the cmd/fontgen/internal/parser version also had an interface, parser.Parser (naming is the hardest part of software engineering 🙄), that Decode could hang off of.
What do you think? Is this worth pursuing, and would you consider upstreaming some version of it? Or should I hold on to it and keep a friendly fork?
Incidentally, with the changes above bdf2pixfont is subsumed by fontgen -bdf blah.bdf in its default text output mode, which produces the textual representation from bitfont/text.
Hey @pbnjay! Sorry, this took longer than I intended thanks to wandering priorities and interests.
I've been working on a branch here that moderately overhauls font parsing in
fontgen
.The core of the change revolves around the isolation of text and image parsing code into individual packages (with tests!) that offer a top-level
Decode
function.Decode
produces a*bitfont.Font
, which is...bitfont.Font
wouldn't be used outside of the parsing/generating code; the internal packed representation would continue to be used in generated packages and for efficient lookup.This would let us move the core parsing logic of
bdf2pixfont
into another package that just produces a*bitfont.Font
. After that, fontgen becomes a thin wrapper around the parser packages -- it serves to direct commandline arguments into the right places. I cobbled together a bit of that code here (though it targets an earlier version of the code where I had named itcmd/fontgen/internal/parser
instead ofinternal/bitfont
)[1].Right now, the API shape for
image.Decode
leaves a bit to be desired; I couldn't decide how to handle offsets and chops in a particularly ergonomic fashion.text.Decode
andbdf.Decode
are relatively sane, though.doc for packages text, image
### text ``` package text // import "github.com/pbnjay/pixfont/internal/bitfont/text" FUNCTIONS func Decode(r io.Reader) (*bitfont.Font, error) ``` ### image ``` package image // import "github.com/pbnjay/pixfont/internal/bitfont/image" FUNCTIONS func Decode(r io.Reader, alphabet string, options *Options) (*bitfont.Font, error) TYPES type Options struct { Offset image.Point Size image.Point // 0 in X or Y is treated as "max"; ew } ```[1] the
cmd/fontgen/internal/parser
version also had an interface,parser.Parser
(naming is the hardest part of software engineering 🙄), thatDecode
could hang off of.What do you think? Is this worth pursuing, and would you consider upstreaming some version of it? Or should I hold on to it and keep a friendly fork?