BioErrorLog Tech Blog

試行錯誤の記録

Ebitengineのテキスト描画位置と指定座標の関係を理解する

text/v2はテキストの左上、text/v1ではテキストのベースライン左端が指定座標になります。

はじめに

Ebitengineでtext描写をtext/v1からtext/v2に書き換えたところ、テキストが描画される場所が変わりました。

それぞれで指定座標に対してどの位置にテキストが描画されるのか、調べてまとめます。

The English translation of this post is here.

Ebitengineのテキスト描画位置と指定座標の関係

まずドキュメントで仕様を確認してから、実際にコードを実行して確かめます。

ドキュメントを確認

By default, if the face's primary direction is left-to-right, the rendering region's upper-left position is (0, 0). Note that this is different from text v1. In text v1, (0, 0) is always the origin position.

Ref. text package - github.com/hajimehoshi/ebiten/v2/text/v2 - Go Packages

このように、ドキュメントによると

  • text/v2ではテキストの左端
  • text/v1ではテキストのorigin position (ベースライン左端の原点)

が指定座標になるようです。

なおベースラインとは、英語などの文字の並び線を指します。

ベースラインの位置 | 画像はwikipediaより引用: Baseline (typography) - Wikipedia

実際にやってみる

では、実際に指定座標に対し、text/v2とtext/v1がそれぞれどの位置にテキストを描画するのかを確かめてみます。

下記のコードを用意しました。 画面中央の座標を指定してテキストを描画し、text/v2とtext/v1でどのような違いがあるのかを確かめます。

package main

import (
    "image/color"
    "log"

    "github.com/hajimehoshi/ebiten/v2"
    testv1 "github.com/hajimehoshi/ebiten/v2/text"
    textv2 "github.com/hajimehoshi/ebiten/v2/text/v2"
    "github.com/hajimehoshi/ebiten/v2/vector"
    "golang.org/x/image/font/basicfont"
)

const (
    screenWidth  = 200
    screenHeight = 200
    centerX      = screenWidth / 2
    centerY      = screenHeight / 2
)

type Game struct {
    faceV2 *textv2.GoXFace
}

func (g *Game) Update() error {
    return nil
}

func (g *Game) Draw(screen *ebiten.Image) {
    // Center lines
    vector.StrokeLine(screen, centerX, 0, centerX, screenHeight, 1, color.White, false)
    vector.StrokeLine(screen, 0, centerY, screenWidth, centerY, 1, color.White, false)
    vector.DrawFilledCircle(screen, centerX, centerY, 3, color.White, false)

    // text v1 drawing at the center
    testv1.Draw(screen, "Text v1", basicfont.Face7x13, centerX, centerY, color.White)

    // text v2 drawing at the center
    op := &textv2.DrawOptions{}
    op.GeoM.Translate(centerX, centerY)
    op.ColorScale.ScaleWithColor(color.White)
    textv2.Draw(screen, "Text v2", g.faceV2, op)
}

func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
    return screenWidth, screenHeight
}

func main() {
    // Font face for text v2
    faceV2 := textv2.NewGoXFace(basicfont.Face7x13)

    game := &Game{
        faceV2: faceV2,
    }

    ebiten.SetWindowSize(screenWidth*2, screenHeight*2)
    ebiten.SetWindowTitle("Text v1 vs v2 Behavior Test")

    if err := ebiten.RunGame(game); err != nil {
        log.Fatal(err)
    }
}

コード全体はこちらに配置しています:

github.com

実行結果はこちら:

画面中央点を指定して、text/v2とtext/v1で描画した結果

このように、text/v2では指定座標がテキストの左上、text/v1では指定座標がテキストのベースライン左端になることが確認できました。

おわりに

以上、Ebitengineのテキスト描画位置と指定座標の関係を整理してまとめました。

どなたかの参考になれば幸いです。

[関連記事]

www.bioerrorlog.work

参考