fixed a transformation issue
This commit is contained in:
parent
857e6c4e47
commit
ff4c73b6b7
4 changed files with 38 additions and 15 deletions
22
canvas.go
22
canvas.go
|
@ -142,6 +142,7 @@ func New(backend backendbase.Backend) *Canvas {
|
||||||
cv.state.fill.color = color.RGBA{A: 255}
|
cv.state.fill.color = color.RGBA{A: 255}
|
||||||
cv.state.stroke.color = color.RGBA{A: 255}
|
cv.state.stroke.color = color.RGBA{A: 255}
|
||||||
cv.state.transform = matIdentity()
|
cv.state.transform = matIdentity()
|
||||||
|
cv.path.cv = cv
|
||||||
return cv
|
return cv
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,7 +394,7 @@ func (cv *Canvas) Restore() {
|
||||||
cv.b.ClearClip()
|
cv.b.ClearClip()
|
||||||
for _, st := range cv.stateStack {
|
for _, st := range cv.stateStack {
|
||||||
if len(st.clip.p) > 0 {
|
if len(st.clip.p) > 0 {
|
||||||
cv.clip(&st.clip)
|
cv.clip(&st.clip, matIdentity())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cv.state = cv.stateStack[l-1]
|
cv.state = cv.stateStack[l-1]
|
||||||
|
@ -464,5 +465,22 @@ func (cv *Canvas) IsPointInPath(x, y float64, rule pathRule) bool {
|
||||||
// IsPointInStroke returns true if the point is in the current
|
// IsPointInStroke returns true if the point is in the current
|
||||||
// path stroke
|
// path stroke
|
||||||
func (cv *Canvas) IsPointInStroke(x, y float64) bool {
|
func (cv *Canvas) IsPointInStroke(x, y float64) bool {
|
||||||
return cv.path.IsPointInStroke(x, y)
|
if len(cv.path.p) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var triBuf [500][2]float64
|
||||||
|
tris := cv.strokeTris(&cv.path, cv.state.transform.invert(), true, triBuf[:0])
|
||||||
|
|
||||||
|
pt := vec{x, y}
|
||||||
|
|
||||||
|
for i := 0; i < len(tris); i += 3 {
|
||||||
|
a := vec{tris[i][0], tris[i][1]}
|
||||||
|
b := vec{tris[i+1][0], tris[i+1][1]}
|
||||||
|
c := vec{tris[i+2][0], tris[i+2][1]}
|
||||||
|
if triangleContainsPoint(a, b, c, pt) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -473,7 +473,7 @@ func TestConvexSelfIntersecting(t *testing.T) {
|
||||||
|
|
||||||
func TestTransform(t *testing.T) {
|
func TestTransform(t *testing.T) {
|
||||||
run(t, func(cv *canvas.Canvas) {
|
run(t, func(cv *canvas.Canvas) {
|
||||||
path := canvas.NewPath2D()
|
path := cv.NewPath2D()
|
||||||
path.MoveTo(-10, -10)
|
path.MoveTo(-10, -10)
|
||||||
path.LineTo(10, -10)
|
path.LineTo(10, -10)
|
||||||
path.LineTo(0, 10)
|
path.LineTo(0, 10)
|
||||||
|
|
25
paths.go
25
paths.go
|
@ -336,11 +336,16 @@ func lineIntersection(a0, a1, b0, b1 vec) (vec, float64, float64) {
|
||||||
|
|
||||||
// Fill fills the current path with the current FillStyle
|
// Fill fills the current path with the current FillStyle
|
||||||
func (cv *Canvas) Fill() {
|
func (cv *Canvas) Fill() {
|
||||||
cv.FillPath(&cv.path)
|
cv.fillPath(&cv.path, matIdentity())
|
||||||
}
|
}
|
||||||
|
|
||||||
// FillPath fills the given path with the current FillStyle
|
// FillPath fills the given path with the current FillStyle
|
||||||
func (cv *Canvas) FillPath(path *Path2D) {
|
func (cv *Canvas) FillPath(path *Path2D) {
|
||||||
|
cv.fillPath(path, cv.state.transform)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FillPath fills the given path with the current FillStyle
|
||||||
|
func (cv *Canvas) fillPath(path *Path2D, tf mat) {
|
||||||
if len(path.p) < 3 {
|
if len(path.p) < 3 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -348,7 +353,7 @@ func (cv *Canvas) FillPath(path *Path2D) {
|
||||||
var triBuf [500][2]float64
|
var triBuf [500][2]float64
|
||||||
tris := triBuf[:0]
|
tris := triBuf[:0]
|
||||||
runSubPaths(path.p, func(sp []pathPoint) bool {
|
runSubPaths(path.p, func(sp []pathPoint) bool {
|
||||||
tris = appendSubPathTriangles(tris, sp)
|
tris = appendSubPathTriangles(tris, tf, sp)
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
if len(tris) == 0 {
|
if len(tris) == 0 {
|
||||||
|
@ -361,23 +366,23 @@ func (cv *Canvas) FillPath(path *Path2D) {
|
||||||
cv.b.Fill(&stl, tris)
|
cv.b.Fill(&stl, tris)
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendSubPathTriangles(tris [][2]float64, path []pathPoint) [][2]float64 {
|
func appendSubPathTriangles(tris [][2]float64, mat mat, path []pathPoint) [][2]float64 {
|
||||||
last := path[len(path)-1]
|
last := path[len(path)-1]
|
||||||
if last.flags&pathIsConvex != 0 {
|
if last.flags&pathIsConvex != 0 {
|
||||||
p0, p1 := path[0].pos, path[1].pos
|
p0, p1 := path[0].pos.mulMat(mat), path[1].pos.mulMat(mat)
|
||||||
last := len(path)
|
last := len(path)
|
||||||
for i := 2; i < last; i++ {
|
for i := 2; i < last; i++ {
|
||||||
p2 := path[i].pos
|
p2 := path[i].pos.mulMat(mat)
|
||||||
tris = append(tris, p0, p1, p2)
|
tris = append(tris, p0, p1, p2)
|
||||||
p1 = p2
|
p1 = p2
|
||||||
}
|
}
|
||||||
} else if last.flags&pathSelfIntersects != 0 {
|
} else if last.flags&pathSelfIntersects != 0 {
|
||||||
selfIntersectingPathParts(path, func(sp []pathPoint) bool {
|
selfIntersectingPathParts(path, func(sp []pathPoint) bool {
|
||||||
tris = triangulatePath(sp, tris)
|
tris = triangulatePath(sp, mat, tris)
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
tris = triangulatePath(path, tris)
|
tris = triangulatePath(path, mat, tris)
|
||||||
}
|
}
|
||||||
return tris
|
return tris
|
||||||
}
|
}
|
||||||
|
@ -385,10 +390,10 @@ func appendSubPathTriangles(tris [][2]float64, path []pathPoint) [][2]float64 {
|
||||||
// Clip uses the current path to clip any further drawing. Use Save/Restore to
|
// Clip uses the current path to clip any further drawing. Use Save/Restore to
|
||||||
// remove the clipping again
|
// remove the clipping again
|
||||||
func (cv *Canvas) Clip() {
|
func (cv *Canvas) Clip() {
|
||||||
cv.clip(&cv.path)
|
cv.clip(&cv.path, matIdentity())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cv *Canvas) clip(path *Path2D) {
|
func (cv *Canvas) clip(path *Path2D, tf mat) {
|
||||||
if len(path.p) < 3 {
|
if len(path.p) < 3 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -396,7 +401,7 @@ func (cv *Canvas) clip(path *Path2D) {
|
||||||
var triBuf [500][2]float64
|
var triBuf [500][2]float64
|
||||||
tris := triBuf[:0]
|
tris := triBuf[:0]
|
||||||
runSubPaths(path.p, func(sp []pathPoint) bool {
|
runSubPaths(path.p, func(sp []pathPoint) bool {
|
||||||
tris = appendSubPathTriangles(tris, sp)
|
tris = appendSubPathTriangles(tris, tf, sp)
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
if len(tris) == 0 {
|
if len(tris) == 0 {
|
||||||
|
|
|
@ -84,11 +84,11 @@ func polygonContainsPoint(polygon []vec, p vec) bool {
|
||||||
return count%2 == 1
|
return count%2 == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func triangulatePath(path []pathPoint, target [][2]float64) [][2]float64 {
|
func triangulatePath(path []pathPoint, mat mat, target [][2]float64) [][2]float64 {
|
||||||
var buf [500]vec
|
var buf [500]vec
|
||||||
polygon := buf[:0]
|
polygon := buf[:0]
|
||||||
for _, p := range path {
|
for _, p := range path {
|
||||||
polygon = append(polygon, p.pos)
|
polygon = append(polygon, p.pos.mulMat(mat))
|
||||||
}
|
}
|
||||||
|
|
||||||
for len(polygon) > 2 {
|
for len(polygon) > 2 {
|
||||||
|
|
Loading…
Reference in a new issue