package assetstore import ( "fmt" "image" "log" "code.ur.gs/lupine/ordoor/internal/fonts" ) type Font struct { Name string mapping map[rune]*Sprite } func (a *AssetStore) Font(name string) (*Font, error) { name = canonical(name) // FIXME: these fonts don't exist. For now, point at one that does. switch name { case "imfnt13", "imfnt14": name = "wh40k_12" } if font, ok := a.fonts[name]; ok { return font, nil } log.Printf("Loading font %v", name) filename, err := a.lookup(name, "fnt", "Fonts") if err != nil { return nil, err } raw, err := fonts.LoadFont(filename) if err != nil { return nil, err } objFile, err := a.lookup(raw.ObjectFile, "", "Fonts") if err != nil { return nil, err } obj, err := a.ObjectByPath(objFile) if err != nil { return nil, err } out := &Font{ Name: name, mapping: make(map[rune]*Sprite, len(raw.Mapping)), } for r, offset := range raw.Mapping { spr, err := obj.Sprite(offset) if err != nil { return nil, err } out.mapping[r] = spr } a.fonts[name] = out return out, nil } // CalculateBounds tries to work out what sort of size the string will be when // rendered func (f *Font) CalculateBounds(text string) image.Rectangle { width := 0 height := 0 for _, r := range text { spr, ok := f.mapping[r] if !ok { continue // FIXME: we could add the space character or something? } width += spr.Rect.Dx() if y := spr.Rect.Dy(); y > height { height = y } } return image.Rect(0, 0, width, height) } func (f *Font) Glyph(r rune) (*Sprite, error) { glyph, ok := f.mapping[r] if !ok { return nil, fmt.Errorf("Font %v does not specify rune %v", f.Name, r) } return glyph, nil }