diff --git a/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFDiagram.java b/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFDiagram.java index c63e6ca0ac..ccd7711697 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFDiagram.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFDiagram.java @@ -172,7 +172,6 @@ public class XSLFDiagram extends XSLFGraphicFrame { // We can't easily (is it even possible?) set a separate xfrm for the text on the openxml CTShape. // Instead, we create a separate textbox shape with the same xfrm. org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties textShapeProps = textShapeCT.addNewSpPr(); - textShapeProps.setXfrm(msShapeCt.getTxXfrm()); textShapeCT.setTxBody(msShapeCt.getTxBody()); textShapeCT.setStyle(msShapeCt.getStyle()); @@ -182,6 +181,16 @@ public class XSLFDiagram extends XSLFGraphicFrame { textShapeCT.setNvSpPr((CTShapeNonVisual) nonVisualCt.copy()); textShapeCT.getNvSpPr().getCNvSpPr().setTxBox(true); + textShapeProps.setXfrm(msShapeCt.getTxXfrm()); + int shapeRotation = msShapeCt.getSpPr().getXfrm().getRot(); + int textRotation = msShapeCt.getTxXfrm().getRot(); + if (textRotation != 0) { + // SmartArt diagrams (e.g. hexagon) have rotated shapes and the txXfrm can change the rotation for visual + // reasons. We perform that same calculation here again and calculate a new rotation for the text box. + int resolvedRotation = shapeRotation + textRotation; + textShapeProps.getXfrm().setRot(resolvedRotation); + } + return textShapeCT; } diff --git a/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFDiagram.java b/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFDiagram.java index 9552cfd656..13e14ac67c 100644 --- a/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFDiagram.java +++ b/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFDiagram.java @@ -35,6 +35,7 @@ import static org.junit.jupiter.api.Assertions.*; public class TestXSLFDiagram { private static final String SIMPLE_DIAGRAM = "smartart-simple.pptx"; + private static final String ROTATED_TEXT_DIAGRAM = "smartart-rotated-text.pptx"; private static List extractDiagrams(XMLSlideShow slideShow) { return slideShow.getSlides() @@ -149,4 +150,30 @@ public class TestXSLFDiagram { assertEquals(ContentTypes.IMAGE_JPEG, texturePaint.getContentType()); } } + + @Test + public void testTextRotationOnShape() throws IOException { + try (XMLSlideShow inputPptx = XSLFTestDataSamples.openSampleDocument(ROTATED_TEXT_DIAGRAM)) { + List diagrams = extractDiagrams(inputPptx); + assertEquals(1, diagrams.size()); + + XSLFDiagram diagram = diagrams.get(0); + XSLFGroupShape groupShape = diagram.getGroupShape(); + + List shapes = groupShape.getShapes(); + + // Text shapes have separate rotation calculation + XSLFTextBox abcText = (XSLFTextBox) shapes.get(1); + assertEquals(-41.3187, abcText.getRotation(), 1E-4); + + XSLFTextBox defText = (XSLFTextBox) shapes.get(5); + assertEquals(49.1812, defText.getRotation(), 1E-4); + + XSLFTextBox ghiText = (XSLFTextBox) shapes.get(9); + assertEquals(0.0, ghiText.getRotation(), 1E-4); + + XSLFTextBox jklText = (XSLFTextBox) shapes.get(11); + assertEquals(0.0, jklText.getRotation(), 1E-4); + } + } } diff --git a/test-data/slideshow/smartart-rotated-text.pptx b/test-data/slideshow/smartart-rotated-text.pptx new file mode 100644 index 0000000000..f308a7d0f8 Binary files /dev/null and b/test-data/slideshow/smartart-rotated-text.pptx differ