From e25b1639b9efb65b8c25329dffdd2f4ec8883833 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Mon, 13 Jan 2020 14:48:31 +0100 Subject: [PATCH] text: make Shaper an interface And rename out the caching implementation to FontRegistry. Signed-off-by: Elias Naur --- font/font.go | 4 ++-- text/shaper.go | 25 ++++++++++++++++--------- widget/editor.go | 6 +++--- widget/label.go | 2 +- widget/material/button.go | 2 +- widget/material/checkable.go | 2 +- widget/material/editor.go | 2 +- widget/material/label.go | 2 +- widget/material/theme.go | 2 +- 9 files changed, 27 insertions(+), 20 deletions(-) diff --git a/font/font.go b/font/font.go index 1a5dd118..0b90251d 100644 --- a/font/font.go +++ b/font/font.go @@ -12,12 +12,12 @@ import ( var ( mu sync.Mutex initialized bool - shaper = new(text.Shaper) + shaper = new(text.FontRegistry) ) // Default returns a singleton *text.Shaper that contains // the registered fonts. -func Default() *text.Shaper { +func Default() *text.FontRegistry { mu.Lock() defer mu.Unlock() initialized = true diff --git a/text/shaper.go b/text/shaper.go index d9f0f584..39bc459b 100644 --- a/text/shaper.go +++ b/text/shaper.go @@ -12,12 +12,19 @@ import ( "golang.org/x/image/math/fixed" ) -// Shaper implements layout and shaping of text and a cache of +// Shaper implements layout and shaping of text. +type Shaper interface { + Layout(c unit.Converter, font Font, str string, opts LayoutOptions) *Layout + Shape(c unit.Converter, font Font, str String) op.CallOp + Metrics(c unit.Converter, font Font) font.Metrics +} + +// FontRegistry implements layout and shaping of text and a cache of // computed results. // -// If a font matches no registered shape, Shaper falls back to the +// If a font matches no registered shape, FontRegistry falls back to the // first registered face. -type Shaper struct { +type FontRegistry struct { def Typeface faces map[Font]*face } @@ -28,7 +35,7 @@ type face struct { pathCache pathCache } -func (s *Shaper) Register(font Font, tf Face) { +func (s *FontRegistry) Register(font Font, tf Face) { if s.faces == nil { s.def = font.Typeface s.faces = make(map[Font]*face) @@ -43,22 +50,22 @@ func (s *Shaper) Register(font Font, tf Face) { } } -func (s *Shaper) Layout(c unit.Converter, font Font, str string, opts LayoutOptions) *Layout { +func (s *FontRegistry) Layout(c unit.Converter, font Font, str string, opts LayoutOptions) *Layout { tf := s.faceForFont(font) return tf.layout(fixed.I(c.Px(font.Size)), str, opts) } -func (s *Shaper) Shape(c unit.Converter, font Font, str String) op.CallOp { +func (s *FontRegistry) Shape(c unit.Converter, font Font, str String) op.CallOp { tf := s.faceForFont(font) return tf.shape(fixed.I(c.Px(font.Size)), str) } -func (s *Shaper) Metrics(c unit.Converter, font Font) font.Metrics { +func (s *FontRegistry) Metrics(c unit.Converter, font Font) font.Metrics { tf := s.faceForFont(font) return tf.metrics(fixed.I(c.Px(font.Size))) } -func (s *Shaper) faceForStyle(font Font) *face { +func (s *FontRegistry) faceForStyle(font Font) *face { tf := s.faces[font] if tf == nil { font := font @@ -79,7 +86,7 @@ func (s *Shaper) faceForStyle(font Font) *face { return tf } -func (s *Shaper) faceForFont(font Font) *face { +func (s *FontRegistry) faceForFont(font Font) *face { font.Size = unit.Value{} tf := s.faceForStyle(font) if tf == nil { diff --git a/widget/editor.go b/widget/editor.go index 7ba8d3c8..0ae7d359 100644 --- a/widget/editor.go +++ b/widget/editor.go @@ -213,7 +213,7 @@ func (e *Editor) Focus() { } // Layout lays out the editor. -func (e *Editor) Layout(gtx *layout.Context, sh *text.Shaper, font text.Font) { +func (e *Editor) Layout(gtx *layout.Context, sh text.Shaper, font text.Font) { // Flush events from before the previous frame. copy(e.events, e.events[e.prevEvents:]) e.events = e.events[:len(e.events)-e.prevEvents] @@ -226,7 +226,7 @@ func (e *Editor) Layout(gtx *layout.Context, sh *text.Shaper, font text.Font) { e.layout(gtx, sh) } -func (e *Editor) layout(gtx *layout.Context, sh *text.Shaper) { +func (e *Editor) layout(gtx *layout.Context, sh text.Shaper) { // Crude configuration change detection. if scale := gtx.Px(unit.Sp(100)); scale != e.scale { e.invalidate() @@ -430,7 +430,7 @@ func (e *Editor) moveCoord(c unit.Converter, pos image.Point) { e.moveToLine(x, carLine) } -func (e *Editor) layoutText(c unit.Converter, s *text.Shaper, font text.Font) ([]text.Line, layout.Dimensions) { +func (e *Editor) layoutText(c unit.Converter, s text.Shaper, font text.Font) ([]text.Line, layout.Dimensions) { txt := e.rr.String() opts := text.LayoutOptions{MaxWidth: e.maxWidth} textLayout := s.Layout(c, font, txt, opts) diff --git a/widget/label.go b/widget/label.go index 16927b06..768ae797 100644 --- a/widget/label.go +++ b/widget/label.go @@ -82,7 +82,7 @@ func (l *lineIterator) Next() (text.String, f32.Point, bool) { return text.String{}, f32.Point{}, false } -func (l Label) Layout(gtx *layout.Context, s *text.Shaper, font text.Font, txt string) { +func (l Label) Layout(gtx *layout.Context, s text.Shaper, font text.Font, txt string) { cs := gtx.Constraints textLayout := s.Layout(gtx, font, txt, text.LayoutOptions{MaxWidth: cs.Width.Max}) lines := textLayout.Lines diff --git a/widget/material/button.go b/widget/material/button.go index b1a440d5..8110e60e 100644 --- a/widget/material/button.go +++ b/widget/material/button.go @@ -24,7 +24,7 @@ type Button struct { Font text.Font Background color.RGBA CornerRadius unit.Value - shaper *text.Shaper + shaper text.Shaper } type IconButton struct { diff --git a/widget/material/checkable.go b/widget/material/checkable.go index 53c5eaff..e9e8d384 100644 --- a/widget/material/checkable.go +++ b/widget/material/checkable.go @@ -20,7 +20,7 @@ type checkable struct { Font text.Font IconColor color.RGBA Size unit.Value - shaper *text.Shaper + shaper text.Shaper checkedStateIcon *Icon uncheckedStateIcon *Icon } diff --git a/widget/material/editor.go b/widget/material/editor.go index 34ec8be7..5d12155e 100644 --- a/widget/material/editor.go +++ b/widget/material/editor.go @@ -21,7 +21,7 @@ type Editor struct { // HintColor is the color of hint text. HintColor color.RGBA - shaper *text.Shaper + shaper text.Shaper } func (t *Theme) Editor(hint string) Editor { diff --git a/widget/material/label.go b/widget/material/label.go index c4c6dca1..c3aea991 100644 --- a/widget/material/label.go +++ b/widget/material/label.go @@ -23,7 +23,7 @@ type Label struct { MaxLines int Text string - shaper *text.Shaper + shaper text.Shaper } func (t *Theme) H1(txt string) Label { diff --git a/widget/material/theme.go b/widget/material/theme.go index 20d1ee7c..46e1821c 100644 --- a/widget/material/theme.go +++ b/widget/material/theme.go @@ -16,7 +16,7 @@ import ( ) type Theme struct { - Shaper *text.Shaper + Shaper text.Shaper Color struct { Primary color.RGBA Text color.RGBA