feat: primitive styling
This commit is contained in:
+41
-29
@@ -67,18 +67,13 @@ type PrimitiveDrawer interface {
|
||||
// Fill renders the current path using the current fill state.
|
||||
Fill()
|
||||
|
||||
// CopyShift shifts the current backing image by (dx, dy) in canvas pixels.
|
||||
// dx > 0 shifts the image to the right, dy > 0 shifts the image down.
|
||||
// Newly exposed areas are cleared to transparent.
|
||||
// CopyShift shifts backing pixels by (dx,dy). Newly exposed areas become transparent/undefined;
|
||||
// caller is expected to ClearRectTo() the dirty areas before drawing.
|
||||
CopyShift(dx, dy int)
|
||||
|
||||
// ClearAll clears the entire backing canvas to transparent.
|
||||
// Must NOT affect the current clip state.
|
||||
ClearAll()
|
||||
|
||||
// ClearRect clears a pixel rectangle to transparent.
|
||||
// Must NOT affect the current clip state.
|
||||
ClearRect(x, y, w, h int)
|
||||
// Clear operations must NOT change clip state.
|
||||
ClearAllTo(bg color.Color)
|
||||
ClearRectTo(x, y, w, h int, bg color.Color)
|
||||
}
|
||||
|
||||
// ggClipRect stores one clip rectangle in canvas pixel coordinates.
|
||||
@@ -283,44 +278,61 @@ func (d *GGDrawer) CopyShift(dx, dy int) {
|
||||
copy(img.Pix, d.scratch.Pix)
|
||||
}
|
||||
|
||||
// ClearAll clears the whole RGBA backing image to transparent.
|
||||
// It does not touch gg clip state.
|
||||
func (d *GGDrawer) ClearAll() {
|
||||
func (d *GGDrawer) ClearAllTo(bg color.Color) {
|
||||
img, ok := d.DC.Image().(*image.RGBA)
|
||||
if !ok || img == nil {
|
||||
panic("GGDrawer.ClearAll: backing image is not *image.RGBA")
|
||||
panic("GGDrawer.ClearAllTo: backing image is not *image.RGBA")
|
||||
}
|
||||
for i := range img.Pix {
|
||||
img.Pix[i] = 0
|
||||
|
||||
r, g, b, a := bg.RGBA()
|
||||
// Convert from 16-bit range to 8-bit.
|
||||
R := byte(r >> 8)
|
||||
G := byte(g >> 8)
|
||||
B := byte(b >> 8)
|
||||
A := byte(a >> 8)
|
||||
|
||||
p := img.Pix
|
||||
for i := 0; i+3 < len(p); i += 4 {
|
||||
p[i+0] = R
|
||||
p[i+1] = G
|
||||
p[i+2] = B
|
||||
p[i+3] = A
|
||||
}
|
||||
}
|
||||
|
||||
// ClearRect clears a region to transparent. It does not touch gg clip state.
|
||||
// Rectangle is clamped to the image bounds.
|
||||
func (d *GGDrawer) ClearRect(x, y, w, h int) {
|
||||
func (d *GGDrawer) ClearRectTo(x, y, w, h int, bg color.Color) {
|
||||
if w <= 0 || h <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
img, ok := d.DC.Image().(*image.RGBA)
|
||||
if !ok || img == nil {
|
||||
panic("GGDrawer.ClearRect: backing image is not *image.RGBA")
|
||||
panic("GGDrawer.ClearRectTo: backing image is not *image.RGBA")
|
||||
}
|
||||
|
||||
b := img.Bounds()
|
||||
x0 := max(x, b.Min.X)
|
||||
y0 := max(y, b.Min.Y)
|
||||
x1 := min(x+w, b.Max.X)
|
||||
y1 := min(y+h, b.Max.Y)
|
||||
bounds := img.Bounds()
|
||||
x0 := max(x, bounds.Min.X)
|
||||
y0 := max(y, bounds.Min.Y)
|
||||
x1 := min(x+w, bounds.Max.X)
|
||||
y1 := min(y+h, bounds.Max.Y)
|
||||
if x0 >= x1 || y0 >= y1 {
|
||||
return
|
||||
}
|
||||
|
||||
// Zero rows.
|
||||
r, g, b, a := bg.RGBA()
|
||||
R := byte(r >> 8)
|
||||
G := byte(g >> 8)
|
||||
B := byte(b >> 8)
|
||||
A := byte(a >> 8)
|
||||
|
||||
rowBytes := (x1 - x0) * 4
|
||||
for yy := y0; yy < y1; yy++ {
|
||||
off := yy*img.Stride + x0*4
|
||||
n := (x1 - x0) * 4
|
||||
for i := 0; i < n; i++ {
|
||||
img.Pix[off+i] = 0
|
||||
for i := 0; i < rowBytes; i += 4 {
|
||||
img.Pix[off+i+0] = R
|
||||
img.Pix[off+i+1] = G
|
||||
img.Pix[off+i+2] = B
|
||||
img.Pix[off+i+3] = A
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user