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  }