tins2021/bitmapfont.go
Sander Schobers 13b6a50a45 Added bitmap font.
Added monsters.
Added animations.
Added rendering of geometries.
2021-08-09 01:25:51 +02:00

107 lines
2.7 KiB
Go

package tins2021
import (
"image/color"
"opslag.de/schobers/geom"
"opslag.de/schobers/zntg/ui"
)
type BitmapFont struct {
texture ui.Texture
height float32
runes map[rune]*geom.RectangleF32
}
var AllCharacters = []rune(`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 ,.?!;:+-=_()[]{}"'@#$%^&*<>\/`)
var AlphaCharacters = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
var LowerCaseAlphaCharacters = []rune("abcdefghijklmnopqrstuvwxyz")
var NumericCharacters = []rune("0123456789")
var SpecialCharacters = []rune(` ,.?!;:+-=_()[]{}"'@#$%^&*<>\/`)
var UpperCaseAlphaCharacters = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
func NewBitmapFont(renderer ui.Renderer, font ui.Font, set ...rune) (*BitmapFont, error) {
texture, err := renderer.TextTexture(font, color.White, string(set))
if err != nil {
return nil, err
}
runes := map[rune]*geom.RectangleF32{}
height := float32(texture.Height())
var left float32
for _, r := range set {
width := font.WidthOf(string([]rune{r}))
right := left + width
rect := geom.RectF32(left, 0, right, height)
runes[r] = &rect
left = right
}
return &BitmapFont{texture, font.Height(), runes}, nil
}
func (f *BitmapFont) Destroy() error { return f.texture.Destroy() }
func (f *BitmapFont) Height() float32 { return f.height }
func (f *BitmapFont) Measure(t string) geom.RectangleF32 {
if len(t) == 0 {
return geom.RectF32(0, 0, 0, 0)
}
var minY, maxY float32
var width float32
var first int
for i, r := range t {
rect := f.runes[r]
if rect == nil {
continue
}
width = rect.Dx()
minY, maxY = rect.Min.Y, rect.Max.Y
first = i
break
}
for _, r := range t[first+1:] {
rect := f.runes[r]
if rect == nil {
continue
}
width += rect.Dx()
if minY > rect.Min.Y {
minY = rect.Min.Y
}
if maxY < rect.Max.Y {
maxY = rect.Max.Y
}
}
return geom.RectF32(0, minY, width, maxY)
}
func (f *BitmapFont) Text(renderer ui.Renderer, pos geom.PointF32, color color.Color, text string) {
f.text(renderer, pos.X, pos.Y, color, text)
}
func (f *BitmapFont) TextAlign(renderer ui.Renderer, pos geom.PointF32, color color.Color, text string, align ui.HorizontalAlignment) {
left := pos.X
width := f.WidthOf(text)
switch align {
case ui.AlignCenter:
left -= .5 * width
case ui.AlignRight:
left -= width
}
f.text(renderer, left, pos.Y, color, text)
}
func (f *BitmapFont) text(renderer ui.Renderer, left, top float32, color color.Color, text string) {
for _, r := range text {
src := f.runes[r]
if src == nil {
continue
}
renderer.DrawTexturePointOptions(f.texture, geom.PtF32(left, top), ui.DrawOptions{Tint: color, Source: src})
left += src.Dx()
}
}
func (f *BitmapFont) WidthOf(t string) float32 {
return f.Measure(t).Dx()
}