Added dot selection visualization

This commit is contained in:
Sasha Koshka 2023-08-04 21:59:52 -04:00
parent 991f72cd8f
commit 639810fb13
1 changed files with 61 additions and 11 deletions

View File

@ -3,6 +3,7 @@ package x
import "image"
import "image/color"
import "golang.org/x/image/font"
import "golang.org/x/image/math/fixed"
import "git.tebibyte.media/tomo/tomo"
import "git.tebibyte.media/tomo/typeset"
import "git.tebibyte.media/tomo/tomo/text"
@ -24,6 +25,7 @@ type textBox struct {
selectable bool
dot text.Dot
dotColor color.Color
drawer typeset.Drawer
@ -98,6 +100,14 @@ func (this *textBox) SetSelectable (selectable bool) {
this.selectable = selectable
}
func (this *textBox) SetDotColor (c color.Color) {
if this.dotColor == c { return }
this.dotColor = c
if !this.dot.Empty() {
this.invalidateDraw()
}
}
func (this *textBox) Select (dot text.Dot) {
if !this.selectable { return }
if this.dot == dot { return }
@ -144,24 +154,64 @@ func (this *textBox) Draw (can canvas.Canvas) {
this.drawer.Draw(can, this.textColor, this.textOffset())
}
func roundPt (point fixed.Point26_6) image.Point {
return image.Pt(point.X.Round(), point.Y.Round())
}
func fixPt (point image.Point) fixed.Point26_6 {
return fixed.P(point.X, point.Y)
}
func (this *textBox) drawDot (can canvas.Canvas) {
pen := can.Pen()
pen.Fill(color.Transparent)
pen.Stroke(this.textColor)
pen.StrokeWeight(1)
bounds := this.InnerBounds()
metrics := this.face.Metrics()
dot := this.dot.Canon()
start := this.drawer.PositionAt(dot.Start).Add(fixPt(this.textOffset()))
end := this.drawer.PositionAt(dot.End ).Add(fixPt(this.textOffset()))
height := this.drawer.LineHeight().Round()
ascent := fixed.Point26_6 { Y: metrics.Descent }
descent := fixed.Point26_6 { Y: metrics.Ascent }
// TODO draw dot
if this.dot.Empty() {
metrics := this.face.Metrics()
position := this.drawer.PositionAt(this.dot.Start)
roundPos :=
image.Pt(position.X.Round(), position.Y.Round()).
Add(this.textOffset())
pen.Path (
roundPos.Add(image.Pt(0, metrics.Descent.Round())),
roundPos.Sub(image.Pt(0, metrics.Ascent.Round())))
} else {
switch {
case dot.Empty():
pen.Path(roundPt(start.Add(ascent)), roundPt(start.Sub(descent)))
case start.Y == end.Y:
pen.Fill(this.dotColor)
pen.StrokeWeight(0)
pen.Rectangle(image.Rectangle {
Min: roundPt(start.Add(ascent)),
Max: roundPt(end.Sub(descent)),
})
default:
pen.Fill(this.dotColor)
pen.StrokeWeight(0)
rect := image.Rectangle {
Min: roundPt(start.Add(ascent)),
Max: roundPt(start.Sub(descent)),
}
rect.Max.X = bounds.Max.X
pen.Rectangle(rect)
if end.Y - start.Y > fixed.I(height) {
rect.Min.X = bounds.Min.X
rect.Min.Y = roundPt(start.Sub(descent)).Y + height
rect.Max.X = bounds.Max.X
rect.Max.Y = roundPt(end.Add(ascent)).Y - height
pen.Rectangle(rect)
}
rect = image.Rectangle {
Min: roundPt(end.Add(ascent)),
Max: roundPt(end.Sub(descent)),
}
rect.Min.X = bounds.Min.X
pen.Rectangle(rect)
}
}