Re: feImage coordinates question

On Mon, 2010-07-12 at 11:24 +0200, Erik Dahlstrom wrote:
> On Sat, 10 Jul 2010 17:46:43 +0200, Tavmjong Bah <tavmjong@free.fr> wrote:
> 
> >
> > Hi,
> >
> >  I've been trying to understand the feImage spec as Inkscape's rendering
> > of a PNG via feImage is quite different from others. So I've trace
> > through the spec all the relevant parts. Here is what I find:
> >
> >
> > Filter effects region:
> >
> >        filterUnits = userSpaceOnUse  or objectBoundingBox (default)
> >
> >        filter "hard clipped" to x, y, width height
> >               (default: -10%, -10%, 120%, 120%)
> >
> >        primitiveUnits  = userSpaceOnUse  (default) or objectBoundingBox
> >
> >
> > Filter effects subregion (filter primitive attribute)
> >
> >        filter primitive "hard clipped" to x, y, width height
> >               (default: 0%, 0%, 100%, 100%)
> >
> >        * First weirdness: the default is specified in percent,
> >          i.e. objectBoundingBox, but primitiveUnits default is
> >          userSpaceOnUse. Shouldn't the primitiveUnits default also be
> >          objectBoundingBox?
> 
> That would break a lot of content. The difference between those two is  
> quite dramatic.

Of course it can't be changed for SVG1.1, I just find it unintuitive.

> > Why is it different from the default of
> >          the filter effects region? (BTW, adding primitiveUnits =
> >          objectBoundingBox without adding x, y, width, and height
> >          breaks Batik.)
> 
> I'm not exactly sure of the history, but I think it's deliberate, there  
> are other examples in the spec using the same convention e.g <mask> and  
> <pattern>.

One thing that is clearly missing from specifications is the history of
why certain choices were made. With the publication of specs on the
web, it should be possible to include "annotations" in the spec, i.e.
links to additional background information (which would not necessarily
be officially part of the spec).

>  From 15.7.3:
> [[ If there are no referenced nodes (e.g., for ‘feImage’ or  
> ‘feTurbulence’), or one or more of the referenced nodes is a standard  
> input (one of SourceGraphic, SourceAlpha, BackgroundImage,  
> BackgroundAlpha, FillPaint or StrokePaint), or for ‘feTile’ (which is  
> special because its principal function is to replicate the referenced node  
> in X and Y and thereby produce a usually larger result), the default  
> subregion is 0%,0%,100%,100%, where percentages are relative to the  
> dimensions of the filter region. ]]
> 
> I agree that it could be made more clear, anyway the last part of the  
> sentence is where it matters. If you don't explicitly specify  
> x,y,width,height on the filter primitive element (feImage in this case),  
> then the default (lacuna) filter primitive subregion is the filter region.  
> You can try yourself what happens if you put the same values in explicitly  
> (x="0%" y="0%" width="100%" height="100%"), the rendering is completely  
> different since the percentages are relative to the viewport not to the  
> filter region.

OK, I think I understand now. Yes, it could be clearer.

> > feImage primitive
> >
> >        Coordinate system depends on "primitiveUnits"
> >
> >        Image is to be rendered according to the "image" element which
> >        specifies that an image is rendered by default so that it
> >        is centered in the specified viewport with at least two
> >        opposite sides touching the viewport sides.
> >
> >        * Second weirdness: The coordinate system "depends on the value
> >          of attribute 'primitiveUnits'" which defaults to bounding box
> >          of the referenced object.
> 
> No, it defaults to 'userSpaceOnUse':
> [[ If primitiveUnits="userSpaceOnUse", any length values within the filter  
> definitions represent values in the current user coordinate system in  
> place at the time when the ‘filter’ element is referenced (i.e., the user  
> coordinate system for the element referencing the ‘filter’ element via a  
> ‘filter’ property). ]]

OK, I was confused by the use of percentages earlier... it didn't occur
to me that the percentages referred to the viewport.

> >  As I read the spec it says that an
> >          image drawn via the feImage primitive should be drawn by
> >          default so that two opposite edges touch the bounding box
> >          (i.e. xMidYMid).
> 
> Well, yes 'preserveAspectRatio' defaults to 'xMidYMid'. However, the  
> feImage edges would touch the referenced element's boundingbox only if  
> primitiveUnits="objectBoundingBox" was specified.
> 
> > This is what Inkscape does. However, Batik
> >          and other browsers draw the image so that two opposite edges
> >          touch the edges of the filter effects region.
> 
> Yes, that is the default when nothing else was specified. Maybe that's the  
> only thing missing in Inkscape?

No, to get the "expected" behavior, I have to also add to <feImage>:

  x="0"
  y="0"
  width="100%"
  height="100%"
  preserveAspectRatio="none"


> It would be useful to test each of the x,y,width,height being unspecified  
> and also comparing to when they are specified and are percentages.

Yes! I've tested your new filters-image-03-f.svg. Inkscape passes only
the first and fourth tests. Obviously there is lots of work to done on
Inkscape. Firefox, Opera, and Batik pass them all, Chrome fails the last
four. 

Can you also provide the same tests but with primitiveUnits =
"objectBoundingBox" ?

I have a simple use case that I would think should be easy to do but it
doesn't seem so:

 Take an arbitrary rectangle, fill it with
 an image, and then blur it uniformly (using
 <feImage> and not <image>!).

      Tav

Received on Tuesday, 13 July 2010 11:33:22 UTC