1
0

cache.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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 text
  15. import (
  16. "image"
  17. "golang.org/x/image/font"
  18. "golang.org/x/image/math/fixed"
  19. )
  20. type glyphBoundsCacheValue struct {
  21. bounds fixed.Rectangle26_6
  22. advance fixed.Int26_6
  23. ok bool
  24. }
  25. type glyphAdvanceCacheValue struct {
  26. advance fixed.Int26_6
  27. ok bool
  28. }
  29. type kernCacheKey struct {
  30. r0 rune
  31. r1 rune
  32. }
  33. type faceWithCache struct {
  34. f font.Face
  35. metrics font.Metrics
  36. glyphBoundsCache map[rune]glyphBoundsCacheValue
  37. glyphAdvanceCache map[rune]glyphAdvanceCacheValue
  38. kernCache map[kernCacheKey]fixed.Int26_6
  39. }
  40. func (f *faceWithCache) Close() error {
  41. if err := f.f.Close(); err != nil {
  42. return err
  43. }
  44. f.glyphBoundsCache = nil
  45. f.glyphAdvanceCache = nil
  46. f.kernCache = nil
  47. return nil
  48. }
  49. var faceWithCacheCache map[font.Face]*faceWithCache
  50. func faceWithCacheFromFace(face font.Face) *faceWithCache {
  51. if f, ok := faceWithCacheCache[face]; ok {
  52. return f
  53. }
  54. f := &faceWithCache{
  55. f: face,
  56. }
  57. if faceWithCacheCache == nil {
  58. faceWithCacheCache = map[font.Face]*faceWithCache{}
  59. }
  60. faceWithCacheCache[face] = f
  61. return f
  62. }
  63. func (f *faceWithCache) Glyph(dot fixed.Point26_6, r rune) (dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool) {
  64. // TODO: Move glyphImageCache to here.
  65. return f.f.Glyph(dot, r)
  66. }
  67. func (f *faceWithCache) GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, ok bool) {
  68. if v, ok := f.glyphBoundsCache[r]; ok {
  69. return v.bounds, v.advance, v.ok
  70. }
  71. bounds, advance, ok = f.f.GlyphBounds(r)
  72. if f.glyphBoundsCache == nil {
  73. f.glyphBoundsCache = map[rune]glyphBoundsCacheValue{}
  74. }
  75. f.glyphBoundsCache[r] = glyphBoundsCacheValue{
  76. bounds: bounds,
  77. advance: advance,
  78. ok: ok,
  79. }
  80. return
  81. }
  82. func (f *faceWithCache) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) {
  83. if v, ok := f.glyphAdvanceCache[r]; ok {
  84. return v.advance, v.ok
  85. }
  86. advance, ok = f.f.GlyphAdvance(r)
  87. if f.glyphAdvanceCache == nil {
  88. f.glyphAdvanceCache = map[rune]glyphAdvanceCacheValue{}
  89. }
  90. f.glyphAdvanceCache[r] = glyphAdvanceCacheValue{
  91. advance: advance,
  92. ok: ok,
  93. }
  94. return
  95. }
  96. func (f *faceWithCache) Kern(r0, r1 rune) fixed.Int26_6 {
  97. key := kernCacheKey{r0: r0, r1: r1}
  98. if v, ok := f.kernCache[key]; ok {
  99. return v
  100. }
  101. v := f.f.Kern(r0, r1)
  102. if f.kernCache == nil {
  103. f.kernCache = map[kernCacheKey]fixed.Int26_6{}
  104. }
  105. f.kernCache[key] = v
  106. return v
  107. }
  108. func (f *faceWithCache) Metrics() font.Metrics {
  109. if f.metrics != (font.Metrics{}) {
  110. return f.metrics
  111. }
  112. f.metrics = f.f.Metrics()
  113. return f.metrics
  114. }