public static final short LINESTYLE__HITLINETEST = 509;
public static final short LINESTYLE__LINEFILLSHAPE = 510;
public static final short LINESTYLE__NOLINEDRAWDASH = 511;
+ public static final short LINESTYLE__NOLINEDRAWDASH_LEFT = 0x057F;
+ public static final short LINESTYLE__NOLINEDRAWDASH_TOP = 0x05BF;
+ public static final short LINESTYLE__NOLINEDRAWDASH_BOTTOM = 0x063F;
+ public static final short LINESTYLE__NOLINEDRAWDASH_RIGHT = 0x05FF;
public static final short SHADOWSTYLE__TYPE = 512;
public static final short SHADOWSTYLE__COLOR = 513;
public static final short SHADOWSTYLE__HIGHLIGHT = 514;
addProp(m, LINESTYLE__HITLINETEST, "linestyle.hitlinetest");
addProp(m, LINESTYLE__LINEFILLSHAPE, "linestyle.linefillshape");
addProp(m, LINESTYLE__NOLINEDRAWDASH, "linestyle.nolinedrawdash", EscherPropertyMetaData.TYPE_BOOLEAN);
+ addProp(m, LINESTYLE__NOLINEDRAWDASH_LEFT, "linestyle.nolinedrawdash.left", EscherPropertyMetaData.TYPE_BOOLEAN);
+ addProp(m, LINESTYLE__NOLINEDRAWDASH_TOP, "linestyle.nolinedrawdash.top", EscherPropertyMetaData.TYPE_BOOLEAN);
+ addProp(m, LINESTYLE__NOLINEDRAWDASH_BOTTOM, "linestyle.nolinedrawdash.bottom", EscherPropertyMetaData.TYPE_BOOLEAN);
+ addProp(m, LINESTYLE__NOLINEDRAWDASH_RIGHT, "linestyle.nolinedrawdash.right", EscherPropertyMetaData.TYPE_BOOLEAN);
addProp(m, SHADOWSTYLE__TYPE, "shadowstyle.type");
addProp(m, SHADOWSTYLE__COLOR, "shadowstyle.color", EscherPropertyMetaData.TYPE_RGB);
addProp(m, SHADOWSTYLE__HIGHLIGHT, "shadowstyle.highlight");
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.sl.draw;\r
+\r
+import java.awt.Dimension;\r
+import java.awt.Graphics;\r
+import java.awt.Graphics2D;\r
+import java.awt.Insets;\r
+import java.awt.Shape;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Rectangle2D;\r
+import java.awt.image.BufferedImage;\r
+import java.awt.image.RescaleOp;\r
+import java.io.ByteArrayInputStream;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+\r
+import javax.imageio.ImageIO;\r
+\r
+import org.apache.poi.util.POILogFactory;\r
+import org.apache.poi.util.POILogger;\r
+\r
+/**\r
+ * For now this class renders only images supported by the javax.imageio.ImageIO framework.\r
+ **/\r
+public class BitmapImageRenderer implements ImageRenderer {\r
+ private final static POILogger LOG = POILogFactory.getLogger(ImageRenderer.class);\r
+\r
+ protected BufferedImage img;\r
+\r
+ @Override\r
+ public void loadImage(InputStream data, String contentType) throws IOException {\r
+ img = convertBufferedImage(ImageIO.read(data), contentType);\r
+ }\r
+\r
+ @Override\r
+ public void loadImage(byte data[], String contentType) throws IOException {\r
+ img = convertBufferedImage(ImageIO.read(new ByteArrayInputStream(data)), contentType);\r
+ }\r
+\r
+ /**\r
+ * Add alpha channel to buffered image\r
+ */\r
+ private static BufferedImage convertBufferedImage(BufferedImage img, String contentType) {\r
+ if (img == null) {\r
+ LOG.log(POILogger.WARN, "Content-type: "+contentType+" is not support. Image ignored.");\r
+ return null;\r
+ }\r
+\r
+ BufferedImage bi = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);\r
+ Graphics g = bi.getGraphics();\r
+ g.drawImage(img, 0, 0, null);\r
+ g.dispose();\r
+ return bi;\r
+ }\r
+\r
+\r
+ /**\r
+ * @return the buffered image\r
+ */\r
+ public BufferedImage getImage() {\r
+ return img;\r
+ }\r
+\r
+ @Override\r
+ public Dimension getDimension() {\r
+ return (img == null)\r
+ ? new Dimension(0,0)\r
+ : new Dimension(img.getWidth(),img.getHeight());\r
+ }\r
+\r
+ @Override\r
+ public void setAlpha(double alpha) {\r
+ if (img == null) return;\r
+\r
+ Dimension dim = getDimension();\r
+ BufferedImage newImg = new BufferedImage((int)dim.getWidth(), (int)dim.getHeight(), BufferedImage.TYPE_INT_ARGB);\r
+ Graphics2D g = newImg.createGraphics();\r
+ RescaleOp op = new RescaleOp(new float[]{1.0f, 1.0f, 1.0f, (float)alpha}, new float[]{0,0,0,0}, null);\r
+ g.drawImage(img, op, 0, 0);\r
+ g.dispose();\r
+\r
+ img = newImg;\r
+ }\r
+\r
+\r
+ @Override\r
+ public boolean drawImage(\r
+ Graphics2D graphics,\r
+ Rectangle2D anchor) {\r
+ return drawImage(graphics, anchor, null);\r
+ }\r
+\r
+ @Override\r
+ public boolean drawImage(\r
+ Graphics2D graphics,\r
+ Rectangle2D anchor,\r
+ Insets clip) {\r
+ if (img == null) return false;\r
+\r
+ boolean isClipped = true;\r
+ if (clip == null) {\r
+ isClipped = false;\r
+ clip = new Insets(0,0,0,0);\r
+ }\r
+\r
+ int iw = img.getWidth();\r
+ int ih = img.getHeight();\r
+\r
+\r
+ double cw = (100000-clip.left-clip.right) / 100000.0;\r
+ double ch = (100000-clip.top-clip.bottom) / 100000.0;\r
+ double sx = anchor.getWidth()/(iw*cw);\r
+ double sy = anchor.getHeight()/(ih*ch);\r
+ double tx = anchor.getX()-(iw*sx*clip.left/100000.0);\r
+ double ty = anchor.getY()-(ih*sy*clip.top/100000.0);\r
+\r
+ AffineTransform at = new AffineTransform(sx, 0, 0, sy, tx, ty) ;\r
+\r
+ Shape clipOld = graphics.getClip();\r
+ if (isClipped) graphics.clip(anchor.getBounds2D());\r
+ graphics.drawRenderedImage(img, at);\r
+ graphics.setClip(clipOld);\r
+\r
+ return true;\r
+ }\r
+}\r
import org.apache.poi.sl.usermodel.Background;\r
import org.apache.poi.sl.usermodel.ConnectorShape;\r
import org.apache.poi.sl.usermodel.FreeformShape;\r
+import org.apache.poi.sl.usermodel.GraphicalFrame;\r
import org.apache.poi.sl.usermodel.GroupShape;\r
import org.apache.poi.sl.usermodel.MasterSheet;\r
import org.apache.poi.sl.usermodel.PictureShape;\r
return getDrawable((GroupShape<?,?>)shape);\r
} else if (shape instanceof PictureShape) {\r
return getDrawable((PictureShape<?,?>)shape);\r
+ } else if (shape instanceof GraphicalFrame) {\r
+ return getDrawable((GraphicalFrame<?,?>)shape);\r
} else if (shape instanceof Background) {\r
return getDrawable((Background<?,?>)shape);\r
} else if (shape instanceof ConnectorShape) {\r
return new DrawPictureShape(shape);\r
}\r
\r
+ public DrawGraphicalFrame getDrawable(GraphicalFrame<?,?> shape) {\r
+ return new DrawGraphicalFrame(shape);\r
+ }\r
+ \r
public DrawTextParagraph getDrawable(TextParagraph<?,?,?> paragraph) {\r
return new DrawTextParagraph(paragraph);\r
}\r
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.sl.draw;\r
+\r
+import java.awt.Graphics2D;\r
+\r
+import org.apache.poi.sl.usermodel.GraphicalFrame;\r
+import org.apache.poi.sl.usermodel.PictureShape;\r
+\r
+\r
+public class DrawGraphicalFrame extends DrawShape {\r
+\r
+ public DrawGraphicalFrame(GraphicalFrame<?,?> shape) {\r
+ super(shape);\r
+ }\r
+ \r
+ public void draw(Graphics2D context) {\r
+ PictureShape<?,?> ps = ((GraphicalFrame<?,?>)getShape()).getFallbackPicture();\r
+ if (ps == null) {\r
+ return;\r
+ }\r
+ DrawPictureShape dps = DrawFactory.getInstance(context).getDrawable(ps);\r
+ dps.draw(context);\r
+ }\r
+}\r
if (is == null) return null;\r
assert(graphics != null);\r
\r
- ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER);\r
- if (renderer == null) renderer = new ImageRenderer();\r
+ ImageRenderer renderer = DrawPictureShape.getImageRenderer(graphics, fill.getContentType());\r
\r
try {\r
renderer.loadImage(is, fill.getContentType());\r
import java.io.IOException;\r
\r
import org.apache.poi.sl.usermodel.PictureData;\r
+import org.apache.poi.sl.usermodel.PictureData.PictureType;\r
+import org.apache.poi.util.POILogFactory;\r
+import org.apache.poi.util.POILogger;\r
import org.apache.poi.sl.usermodel.PictureShape;\r
import org.apache.poi.sl.usermodel.RectAlign;\r
\r
\r
public class DrawPictureShape extends DrawSimpleShape {\r
+ private static final POILogger LOG = POILogFactory.getLogger(DrawPictureShape.class);\r
+ private static final String WMF_IMAGE_RENDERER = "org.apache.poi.hwmf.draw.HwmfSLImageRenderer";\r
+ \r
public DrawPictureShape(PictureShape<?,?> shape) {\r
super(shape);\r
}\r
PictureData data = getShape().getPictureData();\r
if(data == null) return;\r
\r
- ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER);\r
- if (renderer == null) renderer = new ImageRenderer();\r
- \r
Rectangle2D anchor = getAnchor(graphics, getShape());\r
-\r
Insets insets = getShape().getClipping();\r
\r
try {\r
+ ImageRenderer renderer = getImageRenderer(graphics, data.getContentType());\r
renderer.loadImage(data.getData(), data.getContentType());\r
renderer.drawImage(graphics, anchor, insets);\r
} catch (IOException e) {\r
}\r
} \r
\r
+ /**\r
+ * Returns an ImageRenderer for the PictureData\r
+ *\r
+ * @param graphics\r
+ * @return\r
+ */\r
+ public static ImageRenderer getImageRenderer(Graphics2D graphics, String contentType) {\r
+ ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER);\r
+ if (renderer != null) {\r
+ return renderer;\r
+ }\r
+ \r
+ if (PictureType.WMF.contentType.equals(contentType)) {\r
+ try {\r
+ @SuppressWarnings("unchecked")\r
+ Class<? extends ImageRenderer> irc = (Class<? extends ImageRenderer>)\r
+ Thread.currentThread().getContextClassLoader().loadClass(WMF_IMAGE_RENDERER);\r
+ return irc.newInstance();\r
+ } catch (Exception e) {\r
+ // WMF image renderer is not on the classpath, continuing with BitmapRenderer\r
+ // although this doesn't make much sense ...\r
+ LOG.log(POILogger.ERROR, "WMF image renderer is not on the classpath - include poi-scratchpad jar!", e);\r
+ }\r
+ }\r
+ \r
+ return new BitmapImageRenderer();\r
+ }\r
+ \r
@Override\r
protected PictureShape<?,?> getShape() {\r
return (PictureShape<?,?>)shape;\r
// then stroke the shape outline\r
if(line != null) {\r
graphics.setPaint(line);\r
+ graphics.setStroke(stroke);\r
for(Outline o : elems){\r
if(o.getPath().isStroked()){\r
java.awt.Shape s = o.getOutline();\r
import org.apache.poi.util.POILogger;\r
\r
/**\r
- * For now this class renders only images supported by the javax.imageio.ImageIO\r
- * framework. Subclasses can override this class to support other formats, for\r
+ * Classes can implement this interfaces to support other formats, for\r
* example, use Apache Batik to render WMF, PICT can be rendered using Apple QuickTime API for Java:\r
*\r
* <pre>\r
* <code>\r
- * public class MyImageRendener extends ImageRendener {\r
+ * public class MyImageRendener implements ImageRendener {\r
* InputStream data;\r
*\r
* public boolean drawImage(Graphics2D graphics,Rectangle2D anchor,Insets clip) {\r
* </code>\r
* </pre>\r
*/\r
-public class ImageRenderer {\r
- private final static POILogger LOG = POILogFactory.getLogger(ImageRenderer.class);\r
- \r
- protected BufferedImage img;\r
-\r
+public interface ImageRenderer {\r
/**\r
* Load and buffer the image\r
*\r
* @param data the raw image stream\r
* @param contentType the content type\r
*/\r
- public void loadImage(InputStream data, String contentType) throws IOException {\r
- img = convertBufferedImage(ImageIO.read(data), contentType);\r
- }\r
+ void loadImage(InputStream data, String contentType) throws IOException;\r
\r
/**\r
* Load and buffer the image\r
*\r
- * @param data the raw image stream\r
+ * @param data the raw image bytes\r
* @param contentType the content type\r
*/\r
- public void loadImage(byte data[], String contentType) throws IOException {\r
- img = convertBufferedImage(ImageIO.read(new ByteArrayInputStream(data)), contentType);\r
- }\r
-\r
- /**\r
- * Add alpha channel to buffered image \r
- */\r
- private static BufferedImage convertBufferedImage(BufferedImage img, String contentType) {\r
- if (img == null) {\r
- LOG.log(POILogger.WARN, "Content-type: "+contentType+" is not support. Image ignored.");\r
- return null;\r
- }\r
- \r
- BufferedImage bi = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);\r
- Graphics g = bi.getGraphics();\r
- g.drawImage(img, 0, 0, null);\r
- g.dispose();\r
- return bi;\r
- }\r
- \r
- \r
- /**\r
- * @return the buffered image\r
- */\r
- public BufferedImage getImage() {\r
- return img;\r
- }\r
+ void loadImage(byte data[], String contentType) throws IOException;\r
\r
/**\r
* @return the dimension of the buffered image\r
*/\r
- public Dimension getDimension() {\r
- return (img == null)\r
- ? new Dimension(0,0)\r
- : new Dimension(img.getWidth(),img.getHeight());\r
- }\r
+ Dimension getDimension();\r
\r
/**\r
* @param alpha the alpha [0..1] to be added to the image (possibly already containing an alpha channel)\r
*/\r
- public void setAlpha(double alpha) {\r
- if (img == null) return;\r
-\r
- Dimension dim = getDimension();\r
- BufferedImage newImg = new BufferedImage((int)dim.getWidth(), (int)dim.getHeight(), BufferedImage.TYPE_INT_ARGB);\r
- Graphics2D g = newImg.createGraphics();\r
- RescaleOp op = new RescaleOp(new float[]{1.0f, 1.0f, 1.0f, (float)alpha}, new float[]{0,0,0,0}, null);\r
- g.drawImage(img, op, 0, 0);\r
- g.dispose();\r
- \r
- img = newImg;\r
- }\r
-\r
+ void setAlpha(double alpha);\r
\r
+ /**\r
+ * @return the image as buffered image\r
+ */\r
+ BufferedImage getImage();\r
+ \r
/**\r
* Render picture data into the supplied graphics\r
*\r
* @return true if the picture data was successfully rendered\r
*/\r
- public boolean drawImage(\r
- Graphics2D graphics,\r
- Rectangle2D anchor) {\r
- return drawImage(graphics, anchor, null);\r
- }\r
+ boolean drawImage(Graphics2D graphics, Rectangle2D anchor);\r
\r
/**\r
* Render picture data into the supplied graphics\r
*\r
* @return true if the picture data was successfully rendered\r
*/\r
- public boolean drawImage(\r
- Graphics2D graphics,\r
- Rectangle2D anchor,\r
- Insets clip) {\r
- if (img == null) return false;\r
-\r
- boolean isClipped = true;\r
- if (clip == null) {\r
- isClipped = false;\r
- clip = new Insets(0,0,0,0);\r
- }\r
-\r
- int iw = img.getWidth();\r
- int ih = img.getHeight();\r
-\r
- \r
- double cw = (100000-clip.left-clip.right) / 100000.0;\r
- double ch = (100000-clip.top-clip.bottom) / 100000.0;\r
- double sx = anchor.getWidth()/(iw*cw);\r
- double sy = anchor.getHeight()/(ih*ch);\r
- double tx = anchor.getX()-(iw*sx*clip.left/100000.0);\r
- double ty = anchor.getY()-(ih*sy*clip.top/100000.0);\r
-\r
- AffineTransform at = new AffineTransform(sx, 0, 0, sy, tx, ty) ;\r
-\r
- Shape clipOld = graphics.getClip();\r
- if (isClipped) graphics.clip(anchor.getBounds2D());\r
- graphics.drawRenderedImage(img, at);\r
- graphics.setClip(clipOld);\r
-\r
- return true;\r
- }\r
-}\r
+ boolean drawImage(Graphics2D graphics, Rectangle2D anchor, Insets clip);\r
+}
\ No newline at end of file
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.sl.usermodel;\r
+\r
+public interface GraphicalFrame<\r
+ S extends Shape<S,P>,\r
+ P extends TextParagraph<S,P,?>\r
+> extends Shape<S,P>, PlaceableShape<S,P> {\r
+\r
+ /**\r
+ * @return a fallback representation as picture shape\r
+ */\r
+ PictureShape<S,P> getFallbackPicture();\r
+}\r
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
import org.apache.poi.openxml4j.opc.PackagePart;\r
import org.apache.poi.openxml4j.opc.PackageRelationship;\r
-import org.apache.poi.sl.draw.DrawNotImplemented;\r
-import org.apache.poi.sl.usermodel.PlaceableShape;\r
+import org.apache.poi.sl.usermodel.GraphicalFrame;\r
import org.apache.poi.sl.usermodel.ShapeType;\r
import org.apache.poi.util.Beta;\r
+import org.apache.poi.util.POILogFactory;\r
+import org.apache.poi.util.POILogger;\r
import org.apache.poi.util.Units;\r
import org.apache.xmlbeans.XmlCursor;\r
+import org.apache.xmlbeans.XmlException;\r
import org.apache.xmlbeans.XmlObject;\r
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData;\r
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;\r
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;\r
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;\r
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;\r
+import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;\r
\r
-/**\r
- * @author Yegor Kozlov\r
- */\r
@Beta\r
-@DrawNotImplemented\r
-public class XSLFGraphicFrame extends XSLFShape implements PlaceableShape<XSLFShape, XSLFTextParagraph> {\r
+public class XSLFGraphicFrame extends XSLFShape implements GraphicalFrame<XSLFShape, XSLFTextParagraph> {\r
+ private static final POILogger LOG = POILogFactory.getLogger(XSLFGraphicFrame.class);\r
+\r
/*package*/ XSLFGraphicFrame(CTGraphicalObjectFrame shape, XSLFSheet sheet){\r
super(shape,sheet);\r
}\r
public void setRotation(double theta){\r
throw new IllegalArgumentException("Operation not supported");\r
}\r
- \r
+\r
/**\r
* Rotation angle in degrees\r
* <p>\r
public void setFlipVertical(boolean flip){\r
throw new IllegalArgumentException("Operation not supported");\r
}\r
- \r
+\r
/**\r
* Whether the shape is horizontally flipped\r
*\r
}\r
}\r
\r
+ @Override\r
+ public XSLFPictureShape getFallbackPicture() {\r
+ String xquery =\r
+ "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main'; "\r
+ + "declare namespace mc='http://schemas.openxmlformats.org/markup-compatibility/2006' "\r
+ + ".//mc:Fallback/*/p:pic"\r
+ ;\r
+ XmlObject xo = selectProperty(XmlObject.class, xquery);\r
+ if (xo == null) {\r
+ return null;\r
+ }\r
+\r
+ CTGroupShape gs;\r
+ try {\r
+ gs = CTGroupShape.Factory.parse(xo.newDomNode());\r
+ } catch (XmlException e) {\r
+ LOG.log(POILogger.WARN, "Can't parse fallback picture stream of graphical frame", e);\r
+ return null;\r
+ }\r
+\r
+ if (gs.sizeOfPicArray() == 0) {\r
+ return null;\r
+ }\r
+\r
+ return new XSLFPictureShape(gs.getPicArray(0), getSheet());\r
+ }\r
}
\ No newline at end of file
\r
public Placeholder getPlaceholder() {\r
CTPlaceholder ph = getCTPlaceholder();\r
- if (ph == null || !ph.isSetType()) {\r
+ if (ph == null || !(ph.isSetType() || ph.isSetIdx())) {\r
return null;\r
}\r
return Placeholder.lookupOoxml(ph.getType().intValue());\r
POIDataSamples samples = POIDataSamples.getSlideShowInstance();\r
\r
String[] testFiles = {"alterman_security.ppt","alterman_security.pptx","KEY02.pptx","themes.pptx","backgrounds.pptx","layouts.pptx", "sample.pptx", "shapes.pptx",};\r
+// String[] testFiles = {"41246-2.ppt","45543.ppt","53446.ppt","ParagraphStylesShorterThanCharStyles.ppt"};\r
String[] args = {\r
"-format", "null", // png,gif,jpg or null for test\r
"-slide", "-1", // -1 for all\r
opt.setRecordId(EscherOptRecord.RECORD_ID);
_escherContainer.addChildRecord(opt);
- EscherRecord anchor;
+ EscherRecord anchor;
if(isChild) {
anchor = new EscherChildAnchorRecord();
} else {
}
/**
- * @return color of the line. If color is not set returns <code>java.awt.Color.black</code>
+ * @return color of the line. If color is not set returns {@code null}
*/
public Color getLineColor(){
AbstractEscherOptRecord opt = getEscherOptRecord();
if(p != null && (p.getPropertyValue() & 0x8) == 0) return null;
Color clr = getColor(EscherProperties.LINESTYLE__COLOR, EscherProperties.LINESTYLE__OPACITY, -1);
- return clr == null ? Color.black : clr;
+ return clr == null ? null : clr;
}
/**
AbstractEscherOptRecord opt = getEscherOptRecord();
setEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDCAPSTYLE, pen == LineCap.FLAT ? -1 : pen.nativeId);
}
-
+
/**
* Gets line dashing.
*
};
}
-
+
public DecorationShape getLineHeadDecoration(){
AbstractEscherOptRecord opt = getEscherOptRecord();
EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINESTARTARROWHEAD);
AbstractEscherOptRecord opt = getEscherOptRecord();
setEscherProperty(opt, EscherProperties.LINESTYLE__LINESTARTARROWHEAD, decoShape == null ? -1 : decoShape.nativeId);
}
-
+
public DecorationSize getLineHeadWidth(){
AbstractEscherOptRecord opt = getEscherOptRecord();
EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINESTARTARROWWIDTH);
AbstractEscherOptRecord opt = getEscherOptRecord();
setEscherProperty(opt, EscherProperties.LINESTYLE__LINESTARTARROWWIDTH, decoSize == null ? -1 : decoSize.nativeId);
}
-
+
public DecorationSize getLineHeadLength(){
AbstractEscherOptRecord opt = getEscherOptRecord();
EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINESTARTARROWLENGTH);
AbstractEscherOptRecord opt = getEscherOptRecord();
setEscherProperty(opt, EscherProperties.LINESTYLE__LINESTARTARROWLENGTH, decoSize == null ? -1 : decoSize.nativeId);
}
-
+
public DecorationShape getLineTailDecoration(){
AbstractEscherOptRecord opt = getEscherOptRecord();
EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDARROWHEAD);
AbstractEscherOptRecord opt = getEscherOptRecord();
setEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDARROWHEAD, decoShape == null ? -1 : decoShape.nativeId);
}
-
+
public DecorationSize getLineTailWidth(){
AbstractEscherOptRecord opt = getEscherOptRecord();
EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDARROWWIDTH);
AbstractEscherOptRecord opt = getEscherOptRecord();
setEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDARROWWIDTH, decoSize == null ? -1 : decoSize.nativeId);
}
-
+
public DecorationSize getLineTailLength(){
AbstractEscherOptRecord opt = getEscherOptRecord();
EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDARROWLENGTH);
setEscherProperty(opt, EscherProperties.LINESTYLE__LINEENDARROWLENGTH, decoSize == null ? -1 : decoSize.nativeId);
}
-
-
+
+
public LineDecoration getLineDecoration() {
return new LineDecoration() {
}
};
}
-
+
@Override
public Placeholder getPlaceholder() {
List<? extends Record> clRecords = getClientRecords();
return Placeholder.lookupNative(rtp.getPlaceholderId());
}
}
-
+
return null;
}
-
+
@Override
public void setPlaceholder(Placeholder placeholder) {
EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
// Placeholders can't be grouped
setEscherProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, (placeholder == null ? -1 : 262144));
-
+
HSLFEscherClientDataRecord clientData = getClientData(false);
if (placeholder == null) {
if (clientData != null) {
}
return;
}
-
+
if (clientData == null) {
clientData = getClientData(true);
}
} else {
phId = (byte)placeholder.nativeSlideId;
}
-
+
if (phId == -2) {
throw new HSLFException("Placeholder "+placeholder.name()+" not supported for this sheet type ("+sheet.getClass()+")");
}
-
+
switch (placeholder) {
case HEADER:
case FOOTER:
setLineColor(null);
return;
}
-
+
// TODO: handle PaintStyle
for (Object st : styles) {
if (st instanceof Number) {
* This methods gathers and sets the corresponding graphics transformations.\r
*/\r
public void updateWindowMapMode() {\r
- GraphicsConfiguration gc = graphicsCtx.getDeviceConfiguration();\r
Rectangle2D win = prop.getWindow();\r
HwmfMapMode mapMode = prop.getMapMode();\r
graphicsCtx.setTransform(initialAT);\r
case MM_HIMETRIC:\r
case MM_LOENGLISH:\r
case MM_HIENGLISH:\r
- case MM_TWIPS:\r
+ case MM_TWIPS: {\r
// TODO: to be validated ...\r
+ GraphicsConfiguration gc = graphicsCtx.getDeviceConfiguration();\r
graphicsCtx.transform(gc.getNormalizingTransform());\r
graphicsCtx.scale(1./mapMode.scale, -1./mapMode.scale);\r
graphicsCtx.translate(-win.getX(), -win.getY());\r
break;\r
+ }\r
case MM_TEXT:\r
// TODO: to be validated ...\r
break;\r
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.hwmf.draw;\r
+\r
+import java.awt.Dimension;\r
+import java.awt.Graphics2D;\r
+import java.awt.Insets;\r
+import java.awt.RenderingHints;\r
+import java.awt.geom.Rectangle2D;\r
+import java.awt.image.BufferedImage;\r
+import java.awt.image.RescaleOp;\r
+import java.io.ByteArrayInputStream;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+\r
+import org.apache.poi.hwmf.usermodel.HwmfPicture;\r
+import org.apache.poi.sl.draw.ImageRenderer;\r
+import org.apache.poi.sl.usermodel.PictureData;\r
+import org.apache.poi.util.Units;\r
+\r
+public class HwmfSLImageRenderer implements ImageRenderer {\r
+ HwmfPicture image = null;\r
+ double alpha = 0;\r
+ \r
+ @Override\r
+ public void loadImage(InputStream data, String contentType) throws IOException {\r
+ if (!PictureData.PictureType.WMF.contentType.equals(contentType)) {\r
+ throw new IOException("Invalid picture type");\r
+ }\r
+ image = new HwmfPicture(data);\r
+ }\r
+\r
+ @Override\r
+ public void loadImage(byte[] data, String contentType) throws IOException {\r
+ if (!PictureData.PictureType.WMF.contentType.equals(contentType)) {\r
+ throw new IOException("Invalid picture type");\r
+ }\r
+ image = new HwmfPicture(new ByteArrayInputStream(data));\r
+ }\r
+\r
+ @Override\r
+ public Dimension getDimension() {\r
+ int width = 0, height = 0;\r
+ if (image != null) {\r
+ Dimension dim = image.getSize();\r
+ width = Units.pointsToPixel(dim.getWidth());\r
+ // keep aspect ratio for height\r
+ height = Units.pointsToPixel(dim.getHeight());\r
+ }\r
+ return new Dimension(width, height);\r
+ }\r
+\r
+ @Override\r
+ public void setAlpha(double alpha) {\r
+ this.alpha = alpha;\r
+ }\r
+\r
+ @Override\r
+ public BufferedImage getImage() {\r
+ if (image == null) {\r
+ return new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); \r
+ }\r
+ \r
+ Dimension dim = getDimension();\r
+ BufferedImage bufImg = new BufferedImage((int)dim.getWidth(), (int)dim.getHeight(), BufferedImage.TYPE_INT_ARGB);\r
+ Graphics2D g = bufImg.createGraphics();\r
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\r
+ g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);\r
+ g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);\r
+ g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);\r
+ image.draw(g);\r
+ g.dispose();\r
+ \r
+ if (alpha != 0) {\r
+ BufferedImage newImg = new BufferedImage((int)dim.getWidth(), (int)dim.getHeight(), BufferedImage.TYPE_INT_ARGB);\r
+ g = newImg.createGraphics();\r
+ RescaleOp op = new RescaleOp(new float[]{1.0f, 1.0f, 1.0f, (float)alpha}, new float[]{0,0,0,0}, null);\r
+ g.drawImage(bufImg, op, 0, 0);\r
+ g.dispose();\r
+ bufImg = newImg;\r
+ }\r
+ \r
+ return bufImg;\r
+ }\r
+\r
+ @Override\r
+ public boolean drawImage(Graphics2D graphics, Rectangle2D anchor) {\r
+ return drawImage(graphics, anchor, null);\r
+ }\r
+\r
+ @Override\r
+ public boolean drawImage(Graphics2D graphics, Rectangle2D anchor, Insets clip) {\r
+ if (image == null) {\r
+ return false;\r
+ } else {\r
+ image.draw(graphics, anchor);\r
+ return true;\r
+ }\r
+ }\r
+}\r
* The META_DIBCREATEPATTERNBRUSH record creates a Brush Object with a\r
* pattern specified by a DeviceIndependentBitmap (DIB) Object\r
*/\r
- public static class WmfDibCreatePatternBrush implements HwmfRecord, HwmfImageRecord {\r
+ public static class WmfDibCreatePatternBrush implements HwmfRecord, HwmfImageRecord, HwmfObjectTableEntry {\r
\r
private HwmfBrushStyle style;\r
\r
\r
@Override\r
public void draw(HwmfGraphics ctx) {\r
+ ctx.addObjectTableEntry(this);\r
+ }\r
+ \r
+ @Override\r
+ public void applyObject(HwmfGraphics ctx) {\r
HwmfDrawProperties prop = ctx.getProperties();\r
prop.setBrushStyle(style);\r
prop.setBrushBitmap(getImage());\r
try {\r
Rectangle2D wmfBounds = getBounds();\r
// scale output bounds to image bounds\r
+ ctx.translate(graphicsBounds.getX(), graphicsBounds.getY());\r
ctx.scale(graphicsBounds.getWidth()/wmfBounds.getWidth(), graphicsBounds.getHeight()/wmfBounds.getHeight());\r
- ctx.translate(-wmfBounds.getX(), -wmfBounds.getY());\r
\r
HwmfGraphics g = new HwmfGraphics(ctx, wmfBounds);\r
- for (HwmfRecord r : records) {\r
+ for (HwmfRecord r : records) {\r
r.draw(g);\r
}\r
} finally {\r