From f35fe407b39b07927e8198f666fade408fd3aa41 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Fri, 11 Oct 2019 14:09:53 +0200 Subject: [PATCH] text: tighten clip bounds for Editor and Label We're about to remove the extra padding from Editor. To do that, the clipping must account for text drawing that lie outside the viewport. With accurate clip bounds, use it for Label as well. Signed-off-by: Elias Naur --- text/editor.go | 15 ++++++++------- text/label.go | 34 +++++++++++++++++++--------------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/text/editor.go b/text/editor.go index 26dd18d1..e4a42924 100644 --- a/text/editor.go +++ b/text/editor.go @@ -266,9 +266,7 @@ func (e *Editor) draw(gtx *layout.Context, s *Shaper, font Font) { X: -e.scrollOff.X + e.padLeft, Y: -e.scrollOff.Y + e.padTop, } - clip := image.Rectangle{ - Max: image.Point{X: e.viewSize.X, Y: e.viewSize.Y}, - } + clip := e.clipRect() it := lineIterator{ Lines: e.lines, Clip: clip, @@ -297,9 +295,6 @@ func (e *Editor) drawCaret(gtx *layout.Context) { } carLine, _, carX, carY := e.layoutCaret() - clip := image.Rectangle{ - Max: e.viewSize, - } var stack op.StackOp stack.Push(gtx.Ops) carX -= e.carWidth / 2 @@ -312,7 +307,7 @@ func (e *Editor) drawCaret(gtx *layout.Context) { X: -e.scrollOff.X + e.padLeft, Y: -e.scrollOff.Y + e.padTop, }) - carRect = clip.Intersect(carRect) + carRect = e.clipRect().Intersect(carRect) if !carRect.Empty() { paint.PaintOp{Rect: toRectF(carRect)}.Add(gtx.Ops) } @@ -336,6 +331,12 @@ func (e *Editor) SetText(s string) { e.prepend(s) } +func (e *Editor) clipRect() image.Rectangle { + clip := textPadding(e.lines) + clip.Max = clip.Max.Add(e.viewSize) + return clip +} + func (e *Editor) scrollBounds() image.Rectangle { var b image.Rectangle if e.SingleLine { diff --git a/text/label.go b/text/label.go index 9ba40209..ce4e4fc7 100644 --- a/text/label.go +++ b/text/label.go @@ -98,11 +98,8 @@ func (l Label) Layout(gtx *layout.Context, s *Shaper) { } dims := linesDimens(lines) dims.Size = cs.Constrain(dims.Size) - padTop, padBottom := textPadding(lines) - clip := image.Rectangle{ - Min: image.Point{X: -inf, Y: -padTop}, - Max: image.Point{X: inf, Y: dims.Size.Y + padBottom}, - } + clip := textPadding(lines) + clip.Max = clip.Max.Add(dims.Size) it := lineIterator{ Lines: lines, Clip: clip, @@ -135,16 +132,23 @@ func toRectF(r image.Rectangle) f32.Rectangle { } } -func textPadding(lines []Line) (padTop int, padBottom int) { - if len(lines) > 0 { - first := lines[0] - if d := -first.Bounds.Min.Y - first.Ascent; d > 0 { - padTop = d.Ceil() - } - last := lines[len(lines)-1] - if d := last.Bounds.Max.Y - last.Descent; d > 0 { - padBottom = d.Ceil() - } +func textPadding(lines []Line) (padding image.Rectangle) { + if len(lines) == 0 { + return + } + first := lines[0] + if d := first.Ascent + first.Bounds.Min.Y; d < 0 { + padding.Min.Y = d.Ceil() + } + last := lines[len(lines)-1] + if d := last.Bounds.Max.Y - last.Descent; d > 0 { + padding.Max.Y = d.Ceil() + } + if d := first.Bounds.Min.X; d < 0 { + padding.Min.X = d.Ceil() + } + if d := first.Bounds.Max.X - first.Width; d > 0 { + padding.Max.X = d.Ceil() } return }