aboutsummaryrefslogtreecommitdiff
path: root/vendor/gioui.org/text/shaper.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gioui.org/text/shaper.go')
-rw-r--r--vendor/gioui.org/text/shaper.go95
1 files changed, 53 insertions, 42 deletions
diff --git a/vendor/gioui.org/text/shaper.go b/vendor/gioui.org/text/shaper.go
index c4ec48c..59020e0 100644
--- a/vendor/gioui.org/text/shaper.go
+++ b/vendor/gioui.org/text/shaper.go
@@ -6,21 +6,19 @@ import (
"io"
"strings"
- "gioui.org/op"
"golang.org/x/image/math/fixed"
+
+ "gioui.org/op/clip"
)
// Shaper implements layout and shaping of text.
type Shaper interface {
// Layout a text according to a set of options.
Layout(font Font, size fixed.Int26_6, maxWidth int, txt io.Reader) ([]Line, error)
- // Shape a line of text and return a clipping operation for its outline.
- Shape(font Font, size fixed.Int26_6, layout []Glyph) op.CallOp
-
- // LayoutString is like Layout, but for strings.
+ // LayoutString is Layout for strings.
LayoutString(font Font, size fixed.Int26_6, maxWidth int, str string) []Line
- // ShapeString is like Shape for lines previously laid out by LayoutString.
- ShapeString(font Font, size fixed.Int26_6, str string, layout []Glyph) op.CallOp
+ // Shape a line of text and return a clipping operation for its outline.
+ Shape(font Font, size fixed.Int26_6, layout Layout) clip.PathSpec
}
// A FontFace is a Font and a matching Face.
@@ -49,8 +47,7 @@ type faceCache struct {
}
func (c *Cache) lookup(font Font) *faceCache {
- var f *faceCache
- f = c.faceForStyle(font)
+ f := c.faceForStyle(font)
if f == nil {
font.Typeface = c.def
f = c.faceForStyle(font)
@@ -59,24 +56,42 @@ func (c *Cache) lookup(font Font) *faceCache {
}
func (c *Cache) faceForStyle(font Font) *faceCache {
- tf := c.faces[font]
- if tf == nil {
- font := font
- font.Weight = Normal
- tf = c.faces[font]
+ if closest, ok := c.closestFont(font); ok {
+ return c.faces[closest]
}
- if tf == nil {
- font := font
- font.Style = Regular
- tf = c.faces[font]
+ font.Style = Regular
+ if closest, ok := c.closestFont(font); ok {
+ return c.faces[closest]
}
- if tf == nil {
- font := font
- font.Style = Regular
- font.Weight = Normal
- tf = c.faces[font]
+ return nil
+}
+
+// closestFont returns the closest Font by weight, in case of equality the
+// lighter weight will be returned.
+func (c *Cache) closestFont(lookup Font) (Font, bool) {
+ if c.faces[lookup] != nil {
+ return lookup, true
}
- return tf
+ found := false
+ var match Font
+ for cf := range c.faces {
+ if cf.Typeface != lookup.Typeface || cf.Variant != lookup.Variant || cf.Style != lookup.Style {
+ continue
+ }
+ if !found {
+ found = true
+ match = cf
+ continue
+ }
+ cDist := weightDistance(lookup.Weight, cf.Weight)
+ mDist := weightDistance(lookup.Weight, match.Weight)
+ if cDist < mDist {
+ match = cf
+ } else if cDist == mDist && cf.Weight < match.Weight {
+ match = cf
+ }
+ }
+ return match, found
}
func NewCache(collection []FontFace) *Cache {
@@ -84,9 +99,6 @@ func NewCache(collection []FontFace) *Cache {
faces: make(map[Font]*faceCache),
}
for i, ff := range collection {
- if ff.Font.Weight == 0 {
- ff.Font.Weight = Normal
- }
if i == 0 {
c.def = ff.Font.Typeface
}
@@ -95,24 +107,23 @@ func NewCache(collection []FontFace) *Cache {
return c
}
-func (s *Cache) Layout(font Font, size fixed.Int26_6, maxWidth int, txt io.Reader) ([]Line, error) {
- cache := s.lookup(font)
+// Layout implements the Shaper interface.
+func (c *Cache) Layout(font Font, size fixed.Int26_6, maxWidth int, txt io.Reader) ([]Line, error) {
+ cache := c.lookup(font)
return cache.face.Layout(size, maxWidth, txt)
}
-func (s *Cache) Shape(font Font, size fixed.Int26_6, layout []Glyph) op.CallOp {
- cache := s.lookup(font)
- return cache.face.Shape(size, layout)
-}
-
-func (s *Cache) LayoutString(font Font, size fixed.Int26_6, maxWidth int, str string) []Line {
- cache := s.lookup(font)
+// LayoutString is a caching implementation of the Shaper interface.
+func (c *Cache) LayoutString(font Font, size fixed.Int26_6, maxWidth int, str string) []Line {
+ cache := c.lookup(font)
return cache.layout(size, maxWidth, str)
}
-func (s *Cache) ShapeString(font Font, size fixed.Int26_6, str string, layout []Glyph) op.CallOp {
- cache := s.lookup(font)
- return cache.shape(size, str, layout)
+// Shape is a caching implementation of the Shaper interface. Shape assumes that the layout
+// argument is unchanged from a call to Layout or LayoutString.
+func (c *Cache) Shape(font Font, size fixed.Int26_6, layout Layout) clip.PathSpec {
+ cache := c.lookup(font)
+ return cache.shape(size, layout)
}
func (f *faceCache) layout(ppem fixed.Int26_6, maxWidth int, str string) []Line {
@@ -132,13 +143,13 @@ func (f *faceCache) layout(ppem fixed.Int26_6, maxWidth int, str string) []Line
return l
}
-func (f *faceCache) shape(ppem fixed.Int26_6, str string, layout []Glyph) op.CallOp {
+func (f *faceCache) shape(ppem fixed.Int26_6, layout Layout) clip.PathSpec {
if f == nil {
- return op.CallOp{}
+ return clip.PathSpec{}
}
pk := pathKey{
ppem: ppem,
- str: str,
+ str: layout.Text,
}
if clip, ok := f.pathCache.Get(pk); ok {
return clip