op/clip: add Circle and Path.CubeTo

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
This commit is contained in:
Egon Elbre
2021-03-13 14:24:49 +02:00
committed by Elias Naur
parent 2b21b48a7c
commit ee8e267d22
2 changed files with 57 additions and 4 deletions
+7 -4
View File
@@ -294,12 +294,15 @@ func (p *Path) arc(alpha float64, c f32.Point, rx, ry, beg, delta float64) {
// Cube records a cubic Bézier from the pen through
// two control points ending in to.
func (p *Path) Cube(ctrl0, ctrl1, to f32.Point) {
if ctrl0 == (f32.Point{}) && ctrl1 == (f32.Point{}) && to == (f32.Point{}) {
p.CubeTo(p.pen.Add(ctrl0), p.pen.Add(ctrl1), p.pen.Add(to))
}
// CubeTo records a cubic Bézier from the pen through
// two control points ending in to, with absolute coordinates.
func (p *Path) CubeTo(ctrl0, ctrl1, to f32.Point) {
if ctrl0 == p.pen && ctrl1 == p.pen && to == p.pen {
return
}
ctrl0 = ctrl0.Add(p.pen)
ctrl1 = ctrl1.Add(p.pen)
to = to.Add(p.pen)
data := p.ops.Write(scene.CommandSize + 4)
bo := binary.LittleEndian
bo.PutUint32(data[0:], uint32(p.contour))
+50
View File
@@ -4,6 +4,7 @@ package clip
import (
"image"
"math"
"gioui.org/f32"
"gioui.org/op"
@@ -101,6 +102,55 @@ func (rr Border) Add(ops *op.Ops) {
rr.Op(ops).Add(ops)
}
// Circle represents the clip area of a circle.
type Circle struct {
Center f32.Point
Radius float32
}
// Op returns the op for the circle.
func (c Circle) Op(ops *op.Ops) Op {
return Outline{Path: c.path(ops)}.Op()
}
// path returns the path spec for the circle.
func (c Circle) path(ops *op.Ops) PathSpec {
var p Path
p.Begin(ops)
center := c.Center
r := c.Radius
// https://pomax.github.io/bezierinfo/#circles_cubic.
const q = 4 * (math.Sqrt2 - 1) / 3 // 4*(sqrt(2)-1)/3
curve := r * q
top := f32.Point{X: center.X, Y: center.Y - r}
p.MoveTo(top)
p.CubeTo(
f32.Point{X: center.X + curve, Y: center.Y - r},
f32.Point{X: center.X + r, Y: center.Y - curve},
f32.Point{X: center.X + r, Y: center.Y},
)
p.CubeTo(
f32.Point{X: center.X + r, Y: center.Y + curve},
f32.Point{X: center.X + curve, Y: center.Y + r},
f32.Point{X: center.X, Y: center.Y + r},
)
p.CubeTo(
f32.Point{X: center.X - curve, Y: center.Y + r},
f32.Point{X: center.X - r, Y: center.Y + curve},
f32.Point{X: center.X - r, Y: center.Y},
)
p.CubeTo(
f32.Point{X: center.X - r, Y: center.Y - curve},
f32.Point{X: center.X - curve, Y: center.Y - r},
top,
)
return p.End()
}
// roundRect adds the outline of a rectangle with rounded corners to a
// path.
func roundRect(p *Path, size f32.Point, se, sw, nw, ne float32) {