Added dot selection visualization

This commit is contained in:
Sasha Koshka 2023-08-04 21:59:52 -04:00
parent 991f72cd8f
commit 639810fb13

View File

@ -3,6 +3,7 @@ package x
import "image" import "image"
import "image/color" import "image/color"
import "golang.org/x/image/font" import "golang.org/x/image/font"
import "golang.org/x/image/math/fixed"
import "git.tebibyte.media/tomo/tomo" import "git.tebibyte.media/tomo/tomo"
import "git.tebibyte.media/tomo/typeset" import "git.tebibyte.media/tomo/typeset"
import "git.tebibyte.media/tomo/tomo/text" import "git.tebibyte.media/tomo/tomo/text"
@ -24,6 +25,7 @@ type textBox struct {
selectable bool selectable bool
dot text.Dot dot text.Dot
dotColor color.Color
drawer typeset.Drawer drawer typeset.Drawer
@ -98,6 +100,14 @@ func (this *textBox) SetSelectable (selectable bool) {
this.selectable = selectable 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) { func (this *textBox) Select (dot text.Dot) {
if !this.selectable { return } if !this.selectable { return }
if this.dot == dot { 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()) 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) { func (this *textBox) drawDot (can canvas.Canvas) {
pen := can.Pen() pen := can.Pen()
pen.Fill(color.Transparent) pen.Fill(color.Transparent)
pen.Stroke(this.textColor) pen.Stroke(this.textColor)
pen.StrokeWeight(1) pen.StrokeWeight(1)
// TODO draw dot bounds := this.InnerBounds()
if this.dot.Empty() {
metrics := this.face.Metrics() metrics := this.face.Metrics()
position := this.drawer.PositionAt(this.dot.Start) dot := this.dot.Canon()
roundPos := start := this.drawer.PositionAt(dot.Start).Add(fixPt(this.textOffset()))
image.Pt(position.X.Round(), position.Y.Round()). end := this.drawer.PositionAt(dot.End ).Add(fixPt(this.textOffset()))
Add(this.textOffset()) height := this.drawer.LineHeight().Round()
pen.Path ( ascent := fixed.Point26_6 { Y: metrics.Descent }
roundPos.Add(image.Pt(0, metrics.Descent.Round())), descent := fixed.Point26_6 { Y: metrics.Ascent }
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)
} }
} }