Commit Graph

100 Commits

Author SHA1 Message Date
Elias Naur f9cf6ff20a op/clip: separate function for approximating arcs with quadratic curves
Both Path.Arc and the internal stroke package needs to support arcs;
this change isolates the approximation computation into a function we
can move to internal/stroke in a follow-up.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-23 15:01:00 +01:00
Elias Naur 13da40f601 gpu,op/clip: [compute] get rid of stroke vs fill flags
The fill mode is now controlled by a SetFillMode command, not by flags
on each path segment and fill command.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-19 21:46:31 +01:00
pierre ac800a9d8f op/clip: optimize zero corner radius in RRect if pixel-aligned
Signed-off-by: pierre <pierre.curto@gmail.com>
2021-03-16 19:00:47 +01:00
Egon Elbre 9cb9e67a8e op/clip: remove Border
Border can be expressed in-terms of clip.Stroke:

  clip.Stroke{
      Path: clip.UniformRRect(r, rr).Ops(ops),
      Style: clip.StrokeStyle{Width: width},
  }.Add(ops)

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2021-03-14 13:28:21 +01:00
Egon Elbre fecfbbb050 op/clip: expose Circle.Path and RRect.Path.
These can be nicely used together with clip.Stroke.

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2021-03-14 13:28:21 +01:00
Egon Elbre d994d092ae op/clip: use absolute coordinates in RRect
This avoids issues with floating point drift.

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2021-03-14 10:10:00 +01:00
Egon Elbre ee8e267d22 op/clip: add Circle and Path.CubeTo
Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2021-03-14 10:08:50 +01:00
Elias Naur 2b21b48a7c gpu,gpu/shaders: revert attempt to fix path gaps
This is effectively a revert of [0], reintroducing the path gaps
described in [1]. A follow-up change will implement another attempt.

[0] https://gioui.org/commit/2feec23561cd84d6b8ddbab84a202df66b123208
[1] https://github.com/linebender/piet-gpu/issues/62

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-13 15:23:25 +01:00
Egon Elbre 65a2410bb9 op/clip: ensure that roundRect is always closed
Floating point error may accumulate and the round rect may not
necessarily close up entirely. Add an additional "Close" to ensure
it's properly closed.

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2021-03-13 13:49:59 +02:00
Elias Naur c5fb759aef op/clip: make RoundCap and RoundJoin the default stroke style
There's an argument that rounded caps and joins are the simplest stroke,
in that it can be defined to cover all pixels within lineWidth distance
from the supporting path.

However, the more important reason is that the compute renderer natively
supports this stroke style (without dashes), and users that don't care
(much) about the particular stroke style should get the efficient
implementation. A good example is op/clip.Border that strokes a closed
path, where the StrokeCap is irrelevant.

This is a (subtle) API change. If you have code that relies on the
default values of clip.StrokeStyle you may want to set Cap and Join
explicitly. See the test changes for examples. On the other hand, you
will get much better performance from the default Cap and Join values
once the compute renderer becomes the default.

Disablethe TestPaintClippedBorder test; dashes round-capped,
round-joined strokes doesn't seem to work correctly.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-12 12:19:39 +01:00
Elias Naur 9e79cee447 op/clip,gpu,internal/scene: encode cubic bézier curves natively
The compute renderer supports cubic curves, so encode them as such.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-11 18:54:12 +01:00
Elias Naur f1ae923a89 gpu,op/clip: encode lines as compute line commands, not quads
The new renderer supports lines natively; encode them as such and
convert them to a quadratic beziér.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-11 18:54:12 +01:00
Elias Naur a369c408f9 gpu: [compute] skip encoding roundtrip for path data
Since clip.Path now encodes paths in the format expected by
elements.comp, use that data directly instead of a roundtrip through
drawOps.buildVerts.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-11 18:54:12 +01:00
Elias Naur eb9bf60b09 gpu,internal/ops: decode scene commands directly, not through quads
We're about to let clip.Path use more of the compute renderer features
(lines, cubic béziers). This change prepares the gpu package for reading
one of several commands types, not just the quadratic béziers of before.

