@@ 333,11 333,15 @@ func TestStrokedPathArc(t *testing.T) {
Segments: []Segment{
MoveTo(f32.Pt(0, 65)),
LineTo(f32.Pt(20, 65)),
- ArcTo(f32.Pt(70, 65), +math.Pi/3),
+ ArcTo(f32.Pt(70, 65), +math.Pi/6),
LineTo(f32.Pt(70, 65)),
LineTo(f32.Pt(20, 65)),
- ArcTo(f32.Pt(70, 65), -math.Pi/2),
+ ArcTo(f32.Pt(70, 65), -math.Pi/6),
LineTo(f32.Pt(70, 65)),
+ LineTo(f32.Pt(70, 115)),
+ ArcTo(f32.Pt(70, 65), -7*math.Pi/6),
+ LineTo(f32.Pt(70, 65)),
+ LineTo(f32.Pt(70, 15)),
},
}
cl := Stroke{
@@ 352,6 356,7 @@ func TestStrokedPathArc(t *testing.T) {
r.expect(0, 0, transparent)
r.expect(70, 65, colornames.Red)
r.expect(35, 65, colornames.Red)
+ r.expect(120, 65, colornames.Red)
})
}
@@ 4,6 4,8 @@
package stroke
import (
+ "math"
+
"gioui.org/f32"
"gioui.org/op"
"gioui.org/op/clip"
@@ 163,9 165,20 @@ func (s Stroke) Op(ops *op.Ops) clip.Op {
contour = append(contour, stroke.Segment{stroke.Point(pen), stroke.Point(seg.args[0]), stroke.Point(seg.args[1]), stroke.Point(seg.args[2])})
pen = seg.args[2]
case segOpArcTo:
- out := stroke.ArcSegment(stroke.Point(pen), stroke.Point(seg.args[0]), seg.args[1].X)
- contour = append(contour, out)
- pen = f32.Point(out.End)
+ var (
+ start = stroke.Point(pen)
+ center = stroke.Point(seg.args[0])
+ angle = seg.args[1].X
+ )
+ switch {
+ case absF32(angle) > math.Pi:
+ contour = stroke.AppendArc(contour, start, center, angle)
+ pen = f32.Point(contour[len(contour)-1].End)
+ default:
+ out := stroke.ArcSegment(start, center, angle)
+ contour = append(contour, out)
+ pen = f32.Point(out.End)
+ }
}
}
if len(contour) > 0 {
@@ 219,3 232,7 @@ func (s Stroke) Op(ops *op.Ops) clip.Op {
return clip.Outline{Path: outline.End()}.Op()
}
+
+func absF32(x float32) float32 {
+ return math.Float32frombits(math.Float32bits(x) &^ (1 << 31))
+}