mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
9576b659d7
These fields are no longer needed with the new text shaper. Advances is redundant to the glyph information, and Text should never be used during layout, as you should traverse the cluster list instead. This commit also removed the now-unused string field from the path LRU cache key. References: https://todo.sr.ht/~eliasnaur/gio/146 Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
125 lines
2.2 KiB
Go
125 lines
2.2 KiB
Go
// SPDX-License-Identifier: Unlicense OR MIT
|
|
|
|
package text
|
|
|
|
import (
|
|
"gioui.org/io/system"
|
|
"gioui.org/op/clip"
|
|
"golang.org/x/image/math/fixed"
|
|
)
|
|
|
|
type layoutCache struct {
|
|
m map[layoutKey]*layoutElem
|
|
head, tail *layoutElem
|
|
}
|
|
|
|
type pathCache struct {
|
|
m map[pathKey]*path
|
|
head, tail *path
|
|
}
|
|
|
|
type layoutElem struct {
|
|
next, prev *layoutElem
|
|
key layoutKey
|
|
layout []Line
|
|
}
|
|
|
|
type path struct {
|
|
next, prev *path
|
|
key pathKey
|
|
val clip.PathSpec
|
|
layout Layout
|
|
}
|
|
|
|
type layoutKey struct {
|
|
ppem fixed.Int26_6
|
|
maxWidth int
|
|
str string
|
|
locale system.Locale
|
|
}
|
|
|
|
type pathKey struct {
|
|
ppem fixed.Int26_6
|
|
gidHash uint64
|
|
}
|
|
|
|
const maxSize = 1000
|
|
|
|
func (l *layoutCache) Get(k layoutKey) ([]Line, bool) {
|
|
if lt, ok := l.m[k]; ok {
|
|
l.remove(lt)
|
|
l.insert(lt)
|
|
return lt.layout, true
|
|
}
|
|
return nil, false
|
|
}
|
|
|
|
func (l *layoutCache) Put(k layoutKey, lt []Line) {
|
|
if l.m == nil {
|
|
l.m = make(map[layoutKey]*layoutElem)
|
|
l.head = new(layoutElem)
|
|
l.tail = new(layoutElem)
|
|
l.head.prev = l.tail
|
|
l.tail.next = l.head
|
|
}
|
|
val := &layoutElem{key: k, layout: lt}
|
|
l.m[k] = val
|
|
l.insert(val)
|
|
if len(l.m) > maxSize {
|
|
oldest := l.tail.next
|
|
l.remove(oldest)
|
|
delete(l.m, oldest.key)
|
|
}
|
|
}
|
|
|
|
func (l *layoutCache) remove(lt *layoutElem) {
|
|
lt.next.prev = lt.prev
|
|
lt.prev.next = lt.next
|
|
}
|
|
|
|
func (l *layoutCache) insert(lt *layoutElem) {
|
|
lt.next = l.head
|
|
lt.prev = l.head.prev
|
|
lt.prev.next = lt
|
|
lt.next.prev = lt
|
|
}
|
|
|
|
func (c *pathCache) Get(k pathKey, l Layout) (clip.PathSpec, bool) {
|
|
if v, ok := c.m[k]; ok && l.equals(v.layout) {
|
|
c.remove(v)
|
|
c.insert(v)
|
|
return v.val, true
|
|
}
|
|
return clip.PathSpec{}, false
|
|
}
|
|
|
|
func (c *pathCache) Put(k pathKey, l Layout, v clip.PathSpec) {
|
|
if c.m == nil {
|
|
c.m = make(map[pathKey]*path)
|
|
c.head = new(path)
|
|
c.tail = new(path)
|
|
c.head.prev = c.tail
|
|
c.tail.next = c.head
|
|
}
|
|
val := &path{key: k, val: v, layout: l}
|
|
c.m[k] = val
|
|
c.insert(val)
|
|
if len(c.m) > maxSize {
|
|
oldest := c.tail.next
|
|
c.remove(oldest)
|
|
delete(c.m, oldest.key)
|
|
}
|
|
}
|
|
|
|
func (c *pathCache) remove(v *path) {
|
|
v.next.prev = v.prev
|
|
v.prev.next = v.next
|
|
}
|
|
|
|
func (c *pathCache) insert(v *path) {
|
|
v.next = c.head
|
|
v.prev = c.head.prev
|
|
v.prev.next = v
|
|
v.next.prev = v
|
|
}
|