From 408abf1008c75ac60d75e30121090205820c394f Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Sun, 2 Dec 2012 12:24:55 +0000 Subject: [PATCH] Bug 54210 - Fixed rendering text in flipped shapes in PPT2PNG and PPTX2PNG git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1416165 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/status.xml | 2 ++ .../poi/xslf/usermodel/XSLFTextShape.java | 36 ++++++++++++++++++- .../apache/poi/hslf/model/TextPainter.java | 31 ++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index e1bb32f8b4..9172584538 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,8 @@ + Synchronize table headers with parent sheet in XSSF + 54210 - Fixed rendering text in flipped shapes in PPT2PNG and PPTX2PNG 54188 - Avoid NPE in PPT2PNG diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java index 98f63fa72c..af1c174c6a 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java @@ -37,6 +37,7 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.util.ArrayList; @@ -493,6 +494,36 @@ public abstract class XSLFTextShape extends XSLFSimpleShape implements Iterable< double x = anchor.getX() + getLeftInset(); double y = anchor.getY(); + // remember the initial transform + AffineTransform tx = graphics.getTransform(); + + // Transform of text in flipped shapes is special. + // At this point the flip and rotation transform is already applied + // (see XSLFShape#applyTransform ), but we need to restore it to avoid painting "upside down". + // See Bugzilla 54210. + + if(getFlipVertical()){ + graphics.translate(anchor.getX(), anchor.getY() + anchor.getHeight()); + graphics.scale(1, -1); + graphics.translate(-anchor.getX(), -anchor.getY()); + + // text in vertically flipped shapes is rotated by 180 degrees + double centerX = anchor.getX() + anchor.getWidth()/2; + double centerY = anchor.getY() + anchor.getHeight()/2; + graphics.translate(centerX, centerY); + graphics.rotate(Math.toRadians(180)); + graphics.translate(-centerX, -centerY); + } + + // Horizontal flipping applies only to shape outline and not to the text in the shape. + // Applying flip second time restores the original not-flipped transform + if(getFlipHorizontal()){ + graphics.translate(anchor.getX() + anchor.getWidth(), anchor.getY()); + graphics.scale(-1, 1); + graphics.translate(-anchor.getX() , -anchor.getY()); + } + + // first dry-run to calculate the total height of the text double textHeight = getTextHeight(); @@ -512,11 +543,14 @@ public abstract class XSLFTextShape extends XSLFSimpleShape implements Iterable< } drawParagraphs(graphics, x, y); + + // restore the transform + graphics.setTransform(tx); } /** - * pain the paragraphs starting from top left (x,y) + * paint the paragraphs starting from top left (x,y) * * @return the vertical advance, i.e. the cumulative space occupied by the text */ diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/TextPainter.java b/src/scratchpad/src/org/apache/poi/hslf/model/TextPainter.java index 6ae2323927..ca243ff290 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/TextPainter.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/TextPainter.java @@ -24,6 +24,7 @@ import java.awt.font.FontRenderContext; import java.awt.font.LineBreakMeasurer; import java.awt.font.TextAttribute; import java.awt.font.TextLayout; +import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.text.AttributedCharacterIterator; @@ -94,6 +95,8 @@ public final class TextPainter { } public void paint(Graphics2D graphics){ + AffineTransform tx = graphics.getTransform(); + Rectangle2D anchor = _shape.getLogicalAnchor2D(); TextElement[] elem = getTextElements((float)anchor.getWidth(), graphics.getFontRenderContext()); if(elem == null) return; @@ -120,6 +123,32 @@ public final class TextPainter { break; } + + // Transform of text in flipped shapes is special. + // At this point the flip and rotation transform is already applied + // (see XSLFShape#applyTransform ), but we need to restore it to avoid painting "upside down". + // See Bugzilla 54210. + if(_shape.getFlipVertical()){ + graphics.translate(anchor.getX(), anchor.getY() + anchor.getHeight()); + graphics.scale(1, -1); + graphics.translate(-anchor.getX(), -anchor.getY()); + + // text in vertically flipped shapes is rotated by 180 degrees + double centerX = anchor.getX() + anchor.getWidth()/2; + double centerY = anchor.getY() + anchor.getHeight()/2; + graphics.translate(centerX, centerY); + graphics.rotate(Math.toRadians(180)); + graphics.translate(-centerX, -centerY); + } + + // Horizontal flipping applies only to shape outline and not to the text in the shape. + // Applying flip second time restores the original not-flipped transform + if(_shape.getFlipHorizontal()){ + graphics.translate(anchor.getX() + anchor.getWidth(), anchor.getY()); + graphics.scale(-1, 1); + graphics.translate(-anchor.getX() , -anchor.getY()); + } + //finally draw the text fragments for (int i = 0; i < elem.length; i++) { y0 += elem[i].ascent; @@ -149,6 +178,8 @@ public final class TextPainter { } y0 += elem[i].descent; } + + graphics.setTransform(tx); } public TextElement[] getTextElements(float textWidth, FontRenderContext frc){ -- 2.39.5