Added support for rendering text to a texture.

This commit is contained in:
Sander Schobers 2020-05-22 17:42:02 +02:00
parent 9371a8738e
commit 23115b8a0f
4 changed files with 63 additions and 16 deletions

View File

@ -356,6 +356,10 @@ func (r *Renderer) TextAlign(font ui.Font, p geom.PointF32, c color.Color, t str
r.text(font, p, c, t, alignment) r.text(font, p, c, t, alignment)
} }
func (r *Renderer) TextTexture(font ui.Font, color color.Color, text string) (ui.Texture, error) {
return ui.TextTexture(r, font, color, text)
}
// Utility functions // Utility functions
func eventWait(eq *allg5.EventQueue, wait bool) allg5.Event { func eventWait(eq *allg5.EventQueue, wait bool) allg5.Event {

View File

@ -264,6 +264,19 @@ func (r *Renderer) createTexture(source ui.ImageSource, keepSource bool) (ui.Tex
return &Texture{texture}, nil return &Texture{texture}, nil
} }
func (r *Renderer) createTextureTarget(w, h float32) (*Texture, error) {
format, err := r.window.GetPixelFormat()
if err != nil {
return nil, err
}
texture, err := r.renderer.CreateTexture(format, sdl.TEXTUREACCESS_TARGET, int32(w), int32(h))
if err != nil {
return nil, err
}
texture.SetBlendMode(sdl.BLENDMODE_BLEND)
return &Texture{texture}, nil
}
func (r *Renderer) CreateTexture(source ui.ImageSource) (ui.Texture, error) { func (r *Renderer) CreateTexture(source ui.ImageSource) (ui.Texture, error) {
return r.createTexture(source, true) return r.createTexture(source, true)
} }
@ -277,16 +290,7 @@ func (r *Renderer) CreateTexturePath(path string, source bool) (ui.Texture, erro
} }
func (r *Renderer) CreateTextureTarget(w, h float32) (ui.Texture, error) { func (r *Renderer) CreateTextureTarget(w, h float32) (ui.Texture, error) {
format, err := r.window.GetPixelFormat() return r.createTextureTarget(w, h)
if err != nil {
return nil, err
}
texture, err := r.renderer.CreateTexture(format, sdl.TEXTUREACCESS_TARGET, int32(w), int32(h))
if err != nil {
return nil, err
}
texture.SetBlendMode(sdl.BLENDMODE_BLEND)
return &Texture{texture}, nil
} }
func (r *Renderer) DefaultTarget() ui.Texture { return r } func (r *Renderer) DefaultTarget() ui.Texture { return r }
@ -408,21 +412,30 @@ func (r *Renderer) Target() ui.Texture {
return &Texture{target} return &Texture{target}
} }
func (r *Renderer) Text(font ui.Font, p geom.PointF32, color color.Color, text string) { func (r *Renderer) text(font ui.Font, color color.Color, text string) (*Texture, error) {
f := font.(*Font) f, ok := font.(*Font)
if !ok {
return nil, errors.New("font not created with renderer")
}
surface, err := f.RenderUTF8Blended(text, ColorSDL(color)) surface, err := f.RenderUTF8Blended(text, ColorSDL(color))
if err != nil { if err != nil {
return return nil, err
} }
defer surface.Free() defer surface.Free()
texture, err := r.renderer.CreateTextureFromSurface(surface) texture, err := r.renderer.CreateTextureFromSurface(surface)
if err != nil {
return nil, err
}
return &Texture{texture}, nil
}
func (r *Renderer) Text(font ui.Font, p geom.PointF32, color color.Color, text string) {
texture, err := r.text(font, color, text)
if err != nil { if err != nil {
return return
} }
defer texture.Destroy() defer texture.Destroy()
r.DrawTexturePoint(texture, p)
r.DrawTexturePoint(&Texture{texture}, p)
} }
func (r *Renderer) TextAlign(font ui.Font, p geom.PointF32, color color.Color, text string, align ui.HorizontalAlignment) { func (r *Renderer) TextAlign(font ui.Font, p geom.PointF32, color color.Color, text string, align ui.HorizontalAlignment) {
@ -438,6 +451,10 @@ func (r *Renderer) TextAlign(font ui.Font, p geom.PointF32, color color.Color, t
} }
} }
func (r *Renderer) TextTexture(font ui.Font, color color.Color, text string) (ui.Texture, error) {
return r.text(font, color, text)
}
// Resources // Resources
func (r *Renderer) Resources() ui.Resources { return r.resources } func (r *Renderer) Resources() ui.Resources { return r.resources }

View File

@ -1,6 +1,7 @@
package ui package ui
import ( import (
"fmt"
"image/color" "image/color"
"opslag.de/schobers/geom" "opslag.de/schobers/geom"
@ -68,3 +69,11 @@ func (f *Fonts) TextAlign(fontName string, p geom.PointF32, color color.Color, t
} }
f.render.TextAlign(font, p, color, text, align) f.render.TextAlign(font, p, color, text, align)
} }
func (f *Fonts) TextTexture(fontName string, color color.Color, text string) (Texture, error) {
font := f.Font(fontName)
if font == nil {
return nil, fmt.Errorf("no font with name '%s'", fontName)
}
return f.render.TextTexture(font, color, text)
}

View File

@ -5,6 +5,7 @@ import (
"image/color" "image/color"
"opslag.de/schobers/geom" "opslag.de/schobers/geom"
"opslag.de/schobers/zntg"
) )
type Renderer interface { type Renderer interface {
@ -36,8 +37,24 @@ type Renderer interface {
Target() Texture Target() Texture
Text(font Font, p geom.PointF32, color color.Color, text string) Text(font Font, p geom.PointF32, color color.Color, text string)
TextAlign(font Font, p geom.PointF32, color color.Color, text string, align HorizontalAlignment) TextAlign(font Font, p geom.PointF32, color color.Color, text string, align HorizontalAlignment)
TextTexture(font Font, color color.Color, text string) (Texture, error)
// Resources // Resources
Resources() Resources Resources() Resources
SetResourceProvider(factory func() Resources) SetResourceProvider(factory func() Resources)
} }
// TextTexture renders specified text to a new texture.
func TextTexture(render Renderer, font Font, color color.Color, text string) (Texture, error) {
target := render.Target()
defer render.RenderTo(target)
bounds := font.Measure(text)
texture, err := render.CreateTextureTarget(bounds.Dx(), bounds.Dy())
if err != nil {
return nil, err
}
render.RenderTo(texture)
render.Clear(zntg.MustHexColor(`#00000000`))
render.Text(font, bounds.Min.Invert(), color, text)
return texture, nil
}