Shape text rotation is incorrect in PDF when Shape created not using document builder

Hello. I noticed that the text rotation inside a text box is incorrect when a Shape is created via the constructor. There was an old topic on this issue: Shape.Rotation does not rotate the text of shape. The suggested solution was to use DocumentBuilder to create the shape:

DocumentBuilder builder = new DocumentBuilder(doc);
Shape shape = builder.insertShape(ShapeType.TEXT_BOX, 200, 50);

My problem is that I intend to add my Shapes into a GroupShape:

GroupShape groupShape = new GroupShape(documentBuilder.getDocument());
Shape shape = new Shape(documentBuilder.getDocument(), ShapeType.TEXT_BOX)
groupShape.appendChild(shape);

GroupShape can’t be created using document builder. If a create a shape with document builder and try to append to groupShape as a child, I get this error “Cannot insert a Shape into a GroupShape with a different markup language”.

I set shape.getTextBox().setNoTextRotation(false); but that seems to have no effect - the text inside text box still has no rotation.
Rotation of content in text box is correct when the shape is created via DocumentBuilder, but such a shape cannot be appended to groupShape.

The part that confuses me the most is that the rotation is correct in the created Word DOCX file, but not in PDF.

@Martin123 Unfortunately, you are right, currently there is no way to create DML GroupShape.

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-27240

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.

The part that confuses me the most is that the rotation is correct in the created Word DOCX file, but not in PDF.

Could you please attach the problematic DOCX and PDF documents here for our reference?

text-box-rotation.docx (9.0 KB)

text-box-rotation.pdf (16.9 KB)

@Martin123 Thank you for additional information. The problem is not reproducible using the latest 24.7 version of Aspose.Words and the following simple code:

Document doc = new Document("C:\\Temp\\in.docx");
doc.save("C:\\Temp\\out.pdf");

out.pdf (19.3 KB)

Yes, it also doesn’t reproduce for me this way. It only occurs when creating a document by creating group shapes and appending shapes through my code as above. So perhaps there is a some other way or workaround to retain rotation of textbox without having to create a DML GroupShape?

@Martin123 Could you please create a simple code example that will allow us to reproduce the problem?

VML shapes are quite limited if compare to DML shapes. So most likely there is no way to achieve this using VML shapes.

Here is an example with shapes without groups:

// creating DML shape via document builder - correct rotation
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
Shape shape = builder.insertShape(ShapeType.TEXT_BOX, 0d, 0d); //correct rotation of text

Paragraph paragraph = new Paragraph(doc);
shape.appendChild(paragraph);
Run run = new Run(doc);
run.setText("Text in textbox");
paragraph.appendChild(run);

shape.setWrapType(WrapType.NONE);
shape.setBehindText(false);
shape.setAnchorLocked(true);
shape.setAllowOverlap(true);
shape.setRotation(25.0);
shape.setHeight(100.0);
shape.setWidth(200.0);
shape.setFilled(true);
shape.getFill().setColor( new Color(192, 192, 192));
shape.getTextBox().setNoTextRotation(false);

OoxmlSaveOptions saveOptions = new OoxmlSaveOptions();
saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_STRICT);
saveOptions.setSaveFormat(SaveFormat.DOCX);

PdfSaveOptions saveOptionsPdf = new PdfSaveOptions();
saveOptionsPdf.getOutlineOptions().setDefaultBookmarksOutlineLevel(1);
saveOptionsPdf.setDisplayDocTitle(false);
saveOptionsPdf.setInterpolateImages(false);
saveOptionsPdf.setImageCompression(PdfImageCompression.JPEG);
saveOptionsPdf.setPreblendImages(false);
saveOptionsPdf.setJpegQuality(100);
saveOptionsPdf.getDownsampleOptions().setDownsampleImages(false); 

doc.save("/path/result_correct_rotation.pdf", saveOptionsPdf);
doc.save("/path/result_correct_rotation.docx", saveOptions);

//2nd scenario: creating VML shape via constructor - incorrect rotation
Document doc2 = new Document();
DocumentBuilder builder2 = new DocumentBuilder(doc2);
Shape shape2 = new Shape(doc2, ShapeType.TEXT_BOX);//incorrect rotation of text

Paragraph paragraph2 = new Paragraph(doc2);
shape2.appendChild(paragraph2);
Run run2 = new Run(doc2);
run2.setText("Text in textbox2");
paragraph2.appendChild(run2);

builder2.insertNode(shape2); //incorrect rotation of text

shape2.setWrapType(WrapType.NONE);
shape2.setBehindText(false);
shape2.setAnchorLocked(true);
shape2.setAllowOverlap(true);
shape2.setRotation(25.0);
shape2.setHeight(100.0);
shape2.setWidth(200.0);
shape2.setFilled(true);
shape2.getFill().setColor( new Color(192, 192, 192));
shape2.getTextBox().setNoTextRotation(false);

doc2.save("/path/result_incorrect_rotation.pdf", saveOptionsPdf);//always incorrect rotation
doc2.save("/path/result_incorrect_rotation.docx");
doc2.save("/path/result_correct_rotation_with_save_options.docx",saveOptions);//with saveOptions rotation is correct

I discovered that the DOCX document retains the correct rotation due to the saveOptions.

OoxmlSaveOptions saveOptions = new OoxmlSaveOptions();
saveOptions.setCompliance(OoxmlCompliance.ISO_29500_2008_STRICT); 
saveOptions.setSaveFormat(SaveFormat.DOCX);

Without them, the rotation would be incorrect. I added the same saveOptions configuration that we use for both PDF and DOCX.

@Martin123 In OoxmlCompliance.ISO_29500_2008_STRICT compliance it is not allowed to use VML shapes. So the created VML shape is converted to DML. Thank is why when document is saved as .ISO_29500_2008_STRICT rotation is correct. If you switch saving order like this:

doc2.save("/path/result_correct_rotation_with_save_options.docx",saveOptions);//with saveOptions rotation is correct
doc2.save("/path/result_incorrect_rotation.pdf", saveOptionsPdf);//always incorrect rotation

Then in the output PDF text rotation will also correct.

Thank you for the explanation. However, in my actual workflow I need to save only one document (either a pdf or a docx). Is there a way to achieve the document conversion from VML shapes to DML if doing only doc2.save(“/path.pdf”, saveOptionsPdf) without first saving as a docx?

@Martin123 No, unfortunately, there is no such option. You can save the document as ISO_29500_2008_STRICT into stream and then save it to PDF.

The issues you have found earlier (filed as WORDSNET-27240) have been fixed in this Aspose.Words for Java 24.9 update.