etxt

package module
v0.0.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 30, 2022 License: MIT Imports: 22 Imported by: 0

README

etxt

Go Reference

etxt is a package for font management and text rendering in Golang designed to be used with the Ebitengine game engine.

While Ebitengine already provides the ebiten/text package that makes getting some text drawn on screen easy enough, etxt aims to help you actually understand what you are doing, doing it in a structured way and giving you much more control over it.

As a quick summary of what this package provides:

  • Structured font management and usage through the FontLibrary and Renderer types; because having to create and manage new font.Faces just to change text size is not ok.
  • Full control over glyph mask caching and rasterization (or just stay with the defaults!).
  • A few custom rasterizers that allow you to draw faux-bold, oblique, blurred and hollow text (WIP). Not really "main features", though, only examples of what you can do with etxt.
  • Lots of examples and thorough documentation.

Code example

Less talk and more code!

package main

import ( "log" ; "time" ; "image/color" )
import "github.com/hajimehoshi/ebiten/v2"
import "github.com/Kintar/etxt"

type Game struct { txtRenderer *etxt.Renderer }
func (self *Game) Layout(int, int) (int, int) { return 400, 400 }
func (self *Game) Update() error { return nil }
func (self *Game) Draw(screen *ebiten.Image) {
	// hacky color computation
	millis := time.Now().UnixMilli()
	blue := (millis/16) % 512
	if blue >= 256 { blue = 511 - blue }
	changingColor := color.RGBA{ 0, 255, uint8(blue), 255 }

	// set relevant text renderer properties and draw
	self.txtRenderer.SetTarget(screen)
	self.txtRenderer.SetColor(changingColor)
	self.txtRenderer.Draw("Hello World!", 200, 200)
}

func main() {
	// load font library
	fontLib := etxt.NewFontLibrary()
	_, _, err := fontLib.ParseDirFonts("game_dir/assets/fonts") // !!
	if err != nil {
		log.Fatalf("Error while loading fonts: %s", err.Error())
	}

	// check that we have the fonts we want
	// (shown for completeness, you don't need this in most cases)
	expectedFonts := []string{ "Roboto Bold", "Carter One" }  // !!
	for _, fontName := range expectedFonts {
		if !fontLib.HasFont(fontName) {
			log.Fatal("missing font: " + fontName)
		}
	}

	// check that the fonts have the characters we want
	// (shown for completeness, you don't need this in most cases)
	err = fontLib.EachFont(checkMissingRunes)
	if err != nil { log.Fatal(err) }

	// create a new text renderer and configure it
	txtRenderer := etxt.NewStdRenderer()
	glyphsCache := etxt.NewDefaultCache(10*1024*1024) // 10MB
	txtRenderer.SetCacheHandler(glyphsCache.NewHandler())
	txtRenderer.SetFont(fontLib.GetFont(expectedFonts[0]))
	txtRenderer.SetAlign(etxt.YCenter, etxt.XCenter)
	txtRenderer.SetSizePx(64)

	// run the "game"
	ebiten.SetWindowSize(400, 400)
	err = ebiten.RunGame(&Game{ txtRenderer })
	if err != nil { log.Fatal(err) }
}

// helper function used with FontLibrary.EachFont to make sure
// all loaded fonts contain the characters or alphabet we want
func checkMissingRunes(name string, font *etxt.Font) error {
	const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
	const symbols = "0123456789 .,;:!?-()[]{}_&#@"

	missing, err := etxt.GetMissingRunes(font, letters + symbols)
	if err != nil { return err }
	if len(missing) > 0 {
		log.Fatalf("Font '%s' missing runes: %s", name, string(missing))
	}
	return nil
}

This example focuses on the mundane usage of the main etxt FontLibrary and Renderer types, with abundant checks to fail fast if anything seems out of place.

If you want flashier examples you will find many more in the project, make sure to check them out!

Can I use this package without Ebitengine?

Yeah, you can compile it with -tags gtxt. Notice that gtxt will make text drawing happen on the CPU, so don't try to use it for real-time stuff. In particular, be careful to not accidentally use gtxt with Ebitengine (they are compatible in many cases, but performance will die).

