github.com/Kintar/etxt@v0.0.0-20221224033739-2fc69f000137/ecache/impl_default_handler.go (about) 1 package ecache 2 3 import "unsafe" 4 import "golang.org/x/image/math/fixed" 5 6 import "github.com/Kintar/etxt/emask" 7 8 // A default implementation of [GlyphCacheHandler]. 9 type DefaultCacheHandler struct { 10 cache *DefaultCache 11 activeKey [3]uint64 12 } 13 14 // Implements [GlyphCacheHandler].NotifyFontChange(...) 15 func (self *DefaultCacheHandler) NotifyFontChange(font *Font) { 16 self.activeKey[0] = uint64(uintptr(unsafe.Pointer(font))) 17 } 18 19 // Implements [GlyphCacheHandler].NotifyRasterizerChange(...) 20 func (self *DefaultCacheHandler) NotifyRasterizerChange(rasterizer emask.Rasterizer) { 21 self.activeKey[1] = rasterizer.CacheSignature() 22 } 23 24 // Implements [GlyphCacheHandler].NotifySizeChange(...) 25 func (self *DefaultCacheHandler) NotifySizeChange(size fixed.Int26_6) { 26 self.activeKey[2] = (self.activeKey[2] & ^uint64(0xFFFFFFFF00000000)) | (uint64(size) << 32) 27 } 28 29 // Implements [GlyphCacheHandler].NotifyFractChange(...) 30 func (self *DefaultCacheHandler) NotifyFractChange(fract fixed.Point26_6) { 31 bits := uint64(fract.Y&0x0000003F) << 16 32 bits |= uint64(fract.X&0x0000003F) << 22 33 self.activeKey[2] = (self.activeKey[2] & ^uint64(0x000000000FFF0000)) | bits 34 } 35 36 // This is not a thing nowadays, but if sfnt ever implemented proper hinting 37 // and you could detect whether a glyph mask has hinting instructions applied 38 // or not, or if you implemented some other hinting mechanism yourself, you 39 // could use this "variant" change to differentiate the glyphs. This code 40 // only allows 4 bits to encode variants, but since etxt.Renderer doesn't 41 // use all the bits from the size, we could easily shave ~12 bits more from 42 // the size key encoding and go up to 16 bits for variants. 43 // 44 // For rasterizer-based hinting it doesn't matter much, though, as the 64 45 // bits from their cache signature can also do the job. 46 // func (self *DefaultCacheHandler) NotifyVariantChange(variant uint8) { 47 // self.activeKey[2] = (self.activeKey[2] & ^uint64(0x00000000F0000000)) | (uint64(variant ^ 0x0F) << 28) 48 // } 49 50 // Implements [GlyphCacheHandler].GetMask(...) 51 func (self *DefaultCacheHandler) GetMask(index GlyphIndex) (GlyphMask, bool) { 52 self.activeKey[2] = (self.activeKey[2] & ^uint64(0x000000000000FFFF)) | uint64(index) 53 return self.cache.GetMask(self.activeKey) 54 } 55 56 // Implements [GlyphCacheHandler].PassMask(...) 57 func (self *DefaultCacheHandler) PassMask(index GlyphIndex, mask GlyphMask) { 58 self.activeKey[2] = (self.activeKey[2] & ^uint64(0x000000000000FFFF)) | uint64(index) 59 self.cache.PassMask(self.activeKey, mask) 60 } 61 62 // Provides access to [DefaultCache.ApproxByteSize](). 63 func (self *DefaultCacheHandler) ApproxCacheByteSize() int { 64 return self.cache.ApproxByteSize() 65 } 66 67 // Provides access to [DefaultCache.PeakSize](). 68 func (self *DefaultCacheHandler) PeakCacheSize() int { 69 return self.cache.PeakSize() 70 }