examples/2048: use text/v2

Also, this changes fixes a bug in (*text/v2.GoTextFace).Metrics.

Updates #2454
This commit is contained in:
Hajime Hoshi 2023-11-15 12:27:39 +09:00
parent 3080d361ec
commit 5354ccc44f
3 changed files with 32 additions and 62 deletions

View File

@ -15,6 +15,7 @@
package twenty48 package twenty48
import ( import (
"bytes"
"errors" "errors"
"image/color" "image/color"
"log" "log"
@ -22,51 +23,21 @@ import (
"sort" "sort"
"strconv" "strconv"
"golang.org/x/image/font"
"golang.org/x/image/font/opentype"
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/examples/resources/fonts" "github.com/hajimehoshi/ebiten/v2/examples/resources/fonts"
"github.com/hajimehoshi/ebiten/v2/text" "github.com/hajimehoshi/ebiten/v2/text/v2"
) )
var ( var (
mplusSmallFont font.Face mplusFaceSource *text.GoTextFaceSource
mplusNormalFont font.Face
mplusBigFont font.Face
) )
func init() { func init() {
tt, err := opentype.Parse(fonts.MPlus1pRegular_ttf) s, err := text.NewGoTextFaceSource(bytes.NewReader(fonts.MPlus1pRegular_ttf))
if err != nil {
log.Fatal(err)
}
const dpi = 72
mplusSmallFont, err = opentype.NewFace(tt, &opentype.FaceOptions{
Size: 24,
DPI: dpi,
Hinting: font.HintingVertical,
})
if err != nil {
log.Fatal(err)
}
mplusNormalFont, err = opentype.NewFace(tt, &opentype.FaceOptions{
Size: 32,
DPI: dpi,
Hinting: font.HintingVertical,
})
if err != nil {
log.Fatal(err)
}
mplusBigFont, err = opentype.NewFace(tt, &opentype.FaceOptions{
Size: 48,
DPI: dpi,
Hinting: font.HintingVertical,
})
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
mplusFaceSource = s
} }
// TileData represents a tile information like a value and a position. // TileData represents a tile information like a value and a position.
@ -387,17 +358,21 @@ func (t *Tile) Draw(boardImage *ebiten.Image) {
boardImage.DrawImage(tileImage, op) boardImage.DrawImage(tileImage, op)
str := strconv.Itoa(v) str := strconv.Itoa(v)
f := mplusBigFont sizeInPoints := 48.0
switch { switch {
case 3 < len(str): case 3 < len(str):
f = mplusSmallFont sizeInPoints = 24
case 2 < len(str): case 2 < len(str):
f = mplusNormalFont sizeInPoints = 32
} }
w := font.MeasureString(f, str).Floor() textOp := &text.DrawOptions{}
h := (f.Metrics().Ascent + f.Metrics().Descent).Floor() textOp.GeoM.Translate(float64(x)+float64(tileSize)/2, float64(y)+float64(tileSize)/2)
x += (tileSize - w) / 2 textOp.ColorScale.ScaleWithColor(tileColor(v))
y += (tileSize-h)/2 + f.Metrics().Ascent.Floor() textOp.PrimaryAlign = text.AlignCenter
text.Draw(boardImage, str, f, x, y, tileColor(v)) textOp.SecondaryAlign = text.AlignCenter
text.Draw(boardImage, str, &text.GoTextFace{
Source: mplusFaceSource,
SizeInPoints: sizeInPoints,
}, textOp)
} }

View File

@ -179,7 +179,21 @@ func MustParseTag(str string) Tag {
// Metrics implements Face. // Metrics implements Face.
func (g *GoTextFace) Metrics() Metrics { func (g *GoTextFace) Metrics() Metrics {
return g.Source.Metrics() scale := float64(g.SizeInPoints) / float64(g.Source.f.Font.Upem())
var m Metrics
if h, ok := g.Source.f.FontHExtents(); ok {
m.Height = float64(h.Ascender-h.Descender+h.LineGap) * scale
m.HAscent = float64(h.Ascender) * scale
m.HDescent = float64(-h.Descender) * scale
}
if v, ok := g.Source.f.FontVExtents(); ok {
m.Width = float64(v.Ascender-v.Descender+v.LineGap) * scale
m.VAscent = float64(v.Ascender) * scale
m.VDescent = float64(-v.Descender) * scale
}
return m
} }
// UnsafeInternal implements Face. // UnsafeInternal implements Face.

View File

@ -128,25 +128,6 @@ func finalizeGoTextFaceSource(source *GoTextFaceSource) {
}) })
} }
// Metrics returns the font's metrics.
func (g *GoTextFaceSource) Metrics() Metrics {
upem := float64(g.f.Font.Upem())
var m Metrics
if h, ok := g.f.FontHExtents(); ok {
m.Height = float64(h.Ascender-h.Descender+h.LineGap) / upem
m.HAscent = float64(h.Ascender) / upem
m.HDescent = float64(-h.Descender) / upem
}
if v, ok := g.f.FontVExtents(); ok {
m.Width = float64(v.Ascender-v.Descender+v.LineGap) / upem
m.VAscent = float64(v.Ascender) / upem
m.VDescent = float64(-v.Descender) / upem
}
return m
}
func (g *GoTextFaceSource) shape(text string, face *GoTextFace) (shaping.Output, []glyph) { func (g *GoTextFaceSource) shape(text string, face *GoTextFace) (shaping.Output, []glyph) {
g.m.Lock() g.m.Lock()
defer g.m.Unlock() defer g.m.Unlock()