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() }