Should I bother learning to use etxt?

If you are only dealing with text rendering incidentally and ebiten/text does the job well enough for you, feel free to stay with that.

The main consideration when using etxt is that you need to be minimally acquainted with how fonts work. FreeType glyph conventions is the go to reference that you really should be reading (up to section IV or V).

Any future plans?

This package is already quite solid, there are only a few points left to improve:

  • Adding a few more effects (hollow text, shaders, etc).
  • Missing a couple important examples (crisp UI and shaders).

If I get really bored, I'd also like to look into:

  • Contributing to Golang's sfnt to expose more tables and allow the creation of minimal packages to do basic text shaping in arabic or other complex scripts.
  • Add outline expansion. Freetype and libASS do this, and it would be quite nice to get high quality outlines and better faux-bolds... but it's also hard; I don't really know if I want to go there.
  • Triangulation and GPU rendering of Bézier curves are also interesting for Ebitengine (although they probably don't belong in this package).

Documentation

Overview

etxt is a package for font management and text rendering in Golang designed to be used mainly with the Ebitengine game engine.

While the API surface can look slightly intimidating at the beginning, common usage depends only on a couple types and a few functions...

First, you create a FontLibrary and parse the fonts:

fontLib := etxt.NewFontLibrary()
_, _, err := fontLib.ParseDirFonts("path/to/fonts")
if err != nil { ... }

Then, you create a Renderer:

txtRenderer := etxt.NewStdRenderer()
txtRenderer.SetFont(fontLib.GetFont("My Font Name"))

Finally, you set a target and start drawing:

txtRenderer.SetTarget(screen)
txtRenderer.Draw("Hello world!", x, y)

There are a lot of parameters you can configure, but the critical ones are font, size, align, color, cache and target. Take a good look at those and have fun exploring the rest!

Index

Constants

This section is empty.

Variables

View Source
var ErrAlreadyLoaded = errors.New("font already loaded")
View Source
var ErrNotFound = errors.New("font property not found or empty")

Functions

func FontFamily

func FontFamily(font *Font) (string, error)

Returns the family name of the given font. If the information is missing, ErrNotFound will be returned. Other errors are also possible (e.g., if the font naming table is invalid).

func FontIdentifier

func FontIdentifier(font *Font) (string, error)

Returns the identifier of the given font. If the information is missing, ErrNotFound will be returned. Other errors are also possible (e.g., if the font naming table is invalid).

func FontName

func FontName(font *Font) (string, error)

Returns the name of the given font. If the information is missing, ErrNotFound will be returned. Other errors are also possible (e.g., if the font naming table is invalid).

func FontProperty

func FontProperty(font *Font, property sfnt.NameID) (string, error)

Returns the requested font property for the given font. The returned property string might be empty even when error is nil.

func FontSubfamily

func FontSubfamily(font *Font) (string, error)

Returns the subfamily name of the given font. If the information is missing, ErrNotFound will be returned. Other errors are also possible (e.g., if the font naming table is invalid).

In most cases, the subfamily value will be one of:

  • Regular, Italic, Bold, Bold Italic

func GetMissingRunes

func GetMissingRunes(font *Font, text string) ([]rune, error)

Returns the runes in the given text that can't be represented by the font. If runes are repeated in the input text, the returned slice may contain them multiple times too.

If you load fonts dynamically, it is good practice to use this function to make sure that the fonts include all the glyphs that you require.

func GzipDirFonts

func GzipDirFonts(fontsDir string, outputDir string) error

Applies GzipFontFile() to each font of the given directory.

func GzipFontFile

func GzipFontFile(fontPath string, outDir string) error

Compresses the given font by gzipping it and storing the result on outDir with the same name as the original but an extra .gz extension.

The font size reduction can vary a lot depending on the font and format, but it's typically above 33%, with many .ttf font sizes being halved.

If you are wondering why gzip is used instead of supporting .woff formats: gzip has stdlib support, can be applied transparently and compression rates are very similar to what brotli achieves for .woff files.

When working on games, sometimes you might prefer to compress directly with a single command:

gzip --keep --best your_font.ttf

func NewDefaultCache

func NewDefaultCache(maxBytes int) *ecache.DefaultCache

Creates a new cache for font glyphs. For more details on how to use this new cache with renderers, see Renderer.SetCacheHandler() .

This function will panic if maxBytes < 1024 or crypto/rand fails. If you need to handle those errors, see ecache.NewDefaultCache() instead.

Types

type Direction

type Direction int8

Renderers can have their text direction configured as left-to-right or right-to-left.

Directions can be casted directly to unicode/bidi directions:

bidi.Direction(etxt.LeftToRight).
const (
	LeftToRight Direction = iota
	RightToLeft
)

type Feed

type Feed struct {
	Position       fixed.Point26_6 // the feed's working position
	PrevGlyphIndex GlyphIndex      // previous glyph index. used for kern.
	HasPrevGlyph   bool            // false after line breaks and others. used for kern.
	LineBreakX     fixed.Int26_6   // the x coordinate set after a line break
	// contains filtered or unexported fields
}

Feeds are the lowest level mechanism to draw text in etxt, allowing the user to issue each glyph draw call individually and modifying positions or configurations in between.

As a rule of thumb, you should only resort to feeds if neither renderer's Draw* nor Traverse* methods give you enough control to do what you want. Make sure you are well acquainted with those methods first.

Valid Feeds can only be created through Renderer.NewFeed().

func (*Feed) Advance

func (self *Feed) Advance(codePoint rune)

Advances the Feed's position without drawing anything.

func (*Feed) AdvanceGlyph

func (self *Feed) AdvanceGlyph(glyphIndex GlyphIndex)

Advances the Feed's position without drawing anything.

func (*Feed) Draw

func (self *Feed) Draw(codePoint rune)

Draws the given rune and advances the Feed's position.

The drawing configuration is taken from the Feed's associated renderer.

Quantization will be checked before every Draw operation and adjusted if necessary (even vertical quantization).

func (*Feed) DrawGlyph

func (self *Feed) DrawGlyph(glyphIndex GlyphIndex)

Same as Draw, but taking a glyph index instead of a rune.

func (*Feed) LineBreak

func (self *Feed) LineBreak()

Advances the Feed's position with a line break.

type Font

type Font = sfnt.Font

An alias for sfnt.Font so you don't need to import sfnt yourself when working with etxt.

func ParseEmbedFontFrom

func ParseEmbedFontFrom(path string, embedFileSys embed.FS) (*Font, string, error)

Same as ParseFontFrom(), but for embedded filesystems.

This is a low level function; you may prefer to use a FontLibrary instead.

func ParseFontBytes

func ParseFontBytes(fontBytes []byte) (*Font, string, error)

Similar to sfnt.Parse(), but also including the font name in the returned values and accepting gzipped font bytes. The bytes must not be modified while the font is in use.

This is a low level function; you may prefer to use a FontLibrary instead.

func ParseFontFrom

func ParseFontFrom(path string) (*Font, string, error)

Parses a font and returns it along its name and any possible error. Supported formats are .ttf, .otf, .ttf.gz and .otf.gz.

This is a low level function; you may prefer to use a FontLibrary instead.

type FontLibrary

type FontLibrary struct {
	// contains filtered or unexported fields
}

A collection of fonts accessible by name.

The goal of a FontLibrary is to make it easy to load fonts in bulk and keep them all in a single place.

FontLibrary doesn't know about system fonts, but there are other packages out there that can find those for you, if you are interested.

func NewFontLibrary

func NewFontLibrary() *FontLibrary

Creates a new, empty font library.

func (*FontLibrary) EachFont

func (self *FontLibrary) EachFont(fontFunc func(string, *Font) error) error

Calls the given function for each font in the library, passing their names and content as arguments.

If the given function returns a non-nil error, EachFont will immediately stop and return that error. Otherwise, EachFont will always return nil.

Example code to print the names of all the fonts in the library:

fontLib.EachFont(func(name string, _ *etxt.Font) error {
    fmt.Println(name)
    return nil
})

func (*FontLibrary) GetFont

func (self *FontLibrary) GetFont(name string) *Font

Returns the font with the given name, or nil if not found.

If you don't know what are the names of your fonts, there are a few ways to figure it out:

  • Load the fonts into the font library and print their names with FontLibrary.EachFont.
  • Use the FontName() function directly on a *Font object.
  • Open a font with the OS's default font viewer; the name is usually on the title and/or first line of text.

func (*FontLibrary) HasFont

func (self *FontLibrary) HasFont(name string) bool

Finds out whether a font with the given name exists in the library.

func (*FontLibrary) LoadFont

func (self *FontLibrary) LoadFont(font *Font) (string, error)

Loads the given font into the library and returns its name and any possible error. If the given font is nil, the method will panic. If another font with the same name was already loaded, ErrAlreadyLoaded will be returned as the error.

This method is rarely necessary unless the font loading is done by a third-party library. In general, using the FontLibrary.Parse*() functions is preferable.

func (*FontLibrary) ParseDirFonts

func (self *FontLibrary) ParseDirFonts(dirName string) (int, int, error)

Walks the given directory non-recursively and adds all the .ttf and .otf fonts in it. Returns the number of fonts added, the number of fonts skipped (a font with the same name already exists in the FontLibrary) and any error that might happen during the process.

func (*FontLibrary) ParseEmbedDirFonts

func (self *FontLibrary) ParseEmbedDirFonts(dirName string, embedFileSys embed.FS) (int, int, error)

Same as FontLibrary.ParseDirFonts but for embedded filesystems.

func (*FontLibrary) ParseEmbedFontFrom

func (self *FontLibrary) ParseEmbedFontFrom(path string, embedFileSys embed.FS) (string, error)

Same as FontLibrary.ParseFontFrom but for embedded filesystems.

func (*FontLibrary) ParseFontBytes

func (self *FontLibrary) ParseFontBytes(fontBytes []byte) (string, error)

Similar to FontLibrary.ParseFontFrom, but taking the font bytes directly. The font bytes may be gzipped. The bytes must not be modified while the font is in use.

func (*FontLibrary) ParseFontFrom

func (self *FontLibrary) ParseFontFrom(path string) (string, error)

Returns the name of the added font and any possible error. If error == nil, the font name will be non-empty.

If a font with the same name has already been loaded, ErrAlreadyLoaded will be returned.

func (*FontLibrary) RemoveFont

func (self *FontLibrary) RemoveFont(name string) bool

Returns false if the font can't be removed due to not being found.

This function is rarely necessary unless your program also has some mechanism to keep adding fonts without limit.

The given font name must match the name returned by the original font parsing function. Font names can also be recovered through FontLibrary.EachFont.

func (*FontLibrary) Size

func (self *FontLibrary) Size() int

Returns the current number of fonts in the library.

type GlyphIndex

type GlyphIndex = sfnt.GlyphIndex

Glyph indices are used to specify which font glyph are we working with. Glyph indices are a low level construct that most users of etxt dont't have to deal with, but they are important as they can be used to reference font glyphs that don't have any direct mapping to unicode code points.

Support for glyph indices (and not only runes), therefore, is important in order to make renderers usable with text shapers and complex scripts.

type GlyphMask

type GlyphMask = *ebiten.Image

A GlyphMask is the image that results from rasterizing a glyph. You rarely need to use GlyphMasks directly unless using advanced functions.

Without Ebitengine (gtxt version), GlyphMask defaults to *image.Alpha. The image bounds are adjusted to allow drawing the glyph at its intended position. In particular, bounds.Min.Y is typically negative, with y = 0 corresponding to the glyph's baseline, y < 0 to the ascending portions and y > 0 to the descending ones.

With Ebitengine, GlyphMask defaults to *ebiten.Image.

type HorzAlign

type HorzAlign int8
const (
	Left    HorzAlign = 0
	XCenter HorzAlign = 1
	Right   HorzAlign = 2
)

Horizontal align constants for renderer operations. See Renderer.SetAlign for additional details.

type MixMode

type MixMode = ebiten.CompositeMode

Mix modes specify how to compose colors when drawing glyphs on the renderer's target:

  • Without Ebitengine, the mix modes can be MixOver, MixReplace, MixAdd, MixSub, MixMultiply, MixCut and MixFiftyFifty.
  • With Ebitengine, mix modes are Ebitengine's composite modes.

I only ever change mix modes to make cutout text, but there's a lot of weird people out there, what can I say.

type RectSize

type RectSize struct {
	Width  fixed.Int26_6
	Height fixed.Int26_6
}

RectSize objects are used to store the results of text sizing operations. If you need to use the fixed.Int26_6 values directly and would like more context on them, read this document. Otherwise, you can obtain RectSize dimensions as int values like this:

rect   := txtRenderer.SelectionRect(text)
width  := rect.Width.Ceil()
height := rect.Height.Ceil()

func (RectSize) ImageRect

func (self RectSize) ImageRect() image.Rectangle

Returns the RectSize as an image.Rectangle with origin at (0, 0).

Ebitengine and other projects often expect image.Rectangle objects as arguments in their API calls, so this method is offered as a handy conversion shortcut.

type Renderer

type Renderer struct {
	// contains filtered or unexported fields
}

The Renderer is the main type for drawing text provided by etxt.

Renderers allow you to control font, text size, color, text alignment and more from a single place.

Basic usage goes like this:

  • Create, configure and store a renderer.
  • Use Renderer.SetTarget() and then Renderer.Draw() as many times as needed.
  • Re-adjust the properties of the renderer if needed... and keep drawing!

If you need more advice or guidance, check the renderers document and the examples.

func NewRenderer

func NewRenderer(rasterizer emask.Rasterizer) *Renderer

Creates a new renderer with the given glyph mask rasterizer. For the default rasterizer, see NewStdRenderer() instead.

After creating a renderer, you must set at least the font and the target in order to be able to draw. In most cases, you will also want to set a cache handler and a color. Check the setter functions for more details on all those.

Renderers are not safe for concurrent use.

func NewStdRenderer

func NewStdRenderer() *Renderer

Creates a new renderer with the default vector rasterizer. See NewRenderer() documentation for more details.

func (*Renderer) DefaultDrawFunc

func (self *Renderer) DefaultDrawFunc(dot fixed.Point26_6, mask GlyphMask, _ GlyphIndex)

The default glyph drawing function used in renderers. Do not confuse with the main Renderer.Draw() function. DefaultDrawFunc is a low level function, rarely necessary except when paired with Renderer.Traverse*() operations.

func (*Renderer) Draw

func (self *Renderer) Draw(text string, x, y int) fixed.Point26_6

Draws the given text with the current configuration (font, size, color, target, etc). The position at which the text will be drawn depends on the given pixel coordinates and the renderer's align (see Renderer.SetAlign() rules).

The returned value should be ignored except on advanced use-cases (refer to Renderer.Traverse() documentation).

Missing glyphs in the current font will cause the renderer to panic. See GetMissingRunes() if you need to make your system more robust.

Line breaks encoded as \n will be handled automatically.

func (*Renderer) DrawFract

func (self *Renderer) DrawFract(text string, x, y fixed.Int26_6) fixed.Point26_6

Exactly the same as Renderer.Draw(), but accepting fractional pixel coordinates.

Notice that passing a fractional coordinate won't make the draw operation be fractionally aligned by itself, that still depends on the renderer's [QuantizationMode].

func (*Renderer) GetAlign

func (self *Renderer) GetAlign() (VertAlign, HorzAlign)

Returns the current align. See Renderer.SetAlign() documentation for more details on text align.

func (*Renderer) GetCacheHandler

func (self *Renderer) GetCacheHandler() ecache.GlyphCacheHandler

Returns the current glyph cache handler, which is nil by default.

Rarely used unless you are examining the cache handler manually.

func (*Renderer) GetColor

func (self *Renderer) GetColor() color.Color

Returns the current drawing color.

func (*Renderer) GetFont

func (self *Renderer) GetFont() *Font

Returns the current font. The font is nil by default.

func (*Renderer) GetLineAdvance

func (self *Renderer) GetLineAdvance() fixed.Int26_6

Returns the result of lineHeight*lineSpacing. This is a low level function rarely needed unless you are drawing lines one by one and setting their y coordinate manually.

The result is always unquantized and cached.

For more context, see Renderer.SetLineHeight() and Renderer.SetLineSpacing().

func (*Renderer) GetRasterizer

func (self *Renderer) GetRasterizer() emask.Rasterizer

Returns the current glyph mask rasterizer.

This function is only useful when working with configurable rasterizers; ignore it if you are using the default glyph mask rasterizer.

Mask rasterizers are not concurrent-safe, so be careful with what you do and where you put them.

func (*Renderer) GetSizePxFract

func (self *Renderer) GetSizePxFract() fixed.Int26_6

Returns the current font size as a fixed.Int26_6.

func (*Renderer) GetSizer

func (self *Renderer) GetSizer() esizer.Sizer

Returns the current Sizer. You shouldn't worry about sizers unless you are making custom glyph mask rasterizers or want to disable kerning or adjust spacing in some other unusual way.

func (*Renderer) LoadGlyphMask

func (self *Renderer) LoadGlyphMask(index GlyphIndex, dot fixed.Point26_6) GlyphMask

Low-level function typically used with Renderer.Traverse*() functions when drawing glyph masks manually.

LoadGlyphMask loads the mask for the given glyph at the given fractional pixel position. The renderer's cache handler, font, size, rasterizer and mask format are all taken into account.

func (*Renderer) NewFeed

func (self *Renderer) NewFeed(xy fixed.Point26_6) *Feed

Returns a Feed object linked to the Renderer.

Feeds are the lowest level mechanism to draw text in etxt, as they expose and allow one to modify the drawing position manually.

Unlike Traverse* methods, though, Feeds can't automatically align text because the content to work with isn't known ahead of time. Only vertical align will be applied to the starting position as if the content had a single line.

func (*Renderer) SelectionRect

func (self *Renderer) SelectionRect(text string) RectSize

Get the dimensions of the area taken by the given text. Intuitively, this matches the shaded area that you see when highlighting or selecting text in browsers and text editors.

The results are affected by the renderer's font, size, quantization mode, sizer and text direction. If the input text contains \n line breaks, then line height and line spacing will also affect the results.

Notice that spilling (content falling outside the returned rect) is possible. In general it will be non-existent or very minor, but some fancy display or script fonts can really go to crazy places. You should also be careful with italics.

func (*Renderer) SelectionRectGlyphs

func (self *Renderer) SelectionRectGlyphs(glyphIndices []GlyphIndex) RectSize

Same as Renderer.SelectionRect(), but taking a slice of glyph indices instead of a string.

func (*Renderer) SetAlign

func (self *Renderer) SetAlign(vertAlign VertAlign, horzAlign HorzAlign)

Configures how Renderer.Draw*() coordinates will be interpreted. For example:

  • If the alignment is set to (etxt.Top, etxt.Left), coordinates passed to subsequent operations will be interpreted as the top-left corner of the box in which the text has to be drawn.
  • If the alignment is set to (etxt.YCenter, etxt.XCenter), coordinates passed to subsequent operations will be interpreted as the center of the box in which the text has to be drawn.

Check out this image for a visual explanation instead.

By default, the renderer's alignment is (etxt.Baseline, etxt.Left).

func (*Renderer) SetCacheHandler

func (self *Renderer) SetCacheHandler(cacheHandler ecache.GlyphCacheHandler)

Sets the glyph cache handler used by the renderer. By default, no cache is used, but you almost always want to set one, e.g.:

cache := etxt.NewDefaultCache(16*1024*1024) // 16MB
textRenderer.SetCacheHandler(cache.NewHandler())

A cache handler can only be used with a single renderer, but you can create multiple handlers from the same underlying cache and use them with multiple renderers.

func (*Renderer) SetColor

func (self *Renderer) SetColor(mainColor color.Color)

Sets the color to be used on subsequent draw operations. The default color is white.

func (*Renderer) SetDirection

func (self *Renderer) SetDirection(dir Direction)

Sets the text direction to be used on subsequent operations.

By default, the direction is LeftToRight.

func (*Renderer) SetFont

func (self *Renderer) SetFont(font *Font)

Sets the font to be used on subsequent operations. Make sure to set one before starting to draw!

func (*Renderer) SetHorzAlign

func (self *Renderer) SetHorzAlign(horzAlign HorzAlign)

See documentation for Renderer.SetAlign().

func (*Renderer) SetLineHeight

func (self *Renderer) SetLineHeight(heightPx float64)

Sets the line height to be used on subsequent operations.

Line height is only used when line breaks are found in the input text to be processed. Notice that line spacing will also affect the space between lines of text (lineAdvance = lineHeight*lineSpacing).

The units are pixels, not points, and only non-negative values are allowed. If you need negative line heights for some reason, use negative line spacing factors instead.

By default, the line height is set to auto (see Renderer.SetLineHeightAuto()).

func (*Renderer) SetLineHeightAuto

func (self *Renderer) SetLineHeightAuto()

Sets the line height to automatically match the height of the active font and size. This is the default behavior for line height.

For manual line height configuration, see Renderer.SetLineHeight().

func (*Renderer) SetLineSpacing

func (self *Renderer) SetLineSpacing(factor float64)

Sets the line spacing to be used on subsequent operations. By default, the line spacing factor is 1.0.

Line spacing is only applied when line breaks are found in the input text to be processed.

Notice that line spacing and line height are different things. See Renderer.SetLineHeight() for more details.

func (*Renderer) SetMixMode

func (self *Renderer) SetMixMode(mixMode MixMode)

Sets the mix mode to be used on subsequent operations. The default mix mode will compose glyphs over the active target with regular alpha blending.

func (*Renderer) SetQuantizerStep

func (self *Renderer) SetQuantizerStep(horzStep fixed.Int26_6, vertStep fixed.Int26_6)

Sets the granularity of the glyph position quantization applied to rendering and measurement operations, in 1/64th parts of a pixel.

At minimum granularity (step = 1), glyphs will be laid out without any changes to their advances and kerns, fully respecting the font's intended spacing and flow.

At maximum granularity (step = 64), glyphs will be effectively quantized to the pixel grid instead. This is the default value.

The higher the precision, the higher the pressure on the glyph cache (glyphs may have to be cached at many more different fractional pixel positions).

Recommended step values come from the formula ceil(64/N): 64, 32, 22, 16, 13, 11, 10, 8, 7, 6, 5, 4, 3, 2, 1.

For more details, read the quantization document.

func (*Renderer) SetRasterizer

func (self *Renderer) SetRasterizer(rasterizer emask.Rasterizer)

Sets the glyph mask rasterizer to be used on subsequent operations.

func (*Renderer) SetSizePx

func (self *Renderer) SetSizePx(sizePx int)

Sets the font size to be used on subsequent operations.

Sizes are given in pixels and must be >= 1. By default, the renderer will draw text at a size of 16px.

The relationship between font size and the size of its glyphs is complicated and can vary a lot between fonts, but to provide a general reference:

  • A capital latin letter is usually around 70% as tall as the given size. E.g.: at 16px, "A" will be 10-12px tall.
  • A lowercase latin letter is usually around 48% as tall as the given size. E.g.: at 16px, "x" will be 7-9px tall.

func (*Renderer) SetSizePxFract

func (self *Renderer) SetSizePxFract(sizePx fixed.Int26_6)

Like Renderer.SetSizePx, but accepting a fractional pixel size in the form of a 26.6 fixed point integer.

func (*Renderer) SetSizer

func (self *Renderer) SetSizer(sizer esizer.Sizer)

Sets the current sizer, which must be non-nil.

As Renderer.GetSizer() documentation explains, you rarely need to care about or even know what sizers are.

func (*Renderer) SetTarget

func (self *Renderer) SetTarget(target TargetImage)

Sets the target of subsequent operations. Attempting to draw without a target will cause the renderer to panic.

You can also clear the target by setting it to nil once it's no longer needed.

func (*Renderer) SetVertAlign

func (self *Renderer) SetVertAlign(vertAlign VertAlign)

See documentation for Renderer.SetAlign().

func (*Renderer) Traverse

func (self *Renderer) Traverse(text string, xy fixed.Point26_6, operation func(fixed.Point26_6, rune, GlyphIndex)) fixed.Point26_6

Low-level method that can be used to implement your own drawing and bounding operations.

The given function is called for each character in the input string. On line breaks, the function is called with '\n' and glyph index 0.

The returned coordinates correspond to the baseline position of the next glyph that would have to be drawn if the input was longer. The coordinates are unquantized and haven't had kerning applied (as the next glyph is not known yet). Notice that align and text direction can affect the returned coordinate:

  • If HorzAlign is etxt.Left, the returned coordinate will be on the right side of the last character drawn.
  • If HorzAlign is etxt.Right, the returned coordinate will be on the left side of the last character drawn.
  • If HorzAlign is etxt.XCenter, the returned coordinate will be on the right side of the last character drawn if the text direction is LeftToRight, or on the left side otherwise.

This returned coordinate can be useful when implementing bidirectional text renderers, custom multi-style renderers and similar, though for heterogeneous styling using a Feed is often more appropriate.

func (*Renderer) TraverseGlyphs

func (self *Renderer) TraverseGlyphs(glyphIndices []GlyphIndex, xy fixed.Point26_6, operation func(fixed.Point26_6, GlyphIndex)) fixed.Point26_6

Same as Renderer.Traverse(), but taking glyph indices instead of a string. This method can be used as a building block for creating other methods or types that operate with glyphs, as demonstrated by eglyr.Renderer.

This method is only relevant when working with complex scripts and using text shaping.

type TargetImage

type TargetImage = *ebiten.Image

Alias to allow compiling the package without Ebitengine (gtxt version).

Without Ebitengine, TargetImage defaults to image/draw.Image.

type VertAlign

type VertAlign int8
const (
	Top      VertAlign = 0
	YCenter  VertAlign = 1
	Baseline VertAlign = 2
	Bottom   VertAlign = 3
)

Vertical align constants for renderer operations. See Renderer.SetAlign() for additional details.

Directories

Path Synopsis
The ecache subpackage defines the [GlyphCacheHandler] interface used within etxt, provides a default cache implementation and exposes a few more helper types to assist you if you want to implement your own.
The ecache subpackage defines the [GlyphCacheHandler] interface used within etxt, provides a default cache implementation and exposes a few more helper types to assist you if you want to implement your own.
efixed is a utility subpackage containing functions for working with fixed point [fixed.Int26_6 numbers].
efixed is a utility subpackage containing functions for working with fixed point [fixed.Int26_6 numbers].
The eglyr subpackage defines a [Renderer] struct that behaves like the main [etxt.Renderer], but overriding a few methods to operate with glyph indices instead of strings.
The eglyr subpackage defines a [Renderer] struct that behaves like the main [etxt.Renderer], but overriding a few methods to operate with glyph indices instead of strings.
The emask subpackage defines the [Rasterizer] interface used within etxt and provides multiple ready-to-use implementations.
The emask subpackage defines the [Rasterizer] interface used within etxt and provides multiple ready-to-use implementations.
A collection of helper functions for examining certain font or glyph properties, irrelevant unless you are really deep into this mess.
A collection of helper functions for examining certain font or glyph properties, irrelevant unless you are really deep into this mess.
The esizer subpackage defines the [Sizer] interface used within etxt and provides multiple ready-to-use implementations.
The esizer subpackage defines the [Sizer] interface used within etxt and provides multiple ready-to-use implementations.
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL