From 5354ccc44f6468df824a51b2c74c4cba23c110cf Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Wed, 15 Nov 2023 12:27:39 +0900 Subject: [PATCH] examples/2048: use text/v2 Also, this changes fixes a bug in (*text/v2.GoTextFace).Metrics. Updates #2454 --- examples/2048/2048/tile.go | 59 +++++++++++-------------------------- text/v2/gotext.go | 16 +++++++++- text/v2/gotextfacesource.go | 19 ------------ 3 files changed, 32 insertions(+), 62 deletions(-) diff --git a/examples/2048/2048/tile.go b/examples/2048/2048/tile.go index dce737baf..d795d8da0 100644 --- a/examples/2048/2048/tile.go +++ b/examples/2048/2048/tile.go @@ -15,6 +15,7 @@ package twenty48 import ( + "bytes" "errors" "image/color" "log" @@ -22,51 +23,21 @@ import ( "sort" "strconv" - "golang.org/x/image/font" - "golang.org/x/image/font/opentype" - "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/examples/resources/fonts" - "github.com/hajimehoshi/ebiten/v2/text" + "github.com/hajimehoshi/ebiten/v2/text/v2" ) var ( - mplusSmallFont font.Face - mplusNormalFont font.Face - mplusBigFont font.Face + mplusFaceSource *text.GoTextFaceSource ) func init() { - tt, err := opentype.Parse(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, - }) + s, err := text.NewGoTextFaceSource(bytes.NewReader(fonts.MPlus1pRegular_ttf)) if err != nil { log.Fatal(err) } + mplusFaceSource = s } // 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) str := strconv.Itoa(v) - f := mplusBigFont + sizeInPoints := 48.0 switch { case 3 < len(str): - f = mplusSmallFont + sizeInPoints = 24 case 2 < len(str): - f = mplusNormalFont + sizeInPoints = 32 } - w := font.MeasureString(f, str).Floor() - h := (f.Metrics().Ascent + f.Metrics().Descent).Floor() - x += (tileSize - w) / 2 - y += (tileSize-h)/2 + f.Metrics().Ascent.Floor() - text.Draw(boardImage, str, f, x, y, tileColor(v)) + textOp := &text.DrawOptions{} + textOp.GeoM.Translate(float64(x)+float64(tileSize)/2, float64(y)+float64(tileSize)/2) + textOp.ColorScale.ScaleWithColor(tileColor(v)) + textOp.PrimaryAlign = text.AlignCenter + textOp.SecondaryAlign = text.AlignCenter + text.Draw(boardImage, str, &text.GoTextFace{ + Source: mplusFaceSource, + SizeInPoints: sizeInPoints, + }, textOp) } diff --git a/text/v2/gotext.go b/text/v2/gotext.go index fe2c1c7d8..3445538e6 100644 --- a/text/v2/gotext.go +++ b/text/v2/gotext.go @@ -179,7 +179,21 @@ func MustParseTag(str string) Tag { // Metrics implements Face. 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. diff --git a/text/v2/gotextfacesource.go b/text/v2/gotextfacesource.go index 63e838349..5047a8f1e 100644 --- a/text/v2/gotextfacesource.go +++ b/text/v2/gotextfacesource.go @@ -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) { g.m.Lock() defer g.m.Unlock()