The old Quad type is still the basis for the stroking algorithms, but
this change moves it into package gpu which is the only user.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-11 18:54:12 +01:00
Elias Naur 07572387e3 internal/ops: switch quad encoding to compute format
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-11 18:54:12 +01:00
Elias Naur b8bdb96d35 op/clip,gpu,internal/opconst: remove quad count from Path op
The check for path segments in gpu is redundant; clip.Op.Add doesn't add
the Path op if there were no segments.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-11 18:19:31 +01:00
Elias Naur 884e7d27e2 op/clip: don't accept open Paths for Outline
Outline represents a clipping operations that clips all drawing outside
a closed path. Before this change, paths not closed we're patched up by
adding an implicit line from the endpoint to the beginning.

These fixups are inefficient for a rare case, but acceptable because the
old renderer post-processes all paths anyway. However, the new compute
renderer don't need post-processing in most cases, making fixups too
expensive.

Given that clipping to an open path is fundamentally undefined and that
implicit fixup with a closing line segment is merely a way to force the
clip to be well-defined, this change adds a panic to Outline for Paths
that are not closed.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-03-11 08:57:27 +01:00
Elias Naur cd47a158a2 op/clip: move Rect to shapes.go
It's a specialized shape like the others.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-19 20:31:29 +01:00
Chris Waldon d93874005c op/clip: document dimensions of Border.
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2021-01-19 20:30:51 +01:00
Elias Naur d6886737a5 op: change Defer to only restore transformation state
It turns out restoring all operation state from the moment Defer
is executed is too much; for example, a right-click pop-up needs
the transformation, but not the current clip.

Change Defer to only restore the transformation, and reset all
other state.

Other combinations may be needed in future; we'll deal with them then,
possibly by exposing the load state mask.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-19 20:04:30 +01:00
Elias Naur f86703e4b0 op: introduce Defer for deferring CallOps
Updates gio#164

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-14 15:53:49 +01:00
Elias Naur d331dd2de8 op: rename StackOp/Push/Pop to StateOp/Save/Load
The semantics were relaxed in a previous commit; this change renames
to operations accordingly.

API change. Use gofmt to adjust your code accordingly:

gofmt -r 'op.Push(a).Pop() -> op.Save(a).Load()'
gofmt -r 'op.Push(a) -> op.Save(a)'
gofmt -r 'v.Pop() -> v.Load()'
gofmt -r 'op.StackOp -> op.StateOp'

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-12 21:28:59 +01:00
Elias Naur ae2c74ec13 op: relax Push/Pop to Save/Restore semantics
A previous change implemented save/restore semantics where a saved
state can be restored anywhere, not just in a stack-like manner.

This change similarly relaxes the exported Push/Pop operations; the next
change will rename them accordingly.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-12 20:53:47 +01:00
Elias Naur f7902f299b op: implement StackOp in terms of general save/load of state
Push/Pop only allows saving and restoring operation state in a
stack-like manner. We're going to need restoring arbitrary state
for implementing deferred operations.

Generalize state save/restore and implement Push and Pop on top of
that.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-12 20:53:25 +01:00
Sebastien Binet e71bf13c9a gpu,op/clip: implement dashed stroked paths
Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-12-09 11:23:13 +01:00
Sebastien Binet be89f8b945 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>
2020-12-09 09:44:15 +01:00
Elias Naur 951d45a2c6 op/clip: fix incirrent mention of even-odd fill rule
It's the non-zero winding rule.

Noticed by Richard Wilkes.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-12-03 10:03:51 +01:00
Egon Elbre 7bad76ad75 op/clip: handle zero Cube
Currently this comes up with RRect/Border that has zero corners. It
improves them from ~250ns to ~170ns. While it's possible to check this
in RRect implementation, however it'll slow down calls with non-zero
corners.

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2020-11-24 14:38:14 +01:00
Egon Elbre 918a5da308 Many operations do not pass refs to Write. Similarly adding
...interface{} requires constructing a slice, which is slow.

This cuts about 100ns from RRect and Border benchmark.

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2020-11-23 23:43:17 +01:00
Egon Elbre 1899104536 op/clip: expose LineTo and QuadTo
Using delta position with Line and Quad can drift over successive calls.
Also, in some cases it's much more convenient to use absolute
coordinates rather than relative.

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2020-11-21 22:46:03 +01:00
Egon Elbre 21ef492cc9 all: use color.NRGBA in public API
color.RGBA has two problems with regards to using it.

