main.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Copyright 2023 The Ebitengine Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package main
  15. import (
  16. "bytes"
  17. _ "embed"
  18. "fmt"
  19. "log"
  20. "github.com/hajimehoshi/ebiten/v2"
  21. "github.com/hajimehoshi/ebiten/v2/inpututil"
  22. "github.com/hajimehoshi/ebiten/v2/text/v2"
  23. )
  24. const (
  25. screenWidth = 640
  26. screenHeight = 480
  27. )
  28. //go:embed FiraSans-Regular.ttf
  29. var firaSansRegular []byte
  30. var firaSansFaceSource *text.GoTextFaceSource
  31. func init() {
  32. s, err := text.NewGoTextFaceSource(bytes.NewReader(firaSansRegular))
  33. if err != nil {
  34. log.Fatal(err)
  35. }
  36. firaSansFaceSource = s
  37. }
  38. type Game struct {
  39. // liga represents 'Standard Ligatures'.
  40. // https://learn.microsoft.com/en-us/typography/opentype/spec/features_ko#tag-liga
  41. liga uint32
  42. // tnum represents 'Tabular Figures'.
  43. // https://learn.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-tnum
  44. tnum uint32
  45. // smcp represents 'Small Capitals'.
  46. // https://learn.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-smcp
  47. smcp uint32
  48. // zero represents 'Slashed Zero'.
  49. // https://learn.microsoft.com/en-us/typography/opentype/spec/features_uz#tag-zero
  50. zero uint32
  51. }
  52. func (g *Game) Update() error {
  53. if inpututil.IsKeyJustPressed(ebiten.KeyL) {
  54. if g.liga == 0 {
  55. g.liga = 1
  56. } else {
  57. g.liga = 0
  58. }
  59. }
  60. if inpututil.IsKeyJustPressed(ebiten.KeyT) {
  61. if g.tnum == 0 {
  62. g.tnum = 1
  63. } else {
  64. g.tnum = 0
  65. }
  66. }
  67. if inpututil.IsKeyJustPressed(ebiten.KeyS) {
  68. if g.smcp == 0 {
  69. g.smcp = 1
  70. } else {
  71. g.smcp = 0
  72. }
  73. }
  74. if inpututil.IsKeyJustPressed(ebiten.KeyZ) {
  75. if g.zero == 0 {
  76. g.zero = 1
  77. } else {
  78. g.zero = 0
  79. }
  80. }
  81. return nil
  82. }
  83. func (g *Game) Draw(screen *ebiten.Image) {
  84. // Draw the instruction.
  85. inst := fmt.Sprintf(`Press keys to toggle font features.
  86. [L] 'liga' (Standard Ligatures) (%d)
  87. [T] 'tnum' (Tabular Figures) (%d)
  88. [S] 'smcp' (Small Capitals) (%d)
  89. [Z] 'zero' (Slashed Zero) (%d)`, g.liga, g.tnum, g.smcp, g.zero)
  90. op := &text.DrawOptions{}
  91. op.GeoM.Translate(20, 20)
  92. op.LineSpacing = 30
  93. text.Draw(screen, inst, &text.GoTextFace{
  94. Source: firaSansFaceSource,
  95. Size: 20,
  96. }, op)
  97. // Draw the sample text.
  98. const sampleText = `0 (Number) / O (Alphabet)
  99. ffi
  100. 3.14
  101. 2.71`
  102. op = &text.DrawOptions{}
  103. op.GeoM.Translate(20, screenHeight/2)
  104. op.LineSpacing = 50
  105. f := &text.GoTextFace{
  106. Source: firaSansFaceSource,
  107. Size: 40,
  108. }
  109. f.SetFeature(text.MustParseTag("liga"), g.liga)
  110. f.SetFeature(text.MustParseTag("tnum"), g.tnum)
  111. f.SetFeature(text.MustParseTag("smcp"), g.smcp)
  112. f.SetFeature(text.MustParseTag("zero"), g.zero)
  113. text.Draw(screen, sampleText, f, op)
  114. }
  115. func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
  116. return screenWidth, screenHeight
  117. }
  118. func main() {
  119. ebiten.SetWindowSize(screenWidth, screenHeight)
  120. ebiten.SetWindowTitle("Font Feature (Ebitengine Demo)")
  121. if err := ebiten.RunGame(&Game{}); err != nil {
  122. log.Fatal(err)
  123. }
  124. }