Slide slide = ppt.createSlide();
- ShapeGroup group = new ShapeGroup();
+ HSLFGroupShape group = new HSLFGroupShape();
//define position of the drawing in the slide
Rectangle bounds = new java.awt.Rectangle(200, 100, 350, 300);
group.setAnchor(bounds);
//extract embedded OLE documents
Slide[] slide = ppt.getSlides();
for (int i = 0; i < slide.length; i++) {
- Shape[] shape = slide[i].getShapes();
+ HSLFShape[] shape = slide[i].getShapes();
for (int j = 0; j < shape.length; j++) {
if (shape[j] instanceof OLEShape) {
OLEShape ole = (OLEShape) shape[j];
//Pictures
for (int i = 0; i < slide.length; i++) {
- Shape[] shape = slide[i].getShapes();
+ HSLFShape[] shape = slide[i].getShapes();
for (int j = 0; j < shape.length; j++) {
if (shape[j] instanceof Picture) {
Picture p = (Picture) shape[j];
Slide slide = ppt.createSlide();
- ShapeGroup group = new ShapeGroup();
+ HSLFGroupShape group = new HSLFGroupShape();
//define position of the drawing in the slide
Rectangle bounds = new java.awt.Rectangle(200, 100, 350, 300);
group.setAnchor(bounds);
import org.apache.poi.hslf.model.Slide;
import org.apache.poi.hslf.model.TextRun;
import org.apache.poi.hslf.model.Hyperlink;
-import org.apache.poi.hslf.model.Shape;
+import org.apache.poi.hslf.model.HSLFShape;
import java.io.FileInputStream;
//for example to a Line object. The code below demonstrates how to
//read such hyperlinks
System.out.println(" reading hyperlinks from the slide's shapes");
- Shape[] sh = slide[j].getShapes();
+ HSLFShape[] sh = slide[j].getShapes();
for (int k = 0; k < sh.length; k++) {
Hyperlink link = sh[k].getHyperlink();
if(link != null) {
Slide[] slide = ppt.getSlides();
for (int i = 0; i < slide.length; i++) {
- Shape[] shape = slide[i].getShapes();
+ HSLFShape[] shape = slide[i].getShapes();
for (int j = 0; j < shape.length; j++) {
int soundRef = getSoundReference(shape[j]);
if(soundRef != -1) {
* @return 0-based reference to a sound in the sound collection
* or -1 if the shape is not associated with a sound
*/
- protected static int getSoundReference(Shape shape){
+ protected static int getSoundReference(HSLFShape shape){
int soundRef = -1;
//dive into the shape container and search for InteractiveInfoAtom
EscherContainerRecord spContainer = shape.getSpContainer();
\r
package org.apache.poi.xslf.model;\r
\r
-import org.apache.poi.xslf.usermodel.XSLFSimpleShape;\r
+import org.apache.poi.xslf.usermodel.XSLFShape;\r
import org.apache.xmlbeans.XmlObject;\r
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;\r
\r
_level = level;\r
}\r
\r
- public boolean fetch(XSLFSimpleShape shape) {\r
+ public boolean fetch(XSLFShape shape) {\r
\r
XmlObject[] o = shape.getXmlObject().selectPath(\r
"declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " +\r
* @param shape the shape being examined\r
* @return true if the desired property was fetched\r
*/\r
- public abstract boolean fetch(XSLFShape shape) ;\r
+ public abstract boolean fetch(XSLFShape shape);\r
\r
public T getValue(){\r
return _value;\r
\r
package org.apache.poi.xslf.model;\r
\r
-import org.apache.poi.xslf.usermodel.XSLFSimpleShape;\r
+import org.apache.poi.xslf.usermodel.XSLFShape;\r
import org.apache.xmlbeans.XmlObject;\r
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties;\r
\r
*/\r
public abstract class TextBodyPropertyFetcher<T> extends PropertyFetcher<T> {\r
\r
- public boolean fetch(XSLFSimpleShape shape) {\r
+ public boolean fetch(XSLFShape shape) {\r
\r
XmlObject[] o = shape.getXmlObject().selectPath(\r
"declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " +\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
-package org.apache.poi.xslf.usermodel;\r
-\r
-/**\r
- * Represents the shape decoration that appears at the ends of lines.\r
- */\r
-public enum LineDecoration {\r
- NONE,\r
- TRIANGLE,\r
- STEALTH,\r
- DIAMOND,\r
- OVAL,\r
- ARROW\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
-package org.apache.poi.xslf.usermodel;\r
-\r
-/**\r
- * @author Yegor Kozlov\r
- */\r
-public enum LineEndLength {\r
- SMALL,\r
- MEDIUM,\r
- LARGE\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
-package org.apache.poi.xslf.usermodel;\r
-\r
-/**\r
- * @author Yegor Kozlov\r
- */\r
-public enum LineEndWidth {\r
- SMALL,\r
- MEDIUM,\r
- LARGE\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- * ====================================================================\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
-\r
-package org.apache.poi.xslf.usermodel;\r
-\r
-import java.awt.AlphaComposite;\r
-import java.awt.BasicStroke;\r
-import java.awt.Color;\r
-import java.awt.GradientPaint;\r
-import java.awt.Graphics2D;\r
-import java.awt.Paint;\r
-import java.awt.Shape;\r
-import java.awt.Stroke;\r
-import java.awt.TexturePaint;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.Point2D;\r
-import java.awt.geom.Rectangle2D;\r
-import java.awt.image.BufferedImage;\r
-import java.lang.reflect.Constructor;\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.Collection;\r
-import java.util.Comparator;\r
-\r
-import org.apache.poi.openxml4j.opc.PackagePart;\r
-import org.apache.poi.openxml4j.opc.PackageRelationship;\r
-import org.apache.poi.sl.usermodel.LineCap;\r
-import org.apache.poi.sl.usermodel.LineDash;\r
-import org.apache.poi.util.Internal;\r
-import org.apache.poi.util.Units;\r
-import org.apache.poi.xslf.model.PropertyFetcher;\r
-import org.apache.poi.xslf.model.geom.Context;\r
-import org.apache.poi.xslf.model.geom.CustomGeometry;\r
-import org.apache.poi.xslf.model.geom.Guide;\r
-import org.apache.poi.xslf.model.geom.IAdjustableShape;\r
-import org.apache.poi.xslf.model.geom.Outline;\r
-import org.apache.poi.xslf.model.geom.Path;\r
-import org.apache.xmlbeans.XmlObject;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuide;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientFillProperties;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientStop;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTNoFillProperties;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTPathShadeProperties;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.STPathShadeType;\r
-\r
-/**\r
- * Encapsulates logic to translate DrawingML objects to Java2D\r
- */\r
-@Internal\r
-class RenderableShape {\r
- public final static Color NO_PAINT = new Color(0xFF, 0xFF, 0xFF, 0);\r
-\r
- private XSLFSimpleShape _shape;\r
-\r
- public RenderableShape(XSLFSimpleShape shape){\r
- _shape = shape;\r
- }\r
-\r
- /**\r
- * Convert shape fill into java.awt.Paint. The result is either Color or\r
- * TexturePaint or GradientPaint or null\r
- *\r
- * @param graphics the target graphics\r
- * @param obj the xml to read. Must contain elements from the EG_ColorChoice group:\r
- * <code>\r
- * a:scrgbClr RGB Color Model - Percentage Variant\r
- * a:srgbClr RGB Color Model - Hex Variant\r
- * a:hslClr Hue, Saturation, Luminance Color Model\r
- * a:sysClr System Color\r
- * a:schemeClr Scheme Color\r
- * a:prstClr Preset Color\r
- * </code>\r
- *\r
- * @param phClr context color\r
- * @param parentPart the parent package part. Any external references (images, etc.) are resolved relative to it.\r
- *\r
- * @return the applied Paint or null if none was applied\r
- */\r
- public Paint selectPaint(Graphics2D graphics, XmlObject obj, CTSchemeColor phClr, PackagePart parentPart) {\r
- XSLFTheme theme = _shape.getSheet().getTheme();\r
-\r
- Paint paint = null;\r
- if (obj instanceof CTNoFillProperties) {\r
- paint = NO_PAINT;\r
-\r
- }\r
- else if (obj instanceof CTSolidColorFillProperties) {\r
- CTSolidColorFillProperties solidFill = (CTSolidColorFillProperties) obj;\r
- XSLFColor c = new XSLFColor(solidFill, theme, phClr);\r
- paint = c.getColor();\r
- }\r
- else if (obj instanceof CTBlipFillProperties) {\r
- CTBlipFillProperties blipFill = (CTBlipFillProperties)obj;\r
- paint = createTexturePaint(blipFill, graphics, parentPart);\r
- }\r
- else if (obj instanceof CTGradientFillProperties) {\r
- Rectangle2D anchor = getAnchor(graphics);\r
- CTGradientFillProperties gradFill = (CTGradientFillProperties) obj;\r
- if (gradFill.isSetLin()) {\r
- paint = createLinearGradientPaint(graphics, gradFill, anchor, theme, phClr);\r
- } else if (gradFill.isSetPath()){\r
- CTPathShadeProperties ps = gradFill.getPath();\r
- if(ps.getPath() == STPathShadeType.CIRCLE){\r
- paint = createRadialGradientPaint(gradFill, anchor, theme, phClr);\r
- } else if (ps.getPath() == STPathShadeType.SHAPE){\r
- paint = toRadialGradientPaint(gradFill, anchor, theme, phClr);\r
- }\r
- }\r
- }\r
-\r
- return paint;\r
- }\r
-\r
- private Paint createTexturePaint(CTBlipFillProperties blipFill, Graphics2D graphics,\r
- PackagePart parentPart){\r
- Paint paint = null;\r
- CTBlip blip = blipFill.getBlip();\r
- String blipId = blip.getEmbed();\r
- PackageRelationship rel = parentPart.getRelationship(blipId);\r
- if (rel != null) {\r
- XSLFImageRenderer renderer = null;\r
- if (graphics != null)\r
- renderer = (XSLFImageRenderer) graphics.getRenderingHint(XSLFRenderingHint.IMAGE_RENDERER);\r
- if (renderer == null) renderer = new XSLFImageRenderer();\r
-\r
- try {\r
- BufferedImage img = renderer.readImage(parentPart.getRelatedPart(rel));\r
- if (blip.sizeOfAlphaModFixArray() > 0) {\r
- float alpha = blip.getAlphaModFixArray(0).getAmt() / 100000.f;\r
- AlphaComposite ac = AlphaComposite.getInstance(\r
- AlphaComposite.SRC_OVER, alpha);\r
- if (graphics != null) graphics.setComposite(ac);\r
- }\r
-\r
- if(img != null) {\r
- paint = new TexturePaint(\r
- img, new Rectangle2D.Double(0, 0, img.getWidth(), img.getHeight()));\r
- }\r
- }\r
- catch (Exception e) {\r
- e.printStackTrace();\r
- }\r
- }\r
- return paint;\r
- }\r
-\r
- private Paint createLinearGradientPaint(\r
- Graphics2D graphics,\r
- CTGradientFillProperties gradFill, Rectangle2D anchor,\r
- XSLFTheme theme, CTSchemeColor phClr) {\r
- double angle = gradFill.getLin().getAng() / 60000;\r
- @SuppressWarnings("deprecation")\r
- CTGradientStop[] gs = gradFill.getGsLst().getGsArray();\r
-\r
- Arrays.sort(gs, new Comparator<CTGradientStop>() {\r
- public int compare(CTGradientStop o1, CTGradientStop o2) {\r
- Integer pos1 = o1.getPos();\r
- Integer pos2 = o2.getPos();\r
- return pos1.compareTo(pos2);\r
- }\r
- });\r
-\r
- Color[] colors = new Color[gs.length];\r
- float[] fractions = new float[gs.length];\r
-\r
- AffineTransform at = AffineTransform.getRotateInstance(\r
- Math.toRadians(angle),\r
- anchor.getX() + anchor.getWidth() / 2,\r
- anchor.getY() + anchor.getHeight() / 2);\r
-\r
- double diagonal = Math.sqrt(anchor.getHeight() * anchor.getHeight() + anchor.getWidth() * anchor.getWidth());\r
- Point2D p1 = new Point2D.Double(anchor.getX() + anchor.getWidth() / 2 - diagonal / 2,\r
- anchor.getY() + anchor.getHeight() / 2);\r
- p1 = at.transform(p1, null);\r
-\r
- Point2D p2 = new Point2D.Double(anchor.getX() + anchor.getWidth(), anchor.getY() + anchor.getHeight() / 2);\r
- p2 = at.transform(p2, null);\r
-\r
- snapToAnchor(p1, anchor);\r
- snapToAnchor(p2, anchor);\r
-\r
- for (int i = 0; i < gs.length; i++) {\r
- CTGradientStop stop = gs[i];\r
- colors[i] = new XSLFColor(stop, theme, phClr).getColor();\r
- fractions[i] = stop.getPos() / 100000.f;\r
- }\r
-\r
- AffineTransform grAt = new AffineTransform();\r
- if(gradFill.isSetRotWithShape() || !gradFill.getRotWithShape()) {\r
- double rotation = _shape.getRotation();\r
- if (rotation != 0.) {\r
- double centerX = anchor.getX() + anchor.getWidth() / 2;\r
- double centerY = anchor.getY() + anchor.getHeight() / 2;\r
-\r
- grAt.translate(centerX, centerY);\r
- grAt.rotate(Math.toRadians(-rotation));\r
- grAt.translate(-centerX, -centerY);\r
- }\r
- }\r
-\r
- // Trick to return GradientPaint on JDK 1.5 and LinearGradientPaint on JDK 1.6+\r
- Paint paint;\r
- try {\r
- Class clz = Class.forName("java.awt.LinearGradientPaint");\r
- Class clzCycleMethod = Class.forName("java.awt.MultipleGradientPaint$CycleMethod");\r
- Class clzColorSpaceType = Class.forName("java.awt.MultipleGradientPaint$ColorSpaceType");\r
- Constructor c =\r
- clz.getConstructor(Point2D.class, Point2D.class, float[].class, Color[].class,\r
- clzCycleMethod, clzColorSpaceType, AffineTransform.class);\r
- paint = (Paint) c.newInstance(p1, p2, fractions, colors,\r
- Enum.valueOf(clzCycleMethod, "NO_CYCLE"),\r
- Enum.valueOf(clzColorSpaceType, "SRGB"), grAt);\r
- } catch (ClassNotFoundException e) {\r
- paint = new GradientPaint(p1, colors[0], p2, colors[colors.length - 1]);\r
- } catch (Exception e) {\r
- throw new RuntimeException(e);\r
- }\r
- return paint;\r
- }\r
-\r
- /**\r
- * gradients with type=shape are enot supported by Java graphics.\r
- * We approximate it with a radial gradient.\r
- */\r
- private static Paint toRadialGradientPaint(\r
- CTGradientFillProperties gradFill, Rectangle2D anchor,\r
- XSLFTheme theme, CTSchemeColor phClr) {\r
-\r
- @SuppressWarnings("deprecation")\r
- CTGradientStop[] gs = gradFill.getGsLst().getGsArray();\r
- Arrays.sort(gs, new Comparator<CTGradientStop>() {\r
- public int compare(CTGradientStop o1, CTGradientStop o2) {\r
- Integer pos1 = o1.getPos();\r
- Integer pos2 = o2.getPos();\r
- return pos1.compareTo(pos2);\r
- }\r
- });\r
- gs[1].setPos(50000);\r
-\r
- CTGradientFillProperties g = CTGradientFillProperties.Factory.newInstance();\r
- g.set(gradFill);\r
- g.getGsLst().setGsArray(new CTGradientStop[]{gs[0], gs[1]});\r
- return createRadialGradientPaint(g, anchor, theme, phClr);\r
- }\r
-\r
- private static Paint createRadialGradientPaint(\r
- CTGradientFillProperties gradFill, Rectangle2D anchor,\r
- XSLFTheme theme, CTSchemeColor phClr) {\r
- @SuppressWarnings("deprecation")\r
- CTGradientStop[] gs = gradFill.getGsLst().getGsArray();\r
-\r
- Point2D pCenter = new Point2D.Double(anchor.getX() + anchor.getWidth()/2,\r
- anchor.getY() + anchor.getHeight()/2);\r
-\r
- float radius = (float)Math.max(anchor.getWidth(), anchor.getHeight());\r
-\r
- Arrays.sort(gs, new Comparator<CTGradientStop>() {\r
- public int compare(CTGradientStop o1, CTGradientStop o2) {\r
- Integer pos1 = o1.getPos();\r
- Integer pos2 = o2.getPos();\r
- return pos1.compareTo(pos2);\r
- }\r
- });\r
-\r
- Color[] colors = new Color[gs.length];\r
- float[] fractions = new float[gs.length];\r
-\r
-\r
- for (int i = 0; i < gs.length; i++) {\r
- CTGradientStop stop = gs[i];\r
- colors[i] = new XSLFColor(stop, theme, phClr).getColor();\r
- fractions[i] = stop.getPos() / 100000.f;\r
- }\r
-\r
- // Trick to return GradientPaint on JDK 1.5 and RadialGradientPaint on JDK 1.6+\r
- Paint paint;\r
- try {\r
- Class clz = Class.forName("java.awt.RadialGradientPaint");\r
- Constructor c =\r
- clz.getConstructor(Point2D.class, float.class,\r
- float[].class, Color[].class);\r
- paint = (Paint) c.newInstance(pCenter, radius, fractions, colors);\r
- } catch (ClassNotFoundException e) {\r
- // the result on JDK 1.5 is incorrect, but it is better than nothing\r
- paint = new GradientPaint(\r
- new Point2D.Double(anchor.getX(), anchor.getY()),\r
- colors[0], pCenter, colors[colors.length - 1]);\r
- } catch (Exception e) {\r
- throw new RuntimeException(e);\r
- }\r
- return paint;\r
- }\r
-\r
- private static void snapToAnchor(Point2D p, Rectangle2D anchor) {\r
- if (p.getX() < anchor.getX()) {\r
- p.setLocation(anchor.getX(), p.getY());\r
- } else if (p.getX() > (anchor.getX() + anchor.getWidth())) {\r
- p.setLocation(anchor.getX() + anchor.getWidth(), p.getY());\r
- }\r
-\r
- if (p.getY() < anchor.getY()) {\r
- p.setLocation(p.getX(), anchor.getY());\r
- } else if (p.getY() > (anchor.getY() + anchor.getHeight())) {\r
- p.setLocation(p.getX(), anchor.getY() + anchor.getHeight());\r
- }\r
- }\r
-\r
-\r
- Paint getPaint(Graphics2D graphics, XmlObject spPr, CTSchemeColor phClr) {\r
-\r
- Paint paint = null;\r
- for (XmlObject obj : spPr.selectPath("*")) {\r
- paint = selectPaint(graphics, obj, phClr, _shape.getSheet().getPackagePart());\r
- if(paint != null) break;\r
- }\r
- return paint == NO_PAINT ? null : paint;\r
- }\r
-\r
-\r
- /**\r
- * fetch shape fill as a java.awt.Paint\r
- *\r
- * @return either Color or GradientPaint or TexturePaint or null\r
- */\r
- Paint getFillPaint(final Graphics2D graphics) {\r
- PropertyFetcher<Paint> fetcher = new PropertyFetcher<Paint>() {\r
- public boolean fetch(XSLFSimpleShape shape) {\r
- CTShapeProperties spPr = shape.getSpPr();\r
- if (spPr.isSetNoFill()) {\r
- setValue(RenderableShape.NO_PAINT); // use it as 'nofill' value\r
- return true;\r
- }\r
- Paint paint = getPaint(graphics, spPr, null);\r
- if (paint != null) {\r
- setValue(paint);\r
- return true;\r
- }\r
- return false;\r
- }\r
- };\r
- _shape.fetchShapeProperty(fetcher);\r
-\r
- Paint paint = fetcher.getValue();\r
- if (paint == null) {\r
- // fill color was not found, check if it is defined in the theme\r
- CTShapeStyle style = _shape.getSpStyle();\r
- if (style != null) {\r
- // get a reference to a fill style within the style matrix.\r
- CTStyleMatrixReference fillRef = style.getFillRef();\r
- // The idx attribute refers to the index of a fill style or\r
- // background fill style within the presentation's style matrix, defined by the fmtScheme element.\r
- // value of 0 or 1000 indicates no background,\r
- // values 1-999 refer to the index of a fill style within the fillStyleLst element\r
- // values 1001 and above refer to the index of a background fill style within the bgFillStyleLst element.\r
- int idx = (int)fillRef.getIdx();\r
- CTSchemeColor phClr = fillRef.getSchemeClr();\r
- XSLFSheet sheet = _shape.getSheet();\r
- XSLFTheme theme = sheet.getTheme();\r
- XmlObject fillProps = null;\r
- if(idx >= 1 && idx <= 999){\r
- fillProps = theme.getXmlObject().\r
- getThemeElements().getFmtScheme().getFillStyleLst().selectPath("*")[idx - 1];\r
- } else if (idx >= 1001 ){\r
- fillProps = theme.getXmlObject().\r
- getThemeElements().getFmtScheme().getBgFillStyleLst().selectPath("*")[idx - 1001];\r
- }\r
- if(fillProps != null) {\r
- paint = selectPaint(graphics, fillProps, phClr, sheet.getPackagePart());\r
- }\r
- }\r
- }\r
- return paint == RenderableShape.NO_PAINT ? null : paint;\r
- }\r
-\r
- public Paint getLinePaint(final Graphics2D graphics) {\r
- PropertyFetcher<Paint> fetcher = new PropertyFetcher<Paint>() {\r
- public boolean fetch(XSLFSimpleShape shape) {\r
- CTLineProperties spPr = shape.getSpPr().getLn();\r
- if (spPr != null) {\r
- if (spPr.isSetNoFill()) {\r
- setValue(NO_PAINT); // use it as 'nofill' value\r
- return true;\r
- }\r
- Paint paint = getPaint(graphics, spPr, null);\r
- if (paint != null) {\r
- setValue(paint);\r
- return true;\r
- }\r
- }\r
- return false;\r
-\r
- }\r
- };\r
- _shape.fetchShapeProperty(fetcher);\r
-\r
- Paint paint = fetcher.getValue();\r
- if (paint == null) {\r
- // line color was not found, check if it is defined in the theme\r
- CTShapeStyle style = _shape.getSpStyle();\r
- if (style != null) {\r
- // get a reference to a line style within the style matrix.\r
- CTStyleMatrixReference lnRef = style.getLnRef();\r
- int idx = (int)lnRef.getIdx();\r
- CTSchemeColor phClr = lnRef.getSchemeClr();\r
- if(idx > 0){\r
- XSLFTheme theme = _shape.getSheet().getTheme();\r
- XmlObject lnProps = theme.getXmlObject().\r
- getThemeElements().getFmtScheme().getLnStyleLst().selectPath("*")[idx - 1];\r
- paint = getPaint(graphics, lnProps, phClr);\r
- }\r
- }\r
- }\r
-\r
- return paint == NO_PAINT ? null : paint;\r
- }\r
-\r
- /**\r
- * convert PPT dash into java.awt.BasicStroke\r
- *\r
- * The mapping is derived empirically on PowerPoint 2010\r
- */\r
- private static float[] getDashPattern(LineDash lineDash, float lineWidth) {\r
- float[] dash = null;\r
- switch (lineDash) {\r
- case SYS_DOT:\r
- dash = new float[]{lineWidth, lineWidth};\r
- break;\r
- case SYS_DASH:\r
- dash = new float[]{2 * lineWidth, 2 * lineWidth};\r
- break;\r
- case DASH:\r
- dash = new float[]{3 * lineWidth, 4 * lineWidth};\r
- break;\r
- case DASH_DOT:\r
- dash = new float[]{4 * lineWidth, 3 * lineWidth, lineWidth,\r
- 3 * lineWidth};\r
- break;\r
- case LG_DASH:\r
- dash = new float[]{8 * lineWidth, 3 * lineWidth};\r
- break;\r
- case LG_DASH_DOT:\r
- dash = new float[]{8 * lineWidth, 3 * lineWidth, lineWidth,\r
- 3 * lineWidth};\r
- break;\r
- case LG_DASH_DOT_DOT:\r
- dash = new float[]{8 * lineWidth, 3 * lineWidth, lineWidth,\r
- 3 * lineWidth, lineWidth, 3 * lineWidth};\r
- break;\r
- }\r
- return dash;\r
- }\r
-\r
-\r
- public Stroke applyStroke(Graphics2D graphics) {\r
-\r
- float lineWidth = (float) _shape.getLineWidth();\r
- if(lineWidth == 0.0f) lineWidth = 0.25f; // Both PowerPoint and OOo draw zero-length lines as 0.25pt\r
-\r
- LineDash lineDash = _shape.getLineDash();\r
- float[] dash = null;\r
- float dash_phase = 0;\r
- if (lineDash != null) {\r
- dash = getDashPattern(lineDash, lineWidth);\r
- }\r
-\r
- int cap = BasicStroke.CAP_BUTT;\r
- LineCap lineCap = _shape.getLineCap();\r
- if (lineCap != null) {\r
- switch (lineCap) {\r
- case ROUND:\r
- cap = BasicStroke.CAP_ROUND;\r
- break;\r
- case SQUARE:\r
- cap = BasicStroke.CAP_SQUARE;\r
- break;\r
- default:\r
- cap = BasicStroke.CAP_BUTT;\r
- break;\r
- }\r
- }\r
-\r
- int meter = BasicStroke.JOIN_ROUND;\r
-\r
- Stroke stroke = new BasicStroke(lineWidth, cap, meter, Math.max(1, lineWidth), dash,\r
- dash_phase);\r
- graphics.setStroke(stroke);\r
- return stroke;\r
- }\r
-\r
- public void render(Graphics2D graphics){\r
- Collection<Outline> elems = computeOutlines(graphics);\r
-\r
- // shadow\r
- XSLFShadow shadow = _shape.getShadow();\r
-\r
- // first fill\r
- Paint fill = getFillPaint(graphics);\r
- Paint line = getLinePaint(graphics);\r
- applyStroke(graphics); // the stroke applies both to the shadow and the shape\r
-\r
- // first paint the shadow\r
- if(shadow != null) for(Outline o : elems){\r
- if(o.getPath().isFilled()){\r
- if(fill != null) shadow.fill(graphics, o.getOutline());\r
- else if(line != null) shadow.draw(graphics, o.getOutline());\r
- }\r
- }\r
- // then fill the shape interior\r
- if(fill != null) for(Outline o : elems){\r
- if(o.getPath().isFilled()){\r
- graphics.setPaint(fill);\r
- graphics.fill(o.getOutline());\r
- }\r
- }\r
-\r
- // then draw any content within this shape (text, image, etc.)\r
- _shape.drawContent(graphics);\r
-\r
- // then stroke the shape outline\r
- if(line != null) for(Outline o : elems){\r
- if(o.getPath().isStroked()){\r
- graphics.setPaint(line);\r
- graphics.draw(o.getOutline());\r
- }\r
- }\r
- }\r
-\r
- @SuppressWarnings("deprecation")\r
- private Collection<Outline> computeOutlines(Graphics2D graphics) {\r
-\r
- Collection<Outline> lst = new ArrayList<Outline>();\r
- CustomGeometry geom = _shape.getGeometry();\r
- if(geom == null) {\r
- return lst;\r
- }\r
-\r
- Rectangle2D anchor = getAnchor(graphics);\r
- for (Path p : geom) {\r
-\r
- double w = p.getW() == -1 ? anchor.getWidth() * Units.EMU_PER_POINT : p.getW();\r
- double h = p.getH() == -1 ? anchor.getHeight() * Units.EMU_PER_POINT : p.getH();\r
-\r
- // the guides in the shape definitions are all defined relative to each other,\r
- // so we build the path starting from (0,0).\r
- final Rectangle2D pathAnchor = new Rectangle2D.Double(\r
- 0,\r
- 0,\r
- w,\r
- h\r
- );\r
-\r
- Context ctx = new Context(geom, pathAnchor, new IAdjustableShape() {\r
-\r
- public Guide getAdjustValue(String name) {\r
- CTPresetGeometry2D prst = _shape.getSpPr().getPrstGeom();\r
- if (prst.isSetAvLst()) {\r
- for (CTGeomGuide g : prst.getAvLst().getGdArray()) {\r
- if (g.getName().equals(name)) {\r
- return new Guide(g);\r
- }\r
- }\r
- }\r
- return null;\r
- }\r
- }) ;\r
-\r
- Shape gp = p.getPath(ctx);\r
-\r
- // translate the result to the canvas coordinates in points\r
- AffineTransform at = new AffineTransform();\r
- at.translate(anchor.getX(), anchor.getY());\r
-\r
- double scaleX, scaleY;\r
- if (p.getW() != -1) {\r
- scaleX = anchor.getWidth() / p.getW();\r
- } else {\r
- scaleX = 1.0 / Units.EMU_PER_POINT;\r
- }\r
- if (p.getH() != -1) {\r
- scaleY = anchor.getHeight() / p.getH();\r
- } else {\r
- scaleY = 1.0 / Units.EMU_PER_POINT;\r
- }\r
-\r
- at.scale(scaleX, scaleY);\r
-\r
- Shape canvasShape = at.createTransformedShape(gp);\r
-\r
- lst.add(new Outline(canvasShape, p));\r
- }\r
-\r
- return lst;\r
- }\r
-\r
- public Rectangle2D getAnchor(Graphics2D graphics) {\r
- Rectangle2D anchor = _shape.getAnchor();\r
- if(graphics == null) {\r
- return anchor;\r
- }\r
-\r
- AffineTransform tx = (AffineTransform)graphics.getRenderingHint(XSLFRenderingHint.GROUP_TRANSFORM);\r
- if(tx != null) {\r
- anchor = tx.createTransformedShape(anchor).getBounds2D();\r
- }\r
- return anchor;\r
- } \r
-}\r
return null;
}
- public MasterSheet<XSLFShape>[] getMasterSheet() {
+ public XSLFSlideMaster[] getMasterSheet() {
return getSlideMasters();
}
- public MasterSheet<XSLFShape> createMasterSheet() throws IOException {
+ public MasterSheet createMasterSheet() throws IOException {
// TODO: implement!
throw new UnsupportedOperationException();
}
* @author Yegor Kozlov\r
*/\r
@Beta\r
-public class XSLFAutoShape extends XSLFTextShape implements AutoShape {\r
+public class XSLFAutoShape extends XSLFTextShape implements AutoShape<XSLFTextParagraph> {\r
\r
/*package*/ XSLFAutoShape(CTShape shape, XSLFSheet sheet) {\r
super(shape, sheet);\r
}\r
\r
protected CTTextBody getTextBody(boolean create){\r
- CTShape shape = (CTShape) getXmlObject();\r
+ CTShape shape = (CTShape)getXmlObject();\r
CTTextBody txBody = shape.getTxBody();\r
if (txBody == null && create) {\r
txBody = shape.addNewTxBody();\r
import java.awt.*;\r
import java.awt.geom.Rectangle2D;\r
\r
-import org.apache.poi.sl.usermodel.Background;\r
-import org.apache.xmlbeans.XmlObject;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.*;\r
+import org.apache.poi.sl.draw.DrawPaint;\r
+import org.apache.poi.sl.usermodel.*;\r
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;\r
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;\r
\r
/**\r
return new Rectangle2D.Double(0, 0, pg.getWidth(), pg.getHeight());\r
}\r
\r
- public void draw(Graphics2D graphics) {\r
- Rectangle2D anchor = getAnchor();\r
-\r
- Paint fill = getPaint(graphics);\r
- if(fill != null) {\r
- graphics.setPaint(fill);\r
- graphics.fill(anchor);\r
- }\r
- }\r
-\r
- /**\r
- * @return the Paint object to fill\r
- */\r
- Paint getPaint(Graphics2D graphics){\r
- RenderableShape rShape = new RenderableShape(this);\r
-\r
- Paint fill = null;\r
- CTBackground bg = (CTBackground)getXmlObject();\r
- if(bg.isSetBgPr()){\r
- XmlObject spPr = bg.getBgPr();\r
- fill = rShape.getPaint(graphics, spPr, null);\r
- } else if (bg.isSetBgRef()){\r
- CTStyleMatrixReference bgRef= bg.getBgRef();\r
- CTSchemeColor phClr = bgRef.getSchemeClr();\r
-\r
- int idx = (int)bgRef.getIdx() - 1001;\r
- XSLFTheme theme = getSheet().getTheme();\r
- CTBackgroundFillStyleList bgStyles =\r
- theme.getXmlObject().getThemeElements().getFmtScheme().getBgFillStyleLst();\r
-\r
- XmlObject bgStyle = bgStyles.selectPath("*")[idx];\r
- fill = rShape.selectPaint(graphics, bgStyle, phClr, theme.getPackagePart());\r
- }\r
-\r
- return fill;\r
- }\r
-\r
@Override\r
public Color getFillColor(){\r
- Paint p = getPaint(null);\r
- if(p instanceof Color){\r
- return (Color)p;\r
+ FillStyle fs = getFillStyle();\r
+ PaintStyle ps = fs.getPaint();\r
+ if (ps instanceof SolidPaint) {\r
+ SolidPaint sp = (SolidPaint)ps;\r
+ ColorStyle cs = sp.getSolidColor();\r
+ return DrawPaint.applyColorTransform(cs);\r
}\r
return null;\r
}\r
* @return dummy CTTransform2D bean\r
*/\r
@Override\r
- CTTransform2D getXfrm() {\r
+ protected CTTransform2D getXfrm() {\r
return CTTransform2D.Factory.newInstance();\r
}\r
}\r
\r
package org.apache.poi.xslf.usermodel;\r
\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import javax.xml.namespace.QName;\r
+\r
import org.apache.poi.POIXMLException;\r
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;\r
import org.apache.poi.openxml4j.opc.PackagePart;\r
import org.apache.poi.util.Units;\r
import org.apache.xmlbeans.XmlCursor;\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.drawingml.x2006.main.*;\r
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;\r
\r
-import javax.xml.namespace.QName;\r
-\r
-import java.awt.Graphics2D;\r
-import java.awt.geom.Rectangle2D;\r
-\r
/**\r
* @author Yegor Kozlov\r
*/\r
@Beta\r
public class XSLFGraphicFrame extends XSLFShape {\r
- private final CTGraphicalObjectFrame _shape;\r
- private final XSLFSheet _sheet;\r
-\r
/*package*/ XSLFGraphicFrame(CTGraphicalObjectFrame shape, XSLFSheet sheet){\r
- _shape = shape;\r
- _sheet = sheet;\r
- }\r
-\r
- public CTGraphicalObjectFrame getXmlObject(){\r
- return _shape;\r
- }\r
-\r
- public XSLFSheet getSheet(){\r
- return _sheet;\r
+ super(shape,sheet);\r
}\r
\r
public ShapeType getShapeType(){\r
throw new UnsupportedOperationException();\r
}\r
\r
- public int getShapeId(){\r
- return (int)_shape.getNvGraphicFramePr().getCNvPr().getId();\r
- }\r
-\r
- public String getShapeName(){\r
- return _shape.getNvGraphicFramePr().getCNvPr().getName();\r
- }\r
-\r
public Rectangle2D getAnchor(){\r
- CTTransform2D xfrm = _shape.getXfrm();\r
+ CTTransform2D xfrm = ((CTGraphicalObjectFrame)getXmlObject()).getXfrm();\r
CTPoint2D off = xfrm.getOff();\r
long x = off.getX();\r
long y = off.getY();\r
}\r
\r
public void setAnchor(Rectangle2D anchor){\r
- CTTransform2D xfrm = _shape.getXfrm();\r
+ CTTransform2D xfrm = ((CTGraphicalObjectFrame)getXmlObject()).getXfrm();\r
CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff();\r
long x = Units.toEMU(anchor.getX());\r
long y = Units.toEMU(anchor.getY());\r
return false;\r
}\r
\r
- public void draw(Graphics2D graphics){\r
-\r
- }\r
-\r
@Override\r
void copy(XSLFShape sh){\r
super.copy(sh);\r
\r
- CTGraphicalObjectData data = _shape.getGraphic().getGraphicData();\r
+ CTGraphicalObjectData data = ((CTGraphicalObjectFrame)getXmlObject()).getGraphic().getGraphicData();\r
String uri = data.getUri();\r
if(uri.equals("http://schemas.openxmlformats.org/drawingml/2006/diagram")){\r
copyDiagram(data, (XSLFGraphicFrame)sh);\r
String dm = c.getAttributeText(new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "dm"));\r
PackageRelationship dmRel = sheet.getPackagePart().getRelationship(dm);\r
PackagePart dmPart = sheet.getPackagePart().getRelatedPart(dmRel);\r
- _sheet.importPart(dmRel, dmPart);\r
+ getSheet().importPart(dmRel, dmPart);\r
\r
String lo = c.getAttributeText(new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "lo"));\r
PackageRelationship loRel = sheet.getPackagePart().getRelationship(lo);\r
PackagePart loPart = sheet.getPackagePart().getRelatedPart(loRel);\r
- _sheet.importPart(loRel, loPart);\r
+ getSheet().importPart(loRel, loPart);\r
\r
String qs = c.getAttributeText(new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "qs"));\r
PackageRelationship qsRel = sheet.getPackagePart().getRelationship(qs);\r
PackagePart qsPart = sheet.getPackagePart().getRelatedPart(qsRel);\r
- _sheet.importPart(qsRel, qsPart);\r
+ getSheet().importPart(qsRel, qsPart);\r
\r
String cs = c.getAttributeText(new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "cs"));\r
PackageRelationship csRel = sheet.getPackagePart().getRelationship(cs);\r
PackagePart csPart = sheet.getPackagePart().getRelatedPart(csRel);\r
- _sheet.importPart(csRel, csPart);\r
+ getSheet().importPart(csRel, csPart);\r
\r
} catch (InvalidFormatException e){\r
throw new POIXMLException(e);\r
import org.apache.poi.openxml4j.opc.PackagePart;\r
import org.apache.poi.openxml4j.opc.PackageRelationship;\r
import org.apache.poi.openxml4j.opc.TargetMode;\r
-import org.apache.poi.sl.usermodel.ShapeType;\r
+import org.apache.poi.sl.usermodel.*;\r
import org.apache.poi.util.Beta;\r
import org.apache.poi.util.Units;\r
import org.apache.xmlbeans.XmlObject;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupTransform2D;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;\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.*;\r
import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector;\r
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;\r
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShapeNonVisual;\r
* @author Yegor Kozlov\r
*/\r
@Beta\r
-public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer {\r
- private final CTGroupShape _shape;\r
- private final XSLFSheet _sheet;\r
+public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer, PlaceableShape {\r
private final List<XSLFShape> _shapes;\r
- private final CTGroupShapeProperties _spPr;\r
+ private final CTGroupShapeProperties _grpSpPr;\r
private XSLFDrawing _drawing;\r
\r
- /*package*/ XSLFGroupShape(CTGroupShape shape, XSLFSheet sheet){\r
- _shape = shape;\r
- _sheet = sheet;\r
-\r
- _shapes = _sheet.buildShapes(_shape);\r
- _spPr = shape.getGrpSpPr();\r
+ protected XSLFGroupShape(CTGroupShape shape, XSLFSheet sheet){\r
+ super(shape,sheet);\r
+ _shapes = sheet.buildShapes(shape);\r
+ _grpSpPr = shape.getGrpSpPr();\r
}\r
\r
- @Override\r
- public CTGroupShape getXmlObject(){\r
- return _shape;\r
+ protected CTGroupShapeProperties getGrpSpPr() {\r
+ return _grpSpPr;\r
+ }\r
+ \r
+ protected CTGroupTransform2D getSafeXfrm() {\r
+ CTGroupTransform2D xfrm = getXfrm();\r
+ return (xfrm == null ? getGrpSpPr().addNewXfrm() : xfrm);\r
+ }\r
+ \r
+ protected CTGroupTransform2D getXfrm() {\r
+ return getGrpSpPr().getXfrm();\r
}\r
\r
@Override\r
public Rectangle2D getAnchor(){\r
- CTGroupTransform2D xfrm = _spPr.getXfrm();\r
+ CTGroupTransform2D xfrm = getXfrm();\r
CTPoint2D off = xfrm.getOff();\r
long x = off.getX();\r
long y = off.getY();\r
\r
@Override\r
public void setAnchor(Rectangle2D anchor){\r
- CTGroupTransform2D xfrm = _spPr.isSetXfrm() ? _spPr.getXfrm() : _spPr.addNewXfrm();\r
+ CTGroupTransform2D xfrm = getSafeXfrm();\r
CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff();\r
long x = Units.toEMU(anchor.getX());\r
long y = Units.toEMU(anchor.getY());\r
* behavior of shapes placed within a group.\r
*/\r
public Rectangle2D getInteriorAnchor(){\r
- CTGroupTransform2D xfrm = _spPr.getXfrm();\r
+ CTGroupTransform2D xfrm = getXfrm();\r
CTPoint2D off = xfrm.getChOff();\r
long x = off.getX();\r
long y = off.getY();\r
* behavior of shapes placed within a group.\r
*/\r
public void setInteriorAnchor(Rectangle2D anchor){\r
- CTGroupTransform2D xfrm = _spPr.isSetXfrm() ? _spPr.getXfrm() : _spPr.addNewXfrm();\r
+ CTGroupTransform2D xfrm = getSafeXfrm();\r
CTPoint2D off = xfrm.isSetChOff() ? xfrm.getChOff() : xfrm.addNewChOff();\r
long x = Units.toEMU(anchor.getX());\r
long y = Units.toEMU(anchor.getY());\r
*/\r
public boolean removeShape(XSLFShape xShape) {\r
XmlObject obj = xShape.getXmlObject();\r
+ CTGroupShape grpSp = (CTGroupShape)getXmlObject();\r
if(obj instanceof CTShape){\r
- _shape.getSpList().remove(obj);\r
+ grpSp.getSpList().remove(obj);\r
} else if (obj instanceof CTGroupShape){\r
- _shape.getGrpSpList().remove(obj);\r
+ grpSp.getGrpSpList().remove(obj);\r
} else if (obj instanceof CTConnector){\r
- _shape.getCxnSpList().remove(obj);\r
+ grpSp.getCxnSpList().remove(obj);\r
} else {\r
throw new IllegalArgumentException("Unsupported shape: " + xShape);\r
}\r
return _shapes.remove(xShape);\r
}\r
\r
- @Override\r
- public String getShapeName(){\r
- return _shape.getNvGrpSpPr().getCNvPr().getName();\r
- }\r
-\r
- @Override\r
- public int getShapeId(){\r
- return (int)_shape.getNvGrpSpPr().getCNvPr().getId();\r
- }\r
-\r
/**\r
* @param shapeId 1-based shapeId\r
*/\r
// shape factory methods\r
private XSLFDrawing getDrawing(){\r
if(_drawing == null) {\r
- _drawing = new XSLFDrawing(_sheet, _shape);\r
+ _drawing = new XSLFDrawing(getSheet(), (CTGroupShape)getXmlObject());\r
}\r
return _drawing;\r
}\r
\r
public XSLFPictureShape createPicture(int pictureIndex){\r
\r
- List<PackagePart> pics = _sheet.getPackagePart().getPackage()\r
+ List<PackagePart> pics = getSheet().getPackagePart().getPackage()\r
.getPartsByName(Pattern.compile("/ppt/media/image" + (pictureIndex + 1) + ".*?"));\r
\r
if(pics.size() == 0) {\r
\r
PackagePart pic = pics.get(0);\r
\r
- PackageRelationship rel = _sheet.getPackagePart().addRelationship(\r
+ PackageRelationship rel = getSheet().getPackagePart().addRelationship(\r
pic.getPartName(), TargetMode.INTERNAL, XSLFRelation.IMAGES.getRelation());\r
\r
XSLFPictureShape sh = getDrawing().createPicture(rel.getId());\r
\r
@Override\r
public void setFlipHorizontal(boolean flip){\r
- _spPr.getXfrm().setFlipH(flip);\r
+ getSafeXfrm().setFlipH(flip);\r
}\r
\r
@Override\r
public void setFlipVertical(boolean flip){\r
- _spPr.getXfrm().setFlipV(flip);\r
+ getSafeXfrm().setFlipV(flip);\r
}\r
\r
@Override\r
public boolean getFlipHorizontal(){\r
- return _spPr.getXfrm().getFlipH();\r
+ CTGroupTransform2D xfrm = getXfrm();\r
+ return (xfrm == null || !xfrm.isSetFlipH()) ? false : xfrm.getFlipH();\r
}\r
\r
@Override\r
public boolean getFlipVertical(){\r
- return _spPr.getXfrm().getFlipV();\r
+ CTGroupTransform2D xfrm = getXfrm();\r
+ return (xfrm == null || !xfrm.isSetFlipV()) ? false : xfrm.getFlipV();\r
}\r
\r
@Override\r
public void setRotation(double theta){\r
- _spPr.getXfrm().setRot((int)(theta*60000));\r
+ getSafeXfrm().setRot((int) (theta * 60000));\r
}\r
\r
@Override\r
public double getRotation(){\r
- return (double)_spPr.getXfrm().getRot()/60000;\r
- }\r
-\r
- @Override\r
- public void draw(Graphics2D graphics){\r
-\r
- // the coordinate system of this group of shape\r
- Rectangle2D interior = getInteriorAnchor();\r
- // anchor of this group relative to the parent shape\r
- Rectangle2D exterior = getAnchor();\r
-\r
- AffineTransform tx = (AffineTransform)graphics.getRenderingHint(XSLFRenderingHint.GROUP_TRANSFORM);\r
- AffineTransform tx0 = new AffineTransform(tx);\r
-\r
- double scaleX = interior.getWidth() == 0. ? 1.0 : exterior.getWidth() / interior.getWidth();\r
- double scaleY = interior.getHeight() == 0. ? 1.0 : exterior.getHeight() / interior.getHeight();\r
-\r
- tx.translate(exterior.getX(), exterior.getY());\r
- tx.scale(scaleX, scaleY);\r
- tx.translate(-interior.getX(), -interior.getY());\r
-\r
- for (XSLFShape shape : getShapes()) {\r
- // remember the initial transform and restore it after we are done with the drawing\r
- AffineTransform at = graphics.getTransform();\r
- graphics.setRenderingHint(XSLFRenderingHint.GSAVE, true);\r
-\r
- shape.applyTransform(graphics);\r
- shape.draw(graphics);\r
-\r
- // restore the coordinate system\r
- graphics.setTransform(at);\r
- graphics.setRenderingHint(XSLFRenderingHint.GRESTORE, true);\r
- }\r
-\r
- graphics.setRenderingHint(XSLFRenderingHint.GROUP_TRANSFORM, tx0);\r
- \r
+ CTGroupTransform2D xfrm = getXfrm();\r
+ return (xfrm == null || !xfrm.isSetRot()) ? 0 : (xfrm.getRot() / 60000.d);\r
}\r
\r
@Override\r
}\r
}\r
\r
- public ShapeType getShapeType(){\r
- return null;\r
- }\r
-\r
public void addShape(XSLFShape shape) {\r
throw new UnsupportedOperationException(\r
"Adding a shape from a different container is not supported -"\r
- + " create it from scratch witht XSLFGroupShape.create* methods");\r
+ + " create it from scratch with XSLFGroupShape.create* methods");\r
}\r
}
\ No newline at end of file
package org.apache.poi.xslf.usermodel;
import java.io.IOException;
+import java.io.OutputStream;
-import org.apache.poi.POIXMLDocumentPart;
-import org.apache.poi.POIXMLException;
-import org.apache.poi.POIXMLRelation;
+import org.apache.poi.*;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.util.Beta;
import org.apache.poi.util.IOUtils;
* @author Yegor Kozlov
*/
@Beta
-public final class XSLFPictureData extends POIXMLDocumentPart {
+public final class XSLFPictureData extends POIXMLDocumentPart implements PictureData {
/**
* Extended windows meta file
*/
protected void prepareForCommit() {
// do not clear the part here
}
+
+ public String getContentType() {
+ POIXMLRelation rel = RELATIONS[getPictureType()];
+ return (rel == null) ? null : rel.getContentType();
+ }
+
+ public void setData(byte[] data) throws IOException {
+ OutputStream os = getPackagePart().getOutputStream();
+ os.write(data);
+ os.close();
+ }
+
+
}
\ No newline at end of file
return id;\r
}\r
\r
- public Insets getBlipClip(){\r
+ public Insets getClipping(){\r
CTPicture ct = (CTPicture)getXmlObject();\r
CTRelativeRect r = ct.getBlipFill().getSrcRect();\r
return (r == null) ? null : new Insets(r.getT(), r.getL(), r.getB(), r.getR());\r
}\r
\r
- @Override\r
- public void drawContent(Graphics2D graphics) {\r
-\r
- XSLFPictureData data = getPictureData();\r
- if(data == null) return;\r
-\r
- XSLFImageRenderer renderer = (XSLFImageRenderer)graphics.getRenderingHint(XSLFRenderingHint.IMAGE_RENDERER);\r
- if(renderer == null) renderer = new XSLFImageRenderer();\r
-\r
- RenderableShape rShape = new RenderableShape(this);\r
- Rectangle2D anchor = rShape.getAnchor(graphics);\r
- \r
- Insets insets = getBlipClip();\r
-\r
- renderer.drawImage(graphics, data, anchor, insets);\r
- }\r
-\r
-\r
+ @SuppressWarnings("deprecation")\r
@Override\r
void copy(XSLFShape sh){\r
super.copy(sh);\r
\r
package org.apache.poi.xslf.usermodel;\r
\r
-import org.apache.poi.sl.usermodel.Shadow;\r
+import java.awt.Color;\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.apache.poi.sl.draw.DrawPaint;\r
+import org.apache.poi.sl.usermodel.*;\r
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
import org.apache.poi.util.Units;\r
import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect;\r
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;\r
\r
-import java.awt.Color;\r
-import java.awt.Graphics2D;\r
-import java.awt.Shape;\r
-import java.awt.geom.Rectangle2D;\r
-\r
/**\r
* Represents a shadow of a shape. For now supports only outer shadows.\r
*\r
* @author Yegor Kozlov\r
*/\r
-public class XSLFShadow extends XSLFSimpleShape implements Shadow {\r
+public class XSLFShadow extends XSLFShape implements Shadow {\r
\r
private XSLFSimpleShape _parent;\r
\r
_parent = parentShape;\r
}\r
\r
-\r
- public void fill(Graphics2D graphics, Shape outline) {\r
-\r
- double shapeRotation = _parent.getRotation();\r
- if(_parent.getFlipVertical()){\r
- shapeRotation += 180;\r
- }\r
- double angle = getAngle() - shapeRotation;\r
- double dist = getDistance();\r
- double dx = dist * Math.cos(Math.toRadians(angle));\r
- double dy = dist * Math.sin(Math.toRadians(angle));\r
-\r
- graphics.translate(dx, dy);\r
-\r
- Color fillColor = getFillColor();\r
- if (fillColor != null) {\r
- graphics.setColor(fillColor);\r
- graphics.fill(outline);\r
- }\r
-\r
- graphics.translate(-dx, -dy);\r
- }\r
-\r
- public void draw(Graphics2D graphics, Shape outline) {\r
-\r
- double angle = getAngle();\r
- double dist = getDistance();\r
- double dx = dist * Math.cos(Math.toRadians(angle));\r
- double dy = dist * Math.sin(Math.toRadians(angle));\r
-\r
- graphics.translate(dx, dy);\r
-\r
- Color fillColor = getFillColor();\r
- if (fillColor != null) {\r
- graphics.setColor(fillColor);\r
- graphics.draw(outline);\r
- }\r
-\r
- graphics.translate(-dx, -dy);\r
+ @Override\r
+ public XSLFSimpleShape getShadowParent() {\r
+ return _parent;\r
}\r
\r
-\r
- @Override\r
public Rectangle2D getAnchor(){\r
return _parent.getAnchor();\r
}\r
\r
- @Override\r
public void setAnchor(Rectangle2D anchor){\r
throw new IllegalStateException("You can't set anchor of a shadow");\r
}\r
* @return the color of this shadow. \r
* Depending whether the parent shape is filled or stroked, this color is used to fill or stroke this shadow\r
*/\r
- @Override\r
public Color getFillColor() {\r
+ SolidPaint ps = getFillStyle();\r
+ if (ps == TRANSPARENT_PAINT) return null;\r
+ Color col = DrawPaint.applyColorTransform(ps.getSolidColor());\r
+ return col;\r
+ }\r
+\r
+ @Override\r
+ public SolidPaint getFillStyle() {\r
XSLFTheme theme = getSheet().getTheme();\r
CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject();\r
- if(ct == null) {\r
- return null;\r
- } else {\r
- CTSchemeColor phClr = ct.getSchemeClr();\r
- return new XSLFColor(ct, theme, phClr).getColor();\r
- }\r
+ if(ct == null) return TRANSPARENT_PAINT;\r
+ \r
+ CTSchemeColor phClr = ct.getSchemeClr();\r
+ final XSLFColor xc = new XSLFColor(ct, theme, phClr);\r
+ return new SolidPaint(){\r
+ public ColorStyle getSolidColor() {\r
+ return xc.getColorStyle();\r
+ }\r
+ };\r
}\r
}
\ No newline at end of file
package org.apache.poi.xslf.usermodel;\r
\r
import java.awt.Color;\r
-import java.awt.geom.Rectangle2D;\r
import java.io.IOException;\r
import java.io.InputStream;\r
import java.util.Arrays;\r
import org.apache.poi.openxml4j.opc.PackagePart;\r
import org.apache.poi.openxml4j.opc.PackageRelationship;\r
import org.apache.poi.sl.draw.DrawPaint;\r
-import org.apache.poi.sl.draw.geom.CustomGeometry;\r
import org.apache.poi.sl.usermodel.*;\r
-import org.apache.poi.util.*;\r
+import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;\r
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
+import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;\r
+import org.apache.poi.util.Beta;\r
+import org.apache.poi.util.Internal;\r
import org.apache.poi.xslf.model.PropertyFetcher;\r
import org.apache.xmlbeans.XmlObject;\r
import org.openxmlformats.schemas.drawingml.x2006.main.*;\r
-import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;\r
-import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;\r
+import org.openxmlformats.schemas.presentationml.x2006.main.*;\r
\r
/**\r
* Base super-class class for all shapes in PresentationML\r
*/\r
@Beta\r
public abstract class XSLFShape implements Shape {\r
- protected final XmlObject _shape;\r
- protected final XSLFSheet _sheet;\r
- protected XSLFShapeContainer _parent;\r
+ private final XmlObject _shape;\r
+ private final XSLFSheet _sheet;\r
+ private XSLFShapeContainer _parent;\r
\r
private CTShapeProperties _spPr;\r
private CTShapeStyle _spStyle;\r
private CTNonVisualDrawingProps _nvPr;\r
private CTPlaceholder _ph;\r
\r
- private static final PaintStyle TRANSPARENT_PAINT = new SolidPaint() {\r
+ protected static final SolidPaint TRANSPARENT_PAINT = new SolidPaint() {\r
public ColorStyle getSolidColor() {\r
return new ColorStyle(){\r
public Color getColor() { return DrawPaint.NO_PAINT; }\r
}\r
};\r
\r
- \r
protected XSLFShape(XmlObject shape, XSLFSheet sheet) {\r
_shape = shape;\r
_sheet = sheet;\r
}\r
-\r
\r
/**\r
* @return the xml bean holding this shape's data\r
*/\r
- public XmlObject getXmlObject() {\r
+ public final XmlObject getXmlObject() {\r
+ // it's final because the xslf inheritance hierarchy is not necessary the same as\r
+ // the (not existing) xmlbeans hierarchy and subclasses shouldn't narrow it's return value\r
return _shape;\r
}\r
\r
+ public XSLFSheet getSheet() {\r
+ return _sheet;\r
+ }\r
+ \r
/**\r
* @return human-readable name of this shape, e.g. "Rectange 3"\r
*/\r
- public abstract String getShapeName();\r
+ public String getShapeName(){\r
+ return getCNvPr().getName();\r
+ }\r
\r
/**\r
* Returns a unique identifier for this shape within the current document.\r
*\r
* @return unique id of this shape\r
*/\r
- public abstract int getShapeId();\r
-\r
- /**\r
- * Rotate this shape.\r
- * <p>\r
- * Positive angles are clockwise (i.e., towards the positive y axis);\r
- * negative angles are counter-clockwise (i.e., towards the negative y axis).\r
- * </p>\r
- *\r
- * @param theta the rotation angle in degrees.\r
- */\r
- public abstract void setRotation(double theta);\r
-\r
- /**\r
- * Rotation angle in degrees\r
- * <p>\r
- * Positive angles are clockwise (i.e., towards the positive y axis);\r
- * negative angles are counter-clockwise (i.e., towards the negative y axis).\r
- * </p>\r
- *\r
- * @return rotation angle in degrees\r
- */\r
- public abstract double getRotation();\r
-\r
- /**\r
- * @param flip whether the shape is horizontally flipped\r
- */\r
- public abstract void setFlipHorizontal(boolean flip);\r
-\r
- /**\r
- * Whether the shape is vertically flipped\r
- *\r
- * @param flip whether the shape is vertically flipped\r
- */\r
- public abstract void setFlipVertical(boolean flip);\r
-\r
- /**\r
- * Whether the shape is horizontally flipped\r
- *\r
- * @return whether the shape is horizontally flipped\r
- */\r
- public abstract boolean getFlipHorizontal();\r
-\r
- /**\r
- * Whether the shape is vertically flipped\r
- *\r
- * @return whether the shape is vertically flipped\r
- */\r
- public abstract boolean getFlipVertical();\r
+ public int getShapeId() {\r
+ return (int)getCNvPr().getId();\r
+ }\r
\r
/**\r
* Set the contents of this shape to be a copy of the source shape.\r
"Can't copy " + sh.getClass().getSimpleName() + " into " + getClass().getSimpleName());\r
}\r
\r
- setAnchor(sh.getAnchor());\r
+ if (this instanceof PlaceableShape) {\r
+ PlaceableShape ps = (PlaceableShape)this;\r
+ ps.setAnchor(((PlaceableShape)sh).getAnchor());\r
+ }\r
+ \r
+ \r
}\r
\r
public void setParent(XSLFShapeContainer parent) {\r
return this._parent;\r
}\r
\r
- public boolean isPlaceholder() {\r
- return false;\r
+ protected PaintStyle getFillPaint() {\r
+ PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {\r
+ public boolean fetch(XSLFShape shape) {\r
+ XmlObject pr = null;\r
+ try {\r
+ pr = shape.getSpPr();\r
+ if (((CTShapeProperties)pr).isSetNoFill()) {\r
+ setValue(TRANSPARENT_PAINT);\r
+ return true;\r
+ } \r
+ } catch (IllegalStateException e) {}\r
+ // trying background properties now\r
+ if (pr == null) {\r
+ pr = shape.getBgPr();\r
+ }\r
+ if (pr == null) {\r
+ pr = shape.getGrpSpPr();\r
+ }\r
+ if (pr == null) {\r
+ setValue(TRANSPARENT_PAINT);\r
+ return true;\r
+ }\r
+ \r
+ PaintStyle paint = null;\r
+ for (XmlObject obj : pr.selectPath("*")) {\r
+ paint = selectPaint(obj, null, getSheet().getPackagePart());\r
+ if (paint != null) break;\r
+ }\r
+ \r
+ if (paint == null) return false;\r
+ \r
+ setValue(paint);\r
+ return true;\r
+ }\r
+ };\r
+ fetchShapeProperty(fetcher);\r
+\r
+ PaintStyle paint = fetcher.getValue();\r
+ if (paint != null) return paint;\r
+ \r
+ // fill color was not found, check if it is defined in the theme\r
+ // get a reference to a fill style within the style matrix.\r
+ CTStyleMatrixReference fillRef = null;\r
+ if (fillRef == null) {\r
+ CTShapeStyle style = getSpStyle();\r
+ if (style != null) fillRef = style.getFillRef();\r
+ }\r
+ if (fillRef == null) {\r
+ fillRef = getBgRef();\r
+ }\r
+ if (fillRef == null) {\r
+ return TRANSPARENT_PAINT;\r
+ }\r
+\r
+ // The idx attribute refers to the index of a fill style or\r
+ // background fill style within the presentation's style matrix, defined by the fmtScheme element.\r
+ // value of 0 or 1000 indicates no background,\r
+ // values 1-999 refer to the index of a fill style within the fillStyleLst element\r
+ // values 1001 and above refer to the index of a background fill style within the bgFillStyleLst element.\r
+ int idx = (int)fillRef.getIdx();\r
+ CTSchemeColor phClr = fillRef.getSchemeClr();\r
+ XSLFSheet sheet = getSheet();\r
+ XSLFTheme theme = sheet.getTheme();\r
+ XmlObject fillProps = null;\r
+ CTStyleMatrix matrix = theme.getXmlObject().getThemeElements().getFmtScheme();\r
+ if(idx >= 1 && idx <= 999){\r
+ fillProps = matrix.getFillStyleLst().selectPath("*")[idx - 1];\r
+ } else if (idx >= 1001 ){\r
+ fillProps = matrix.getBgFillStyleLst().selectPath("*")[idx - 1001];\r
+ }\r
+ if(fillProps != null) {\r
+ paint = selectPaint(fillProps, phClr, sheet.getPackagePart());\r
+ }\r
+\r
+ return paint == null ? TRANSPARENT_PAINT : paint;\r
}\r
\r
- public StrokeStyle getStrokeStyle() {\r
- // TODO Auto-generated method stub\r
- return null;\r
+ protected CTBackgroundProperties getBgPr() {\r
+ String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:bgPr";\r
+ return selectProperty(CTBackgroundProperties.class, xquery);\r
+ }\r
+ \r
+ protected CTStyleMatrixReference getBgRef() {\r
+ String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:bgRef";\r
+ return selectProperty(CTStyleMatrixReference.class, xquery);\r
+ }\r
+ \r
+ protected CTGroupShapeProperties getGrpSpPr() {\r
+ String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:grpSpPr";\r
+ return selectProperty(CTGroupShapeProperties.class, xquery);\r
+ }\r
+ \r
+ protected CTNonVisualDrawingProps getCNvPr() {\r
+ if (_nvPr == null) {\r
+ String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr";\r
+ _nvPr = selectProperty(CTNonVisualDrawingProps.class, xquery);\r
+ }\r
+ return _nvPr;\r
}\r
\r
- public CustomGeometry getGeometry() {\r
- // TODO Auto-generated method stub\r
- return null;\r
+ protected CTShapeProperties getSpPr() {\r
+ if (_spPr == null) {\r
+ String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:spPr";\r
+ _spPr = selectProperty(CTShapeProperties.class, xquery);\r
+ }\r
+ if (_spPr == null) {\r
+ throw new IllegalStateException("CTShapeProperties was not found.");\r
+ }\r
+ return _spPr;\r
}\r
\r
- public ShapeType getShapeType() {\r
- // TODO Auto-generated method stub\r
- return null;\r
+ protected CTShapeStyle getSpStyle() {\r
+ if (_spStyle == null) {\r
+ String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:style";\r
+ _spStyle = selectProperty(CTShapeStyle.class, xquery);\r
+ }\r
+ return _spStyle;\r
}\r
\r
- public XSLFSheet getSheet() {\r
- // TODO Auto-generated method stub\r
- return null;\r
+ protected CTPlaceholder getCTPlaceholder() {\r
+ if (_ph == null) {\r
+ String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:nvPr/p:ph";\r
+ _ph = selectProperty(CTPlaceholder.class, xquery);\r
+ }\r
+ return _ph;\r
}\r
\r
/**\r
- * fetch shape fill as a java.awt.Paint\r
+ * As there's no xmlbeans hierarchy, but XSLF works with subclassing, not all\r
+ * child classes work with a {@link CTShape} object, but often contain the same\r
+ * properties. This method is the generalized form of selecting and casting those\r
+ * properties.\r
*\r
- * @return either Color or GradientPaint or TexturePaint or null\r
+ * @param resultClass\r
+ * @param xquery\r
+ * @return\r
*/\r
- @Override\r
- public FillStyle getFillStyle() {\r
- return new FillStyle() {\r
- public PaintStyle getPaint() {\r
- PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {\r
- public boolean fetch(XSLFShape shape) {\r
- CTShapeProperties spPr = shape.getSpPr();\r
- if (spPr.isSetNoFill()) {\r
- setValue(TRANSPARENT_PAINT);\r
- return true;\r
- }\r
- \r
- PaintStyle paint = null;\r
- for (XmlObject obj : spPr.selectPath("*")) {\r
- paint = selectPaint(obj, null, getSheet().getPackagePart());\r
- if (paint != null) break;\r
- }\r
- \r
- if (paint == null) return false;\r
- \r
- setValue(paint);\r
- return true;\r
- }\r
- };\r
- fetchShapeProperty(fetcher);\r
-\r
- PaintStyle paint = fetcher.getValue();\r
-\r
- if (paint != null) return paint;\r
- \r
- // fill color was not found, check if it is defined in the theme\r
- CTShapeStyle style = getSpStyle();\r
- if (style != null) {\r
- // get a reference to a fill style within the style matrix.\r
- CTStyleMatrixReference fillRef = style.getFillRef();\r
- // The idx attribute refers to the index of a fill style or\r
- // background fill style within the presentation's style matrix, defined by the fmtScheme element.\r
- // value of 0 or 1000 indicates no background,\r
- // values 1-999 refer to the index of a fill style within the fillStyleLst element\r
- // values 1001 and above refer to the index of a background fill style within the bgFillStyleLst element.\r
- int idx = (int)fillRef.getIdx();\r
- CTSchemeColor phClr = fillRef.getSchemeClr();\r
- XSLFSheet sheet = _sheet;\r
- XSLFTheme theme = sheet.getTheme();\r
- XmlObject fillProps = null;\r
- CTStyleMatrix matrix = theme.getXmlObject().getThemeElements().getFmtScheme();\r
- if(idx >= 1 && idx <= 999){\r
- fillProps = matrix.getFillStyleLst().selectPath("*")[idx - 1];\r
- } else if (idx >= 1001 ){\r
- fillProps = matrix.getBgFillStyleLst().selectPath("*")[idx - 1001];\r
- }\r
- if(fillProps != null) {\r
- paint = selectPaint(fillProps, phClr, sheet.getPackagePart());\r
- }\r
- }\r
- return paint == RenderableShape.NO_PAINT ? null : paint;\r
- }\r
- };\r
+ @SuppressWarnings("unchecked")\r
+ protected <T extends XmlObject> T selectProperty(Class<T> resultClass, String xquery) {\r
+ XmlObject[] rs = getXmlObject().selectPath(xquery);\r
+ if (rs.length == 0) return null;\r
+ return (resultClass.isInstance(rs[0])) ? (T)rs[0] : null;\r
}\r
\r
/**\r
return ok;\r
}\r
\r
- protected CTPlaceholder getCTPlaceholder() {\r
- if (_ph == null) {\r
- XmlObject[] obj = _shape.selectPath(\r
- "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:nvPr/p:ph");\r
- if (obj.length == 1) {\r
- _ph = (CTPlaceholder) obj[0];\r
- }\r
- }\r
- return _ph;\r
- }\r
- \r
- protected CTShapeStyle getSpStyle() {\r
- if (_spStyle == null) {\r
- for (XmlObject obj : _shape.selectPath("*")) {\r
- if (obj instanceof CTShapeStyle) {\r
- _spStyle = (CTShapeStyle) obj;\r
- }\r
- }\r
- }\r
- return _spStyle;\r
- }\r
-\r
- protected CTNonVisualDrawingProps getNvPr() {\r
- if (_nvPr == null) {\r
- XmlObject[] rs = _shape\r
- .selectPath("declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr");\r
- if (rs.length != 0) {\r
- _nvPr = (CTNonVisualDrawingProps) rs[0];\r
- }\r
- }\r
- return _nvPr;\r
- }\r
-\r
- protected CTShapeProperties getSpPr() {\r
- if (_spPr == null) {\r
- for (XmlObject obj : _shape.selectPath("*")) {\r
- if (obj instanceof CTShapeProperties) {\r
- _spPr = (CTShapeProperties) obj;\r
- }\r
- }\r
- }\r
- if (_spPr == null) {\r
- throw new IllegalStateException("CTShapeProperties was not found.");\r
+ protected PaintStyle getPaint(XmlObject spPr, CTSchemeColor phClr) {\r
+ PaintStyle paint = null;\r
+ PackagePart pp = getSheet().getPackagePart();\r
+ for (XmlObject obj : spPr.selectPath("*")) {\r
+ paint = selectPaint(obj, phClr, pp);\r
+ if(paint != null) break;\r
}\r
- return _spPr;\r
- }\r
-\r
- CTTransform2D getXfrm() {\r
- PropertyFetcher<CTTransform2D> fetcher = new PropertyFetcher<CTTransform2D>() {\r
- public boolean fetch(XSLFShape shape) {\r
- CTShapeProperties pr = shape.getSpPr();\r
- if (pr.isSetXfrm()) {\r
- setValue(pr.getXfrm());\r
- return true;\r
- }\r
- return false;\r
- }\r
- };\r
- fetchShapeProperty(fetcher);\r
- return fetcher.getValue();\r
- }\r
- \r
- /**\r
- * @return the position of this shape within the drawing canvas.\r
- * The coordinates are expressed in points\r
- */\r
- public Rectangle2D getAnchor() {\r
- CTTransform2D xfrm = getXfrm();\r
- if (xfrm == null) return null;\r
-\r
- CTPoint2D off = xfrm.getOff();\r
- long x = off.getX();\r
- long y = off.getY();\r
- CTPositiveSize2D ext = xfrm.getExt();\r
- long cx = ext.getCx();\r
- long cy = ext.getCy();\r
- return new Rectangle2D.Double(\r
- Units.toPoints(x), Units.toPoints(y),\r
- Units.toPoints(cx), Units.toPoints(cy));\r
- }\r
-\r
- /**\r
- * @param anchor the position of this shape within the drawing canvas.\r
- * The coordinates are expressed in points\r
- */\r
- public void setAnchor(Rectangle2D anchor) {\r
- CTShapeProperties spPr = getSpPr();\r
- if (spPr == null) return;\r
- \r
- CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();\r
- CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff();\r
- long x = Units.toEMU(anchor.getX());\r
- long y = Units.toEMU(anchor.getY());\r
- off.setX(x);\r
- off.setY(y);\r
- CTPositiveSize2D ext = xfrm.isSetExt() ? xfrm.getExt() : xfrm\r
- .addNewExt();\r
- long cx = Units.toEMU(anchor.getWidth());\r
- long cy = Units.toEMU(anchor.getHeight());\r
- ext.setCx(cx);\r
- ext.setCy(cy);\r
- }\r
+ return paint == null ? TRANSPARENT_PAINT : paint;\r
+ } \r
\r
/**\r
* Convert shape fill into java.awt.Paint. The result is either Color or\r
* @return the applied Paint or null if none was applied\r
*/\r
protected PaintStyle selectPaint(XmlObject obj, final CTSchemeColor phClr, final PackagePart parentPart) {\r
- final XSLFTheme theme = getSheet().getTheme();\r
-\r
if (obj instanceof CTNoFillProperties) {\r
return TRANSPARENT_PAINT;\r
+ } else if (obj instanceof CTSolidColorFillProperties) {\r
+ return selectPaint((CTSolidColorFillProperties)obj, phClr, parentPart);\r
+ } else if (obj instanceof CTBlipFillProperties) {\r
+ return selectPaint((CTBlipFillProperties)obj, phClr, parentPart);\r
+ } else if (obj instanceof CTGradientFillProperties) {\r
+ return selectPaint((CTGradientFillProperties) obj, phClr, parentPart);\r
+ } else {\r
+ return null;\r
}\r
- \r
- if (obj instanceof CTSolidColorFillProperties) {\r
- CTSolidColorFillProperties solidFill = (CTSolidColorFillProperties) obj;\r
- final XSLFColor c = new XSLFColor(solidFill, theme, phClr);\r
- return new SolidPaint() {\r
- public ColorStyle getSolidColor() {\r
- return c.getColorStyle();\r
- }\r
- };\r
- }\r
- \r
- if (obj instanceof CTBlipFillProperties) {\r
- CTBlipFillProperties blipFill = (CTBlipFillProperties)obj;\r
- final CTBlip blip = blipFill.getBlip();\r
- return new TexturePaint() {\r
- private PackagePart getPart() {\r
- try {\r
- String blipId = blip.getEmbed();\r
- PackageRelationship rel = parentPart.getRelationship(blipId);\r
- return parentPart.getRelatedPart(rel);\r
- } catch (InvalidFormatException e) {\r
- throw new RuntimeException(e);\r
- }\r
+ }\r
+\r
+ protected PaintStyle selectPaint(final CTSolidColorFillProperties solidFill, final CTSchemeColor phClr, final PackagePart parentPart) {\r
+ final XSLFTheme theme = getSheet().getTheme();\r
+ final XSLFColor c = new XSLFColor(solidFill, theme, phClr);\r
+ return new SolidPaint() {\r
+ public ColorStyle getSolidColor() {\r
+ return c.getColorStyle();\r
+ }\r
+ };\r
+ }\r
+ \r
+ protected PaintStyle selectPaint(final CTBlipFillProperties blipFill, final CTSchemeColor phClr, final PackagePart parentPart) {\r
+ final CTBlip blip = blipFill.getBlip();\r
+ return new TexturePaint() {\r
+ private PackagePart getPart() {\r
+ try {\r
+ String blipId = blip.getEmbed();\r
+ PackageRelationship rel = parentPart.getRelationship(blipId);\r
+ return parentPart.getRelatedPart(rel);\r
+ } catch (InvalidFormatException e) {\r
+ throw new RuntimeException(e);\r
}\r
- \r
- public InputStream getImageData() {\r
- try {\r
- return getPart().getInputStream();\r
- } catch (IOException e) {\r
- throw new RuntimeException(e);\r
- }\r
+ }\r
+ \r
+ public InputStream getImageData() {\r
+ try {\r
+ return getPart().getInputStream();\r
+ } catch (IOException e) {\r
+ throw new RuntimeException(e);\r
}\r
+ }\r
\r
- public String getContentType() {\r
- /* TOOD: map content-type */\r
- return getPart().getContentType();\r
- }\r
+ public String getContentType() {\r
+ /* TOOD: map content-type */\r
+ return getPart().getContentType();\r
+ }\r
\r
- public int getAlpha() {\r
- return (blip.sizeOfAlphaModFixArray() > 0)\r
- ? blip.getAlphaModFixArray(0).getAmt()\r
- : 0;\r
- }\r
- };\r
- }\r
- \r
- if (obj instanceof CTGradientFillProperties) {\r
- final CTGradientFillProperties gradFill = (CTGradientFillProperties) obj;\r
+ public int getAlpha() {\r
+ return (blip.sizeOfAlphaModFixArray() > 0)\r
+ ? blip.getAlphaModFixArray(0).getAmt()\r
+ : 0;\r
+ }\r
+ }; \r
+ }\r
+ \r
+ protected PaintStyle selectPaint(final CTGradientFillProperties gradFill, final CTSchemeColor phClr, final PackagePart parentPart) {\r
\r
- @SuppressWarnings("deprecation")\r
- final CTGradientStop[] gs = gradFill.getGsLst().getGsArray();\r
+ @SuppressWarnings("deprecation")\r
+ final CTGradientStop[] gs = gradFill.getGsLst().getGsArray();\r
\r
- Arrays.sort(gs, new Comparator<CTGradientStop>() {\r
- public int compare(CTGradientStop o1, CTGradientStop o2) {\r
- Integer pos1 = o1.getPos();\r
- Integer pos2 = o2.getPos();\r
- return pos1.compareTo(pos2);\r
- }\r
- });\r
+ Arrays.sort(gs, new Comparator<CTGradientStop>() {\r
+ public int compare(CTGradientStop o1, CTGradientStop o2) {\r
+ Integer pos1 = o1.getPos();\r
+ Integer pos2 = o2.getPos();\r
+ return pos1.compareTo(pos2);\r
+ }\r
+ });\r
\r
- final ColorStyle cs[] = new ColorStyle[gs.length];\r
- final float fractions[] = new float[gs.length];\r
- \r
- int i=0;\r
- for (CTGradientStop cgs : gs) {\r
- cs[i] = new XSLFColor(cgs, theme, phClr).getColorStyle();\r
- fractions[i] = cgs.getPos() / 100000.f;\r
+ final ColorStyle cs[] = new ColorStyle[gs.length];\r
+ final float fractions[] = new float[gs.length];\r
+ XSLFTheme theme = getSheet().getTheme();\r
+ \r
+ int i=0;\r
+ for (CTGradientStop cgs : gs) {\r
+ cs[i] = new XSLFColor(cgs, theme, phClr).getColorStyle();\r
+ fractions[i] = cgs.getPos() / 100000.f;\r
+ }\r
+ \r
+ return new GradientPaint() {\r
+\r
+ public double getGradientAngle() {\r
+ return (gradFill.isSetLin())\r
+ ? gradFill.getLin().getAng() / 60000.d\r
+ : 0;\r
}\r
- \r
- return new GradientPaint() {\r
\r
- public double getGradientAngle() {\r
- return (gradFill.isSetLin())\r
- ? gradFill.getLin().getAng() / 60000.d\r
- : 0;\r
- }\r
+ public ColorStyle[] getGradientColors() {\r
+ return cs;\r
+ }\r
\r
- public ColorStyle[] getGradientColors() {\r
- return cs;\r
- }\r
+ public float[] getGradientFractions() {\r
+ return fractions;\r
+ }\r
\r
- public float[] getGradientFractions() {\r
- return fractions;\r
- }\r
+ public boolean isRotatedWithShape() {\r
+ // TODO: is this correct???\r
+ return (gradFill.isSetRotWithShape() || !gradFill.getRotWithShape());\r
+ }\r
\r
- public boolean isRotatedWithShape() {\r
- // TODO: is this correct???\r
- return (gradFill.isSetRotWithShape() || !gradFill.getRotWithShape());\r
+ public GradientType getGradientType() {\r
+ if (gradFill.isSetLin()) {\r
+ return GradientType.linear;\r
}\r
-\r
- public GradientType getGradientType() {\r
- if (gradFill.isSetLin()) {\r
- return GradientType.linear;\r
- }\r
- \r
- if (gradFill.isSetPath()) {\r
- /* TODO: handle rect path */\r
- STPathShadeType.Enum ps = gradFill.getPath().getPath();\r
- if (ps == STPathShadeType.CIRCLE) {\r
- return GradientType.circular;\r
- } else if (ps == STPathShadeType.SHAPE) {\r
- return GradientType.shape;\r
- }\r
+ \r
+ if (gradFill.isSetPath()) {\r
+ /* TODO: handle rect path */\r
+ STPathShadeType.Enum ps = gradFill.getPath().getPath();\r
+ if (ps == STPathShadeType.CIRCLE) {\r
+ return GradientType.circular;\r
+ } else if (ps == STPathShadeType.SHAPE) {\r
+ return GradientType.shape;\r
}\r
- \r
- return GradientType.linear;\r
}\r
- };\r
- }\r
- \r
- return TRANSPARENT_PAINT;\r
+ \r
+ return GradientType.linear;\r
+ }\r
+ }; \r
}\r
+ \r
\r
}
\ No newline at end of file
/**
* Common interface for shape containers, e.g. sheets or groups of shapes
*/
-public interface XSLFShapeContainer extends ShapeContainer {
+public interface XSLFShapeContainer extends ShapeContainer<XSLFShape> {
/**
* create a new shape with a predefined geometry and add it to this shape container
==================================================================== */
package org.apache.poi.xslf.usermodel;
+import java.awt.Graphics2D;
+import java.io.*;
+import java.util.*;
+import java.util.regex.Pattern;
+
+import javax.xml.namespace.QName;
+
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLException;
-import org.apache.poi.openxml4j.opc.OPCPackage;
-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.openxml4j.exceptions.InvalidFormatException;
-import org.apache.poi.sl.usermodel.MasterSheet;
+import org.apache.poi.openxml4j.opc.*;
+import org.apache.poi.sl.draw.DrawFactory;
+import org.apache.poi.sl.draw.Drawable;
import org.apache.poi.sl.usermodel.Sheet;
-import org.apache.poi.util.Beta;
-import org.apache.poi.util.IOUtils;
-import org.apache.poi.util.Internal;
+import org.apache.poi.util.*;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTCommonSlideData;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
-
-import com.sun.org.apache.xml.internal.utils.UnImplNode;
-
-import javax.xml.namespace.QName;
-
-import java.awt.Graphics2D;
-import java.awt.geom.AffineTransform;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
+import org.openxmlformats.schemas.presentationml.x2006.main.*;
@Beta
-public abstract class XSLFSheet extends POIXMLDocumentPart implements XSLFShapeContainer, Sheet {
+public abstract class XSLFSheet extends POIXMLDocumentPart implements XSLFShapeContainer, Sheet<XSLFShape> {
private XSLFCommonSlideData _commonSlideData;
private XSLFDrawing _drawing;
private List<XSLFShape> _shapes;
* @param graphics
*/
public void draw(Graphics2D graphics){
- XSLFSheet master = (XSLFSheet)getMasterSheet();
- if(getFollowMasterGraphics() && master != null) master.draw(graphics);
-
- graphics.setRenderingHint(XSLFRenderingHint.GROUP_TRANSFORM, new AffineTransform());
- for(XSLFShape shape : getShapeList()) {
- if(!canDraw(shape)) continue;
-
- // remember the initial transform and restore it after we are done with drawing
- AffineTransform at = graphics.getTransform();
-
- // concrete implementations can make sense of this hint,
- // for example PSGraphics2D or PDFGraphics2D would call gsave() / grestore
- graphics.setRenderingHint(XSLFRenderingHint.GSAVE, true);
-
- // apply rotation and flipping
- shape.applyTransform(graphics);
- // draw stuff
- shape.draw(graphics);
-
- // restore the coordinate system
- graphics.setTransform(at);
-
- graphics.setRenderingHint(XSLFRenderingHint.GRESTORE, true);
-
- }
+ DrawFactory drawFact = DrawFactory.getInstance(graphics);
+ Drawable draw = drawFact.getDrawable(this);
+ draw.draw(graphics);
}
/**
\r
package org.apache.poi.xslf.usermodel;\r
\r
-import java.awt.*;\r
-import java.awt.Shape;\r
-import java.awt.geom.*;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
+import java.awt.Color;\r
+import java.awt.geom.Rectangle2D;\r
\r
import javax.xml.stream.XMLStreamException;\r
import javax.xml.stream.XMLStreamReader;\r
\r
+import org.apache.poi.sl.draw.DrawPaint;\r
import org.apache.poi.sl.draw.geom.*;\r
import org.apache.poi.sl.usermodel.*;\r
+import org.apache.poi.sl.usermodel.LineDecoration.DecorationShape;\r
+import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize;\r
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;\r
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;\r
import org.apache.poi.util.Beta;\r
import org.apache.poi.xslf.model.PropertyFetcher;\r
import org.apache.xmlbeans.XmlObject;\r
import org.openxmlformats.schemas.drawingml.x2006.main.*;\r
-import org.openxmlformats.schemas.presentationml.x2006.main.*;\r
+import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;\r
\r
/**\r
* Represents a single (non-group) shape in a .pptx slide show\r
super(shape,sheet);\r
}\r
\r
- /**\r
- *\r
- * @return the sheet this shape belongs to\r
- */\r
- public XSLFSheet getSheet() {\r
- return _sheet;\r
- }\r
-\r
/**\r
*\r
* @param type\r
*/\r
public void setShapeType(ShapeType type){\r
- CTShape shape = (CTShape) getXmlObject();\r
STShapeType.Enum geom = STShapeType.Enum.forInt(type.ooxmlId);\r
- shape.getSpPr().getPrstGeom().setPrst(geom);\r
+ getSpPr().getPrstGeom().setPrst(geom);\r
}\r
\r
public ShapeType getShapeType(){\r
- CTShape shape = (CTShape) getXmlObject();\r
- STShapeType.Enum geom = shape.getSpPr().getPrstGeom().getPrst();\r
+ STShapeType.Enum geom = getSpPr().getPrstGeom().getPrst();\r
return ShapeType.forId(geom.intValue(), true);\r
}\r
+ \r
+ protected CTTransform2D getSafeXfrm() {\r
+ CTTransform2D xfrm = getXfrm();\r
+ return (xfrm == null ? getSpPr().addNewXfrm() : xfrm);\r
+ }\r
+ \r
+ protected CTTransform2D getXfrm() {\r
+ PropertyFetcher<CTTransform2D> fetcher = new PropertyFetcher<CTTransform2D>() {\r
+ public boolean fetch(XSLFShape shape) {\r
+ CTShapeProperties pr = getSpPr();\r
+ if (pr.isSetXfrm()) {\r
+ setValue(pr.getXfrm());\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+ };\r
+ fetchShapeProperty(fetcher);\r
+ return fetcher.getValue();\r
+ }\r
\r
@Override\r
- public String getShapeName() {\r
- return getNvPr().getName();\r
+ public Rectangle2D getAnchor() {\r
+\r
+ CTTransform2D xfrm = getXfrm();\r
+\r
+ CTPoint2D off = xfrm.getOff();\r
+ long x = off.getX();\r
+ long y = off.getY();\r
+ CTPositiveSize2D ext = xfrm.getExt();\r
+ long cx = ext.getCx();\r
+ long cy = ext.getCy();\r
+ return new Rectangle2D.Double(\r
+ Units.toPoints(x), Units.toPoints(y),\r
+ Units.toPoints(cx), Units.toPoints(cy));\r
}\r
\r
@Override\r
- public int getShapeId() {\r
- return (int) getNvPr().getId();\r
+ public void setAnchor(Rectangle2D anchor) {\r
+ CTTransform2D xfrm = getSafeXfrm();\r
+ CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff();\r
+ long x = Units.toEMU(anchor.getX());\r
+ long y = Units.toEMU(anchor.getY());\r
+ off.setX(x);\r
+ off.setY(y);\r
+ CTPositiveSize2D ext = xfrm.isSetExt() ? xfrm.getExt() : xfrm\r
+ .addNewExt();\r
+ long cx = Units.toEMU(anchor.getWidth());\r
+ long cy = Units.toEMU(anchor.getHeight());\r
+ ext.setCx(cx);\r
+ ext.setCy(cy);\r
}\r
-\r
+ \r
@Override\r
public void setRotation(double theta) {\r
- CTShapeProperties spPr = getSpPr();\r
- CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();\r
- xfrm.setRot((int) (theta * 60000));\r
+ getSafeXfrm().setRot((int) (theta * 60000));\r
}\r
\r
@Override\r
public double getRotation() {\r
CTTransform2D xfrm = getXfrm();\r
- return (double) xfrm.getRot() / 60000;\r
+ return (xfrm == null || !xfrm.isSetRot()) ? 0 : (xfrm.getRot() / 60000.d);\r
}\r
\r
@Override\r
public void setFlipHorizontal(boolean flip) {\r
- CTShapeProperties spPr = getSpPr();\r
- CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();\r
- xfrm.setFlipH(flip);\r
+ getSafeXfrm().setFlipH(flip);\r
}\r
\r
@Override\r
public void setFlipVertical(boolean flip) {\r
- CTShapeProperties spPr = getSpPr();\r
- CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();\r
- xfrm.setFlipV(flip);\r
+ getSafeXfrm().setFlipV(flip);\r
}\r
\r
@Override\r
public boolean getFlipHorizontal() {\r
- return getXfrm().getFlipH();\r
+ CTTransform2D xfrm = getXfrm();\r
+ return (xfrm == null || !xfrm.isSetFlipH()) ? false : getXfrm().getFlipH();\r
}\r
\r
@Override\r
public boolean getFlipVertical() {\r
- return getXfrm().getFlipV();\r
+ CTTransform2D xfrm = getXfrm();\r
+ return (xfrm == null || !xfrm.isSetFlipV()) ? false : getXfrm().getFlipV();\r
}\r
\r
+ \r
/**\r
* Get default line properties defined in the theme (if any).\r
* Used internally to resolve shape properties.\r
if (style != null) {\r
// 1-based index of a line style within the style matrix\r
int idx = (int) style.getLnRef().getIdx();\r
- CTStyleMatrix styleMatrix = _sheet.getTheme().getXmlObject().getThemeElements().getFmtScheme();\r
+ CTStyleMatrix styleMatrix = getSheet().getTheme().getXmlObject().getThemeElements().getFmtScheme();\r
ln = styleMatrix.getLnStyleLst().getLnArray(idx - 1);\r
}\r
return ln;\r
* if outline is turned off\r
*/\r
public Color getLineColor() {\r
- RenderableShape rShape = new RenderableShape(this);\r
- Paint paint = rShape.getLinePaint(null);\r
- if (paint instanceof Color) {\r
- return (Color) paint;\r
+ PaintStyle ps = getLinePaint();\r
+ if (ps == null || ps == TRANSPARENT_PAINT) return null;\r
+ if (ps instanceof SolidPaint) {\r
+ Color col = ((SolidPaint)ps).getSolidColor().getColor();\r
+ return (col == DrawPaint.NO_PAINT) ? null : col;\r
}\r
return null;\r
}\r
\r
+ protected PaintStyle getLinePaint() {\r
+ PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {\r
+ public boolean fetch(XSLFShape shape) {\r
+ CTLineProperties spPr = shape.getSpPr().getLn();\r
+ if (spPr != null) {\r
+ if (spPr.isSetNoFill()) {\r
+ setValue(TRANSPARENT_PAINT); // use it as 'nofill' value\r
+ return true;\r
+ }\r
+ PaintStyle paint = getPaint(spPr, null);\r
+ if (paint != null) {\r
+ setValue(paint);\r
+ return true;\r
+ }\r
+ }\r
+ return false;\r
+\r
+ }\r
+ };\r
+ fetchShapeProperty(fetcher);\r
+\r
+ PaintStyle paint = fetcher.getValue();\r
+ if (paint != null) return paint;\r
+ \r
+ // line color was not found, check if it is defined in the theme\r
+ CTShapeStyle style = getSpStyle();\r
+ if (style == null) return TRANSPARENT_PAINT;\r
+ \r
+ // get a reference to a line style within the style matrix.\r
+ CTStyleMatrixReference lnRef = style.getLnRef();\r
+ int idx = (int)lnRef.getIdx();\r
+ CTSchemeColor phClr = lnRef.getSchemeClr();\r
+ if(idx > 0){\r
+ XSLFTheme theme = getSheet().getTheme();\r
+ XmlObject lnProps = theme.getXmlObject().\r
+ getThemeElements().getFmtScheme().getLnStyleLst().selectPath("*")[idx - 1];\r
+ paint = getPaint(lnProps, phClr);\r
+ }\r
+\r
+ return paint == null ? TRANSPARENT_PAINT : paint;\r
+ }\r
+ \r
/**\r
*\r
* @param width line width in points. <code>0</code> means no line\r
* is not solid (pattern or gradient)\r
*/\r
public Color getFillColor() {\r
- RenderableShape rShape = new RenderableShape(this);\r
- Paint paint = rShape.getFillPaint(null);\r
- if (paint instanceof Color) {\r
- return (Color) paint;\r
+ PaintStyle ps = getFillPaint();\r
+ if (ps == null || ps == TRANSPARENT_PAINT) return null;\r
+ if (ps instanceof SolidPaint) {\r
+ Color col = ((SolidPaint)ps).getSolidColor().getColor();\r
+ return (col == DrawPaint.NO_PAINT) ? null : col;\r
}\r
return null;\r
}\r
// 1-based index of a shadow style within the style matrix\r
int idx = (int) style.getEffectRef().getIdx();\r
if(idx != 0) {\r
- CTStyleMatrix styleMatrix = _sheet.getTheme().getXmlObject().getThemeElements().getFmtScheme();\r
+ CTStyleMatrix styleMatrix = getSheet().getTheme().getXmlObject().getThemeElements().getFmtScheme();\r
CTEffectStyleItem ef = styleMatrix.getEffectStyleLst().getEffectStyleArray(idx - 1);\r
obj = ef.getEffectLst().getOuterShdw();\r
}\r
/**\r
* Specifies the line end decoration, such as a triangle or arrowhead.\r
*/\r
- public void setLineHeadDecoration(LineDecoration style) {\r
+ public void setLineHeadDecoration(DecorationShape style) {\r
CTLineProperties ln = getSpPr().getLn();\r
CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();\r
if (style == null) {\r
}\r
}\r
\r
- public LineDecoration getLineHeadDecoration() {\r
+ public DecorationShape getLineHeadDecoration() {\r
CTLineProperties ln = getSpPr().getLn();\r
- if (ln == null || !ln.isSetHeadEnd()) return LineDecoration.NONE;\r
+ if (ln == null || !ln.isSetHeadEnd()) return DecorationShape.NONE;\r
\r
STLineEndType.Enum end = ln.getHeadEnd().getType();\r
- return end == null ? LineDecoration.NONE : LineDecoration.values()[end.intValue() - 1];\r
+ return end == null ? DecorationShape.NONE : DecorationShape.values()[end.intValue() - 1];\r
}\r
\r
/**\r
* specifies decorations which can be added to the head of a line.\r
*/\r
- public void setLineHeadWidth(LineEndWidth style) {\r
+ public void setLineHeadWidth(DecorationSize style) {\r
CTLineProperties ln = getSpPr().getLn();\r
CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();\r
if (style == null) {\r
}\r
}\r
\r
- public LineEndWidth getLineHeadWidth() {\r
+ public DecorationSize getLineHeadWidth() {\r
CTLineProperties ln = getSpPr().getLn();\r
- if (ln == null || !ln.isSetHeadEnd()) return LineEndWidth.MEDIUM;\r
+ if (ln == null || !ln.isSetHeadEnd()) return DecorationSize.MEDIUM;\r
\r
STLineEndWidth.Enum w = ln.getHeadEnd().getW();\r
- return w == null ? LineEndWidth.MEDIUM : LineEndWidth.values()[w.intValue() - 1];\r
+ return w == null ? DecorationSize.MEDIUM : DecorationSize.values()[w.intValue() - 1];\r
}\r
\r
/**\r
* Specifies the line end width in relation to the line width.\r
*/\r
- public void setLineHeadLength(LineEndLength style) {\r
+ public void setLineHeadLength(DecorationSize style) {\r
CTLineProperties ln = getSpPr().getLn();\r
CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();\r
\r
}\r
}\r
\r
- public LineEndLength getLineHeadLength() {\r
+ public DecorationSize getLineHeadLength() {\r
CTLineProperties ln = getSpPr().getLn();\r
- if (ln == null || !ln.isSetHeadEnd()) return LineEndLength.MEDIUM;\r
+ if (ln == null || !ln.isSetHeadEnd()) return DecorationSize.MEDIUM;\r
\r
STLineEndLength.Enum len = ln.getHeadEnd().getLen();\r
- return len == null ? LineEndLength.MEDIUM : LineEndLength.values()[len.intValue() - 1];\r
+ return len == null ? DecorationSize.MEDIUM : DecorationSize.values()[len.intValue() - 1];\r
}\r
\r
/**\r
* Specifies the line end decoration, such as a triangle or arrowhead.\r
*/\r
- public void setLineTailDecoration(LineDecoration style) {\r
+ public void setLineTailDecoration(DecorationShape style) {\r
CTLineProperties ln = getSpPr().getLn();\r
CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();\r
if (style == null) {\r
}\r
}\r
\r
- public LineDecoration getLineTailDecoration() {\r
+ public DecorationShape getLineTailDecoration() {\r
CTLineProperties ln = getSpPr().getLn();\r
- if (ln == null || !ln.isSetTailEnd()) return LineDecoration.NONE;\r
+ if (ln == null || !ln.isSetTailEnd()) return DecorationShape.NONE;\r
\r
STLineEndType.Enum end = ln.getTailEnd().getType();\r
- return end == null ? LineDecoration.NONE : LineDecoration.values()[end.intValue() - 1];\r
+ return end == null ? DecorationShape.NONE : DecorationShape.values()[end.intValue() - 1];\r
}\r
\r
/**\r
* specifies decorations which can be added to the tail of a line.\r
*/\r
- public void setLineTailWidth(LineEndWidth style) {\r
+ public void setLineTailWidth(DecorationSize style) {\r
CTLineProperties ln = getSpPr().getLn();\r
CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();\r
if (style == null) {\r
}\r
}\r
\r
- public LineEndWidth getLineTailWidth() {\r
+ public DecorationSize getLineTailWidth() {\r
CTLineProperties ln = getSpPr().getLn();\r
- if (ln == null || !ln.isSetTailEnd()) return LineEndWidth.MEDIUM;\r
+ if (ln == null || !ln.isSetTailEnd()) return DecorationSize.MEDIUM;\r
\r
STLineEndWidth.Enum w = ln.getTailEnd().getW();\r
- return w == null ? LineEndWidth.MEDIUM : LineEndWidth.values()[w.intValue() - 1];\r
+ return w == null ? DecorationSize.MEDIUM : DecorationSize.values()[w.intValue() - 1];\r
}\r
\r
/**\r
* Specifies the line end width in relation to the line width.\r
*/\r
- public void setLineTailLength(LineEndLength style) {\r
+ public void setLineTailLength(DecorationSize style) {\r
CTLineProperties ln = getSpPr().getLn();\r
CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();\r
\r
}\r
}\r
\r
- public LineEndLength getLineTailLength() {\r
+ public DecorationSize getLineTailLength() {\r
CTLineProperties ln = getSpPr().getLn();\r
- if (ln == null || !ln.isSetTailEnd()) return LineEndLength.MEDIUM;\r
+ if (ln == null || !ln.isSetTailEnd()) return DecorationSize.MEDIUM;\r
\r
STLineEndLength.Enum len = ln.getTailEnd().getLen();\r
- return len == null ? LineEndLength.MEDIUM : LineEndLength.values()[len.intValue() - 1];\r
- }\r
-\r
- Outline getTailDecoration(Graphics2D graphics) {\r
- LineEndLength tailLength = getLineTailLength();\r
- LineEndWidth tailWidth = getLineTailWidth();\r
-\r
- double lineWidth = Math.max(2.5, getLineWidth());\r
-\r
- Rectangle2D anchor = new RenderableShape(this).getAnchor(graphics);\r
- double x2 = anchor.getX() + anchor.getWidth(),\r
- y2 = anchor.getY() + anchor.getHeight();\r
-\r
- double alpha = Math.atan(anchor.getHeight() / anchor.getWidth());\r
-\r
- AffineTransform at = new AffineTransform();\r
- Shape shape = null;\r
- Path p = null;\r
- Rectangle2D bounds;\r
- double scaleY = Math.pow(2, tailWidth.ordinal());\r
- double scaleX = Math.pow(2, tailLength.ordinal());\r
- switch (getLineTailDecoration()) {\r
- case OVAL:\r
- p = new Path();\r
- shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);\r
- bounds = shape.getBounds2D();\r
- at.translate(x2 - bounds.getWidth() / 2, y2 - bounds.getHeight() / 2);\r
- at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2);\r
- break;\r
- case ARROW:\r
- p = new Path();\r
- GeneralPath arrow = new GeneralPath();\r
- arrow.moveTo((float) (-lineWidth * 3), (float) (-lineWidth * 2));\r
- arrow.lineTo(0, 0);\r
- arrow.lineTo((float) (-lineWidth * 3), (float) (lineWidth * 2));\r
- shape = arrow;\r
- at.translate(x2, y2);\r
- at.rotate(alpha);\r
- break;\r
- case TRIANGLE:\r
- p = new Path();\r
- scaleY = tailWidth.ordinal() + 1;\r
- scaleX = tailLength.ordinal() + 1;\r
- GeneralPath triangle = new GeneralPath();\r
- triangle.moveTo((float) (-lineWidth * scaleX), (float) (-lineWidth * scaleY / 2));\r
- triangle.lineTo(0, 0);\r
- triangle.lineTo((float) (-lineWidth * scaleX), (float) (lineWidth * scaleY / 2));\r
- triangle.closePath();\r
- shape = triangle;\r
- at.translate(x2, y2);\r
- at.rotate(alpha);\r
- break;\r
- default:\r
- break;\r
- }\r
-\r
- if (shape != null) {\r
- shape = at.createTransformedShape(shape);\r
- }\r
- return shape == null ? null : new Outline(shape, p);\r
- }\r
-\r
- Outline getHeadDecoration(Graphics2D graphics) {\r
- LineEndLength headLength = getLineHeadLength();\r
- LineEndWidth headWidth = getLineHeadWidth();\r
-\r
- double lineWidth = Math.max(2.5, getLineWidth());\r
-\r
- Rectangle2D anchor = new RenderableShape(this).getAnchor(graphics);\r
- double x1 = anchor.getX(),\r
- y1 = anchor.getY();\r
-\r
- double alpha = Math.atan(anchor.getHeight() / anchor.getWidth());\r
-\r
- AffineTransform at = new AffineTransform();\r
- Shape shape = null;\r
- Path p = null;\r
- Rectangle2D bounds;\r
- double scaleY = 1;\r
- double scaleX = 1;\r
- switch (getLineHeadDecoration()) {\r
- case OVAL:\r
- p = new Path();\r
- shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);\r
- bounds = shape.getBounds2D();\r
- at.translate(x1 - bounds.getWidth() / 2, y1 - bounds.getHeight() / 2);\r
- at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2);\r
- break;\r
- case STEALTH:\r
- case ARROW:\r
- p = new Path(false, true);\r
- GeneralPath arrow = new GeneralPath();\r
- arrow.moveTo((float) (lineWidth * 3 * scaleX), (float) (-lineWidth * scaleY * 2));\r
- arrow.lineTo(0, 0);\r
- arrow.lineTo((float) (lineWidth * 3 * scaleX), (float) (lineWidth * scaleY * 2));\r
- shape = arrow;\r
- at.translate(x1, y1);\r
- at.rotate(alpha);\r
- break;\r
- case TRIANGLE:\r
- p = new Path();\r
- scaleY = headWidth.ordinal() + 1;\r
- scaleX = headLength.ordinal() + 1;\r
- GeneralPath triangle = new GeneralPath();\r
- triangle.moveTo((float) (lineWidth * scaleX), (float) (-lineWidth * scaleY / 2));\r
- triangle.lineTo(0, 0);\r
- triangle.lineTo((float) (lineWidth * scaleX), (float) (lineWidth * scaleY / 2));\r
- triangle.closePath();\r
- shape = triangle;\r
- at.translate(x1, y1);\r
- at.rotate(alpha);\r
- break;\r
- default:\r
- break;\r
- }\r
-\r
- if (shape != null) {\r
- shape = at.createTransformedShape(shape);\r
- }\r
- return shape == null ? null : new Outline(shape, p);\r
- }\r
-\r
- private List<Outline> getDecorationOutlines(Graphics2D graphics){\r
- List<Outline> lst = new ArrayList<Outline>();\r
-\r
- Outline head = getHeadDecoration(graphics);\r
- if(head != null) lst.add(head);\r
-\r
- Outline tail = getTailDecoration(graphics);\r
- if(tail != null) lst.add(tail);\r
- return lst;\r
+ return len == null ? DecorationSize.MEDIUM : DecorationSize.values()[len.intValue() - 1];\r
}\r
\r
public boolean isPlaceholder() {\r
return ph != null;\r
}\r
\r
- public Hyperlink getHyperlink() {\r
- // TODO Auto-generated method stub\r
+ @SuppressWarnings("deprecation")\r
+ public Guide getAdjustValue(String name) {\r
+ CTPresetGeometry2D prst = getSpPr().getPrstGeom();\r
+ if (prst.isSetAvLst()) {\r
+ for (CTGeomGuide g : prst.getAvLst().getGdArray()) {\r
+ if (g.getName().equals(name)) {\r
+ return new Guide(g.getName(), g.getFmla());\r
+ }\r
+ }\r
+ }\r
+\r
return null;\r
}\r
\r
- public void setHyperlink(Hyperlink hyperlink) {\r
- // TODO Auto-generated method stub\r
- \r
+ public LineDecoration getLineDecoration() {\r
+ return new LineDecoration() {\r
+ public DecorationShape getHeadShape() {\r
+ return getLineHeadDecoration();\r
+ }\r
+\r
+ public DecorationSize getHeadWidth() {\r
+ return getLineHeadWidth();\r
+ }\r
+\r
+ public DecorationSize getHeadLength() {\r
+ return getLineHeadLength();\r
+ }\r
+\r
+ public DecorationShape getTailShape() {\r
+ return getLineTailDecoration();\r
+ }\r
+\r
+ public DecorationSize getTailWidth() {\r
+ return getLineTailWidth();\r
+ }\r
+\r
+ public DecorationSize getTailLength() {\r
+ return getLineTailLength();\r
+ }\r
+ };\r
}\r
\r
- public Guide getAdjustValue(String name) {\r
- // TODO Auto-generated method stub\r
- return null;\r
+ /**\r
+ * fetch shape fill as a java.awt.Paint\r
+ *\r
+ * @return either Color or GradientPaint or TexturePaint or null\r
+ */\r
+ public FillStyle getFillStyle() {\r
+ return new FillStyle() {\r
+ public PaintStyle getPaint() {\r
+ return XSLFSimpleShape.this.getFillPaint();\r
+ }\r
+ };\r
}\r
\r
- public org.apache.poi.sl.usermodel.LineDecoration getLineDecoration() {\r
- // TODO Auto-generated method stub\r
- return null;\r
+ public StrokeStyle getStrokeStyle() {\r
+ return new StrokeStyle() {\r
+ public PaintStyle getPaint() {\r
+ return XSLFSimpleShape.this.getLinePaint();\r
+ }\r
+\r
+ public LineCap getLineCap() {\r
+ return XSLFSimpleShape.this.getLineCap();\r
+ }\r
+\r
+ public LineDash getLineDash() {\r
+ return XSLFSimpleShape.this.getLineDash();\r
+ }\r
+\r
+ public double getLineWidth() {\r
+ return XSLFSimpleShape.this.getLineWidth();\r
+ }\r
+ \r
+ };\r
}\r
- \r
- \r
}\r
==================================================================== */
package org.apache.poi.xslf.usermodel;
-import java.awt.Graphics2D;
import java.io.IOException;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.util.Beta;
import org.apache.xmlbeans.XmlException;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupTransform2D;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTCommonSlideData;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShapeNonVisual;
-import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide;
-import org.openxmlformats.schemas.presentationml.x2006.main.SldDocument;
+import org.openxmlformats.schemas.drawingml.x2006.main.*;
+import org.openxmlformats.schemas.presentationml.x2006.main.*;
@Beta
-public final class XSLFSlide extends XSLFSheet implements Slide {
+public final class XSLFSlide extends XSLFSheet implements Slide<XSLFShape> {
private final CTSlide _slide;
private XSLFSlideLayout _layout;
private XSLFComments _comments;
setFollowMasterGraphics(follow);
}
-
- @Override
- public void draw(Graphics2D graphics){
-
- XSLFBackground bg = getBackground();
- if(bg != null) bg.draw(graphics);
-
- super.draw(graphics);
- }
-
-
@Override
public XSLFSlide importContent(XSLFSheet src){
super.importContent(src);
import java.io.IOException;
@Beta
-public class XSLFSlideLayout extends XSLFSheet implements MasterSheet {
+public class XSLFSlideLayout extends XSLFSheet implements MasterSheet<XSLFShape> {
private CTSlideLayout _layout;
private XSLFSlideMaster _master;
* @author Yegor Kozlov
*/
@Beta
- public class XSLFSlideMaster extends XSLFSheet implements MasterSheet {
+ public class XSLFSlideMaster extends XSLFSheet implements MasterSheet<XSLFShape> {
private CTSlideMaster _slide;
private Map<String, XSLFSlideLayout> _layouts;
private XSLFTheme _theme;
\r
import org.apache.poi.sl.usermodel.VerticalAlignment;\r
import org.apache.poi.util.Units;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTLineEndProperties;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCellProperties;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.STCompoundLine;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndLength;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndType;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndWidth;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.STPenAlignment;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.*;\r
\r
/**\r
* Represents a cell of a table in a .pptx presentation\r
- *\r
- * @author Yegor Kozlov\r
*/\r
public class XSLFTableCell extends XSLFTextShape {\r
static double defaultBorderWidth = 1.0;\r
+ private CTTableCellProperties _tcPr = null;\r
\r
/*package*/ XSLFTableCell(CTTableCell cell, XSLFSheet sheet){\r
super(cell, sheet);\r
}\r
\r
- @Override\r
- public CTTableCell getXmlObject(){\r
- return (CTTableCell)super.getXmlObject();\r
- }\r
-\r
@Override\r
protected CTTextBody getTextBody(boolean create){\r
- CTTableCell cell = getXmlObject();\r
+ CTTableCell cell = (CTTableCell)getXmlObject();\r
CTTextBody txBody = cell.getTxBody();\r
if (txBody == null && create) {\r
txBody = cell.addNewTxBody();\r
return cell;\r
}\r
\r
+ protected CTTableCellProperties getCellProperties(boolean create) {\r
+ if (_tcPr == null) {\r
+ CTTableCell cell = (CTTableCell)getXmlObject();\r
+ _tcPr = cell.getTcPr();\r
+ if (_tcPr == null && create) {\r
+ _tcPr = cell.addNewTcPr();\r
+ }\r
+ }\r
+ return _tcPr;\r
+ }\r
+ \r
@Override\r
public void setLeftInset(double margin){\r
- CTTableCellProperties pr = getXmlObject().getTcPr();\r
- if(pr == null) pr = getXmlObject().addNewTcPr();\r
-\r
+ CTTableCellProperties pr = getCellProperties(true);\r
pr.setMarL(Units.toEMU(margin));\r
}\r
\r
@Override\r
public void setRightInset(double margin){\r
- CTTableCellProperties pr = getXmlObject().getTcPr();\r
- if(pr == null) pr = getXmlObject().addNewTcPr();\r
-\r
+ CTTableCellProperties pr = getCellProperties(true);\r
pr.setMarR(Units.toEMU(margin));\r
}\r
\r
@Override\r
public void setTopInset(double margin){\r
- CTTableCellProperties pr = getXmlObject().getTcPr();\r
- if(pr == null) pr = getXmlObject().addNewTcPr();\r
-\r
+ CTTableCellProperties pr = getCellProperties(true);\r
pr.setMarT(Units.toEMU(margin));\r
}\r
\r
@Override\r
public void setBottomInset(double margin){\r
- CTTableCellProperties pr = getXmlObject().getTcPr();\r
- if(pr == null) pr = getXmlObject().addNewTcPr();\r
-\r
+ CTTableCellProperties pr = getCellProperties(true);\r
pr.setMarB(Units.toEMU(margin));\r
}\r
\r
- public void setBorderLeft(double width){\r
- CTTableCellProperties pr = getXmlObject().getTcPr();\r
-\r
- CTLineProperties ln = pr.isSetLnL() ? pr.getLnL() : pr.addNewLnL();\r
- ln.setW(Units.toEMU(width));\r
- }\r
-\r
- public double getBorderLeft(){\r
- CTTableCellProperties pr = getXmlObject().getTcPr();\r
-\r
- CTLineProperties ln = pr.getLnL();\r
- return ln == null || !ln.isSetW() ? defaultBorderWidth : Units.toPoints(ln.getW());\r
- }\r
-\r
- public void setBorderLeftColor(Color color){\r
- CTTableCellProperties pr = getXmlObject().getTcPr();\r
- CTLineProperties ln = pr.isSetLnL() ? pr.getLnL() : pr.addNewLnL();\r
- setLineColor(ln, color);\r
- }\r
-\r
- public Color getBorderLeftColor(){\r
- return getLineColor(getXmlObject().getTcPr().getLnL());\r
- }\r
-\r
- public void setBorderRight(double width){\r
- CTTableCellProperties pr = getXmlObject().getTcPr();\r
-\r
- CTLineProperties ln = pr.isSetLnR() ? pr.getLnR() : pr.addNewLnR();\r
- ln.setW(Units.toEMU(width));\r
- }\r
-\r
- public double getBorderRight(){\r
- CTTableCellProperties pr = getXmlObject().getTcPr();\r
-\r
- CTLineProperties ln = pr.getLnR();\r
- return ln == null || !ln.isSetW() ? defaultBorderWidth : Units.toPoints(ln.getW());\r
- }\r
-\r
- public void setBorderRightColor(Color color){\r
- CTTableCellProperties pr = getXmlObject().getTcPr();\r
- CTLineProperties ln = pr.isSetLnR() ? pr.getLnR() : pr.addNewLnR();\r
- setLineColor(ln, color);\r
- }\r
-\r
- public Color getBorderRightColor(){\r
- return getLineColor(getXmlObject().getTcPr().getLnR());\r
- }\r
-\r
- public void setBorderTop(double width){\r
- CTTableCellProperties pr = getXmlObject().getTcPr();\r
-\r
- CTLineProperties ln = pr.isSetLnT() ? pr.getLnT() : pr.addNewLnT();\r
- ln.setW(Units.toEMU(width));\r
- }\r
-\r
- public double getBorderTop(){\r
- CTTableCellProperties pr = getXmlObject().getTcPr();\r
-\r
- CTLineProperties ln = pr.getLnT();\r
- return ln == null || !ln.isSetW() ? defaultBorderWidth : Units.toPoints(ln.getW());\r
- }\r
-\r
- public void setBorderTopColor(Color color){\r
- CTTableCellProperties pr = getXmlObject().getTcPr();\r
- CTLineProperties ln = pr.isSetLnT() ? pr.getLnT() : pr.addNewLnT();\r
- setLineColor(ln, color);\r
- }\r
-\r
- public Color getBorderTopColor(){\r
- return getLineColor(getXmlObject().getTcPr().getLnT());\r
+ private CTLineProperties getCTLine(char bltr, boolean create) {\r
+ CTTableCellProperties pr = getCellProperties(create);\r
+ if (pr == null) return null;\r
+ \r
+ switch (bltr) {\r
+ case 'b':\r
+ return (pr.isSetLnB()) ? pr.getLnB() : (create ? pr.addNewLnB() : null);\r
+ case 'l':\r
+ return (pr.isSetLnL()) ? pr.getLnL() : (create ? pr.addNewLnL() : null);\r
+ case 't':\r
+ return (pr.isSetLnT()) ? pr.getLnT() : (create ? pr.addNewLnT() : null);\r
+ case 'r':\r
+ return (pr.isSetLnR()) ? pr.getLnR() : (create ? pr.addNewLnR() : null);\r
+ default:\r
+ return null;\r
+ }\r
}\r
-\r
- public void setBorderBottom(double width){\r
- CTTableCellProperties pr = getXmlObject().getTcPr();\r
-\r
- CTLineProperties ln = pr.isSetLnB() ? pr.getLnB() : pr.addNewLnB();\r
+ \r
+ private void setBorderWidth(char bltr, double width) {\r
+ CTLineProperties ln = getCTLine(bltr, true);\r
ln.setW(Units.toEMU(width));\r
}\r
\r
- public double getBorderBottom(){\r
- CTTableCellProperties pr = getXmlObject().getTcPr();\r
-\r
- CTLineProperties ln = pr.getLnB();\r
- return ln == null || !ln.isSetW() ? defaultBorderWidth : Units.toPoints(ln.getW());\r
+ private double getBorderWidth(char bltr) {\r
+ CTLineProperties ln = getCTLine(bltr, false);\r
+ return (ln == null) ? defaultBorderWidth : Units.toPoints(ln.getW());\r
}\r
\r
- public void setBorderBottomColor(Color color){\r
- CTTableCellProperties pr = getXmlObject().getTcPr();\r
- CTLineProperties ln = pr.isSetLnB() ? pr.getLnB() : pr.addNewLnB();\r
- setLineColor(ln, color);\r
- }\r
+ private void setBorderColor(char bltr, Color color) {\r
+ CTLineProperties ln = getCTLine(bltr, true);\r
\r
- public Color getBorderBottomColor(){\r
- return getLineColor(getXmlObject().getTcPr().getLnB());\r
- }\r
-\r
- private void setLineColor(CTLineProperties ln, Color color){\r
if(color == null){\r
ln.addNewNoFill();\r
if(ln.isSetSolidFill()) ln.unsetSolidFill();\r
rgb.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()});\r
ln.addNewSolidFill().setSrgbClr(rgb);\r
}\r
- }\r
-\r
- private Color getLineColor(CTLineProperties ln){\r
- if(ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) return null;\r
+ } \r
+ \r
+ private Color getBorderColor(char bltr) {\r
+ CTLineProperties ln = getCTLine(bltr,false);\r
+ if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) return null;\r
\r
CTSolidColorFillProperties fill = ln.getSolidFill();\r
- if(!fill.isSetSrgbClr()) {\r
+ if (!fill.isSetSrgbClr()) {\r
// TODO for now return null for all colors except explicit RGB\r
return null;\r
}\r
byte[] val = fill.getSrgbClr().getVal();\r
return new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]);\r
+ } \r
+ \r
+ public void setBorderLeft(double width) {\r
+ setBorderWidth('l', width);\r
}\r
+\r
+ public double getBorderLeft() {\r
+ return getBorderWidth('l');\r
+ }\r
+\r
+ public void setBorderLeftColor(Color color) {\r
+ setBorderColor('l', color);\r
+ }\r
+\r
+ public Color getBorderLeftColor() {\r
+ return getBorderColor('l');\r
+ }\r
+\r
+ public void setBorderRight(double width) {\r
+ setBorderWidth('r', width);\r
+ }\r
+\r
+ public double getBorderRight() {\r
+ return getBorderWidth('r');\r
+ }\r
+\r
+ public void setBorderRightColor(Color color) {\r
+ setBorderColor('r', color);\r
+ }\r
+\r
+ public Color getBorderRightColor() {\r
+ return getBorderColor('r');\r
+ }\r
+\r
+ public void setBorderTop(double width) {\r
+ setBorderWidth('t', width);\r
+ }\r
+\r
+ public double getBorderTop() {\r
+ return getBorderWidth('t');\r
+ }\r
+\r
+ public void setBorderTopColor(Color color) {\r
+ setBorderColor('t', color);\r
+ }\r
+\r
+ public Color getBorderTopColor() {\r
+ return getBorderColor('t');\r
+ }\r
+\r
+ public void setBorderBottom(double width) {\r
+ setBorderWidth('b', width);\r
+ }\r
+\r
+ public double getBorderBottom() {\r
+ return getBorderWidth('b');\r
+ }\r
+\r
+ public void setBorderBottomColor(Color color) {\r
+ setBorderColor('b', color);\r
+ }\r
+\r
+ public Color getBorderBottomColor(){\r
+ return getBorderColor('b');\r
+ }\r
+\r
/**\r
* Specifies a solid color fill. The shape is filled entirely with the specified color.\r
*\r
*/\r
@Override\r
public void setFillColor(Color color) {\r
- CTTableCellProperties spPr = getXmlObject().getTcPr();\r
+ CTTableCellProperties spPr = getCellProperties(true);\r
if (color == null) {\r
if(spPr.isSetSolidFill()) spPr.unsetSolidFill();\r
}\r
*/\r
@Override\r
public Color getFillColor(){\r
- CTTableCellProperties spPr = getXmlObject().getTcPr();\r
- if(!spPr.isSetSolidFill() ) return null;\r
+ CTTableCellProperties spPr = getCellProperties(false);\r
+ if (spPr == null || !spPr.isSetSolidFill()) return null;\r
\r
CTSolidColorFillProperties fill = spPr.getSolidFill();\r
- if(!fill.isSetSrgbClr()) {\r
+ if (!fill.isSetSrgbClr()) {\r
// TODO for now return null for all colors except explicit RGB\r
return null;\r
}\r
}\r
\r
void setGridSpan(int gridSpan_) {\r
- getXmlObject().setGridSpan(gridSpan_);\r
+ ((CTTableCell)getXmlObject()).setGridSpan(gridSpan_);\r
}\r
\r
void setRowSpan(int rowSpan_) {\r
- getXmlObject().setRowSpan(rowSpan_);\r
+ ((CTTableCell)getXmlObject()).setRowSpan(rowSpan_);\r
}\r
\r
void setHMerge(boolean merge_) {\r
- getXmlObject().setHMerge(merge_);\r
+ ((CTTableCell)getXmlObject()).setHMerge(merge_);\r
}\r
\r
void setVMerge(boolean merge_) {\r
- getXmlObject().setVMerge(merge_);\r
+ ((CTTableCell)getXmlObject()).setVMerge(merge_);\r
}\r
\r
@Override\r
public void setVerticalAlignment(VerticalAlignment anchor){\r
- CTTableCellProperties cellProps = getXmlObject().getTcPr();\r
- if(cellProps != null) {\r
- if(anchor == null) {\r
- if(cellProps.isSetAnchor()) {\r
- cellProps.unsetAnchor();\r
- }\r
- } else {\r
- cellProps.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1));\r
+ CTTableCellProperties cellProps = getCellProperties(true);\r
+ if(anchor == null) {\r
+ if(cellProps.isSetAnchor()) {\r
+ cellProps.unsetAnchor();\r
}\r
- }\r
+ } else {\r
+ cellProps.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1));\r
+ }\r
}\r
\r
@Override\r
public VerticalAlignment getVerticalAlignment(){\r
- CTTableCellProperties cellProps = getXmlObject().getTcPr();\r
+ CTTableCellProperties cellProps = getCellProperties(false);\r
\r
VerticalAlignment align = VerticalAlignment.TOP;\r
if(cellProps != null && cellProps.isSetAnchor()) {\r
package org.apache.poi.xslf.usermodel;\r
\r
import java.awt.Color;\r
-import java.awt.Graphics2D;\r
-import java.awt.geom.Rectangle2D;\r
import java.util.*;\r
\r
import org.apache.poi.sl.usermodel.TextParagraph;\r
* @since POI-3.8\r
*/\r
@Beta\r
-public class XSLFTextParagraph implements TextParagraph {\r
+public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {\r
private final CTTextParagraph _p;\r
private final List<XSLFTextRun> _runs;\r
private final XSLFTextShape _shape;\r
return "[" + getClass() + "]" + getText();\r
}\r
\r
- /**\r
- * Returns wrapping width to break lines in this paragraph\r
- *\r
- * @param firstLine whether the first line is breaking\r
- *\r
- * @return wrapping width in points\r
- */\r
- double getWrappingWidth(boolean firstLine, Graphics2D graphics){\r
- // internal margins for the text box\r
- double leftInset = _shape.getLeftInset();\r
- double rightInset = _shape.getRightInset();\r
-\r
- RenderableShape rShape = new RenderableShape(_shape);\r
- Rectangle2D anchor = rShape.getAnchor(graphics);\r
-\r
- double leftMargin = getLeftMargin();\r
- double indent = getIndent();\r
-\r
- double width;\r
- if(!_shape.getWordWrap()) {\r
- // if wordWrap == false then we return the advance to the right border of the sheet\r
- width = _shape.getSheet().getSlideShow().getPageSize().getWidth() - anchor.getX();\r
- } else {\r
- width = anchor.getWidth() - leftInset - rightInset - leftMargin;\r
- if(firstLine) {\r
- if(isBullet()){\r
- if(indent > 0) width -= indent;\r
- } else {\r
- if(indent > 0) width -= indent; // first line indentation\r
- else if (indent < 0) { // hanging indentation: the first line start at the left margin\r
- width += leftMargin;\r
- }\r
- }\r
- }\r
- }\r
-\r
- return width;\r
- }\r
\r
CTTextParagraphProperties getDefaultMasterStyle(){\r
CTPlaceholder ph = _shape.getCTPlaceholder();\r
package org.apache.poi.xslf.usermodel;
-import java.awt.Graphics2D;
-import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
import java.util.*;
import org.apache.poi.POIXMLException;
import org.apache.poi.sl.draw.DrawFactory;
-import org.apache.poi.sl.draw.geom.Guide;
+import org.apache.poi.sl.draw.DrawTextShape;
import org.apache.poi.sl.usermodel.*;
-import org.apache.poi.sl.usermodel.LineDecoration;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Units;
import org.apache.poi.xslf.model.PropertyFetcher;
/**
* Represents a shape that can hold text.
- *
- * @author Yegor Kozlov
*/
@Beta
-public abstract class XSLFTextShape extends XSLFSimpleShape implements TextShape {
+public abstract class XSLFTextShape extends XSLFSimpleShape implements TextShape<XSLFTextParagraph> {
private final List<XSLFTextParagraph> _paragraphs;
- /**
- * whether the text was broken into lines.
- */
- private boolean _isTextBroken;
-
@SuppressWarnings("deprecation")
/*package*/ XSLFTextShape(XmlObject shape, XSLFSheet sheet) {
super(shape, sheet);
}
public Iterator<XSLFTextParagraph> iterator(){
- return _paragraphs.iterator();
+ return getTextParagraphs().iterator();
}
/**
return textBody == null ? null : textBody.getBodyPr();
}
-
protected abstract CTTextBody getTextBody(boolean create);
public Placeholder getTextType(){
- CTPlaceholder ph;
- XmlObject[] obj = getXmlObject().selectPath(
- "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:nvPr/p:ph");
- if(obj.length == 1){
- ph = (CTPlaceholder)obj[0];
- int val = ph.getType().intValue();
- return Placeholder.values()[val - 1];
- }
- else {
- return null;
- }
+ CTPlaceholder ph = getCTPlaceholder();
+ if (ph == null) return null;
+
+ int val = ph.getType().intValue();
+ return Placeholder.values()[val - 1];
}
* @param placeholder
*/
public void setPlaceholder(Placeholder placeholder){
- CTShape sh = (CTShape)getXmlObject();
- CTApplicationNonVisualDrawingProps nv = sh.getNvSpPr().getNvPr();
+ String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:nvPr";
+ CTApplicationNonVisualDrawingProps nv = selectProperty(CTApplicationNonVisualDrawingProps.class, xquery);
+ if (nv == null) return;
if(placeholder == null) {
- if(nv.isSetPh()) nv.unsetPh();
+ if (nv.isSetPh()) nv.unsetPh();
} else {
nv.addNewPh().setType(STPlaceholderType.Enum.forInt(placeholder.ordinal() + 1));
}
* Compute the cumulative height occupied by the text
*/
public double getTextHeight(){
- // dry-run in a 1x1 image and return the vertical advance
- BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
- Graphics2D graphics = img.createGraphics();
- DrawFactory fact = DrawFactory.getInstance(graphics);
- fact.getDrawable(this);
-
- breakText(graphics);
- return drawParagraphs(graphics, 0, 0);
+ DrawFactory drawFact = DrawFactory.getInstance(null);
+ DrawTextShape<XSLFTextShape> dts = drawFact.getDrawable(this);
+ return dts.getTextHeight();
}
/**
}
}
-
- public LineDecoration getLineDecoration() {
- // TODO Auto-generated method stub
- return null;
- }
-
- public FillStyle getFillStyle() {
- // TODO Auto-generated method stub
- return null;
- }
-
- public Guide getAdjustValue(String name) {
- // TODO Auto-generated method stub
- return null;
- }
}
\ No newline at end of file
package org.apache.poi.hslf.blip;
import org.apache.poi.hslf.model.Picture;
-import org.apache.poi.hslf.model.Shape;
+import org.apache.poi.hslf.model.HSLFShape;
import org.apache.poi.hslf.exceptions.HSLFException;
import java.io.ByteArrayOutputStream;
header.wmfsize = data.length;
//we don't have a EMF reader in java, have to set default image size 200x200
header.bounds = new java.awt.Rectangle(0, 0, 200, 200);
- header.size = new java.awt.Dimension(header.bounds.width*Shape.EMU_PER_POINT, header.bounds.height*Shape.EMU_PER_POINT);
+ header.size = new java.awt.Dimension(header.bounds.width*HSLFShape.EMU_PER_POINT, header.bounds.height*HSLFShape.EMU_PER_POINT);
header.zipsize = compressed.length;
byte[] checksum = getChecksum(data);
import org.apache.poi.hslf.exceptions.HSLFException;
import org.apache.poi.hslf.model.Picture;
-import org.apache.poi.hslf.model.Shape;
+import org.apache.poi.hslf.model.HSLFShape;
/**
* Represents Macintosh PICT picture data.
header.wmfsize = data.length - 512;
//we don't have a PICT reader in java, have to set default image size 200x200
header.bounds = new java.awt.Rectangle(0, 0, 200, 200);
- header.size = new java.awt.Dimension(header.bounds.width*Shape.EMU_PER_POINT,
- header.bounds.height*Shape.EMU_PER_POINT);
+ header.size = new java.awt.Dimension(header.bounds.width*HSLFShape.EMU_PER_POINT,
+ header.bounds.height*HSLFShape.EMU_PER_POINT);
header.zipsize = compressed.length;
byte[] checksum = getChecksum(data);
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogger;
import org.apache.poi.hslf.model.Picture;
-import org.apache.poi.hslf.model.Shape;
+import org.apache.poi.hslf.model.HSLFShape;
import org.apache.poi.hslf.exceptions.HSLFException;
import java.io.*;
header.wmfsize = data.length - aldus.getSize();
header.bounds = new java.awt.Rectangle((short)aldus.left, (short)aldus.top, (short)aldus.right-(short)aldus.left, (short)aldus.bottom-(short)aldus.top);
//coefficient to translate from WMF dpi to 96pdi
- int coeff = 96*Shape.EMU_PER_POINT/aldus.inch;
+ int coeff = 96*HSLFShape.EMU_PER_POINT/aldus.inch;
header.size = new java.awt.Dimension(header.bounds.width*coeff, header.bounds.height*coeff);
header.zipsize = compressed.length;
for (int i = 0; i < _slides.length; i++) {
Slide slide = _slides[i];
- Shape[] shapes = slide.getShapes();
+ HSLFShape[] shapes = slide.getShapes();
for (int j = 0; j < shapes.length; j++) {
if (shapes[j] instanceof OLEShape) {
list.add((OLEShape) shapes[j]);
if (getSlideText) {
if (getMasterText) {
for (SlideMaster master : _show.getSlidesMasters()) {
- for(Shape sh : master.getShapes()){
+ for(HSLFShape sh : master.getShapes()){
if(sh instanceof TextShape){
if(MasterSheet.isPlaceholder(sh)) {
// don't bother about boiler
textRunsToText(ret, slide.getTextRuns());
// Table text
- for (Shape shape : slide.getShapes()){
+ for (HSLFShape shape : slide.getShapes()){
if (shape instanceof Table){
extractTableText(ret, (Table)shape);
}
* this picture in the <code>Slide</code>
* @param parent the parent shape of this picture
*/
- protected ActiveXShape(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
+ protected ActiveXShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
*/
public class AutoShape extends TextShape {
- protected AutoShape(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
+ protected AutoShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
- public AutoShape(ShapeType type, ShapeContainer<Shape> parent){
+ public AutoShape(ShapeType type, ShapeContainer<HSLFShape> parent){
super(null, parent);
- _escherContainer = createSpContainer(type, parent instanceof ShapeGroup);
+ _escherContainer = createSpContainer(type, parent instanceof HSLFGroupShape);
}
public AutoShape(ShapeType type){
shapes = new ShapeOutline[255];
shapes[ShapeType.RECT.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
Rectangle2D path = new Rectangle2D.Float(0, 0, 21600, 21600);
return path;
}
};
shapes[ShapeType.ROUND_RECT.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 5400);
RoundRectangle2D path = new RoundRectangle2D.Float(0, 0, 21600, 21600, adjval, adjval);
return path;
};
shapes[ShapeType.ELLIPSE.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
Ellipse2D path = new Ellipse2D.Float(0, 0, 21600, 21600);
return path;
}
};
shapes[ShapeType.DIAMOND.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
GeneralPath path = new GeneralPath();
path.moveTo(10800, 0);
path.lineTo(21600, 10800);
//m@0,l,21600r21600
shapes[ShapeType.TRIANGLE.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 10800);
GeneralPath path = new GeneralPath();
path.moveTo(adjval, 0);
};
shapes[ShapeType.RT_TRIANGLE.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
GeneralPath path = new GeneralPath();
path.moveTo(0, 0);
path.lineTo(21600, 21600);
};
shapes[ShapeType.PARALLELOGRAM.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 5400);
GeneralPath path = new GeneralPath();
};
shapes[ShapeType.TRAPEZOID.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 5400);
GeneralPath path = new GeneralPath();
};
shapes[ShapeType.HEXAGON.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 5400);
GeneralPath path = new GeneralPath();
};
shapes[ShapeType.OCTAGON.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 6326);
GeneralPath path = new GeneralPath();
};
shapes[ShapeType.PLUS.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 5400);
GeneralPath path = new GeneralPath();
};
shapes[ShapeType.PENTAGON.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
GeneralPath path = new GeneralPath();
path.moveTo(10800, 0);
};
shapes[ShapeType.DOWN_ARROW.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
//m0@0 l@1@0 @1,0 @2,0 @2@0,21600@0,10800,21600xe
int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 16200);
int adjval2 = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUST2VALUE, 5400);
};
shapes[ShapeType.UP_ARROW.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
//m0@0 l@1@0 @1,21600@2,21600@2@0,21600@0,10800,xe
int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 5400);
int adjval2 = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUST2VALUE, 5400);
};
shapes[ShapeType.RIGHT_ARROW.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
//m@0, l@0@1 ,0@1,0@2@0@2@0,21600,21600,10800xe
int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 16200);
int adjval2 = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUST2VALUE, 5400);
};
shapes[ShapeType.LEFT_ARROW.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
//m@0, l@0@1,21600@1,21600@2@0@2@0,21600,,10800xe
int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 5400);
int adjval2 = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUST2VALUE, 5400);
};
shapes[ShapeType.CAN.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
//m10800,qx0@1l0@2qy10800,21600,21600@2l21600@1qy10800,xem0@1qy10800@0,21600@1nfe
int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 5400);
};
shapes[ShapeType.LEFT_BRACE.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
//m21600,qx10800@0l10800@2qy0@11,10800@3l10800@1qy21600,21600e
int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 1800);
int adjval2 = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUST2VALUE, 10800);
};
shapes[ShapeType.RIGHT_BRACE.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
//m,qx10800@0 l10800@2qy21600@11,10800@3l10800@1qy,21600e
int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 1800);
int adjval2 = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUST2VALUE, 10800);
};
shapes[ShapeType.STRAIGHT_CONNECTOR_1.nativeId] = new ShapeOutline(){
- public java.awt.Shape getOutline(Shape shape){
+ public java.awt.Shape getOutline(HSLFShape shape){
return new Line2D.Float(0, 0, 21600, 21600);
}
};
*
* @author Yegor Kozlov
*/
-public final class Background extends Shape {
+public final class Background extends HSLFShape {
- protected Background(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent) {
+ protected Background(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent) {
super(escherRecord, parent);
}
/**
* The shape this background applies to
*/
- protected Shape shape;
+ protected HSLFShape shape;
/**
* Construct a <code>Fill</code> object for a shape.
*
* @param shape the shape this background applies to
*/
- public Fill(Shape shape){
+ public Fill(HSLFShape shape){
this.shape = shape;
}
*/
public int getFillType(){
EscherOptRecord opt = shape.getEscherOptRecord();
- EscherSimpleProperty prop = Shape.getEscherProperty(opt, EscherProperties.FILL__FILLTYPE);
+ EscherSimpleProperty prop = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__FILLTYPE);
return prop == null ? FILL_SOLID : prop.getPropertyValue();
}
*/
protected void afterInsert(Sheet sh){
EscherOptRecord opt = shape.getEscherOptRecord();
- EscherSimpleProperty p = Shape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE);
+ EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE);
if(p != null) {
int idx = p.getPropertyValue();
EscherBSERecord bse = getEscherBSERecord(idx);
SlideShow ppt = sheet.getSlideShow();
Document doc = ppt.getDocumentRecord();
EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
- EscherContainerRecord bstore = Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
+ EscherContainerRecord bstore = HSLFShape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
if(bstore == null) {
logger.log(POILogger.DEBUG, "EscherContainerRecord.BSTORE_CONTAINER was not found ");
return null;
*/
public void setFillType(int type){
EscherOptRecord opt = shape.getEscherOptRecord();
- Shape.setEscherProperty(opt, EscherProperties.FILL__FILLTYPE, type);
+ HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLTYPE, type);
}
/**
*/
public Color getForegroundColor(){
EscherOptRecord opt = shape.getEscherOptRecord();
- EscherSimpleProperty p = Shape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST);
+ EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST);
if(p != null && (p.getPropertyValue() & 0x10) == 0) return null;
public void setForegroundColor(Color color){
EscherOptRecord opt = shape.getEscherOptRecord();
if (color == null) {
- Shape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150000);
+ HSLFShape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150000);
}
else {
int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB();
- Shape.setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, rgb);
- Shape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150011);
+ HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, rgb);
+ HSLFShape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150011);
}
}
*/
public Color getBackgroundColor(){
EscherOptRecord opt = shape.getEscherOptRecord();
- EscherSimpleProperty p = Shape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST);
+ EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST);
if(p != null && (p.getPropertyValue() & 0x10) == 0) return null;
public void setBackgroundColor(Color color){
EscherOptRecord opt = shape.getEscherOptRecord();
if (color == null) {
- Shape.setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, -1);
+ HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, -1);
}
else {
int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB();
- Shape.setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, rgb);
+ HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, rgb);
}
}
*/
public PictureData getPictureData(){
EscherOptRecord opt = shape.getEscherOptRecord();
- EscherSimpleProperty p = Shape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE);
+ EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE);
if (p == null) return null;
SlideShow ppt = shape.getSheet().getSlideShow();
Document doc = ppt.getDocumentRecord();
EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
- EscherContainerRecord bstore = Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
+ EscherContainerRecord bstore = HSLFShape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
java.util.List<EscherRecord> lst = bstore.getChildRecords();
int idx = p.getPropertyValue();
*/
public void setPictureData(int idx){
EscherOptRecord opt = shape.getEscherOptRecord();
- Shape.setEscherProperty(opt, (short)(EscherProperties.FILL__PATTERNTEXTURE + 0x4000), idx);
+ HSLFShape.setEscherProperty(opt, (short)(EscherProperties.FILL__PATTERNTEXTURE + 0x4000), idx);
if( idx != 0 ) {
if( shape.getSheet() != null ) {
EscherBSERecord bse = getEscherBSERecord(idx);
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
* @param parent the parent of the shape
*/
- protected Freeform(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
+ protected Freeform(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
* @param parent the parent of this Shape. For example, if this text box is a cell
* in a table then the parent is Table.
*/
- public Freeform(ShapeContainer<Shape> parent){
+ public Freeform(ShapeContainer<HSLFShape> parent){
super((EscherContainerRecord)null, parent);
- _escherContainer = createSpContainer(ShapeType.NOT_PRIMITIVE, parent instanceof ShapeGroup);
+ _escherContainer = createSpContainer(ShapeType.NOT_PRIMITIVE, parent instanceof HSLFGroupShape);
}
/**
--- /dev/null
+/* ====================================================================
+ 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.model;
+
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.poi.ddf.EscherChildAnchorRecord;
+import org.apache.poi.ddf.EscherClientAnchorRecord;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.ddf.EscherSpRecord;
+import org.apache.poi.ddf.EscherSpgrRecord;
+import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.sl.usermodel.ShapeType;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.POILogger;
+
+/**
+ * Represents a group of shapes.
+ *
+ * @author Yegor Kozlov
+ */
+public class HSLFGroupShape extends HSLFShape implements ShapeContainer<HSLFShape> {
+
+ /**
+ * Create a new ShapeGroup. This constructor is used when a new shape is created.
+ *
+ */
+ public HSLFGroupShape(){
+ this(null, null);
+ _escherContainer = createSpContainer(false);
+ }
+
+ /**
+ * Create a ShapeGroup object and initilize it from the supplied Record container.
+ *
+ * @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
+ * @param parent the parent of the shape
+ */
+ protected HSLFGroupShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
+ super(escherRecord, parent);
+ }
+
+ /**
+ * @return the shapes contained in this group container
+ */
+ public HSLFShape[] getShapes() {
+ List<HSLFShape> shapeList = getShapeList();
+ HSLFShape[] shapes = shapeList.toArray(new HSLFShape[shapeList.size()]);
+ return shapes;
+ }
+
+ /**
+ * Sets the anchor (the bounding box rectangle) of this shape.
+ * All coordinates should be expressed in Master units (576 dpi).
+ *
+ * @param anchor new anchor
+ */
+ public void setAnchor(java.awt.Rectangle anchor){
+
+ EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
+ //hack. internal variable EscherClientAnchorRecord.shortRecord can be
+ //initialized only in fillFields(). We need to set shortRecord=false;
+ byte[] header = new byte[16];
+ LittleEndian.putUShort(header, 0, 0);
+ LittleEndian.putUShort(header, 2, 0);
+ LittleEndian.putInt(header, 4, 8);
+ clientAnchor.fillFields(header, 0, null);
+
+ clientAnchor.setFlag((short)(anchor.y*MASTER_DPI/POINT_DPI));
+ clientAnchor.setCol1((short)(anchor.x*MASTER_DPI/POINT_DPI));
+ clientAnchor.setDx1((short)((anchor.width + anchor.x)*MASTER_DPI/POINT_DPI));
+ clientAnchor.setRow1((short)((anchor.height + anchor.y)*MASTER_DPI/POINT_DPI));
+
+ EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
+
+ spgr.setRectX1(anchor.x*MASTER_DPI/POINT_DPI);
+ spgr.setRectY1(anchor.y*MASTER_DPI/POINT_DPI);
+ spgr.setRectX2((anchor.x + anchor.width)*MASTER_DPI/POINT_DPI);
+ spgr.setRectY2((anchor.y + anchor.height)*MASTER_DPI/POINT_DPI);
+ }
+
+ /**
+ * Sets the coordinate space of this group. All children are constrained
+ * to these coordinates.
+ *
+ * @param anchor the coordinate space of this group
+ */
+ public void setCoordinates(Rectangle2D anchor){
+ EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
+
+ int x1 = (int)Math.round(anchor.getX()*MASTER_DPI/POINT_DPI);
+ int y1 = (int)Math.round(anchor.getY()*MASTER_DPI/POINT_DPI);
+ int x2 = (int)Math.round((anchor.getX() + anchor.getWidth())*MASTER_DPI/POINT_DPI);
+ int y2 = (int)Math.round((anchor.getY() + anchor.getHeight())*MASTER_DPI/POINT_DPI);
+
+ spgr.setRectX1(x1);
+ spgr.setRectY1(y1);
+ spgr.setRectX2(x2);
+ spgr.setRectY2(y2);
+
+ }
+
+ /**
+ * Gets the coordinate space of this group. All children are constrained
+ * to these coordinates.
+ *
+ * @return the coordinate space of this group
+ */
+ public Rectangle2D getCoordinates(){
+ EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
+
+ Rectangle2D.Float anchor = new Rectangle2D.Float();
+ anchor.x = (float)spgr.getRectX1()*POINT_DPI/MASTER_DPI;
+ anchor.y = (float)spgr.getRectY1()*POINT_DPI/MASTER_DPI;
+ anchor.width = (float)(spgr.getRectX2() - spgr.getRectX1())*POINT_DPI/MASTER_DPI;
+ anchor.height = (float)(spgr.getRectY2() - spgr.getRectY1())*POINT_DPI/MASTER_DPI;
+
+ return anchor;
+ }
+
+ /**
+ * Create a new ShapeGroup and create an instance of <code>EscherSpgrContainer</code> which represents a group of shapes
+ */
+ protected EscherContainerRecord createSpContainer(boolean isChild) {
+ EscherContainerRecord spgr = new EscherContainerRecord();
+ spgr.setRecordId(EscherContainerRecord.SPGR_CONTAINER);
+ spgr.setOptions((short)15);
+
+ //The group itself is a shape, and always appears as the first EscherSpContainer in the group container.
+ EscherContainerRecord spcont = new EscherContainerRecord();
+ spcont.setRecordId(EscherContainerRecord.SP_CONTAINER);
+ spcont.setOptions((short)15);
+
+ EscherSpgrRecord spg = new EscherSpgrRecord();
+ spg.setOptions((short)1);
+ spcont.addChildRecord(spg);
+
+ EscherSpRecord sp = new EscherSpRecord();
+ short type = (short)((ShapeType.NOT_PRIMITIVE.nativeId << 4) + 2);
+ sp.setOptions(type);
+ sp.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_GROUP);
+ spcont.addChildRecord(sp);
+
+ EscherClientAnchorRecord anchor = new EscherClientAnchorRecord();
+ spcont.addChildRecord(anchor);
+
+ spgr.addChildRecord(spcont);
+ return spgr;
+ }
+
+ /**
+ * Add a shape to this group.
+ *
+ * @param shape - the Shape to add
+ */
+ public void addShape(HSLFShape shape){
+ _escherContainer.addChildRecord(shape.getSpContainer());
+
+ Sheet sheet = getSheet();
+ shape.setSheet(sheet);
+ shape.setShapeId(sheet.allocateShapeId());
+ shape.afterInsert(sheet);
+ }
+
+ /**
+ * Moves this <code>ShapeGroup</code> to the specified location.
+ * <p>
+ * @param x the x coordinate of the top left corner of the shape in new location
+ * @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();
+ int dx = x - anchor.x;
+ int dy = y - anchor.y;
+ anchor.translate(dx, dy);
+ setAnchor(anchor);
+
+ HSLFShape[] shape = getShapes();
+ for (int i = 0; i < shape.length; i++) {
+ java.awt.Rectangle chanchor = shape[i].getAnchor();
+ chanchor.translate(dx, dy);
+ shape[i].setAnchor(chanchor);
+ }
+ }
+
+ /**
+ * Returns the anchor (the bounding box rectangle) of this shape group.
+ * All coordinates are expressed in points (72 dpi).
+ *
+ * @return the anchor of this shape group
+ */
+ public Rectangle2D getAnchor2D(){
+ EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
+ Rectangle2D.Float anchor = new Rectangle2D.Float();
+ if(clientAnchor == null){
+ logger.log(POILogger.INFO, "EscherClientAnchorRecord was not found for shape group. Searching for EscherChildAnchorRecord.");
+ EscherChildAnchorRecord rec = getEscherChild(EscherChildAnchorRecord.RECORD_ID);
+ anchor = new Rectangle2D.Float(
+ (float)rec.getDx1()*POINT_DPI/MASTER_DPI,
+ (float)rec.getDy1()*POINT_DPI/MASTER_DPI,
+ (float)(rec.getDx2()-rec.getDx1())*POINT_DPI/MASTER_DPI,
+ (float)(rec.getDy2()-rec.getDy1())*POINT_DPI/MASTER_DPI
+ );
+ } else {
+ anchor.x = (float)clientAnchor.getCol1()*POINT_DPI/MASTER_DPI;
+ anchor.y = (float)clientAnchor.getFlag()*POINT_DPI/MASTER_DPI;
+ anchor.width = (float)(clientAnchor.getDx1() - clientAnchor.getCol1())*POINT_DPI/MASTER_DPI ;
+ anchor.height = (float)(clientAnchor.getRow1() - clientAnchor.getFlag())*POINT_DPI/MASTER_DPI;
+ }
+
+ return anchor;
+ }
+
+ /**
+ * Return type of the shape.
+ * In most cases shape group type is {@link org.apache.poi.hslf.model.ShapeTypes#NotPrimitive}
+ *
+ * @return type of the shape.
+ */
+ public ShapeType getShapeType(){
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+ int nativeId = spRecord.getOptions() >> 4;
+ return ShapeType.forId(nativeId, false);
+ }
+
+ /**
+ * Returns <code>null</code> - shape groups can't have hyperlinks
+ *
+ * @return <code>null</code>.
+ */
+ public Hyperlink getHyperlink(){
+ return null;
+ }
+
+ public void draw(Graphics2D graphics){
+
+ AffineTransform at = graphics.getTransform();
+
+ HSLFShape[] sh = getShapes();
+ for (int i = 0; i < sh.length; i++) {
+ sh[i].draw(graphics);
+ }
+
+ graphics.setTransform(at);
+ }
+
+ @Override
+ public <T extends EscherRecord> T getEscherChild(int recordId){
+ EscherContainerRecord groupInfoContainer = (EscherContainerRecord)_escherContainer.getChild(0);
+ return groupInfoContainer.getChildById((short)recordId);
+ }
+
+ public Iterator<HSLFShape> iterator() {
+ return getShapeList().iterator();
+ }
+
+ public boolean removeShape(HSLFShape shape) {
+ // TODO: implement!
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @return the shapes contained in this group container
+ */
+ protected List<HSLFShape> getShapeList() {
+ // Out escher container record should contain several
+ // SpContainers, the first of which is the group shape itself
+ Iterator<EscherRecord> iter = _escherContainer.getChildIterator();
+
+ // Don't include the first SpContainer, it is always NotPrimitive
+ if (iter.hasNext()) {
+ iter.next();
+ }
+ List<HSLFShape> shapeList = new ArrayList<HSLFShape>();
+ while (iter.hasNext()) {
+ EscherRecord r = iter.next();
+ if(r instanceof EscherContainerRecord) {
+ // Create the Shape for it
+ EscherContainerRecord container = (EscherContainerRecord)r;
+ HSLFShape shape = ShapeFactory.createShape(container, this);
+ shape.setSheet(getSheet());
+ shapeList.add( shape );
+ } else {
+ // Should we do anything special with these non
+ // Container records?
+ logger.log(POILogger.ERROR, "Shape contained non container escher record, was " + r.getClass().getName());
+ }
+ }
+
+ return shapeList;
+ }
+
+}
--- /dev/null
+/* ====================================================================
+ 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.model;
+
+import org.apache.poi.ddf.*;
+import org.apache.poi.hslf.record.ColorSchemeAtom;
+import org.apache.poi.sl.usermodel.ShapeContainer;
+import org.apache.poi.sl.usermodel.ShapeType;
+import org.apache.poi.util.POILogger;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.Units;
+
+import java.util.*;
+import java.awt.*;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * <p>
+ * Represents a Shape which is the elemental object that composes a drawing.
+ * This class is a wrapper around EscherSpContainer which holds all information
+ * about a shape in PowerPoint document.
+ * </p>
+ * <p>
+ * When you add a shape, you usually specify the dimensions of the shape and the position
+ * of the upper'left corner of the bounding box for the shape relative to the upper'left
+ * corner of the page, worksheet, or slide. Distances in the drawing layer are measured
+ * in points (72 points = 1 inch).
+ * </p>
+ * <p>
+ *
+ * @author Yegor Kozlov
+ */
+public abstract class HSLFShape implements org.apache.poi.sl.usermodel.Shape<HSLFShape> {
+
+ // For logging
+ protected POILogger logger = POILogFactory.getLogger(this.getClass());
+
+ /**
+ * In Escher absolute distances are specified in
+ * English Metric Units (EMUs), occasionally referred to as A units;
+ * there are 360000 EMUs per centimeter, 914400 EMUs per inch, 12700 EMUs per point.
+ */
+ public static final int EMU_PER_INCH = 914400;
+ public static final int EMU_PER_POINT = 12700;
+ public static final int EMU_PER_CENTIMETER = 360000;
+
+ /**
+ * Master DPI (576 pixels per inch).
+ * Used by the reference coordinate system in PowerPoint.
+ */
+ public static final int MASTER_DPI = 576;
+
+ /**
+ * Pixels DPI (96 pixels per inch)
+ */
+ public static final int PIXEL_DPI = 96;
+
+ /**
+ * Points DPI (72 pixels per inch)
+ */
+ public static final int POINT_DPI = 72;
+
+ /**
+ * Either EscherSpContainer or EscheSpgrContainer record
+ * which holds information about this shape.
+ */
+ protected EscherContainerRecord _escherContainer;
+
+ /**
+ * Parent of this shape.
+ * <code>null</code> for the topmost shapes.
+ */
+ protected ShapeContainer<HSLFShape> _parent;
+
+ /**
+ * The <code>Sheet</code> this shape belongs to
+ */
+ protected Sheet _sheet;
+
+ /**
+ * Fill
+ */
+ protected Fill _fill;
+
+ /**
+ * Create a Shape object. This constructor is used when an existing Shape is read from from a PowerPoint document.
+ *
+ * @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
+ * @param parent the parent of this Shape
+ */
+ protected HSLFShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
+ _escherContainer = escherRecord;
+ _parent = parent;
+ }
+
+ /**
+ * Creates the lowerlevel escher records for this shape.
+ */
+ protected abstract EscherContainerRecord createSpContainer(boolean isChild);
+
+ /**
+ * @return the parent of this shape
+ */
+ public ShapeContainer<HSLFShape> getParent(){
+ return _parent;
+ }
+
+ /**
+ * @return name of the shape.
+ */
+ public String getShapeName(){
+ return getShapeType().nativeName;
+ }
+
+ /**
+ * @return type of the shape.
+ * @see org.apache.poi.hslf.record.RecordTypes
+ */
+ public ShapeType getShapeType(){
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+ return ShapeType.forId(spRecord.getShapeType(), false);
+ }
+
+ /**
+ * @param type type of the shape.
+ * @see org.apache.poi.hslf.record.RecordTypes
+ */
+ public void setShapeType(ShapeType type){
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+ spRecord.setShapeType( (short) type.nativeId );
+ spRecord.setVersion( (short) 0x2 );
+ }
+
+ /**
+ * 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 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(){
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+ int flags = spRecord.getFlags();
+ Rectangle2D anchor=null;
+ if ((flags & EscherSpRecord.FLAG_CHILD) != 0){
+ EscherChildAnchorRecord rec = getEscherChild(EscherChildAnchorRecord.RECORD_ID);
+ anchor = new java.awt.Rectangle();
+ if(rec == null){
+ logger.log(POILogger.WARN, "EscherSpRecord.FLAG_CHILD is set but EscherChildAnchorRecord was not found");
+ EscherClientAnchorRecord clrec = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
+ anchor = new java.awt.Rectangle();
+ anchor = new Rectangle2D.Float(
+ (float)clrec.getCol1()*POINT_DPI/MASTER_DPI,
+ (float)clrec.getFlag()*POINT_DPI/MASTER_DPI,
+ (float)(clrec.getDx1()-clrec.getCol1())*POINT_DPI/MASTER_DPI,
+ (float)(clrec.getRow1()-clrec.getFlag())*POINT_DPI/MASTER_DPI
+ );
+ } else {
+ anchor = new Rectangle2D.Float(
+ (float)rec.getDx1()*POINT_DPI/MASTER_DPI,
+ (float)rec.getDy1()*POINT_DPI/MASTER_DPI,
+ (float)(rec.getDx2()-rec.getDx1())*POINT_DPI/MASTER_DPI,
+ (float)(rec.getDy2()-rec.getDy1())*POINT_DPI/MASTER_DPI
+ );
+ }
+ }
+ else {
+ EscherClientAnchorRecord rec = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
+ anchor = new java.awt.Rectangle();
+ anchor = new Rectangle2D.Float(
+ (float)rec.getCol1()*POINT_DPI/MASTER_DPI,
+ (float)rec.getFlag()*POINT_DPI/MASTER_DPI,
+ (float)(rec.getDx1()-rec.getCol1())*POINT_DPI/MASTER_DPI,
+ (float)(rec.getRow1()-rec.getFlag())*POINT_DPI/MASTER_DPI
+ );
+ }
+ return anchor;
+ }
+
+ public Rectangle2D getLogicalAnchor2D(){
+ return getAnchor2D();
+ }
+
+ /**
+ * Sets the anchor (the bounding box rectangle) of this shape.
+ * All coordinates should be expressed in points (72 dpi).
+ *
+ * @param anchor new anchor
+ */
+ public void setAnchor(Rectangle2D anchor){
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+ int flags = spRecord.getFlags();
+ if ((flags & EscherSpRecord.FLAG_CHILD) != 0){
+ EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(EscherChildAnchorRecord.RECORD_ID);
+ rec.setDx1((int)(anchor.getX()*MASTER_DPI/POINT_DPI));
+ rec.setDy1((int)(anchor.getY()*MASTER_DPI/POINT_DPI));
+ rec.setDx2((int)((anchor.getWidth() + anchor.getX())*MASTER_DPI/POINT_DPI));
+ rec.setDy2((int)((anchor.getHeight() + anchor.getY())*MASTER_DPI/POINT_DPI));
+ }
+ else {
+ EscherClientAnchorRecord rec = (EscherClientAnchorRecord)getEscherChild(EscherClientAnchorRecord.RECORD_ID);
+ rec.setFlag((short)(anchor.getY()*MASTER_DPI/POINT_DPI));
+ rec.setCol1((short)(anchor.getX()*MASTER_DPI/POINT_DPI));
+ rec.setDx1((short)(((anchor.getWidth() + anchor.getX())*MASTER_DPI/POINT_DPI)));
+ rec.setRow1((short)(((anchor.getHeight() + anchor.getY())*MASTER_DPI/POINT_DPI)));
+ }
+
+ }
+
+ /**
+ * Moves the top left corner of the shape to the specified point.
+ *
+ * @param x the x coordinate of the top left corner of the shape
+ * @param y the y coordinate of the top left corner of the shape
+ */
+ public void moveTo(float x, float y){
+ Rectangle2D anchor = getAnchor2D();
+ anchor.setRect(x, y, anchor.getWidth(), anchor.getHeight());
+ setAnchor(anchor);
+ }
+
+ /**
+ * Helper method to return escher child by record ID
+ *
+ * @return escher record or <code>null</code> if not found.
+ */
+ public static <T extends EscherRecord> T getEscherChild(EscherContainerRecord owner, int recordId){
+ return owner.getChildById((short)recordId);
+ }
+
+ public <T extends EscherRecord> T getEscherChild(int recordId){
+ return _escherContainer.getChildById((short)recordId);
+ }
+
+ /**
+ * Returns escher property by id.
+ *
+ * @return escher property or <code>null</code> if not found.
+ */
+ public static <T extends EscherProperty> T getEscherProperty(EscherOptRecord opt, int propId){
+ return opt.lookup(propId);
+ }
+
+ /**
+ * Set an escher property for this shape.
+ *
+ * @param opt The opt record to set the properties to.
+ * @param propId The id of the property. One of the constants defined in EscherOptRecord.
+ * @param value value of the property. If value = -1 then the property is removed.
+ */
+ public static void setEscherProperty(EscherOptRecord opt, short propId, int value){
+ java.util.List<EscherProperty> props = opt.getEscherProperties();
+ for ( Iterator<EscherProperty> iterator = props.iterator(); iterator.hasNext(); ) {
+ if (iterator.next().getPropertyNumber() == propId){
+ iterator.remove();
+ break;
+ }
+ }
+ if (value != -1) {
+ opt.addEscherProperty(new EscherSimpleProperty(propId, value));
+ opt.sortProperties();
+ }
+ }
+
+ /**
+ * Set an simple escher property for this shape.
+ *
+ * @param propId The id of the property. One of the constants defined in EscherOptRecord.
+ * @param value value of the property. If value = -1 then the property is removed.
+ */
+ public void setEscherProperty(short propId, int value){
+ EscherOptRecord opt = getEscherOptRecord();
+ setEscherProperty(opt, propId, value);
+ }
+
+ /**
+ * Get the value of a simple escher property for this shape.
+ *
+ * @param propId The id of the property. One of the constants defined in EscherOptRecord.
+ */
+ public int getEscherProperty(short propId){
+ EscherOptRecord opt = getEscherOptRecord();
+ EscherSimpleProperty prop = getEscherProperty(opt, propId);
+ return prop == null ? 0 : prop.getPropertyValue();
+ }
+
+ /**
+ * Get the value of a simple escher property for this shape.
+ *
+ * @param propId The id of the property. One of the constants defined in EscherOptRecord.
+ */
+ public int getEscherProperty(short propId, int defaultValue){
+ EscherOptRecord opt = getEscherOptRecord();
+ EscherSimpleProperty prop = getEscherProperty(opt, propId);
+ return prop == null ? defaultValue : prop.getPropertyValue();
+ }
+
+ /**
+ * @return The shape container and it's children that can represent this
+ * shape.
+ */
+ public EscherContainerRecord getSpContainer(){
+ return _escherContainer;
+ }
+
+ /**
+ * Event which fires when a shape is inserted in the sheet.
+ * In some cases we need to propagate changes to upper level containers.
+ * <br>
+ * Default implementation does nothing.
+ *
+ * @param sh - owning shape
+ */
+ protected void afterInsert(Sheet sh){
+ if(_fill != null) {
+ _fill.afterInsert(sh);
+ }
+ }
+
+ /**
+ * @return the <code>SlideShow</code> this shape belongs to
+ */
+ public Sheet getSheet(){
+ return _sheet;
+ }
+
+ /**
+ * Assign the <code>SlideShow</code> this shape belongs to
+ *
+ * @param sheet owner of this shape
+ */
+ public void setSheet(Sheet sheet){
+ _sheet = sheet;
+ }
+
+ Color getColor(short colorProperty, short opacityProperty, int defaultColor){
+ EscherOptRecord opt = getEscherOptRecord();
+ EscherSimpleProperty p = getEscherProperty(opt, colorProperty);
+ if(p == null && defaultColor == -1) return null;
+
+ int val = (p == null) ? defaultColor : p.getPropertyValue();
+
+ EscherColorRef ecr = new EscherColorRef(val);
+
+ boolean fPaletteIndex = ecr.hasPaletteIndexFlag();
+ boolean fPaletteRGB = ecr.hasPaletteRGBFlag();
+ boolean fSystemRGB = ecr.hasSystemRGBFlag();
+ boolean fSchemeIndex = ecr.hasSchemeIndexFlag();
+ boolean fSysIndex = ecr.hasSysIndexFlag();
+
+ int rgb[] = ecr.getRGB();
+
+ Sheet sheet = getSheet();
+ if (fSchemeIndex && sheet != null) {
+ //red is the index to the color scheme
+ ColorSchemeAtom ca = sheet.getColorScheme();
+ int schemeColor = ca.getColor(ecr.getSchemeIndex());
+
+ rgb[0] = (schemeColor >> 0) & 0xFF;
+ rgb[1] = (schemeColor >> 8) & 0xFF;
+ rgb[2] = (schemeColor >> 16) & 0xFF;
+ } else if (fPaletteIndex){
+ //TODO
+ } else if (fPaletteRGB){
+ //TODO
+ } else if (fSystemRGB){
+ //TODO
+ } else if (fSysIndex){
+ //TODO
+ }
+
+ EscherSimpleProperty op = getEscherProperty(opt, opacityProperty);
+ int defaultOpacity = 0x00010000;
+ int opacity = (op == null) ? defaultOpacity : op.getPropertyValue();
+ double alpha = Units.fixedPointToDouble(opacity)*255.0;
+ return new Color(rgb[0], rgb[1], rgb[2], (int)alpha);
+ }
+
+ Color toRGB(int val){
+ int a = (val >> 24) & 0xFF;
+ int b = (val >> 16) & 0xFF;
+ int g = (val >> 8) & 0xFF;
+ int r = (val >> 0) & 0xFF;
+
+ if(a == 0xFE){
+ // Color is an sRGB value specified by red, green, and blue fields.
+ } else if (a == 0xFF){
+ // Color is undefined.
+ } else {
+ // index in the color scheme
+ ColorSchemeAtom ca = getSheet().getColorScheme();
+ int schemeColor = ca.getColor(a);
+
+ r = (schemeColor >> 0) & 0xFF;
+ g = (schemeColor >> 8) & 0xFF;
+ b = (schemeColor >> 16) & 0xFF;
+ }
+ return new Color(r, g, b);
+ }
+
+ /**
+ * @return id for the shape.
+ */
+ public int getShapeId(){
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+ return spRecord == null ? 0 : spRecord.getShapeId();
+ }
+
+ /**
+ * Sets shape ID
+ *
+ * @param id of the shape
+ */
+ public void setShapeId(int id){
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+ if(spRecord != null) spRecord.setShapeId(id);
+ }
+
+ /**
+ * Fill properties of this shape
+ *
+ * @return fill properties of this shape
+ */
+ public Fill getFill(){
+ if(_fill == null) _fill = new Fill(this);
+ return _fill;
+ }
+
+
+ /**
+ * Returns the hyperlink assigned to this shape
+ *
+ * @return the hyperlink assigned to this shape
+ * or <code>null</code> if not found.
+ */
+ public Hyperlink getHyperlink(){
+ return Hyperlink.find(this);
+ }
+
+ public void draw(Graphics2D graphics){
+ logger.log(POILogger.INFO, "Rendering " + getShapeName());
+ }
+
+ /**
+ * Return shape outline as a java.awt.Shape object
+ *
+ * @return the shape outline
+ */
+ public java.awt.Shape getOutline(){
+ return getLogicalAnchor2D();
+ }
+
+ public EscherOptRecord getEscherOptRecord() {
+ return getEscherChild(EscherOptRecord.RECORD_ID);
+ }
+
+ @Override
+ public boolean getFlipHorizontal(){
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+ return (spRecord.getFlags()& EscherSpRecord.FLAG_FLIPHORIZ) != 0;
+ }
+
+ @Override
+ public void setFlipHorizontal(boolean flip) {
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+ int flag = spRecord.getFlags() | EscherSpRecord.FLAG_FLIPHORIZ;
+ spRecord.setFlags(flag);
+ }
+
+ @Override
+ public boolean getFlipVertical(){
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+ return (spRecord.getFlags()& EscherSpRecord.FLAG_FLIPVERT) != 0;
+ }
+
+ @Override
+ public void setFlipVertical(boolean flip) {
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+ int flag = spRecord.getFlags() | EscherSpRecord.FLAG_FLIPVERT;
+ spRecord.setFlags(flag);
+ }
+
+ @Override
+ public double getRotation(){
+ int rot = getEscherProperty(EscherProperties.TRANSFORM__ROTATION);
+ double angle = Units.fixedPointToDouble(rot) % 360.0;
+ return angle;
+ }
+
+ @Override
+ public void setRotation(double theta){
+ int rot = Units.doubleToFixedPoint(theta % 360.0);
+ setEscherProperty(EscherProperties.TRANSFORM__ROTATION, rot);
+ }
+
+ @Override
+ public boolean isPlaceholder() {
+ return false;
+ }
+}
* @param shape <code>Shape</code> to lookup hyperlink in
* @return found hyperlink or <code>null</code>
*/
- protected static Hyperlink find(Shape shape){
+ protected static Hyperlink find(HSLFShape shape){
List<Hyperlink> lst = new ArrayList<Hyperlink>();
SlideShow ppt = shape.getSheet().getSlideShow();
//document-level container which stores info about all links in a presentation
public static final int LINE_TRIPLE = 4;
- protected Line(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
+ protected Line(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
- public Line(ShapeContainer<Shape> parent){
+ public Line(ShapeContainer<HSLFShape> parent){
super(null, parent);
- _escherContainer = createSpContainer(parent instanceof ShapeGroup);
+ _escherContainer = createSpContainer(parent instanceof HSLFGroupShape);
}
public Line(){
*
* @return true if the shape is a placeholder
*/
- public static boolean isPlaceholder(Shape shape){
+ public static boolean isPlaceholder(HSLFShape shape){
if(!(shape instanceof TextShape)) return false;
TextShape tx = (TextShape)shape;
* @param idx the index of the picture
* @param parent the parent shape
*/
- public MovieShape(int movieIdx, int idx, ShapeContainer<Shape> parent) {
+ public MovieShape(int movieIdx, int idx, ShapeContainer<HSLFShape> parent) {
super(idx, parent);
setMovieIndex(movieIdx);
}
* this picture in the <code>Slide</code>
* @param parent the parent shape of this picture
*/
- protected MovieShape(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
+ protected MovieShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
* @param idx the index of the picture
* @param parent the parent shape
*/
- public OLEShape(int idx, ShapeContainer<Shape> parent) {
+ public OLEShape(int idx, ShapeContainer<HSLFShape> parent) {
super(idx, parent);
}
* this picture in the <code>Slide</code>
* @param parent the parent shape of this picture
*/
- protected OLEShape(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
+ protected OLEShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
protected POILogger log = POILogFactory.getLogger(this.getClass());
//The ppt object to write into.
- private ShapeGroup _group;
+ private HSLFGroupShape _group;
private AffineTransform _transform;
private Stroke _stroke;
*
* @param group The shape group to write the graphics calls into.
*/
- public PPGraphics2D(ShapeGroup group){
+ public PPGraphics2D(HSLFGroupShape group){
this._group = group;
_transform = new AffineTransform();
/**
* @return the shape group being used for drawing
*/
- public ShapeGroup getShapeGroup(){
+ public HSLFGroupShape getShapeGroup(){
return _group;
}
* @param idx the index of the picture
* @param parent the parent shape
*/
- public Picture(int idx, ShapeContainer<Shape> parent) {
+ public Picture(int idx, ShapeContainer<HSLFShape> parent) {
super(null, parent);
- _escherContainer = createSpContainer(idx, parent instanceof ShapeGroup);
+ _escherContainer = createSpContainer(idx, parent instanceof HSLFGroupShape);
}
/**
* this picture in the <code>Slide</code>
* @param parent the parent shape of this picture
*/
- protected Picture(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
+ protected Picture(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
SlideShow ppt = getSheet().getSlideShow();
Document doc = ppt.getDocumentRecord();
EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
- EscherContainerRecord bstore = Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
+ EscherContainerRecord bstore = HSLFShape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
if(bstore == null) {
logger.log(POILogger.DEBUG, "EscherContainerRecord.BSTORE_CONTAINER was not found ");
return null;
*/
public final class Placeholder extends TextBox {
- protected Placeholder(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
+ protected Placeholder(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
- public Placeholder(ShapeContainer<Shape> parent){
+ public Placeholder(ShapeContainer<HSLFShape> parent){
super(parent);
}
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
* @param parent the parent of the shape
*/
- protected Polygon(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
+ protected Polygon(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
* @param parent the parent of this Shape. For example, if this text box is a cell
* in a table then the parent is Table.
*/
- public Polygon(ShapeContainer<Shape> parent){
+ public Polygon(ShapeContainer<HSLFShape> parent){
super((EscherContainerRecord)null, parent);
- _escherContainer = createSpContainer(ShapeType.NOT_PRIMITIVE, parent instanceof ShapeGroup);
+ _escherContainer = createSpContainer(ShapeType.NOT_PRIMITIVE, parent instanceof HSLFGroupShape);
}
/**
+++ /dev/null
-/* ====================================================================
- 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.model;
-
-import org.apache.poi.ddf.*;
-import org.apache.poi.hslf.record.ColorSchemeAtom;
-import org.apache.poi.sl.usermodel.ShapeContainer;
-import org.apache.poi.sl.usermodel.ShapeType;
-import org.apache.poi.util.POILogger;
-import org.apache.poi.util.POILogFactory;
-import org.apache.poi.util.Units;
-
-import java.util.*;
-import java.awt.*;
-import java.awt.geom.Rectangle2D;
-
-/**
- * <p>
- * Represents a Shape which is the elemental object that composes a drawing.
- * This class is a wrapper around EscherSpContainer which holds all information
- * about a shape in PowerPoint document.
- * </p>
- * <p>
- * When you add a shape, you usually specify the dimensions of the shape and the position
- * of the upper'left corner of the bounding box for the shape relative to the upper'left
- * corner of the page, worksheet, or slide. Distances in the drawing layer are measured
- * in points (72 points = 1 inch).
- * </p>
- * <p>
- *
- * @author Yegor Kozlov
- */
-public abstract class Shape implements org.apache.poi.sl.usermodel.Shape<Shape> {
-
- // For logging
- protected POILogger logger = POILogFactory.getLogger(this.getClass());
-
- /**
- * In Escher absolute distances are specified in
- * English Metric Units (EMUs), occasionally referred to as A units;
- * there are 360000 EMUs per centimeter, 914400 EMUs per inch, 12700 EMUs per point.
- */
- public static final int EMU_PER_INCH = 914400;
- public static final int EMU_PER_POINT = 12700;
- public static final int EMU_PER_CENTIMETER = 360000;
-
- /**
- * Master DPI (576 pixels per inch).
- * Used by the reference coordinate system in PowerPoint.
- */
- public static final int MASTER_DPI = 576;
-
- /**
- * Pixels DPI (96 pixels per inch)
- */
- public static final int PIXEL_DPI = 96;
-
- /**
- * Points DPI (72 pixels per inch)
- */
- public static final int POINT_DPI = 72;
-
- /**
- * Either EscherSpContainer or EscheSpgrContainer record
- * which holds information about this shape.
- */
- protected EscherContainerRecord _escherContainer;
-
- /**
- * Parent of this shape.
- * <code>null</code> for the topmost shapes.
- */
- protected ShapeContainer<Shape> _parent;
-
- /**
- * The <code>Sheet</code> this shape belongs to
- */
- protected Sheet _sheet;
-
- /**
- * Fill
- */
- protected Fill _fill;
-
- /**
- * Create a Shape object. This constructor is used when an existing Shape is read from from a PowerPoint document.
- *
- * @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
- * @param parent the parent of this Shape
- */
- protected Shape(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
- _escherContainer = escherRecord;
- _parent = parent;
- }
-
- /**
- * Creates the lowerlevel escher records for this shape.
- */
- protected abstract EscherContainerRecord createSpContainer(boolean isChild);
-
- /**
- * @return the parent of this shape
- */
- public ShapeContainer<Shape> getParent(){
- return _parent;
- }
-
- /**
- * @return name of the shape.
- */
- public String getShapeName(){
- return getShapeType().nativeName;
- }
-
- /**
- * @return type of the shape.
- * @see org.apache.poi.hslf.record.RecordTypes
- */
- public ShapeType getShapeType(){
- EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
- return ShapeType.forId(spRecord.getShapeType(), false);
- }
-
- /**
- * @param type type of the shape.
- * @see org.apache.poi.hslf.record.RecordTypes
- */
- public void setShapeType(ShapeType type){
- EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
- spRecord.setShapeType( (short) type.nativeId );
- spRecord.setVersion( (short) 0x2 );
- }
-
- /**
- * 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 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(){
- EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
- int flags = spRecord.getFlags();
- Rectangle2D anchor=null;
- if ((flags & EscherSpRecord.FLAG_CHILD) != 0){
- EscherChildAnchorRecord rec = getEscherChild(EscherChildAnchorRecord.RECORD_ID);
- anchor = new java.awt.Rectangle();
- if(rec == null){
- logger.log(POILogger.WARN, "EscherSpRecord.FLAG_CHILD is set but EscherChildAnchorRecord was not found");
- EscherClientAnchorRecord clrec = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
- anchor = new java.awt.Rectangle();
- anchor = new Rectangle2D.Float(
- (float)clrec.getCol1()*POINT_DPI/MASTER_DPI,
- (float)clrec.getFlag()*POINT_DPI/MASTER_DPI,
- (float)(clrec.getDx1()-clrec.getCol1())*POINT_DPI/MASTER_DPI,
- (float)(clrec.getRow1()-clrec.getFlag())*POINT_DPI/MASTER_DPI
- );
- } else {
- anchor = new Rectangle2D.Float(
- (float)rec.getDx1()*POINT_DPI/MASTER_DPI,
- (float)rec.getDy1()*POINT_DPI/MASTER_DPI,
- (float)(rec.getDx2()-rec.getDx1())*POINT_DPI/MASTER_DPI,
- (float)(rec.getDy2()-rec.getDy1())*POINT_DPI/MASTER_DPI
- );
- }
- }
- else {
- EscherClientAnchorRecord rec = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
- anchor = new java.awt.Rectangle();
- anchor = new Rectangle2D.Float(
- (float)rec.getCol1()*POINT_DPI/MASTER_DPI,
- (float)rec.getFlag()*POINT_DPI/MASTER_DPI,
- (float)(rec.getDx1()-rec.getCol1())*POINT_DPI/MASTER_DPI,
- (float)(rec.getRow1()-rec.getFlag())*POINT_DPI/MASTER_DPI
- );
- }
- return anchor;
- }
-
- public Rectangle2D getLogicalAnchor2D(){
- return getAnchor2D();
- }
-
- /**
- * Sets the anchor (the bounding box rectangle) of this shape.
- * All coordinates should be expressed in points (72 dpi).
- *
- * @param anchor new anchor
- */
- public void setAnchor(Rectangle2D anchor){
- EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
- int flags = spRecord.getFlags();
- if ((flags & EscherSpRecord.FLAG_CHILD) != 0){
- EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(EscherChildAnchorRecord.RECORD_ID);
- rec.setDx1((int)(anchor.getX()*MASTER_DPI/POINT_DPI));
- rec.setDy1((int)(anchor.getY()*MASTER_DPI/POINT_DPI));
- rec.setDx2((int)((anchor.getWidth() + anchor.getX())*MASTER_DPI/POINT_DPI));
- rec.setDy2((int)((anchor.getHeight() + anchor.getY())*MASTER_DPI/POINT_DPI));
- }
- else {
- EscherClientAnchorRecord rec = (EscherClientAnchorRecord)getEscherChild(EscherClientAnchorRecord.RECORD_ID);
- rec.setFlag((short)(anchor.getY()*MASTER_DPI/POINT_DPI));
- rec.setCol1((short)(anchor.getX()*MASTER_DPI/POINT_DPI));
- rec.setDx1((short)(((anchor.getWidth() + anchor.getX())*MASTER_DPI/POINT_DPI)));
- rec.setRow1((short)(((anchor.getHeight() + anchor.getY())*MASTER_DPI/POINT_DPI)));
- }
-
- }
-
- /**
- * Moves the top left corner of the shape to the specified point.
- *
- * @param x the x coordinate of the top left corner of the shape
- * @param y the y coordinate of the top left corner of the shape
- */
- public void moveTo(float x, float y){
- Rectangle2D anchor = getAnchor2D();
- anchor.setRect(x, y, anchor.getWidth(), anchor.getHeight());
- setAnchor(anchor);
- }
-
- /**
- * Helper method to return escher child by record ID
- *
- * @return escher record or <code>null</code> if not found.
- */
- public static <T extends EscherRecord> T getEscherChild(EscherContainerRecord owner, int recordId){
- return owner.getChildById((short)recordId);
- }
-
- public <T extends EscherRecord> T getEscherChild(int recordId){
- return _escherContainer.getChildById((short)recordId);
- }
-
- /**
- * Returns escher property by id.
- *
- * @return escher property or <code>null</code> if not found.
- */
- public static <T extends EscherProperty> T getEscherProperty(EscherOptRecord opt, int propId){
- return opt.lookup(propId);
- }
-
- /**
- * Set an escher property for this shape.
- *
- * @param opt The opt record to set the properties to.
- * @param propId The id of the property. One of the constants defined in EscherOptRecord.
- * @param value value of the property. If value = -1 then the property is removed.
- */
- public static void setEscherProperty(EscherOptRecord opt, short propId, int value){
- java.util.List<EscherProperty> props = opt.getEscherProperties();
- for ( Iterator<EscherProperty> iterator = props.iterator(); iterator.hasNext(); ) {
- if (iterator.next().getPropertyNumber() == propId){
- iterator.remove();
- break;
- }
- }
- if (value != -1) {
- opt.addEscherProperty(new EscherSimpleProperty(propId, value));
- opt.sortProperties();
- }
- }
-
- /**
- * Set an simple escher property for this shape.
- *
- * @param propId The id of the property. One of the constants defined in EscherOptRecord.
- * @param value value of the property. If value = -1 then the property is removed.
- */
- public void setEscherProperty(short propId, int value){
- EscherOptRecord opt = getEscherOptRecord();
- setEscherProperty(opt, propId, value);
- }
-
- /**
- * Get the value of a simple escher property for this shape.
- *
- * @param propId The id of the property. One of the constants defined in EscherOptRecord.
- */
- public int getEscherProperty(short propId){
- EscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = getEscherProperty(opt, propId);
- return prop == null ? 0 : prop.getPropertyValue();
- }
-
- /**
- * Get the value of a simple escher property for this shape.
- *
- * @param propId The id of the property. One of the constants defined in EscherOptRecord.
- */
- public int getEscherProperty(short propId, int defaultValue){
- EscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = getEscherProperty(opt, propId);
- return prop == null ? defaultValue : prop.getPropertyValue();
- }
-
- /**
- * @return The shape container and it's children that can represent this
- * shape.
- */
- public EscherContainerRecord getSpContainer(){
- return _escherContainer;
- }
-
- /**
- * Event which fires when a shape is inserted in the sheet.
- * In some cases we need to propagate changes to upper level containers.
- * <br>
- * Default implementation does nothing.
- *
- * @param sh - owning shape
- */
- protected void afterInsert(Sheet sh){
- if(_fill != null) {
- _fill.afterInsert(sh);
- }
- }
-
- /**
- * @return the <code>SlideShow</code> this shape belongs to
- */
- public Sheet getSheet(){
- return _sheet;
- }
-
- /**
- * Assign the <code>SlideShow</code> this shape belongs to
- *
- * @param sheet owner of this shape
- */
- public void setSheet(Sheet sheet){
- _sheet = sheet;
- }
-
- Color getColor(short colorProperty, short opacityProperty, int defaultColor){
- EscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty p = getEscherProperty(opt, colorProperty);
- if(p == null && defaultColor == -1) return null;
-
- int val = (p == null) ? defaultColor : p.getPropertyValue();
-
- EscherColorRef ecr = new EscherColorRef(val);
-
- boolean fPaletteIndex = ecr.hasPaletteIndexFlag();
- boolean fPaletteRGB = ecr.hasPaletteRGBFlag();
- boolean fSystemRGB = ecr.hasSystemRGBFlag();
- boolean fSchemeIndex = ecr.hasSchemeIndexFlag();
- boolean fSysIndex = ecr.hasSysIndexFlag();
-
- int rgb[] = ecr.getRGB();
-
- Sheet sheet = getSheet();
- if (fSchemeIndex && sheet != null) {
- //red is the index to the color scheme
- ColorSchemeAtom ca = sheet.getColorScheme();
- int schemeColor = ca.getColor(ecr.getSchemeIndex());
-
- rgb[0] = (schemeColor >> 0) & 0xFF;
- rgb[1] = (schemeColor >> 8) & 0xFF;
- rgb[2] = (schemeColor >> 16) & 0xFF;
- } else if (fPaletteIndex){
- //TODO
- } else if (fPaletteRGB){
- //TODO
- } else if (fSystemRGB){
- //TODO
- } else if (fSysIndex){
- //TODO
- }
-
- EscherSimpleProperty op = getEscherProperty(opt, opacityProperty);
- int defaultOpacity = 0x00010000;
- int opacity = (op == null) ? defaultOpacity : op.getPropertyValue();
- double alpha = Units.fixedPointToDouble(opacity)*255.0;
- return new Color(rgb[0], rgb[1], rgb[2], (int)alpha);
- }
-
- Color toRGB(int val){
- int a = (val >> 24) & 0xFF;
- int b = (val >> 16) & 0xFF;
- int g = (val >> 8) & 0xFF;
- int r = (val >> 0) & 0xFF;
-
- if(a == 0xFE){
- // Color is an sRGB value specified by red, green, and blue fields.
- } else if (a == 0xFF){
- // Color is undefined.
- } else {
- // index in the color scheme
- ColorSchemeAtom ca = getSheet().getColorScheme();
- int schemeColor = ca.getColor(a);
-
- r = (schemeColor >> 0) & 0xFF;
- g = (schemeColor >> 8) & 0xFF;
- b = (schemeColor >> 16) & 0xFF;
- }
- return new Color(r, g, b);
- }
-
- /**
- * @return id for the shape.
- */
- public int getShapeId(){
- EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
- return spRecord == null ? 0 : spRecord.getShapeId();
- }
-
- /**
- * Sets shape ID
- *
- * @param id of the shape
- */
- public void setShapeId(int id){
- EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
- if(spRecord != null) spRecord.setShapeId(id);
- }
-
- /**
- * Fill properties of this shape
- *
- * @return fill properties of this shape
- */
- public Fill getFill(){
- if(_fill == null) _fill = new Fill(this);
- return _fill;
- }
-
-
- /**
- * Returns the hyperlink assigned to this shape
- *
- * @return the hyperlink assigned to this shape
- * or <code>null</code> if not found.
- */
- public Hyperlink getHyperlink(){
- return Hyperlink.find(this);
- }
-
- public void draw(Graphics2D graphics){
- logger.log(POILogger.INFO, "Rendering " + getShapeName());
- }
-
- /**
- * Return shape outline as a java.awt.Shape object
- *
- * @return the shape outline
- */
- public java.awt.Shape getOutline(){
- return getLogicalAnchor2D();
- }
-
- public EscherOptRecord getEscherOptRecord() {
- return getEscherChild(EscherOptRecord.RECORD_ID);
- }
-
- @Override
- public boolean getFlipHorizontal(){
- EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
- return (spRecord.getFlags()& EscherSpRecord.FLAG_FLIPHORIZ) != 0;
- }
-
- @Override
- public void setFlipHorizontal(boolean flip) {
- EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
- int flag = spRecord.getFlags() | EscherSpRecord.FLAG_FLIPHORIZ;
- spRecord.setFlags(flag);
- }
-
- @Override
- public boolean getFlipVertical(){
- EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
- return (spRecord.getFlags()& EscherSpRecord.FLAG_FLIPVERT) != 0;
- }
-
- @Override
- public void setFlipVertical(boolean flip) {
- EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
- int flag = spRecord.getFlags() | EscherSpRecord.FLAG_FLIPVERT;
- spRecord.setFlags(flag);
- }
-
- @Override
- public double getRotation(){
- int rot = getEscherProperty(EscherProperties.TRANSFORM__ROTATION);
- double angle = Units.fixedPointToDouble(rot) % 360.0;
- return angle;
- }
-
- @Override
- public void setRotation(double theta){
- int rot = Units.doubleToFixedPoint(theta % 360.0);
- setEscherProperty(EscherProperties.TRANSFORM__ROTATION, rot);
- }
-
- @Override
- public boolean isPlaceholder() {
- return false;
- }
-}
/**
* Create a new shape from the data provided.
*/
- public static Shape createShape(EscherContainerRecord spContainer, ShapeContainer<Shape> parent){
+ public static HSLFShape createShape(EscherContainerRecord spContainer, ShapeContainer<HSLFShape> parent){
if (spContainer.getRecordId() == EscherContainerRecord.SPGR_CONTAINER){
return createShapeGroup(spContainer, parent);
}
return createSimpeShape(spContainer, parent);
}
- public static ShapeGroup createShapeGroup(EscherContainerRecord spContainer, ShapeContainer<Shape> parent){
- ShapeGroup group = null;
- EscherRecord opt = Shape.getEscherChild((EscherContainerRecord)spContainer.getChild(0), (short)0xF122);
+ public static HSLFGroupShape createShapeGroup(EscherContainerRecord spContainer, ShapeContainer<HSLFShape> parent){
+ HSLFGroupShape group = null;
+ EscherRecord opt = HSLFShape.getEscherChild((EscherContainerRecord)spContainer.getChild(0), (short)0xF122);
if(opt != null){
try {
EscherPropertyFactory f = new EscherPropertyFactory();
if(p.getPropertyNumber() == 0x39F && p.getPropertyValue() == 1){
group = new Table(spContainer, parent);
} else {
- group = new ShapeGroup(spContainer, parent);
+ group = new HSLFGroupShape(spContainer, parent);
}
} catch (Exception e){
logger.log(POILogger.WARN, e.getMessage());
- group = new ShapeGroup(spContainer, parent);
+ group = new HSLFGroupShape(spContainer, parent);
}
} else {
- group = new ShapeGroup(spContainer, parent);
+ group = new HSLFGroupShape(spContainer, parent);
}
return group;
}
- public static Shape createSimpeShape(EscherContainerRecord spContainer, ShapeContainer<Shape> parent){
- Shape shape = null;
+ public static HSLFShape createSimpeShape(EscherContainerRecord spContainer, ShapeContainer<HSLFShape> parent){
+ HSLFShape shape = null;
EscherSpRecord spRecord = spContainer.getChildById(EscherSpRecord.RECORD_ID);
ShapeType type = ShapeType.forId(spRecord.getShapeType(), false);
shape = new Line(spContainer, parent);
break;
case NOT_PRIMITIVE: {
- EscherOptRecord opt = Shape.getEscherChild(spContainer, EscherOptRecord.RECORD_ID);
- EscherProperty prop = Shape.getEscherProperty(opt, EscherProperties.GEOMETRY__VERTICES);
+ EscherOptRecord opt = HSLFShape.getEscherChild(spContainer, EscherOptRecord.RECORD_ID);
+ EscherProperty prop = HSLFShape.getEscherProperty(opt, EscherProperties.GEOMETRY__VERTICES);
if(prop != null)
shape = new Freeform(spContainer, parent);
else {
+++ /dev/null
-/* ====================================================================
- 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.model;
-
-import java.awt.Graphics2D;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.poi.ddf.EscherChildAnchorRecord;
-import org.apache.poi.ddf.EscherClientAnchorRecord;
-import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.ddf.EscherRecord;
-import org.apache.poi.ddf.EscherSpRecord;
-import org.apache.poi.ddf.EscherSpgrRecord;
-import org.apache.poi.sl.usermodel.ShapeContainer;
-import org.apache.poi.sl.usermodel.ShapeType;
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.POILogger;
-
-/**
- * Represents a group of shapes.
- *
- * @author Yegor Kozlov
- */
-public class ShapeGroup extends Shape implements ShapeContainer<Shape> {
-
- /**
- * Create a new ShapeGroup. This constructor is used when a new shape is created.
- *
- */
- public ShapeGroup(){
- this(null, null);
- _escherContainer = createSpContainer(false);
- }
-
- /**
- * Create a ShapeGroup object and initilize it from the supplied Record container.
- *
- * @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
- * @param parent the parent of the shape
- */
- protected ShapeGroup(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
- super(escherRecord, parent);
- }
-
- /**
- * @return the shapes contained in this group container
- */
- public Shape[] getShapes() {
- List<Shape> shapeList = getShapeList();
- Shape[] shapes = shapeList.toArray(new Shape[shapeList.size()]);
- return shapes;
- }
-
- /**
- * Sets the anchor (the bounding box rectangle) of this shape.
- * All coordinates should be expressed in Master units (576 dpi).
- *
- * @param anchor new anchor
- */
- public void setAnchor(java.awt.Rectangle anchor){
-
- EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
- //hack. internal variable EscherClientAnchorRecord.shortRecord can be
- //initialized only in fillFields(). We need to set shortRecord=false;
- byte[] header = new byte[16];
- LittleEndian.putUShort(header, 0, 0);
- LittleEndian.putUShort(header, 2, 0);
- LittleEndian.putInt(header, 4, 8);
- clientAnchor.fillFields(header, 0, null);
-
- clientAnchor.setFlag((short)(anchor.y*MASTER_DPI/POINT_DPI));
- clientAnchor.setCol1((short)(anchor.x*MASTER_DPI/POINT_DPI));
- clientAnchor.setDx1((short)((anchor.width + anchor.x)*MASTER_DPI/POINT_DPI));
- clientAnchor.setRow1((short)((anchor.height + anchor.y)*MASTER_DPI/POINT_DPI));
-
- EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
-
- spgr.setRectX1(anchor.x*MASTER_DPI/POINT_DPI);
- spgr.setRectY1(anchor.y*MASTER_DPI/POINT_DPI);
- spgr.setRectX2((anchor.x + anchor.width)*MASTER_DPI/POINT_DPI);
- spgr.setRectY2((anchor.y + anchor.height)*MASTER_DPI/POINT_DPI);
- }
-
- /**
- * Sets the coordinate space of this group. All children are constrained
- * to these coordinates.
- *
- * @param anchor the coordinate space of this group
- */
- public void setCoordinates(Rectangle2D anchor){
- EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
-
- int x1 = (int)Math.round(anchor.getX()*MASTER_DPI/POINT_DPI);
- int y1 = (int)Math.round(anchor.getY()*MASTER_DPI/POINT_DPI);
- int x2 = (int)Math.round((anchor.getX() + anchor.getWidth())*MASTER_DPI/POINT_DPI);
- int y2 = (int)Math.round((anchor.getY() + anchor.getHeight())*MASTER_DPI/POINT_DPI);
-
- spgr.setRectX1(x1);
- spgr.setRectY1(y1);
- spgr.setRectX2(x2);
- spgr.setRectY2(y2);
-
- }
-
- /**
- * Gets the coordinate space of this group. All children are constrained
- * to these coordinates.
- *
- * @return the coordinate space of this group
- */
- public Rectangle2D getCoordinates(){
- EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
-
- Rectangle2D.Float anchor = new Rectangle2D.Float();
- anchor.x = (float)spgr.getRectX1()*POINT_DPI/MASTER_DPI;
- anchor.y = (float)spgr.getRectY1()*POINT_DPI/MASTER_DPI;
- anchor.width = (float)(spgr.getRectX2() - spgr.getRectX1())*POINT_DPI/MASTER_DPI;
- anchor.height = (float)(spgr.getRectY2() - spgr.getRectY1())*POINT_DPI/MASTER_DPI;
-
- return anchor;
- }
-
- /**
- * Create a new ShapeGroup and create an instance of <code>EscherSpgrContainer</code> which represents a group of shapes
- */
- protected EscherContainerRecord createSpContainer(boolean isChild) {
- EscherContainerRecord spgr = new EscherContainerRecord();
- spgr.setRecordId(EscherContainerRecord.SPGR_CONTAINER);
- spgr.setOptions((short)15);
-
- //The group itself is a shape, and always appears as the first EscherSpContainer in the group container.
- EscherContainerRecord spcont = new EscherContainerRecord();
- spcont.setRecordId(EscherContainerRecord.SP_CONTAINER);
- spcont.setOptions((short)15);
-
- EscherSpgrRecord spg = new EscherSpgrRecord();
- spg.setOptions((short)1);
- spcont.addChildRecord(spg);
-
- EscherSpRecord sp = new EscherSpRecord();
- short type = (short)((ShapeType.NOT_PRIMITIVE.nativeId << 4) + 2);
- sp.setOptions(type);
- sp.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_GROUP);
- spcont.addChildRecord(sp);
-
- EscherClientAnchorRecord anchor = new EscherClientAnchorRecord();
- spcont.addChildRecord(anchor);
-
- spgr.addChildRecord(spcont);
- return spgr;
- }
-
- /**
- * Add a shape to this group.
- *
- * @param shape - the Shape to add
- */
- public void addShape(Shape shape){
- _escherContainer.addChildRecord(shape.getSpContainer());
-
- Sheet sheet = getSheet();
- shape.setSheet(sheet);
- shape.setShapeId(sheet.allocateShapeId());
- shape.afterInsert(sheet);
- }
-
- /**
- * Moves this <code>ShapeGroup</code> to the specified location.
- * <p>
- * @param x the x coordinate of the top left corner of the shape in new location
- * @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();
- int dx = x - anchor.x;
- int dy = y - anchor.y;
- anchor.translate(dx, dy);
- setAnchor(anchor);
-
- Shape[] shape = getShapes();
- for (int i = 0; i < shape.length; i++) {
- java.awt.Rectangle chanchor = shape[i].getAnchor();
- chanchor.translate(dx, dy);
- shape[i].setAnchor(chanchor);
- }
- }
-
- /**
- * Returns the anchor (the bounding box rectangle) of this shape group.
- * All coordinates are expressed in points (72 dpi).
- *
- * @return the anchor of this shape group
- */
- public Rectangle2D getAnchor2D(){
- EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
- Rectangle2D.Float anchor = new Rectangle2D.Float();
- if(clientAnchor == null){
- logger.log(POILogger.INFO, "EscherClientAnchorRecord was not found for shape group. Searching for EscherChildAnchorRecord.");
- EscherChildAnchorRecord rec = getEscherChild(EscherChildAnchorRecord.RECORD_ID);
- anchor = new Rectangle2D.Float(
- (float)rec.getDx1()*POINT_DPI/MASTER_DPI,
- (float)rec.getDy1()*POINT_DPI/MASTER_DPI,
- (float)(rec.getDx2()-rec.getDx1())*POINT_DPI/MASTER_DPI,
- (float)(rec.getDy2()-rec.getDy1())*POINT_DPI/MASTER_DPI
- );
- } else {
- anchor.x = (float)clientAnchor.getCol1()*POINT_DPI/MASTER_DPI;
- anchor.y = (float)clientAnchor.getFlag()*POINT_DPI/MASTER_DPI;
- anchor.width = (float)(clientAnchor.getDx1() - clientAnchor.getCol1())*POINT_DPI/MASTER_DPI ;
- anchor.height = (float)(clientAnchor.getRow1() - clientAnchor.getFlag())*POINT_DPI/MASTER_DPI;
- }
-
- return anchor;
- }
-
- /**
- * Return type of the shape.
- * In most cases shape group type is {@link org.apache.poi.hslf.model.ShapeTypes#NotPrimitive}
- *
- * @return type of the shape.
- */
- public ShapeType getShapeType(){
- EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
- int nativeId = spRecord.getOptions() >> 4;
- return ShapeType.forId(nativeId, false);
- }
-
- /**
- * Returns <code>null</code> - shape groups can't have hyperlinks
- *
- * @return <code>null</code>.
- */
- public Hyperlink getHyperlink(){
- return null;
- }
-
- public void draw(Graphics2D graphics){
-
- AffineTransform at = graphics.getTransform();
-
- Shape[] sh = getShapes();
- for (int i = 0; i < sh.length; i++) {
- sh[i].draw(graphics);
- }
-
- graphics.setTransform(at);
- }
-
- @Override
- public <T extends EscherRecord> T getEscherChild(int recordId){
- EscherContainerRecord groupInfoContainer = (EscherContainerRecord)_escherContainer.getChild(0);
- return groupInfoContainer.getChildById((short)recordId);
- }
-
- public Iterator<Shape> iterator() {
- return getShapeList().iterator();
- }
-
- public boolean removeShape(Shape shape) {
- // TODO: implement!
- throw new UnsupportedOperationException();
- }
-
- /**
- * @return the shapes contained in this group container
- */
- protected List<Shape> getShapeList() {
- // Out escher container record should contain several
- // SpContainers, the first of which is the group shape itself
- Iterator<EscherRecord> iter = _escherContainer.getChildIterator();
-
- // Don't include the first SpContainer, it is always NotPrimitive
- if (iter.hasNext()) {
- iter.next();
- }
- List<Shape> shapeList = new ArrayList<Shape>();
- while (iter.hasNext()) {
- EscherRecord r = iter.next();
- if(r instanceof EscherContainerRecord) {
- // Create the Shape for it
- EscherContainerRecord container = (EscherContainerRecord)r;
- Shape shape = ShapeFactory.createShape(container, this);
- shape.setSheet(getSheet());
- shapeList.add( shape );
- } else {
- // Should we do anything special with these non
- // Container records?
- logger.log(POILogger.ERROR, "Shape contained non container escher record, was " + r.getClass().getName());
- }
- }
-
- return shapeList;
- }
-
-}
* @author Yegor Kozlov
*/
public interface ShapeOutline {
- java.awt.Shape getOutline(Shape shape);
+ java.awt.Shape getOutline(HSLFShape shape);
}
* @author Yegor Kozlov
*/
-public abstract class Sheet implements ShapeContainer<Shape> {
+public abstract class Sheet implements ShapeContainer<HSLFShape> {
private static POILogger logger = POILogFactory.getLogger(Sheet.class);
/**
*
* @return all shapes contained in this Sheet (Slide or Notes)
*/
- public Shape[] getShapes() {
- List<Shape> shapeList = getShapeList();
- return shapeList.toArray(new Shape[shapeList.size()]);
+ public HSLFShape[] getShapes() {
+ List<HSLFShape> shapeList = getShapeList();
+ return shapeList.toArray(new HSLFShape[shapeList.size()]);
}
/**
*
* @param shape - the Shape to add
*/
- public void addShape(Shape shape) {
+ public void addShape(HSLFShape shape) {
PPDrawing ppdrawing = getPPDrawing();
EscherContainerRecord dgContainer = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
- EscherContainerRecord spgr = (EscherContainerRecord) Shape.getEscherChild(dgContainer, EscherContainerRecord.SPGR_CONTAINER);
+ EscherContainerRecord spgr = (EscherContainerRecord) HSLFShape.getEscherChild(dgContainer, EscherContainerRecord.SPGR_CONTAINER);
spgr.addChildRecord(shape.getSpContainer());
shape.setSheet(this);
* @param shape shape to be removed from this sheet, if present.
* @return <tt>true</tt> if the shape was deleted.
*/
- public boolean removeShape(Shape shape) {
+ public boolean removeShape(HSLFShape shape) {
PPDrawing ppdrawing = getPPDrawing();
EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
* @return <code>TextShape</code> or <code>null</code>
*/
public TextShape getPlaceholderByTextType(int type){
- Shape[] shape = getShapes();
+ HSLFShape[] shape = getShapes();
for (int i = 0; i < shape.length; i++) {
if(shape[i] instanceof TextShape){
TextShape tx = (TextShape)shape[i];
* @return <code>TextShape</code> or <code>null</code>
*/
public TextShape getPlaceholder(int type){
- Shape[] shape = getShapes();
+ HSLFShape[] shape = getShapes();
for (int i = 0; i < shape.length; i++) {
if(shape[i] instanceof TextShape){
TextShape tx = (TextShape)shape[i];
}
- public Iterator<Shape> iterator() {
+ public Iterator<HSLFShape> iterator() {
return getShapeList().iterator();
}
*
* @return all shapes contained in this Sheet (Slide or Notes)
*/
- protected List<Shape> getShapeList() {
+ protected List<HSLFShape> getShapeList() {
PPDrawing ppdrawing = getPPDrawing();
EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
throw new IllegalStateException("spgr not found");
}
- List<Shape> shapeList = new ArrayList<Shape>();
+ List<HSLFShape> shapeList = new ArrayList<HSLFShape>();
Iterator<EscherRecord> it = spgr.getChildIterator();
if (it.hasNext()) {
// skip first item
}
for (; it.hasNext();) {
EscherContainerRecord sp = (EscherContainerRecord) it.next();
- Shape sh = ShapeFactory.createShape(sp, null);
+ HSLFShape sh = ShapeFactory.createShape(sp, null);
sh.setSheet(this);
shapeList.add(sh);
}
*
* @author Yegor Kozlov
*/
-public abstract class SimpleShape extends Shape {
+public abstract class SimpleShape extends HSLFShape {
public final static double DEFAULT_LINE_WIDTH = 0.75;
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
* @param parent the parent of the shape
*/
- protected SimpleShape(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
+ protected SimpleShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
//if it is a groupped shape see if we need to transform the coordinates
if (getParent() != null){
- ArrayList<ShapeGroup> lst = new ArrayList<ShapeGroup>();
- for (ShapeContainer<Shape> parent=this.getParent();
- parent instanceof ShapeGroup;
- parent = ((ShapeGroup)parent).getParent()) {
- lst.add(0, (ShapeGroup)parent);
+ ArrayList<HSLFGroupShape> lst = new ArrayList<HSLFGroupShape>();
+ for (ShapeContainer<HSLFShape> parent=this.getParent();
+ parent instanceof HSLFGroupShape;
+ parent = ((HSLFGroupShape)parent).getParent()) {
+ lst.add(0, (HSLFGroupShape)parent);
}
AffineTransform tx = new AffineTransform();
- for(ShapeGroup prnt : lst) {
+ for(HSLFGroupShape prnt : lst) {
Rectangle2D exterior = prnt.getAnchor2D();
Rectangle2D interior = prnt.getCoordinates();
//initialize drawing group id
EscherDggRecord dgg = getSlideShow().getDocumentRecord().getPPDrawingGroup().getEscherDggRecord();
EscherContainerRecord dgContainer = (EscherContainerRecord)getSheetContainer().getPPDrawing().getEscherRecords()[0];
- EscherDgRecord dg = (EscherDgRecord) Shape.getEscherChild(dgContainer, EscherDgRecord.RECORD_ID);
+ EscherDgRecord dg = (EscherDgRecord) HSLFShape.getEscherChild(dgContainer, EscherDgRecord.RECORD_ID);
int dgId = dgg.getMaxDrawingGroupId() + 1;
dg.setOptions((short)(dgId << 4));
dgg.setDrawingsSaved(dgg.getDrawingsSaved() + 1);
if(bg != null)bg.draw(graphics);
if(getFollowMasterObjects()){
- Shape[] sh = master.getShapes();
+ HSLFShape[] sh = master.getShapes();
for (int i = 0; i < sh.length; i++) {
if(MasterSheet.isPlaceholder(sh[i])) continue;
}
}
- Shape[] sh = getShapes();
+ HSLFShape[] sh = getShapes();
for (int i = 0; i < sh.length; i++) {
sh[i].draw(graphics);
}
*
* @author Yegor Kozlov
*/
-public final class Table extends ShapeGroup {
+public final class Table extends HSLFGroupShape {
protected static final int BORDER_TOP = 1;
protected static final int BORDER_RIGHT = 2;
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
* @param parent the parent of the shape
*/
- public Table(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent) {
+ public Table(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent) {
super(escherRecord, parent);
}
}
protected void initTable(){
- List<Shape> shapeList = getShapeList();
- Collections.sort(shapeList, new Comparator<Shape>(){
- public int compare( Shape o1, Shape o2 ) {
+ List<HSLFShape> shapeList = getShapeList();
+ Collections.sort(shapeList, new Comparator<HSLFShape>(){
+ public int compare( HSLFShape o1, HSLFShape o2 ) {
Rectangle anchor1 = o1.getAnchor();
Rectangle anchor2 = o2.getAnchor();
int delta = anchor1.y - anchor2.y;
});
int y0 = -1;
int maxrowlen = 0;
- List<List<Shape>> lst = new ArrayList<List<Shape>>();
- List<Shape> row = null;
- for (Shape sh : shapeList) {
+ List<List<HSLFShape>> lst = new ArrayList<List<HSLFShape>>();
+ List<HSLFShape> row = null;
+ for (HSLFShape sh : shapeList) {
if(sh instanceof TextShape){
Rectangle anchor = sh.getAnchor();
if(anchor.y != y0){
y0 = anchor.y;
- row = new ArrayList<Shape>();
+ row = new ArrayList<HSLFShape>();
lst.add(row);
}
row.add(sh);
* @param escherRecord {@link EscherSpContainer} container which holds information about this shape
* @param parent the parent of the shape
*/
- protected TableCell(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
+ protected TableCell(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
* @param parent the parent of this Shape. For example, if this text box is a cell
* in a table then the parent is Table.
*/
- public TableCell(ShapeContainer<Shape> parent){
+ public TableCell(ShapeContainer<HSLFShape> parent){
super(parent);
setShapeType(ShapeType.RECT);
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
* @param parent the parent of the shape
*/
- protected TextBox(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
+ protected TextBox(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
* @param parent the parent of this Shape. For example, if this text box is a cell
* in a table then the parent is Table.
*/
- public TextBox(ShapeContainer<Shape> parent){
+ public TextBox(ShapeContainer<HSLFShape> parent){
super(parent);
}
TextRulerAtom ruler = run.getTextRuler();
if(ruler != null) {
- int bullet_val = ruler.getBulletOffsets()[indent]*Shape.POINT_DPI/Shape.MASTER_DPI;
- int text_val = ruler.getTextOffsets()[indent]*Shape.POINT_DPI/Shape.MASTER_DPI;
+ int bullet_val = ruler.getBulletOffsets()[indent]*HSLFShape.POINT_DPI/HSLFShape.MASTER_DPI;
+ int text_val = ruler.getTextOffsets()[indent]*HSLFShape.POINT_DPI/HSLFShape.MASTER_DPI;
if(bullet_val > text_val){
int a = bullet_val;
bullet_val = text_val;
if(linespacing >= 0){
el.ascent = textLayout.getAscent()*linespacing/100;
} else {
- el.ascent = -linespacing*Shape.POINT_DPI/Shape.MASTER_DPI;
+ el.ascent = -linespacing*HSLFShape.POINT_DPI/HSLFShape.MASTER_DPI;
}
el._align = rt.getAlignment();
if(sp >= 0){
spaceBefore = lineHeight * sp/100;
} else {
- spaceBefore = -sp*Shape.POINT_DPI/Shape.MASTER_DPI;
+ spaceBefore = -sp*HSLFShape.POINT_DPI/HSLFShape.MASTER_DPI;
}
el.ascent += spaceBefore;
}
if(linespacing >= 0){
descent = (textLayout.getDescent() + textLayout.getLeading())*linespacing/100;
} else {
- descent = -linespacing*Shape.POINT_DPI/Shape.MASTER_DPI;
+ descent = -linespacing*HSLFShape.POINT_DPI/HSLFShape.MASTER_DPI;
}
if (prStart){
int sp = rt.getSpaceAfter();
if(sp >= 0){
spaceAfter = lineHeight * sp/100;
} else {
- spaceAfter = -sp*Shape.POINT_DPI/Shape.MASTER_DPI;
+ spaceAfter = -sp*HSLFShape.POINT_DPI/HSLFShape.MASTER_DPI;
}
el.ascent += spaceAfter;
}
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
* @param parent the parent of the shape
*/
- protected TextShape(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
+ protected TextShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
* @param parent the parent of this Shape. For example, if this text box is a cell
* in a table then the parent is Table.
*/
- public TextShape(ShapeContainer<Shape> parent){
+ public TextShape(ShapeContainer<HSLFShape> parent){
super(null, parent);
- _escherContainer = createSpContainer(parent instanceof ShapeGroup);
+ _escherContainer = createSpContainer(parent instanceof HSLFGroupShape);
}
/**
import java.awt.Color;
import org.apache.poi.hslf.model.MasterSheet;
-import org.apache.poi.hslf.model.Shape;
+import org.apache.poi.hslf.model.HSLFShape;
import org.apache.poi.hslf.model.Sheet;
import org.apache.poi.hslf.model.TextRun;
import org.apache.poi.hslf.model.textproperties.BitMaskTextProp;
* Sets the bullet offset
*/
public void setBulletOffset(int offset) {
- setParaTextPropVal("bullet.offset", offset*Shape.MASTER_DPI/Shape.POINT_DPI);
+ setParaTextPropVal("bullet.offset", offset*HSLFShape.MASTER_DPI/HSLFShape.POINT_DPI);
}
/**
* Returns the bullet offset
*/
public int getBulletOffset() {
- return getParaTextPropVal("bullet.offset")*Shape.POINT_DPI/Shape.MASTER_DPI;
+ return getParaTextPropVal("bullet.offset")*HSLFShape.POINT_DPI/HSLFShape.MASTER_DPI;
}
/**
* Sets the text offset
*/
public void setTextOffset(int offset) {
- setParaTextPropVal("text.offset", offset*Shape.MASTER_DPI/Shape.POINT_DPI);
+ setParaTextPropVal("text.offset", offset*HSLFShape.MASTER_DPI/HSLFShape.POINT_DPI);
}
/**
* Returns the text offset
*/
public int getTextOffset() {
- return getParaTextPropVal("text.offset")*Shape.POINT_DPI/Shape.MASTER_DPI;
+ return getParaTextPropVal("text.offset")*HSLFShape.POINT_DPI/HSLFShape.MASTER_DPI;
}
/**
import org.apache.poi.hslf.model.Notes;
import org.apache.poi.hslf.model.PPFont;
import org.apache.poi.hslf.model.Picture;
-import org.apache.poi.hslf.model.Shape;
+import org.apache.poi.hslf.model.HSLFShape;
import org.apache.poi.hslf.model.Slide;
import org.apache.poi.hslf.model.SlideMaster;
import org.apache.poi.hslf.model.TitleMaster;
*/
public Dimension getPageSize() {
DocumentAtom docatom = _documentRecord.getDocumentAtom();
- int pgx = (int) docatom.getSlideSizeX() * Shape.POINT_DPI / Shape.MASTER_DPI;
- int pgy = (int) docatom.getSlideSizeY() * Shape.POINT_DPI / Shape.MASTER_DPI;
+ int pgx = (int) docatom.getSlideSizeX() * HSLFShape.POINT_DPI / HSLFShape.MASTER_DPI;
+ int pgy = (int) docatom.getSlideSizeY() * HSLFShape.POINT_DPI / HSLFShape.MASTER_DPI;
return new Dimension(pgx, pgy);
}
*/
public void setPageSize(Dimension pgsize) {
DocumentAtom docatom = _documentRecord.getDocumentAtom();
- docatom.setSlideSizeX(pgsize.width * Shape.MASTER_DPI / Shape.POINT_DPI);
- docatom.setSlideSizeY(pgsize.height * Shape.MASTER_DPI / Shape.POINT_DPI);
+ docatom.setSlideSizeX(pgsize.width * HSLFShape.MASTER_DPI / HSLFShape.POINT_DPI);
+ docatom.setSlideSizeY(pgsize.height * HSLFShape.MASTER_DPI / HSLFShape.POINT_DPI);
}
/**
EscherContainerRecord bstore;
EscherContainerRecord dggContainer = _documentRecord.getPPDrawingGroup().getDggContainer();
- bstore = (EscherContainerRecord) Shape.getEscherChild(dggContainer,
+ bstore = (EscherContainerRecord) HSLFShape.getEscherChild(dggContainer,
EscherContainerRecord.BSTORE_CONTAINER);
if (bstore == null) {
bstore = new EscherContainerRecord();
import org.apache.poi.sl.usermodel.*;\r
\r
\r
-public class DrawAutoShape<T extends AutoShape> extends DrawTextShape<T> {\r
+public class DrawAutoShape<T extends AutoShape<? extends TextParagraph>> extends DrawTextShape<T> {\r
public DrawAutoShape(T shape) {\r
super(shape);\r
}\r
--- /dev/null
+package org.apache.poi.sl.draw;\r
+\r
+import java.awt.*;\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.apache.poi.sl.usermodel.*;\r
+\r
+\r
+public class DrawBackground<T extends Background> extends DrawShape<T> {\r
+ public DrawBackground(T shape) {\r
+ super(shape);\r
+ }\r
+\r
+ public void draw(Graphics2D graphics) {\r
+ Dimension pg = shape.getSheet().getSlideShow().getPageSize();\r
+ final Rectangle2D anchor = new Rectangle2D.Double(0, 0, pg.getWidth(), pg.getHeight());\r
+\r
+ PlaceableShape ps = new PlaceableShape(){\r
+ public Rectangle2D getAnchor() { return anchor; }\r
+ public void setAnchor(Rectangle2D anchor) {}\r
+ public double getRotation() { return 0; }\r
+ public void setRotation(double theta) {}\r
+ public void setFlipHorizontal(boolean flip) {}\r
+ public void setFlipVertical(boolean flip) {}\r
+ public boolean getFlipHorizontal() { return false; }\r
+ public boolean getFlipVertical() { return false; }\r
+ };\r
+ \r
+ DrawFactory drawFact = DrawFactory.getInstance(graphics);\r
+ DrawPaint dp = drawFact.getPaint(ps);\r
+ Paint fill = dp.getPaint(graphics, shape.getFillStyle().getPaint());\r
+ Rectangle2D anchor2 = getAnchor(graphics, anchor);\r
+ \r
+ if(fill != null) {\r
+ graphics.setPaint(fill);\r
+ graphics.fill(anchor2);\r
+ }\r
+ }\r
+ \r
+ \r
+}\r
}\r
\r
public static DrawFactory getInstance(Graphics2D graphics) {\r
- // first try to find the factory over the rendering hing\r
- DrawFactory factory = (DrawFactory)graphics.getRenderingHint(DRAW_FACTORY);\r
+ // first try to find the factory over the rendering hint\r
+ DrawFactory factory = null;\r
+ boolean isHint = false;\r
+ if (graphics != null) {\r
+ factory = (DrawFactory)graphics.getRenderingHint(DRAW_FACTORY);\r
+ isHint = true;\r
+ }\r
// secondly try the thread local default\r
if (factory == null) {\r
factory = defaultFactory.get();\r
// and at last, use the default factory\r
if (factory == null) {\r
factory = new DrawFactory();\r
+ }\r
+ if (graphics != null && !isHint) {\r
graphics.setRenderingHint(DRAW_FACTORY, factory);\r
}\r
return factory;\r
}\r
\r
- public Drawable getDrawable(Sheet sheet) {\r
- return new DrawSheet(sheet);\r
- }\r
-\r
- public Drawable getDrawable(MasterSheet sheet) {\r
- return new DrawMasterSheet(sheet);\r
- }\r
-\r
@SuppressWarnings("unchecked")\r
public Drawable getDrawable(Shape shape) {\r
if (shape instanceof TextBox) {\r
- return getDrawable((TextBox)shape);\r
+ return getDrawable((TextBox<? extends TextParagraph<? extends TextRun>>)shape);\r
} else if (shape instanceof FreeformShape) {\r
- return getDrawable((FreeformShape)shape);\r
+ return getDrawable((FreeformShape<? extends TextParagraph<? extends TextRun>>)shape);\r
+ } else if (shape instanceof TextShape) {\r
+ return getDrawable((TextShape<? extends TextParagraph<? extends TextRun>>)shape);\r
+ } else if (shape instanceof ShapeGroup) {\r
+ return getDrawable((ShapeGroup<? extends Shape>)shape);\r
+ } else if (shape instanceof PictureShape) {\r
+ return getDrawable((PictureShape)shape);\r
+ } else if (shape instanceof Background) {\r
+ return getDrawable((Background)shape);\r
+ } else if (shape instanceof Slide) {\r
+ return getDrawable((Slide<? extends Shape>)shape);\r
+ } else if (shape instanceof MasterSheet) {\r
+ return getDrawable((MasterSheet<? extends Shape>)shape);\r
+ } else if (shape instanceof Sheet) {\r
+ return getDrawable((Sheet<? extends Shape>)shape);\r
}\r
\r
throw new IllegalArgumentException("Unsupported shape type: "+shape.getClass());\r
}\r
\r
- public <T extends TextBox> DrawTextBox<T> getDrawable(T shape) {\r
+ public <T extends Slide<? extends Shape>> DrawSlide<T> getDrawable(T sheet) {\r
+ return new DrawSlide<T>(sheet);\r
+ }\r
+\r
+ public <T extends Sheet<? extends Shape>> DrawSheet<T> getDrawable(T sheet) {\r
+ return new DrawSheet<T>(sheet);\r
+ }\r
+\r
+ public <T extends MasterSheet<? extends Shape>> DrawMasterSheet<T> getDrawable(T sheet) {\r
+ return new DrawMasterSheet<T>(sheet);\r
+ }\r
+\r
+ public <T extends TextBox<? extends TextParagraph<?>>> DrawTextBox<T> getDrawable(T shape) {\r
return new DrawTextBox<T>(shape);\r
}\r
\r
- public <T extends FreeformShape> DrawFreeformShape<T> getDrawable(T shape) {\r
+ public <T extends FreeformShape<? extends TextParagraph<? extends TextRun>>> DrawFreeformShape<T> getDrawable(T shape) {\r
return new DrawFreeformShape<T>(shape);\r
}\r
\r
+ public <T extends TextShape<? extends TextParagraph<? extends TextRun>>> DrawTextShape<T> getDrawable(T shape) {\r
+ return new DrawTextShape<T>(shape);\r
+ }\r
+\r
+ public <T extends ShapeGroup<? extends Shape>> DrawShapeGroup<T> getDrawable(T shape) {\r
+ return new DrawShapeGroup<T>(shape);\r
+ }\r
\r
- public DrawTextParagraph getDrawable(TextParagraph paragraph) {\r
- return new DrawTextParagraph(paragraph);\r
+ public <T extends PictureShape> DrawPictureShape<T> getDrawable(T shape) {\r
+ return new DrawPictureShape<T>(shape);\r
+ }\r
+ \r
+ public <T extends TextRun> DrawTextParagraph<T> getDrawable(TextParagraph<T> paragraph) {\r
+ return new DrawTextParagraph<T>(paragraph);\r
}\r
\r
+ public <T extends Background> DrawBackground<T> getDrawable(T shape) {\r
+ return new DrawBackground<T>(shape);\r
+ }\r
+ \r
public DrawTextFragment getTextFragment(TextLayout layout, AttributedString str) {\r
return new DrawTextFragment(layout, str);\r
}\r
\r
import org.apache.poi.sl.usermodel.*;\r
\r
-public class DrawFreeformShape<T extends FreeformShape> extends DrawAutoShape<T> {\r
+public class DrawFreeformShape<T extends FreeformShape<? extends TextParagraph<? extends TextRun>>> extends DrawAutoShape<T> {\r
public DrawFreeformShape(T shape) {\r
super(shape);\r
}\r
package org.apache.poi.sl.draw;\r
\r
-import org.apache.poi.sl.usermodel.MasterSheet;\r
-import org.apache.poi.sl.usermodel.Shape;\r
+import org.apache.poi.sl.usermodel.*;\r
\r
\r
-public class DrawMasterSheet extends DrawSheet {\r
+public class DrawMasterSheet<T extends MasterSheet<? extends Shape>> extends DrawSheet<T> {\r
\r
- public DrawMasterSheet(MasterSheet sheet) {\r
+ public DrawMasterSheet(T sheet) {\r
super(sheet);\r
}\r
\r
* for instance, slide masters and layouts don't display placeholders\r
*/\r
protected boolean canDraw(Shape shape){\r
- return !shape.isPlaceholder();\r
+ return !(shape instanceof SimpleShape) || !((SimpleShape)shape).isPlaceholder();\r
}\r
}\r
import java.io.InputStream;\r
\r
import org.apache.poi.sl.usermodel.*;\r
-import org.apache.poi.sl.usermodel.GradientPaint;\r
-import org.apache.poi.sl.usermodel.TexturePaint;\r
+import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;\r
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
+import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;\r
import org.apache.poi.util.POILogFactory;\r
import org.apache.poi.util.POILogger;\r
\r
\r
float red,green,blue;\r
\r
- Color color;\r
if (lumOff > 0) {\r
float flumOff = lumOff / 100000.f;\r
red = (255.f - r) * (1.f - flumOff) + r;\r
blue = (255.f - b) * flumOff + b;\r
} else {\r
float flumMod = lumMod / 100000.f;\r
- red = r * lumMod;\r
- green = g * lumMod;\r
- blue = b * lumMod;\r
+ red = r * flumMod;\r
+ green = g * flumMod;\r
+ blue = b * flumMod;\r
}\r
return new Color(Math.round(red), Math.round(green), Math.round(blue), c.getAlpha());\r
}\r
--- /dev/null
+package org.apache.poi.sl.draw;\r
+\r
+import java.awt.Graphics2D;\r
+import java.awt.Insets;\r
+import java.awt.geom.Rectangle2D;\r
+import java.io.IOException;\r
+\r
+import org.apache.poi.sl.usermodel.PictureData;\r
+import org.apache.poi.sl.usermodel.PictureShape;\r
+\r
+\r
+public class DrawPictureShape<T extends PictureShape> extends DrawSimpleShape<T> {\r
+ public DrawPictureShape(T shape) {\r
+ super(shape);\r
+ }\r
+ \r
+ @Override\r
+ public void drawContent(Graphics2D graphics) {\r
+ PictureData data = shape.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, shape);\r
+\r
+ Insets insets = shape.getClipping();\r
+\r
+ try {\r
+ renderer.loadImage(data.getData(), data.getContentType());\r
+ renderer.drawImage(graphics, anchor, insets);\r
+ } catch (IOException e) {\r
+ // TODO: draw specific runtime exception?\r
+ throw new RuntimeException(e);\r
+ }\r
+ } \r
+}\r
* @param graphics the graphics whos transform matrix will be modified\r
*/\r
public void applyTransform(Graphics2D graphics) {\r
- Rectangle2D anchor = shape.getAnchor();\r
+ if (!(shape instanceof PlaceableShape)) return;\r
+ \r
+ PlaceableShape ps = (PlaceableShape)shape;\r
+ Rectangle2D anchor = ps.getAnchor();\r
AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM);\r
if(tx != null) {\r
anchor = tx.createTransformedShape(anchor).getBounds2D();\r
}\r
\r
// rotation\r
- double rotation = shape.getRotation();\r
+ double rotation = ps.getRotation();\r
if (rotation != 0.) {\r
// PowerPoint rotates shapes relative to the geometric center\r
double centerX = anchor.getCenterX();\r
txs.rotate(Math.toRadians(-quadrant*90));\r
txs.translate(-centerX, -centerY);\r
txg.concatenate(txs);\r
- Rectangle2D anchor2 = txg.createTransformedShape(shape.getAnchor()).getBounds2D();\r
+ Rectangle2D anchor2 = txg.createTransformedShape(ps.getAnchor()).getBounds2D();\r
scaleX = anchor.getWidth() == 0. ? 1.0 : anchor.getWidth() / anchor2.getWidth();\r
scaleY = anchor.getHeight() == 0. ? 1.0 : anchor.getHeight() / anchor2.getHeight();\r
}\r
}\r
\r
//flip horizontal\r
- if (shape.getFlipHorizontal()) {\r
+ if (ps.getFlipHorizontal()) {\r
graphics.translate(anchor.getX() + anchor.getWidth(), anchor.getY());\r
graphics.scale(-1, 1);\r
graphics.translate(-anchor.getX(), -anchor.getY());\r
}\r
\r
//flip vertical\r
- if (shape.getFlipVertical()) {\r
+ if (ps.getFlipVertical()) {\r
graphics.translate(anchor.getX(), anchor.getY() + anchor.getHeight());\r
graphics.scale(1, -1);\r
graphics.translate(-anchor.getX(), -anchor.getY());\r
\r
public void drawContent(Graphics2D context) {\r
}\r
- \r
+\r
public static Rectangle2D getAnchor(Graphics2D graphics, PlaceableShape shape) {\r
- Rectangle2D anchor = shape.getAnchor();\r
+ return getAnchor(graphics, shape.getAnchor());\r
+ }\r
+ \r
+ public static Rectangle2D getAnchor(Graphics2D graphics, Rectangle2D anchor) {\r
if(graphics == null) {\r
return anchor;\r
}\r
--- /dev/null
+package org.apache.poi.sl.draw;\r
+\r
+import java.awt.Graphics2D;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.apache.poi.sl.usermodel.*;\r
+\r
+\r
+public class DrawShapeGroup<T extends ShapeGroup<? extends Shape>> implements Drawable {\r
+\r
+ protected final T shape;\r
+ \r
+ public DrawShapeGroup(T shape) {\r
+ this.shape = shape;\r
+ }\r
+ \r
+ public void applyTransform(Graphics2D context) {\r
+ }\r
+\r
+ public void draw(Graphics2D graphics) {\r
+\r
+ // the coordinate system of this group of shape\r
+ Rectangle2D interior = shape.getInteriorAnchor();\r
+ // anchor of this group relative to the parent shape\r
+ Rectangle2D exterior = shape.getAnchor();\r
+\r
+ AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM);\r
+ AffineTransform tx0 = new AffineTransform(tx);\r
+\r
+ double scaleX = interior.getWidth() == 0. ? 1.0 : exterior.getWidth() / interior.getWidth();\r
+ double scaleY = interior.getHeight() == 0. ? 1.0 : exterior.getHeight() / interior.getHeight();\r
+\r
+ tx.translate(exterior.getX(), exterior.getY());\r
+ tx.scale(scaleX, scaleY);\r
+ tx.translate(-interior.getX(), -interior.getY());\r
+\r
+ DrawFactory drawFact = DrawFactory.getInstance(graphics);\r
+ \r
+ for (Shape child : shape) {\r
+ // remember the initial transform and restore it after we are done with the drawing\r
+ AffineTransform at = graphics.getTransform();\r
+ graphics.setRenderingHint(Drawable.GSAVE, true);\r
+\r
+ Drawable draw = drawFact.getDrawable(child);\r
+ draw.applyTransform(graphics);\r
+ draw.draw(graphics);\r
+\r
+ // restore the coordinate system\r
+ graphics.setTransform(at);\r
+ graphics.setRenderingHint(Drawable.GRESTORE, true);\r
+ }\r
+\r
+ graphics.setRenderingHint(Drawable.GROUP_TRANSFORM, tx0);\r
+ \r
+ }\r
+\r
+ public void drawContent(Graphics2D context) {\r
+ }\r
+}\r
import java.awt.Graphics2D;\r
import java.awt.geom.AffineTransform;\r
\r
-import org.apache.poi.sl.usermodel.MasterSheet;\r
-import org.apache.poi.sl.usermodel.Shape;\r
-import org.apache.poi.sl.usermodel.Sheet;\r
+import org.apache.poi.sl.usermodel.*;\r
\r
\r
-public class DrawSheet implements Drawable {\r
+public class DrawSheet<T extends Sheet<? extends Shape>> implements Drawable {\r
\r
- protected final Sheet sheet;\r
+ protected final T sheet;\r
\r
- public DrawSheet(Sheet sheet) {\r
+ public DrawSheet(T sheet) {\r
this.sheet = sheet;\r
}\r
\r
\r
public void draw(Graphics2D graphics) {\r
DrawFactory drawFact = DrawFactory.getInstance(graphics);\r
- MasterSheet master = sheet.getMasterSheet();\r
+ MasterSheet<? extends Shape> master = sheet.getMasterSheet();\r
\r
if(sheet.getFollowMasterGraphics() && master != null) {\r
Drawable drawer = drawFact.getDrawable(master);\r
import org.apache.poi.sl.draw.geom.*;\r
import org.apache.poi.sl.usermodel.*;\r
import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize;\r
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;\r
import org.apache.poi.util.Units;\r
\r
Shadow shadow = shape.getShadow();\r
if (shadow == null || (fill == null && line == null)) return;\r
\r
+ SolidPaint shadowPaint = shadow.getFillStyle();\r
+ Color shadowColor = DrawPaint.applyColorTransform(shadowPaint.getSolidColor());\r
+ \r
double shapeRotation = shape.getRotation();\r
if(shape.getFlipVertical()) {\r
shapeRotation += 180;\r
java.awt.Shape s = o.getOutline();\r
Path p = o.getPath();\r
graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, s);\r
+ graphics.setPaint(shadowColor);\r
\r
if(fill != null && p.isFilled()){\r
- graphics.setPaint(fill);\r
graphics.fill(s);\r
} else if (line != null && p.isStroked()) {\r
- graphics.setPaint(line);\r
graphics.draw(s);\r
}\r
}\r
--- /dev/null
+package org.apache.poi.sl.draw;\r
+\r
+import java.awt.Graphics2D;\r
+\r
+import org.apache.poi.sl.usermodel.*;\r
+\r
+\r
+public class DrawSlide<T extends Slide<? extends Shape>> extends DrawSheet<T> {\r
+\r
+ public DrawSlide(T slide) {\r
+ super(slide);\r
+ }\r
+ \r
+ public void draw(Graphics2D graphics) {\r
+ Background bg = sheet.getBackground();\r
+ if(bg != null) {\r
+ DrawFactory drawFact = DrawFactory.getInstance(graphics);\r
+ DrawBackground<Background> db = drawFact.getDrawable(bg);\r
+ db.draw(graphics);\r
+ }\r
+\r
+ super.draw(graphics);\r
+ }\r
+}\r
\r
import org.apache.poi.sl.usermodel.*;\r
\r
-public class DrawTextBox<T extends TextBox> extends DrawAutoShape<T> {\r
+public class DrawTextBox<T extends TextBox<? extends TextParagraph<? extends TextRun>>> extends DrawAutoShape<T> {\r
public DrawTextBox(T shape) {\r
super(shape);\r
}\r
import org.apache.poi.sl.usermodel.TextRun.TextCap;\r
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;\r
\r
-public class DrawTextParagraph implements Drawable {\r
- protected TextParagraph paragraph;\r
+public class DrawTextParagraph<T extends TextRun> implements Drawable {\r
+ protected TextParagraph<T> paragraph;\r
double x, y;\r
protected Insets2D insets = new Insets2D(0,0,0,0);\r
protected List<DrawTextFragment> lines = new ArrayList<DrawTextFragment>();\r
*/\r
protected double maxLineHeight;\r
\r
- public DrawTextParagraph(TextParagraph paragraph) {\r
+ public DrawTextParagraph(TextParagraph<T> paragraph) {\r
this.paragraph = paragraph;\r
}\r
\r
double indent = paragraph.getIndent();\r
\r
double width;\r
- TextShape ts = paragraph.getParentShape();\r
+ TextShape<? extends TextParagraph<T>> ts = paragraph.getParentShape();\r
if (!ts.getWordWrap()) {\r
// if wordWrap == false then we return the advance to the right border of the sheet\r
width = ts.getSheet().getSlideShow().getPageSize().getWidth() - anchor.getX();\r
\r
import org.apache.poi.sl.usermodel.*;\r
\r
-public class DrawTextShape<T extends TextShape> extends DrawSimpleShape<T> {\r
+public class DrawTextShape<T extends TextShape<? extends TextParagraph>> extends DrawSimpleShape<T> {\r
\r
public DrawTextShape(T shape) {\r
super(shape);\r
Insets2D shapePadding = shape.getInsets();\r
\r
double y0 = y;\r
- Iterator<TextParagraph> paragraphs = shape.iterator();\r
+ Iterator<? extends TextParagraph> paragraphs = shape.iterator();\r
\r
boolean isFirstLine = true;\r
while (paragraphs.hasNext()){\r
/**\r
* Compute the cumulative height occupied by the text\r
*/\r
- protected double getTextHeight(){\r
+ public double getTextHeight(){\r
// dry-run in a 1x1 image and return the vertical advance\r
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);\r
Graphics2D graphics = img.createGraphics();\r
return drawParagraphs(graphics, 0, 0);\r
}\r
-\r
- \r
}\r
import java.awt.geom.Rectangle2D;\r
import java.awt.image.BufferedImage;\r
import java.awt.image.RescaleOp;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
+import java.io.*;\r
\r
import javax.imageio.ImageIO;\r
\r
img = ImageIO.read(data);\r
}\r
\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(byte data[], String contentType) throws IOException {\r
+ img = ImageIO.read(new ByteArrayInputStream(data));\r
+ }\r
+\r
+ \r
/**\r
* @return the buffered image\r
*/\r
package org.apache.poi.sl.usermodel;
-public interface AutoShape extends TextShape {
- public TextRun getTextRun();
+public interface AutoShape<T extends TextParagraph> extends TextShape<T> {
}
package org.apache.poi.sl.usermodel;
public interface Background extends Shape {
-
+ FillStyle getFillStyle();
}
\r
package org.apache.poi.sl.usermodel;\r
\r
-public interface FreeformShape extends AutoShape {\r
+public interface FreeformShape<T extends TextParagraph> extends AutoShape<T> {\r
\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.usermodel;\r
-\r
-\r
-public interface GradientPaint extends PaintStyle {\r
- enum GradientType { linear, circular, shape }\r
- \r
- /**\r
- * @return the angle of the gradient\r
- */\r
- double getGradientAngle();\r
- ColorStyle[] getGradientColors();\r
- float[] getGradientFractions();\r
- boolean isRotatedWithShape();\r
- GradientType getGradientType();\r
-}\r
package org.apache.poi.sl.usermodel;
-public interface MasterSheet extends Sheet {
+public interface MasterSheet<T extends Shape> extends Sheet<T> {
}
package org.apache.poi.sl.usermodel;
-public interface Notes extends Sheet {
+public interface Notes<T extends Shape> extends Sheet<T> {
public TextRun getTextRun();
}
package org.apache.poi.sl.usermodel;
+import java.io.InputStream;
+
public interface PaintStyle {
+ public interface SolidPaint extends PaintStyle {
+ ColorStyle getSolidColor();
+ }
+ public interface GradientPaint extends PaintStyle {
+ enum GradientType { linear, circular, shape }
+
+ /**
+ * @return the angle of the gradient
+ */
+ double getGradientAngle();
+ ColorStyle[] getGradientColors();
+ float[] getGradientFractions();
+ boolean isRotatedWithShape();
+ GradientType getGradientType();
+ }
+ public interface TexturePaint extends PaintStyle {
+ /**
+ * @return the raw image stream
+ */
+ InputStream getImageData();
+
+ /**
+ * @return the content type of the image data
+ */
+ String getContentType();
+
+ /**
+ * @return the alpha mask in percents [0..100000]
+ */
+ int getAlpha();
+ }
}
+++ /dev/null
-/* ====================================================================
- 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;
-
-public interface Picture extends SimpleShape {
- public PictureData getPictureData();
-}
package org.apache.poi.sl.usermodel;
+import java.io.IOException;
+
public interface PictureData {
- public int getType();
- public byte[] getUID();
+ public String getContentType();
public byte[] getData();
- public void setData(byte[] data);
+ public void setData(byte[] data) throws IOException;
}
--- /dev/null
+/* ====================================================================
+ 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.awt.Insets;
+
+public interface PictureShape extends SimpleShape {
+ PictureData getPictureData();
+
+ /**
+ * @return the clipping rectangle, which is given in percent in relation to the image width/height
+ */
+ Insets getClipping();
+}
import java.awt.geom.Rectangle2D;\r
\r
public interface PlaceableShape {\r
+ /**\r
+ * @return the position of this shape within the drawing canvas.\r
+ * The coordinates are expressed in points\r
+ */\r
Rectangle2D getAnchor();\r
\r
- FillStyle getFillStyle();\r
- \r
- StrokeStyle getStrokeStyle();\r
+ /**\r
+ * @param anchor the position of this shape within the drawing canvas.\r
+ * The coordinates are expressed in points\r
+ */\r
+ void setAnchor(Rectangle2D anchor);\r
\r
/**\r
* Rotation angle in degrees\r
* @return rotation angle in degrees\r
*/\r
double getRotation();\r
+\r
+ /**\r
+ * Rotate this shape.\r
+ * <p>\r
+ * Positive angles are clockwise (i.e., towards the positive y axis);\r
+ * negative angles are counter-clockwise (i.e., towards the negative y axis).\r
+ * </p>\r
+ *\r
+ * @param theta the rotation angle in degrees.\r
+ */\r
+ void setRotation(double theta);\r
+\r
+ /**\r
+ * @param flip whether the shape is horizontally flipped\r
+ */\r
+ void setFlipHorizontal(boolean flip);\r
+\r
+ /**\r
+ * Whether the shape is vertically flipped\r
+ *\r
+ * @param flip whether the shape is vertically flipped\r
+ */\r
+ void setFlipVertical(boolean flip);\r
+\r
+ /**\r
+ * Whether the shape is horizontally flipped\r
+ *\r
+ * @return whether the shape is horizontally flipped\r
+ */\r
+ boolean getFlipHorizontal();\r
+\r
+ /**\r
+ * Whether the shape is vertically flipped\r
+ *\r
+ * @return whether the shape is vertically flipped\r
+ */\r
+ boolean getFlipVertical();\r
}\r
\r
package org.apache.poi.sl.usermodel;\r
\r
-import java.awt.Color;\r
+import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;\r
+\r
\r
\r
public interface Shadow {\r
+ SimpleShape getShadowParent();\r
+ \r
/**\r
* @return the offset of this shadow in points\r
*/\r
* @return the color of this shadow. \r
* Depending whether the parent shape is filled or stroked, this color is used to fill or stroke this shadow\r
*/\r
- Color getColor(); \r
+ SolidPaint getFillStyle(); \r
}\r
package org.apache.poi.sl.usermodel;
-import java.awt.geom.Rectangle2D;
-
-import org.apache.poi.sl.draw.geom.CustomGeometry;
-
-public interface Shape extends PlaceableShape {
- CustomGeometry getGeometry();
-
- ShapeType getShapeType();
-
- void setAnchor(Rectangle2D anchor);
+public interface Shape {
ShapeContainer getParent();
- boolean isPlaceholder();
-
/**
*
* @return the sheet this shape belongs to
*/
Sheet getSheet();
- /**
- * Rotate this shape.
- * <p>
- * Positive angles are clockwise (i.e., towards the positive y axis);
- * negative angles are counter-clockwise (i.e., towards the negative y axis).
- * </p>
- *
- * @param theta the rotation angle in degrees.
- */
- void setRotation(double theta);
-
- /**
- * @param flip whether the shape is horizontally flipped
- */
- void setFlipHorizontal(boolean flip);
-
- /**
- * Whether the shape is vertically flipped
- *
- * @param flip whether the shape is vertically flipped
- */
- void setFlipVertical(boolean flip);
-
- /**
- * Whether the shape is horizontally flipped
- *
- * @return whether the shape is horizontally flipped
- */
- boolean getFlipHorizontal();
-
- /**
- * Whether the shape is vertically flipped
- *
- * @return whether the shape is vertically flipped
- */
- boolean getFlipVertical();
}
package org.apache.poi.sl.usermodel;
-public interface ShapeContainer extends Iterable<Shape>, PlaceableShape {
+public interface ShapeContainer<T extends Shape> extends Iterable<T> {
/**
* Returns an array containing all of the elements in this container in proper
* sequence (from first to last element).
* @return an array containing all of the elements in this container in proper
* sequence
*/
- public Shape[] getShapes();
+ public T[] getShapes();
- public void addShape(Shape shape);
+ public void addShape(T shape);
/**
* Removes the specified shape from this sheet, if it is present
* @throws IllegalArgumentException if the type of the specified shape
* is incompatible with this sheet (optional)
*/
- public boolean removeShape(Shape shape);
+ public boolean removeShape(T shape);
}
package org.apache.poi.sl.usermodel;
-public interface ShapeGroup extends ShapeContainer {
+import java.awt.geom.Rectangle2D;
+public interface ShapeGroup<T extends Shape> extends ShapeContainer<T>, PlaceableShape {
+ Rectangle2D getInteriorAnchor();
}
/**
* Common parent of Slides, Notes and Masters
*/
-public interface Sheet extends ShapeContainer {
+public interface Sheet<T extends Shape> extends ShapeContainer<T> {
SlideShow getSlideShow();
/**
*/
boolean getFollowMasterGraphics();
- MasterSheet getMasterSheet();
+ MasterSheet<T> getMasterSheet();
Background getBackground();
}
package org.apache.poi.sl.usermodel;
+import org.apache.poi.sl.draw.geom.CustomGeometry;
import org.apache.poi.sl.draw.geom.IAdjustableShape;
-public interface SimpleShape extends Shape, IAdjustableShape {
- StrokeStyle getStrokeStyle();
+public interface SimpleShape extends Shape, IAdjustableShape, PlaceableShape {
+ FillStyle getFillStyle();
+ LineDecoration getLineDecoration();
+ StrokeStyle getStrokeStyle();
+
+ CustomGeometry getGeometry();
+
+ ShapeType getShapeType();
+
+ boolean isPlaceholder();
+
Shadow getShadow();
- LineDecoration getLineDecoration();
-
- Hyperlink getHyperlink();
- void setHyperlink(Hyperlink hyperlink);
}
package org.apache.poi.sl.usermodel;
-public interface Slide extends Sheet {
- public Notes getNotes();
- public void setNotes(Notes notes);
+public interface Slide<T extends Shape> extends Sheet<T> {
+ public Notes<T> getNotes();
+ public void setNotes(Notes<T> notes);
public boolean getFollowMasterBackground();
public void setFollowMasterBackground(boolean follow);
+++ /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
-\r
-public interface SolidPaint extends PaintStyle {\r
- ColorStyle getSolidColor();\r
-}\r
package org.apache.poi.sl.usermodel;
-public interface TextBox extends AutoShape {
+public interface TextBox<T extends TextParagraph> extends AutoShape<T> {
}
import java.awt.Color;\r
\r
\r
-public interface TextParagraph extends Iterable<TextRun> {\r
+public interface TextParagraph<T extends TextRun> extends Iterable<T> {\r
/**\r
* Specified a list of text alignment types\r
*/\r
*/\r
BulletStyle getBulletStyle();\r
\r
- TextShape getParentShape();\r
+ TextShape<? extends TextParagraph<T>> getParentShape();\r
}\r
\r
\r
\r
-public interface TextShape extends SimpleShape, Iterable<TextParagraph> {\r
+public interface TextShape<T extends TextParagraph<?>> extends SimpleShape, Iterable<T> {\r
/**\r
* Vertical Text Types\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.usermodel;\r
-\r
-import java.io.InputStream;\r
-\r
-public interface TexturePaint extends PaintStyle {\r
- /**\r
- * @return the raw image stream\r
- */\r
- InputStream getImageData();\r
-\r
- /**\r
- * @return the content type of the image data\r
- */\r
- String getContentType();\r
- \r
- /**\r
- * @return the alpha mask in percents [0..100000]\r
- */\r
- int getAlpha();\r
-}\r
assertTrue(slide.getFollowMasterBackground());
assertEquals(Fill.FILL_SOLID, slide.getBackground().getFill().getFillType());
- Shape shape = new AutoShape(ShapeType.RECT);
+ HSLFShape shape = new AutoShape(ShapeType.RECT);
assertEquals(Fill.FILL_SOLID, shape.getFill().getFillType());
}
public void readBackground() throws Exception {
SlideShow ppt = new SlideShow(_slTests.openResourceAsStream("backgrounds.ppt"));
Fill fill;
- Shape shape;
+ HSLFShape shape;
Slide[] slide = ppt.getSlides();
SlideShow ppt = new SlideShow();
Slide slide;
Fill fill;
- Shape shape;
+ HSLFShape shape;
int idx;
//slide 1
}
- private int getFillPictureRefCount(Shape shape, Fill fill) {
+ private int getFillPictureRefCount(HSLFShape shape, Fill fill) {
EscherOptRecord opt = shape.getEscherOptRecord();
- EscherSimpleProperty p = Shape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE);
+ EscherSimpleProperty p = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE);
if(p != null) {
int idx = p.getPropertyValue();
SlideShow ppt = sheet.getSlideShow();
Document doc = ppt.getDocumentRecord();
EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
- EscherContainerRecord bstore = Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
+ EscherContainerRecord bstore = HSLFShape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
List<EscherRecord> lst = bstore.getChildRecords();
return ((EscherBSERecord)lst.get(idx-1)).getRef();
}
SlideShow ppt = new SlideShow(_slTests.openResourceAsStream("ole2-embedding-2003.ppt"));
Slide slide = ppt.getSlides()[0];
- Shape[] sh = slide.getShapes();
+ HSLFShape[] sh = slide.getShapes();
int cnt = 0;
for (int i = 0; i < sh.length; i++) {
if(sh[i] instanceof OLEShape){
assertEquals(1, ppt.getSlides().length);
// Add some stuff into it
- ShapeGroup group = new ShapeGroup();
+ HSLFGroupShape group = new HSLFGroupShape();
Dimension pgsize = ppt.getPageSize();
java.awt.Rectangle bounds = new java.awt.Rectangle(0, 0, (int)pgsize.getWidth(), (int)pgsize.getHeight());
group.setAnchor(bounds);
assertEquals(1, ppt.getSlides().length);
slide = ppt.getSlides()[0];
- Shape[] shape = slide.getShapes();
+ HSLFShape[] shape = slide.getShapes();
assertEquals(shape.length, 1); //group shape
- assertTrue(shape[0] instanceof ShapeGroup); //group shape
+ assertTrue(shape[0] instanceof HSLFGroupShape); //group shape
- group = (ShapeGroup)shape[0];
+ group = (HSLFGroupShape)shape[0];
shape = group.getShapes();
assertEquals(shape.length, 3);
}
assertEquals(1, ppt.getSlides().length);
slide = ppt.getSlides()[0];
- Shape[] shape = slide.getShapes();
+ HSLFShape[] shape = slide.getShapes();
assertEquals(2, shape.length);
assertTrue(shape[0] instanceof Line); //group shape
public void textBoxRead() throws Exception {
ppt = new SlideShow(_slTests.openResourceAsStream("with_textbox.ppt"));
Slide sl = ppt.getSlides()[0];
- Shape[] sh = sl.getShapes();
+ HSLFShape[] sh = sl.getShapes();
for (int i = 0; i < sh.length; i++) {
assertTrue(sh[i] instanceof TextBox);
TextBox txtbox = (TextBox)sh[i];
}
ArrayList<String> lst2 = new ArrayList<String>();
- Shape[] sh = sl[k].getShapes();
+ HSLFShape[] sh = sl[k].getShapes();
for (int i = 0; i < sh.length; i++) {
if (sh[i] instanceof TextShape){
TextShape tbox = (TextShape)sh[i];
Slide slide = ppt.createSlide();
Dimension pgsize = ppt.getPageSize();
- ShapeGroup group = new ShapeGroup();
+ HSLFGroupShape group = new HSLFGroupShape();
group.setAnchor(new Rectangle(0, 0, (int)pgsize.getWidth(), (int)pgsize.getHeight()));
slide.addShape(group);
slide = ppt.getSlides()[0];
- Shape[] shape = slide.getShapes();
+ HSLFShape[] shape = slide.getShapes();
assertEquals(1, shape.length);
- assertTrue(shape[0] instanceof ShapeGroup);
+ assertTrue(shape[0] instanceof HSLFGroupShape);
- group = (ShapeGroup)shape[0];
- Shape[] grshape = group.getShapes();
+ group = (HSLFGroupShape)shape[0];
+ HSLFShape[] grshape = group.getShapes();
assertEquals(2, grshape.length);
assertTrue(grshape[0] instanceof Picture);
assertTrue(grshape[1] instanceof Line);
String file = "with_textbox.ppt";
SlideShow ppt = new SlideShow(_slTests.openResourceAsStream(file));
Slide sl = ppt.getSlides()[0];
- Shape[] sh = sl.getShapes();
+ HSLFShape[] sh = sl.getShapes();
assertEquals("expected four shaped in " + file, 4, sh.length);
//remove all
for (int i = 0; i < sh.length; i++) {
public void shapeId() {
SlideShow ppt = new SlideShow();
Slide slide = ppt.createSlide();
- Shape shape = null;
+ HSLFShape shape = null;
//EscherDgg is a document-level record which keeps track of the drawing groups
EscherDggRecord dgg = ppt.getDocumentRecord().getPPDrawingGroup().getEscherDggRecord();
@Test
public void lineColor() throws IOException {
SlideShow ppt = new SlideShow(_slTests.openResourceAsStream("51731.ppt"));
- Shape[] shape = ppt.getSlides()[0].getShapes();
+ HSLFShape[] shape = ppt.getSlides()[0].getShapes();
assertEquals(4, shape.length);
assertNotNull(txt[i].getSheet());
}
- Shape[] shape = sheet.getShapes();
+ HSLFShape[] shape = sheet.getShapes();
if (shape == null) {
throw new AssertionFailedError("no shapes");
}
public void test45889(){
SlideShow ppt = new SlideShow();
Slide slide = ppt.createSlide();
- Shape[] shapes;
+ HSLFShape[] shapes;
Table tbl1 = new Table(1, 5);
assertEquals(5, tbl1.getNumberOfColumns());
assertEquals(1, tbl1.getNumberOfRows());
assertSame(run2, runs[1]);
//as getShapes()
- Shape[] sh = slide.getShapes();
+ HSLFShape[] sh = slide.getShapes();
assertEquals(2, sh.length);
assertTrue(sh[0] instanceof TextBox);
TextBox box1 = (TextBox)sh[0];
public void test48916() throws IOException {
SlideShow ppt = new SlideShow(_slTests.openResourceAsStream("SampleShow.ppt"));
for(Slide slide : ppt.getSlides()){
- for(Shape sh : slide.getShapes()){
+ for(HSLFShape sh : slide.getShapes()){
if(sh instanceof TextShape){
TextShape tx = (TextShape)sh;
TextRun run = tx.getTextRun();
ppt.write(out);
ppt = new SlideShow(new ByteArrayInputStream(out.toByteArray()));
for(Slide slide : ppt.getSlides()){
- for(Shape sh : slide.getShapes()){
+ for(HSLFShape sh : slide.getShapes()){
if(sh instanceof TextShape){
TextShape tx = (TextShape)sh;
TextRun run = tx.getTextRun();
List<String> lst1 = new ArrayList<String>();
Slide slide = ppt.getSlides()[0];
- Shape[] shape = slide.getShapes();
+ HSLFShape[] shape = slide.getShapes();
for (int i = 0; i < shape.length; i++) {
assertTrue("Expected TextShape but found " + shape[i].getClass().getName(), shape[i] instanceof TextShape);
TextShape tx = (TextShape)shape[i];
ppt = new SlideShow(new ByteArrayInputStream(out.toByteArray()));
slide = ppt.getSlides()[0];
- Shape[] shape = slide.getShapes();
+ HSLFShape[] shape = slide.getShapes();
assertTrue(shape[0] instanceof TextShape);
shape1 = (TextShape)shape[0];
Slide slide = ppt.getSlides()[0];
Map<String,TextShape> map = new HashMap<String,TextShape>();
- Shape[] shape = slide.getShapes();
+ HSLFShape[] shape = slide.getShapes();
for (int i = 0; i < shape.length; i++) {
if(shape[i] instanceof TextShape){
TextShape tx = (TextShape)shape[i];
TextShape tx;
tx = map.get("TEST1");
- assertEquals(0.1, tx.getMarginLeft()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
- assertEquals(0.1, tx.getMarginRight()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
- assertEquals(0.39, tx.getMarginTop()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
- assertEquals(0.05, tx.getMarginBottom()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
+ assertEquals(0.1, tx.getMarginLeft()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+ assertEquals(0.1, tx.getMarginRight()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+ assertEquals(0.39, tx.getMarginTop()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+ assertEquals(0.05, tx.getMarginBottom()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
tx = map.get("TEST2");
- assertEquals(0.1, tx.getMarginLeft()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
- assertEquals(0.1, tx.getMarginRight()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
- assertEquals(0.05, tx.getMarginTop()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
- assertEquals(0.39, tx.getMarginBottom()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
+ assertEquals(0.1, tx.getMarginLeft()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+ assertEquals(0.1, tx.getMarginRight()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+ assertEquals(0.05, tx.getMarginTop()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+ assertEquals(0.39, tx.getMarginBottom()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
tx = map.get("TEST3");
- assertEquals(0.39, tx.getMarginLeft()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
- assertEquals(0.1, tx.getMarginRight()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
- assertEquals(0.05, tx.getMarginTop()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
- assertEquals(0.05, tx.getMarginBottom()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
+ assertEquals(0.39, tx.getMarginLeft()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+ assertEquals(0.1, tx.getMarginRight()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+ assertEquals(0.05, tx.getMarginTop()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+ assertEquals(0.05, tx.getMarginBottom()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
tx = map.get("TEST4");
- assertEquals(0.1, tx.getMarginLeft()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
- assertEquals(0.39, tx.getMarginRight()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
- assertEquals(0.05, tx.getMarginTop()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
- assertEquals(0.05, tx.getMarginBottom()*Shape.EMU_PER_POINT/Shape.EMU_PER_INCH, 0.01);
+ assertEquals(0.1, tx.getMarginLeft()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+ assertEquals(0.39, tx.getMarginRight()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+ assertEquals(0.05, tx.getMarginTop()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
+ assertEquals(0.05, tx.getMarginBottom()*HSLFShape.EMU_PER_POINT/HSLFShape.EMU_PER_INCH, 0.01);
}
@Test
SlideShow ppt = new SlideShow(_slTests.openResourceAsStream("52599.ppt"));
Slide slide = ppt.getSlides()[0];
- Shape[] sh = slide.getShapes();
+ HSLFShape[] sh = slide.getShapes();
assertEquals(3, sh.length);
TextShape sh0 = (TextShape)sh[0];
import org.apache.poi.hslf.model.MasterSheet;
import org.apache.poi.hslf.model.Notes;
import org.apache.poi.hslf.model.Picture;
-import org.apache.poi.hslf.model.Shape;
-import org.apache.poi.hslf.model.ShapeGroup;
+import org.apache.poi.hslf.model.HSLFShape;
+import org.apache.poi.hslf.model.HSLFGroupShape;
import org.apache.poi.hslf.model.Slide;
import org.apache.poi.hslf.model.SlideMaster;
import org.apache.poi.hslf.model.TextBox;
HSLFSlideShow hslf = new HSLFSlideShow(_slTests.openResourceAsStream("42485.ppt"));
SlideShow ppt = new SlideShow(hslf);
- Shape[] shape = ppt.getSlides()[0].getShapes();
+ HSLFShape[] shape = ppt.getSlides()[0].getShapes();
for (int i = 0; i < shape.length; i++) {
- if(shape[i] instanceof ShapeGroup){
- ShapeGroup group = (ShapeGroup)shape[i];
- Shape[] sh = group.getShapes();
+ if(shape[i] instanceof HSLFGroupShape){
+ HSLFGroupShape group = (HSLFGroupShape)shape[i];
+ HSLFShape[] sh = group.getShapes();
for (int j = 0; j < sh.length; j++) {
if( sh[j] instanceof TextBox){
TextBox txt = (TextBox)sh[j];
HSLFSlideShow hslf = new HSLFSlideShow(_slTests.openResourceAsStream("42485.ppt"));
SlideShow ppt = new SlideShow(hslf);
- Shape[] shape = ppt.getSlides()[0].getShapes();
+ HSLFShape[] shape = ppt.getSlides()[0].getShapes();
for (int i = 0; i < shape.length; i++) {
- if(shape[i] instanceof ShapeGroup){
- ShapeGroup group = (ShapeGroup)shape[i];
+ if(shape[i] instanceof HSLFGroupShape){
+ HSLFGroupShape group = (HSLFGroupShape)shape[i];
assertNotNull(group.getAnchor());
- Shape[] sh = group.getShapes();
+ HSLFShape[] sh = group.getShapes();
for (int j = 0; j < sh.length; j++) {
assertNotNull(sh[j].getAnchor());
}
Slide[] slide = ppt.getSlides();
for (int i = 0; i < slide.length; i++) {
@SuppressWarnings("unused")
- Shape[] shape = slide[i].getShapes();
+ HSLFShape[] shape = slide[i].getShapes();
}
assertTrue("No Exceptions while reading file", true);
//walk down the tree and see if there were no errors while reading
Slide[] slide = ppt.getSlides();
for (int i = 0; i < slide.length; i++) {
- Shape[] shape = slide[i].getShapes();
+ HSLFShape[] shape = slide[i].getShapes();
for (int j = 0; j < shape.length; j++) {
assertNotNull(shape[j].getShapeName());
- if (shape[j] instanceof ShapeGroup){
- ShapeGroup group = (ShapeGroup)shape[j];
- Shape[] comps = group.getShapes();
+ if (shape[j] instanceof HSLFGroupShape){
+ HSLFGroupShape group = (HSLFGroupShape)shape[j];
+ HSLFShape[] comps = group.getShapes();
for (int k = 0; k < comps.length; k++) {
assertNotNull(comps[k].getShapeName());
}
SlideShow ppt = new SlideShow(hslf);
//test case from the bug report
- ShapeGroup shapeGroup = (ShapeGroup)ppt.getSlides()[11].getShapes()[10];
+ HSLFGroupShape shapeGroup = (HSLFGroupShape)ppt.getSlides()[11].getShapes()[10];
Picture picture = (Picture)shapeGroup.getShapes()[0];
picture.getPictureData();
//walk down the tree and see if there were no errors while reading
Slide[] slide = ppt.getSlides();
for (int i = 0; i < slide.length; i++) {
- Shape[] shape = slide[i].getShapes();
+ HSLFShape[] shape = slide[i].getShapes();
for (int j = 0; j < shape.length; j++) {
- if (shape[j] instanceof ShapeGroup){
- ShapeGroup group = (ShapeGroup)shape[j];
- Shape[] comps = group.getShapes();
+ if (shape[j] instanceof HSLFGroupShape){
+ HSLFGroupShape group = (HSLFGroupShape)shape[j];
+ HSLFShape[] comps = group.getShapes();
for (int k = 0; k < comps.length; k++) {
- Shape comp = comps[k];
+ HSLFShape comp = comps[k];
if (comp instanceof Picture){
@SuppressWarnings("unused")
PictureData pict = ((Picture)comp).getPictureData();
// Check the shape based text runs
List<TextRun> lst = new ArrayList<TextRun>();
- Shape[] shape = slide.getShapes();
+ HSLFShape[] shape = slide.getShapes();
for (int i = 0; i < shape.length; i++) {
if( shape[i] instanceof TextShape){
TextRun textRun = ((TextShape)shape[i]).getTextRun();
SlideShow ppt = new SlideShow(_slTests.openResourceAsStream("41071.ppt"));
Slide slide = ppt.getSlides()[0];
- Shape[] sh = slide.getShapes();
+ HSLFShape[] sh = slide.getShapes();
assertEquals(1, sh.length);
assertTrue(sh[0] instanceof TextShape);
TextShape tx = (TextShape)sh[0];
// get slides
for (Slide slide : ppt.getSlides()) {
- for (Shape shape : slide.getShapes()) {
+ for (HSLFShape shape : slide.getShapes()) {
if (!(shape instanceof TextBox)) continue;
TextBox tb = (TextBox) shape;
// work with TextBox
try {
SlideShow slideShow = new SlideShow(inputStream);
Slide slide = slideShow.getSlides()[0];
- ShapeGroup sg = (ShapeGroup)slide.getShapes()[0];
+ HSLFGroupShape sg = (HSLFGroupShape)slide.getShapes()[0];
TextBox tb = (TextBox)sg.getShapes()[0];
String text = StringUtil.mapMsCodepointString(tb.getText());
assertEquals("\u226575 years", text);
SlideShow slideShow = new SlideShow(inputStream);
AutoShape as = (AutoShape)slideShow.getSlides()[0].getShapes()[0];
EscherOptRecord opt = as.getEscherOptRecord();
- EscherArrayProperty ep = Shape.getEscherProperty(opt, EscherProperties.FILL__SHADECOLORS);
+ EscherArrayProperty ep = HSLFShape.getEscherProperty(opt, EscherProperties.FILL__SHADECOLORS);
double exp[][] = {
// r, g, b, position
{ 94, 158, 255, 0 },
import org.apache.poi.hslf.blip.PNG;
import org.apache.poi.hslf.blip.WMF;
import org.apache.poi.hslf.model.Picture;
-import org.apache.poi.hslf.model.Shape;
+import org.apache.poi.hslf.model.HSLFShape;
import org.apache.poi.hslf.model.Slide;
/**
ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
//make sure we can read this picture shape and it refers to the correct picture data
- Shape[] sh = ppt.getSlides()[0].getShapes();
+ HSLFShape[] sh = ppt.getSlides()[0].getShapes();
assertEquals(1, sh.length);
pict = (Picture)sh[0];
assertEquals(idx, pict.getPictureIndex());
ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
//make sure we can read this picture shape and it refers to the correct picture data
- Shape[] sh = ppt.getSlides()[0].getShapes();
+ HSLFShape[] sh = ppt.getSlides()[0].getShapes();
assertEquals(1, sh.length);
pict = (Picture)sh[0];
assertEquals(idx, pict.getPictureIndex());
ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
//make sure we can get this picture shape and it refers to the correct picture data
- Shape[] sh = ppt.getSlides()[0].getShapes();
+ HSLFShape[] sh = ppt.getSlides()[0].getShapes();
assertEquals(1, sh.length);
pict = (Picture)sh[0];
assertEquals(idx, pict.getPictureIndex());
ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
//make sure we can read this picture shape and it refers to the correct picture data
- Shape[] sh = ppt.getSlides()[0].getShapes();
+ HSLFShape[] sh = ppt.getSlides()[0].getShapes();
assertEquals(1, sh.length);
pict = (Picture)sh[0];
assertEquals(idx, pict.getPictureIndex());
ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
//make sure we can read this picture shape and it refers to the correct picture data
- Shape[] sh = ppt.getSlides()[0].getShapes();
+ HSLFShape[] sh = ppt.getSlides()[0].getShapes();
assertEquals(1, sh.length);
pict = (Picture)sh[0];
assertEquals(idx, pict.getPictureIndex());
ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
//make sure we can read this picture shape and it refers to the correct picture data
- Shape[] sh = ppt.getSlides()[0].getShapes();
+ HSLFShape[] sh = ppt.getSlides()[0].getShapes();
assertEquals(1, sh.length);
pict = (Picture)sh[0];
assertEquals(idx, pict.getPictureIndex());
import junit.framework.TestCase;
-import org.apache.poi.hslf.model.Shape;
+import org.apache.poi.hslf.model.HSLFShape;
import org.apache.poi.hslf.model.Slide;
import org.apache.poi.hslf.model.Table;
import org.apache.poi.hslf.model.TextRun;
assertEquals("Dummy text", textRuns[1].getRawText());
- final Shape[] shapes = s.getShapes();
+ final HSLFShape[] shapes = s.getShapes();
assertNotNull(shapes);
assertEquals(3, shapes.length);
assertTrue(shapes[2] instanceof Table);