mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
gpu: respect the offset fraction when clipping
Fixes: https://todo.sr.ht/~eliasnaur/gio/534 Signed-off-by: Walter Werner SCHNEIDER <contact@schnwalter.eu> Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
committed by
Elias Naur
parent
a274f6fe0f
commit
bbb6d05f09
+15
-11
@@ -1036,7 +1036,7 @@ loop:
|
|||||||
op.Decode(encOp.Data)
|
op.Decode(encOp.Data)
|
||||||
quads.key.outline = op.Outline
|
quads.key.outline = op.Outline
|
||||||
bounds := f32.FRect(op.Bounds)
|
bounds := f32.FRect(op.Bounds)
|
||||||
trans, off := state.t.Split()
|
trans, off := transformOffset(state.t)
|
||||||
if len(quads.aux) > 0 {
|
if len(quads.aux) > 0 {
|
||||||
// There is a clipping path, build the gpu data and update the
|
// There is a clipping path, build the gpu data and update the
|
||||||
// cache key such that it will be equal only if the transform is the
|
// cache key such that it will be equal only if the transform is the
|
||||||
@@ -1083,7 +1083,7 @@ loop:
|
|||||||
// Transform (if needed) the painting rectangle and if so generate a clip path,
|
// Transform (if needed) the painting rectangle and if so generate a clip path,
|
||||||
// for those cases also compute a partialTrans that maps texture coordinates between
|
// for those cases also compute a partialTrans that maps texture coordinates between
|
||||||
// the new bounding rectangle and the transformed original paint rectangle.
|
// the new bounding rectangle and the transformed original paint rectangle.
|
||||||
t, off := state.t.Split()
|
t, off := transformOffset(state.t)
|
||||||
// Fill the clip area, unless the material is a (bounded) image.
|
// Fill the clip area, unless the material is a (bounded) image.
|
||||||
// TODO: Find a tighter bound.
|
// TODO: Find a tighter bound.
|
||||||
inf := float32(1e6)
|
inf := float32(1e6)
|
||||||
@@ -1526,12 +1526,9 @@ func decodeToOutlineQuads(qs *quadSplitter, tr f32.Affine2D, pathData []byte) {
|
|||||||
// create GPU vertices for transformed r, find the bounds and establish texture transform.
|
// create GPU vertices for transformed r, find the bounds and establish texture transform.
|
||||||
func (d *drawOps) boundsForTransformedRect(r f32.Rectangle, tr f32.Affine2D) (aux []byte, bnd f32.Rectangle, ptr f32.Affine2D) {
|
func (d *drawOps) boundsForTransformedRect(r f32.Rectangle, tr f32.Affine2D) (aux []byte, bnd f32.Rectangle, ptr f32.Affine2D) {
|
||||||
ptr = f32.AffineId()
|
ptr = f32.AffineId()
|
||||||
if isPureOffset(tr) {
|
if tr == f32.AffineId() {
|
||||||
// fast-path to allow blitting of pure rectangles
|
// fast-path to allow blitting of pure rectangles.
|
||||||
_, _, ox, _, _, oy := tr.Elems()
|
bnd = r
|
||||||
off := f32.Pt(ox, oy)
|
|
||||||
bnd.Min = r.Min.Add(off)
|
|
||||||
bnd.Max = r.Max.Add(off)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1581,9 +1578,16 @@ func (d *drawOps) boundsForTransformedRect(r f32.Rectangle, tr f32.Affine2D) (au
|
|||||||
return aux, bnd, ptr
|
return aux, bnd, ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
func isPureOffset(t f32.Affine2D) bool {
|
// transformOffset a transform into two parts, one which is pure integer offset
|
||||||
a, b, _, d, e, _ := t.Elems()
|
// and the other representing the scaling, shearing and rotation and fractional
|
||||||
return a == 1 && b == 0 && d == 0 && e == 1
|
// offset.
|
||||||
|
func transformOffset(t f32.Affine2D) (f32.Affine2D, f32.Point) {
|
||||||
|
sx, hx, ox, hy, sy, oy := t.Elems()
|
||||||
|
iox, fox := math.Modf(float64(ox))
|
||||||
|
ioy, foy := math.Modf(float64(oy))
|
||||||
|
ft := f32.NewAffine2D(sx, hx, float32(fox), hy, sy, float32(foy))
|
||||||
|
ip := f32.Pt(float32(iox), float32(ioy))
|
||||||
|
return ft, ip
|
||||||
}
|
}
|
||||||
|
|
||||||
func newShaders(ctx driver.Device, vsrc, fsrc shader.Sources) (vert driver.VertexShader, frag driver.FragmentShader, err error) {
|
func newShaders(ctx driver.Device, vsrc, fsrc shader.Sources) (vert driver.VertexShader, frag driver.FragmentShader, err error) {
|
||||||
|
|||||||
@@ -40,6 +40,25 @@ func TestPaintClippedRect(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPaintClippedRectOffset(t *testing.T) {
|
||||||
|
run(t, func(o *op.Ops) {
|
||||||
|
defer op.Affine(f32.AffineId().Offset(f32.Pt(0.5, 0.5))).Push(o).Pop()
|
||||||
|
defer clip.RRect{Rect: image.Rect(25, 25, 60, 60)}.Push(o).Pop()
|
||||||
|
paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 50, 50)).Op())
|
||||||
|
}, func(r result) {
|
||||||
|
r.expect(0, 0, transparent)
|
||||||
|
r.expect(24, 35, transparent)
|
||||||
|
r.expect(24, 24, transparent)
|
||||||
|
r.expect(25, 25, color.RGBA{R: 137, A: 64})
|
||||||
|
r.expect(25, 35, color.RGBA{R: 187, A: 128})
|
||||||
|
r.expect(35, 25, color.RGBA{R: 187, A: 128})
|
||||||
|
r.expect(50, 50, color.RGBA{R: 137, A: 64})
|
||||||
|
r.expect(51, 51, transparent)
|
||||||
|
r.expect(50, 0, transparent)
|
||||||
|
r.expect(10, 50, transparent)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestPaintClippedCircle(t *testing.T) {
|
func TestPaintClippedCircle(t *testing.T) {
|
||||||
run(t, func(o *op.Ops) {
|
run(t, func(o *op.Ops) {
|
||||||
const r = 10
|
const r = 10
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 435 B |
Reference in New Issue
Block a user