110 lines
2.3 KiB
Go
110 lines
2.3 KiB
Go
package softwarebackend
|
|
|
|
import (
|
|
"image"
|
|
"image/color"
|
|
"math"
|
|
|
|
"github.com/tfriedel6/canvas/backend/backendbase"
|
|
)
|
|
|
|
func (b *SoftwareBackend) Clear(pts [4][2]float64) {
|
|
iterateTriangles(pts[:], func(tri [][2]float64) {
|
|
b.fillTriangle(tri, func(x, y int) {
|
|
if b.clip.AlphaAt(x, y).A == 0 {
|
|
return
|
|
}
|
|
b.Image.SetRGBA(x, y, color.RGBA{})
|
|
})
|
|
})
|
|
}
|
|
|
|
func (b *SoftwareBackend) Fill(style *backendbase.FillStyle, pts [][2]float64) {
|
|
iterateTriangles(pts[:], func(tri [][2]float64) {
|
|
b.fillTriangle(tri, func(x, y int) {
|
|
if b.clip.AlphaAt(x, y).A == 0 {
|
|
return
|
|
}
|
|
b.Image.SetRGBA(x, y, mix(style.Color, b.Image.RGBAAt(x, y)))
|
|
})
|
|
})
|
|
}
|
|
|
|
func mix(src, dest color.Color) color.RGBA {
|
|
ir1, ig1, ib1, ia1 := src.RGBA()
|
|
r1 := float64(ir1) / 65535.0
|
|
g1 := float64(ig1) / 65535.0
|
|
b1 := float64(ib1) / 65535.0
|
|
a1 := float64(ia1) / 65535.0
|
|
|
|
ir2, ig2, ib2, _ := dest.RGBA()
|
|
r2 := float64(ir2) / 65535.0
|
|
g2 := float64(ig2) / 65535.0
|
|
b2 := float64(ib2) / 65535.0
|
|
|
|
r := (r1-r2)*a1 + r2
|
|
g := (g1-g2)*a1 + g2
|
|
b := (b1-b2)*a1 + b2
|
|
|
|
return color.RGBA{
|
|
R: uint8(math.Round(r * 255.0)),
|
|
G: uint8(math.Round(g * 255.0)),
|
|
B: uint8(math.Round(b * 255.0)),
|
|
A: 255,
|
|
}
|
|
}
|
|
|
|
func alphaColor(col color.Color, alpha color.Alpha) color.RGBA {
|
|
ir, ig, ib, _ := col.RGBA()
|
|
a2 := float64(alpha.A) / 255.0
|
|
r := float64(ir) * a2 / 65535.0
|
|
g := float64(ig) * a2 / 65535.0
|
|
b := float64(ib) * a2 / 65535.0
|
|
return color.RGBA{
|
|
R: uint8(r * 255.0),
|
|
G: uint8(g * 255.0),
|
|
B: uint8(b * 255.0),
|
|
A: 255,
|
|
}
|
|
}
|
|
|
|
func (b *SoftwareBackend) FillImageMask(style *backendbase.FillStyle, mask *image.Alpha, pts [4][2]float64) {
|
|
mw := float64(mask.Bounds().Dx())
|
|
mh := float64(mask.Bounds().Dy())
|
|
b.fillQuad(pts, func(x, y int, sx2, sy2 float64) {
|
|
sxi := int(mw*sx2 + 0.5)
|
|
syi := int(mh*sy2 + 0.5)
|
|
a := mask.AlphaAt(sxi, syi)
|
|
if a.A == 0 {
|
|
return
|
|
}
|
|
b.Image.SetRGBA(x, y, alphaColor(style.Color, a))
|
|
})
|
|
}
|
|
|
|
func (b *SoftwareBackend) ClearClip() {
|
|
p := b.clip.Pix
|
|
for i := range p {
|
|
p[i] = 255
|
|
}
|
|
}
|
|
|
|
func (b *SoftwareBackend) Clip(pts [][2]float64) {
|
|
p2 := b.clip2.Pix
|
|
for i := range p2 {
|
|
p2[i] = 0
|
|
}
|
|
|
|
iterateTriangles(pts[:], func(tri [][2]float64) {
|
|
b.fillTriangle(tri, func(x, y int) {
|
|
b.clip2.SetAlpha(x, y, color.Alpha{A: 255})
|
|
})
|
|
})
|
|
|
|
p := b.clip.Pix
|
|
for i := range p {
|
|
if p2[i] == 0 {
|
|
p[i] = 0
|
|
}
|
|
}
|
|
}
|