From: Yegor Kozlov Date: Sat, 25 Feb 2012 09:40:16 +0000 (+0000) Subject: Bugzilla 52078 - avoid OutOfMemoryError when rendering groupped pictures in HSLF X-Git-Tag: REL_3_8_FINAL~34 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=b19a144522b6501f7150adc987f83315ae5251e6;p=poi.git Bugzilla 52078 - avoid OutOfMemoryError when rendering groupped pictures in HSLF git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1293561 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 57161cd5ae..45a875eb1f 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 52078 - avoid OutOfMemoryError when rendering groupped pictures in HSLF 52745 - fixed XSSFRichtextString.append to preserve leading / trailing spaces 52716 - tolerate hyperlinks that have neither location nor relation 52599 - avoid duplicate text when rendering slides in HSLF diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/BitmapPainter.java b/src/scratchpad/src/org/apache/poi/hslf/blip/BitmapPainter.java index b9ba597115..56f1dea44c 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/blip/BitmapPainter.java +++ b/src/scratchpad/src/org/apache/poi/hslf/blip/BitmapPainter.java @@ -40,6 +40,8 @@ import org.apache.poi.util.POILogFactory; ==================================================================== */ import javax.imageio.ImageIO; import java.awt.*; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; @@ -60,9 +62,9 @@ public final class BitmapPainter implements ImagePainter { logger.log(POILogger.WARN, "ImageIO failed to create image. image.type: " + pict.getType()); return; } - Rectangle anchor = parent.getAnchor(); - Image scaledImg = img.getScaledInstance(anchor.width, anchor.height, Image.SCALE_SMOOTH); - graphics.drawImage(scaledImg, anchor.x, anchor.y, null); + + Rectangle anchor = parent.getLogicalAnchor2D().getBounds(); + graphics.drawImage(img, anchor.x, anchor.y, anchor.width, anchor.height, null); } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java index 3f7ce7cb31..672b191aaa 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java @@ -22,6 +22,8 @@ import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.io.ByteArrayOutputStream; +import java.util.ArrayList; +import java.util.List; import org.apache.poi.ddf.*; import org.apache.poi.ddf.EscherSpRecord; @@ -246,27 +248,37 @@ public abstract class SimpleShape extends Shape { setEscherProperty(EscherProperties.TRANSFORM__ROTATION, (theta << 16)); } + /** + * + * @return 'absolute' anchor of this shape relative to the parent sheet + */ public Rectangle2D getLogicalAnchor2D(){ Rectangle2D anchor = getAnchor2D(); //if it is a groupped shape see if we need to transform the coordinates if (_parent != null){ + List lst = new ArrayList(); + lst.add(_parent); Shape top = _parent; - while(top.getParent() != null) top = top.getParent(); - - Rectangle2D clientAnchor = top.getAnchor2D(); - Rectangle2D spgrAnchor = ((ShapeGroup)top).getCoordinates(); - - double scalex = spgrAnchor.getWidth()/clientAnchor.getWidth(); - double scaley = spgrAnchor.getHeight()/clientAnchor.getHeight(); + while(top.getParent() != null) { + top = top.getParent(); + lst.add(top); + } - double x = clientAnchor.getX() + (anchor.getX() - spgrAnchor.getX())/scalex; - double y = clientAnchor.getY() + (anchor.getY() - spgrAnchor.getY())/scaley; - double width = anchor.getWidth()/scalex; - double height = anchor.getHeight()/scaley; + AffineTransform tx = new AffineTransform(); + for(int i = lst.size() - 1; i >= 0; i--) { + ShapeGroup prnt = (ShapeGroup)lst.get(i); + Rectangle2D exterior = prnt.getAnchor2D(); + Rectangle2D interior = prnt.getCoordinates(); - anchor = new Rectangle2D.Double(x, y, width, height); + double scaleX = exterior.getWidth() / interior.getWidth(); + double scaleY = exterior.getHeight() / interior.getHeight(); + tx.translate(exterior.getX(), exterior.getY()); + tx.scale(scaleX, scaleY); + tx.translate(-interior.getX(), -interior.getY()); + } + anchor = tx.createTransformedShape(anchor).getBounds2D(); } int angle = getRotation();