Make a start on font rendering
I was hopeful I could use ebiten/text, but font.Face doesn't seem set up for fixed-colour fonts.
This commit is contained in:
@@ -10,17 +10,28 @@ import (
|
||||
"code.ur.gs/lupine/ordoor/internal/util/asciiscan"
|
||||
)
|
||||
|
||||
type Range struct {
|
||||
Min Point
|
||||
Max Point
|
||||
}
|
||||
|
||||
type Point struct {
|
||||
Rune rune
|
||||
Sprite int
|
||||
}
|
||||
|
||||
type Font struct {
|
||||
Name string
|
||||
// Contains the sprite data for the font. FIXME: load this?
|
||||
// Contains the sprite data for the font
|
||||
ObjectFile string
|
||||
|
||||
// Maps ASCII bytes to a sprite offset in the ObjectFile
|
||||
mapping map[int]int
|
||||
Ranges []Range
|
||||
Mapping map[rune]int
|
||||
}
|
||||
|
||||
func (f *Font) Entries() int {
|
||||
return len(f.mapping)
|
||||
return len(f.Mapping)
|
||||
}
|
||||
|
||||
// Returns the offsets required to display a given string, returning an error if
|
||||
@@ -30,7 +41,7 @@ func (f *Font) Indices(s string) ([]int, error) {
|
||||
|
||||
for i, b := range []byte(s) {
|
||||
|
||||
offset, ok := f.mapping[int(b)]
|
||||
offset, ok := f.Mapping[rune(b)]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("Unknown codepoint %v at offset %v in string %s", b, i, s)
|
||||
}
|
||||
@@ -58,7 +69,7 @@ func LoadFont(filename string) (*Font, error) {
|
||||
out := &Font{
|
||||
Name: filepath.Base(filename),
|
||||
ObjectFile: objFile,
|
||||
mapping: make(map[int]int),
|
||||
Mapping: make(map[rune]int),
|
||||
}
|
||||
|
||||
for {
|
||||
@@ -82,15 +93,32 @@ func LoadFont(filename string) (*Font, error) {
|
||||
cpEnd, _ := strconv.Atoi(fields[2])
|
||||
idxStart, _ := strconv.Atoi(fields[3])
|
||||
idxEnd, _ := strconv.Atoi(fields[4])
|
||||
size := idxEnd - idxStart
|
||||
cpSize := cpEnd - cpStart
|
||||
idxSize := idxEnd - idxStart
|
||||
|
||||
// FIXME: I'd love this to be an error but several .fnt files do it
|
||||
if cpEnd-cpStart != size {
|
||||
fmt.Printf("WARNING: %v has mismatched codepoints and indices: %q\n", filename, str)
|
||||
// Take the smallest range
|
||||
if cpSize != idxSize {
|
||||
fmt.Printf("WARNING: %v has mismatched codepoints (sz=%v) and indices (sz=%v): %q\n", filename, cpSize, idxSize, str)
|
||||
if cpSize < idxSize {
|
||||
idxEnd = idxStart + cpSize
|
||||
idxSize = cpSize
|
||||
} else {
|
||||
cpEnd = cpStart + idxSize
|
||||
cpSize = idxSize
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for offset := 0; offset < size; offset++ {
|
||||
out.mapping[cpStart+offset] = idxStart + offset
|
||||
r := Range{
|
||||
Min: Point{Rune: rune(cpStart), Sprite: idxStart},
|
||||
Max: Point{Rune: rune(cpEnd), Sprite: idxEnd},
|
||||
}
|
||||
|
||||
out.Ranges = append(out.Ranges, r)
|
||||
|
||||
for offset := 0; offset <= cpSize; offset++ {
|
||||
out.Mapping[rune(cpStart+offset)] = idxStart + offset
|
||||
}
|
||||
case "v": // A single codepoint, 4 fields
|
||||
if len(fields) < 3 {
|
||||
@@ -99,8 +127,11 @@ func LoadFont(filename string) (*Font, error) {
|
||||
|
||||
cp, _ := strconv.Atoi(fields[1])
|
||||
idx, _ := strconv.Atoi(fields[2])
|
||||
pt := Point{Rune: rune(cp), Sprite: idx}
|
||||
|
||||
out.mapping[cp] = idx
|
||||
out.Ranges = append(out.Ranges, Range{Min: pt, Max: pt})
|
||||
|
||||
out.Mapping[rune(cp)] = idx
|
||||
default:
|
||||
return nil, parseErr
|
||||
}
|
||||
|
Reference in New Issue
Block a user