dplug:canvas enhancements
- [x] ways to do multiple lineTo in one call.
- [ ] Clipping rect, to avoid reinitializing the canvas for each dirtyRect (need to fix gradients coordinates I think)
- [ ] Note that if we had arbitrary clipping rect, would redraw even less, perhaps doable in canvasity!
- [ ] Gradients coordinates should be transformed on use based on current matrix and not before, breaking => superseded by
canvasitysomehow - [ ] fillStyle should be saveable, breaking too
- [x] add even-odd rule (savable state) in order to allows circles with holes
- [x] bypass transform if just a translation? => not worth it
- [ ] backport the new circle gradient from upstream
dg2d, which is like in a browser Behaviour observed in both Chrome and Firefox. - [x] is it possible to blit on separate buffer then composite afterwards? In order to have more operations than source-over?
- blitting white on black can makes a coverage mask! => yes, but only a few blend modes doable
- [x] make extra sure no down reallocate are happening
- [x] it should be possible to pass an ImageRef!L16 as destination. Colors should be converted L16 to RGBA8, using the 1/3 trick, and blitted back. This will allow to remove more oldschool draw.d methods => superseded by
canvasity - [x] globalAlpha (non-optimal path), state-saveable => superseded by
canvasity
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="300" height="300" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var grd = ctx.createRadialGradient(75, 50, 5, 90, 60, 100);
grd.addColorStop(0, "red");
grd.addColorStop(1, "white");
ctx.fillStyle = grd;
ctx.translate(20,0);
ctx.fillRect(10, 10, 150, 100);
ctx.translate(50,0);
ctx.fillRect(10, 120, 150, 100);
</script>
</body>
</html>
```
On second `fillRect` center of gradient is translated vs the first rectangle.
It is indeed more intuitive on use.
This will also allow to reuse gradients over several dirty rects.
I do'nt know how to do it in case of scale(x, y) with x different from y as then it's not circles anymore.
But it gets much harder with scale since circles won't stay circles, this is actually supported in browsers. (EDIT: it worked, but wouldn't work if shearing was allowed)
Point coord
- [x] Use
vec2fas alternative whenever possible.
Reference for possible composite operations: https://www.w3schools.com/tags/playcanvas.php?filename=playcanvas_globalcompop
Is globalCompositeOperation implementable?
-
source-overthe only one we support.- the rasterizer currently does:
dest = dest * (1 - alpha) + alpha * src. If we do that on black, we obtainalpha * source color. - what happens to source alpha? Typically copied to dest alpha. So what we may have is:
RGBA(source-red * source-alpha, source-green * source-alpha, source-blue * source-alpha, source-alpha)not clear all blitters will give that - now if source color is white, dst is black, then we can output source-alpha. But that wouldn't account for color and alpha of gradients separately. We would need a special blitter function that outputs
RGBA(source-red, source-green, source-blue, source-alpha)instead of premultiplied? (or, we could unpremultiply lol)
- the rasterizer currently does:
-
source-atop: alpha of source should be premultiplied with alpha of dest. -
source-in: alpha of destination multiplied with alpha of source, and alpha of source should be multiplied with alpha of dest. -
source-out: alpha of dest taken instead of alpha of source -
lighter: take max of dest and alpha*src (not sure what happens to alpha) -
copy: only consider source -
xor: alpha is down to zero if both alpha are 1
All explained in https://ssp.impulsetrain.com/porterduff.html
From my understanding:
- We have only "Over" right now.
- We could have "Xor" and "Atop" rather easily.
- Desirable GIMP blending = Add, Multiply, Lighen Only, Darken Only, Divide, Grain Fusion, Difference, they would combine a blend mode and a porter-duff operator apparently. I think we can implement those instead of PorterDuff... all those for which source-alpha acts effectively like opacity.
Implemented sourceOver, add, subtract. We don't follow html spec here, in that background alpha is always assumed to be opaque (= 255). (EDIT: added lighten and darken modes too) Eventually we could also add globalAlpha which also breaks the fast path. Well that's 5 interesting modes without unpremultiply or redo the blitters.