]> source.dussan.org Git - poi.git/commitdiff
Bug 54210 - Fixed rendering text in flipped shapes in PPT2PNG and PPTX2PNG
authorYegor Kozlov <yegor@apache.org>
Sun, 2 Dec 2012 12:24:55 +0000 (12:24 +0000)
committerYegor Kozlov <yegor@apache.org>
Sun, 2 Dec 2012 12:24:55 +0000 (12:24 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1416165 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/status.xml
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
src/scratchpad/src/org/apache/poi/hslf/model/TextPainter.java

index e1bb32f8b4ed2aca1748c90e46ef6ef3091b746b..9172584538346f50742a24fb8bcdd84052e07540 100644 (file)
@@ -34,6 +34,8 @@
 
     <changes>
         <release version="4.0-beta1" date="2013-??-??">
+          <action dev="poi-developers" type="fix">Synchronize table headers with parent sheet in XSSF</action>
+          <action dev="poi-developers" type="fix">54210 - Fixed rendering text in flipped shapes in PPT2PNG and PPTX2PNG</action>
         </release>
         <release version="3.9" date="2012-12-03">
           <action dev="poi-developers" type="fix">54188 - Avoid NPE in PPT2PNG</action>
index 98f63fa72c52afddad86da918a4398a9bd7bc5b6..af1c174c6a6b4fb9e97b9e9610532d73cfbcbe3c 100644 (file)
@@ -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
      */
index 6ae2323927953acddfd06f08d6a3383d87354ff0..ca243ff290c9b2bb51ba590ff36a4d7390dba406 100644 (file)
@@ -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){