[cairo] cairo-1.13 finally opens

Henry (Yu) Song - SISA henry.song at samsung.com
Thu Sep 5 11:38:34 PDT 2013

Details of gaussian blur on each backend as implemented 

1. image backend - two passes (horizontal and vertical) use pixman convolution function.  It is quite slow and not optimized, might be a 3-pass boxshadow to approximate that would be faster
2. gl/gles - two passes (horizontal and vertical) shaders
3. xcb backend - two passes using xrender "convolution" filter
4. quartz backend - one pass, use Apple's Accelerate framework.  I found doing two pases is slower.
5. as an optimization, the image to be blurred is scaled down first and scale up using bilinear sampling - similar to skia

The shadow parameters (blur, offset) are not affected by CTM (recall somewhere in html/css spec that shadow blur/offset should not be affected by ctm).

CSS3 only defines blur, offset, and spread.  The current implementation of shadow is much more flexible than that, it allows arbitrary shadow path to be drawn similar to osx's CALayer.shadowPath

Regarding to different operators with shadow.  The drop shadow implementation follows what HTML/css spec, it draws drop shadow with current compositing operator, then draw drawing itself with again the current operator.  The problem is the inset shadow.  I am not clear about that with operators other than OVER.   

If you are interested to see custom shadow sample, I will send sample code.


From: Bill Spitzak [spitzak at gmail.com]
Sent: Thursday, September 05, 2013 11:05 AM
To: Henry (Yu) Song - SISA
Cc: Chris Wilson; cairo at cairographics.org
Subject: Re: [cairo] cairo-1.13 finally opens

Looking at the css and html documentation, it appears what the shadow
does in order to combine both is:

- Compute an alpha image that is the alpha of the source intersected
with the path

- Translate it by the "offset". This should be measured in the CTM

- There are 2 numbers that are the "spread". The CSS description of
using a thresholded blur will not preserve antialiasing or actually
produce the desired offset. I believe the correct rule is something like
the following:

   - You can do this in two passes, horizontal and vertical

   - If the number is positive, find the pixel with the largest alpha
value in a range of 2x centered on the current pixel. For non-integers
also try the bilinear interpolation at distance x in each direction.

   - If the number is negative instead find the pixel with the lowest alpha.

   - Produce an output image of these min/max alphas.

   - IMHO if the CTM has rotation it is acceptable to perform this
axis-aligned in either input or output space, provided the area of the
filter is the same and it is correct for 90 degree rotations.

- Blur this alpha using a 2-pass gaussian filter. The size is specified
in the CTM as two numbers. If there is rotation then the same
axis-alignment as for the spread must be used (otherwise a blur smaller
than the spread may still effect pixels on the wrong side of the path).

- Multiply this alpha image by the shadow color and composite it using
the current operation

- Then do the rest of the drawing as normal atop this result.

I am not clear on what the various inset/outset controls being proposed
are for. It does not look like they are relying on transforming the path
to an inset one, which would be much more complex than the minmax
filtering approach.

To reduce the number of entry points, could drawing the shadow be a
separate operation? It would preserve the path. Then the current color
can be reused to set the shadow color, and the compositing operation
changed between the shadow and the object.

More information about the cairo mailing list