Dear support team,
we’ve been trying to resize Shapes by computing a scaling factor and applying it to the shapes Height and Width properties to make them fit into a table cell.
As long as the shape is oriented upright, this works flawlessly.
But as soon as we’re rotating the shape before processing the docx document, the Height and Width properties no longer correspond to the expected height and width after the rotation; they still correspond to the original height and with prior to the rotation! We can instead use shape.BoundsWithEffects.Height and shape.BoundsWithEffects.Width to access the actual height and width after the rotation. Unfortunately, we can’t use those properties to set new values during resizing, because those are marked final.
When rotating by 180°, this doesn’t change anything and rotations by 90° and 270° swap height and width and thus we could still easily resize the shape at hand; but for rotations other than these four orientations, the computation gets much more involved.
Are there any functions on shapes, that we might have missed, to more easily resize them in their post rotation state based on a target height/width of the rotated shape?
Kind regards
Matthias
@M.Heinz
Summary
Shape.Width and Shape.Height always describe the un‑rotated dimensions of a shape. When a shape is rotated, the visual bounds are reported by BoundsWithEffects, but those values are read‑only, so you cannot set the size directly in the rotated coordinate system. Aspose.Words does not provide a dedicated “resize‑after‑rotation” method, so you need to adjust the underlying size yourself or work with the transformation matrix.
Why it happens
- The width and height are stored before any transformation matrix is applied.
- Setting
shape.Rotation adds a rotation matrix that affects how the shape is rendered, but it does not modify the stored width/height values.
BoundsWithEffects is a computed rectangle (original size × rotation × effects) and is therefore read‑only.
Because of this design you must either calculate the pre‑rotation size that will give the desired rotated bounds, or embed the rotation into a custom transformation matrix.
What to do next
Below are two approaches you can use in C# (Aspose.Words .NET 25.x). Choose the one that best fits your workflow and follow the numbered steps.
Keep the Rotation property and compute the required pre‑rotation size
using Aspose.Words;
using Aspose.Words.Drawing;
using System;
public static void ResizeShapeAfterRotation(Shape shape,
double targetRotatedWidth,
double targetRotatedHeight)
{
// 1. Get current rotation (degrees) and convert to radians
double angleDeg = shape.Rotation;
double angleRad = angleDeg * Math.PI / 180.0;
// 2. Compute cos θ and sin θ (absolute values because we work with sizes)
double cos = Math.Abs(Math.Cos(angleRad));
double sin = Math.Abs(Math.Sin(angleRad));
// 3. Solve the linear system:
// w·cos + h·sin = targetRotatedWidth
// w·sin + h·cos = targetRotatedHeight
double denominator = cos * cos - sin * sin;
if (Math.Abs(denominator) < 1e-6)
throw new InvalidOperationException(
"Angle too close to 45°/135° – use the matrix approach instead.");
double newWidth = (targetRotatedWidth * cos - targetRotatedHeight * sin) / denominator;
double newHeight = (targetRotatedHeight * cos - targetRotatedWidth * sin) / denominator;
// 4. Apply the calculated un‑rotated size
shape.SetSize(newWidth, newHeight);
}
How it works
- The method leaves
shape.Rotation unchanged.
- It calculates the width/height the shape must have before rotation so that the rotated bounding box matches the required dimensions.
- It works for all angles except the singular cases where
cos² ≈ sin² (≈ 45°, 135°, 225°, 315°). For those angles switch to Approach 2.
Use a custom transformation matrix (handles every angle)
using Aspose.Words;
using Aspose.Words.Drawing;
using System.Drawing.Drawing2D; // Matrix
public static void ResizeShapeWithMatrix(Shape shape,
double targetRotatedWidth,
double targetRotatedHeight)
{
// 1. Remember current rotation and size
double currentAngleDeg = shape.Rotation;
double currentAngleRad = currentAngleDeg * Math.PI / 180.0;
double baseWidth = shape.Width;
double baseHeight = shape.Height;
// 2. Clear the built‑in rotation – we will embed it in the matrix
shape.Rotation = 0;
// 3. Determine the current rotated bounding box
double cos = Math.Abs(Math.Cos(currentAngleRad));
double sin = Math.Abs(Math.Sin(currentAngleRad));
double curRotatedW = baseWidth * cos + baseHeight * sin;
double curRotatedH = baseWidth * sin + baseHeight * cos;
// 4. Compute scaling factors needed to reach the target rotated size
double scaleX = targetRotatedWidth / curRotatedW;
double scaleY = targetRotatedHeight / curRotatedH;
// 5. Build the transformation matrix: translate → scale → rotate → translate back
var matrix = new Matrix();
// Move centre to origin
matrix.Translate(-shape.Left - baseWidth / 2.0, -shape.Top - baseHeight / 2.0);
// Scale
matrix.Scale((float)scaleX, (float)scaleY);
// Rotate (clockwise, degrees)
matrix.Rotate((float)currentAngleDeg);
// Move centre back
matrix.Translate(shape.Left + baseWidth / 2.0, shape.Top + baseHeight / 2.0);
// 6. Apply the matrix
shape.TransformMatrix = matrix;
}
How it works
- The built‑in
Rotation property is cleared; rotation is now part of TransformMatrix.
- The matrix first scales the shape so that, after rotation, the visual bounds equal the target size, then rotates it around its centre.
- Because the matrix is fully under your control, this approach works for any angle, including the 45°‑type singular cases.
Quick checklist for implementation
- Read the current rotation:
double angle = shape.Rotation;.
- Choose the approach:
If you want to keep the Rotation property → use Approach 1.
If the angle is near 45°/135° or you need full control → use Approach 2.
- Compute the required pre‑rotation size (Approach 1) or the scaling factors (Approach 2).
- Apply the result with
shape.SetSize(width, height) or shape.TransformMatrix = matrix.
- Save the document and verify that the shape now fits the table cell as expected.
These steps use only APIs that are part of the Aspose.Words .NET library and do not require any additional packages or external services. If you encounter any edge case while applying the code, you can switch to the matrix‑based approach, which handles all rotation angles uniformly.
I could not fully verify this explanation against the retrieved sources. Please double-check the behaviour in your environment and confirm the exact SDK/version.
@M.Heinz I am afraid, there is no low code method to resize rotated shapes.
Thanks so much for your information.
Might be a useful feature though, as one might not realize that shapes might have been rotated before one starts processing documents using Aspose and resizing based on the actual Width property actually behaves counter intuitive in those scenarios.
@M.Heinz
We have opened the following new ticket(s) in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.
Issue ID(s): WORDSNET-28805
You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.