op/clip: split clip operations into its own package

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-11-09 19:05:03 +01:00
parent 560cf6054c
commit e864ac3fc3
14 changed files with 72 additions and 53 deletions
+1 -1
View File
@@ -119,7 +119,7 @@ type material struct {
uvOffset f32.Point
}
// clipOp is the shadow of paint.ClipOp.
// clipOp is the shadow of clip.Op.
type clipOp struct {
bounds f32.Rectangle
}
+4 -4
View File
@@ -11,7 +11,7 @@ import (
"gioui.org/f32"
"gioui.org/op"
"gioui.org/op/paint"
"gioui.org/op/clip"
"gioui.org/text"
"golang.org/x/image/font"
"golang.org/x/image/font/sfnt"
@@ -43,7 +43,7 @@ func (f *Font) Layout(ppem fixed.Int26_6, str string, opts text.LayoutOptions) *
return layoutText(&f.buf, ppem, str, &opentype{Font: f.font, Hinting: font.HintingFull}, opts)
}
func (f *Font) Shape(ppem fixed.Int26_6, str text.String) paint.ClipOp {
func (f *Font) Shape(ppem fixed.Int26_6, str text.String) clip.Op {
return textPath(&f.buf, ppem, &opentype{Font: f.font, Hinting: font.HintingFull}, str)
}
@@ -136,9 +136,9 @@ func layoutText(buf *sfnt.Buffer, ppem fixed.Int26_6, str string, f *opentype, o
return &text.Layout{Lines: lines}
}
func textPath(buf *sfnt.Buffer, ppem fixed.Int26_6, f *opentype, str text.String) paint.ClipOp {
func textPath(buf *sfnt.Buffer, ppem fixed.Int26_6, f *opentype, str text.String) clip.Op {
var lastPos f32.Point
var builder paint.Path
var builder clip.Path
ops := new(op.Ops)
var x fixed.Int26_6
var advIdx int
+2 -2
View File
@@ -8,7 +8,7 @@ import (
"gioui.org/gesture"
"gioui.org/io/pointer"
"gioui.org/op"
"gioui.org/op/paint"
"gioui.org/op/clip"
)
type scrollChild struct {
@@ -248,7 +248,7 @@ func (l *List) layout() Dimensions {
}
var stack op.StackOp
stack.Push(ops)
paint.RectClip(r).Add(ops)
clip.Rect(r).Add(ops)
op.TransformOp{}.Offset(toPointF(axisPoint(l.Axis, pos, cross))).Add(ops)
child.macro.Add(ops)
stack.Pop()
+29 -13
View File
@@ -1,9 +1,10 @@
// SPDX-License-Identifier: Unlicense OR MIT
package paint
package clip
import (
"encoding/binary"
"image"
"math"
"gioui.org/f32"
@@ -12,10 +13,13 @@ import (
"gioui.org/op"
)
// Path constructs a ClipOp clip path described by lines and
// Bézier curves. Path generates no garbage and can be used for
// dynamic paths; path data is stored directly in the Ops list
// supplied to Begin.
// Path constructs a Op clip path described by lines and
// Bézier curves, where drawing outside the Path is discarded.
// The inside-ness of a pixel is determines by the even-odd rule,
// similar to the SVG rule of the same name.
//
// Path generates no garbage and can be used for dynamic paths; path
// data is stored directly in the Ops list supplied to Begin.
type Path struct {
ops *op.Ops
contour int
@@ -25,17 +29,17 @@ type Path struct {
macro op.MacroOp
}
// ClipOp sets the current clip to the intersection of
// Op sets the current clip to the intersection of
// the existing clip with this clip.
//
// If you need to reset the clip to its previous values after
// applying a ClipOp, use op.StackOp.
type ClipOp struct {
// applying a Op, use op.StackOp.
type Op struct {
macro op.MacroOp
bounds f32.Rectangle
}
func (p ClipOp) Add(o *op.Ops) {
func (p Op) Add(o *op.Ops) {
p.macro.Add(o)
data := o.Write(opconst.TypeClipLen)
data[0] = byte(opconst.TypeClip)
@@ -46,7 +50,7 @@ func (p ClipOp) Add(o *op.Ops) {
bo.PutUint32(data[13:], math.Float32bits(p.bounds.Max.Y))
}
// Begin the path, storing the path data and final ClipOp into ops.
// Begin the path, storing the path data and final Op into ops.
func (p *Path) Begin(ops *op.Ops) {
p.ops = ops
p.macro.Record(ops)
@@ -270,12 +274,24 @@ func (p *Path) simpleQuadTo(ctrl, to f32.Point) {
p.pen = to
}
// End the path and return the resulting ClipOp.
func (p *Path) End() ClipOp {
// End the path and return a clip operation that represents it.
func (p *Path) End() Op {
p.end()
p.macro.Stop()
return ClipOp{
return Op{
macro: p.macro,
bounds: p.bounds,
}
}
// Rect returns the clip area of a pixel aligned rectangular area.
func Rect(r image.Rectangle) Op {
return Op{bounds: toRectF(r)}
}
func toRectF(r image.Rectangle) f32.Rectangle {
return f32.Rectangle{
Min: f32.Point{X: float32(r.Min.X), Y: float32(r.Min.Y)},
Max: f32.Point{X: float32(r.Max.X), Y: float32(r.Max.Y)},
}
}
+16
View File
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: Unlicense OR MIT
/*
Package clip provides operations for clipping paint operations.
Drawing outside the current clip area is ignored.
The current clip is initially the infinite set. An Op sets the clip
to the intersection of the current clip and the clip area it
represents. If you need to reset the current clip to its value
before applying an Op, use op.StackOp.
General clipping areas are constructed with Path. Simpler special
cases such as rectangular clip areas also exist as convenient
constructors.
*/
package clip
+1 -4
View File
@@ -1,15 +1,12 @@
// SPDX-License-Identifier: Unlicense OR MIT
/*
Package paint provides operations for 2D graphics.
Package paint provides drawing operations for 2D graphics.
The PaintOp operation draws the current material into a rectangular
area, taking the current clip path and transformation into account.
The material is set by either a ColorOp for a constant color, or
ImageOp for an image.
The ClipOp operation sets the clip path. Drawing outside the clip
path is ignored. A path is a closed shape of lines or curves.
*/
package paint
-13
View File
@@ -102,16 +102,3 @@ func (d PaintOp) Add(o *op.Ops) {
bo.PutUint32(data[9:], math.Float32bits(d.Rect.Max.X))
bo.PutUint32(data[13:], math.Float32bits(d.Rect.Max.Y))
}
// RectClip returns a ClipOp corresponding to a pixel aligned
// rectangular area.
func RectClip(r image.Rectangle) ClipOp {
return ClipOp{bounds: toRectF(r)}
}
func toRectF(r image.Rectangle) f32.Rectangle {
return f32.Rectangle{
Min: f32.Point{X: float32(r.Min.X), Y: float32(r.Min.Y)},
Max: f32.Point{X: float32(r.Max.X), Y: float32(r.Max.Y)},
}
}
+5 -5
View File
@@ -3,7 +3,7 @@
package text
import (
"gioui.org/op/paint"
"gioui.org/op/clip"
"golang.org/x/image/math/fixed"
)
@@ -26,7 +26,7 @@ type layoutElem struct {
type path struct {
next, prev *path
key pathKey
val paint.ClipOp
val clip.Op
}
type layoutKey struct {
@@ -81,16 +81,16 @@ func (l *layoutCache) insert(lt *layoutElem) {
lt.next.prev = lt
}
func (c *pathCache) Get(k pathKey) (paint.ClipOp, bool) {
func (c *pathCache) Get(k pathKey) (clip.Op, bool) {
if v, ok := c.m[k]; ok {
c.remove(v)
c.insert(v)
return v.val, true
}
return paint.ClipOp{}, false
return clip.Op{}, false
}
func (c *pathCache) Put(k pathKey, v paint.ClipOp) {
func (c *pathCache) Put(k pathKey, v clip.Op) {
if c.m == nil {
c.m = make(map[pathKey]*path)
c.head = new(path)
+2 -2
View File
@@ -6,7 +6,7 @@ import (
"strconv"
"testing"
"gioui.org/op/paint"
"gioui.org/op/clip"
)
func TestLayoutLRU(t *testing.T) {
@@ -24,7 +24,7 @@ func TestLayoutLRU(t *testing.T) {
func TestPathLRU(t *testing.T) {
c := new(pathCache)
put := func(i int) {
c.Put(pathKey{str: strconv.Itoa(i)}, paint.ClipOp{})
c.Put(pathKey{str: strconv.Itoa(i)}, clip.Op{})
}
get := func(i int) bool {
_, ok := c.Get(pathKey{str: strconv.Itoa(i)})
+4 -4
View File
@@ -5,7 +5,7 @@ package text
import (
"unicode/utf8"
"gioui.org/op/paint"
"gioui.org/op/clip"
"gioui.org/unit"
"golang.org/x/image/math/fixed"
)
@@ -46,7 +46,7 @@ func (s *Shaper) Layout(c unit.Converter, font Font, str string, opts LayoutOpti
return tf.layout(fixed.I(c.Px(font.Size)), str, opts)
}
func (s *Shaper) Shape(c unit.Converter, font Font, str String) paint.ClipOp {
func (s *Shaper) Shape(c unit.Converter, font Font, str String) clip.Op {
tf := s.faceForFont(font)
return tf.shape(fixed.I(c.Px(font.Size)), str)
}
@@ -99,9 +99,9 @@ func (t *face) layout(ppem fixed.Int26_6, str string, opts LayoutOptions) *Layou
return l
}
func (t *face) shape(ppem fixed.Int26_6, str String) paint.ClipOp {
func (t *face) shape(ppem fixed.Int26_6, str String) clip.Op {
if t == nil {
return paint.ClipOp{}
return clip.Op{}
}
pk := pathKey{
ppem: ppem,
+2 -2
View File
@@ -3,7 +3,7 @@
package text
import (
"gioui.org/op/paint"
"gioui.org/op/clip"
"gioui.org/unit"
"golang.org/x/image/math/fixed"
)
@@ -61,7 +61,7 @@ type Font struct {
// Face implements text layout and shaping for a particular font.
type Face interface {
Layout(ppem fixed.Int26_6, str string, opts LayoutOptions) *Layout
Shape(ppem fixed.Int26_6, str String) paint.ClipOp
Shape(ppem fixed.Int26_6, str String) clip.Op
}
// Typeface identifies a particular typeface design. The empty
+2 -1
View File
@@ -14,6 +14,7 @@ import (
"gioui.org/io/pointer"
"gioui.org/layout"
"gioui.org/op"
"gioui.org/op/clip"
"gioui.org/op/paint"
"gioui.org/text"
"gioui.org/unit"
@@ -79,7 +80,7 @@ type SubmitEvent struct {
type line struct {
offset f32.Point
clip paint.ClipOp
clip clip.Op
}
const (
+2 -1
View File
@@ -8,6 +8,7 @@ import (
"gioui.org/f32"
"gioui.org/layout"
"gioui.org/op"
"gioui.org/op/clip"
"gioui.org/op/paint"
"gioui.org/unit"
)
@@ -36,7 +37,7 @@ func (im Image) Layout(gtx *layout.Context) {
d := image.Point{X: cs.Width.Constrain(w), Y: cs.Height.Constrain(h)}
var s op.StackOp
s.Push(gtx.Ops)
paint.RectClip(image.Rectangle{Max: d}).Add(gtx.Ops)
clip.Rect(image.Rectangle{Max: d}).Add(gtx.Ops)
im.Src.Add(gtx.Ops)
paint.PaintOp{Rect: f32.Rectangle{Max: f32.Point{X: float32(w), Y: float32(h)}}}.Add(gtx.Ops)
s.Pop()
+2 -1
View File
@@ -10,6 +10,7 @@ import (
"gioui.org/font"
"gioui.org/layout"
"gioui.org/op"
"gioui.org/op/clip"
"gioui.org/op/paint"
"gioui.org/text"
"gioui.org/unit"
@@ -79,7 +80,7 @@ func fill(gtx *layout.Context, col color.RGBA) {
func rrect(ops *op.Ops, width, height, se, sw, nw, ne float32) {
w, h := float32(width), float32(height)
const c = 0.55228475 // 4*(sqrt(2)-1)/3
var b paint.Path
var b clip.Path
b.Begin(ops)
b.Move(f32.Point{X: w, Y: h - se})
b.Cube(f32.Point{X: 0, Y: se * c}, f32.Point{X: -se + se*c, Y: se}, f32.Point{X: -se, Y: se}) // SE