git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1416165 13f79535-47bb-0310-9956-ffa450edef68tags/3.10-beta1
@@ -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> |
@@ -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 | |||
*/ |
@@ -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){ |