[CREATE] OpenRaster fallbacks (proposal/RFC)

Martin Renold martinxyz at gmx.ch
Sat Jul 25 09:26:32 PDT 2009


hi,

This is a proposal to add generic fallbacks to OpenRaster.

My motivation for pushing this is that I want to save the tiled
background in MyPaint properly and compatible with Krita, and I want
the new images to look correct in today's version of Krita, MyPaint
and DrawPile.

Summary:

A <try> element can be put around something that provides a fallback.
If the required features are implemented, then the element that
follows the <try> is removed and the content of the <replacement> is
inserted in its place. Otherwise the try itself is dropped.

...
<stack>
  ...
  <try>
    <require>
      <feature name="text layers" />
    </require>
    <replacement>
      <text>
        some text
      </text>
    </replacement>
  </try>
  <layer name="rendered text" src="data/text_fallback.png" />
  ...
  
Considerations:

- Applications that don't implement fallbacks are the ones that need
  them most. They will just ignore the <try> element and use the
  fallback for everything. This keeps the minimal OpenRaster load
  implementation simple and hard to screw up.

- Many <try> elements can be nested to give partial fallbacks.

- The content of the <replacement> is equal to the content of a
  <stack> element. Forcing a <stack> element would break filters.

- The <try> elements makes implementations that keep the XML tree as
  their main model more complicated. (Workaround is not hard.)

The Feature Namespace:

Each feature (or set of features) gets a well-known name string
(documented together with the feature). The application that loads the
image knows the list of features that it implements.

Possible feature names could be:
- "pixel format: 16bit png"
- "tiled background"
- "text layers: basic format attributes"
- "OpenRaster Core v2.0"
- "layer mode: gimp_soft_light v2"

Private feature spaces are also possible, like "MyPaint 1.0" or "Krita
3.0 extra filters". This allows to provide fallbacks for features that
are not yet standardized, while still using the standard OpenRaster
way to save the extra information.

Fallbacks are optional. It is okay to implement private features without
giving them a feature name.  Other applications will just drop those, or
make a decision if they hit a filter or mode that is not implemented, and it
is possible to give them a name later to add fallbacks.

If an image has advanced features without fallbacks, then another
implementation might screw up without knowing.  To detect this, we should
allow a <require> element below the toplevel <image>.  This allows us to
declare an image for example as "GIMP only" by requiring the feature "GIMP
3.0".  Other apps can still try to load this file, but should show the user
the list of missing features.  (Applications-specific files should still
have a different extension than .ora in addition to that, IMO.)


Implementation:

My test implementation (for loading) uses a recursive function called
get_compatible_stack_elements(stack) that processes all <try> elements,
returning a list of elements to be processed as before.

Variants:

To make it more self-describing, the tag could be called
<replace-next-element> instead of <try>.

It might be more logical to replace the previous element, not the next.

Critic:

The saving application dictates which fallback to use. Maybe the user
wanted a different fallback. For example, the user might end up with a
color-corrected layer but would rather want the original back.

When an application implements a feature only partially (like "tiled layers"
that only work for the background) things get a bit complicated: this
application cannot claim to support "tiled layers".  It could still accept
the <try> after checking its contents.  Or it could save them with a feature
requirement for "tiled background", forcing all implementations that already
know they can do "tiled layers" to learn that they can also do "tiled
background".  Or it could save a more complex <try> cascade, giving the same
content twice, effectively OR'ing the feature requirements.


Does anyone think this is a bad idea?  Anyone got a different idea?
Is there some standard way to do this that I don't know about?

bye,
Martin


More information about the CREATE mailing list