shameless self-promoting website
»Rejourn root
»LibreOffice Community Blogs
Posted Saturday, 27 December 2014 by Miklos
Tags: en libreoffice

TL;DR: see above -- a number of preset shapes are now rendered correctly at any scale factors, where previously rendering problems occurred.

fdo#87448 has a reproducer document that shows rendering errors with the scaled cloud preset shape definition. At first I thought that the OOXML spec has wrong definition for this shape type, but that turned out to be not the case. What was a problem is our implementation of the drawingML arcTo command. This implementation defines how we render such arcs as polygons when the shape is to be painted, and given that LibreOffice has native support for the drawingML arcTo / ODF G command, this implementation is invoked during rendering, it’s not an import/export problem.

The rendering result looked like this before:

The cloud is drawn using a set of moveTo and arcTo commands. MoveTo is easier, as it uses explicit coordinates, but arcTo is more complex. It has 4 parameters: the height and width of a "circle", and the start / end angle of an arc on that circle. (Of course if height and width do not equal, than that’s no longer a circle… ;-) ) The problem is that due to this, the distance vector between the arc’s start and end points is implicit — so if something is miscalculated, errors are nicely added to each other as more and more arcs are drawn. This is especially a problem if you later return to the end of an earlier arc using moveTo: if arcTo has some problem, then it’ll be clearly visible.

After fixing UNO ARCANGLETO to only take care of scaling / translation only after counting the actual arc, we started to produce correct end points for the arcs and shapes started to appear correctly at any scale factor, yay! :-)

One remaining problem was how to test this from cppunit, in the above commit I exported the shape to a metafile, and then I could use Tomaž's excellent MetafileXmlDump to assert that the end of an arc (implicit location) and the parameters of a moveTo command (explicit location) equal — when they do not, that’s what your eyes call a "rendering problem".