github.com/jmigpin/editor@v1.6.0/util/fontutil/facecachel2.go (about) 1 package fontutil 2 3 import ( 4 "image" 5 "sync" 6 7 "golang.org/x/image/font" 8 "golang.org/x/image/math/fixed" 9 ) 10 11 // Same as FaceCacheL but with sync.map. 12 type FaceCacheL2 struct { 13 font.Face 14 mu sync.RWMutex 15 gc sync.Map 16 gac sync.Map 17 gbc sync.Map 18 kc sync.Map // kern cache 19 } 20 21 func NewFaceCacheL2(face font.Face) *FaceCacheL2 { 22 fc := &FaceCacheL2{Face: face} 23 return fc 24 } 25 func (fc *FaceCacheL2) Glyph(dot fixed.Point26_6, ru rune) ( 26 dr image.Rectangle, 27 mask image.Image, 28 maskp image.Point, 29 advance fixed.Int26_6, 30 ok bool, 31 ) { 32 v, ok := fc.gc.Load(ru) 33 var gc *GlyphCache 34 if ok { 35 gc = v.(*GlyphCache) 36 } else { 37 fc.mu.Lock() 38 gc = NewGlyphCache(fc.Face, ru) 39 fc.gc.Store(ru, gc) 40 fc.mu.Unlock() 41 } 42 p := image.Point{dot.X.Floor(), dot.Y.Floor()} 43 dr2 := gc.dr.Add(p) 44 return dr2, gc.mask, gc.maskp, gc.advance, gc.ok 45 } 46 func (fc *FaceCacheL2) GlyphAdvance(ru rune) (advance fixed.Int26_6, ok bool) { 47 v, ok := fc.gac.Load(ru) 48 var gac *GlyphAdvanceCache 49 if ok { 50 gac = v.(*GlyphAdvanceCache) 51 } else { 52 fc.mu.Lock() 53 gac = NewGlyphAdvanceCache(fc.Face, ru) 54 fc.gac.Store(ru, gac) 55 fc.mu.Unlock() 56 } 57 return gac.advance, gac.ok 58 } 59 func (fc *FaceCacheL2) GlyphBounds(ru rune) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, ok bool) { 60 v, ok := fc.gbc.Load(ru) 61 var gbc *GlyphBoundsCache 62 if ok { 63 gbc = v.(*GlyphBoundsCache) 64 } else { 65 fc.mu.Lock() 66 gbc = NewGlyphBoundsCache(fc.Face, ru) 67 fc.gbc.Store(ru, gbc) 68 fc.mu.Unlock() 69 } 70 return gbc.bounds, gbc.advance, gbc.ok 71 } 72 func (fc *FaceCacheL2) Kern(r0, r1 rune) fixed.Int26_6 { 73 i := kernIndex(r0, r1) 74 v, ok := fc.kc.Load(i) 75 var k fixed.Int26_6 76 if ok { 77 k = v.(fixed.Int26_6) 78 } else { 79 fc.mu.Lock() 80 k = NewKernCache(fc.Face, r0, r1) 81 fc.kc.Store(i, k) 82 fc.mu.Unlock() 83 } 84 return k 85 }