Problems with SetSnapRect() for rotated and/or sheared custom shapes

Regina Henschel rb.henschel at
Mon Nov 4 18:00:18 UTC 2019

Hi all,

During my work on the oox import of vert="eaVert" I encountered, that my 
changes in oox do not work as expected, because 
SdrObjCustomShape::SetVerticalWriting() is faulty. The origin of the 
error is in SdrObjCustomShape::SetSnapRect().

SdrObjCustomShape::SetSnapRect() has a rectangle as input and sets this 
rectangle as logic rectangle of the shape. But there exists some places, 
where similar combinations like the following are used.
350          const tools::Rectangle aSnapRect = pObj->GetSnapRect();
385              pObj->NbcSetSnapRect(aSnapRect);

This means, that the size and position of the rotated and/or sheared 
object is set as new logical (which means unrotate and unsheared) 
rectangle. That results in wrong size and position of the object.

To try it out:
Draw a custom shape, enter some text and rotate the shape. Now change 
the shape e.g. the line color and make an Undo. Result: The shape 
changes its position and size.
Or draw a custom shape in Calc, rotate it and anchor it "to Cell". Then 
use the item "Fit to Cell Size" from context menu.
Or draw a custom shape in Impress, enter some text, then rotate the 
shape. Enter edit mode of the shape and switch on "Vertical Writing" 
mode (it is in the text formatting toolbar).

I have seen the problem in SdrObjCustomShape::SetVerticalWriting(), 
SdrUndoAttrObj::Undo(), SdrUndoAttrObj::Redo() and 
ScDrawView::FitToCellSize(). There might be other places.

So my question is:
What is SdrObjCustomShape::SetSnapRect() supposed to do?

It is not straight forward to use the input rectangle as snap rectangle, 
because the snap rectangle is calculated from the logic rectangle using 
the given rotation and shear angle, and it is possible, that there 
exists no logic rectangle, which would result in the input rectangle as 
snap rectangle.

A different approach would be, to keep the current version of 
SdrObjCustomShape::SetSnapRect() and change the found combinations so, 
that in case of a SdrObjCustomShape, not GetSnapRect() but 
GetLogicRect() is used.

So what to do?

Kind regards

More information about the LibreOffice mailing list