Unable to correctly calculate position of rotated shapes

Hi,

In one of our business use cases, we need to be able to correctly position the Shape based on the coordinates that are relative to the page. Our current implementation correctly calculates the position when the Shape object is anchored to various nodes including the table cell. However, the problem occurs when the Shape is rotated, and then the rectangle returned from the LayoutEnumerator contains incorrect X and Y coordinates.
After some more analysis of the problem, we found that if the Shape is rotated by 90/180/270 degrees, the X/Y coordinates match the unrotated Shape.
Note: that in our specific use case, the Shape will always be anchored to the first table cell, thus this calculation is required to correctly adjust the Shape position.

Below is the code snippet we use to adjust the Shape position:

var layoutEnumerator = new LayoutEnumerator(document);
NodeCollection<Shape> shapes = document.getChildNodes(NodeType.SHAPE, true);
var rotation = shape.getRotation();
var isRotationSet = rotation != 0;

if (isRotationSet)
{
    shape.setRotation(0);
    document.updatePageLayout();
}

layoutEnumerator.setCurrent(layoutCollector.getEntity(shape));
var rect = layoutEnumerator.getRectangle();

var offsetX = rect.getX() - shape.getLeft();
var offsetY = rect.getY() - shape.getTop();

shape.setLeft(shape.getLeft() - offsetX);
shape.setTop(shape.getTop() - offsetY);

if (isRotationSet)
{
    shape.setRotation(rotation);
}
document.updatePageLayout();

I’ve found a similar issue related to Aspose.Cells:
https://forum.aspose.com/t/rotated-shapes-do-not-return-the-correct-position-or-dimensions/190835

@ANDREA.FARRIS Could you please attach your problematic input document here for testing? We will check the issue and provide you more information.

For testing I have created a simple document with a 90 degrease rotated shape and then calculated the shape’s rectangle using LayoutCollector and LayoutEnumerator. The calculated rectangle is correct.

Document doc = new Document("C:\\Temp\\in.docx");
LayoutCollector collector = new LayoutCollector(doc);
LayoutEnumerator enumerator = new LayoutEnumerator(doc);

Shape shape = (Shape)doc.getChild(NodeType.SHAPE, 0, true);

enumerator.setCurrent(collector.getEntity(shape));

Shape rect = new Shape(doc, ShapeType.RECTANGLE);
rect.setWrapType(WrapType.NONE);
rect.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE);
rect.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE);
rect.setLeft(enumerator.getRectangle().getX());
rect.setTop(enumerator.getRectangle().getY());
rect.setWidth(enumerator.getRectangle().getWidth());
rect.setHeight(enumerator.getRectangle().getHeight());
rect.getStroke().setForeColor(Color.RED);
rect.getStroke().setWeight(2);
rect.setFilled(false);

doc.getFirstSection().getBody().getFirstParagraph().appendChild(rect);

doc.save("C:\\Temp\\out.docx");

As you can see the frame is drawn exactly where the rotated shape is.
in.docx (13.6 KB)
out.docx (11.1 KB)

Hi Alexey,

As I mentioned the problem does not exist if the Shape is rotated by 90/180/270 degrees (the position is calculated correctly), but if you rotate the Shape by 315 degrees that’s when the problem appears.

Also, in your provided code snippet, you haven’t anchored the Shape to the table, that might affect the position calculation.

Bellow I attached 3 documents:

  1. Without rotation
  2. With 270deg rotation
  3. With 315deg rotation

case_1.docx (9.7 KB)

case_2.docx (9.7 KB)

case_3.docx (9.7 KB)

@ANDREA.FARRIS Thank you for additional information. I think the behavior is expected since there is no way to specify rotation in Rectangle structure. Rotation must be specified separately as a transformation matrix. LayoutEnumerator returns the shape bounding box that fits the rotated shape: