forked from joejulian/gio
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
+21
-20
@@ -106,14 +106,14 @@ func (qs strokeQuads) split() []strokeQuads {
|
||||
return o
|
||||
}
|
||||
|
||||
func (qs strokeQuads) stroke(width float32, sty clip.StrokeStyle) strokeQuads {
|
||||
func (qs strokeQuads) stroke(stroke clip.StrokeStyle) strokeQuads {
|
||||
var (
|
||||
o strokeQuads
|
||||
hw = 0.5 * width
|
||||
hw = 0.5 * stroke.Width
|
||||
)
|
||||
|
||||
for _, ps := range qs.split() {
|
||||
rhs, lhs := ps.offset(hw, sty)
|
||||
rhs, lhs := ps.offset(hw, stroke)
|
||||
switch lhs {
|
||||
case nil:
|
||||
o = o.append(rhs)
|
||||
@@ -132,13 +132,14 @@ func (qs strokeQuads) stroke(width float32, sty clip.StrokeStyle) strokeQuads {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return o
|
||||
}
|
||||
|
||||
// offset returns the right-hand and left-hand sides of the path, offset by
|
||||
// the half-width hw.
|
||||
// The stroke style sty handles how segments are joined and ends are capped.
|
||||
func (qs strokeQuads) offset(hw float32, sty clip.StrokeStyle) (rhs, lhs strokeQuads) {
|
||||
// The stroke handles how segments are joined and ends are capped.
|
||||
func (qs strokeQuads) offset(hw float32, stroke clip.StrokeStyle) (rhs, lhs strokeQuads) {
|
||||
var (
|
||||
states []strokeState
|
||||
beg = qs[0].quad.From
|
||||
@@ -180,7 +181,7 @@ func (qs strokeQuads) offset(hw float32, sty clip.StrokeStyle) (rhs, lhs strokeQ
|
||||
next = states[0]
|
||||
}
|
||||
if state.n1 != next.n0 {
|
||||
strokePathJoin(sty, &rhs, &lhs, hw, state.p1, state.n1, next.n0, state.r1, next.r0)
|
||||
strokePathJoin(stroke, &rhs, &lhs, hw, state.p1, state.n1, next.n0, state.r1, next.r0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,10 +197,10 @@ func (qs strokeQuads) offset(hw float32, sty clip.StrokeStyle) (rhs, lhs strokeQ
|
||||
|
||||
// Default to counter-clockwise direction.
|
||||
lhs = lhs.reverse()
|
||||
strokePathCap(sty, &rhs, hw, qend.p1, qend.n1)
|
||||
strokePathCap(stroke, &rhs, hw, qend.p1, qend.n1)
|
||||
|
||||
rhs = rhs.append(lhs)
|
||||
strokePathCap(sty, &rhs, hw, qbeg.p0, qbeg.n0.Mul(-1))
|
||||
strokePathCap(stroke, &rhs, hw, qbeg.p0, qbeg.n0.Mul(-1))
|
||||
|
||||
rhs.close()
|
||||
|
||||
@@ -421,13 +422,13 @@ func quadBezierSplit(p0, p1, p2 f32.Point, t float32) (f32.Point, f32.Point, f32
|
||||
}
|
||||
|
||||
// strokePathJoin joins the two paths rhs and lhs, according to the provided
|
||||
// stroke style sty.
|
||||
func strokePathJoin(sty clip.StrokeStyle, rhs, lhs *strokeQuads, hw float32, pivot, n0, n1 f32.Point, r0, r1 float32) {
|
||||
if sty.Miter > 0 {
|
||||
strokePathMiterJoin(sty, rhs, lhs, hw, pivot, n0, n1, r0, r1)
|
||||
// stroke operation.
|
||||
func strokePathJoin(stroke clip.StrokeStyle, rhs, lhs *strokeQuads, hw float32, pivot, n0, n1 f32.Point, r0, r1 float32) {
|
||||
if stroke.Miter > 0 {
|
||||
strokePathMiterJoin(stroke, rhs, lhs, hw, pivot, n0, n1, r0, r1)
|
||||
return
|
||||
}
|
||||
switch sty.Join {
|
||||
switch stroke.Join {
|
||||
case clip.BevelJoin:
|
||||
strokePathBevelJoin(rhs, lhs, hw, pivot, n0, n1, r0, r1)
|
||||
case clip.RoundJoin:
|
||||
@@ -468,14 +469,14 @@ func strokePathRoundJoin(rhs, lhs *strokeQuads, hw float32, pivot, n0, n1 f32.Po
|
||||
}
|
||||
}
|
||||
|
||||
func strokePathMiterJoin(sty clip.StrokeStyle, rhs, lhs *strokeQuads, hw float32, pivot, n0, n1 f32.Point, r0, r1 float32) {
|
||||
func strokePathMiterJoin(stroke clip.StrokeStyle, rhs, lhs *strokeQuads, hw float32, pivot, n0, n1 f32.Point, r0, r1 float32) {
|
||||
if n0 == n1.Mul(-1) {
|
||||
strokePathBevelJoin(rhs, lhs, hw, pivot, n0, n1, r0, r1)
|
||||
return
|
||||
}
|
||||
|
||||
// This is to handle nearly linear joints that would be clipped otherwise.
|
||||
limit := math.Max(float64(sty.Miter), 1.001)
|
||||
limit := math.Max(float64(stroke.Miter), 1.001)
|
||||
|
||||
cw := dotPt(rot90CW(n0), n1) >= 0.0
|
||||
if cw {
|
||||
@@ -489,8 +490,8 @@ func strokePathMiterJoin(sty clip.StrokeStyle, rhs, lhs *strokeQuads, hw float32
|
||||
cos := math.Sqrt(0.5 * (1 + float64(cosPt(n0, n1))))
|
||||
d := hw64 / cos
|
||||
if math.Abs(limit*hw64) < math.Abs(d) {
|
||||
sty.Miter = 0 // Set miter to zero to disable the miter joint.
|
||||
strokePathJoin(sty, rhs, lhs, hw, pivot, n0, n1, r0, r1)
|
||||
stroke.Miter = 0 // Set miter to zero to disable the miter joint.
|
||||
strokePathJoin(stroke, rhs, lhs, hw, pivot, n0, n1, r0, r1)
|
||||
return
|
||||
}
|
||||
mid := pivot.Add(normPt(n0.Add(n1), float32(d)))
|
||||
@@ -509,9 +510,9 @@ func strokePathMiterJoin(sty clip.StrokeStyle, rhs, lhs *strokeQuads, hw float32
|
||||
lhs.lineTo(lp)
|
||||
}
|
||||
|
||||
// strokePathCap caps the provided path qs, according to the provided stroke style sty.
|
||||
func strokePathCap(sty clip.StrokeStyle, qs *strokeQuads, hw float32, pivot, n0 f32.Point) {
|
||||
switch sty.Cap {
|
||||
// strokePathCap caps the provided path qs, according to the provided stroke operation.
|
||||
func strokePathCap(stroke clip.StrokeStyle, qs *strokeQuads, hw float32, pivot, n0 f32.Point) {
|
||||
switch stroke.Cap {
|
||||
case clip.FlatCap:
|
||||
strokePathFlatCap(qs, hw, pivot, n0)
|
||||
case clip.SquareCap:
|
||||
|
||||
Reference in New Issue
Block a user