2023-07-11 19:54:29 -06:00
|
|
|
package typeset
|
2023-07-06 23:49:32 -06:00
|
|
|
|
|
|
|
import "image"
|
|
|
|
import "unicode"
|
|
|
|
import "image/draw"
|
|
|
|
import "image/color"
|
|
|
|
import "golang.org/x/image/math/fixed"
|
|
|
|
|
|
|
|
// Drawer is an extended TypeSetter that is able to draw text. Much like
|
|
|
|
// TypeSetter, It has no constructor and its zero value can be used safely.
|
|
|
|
type Drawer struct { TypeSetter }
|
|
|
|
|
|
|
|
// Draw draws the drawer's text onto the specified canvas at the given offset.
|
|
|
|
func (drawer Drawer) Draw (
|
|
|
|
destination draw.Image,
|
2023-07-11 20:25:44 -06:00
|
|
|
color color.Color,
|
2023-07-06 23:49:32 -06:00
|
|
|
offset image.Point,
|
|
|
|
) (
|
|
|
|
updatedRegion image.Rectangle,
|
|
|
|
) {
|
2023-07-11 20:25:44 -06:00
|
|
|
source := image.NewUniform(color)
|
|
|
|
|
2023-07-06 23:49:32 -06:00
|
|
|
drawer.For (func (
|
|
|
|
index int,
|
|
|
|
char rune,
|
|
|
|
position fixed.Point26_6,
|
|
|
|
) bool {
|
|
|
|
destinationRectangle,
|
|
|
|
mask, maskPoint, _, ok := drawer.face.Glyph (
|
|
|
|
fixed.P (
|
|
|
|
offset.X + position.X.Round(),
|
|
|
|
offset.Y + position.Y.Round()),
|
|
|
|
char)
|
|
|
|
if !ok || unicode.IsSpace(char) || char == 0 {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME:? clip destination rectangle if we are on the cusp of
|
|
|
|
// the maximum height.
|
|
|
|
|
|
|
|
draw.DrawMask (
|
|
|
|
destination,
|
|
|
|
destinationRectangle,
|
2023-07-11 20:25:44 -06:00
|
|
|
source, image.Point { },
|
2023-07-06 23:49:32 -06:00
|
|
|
mask, maskPoint,
|
|
|
|
draw.Over)
|
|
|
|
|
|
|
|
updatedRegion = updatedRegion.Union(destinationRectangle)
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
return
|
|
|
|
}
|