- moved SlideShowFactory to Common SL - changed get/setAnchor to Rectangle instead of Rectangle2D - Fixed some Common SL generic definitions - picture dimensions are now in points and an additional method exists for pixels git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1704206 13f79535-47bb-0310-9956-ffa450edef68pull/24/head
@@ -20,7 +20,7 @@ | |||
package org.apache.poi.xslf.usermodel; | |||
import java.awt.Color; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.Rectangle; | |||
import java.io.FileOutputStream; | |||
import java.io.IOException; | |||
@@ -40,7 +40,7 @@ public class Tutorial4 { | |||
XSLFSlide slide = ppt.createSlide(); | |||
XSLFTable tbl = slide.createTable(); | |||
tbl.setAnchor(new Rectangle2D.Double(50, 50, 450, 300)); | |||
tbl.setAnchor(new Rectangle(50, 50, 450, 300)); | |||
int numColumns = 3; | |||
int numRows = 5; |
@@ -29,14 +29,13 @@ import java.io.IOException; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; | |||
import org.apache.poi.sl.SlideShowFactory; | |||
import org.apache.poi.sl.draw.Drawable; | |||
import org.apache.poi.sl.usermodel.PictureData; | |||
import org.apache.poi.sl.usermodel.Shape; | |||
import org.apache.poi.sl.usermodel.ShapeContainer; | |||
import org.apache.poi.sl.usermodel.Slide; | |||
import org.apache.poi.sl.usermodel.SlideShow; | |||
import org.apache.poi.sl.usermodel.SlideShowFactory; | |||
import org.apache.poi.sl.usermodel.TextParagraph; | |||
import org.apache.poi.sl.usermodel.TextRun; | |||
import org.apache.poi.sl.usermodel.TextShape; | |||
@@ -55,12 +54,7 @@ public abstract class SlideShowHandler extends POIFSFileHandler { | |||
readContent(ss); | |||
// read in the writen file | |||
SlideShow<?,?> read; | |||
try { | |||
read = SlideShowFactory.create(new ByteArrayInputStream(out.toByteArray())); | |||
} catch (InvalidFormatException e) { | |||
throw new IllegalStateException(e); | |||
} | |||
SlideShow<?,?> read = SlideShowFactory.create(new ByteArrayInputStream(out.toByteArray())); | |||
assertNotNull(read); | |||
readContent(read); |
@@ -20,6 +20,7 @@ package org.apache.poi.sl.draw; | |||
import java.awt.Dimension; | |||
import java.awt.Graphics2D; | |||
import java.awt.Paint; | |||
import java.awt.Rectangle; | |||
import java.awt.geom.Rectangle2D; | |||
import org.apache.poi.sl.usermodel.Background; | |||
@@ -35,12 +36,12 @@ public class DrawBackground extends DrawShape { | |||
@SuppressWarnings("rawtypes") | |||
public void draw(Graphics2D graphics) { | |||
Dimension pg = shape.getSheet().getSlideShow().getPageSize(); | |||
final Rectangle2D anchor = new Rectangle2D.Double(0, 0, pg.getWidth(), pg.getHeight()); | |||
final Rectangle anchor = new Rectangle(0, 0, (int)pg.getWidth(), (int)pg.getHeight()); | |||
PlaceableShape<?,?> ps = new PlaceableShape(){ | |||
public ShapeContainer<?,?> getParent() { return null; } | |||
public Rectangle2D getAnchor() { return anchor; } | |||
public void setAnchor(Rectangle2D anchor) {} | |||
public Rectangle getAnchor() { return anchor; } | |||
public void setAnchor(Rectangle newAnchor) {} | |||
public double getRotation() { return 0; } | |||
public void setRotation(double theta) {} | |||
public void setFlipHorizontal(boolean flip) {} |
@@ -17,13 +17,16 @@ | |||
package org.apache.poi.sl.draw; | |||
import java.awt.Dimension; | |||
import java.awt.Graphics2D; | |||
import java.awt.Insets; | |||
import java.awt.Rectangle; | |||
import java.awt.geom.Rectangle2D; | |||
import java.io.IOException; | |||
import org.apache.poi.sl.usermodel.PictureData; | |||
import org.apache.poi.sl.usermodel.PictureShape; | |||
import org.apache.poi.sl.usermodel.RectAlign; | |||
public class DrawPictureShape extends DrawSimpleShape { | |||
@@ -56,4 +59,117 @@ public class DrawPictureShape extends DrawSimpleShape { | |||
protected PictureShape<?,?> getShape() { | |||
return (PictureShape<?,?>)shape; | |||
} | |||
/** | |||
* Resize this picture to the default size. | |||
* | |||
* For PNG and JPEG resizes the image to 100%, | |||
* for other types, if the size can't be determined it will be 200x200 pixels. | |||
*/ | |||
public void resize() { | |||
PictureShape<?,?> ps = getShape(); | |||
Dimension dim = ps.getPictureData().getImageDimension(); | |||
Rectangle origRect = ps.getAnchor(); | |||
int x = (int)origRect.getX(); | |||
int y = (int)origRect.getY(); | |||
int w = (int)dim.getWidth(); | |||
int h = (int)dim.getHeight(); | |||
ps.setAnchor(new Rectangle(x, y, w, h)); | |||
} | |||
/** | |||
* Fit picture shape into the target rectangle, maintaining the aspect ratio | |||
* and repositioning within the target rectangle with a centered alignment. | |||
* | |||
* @param target The target rectangle | |||
*/ | |||
public void resize(Rectangle target) { | |||
resize(target, RectAlign.CENTER); | |||
} | |||
/** | |||
* Fit picture shape into the target rectangle, maintaining the aspect ratio | |||
* and repositioning within the target rectangle based on the specified | |||
* alignment (gravity). | |||
* | |||
* @param target The target rectangle | |||
* @param align | |||
* The alignment within the target rectangle when resizing. | |||
* A null value corresponds to RectAlign.CENTER | |||
*/ | |||
public void resize(Rectangle target, RectAlign align) { | |||
PictureShape<?,?> ps = getShape(); | |||
Dimension dim = ps.getPictureData().getImageDimension(); | |||
if (dim.width <= 0 || dim.height <= 0) { | |||
// nothing useful to be done for this case | |||
ps.setAnchor(target); | |||
return; | |||
} | |||
double w = target.getWidth(); | |||
double h = target.getHeight(); | |||
// scaling | |||
double sx = w / dim.width; | |||
double sy = h / dim.height; | |||
// position adjustments | |||
double dx = 0, dy = 0; | |||
if (sx > sy) { | |||
// use y-scaling for both, reposition x accordingly | |||
w = sy * dim.width; | |||
dx = target.getWidth() - w; | |||
} else if (sy > sx) { | |||
// use x-scaling for both, reposition y accordingly | |||
h = sx * dim.height; | |||
dy = target.getHeight() - h; | |||
} else { | |||
// uniform scaling, can use target values directly | |||
ps.setAnchor(target); | |||
return; | |||
} | |||
// the positioning | |||
double x = target.getX(); | |||
double y = target.getY(); | |||
switch (align) { | |||
case TOP: // X=balance, Y=ok | |||
x += dx/2; | |||
break; | |||
case TOP_RIGHT: // X=shift, Y=ok | |||
x += dx; | |||
break; | |||
case RIGHT: // X=shift, Y=balance | |||
x += dx; | |||
y += dy/2; | |||
break; | |||
case BOTTOM_RIGHT: // X=shift, Y=shift | |||
x += dx; | |||
y += dy; | |||
break; | |||
case BOTTOM: // X=balance, Y=shift | |||
x += dx/2; | |||
y += dy; | |||
break; | |||
case BOTTOM_LEFT: // X=ok, Y=shift | |||
y += dy; | |||
break; | |||
case LEFT: // X=ok, Y=balance | |||
y += dy/2; | |||
break; | |||
case TOP_LEFT: // X=ok, Y=ok | |||
/* no-op */ | |||
break; | |||
default: // CENTER: X=balance, Y=balance | |||
x += dx/2; | |||
y += dy/2; | |||
break; | |||
} | |||
ps.setAnchor(new Rectangle((int)x, (int)y, (int)w, (int)h)); | |||
} | |||
} |
@@ -25,10 +25,8 @@ import java.awt.geom.AffineTransform; | |||
import java.awt.geom.Ellipse2D; | |||
import java.awt.geom.GeneralPath; | |||
import java.awt.geom.Rectangle2D; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.InputStreamReader; | |||
import java.io.Reader; | |||
import java.nio.charset.Charset; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
import java.util.HashMap; | |||
@@ -145,7 +143,7 @@ public class DrawSimpleShape extends DrawShape { | |||
double alpha = Math.atan(anchor.getHeight() / anchor.getWidth()); | |||
AffineTransform at = new AffineTransform(); | |||
java.awt.Shape shape = null; | |||
java.awt.Shape tailShape = null; | |||
Path p = null; | |||
Rectangle2D bounds; | |||
final double scaleY = Math.pow(2, tailWidth.ordinal()+1); | |||
@@ -153,8 +151,8 @@ public class DrawSimpleShape extends DrawShape { | |||
switch (deco.getTailShape()) { | |||
case OVAL: | |||
p = new Path(); | |||
shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY); | |||
bounds = shape.getBounds2D(); | |||
tailShape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY); | |||
bounds = tailShape.getBounds2D(); | |||
at.translate(x2 - bounds.getWidth() / 2, y2 - bounds.getHeight() / 2); | |||
at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2); | |||
break; | |||
@@ -165,7 +163,7 @@ public class DrawSimpleShape extends DrawShape { | |||
arrow.moveTo((float) (-lineWidth * scaleX), (float) (-lineWidth * scaleY / 2)); | |||
arrow.lineTo(0, 0); | |||
arrow.lineTo((float) (-lineWidth * scaleX), (float) (lineWidth * scaleY / 2)); | |||
shape = arrow; | |||
tailShape = arrow; | |||
at.translate(x2, y2); | |||
at.rotate(alpha); | |||
break; | |||
@@ -176,7 +174,7 @@ public class DrawSimpleShape extends DrawShape { | |||
triangle.lineTo(0, 0); | |||
triangle.lineTo((float) (-lineWidth * scaleX), (float) (lineWidth * scaleY / 2)); | |||
triangle.closePath(); | |||
shape = triangle; | |||
tailShape = triangle; | |||
at.translate(x2, y2); | |||
at.rotate(alpha); | |||
break; | |||
@@ -184,10 +182,10 @@ public class DrawSimpleShape extends DrawShape { | |||
break; | |||
} | |||
if (shape != null) { | |||
shape = at.createTransformedShape(shape); | |||
if (tailShape != null) { | |||
tailShape = at.createTransformedShape(tailShape); | |||
} | |||
return shape == null ? null : new Outline(shape, p); | |||
return tailShape == null ? null : new Outline(tailShape, p); | |||
} | |||
protected Outline getHeadDecoration(Graphics2D graphics, LineDecoration deco, BasicStroke stroke) { | |||
@@ -203,7 +201,7 @@ public class DrawSimpleShape extends DrawShape { | |||
double alpha = Math.atan(anchor.getHeight() / anchor.getWidth()); | |||
AffineTransform at = new AffineTransform(); | |||
java.awt.Shape shape = null; | |||
java.awt.Shape headShape = null; | |||
Path p = null; | |||
Rectangle2D bounds; | |||
final double scaleY = Math.pow(2, headWidth.ordinal()+1); | |||
@@ -211,8 +209,8 @@ public class DrawSimpleShape extends DrawShape { | |||
switch (deco.getHeadShape()) { | |||
case OVAL: | |||
p = new Path(); | |||
shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY); | |||
bounds = shape.getBounds2D(); | |||
headShape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY); | |||
bounds = headShape.getBounds2D(); | |||
at.translate(x1 - bounds.getWidth() / 2, y1 - bounds.getHeight() / 2); | |||
at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2); | |||
break; | |||
@@ -223,7 +221,7 @@ public class DrawSimpleShape extends DrawShape { | |||
arrow.moveTo((float) (lineWidth * scaleX), (float) (-lineWidth * scaleY / 2)); | |||
arrow.lineTo(0, 0); | |||
arrow.lineTo((float) (lineWidth * scaleX), (float) (lineWidth * scaleY / 2)); | |||
shape = arrow; | |||
headShape = arrow; | |||
at.translate(x1, y1); | |||
at.rotate(alpha); | |||
break; | |||
@@ -234,7 +232,7 @@ public class DrawSimpleShape extends DrawShape { | |||
triangle.lineTo(0, 0); | |||
triangle.lineTo((float) (lineWidth * scaleX), (float) (lineWidth * scaleY / 2)); | |||
triangle.closePath(); | |||
shape = triangle; | |||
headShape = triangle; | |||
at.translate(x1, y1); | |||
at.rotate(alpha); | |||
break; | |||
@@ -242,10 +240,10 @@ public class DrawSimpleShape extends DrawShape { | |||
break; | |||
} | |||
if (shape != null) { | |||
shape = at.createTransformedShape(shape); | |||
if (headShape != null) { | |||
headShape = at.createTransformedShape(headShape); | |||
} | |||
return shape == null ? null : new Outline(shape, p); | |||
return headShape == null ? null : new Outline(headShape, p); | |||
} | |||
public BasicStroke getStroke() { | |||
@@ -296,7 +294,7 @@ public class DrawSimpleShape extends DrawShape { | |||
, Paint fill | |||
, Paint line | |||
) { | |||
Shadow shadow = getShape().getShadow(); | |||
Shadow<?,?> shadow = getShape().getShadow(); | |||
if (shadow == null || (fill == null && line == null)) return; | |||
SolidPaint shadowPaint = shadow.getFillStyle(); | |||
@@ -347,7 +345,6 @@ public class DrawSimpleShape extends DrawShape { | |||
String packageName = "org.apache.poi.sl.draw.binding"; | |||
InputStream presetIS = Drawable.class.getResourceAsStream("presetShapeDefinitions.xml"); | |||
Reader xml = new InputStreamReader( presetIS, Charset.forName("UTF-8") ); | |||
// StAX: | |||
EventFilter startElementFilter = new EventFilter() { | |||
@@ -359,7 +356,7 @@ public class DrawSimpleShape extends DrawShape { | |||
try { | |||
XMLInputFactory staxFactory = XMLInputFactory.newInstance(); | |||
XMLEventReader staxReader = staxFactory.createXMLEventReader(xml); | |||
XMLEventReader staxReader = staxFactory.createXMLEventReader(presetIS); | |||
XMLEventReader staxFiltRd = staxFactory.createFilteredReader(staxReader, startElementFilter); | |||
// Ignore StartElement: | |||
staxFiltRd.nextEvent(); | |||
@@ -378,6 +375,12 @@ public class DrawSimpleShape extends DrawShape { | |||
} | |||
} catch (Exception e) { | |||
throw new RuntimeException("Unable to load preset geometries.", e); | |||
} finally { | |||
try { | |||
presetIS.close(); | |||
} catch (IOException e) { | |||
throw new RuntimeException("Unable to load preset geometries.", e); | |||
} | |||
} | |||
} | |||
@@ -19,6 +19,7 @@ package org.apache.poi.sl.draw; | |||
import java.awt.Graphics2D; | |||
import java.awt.Paint; | |||
import java.awt.Rectangle; | |||
import java.awt.font.FontRenderContext; | |||
import java.awt.font.LineBreakMeasurer; | |||
import java.awt.font.TextAttribute; | |||
@@ -416,8 +417,8 @@ public class DrawTextParagraph implements Drawable { | |||
private PlaceableShape<?,?> getParagraphShape() { | |||
PlaceableShape<?,?> ps = new PlaceableShape(){ | |||
public ShapeContainer<?,?> getParent() { return null; } | |||
public Rectangle2D getAnchor() { return paragraph.getParentShape().getAnchor(); } | |||
public void setAnchor(Rectangle2D anchor) {} | |||
public Rectangle getAnchor() { return paragraph.getParentShape().getAnchor(); } | |||
public void setAnchor(Rectangle anchor) {} | |||
public double getRotation() { return 0; } | |||
public void setRotation(double theta) {} | |||
public void setFlipHorizontal(boolean flip) {} |
@@ -17,7 +17,7 @@ | |||
package org.apache.poi.sl.usermodel; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.Rectangle; | |||
public interface GroupShape< | |||
S extends Shape<S,P>, | |||
@@ -30,7 +30,7 @@ public interface GroupShape< | |||
* | |||
* @return the coordinate space of this group | |||
*/ | |||
Rectangle2D getInteriorAnchor(); | |||
Rectangle getInteriorAnchor(); | |||
/** | |||
* Sets the coordinate space of this group. All children are constrained | |||
@@ -38,5 +38,5 @@ public interface GroupShape< | |||
* | |||
* @param anchor the coordinate space of this group | |||
*/ | |||
void setInteriorAnchor(Rectangle2D anchor); | |||
void setInteriorAnchor(Rectangle anchor); | |||
} |
@@ -106,10 +106,16 @@ public interface PictureData { | |||
byte[] getChecksum(); | |||
/** | |||
* Return the original image dimensions | |||
* Return the original image dimensions in points | |||
* (for formats supported by BufferedImage). | |||
* | |||
* Will return a Dimension with zero width/height if the format unsupported. | |||
* Will return a Dimension with a default width of 200x200 if the format unsupported. | |||
*/ | |||
Dimension getImageDimension(); | |||
/** | |||
* Return the original image dimensions in pixels | |||
* @see PictureData#getImageDimension() | |||
*/ | |||
Dimension getImageDimensionInPixels(); | |||
} |
@@ -17,7 +17,7 @@ | |||
package org.apache.poi.sl.usermodel; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.Rectangle; | |||
public interface PlaceableShape< | |||
S extends Shape<S,P>, | |||
@@ -29,13 +29,13 @@ public interface PlaceableShape< | |||
* @return the position of this shape within the drawing canvas. | |||
* The coordinates are expressed in points | |||
*/ | |||
Rectangle2D getAnchor(); | |||
Rectangle getAnchor(); | |||
/** | |||
* @param anchor the position of this shape within the drawing canvas. | |||
* The coordinates are expressed in points | |||
*/ | |||
void setAnchor(Rectangle2D anchor); | |||
void setAnchor(Rectangle anchor); | |||
/** | |||
* Rotation angle in degrees |
@@ -0,0 +1,74 @@ | |||
/* | |||
* ==================================================================== | |||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||
* contributor license agreements. See the NOTICE file distributed with | |||
* this work for additional information regarding copyright ownership. | |||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||
* (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
* ==================================================================== | |||
*/ | |||
package org.apache.poi.sl.usermodel; | |||
/** | |||
* Specifies possible rectangle alignment types. | |||
* | |||
* @see {@link org.openxmlformats.schemas.drawingml.x2006.main.STRectAlignment} | |||
* @see {@link org.apache.poi.sl.draw.binding.STRectAlignment} | |||
*/ | |||
public enum RectAlign { | |||
/** Top-Left rectangle alignment */ | |||
TOP_LEFT("tl"), | |||
/** Top rectangle alignment */ | |||
TOP("t"), | |||
/** Top-Right rectangle alignment */ | |||
TOP_RIGHT("tr"), | |||
/** Left rectangle alignment */ | |||
LEFT("l"), | |||
/** Center rectangle alignment */ | |||
CENTER("ctr"), | |||
/** Right rectangle alignment */ | |||
RIGHT("r"), | |||
/** Bottom-Left rectangle alignment */ | |||
BOTTOM_LEFT("bl"), | |||
/** Bottom rectangle alignment */ | |||
BOTTOM("b"), | |||
/** Bottom-Right rectangle alignment */ | |||
BOTTOM_RIGHT("br"); | |||
/** The corresponding xml enum value */ | |||
private final String dir; | |||
private RectAlign(String dir) { | |||
this.dir = dir; | |||
} | |||
/** | |||
* The string representation, | |||
* which corresponds to the internal XML enum value | |||
*/ | |||
@Override | |||
public String toString() { | |||
return dir; | |||
} | |||
} | |||
/* ************************************************************************** */ |
@@ -21,8 +21,11 @@ import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; | |||
public interface Shadow { | |||
SimpleShape getShadowParent(); | |||
public interface Shadow< | |||
S extends Shape<S,P>, | |||
P extends TextParagraph<S,P,?> | |||
> { | |||
SimpleShape<S,P> getShadowParent(); | |||
/** | |||
* @return the offset of this shadow in points |
@@ -17,6 +17,7 @@ | |||
package org.apache.poi.sl.usermodel; | |||
import java.awt.Rectangle; | |||
public interface Shape< | |||
S extends Shape<S,P>, | |||
@@ -29,4 +30,12 @@ public interface Shape< | |||
* @return the sheet this shape belongs to | |||
*/ | |||
Sheet<S,P> getSheet(); | |||
/** | |||
* Returns the anchor (the bounding box rectangle) of this shape. | |||
* All coordinates are expressed in points (72 dpi). | |||
* | |||
* @return the anchor of this shape | |||
*/ | |||
Rectangle getAnchor(); | |||
} |
@@ -35,5 +35,5 @@ public interface SimpleShape< | |||
boolean isPlaceholder(); | |||
Shadow getShadow(); | |||
Shadow<S,P> getShadow(); | |||
} |
@@ -0,0 +1,315 @@ | |||
/* ==================================================================== | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
==================================================================== */ | |||
package org.apache.poi.sl.usermodel; | |||
import java.io.File; | |||
import java.io.FileNotFoundException; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.PushbackInputStream; | |||
import java.lang.reflect.InvocationTargetException; | |||
import java.lang.reflect.Method; | |||
import java.security.GeneralSecurityException; | |||
import org.apache.poi.EncryptedDocumentException; | |||
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; | |||
import org.apache.poi.poifs.crypt.Decryptor; | |||
import org.apache.poi.poifs.crypt.EncryptionInfo; | |||
import org.apache.poi.poifs.filesystem.DirectoryNode; | |||
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; | |||
import org.apache.poi.poifs.filesystem.OfficeXmlFileException; | |||
import org.apache.poi.util.IOUtils; | |||
public class SlideShowFactory { | |||
/** The first 4 bytes of an OOXML file, used in detection */ | |||
private static final byte[] OOXML_FILE_HEADER = { 0x50, 0x4b, 0x03, 0x04 }; | |||
/** | |||
* Creates a SlideShow from the given NPOIFSFileSystem. | |||
* | |||
* @param fs The {@link NPOIFSFileSystem} to read the document from | |||
* | |||
* @return The created SlideShow | |||
* | |||
* @throws IOException if an error occurs while reading the data | |||
*/ | |||
public static SlideShow<?,?> create(NPOIFSFileSystem fs) throws IOException { | |||
return create(fs, null); | |||
} | |||
/** | |||
* Creates a SlideShow from the given NPOIFSFileSystem, which may | |||
* be password protected | |||
* | |||
* @param fs The {@link NPOIFSFileSystem} to read the document from | |||
* @param password The password that should be used or null if no password is necessary. | |||
* | |||
* @return The created SlideShow | |||
* | |||
* @throws IOException if an error occurs while reading the data | |||
*/ | |||
public static SlideShow<?,?> create(NPOIFSFileSystem fs, String password) throws IOException { | |||
DirectoryNode root = fs.getRoot(); | |||
// Encrypted OOXML files go inside OLE2 containers, is this one? | |||
if (root.hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) { | |||
EncryptionInfo info = new EncryptionInfo(fs); | |||
Decryptor d = Decryptor.getInstance(info); | |||
boolean passwordCorrect = false; | |||
InputStream stream = null; | |||
try { | |||
if (password != null && d.verifyPassword(password)) { | |||
passwordCorrect = true; | |||
} | |||
if (!passwordCorrect && d.verifyPassword(Decryptor.DEFAULT_PASSWORD)) { | |||
passwordCorrect = true; | |||
} | |||
if (passwordCorrect) { | |||
stream = d.getDataStream(root); | |||
} | |||
if (!passwordCorrect) { | |||
String err = (password != null) | |||
? "Password incorrect" | |||
: "The supplied spreadsheet is protected, but no password was supplied"; | |||
throw new EncryptedDocumentException(err); | |||
} | |||
return createXSLFSlideShow(stream); | |||
} catch (GeneralSecurityException e) { | |||
throw new IOException(e); | |||
} finally { | |||
if (stream != null) stream.close(); | |||
} | |||
} | |||
// If we get here, it isn't an encrypted PPTX file | |||
// So, treat it as a regular HSLF PPT one | |||
if (password != null) { | |||
Biff8EncryptionKey.setCurrentUserPassword(password); | |||
} | |||
try { | |||
return createHSLFSlideShow(fs); | |||
} finally { | |||
Biff8EncryptionKey.setCurrentUserPassword(null); | |||
} | |||
} | |||
/** | |||
* Creates the appropriate HSLFSlideShow / XMLSlideShow from | |||
* the given InputStream. | |||
* | |||
* <p>Your input stream MUST either support mark/reset, or | |||
* be wrapped as a {@link PushbackInputStream}! Note that | |||
* using an {@link InputStream} has a higher memory footprint | |||
* than using a {@link File}.</p> | |||
* | |||
* <p>Note that in order to properly release resources the | |||
* SlideShow should be closed after use. Note also that loading | |||
* from an InputStream requires more memory than loading | |||
* from a File, so prefer {@link #create(File)} where possible. | |||
* | |||
* @param inp The {@link InputStream} to read data from. | |||
* | |||
* @return The created SlideShow | |||
* | |||
* @throws IOException if an error occurs while reading the data | |||
* @throws EncryptedDocumentException If the SlideShow given is password protected | |||
*/ | |||
public static SlideShow<?,?> create(InputStream inp) throws IOException, EncryptedDocumentException { | |||
return create(inp, null); | |||
} | |||
/** | |||
* Creates the appropriate HSLFSlideShow / XMLSlideShow from | |||
* the given InputStream, which may be password protected. | |||
* <p>Your input stream MUST either support mark/reset, or | |||
* be wrapped as a {@link PushbackInputStream}! Note that | |||
* using an {@link InputStream} has a higher memory footprint | |||
* than using a {@link File}.</p> | |||
* | |||
* <p>Note that in order to properly release resources the | |||
* SlideShow should be closed after use. Note also that loading | |||
* from an InputStream requires more memory than loading | |||
* from a File, so prefer {@link #create(File)} where possible.</p> | |||
* | |||
* @param inp The {@link InputStream} to read data from. | |||
* @param password The password that should be used or null if no password is necessary. | |||
* | |||
* @return The created SlideShow | |||
* | |||
* @throws IOException if an error occurs while reading the data | |||
* @throws EncryptedDocumentException If the wrong password is given for a protected file | |||
*/ | |||
@SuppressWarnings("resource") | |||
public static SlideShow<?,?> create(InputStream inp, String password) throws IOException, EncryptedDocumentException { | |||
// If clearly doesn't do mark/reset, wrap up | |||
if (! inp.markSupported()) { | |||
inp = new PushbackInputStream(inp, 8); | |||
} | |||
// Ensure that there is at least some data there | |||
byte[] header8 = IOUtils.peekFirst8Bytes(inp); | |||
// Try to create | |||
if (NPOIFSFileSystem.hasPOIFSHeader(header8)) { | |||
NPOIFSFileSystem fs = new NPOIFSFileSystem(inp); | |||
return create(fs, password); | |||
} | |||
if (hasOOXMLHeader(inp)) { | |||
return createXSLFSlideShow(inp); | |||
} | |||
throw new IllegalArgumentException("Your InputStream was neither an OLE2 stream, nor an OOXML stream"); | |||
} | |||
/** | |||
* Creates the appropriate HSLFSlideShow / XMLSlideShow from | |||
* the given File, which must exist and be readable. | |||
* <p>Note that in order to properly release resources the | |||
* SlideShow should be closed after use. | |||
* | |||
* @param file The file to read data from. | |||
* | |||
* @return The created SlideShow | |||
* | |||
* @throws IOException if an error occurs while reading the data | |||
* @throws EncryptedDocumentException If the SlideShow given is password protected | |||
*/ | |||
public static SlideShow<?,?> create(File file) throws IOException, EncryptedDocumentException { | |||
return create(file, null); | |||
} | |||
/** | |||
* Creates the appropriate HSLFSlideShow / XMLSlideShow from | |||
* the given File, which must exist and be readable, and | |||
* may be password protected | |||
* <p>Note that in order to properly release resources the | |||
* SlideShow should be closed after use. | |||
* | |||
* @param file The file to read data from. | |||
* @param password The password that should be used or null if no password is necessary. | |||
* | |||
* @return The created SlideShow | |||
* | |||
* @throws IOException if an error occurs while reading the data | |||
* @throws EncryptedDocumentException If the wrong password is given for a protected file | |||
*/ | |||
public static SlideShow<?,?> create(File file, String password) throws IOException, EncryptedDocumentException { | |||
return create(file, password, false); | |||
} | |||
/** | |||
* Creates the appropriate HSLFSlideShow / XMLSlideShow from | |||
* the given File, which must exist and be readable, and | |||
* may be password protected | |||
* <p>Note that in order to properly release resources the | |||
* SlideShow should be closed after use. | |||
* | |||
* @param file The file to read data from. | |||
* @param password The password that should be used or null if no password is necessary. | |||
* @param readOnly If the SlideShow should be opened in read-only mode to avoid writing back | |||
* changes when the document is closed. | |||
* | |||
* @return The created SlideShow | |||
* | |||
* @throws IOException if an error occurs while reading the data | |||
* @throws EncryptedDocumentException If the wrong password is given for a protected file | |||
*/ | |||
@SuppressWarnings("resource") | |||
public static SlideShow<?,?> create(File file, String password, boolean readOnly) throws IOException, EncryptedDocumentException { | |||
if (!file.exists()) { | |||
throw new FileNotFoundException(file.toString()); | |||
} | |||
try { | |||
NPOIFSFileSystem fs = new NPOIFSFileSystem(file, readOnly); | |||
return create(fs, password); | |||
} catch(OfficeXmlFileException e) { | |||
return createXSLFSlideShow(file, readOnly); | |||
} | |||
} | |||
protected static SlideShow<?,?> createHSLFSlideShow(Object... args) throws IOException, EncryptedDocumentException { | |||
return createSlideShow("org.apache.poi.hslf.usermodel.HSLFSlideShowFactory", args); | |||
} | |||
protected static SlideShow<?,?> createXSLFSlideShow(Object... args) throws IOException, EncryptedDocumentException { | |||
return createSlideShow("org.apache.poi.xslf.usermodel.XSLFSlideShowFactory", args); | |||
} | |||
protected static SlideShow<?,?> createSlideShow(String factoryClass, Object args[]) throws IOException, EncryptedDocumentException { | |||
try { | |||
Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(factoryClass); | |||
Class<?> argsClz[] = new Class<?>[args.length]; | |||
int i=0; | |||
for (Object o : args) { | |||
Class<?> c = o.getClass(); | |||
if (Boolean.class.isAssignableFrom(c)) { | |||
c = boolean.class; | |||
} else if (InputStream.class.isAssignableFrom(c)) { | |||
c = InputStream.class; | |||
} | |||
argsClz[i++] = c; | |||
} | |||
Method m = clazz.getMethod("createSlideShow", argsClz); | |||
return (SlideShow<?,?>)m.invoke(null, args); | |||
} catch (InvocationTargetException e) { | |||
Throwable t = e.getCause(); | |||
if (t instanceof IOException) { | |||
throw (IOException)t; | |||
} else if (t instanceof EncryptedDocumentException) { | |||
throw (EncryptedDocumentException)t; | |||
} else { | |||
throw new IOException(t); | |||
} | |||
} catch (Exception e) { | |||
throw new IOException(e); | |||
} | |||
} | |||
/** | |||
* This copied over from ooxml, because we can't rely on these classes in the main package | |||
* | |||
* @see org.apache.poi.POIXMLDocument#hasOOXMLHeader(InputStream) | |||
*/ | |||
protected static boolean hasOOXMLHeader(InputStream inp) throws IOException { | |||
// We want to peek at the first 4 bytes | |||
inp.mark(4); | |||
byte[] header = new byte[4]; | |||
int bytesRead = IOUtils.readFully(inp, header); | |||
// Wind back those 4 bytes | |||
if(inp instanceof PushbackInputStream) { | |||
PushbackInputStream pin = (PushbackInputStream)inp; | |||
pin.unread(header, 0, bytesRead); | |||
} else { | |||
inp.reset(); | |||
} | |||
// Did it match the ooxml zip signature? | |||
return ( | |||
bytesRead == 4 && | |||
header[0] == OOXML_FILE_HEADER[0] && | |||
header[1] == OOXML_FILE_HEADER[1] && | |||
header[2] == OOXML_FILE_HEADER[2] && | |||
header[3] == OOXML_FILE_HEADER[3] | |||
); | |||
} | |||
} |
@@ -19,7 +19,7 @@ package org.apache.poi.xslf.usermodel; | |||
import java.awt.Color; | |||
import java.awt.Dimension; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.Rectangle; | |||
import org.apache.poi.sl.draw.DrawPaint; | |||
import org.apache.poi.sl.usermodel.Background; | |||
@@ -43,9 +43,9 @@ public class XSLFBackground extends XSLFSimpleShape | |||
} | |||
@Override | |||
public Rectangle2D getAnchor(){ | |||
public Rectangle getAnchor(){ | |||
Dimension pg = getSheet().getSlideShow().getPageSize(); | |||
return new Rectangle2D.Double(0, 0, pg.getWidth(), pg.getHeight()); | |||
return new Rectangle(0, 0, (int)pg.getWidth(), (int)pg.getHeight()); | |||
} | |||
@Override |
@@ -19,6 +19,7 @@ | |||
package org.apache.poi.xslf.usermodel; | |||
import java.awt.Rectangle; | |||
import java.awt.geom.AffineTransform; | |||
import java.awt.geom.GeneralPath; | |||
import java.awt.geom.PathIterator; | |||
@@ -60,7 +61,7 @@ public class XSLFFreeformShape extends XSLFAutoShape | |||
public int setPath(GeneralPath path) { | |||
CTPath2D ctPath = CTPath2D.Factory.newInstance(); | |||
Rectangle2D bounds = path.getBounds2D(); | |||
Rectangle bounds = path.getBounds(); | |||
int x0 = Units.toEMU(bounds.getX()); | |||
int y0 = Units.toEMU(bounds.getY()); | |||
PathIterator it = path.getPathIterator(new AffineTransform()); |
@@ -19,7 +19,7 @@ | |||
package org.apache.poi.xslf.usermodel; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.Rectangle; | |||
import javax.xml.namespace.QName; | |||
@@ -53,20 +53,19 @@ public class XSLFGraphicFrame extends XSLFShape { | |||
throw new UnsupportedOperationException(); | |||
} | |||
public Rectangle2D getAnchor(){ | |||
@Override | |||
public Rectangle getAnchor(){ | |||
CTTransform2D xfrm = ((CTGraphicalObjectFrame)getXmlObject()).getXfrm(); | |||
CTPoint2D off = xfrm.getOff(); | |||
long x = off.getX(); | |||
long y = off.getY(); | |||
int x = (int)Units.toPoints(off.getX()); | |||
int y = (int)Units.toPoints(off.getY()); | |||
CTPositiveSize2D ext = xfrm.getExt(); | |||
long cx = ext.getCx(); | |||
long cy = ext.getCy(); | |||
return new Rectangle2D.Double( | |||
Units.toPoints(x), Units.toPoints(y), | |||
Units.toPoints(cx), Units.toPoints(cy)); | |||
int cx = (int)Units.toPoints(ext.getCx()); | |||
int cy = (int)Units.toPoints(ext.getCy()); | |||
return new Rectangle(x, y, cx, cy); | |||
} | |||
public void setAnchor(Rectangle2D anchor){ | |||
public void setAnchor(Rectangle anchor){ | |||
CTTransform2D xfrm = ((CTGraphicalObjectFrame)getXmlObject()).getXfrm(); | |||
CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff(); | |||
long x = Units.toEMU(anchor.getX()); |
@@ -19,7 +19,7 @@ | |||
package org.apache.poi.xslf.usermodel; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.Rectangle; | |||
import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
@@ -27,6 +27,7 @@ import java.util.List; | |||
import org.apache.poi.openxml4j.opc.PackagePart; | |||
import org.apache.poi.openxml4j.opc.PackageRelationship; | |||
import org.apache.poi.openxml4j.opc.TargetMode; | |||
import org.apache.poi.sl.draw.DrawPictureShape; | |||
import org.apache.poi.sl.usermodel.GroupShape; | |||
import org.apache.poi.sl.usermodel.PictureData; | |||
import org.apache.poi.util.Beta; | |||
@@ -78,21 +79,19 @@ implements XSLFShapeContainer, GroupShape<XSLFShape,XSLFTextParagraph> { | |||
} | |||
@Override | |||
public Rectangle2D getAnchor(){ | |||
public Rectangle getAnchor(){ | |||
CTGroupTransform2D xfrm = getXfrm(); | |||
CTPoint2D off = xfrm.getOff(); | |||
long x = off.getX(); | |||
long y = off.getY(); | |||
int x = (int)Units.toPoints(off.getX()); | |||
int y = (int)Units.toPoints(off.getY()); | |||
CTPositiveSize2D ext = xfrm.getExt(); | |||
long cx = ext.getCx(); | |||
long cy = ext.getCy(); | |||
return new Rectangle2D.Double( | |||
Units.toPoints(x), Units.toPoints(y), | |||
Units.toPoints(cx), Units.toPoints(cy)); | |||
int cx = (int)Units.toPoints(ext.getCx()); | |||
int cy = (int)Units.toPoints(ext.getCy()); | |||
return new Rectangle(x,y,cx,cy); | |||
} | |||
@Override | |||
public void setAnchor(Rectangle2D anchor){ | |||
public void setAnchor(Rectangle anchor){ | |||
CTGroupTransform2D xfrm = getSafeXfrm(); | |||
CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff(); | |||
long x = Units.toEMU(anchor.getX()); | |||
@@ -112,17 +111,15 @@ implements XSLFShapeContainer, GroupShape<XSLFShape,XSLFTextParagraph> { | |||
* used for calculations of grouping, scaling, and rotation | |||
* behavior of shapes placed within a group. | |||
*/ | |||
public Rectangle2D getInteriorAnchor(){ | |||
public Rectangle getInteriorAnchor(){ | |||
CTGroupTransform2D xfrm = getXfrm(); | |||
CTPoint2D off = xfrm.getChOff(); | |||
long x = off.getX(); | |||
long y = off.getY(); | |||
int x = (int)Units.toPoints(off.getX()); | |||
int y = (int)Units.toPoints(off.getY()); | |||
CTPositiveSize2D ext = xfrm.getChExt(); | |||
long cx = ext.getCx(); | |||
long cy = ext.getCy(); | |||
return new Rectangle2D.Double( | |||
Units.toPoints(x), Units.toPoints(y), | |||
Units.toPoints(cx), Units.toPoints(cy)); | |||
int cx = (int)Units.toPoints(ext.getCx()); | |||
int cy = (int)Units.toPoints(ext.getCy()); | |||
return new Rectangle(x, y, cx, cy); | |||
} | |||
/** | |||
@@ -131,7 +128,7 @@ implements XSLFShapeContainer, GroupShape<XSLFShape,XSLFTextParagraph> { | |||
* used for calculations of grouping, scaling, and rotation | |||
* behavior of shapes placed within a group. | |||
*/ | |||
public void setInteriorAnchor(Rectangle2D anchor) { | |||
public void setInteriorAnchor(Rectangle anchor) { | |||
CTGroupTransform2D xfrm = getSafeXfrm(); | |||
CTPoint2D off = xfrm.isSetChOff() ? xfrm.getChOff() : xfrm.addNewChOff(); | |||
long x = Units.toEMU(anchor.getX()); | |||
@@ -250,7 +247,7 @@ implements XSLFShapeContainer, GroupShape<XSLFShape,XSLFTextParagraph> { | |||
pic.getPartName(), TargetMode.INTERNAL, XSLFRelation.IMAGES.getRelation()); | |||
XSLFPictureShape sh = getDrawing().createPicture(rel.getId()); | |||
sh.resize(); | |||
new DrawPictureShape(sh).resize(); | |||
_shapes.add(sh); | |||
sh.setParent(this); | |||
return sh; |
@@ -42,6 +42,7 @@ import org.apache.poi.util.LittleEndian; | |||
import org.apache.poi.util.LittleEndianConsts; | |||
import org.apache.poi.util.POILogFactory; | |||
import org.apache.poi.util.POILogger; | |||
import org.apache.poi.util.Units; | |||
/** | |||
* Instantiates sub-classes of POIXMLDocumentPart depending on their relationship type | |||
@@ -134,6 +135,15 @@ public final class XSLFPictureData extends POIXMLDocumentPart implements Picture | |||
return _origSize; | |||
} | |||
@Override | |||
public Dimension getImageDimensionInPixels() { | |||
Dimension dim = getImageDimension(); | |||
return new Dimension( | |||
Units.pointsToPixel(dim.getWidth()), | |||
Units.pointsToPixel(dim.getHeight()) | |||
); | |||
} | |||
/** | |||
* Determine and cache image properties | |||
*/ | |||
@@ -155,14 +165,19 @@ public final class XSLFPictureData extends POIXMLDocumentPart implements Picture | |||
_origSize = new PICT.NativeHeader(data, 0).getSize(); | |||
break; | |||
default: | |||
BufferedImage img = null; | |||
try { | |||
BufferedImage img = ImageIO.read(new ByteArrayInputStream(data)); | |||
_origSize = (img == null) ? new Dimension() : new Dimension(img.getWidth(), img.getHeight()); | |||
img = ImageIO.read(new ByteArrayInputStream(data)); | |||
} catch (IOException e) { | |||
logger.log(POILogger.WARN, "Can't determine image dimensions", e); | |||
// failed to get information, set dummy size | |||
_origSize = new Dimension(200,200); | |||
} | |||
// set dummy size, in case of dummy dimension can't be set | |||
_origSize = (img == null) | |||
? new Dimension(200,200) | |||
: new Dimension( | |||
(int)Units.pixelToPoints(img.getWidth()), | |||
(int)Units.pixelToPoints(img.getHeight()) | |||
); | |||
break; | |||
} | |||
} |
@@ -19,10 +19,9 @@ | |||
package org.apache.poi.xslf.usermodel; | |||
import java.awt.Dimension; | |||
import java.awt.Insets; | |||
import java.awt.Rectangle; | |||
import java.net.URI; | |||
import javax.xml.namespace.QName; | |||
import org.apache.poi.POIXMLException; | |||
@@ -83,24 +82,6 @@ public class XSLFPictureShape extends XSLFSimpleShape | |||
return ct; | |||
} | |||
/** | |||
* Resize this picture to the default size. | |||
* | |||
* For PNG and JPEG resizes the image to 100%, | |||
* for other types sets the default size to 200x200 pixels. | |||
*/ | |||
public void resize() { | |||
Dimension dim = getPictureData().getImageDimension(); | |||
if (dim.width > 0 && dim.height > 0) | |||
{ | |||
setAnchor(new Rectangle(0, 0, dim.width, dim.height)); | |||
} | |||
else | |||
{ | |||
// unsupported/unknown formats | |||
setAnchor(new Rectangle(50, 50, 200, 200)); | |||
} | |||
} | |||
/** | |||
* Is this an internal picture (image data included within |
@@ -18,7 +18,7 @@ | |||
package org.apache.poi.xslf.usermodel; | |||
import java.awt.Color; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.Rectangle; | |||
import org.apache.poi.sl.draw.DrawPaint; | |||
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; | |||
@@ -32,7 +32,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; | |||
* | |||
* @author Yegor Kozlov | |||
*/ | |||
public class XSLFShadow extends XSLFShape implements Shadow { | |||
public class XSLFShadow extends XSLFShape implements Shadow<XSLFShape,XSLFTextParagraph> { | |||
private XSLFSimpleShape _parent; | |||
@@ -47,11 +47,12 @@ public class XSLFShadow extends XSLFShape implements Shadow { | |||
return _parent; | |||
} | |||
public Rectangle2D getAnchor(){ | |||
@Override | |||
public Rectangle getAnchor(){ | |||
return _parent.getAnchor(); | |||
} | |||
public void setAnchor(Rectangle2D anchor){ | |||
public void setAnchor(Rectangle anchor){ | |||
throw new IllegalStateException("You can't set anchor of a shadow"); | |||
} | |||
@@ -36,6 +36,7 @@ import org.apache.poi.openxml4j.opc.PackagePartName; | |||
import org.apache.poi.openxml4j.opc.PackageRelationship; | |||
import org.apache.poi.openxml4j.opc.TargetMode; | |||
import org.apache.poi.sl.draw.DrawFactory; | |||
import org.apache.poi.sl.draw.DrawPictureShape; | |||
import org.apache.poi.sl.draw.Drawable; | |||
import org.apache.poi.sl.usermodel.PictureData; | |||
import org.apache.poi.sl.usermodel.Sheet; | |||
@@ -213,7 +214,7 @@ implements XSLFShapeContainer, Sheet<XSLFShape,XSLFTextParagraph> { | |||
addRelation(rel.getId(), new XSLFPictureData(pic, rel)); | |||
XSLFPictureShape sh = getDrawing().createPicture(rel.getId()); | |||
sh.resize(); | |||
new DrawPictureShape(sh).resize(); | |||
getShapes().add(sh); | |||
sh.setParent(this); | |||
return sh; | |||
@@ -537,6 +538,7 @@ implements XSLFShapeContainer, Sheet<XSLFShape,XSLFTextParagraph> { | |||
* @param packagePart package part containing the data to import | |||
* @return ID of the created relationship | |||
*/ | |||
@SuppressWarnings("resource") | |||
String importBlip(String blipId, PackagePart packagePart) { | |||
PackageRelationship blipRel = packagePart.getRelationship(blipId); | |||
PackagePart blipPart; | |||
@@ -561,6 +563,7 @@ implements XSLFShapeContainer, Sheet<XSLFShape,XSLFTextParagraph> { | |||
/** | |||
* Import a package part into this sheet. | |||
*/ | |||
@SuppressWarnings("resource") | |||
PackagePart importPart(PackageRelationship srcRel, PackagePart srcPafrt) { | |||
PackagePart destPP = getPackagePart(); | |||
PackagePartName srcPPName = srcPafrt.getPartName(); | |||
@@ -574,10 +577,11 @@ implements XSLFShapeContainer, Sheet<XSLFShape,XSLFTextParagraph> { | |||
destPP.addRelationship(srcPPName, TargetMode.INTERNAL, srcRel.getRelationshipType()); | |||
PackagePart part = pkg.createPart(srcPPName, srcPafrt.getContentType()); | |||
OutputStream out = part.getOutputStream(); | |||
try { | |||
OutputStream out = part.getOutputStream(); | |||
InputStream is = srcPafrt.getInputStream(); | |||
IOUtils.copy(is, out); | |||
is.close(); | |||
out.close(); | |||
} catch (IOException e){ | |||
throw new POIXMLException(e); |
@@ -20,7 +20,7 @@ | |||
package org.apache.poi.xslf.usermodel; | |||
import java.awt.Color; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.Rectangle; | |||
import javax.xml.stream.XMLStreamException; | |||
import javax.xml.stream.XMLStreamReader; | |||
@@ -45,7 +45,33 @@ import org.apache.poi.util.Beta; | |||
import org.apache.poi.util.Units; | |||
import org.apache.poi.xslf.model.PropertyFetcher; | |||
import org.apache.xmlbeans.XmlObject; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.*; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTBaseStyles; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleItem; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuide; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTLineEndProperties; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTLineStyleList; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetLineDashProperties; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.STCompoundLine; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndLength; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndType; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndWidth; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; | |||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; | |||
/** | |||
@@ -97,23 +123,21 @@ public abstract class XSLFSimpleShape extends XSLFShape | |||
} | |||
@Override | |||
public Rectangle2D getAnchor() { | |||
public Rectangle getAnchor() { | |||
CTTransform2D xfrm = getXfrm(); | |||
CTPoint2D off = xfrm.getOff(); | |||
long x = off.getX(); | |||
long y = off.getY(); | |||
int x = (int)Units.toPoints(off.getX()); | |||
int y = (int)Units.toPoints(off.getY()); | |||
CTPositiveSize2D ext = xfrm.getExt(); | |||
long cx = ext.getCx(); | |||
long cy = ext.getCy(); | |||
return new Rectangle2D.Double( | |||
Units.toPoints(x), Units.toPoints(y), | |||
Units.toPoints(cx), Units.toPoints(cy)); | |||
int cx = (int)Units.toPoints(ext.getCx()); | |||
int cy = (int)Units.toPoints(ext.getCy()); | |||
return new Rectangle(x, y, cx, cy); | |||
} | |||
@Override | |||
public void setAnchor(Rectangle2D anchor) { | |||
public void setAnchor(Rectangle anchor) { | |||
CTTransform2D xfrm = getSafeXfrm(); | |||
CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff(); | |||
long x = Units.toEMU(anchor.getX()); |
@@ -0,0 +1,100 @@ | |||
/* ==================================================================== | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
==================================================================== */ | |||
package org.apache.poi.xslf.usermodel; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import org.apache.poi.EncryptedDocumentException; | |||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; | |||
import org.apache.poi.openxml4j.opc.OPCPackage; | |||
import org.apache.poi.openxml4j.opc.PackageAccess; | |||
import org.apache.poi.sl.usermodel.SlideShow; | |||
import org.apache.poi.sl.usermodel.SlideShowFactory; | |||
import org.apache.poi.util.Internal; | |||
@Internal | |||
public class XSLFSlideShowFactory extends SlideShowFactory { | |||
/** | |||
* Creates a XMLSlideShow from the given OOXML Package | |||
* | |||
* <p>Note that in order to properly release resources the | |||
* SlideShow should be closed after use.</p> | |||
* | |||
* @param pkg The {@link OPCPackage} opened for reading data. | |||
* | |||
* @return The created SlideShow | |||
* | |||
* @throws IOException if an error occurs while reading the data | |||
* @throws InvalidFormatException | |||
*/ | |||
public static SlideShow<?,?> createSlideShow(OPCPackage pkg) throws IOException { | |||
try { | |||
return new XMLSlideShow(pkg); | |||
} catch (IllegalArgumentException ioe) { | |||
// ensure that file handles are closed (use revert() to not re-write the file) | |||
pkg.revert(); | |||
//pkg.close(); | |||
// rethrow exception | |||
throw ioe; | |||
} | |||
} | |||
/** | |||
* Creates the XMLSlideShow from the given File, which must exist and be readable. | |||
* <p>Note that in order to properly release resources theSlideShow should be closed after use. | |||
* | |||
* @param file The file to read data from. | |||
* @param readOnly If the SlideShow should be opened in read-only mode to avoid writing back | |||
* changes when the document is closed. | |||
* | |||
* @return The created SlideShow | |||
* | |||
* @throws IOException if an error occurs while reading the data | |||
* @throws EncryptedDocumentException If the wrong password is given for a protected file | |||
*/ | |||
@SuppressWarnings("resource") | |||
public static SlideShow<?,?> createSlideShow(File file, boolean readOnly) | |||
throws IOException, InvalidFormatException { | |||
OPCPackage pkg = OPCPackage.open(file, readOnly ? PackageAccess.READ : PackageAccess.READ_WRITE); | |||
return createSlideShow(pkg); | |||
} | |||
/** | |||
* Creates a XMLSlideShow from the given InputStream | |||
* | |||
* <p>Note that in order to properly release resources the | |||
* SlideShow should be closed after use.</p> | |||
* | |||
* @param stream The {@link InputStream} to read data from. | |||
* | |||
* @return The created SlideShow | |||
* | |||
* @throws IOException if an error occurs while reading the data | |||
* @throws InvalidFormatException | |||
*/ | |||
@SuppressWarnings("resource") | |||
public static SlideShow<?,?> createSlideShow(InputStream stream) throws IOException, InvalidFormatException { | |||
OPCPackage pkg = OPCPackage.open(stream); | |||
return createSlideShow(pkg); | |||
} | |||
} |
@@ -19,7 +19,7 @@ | |||
package org.apache.poi.xslf.usermodel; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.Rectangle; | |||
import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
@@ -466,8 +466,8 @@ public abstract class XSLFTextShape extends XSLFSimpleShape | |||
* | |||
* @return a <code>Rectangle2D</code> that is the bounds of this shape. | |||
*/ | |||
public Rectangle2D resizeToFitText(){ | |||
Rectangle2D anchor = getAnchor(); | |||
public Rectangle resizeToFitText(){ | |||
Rectangle anchor = getAnchor(); | |||
if(anchor.getWidth() == 0.) throw new POIXMLException( | |||
"Anchor of the shape was not set."); | |||
double height = getTextHeight(); |
@@ -31,10 +31,10 @@ import java.util.Map; | |||
import javax.imageio.ImageIO; | |||
import org.apache.poi.sl.SlideShowFactory; | |||
import org.apache.poi.sl.draw.Drawable; | |||
import org.apache.poi.sl.usermodel.Slide; | |||
import org.apache.poi.sl.usermodel.SlideShow; | |||
import org.apache.poi.sl.usermodel.SlideShowFactory; | |||
import org.apache.poi.util.JvmBugs; | |||
/** |
@@ -0,0 +1,71 @@ | |||
/* | |||
* ==================================================================== | |||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||
* contributor license agreements. See the NOTICE file distributed with | |||
* this work for additional information regarding copyright ownership. | |||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||
* (the "License"); you may not use this file except in compliance with | |||
* the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
* ==================================================================== | |||
*/ | |||
package org.apache.poi.sl.draw; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertNotNull; | |||
import java.awt.Dimension; | |||
import java.awt.Rectangle; | |||
import org.apache.poi.POIDataSamples; | |||
import org.apache.poi.sl.usermodel.PictureData; | |||
import org.apache.poi.sl.usermodel.PictureShape; | |||
import org.apache.poi.sl.usermodel.RectAlign; | |||
import org.apache.poi.sl.usermodel.Shape; | |||
import org.apache.poi.sl.usermodel.Slide; | |||
import org.apache.poi.sl.usermodel.SlideShow; | |||
import org.apache.poi.sl.usermodel.SlideShowFactory; | |||
import org.junit.Test; | |||
public class TestDrawPictureShape { | |||
final static POIDataSamples ssSamples = POIDataSamples.getSlideShowInstance(); | |||
@Test | |||
public void testResize() throws Exception { | |||
String files[] = { "pictures.ppt", "shapes.pptx" }; | |||
for (String file : files) { | |||
SlideShow<?,?> ss = SlideShowFactory.create(ssSamples.getFile(file)); | |||
Slide<?,?> slide = ss.getSlides().get(0); | |||
PictureShape<?,?> picShape = null; | |||
for (Shape<?,?> shape : slide.getShapes()) { | |||
if (shape instanceof PictureShape) { | |||
picShape = (PictureShape<?,?>)shape; | |||
break; | |||
} | |||
} | |||
assertNotNull(picShape); | |||
PictureData pd = picShape.getPictureData(); | |||
Dimension dimPd = pd.getImageDimension(); | |||
new DrawPictureShape(picShape).resize(); | |||
Dimension dimShape = picShape.getAnchor().getSize(); | |||
assertEquals(dimPd, dimShape); | |||
int newWidth = (int)(dimPd.getWidth()*(100d/dimPd.getHeight())); | |||
// ... -1 is a rounding error | |||
Rectangle expRect = new Rectangle(50+300-newWidth-1, 50, newWidth, 100); | |||
Rectangle target = new Rectangle(50,50,300,100); | |||
new DrawPictureShape(picShape).resize(target, RectAlign.BOTTOM_RIGHT); | |||
Rectangle actRect = picShape.getAnchor(); | |||
assertEquals(expRect, actRect); | |||
} | |||
} | |||
} |
@@ -16,10 +16,12 @@ | |||
==================================================================== */ | |||
package org.apache.poi.xslf.usermodel; | |||
import static org.junit.Assert.*; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertSame; | |||
import static org.junit.Assert.assertTrue; | |||
import java.awt.Dimension; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.Rectangle; | |||
import org.junit.Test; | |||
@@ -29,7 +31,7 @@ import org.junit.Test; | |||
public class TestXSLFGroupShape { | |||
@Test | |||
public void testCreateShapes() { | |||
public void testCreateShapes() throws Exception { | |||
XMLSlideShow ppt = new XMLSlideShow(); | |||
XSLFSlide slide = ppt.createSlide(); | |||
@@ -38,11 +40,11 @@ public class TestXSLFGroupShape { | |||
XSLFGroupShape group = slide.createGroup(); | |||
assertEquals(1, slide.getShapes().size()); | |||
Rectangle2D interior = new Rectangle2D.Double(-10, -10, 20, 20); | |||
Rectangle interior = new Rectangle(-10, -10, 20, 20); | |||
group.setInteriorAnchor(interior); | |||
assertEquals(interior, group.getInteriorAnchor()); | |||
Rectangle2D anchor = new Rectangle2D.Double(0, 0, 792, 612); | |||
Rectangle anchor = new Rectangle(0, 0, 792, 612); | |||
group.setAnchor(anchor); | |||
assertEquals(anchor, group.getAnchor()); | |||
@@ -83,10 +85,12 @@ public class TestXSLFGroupShape { | |||
group.removeShape(shape1); | |||
group.removeShape(shape4); | |||
assertTrue(group.getShapes().isEmpty()); | |||
ppt.close(); | |||
} | |||
@Test | |||
public void testRemoveShapes() { | |||
public void testRemoveShapes() throws Exception { | |||
XMLSlideShow ppt = new XMLSlideShow(); | |||
XSLFSlide slide = ppt.createSlide(); | |||
@@ -99,5 +103,6 @@ public class TestXSLFGroupShape { | |||
slide.removeShape(group2); | |||
slide.removeShape(group3); | |||
ppt.close(); | |||
} | |||
} |
@@ -0,0 +1,66 @@ | |||
/* ==================================================================== | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
==================================================================== */ | |||
package org.apache.poi.xslf.usermodel; | |||
import java.io.File; | |||
import java.io.FileOutputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.OutputStream; | |||
import java.security.GeneralSecurityException; | |||
import org.apache.poi.POIDataSamples; | |||
import org.apache.poi.poifs.crypt.EncryptionInfo; | |||
import org.apache.poi.poifs.crypt.EncryptionMode; | |||
import org.apache.poi.poifs.crypt.Encryptor; | |||
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; | |||
import org.apache.poi.sl.usermodel.BaseTestSlideShowFactory; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.util.TempFile; | |||
import org.junit.Test; | |||
public final class TestXSLFSlideShowFactory extends BaseTestSlideShowFactory { | |||
private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance(); | |||
@Test | |||
public void testFactory() throws Exception { | |||
File pFile = createProtected("SampleShow.pptx", "foobaa"); | |||
testFactory("SampleShow.pptx", pFile.getAbsolutePath(), "foobaa"); | |||
} | |||
private static File createProtected(String basefile, String password) | |||
throws IOException, GeneralSecurityException { | |||
NPOIFSFileSystem fs = new NPOIFSFileSystem(); | |||
EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile); | |||
Encryptor enc = info.getEncryptor(); | |||
enc.confirmPassword(password); | |||
InputStream fis = _slTests.openResourceAsStream("SampleShow.pptx"); | |||
OutputStream os = enc.getDataStream(fs); | |||
IOUtils.copy(fis, os); | |||
os.close(); | |||
fis.close(); | |||
File tf = TempFile.createTempFile("test-xslf-slidefactory", "pptx"); | |||
FileOutputStream fos = new FileOutputStream(tf); | |||
fs.writeFilesystem(fos); | |||
fos.close(); | |||
fs.close(); | |||
return tf; | |||
} | |||
} |
@@ -25,7 +25,6 @@ import static org.junit.Assert.assertTrue; | |||
import java.awt.Color; | |||
import java.awt.Graphics2D; | |||
import java.awt.Rectangle; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.image.BufferedImage; | |||
import java.io.IOException; | |||
import java.util.List; | |||
@@ -75,7 +74,7 @@ public class TestXSLFTextParagraph { | |||
"of text within a shape. Properties here apply to all text " + | |||
"residing within the corresponding paragraph."); | |||
Rectangle2D anchor = new Rectangle(50, 50, 300, 200); | |||
Rectangle anchor = new Rectangle(50, 50, 300, 200); | |||
sh.setAnchor(anchor); | |||
DrawTextParagraphProxy dtp = new DrawTextParagraphProxy(p); |
@@ -26,6 +26,7 @@ import java.io.IOException; | |||
import javax.imageio.ImageIO; | |||
import org.apache.poi.hslf.usermodel.HSLFPictureData; | |||
import org.apache.poi.util.Units; | |||
/** | |||
* Represents a bitmap picture data: JPEG or PNG. | |||
@@ -55,10 +56,14 @@ public abstract class Bitmap extends HSLFPictureData { | |||
setRawData(out.toByteArray()); | |||
} | |||
@Override | |||
public Dimension getImageDimension() { | |||
try { | |||
BufferedImage bi = ImageIO.read(new ByteArrayInputStream(getData())); | |||
return new Dimension(bi.getWidth(), bi.getHeight()); | |||
return new Dimension( | |||
(int)Units.pixelToPoints(bi.getWidth()), | |||
(int)Units.pixelToPoints(bi.getHeight()) | |||
); | |||
} catch (IOException e) { | |||
return new Dimension(200,200); | |||
} |
@@ -126,7 +126,7 @@ public abstract class Metafile extends HSLFPictureData { | |||
return out.toByteArray(); | |||
} | |||
@Override | |||
public Dimension getImageDimension() { | |||
int prefixLen = 16*uidInstanceCount; | |||
Header header = new Header(); |
@@ -42,7 +42,6 @@ import java.awt.geom.Arc2D; | |||
import java.awt.geom.Ellipse2D; | |||
import java.awt.geom.GeneralPath; | |||
import java.awt.geom.Line2D; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.geom.RoundRectangle2D; | |||
import java.awt.image.BufferedImage; | |||
import java.awt.image.BufferedImageOp; | |||
@@ -327,7 +326,7 @@ public final class PPGraphics2D extends Graphics2D implements Cloneable { | |||
Java graphics sets string coordinates by the baseline of the first character | |||
so we need to shift down by the height of the textbox | |||
*/ | |||
txt.setAnchor(new Rectangle2D.Float(x, y, width, height)); | |||
txt.setAnchor(new Rectangle((int)x, (int)y, (int)width, (int)height)); | |||
_group.addShape(txt); | |||
} |
@@ -17,6 +17,7 @@ | |||
package org.apache.poi.hslf.usermodel; | |||
import java.awt.Rectangle; | |||
import java.awt.geom.AffineTransform; | |||
import java.awt.geom.GeneralPath; | |||
import java.awt.geom.PathIterator; | |||
@@ -45,7 +46,6 @@ import org.apache.poi.util.Units; | |||
* Shapes drawn with the "Freeform" tool have cubic bezier curve segments in the smooth sections | |||
* and straight-line segments in the straight sections. This object closely corresponds to <code>java.awt.geom.GeneralPath</code>. | |||
* </p> | |||
* @author Yegor Kozlov | |||
*/ | |||
public final class HSLFFreeformShape extends HSLFAutoShape implements FreeformShape<HSLFShape,HSLFTextParagraph> { | |||
@@ -90,7 +90,7 @@ public final class HSLFFreeformShape extends HSLFAutoShape implements FreeformSh | |||
@Override | |||
public int setPath(GeneralPath path) { | |||
Rectangle2D bounds = path.getBounds2D(); | |||
Rectangle bounds = path.getBounds(); | |||
PathIterator it = path.getPathIterator(new AffineTransform()); | |||
List<byte[]> segInfo = new ArrayList<byte[]>(); | |||
@@ -241,7 +241,7 @@ public final class HSLFFreeformShape extends HSLFAutoShape implements FreeformSh | |||
} | |||
} | |||
Rectangle2D anchor = getAnchor2D(); | |||
Rectangle2D anchor = getAnchor(); | |||
Rectangle2D bounds = path.getBounds2D(); | |||
AffineTransform at = new AffineTransform(); | |||
at.translate(anchor.getX(), anchor.getY()); |
@@ -18,7 +18,6 @@ | |||
package org.apache.poi.hslf.usermodel; | |||
import java.awt.Rectangle; | |||
import java.awt.geom.Rectangle2D; | |||
import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
@@ -105,7 +104,7 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> { | |||
} | |||
@Override | |||
public void setInteriorAnchor(Rectangle2D anchor){ | |||
public void setInteriorAnchor(Rectangle anchor){ | |||
EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID); | |||
int x1 = Units.pointsToMaster(anchor.getX()); | |||
@@ -121,13 +120,13 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> { | |||
} | |||
@Override | |||
public Rectangle2D getInteriorAnchor(){ | |||
public Rectangle getInteriorAnchor(){ | |||
EscherSpgrRecord rec = getEscherChild(EscherSpgrRecord.RECORD_ID); | |||
double x1 = Units.masterToPoints(rec.getRectX1()); | |||
double y1 = Units.masterToPoints(rec.getRectY1()); | |||
double x2 = Units.masterToPoints(rec.getRectX2()); | |||
double y2 = Units.masterToPoints(rec.getRectY2()); | |||
return new Rectangle2D.Double(x1,y1,x2-x1,y2-y1); | |||
int x1 = (int)Units.masterToPoints(rec.getRectX1()); | |||
int y1 = (int)Units.masterToPoints(rec.getRectY1()); | |||
int x2 = (int)Units.masterToPoints(rec.getRectX2()); | |||
int y2 = (int)Units.masterToPoints(rec.getRectY2()); | |||
return new Rectangle(x1,y1,x2-x1,y2-y1); | |||
} | |||
/** | |||
@@ -181,7 +180,7 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> { | |||
* @param y the y coordinate of the top left corner of the shape in new location | |||
*/ | |||
public void moveTo(int x, int y){ | |||
java.awt.Rectangle anchor = getAnchor(); | |||
Rectangle anchor = getAnchor(); | |||
int dx = x - anchor.x; | |||
int dy = y - anchor.y; | |||
anchor.translate(dx, dy); | |||
@@ -189,7 +188,7 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> { | |||
for (HSLFShape shape : getShapes()) { | |||
java.awt.Rectangle chanchor = shape.getAnchor(); | |||
Rectangle chanchor = shape.getAnchor(); | |||
chanchor.translate(dx, dy); | |||
shape.setAnchor(chanchor); | |||
} | |||
@@ -201,7 +200,7 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> { | |||
* | |||
* @return the anchor of this shape group | |||
*/ | |||
public Rectangle2D getAnchor2D(){ | |||
public Rectangle getAnchor(){ | |||
EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID); | |||
int x1,y1,x2,y2; | |||
if(clientAnchor == null){ | |||
@@ -217,11 +216,11 @@ implements HSLFShapeContainer, GroupShape<HSLFShape,HSLFTextParagraph> { | |||
x2 = clientAnchor.getDx1(); | |||
y2 = clientAnchor.getRow1(); | |||
} | |||
Rectangle2D anchor= new Rectangle2D.Double( | |||
(x1 == -1 ? -1 : Units.masterToPoints(x1)), | |||
(y1 == -1 ? -1 : Units.masterToPoints(y1)), | |||
(x2 == -1 ? -1 : Units.masterToPoints(x2-x1)), | |||
(y2 == -1 ? -1 : Units.masterToPoints(y2-y1)) | |||
Rectangle anchor= new Rectangle( | |||
(int)(x1 == -1 ? -1 : Units.masterToPoints(x1)), | |||
(int)(y1 == -1 ? -1 : Units.masterToPoints(y1)), | |||
(int)(x2 == -1 ? -1 : Units.masterToPoints(x2-x1)), | |||
(int)(y2 == -1 ? -1 : Units.masterToPoints(y2-y1)) | |||
); | |||
return anchor; |
@@ -17,6 +17,7 @@ | |||
package org.apache.poi.hslf.usermodel; | |||
import java.awt.Dimension; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import java.security.MessageDigest; | |||
@@ -219,4 +220,13 @@ public abstract class HSLFPictureData implements PictureData { | |||
public final String getContentType() { | |||
return getType().contentType; | |||
} | |||
@Override | |||
public Dimension getImageDimensionInPixels() { | |||
Dimension dim = getImageDimension(); | |||
return new Dimension( | |||
Units.pointsToPixel(dim.getWidth()), | |||
Units.pointsToPixel(dim.getHeight()) | |||
); | |||
} | |||
} |
@@ -17,9 +17,8 @@ | |||
package org.apache.poi.hslf.usermodel; | |||
import java.awt.Dimension; | |||
import java.awt.Insets; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.Rectangle; | |||
import java.util.List; | |||
import org.apache.poi.ddf.AbstractEscherOptRecord; | |||
@@ -31,6 +30,7 @@ import org.apache.poi.ddf.EscherRecord; | |||
import org.apache.poi.ddf.EscherSimpleProperty; | |||
import org.apache.poi.ddf.EscherSpRecord; | |||
import org.apache.poi.hslf.record.Document; | |||
import org.apache.poi.sl.draw.DrawPictureShape; | |||
import org.apache.poi.sl.usermodel.PictureShape; | |||
import org.apache.poi.sl.usermodel.ShapeContainer; | |||
import org.apache.poi.sl.usermodel.ShapeType; | |||
@@ -113,21 +113,6 @@ public class HSLFPictureShape extends HSLFSimpleShape implements PictureShape<HS | |||
return _escherContainer; | |||
} | |||
/** | |||
* Resize this picture to the default size. | |||
* For PNG and JPEG resizes the image to 100%, | |||
* for other types, if the size can't be determined it will be 200x200 pixels. | |||
*/ | |||
public void setDefaultSize(){ | |||
Dimension dim = getPictureData().getImageDimension(); | |||
Rectangle2D origRect = getAnchor2D(); | |||
double x = origRect.getX(); | |||
double y = origRect.getY(); | |||
double w = Units.pixelToPoints((int)dim.getWidth()); | |||
double h = Units.pixelToPoints((int)dim.getHeight()); | |||
setAnchor(new Rectangle2D.Double(x, y, w, h)); | |||
} | |||
@Override | |||
public HSLFPictureData getPictureData(){ | |||
HSLFSlideShow ppt = getSheet().getSlideShow(); | |||
@@ -199,9 +184,9 @@ public class HSLFPictureShape extends HSLFSimpleShape implements PictureShape<HS | |||
EscherBSERecord bse = getEscherBSERecord(); | |||
bse.setRef(bse.getRef() + 1); | |||
java.awt.Rectangle anchor = getAnchor(); | |||
if (anchor.equals(new java.awt.Rectangle())){ | |||
setDefaultSize(); | |||
Rectangle anchor = getAnchor(); | |||
if (anchor.isEmpty()){ | |||
new DrawPictureShape(this).resize(); | |||
} | |||
} | |||
@@ -19,14 +19,29 @@ package org.apache.poi.hslf.usermodel; | |||
import java.awt.Color; | |||
import java.awt.Graphics2D; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.Rectangle; | |||
import java.util.Iterator; | |||
import org.apache.poi.ddf.*; | |||
import org.apache.poi.ddf.AbstractEscherOptRecord; | |||
import org.apache.poi.ddf.EscherChildAnchorRecord; | |||
import org.apache.poi.ddf.EscherClientAnchorRecord; | |||
import org.apache.poi.ddf.EscherColorRef; | |||
import org.apache.poi.ddf.EscherContainerRecord; | |||
import org.apache.poi.ddf.EscherOptRecord; | |||
import org.apache.poi.ddf.EscherProperties; | |||
import org.apache.poi.ddf.EscherProperty; | |||
import org.apache.poi.ddf.EscherRecord; | |||
import org.apache.poi.ddf.EscherSimpleProperty; | |||
import org.apache.poi.ddf.EscherSpRecord; | |||
import org.apache.poi.hslf.record.ColorSchemeAtom; | |||
import org.apache.poi.hslf.record.RecordTypes; | |||
import org.apache.poi.sl.usermodel.*; | |||
import org.apache.poi.util.*; | |||
import org.apache.poi.sl.usermodel.FillStyle; | |||
import org.apache.poi.sl.usermodel.Shape; | |||
import org.apache.poi.sl.usermodel.ShapeContainer; | |||
import org.apache.poi.sl.usermodel.ShapeType; | |||
import org.apache.poi.util.POILogFactory; | |||
import org.apache.poi.util.POILogger; | |||
import org.apache.poi.util.Units; | |||
/** | |||
* <p> | |||
@@ -126,18 +141,7 @@ public abstract class HSLFShape implements Shape<HSLFShape,HSLFTextParagraph> { | |||
* | |||
* @return the anchor of this shape | |||
*/ | |||
public java.awt.Rectangle getAnchor(){ | |||
Rectangle2D anchor2d = getAnchor2D(); | |||
return anchor2d.getBounds(); | |||
} | |||
/** | |||
* Returns the anchor (the bounding box rectangle) of this shape. | |||
* All coordinates are expressed in points (72 dpi). | |||
* | |||
* @return the anchor of this shape | |||
*/ | |||
public Rectangle2D getAnchor2D(){ | |||
public Rectangle getAnchor() { | |||
EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID); | |||
int flags = spRecord.getFlags(); | |||
int x1,y1,x2,y2; | |||
@@ -160,11 +164,11 @@ public abstract class HSLFShape implements Shape<HSLFShape,HSLFTextParagraph> { | |||
} | |||
// TODO: find out where this -1 value comes from at #57820 (link to ms docs?) | |||
Rectangle2D anchor = new Rectangle2D.Double( | |||
(x1 == -1 ? -1 : Units.masterToPoints(x1)), | |||
(y1 == -1 ? -1 : Units.masterToPoints(y1)), | |||
(x2 == -1 ? -1 : Units.masterToPoints(x2-x1)), | |||
(y2 == -1 ? -1 : Units.masterToPoints(y2-y1)) | |||
Rectangle anchor = new Rectangle( | |||
(int)(x1 == -1 ? -1 : Units.masterToPoints(x1)), | |||
(int)(y1 == -1 ? -1 : Units.masterToPoints(y1)), | |||
(int)(x2 == -1 ? -1 : Units.masterToPoints(x2-x1)), | |||
(int)(y2 == -1 ? -1 : Units.masterToPoints(y2-y1)) | |||
); | |||
return anchor; | |||
@@ -176,7 +180,7 @@ public abstract class HSLFShape implements Shape<HSLFShape,HSLFTextParagraph> { | |||
* | |||
* @param anchor new anchor | |||
*/ | |||
public void setAnchor(Rectangle2D anchor){ | |||
public void setAnchor(Rectangle anchor){ | |||
int x = Units.pointsToMaster(anchor.getX()); | |||
int y = Units.pointsToMaster(anchor.getY()); | |||
int w = Units.pointsToMaster(anchor.getWidth() + anchor.getX()); | |||
@@ -206,7 +210,7 @@ public abstract class HSLFShape implements Shape<HSLFShape,HSLFTextParagraph> { | |||
* @param y the y coordinate of the top left corner of the shape | |||
*/ | |||
public void moveTo(float x, float y){ | |||
Rectangle2D anchor = getAnchor2D(); | |||
Rectangle anchor = getAnchor(); | |||
anchor.setRect(x, y, anchor.getWidth(), anchor.getHeight()); | |||
setAnchor(anchor); | |||
} |
@@ -414,12 +414,12 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H | |||
return clr == null ? Color.black : clr; | |||
} | |||
public Shadow getShadow() { | |||
public Shadow<HSLFShape,HSLFTextParagraph> getShadow() { | |||
AbstractEscherOptRecord opt = getEscherOptRecord(); | |||
EscherProperty shadowType = opt.lookup(EscherProperties.SHADOWSTYLE__TYPE); | |||
if (shadowType == null) return null; | |||
return new Shadow(){ | |||
return new Shadow<HSLFShape,HSLFTextParagraph>(){ | |||
public SimpleShape<HSLFShape,HSLFTextParagraph> getShadowParent() { | |||
return HSLFSimpleShape.this; | |||
} |
@@ -69,6 +69,7 @@ import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet; | |||
import org.apache.poi.hslf.record.SlidePersistAtom; | |||
import org.apache.poi.hslf.record.UserEditAtom; | |||
import org.apache.poi.poifs.filesystem.DirectoryNode; | |||
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; | |||
import org.apache.poi.poifs.filesystem.POIFSFileSystem; | |||
import org.apache.poi.sl.usermodel.MasterSheet; | |||
import org.apache.poi.sl.usermodel.PictureData.PictureType; | |||
@@ -159,8 +160,8 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap | |||
/** | |||
* Constructs a Powerpoint document from an POIFSFileSystem. | |||
*/ | |||
public HSLFSlideShow(POIFSFileSystem inputStream) throws IOException { | |||
this(new HSLFSlideShowImpl(inputStream)); | |||
public HSLFSlideShow(NPOIFSFileSystem npoifs) throws IOException { | |||
this(new HSLFSlideShowImpl(npoifs)); | |||
} | |||
/** |
@@ -0,0 +1,38 @@ | |||
/* ==================================================================== | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
==================================================================== */ | |||
package org.apache.poi.hslf.usermodel; | |||
import java.io.IOException; | |||
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; | |||
import org.apache.poi.sl.usermodel.SlideShow; | |||
import org.apache.poi.sl.usermodel.SlideShowFactory; | |||
import org.apache.poi.util.Internal; | |||
@Internal | |||
public class HSLFSlideShowFactory extends SlideShowFactory { | |||
/** | |||
* Creates a HSLFSlideShow from the given NPOIFSFileSystem | |||
* <p>Note that in order to properly release resources the | |||
* SlideShow should be closed after use. | |||
*/ | |||
public static SlideShow<?,?> createSlideShow(NPOIFSFileSystem fs) throws IOException { | |||
return new HSLFSlideShow(fs); | |||
} | |||
} |
@@ -139,15 +139,15 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { | |||
storeText(); | |||
EscherTextboxWrapper _txtbox = getEscherTextboxWrapper(); | |||
if(_txtbox != null){ | |||
_escherContainer.addChildRecord(_txtbox.getEscherRecord()); | |||
EscherTextboxWrapper thisTxtbox = getEscherTextboxWrapper(); | |||
if(thisTxtbox != null){ | |||
_escherContainer.addChildRecord(thisTxtbox.getEscherRecord()); | |||
PPDrawing ppdrawing = sh.getPPDrawing(); | |||
ppdrawing.addTextboxWrapper(_txtbox); | |||
ppdrawing.addTextboxWrapper(thisTxtbox); | |||
// Ensure the escher layer knows about the added records | |||
try { | |||
_txtbox.writeOut(null); | |||
thisTxtbox.writeOut(null); | |||
} catch (IOException e){ | |||
throw new HSLFException(e); | |||
} | |||
@@ -192,10 +192,10 @@ implements TextShape<HSLFShape,HSLFTextParagraph> { | |||
* @return a <code>Rectangle2D</code> that is the bounds of this shape. | |||
*/ | |||
public Rectangle2D resizeToFitText(){ | |||
Rectangle2D anchor = getAnchor(); | |||
Rectangle anchor = getAnchor(); | |||
if(anchor.getWidth() == 0.) { | |||
logger.log(POILogger.WARN, "Width of shape wasn't set. Defaulting to 200px"); | |||
anchor = new Rectangle2D.Double(anchor.getX(), anchor.getY(), 200, anchor.getHeight()); | |||
anchor.setSize(200, (int)anchor.getHeight()); | |||
setAnchor(anchor); | |||
} | |||
double height = getTextHeight(); |
@@ -21,7 +21,7 @@ import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertFalse; | |||
import static org.junit.Assert.assertTrue; | |||
import java.awt.geom.Rectangle2D; | |||
import java.awt.Rectangle; | |||
import java.io.ByteArrayInputStream; | |||
import java.io.ByteArrayOutputStream; | |||
@@ -34,8 +34,6 @@ import org.junit.Test; | |||
/** | |||
* Test <code>MovieShape</code> object. | |||
* | |||
* @author Yegor Kozlov | |||
*/ | |||
public final class TestMovieShape { | |||
@@ -52,7 +50,7 @@ public final class TestMovieShape { | |||
HSLFPictureData thumbnailData = ppt.addPicture(_slTests.readFile("tomcat.png"), PictureType.PNG); | |||
MovieShape shape = new MovieShape(movieIdx, thumbnailData); | |||
shape.setAnchor(new Rectangle2D.Float(300,225,120,90)); | |||
shape.setAnchor(new Rectangle(300,225,120,90)); | |||
slide.addShape(shape); | |||
assertEquals(path, shape.getPath()); |
@@ -20,18 +20,26 @@ package org.apache.poi.hslf.model; | |||
import static org.junit.Assert.assertArrayEquals; | |||
import static org.junit.Assert.assertEquals; | |||
import java.awt.geom.Rectangle2D; | |||
import java.io.*; | |||
import java.awt.Rectangle; | |||
import java.io.ByteArrayInputStream; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.File; | |||
import java.io.InputStream; | |||
import java.util.List; | |||
import org.apache.poi.POIDataSamples; | |||
import org.apache.poi.hslf.usermodel.*; | |||
import org.apache.poi.hslf.usermodel.HSLFObjectData; | |||
import org.apache.poi.hslf.usermodel.HSLFPictureData; | |||
import org.apache.poi.hslf.usermodel.HSLFShape; | |||
import org.apache.poi.hslf.usermodel.HSLFSlide; | |||
import org.apache.poi.hslf.usermodel.HSLFSlideShow; | |||
import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl; | |||
import org.apache.poi.hssf.usermodel.HSSFSheet; | |||
import org.apache.poi.hssf.usermodel.HSSFWorkbook; | |||
import org.apache.poi.hwpf.HWPFDocument; | |||
import org.apache.poi.poifs.filesystem.POIFSFileSystem; | |||
import org.apache.poi.util.IOUtils; | |||
import org.apache.poi.sl.usermodel.PictureData.PictureType; | |||
import org.apache.poi.util.IOUtils; | |||
import org.junit.Test; | |||
public final class TestOleEmbedding { | |||
@@ -109,7 +117,7 @@ public final class TestOleEmbedding { | |||
OLEShape oleShape1 = new OLEShape(pictData); | |||
oleShape1.setObjectID(oleObjectId1); | |||
slide1.addShape(oleShape1); | |||
oleShape1.setAnchor(new Rectangle2D.Double(100,100,100,100)); | |||
oleShape1.setAnchor(new Rectangle(100,100,100,100)); | |||
// add second slide with different order in object creation | |||
HSLFSlide slide2 = ppt.createSlide(); | |||
@@ -123,7 +131,7 @@ public final class TestOleEmbedding { | |||
oleShape2.setObjectID(oleObjectId2); | |||
slide2.addShape(oleShape2); | |||
oleShape2.setAnchor(new Rectangle2D.Double(100,100,100,100)); | |||
oleShape2.setAnchor(new Rectangle(100,100,100,100)); | |||
ByteArrayOutputStream bos = new ByteArrayOutputStream(); | |||
ppt.write(bos); |
@@ -27,7 +27,6 @@ import static org.junit.Assert.assertTrue; | |||
import java.awt.Color; | |||
import java.awt.Dimension; | |||
import java.awt.Rectangle; | |||
import java.awt.geom.Rectangle2D; | |||
import java.io.ByteArrayInputStream; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.IOException; | |||
@@ -63,8 +62,6 @@ import org.junit.Test; | |||
/** | |||
* Test drawing shapes via Graphics2D | |||
* | |||
* @author Yegor Kozlov | |||
*/ | |||
public final class TestShapes { | |||
private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance(); | |||
@@ -165,8 +162,8 @@ public final class TestShapes { | |||
@SuppressWarnings("unused") | |||
@Test | |||
public void testParagraphs() throws Exception { | |||
HSLFSlideShow ppt = new HSLFSlideShow(); | |||
HSLFSlide slide = ppt.createSlide(); | |||
HSLFSlideShow ss = new HSLFSlideShow(); | |||
HSLFSlide slide = ss.createSlide(); | |||
HSLFTextBox shape = new HSLFTextBox(); | |||
HSLFTextRun p1r1 = shape.setText("para 1 run 1. "); | |||
HSLFTextRun p1r2 = shape.appendText("para 1 run 2.", false); | |||
@@ -178,15 +175,15 @@ public final class TestShapes { | |||
p2r2.setStrikethrough(true); | |||
// run 3 has same text properties as run 2 and will be merged when saving | |||
HSLFTextRun p2r3 = shape.appendText("para 2 run 3.", false); | |||
shape.setAnchor(new Rectangle2D.Double(100,100,100,10)); | |||
shape.setAnchor(new Rectangle(100,100,100,10)); | |||
slide.addShape(shape); | |||
shape.resizeToFitText(); | |||
ByteArrayOutputStream bos = new ByteArrayOutputStream(); | |||
ppt.write(bos); | |||
ss.write(bos); | |||
ppt = new HSLFSlideShow(new ByteArrayInputStream(bos.toByteArray())); | |||
slide = ppt.getSlides().get(0); | |||
ss = new HSLFSlideShow(new ByteArrayInputStream(bos.toByteArray())); | |||
slide = ss.getSlides().get(0); | |||
HSLFTextBox tb = (HSLFTextBox)slide.getShapes().get(0); | |||
List<HSLFTextParagraph> para = tb.getTextParagraphs(); | |||
HSLFTextRun tr = para.get(0).getTextRuns().get(0); | |||
@@ -289,8 +286,8 @@ public final class TestShapes { | |||
} | |||
private void textBoxSet(String filename) throws Exception { | |||
HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream(filename)); | |||
for (HSLFSlide sld : ppt.getSlides()) { | |||
HSLFSlideShow ss = new HSLFSlideShow(_slTests.openResourceAsStream(filename)); | |||
for (HSLFSlide sld : ss.getSlides()) { | |||
ArrayList<String> lst1 = new ArrayList<String>(); | |||
for (List<HSLFTextParagraph> txt : sld.getTextParagraphs()) { | |||
for (HSLFTextParagraph p : txt) { | |||
@@ -321,17 +318,17 @@ public final class TestShapes { | |||
*/ | |||
@Test | |||
public void shapeGroup() throws Exception { | |||
HSLFSlideShow ppt = new HSLFSlideShow(); | |||
HSLFSlideShow ss = new HSLFSlideShow(); | |||
HSLFSlide slide = ppt.createSlide(); | |||
Dimension pgsize = ppt.getPageSize(); | |||
HSLFSlide slide = ss.createSlide(); | |||
Dimension pgsize = ss.getPageSize(); | |||
HSLFGroupShape group = new HSLFGroupShape(); | |||
group.setAnchor(new Rectangle(0, 0, (int)pgsize.getWidth(), (int)pgsize.getHeight())); | |||
slide.addShape(group); | |||
HSLFPictureData data = ppt.addPicture(_slTests.readFile("clock.jpg"), PictureType.JPEG); | |||
HSLFPictureData data = ss.addPicture(_slTests.readFile("clock.jpg"), PictureType.JPEG); | |||
HSLFPictureShape pict = new HSLFPictureShape(data, group); | |||
pict.setAnchor(new Rectangle(0, 0, 200, 200)); | |||
group.addShape(pict); | |||
@@ -342,14 +339,14 @@ public final class TestShapes { | |||
//serialize and read again. | |||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
ppt.write(out); | |||
ss.write(out); | |||
out.close(); | |||
ByteArrayInputStream is = new ByteArrayInputStream(out.toByteArray()); | |||
ppt = new HSLFSlideShow(is); | |||
ss = new HSLFSlideShow(is); | |||
is.close(); | |||
slide = ppt.getSlides().get(0); | |||
slide = ss.getSlides().get(0); | |||
List<HSLFShape> shape = slide.getShapes(); | |||
assertEquals(1, shape.size()); | |||
@@ -374,8 +371,8 @@ public final class TestShapes { | |||
@Test | |||
public void removeShapes() throws IOException { | |||
String file = "with_textbox.ppt"; | |||
HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream(file)); | |||
HSLFSlide sl = ppt.getSlides().get(0); | |||
HSLFSlideShow ss = new HSLFSlideShow(_slTests.openResourceAsStream(file)); | |||
HSLFSlide sl = ss.getSlides().get(0); | |||
List<HSLFShape> sh = sl.getShapes(); | |||
assertEquals("expected four shaped in " + file, 4, sh.size()); | |||
//remove all | |||
@@ -388,11 +385,11 @@ public final class TestShapes { | |||
//serialize and read again. The file should be readable and contain no shapes | |||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
ppt.write(out); | |||
ss.write(out); | |||
out.close(); | |||
ppt = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())); | |||
sl = ppt.getSlides().get(0); | |||
ss = new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())); | |||
sl = ss.getSlides().get(0); | |||
assertEquals("expected 0 shaped in " + file, 0, sl.getShapes().size()); | |||
} | |||
@@ -413,12 +410,12 @@ public final class TestShapes { | |||
@Test | |||
public void shapeId() { | |||
HSLFSlideShow ppt = new HSLFSlideShow(); | |||
HSLFSlide slide = ppt.createSlide(); | |||
HSLFSlideShow ss = new HSLFSlideShow(); | |||
HSLFSlide slide = ss.createSlide(); | |||
HSLFShape shape = null; | |||
//EscherDgg is a document-level record which keeps track of the drawing groups | |||
EscherDggRecord dgg = ppt.getDocumentRecord().getPPDrawingGroup().getEscherDggRecord(); | |||
EscherDggRecord dgg = ss.getDocumentRecord().getPPDrawingGroup().getEscherDggRecord(); | |||
EscherDgRecord dg = slide.getSheetContainer().getPPDrawing().getEscherDgRecord(); | |||
int dggShapesUsed = dgg.getNumShapesSaved(); //total number of shapes in the ppt | |||
@@ -463,8 +460,8 @@ public final class TestShapes { | |||
@Test | |||
public void lineColor() throws IOException { | |||
HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("51731.ppt")); | |||
List<HSLFShape> shape = ppt.getSlides().get(0).getShapes(); | |||
HSLFSlideShow ss = new HSLFSlideShow(_slTests.openResourceAsStream("51731.ppt")); | |||
List<HSLFShape> shape = ss.getSlides().get(0).getShapes(); | |||
assertEquals(4, shape.size()); | |||
@@ -0,0 +1,28 @@ | |||
/* ==================================================================== | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
==================================================================== */ | |||
package org.apache.poi.hslf.usermodel; | |||
import org.apache.poi.sl.usermodel.BaseTestSlideShowFactory; | |||
import org.junit.Test; | |||
public final class TestHSLFSlideShowFactory extends BaseTestSlideShowFactory { | |||
@Test | |||
public void testFactory() throws Exception { | |||
testFactory("pictures.ppt", "Password_Protected-hello.ppt", "hello"); | |||
} | |||
} |
@@ -35,6 +35,7 @@ import org.apache.poi.hslf.blip.PICT; | |||
import org.apache.poi.hslf.blip.PNG; | |||
import org.apache.poi.hslf.blip.WMF; | |||
import org.apache.poi.sl.usermodel.PictureData.PictureType; | |||
import org.apache.poi.util.Units; | |||
import org.junit.Ignore; | |||
import org.junit.Test; | |||
@@ -46,8 +47,6 @@ import org.junit.Test; | |||
public final class TestPictures { | |||
private static POIDataSamples slTests = POIDataSamples.getSlideShowInstance(); | |||
//protected File cwd; | |||
/** | |||
* Test read/write Macintosh PICT | |||
*/ | |||
@@ -64,9 +63,9 @@ public final class TestPictures { | |||
assertEquals(expWidth, nDim.getWidth(), 0); | |||
assertEquals(expHeight, nDim.getHeight(), 0); | |||
Dimension dim = data.getImageDimension(); | |||
assertEquals(expWidth, dim.getWidth(), 0); | |||
assertEquals(expHeight, dim.getHeight(), 0); | |||
Dimension dim = data.getImageDimensionInPixels(); | |||
assertEquals(Units.pointsToPixel(expWidth), dim.getWidth(), 0); | |||
assertEquals(Units.pointsToPixel(expHeight), dim.getHeight(), 0); | |||
HSLFPictureShape pict = new HSLFPictureShape(data); | |||
assertEquals(data.getIndex(), pict.getPictureIndex()); | |||
@@ -127,9 +126,9 @@ public final class TestPictures { | |||
assertEquals(expWidth, nDim.getWidth(), 0); | |||
assertEquals(expHeight, nDim.getHeight(), 0); | |||
Dimension dim = data.getImageDimension(); | |||
assertEquals(expWidth, dim.getWidth(), 0); | |||
assertEquals(expHeight, dim.getHeight(), 0); | |||
Dimension dim = data.getImageDimensionInPixels(); | |||
assertEquals(Units.pointsToPixel(expWidth), dim.getWidth(), 0); | |||
assertEquals(Units.pointsToPixel(expHeight), dim.getHeight(), 0); | |||
HSLFPictureShape pict = new HSLFPictureShape(data); | |||
assertEquals(data.getIndex(), pict.getPictureIndex()); | |||
@@ -189,9 +188,9 @@ public final class TestPictures { | |||
assertEquals(expWidth, nDim.getWidth(), 0); | |||
assertEquals(expHeight, nDim.getHeight(), 0); | |||
Dimension dim = data.getImageDimension(); | |||
assertEquals(expWidth, dim.getWidth(), 0); | |||
assertEquals(expHeight, dim.getHeight(), 0); | |||
Dimension dim = data.getImageDimensionInPixels(); | |||
assertEquals(Units.pointsToPixel(expWidth), dim.getWidth(), 0); | |||
assertEquals(Units.pointsToPixel(expHeight), dim.getHeight(), 0); | |||
HSLFPictureShape pict = new HSLFPictureShape(data); | |||
assertEquals(data.getIndex(), pict.getPictureIndex()); |
@@ -22,19 +22,14 @@ import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertNotNull; | |||
import static org.junit.Assert.assertTrue; | |||
import java.awt.Rectangle; | |||
import java.awt.geom.GeneralPath; | |||
import java.awt.geom.Rectangle2D; | |||
import java.net.URL; | |||
import java.util.Enumeration; | |||
import java.util.Map; | |||
import org.junit.Test; | |||
/** | |||
* Date: 10/24/11 | |||
* | |||
* @author Yegor Kozlov | |||
*/ | |||
public class TestPresetGeometries { | |||
@Test | |||
public void testRead(){ | |||
@@ -43,8 +38,8 @@ public class TestPresetGeometries { | |||
for(String name : shapes.keySet()) { | |||
CustomGeometry geom = shapes.get(name); | |||
Context ctx = new Context(geom, new Rectangle2D.Double(0, 0, 100, 100), new IAdjustableShape() { | |||
public Guide getAdjustValue(String name) { | |||
Context ctx = new Context(geom, new Rectangle(0, 0, 100, 100), new IAdjustableShape() { | |||
public Guide getAdjustValue(String presetName) { | |||
return null; | |||
} | |||
}); |
@@ -0,0 +1,73 @@ | |||
/* ==================================================================== | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
==================================================================== */ | |||
package org.apache.poi.sl.usermodel; | |||
import static org.junit.Assert.assertNotNull; | |||
import java.io.File; | |||
import java.io.FileInputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import org.apache.poi.POIDataSamples; | |||
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; | |||
public class BaseTestSlideShowFactory { | |||
private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance(); | |||
public void testFactory(String file, String protectedFile, String password) | |||
throws Exception { | |||
SlideShow<?,?> ss; | |||
// from file | |||
ss = SlideShowFactory.create(fromFile(file)); | |||
assertNotNull(ss); | |||
// from stream | |||
ss = SlideShowFactory.create(fromStream(file)); | |||
assertNotNull(ss); | |||
// from NPOIFS | |||
if (!file.contains("pptx")) { | |||
NPOIFSFileSystem npoifs = new NPOIFSFileSystem(fromFile(file)); | |||
ss = SlideShowFactory.create(npoifs); | |||
assertNotNull(ss); | |||
npoifs.close(); | |||
} | |||
// from protected file | |||
ss = SlideShowFactory.create(fromFile(protectedFile), password); | |||
assertNotNull(ss); | |||
// from protected stream | |||
ss = SlideShowFactory.create(fromStream(protectedFile), password); | |||
assertNotNull(ss); | |||
// from protected NPOIFS | |||
NPOIFSFileSystem npoifs = new NPOIFSFileSystem(fromFile(protectedFile)); | |||
ss = SlideShowFactory.create(npoifs, password); | |||
assertNotNull(ss); | |||
npoifs.close(); | |||
} | |||
private static File fromFile(String file) { | |||
return (file.contains("/") || file.contains("\\")) | |||
? new File(file) | |||
: _slTests.getFile(file); | |||
} | |||
private static InputStream fromStream(String file) throws IOException { | |||
return (file.contains("/") || file.contains("\\")) | |||
? new FileInputStream(file) | |||
: _slTests.openResourceAsStream(file); | |||
} | |||
} |