change text.New to take an Atlas

This commit is contained in:
faiface 2017-05-10 17:56:09 +02:00
parent a510048648
commit e86120db20
2 changed files with 25 additions and 22 deletions

View File

@ -28,11 +28,24 @@ type Atlas struct {
lineHeight float64 lineHeight float64
} }
// NewAtlas creates a new Atlas containing glyphs of the given set of runes from the given font // NewAtlas creates a new Atlas containing glyphs of the union of the given sets of runes (plus
// face. // unicode.ReplacementChar) from the given font face.
// //
// Do not destroy or close the font.Face after creating the Atlas. // Creating an Atlas is rather expensive, do not create a new Atlas each frame.
func NewAtlas(face font.Face, runes []rune) *Atlas { //
// Do not destroy or close the font.Face after creating the Atlas. Atlas still uses it.
func NewAtlas(face font.Face, runeSets ...[]rune) *Atlas {
seen := make(map[rune]bool)
runes := []rune{unicode.ReplacementChar}
for _, set := range runeSets {
for _, r := range set {
if !seen[r] {
runes = append(runes, r)
seen[r] = true
}
}
}
fixedMapping, fixedBounds := makeSquareMapping(face, runes, fixed.I(2)) fixedMapping, fixedBounds := makeSquareMapping(face, runes, fixed.I(2))
atlasImg := image.NewRGBA(image.Rect( atlasImg := image.NewRGBA(image.Rect(

View File

@ -7,7 +7,6 @@ import (
"unicode/utf8" "unicode/utf8"
"github.com/faiface/pixel" "github.com/faiface/pixel"
"golang.org/x/image/font"
) )
// ASCII is a set of all ASCII runes. These runes are codepoints from 32 to 127 inclusive. // ASCII is a set of all ASCII runes. These runes are codepoints from 32 to 127 inclusive.
@ -40,14 +39,14 @@ func RangeTable(table *unicode.RangeTable) []rune {
// Text allows for effiecient and convenient text drawing. // Text allows for effiecient and convenient text drawing.
// //
// To create a Text object, use the New constructor: // To create a Text object, use the New constructor:
// txt := text.New(face, text.ASCII) // txt := text.New(pixel.V(0, 0), text.NewAtlas(face, text.ASCII))
// //
// As suggested by the constructor, a Text object is always associated with one font face and a // As suggested by the constructor, a Text object is always associated with one font face and a
// fixed set of runes. For example, the Text we created above can draw text using the font face // fixed set of runes. For example, the Text we created above can draw text using the font face
// contained in the face variable and is capable of drawing ASCII characters. // contained in the face variable and is capable of drawing ASCII characters.
// //
// Here we create a Text object which can draw ASCII and Katakana characters: // Here we create a Text object which can draw ASCII and Katakana characters:
// txt := text.New(face, text.ASCII, text.RangeTable(unicode.Katakana)) // txt := text.New(0, text.NewAtlas(face, text.ASCII, text.RangeTable(unicode.Katakana)))
// //
// Similarly to IMDraw, Text functions as a buffer. It implements io.Writer interface, so writing // Similarly to IMDraw, Text functions as a buffer. It implements io.Writer interface, so writing
// text to it is really simple: // text to it is really simple:
@ -92,12 +91,8 @@ type Text struct {
dirty bool dirty bool
} }
// New creates a new Text capable of drawing runes contained in the provided rune sets, plus // New creates a new Text capable of drawing runes contained in the provided Atlas. Orig and Dot
// unicode.ReplacementChar using the provided font.Face. New automatically generates an Atlas for // will be initially set to orig.
// the Text.
//
// Do not destroy or close the font.Face after creating a Text. Although Text caches most of the
// stuff (pre-drawn glyphs, etc.), it still uses the face for a few things.
// //
// Here we create a Text capable of drawing ASCII characters using the Go Regular font. // Here we create a Text capable of drawing ASCII characters using the Go Regular font.
// ttf, err := truetype.Parse(goregular.TTF) // ttf, err := truetype.Parse(goregular.TTF)
@ -107,16 +102,11 @@ type Text struct {
// face := truetype.NewFace(ttf, &truetype.Options{ // face := truetype.NewFace(ttf, &truetype.Options{
// Size: 14, // Size: 14,
// }) // })
// txt := text.New(face, text.ASCII) // txt := text.New(orig, text.NewAtlas(face, text.ASCII))
func New(face font.Face, runeSets ...[]rune) *Text { func New(orig pixel.Vec, atlas *Atlas) *Text {
runes := []rune{unicode.ReplacementChar}
for _, set := range runeSets {
runes = append(runes, set...)
}
atlas := NewAtlas(face, runes)
txt := &Text{ txt := &Text{
Orig: orig,
Dot: orig,
atlas: atlas, atlas: atlas,
lineHeight: atlas.LineHeight(), lineHeight: atlas.LineHeight(),
tabWidth: atlas.Glyph(' ').Advance * 4, tabWidth: atlas.Glyph(' ').Advance * 4,