Skip navigation

Monthly Archives: July 2009

As mentioned by several, last week saw Novell’s HackWeek IV. I had two important vectors along which I wanted to advance, namely bringing slideshow a bit closer to using the new drawinglayer primitives, and improving on the built-in testing facilities in ooo-build.

I started with doing an inventory of things to do for the slideshow upgrade, a pleasant surprise was the fact that Armin already provides a factory for retrieving XPrimitive2D for a given Impress XShape – so technically, the slideshow can retrieve all that’s necessary via pure UNO. Looking at the renderer implementation (that outputs XPrimitive2D on the XCanvas render substrate used in slideshow), I found a bunch of loose ends, and got side-tracked fixing those.

The first thing I actually tackled was the way canvas implements gradients (I seem to develop a knack for those recently). The initial interface for those was rather rigid, and to add insult to injury, extremely tied to ODF’s weird gradient definitions. So I changed the XParametricPolyPolygon2DFactory into a generic XMultiServiceFactory instead, that takes the following parameters:

   Gradients - all gradients need to support two construction
   parameters, "Colors" being a sequence of a sequence of doubles
   and "Stops" being a sequence of doubles. Both must
   have the same length, and at least two elements. See
   http://www.w3.org/TR/SVG11/pservers.html#GradientStops for
   the semantics of gradient stops and colors.
   Required gradient services:

   * "LinearGradient" - the gradient varies linearly between
     the given colors. without coordinate system
     transformation, the color interpolation happens in
     increasing x direction, and is constant in y
     direction. Equivalent to svg linear gradient

http://www.w3.org/TR/SVG11/pservers.html#LinearGradients

   * "EllipticalGradient" - this gradient has zeroth color
     index in the middle, and varies linearly between center
     and final color. The services takes an additional
     parameter named "AspectRatio" of double
     (width divided by height), if this aspect ratio is 1, the
     gradient is circular. If it's not 1, the gradient is
     elliptical, with the special twist that the aspect ratio
     is maintained also for the center color: the gradient will
     not collapse into a single point, but become a line of
     center color. If "AspectRatio" is missing, or equal to 1,
     this gradient yields similar results as the svg radial
     gradient

http://www.w3.org/TR/SVG11/pservers.html#RadialGradients

   * "RectangularGradient" - this gradient has zeroth color
     index in the middle, and varies linearly between center
     and final color via rectangular boxes
     around the center point. The services takes an additional
     parameter named "AspectRatio" of double
     (width divided by height), if this aspect ratio is 1, the
     gradient is quadratic. If it's not 1, the gradient is
     rectangular, with the special twist that the aspect ratio
     is maintained also for the center color: the gradient will
     not collapse into a single point, but become a line of
     center color.

Further massaging the code to share the same gradient texture transformation setup across drawinglayer, canvas, and cppcanvas module, this not only finally gave a nicely uniform rendering of gradients (especially the canvas had some glitches before, with one or the other canvas implementation even missing a gradient type), but also much cleaner code (in terms of comprehensibility, and in terms of implicit duplication of functionality). Final patch has 1237 insertions(+), 1016 deletions(-), containing new functionality (see below) plus substantial commentary (amounting, in total, to about 150 lines). Which gets me quite close to one of my unstated goals of getting less code with more features, when doing refactoring. ;-)

Kudos to Armin btw. for abstracting away the legacy gradients pixel-by-pixel into the usual matrix plus texture function concept!

If you’ve read closely the parameter description for the new gradient factory, you’ve noticed that svg gradients are already fully covered by the canvas now (the little twist is to omit the AspectRatio parameter, and instead scale the gradient anisotrophically via the texture transform, to get the normal svg way of isobare gradient rasterization). Possibly one of the next useful additions would be an optional color transformation function, like the sigmoidal gradient that’s often used in MSO docs – with that, we should get fairly close to implementing the superset of all relevant gradient concepts in office land (well, still missing gdiplus-like path gradient, but that’s rather arcane and seldomly used))

‘Nuff said, in the end, I used most of the week on this gradient rework, but it was time well spent. I used Friday to hack up slideshow to use the primitive renderer for XShapes, which actually works, but of course needs much more changes to e.g. properly support attribute animations (like changing fill color, font size etc.). Full patch is here and here. The more relevant achievement of Friday was the addition of ~convenient convwatch support in ooo-build:

On a known-good version, do this (ooconvwatch is here):

   "cd ooo-build/build/install/program; source ooenv; ooconvwatch -c \
    -d path_to_testdocs"

Wait.

When ooconvwatch finally returns, rebuild with your dubious patches, then:

   "cd ooo-build/build/install/program; source ooenv; ooconvwatch \
    -d path_to_testdocs"

Check /tmp/allfiles.txt for list of docs processed, check /tmp/_filename_.prn.diff.jpg for the graphical diffs.

Todo: collect sensible set of test docs. Throwing huge amounts of random docs at this is a waste. I’m pretty sure I can put everything that will possibly break on a handful of Impress pages. Times the number of odf/sxi/ppt/pptx format versions, and one still has a smallish number. Explore the database usage of convwatch – someone willing to share a description of that feature?

Update: in case it’s not painstakingly obvious, the set of test docs of course will not be closed; instead, after each regression not found by convwatch, it needs to be updated to henceforth catch the problem (referring to the “I have a good idea about what will possibly break in Impress”). ;-)

Part of ooo-build since early June, and now on the way to 3.2 for vanilla. Just a few pictures that should tell the story, starting with the state of affairs up to and including OOo 3.1:

blog-sample-0-ooold

The competition:

blog-sample-0

After the fix:

blog-sample-0-ooo

The differences are a bit subtle when looked at on this scale, but quite annoying when encountered by someone who designs her presentations with an eye for details. Especially the way sub-shapes were gradient-filled before, like the top end of the can or the eyes of the smiley. Kudos to haui btw. for the very nice hack to make OOo believe a sub-shape actually has the same bounding box as the main shape. Here’s the patch for those interested in the gory details.

Follow

Get every new post delivered to your Inbox.