mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 01:45:36 +00:00
all: introduce Outline and Stroke builders
This CL introduces 2 new path builders:
- Outline which takes a PathSpec to be outlined
- Stroke which takes a PathSpec and a stroke style, to stroke a path.
typically, code like this:
var p clip.Path
...
p.Outline().Add(o)
should be replaced with:
var p clip.Path
...
clip.Outline{Path: p.End()}.Op().Add(o)
similarly, stroking should be modified from:
var p clip.Path
...
p.Stroke(width, clip.StrokeStyle{...}).Add(o)
to:
var p clip.Path
...
clip.Stroke{Path: p.End(), Style: clip.StrokeStyle{Width:...}}.Op().Add(o)
here are tentative 'rf' scripts (see rsc.io/rf for more details):
```
ex {
import "gioui.org/op";
import "gioui.org/op/clip";
var p clip.Path;
var o *op.Ops;
p.Outline().Add(o) -> clip.Outline{Path:p.End()}.Op().Add(o);
}
ex {
import "gioui.org/op";
import "gioui.org/op/clip";
var o *op.Ops;
var p clip.Path;
var sty clip.StrokeStyle;
var width float32;
p.Stroke(width, sty).Add(o) -> \
clip.Stroke{ \
Path:p.End(), \
Style: clip.StrokeStyle{ \
Width: width, \
}}.Op().Add(o);
}
```
Signed-off-by: Sebastien Binet <s@sbinet.org>
This commit is contained in:
committed by
Elias Naur
parent
7c5bcd3db8
commit
be89f8b945
+132
-132
@@ -68,7 +68,9 @@ func TestPaintArc(t *testing.T) {
|
||||
p.Arc(f32.Pt(-10, -20), f32.Pt(10, -5), math.Pi)
|
||||
p.Line(f32.Pt(0, -10))
|
||||
p.Line(f32.Pt(-50, 0))
|
||||
p.Outline().Add(o)
|
||||
clip.Outline{
|
||||
Path: p.End(),
|
||||
}.Op().Add(o)
|
||||
|
||||
paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 128, 128)).Op())
|
||||
}, func(r result) {
|
||||
@@ -87,7 +89,9 @@ func TestPaintAbsolute(t *testing.T) {
|
||||
p.MoveTo(f32.Pt(20, 20))
|
||||
p.LineTo(f32.Pt(80, 20))
|
||||
p.QuadTo(f32.Pt(80, 80), f32.Pt(20, 80))
|
||||
p.Outline().Add(o)
|
||||
clip.Outline{
|
||||
Path: p.End(),
|
||||
}.Op().Add(o)
|
||||
|
||||
paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 128, 128)).Op())
|
||||
}, func(r result) {
|
||||
@@ -125,23 +129,15 @@ func TestPaintClippedTexture(t *testing.T) {
|
||||
|
||||
func TestStrokedPathBevelFlat(t *testing.T) {
|
||||
run(t, func(o *op.Ops) {
|
||||
const width = 2.5
|
||||
sty := clip.StrokeStyle{
|
||||
Cap: clip.FlatCap,
|
||||
Join: clip.BevelJoin,
|
||||
}
|
||||
|
||||
p := new(clip.Path)
|
||||
p.Begin(o)
|
||||
p.Move(f32.Pt(10, 50))
|
||||
p.Line(f32.Pt(10, 0))
|
||||
p.Arc(f32.Pt(10, 0), f32.Pt(20, 0), math.Pi)
|
||||
p.Line(f32.Pt(10, 0))
|
||||
p.Line(f32.Pt(10, 10))
|
||||
p.Arc(f32.Pt(0, 30), f32.Pt(0, 30), 2*math.Pi)
|
||||
p.Line(f32.Pt(-20, 0))
|
||||
p.Quad(f32.Pt(-10, -10), f32.Pt(-30, 30))
|
||||
p.Stroke(width, sty).Add(o)
|
||||
p := newStrokedPath(o)
|
||||
clip.Stroke{
|
||||
Path: p,
|
||||
Style: clip.StrokeStyle{
|
||||
Width: 2.5,
|
||||
Cap: clip.FlatCap,
|
||||
Join: clip.BevelJoin,
|
||||
},
|
||||
}.Op().Add(o)
|
||||
|
||||
paint.Fill(o, red)
|
||||
}, func(r result) {
|
||||
@@ -152,23 +148,15 @@ func TestStrokedPathBevelFlat(t *testing.T) {
|
||||
|
||||
func TestStrokedPathBevelRound(t *testing.T) {
|
||||
run(t, func(o *op.Ops) {
|
||||
const width = 2.5
|
||||
sty := clip.StrokeStyle{
|
||||
Cap: clip.RoundCap,
|
||||
Join: clip.BevelJoin,
|
||||
}
|
||||
|
||||
p := new(clip.Path)
|
||||
p.Begin(o)
|
||||
p.Move(f32.Pt(10, 50))
|
||||
p.Line(f32.Pt(10, 0))
|
||||
p.Arc(f32.Pt(10, 0), f32.Pt(20, 0), math.Pi)
|
||||
p.Line(f32.Pt(10, 0))
|
||||
p.Line(f32.Pt(10, 10))
|
||||
p.Arc(f32.Pt(0, 30), f32.Pt(0, 30), 2*math.Pi)
|
||||
p.Line(f32.Pt(-20, 0))
|
||||
p.Quad(f32.Pt(-10, -10), f32.Pt(-30, 30))
|
||||
p.Stroke(width, sty).Add(o)
|
||||
p := newStrokedPath(o)
|
||||
clip.Stroke{
|
||||
Path: p,
|
||||
Style: clip.StrokeStyle{
|
||||
Width: 2.5,
|
||||
Cap: clip.RoundCap,
|
||||
Join: clip.BevelJoin,
|
||||
},
|
||||
}.Op().Add(o)
|
||||
|
||||
paint.Fill(o, red)
|
||||
}, func(r result) {
|
||||
@@ -179,23 +167,15 @@ func TestStrokedPathBevelRound(t *testing.T) {
|
||||
|
||||
func TestStrokedPathBevelSquare(t *testing.T) {
|
||||
run(t, func(o *op.Ops) {
|
||||
const width = 2.5
|
||||
sty := clip.StrokeStyle{
|
||||
Cap: clip.SquareCap,
|
||||
Join: clip.BevelJoin,
|
||||
}
|
||||
|
||||
p := new(clip.Path)
|
||||
p.Begin(o)
|
||||
p.Move(f32.Pt(10, 50))
|
||||
p.Line(f32.Pt(10, 0))
|
||||
p.Arc(f32.Pt(10, 0), f32.Pt(20, 0), math.Pi)
|
||||
p.Line(f32.Pt(10, 0))
|
||||
p.Line(f32.Pt(10, 10))
|
||||
p.Arc(f32.Pt(0, 30), f32.Pt(0, 30), 2*math.Pi)
|
||||
p.Line(f32.Pt(-20, 0))
|
||||
p.Quad(f32.Pt(-10, -10), f32.Pt(-30, 30))
|
||||
p.Stroke(width, sty).Add(o)
|
||||
p := newStrokedPath(o)
|
||||
clip.Stroke{
|
||||
Path: p,
|
||||
Style: clip.StrokeStyle{
|
||||
Width: 2.5,
|
||||
Cap: clip.SquareCap,
|
||||
Join: clip.BevelJoin,
|
||||
},
|
||||
}.Op().Add(o)
|
||||
|
||||
paint.Fill(o, red)
|
||||
}, func(r result) {
|
||||
@@ -206,23 +186,15 @@ func TestStrokedPathBevelSquare(t *testing.T) {
|
||||
|
||||
func TestStrokedPathRoundRound(t *testing.T) {
|
||||
run(t, func(o *op.Ops) {
|
||||
const width = 2.5
|
||||
sty := clip.StrokeStyle{
|
||||
Cap: clip.RoundCap,
|
||||
Join: clip.RoundJoin,
|
||||
}
|
||||
|
||||
p := new(clip.Path)
|
||||
p.Begin(o)
|
||||
p.Move(f32.Pt(10, 50))
|
||||
p.Line(f32.Pt(10, 0))
|
||||
p.Arc(f32.Pt(10, 0), f32.Pt(20, 0), math.Pi)
|
||||
p.Line(f32.Pt(10, 0))
|
||||
p.Line(f32.Pt(10, 10))
|
||||
p.Arc(f32.Pt(0, 30), f32.Pt(0, 30), 2*math.Pi)
|
||||
p.Line(f32.Pt(-20, 0))
|
||||
p.Quad(f32.Pt(-10, -10), f32.Pt(-30, 30))
|
||||
p.Stroke(width, sty).Add(o)
|
||||
p := newStrokedPath(o)
|
||||
clip.Stroke{
|
||||
Path: p,
|
||||
Style: clip.StrokeStyle{
|
||||
Width: 2.5,
|
||||
Cap: clip.RoundCap,
|
||||
Join: clip.RoundJoin,
|
||||
},
|
||||
}.Op().Add(o)
|
||||
|
||||
paint.Fill(o, red)
|
||||
}, func(r result) {
|
||||
@@ -233,40 +205,32 @@ func TestStrokedPathRoundRound(t *testing.T) {
|
||||
|
||||
func TestStrokedPathFlatMiter(t *testing.T) {
|
||||
run(t, func(o *op.Ops) {
|
||||
const width = 10
|
||||
sty := clip.StrokeStyle{
|
||||
Cap: clip.FlatCap,
|
||||
Join: clip.BevelJoin,
|
||||
Miter: 5,
|
||||
}
|
||||
|
||||
beg := f32.Pt(40, 10)
|
||||
{
|
||||
p := new(clip.Path)
|
||||
p.Begin(o)
|
||||
p.Move(beg)
|
||||
p.Line(f32.Pt(50, 0))
|
||||
p.Line(f32.Pt(-50, 50))
|
||||
p.Line(f32.Pt(50, 0))
|
||||
p.Quad(f32.Pt(-50, 20), f32.Pt(-50, 50))
|
||||
p.Line(f32.Pt(50, 0))
|
||||
|
||||
p.Stroke(width, sty).Add(o)
|
||||
stk := op.Push(o)
|
||||
p := newZigZagPath(o)
|
||||
clip.Stroke{
|
||||
Path: p,
|
||||
Style: clip.StrokeStyle{
|
||||
Width: 10,
|
||||
Cap: clip.FlatCap,
|
||||
Join: clip.BevelJoin,
|
||||
Miter: 5,
|
||||
},
|
||||
}.Op().Add(o)
|
||||
paint.Fill(o, red)
|
||||
stk.Pop()
|
||||
}
|
||||
|
||||
{
|
||||
p := new(clip.Path)
|
||||
p.Begin(o)
|
||||
p.Move(beg)
|
||||
p.Line(f32.Pt(50, 0))
|
||||
p.Line(f32.Pt(-50, 50))
|
||||
p.Line(f32.Pt(50, 0))
|
||||
p.Quad(f32.Pt(-50, 20), f32.Pt(-50, 50))
|
||||
p.Line(f32.Pt(50, 0))
|
||||
|
||||
p.Stroke(2, clip.StrokeStyle{}).Add(o)
|
||||
stk := op.Push(o)
|
||||
p := newZigZagPath(o)
|
||||
clip.Stroke{
|
||||
Path: p,
|
||||
Style: clip.StrokeStyle{
|
||||
Width: 2,
|
||||
},
|
||||
}.Op().Add(o)
|
||||
paint.Fill(o, black)
|
||||
stk.Pop()
|
||||
}
|
||||
|
||||
}, func(r result) {
|
||||
@@ -278,40 +242,32 @@ func TestStrokedPathFlatMiter(t *testing.T) {
|
||||
|
||||
func TestStrokedPathFlatMiterInf(t *testing.T) {
|
||||
run(t, func(o *op.Ops) {
|
||||
const width = 10
|
||||
sty := clip.StrokeStyle{
|
||||
Cap: clip.FlatCap,
|
||||
Join: clip.BevelJoin,
|
||||
Miter: float32(math.Inf(+1)),
|
||||
}
|
||||
|
||||
beg := f32.Pt(40, 10)
|
||||
{
|
||||
p := new(clip.Path)
|
||||
p.Begin(o)
|
||||
p.Move(beg)
|
||||
p.Line(f32.Pt(50, 0))
|
||||
p.Line(f32.Pt(-50, 50))
|
||||
p.Line(f32.Pt(50, 0))
|
||||
p.Quad(f32.Pt(-50, 20), f32.Pt(-50, 50))
|
||||
p.Line(f32.Pt(50, 0))
|
||||
|
||||
p.Stroke(width, sty).Add(o)
|
||||
stk := op.Push(o)
|
||||
p := newZigZagPath(o)
|
||||
clip.Stroke{
|
||||
Path: p,
|
||||
Style: clip.StrokeStyle{
|
||||
Width: 10,
|
||||
Cap: clip.FlatCap,
|
||||
Join: clip.BevelJoin,
|
||||
Miter: float32(math.Inf(+1)),
|
||||
},
|
||||
}.Op().Add(o)
|
||||
paint.Fill(o, red)
|
||||
stk.Pop()
|
||||
}
|
||||
|
||||
{
|
||||
p := new(clip.Path)
|
||||
p.Begin(o)
|
||||
p.Move(beg)
|
||||
p.Line(f32.Pt(50, 0))
|
||||
p.Line(f32.Pt(-50, 50))
|
||||
p.Line(f32.Pt(50, 0))
|
||||
p.Quad(f32.Pt(-50, 20), f32.Pt(-50, 50))
|
||||
p.Line(f32.Pt(50, 0))
|
||||
|
||||
p.Stroke(2, clip.StrokeStyle{}).Add(o)
|
||||
stk := op.Push(o)
|
||||
p := newZigZagPath(o)
|
||||
clip.Stroke{
|
||||
Path: p,
|
||||
Style: clip.StrokeStyle{
|
||||
Width: 2,
|
||||
},
|
||||
}.Op().Add(o)
|
||||
paint.Fill(o, black)
|
||||
stk.Pop()
|
||||
}
|
||||
|
||||
}, func(r result) {
|
||||
@@ -323,26 +279,35 @@ func TestStrokedPathFlatMiterInf(t *testing.T) {
|
||||
|
||||
func TestStrokedPathZeroWidth(t *testing.T) {
|
||||
run(t, func(o *op.Ops) {
|
||||
const width = 2
|
||||
var sty clip.StrokeStyle
|
||||
{
|
||||
stk := op.Push(o)
|
||||
p := new(clip.Path)
|
||||
p.Begin(o)
|
||||
p.Move(f32.Pt(10, 50))
|
||||
p.Line(f32.Pt(50, 0))
|
||||
p.Stroke(width, sty).Add(o)
|
||||
clip.Stroke{
|
||||
Path: p.End(),
|
||||
Style: clip.StrokeStyle{
|
||||
Width: 2,
|
||||
},
|
||||
}.Op().Add(o)
|
||||
|
||||
paint.Fill(o, black)
|
||||
stk.Pop()
|
||||
}
|
||||
|
||||
{
|
||||
stk := op.Push(o)
|
||||
p := new(clip.Path)
|
||||
p.Begin(o)
|
||||
p.Move(f32.Pt(10, 50))
|
||||
p.Line(f32.Pt(30, 0))
|
||||
p.Stroke(0, sty).Add(o) // width=0, disable stroke
|
||||
clip.Stroke{
|
||||
Path: p.End(),
|
||||
}.Op().Add(o) // width=0, disable stroke
|
||||
|
||||
paint.Fill(o, red)
|
||||
stk.Pop()
|
||||
}
|
||||
|
||||
}, func(r result) {
|
||||
@@ -352,3 +317,38 @@ func TestStrokedPathZeroWidth(t *testing.T) {
|
||||
r.expect(65, 50, colornames.White)
|
||||
})
|
||||
}
|
||||
|
||||
func newStrokedPath(o *op.Ops) clip.PathSpec {
|
||||
p := new(clip.Path)
|
||||
p.Begin(o)
|
||||
p.Move(f32.Pt(10, 50))
|
||||
p.Line(f32.Pt(10, 0))
|
||||
p.Arc(f32.Pt(10, 0), f32.Pt(20, 0), math.Pi)
|
||||
p.Line(f32.Pt(10, 0))
|
||||
p.Line(f32.Pt(10, 10))
|
||||
p.Arc(f32.Pt(0, 30), f32.Pt(0, 30), 2*math.Pi)
|
||||
p.Line(f32.Pt(-20, 0))
|
||||
p.Quad(f32.Pt(-10, -10), f32.Pt(-30, 30))
|
||||
return p.End()
|
||||
}
|
||||
|
||||
func newZigZagPath(o *op.Ops) clip.PathSpec {
|
||||
p := new(clip.Path)
|
||||
p.Begin(o)
|
||||
p.Move(f32.Pt(40, 10))
|
||||
p.Line(f32.Pt(50, 0))
|
||||
p.Line(f32.Pt(-50, 50))
|
||||
p.Line(f32.Pt(50, 0))
|
||||
p.Quad(f32.Pt(-50, 20), f32.Pt(-50, 50))
|
||||
p.Line(f32.Pt(50, 0))
|
||||
return p.End()
|
||||
}
|
||||
|
||||
func newEllipsePath(o *op.Ops) clip.PathSpec {
|
||||
p := new(clip.Path)
|
||||
p.Begin(o)
|
||||
p.Move(f32.Pt(0, 65))
|
||||
p.Line(f32.Pt(20, 0))
|
||||
p.Arc(f32.Pt(20, 0), f32.Pt(70, 0), 2*math.Pi)
|
||||
return p.End()
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.2 KiB |
@@ -71,7 +71,10 @@ func TestRepeatedPaintsZ(t *testing.T) {
|
||||
builder.Line(f32.Pt(0, 10))
|
||||
builder.Line(f32.Pt(-10, 0))
|
||||
builder.Line(f32.Pt(0, -10))
|
||||
builder.Outline().Add(o)
|
||||
p := builder.End()
|
||||
clip.Outline{
|
||||
Path: p,
|
||||
}.Op().Add(o)
|
||||
paint.Fill(o, red)
|
||||
}, func(r result) {
|
||||
r.expect(5, 5, colornames.Red)
|
||||
@@ -109,7 +112,8 @@ func constSqPath() op.CallOp {
|
||||
builder.Line(f32.Pt(0, 10))
|
||||
builder.Line(f32.Pt(-10, 0))
|
||||
builder.Line(f32.Pt(0, -10))
|
||||
builder.Outline().Add(innerOps)
|
||||
p := builder.End()
|
||||
clip.Outline{Path: p}.Op().Add(innerOps)
|
||||
return m.Stop()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user