First the color values need to be premultiplied, whereas most APIs
have non-premultiplied values. This is mainly to preserve color components
with low alpha values.

Second there are two ways to premultiply with sRGB. One is to premultiply
after sRGB conversion, the other is before. This makes using the API more
confusing.

Using color.NRGBA in sRGB makes it align with CSS.e

Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2020-11-19 11:30:11 +01:00
Elias Naur 23fa3480c6 op/paint: update documentation to match the removal of PaintOp.Rect
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-11-16 12:54:58 +01:00
Sebastien Binet 7eb32360e5 gpu,op/clip: implement stroked paths with miter joins
Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-11-11 16:14:49 +01:00
Sebastien Binet 700cec440e gpu,op/clip: implement stroked paths with round joins
Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-11-11 14:03:30 +01:00
Sebastien Binet 1106d90f11 gpu,op/clip: implement stroked paths with round caps
Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-11-11 12:25:24 +01:00
Sebastien Binet ae256b5be8 op/clip: use stroked path to draw Border
Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-11-10 16:41:14 +01:00
Sebastien Binet 33c5fb63db gpu,op/clip: implement stroked paths
Flat and Square caps are implemented.
Bevel joins are implemented.

Round caps, Round joins and Miter joins are left for another PR.

Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-11-10 15:58:10 +01:00
Sebastien Binet 936eb52b7e all: rename clip.Path.End into clip.Path.Outline
Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-11-10 15:58:07 +01:00
Elias Naur 8b5c0d8b0c op/paint: document that color.RGBA values are in the sRGB color space
Updates gio#169

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-11-08 19:31:38 +01:00
Elias Naur 94d242d18c op/paint: remove support for PaintOp.Rect
PaintOp.Rect is the wrong abstraction; it implies a clip operation
better handled by package clip, and not all paints need it (colors).
Furthermore, it's awkward to specify a PaintOp that fills up the
current clip area, regardless of its size.

Redefine PathOp to mean "fill current clip area".

API change. Replace uses of PaintOp.Rect with a TransformOp applied
before the PaintOp.

Leave a TODO for the PathOp infinity area.

Fixes gio#167

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-11-05 16:32:19 +01:00
Elias Naur afb52194d1 app/headless,internal/rendertest: replace PaintOps with Fill/FillShape
We're about to remove PaintOp.Rect. Replacing PaintOps with Fill or
FillShape where possible will ease the transition.

Using Fill in tests exposed a problem with the infinity in paint.Fill.
Adjust it for now; it will be removed later.

Updates gio#167

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-11-05 16:12:39 +01:00
Elias Naur 852958f4b5 gpu,widget,op/paint,gpu: remove support for ImageOp.Rect
This is effectively a revert of commit gioui.org/commit/69dfd2e3a5541.

ImageOp.Rect is the wrong abstraction; it implies a clipping operation that is
better handled by package clip.

API change. Uses of ImageOp.Rect should apply a clip.Rect before the PaintOp,
or use image.RGBA.SubImage (or similar).

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-11-05 13:36:36 +01:00
Elias Naur efdd5ae602 op/paint: make the shape argument last in FillShape
FillShape is a generalization of Fill, so it seems more natural to
have the extra argument last.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-11-03 18:57:25 +01:00
Elias Naur 3107c95757 op/clip: remove unused parameter from Rect.Op
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-11-03 18:57:25 +01:00
Egon Elbre f00f3a3359 gpu: add linear gradient
Signed-off-by: Egon Elbre <egonelbre@gmail.com>
2020-11-03 15:39:06 +01:00
Chris Waldon fc307c1e71 op/paint: add Fill helpers for painting an area with a solid color
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2020-10-22 18:57:47 +02:00
Chris Waldon 685e0772a3 op/clip: add UniformRRect to create rects with uniform corner radii
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2020-10-22 18:57:43 +02:00
Chris Waldon 8bdca84c56 op/clip: export Op method of clip shapes
This allows passing the resulting clip.Op types into functions that
draw shapes.

Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
2020-10-22 18:57:40 +02:00
Sebastien Binet f2cd504a9f op/clip: smoother implementation of Arc for large angles
Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-08-29 17:36:37 +02:00
Sebastien Binet 3fe0f62fa3 op/clip: export Path's current pen position
Signed-off-by: Sebastien Binet <s@sbinet.org>
2020-08-27 14:46:05 +02:00