I would like to propose the following (updated) amendments to the OpenRaster specification. Thanks to everyone who's taken the time to review the original proposal and comment on it.
The addition of svg:dst-in and svg:dst-out to the OpenRaster format would allow MyPaint, an app I co-maintain, implement layer masking. There is accordingly an experimental code branch with a draft implementation of these updates.
To the Layer Stack specification, the following change:
- Support for at least two new composite-ops:
svg:dst-in
andsvg:dst-out
. These names come from the old SVG Compositing 1.2 standard.
We could also add support for all Porter-Duff operators as defined in this and in Compositing-1, however only a limited subset are actually of practical use to artists. These two in particular allow entire layer groups to be masked; others which might be of use are the src-in and src-out variants (also useful for masking), and src-atop which can be used for texturing the layer below.
See "Reference Updates" below for updates to the normative references for these modes.
To the Layer Stack specification, the following changes:
-
The text "Layer stacks should be composited in a manner conforming to the W3C's Compositing and Blending Level 1 specification. The root stack is to composite as an isolated group over a background of the application's choice."
-
The text "Non-root stacks should be rendered as isolated groups if: a) their "isolation" property is
isolate
(and notauto
); or b) Theiropacity
is less that 1.0; or c) They use acomposite-op
other thansvg:src-over
." -
Define what "group isolation" is by pointing at the relevant part of the Compositing-1 spec. Add brief summary text: "Isolated groups are rendered independently, starting with a fully-transparent 'black' backdrop (rgba={0,0,0,0}). The results of this independent composite are then rendered on top of the group's own backdrop using its opacity and composite mode settings. Conversely, for non-isolated groups, each component layer is rendered in turn to the group's backdrop, just as if there were no stacked group
-
The text "Applications may assume that all stacks are isolated groups if that is all they support. If they do so, they must declare when writing OpenRaster files that their layer groups are isolated (isolation='isolate')."
-
Consolidate all the modes into a single table, and provide deep links into the Compositing-1 specification, which provides a (much improved) normative reference for them and the mathematics involved.
The rather unusual point 3 above is part of the Compositing-1 spec which is intended to provide backwards compatibility for SVG's old layer model which only supported src-over (regular alpha-compositing). See Extra properties for layer groups below for details of the isolation
property, but note that most apps which support OpenRaster only support isolated layer groups.
To the Layer Stack specification, the following changes to the definition for non-root <stack/>
elements:
-
Add the Compositing-1
isolation
property as an XML attribute, taking the valuesauto
orisolate
. The default value isauto
. Its meaning is as described above in Reference Updates. -
Support for
opacity
,visibility
, andcomposite-op
properties, as defined for the<layer/>
element.
The root layer stack has a fixed, implicit rendering in OpenRaster. For sub-stacks, which are commonly called "layer groups" in painting apps, the behaviour described for inferring group isolation based on unusual opacities or layer modes should suffice to provide backwards compatibility with apps which formerly didn't care about group isolation.
In terms of the Compositing-1 spec's terminology, current painting apps with OpenRaster support have the following behaviours:
-
GIMP 2.8.6: All layer groups are isolated regardless of layer flags and opacities, and this cannot be turned off. In addition, "effects" layers (e.g. "Colour" or "Screen") are always masked by the "normal" layers ("Normal" or "Dissolve") below them within their group. Thus, "effects" layers in GIMP use an implicit SRC-ATOP Porter-Duff compositing operator (I think). "Normal" layers use the regular SRC-OVER operator.
-
Krita 2.7.5: All layer groups are isolated regardless of layer flags and opacities. Effects layers (e.g. "Colour" or "Screen") are not masked by layers below them within their group. The implicit Porter-Duff compositing operator appears to be SRC-OVER. Of note: Krita already has an "erase" mode which is identical to experimental MyPaint DST-OUT modes.
-
MyPaint master as of 2014-02-14: all layer groups are non-isolated, regardless of layer flags or opacities. Hence, nothing is masked, and all effects layers composite with an implicit SRC-OVER Porter-Duff mode.
It's fairly clear that MyPaint has an unusual (non-)treatment of group isolation. Defaulting "isolation" to "auto" should allow this app to evolve closer to the Krita and GIMP models as time progresses. OpenRaster is MyPaint's default format.
The venerable GIMP has a different unusual behaviour: the implicit SRC-ATOP compositing of "effects" layers, applied after the blend result is calculated. This can be expressed simply by creating a mask consisting of the simple alpha composition of the underlying layers. Consider a GIMP document with::
root
├ "layer group" (Normal)
│ ├ "layer 3" (Screen)
│ ├ "layer 2" (Normal)
│ └ "layer 1" (Normal)
└ "bg" (Normal)
This might be represented in OpenRaster as the admittedly more complex::
root
├ "layer group" (svg:normal) ← ORA substack representing a GIMP group
│ ├ "layer 3" (svg:screen) ← ORA substack representing a GIMP effect layer
│ │ ├ "artificial composite mask" (svg:dst-in)
│ │ │ ├ data/layer2.png (svg:src-over) ←note reuse of layer2.png
│ │ │ └ data/layer1.png (svg:src-over) ←note reuse of layer1.png
│ │ └ data/layer3.png (svg:src-over)
│ ├ data/layer2.png "layer 2" (svg:src-over)
│ └ data/layer1.png "layer 1" (svg:src-over)
└ data/bg.png "bg" (svg:src-over)
Or any other structure which masks "layer 3" correctly.
Krita would be unaffected by this proposed change.
Posted to the CREATE list too: http://lists.freedesktop.org/archives/create/2013-December/004690.html