github.com/Kintar/etxt@v0.0.0-20221224033739-2fc69f000137/examples/ebiten/select_rect_viz/main.go (about) 1 package main 2 3 import "image" 4 import "os" 5 import "image/color" 6 import "log" 7 import "fmt" 8 9 import "github.com/hajimehoshi/ebiten/v2" 10 import "github.com/Kintar/etxt" 11 12 // This example allows you to interactively write text in an Ebitengine 13 // program and see how the SelectionRect for the text changes. You 14 // can use backspace to remove characters, and enter to create line 15 // breaks. 16 17 type Game struct { 18 txtRenderer *etxt.Renderer 19 sinceLastSpecialKey int 20 text []rune 21 } 22 23 func (self *Game) Layout(w int, h int) (int, int) { 24 scale := ebiten.DeviceScaleFactor() 25 return int(float64(w) * scale), int(float64(h) * scale) 26 } 27 func (self *Game) Update() error { 28 backspacePressed := ebiten.IsKeyPressed(ebiten.KeyBackspace) 29 enterPressed := ebiten.IsKeyPressed(ebiten.KeyEnter) 30 31 if backspacePressed && self.sinceLastSpecialKey >= 7 && len(self.text) >= 1 { 32 self.sinceLastSpecialKey = 0 33 self.text = self.text[0 : len(self.text)-1] 34 } else if enterPressed && self.sinceLastSpecialKey >= 20 { 35 self.sinceLastSpecialKey = 0 36 self.text = append(self.text, '\n') 37 } else { 38 self.sinceLastSpecialKey += 1 39 self.text = ebiten.AppendInputChars(self.text) 40 } 41 42 return nil 43 } 44 45 func (self *Game) Draw(screen *ebiten.Image) { 46 // dark background 47 screen.Fill(color.RGBA{2, 1, 0, 255}) 48 49 // draw text's selection rect 50 x, y := 8, 8 51 rect := self.txtRenderer.SelectionRect(string(self.text)).ImageRect() 52 rectImg := screen.SubImage(rect.Add(image.Pt(x, y))).(*ebiten.Image) 53 rectImg.Fill(color.RGBA{8, 72, 88, 255}) 54 55 // draw text 56 self.txtRenderer.SetTarget(screen) 57 self.txtRenderer.Draw(string(self.text), x, y) 58 59 // draw fps and other info for fun 60 self.txtRenderer.SetAlign(etxt.Bottom, etxt.Right) 61 w, h := screen.Size() 62 info := fmt.Sprintf("%d glyphs - %.2fFPS", len(self.text), ebiten.CurrentFPS()) 63 self.txtRenderer.Draw(info, w-2, h-2) 64 self.txtRenderer.SetAlign(etxt.Top, etxt.Left) 65 } 66 67 func main() { 68 // get font path 69 if len(os.Args) != 2 { 70 msg := "Usage: expects one argument with the path to the font to be used\n" 71 fmt.Fprint(os.Stderr, msg) 72 os.Exit(1) 73 } 74 75 // parse font 76 font, fontName, err := etxt.ParseFontFrom(os.Args[1]) 77 if err != nil { 78 log.Fatal(err) 79 } 80 fmt.Printf("Font loaded: %s\n", fontName) 81 82 // create cache 83 cache := etxt.NewDefaultCache(1024 * 1024 * 1024) // 1GB cache 84 85 // create and configure renderer 86 scale := ebiten.DeviceScaleFactor() 87 renderer := etxt.NewStdRenderer() 88 renderer.SetCacheHandler(cache.NewHandler()) 89 renderer.SetSizePx(int(18 * scale)) 90 renderer.SetFont(font) 91 renderer.SetAlign(etxt.Top, etxt.Left) 92 renderer.SetColor(color.RGBA{255, 255, 255, 255}) // white 93 94 // run the game 95 ebiten.SetWindowTitle("etxt/examples/ebiten/select_rect_viz") 96 ebiten.SetWindowSize(640, 480) 97 err = ebiten.RunGame(&Game{renderer, 0, []rune("Interactive text")}) 98 if err != nil { 99 log.Fatal(err) 100 } 101 }