diff --git a/README.md b/README.md index 12b2847..ba01bc8 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ import ( func main() { // Load fonts for normal, bold and italic text styles. - fonts, err := crt.LoadFaces("./fonts/SomeFont-Regular.ttf", "./fonts/SomeFont-Bold.ttf", "./fonts/SomeFont-Italic.ttf", 72.0, 16.0) + fonts, err := crt.LoadFaces("./fonts/SomeFont-Regular.ttf", "./fonts/SomeFont-Bold.ttf", "./fonts/SomeFont-Italic.ttf", crt.GetFontDPI(), 16.0) if err != nil { panic(err) } diff --git a/crt.go b/crt.go index c4f5f33..783ae68 100644 --- a/crt.go +++ b/crt.go @@ -73,12 +73,12 @@ func NewGame(width int, height int, fonts Fonts, tty io.Reader, adapter InputAda bounds, _, _ := fonts.Normal.GlyphBounds([]rune("█")[0]) size := bounds.Max.Sub(bounds.Min) - cellWidth := size.X.Round() - cellHeight := size.Y.Round() - cellOffsetY := -bounds.Min.Y.Round() + cellWidth := size.X.Ceil() + cellHeight := size.Y.Ceil() + cellOffsetY := -bounds.Min.Y.Ceil() - cellsWidth := width / cellWidth - cellsHeight := height / cellHeight + cellsWidth := int(float64(width)*DeviceScale()) / cellWidth + cellsHeight := int(float64(height)*DeviceScale()) / cellHeight grid := make([][]GridCell, cellsHeight) for y := 0; y < cellsHeight; y++ { @@ -597,14 +597,13 @@ func (g *Window) Draw(screen *ebiten.Image) { } func (g *Window) Layout(outsideWidth, outsideHeight int) (int, int) { - return g.cellsWidth * g.cellWidth, g.cellsHeight * g.cellHeight + s := DeviceScale() + return int(float64(outsideWidth) * s), int(float64(outsideHeight) * s) } func (g *Window) Run(title string) error { - sw, sh := g.Layout(0, 0) - ebiten.SetScreenFilterEnabled(false) - ebiten.SetWindowSize(sw, sh) + ebiten.SetWindowSize(int(float64(g.cellsWidth*g.cellWidth)/DeviceScale()), int(float64(g.cellsHeight*g.cellHeight)/DeviceScale())) ebiten.SetWindowTitle(title) if err := ebiten.RunGame(g); err != nil { return err diff --git a/dpi.go b/dpi.go new file mode 100644 index 0000000..e3454a8 --- /dev/null +++ b/dpi.go @@ -0,0 +1,26 @@ +package crt + +import ( + "github.com/hajimehoshi/ebiten/v2" + "os" + "strconv" +) + +// DeviceScale returns the current device scale factor. +// +// If the environment variable CRT_DEVICE_SCALE is set, it will be used instead. +func DeviceScale() float64 { + if os.Getenv("CRT_DEVICE_SCALE") != "" { + s, err := strconv.ParseFloat(os.Getenv("CRT_DEVICE_SCALE"), 64) + if err == nil { + return s + } + } + + return ebiten.DeviceScaleFactor() +} + +// GetFontDPI returns the recommended font DPI for the current device. +func GetFontDPI() float64 { + return 72.0 * DeviceScale() +} diff --git a/examples/benchmark/main.go b/examples/benchmark/main.go index de6fb73..8839bbd 100644 --- a/examples/benchmark/main.go +++ b/examples/benchmark/main.go @@ -47,7 +47,7 @@ func main() { enableShader := flag.Bool("shader", false, "Enable shader") flag.Parse() - fonts, err := crt.LoadFaces("./fonts/IosevkaTermNerdFontMono-Regular.ttf", "./fonts/IosevkaTermNerdFontMono-Bold.ttf", "./fonts/IosevkaTermNerdFontMono-Italic.ttf", 72.0, 9.0) + fonts, err := crt.LoadFaces("./fonts/IosevkaTermNerdFontMono-Regular.ttf", "./fonts/IosevkaTermNerdFontMono-Bold.ttf", "./fonts/IosevkaTermNerdFontMono-Italic.ttf", crt.GetFontDPI(), 9.0) if err != nil { panic(err) } diff --git a/examples/keys/main.go b/examples/keys/main.go index 034a6dd..bb11768 100644 --- a/examples/keys/main.go +++ b/examples/keys/main.go @@ -38,7 +38,7 @@ func (m model) View() string { } func main() { - fonts, err := crt.LoadFaces("./fonts/IosevkaTermNerdFontMono-Regular.ttf", "./fonts/IosevkaTermNerdFontMono-Bold.ttf", "./fonts/IosevkaTermNerdFontMono-Italic.ttf", 72.0, 16.0) + fonts, err := crt.LoadFaces("./fonts/IosevkaTermNerdFontMono-Regular.ttf", "./fonts/IosevkaTermNerdFontMono-Bold.ttf", "./fonts/IosevkaTermNerdFontMono-Italic.ttf", crt.GetFontDPI(), 16.0) if err != nil { panic(err) } diff --git a/examples/package-manager/main.go b/examples/package-manager/main.go index 76ee78e..8de2526 100644 --- a/examples/package-manager/main.go +++ b/examples/package-manager/main.go @@ -187,7 +187,7 @@ func max(a, b int) int { func main() { rand.Seed(time.Now().Unix()) - fonts, err := crt.LoadFaces("./fonts/IosevkaTermNerdFontMono-Regular.ttf", "./fonts/IosevkaTermNerdFontMono-Bold.ttf", "./fonts/IosevkaTermNerdFontMono-Italic.ttf", 72.0, 16.0) + fonts, err := crt.LoadFaces("./fonts/IosevkaTermNerdFontMono-Regular.ttf", "./fonts/IosevkaTermNerdFontMono-Bold.ttf", "./fonts/IosevkaTermNerdFontMono-Italic.ttf", crt.GetFontDPI(), 16.0) if err != nil { panic(err) } diff --git a/examples/shader/main.go b/examples/shader/main.go index 06705c3..70f3443 100644 --- a/examples/shader/main.go +++ b/examples/shader/main.go @@ -188,7 +188,7 @@ func max(a, b int) int { func main() { rand.Seed(time.Now().Unix()) - fonts, err := crt.LoadFaces("./fonts/IosevkaTermNerdFontMono-Regular.ttf", "./fonts/IosevkaTermNerdFontMono-Bold.ttf", "./fonts/IosevkaTermNerdFontMono-Italic.ttf", 72.0, 16.0) + fonts, err := crt.LoadFaces("./fonts/IosevkaTermNerdFontMono-Regular.ttf", "./fonts/IosevkaTermNerdFontMono-Bold.ttf", "./fonts/IosevkaTermNerdFontMono-Italic.ttf", crt.GetFontDPI(), 16.0) if err != nil { panic(err) } diff --git a/examples/simple/main.go b/examples/simple/main.go index ade1498..27547a2 100644 --- a/examples/simple/main.go +++ b/examples/simple/main.go @@ -29,7 +29,7 @@ func (m model) View() string { } func main() { - fonts, err := crt.LoadFaces("./fonts/IosevkaTermNerdFontMono-Regular.ttf", "./fonts/IosevkaTermNerdFontMono-Bold.ttf", "./fonts/IosevkaTermNerdFontMono-Italic.ttf", 72.0, 16.0) + fonts, err := crt.LoadFaces("./fonts/IosevkaTermNerdFontMono-Regular.ttf", "./fonts/IosevkaTermNerdFontMono-Bold.ttf", "./fonts/IosevkaTermNerdFontMono-Italic.ttf", crt.GetFontDPI(), 16.0) if err != nil { panic(err) }