Saturday 18 August 2007

Large improvements in filtering framework

I've been rather busy lately, and it's been cutting into time, I can spend developing Inkscape. Nevertheless, I've now committed a big filtering framework update. The filtering code can now access the bounding box as defined in SVG standard, not only the visual bounding box, that's used in many parts of display code. Also, the filtering code can now handle many more different situations involving rotated and/or skewed objects. This update has been needed for some time already, but I thought it might be too big to fit in this summer.

The most visible problem this fixes is a crash when trying to use blending modes on a rotated or skewed object. It transformed the object to a coordinate system, where the object's x- and y-axis were paraller to bitmap axis. Then it tried to blend that with the background image, that was still in display coordinates. The blending code then tried to fit these in same buffer, which became really huge and couldn't be reserved.

This also fixes several less visible bugs. If an object was rotated/skewed and the resolution for filter was specified, the specified resolution was discarded and automatic resolution used instead. Filter area calculations are more correct, because they can be made in correct coordinate system.

This also opens new parts, that should be improved. The filters, for which it makes a difference, what direction the object's axis point, should be tagged as such. Cutting the filter result to filter effects area should be implemented. A better sampling than nearest neighbour should be implemented for pixel block transformations. Probably several others too.

This modification isn't all good, though. In some cases with rotation or skewing, the image quality is visibly detoriated. Also there's a rather interesting effect with low-resolution filters. In the following images, first has a slight blur applied with 16x16 resolution. Second is same image, but with a slight rotation applied. This is caused by the fact, that for scaling there exists a bicubic scaler, but for more complex transformations there is only nearest neighbour filtering available. Actually, this behaviour doesn't even violate SVG standard, but it definitely is rather unintuitive. (also, if you look closely, you can notice an off-by-one bug with the resolution)

No comments: