From 23115b8a0fda133b9030ad3a2107fb461ceed970 Mon Sep 17 00:00:00 2001 From: Sander Schobers Date: Fri, 22 May 2020 17:42:02 +0200 Subject: [PATCH] Added support for rendering text to a texture. --- allg5ui/renderer.go | 4 ++++ sdlui/renderer.go | 49 ++++++++++++++++++++++++++++++--------------- ui/fonts.go | 9 +++++++++ ui/renderer.go | 17 ++++++++++++++++ 4 files changed, 63 insertions(+), 16 deletions(-) diff --git a/allg5ui/renderer.go b/allg5ui/renderer.go index ed53cb8..7d77db1 100644 --- a/allg5ui/renderer.go +++ b/allg5ui/renderer.go @@ -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) } +func (r *Renderer) TextTexture(font ui.Font, color color.Color, text string) (ui.Texture, error) { + return ui.TextTexture(r, font, color, text) +} + // Utility functions func eventWait(eq *allg5.EventQueue, wait bool) allg5.Event { diff --git a/sdlui/renderer.go b/sdlui/renderer.go index 7d4ef86..fe38d39 100644 --- a/sdlui/renderer.go +++ b/sdlui/renderer.go @@ -264,6 +264,19 @@ func (r *Renderer) createTexture(source ui.ImageSource, keepSource bool) (ui.Tex 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) { 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) { - 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 + return r.createTextureTarget(w, h) } func (r *Renderer) DefaultTarget() ui.Texture { return r } @@ -408,21 +412,30 @@ func (r *Renderer) Target() ui.Texture { return &Texture{target} } -func (r *Renderer) Text(font ui.Font, p geom.PointF32, color color.Color, text string) { - f := font.(*Font) - +func (r *Renderer) text(font ui.Font, color color.Color, text string) (*Texture, error) { + f, ok := font.(*Font) + if !ok { + return nil, errors.New("font not created with renderer") + } surface, err := f.RenderUTF8Blended(text, ColorSDL(color)) if err != nil { - return + return nil, err } defer surface.Free() 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 { return } defer texture.Destroy() - - r.DrawTexturePoint(&Texture{texture}, p) + r.DrawTexturePoint(texture, p) } 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 func (r *Renderer) Resources() ui.Resources { return r.resources } diff --git a/ui/fonts.go b/ui/fonts.go index 23140f5..9b650b3 100644 --- a/ui/fonts.go +++ b/ui/fonts.go @@ -1,6 +1,7 @@ package ui import ( + "fmt" "image/color" "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) } + +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) +} diff --git a/ui/renderer.go b/ui/renderer.go index 85a2488..570b07f 100644 --- a/ui/renderer.go +++ b/ui/renderer.go @@ -5,6 +5,7 @@ import ( "image/color" "opslag.de/schobers/geom" + "opslag.de/schobers/zntg" ) type Renderer interface { @@ -36,8 +37,24 @@ type Renderer interface { Target() Texture Text(font Font, p geom.PointF32, color color.Color, text string) 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 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 +}