raw-buffer-api #1
12
artist/pattern.go
Normal file
12
artist/pattern.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package artist
|
||||||
|
|
||||||
|
import "image/color"
|
||||||
|
|
||||||
|
// Pattern is capable of generating a pattern pixel by pixel.
|
||||||
|
type Pattern interface {
|
||||||
|
// AtWhen returns the color of the pixel located at (x, y) relative to
|
||||||
|
// the origin point of the pattern (0, 0), when the pattern has the
|
||||||
|
// specified width and height. Patterns may ignore the width and height
|
||||||
|
// parameters, but it may be useful for some patterns such as gradients.
|
||||||
|
AtWhen (x, y, width, height int) (color.RGBA)
|
||||||
|
}
|
@ -29,6 +29,7 @@ func Paste (
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FillRectangle draws a filled rectangle with the specified pattern.
|
||||||
func FillRectangle (
|
func FillRectangle (
|
||||||
destination tomo.Canvas,
|
destination tomo.Canvas,
|
||||||
source Pattern,
|
source Pattern,
|
||||||
|
@ -3,7 +3,7 @@ package artist
|
|||||||
// import "fmt"
|
// import "fmt"
|
||||||
import "image"
|
import "image"
|
||||||
import "unicode"
|
import "unicode"
|
||||||
// import "image/draw"
|
import "image/draw"
|
||||||
import "golang.org/x/image/font"
|
import "golang.org/x/image/font"
|
||||||
import "golang.org/x/image/math/fixed"
|
import "golang.org/x/image/math/fixed"
|
||||||
import "git.tebibyte.media/sashakoshka/tomo"
|
import "git.tebibyte.media/sashakoshka/tomo"
|
||||||
@ -100,30 +100,36 @@ func (drawer *TextDrawer) Draw (
|
|||||||
) (
|
) (
|
||||||
updatedRegion image.Rectangle,
|
updatedRegion image.Rectangle,
|
||||||
) {
|
) {
|
||||||
|
wrappedSource := WrappedPattern {
|
||||||
|
Pattern: source,
|
||||||
|
Width: 0,
|
||||||
|
Height: 0, // TODO: choose a better width and height
|
||||||
|
}
|
||||||
|
|
||||||
if !drawer.layoutClean { drawer.recalculate() }
|
if !drawer.layoutClean { drawer.recalculate() }
|
||||||
// TODO: reimplement a version of draw mask that takes in a pattern
|
// TODO: reimplement a version of draw mask that takes in a pattern
|
||||||
// for _, word := range drawer.layout {
|
for _, word := range drawer.layout {
|
||||||
// for _, character := range word.text {
|
for _, character := range word.text {
|
||||||
// destinationRectangle,
|
destinationRectangle,
|
||||||
// mask, maskPoint, _, ok := drawer.face.Glyph (
|
mask, maskPoint, _, ok := drawer.face.Glyph (
|
||||||
// fixed.P (
|
fixed.P (
|
||||||
// offset.X + word.position.X + character.x,
|
offset.X + word.position.X + character.x,
|
||||||
// offset.Y + word.position.Y),
|
offset.Y + word.position.Y),
|
||||||
// character.character)
|
character.character)
|
||||||
// if !ok { continue }
|
if !ok { continue }
|
||||||
|
|
||||||
// FIXME: clip destination rectangle if we are on the cusp of
|
// FIXME: clip destination rectangle if we are on the cusp of
|
||||||
// the maximum height.
|
// the maximum height.
|
||||||
|
|
||||||
// draw.DrawMask (
|
draw.DrawMask (
|
||||||
// destination,
|
destination,
|
||||||
// destinationRectangle,
|
destinationRectangle,
|
||||||
// source, image.Point { },
|
wrappedSource, image.Point { },
|
||||||
// mask, maskPoint,
|
mask, maskPoint,
|
||||||
// draw.Over)
|
draw.Over)
|
||||||
|
|
||||||
// updatedRegion = updatedRegion.Union(destinationRectangle)
|
updatedRegion = updatedRegion.Union(destinationRectangle)
|
||||||
// }}
|
}}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,15 +3,6 @@ package artist
|
|||||||
import "image"
|
import "image"
|
||||||
import "image/color"
|
import "image/color"
|
||||||
|
|
||||||
// Pattern is capable of generating a pattern pixel by pixel.
|
|
||||||
type Pattern interface {
|
|
||||||
// AtWhen returns the color of the pixel located at (x, y) relative to
|
|
||||||
// the origin point of the pattern (0, 0), when the pattern has the
|
|
||||||
// specified width and height. Patterns may ignore the width and height
|
|
||||||
// parameters, but it may be useful for some patterns such as gradients.
|
|
||||||
AtWhen (x, y, width, height int) (color.RGBA)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Texture is a struct that allows an image to be converted into a tiling
|
// Texture is a struct that allows an image to be converted into a tiling
|
||||||
// texture pattern.
|
// texture pattern.
|
||||||
type Texture struct {
|
type Texture struct {
|
@ -4,61 +4,52 @@ import "image"
|
|||||||
import "image/color"
|
import "image/color"
|
||||||
|
|
||||||
// Uniform is an infinite-sized pattern of uniform color. It implements the
|
// Uniform is an infinite-sized pattern of uniform color. It implements the
|
||||||
// color.Color, color.Model, and image.Image interfaces.
|
// Pattern, color.Color, color.Model, and image.Image interfaces.
|
||||||
type Uniform struct {
|
type Uniform color.RGBA
|
||||||
C color.RGBA
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUniform returns a new Uniform image of the given color.
|
// NewUniform returns a new Uniform image of the given color.
|
||||||
func NewUniform (c color.Color) (uniform *Uniform) {
|
func NewUniform (c color.Color) (uniform Uniform) {
|
||||||
uniform = &Uniform { }
|
|
||||||
r, g, b, a := c.RGBA()
|
r, g, b, a := c.RGBA()
|
||||||
uniform.C.R = uint8(r >> 8)
|
uniform.R = uint8(r >> 8)
|
||||||
uniform.C.G = uint8(g >> 8)
|
uniform.G = uint8(g >> 8)
|
||||||
uniform.C.B = uint8(b >> 8)
|
uniform.B = uint8(b >> 8)
|
||||||
uniform.C.A = uint8(a >> 8)
|
uniform.A = uint8(a >> 8)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (uniform *Uniform) RGBA () (r, g, b, a uint32) {
|
// ColorModel satisfies the image.Image interface.
|
||||||
r = uint32(uniform.C.R) << 8 | uint32(uniform.C.R)
|
func (uniform Uniform) ColorModel () (model color.Model) {
|
||||||
g = uint32(uniform.C.G) << 8 | uint32(uniform.C.G)
|
|
||||||
b = uint32(uniform.C.B) << 8 | uint32(uniform.C.B)
|
|
||||||
a = uint32(uniform.C.A) << 8 | uint32(uniform.C.A)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (uniform *Uniform) ColorModel () (model color.Model) {
|
|
||||||
return uniform
|
return uniform
|
||||||
}
|
}
|
||||||
|
|
||||||
func (uniform *Uniform) Convert (in color.Color) (c color.Color) {
|
// Convert satisfies the color.Model interface.
|
||||||
return uniform.C
|
func (uniform Uniform) Convert (in color.Color) (c color.Color) {
|
||||||
|
return color.RGBA(uniform)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (uniform *Uniform) Bounds () (rectangle image.Rectangle) {
|
// Bounds satisfies the image.Image interface.
|
||||||
|
func (uniform Uniform) Bounds () (rectangle image.Rectangle) {
|
||||||
rectangle.Min = image.Point { -1e9, -1e9 }
|
rectangle.Min = image.Point { -1e9, -1e9 }
|
||||||
rectangle.Max = image.Point { 1e9, 1e9 }
|
rectangle.Max = image.Point { 1e9, 1e9 }
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (uniform *Uniform) At (x, y int) (c color.Color) {
|
// At satisfies the image.Image interface.
|
||||||
return uniform.C
|
func (uniform Uniform) At (x, y int) (c color.Color) {
|
||||||
|
return color.RGBA(uniform)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (uniform *Uniform) AtWhen (x, y, width, height int) (c color.RGBA) {
|
// AtWhen satisfies the Pattern interface.
|
||||||
return uniform.C
|
func (uniform Uniform) AtWhen (x, y, width, height int) (c color.RGBA) {
|
||||||
|
return color.RGBA(uniform)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (uniform *Uniform) RGBA64At (x, y int) (c color.RGBA64) {
|
// RGBA satisfies the color.Color interface.
|
||||||
r := uint16(uniform.C.R) << 8 | uint16(uniform.C.R)
|
func (uniform Uniform) RGBA () (r, g, b, a uint32) {
|
||||||
g := uint16(uniform.C.G) << 8 | uint16(uniform.C.G)
|
return color.RGBA(uniform).RGBA()
|
||||||
b := uint16(uniform.C.B) << 8 | uint16(uniform.C.B)
|
|
||||||
a := uint16(uniform.C.A) << 8 | uint16(uniform.C.A)
|
|
||||||
return color.RGBA64 { R: r, G: g, B: b, A: a }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opaque scans the entire image and reports whether it is fully opaque.
|
// Opaque scans the entire image and reports whether it is fully opaque.
|
||||||
func (uniform *Uniform) Opaque () (opaque bool) {
|
func (uniform Uniform) Opaque () (opaque bool) {
|
||||||
return uniform.C.A == 0xFF
|
return uniform.A == 0xFF
|
||||||
}
|
}
|
||||||
|
@ -1 +1,27 @@
|
|||||||
package artist
|
package artist
|
||||||
|
|
||||||
|
import "image"
|
||||||
|
import "image/color"
|
||||||
|
|
||||||
|
// WrappedPattern is a pattern that is able to behave like an image.Image.
|
||||||
|
type WrappedPattern struct {
|
||||||
|
Pattern
|
||||||
|
Width, Height int
|
||||||
|
}
|
||||||
|
|
||||||
|
// At satisfies the image.Image interface.
|
||||||
|
func (pattern WrappedPattern) At (x, y int) (c color.Color) {
|
||||||
|
return pattern.Pattern.AtWhen(x, y, pattern.Width, pattern.Height)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bounds satisfies the image.Image interface.
|
||||||
|
func (pattern WrappedPattern) Bounds () (rectangle image.Rectangle) {
|
||||||
|
rectangle.Min = image.Point { -1e9, -1e9 }
|
||||||
|
rectangle.Max = image.Point { 1e9, 1e9 }
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ColorModel satisfies the image.Image interface.
|
||||||
|
func (pattern WrappedPattern) ColorModel () (model color.Model) {
|
||||||
|
return color.RGBAModel
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user