From: Andreas Beeker Date: Sat, 7 Mar 2015 23:35:40 +0000 (+0000) Subject: committing intermediate results - xslf now compiles - hslf needs to be migrated to... X-Git-Tag: REL_3_13_FINAL~207^2~21 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=7afac11f67ef21f520dc7b2e797e36f432624222;p=poi.git committing intermediate results - xslf now compiles - hslf needs to be migrated to common interface - drawing is not yet tested git-svn-id: https://svn.apache.org/repos/asf/poi/branches/common_sl@1664935 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java b/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java index 489ba22a14..7d013237ff 100644 --- a/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java +++ b/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java @@ -419,7 +419,7 @@ public final class ApacheconEU08 { 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); diff --git a/src/examples/src/org/apache/poi/hslf/examples/DataExtraction.java b/src/examples/src/org/apache/poi/hslf/examples/DataExtraction.java index a278e894b6..e0f58741e1 100644 --- a/src/examples/src/org/apache/poi/hslf/examples/DataExtraction.java +++ b/src/examples/src/org/apache/poi/hslf/examples/DataExtraction.java @@ -60,7 +60,7 @@ public final class DataExtraction { //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]; @@ -102,7 +102,7 @@ public final class DataExtraction { //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]; diff --git a/src/examples/src/org/apache/poi/hslf/examples/Graphics2DDemo.java b/src/examples/src/org/apache/poi/hslf/examples/Graphics2DDemo.java index 8d7921146a..a2f14ac41b 100644 --- a/src/examples/src/org/apache/poi/hslf/examples/Graphics2DDemo.java +++ b/src/examples/src/org/apache/poi/hslf/examples/Graphics2DDemo.java @@ -46,7 +46,7 @@ public final class Graphics2DDemo { 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); diff --git a/src/examples/src/org/apache/poi/hslf/examples/Hyperlinks.java b/src/examples/src/org/apache/poi/hslf/examples/Hyperlinks.java index 968426c513..a90b6a1df0 100644 --- a/src/examples/src/org/apache/poi/hslf/examples/Hyperlinks.java +++ b/src/examples/src/org/apache/poi/hslf/examples/Hyperlinks.java @@ -21,7 +21,7 @@ import org.apache.poi.hslf.usermodel.SlideShow; 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; @@ -63,7 +63,7 @@ public final class Hyperlinks { //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) { diff --git a/src/examples/src/org/apache/poi/hslf/examples/SoundFinder.java b/src/examples/src/org/apache/poi/hslf/examples/SoundFinder.java index b31019db94..571c86a425 100644 --- a/src/examples/src/org/apache/poi/hslf/examples/SoundFinder.java +++ b/src/examples/src/org/apache/poi/hslf/examples/SoundFinder.java @@ -37,7 +37,7 @@ public class SoundFinder { 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) { @@ -54,7 +54,7 @@ public class SoundFinder { * @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(); diff --git a/src/ooxml/java/org/apache/poi/xslf/model/ParagraphPropertyFetcher.java b/src/ooxml/java/org/apache/poi/xslf/model/ParagraphPropertyFetcher.java index 65c19e6d74..c6c583616c 100644 --- a/src/ooxml/java/org/apache/poi/xslf/model/ParagraphPropertyFetcher.java +++ b/src/ooxml/java/org/apache/poi/xslf/model/ParagraphPropertyFetcher.java @@ -19,7 +19,7 @@ package org.apache.poi.xslf.model; -import org.apache.poi.xslf.usermodel.XSLFSimpleShape; +import org.apache.poi.xslf.usermodel.XSLFShape; import org.apache.xmlbeans.XmlObject; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; @@ -34,7 +34,7 @@ public abstract class ParagraphPropertyFetcher extends PropertyFetcher { _level = level; } - public boolean fetch(XSLFSimpleShape shape) { + public boolean fetch(XSLFShape shape) { XmlObject[] o = shape.getXmlObject().selectPath( "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " + diff --git a/src/ooxml/java/org/apache/poi/xslf/model/PropertyFetcher.java b/src/ooxml/java/org/apache/poi/xslf/model/PropertyFetcher.java index ddb3f0745b..f9e8a780da 100644 --- a/src/ooxml/java/org/apache/poi/xslf/model/PropertyFetcher.java +++ b/src/ooxml/java/org/apache/poi/xslf/model/PropertyFetcher.java @@ -36,7 +36,7 @@ public abstract class PropertyFetcher { * @param shape the shape being examined * @return true if the desired property was fetched */ - public abstract boolean fetch(XSLFShape shape) ; + public abstract boolean fetch(XSLFShape shape); public T getValue(){ return _value; diff --git a/src/ooxml/java/org/apache/poi/xslf/model/TextBodyPropertyFetcher.java b/src/ooxml/java/org/apache/poi/xslf/model/TextBodyPropertyFetcher.java index b66a1e5f7a..cc8486a33c 100644 --- a/src/ooxml/java/org/apache/poi/xslf/model/TextBodyPropertyFetcher.java +++ b/src/ooxml/java/org/apache/poi/xslf/model/TextBodyPropertyFetcher.java @@ -19,7 +19,7 @@ package org.apache.poi.xslf.model; -import org.apache.poi.xslf.usermodel.XSLFSimpleShape; +import org.apache.poi.xslf.usermodel.XSLFShape; import org.apache.xmlbeans.XmlObject; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties; @@ -32,7 +32,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties; */ public abstract class TextBodyPropertyFetcher extends PropertyFetcher { - public boolean fetch(XSLFSimpleShape shape) { + public boolean fetch(XSLFShape shape) { XmlObject[] o = shape.getXmlObject().selectPath( "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " + diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/LineDecoration.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/LineDecoration.java deleted file mode 100644 index 72b28c0b34..0000000000 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/LineDecoration.java +++ /dev/null @@ -1,29 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -/** - * Represents the shape decoration that appears at the ends of lines. - */ -public enum LineDecoration { - NONE, - TRIANGLE, - STEALTH, - DIAMOND, - OVAL, - ARROW -} diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/LineEndLength.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/LineEndLength.java deleted file mode 100644 index 43ccb566fa..0000000000 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/LineEndLength.java +++ /dev/null @@ -1,26 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -/** - * @author Yegor Kozlov - */ -public enum LineEndLength { - SMALL, - MEDIUM, - LARGE -} diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/LineEndWidth.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/LineEndWidth.java deleted file mode 100644 index cee716bff7..0000000000 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/LineEndWidth.java +++ /dev/null @@ -1,26 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.xslf.usermodel; - -/** - * @author Yegor Kozlov - */ -public enum LineEndWidth { - SMALL, - MEDIUM, - LARGE -} \ No newline at end of file diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/RenderableShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/RenderableShape.java deleted file mode 100644 index 8a11c1cd17..0000000000 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/RenderableShape.java +++ /dev/null @@ -1,632 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - -package org.apache.poi.xslf.usermodel; - -import java.awt.AlphaComposite; -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.GradientPaint; -import java.awt.Graphics2D; -import java.awt.Paint; -import java.awt.Shape; -import java.awt.Stroke; -import java.awt.TexturePaint; -import java.awt.geom.AffineTransform; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.lang.reflect.Constructor; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Comparator; - -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; -import org.apache.poi.sl.usermodel.LineCap; -import org.apache.poi.sl.usermodel.LineDash; -import org.apache.poi.util.Internal; -import org.apache.poi.util.Units; -import org.apache.poi.xslf.model.PropertyFetcher; -import org.apache.poi.xslf.model.geom.Context; -import org.apache.poi.xslf.model.geom.CustomGeometry; -import org.apache.poi.xslf.model.geom.Guide; -import org.apache.poi.xslf.model.geom.IAdjustableShape; -import org.apache.poi.xslf.model.geom.Outline; -import org.apache.poi.xslf.model.geom.Path; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip; -import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuide; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientStop; -import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTNoFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPathShadeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference; -import org.openxmlformats.schemas.drawingml.x2006.main.STPathShadeType; - -/** - * Encapsulates logic to translate DrawingML objects to Java2D - */ -@Internal -class RenderableShape { - public final static Color NO_PAINT = new Color(0xFF, 0xFF, 0xFF, 0); - - private XSLFSimpleShape _shape; - - public RenderableShape(XSLFSimpleShape shape){ - _shape = shape; - } - - /** - * Convert shape fill into java.awt.Paint. The result is either Color or - * TexturePaint or GradientPaint or null - * - * @param graphics the target graphics - * @param obj the xml to read. Must contain elements from the EG_ColorChoice group: - * - * a:scrgbClr RGB Color Model - Percentage Variant - * a:srgbClr RGB Color Model - Hex Variant - * a:hslClr Hue, Saturation, Luminance Color Model - * a:sysClr System Color - * a:schemeClr Scheme Color - * a:prstClr Preset Color - * - * - * @param phClr context color - * @param parentPart the parent package part. Any external references (images, etc.) are resolved relative to it. - * - * @return the applied Paint or null if none was applied - */ - public Paint selectPaint(Graphics2D graphics, XmlObject obj, CTSchemeColor phClr, PackagePart parentPart) { - XSLFTheme theme = _shape.getSheet().getTheme(); - - Paint paint = null; - if (obj instanceof CTNoFillProperties) { - paint = NO_PAINT; - - } - else if (obj instanceof CTSolidColorFillProperties) { - CTSolidColorFillProperties solidFill = (CTSolidColorFillProperties) obj; - XSLFColor c = new XSLFColor(solidFill, theme, phClr); - paint = c.getColor(); - } - else if (obj instanceof CTBlipFillProperties) { - CTBlipFillProperties blipFill = (CTBlipFillProperties)obj; - paint = createTexturePaint(blipFill, graphics, parentPart); - } - else if (obj instanceof CTGradientFillProperties) { - Rectangle2D anchor = getAnchor(graphics); - CTGradientFillProperties gradFill = (CTGradientFillProperties) obj; - if (gradFill.isSetLin()) { - paint = createLinearGradientPaint(graphics, gradFill, anchor, theme, phClr); - } else if (gradFill.isSetPath()){ - CTPathShadeProperties ps = gradFill.getPath(); - if(ps.getPath() == STPathShadeType.CIRCLE){ - paint = createRadialGradientPaint(gradFill, anchor, theme, phClr); - } else if (ps.getPath() == STPathShadeType.SHAPE){ - paint = toRadialGradientPaint(gradFill, anchor, theme, phClr); - } - } - } - - return paint; - } - - private Paint createTexturePaint(CTBlipFillProperties blipFill, Graphics2D graphics, - PackagePart parentPart){ - Paint paint = null; - CTBlip blip = blipFill.getBlip(); - String blipId = blip.getEmbed(); - PackageRelationship rel = parentPart.getRelationship(blipId); - if (rel != null) { - XSLFImageRenderer renderer = null; - if (graphics != null) - renderer = (XSLFImageRenderer) graphics.getRenderingHint(XSLFRenderingHint.IMAGE_RENDERER); - if (renderer == null) renderer = new XSLFImageRenderer(); - - try { - BufferedImage img = renderer.readImage(parentPart.getRelatedPart(rel)); - if (blip.sizeOfAlphaModFixArray() > 0) { - float alpha = blip.getAlphaModFixArray(0).getAmt() / 100000.f; - AlphaComposite ac = AlphaComposite.getInstance( - AlphaComposite.SRC_OVER, alpha); - if (graphics != null) graphics.setComposite(ac); - } - - if(img != null) { - paint = new TexturePaint( - img, new Rectangle2D.Double(0, 0, img.getWidth(), img.getHeight())); - } - } - catch (Exception e) { - e.printStackTrace(); - } - } - return paint; - } - - private Paint createLinearGradientPaint( - Graphics2D graphics, - CTGradientFillProperties gradFill, Rectangle2D anchor, - XSLFTheme theme, CTSchemeColor phClr) { - double angle = gradFill.getLin().getAng() / 60000; - @SuppressWarnings("deprecation") - CTGradientStop[] gs = gradFill.getGsLst().getGsArray(); - - Arrays.sort(gs, new Comparator() { - public int compare(CTGradientStop o1, CTGradientStop o2) { - Integer pos1 = o1.getPos(); - Integer pos2 = o2.getPos(); - return pos1.compareTo(pos2); - } - }); - - Color[] colors = new Color[gs.length]; - float[] fractions = new float[gs.length]; - - AffineTransform at = AffineTransform.getRotateInstance( - Math.toRadians(angle), - anchor.getX() + anchor.getWidth() / 2, - anchor.getY() + anchor.getHeight() / 2); - - double diagonal = Math.sqrt(anchor.getHeight() * anchor.getHeight() + anchor.getWidth() * anchor.getWidth()); - Point2D p1 = new Point2D.Double(anchor.getX() + anchor.getWidth() / 2 - diagonal / 2, - anchor.getY() + anchor.getHeight() / 2); - p1 = at.transform(p1, null); - - Point2D p2 = new Point2D.Double(anchor.getX() + anchor.getWidth(), anchor.getY() + anchor.getHeight() / 2); - p2 = at.transform(p2, null); - - snapToAnchor(p1, anchor); - snapToAnchor(p2, anchor); - - for (int i = 0; i < gs.length; i++) { - CTGradientStop stop = gs[i]; - colors[i] = new XSLFColor(stop, theme, phClr).getColor(); - fractions[i] = stop.getPos() / 100000.f; - } - - AffineTransform grAt = new AffineTransform(); - if(gradFill.isSetRotWithShape() || !gradFill.getRotWithShape()) { - double rotation = _shape.getRotation(); - if (rotation != 0.) { - double centerX = anchor.getX() + anchor.getWidth() / 2; - double centerY = anchor.getY() + anchor.getHeight() / 2; - - grAt.translate(centerX, centerY); - grAt.rotate(Math.toRadians(-rotation)); - grAt.translate(-centerX, -centerY); - } - } - - // Trick to return GradientPaint on JDK 1.5 and LinearGradientPaint on JDK 1.6+ - Paint paint; - try { - Class clz = Class.forName("java.awt.LinearGradientPaint"); - Class clzCycleMethod = Class.forName("java.awt.MultipleGradientPaint$CycleMethod"); - Class clzColorSpaceType = Class.forName("java.awt.MultipleGradientPaint$ColorSpaceType"); - Constructor c = - clz.getConstructor(Point2D.class, Point2D.class, float[].class, Color[].class, - clzCycleMethod, clzColorSpaceType, AffineTransform.class); - paint = (Paint) c.newInstance(p1, p2, fractions, colors, - Enum.valueOf(clzCycleMethod, "NO_CYCLE"), - Enum.valueOf(clzColorSpaceType, "SRGB"), grAt); - } catch (ClassNotFoundException e) { - paint = new GradientPaint(p1, colors[0], p2, colors[colors.length - 1]); - } catch (Exception e) { - throw new RuntimeException(e); - } - return paint; - } - - /** - * gradients with type=shape are enot supported by Java graphics. - * We approximate it with a radial gradient. - */ - private static Paint toRadialGradientPaint( - CTGradientFillProperties gradFill, Rectangle2D anchor, - XSLFTheme theme, CTSchemeColor phClr) { - - @SuppressWarnings("deprecation") - CTGradientStop[] gs = gradFill.getGsLst().getGsArray(); - Arrays.sort(gs, new Comparator() { - public int compare(CTGradientStop o1, CTGradientStop o2) { - Integer pos1 = o1.getPos(); - Integer pos2 = o2.getPos(); - return pos1.compareTo(pos2); - } - }); - gs[1].setPos(50000); - - CTGradientFillProperties g = CTGradientFillProperties.Factory.newInstance(); - g.set(gradFill); - g.getGsLst().setGsArray(new CTGradientStop[]{gs[0], gs[1]}); - return createRadialGradientPaint(g, anchor, theme, phClr); - } - - private static Paint createRadialGradientPaint( - CTGradientFillProperties gradFill, Rectangle2D anchor, - XSLFTheme theme, CTSchemeColor phClr) { - @SuppressWarnings("deprecation") - CTGradientStop[] gs = gradFill.getGsLst().getGsArray(); - - Point2D pCenter = new Point2D.Double(anchor.getX() + anchor.getWidth()/2, - anchor.getY() + anchor.getHeight()/2); - - float radius = (float)Math.max(anchor.getWidth(), anchor.getHeight()); - - Arrays.sort(gs, new Comparator() { - public int compare(CTGradientStop o1, CTGradientStop o2) { - Integer pos1 = o1.getPos(); - Integer pos2 = o2.getPos(); - return pos1.compareTo(pos2); - } - }); - - Color[] colors = new Color[gs.length]; - float[] fractions = new float[gs.length]; - - - for (int i = 0; i < gs.length; i++) { - CTGradientStop stop = gs[i]; - colors[i] = new XSLFColor(stop, theme, phClr).getColor(); - fractions[i] = stop.getPos() / 100000.f; - } - - // Trick to return GradientPaint on JDK 1.5 and RadialGradientPaint on JDK 1.6+ - Paint paint; - try { - Class clz = Class.forName("java.awt.RadialGradientPaint"); - Constructor c = - clz.getConstructor(Point2D.class, float.class, - float[].class, Color[].class); - paint = (Paint) c.newInstance(pCenter, radius, fractions, colors); - } catch (ClassNotFoundException e) { - // the result on JDK 1.5 is incorrect, but it is better than nothing - paint = new GradientPaint( - new Point2D.Double(anchor.getX(), anchor.getY()), - colors[0], pCenter, colors[colors.length - 1]); - } catch (Exception e) { - throw new RuntimeException(e); - } - return paint; - } - - private static void snapToAnchor(Point2D p, Rectangle2D anchor) { - if (p.getX() < anchor.getX()) { - p.setLocation(anchor.getX(), p.getY()); - } else if (p.getX() > (anchor.getX() + anchor.getWidth())) { - p.setLocation(anchor.getX() + anchor.getWidth(), p.getY()); - } - - if (p.getY() < anchor.getY()) { - p.setLocation(p.getX(), anchor.getY()); - } else if (p.getY() > (anchor.getY() + anchor.getHeight())) { - p.setLocation(p.getX(), anchor.getY() + anchor.getHeight()); - } - } - - - Paint getPaint(Graphics2D graphics, XmlObject spPr, CTSchemeColor phClr) { - - Paint paint = null; - for (XmlObject obj : spPr.selectPath("*")) { - paint = selectPaint(graphics, obj, phClr, _shape.getSheet().getPackagePart()); - if(paint != null) break; - } - return paint == NO_PAINT ? null : paint; - } - - - /** - * fetch shape fill as a java.awt.Paint - * - * @return either Color or GradientPaint or TexturePaint or null - */ - Paint getFillPaint(final Graphics2D graphics) { - PropertyFetcher fetcher = new PropertyFetcher() { - public boolean fetch(XSLFSimpleShape shape) { - CTShapeProperties spPr = shape.getSpPr(); - if (spPr.isSetNoFill()) { - setValue(RenderableShape.NO_PAINT); // use it as 'nofill' value - return true; - } - Paint paint = getPaint(graphics, spPr, null); - if (paint != null) { - setValue(paint); - return true; - } - return false; - } - }; - _shape.fetchShapeProperty(fetcher); - - Paint paint = fetcher.getValue(); - if (paint == null) { - // fill color was not found, check if it is defined in the theme - CTShapeStyle style = _shape.getSpStyle(); - if (style != null) { - // get a reference to a fill style within the style matrix. - CTStyleMatrixReference fillRef = style.getFillRef(); - // The idx attribute refers to the index of a fill style or - // background fill style within the presentation's style matrix, defined by the fmtScheme element. - // value of 0 or 1000 indicates no background, - // values 1-999 refer to the index of a fill style within the fillStyleLst element - // values 1001 and above refer to the index of a background fill style within the bgFillStyleLst element. - int idx = (int)fillRef.getIdx(); - CTSchemeColor phClr = fillRef.getSchemeClr(); - XSLFSheet sheet = _shape.getSheet(); - XSLFTheme theme = sheet.getTheme(); - XmlObject fillProps = null; - if(idx >= 1 && idx <= 999){ - fillProps = theme.getXmlObject(). - getThemeElements().getFmtScheme().getFillStyleLst().selectPath("*")[idx - 1]; - } else if (idx >= 1001 ){ - fillProps = theme.getXmlObject(). - getThemeElements().getFmtScheme().getBgFillStyleLst().selectPath("*")[idx - 1001]; - } - if(fillProps != null) { - paint = selectPaint(graphics, fillProps, phClr, sheet.getPackagePart()); - } - } - } - return paint == RenderableShape.NO_PAINT ? null : paint; - } - - public Paint getLinePaint(final Graphics2D graphics) { - PropertyFetcher fetcher = new PropertyFetcher() { - public boolean fetch(XSLFSimpleShape shape) { - CTLineProperties spPr = shape.getSpPr().getLn(); - if (spPr != null) { - if (spPr.isSetNoFill()) { - setValue(NO_PAINT); // use it as 'nofill' value - return true; - } - Paint paint = getPaint(graphics, spPr, null); - if (paint != null) { - setValue(paint); - return true; - } - } - return false; - - } - }; - _shape.fetchShapeProperty(fetcher); - - Paint paint = fetcher.getValue(); - if (paint == null) { - // line color was not found, check if it is defined in the theme - CTShapeStyle style = _shape.getSpStyle(); - if (style != null) { - // get a reference to a line style within the style matrix. - CTStyleMatrixReference lnRef = style.getLnRef(); - int idx = (int)lnRef.getIdx(); - CTSchemeColor phClr = lnRef.getSchemeClr(); - if(idx > 0){ - XSLFTheme theme = _shape.getSheet().getTheme(); - XmlObject lnProps = theme.getXmlObject(). - getThemeElements().getFmtScheme().getLnStyleLst().selectPath("*")[idx - 1]; - paint = getPaint(graphics, lnProps, phClr); - } - } - } - - return paint == NO_PAINT ? null : paint; - } - - /** - * convert PPT dash into java.awt.BasicStroke - * - * The mapping is derived empirically on PowerPoint 2010 - */ - private static float[] getDashPattern(LineDash lineDash, float lineWidth) { - float[] dash = null; - switch (lineDash) { - case SYS_DOT: - dash = new float[]{lineWidth, lineWidth}; - break; - case SYS_DASH: - dash = new float[]{2 * lineWidth, 2 * lineWidth}; - break; - case DASH: - dash = new float[]{3 * lineWidth, 4 * lineWidth}; - break; - case DASH_DOT: - dash = new float[]{4 * lineWidth, 3 * lineWidth, lineWidth, - 3 * lineWidth}; - break; - case LG_DASH: - dash = new float[]{8 * lineWidth, 3 * lineWidth}; - break; - case LG_DASH_DOT: - dash = new float[]{8 * lineWidth, 3 * lineWidth, lineWidth, - 3 * lineWidth}; - break; - case LG_DASH_DOT_DOT: - dash = new float[]{8 * lineWidth, 3 * lineWidth, lineWidth, - 3 * lineWidth, lineWidth, 3 * lineWidth}; - break; - } - return dash; - } - - - public Stroke applyStroke(Graphics2D graphics) { - - float lineWidth = (float) _shape.getLineWidth(); - if(lineWidth == 0.0f) lineWidth = 0.25f; // Both PowerPoint and OOo draw zero-length lines as 0.25pt - - LineDash lineDash = _shape.getLineDash(); - float[] dash = null; - float dash_phase = 0; - if (lineDash != null) { - dash = getDashPattern(lineDash, lineWidth); - } - - int cap = BasicStroke.CAP_BUTT; - LineCap lineCap = _shape.getLineCap(); - if (lineCap != null) { - switch (lineCap) { - case ROUND: - cap = BasicStroke.CAP_ROUND; - break; - case SQUARE: - cap = BasicStroke.CAP_SQUARE; - break; - default: - cap = BasicStroke.CAP_BUTT; - break; - } - } - - int meter = BasicStroke.JOIN_ROUND; - - Stroke stroke = new BasicStroke(lineWidth, cap, meter, Math.max(1, lineWidth), dash, - dash_phase); - graphics.setStroke(stroke); - return stroke; - } - - public void render(Graphics2D graphics){ - Collection elems = computeOutlines(graphics); - - // shadow - XSLFShadow shadow = _shape.getShadow(); - - // first fill - Paint fill = getFillPaint(graphics); - Paint line = getLinePaint(graphics); - applyStroke(graphics); // the stroke applies both to the shadow and the shape - - // first paint the shadow - if(shadow != null) for(Outline o : elems){ - if(o.getPath().isFilled()){ - if(fill != null) shadow.fill(graphics, o.getOutline()); - else if(line != null) shadow.draw(graphics, o.getOutline()); - } - } - // then fill the shape interior - if(fill != null) for(Outline o : elems){ - if(o.getPath().isFilled()){ - graphics.setPaint(fill); - graphics.fill(o.getOutline()); - } - } - - // then draw any content within this shape (text, image, etc.) - _shape.drawContent(graphics); - - // then stroke the shape outline - if(line != null) for(Outline o : elems){ - if(o.getPath().isStroked()){ - graphics.setPaint(line); - graphics.draw(o.getOutline()); - } - } - } - - @SuppressWarnings("deprecation") - private Collection computeOutlines(Graphics2D graphics) { - - Collection lst = new ArrayList(); - CustomGeometry geom = _shape.getGeometry(); - if(geom == null) { - return lst; - } - - Rectangle2D anchor = getAnchor(graphics); - for (Path p : geom) { - - double w = p.getW() == -1 ? anchor.getWidth() * Units.EMU_PER_POINT : p.getW(); - double h = p.getH() == -1 ? anchor.getHeight() * Units.EMU_PER_POINT : p.getH(); - - // the guides in the shape definitions are all defined relative to each other, - // so we build the path starting from (0,0). - final Rectangle2D pathAnchor = new Rectangle2D.Double( - 0, - 0, - w, - h - ); - - Context ctx = new Context(geom, pathAnchor, new IAdjustableShape() { - - public Guide getAdjustValue(String name) { - CTPresetGeometry2D prst = _shape.getSpPr().getPrstGeom(); - if (prst.isSetAvLst()) { - for (CTGeomGuide g : prst.getAvLst().getGdArray()) { - if (g.getName().equals(name)) { - return new Guide(g); - } - } - } - return null; - } - }) ; - - Shape gp = p.getPath(ctx); - - // translate the result to the canvas coordinates in points - AffineTransform at = new AffineTransform(); - at.translate(anchor.getX(), anchor.getY()); - - double scaleX, scaleY; - if (p.getW() != -1) { - scaleX = anchor.getWidth() / p.getW(); - } else { - scaleX = 1.0 / Units.EMU_PER_POINT; - } - if (p.getH() != -1) { - scaleY = anchor.getHeight() / p.getH(); - } else { - scaleY = 1.0 / Units.EMU_PER_POINT; - } - - at.scale(scaleX, scaleY); - - Shape canvasShape = at.createTransformedShape(gp); - - lst.add(new Outline(canvasShape, p)); - } - - return lst; - } - - public Rectangle2D getAnchor(Graphics2D graphics) { - Rectangle2D anchor = _shape.getAnchor(); - if(graphics == null) { - return anchor; - } - - AffineTransform tx = (AffineTransform)graphics.getRenderingHint(XSLFRenderingHint.GROUP_TRANSFORM); - if(tx != null) { - anchor = tx.createTransformedShape(anchor).getBounds2D(); - } - return anchor; - } -} diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java index 1c5f855db3..26780f9662 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XMLSlideShow.java @@ -496,11 +496,11 @@ public class XMLSlideShow extends POIXMLDocument implements SlideShow { return null; } - public MasterSheet[] getMasterSheet() { + public XSLFSlideMaster[] getMasterSheet() { return getSlideMasters(); } - public MasterSheet createMasterSheet() throws IOException { + public MasterSheet createMasterSheet() throws IOException { // TODO: implement! throw new UnsupportedOperationException(); } diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java index 47bcace2f3..a87d91bd58 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFAutoShape.java @@ -36,7 +36,7 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual; * @author Yegor Kozlov */ @Beta -public class XSLFAutoShape extends XSLFTextShape implements AutoShape { +public class XSLFAutoShape extends XSLFTextShape implements AutoShape { /*package*/ XSLFAutoShape(CTShape shape, XSLFSheet sheet) { super(shape, sheet); @@ -72,7 +72,7 @@ public class XSLFAutoShape extends XSLFTextShape implements AutoShape { } protected CTTextBody getTextBody(boolean create){ - CTShape shape = (CTShape) getXmlObject(); + CTShape shape = (CTShape)getXmlObject(); CTTextBody txBody = shape.getTxBody(); if (txBody == null && create) { txBody = shape.addNewTxBody(); diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFBackground.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFBackground.java index 80c6a1acbe..bfa3f31ec0 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFBackground.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFBackground.java @@ -20,9 +20,10 @@ package org.apache.poi.xslf.usermodel; import java.awt.*; import java.awt.geom.Rectangle2D; -import org.apache.poi.sl.usermodel.Background; -import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.*; +import org.apache.poi.sl.draw.DrawPaint; +import org.apache.poi.sl.usermodel.*; +import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; +import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground; /** @@ -42,48 +43,14 @@ public class XSLFBackground extends XSLFSimpleShape implements Background { return new Rectangle2D.Double(0, 0, pg.getWidth(), pg.getHeight()); } - public void draw(Graphics2D graphics) { - Rectangle2D anchor = getAnchor(); - - Paint fill = getPaint(graphics); - if(fill != null) { - graphics.setPaint(fill); - graphics.fill(anchor); - } - } - - /** - * @return the Paint object to fill - */ - Paint getPaint(Graphics2D graphics){ - RenderableShape rShape = new RenderableShape(this); - - Paint fill = null; - CTBackground bg = (CTBackground)getXmlObject(); - if(bg.isSetBgPr()){ - XmlObject spPr = bg.getBgPr(); - fill = rShape.getPaint(graphics, spPr, null); - } else if (bg.isSetBgRef()){ - CTStyleMatrixReference bgRef= bg.getBgRef(); - CTSchemeColor phClr = bgRef.getSchemeClr(); - - int idx = (int)bgRef.getIdx() - 1001; - XSLFTheme theme = getSheet().getTheme(); - CTBackgroundFillStyleList bgStyles = - theme.getXmlObject().getThemeElements().getFmtScheme().getBgFillStyleLst(); - - XmlObject bgStyle = bgStyles.selectPath("*")[idx]; - fill = rShape.selectPaint(graphics, bgStyle, phClr, theme.getPackagePart()); - } - - return fill; - } - @Override public Color getFillColor(){ - Paint p = getPaint(null); - if(p instanceof Color){ - return (Color)p; + FillStyle fs = getFillStyle(); + PaintStyle ps = fs.getPaint(); + if (ps instanceof SolidPaint) { + SolidPaint sp = (SolidPaint)ps; + ColorStyle cs = sp.getSolidColor(); + return DrawPaint.applyColorTransform(cs); } return null; } @@ -95,7 +62,7 @@ public class XSLFBackground extends XSLFSimpleShape implements Background { * @return dummy CTTransform2D bean */ @Override - CTTransform2D getXfrm() { + protected CTTransform2D getXfrm() { return CTTransform2D.Factory.newInstance(); } } diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java index 514c1bc90f..608cb3adba 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java @@ -19,6 +19,10 @@ package org.apache.poi.xslf.usermodel; +import java.awt.geom.Rectangle2D; + +import javax.xml.namespace.QName; + import org.apache.poi.POIXMLException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.opc.PackagePart; @@ -28,52 +32,24 @@ import org.apache.poi.util.Beta; import org.apache.poi.util.Units; import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlObject; -import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; +import org.openxmlformats.schemas.drawingml.x2006.main.*; import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame; -import javax.xml.namespace.QName; - -import java.awt.Graphics2D; -import java.awt.geom.Rectangle2D; - /** * @author Yegor Kozlov */ @Beta public class XSLFGraphicFrame extends XSLFShape { - private final CTGraphicalObjectFrame _shape; - private final XSLFSheet _sheet; - /*package*/ XSLFGraphicFrame(CTGraphicalObjectFrame shape, XSLFSheet sheet){ - _shape = shape; - _sheet = sheet; - } - - public CTGraphicalObjectFrame getXmlObject(){ - return _shape; - } - - public XSLFSheet getSheet(){ - return _sheet; + super(shape,sheet); } public ShapeType getShapeType(){ throw new UnsupportedOperationException(); } - public int getShapeId(){ - return (int)_shape.getNvGraphicFramePr().getCNvPr().getId(); - } - - public String getShapeName(){ - return _shape.getNvGraphicFramePr().getCNvPr().getName(); - } - public Rectangle2D getAnchor(){ - CTTransform2D xfrm = _shape.getXfrm(); + CTTransform2D xfrm = ((CTGraphicalObjectFrame)getXmlObject()).getXfrm(); CTPoint2D off = xfrm.getOff(); long x = off.getX(); long y = off.getY(); @@ -86,7 +62,7 @@ public class XSLFGraphicFrame extends XSLFShape { } public void setAnchor(Rectangle2D anchor){ - CTTransform2D xfrm = _shape.getXfrm(); + CTTransform2D xfrm = ((CTGraphicalObjectFrame)getXmlObject()).getXfrm(); CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff(); long x = Units.toEMU(anchor.getX()); long y = Units.toEMU(anchor.getY()); @@ -157,15 +133,11 @@ public class XSLFGraphicFrame extends XSLFShape { return false; } - public void draw(Graphics2D graphics){ - - } - @Override void copy(XSLFShape sh){ super.copy(sh); - CTGraphicalObjectData data = _shape.getGraphic().getGraphicData(); + CTGraphicalObjectData data = ((CTGraphicalObjectFrame)getXmlObject()).getGraphic().getGraphicData(); String uri = data.getUri(); if(uri.equals("http://schemas.openxmlformats.org/drawingml/2006/diagram")){ copyDiagram(data, (XSLFGraphicFrame)sh); @@ -187,22 +159,22 @@ public class XSLFGraphicFrame extends XSLFShape { String dm = c.getAttributeText(new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "dm")); PackageRelationship dmRel = sheet.getPackagePart().getRelationship(dm); PackagePart dmPart = sheet.getPackagePart().getRelatedPart(dmRel); - _sheet.importPart(dmRel, dmPart); + getSheet().importPart(dmRel, dmPart); String lo = c.getAttributeText(new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "lo")); PackageRelationship loRel = sheet.getPackagePart().getRelationship(lo); PackagePart loPart = sheet.getPackagePart().getRelatedPart(loRel); - _sheet.importPart(loRel, loPart); + getSheet().importPart(loRel, loPart); String qs = c.getAttributeText(new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "qs")); PackageRelationship qsRel = sheet.getPackagePart().getRelationship(qs); PackagePart qsPart = sheet.getPackagePart().getRelatedPart(qsRel); - _sheet.importPart(qsRel, qsPart); + getSheet().importPart(qsRel, qsPart); String cs = c.getAttributeText(new QName("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "cs")); PackageRelationship csRel = sheet.getPackagePart().getRelationship(cs); PackagePart csPart = sheet.getPackagePart().getRelatedPart(csRel); - _sheet.importPart(csRel, csPart); + getSheet().importPart(csRel, csPart); } catch (InvalidFormatException e){ throw new POIXMLException(e); diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java index f93fc803fb..57e96f8ee5 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java @@ -29,15 +29,11 @@ import java.util.regex.Pattern; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.openxml4j.opc.TargetMode; -import org.apache.poi.sl.usermodel.ShapeType; +import org.apache.poi.sl.usermodel.*; import org.apache.poi.util.Beta; import org.apache.poi.util.Units; import org.apache.xmlbeans.XmlObject; -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.drawingml.x2006.main.*; import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector; import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape; import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShapeNonVisual; @@ -49,29 +45,33 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; * @author Yegor Kozlov */ @Beta -public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer { - private final CTGroupShape _shape; - private final XSLFSheet _sheet; +public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer, PlaceableShape { private final List _shapes; - private final CTGroupShapeProperties _spPr; + private final CTGroupShapeProperties _grpSpPr; private XSLFDrawing _drawing; - /*package*/ XSLFGroupShape(CTGroupShape shape, XSLFSheet sheet){ - _shape = shape; - _sheet = sheet; - - _shapes = _sheet.buildShapes(_shape); - _spPr = shape.getGrpSpPr(); + protected XSLFGroupShape(CTGroupShape shape, XSLFSheet sheet){ + super(shape,sheet); + _shapes = sheet.buildShapes(shape); + _grpSpPr = shape.getGrpSpPr(); } - @Override - public CTGroupShape getXmlObject(){ - return _shape; + protected CTGroupShapeProperties getGrpSpPr() { + return _grpSpPr; + } + + protected CTGroupTransform2D getSafeXfrm() { + CTGroupTransform2D xfrm = getXfrm(); + return (xfrm == null ? getGrpSpPr().addNewXfrm() : xfrm); + } + + protected CTGroupTransform2D getXfrm() { + return getGrpSpPr().getXfrm(); } @Override public Rectangle2D getAnchor(){ - CTGroupTransform2D xfrm = _spPr.getXfrm(); + CTGroupTransform2D xfrm = getXfrm(); CTPoint2D off = xfrm.getOff(); long x = off.getX(); long y = off.getY(); @@ -85,7 +85,7 @@ public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer { @Override public void setAnchor(Rectangle2D anchor){ - CTGroupTransform2D xfrm = _spPr.isSetXfrm() ? _spPr.getXfrm() : _spPr.addNewXfrm(); + CTGroupTransform2D xfrm = getSafeXfrm(); CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff(); long x = Units.toEMU(anchor.getX()); long y = Units.toEMU(anchor.getY()); @@ -105,7 +105,7 @@ public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer { * behavior of shapes placed within a group. */ public Rectangle2D getInteriorAnchor(){ - CTGroupTransform2D xfrm = _spPr.getXfrm(); + CTGroupTransform2D xfrm = getXfrm(); CTPoint2D off = xfrm.getChOff(); long x = off.getX(); long y = off.getY(); @@ -124,7 +124,7 @@ public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer { * behavior of shapes placed within a group. */ public void setInteriorAnchor(Rectangle2D anchor){ - CTGroupTransform2D xfrm = _spPr.isSetXfrm() ? _spPr.getXfrm() : _spPr.addNewXfrm(); + CTGroupTransform2D xfrm = getSafeXfrm(); CTPoint2D off = xfrm.isSetChOff() ? xfrm.getChOff() : xfrm.addNewChOff(); long x = Units.toEMU(anchor.getX()); long y = Units.toEMU(anchor.getY()); @@ -159,28 +159,19 @@ public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer { */ public boolean removeShape(XSLFShape xShape) { XmlObject obj = xShape.getXmlObject(); + CTGroupShape grpSp = (CTGroupShape)getXmlObject(); if(obj instanceof CTShape){ - _shape.getSpList().remove(obj); + grpSp.getSpList().remove(obj); } else if (obj instanceof CTGroupShape){ - _shape.getGrpSpList().remove(obj); + grpSp.getGrpSpList().remove(obj); } else if (obj instanceof CTConnector){ - _shape.getCxnSpList().remove(obj); + grpSp.getCxnSpList().remove(obj); } else { throw new IllegalArgumentException("Unsupported shape: " + xShape); } return _shapes.remove(xShape); } - @Override - public String getShapeName(){ - return _shape.getNvGrpSpPr().getCNvPr().getName(); - } - - @Override - public int getShapeId(){ - return (int)_shape.getNvGrpSpPr().getCNvPr().getId(); - } - /** * @param shapeId 1-based shapeId */ @@ -200,7 +191,7 @@ public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer { // shape factory methods private XSLFDrawing getDrawing(){ if(_drawing == null) { - _drawing = new XSLFDrawing(_sheet, _shape); + _drawing = new XSLFDrawing(getSheet(), (CTGroupShape)getXmlObject()); } return _drawing; } @@ -242,7 +233,7 @@ public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer { public XSLFPictureShape createPicture(int pictureIndex){ - List pics = _sheet.getPackagePart().getPackage() + List pics = getSheet().getPackagePart().getPackage() .getPartsByName(Pattern.compile("/ppt/media/image" + (pictureIndex + 1) + ".*?")); if(pics.size() == 0) { @@ -251,7 +242,7 @@ public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer { PackagePart pic = pics.get(0); - PackageRelationship rel = _sheet.getPackagePart().addRelationship( + PackageRelationship rel = getSheet().getPackagePart().addRelationship( pic.getPartName(), TargetMode.INTERNAL, XSLFRelation.IMAGES.getRelation()); XSLFPictureShape sh = getDrawing().createPicture(rel.getId()); @@ -263,67 +254,35 @@ public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer { @Override public void setFlipHorizontal(boolean flip){ - _spPr.getXfrm().setFlipH(flip); + getSafeXfrm().setFlipH(flip); } @Override public void setFlipVertical(boolean flip){ - _spPr.getXfrm().setFlipV(flip); + getSafeXfrm().setFlipV(flip); } @Override public boolean getFlipHorizontal(){ - return _spPr.getXfrm().getFlipH(); + CTGroupTransform2D xfrm = getXfrm(); + return (xfrm == null || !xfrm.isSetFlipH()) ? false : xfrm.getFlipH(); } @Override public boolean getFlipVertical(){ - return _spPr.getXfrm().getFlipV(); + CTGroupTransform2D xfrm = getXfrm(); + return (xfrm == null || !xfrm.isSetFlipV()) ? false : xfrm.getFlipV(); } @Override public void setRotation(double theta){ - _spPr.getXfrm().setRot((int)(theta*60000)); + getSafeXfrm().setRot((int) (theta * 60000)); } @Override public double getRotation(){ - return (double)_spPr.getXfrm().getRot()/60000; - } - - @Override - public void draw(Graphics2D graphics){ - - // the coordinate system of this group of shape - Rectangle2D interior = getInteriorAnchor(); - // anchor of this group relative to the parent shape - Rectangle2D exterior = getAnchor(); - - AffineTransform tx = (AffineTransform)graphics.getRenderingHint(XSLFRenderingHint.GROUP_TRANSFORM); - AffineTransform tx0 = new AffineTransform(tx); - - double scaleX = interior.getWidth() == 0. ? 1.0 : exterior.getWidth() / interior.getWidth(); - double scaleY = interior.getHeight() == 0. ? 1.0 : exterior.getHeight() / interior.getHeight(); - - tx.translate(exterior.getX(), exterior.getY()); - tx.scale(scaleX, scaleY); - tx.translate(-interior.getX(), -interior.getY()); - - for (XSLFShape shape : getShapes()) { - // remember the initial transform and restore it after we are done with the drawing - AffineTransform at = graphics.getTransform(); - graphics.setRenderingHint(XSLFRenderingHint.GSAVE, true); - - shape.applyTransform(graphics); - shape.draw(graphics); - - // restore the coordinate system - graphics.setTransform(at); - graphics.setRenderingHint(XSLFRenderingHint.GRESTORE, true); - } - - graphics.setRenderingHint(XSLFRenderingHint.GROUP_TRANSFORM, tx0); - + CTGroupTransform2D xfrm = getXfrm(); + return (xfrm == null || !xfrm.isSetRot()) ? 0 : (xfrm.getRot() / 60000.d); } @Override @@ -350,13 +309,9 @@ public class XSLFGroupShape extends XSLFShape implements XSLFShapeContainer { } } - public ShapeType getShapeType(){ - return null; - } - public void addShape(XSLFShape shape) { throw new UnsupportedOperationException( "Adding a shape from a different container is not supported -" - + " create it from scratch witht XSLFGroupShape.create* methods"); + + " create it from scratch with XSLFGroupShape.create* methods"); } } \ No newline at end of file diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java index 7ade4f948d..3b6053b0bd 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java @@ -20,12 +20,12 @@ 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; @@ -35,7 +35,7 @@ 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 */ @@ -215,4 +215,17 @@ public final class XSLFPictureData extends POIXMLDocumentPart { 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 diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java index a7e7e5e815..d0f75e0535 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java @@ -179,30 +179,13 @@ public class XSLFPictureShape extends XSLFSimpleShape { return id; } - public Insets getBlipClip(){ + public Insets getClipping(){ CTPicture ct = (CTPicture)getXmlObject(); CTRelativeRect r = ct.getBlipFill().getSrcRect(); return (r == null) ? null : new Insets(r.getT(), r.getL(), r.getB(), r.getR()); } - @Override - public void drawContent(Graphics2D graphics) { - - XSLFPictureData data = getPictureData(); - if(data == null) return; - - XSLFImageRenderer renderer = (XSLFImageRenderer)graphics.getRenderingHint(XSLFRenderingHint.IMAGE_RENDERER); - if(renderer == null) renderer = new XSLFImageRenderer(); - - RenderableShape rShape = new RenderableShape(this); - Rectangle2D anchor = rShape.getAnchor(graphics); - - Insets insets = getBlipClip(); - - renderer.drawImage(graphics, data, anchor, insets); - } - - + @SuppressWarnings("deprecation") @Override void copy(XSLFShape sh){ super.copy(sh); diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java index fa4b192ec4..9004a6be5f 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java @@ -17,22 +17,22 @@ package org.apache.poi.xslf.usermodel; -import org.apache.poi.sl.usermodel.Shadow; +import java.awt.Color; +import java.awt.geom.Rectangle2D; + +import org.apache.poi.sl.draw.DrawPaint; +import org.apache.poi.sl.usermodel.*; +import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; import org.apache.poi.util.Units; import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect; import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.Shape; -import java.awt.geom.Rectangle2D; - /** * Represents a shadow of a shape. For now supports only outer shadows. * * @author Yegor Kozlov */ -public class XSLFShadow extends XSLFSimpleShape implements Shadow { +public class XSLFShadow extends XSLFShape implements Shadow { private XSLFSimpleShape _parent; @@ -42,54 +42,15 @@ public class XSLFShadow extends XSLFSimpleShape implements Shadow { _parent = parentShape; } - - public void fill(Graphics2D graphics, Shape outline) { - - double shapeRotation = _parent.getRotation(); - if(_parent.getFlipVertical()){ - shapeRotation += 180; - } - double angle = getAngle() - shapeRotation; - double dist = getDistance(); - double dx = dist * Math.cos(Math.toRadians(angle)); - double dy = dist * Math.sin(Math.toRadians(angle)); - - graphics.translate(dx, dy); - - Color fillColor = getFillColor(); - if (fillColor != null) { - graphics.setColor(fillColor); - graphics.fill(outline); - } - - graphics.translate(-dx, -dy); - } - - public void draw(Graphics2D graphics, Shape outline) { - - double angle = getAngle(); - double dist = getDistance(); - double dx = dist * Math.cos(Math.toRadians(angle)); - double dy = dist * Math.sin(Math.toRadians(angle)); - - graphics.translate(dx, dy); - - Color fillColor = getFillColor(); - if (fillColor != null) { - graphics.setColor(fillColor); - graphics.draw(outline); - } - - graphics.translate(-dx, -dy); + @Override + public XSLFSimpleShape getShadowParent() { + return _parent; } - - @Override public Rectangle2D getAnchor(){ return _parent.getAnchor(); } - @Override public void setAnchor(Rectangle2D anchor){ throw new IllegalStateException("You can't set anchor of a shadow"); } @@ -125,15 +86,25 @@ public class XSLFShadow extends XSLFSimpleShape implements Shadow { * @return the color of this shadow. * Depending whether the parent shape is filled or stroked, this color is used to fill or stroke this shadow */ - @Override public Color getFillColor() { + SolidPaint ps = getFillStyle(); + if (ps == TRANSPARENT_PAINT) return null; + Color col = DrawPaint.applyColorTransform(ps.getSolidColor()); + return col; + } + + @Override + public SolidPaint getFillStyle() { XSLFTheme theme = getSheet().getTheme(); CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject(); - if(ct == null) { - return null; - } else { - CTSchemeColor phClr = ct.getSchemeClr(); - return new XSLFColor(ct, theme, phClr).getColor(); - } + if(ct == null) return TRANSPARENT_PAINT; + + CTSchemeColor phClr = ct.getSchemeClr(); + final XSLFColor xc = new XSLFColor(ct, theme, phClr); + return new SolidPaint(){ + public ColorStyle getSolidColor() { + return xc.getColorStyle(); + } + }; } } \ No newline at end of file diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java index aa6e2c712f..5634838302 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShape.java @@ -20,7 +20,6 @@ package org.apache.poi.xslf.usermodel; import java.awt.Color; -import java.awt.geom.Rectangle2D; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; @@ -30,14 +29,16 @@ import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.sl.draw.DrawPaint; -import org.apache.poi.sl.draw.geom.CustomGeometry; import org.apache.poi.sl.usermodel.*; -import org.apache.poi.util.*; +import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint; +import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; +import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint; +import org.apache.poi.util.Beta; +import org.apache.poi.util.Internal; import org.apache.poi.xslf.model.PropertyFetcher; import org.apache.xmlbeans.XmlObject; import org.openxmlformats.schemas.drawingml.x2006.main.*; -import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; -import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; +import org.openxmlformats.schemas.presentationml.x2006.main.*; /** * Base super-class class for all shapes in PresentationML @@ -46,16 +47,16 @@ import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; */ @Beta public abstract class XSLFShape implements Shape { - protected final XmlObject _shape; - protected final XSLFSheet _sheet; - protected XSLFShapeContainer _parent; + private final XmlObject _shape; + private final XSLFSheet _sheet; + private XSLFShapeContainer _parent; private CTShapeProperties _spPr; private CTShapeStyle _spStyle; private CTNonVisualDrawingProps _nvPr; private CTPlaceholder _ph; - private static final PaintStyle TRANSPARENT_PAINT = new SolidPaint() { + protected static final SolidPaint TRANSPARENT_PAINT = new SolidPaint() { public ColorStyle getSolidColor() { return new ColorStyle(){ public Color getColor() { return DrawPaint.NO_PAINT; } @@ -68,24 +69,30 @@ public abstract class XSLFShape implements Shape { } }; - protected XSLFShape(XmlObject shape, XSLFSheet sheet) { _shape = shape; _sheet = sheet; } - /** * @return the xml bean holding this shape's data */ - public XmlObject getXmlObject() { + public final XmlObject getXmlObject() { + // it's final because the xslf inheritance hierarchy is not necessary the same as + // the (not existing) xmlbeans hierarchy and subclasses shouldn't narrow it's return value return _shape; } + public XSLFSheet getSheet() { + return _sheet; + } + /** * @return human-readable name of this shape, e.g. "Rectange 3" */ - public abstract String getShapeName(); + public String getShapeName(){ + return getCNvPr().getName(); + } /** * Returns a unique identifier for this shape within the current document. @@ -98,55 +105,9 @@ public abstract class XSLFShape implements Shape { * * @return unique id of this shape */ - public abstract int getShapeId(); - - /** - * Rotate this shape. - *

- * Positive angles are clockwise (i.e., towards the positive y axis); - * negative angles are counter-clockwise (i.e., towards the negative y axis). - *

- * - * @param theta the rotation angle in degrees. - */ - public abstract void setRotation(double theta); - - /** - * Rotation angle in degrees - *

- * Positive angles are clockwise (i.e., towards the positive y axis); - * negative angles are counter-clockwise (i.e., towards the negative y axis). - *

- * - * @return rotation angle in degrees - */ - public abstract double getRotation(); - - /** - * @param flip whether the shape is horizontally flipped - */ - public abstract void setFlipHorizontal(boolean flip); - - /** - * Whether the shape is vertically flipped - * - * @param flip whether the shape is vertically flipped - */ - public abstract void setFlipVertical(boolean flip); - - /** - * Whether the shape is horizontally flipped - * - * @return whether the shape is horizontally flipped - */ - public abstract boolean getFlipHorizontal(); - - /** - * Whether the shape is vertically flipped - * - * @return whether the shape is vertically flipped - */ - public abstract boolean getFlipVertical(); + public int getShapeId() { + return (int)getCNvPr().getId(); + } /** * Set the contents of this shape to be a copy of the source shape. @@ -162,7 +123,12 @@ public abstract class XSLFShape implements Shape { "Can't copy " + sh.getClass().getSimpleName() + " into " + getClass().getSimpleName()); } - setAnchor(sh.getAnchor()); + if (this instanceof PlaceableShape) { + PlaceableShape ps = (PlaceableShape)this; + ps.setAnchor(((PlaceableShape)sh).getAnchor()); + } + + } public void setParent(XSLFShapeContainer parent) { @@ -173,93 +139,148 @@ public abstract class XSLFShape implements Shape { return this._parent; } - public boolean isPlaceholder() { - return false; + protected PaintStyle getFillPaint() { + PropertyFetcher fetcher = new PropertyFetcher() { + public boolean fetch(XSLFShape shape) { + XmlObject pr = null; + try { + pr = shape.getSpPr(); + if (((CTShapeProperties)pr).isSetNoFill()) { + setValue(TRANSPARENT_PAINT); + return true; + } + } catch (IllegalStateException e) {} + // trying background properties now + if (pr == null) { + pr = shape.getBgPr(); + } + if (pr == null) { + pr = shape.getGrpSpPr(); + } + if (pr == null) { + setValue(TRANSPARENT_PAINT); + return true; + } + + PaintStyle paint = null; + for (XmlObject obj : pr.selectPath("*")) { + paint = selectPaint(obj, null, getSheet().getPackagePart()); + if (paint != null) break; + } + + if (paint == null) return false; + + setValue(paint); + return true; + } + }; + fetchShapeProperty(fetcher); + + PaintStyle paint = fetcher.getValue(); + if (paint != null) return paint; + + // fill color was not found, check if it is defined in the theme + // get a reference to a fill style within the style matrix. + CTStyleMatrixReference fillRef = null; + if (fillRef == null) { + CTShapeStyle style = getSpStyle(); + if (style != null) fillRef = style.getFillRef(); + } + if (fillRef == null) { + fillRef = getBgRef(); + } + if (fillRef == null) { + return TRANSPARENT_PAINT; + } + + // The idx attribute refers to the index of a fill style or + // background fill style within the presentation's style matrix, defined by the fmtScheme element. + // value of 0 or 1000 indicates no background, + // values 1-999 refer to the index of a fill style within the fillStyleLst element + // values 1001 and above refer to the index of a background fill style within the bgFillStyleLst element. + int idx = (int)fillRef.getIdx(); + CTSchemeColor phClr = fillRef.getSchemeClr(); + XSLFSheet sheet = getSheet(); + XSLFTheme theme = sheet.getTheme(); + XmlObject fillProps = null; + CTStyleMatrix matrix = theme.getXmlObject().getThemeElements().getFmtScheme(); + if(idx >= 1 && idx <= 999){ + fillProps = matrix.getFillStyleLst().selectPath("*")[idx - 1]; + } else if (idx >= 1001 ){ + fillProps = matrix.getBgFillStyleLst().selectPath("*")[idx - 1001]; + } + if(fillProps != null) { + paint = selectPaint(fillProps, phClr, sheet.getPackagePart()); + } + + return paint == null ? TRANSPARENT_PAINT : paint; } - public StrokeStyle getStrokeStyle() { - // TODO Auto-generated method stub - return null; + protected CTBackgroundProperties getBgPr() { + String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:bgPr"; + return selectProperty(CTBackgroundProperties.class, xquery); + } + + protected CTStyleMatrixReference getBgRef() { + String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:bgRef"; + return selectProperty(CTStyleMatrixReference.class, xquery); + } + + protected CTGroupShapeProperties getGrpSpPr() { + String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:grpSpPr"; + return selectProperty(CTGroupShapeProperties.class, xquery); + } + + protected CTNonVisualDrawingProps getCNvPr() { + if (_nvPr == null) { + String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr"; + _nvPr = selectProperty(CTNonVisualDrawingProps.class, xquery); + } + return _nvPr; } - public CustomGeometry getGeometry() { - // TODO Auto-generated method stub - return null; + protected CTShapeProperties getSpPr() { + if (_spPr == null) { + String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:spPr"; + _spPr = selectProperty(CTShapeProperties.class, xquery); + } + if (_spPr == null) { + throw new IllegalStateException("CTShapeProperties was not found."); + } + return _spPr; } - public ShapeType getShapeType() { - // TODO Auto-generated method stub - return null; + protected CTShapeStyle getSpStyle() { + if (_spStyle == null) { + String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:style"; + _spStyle = selectProperty(CTShapeStyle.class, xquery); + } + return _spStyle; } - public XSLFSheet getSheet() { - // TODO Auto-generated method stub - return null; + protected CTPlaceholder getCTPlaceholder() { + if (_ph == null) { + String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:nvPr/p:ph"; + _ph = selectProperty(CTPlaceholder.class, xquery); + } + return _ph; } /** - * fetch shape fill as a java.awt.Paint + * As there's no xmlbeans hierarchy, but XSLF works with subclassing, not all + * child classes work with a {@link CTShape} object, but often contain the same + * properties. This method is the generalized form of selecting and casting those + * properties. * - * @return either Color or GradientPaint or TexturePaint or null + * @param resultClass + * @param xquery + * @return */ - @Override - public FillStyle getFillStyle() { - return new FillStyle() { - public PaintStyle getPaint() { - PropertyFetcher fetcher = new PropertyFetcher() { - public boolean fetch(XSLFShape shape) { - CTShapeProperties spPr = shape.getSpPr(); - if (spPr.isSetNoFill()) { - setValue(TRANSPARENT_PAINT); - return true; - } - - PaintStyle paint = null; - for (XmlObject obj : spPr.selectPath("*")) { - paint = selectPaint(obj, null, getSheet().getPackagePart()); - if (paint != null) break; - } - - if (paint == null) return false; - - setValue(paint); - return true; - } - }; - fetchShapeProperty(fetcher); - - PaintStyle paint = fetcher.getValue(); - - if (paint != null) return paint; - - // fill color was not found, check if it is defined in the theme - CTShapeStyle style = getSpStyle(); - if (style != null) { - // get a reference to a fill style within the style matrix. - CTStyleMatrixReference fillRef = style.getFillRef(); - // The idx attribute refers to the index of a fill style or - // background fill style within the presentation's style matrix, defined by the fmtScheme element. - // value of 0 or 1000 indicates no background, - // values 1-999 refer to the index of a fill style within the fillStyleLst element - // values 1001 and above refer to the index of a background fill style within the bgFillStyleLst element. - int idx = (int)fillRef.getIdx(); - CTSchemeColor phClr = fillRef.getSchemeClr(); - XSLFSheet sheet = _sheet; - XSLFTheme theme = sheet.getTheme(); - XmlObject fillProps = null; - CTStyleMatrix matrix = theme.getXmlObject().getThemeElements().getFmtScheme(); - if(idx >= 1 && idx <= 999){ - fillProps = matrix.getFillStyleLst().selectPath("*")[idx - 1]; - } else if (idx >= 1001 ){ - fillProps = matrix.getBgFillStyleLst().selectPath("*")[idx - 1001]; - } - if(fillProps != null) { - paint = selectPaint(fillProps, phClr, sheet.getPackagePart()); - } - } - return paint == RenderableShape.NO_PAINT ? null : paint; - } - }; + @SuppressWarnings("unchecked") + protected T selectProperty(Class resultClass, String xquery) { + XmlObject[] rs = getXmlObject().selectPath(xquery); + if (rs.length == 0) return null; + return (resultClass.isInstance(rs[0])) ? (T)rs[0] : null; } /** @@ -320,108 +341,15 @@ public abstract class XSLFShape implements Shape { return ok; } - protected CTPlaceholder getCTPlaceholder() { - if (_ph == null) { - XmlObject[] obj = _shape.selectPath( - "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:nvPr/p:ph"); - if (obj.length == 1) { - _ph = (CTPlaceholder) obj[0]; - } - } - return _ph; - } - - protected CTShapeStyle getSpStyle() { - if (_spStyle == null) { - for (XmlObject obj : _shape.selectPath("*")) { - if (obj instanceof CTShapeStyle) { - _spStyle = (CTShapeStyle) obj; - } - } - } - return _spStyle; - } - - protected CTNonVisualDrawingProps getNvPr() { - if (_nvPr == null) { - XmlObject[] rs = _shape - .selectPath("declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr"); - if (rs.length != 0) { - _nvPr = (CTNonVisualDrawingProps) rs[0]; - } - } - return _nvPr; - } - - protected CTShapeProperties getSpPr() { - if (_spPr == null) { - for (XmlObject obj : _shape.selectPath("*")) { - if (obj instanceof CTShapeProperties) { - _spPr = (CTShapeProperties) obj; - } - } - } - if (_spPr == null) { - throw new IllegalStateException("CTShapeProperties was not found."); + protected PaintStyle getPaint(XmlObject spPr, CTSchemeColor phClr) { + PaintStyle paint = null; + PackagePart pp = getSheet().getPackagePart(); + for (XmlObject obj : spPr.selectPath("*")) { + paint = selectPaint(obj, phClr, pp); + if(paint != null) break; } - return _spPr; - } - - CTTransform2D getXfrm() { - PropertyFetcher fetcher = new PropertyFetcher() { - public boolean fetch(XSLFShape shape) { - CTShapeProperties pr = shape.getSpPr(); - if (pr.isSetXfrm()) { - setValue(pr.getXfrm()); - return true; - } - return false; - } - }; - fetchShapeProperty(fetcher); - return fetcher.getValue(); - } - - /** - * @return the position of this shape within the drawing canvas. - * The coordinates are expressed in points - */ - public Rectangle2D getAnchor() { - CTTransform2D xfrm = getXfrm(); - if (xfrm == null) return null; - - CTPoint2D off = xfrm.getOff(); - long x = off.getX(); - long y = off.getY(); - CTPositiveSize2D ext = xfrm.getExt(); - long cx = ext.getCx(); - long cy = ext.getCy(); - return new Rectangle2D.Double( - Units.toPoints(x), Units.toPoints(y), - Units.toPoints(cx), Units.toPoints(cy)); - } - - /** - * @param anchor the position of this shape within the drawing canvas. - * The coordinates are expressed in points - */ - public void setAnchor(Rectangle2D anchor) { - CTShapeProperties spPr = getSpPr(); - if (spPr == null) return; - - CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm(); - CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff(); - long x = Units.toEMU(anchor.getX()); - long y = Units.toEMU(anchor.getY()); - off.setX(x); - off.setY(y); - CTPositiveSize2D ext = xfrm.isSetExt() ? xfrm.getExt() : xfrm - .addNewExt(); - long cx = Units.toEMU(anchor.getWidth()); - long cy = Units.toEMU(anchor.getHeight()); - ext.setCx(cx); - ext.setCy(cy); - } + return paint == null ? TRANSPARENT_PAINT : paint; + } /** * Convert shape fill into java.awt.Paint. The result is either Color or @@ -444,122 +372,126 @@ public abstract class XSLFShape implements Shape { * @return the applied Paint or null if none was applied */ protected PaintStyle selectPaint(XmlObject obj, final CTSchemeColor phClr, final PackagePart parentPart) { - final XSLFTheme theme = getSheet().getTheme(); - if (obj instanceof CTNoFillProperties) { return TRANSPARENT_PAINT; + } else if (obj instanceof CTSolidColorFillProperties) { + return selectPaint((CTSolidColorFillProperties)obj, phClr, parentPart); + } else if (obj instanceof CTBlipFillProperties) { + return selectPaint((CTBlipFillProperties)obj, phClr, parentPart); + } else if (obj instanceof CTGradientFillProperties) { + return selectPaint((CTGradientFillProperties) obj, phClr, parentPart); + } else { + return null; } - - if (obj instanceof CTSolidColorFillProperties) { - CTSolidColorFillProperties solidFill = (CTSolidColorFillProperties) obj; - final XSLFColor c = new XSLFColor(solidFill, theme, phClr); - return new SolidPaint() { - public ColorStyle getSolidColor() { - return c.getColorStyle(); - } - }; - } - - if (obj instanceof CTBlipFillProperties) { - CTBlipFillProperties blipFill = (CTBlipFillProperties)obj; - final CTBlip blip = blipFill.getBlip(); - return new TexturePaint() { - private PackagePart getPart() { - try { - String blipId = blip.getEmbed(); - PackageRelationship rel = parentPart.getRelationship(blipId); - return parentPart.getRelatedPart(rel); - } catch (InvalidFormatException e) { - throw new RuntimeException(e); - } + } + + protected PaintStyle selectPaint(final CTSolidColorFillProperties solidFill, final CTSchemeColor phClr, final PackagePart parentPart) { + final XSLFTheme theme = getSheet().getTheme(); + final XSLFColor c = new XSLFColor(solidFill, theme, phClr); + return new SolidPaint() { + public ColorStyle getSolidColor() { + return c.getColorStyle(); + } + }; + } + + protected PaintStyle selectPaint(final CTBlipFillProperties blipFill, final CTSchemeColor phClr, final PackagePart parentPart) { + final CTBlip blip = blipFill.getBlip(); + return new TexturePaint() { + private PackagePart getPart() { + try { + String blipId = blip.getEmbed(); + PackageRelationship rel = parentPart.getRelationship(blipId); + return parentPart.getRelatedPart(rel); + } catch (InvalidFormatException e) { + throw new RuntimeException(e); } - - public InputStream getImageData() { - try { - return getPart().getInputStream(); - } catch (IOException e) { - throw new RuntimeException(e); - } + } + + public InputStream getImageData() { + try { + return getPart().getInputStream(); + } catch (IOException e) { + throw new RuntimeException(e); } + } - public String getContentType() { - /* TOOD: map content-type */ - return getPart().getContentType(); - } + public String getContentType() { + /* TOOD: map content-type */ + return getPart().getContentType(); + } - public int getAlpha() { - return (blip.sizeOfAlphaModFixArray() > 0) - ? blip.getAlphaModFixArray(0).getAmt() - : 0; - } - }; - } - - if (obj instanceof CTGradientFillProperties) { - final CTGradientFillProperties gradFill = (CTGradientFillProperties) obj; + public int getAlpha() { + return (blip.sizeOfAlphaModFixArray() > 0) + ? blip.getAlphaModFixArray(0).getAmt() + : 0; + } + }; + } + + protected PaintStyle selectPaint(final CTGradientFillProperties gradFill, final CTSchemeColor phClr, final PackagePart parentPart) { - @SuppressWarnings("deprecation") - final CTGradientStop[] gs = gradFill.getGsLst().getGsArray(); + @SuppressWarnings("deprecation") + final CTGradientStop[] gs = gradFill.getGsLst().getGsArray(); - Arrays.sort(gs, new Comparator() { - public int compare(CTGradientStop o1, CTGradientStop o2) { - Integer pos1 = o1.getPos(); - Integer pos2 = o2.getPos(); - return pos1.compareTo(pos2); - } - }); + Arrays.sort(gs, new Comparator() { + public int compare(CTGradientStop o1, CTGradientStop o2) { + Integer pos1 = o1.getPos(); + Integer pos2 = o2.getPos(); + return pos1.compareTo(pos2); + } + }); - final ColorStyle cs[] = new ColorStyle[gs.length]; - final float fractions[] = new float[gs.length]; - - int i=0; - for (CTGradientStop cgs : gs) { - cs[i] = new XSLFColor(cgs, theme, phClr).getColorStyle(); - fractions[i] = cgs.getPos() / 100000.f; + final ColorStyle cs[] = new ColorStyle[gs.length]; + final float fractions[] = new float[gs.length]; + XSLFTheme theme = getSheet().getTheme(); + + int i=0; + for (CTGradientStop cgs : gs) { + cs[i] = new XSLFColor(cgs, theme, phClr).getColorStyle(); + fractions[i] = cgs.getPos() / 100000.f; + } + + return new GradientPaint() { + + public double getGradientAngle() { + return (gradFill.isSetLin()) + ? gradFill.getLin().getAng() / 60000.d + : 0; } - - return new GradientPaint() { - public double getGradientAngle() { - return (gradFill.isSetLin()) - ? gradFill.getLin().getAng() / 60000.d - : 0; - } + public ColorStyle[] getGradientColors() { + return cs; + } - public ColorStyle[] getGradientColors() { - return cs; - } + public float[] getGradientFractions() { + return fractions; + } - public float[] getGradientFractions() { - return fractions; - } + public boolean isRotatedWithShape() { + // TODO: is this correct??? + return (gradFill.isSetRotWithShape() || !gradFill.getRotWithShape()); + } - public boolean isRotatedWithShape() { - // TODO: is this correct??? - return (gradFill.isSetRotWithShape() || !gradFill.getRotWithShape()); + public GradientType getGradientType() { + if (gradFill.isSetLin()) { + return GradientType.linear; } - - public GradientType getGradientType() { - if (gradFill.isSetLin()) { - return GradientType.linear; - } - - if (gradFill.isSetPath()) { - /* TODO: handle rect path */ - STPathShadeType.Enum ps = gradFill.getPath().getPath(); - if (ps == STPathShadeType.CIRCLE) { - return GradientType.circular; - } else if (ps == STPathShadeType.SHAPE) { - return GradientType.shape; - } + + if (gradFill.isSetPath()) { + /* TODO: handle rect path */ + STPathShadeType.Enum ps = gradFill.getPath().getPath(); + if (ps == STPathShadeType.CIRCLE) { + return GradientType.circular; + } else if (ps == STPathShadeType.SHAPE) { + return GradientType.shape; } - - return GradientType.linear; } - }; - } - - return TRANSPARENT_PAINT; + + return GradientType.linear; + } + }; } + } \ No newline at end of file diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShapeContainer.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShapeContainer.java index d839a49d37..e1d00c58d4 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShapeContainer.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShapeContainer.java @@ -24,7 +24,7 @@ import org.apache.poi.sl.usermodel.ShapeContainer; /** * Common interface for shape containers, e.g. sheets or groups of shapes */ -public interface XSLFShapeContainer extends ShapeContainer { +public interface XSLFShapeContainer extends ShapeContainer { /** * create a new shape with a predefined geometry and add it to this shape container diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java index c9694e2185..163d8a65aa 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSheet.java @@ -16,47 +16,28 @@ ==================================================================== */ 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 { private XSLFCommonSlideData _commonSlideData; private XSLFDrawing _drawing; private List _shapes; @@ -498,31 +479,9 @@ public abstract class XSLFSheet extends POIXMLDocumentPart implements XSLFShapeC * @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); } /** diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java index ca548dd636..ffe0fc823d 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java @@ -19,17 +19,18 @@ package org.apache.poi.xslf.usermodel; -import java.awt.*; -import java.awt.Shape; -import java.awt.geom.*; -import java.util.ArrayList; -import java.util.List; +import java.awt.Color; +import java.awt.geom.Rectangle2D; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; +import org.apache.poi.sl.draw.DrawPaint; import org.apache.poi.sl.draw.geom.*; import org.apache.poi.sl.usermodel.*; +import org.apache.poi.sl.usermodel.LineDecoration.DecorationShape; +import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize; +import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; import org.apache.poi.sl.usermodel.StrokeStyle.LineCap; import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; import org.apache.poi.util.Beta; @@ -37,7 +38,7 @@ import org.apache.poi.util.Units; import org.apache.poi.xslf.model.PropertyFetcher; import org.apache.xmlbeans.XmlObject; import org.openxmlformats.schemas.drawingml.x2006.main.*; -import org.openxmlformats.schemas.presentationml.x2006.main.*; +import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; /** * Represents a single (non-group) shape in a .pptx slide show @@ -52,77 +53,106 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { super(shape,sheet); } - /** - * - * @return the sheet this shape belongs to - */ - public XSLFSheet getSheet() { - return _sheet; - } - /** * * @param type */ public void setShapeType(ShapeType type){ - CTShape shape = (CTShape) getXmlObject(); STShapeType.Enum geom = STShapeType.Enum.forInt(type.ooxmlId); - shape.getSpPr().getPrstGeom().setPrst(geom); + getSpPr().getPrstGeom().setPrst(geom); } public ShapeType getShapeType(){ - CTShape shape = (CTShape) getXmlObject(); - STShapeType.Enum geom = shape.getSpPr().getPrstGeom().getPrst(); + STShapeType.Enum geom = getSpPr().getPrstGeom().getPrst(); return ShapeType.forId(geom.intValue(), true); } + + protected CTTransform2D getSafeXfrm() { + CTTransform2D xfrm = getXfrm(); + return (xfrm == null ? getSpPr().addNewXfrm() : xfrm); + } + + protected CTTransform2D getXfrm() { + PropertyFetcher fetcher = new PropertyFetcher() { + public boolean fetch(XSLFShape shape) { + CTShapeProperties pr = getSpPr(); + if (pr.isSetXfrm()) { + setValue(pr.getXfrm()); + return true; + } + return false; + } + }; + fetchShapeProperty(fetcher); + return fetcher.getValue(); + } @Override - public String getShapeName() { - return getNvPr().getName(); + public Rectangle2D getAnchor() { + + CTTransform2D xfrm = getXfrm(); + + CTPoint2D off = xfrm.getOff(); + long x = off.getX(); + long y = off.getY(); + CTPositiveSize2D ext = xfrm.getExt(); + long cx = ext.getCx(); + long cy = ext.getCy(); + return new Rectangle2D.Double( + Units.toPoints(x), Units.toPoints(y), + Units.toPoints(cx), Units.toPoints(cy)); } @Override - public int getShapeId() { - return (int) getNvPr().getId(); + public void setAnchor(Rectangle2D anchor) { + CTTransform2D xfrm = getSafeXfrm(); + CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff(); + long x = Units.toEMU(anchor.getX()); + long y = Units.toEMU(anchor.getY()); + off.setX(x); + off.setY(y); + CTPositiveSize2D ext = xfrm.isSetExt() ? xfrm.getExt() : xfrm + .addNewExt(); + long cx = Units.toEMU(anchor.getWidth()); + long cy = Units.toEMU(anchor.getHeight()); + ext.setCx(cx); + ext.setCy(cy); } - + @Override public void setRotation(double theta) { - CTShapeProperties spPr = getSpPr(); - CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm(); - xfrm.setRot((int) (theta * 60000)); + getSafeXfrm().setRot((int) (theta * 60000)); } @Override public double getRotation() { CTTransform2D xfrm = getXfrm(); - return (double) xfrm.getRot() / 60000; + return (xfrm == null || !xfrm.isSetRot()) ? 0 : (xfrm.getRot() / 60000.d); } @Override public void setFlipHorizontal(boolean flip) { - CTShapeProperties spPr = getSpPr(); - CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm(); - xfrm.setFlipH(flip); + getSafeXfrm().setFlipH(flip); } @Override public void setFlipVertical(boolean flip) { - CTShapeProperties spPr = getSpPr(); - CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm(); - xfrm.setFlipV(flip); + getSafeXfrm().setFlipV(flip); } @Override public boolean getFlipHorizontal() { - return getXfrm().getFlipH(); + CTTransform2D xfrm = getXfrm(); + return (xfrm == null || !xfrm.isSetFlipH()) ? false : getXfrm().getFlipH(); } @Override public boolean getFlipVertical() { - return getXfrm().getFlipV(); + CTTransform2D xfrm = getXfrm(); + return (xfrm == null || !xfrm.isSetFlipV()) ? false : getXfrm().getFlipV(); } + /** * Get default line properties defined in the theme (if any). * Used internally to resolve shape properties. @@ -135,7 +165,7 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { if (style != null) { // 1-based index of a line style within the style matrix int idx = (int) style.getLnRef().getIdx(); - CTStyleMatrix styleMatrix = _sheet.getTheme().getXmlObject().getThemeElements().getFmtScheme(); + CTStyleMatrix styleMatrix = getSheet().getTheme().getXmlObject().getThemeElements().getFmtScheme(); ln = styleMatrix.getLnStyleLst().getLnArray(idx - 1); } return ln; @@ -175,14 +205,57 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { * if outline is turned off */ public Color getLineColor() { - RenderableShape rShape = new RenderableShape(this); - Paint paint = rShape.getLinePaint(null); - if (paint instanceof Color) { - return (Color) paint; + PaintStyle ps = getLinePaint(); + if (ps == null || ps == TRANSPARENT_PAINT) return null; + if (ps instanceof SolidPaint) { + Color col = ((SolidPaint)ps).getSolidColor().getColor(); + return (col == DrawPaint.NO_PAINT) ? null : col; } return null; } + protected PaintStyle getLinePaint() { + PropertyFetcher fetcher = new PropertyFetcher() { + public boolean fetch(XSLFShape shape) { + CTLineProperties spPr = shape.getSpPr().getLn(); + if (spPr != null) { + if (spPr.isSetNoFill()) { + setValue(TRANSPARENT_PAINT); // use it as 'nofill' value + return true; + } + PaintStyle paint = getPaint(spPr, null); + if (paint != null) { + setValue(paint); + return true; + } + } + return false; + + } + }; + fetchShapeProperty(fetcher); + + PaintStyle paint = fetcher.getValue(); + if (paint != null) return paint; + + // line color was not found, check if it is defined in the theme + CTShapeStyle style = getSpStyle(); + if (style == null) return TRANSPARENT_PAINT; + + // get a reference to a line style within the style matrix. + CTStyleMatrixReference lnRef = style.getLnRef(); + int idx = (int)lnRef.getIdx(); + CTSchemeColor phClr = lnRef.getSchemeClr(); + if(idx > 0){ + XSLFTheme theme = getSheet().getTheme(); + XmlObject lnProps = theme.getXmlObject(). + getThemeElements().getFmtScheme().getLnStyleLst().selectPath("*")[idx - 1]; + paint = getPaint(lnProps, phClr); + } + + return paint == null ? TRANSPARENT_PAINT : paint; + } + /** * * @param width line width in points. 0 means no line @@ -377,10 +450,11 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { * is not solid (pattern or gradient) */ public Color getFillColor() { - RenderableShape rShape = new RenderableShape(this); - Paint paint = rShape.getFillPaint(null); - if (paint instanceof Color) { - return (Color) paint; + PaintStyle ps = getFillPaint(); + if (ps == null || ps == TRANSPARENT_PAINT) return null; + if (ps instanceof SolidPaint) { + Color col = ((SolidPaint)ps).getSolidColor().getColor(); + return (col == DrawPaint.NO_PAINT) ? null : col; } return null; } @@ -410,7 +484,7 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { // 1-based index of a shadow style within the style matrix int idx = (int) style.getEffectRef().getIdx(); if(idx != 0) { - CTStyleMatrix styleMatrix = _sheet.getTheme().getXmlObject().getThemeElements().getFmtScheme(); + CTStyleMatrix styleMatrix = getSheet().getTheme().getXmlObject().getThemeElements().getFmtScheme(); CTEffectStyleItem ef = styleMatrix.getEffectStyleLst().getEffectStyleArray(idx - 1); obj = ef.getEffectLst().getOuterShdw(); } @@ -493,7 +567,7 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { /** * Specifies the line end decoration, such as a triangle or arrowhead. */ - public void setLineHeadDecoration(LineDecoration style) { + public void setLineHeadDecoration(DecorationShape style) { CTLineProperties ln = getSpPr().getLn(); CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd(); if (style == null) { @@ -503,18 +577,18 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { } } - public LineDecoration getLineHeadDecoration() { + public DecorationShape getLineHeadDecoration() { CTLineProperties ln = getSpPr().getLn(); - if (ln == null || !ln.isSetHeadEnd()) return LineDecoration.NONE; + if (ln == null || !ln.isSetHeadEnd()) return DecorationShape.NONE; STLineEndType.Enum end = ln.getHeadEnd().getType(); - return end == null ? LineDecoration.NONE : LineDecoration.values()[end.intValue() - 1]; + return end == null ? DecorationShape.NONE : DecorationShape.values()[end.intValue() - 1]; } /** * specifies decorations which can be added to the head of a line. */ - public void setLineHeadWidth(LineEndWidth style) { + public void setLineHeadWidth(DecorationSize style) { CTLineProperties ln = getSpPr().getLn(); CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd(); if (style == null) { @@ -524,18 +598,18 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { } } - public LineEndWidth getLineHeadWidth() { + public DecorationSize getLineHeadWidth() { CTLineProperties ln = getSpPr().getLn(); - if (ln == null || !ln.isSetHeadEnd()) return LineEndWidth.MEDIUM; + if (ln == null || !ln.isSetHeadEnd()) return DecorationSize.MEDIUM; STLineEndWidth.Enum w = ln.getHeadEnd().getW(); - return w == null ? LineEndWidth.MEDIUM : LineEndWidth.values()[w.intValue() - 1]; + return w == null ? DecorationSize.MEDIUM : DecorationSize.values()[w.intValue() - 1]; } /** * Specifies the line end width in relation to the line width. */ - public void setLineHeadLength(LineEndLength style) { + public void setLineHeadLength(DecorationSize style) { CTLineProperties ln = getSpPr().getLn(); CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd(); @@ -546,18 +620,18 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { } } - public LineEndLength getLineHeadLength() { + public DecorationSize getLineHeadLength() { CTLineProperties ln = getSpPr().getLn(); - if (ln == null || !ln.isSetHeadEnd()) return LineEndLength.MEDIUM; + if (ln == null || !ln.isSetHeadEnd()) return DecorationSize.MEDIUM; STLineEndLength.Enum len = ln.getHeadEnd().getLen(); - return len == null ? LineEndLength.MEDIUM : LineEndLength.values()[len.intValue() - 1]; + return len == null ? DecorationSize.MEDIUM : DecorationSize.values()[len.intValue() - 1]; } /** * Specifies the line end decoration, such as a triangle or arrowhead. */ - public void setLineTailDecoration(LineDecoration style) { + public void setLineTailDecoration(DecorationShape style) { CTLineProperties ln = getSpPr().getLn(); CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd(); if (style == null) { @@ -567,18 +641,18 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { } } - public LineDecoration getLineTailDecoration() { + public DecorationShape getLineTailDecoration() { CTLineProperties ln = getSpPr().getLn(); - if (ln == null || !ln.isSetTailEnd()) return LineDecoration.NONE; + if (ln == null || !ln.isSetTailEnd()) return DecorationShape.NONE; STLineEndType.Enum end = ln.getTailEnd().getType(); - return end == null ? LineDecoration.NONE : LineDecoration.values()[end.intValue() - 1]; + return end == null ? DecorationShape.NONE : DecorationShape.values()[end.intValue() - 1]; } /** * specifies decorations which can be added to the tail of a line. */ - public void setLineTailWidth(LineEndWidth style) { + public void setLineTailWidth(DecorationSize style) { CTLineProperties ln = getSpPr().getLn(); CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd(); if (style == null) { @@ -588,18 +662,18 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { } } - public LineEndWidth getLineTailWidth() { + public DecorationSize getLineTailWidth() { CTLineProperties ln = getSpPr().getLn(); - if (ln == null || !ln.isSetTailEnd()) return LineEndWidth.MEDIUM; + if (ln == null || !ln.isSetTailEnd()) return DecorationSize.MEDIUM; STLineEndWidth.Enum w = ln.getTailEnd().getW(); - return w == null ? LineEndWidth.MEDIUM : LineEndWidth.values()[w.intValue() - 1]; + return w == null ? DecorationSize.MEDIUM : DecorationSize.values()[w.intValue() - 1]; } /** * Specifies the line end width in relation to the line width. */ - public void setLineTailLength(LineEndLength style) { + public void setLineTailLength(DecorationSize style) { CTLineProperties ln = getSpPr().getLn(); CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd(); @@ -610,142 +684,12 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { } } - public LineEndLength getLineTailLength() { + public DecorationSize getLineTailLength() { CTLineProperties ln = getSpPr().getLn(); - if (ln == null || !ln.isSetTailEnd()) return LineEndLength.MEDIUM; + if (ln == null || !ln.isSetTailEnd()) return DecorationSize.MEDIUM; STLineEndLength.Enum len = ln.getTailEnd().getLen(); - return len == null ? LineEndLength.MEDIUM : LineEndLength.values()[len.intValue() - 1]; - } - - Outline getTailDecoration(Graphics2D graphics) { - LineEndLength tailLength = getLineTailLength(); - LineEndWidth tailWidth = getLineTailWidth(); - - double lineWidth = Math.max(2.5, getLineWidth()); - - Rectangle2D anchor = new RenderableShape(this).getAnchor(graphics); - double x2 = anchor.getX() + anchor.getWidth(), - y2 = anchor.getY() + anchor.getHeight(); - - double alpha = Math.atan(anchor.getHeight() / anchor.getWidth()); - - AffineTransform at = new AffineTransform(); - Shape shape = null; - Path p = null; - Rectangle2D bounds; - double scaleY = Math.pow(2, tailWidth.ordinal()); - double scaleX = Math.pow(2, tailLength.ordinal()); - switch (getLineTailDecoration()) { - case OVAL: - p = new Path(); - shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY); - bounds = shape.getBounds2D(); - at.translate(x2 - bounds.getWidth() / 2, y2 - bounds.getHeight() / 2); - at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2); - break; - case ARROW: - p = new Path(); - GeneralPath arrow = new GeneralPath(); - arrow.moveTo((float) (-lineWidth * 3), (float) (-lineWidth * 2)); - arrow.lineTo(0, 0); - arrow.lineTo((float) (-lineWidth * 3), (float) (lineWidth * 2)); - shape = arrow; - at.translate(x2, y2); - at.rotate(alpha); - break; - case TRIANGLE: - p = new Path(); - scaleY = tailWidth.ordinal() + 1; - scaleX = tailLength.ordinal() + 1; - GeneralPath triangle = new GeneralPath(); - triangle.moveTo((float) (-lineWidth * scaleX), (float) (-lineWidth * scaleY / 2)); - triangle.lineTo(0, 0); - triangle.lineTo((float) (-lineWidth * scaleX), (float) (lineWidth * scaleY / 2)); - triangle.closePath(); - shape = triangle; - at.translate(x2, y2); - at.rotate(alpha); - break; - default: - break; - } - - if (shape != null) { - shape = at.createTransformedShape(shape); - } - return shape == null ? null : new Outline(shape, p); - } - - Outline getHeadDecoration(Graphics2D graphics) { - LineEndLength headLength = getLineHeadLength(); - LineEndWidth headWidth = getLineHeadWidth(); - - double lineWidth = Math.max(2.5, getLineWidth()); - - Rectangle2D anchor = new RenderableShape(this).getAnchor(graphics); - double x1 = anchor.getX(), - y1 = anchor.getY(); - - double alpha = Math.atan(anchor.getHeight() / anchor.getWidth()); - - AffineTransform at = new AffineTransform(); - Shape shape = null; - Path p = null; - Rectangle2D bounds; - double scaleY = 1; - double scaleX = 1; - switch (getLineHeadDecoration()) { - case OVAL: - p = new Path(); - shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY); - bounds = shape.getBounds2D(); - at.translate(x1 - bounds.getWidth() / 2, y1 - bounds.getHeight() / 2); - at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2); - break; - case STEALTH: - case ARROW: - p = new Path(false, true); - GeneralPath arrow = new GeneralPath(); - arrow.moveTo((float) (lineWidth * 3 * scaleX), (float) (-lineWidth * scaleY * 2)); - arrow.lineTo(0, 0); - arrow.lineTo((float) (lineWidth * 3 * scaleX), (float) (lineWidth * scaleY * 2)); - shape = arrow; - at.translate(x1, y1); - at.rotate(alpha); - break; - case TRIANGLE: - p = new Path(); - scaleY = headWidth.ordinal() + 1; - scaleX = headLength.ordinal() + 1; - GeneralPath triangle = new GeneralPath(); - triangle.moveTo((float) (lineWidth * scaleX), (float) (-lineWidth * scaleY / 2)); - triangle.lineTo(0, 0); - triangle.lineTo((float) (lineWidth * scaleX), (float) (lineWidth * scaleY / 2)); - triangle.closePath(); - shape = triangle; - at.translate(x1, y1); - at.rotate(alpha); - break; - default: - break; - } - - if (shape != null) { - shape = at.createTransformedShape(shape); - } - return shape == null ? null : new Outline(shape, p); - } - - private List getDecorationOutlines(Graphics2D graphics){ - List lst = new ArrayList(); - - Outline head = getHeadDecoration(graphics); - if(head != null) lst.add(head); - - Outline tail = getTailDecoration(graphics); - if(tail != null) lst.add(tail); - return lst; + return len == null ? DecorationSize.MEDIUM : DecorationSize.values()[len.intValue() - 1]; } public boolean isPlaceholder() { @@ -753,25 +697,79 @@ public abstract class XSLFSimpleShape extends XSLFShape implements SimpleShape { return ph != null; } - public Hyperlink getHyperlink() { - // TODO Auto-generated method stub + @SuppressWarnings("deprecation") + public Guide getAdjustValue(String name) { + CTPresetGeometry2D prst = getSpPr().getPrstGeom(); + if (prst.isSetAvLst()) { + for (CTGeomGuide g : prst.getAvLst().getGdArray()) { + if (g.getName().equals(name)) { + return new Guide(g.getName(), g.getFmla()); + } + } + } + return null; } - public void setHyperlink(Hyperlink hyperlink) { - // TODO Auto-generated method stub - + public LineDecoration getLineDecoration() { + return new LineDecoration() { + public DecorationShape getHeadShape() { + return getLineHeadDecoration(); + } + + public DecorationSize getHeadWidth() { + return getLineHeadWidth(); + } + + public DecorationSize getHeadLength() { + return getLineHeadLength(); + } + + public DecorationShape getTailShape() { + return getLineTailDecoration(); + } + + public DecorationSize getTailWidth() { + return getLineTailWidth(); + } + + public DecorationSize getTailLength() { + return getLineTailLength(); + } + }; } - public Guide getAdjustValue(String name) { - // TODO Auto-generated method stub - return null; + /** + * fetch shape fill as a java.awt.Paint + * + * @return either Color or GradientPaint or TexturePaint or null + */ + public FillStyle getFillStyle() { + return new FillStyle() { + public PaintStyle getPaint() { + return XSLFSimpleShape.this.getFillPaint(); + } + }; } - public org.apache.poi.sl.usermodel.LineDecoration getLineDecoration() { - // TODO Auto-generated method stub - return null; + public StrokeStyle getStrokeStyle() { + return new StrokeStyle() { + public PaintStyle getPaint() { + return XSLFSimpleShape.this.getLinePaint(); + } + + public LineCap getLineCap() { + return XSLFSimpleShape.this.getLineCap(); + } + + public LineDash getLineDash() { + return XSLFSimpleShape.this.getLineDash(); + } + + public double getLineWidth() { + return XSLFSimpleShape.this.getLineWidth(); + } + + }; } - - } diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java index af80a57ffc..795daa30b5 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlide.java @@ -16,7 +16,6 @@ ==================================================================== */ package org.apache.poi.xslf.usermodel; -import java.awt.Graphics2D; import java.io.IOException; import org.apache.poi.POIXMLDocumentPart; @@ -26,21 +25,11 @@ import org.apache.poi.sl.usermodel.Notes; 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 { private final CTSlide _slide; private XSLFSlideLayout _layout; private XSLFComments _comments; @@ -220,17 +209,6 @@ public final class XSLFSlide extends XSLFSheet implements Slide { 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); diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java index 2373641354..bd6c38ca46 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideLayout.java @@ -31,7 +31,7 @@ import org.openxmlformats.schemas.presentationml.x2006.main.SldLayoutDocument; import java.io.IOException; @Beta -public class XSLFSlideLayout extends XSLFSheet implements MasterSheet { +public class XSLFSlideLayout extends XSLFSheet implements MasterSheet { private CTSlideLayout _layout; private XSLFSlideMaster _master; diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java index ebeec01efb..0b64306fd1 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSlideMaster.java @@ -54,7 +54,7 @@ import java.util.Map; * @author Yegor Kozlov */ @Beta - public class XSLFSlideMaster extends XSLFSheet implements MasterSheet { + public class XSLFSlideMaster extends XSLFSheet implements MasterSheet { private CTSlideMaster _slide; private Map _layouts; private XSLFTheme _theme; diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java index a21b9d5e37..fcd28a8b10 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java @@ -23,42 +23,22 @@ import java.awt.Color; import org.apache.poi.sl.usermodel.VerticalAlignment; import org.apache.poi.util.Units; -import org.openxmlformats.schemas.drawingml.x2006.main.CTLineEndProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; -import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCellProperties; -import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; -import org.openxmlformats.schemas.drawingml.x2006.main.STCompoundLine; -import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap; -import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndLength; -import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndType; -import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndWidth; -import org.openxmlformats.schemas.drawingml.x2006.main.STPenAlignment; -import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal; -import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType; +import org.openxmlformats.schemas.drawingml.x2006.main.*; /** * Represents a cell of a table in a .pptx presentation - * - * @author Yegor Kozlov */ public class XSLFTableCell extends XSLFTextShape { static double defaultBorderWidth = 1.0; + private CTTableCellProperties _tcPr = null; /*package*/ XSLFTableCell(CTTableCell cell, XSLFSheet sheet){ super(cell, sheet); } - @Override - public CTTableCell getXmlObject(){ - return (CTTableCell)super.getXmlObject(); - } - @Override protected CTTextBody getTextBody(boolean create){ - CTTableCell cell = getXmlObject(); + CTTableCell cell = (CTTableCell)getXmlObject(); CTTextBody txBody = cell.getTxBody(); if (txBody == null && create) { txBody = cell.addNewTxBody(); @@ -78,135 +58,72 @@ public class XSLFTableCell extends XSLFTextShape { return cell; } + protected CTTableCellProperties getCellProperties(boolean create) { + if (_tcPr == null) { + CTTableCell cell = (CTTableCell)getXmlObject(); + _tcPr = cell.getTcPr(); + if (_tcPr == null && create) { + _tcPr = cell.addNewTcPr(); + } + } + return _tcPr; + } + @Override public void setLeftInset(double margin){ - CTTableCellProperties pr = getXmlObject().getTcPr(); - if(pr == null) pr = getXmlObject().addNewTcPr(); - + CTTableCellProperties pr = getCellProperties(true); pr.setMarL(Units.toEMU(margin)); } @Override public void setRightInset(double margin){ - CTTableCellProperties pr = getXmlObject().getTcPr(); - if(pr == null) pr = getXmlObject().addNewTcPr(); - + CTTableCellProperties pr = getCellProperties(true); pr.setMarR(Units.toEMU(margin)); } @Override public void setTopInset(double margin){ - CTTableCellProperties pr = getXmlObject().getTcPr(); - if(pr == null) pr = getXmlObject().addNewTcPr(); - + CTTableCellProperties pr = getCellProperties(true); pr.setMarT(Units.toEMU(margin)); } @Override public void setBottomInset(double margin){ - CTTableCellProperties pr = getXmlObject().getTcPr(); - if(pr == null) pr = getXmlObject().addNewTcPr(); - + CTTableCellProperties pr = getCellProperties(true); pr.setMarB(Units.toEMU(margin)); } - public void setBorderLeft(double width){ - CTTableCellProperties pr = getXmlObject().getTcPr(); - - CTLineProperties ln = pr.isSetLnL() ? pr.getLnL() : pr.addNewLnL(); - ln.setW(Units.toEMU(width)); - } - - public double getBorderLeft(){ - CTTableCellProperties pr = getXmlObject().getTcPr(); - - CTLineProperties ln = pr.getLnL(); - return ln == null || !ln.isSetW() ? defaultBorderWidth : Units.toPoints(ln.getW()); - } - - public void setBorderLeftColor(Color color){ - CTTableCellProperties pr = getXmlObject().getTcPr(); - CTLineProperties ln = pr.isSetLnL() ? pr.getLnL() : pr.addNewLnL(); - setLineColor(ln, color); - } - - public Color getBorderLeftColor(){ - return getLineColor(getXmlObject().getTcPr().getLnL()); - } - - public void setBorderRight(double width){ - CTTableCellProperties pr = getXmlObject().getTcPr(); - - CTLineProperties ln = pr.isSetLnR() ? pr.getLnR() : pr.addNewLnR(); - ln.setW(Units.toEMU(width)); - } - - public double getBorderRight(){ - CTTableCellProperties pr = getXmlObject().getTcPr(); - - CTLineProperties ln = pr.getLnR(); - return ln == null || !ln.isSetW() ? defaultBorderWidth : Units.toPoints(ln.getW()); - } - - public void setBorderRightColor(Color color){ - CTTableCellProperties pr = getXmlObject().getTcPr(); - CTLineProperties ln = pr.isSetLnR() ? pr.getLnR() : pr.addNewLnR(); - setLineColor(ln, color); - } - - public Color getBorderRightColor(){ - return getLineColor(getXmlObject().getTcPr().getLnR()); - } - - public void setBorderTop(double width){ - CTTableCellProperties pr = getXmlObject().getTcPr(); - - CTLineProperties ln = pr.isSetLnT() ? pr.getLnT() : pr.addNewLnT(); - ln.setW(Units.toEMU(width)); - } - - public double getBorderTop(){ - CTTableCellProperties pr = getXmlObject().getTcPr(); - - CTLineProperties ln = pr.getLnT(); - return ln == null || !ln.isSetW() ? defaultBorderWidth : Units.toPoints(ln.getW()); - } - - public void setBorderTopColor(Color color){ - CTTableCellProperties pr = getXmlObject().getTcPr(); - CTLineProperties ln = pr.isSetLnT() ? pr.getLnT() : pr.addNewLnT(); - setLineColor(ln, color); - } - - public Color getBorderTopColor(){ - return getLineColor(getXmlObject().getTcPr().getLnT()); + private CTLineProperties getCTLine(char bltr, boolean create) { + CTTableCellProperties pr = getCellProperties(create); + if (pr == null) return null; + + switch (bltr) { + case 'b': + return (pr.isSetLnB()) ? pr.getLnB() : (create ? pr.addNewLnB() : null); + case 'l': + return (pr.isSetLnL()) ? pr.getLnL() : (create ? pr.addNewLnL() : null); + case 't': + return (pr.isSetLnT()) ? pr.getLnT() : (create ? pr.addNewLnT() : null); + case 'r': + return (pr.isSetLnR()) ? pr.getLnR() : (create ? pr.addNewLnR() : null); + default: + return null; + } } - - public void setBorderBottom(double width){ - CTTableCellProperties pr = getXmlObject().getTcPr(); - - CTLineProperties ln = pr.isSetLnB() ? pr.getLnB() : pr.addNewLnB(); + + private void setBorderWidth(char bltr, double width) { + CTLineProperties ln = getCTLine(bltr, true); ln.setW(Units.toEMU(width)); } - public double getBorderBottom(){ - CTTableCellProperties pr = getXmlObject().getTcPr(); - - CTLineProperties ln = pr.getLnB(); - return ln == null || !ln.isSetW() ? defaultBorderWidth : Units.toPoints(ln.getW()); + private double getBorderWidth(char bltr) { + CTLineProperties ln = getCTLine(bltr, false); + return (ln == null) ? defaultBorderWidth : Units.toPoints(ln.getW()); } - public void setBorderBottomColor(Color color){ - CTTableCellProperties pr = getXmlObject().getTcPr(); - CTLineProperties ln = pr.isSetLnB() ? pr.getLnB() : pr.addNewLnB(); - setLineColor(ln, color); - } + private void setBorderColor(char bltr, Color color) { + CTLineProperties ln = getCTLine(bltr, true); - public Color getBorderBottomColor(){ - return getLineColor(getXmlObject().getTcPr().getLnB()); - } - - private void setLineColor(CTLineProperties ln, Color color){ if(color == null){ ln.addNewNoFill(); if(ln.isSetSolidFill()) ln.unsetSolidFill(); @@ -233,19 +150,85 @@ public class XSLFTableCell extends XSLFTextShape { rgb.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()}); ln.addNewSolidFill().setSrgbClr(rgb); } - } - - private Color getLineColor(CTLineProperties ln){ - if(ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) return null; + } + + private Color getBorderColor(char bltr) { + CTLineProperties ln = getCTLine(bltr,false); + if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) return null; CTSolidColorFillProperties fill = ln.getSolidFill(); - if(!fill.isSetSrgbClr()) { + if (!fill.isSetSrgbClr()) { // TODO for now return null for all colors except explicit RGB return null; } byte[] val = fill.getSrgbClr().getVal(); return new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]); + } + + public void setBorderLeft(double width) { + setBorderWidth('l', width); } + + public double getBorderLeft() { + return getBorderWidth('l'); + } + + public void setBorderLeftColor(Color color) { + setBorderColor('l', color); + } + + public Color getBorderLeftColor() { + return getBorderColor('l'); + } + + public void setBorderRight(double width) { + setBorderWidth('r', width); + } + + public double getBorderRight() { + return getBorderWidth('r'); + } + + public void setBorderRightColor(Color color) { + setBorderColor('r', color); + } + + public Color getBorderRightColor() { + return getBorderColor('r'); + } + + public void setBorderTop(double width) { + setBorderWidth('t', width); + } + + public double getBorderTop() { + return getBorderWidth('t'); + } + + public void setBorderTopColor(Color color) { + setBorderColor('t', color); + } + + public Color getBorderTopColor() { + return getBorderColor('t'); + } + + public void setBorderBottom(double width) { + setBorderWidth('b', width); + } + + public double getBorderBottom() { + return getBorderWidth('b'); + } + + public void setBorderBottomColor(Color color) { + setBorderColor('b', color); + } + + public Color getBorderBottomColor(){ + return getBorderColor('b'); + } + /** * Specifies a solid color fill. The shape is filled entirely with the specified color. * @@ -254,7 +237,7 @@ public class XSLFTableCell extends XSLFTextShape { */ @Override public void setFillColor(Color color) { - CTTableCellProperties spPr = getXmlObject().getTcPr(); + CTTableCellProperties spPr = getCellProperties(true); if (color == null) { if(spPr.isSetSolidFill()) spPr.unsetSolidFill(); } @@ -274,11 +257,11 @@ public class XSLFTableCell extends XSLFTextShape { */ @Override public Color getFillColor(){ - CTTableCellProperties spPr = getXmlObject().getTcPr(); - if(!spPr.isSetSolidFill() ) return null; + CTTableCellProperties spPr = getCellProperties(false); + if (spPr == null || !spPr.isSetSolidFill()) return null; CTSolidColorFillProperties fill = spPr.getSolidFill(); - if(!fill.isSetSrgbClr()) { + if (!fill.isSetSrgbClr()) { // TODO for now return null for all colors except explicit RGB return null; } @@ -287,38 +270,36 @@ public class XSLFTableCell extends XSLFTextShape { } void setGridSpan(int gridSpan_) { - getXmlObject().setGridSpan(gridSpan_); + ((CTTableCell)getXmlObject()).setGridSpan(gridSpan_); } void setRowSpan(int rowSpan_) { - getXmlObject().setRowSpan(rowSpan_); + ((CTTableCell)getXmlObject()).setRowSpan(rowSpan_); } void setHMerge(boolean merge_) { - getXmlObject().setHMerge(merge_); + ((CTTableCell)getXmlObject()).setHMerge(merge_); } void setVMerge(boolean merge_) { - getXmlObject().setVMerge(merge_); + ((CTTableCell)getXmlObject()).setVMerge(merge_); } @Override public void setVerticalAlignment(VerticalAlignment anchor){ - CTTableCellProperties cellProps = getXmlObject().getTcPr(); - if(cellProps != null) { - if(anchor == null) { - if(cellProps.isSetAnchor()) { - cellProps.unsetAnchor(); - } - } else { - cellProps.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1)); + CTTableCellProperties cellProps = getCellProperties(true); + if(anchor == null) { + if(cellProps.isSetAnchor()) { + cellProps.unsetAnchor(); } - } + } else { + cellProps.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1)); + } } @Override public VerticalAlignment getVerticalAlignment(){ - CTTableCellProperties cellProps = getXmlObject().getTcPr(); + CTTableCellProperties cellProps = getCellProperties(false); VerticalAlignment align = VerticalAlignment.TOP; if(cellProps != null && cellProps.isSetAnchor()) { diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java index 869421e5c0..6f6dad8ee8 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java @@ -17,8 +17,6 @@ package org.apache.poi.xslf.usermodel; import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.geom.Rectangle2D; import java.util.*; import org.apache.poi.sl.usermodel.TextParagraph; @@ -37,7 +35,7 @@ import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; * @since POI-3.8 */ @Beta -public class XSLFTextParagraph implements TextParagraph { +public class XSLFTextParagraph implements TextParagraph { private final CTTextParagraph _p; private final List _runs; private final XSLFTextShape _shape; @@ -697,44 +695,6 @@ public class XSLFTextParagraph implements TextParagraph { return "[" + getClass() + "]" + getText(); } - /** - * Returns wrapping width to break lines in this paragraph - * - * @param firstLine whether the first line is breaking - * - * @return wrapping width in points - */ - double getWrappingWidth(boolean firstLine, Graphics2D graphics){ - // internal margins for the text box - double leftInset = _shape.getLeftInset(); - double rightInset = _shape.getRightInset(); - - RenderableShape rShape = new RenderableShape(_shape); - Rectangle2D anchor = rShape.getAnchor(graphics); - - double leftMargin = getLeftMargin(); - double indent = getIndent(); - - double width; - if(!_shape.getWordWrap()) { - // if wordWrap == false then we return the advance to the right border of the sheet - width = _shape.getSheet().getSlideShow().getPageSize().getWidth() - anchor.getX(); - } else { - width = anchor.getWidth() - leftInset - rightInset - leftMargin; - if(firstLine) { - if(isBullet()){ - if(indent > 0) width -= indent; - } else { - if(indent > 0) width -= indent; // first line indentation - else if (indent < 0) { // hanging indentation: the first line start at the left margin - width += leftMargin; - } - } - } - } - - return width; - } CTTextParagraphProperties getDefaultMasterStyle(){ CTPlaceholder ph = _shape.getCTPlaceholder(); diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java index b4308c46c9..ac482a981f 100644 --- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java +++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java @@ -19,17 +19,13 @@ 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; @@ -40,18 +36,11 @@ import org.openxmlformats.schemas.presentationml.x2006.main.*; /** * 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 { private final List _paragraphs; - /** - * whether the text was broken into lines. - */ - private boolean _isTextBroken; - @SuppressWarnings("deprecation") /*package*/ XSLFTextShape(XmlObject shape, XSLFSheet sheet) { super(shape, sheet); @@ -66,7 +55,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape implements TextShape } public Iterator iterator(){ - return _paragraphs.iterator(); + return getTextParagraphs().iterator(); } /** @@ -408,22 +397,15 @@ public abstract class XSLFTextShape extends XSLFSimpleShape implements TextShape 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]; } @@ -437,10 +419,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape implements TextShape * @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)); } @@ -450,14 +433,9 @@ public abstract class XSLFTextShape extends XSLFSimpleShape implements TextShape * 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 dts = drawFact.getDrawable(this); + return dts.getTextHeight(); } /** @@ -521,19 +499,4 @@ public abstract class XSLFTextShape extends XSLFSimpleShape implements TextShape } } - - 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 diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/EMF.java b/src/scratchpad/src/org/apache/poi/hslf/blip/EMF.java index 182e96a44e..7ad569aa8d 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/blip/EMF.java +++ b/src/scratchpad/src/org/apache/poi/hslf/blip/EMF.java @@ -18,7 +18,7 @@ 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; @@ -67,7 +67,7 @@ public final class EMF extends Metafile { 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); diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java b/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java index 0796db8555..4b401518ee 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java +++ b/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java @@ -24,7 +24,7 @@ import java.util.zip.InflaterInputStream; 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. @@ -86,8 +86,8 @@ public final class PICT extends Metafile { 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); diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java b/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java index 4400c95594..76f680eafd 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java +++ b/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java @@ -20,7 +20,7 @@ package org.apache.poi.hslf.blip; 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.*; @@ -78,7 +78,7 @@ public final class WMF extends Metafile { 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; diff --git a/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java b/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java index d96e2243d1..e870e5d0f8 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java +++ b/src/scratchpad/src/org/apache/poi/hslf/extractor/PowerPointExtractor.java @@ -192,7 +192,7 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor { 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]); @@ -221,7 +221,7 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor { 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 @@ -255,7 +255,7 @@ public final class PowerPointExtractor extends POIOLE2TextExtractor { textRunsToText(ret, slide.getTextRuns()); // Table text - for (Shape shape : slide.getShapes()){ + for (HSLFShape shape : slide.getShapes()){ if (shape instanceof Table){ extractTableText(ret, (Table)shape); } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/ActiveXShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/ActiveXShape.java index 8036695285..f1c90130db 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/ActiveXShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/ActiveXShape.java @@ -65,7 +65,7 @@ public final class ActiveXShape extends Picture { * this picture in the Slide * @param parent the parent shape of this picture */ - protected ActiveXShape(EscherContainerRecord escherRecord, ShapeContainer parent){ + protected ActiveXShape(EscherContainerRecord escherRecord, ShapeContainer parent){ super(escherRecord, parent); } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java index ccb302d715..0cadd7c0d9 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java @@ -35,13 +35,13 @@ import java.awt.geom.Rectangle2D; */ public class AutoShape extends TextShape { - protected AutoShape(EscherContainerRecord escherRecord, ShapeContainer parent){ + protected AutoShape(EscherContainerRecord escherRecord, ShapeContainer parent){ super(escherRecord, parent); } - public AutoShape(ShapeType type, ShapeContainer parent){ + public AutoShape(ShapeType type, ShapeContainer parent){ super(null, parent); - _escherContainer = createSpContainer(type, parent instanceof ShapeGroup); + _escherContainer = createSpContainer(type, parent instanceof HSLFGroupShape); } public AutoShape(ShapeType type){ diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/AutoShapes.java b/src/scratchpad/src/org/apache/poi/hslf/model/AutoShapes.java index 25a68dfcd8..0afc71076b 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/AutoShapes.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/AutoShapes.java @@ -70,14 +70,14 @@ public final class AutoShapes { 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; @@ -85,14 +85,14 @@ public final class AutoShapes { }; 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); @@ -105,7 +105,7 @@ public final class AutoShapes { //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); @@ -117,7 +117,7 @@ public final class AutoShapes { }; 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); @@ -128,7 +128,7 @@ public final class AutoShapes { }; 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(); @@ -142,7 +142,7 @@ public final class AutoShapes { }; 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(); @@ -156,7 +156,7 @@ public final class AutoShapes { }; 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(); @@ -172,7 +172,7 @@ public final class AutoShapes { }; 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(); @@ -190,7 +190,7 @@ public final class AutoShapes { }; 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(); @@ -212,7 +212,7 @@ public final class AutoShapes { }; 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); @@ -226,7 +226,7 @@ public final class AutoShapes { }; 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); @@ -244,7 +244,7 @@ public final class AutoShapes { }; 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); @@ -262,7 +262,7 @@ public final class AutoShapes { }; 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); @@ -280,7 +280,7 @@ public final class AutoShapes { }; 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); @@ -298,7 +298,7 @@ public final class AutoShapes { }; 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); @@ -322,7 +322,7 @@ public final class AutoShapes { }; 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); @@ -350,7 +350,7 @@ public final class AutoShapes { }; 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); @@ -378,7 +378,7 @@ public final class AutoShapes { }; 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); } }; diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Background.java b/src/scratchpad/src/org/apache/poi/hslf/model/Background.java index 12070cdf62..1b172bdb8f 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Background.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Background.java @@ -38,9 +38,9 @@ import org.apache.poi.util.POILogger; * * @author Yegor Kozlov */ -public final class Background extends Shape { +public final class Background extends HSLFShape { - protected Background(EscherContainerRecord escherRecord, ShapeContainer parent) { + protected Background(EscherContainerRecord escherRecord, ShapeContainer parent) { super(escherRecord, parent); } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Fill.java b/src/scratchpad/src/org/apache/poi/hslf/model/Fill.java index 5302e267d0..a394cac474 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Fill.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Fill.java @@ -98,7 +98,7 @@ public final class Fill { /** * The shape this background applies to */ - protected Shape shape; + protected HSLFShape shape; /** * Construct a Fill object for a shape. @@ -106,7 +106,7 @@ public final class Fill { * * @param shape the shape this background applies to */ - public Fill(Shape shape){ + public Fill(HSLFShape shape){ this.shape = shape; } @@ -118,7 +118,7 @@ public final class Fill { */ 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(); } @@ -126,7 +126,7 @@ public final class Fill { */ 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); @@ -143,7 +143,7 @@ public final class Fill { 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; @@ -160,7 +160,7 @@ public final class Fill { */ public void setFillType(int type){ EscherOptRecord opt = shape.getEscherOptRecord(); - Shape.setEscherProperty(opt, EscherProperties.FILL__FILLTYPE, type); + HSLFShape.setEscherProperty(opt, EscherProperties.FILL__FILLTYPE, type); } /** @@ -168,7 +168,7 @@ public final class Fill { */ 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; @@ -182,12 +182,12 @@ public final class Fill { 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); } } @@ -196,7 +196,7 @@ public final class Fill { */ 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; @@ -209,11 +209,11 @@ public final class Fill { 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); } } @@ -222,7 +222,7 @@ public final class Fill { */ 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(); @@ -230,7 +230,7 @@ public final class Fill { 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 lst = bstore.getChildRecords(); int idx = p.getPropertyValue(); @@ -255,7 +255,7 @@ public final class Fill { */ 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); diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Freeform.java b/src/scratchpad/src/org/apache/poi/hslf/model/Freeform.java index 187bfd0ca2..6bf232af46 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Freeform.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Freeform.java @@ -62,7 +62,7 @@ public final class Freeform extends AutoShape { * @param escherRecord EscherSpContainer container which holds information about this shape * @param parent the parent of the shape */ - protected Freeform(EscherContainerRecord escherRecord, ShapeContainer parent){ + protected Freeform(EscherContainerRecord escherRecord, ShapeContainer parent){ super(escherRecord, parent); } @@ -73,9 +73,9 @@ public final class Freeform extends AutoShape { * @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 parent){ + public Freeform(ShapeContainer parent){ super((EscherContainerRecord)null, parent); - _escherContainer = createSpContainer(ShapeType.NOT_PRIMITIVE, parent instanceof ShapeGroup); + _escherContainer = createSpContainer(ShapeType.NOT_PRIMITIVE, parent instanceof HSLFGroupShape); } /** diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFGroupShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFGroupShape.java new file mode 100644 index 0000000000..336f11743a --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFGroupShape.java @@ -0,0 +1,314 @@ +/* ==================================================================== + 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 { + + /** + * 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 EscherSpContainer container which holds information about this shape + * @param parent the parent of the shape + */ + protected HSLFGroupShape(EscherContainerRecord escherRecord, ShapeContainer parent){ + super(escherRecord, parent); + } + + /** + * @return the shapes contained in this group container + */ + public HSLFShape[] getShapes() { + List 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 EscherSpgrContainer 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 ShapeGroup to the specified location. + *

+ * @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 null - shape groups can't have hyperlinks + * + * @return null. + */ + 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 getEscherChild(int recordId){ + EscherContainerRecord groupInfoContainer = (EscherContainerRecord)_escherContainer.getChild(0); + return groupInfoContainer.getChildById((short)recordId); + } + + public Iterator iterator() { + return getShapeList().iterator(); + } + + public boolean removeShape(HSLFShape shape) { + // TODO: implement! + throw new UnsupportedOperationException(); + } + + /** + * @return the shapes contained in this group container + */ + protected List getShapeList() { + // Out escher container record should contain several + // SpContainers, the first of which is the group shape itself + Iterator iter = _escherContainer.getChildIterator(); + + // Don't include the first SpContainer, it is always NotPrimitive + if (iter.hasNext()) { + iter.next(); + } + List shapeList = new ArrayList(); + 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; + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/HSLFShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFShape.java new file mode 100644 index 0000000000..c673cae2de --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/model/HSLFShape.java @@ -0,0 +1,525 @@ +/* ==================================================================== + 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; + +/** + *

+ * 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. + *

+ *

+ * 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). + *

+ *

+ * + * @author Yegor Kozlov + */ +public abstract class HSLFShape implements org.apache.poi.sl.usermodel.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. + * null for the topmost shapes. + */ + protected ShapeContainer _parent; + + /** + * The Sheet 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 EscherSpContainer container which holds information about this shape + * @param parent the parent of this Shape + */ + protected HSLFShape(EscherContainerRecord escherRecord, ShapeContainer 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 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 null if not found. + */ + public static T getEscherChild(EscherContainerRecord owner, int recordId){ + return owner.getChildById((short)recordId); + } + + public T getEscherChild(int recordId){ + return _escherContainer.getChildById((short)recordId); + } + + /** + * Returns escher property by id. + * + * @return escher property or null if not found. + */ + public static 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 props = opt.getEscherProperties(); + for ( Iterator 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. + *
+ * Default implementation does nothing. + * + * @param sh - owning shape + */ + protected void afterInsert(Sheet sh){ + if(_fill != null) { + _fill.afterInsert(sh); + } + } + + /** + * @return the SlideShow this shape belongs to + */ + public Sheet getSheet(){ + return _sheet; + } + + /** + * Assign the SlideShow 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 null 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; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Hyperlink.java b/src/scratchpad/src/org/apache/poi/hslf/model/Hyperlink.java index d317b6ad56..df207e6716 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Hyperlink.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Hyperlink.java @@ -176,7 +176,7 @@ public final class Hyperlink { * @param shape Shape to lookup hyperlink in * @return found hyperlink or null */ - protected static Hyperlink find(Shape shape){ + protected static Hyperlink find(HSLFShape shape){ List lst = new ArrayList(); SlideShow ppt = shape.getSheet().getSlideShow(); //document-level container which stores info about all links in a presentation diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Line.java b/src/scratchpad/src/org/apache/poi/hslf/model/Line.java index 3c078ec5a0..e811aeb6bf 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Line.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Line.java @@ -97,13 +97,13 @@ public final class Line extends SimpleShape { public static final int LINE_TRIPLE = 4; - protected Line(EscherContainerRecord escherRecord, ShapeContainer parent){ + protected Line(EscherContainerRecord escherRecord, ShapeContainer parent){ super(escherRecord, parent); } - public Line(ShapeContainer parent){ + public Line(ShapeContainer parent){ super(null, parent); - _escherContainer = createSpContainer(parent instanceof ShapeGroup); + _escherContainer = createSpContainer(parent instanceof HSLFGroupShape); } public Line(){ diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/MasterSheet.java b/src/scratchpad/src/org/apache/poi/hslf/model/MasterSheet.java index c3cfaba90f..5f7bd1a592 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/MasterSheet.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/MasterSheet.java @@ -46,7 +46,7 @@ public abstract class MasterSheet extends Sheet { * * @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; diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java index 6b5225e925..834dc870e4 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java @@ -55,7 +55,7 @@ public final class MovieShape extends Picture { * @param idx the index of the picture * @param parent the parent shape */ - public MovieShape(int movieIdx, int idx, ShapeContainer parent) { + public MovieShape(int movieIdx, int idx, ShapeContainer parent) { super(idx, parent); setMovieIndex(movieIdx); } @@ -67,7 +67,7 @@ public final class MovieShape extends Picture { * this picture in the Slide * @param parent the parent shape of this picture */ - protected MovieShape(EscherContainerRecord escherRecord, ShapeContainer parent){ + protected MovieShape(EscherContainerRecord escherRecord, ShapeContainer parent){ super(escherRecord, parent); } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/OLEShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/OLEShape.java index c4e560a91f..a1e9c94e08 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/OLEShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/OLEShape.java @@ -52,7 +52,7 @@ public final class OLEShape extends Picture { * @param idx the index of the picture * @param parent the parent shape */ - public OLEShape(int idx, ShapeContainer parent) { + public OLEShape(int idx, ShapeContainer parent) { super(idx, parent); } @@ -63,7 +63,7 @@ public final class OLEShape extends Picture { * this picture in the Slide * @param parent the parent shape of this picture */ - protected OLEShape(EscherContainerRecord escherRecord, ShapeContainer parent){ + protected OLEShape(EscherContainerRecord escherRecord, ShapeContainer parent){ super(escherRecord, parent); } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java b/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java index e592d77f8f..f775addac3 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java @@ -43,7 +43,7 @@ public final class PPGraphics2D extends Graphics2D implements Cloneable { 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; @@ -58,7 +58,7 @@ public final class PPGraphics2D extends Graphics2D implements Cloneable { * * @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(); @@ -73,7 +73,7 @@ public final class PPGraphics2D extends Graphics2D implements Cloneable { /** * @return the shape group being used for drawing */ - public ShapeGroup getShapeGroup(){ + public HSLFGroupShape getShapeGroup(){ return _group; } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java b/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java index f57ced0ac4..8c3b2b6399 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java @@ -98,9 +98,9 @@ public class Picture extends SimpleShape { * @param idx the index of the picture * @param parent the parent shape */ - public Picture(int idx, ShapeContainer parent) { + public Picture(int idx, ShapeContainer parent) { super(null, parent); - _escherContainer = createSpContainer(idx, parent instanceof ShapeGroup); + _escherContainer = createSpContainer(idx, parent instanceof HSLFGroupShape); } /** @@ -110,7 +110,7 @@ public class Picture extends SimpleShape { * this picture in the Slide * @param parent the parent shape of this picture */ - protected Picture(EscherContainerRecord escherRecord, ShapeContainer parent){ + protected Picture(EscherContainerRecord escherRecord, ShapeContainer parent){ super(escherRecord, parent); } @@ -205,7 +205,7 @@ public class Picture extends SimpleShape { 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; diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java b/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java index 4b30c110e4..0e6052e969 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java @@ -31,11 +31,11 @@ import java.io.ByteArrayOutputStream; */ public final class Placeholder extends TextBox { - protected Placeholder(EscherContainerRecord escherRecord, ShapeContainer parent){ + protected Placeholder(EscherContainerRecord escherRecord, ShapeContainer parent){ super(escherRecord, parent); } - public Placeholder(ShapeContainer parent){ + public Placeholder(ShapeContainer parent){ super(parent); } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Polygon.java b/src/scratchpad/src/org/apache/poi/hslf/model/Polygon.java index b7ea9c8356..2d67c03fdc 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Polygon.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Polygon.java @@ -36,7 +36,7 @@ public final class Polygon extends AutoShape { * @param escherRecord EscherSpContainer container which holds information about this shape * @param parent the parent of the shape */ - protected Polygon(EscherContainerRecord escherRecord, ShapeContainer parent){ + protected Polygon(EscherContainerRecord escherRecord, ShapeContainer parent){ super(escherRecord, parent); } @@ -47,9 +47,9 @@ public final class Polygon extends AutoShape { * @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 parent){ + public Polygon(ShapeContainer parent){ super((EscherContainerRecord)null, parent); - _escherContainer = createSpContainer(ShapeType.NOT_PRIMITIVE, parent instanceof ShapeGroup); + _escherContainer = createSpContainer(ShapeType.NOT_PRIMITIVE, parent instanceof HSLFGroupShape); } /** diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java b/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java deleted file mode 100644 index 67da50097f..0000000000 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java +++ /dev/null @@ -1,525 +0,0 @@ -/* ==================================================================== - 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; - -/** - *

- * 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. - *

- *

- * 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). - *

- *

- * - * @author Yegor Kozlov - */ -public abstract class Shape implements org.apache.poi.sl.usermodel.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. - * null for the topmost shapes. - */ - protected ShapeContainer _parent; - - /** - * The Sheet 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 EscherSpContainer container which holds information about this shape - * @param parent the parent of this Shape - */ - protected Shape(EscherContainerRecord escherRecord, ShapeContainer 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 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 null if not found. - */ - public static T getEscherChild(EscherContainerRecord owner, int recordId){ - return owner.getChildById((short)recordId); - } - - public T getEscherChild(int recordId){ - return _escherContainer.getChildById((short)recordId); - } - - /** - * Returns escher property by id. - * - * @return escher property or null if not found. - */ - public static 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 props = opt.getEscherProperties(); - for ( Iterator 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. - *
- * Default implementation does nothing. - * - * @param sh - owning shape - */ - protected void afterInsert(Sheet sh){ - if(_fill != null) { - _fill.afterInsert(sh); - } - } - - /** - * @return the SlideShow this shape belongs to - */ - public Sheet getSheet(){ - return _sheet; - } - - /** - * Assign the SlideShow 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 null 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; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java index e9c2172649..01ac53855c 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java @@ -51,16 +51,16 @@ public final class ShapeFactory { /** * Create a new shape from the data provided. */ - public static Shape createShape(EscherContainerRecord spContainer, ShapeContainer parent){ + public static HSLFShape createShape(EscherContainerRecord spContainer, ShapeContainer parent){ if (spContainer.getRecordId() == EscherContainerRecord.SPGR_CONTAINER){ return createShapeGroup(spContainer, parent); } return createSimpeShape(spContainer, parent); } - public static ShapeGroup createShapeGroup(EscherContainerRecord spContainer, ShapeContainer parent){ - ShapeGroup group = null; - EscherRecord opt = Shape.getEscherChild((EscherContainerRecord)spContainer.getChild(0), (short)0xF122); + public static HSLFGroupShape createShapeGroup(EscherContainerRecord spContainer, ShapeContainer parent){ + HSLFGroupShape group = null; + EscherRecord opt = HSLFShape.getEscherChild((EscherContainerRecord)spContainer.getChild(0), (short)0xF122); if(opt != null){ try { EscherPropertyFactory f = new EscherPropertyFactory(); @@ -69,21 +69,21 @@ public final class ShapeFactory { 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 parent){ - Shape shape = null; + public static HSLFShape createSimpeShape(EscherContainerRecord spContainer, ShapeContainer parent){ + HSLFShape shape = null; EscherSpRecord spRecord = spContainer.getChildById(EscherSpRecord.RECORD_ID); ShapeType type = ShapeType.forId(spRecord.getShapeType(), false); @@ -117,8 +117,8 @@ public final class ShapeFactory { 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 { diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java deleted file mode 100644 index f18701a0e4..0000000000 --- a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java +++ /dev/null @@ -1,314 +0,0 @@ -/* ==================================================================== - 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 { - - /** - * 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 EscherSpContainer container which holds information about this shape - * @param parent the parent of the shape - */ - protected ShapeGroup(EscherContainerRecord escherRecord, ShapeContainer parent){ - super(escherRecord, parent); - } - - /** - * @return the shapes contained in this group container - */ - public Shape[] getShapes() { - List 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 EscherSpgrContainer 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 ShapeGroup to the specified location. - *

- * @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 null - shape groups can't have hyperlinks - * - * @return null. - */ - 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 getEscherChild(int recordId){ - EscherContainerRecord groupInfoContainer = (EscherContainerRecord)_escherContainer.getChild(0); - return groupInfoContainer.getChildById((short)recordId); - } - - public Iterator iterator() { - return getShapeList().iterator(); - } - - public boolean removeShape(Shape shape) { - // TODO: implement! - throw new UnsupportedOperationException(); - } - - /** - * @return the shapes contained in this group container - */ - protected List getShapeList() { - // Out escher container record should contain several - // SpContainers, the first of which is the group shape itself - Iterator iter = _escherContainer.getChildIterator(); - - // Don't include the first SpContainer, it is always NotPrimitive - if (iter.hasNext()) { - iter.next(); - } - List shapeList = new ArrayList(); - 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; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeOutline.java b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeOutline.java index 591bb55523..52e5a86bb1 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeOutline.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeOutline.java @@ -23,6 +23,6 @@ package org.apache.poi.hslf.model; * @author Yegor Kozlov */ public interface ShapeOutline { - java.awt.Shape getOutline(Shape shape); + java.awt.Shape getOutline(HSLFShape shape); } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java b/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java index c3383f4d69..197043fa65 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java @@ -57,7 +57,7 @@ import org.apache.poi.util.POILogger; * @author Yegor Kozlov */ -public abstract class Sheet implements ShapeContainer { +public abstract class Sheet implements ShapeContainer { private static POILogger logger = POILogFactory.getLogger(Sheet.class); /** @@ -272,9 +272,9 @@ public abstract class Sheet implements ShapeContainer { * * @return all shapes contained in this Sheet (Slide or Notes) */ - public Shape[] getShapes() { - List shapeList = getShapeList(); - return shapeList.toArray(new Shape[shapeList.size()]); + public HSLFShape[] getShapes() { + List shapeList = getShapeList(); + return shapeList.toArray(new HSLFShape[shapeList.size()]); } /** @@ -282,11 +282,11 @@ public abstract class Sheet implements ShapeContainer { * * @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); @@ -339,7 +339,7 @@ public abstract class Sheet implements ShapeContainer { * @param shape shape to be removed from this sheet, if present. * @return true if the shape was deleted. */ - public boolean removeShape(Shape shape) { + public boolean removeShape(HSLFShape shape) { PPDrawing ppdrawing = getPPDrawing(); EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0]; @@ -427,7 +427,7 @@ public abstract class Sheet implements ShapeContainer { * @return TextShape or null */ 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]; @@ -447,7 +447,7 @@ public abstract class Sheet implements ShapeContainer { * @return TextShape or null */ 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]; @@ -497,7 +497,7 @@ public abstract class Sheet implements ShapeContainer { } - public Iterator iterator() { + public Iterator iterator() { return getShapeList().iterator(); } @@ -507,7 +507,7 @@ public abstract class Sheet implements ShapeContainer { * * @return all shapes contained in this Sheet (Slide or Notes) */ - protected List getShapeList() { + protected List getShapeList() { PPDrawing ppdrawing = getPPDrawing(); EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0]; @@ -524,7 +524,7 @@ public abstract class Sheet implements ShapeContainer { throw new IllegalStateException("spgr not found"); } - List shapeList = new ArrayList(); + List shapeList = new ArrayList(); Iterator it = spgr.getChildIterator(); if (it.hasNext()) { // skip first item @@ -532,7 +532,7 @@ public abstract class Sheet implements ShapeContainer { } 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); } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java index 7694cacba2..bfe6a1d95a 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java @@ -47,7 +47,7 @@ import org.apache.poi.util.LittleEndian; * * @author Yegor Kozlov */ -public abstract class SimpleShape extends Shape { +public abstract class SimpleShape extends HSLFShape { public final static double DEFAULT_LINE_WIDTH = 0.75; @@ -63,7 +63,7 @@ public abstract class SimpleShape extends Shape { * @param escherRecord EscherSpContainer container which holds information about this shape * @param parent the parent of the shape */ - protected SimpleShape(EscherContainerRecord escherRecord, ShapeContainer parent){ + protected SimpleShape(EscherContainerRecord escherRecord, ShapeContainer parent){ super(escherRecord, parent); } @@ -223,15 +223,15 @@ public abstract class SimpleShape extends Shape { //if it is a groupped shape see if we need to transform the coordinates if (getParent() != null){ - ArrayList lst = new ArrayList(); - for (ShapeContainer parent=this.getParent(); - parent instanceof ShapeGroup; - parent = ((ShapeGroup)parent).getParent()) { - lst.add(0, (ShapeGroup)parent); + ArrayList lst = new ArrayList(); + for (ShapeContainer 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(); diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java b/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java index f5342534a5..1db3173e6a 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java @@ -149,7 +149,7 @@ public final class Slide extends Sheet { //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); @@ -428,7 +428,7 @@ public final class Slide extends Sheet { 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; @@ -436,7 +436,7 @@ public final class Slide extends Sheet { } } - Shape[] sh = getShapes(); + HSLFShape[] sh = getShapes(); for (int i = 0; i < sh.length; i++) { sh[i].draw(graphics); } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Table.java b/src/scratchpad/src/org/apache/poi/hslf/model/Table.java index 266e6d913b..f94bd7f5b6 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Table.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Table.java @@ -30,7 +30,7 @@ import java.awt.*; * * @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; @@ -93,7 +93,7 @@ public final class Table extends ShapeGroup { * @param escherRecord EscherSpContainer container which holds information about this shape * @param parent the parent of the shape */ - public Table(EscherContainerRecord escherRecord, ShapeContainer parent) { + public Table(EscherContainerRecord escherRecord, ShapeContainer parent) { super(escherRecord, parent); } @@ -150,9 +150,9 @@ public final class Table extends ShapeGroup { } protected void initTable(){ - List shapeList = getShapeList(); - Collections.sort(shapeList, new Comparator(){ - public int compare( Shape o1, Shape o2 ) { + List shapeList = getShapeList(); + Collections.sort(shapeList, new Comparator(){ + public int compare( HSLFShape o1, HSLFShape o2 ) { Rectangle anchor1 = o1.getAnchor(); Rectangle anchor2 = o2.getAnchor(); int delta = anchor1.y - anchor2.y; @@ -162,14 +162,14 @@ public final class Table extends ShapeGroup { }); int y0 = -1; int maxrowlen = 0; - List> lst = new ArrayList>(); - List row = null; - for (Shape sh : shapeList) { + List> lst = new ArrayList>(); + List row = null; + for (HSLFShape sh : shapeList) { if(sh instanceof TextShape){ Rectangle anchor = sh.getAnchor(); if(anchor.y != y0){ y0 = anchor.y; - row = new ArrayList(); + row = new ArrayList(); lst.add(row); } row.add(sh); diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/TableCell.java b/src/scratchpad/src/org/apache/poi/hslf/model/TableCell.java index 15854bb50a..715181cfad 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/TableCell.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/TableCell.java @@ -45,7 +45,7 @@ public final class TableCell extends TextBox { * @param escherRecord {@link EscherSpContainer} container which holds information about this shape * @param parent the parent of the shape */ - protected TableCell(EscherContainerRecord escherRecord, ShapeContainer parent){ + protected TableCell(EscherContainerRecord escherRecord, ShapeContainer parent){ super(escherRecord, parent); } @@ -55,7 +55,7 @@ public final class TableCell extends TextBox { * @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 parent){ + public TableCell(ShapeContainer parent){ super(parent); setShapeType(ShapeType.RECT); diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java b/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java index 267102aa52..dc5ac94104 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java @@ -38,7 +38,7 @@ public class TextBox extends TextShape { * @param escherRecord EscherSpContainer container which holds information about this shape * @param parent the parent of the shape */ - protected TextBox(EscherContainerRecord escherRecord, ShapeContainer parent){ + protected TextBox(EscherContainerRecord escherRecord, ShapeContainer parent){ super(escherRecord, parent); } @@ -49,7 +49,7 @@ public class TextBox extends TextShape { * @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 parent){ + public TextBox(ShapeContainer parent){ super(parent); } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/TextPainter.java b/src/scratchpad/src/org/apache/poi/hslf/model/TextPainter.java index 6d0dbc82d0..4b8805c266 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/TextPainter.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/TextPainter.java @@ -270,8 +270,8 @@ public final class TextPainter { 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; @@ -309,7 +309,7 @@ public final class TextPainter { 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(); @@ -325,7 +325,7 @@ public final class TextPainter { 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; } @@ -334,7 +334,7 @@ public final class TextPainter { 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(); @@ -342,7 +342,7 @@ public final class TextPainter { 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; } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java index e1e053e397..3f47ae6a5b 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java @@ -111,7 +111,7 @@ public abstract class TextShape extends SimpleShape { * @param escherRecord EscherSpContainer container which holds information about this shape * @param parent the parent of the shape */ - protected TextShape(EscherContainerRecord escherRecord, ShapeContainer parent){ + protected TextShape(EscherContainerRecord escherRecord, ShapeContainer parent){ super(escherRecord, parent); } @@ -122,9 +122,9 @@ public abstract class TextShape extends SimpleShape { * @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 parent){ + public TextShape(ShapeContainer parent){ super(null, parent); - _escherContainer = createSpContainer(parent instanceof ShapeGroup); + _escherContainer = createSpContainer(parent instanceof HSLFGroupShape); } /** diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java index a02d82ce06..878f8c12eb 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java @@ -20,7 +20,7 @@ package org.apache.poi.hslf.usermodel; 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; @@ -618,28 +618,28 @@ public final class RichTextRun { * 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; } /** diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java index 22aa0b61d0..d6829b4b4e 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java @@ -46,7 +46,7 @@ import org.apache.poi.hslf.model.MovieShape; 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; @@ -532,8 +532,8 @@ public final class SlideShow { */ 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); } @@ -545,8 +545,8 @@ public final class SlideShow { */ 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); } /** @@ -784,7 +784,7 @@ public final class SlideShow { 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(); diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawAutoShape.java b/src/scratchpad/src/org/apache/poi/sl/draw/DrawAutoShape.java index a8dcca5958..f28c2cbfd4 100644 --- a/src/scratchpad/src/org/apache/poi/sl/draw/DrawAutoShape.java +++ b/src/scratchpad/src/org/apache/poi/sl/draw/DrawAutoShape.java @@ -3,7 +3,7 @@ package org.apache.poi.sl.draw; import org.apache.poi.sl.usermodel.*; -public class DrawAutoShape extends DrawTextShape { +public class DrawAutoShape> extends DrawTextShape { public DrawAutoShape(T shape) { super(shape); } diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawBackground.java b/src/scratchpad/src/org/apache/poi/sl/draw/DrawBackground.java new file mode 100644 index 0000000000..30b3386266 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/sl/draw/DrawBackground.java @@ -0,0 +1,41 @@ +package org.apache.poi.sl.draw; + +import java.awt.*; +import java.awt.geom.Rectangle2D; + +import org.apache.poi.sl.usermodel.*; + + +public class DrawBackground extends DrawShape { + public DrawBackground(T shape) { + super(shape); + } + + public void draw(Graphics2D graphics) { + Dimension pg = shape.getSheet().getSlideShow().getPageSize(); + final Rectangle2D anchor = new Rectangle2D.Double(0, 0, pg.getWidth(), pg.getHeight()); + + PlaceableShape ps = new PlaceableShape(){ + public Rectangle2D getAnchor() { return anchor; } + public void setAnchor(Rectangle2D anchor) {} + public double getRotation() { return 0; } + public void setRotation(double theta) {} + public void setFlipHorizontal(boolean flip) {} + public void setFlipVertical(boolean flip) {} + public boolean getFlipHorizontal() { return false; } + public boolean getFlipVertical() { return false; } + }; + + DrawFactory drawFact = DrawFactory.getInstance(graphics); + DrawPaint dp = drawFact.getPaint(ps); + Paint fill = dp.getPaint(graphics, shape.getFillStyle().getPaint()); + Rectangle2D anchor2 = getAnchor(graphics, anchor); + + if(fill != null) { + graphics.setPaint(fill); + graphics.fill(anchor2); + } + } + + +} diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawFactory.java b/src/scratchpad/src/org/apache/poi/sl/draw/DrawFactory.java index 9270091a1d..80b95ee5f6 100644 --- a/src/scratchpad/src/org/apache/poi/sl/draw/DrawFactory.java +++ b/src/scratchpad/src/org/apache/poi/sl/draw/DrawFactory.java @@ -40,8 +40,13 @@ public class DrawFactory { } public static DrawFactory getInstance(Graphics2D graphics) { - // first try to find the factory over the rendering hing - DrawFactory factory = (DrawFactory)graphics.getRenderingHint(DRAW_FACTORY); + // first try to find the factory over the rendering hint + DrawFactory factory = null; + boolean isHint = false; + if (graphics != null) { + factory = (DrawFactory)graphics.getRenderingHint(DRAW_FACTORY); + isHint = true; + } // secondly try the thread local default if (factory == null) { factory = defaultFactory.get(); @@ -49,43 +54,78 @@ public class DrawFactory { // and at last, use the default factory if (factory == null) { factory = new DrawFactory(); + } + if (graphics != null && !isHint) { graphics.setRenderingHint(DRAW_FACTORY, factory); } return factory; } - public Drawable getDrawable(Sheet sheet) { - return new DrawSheet(sheet); - } - - public Drawable getDrawable(MasterSheet sheet) { - return new DrawMasterSheet(sheet); - } - @SuppressWarnings("unchecked") public Drawable getDrawable(Shape shape) { if (shape instanceof TextBox) { - return getDrawable((TextBox)shape); + return getDrawable((TextBox>)shape); } else if (shape instanceof FreeformShape) { - return getDrawable((FreeformShape)shape); + return getDrawable((FreeformShape>)shape); + } else if (shape instanceof TextShape) { + return getDrawable((TextShape>)shape); + } else if (shape instanceof ShapeGroup) { + return getDrawable((ShapeGroup)shape); + } else if (shape instanceof PictureShape) { + return getDrawable((PictureShape)shape); + } else if (shape instanceof Background) { + return getDrawable((Background)shape); + } else if (shape instanceof Slide) { + return getDrawable((Slide)shape); + } else if (shape instanceof MasterSheet) { + return getDrawable((MasterSheet)shape); + } else if (shape instanceof Sheet) { + return getDrawable((Sheet)shape); } throw new IllegalArgumentException("Unsupported shape type: "+shape.getClass()); } - public DrawTextBox getDrawable(T shape) { + public > DrawSlide getDrawable(T sheet) { + return new DrawSlide(sheet); + } + + public > DrawSheet getDrawable(T sheet) { + return new DrawSheet(sheet); + } + + public > DrawMasterSheet getDrawable(T sheet) { + return new DrawMasterSheet(sheet); + } + + public >> DrawTextBox getDrawable(T shape) { return new DrawTextBox(shape); } - public DrawFreeformShape getDrawable(T shape) { + public >> DrawFreeformShape getDrawable(T shape) { return new DrawFreeformShape(shape); } + public >> DrawTextShape getDrawable(T shape) { + return new DrawTextShape(shape); + } + + public > DrawShapeGroup getDrawable(T shape) { + return new DrawShapeGroup(shape); + } - public DrawTextParagraph getDrawable(TextParagraph paragraph) { - return new DrawTextParagraph(paragraph); + public DrawPictureShape getDrawable(T shape) { + return new DrawPictureShape(shape); + } + + public DrawTextParagraph getDrawable(TextParagraph paragraph) { + return new DrawTextParagraph(paragraph); } + public DrawBackground getDrawable(T shape) { + return new DrawBackground(shape); + } + public DrawTextFragment getTextFragment(TextLayout layout, AttributedString str) { return new DrawTextFragment(layout, str); } diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawFreeformShape.java b/src/scratchpad/src/org/apache/poi/sl/draw/DrawFreeformShape.java index 666b85a1c7..ed237997a6 100644 --- a/src/scratchpad/src/org/apache/poi/sl/draw/DrawFreeformShape.java +++ b/src/scratchpad/src/org/apache/poi/sl/draw/DrawFreeformShape.java @@ -2,7 +2,7 @@ package org.apache.poi.sl.draw; import org.apache.poi.sl.usermodel.*; -public class DrawFreeformShape extends DrawAutoShape { +public class DrawFreeformShape>> extends DrawAutoShape { public DrawFreeformShape(T shape) { super(shape); } diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawMasterSheet.java b/src/scratchpad/src/org/apache/poi/sl/draw/DrawMasterSheet.java index c4afeb35e6..7a89828ede 100644 --- a/src/scratchpad/src/org/apache/poi/sl/draw/DrawMasterSheet.java +++ b/src/scratchpad/src/org/apache/poi/sl/draw/DrawMasterSheet.java @@ -1,12 +1,11 @@ package org.apache.poi.sl.draw; -import org.apache.poi.sl.usermodel.MasterSheet; -import org.apache.poi.sl.usermodel.Shape; +import org.apache.poi.sl.usermodel.*; -public class DrawMasterSheet extends DrawSheet { +public class DrawMasterSheet> extends DrawSheet { - public DrawMasterSheet(MasterSheet sheet) { + public DrawMasterSheet(T sheet) { super(sheet); } @@ -17,6 +16,6 @@ public class DrawMasterSheet extends DrawSheet { * for instance, slide masters and layouts don't display placeholders */ protected boolean canDraw(Shape shape){ - return !shape.isPlaceholder(); + return !(shape instanceof SimpleShape) || !((SimpleShape)shape).isPlaceholder(); } } diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawPaint.java b/src/scratchpad/src/org/apache/poi/sl/draw/DrawPaint.java index c608ec3b05..77a0da740a 100644 --- a/src/scratchpad/src/org/apache/poi/sl/draw/DrawPaint.java +++ b/src/scratchpad/src/org/apache/poi/sl/draw/DrawPaint.java @@ -27,8 +27,9 @@ import java.io.IOException; import java.io.InputStream; import org.apache.poi.sl.usermodel.*; -import org.apache.poi.sl.usermodel.GradientPaint; -import org.apache.poi.sl.usermodel.TexturePaint; +import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint; +import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; +import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; @@ -142,7 +143,6 @@ public class DrawPaint { float red,green,blue; - Color color; if (lumOff > 0) { float flumOff = lumOff / 100000.f; red = (255.f - r) * (1.f - flumOff) + r; @@ -150,9 +150,9 @@ public class DrawPaint { blue = (255.f - b) * flumOff + b; } else { float flumMod = lumMod / 100000.f; - red = r * lumMod; - green = g * lumMod; - blue = b * lumMod; + red = r * flumMod; + green = g * flumMod; + blue = b * flumMod; } return new Color(Math.round(red), Math.round(green), Math.round(blue), c.getAlpha()); } diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawPictureShape.java b/src/scratchpad/src/org/apache/poi/sl/draw/DrawPictureShape.java new file mode 100644 index 0000000000..72a59b8b60 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/sl/draw/DrawPictureShape.java @@ -0,0 +1,37 @@ +package org.apache.poi.sl.draw; + +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.geom.Rectangle2D; +import java.io.IOException; + +import org.apache.poi.sl.usermodel.PictureData; +import org.apache.poi.sl.usermodel.PictureShape; + + +public class DrawPictureShape extends DrawSimpleShape { + public DrawPictureShape(T shape) { + super(shape); + } + + @Override + public void drawContent(Graphics2D graphics) { + PictureData data = shape.getPictureData(); + if(data == null) return; + + ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER); + if (renderer == null) renderer = new ImageRenderer(); + + Rectangle2D anchor = getAnchor(graphics, shape); + + Insets insets = shape.getClipping(); + + try { + renderer.loadImage(data.getData(), data.getContentType()); + renderer.drawImage(graphics, anchor, insets); + } catch (IOException e) { + // TODO: draw specific runtime exception? + throw new RuntimeException(e); + } + } +} diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawShape.java b/src/scratchpad/src/org/apache/poi/sl/draw/DrawShape.java index f2510a0cc1..6cb60c9b01 100644 --- a/src/scratchpad/src/org/apache/poi/sl/draw/DrawShape.java +++ b/src/scratchpad/src/org/apache/poi/sl/draw/DrawShape.java @@ -22,14 +22,17 @@ public class DrawShape implements Drawable { * @param graphics the graphics whos transform matrix will be modified */ public void applyTransform(Graphics2D graphics) { - Rectangle2D anchor = shape.getAnchor(); + if (!(shape instanceof PlaceableShape)) return; + + PlaceableShape ps = (PlaceableShape)shape; + Rectangle2D anchor = ps.getAnchor(); AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM); if(tx != null) { anchor = tx.createTransformedShape(anchor).getBounds2D(); } // rotation - double rotation = shape.getRotation(); + double rotation = ps.getRotation(); if (rotation != 0.) { // PowerPoint rotates shapes relative to the geometric center double centerX = anchor.getCenterX(); @@ -59,7 +62,7 @@ public class DrawShape implements Drawable { txs.rotate(Math.toRadians(-quadrant*90)); txs.translate(-centerX, -centerY); txg.concatenate(txs); - Rectangle2D anchor2 = txg.createTransformedShape(shape.getAnchor()).getBounds2D(); + Rectangle2D anchor2 = txg.createTransformedShape(ps.getAnchor()).getBounds2D(); scaleX = anchor.getWidth() == 0. ? 1.0 : anchor.getWidth() / anchor2.getWidth(); scaleY = anchor.getHeight() == 0. ? 1.0 : anchor.getHeight() / anchor2.getHeight(); } @@ -73,14 +76,14 @@ public class DrawShape implements Drawable { } //flip horizontal - if (shape.getFlipHorizontal()) { + if (ps.getFlipHorizontal()) { graphics.translate(anchor.getX() + anchor.getWidth(), anchor.getY()); graphics.scale(-1, 1); graphics.translate(-anchor.getX(), -anchor.getY()); } //flip vertical - if (shape.getFlipVertical()) { + if (ps.getFlipVertical()) { graphics.translate(anchor.getX(), anchor.getY() + anchor.getHeight()); graphics.scale(1, -1); graphics.translate(-anchor.getX(), -anchor.getY()); @@ -93,9 +96,12 @@ public class DrawShape implements Drawable { public void drawContent(Graphics2D context) { } - + public static Rectangle2D getAnchor(Graphics2D graphics, PlaceableShape shape) { - Rectangle2D anchor = shape.getAnchor(); + return getAnchor(graphics, shape.getAnchor()); + } + + public static Rectangle2D getAnchor(Graphics2D graphics, Rectangle2D anchor) { if(graphics == null) { return anchor; } diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawShapeGroup.java b/src/scratchpad/src/org/apache/poi/sl/draw/DrawShapeGroup.java new file mode 100644 index 0000000000..238bb1a116 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/sl/draw/DrawShapeGroup.java @@ -0,0 +1,60 @@ +package org.apache.poi.sl.draw; + +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; + +import org.apache.poi.sl.usermodel.*; + + +public class DrawShapeGroup> implements Drawable { + + protected final T shape; + + public DrawShapeGroup(T shape) { + this.shape = shape; + } + + public void applyTransform(Graphics2D context) { + } + + public void draw(Graphics2D graphics) { + + // the coordinate system of this group of shape + Rectangle2D interior = shape.getInteriorAnchor(); + // anchor of this group relative to the parent shape + Rectangle2D exterior = shape.getAnchor(); + + AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM); + AffineTransform tx0 = new AffineTransform(tx); + + double scaleX = interior.getWidth() == 0. ? 1.0 : exterior.getWidth() / interior.getWidth(); + double scaleY = interior.getHeight() == 0. ? 1.0 : exterior.getHeight() / interior.getHeight(); + + tx.translate(exterior.getX(), exterior.getY()); + tx.scale(scaleX, scaleY); + tx.translate(-interior.getX(), -interior.getY()); + + DrawFactory drawFact = DrawFactory.getInstance(graphics); + + for (Shape child : shape) { + // remember the initial transform and restore it after we are done with the drawing + AffineTransform at = graphics.getTransform(); + graphics.setRenderingHint(Drawable.GSAVE, true); + + Drawable draw = drawFact.getDrawable(child); + draw.applyTransform(graphics); + draw.draw(graphics); + + // restore the coordinate system + graphics.setTransform(at); + graphics.setRenderingHint(Drawable.GRESTORE, true); + } + + graphics.setRenderingHint(Drawable.GROUP_TRANSFORM, tx0); + + } + + public void drawContent(Graphics2D context) { + } +} diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawSheet.java b/src/scratchpad/src/org/apache/poi/sl/draw/DrawSheet.java index 7598d21420..d3901b39b3 100644 --- a/src/scratchpad/src/org/apache/poi/sl/draw/DrawSheet.java +++ b/src/scratchpad/src/org/apache/poi/sl/draw/DrawSheet.java @@ -3,16 +3,14 @@ package org.apache.poi.sl.draw; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; -import org.apache.poi.sl.usermodel.MasterSheet; -import org.apache.poi.sl.usermodel.Shape; -import org.apache.poi.sl.usermodel.Sheet; +import org.apache.poi.sl.usermodel.*; -public class DrawSheet implements Drawable { +public class DrawSheet> implements Drawable { - protected final Sheet sheet; + protected final T sheet; - public DrawSheet(Sheet sheet) { + public DrawSheet(T sheet) { this.sheet = sheet; } @@ -23,7 +21,7 @@ public class DrawSheet implements Drawable { public void draw(Graphics2D graphics) { DrawFactory drawFact = DrawFactory.getInstance(graphics); - MasterSheet master = sheet.getMasterSheet(); + MasterSheet master = sheet.getMasterSheet(); if(sheet.getFollowMasterGraphics() && master != null) { Drawable drawer = drawFact.getDrawable(master); diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawSimpleShape.java b/src/scratchpad/src/org/apache/poi/sl/draw/DrawSimpleShape.java index 5bb6f34c39..c5e5b4244c 100644 --- a/src/scratchpad/src/org/apache/poi/sl/draw/DrawSimpleShape.java +++ b/src/scratchpad/src/org/apache/poi/sl/draw/DrawSimpleShape.java @@ -17,6 +17,7 @@ import org.apache.poi.sl.draw.binding.CTCustomGeometry2D; import org.apache.poi.sl.draw.geom.*; import org.apache.poi.sl.usermodel.*; import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize; +import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; import org.apache.poi.util.Units; @@ -257,6 +258,9 @@ public class DrawSimpleShape extends DrawShape { Shadow shadow = shape.getShadow(); if (shadow == null || (fill == null && line == null)) return; + SolidPaint shadowPaint = shadow.getFillStyle(); + Color shadowColor = DrawPaint.applyColorTransform(shadowPaint.getSolidColor()); + double shapeRotation = shape.getRotation(); if(shape.getFlipVertical()) { shapeRotation += 180; @@ -272,12 +276,11 @@ public class DrawSimpleShape extends DrawShape { java.awt.Shape s = o.getOutline(); Path p = o.getPath(); graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, s); + graphics.setPaint(shadowColor); if(fill != null && p.isFilled()){ - graphics.setPaint(fill); graphics.fill(s); } else if (line != null && p.isStroked()) { - graphics.setPaint(line); graphics.draw(s); } } diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawSlide.java b/src/scratchpad/src/org/apache/poi/sl/draw/DrawSlide.java new file mode 100644 index 0000000000..8bc4eaf686 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/sl/draw/DrawSlide.java @@ -0,0 +1,24 @@ +package org.apache.poi.sl.draw; + +import java.awt.Graphics2D; + +import org.apache.poi.sl.usermodel.*; + + +public class DrawSlide> extends DrawSheet { + + public DrawSlide(T slide) { + super(slide); + } + + public void draw(Graphics2D graphics) { + Background bg = sheet.getBackground(); + if(bg != null) { + DrawFactory drawFact = DrawFactory.getInstance(graphics); + DrawBackground db = drawFact.getDrawable(bg); + db.draw(graphics); + } + + super.draw(graphics); + } +} diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextBox.java b/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextBox.java index 42f5316447..3c228686f1 100644 --- a/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextBox.java +++ b/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextBox.java @@ -2,7 +2,7 @@ package org.apache.poi.sl.draw; import org.apache.poi.sl.usermodel.*; -public class DrawTextBox extends DrawAutoShape { +public class DrawTextBox>> extends DrawAutoShape { public DrawTextBox(T shape) { super(shape); } diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextParagraph.java b/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextParagraph.java index f116f1b5b2..700edf0eb0 100644 --- a/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextParagraph.java +++ b/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextParagraph.java @@ -13,8 +13,8 @@ import org.apache.poi.sl.usermodel.TextParagraph.BulletStyle; import org.apache.poi.sl.usermodel.TextRun.TextCap; import org.apache.poi.sl.usermodel.TextParagraph.TextAlign; -public class DrawTextParagraph implements Drawable { - protected TextParagraph paragraph; +public class DrawTextParagraph implements Drawable { + protected TextParagraph paragraph; double x, y; protected Insets2D insets = new Insets2D(0,0,0,0); protected List lines = new ArrayList(); @@ -26,7 +26,7 @@ public class DrawTextParagraph implements Drawable { */ protected double maxLineHeight; - public DrawTextParagraph(TextParagraph paragraph) { + public DrawTextParagraph(TextParagraph paragraph) { this.paragraph = paragraph; } @@ -275,7 +275,7 @@ public class DrawTextParagraph implements Drawable { double indent = paragraph.getIndent(); double width; - TextShape ts = paragraph.getParentShape(); + TextShape> ts = paragraph.getParentShape(); if (!ts.getWordWrap()) { // if wordWrap == false then we return the advance to the right border of the sheet width = ts.getSheet().getSlideShow().getPageSize().getWidth() - anchor.getX(); diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextShape.java b/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextShape.java index c71c1082d9..cda6a1a88f 100644 --- a/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextShape.java +++ b/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextShape.java @@ -8,7 +8,7 @@ import java.util.Iterator; import org.apache.poi.sl.usermodel.*; -public class DrawTextShape extends DrawSimpleShape { +public class DrawTextShape> extends DrawSimpleShape { public DrawTextShape(T shape) { super(shape); @@ -84,7 +84,7 @@ public class DrawTextShape extends DrawSimpleShape { Insets2D shapePadding = shape.getInsets(); double y0 = y; - Iterator paragraphs = shape.iterator(); + Iterator paragraphs = shape.iterator(); boolean isFirstLine = true; while (paragraphs.hasNext()){ @@ -129,12 +129,10 @@ public class DrawTextShape extends DrawSimpleShape { /** * Compute the cumulative height occupied by the text */ - protected double getTextHeight(){ + 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(); return drawParagraphs(graphics, 0, 0); } - - } diff --git a/src/scratchpad/src/org/apache/poi/sl/draw/ImageRenderer.java b/src/scratchpad/src/org/apache/poi/sl/draw/ImageRenderer.java index 74ac997ab5..9704c2c0a7 100644 --- a/src/scratchpad/src/org/apache/poi/sl/draw/ImageRenderer.java +++ b/src/scratchpad/src/org/apache/poi/sl/draw/ImageRenderer.java @@ -23,8 +23,7 @@ import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.image.RescaleOp; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import javax.imageio.ImageIO; @@ -73,6 +72,17 @@ public class ImageRenderer { img = ImageIO.read(data); } + /** + * Load and buffer the image + * + * @param data the raw image stream + * @param contentType the content type + */ + public void loadImage(byte data[], String contentType) throws IOException { + img = ImageIO.read(new ByteArrayInputStream(data)); + } + + /** * @return the buffered image */ diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/AutoShape.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/AutoShape.java index 0e0b1dbbe1..21c3a507fd 100644 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/AutoShape.java +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/AutoShape.java @@ -17,6 +17,5 @@ package org.apache.poi.sl.usermodel; -public interface AutoShape extends TextShape { - public TextRun getTextRun(); +public interface AutoShape extends TextShape { } diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/Background.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/Background.java index f67c57b95a..8d868b8600 100644 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/Background.java +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/Background.java @@ -18,5 +18,5 @@ package org.apache.poi.sl.usermodel; public interface Background extends Shape { - + FillStyle getFillStyle(); } diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/FreeformShape.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/FreeformShape.java index 4d2ffb67a1..09d61989df 100644 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/FreeformShape.java +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/FreeformShape.java @@ -17,6 +17,6 @@ package org.apache.poi.sl.usermodel; -public interface FreeformShape extends AutoShape { +public interface FreeformShape extends AutoShape { } diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/GradientPaint.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/GradientPaint.java deleted file mode 100644 index e16b430be3..0000000000 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/GradientPaint.java +++ /dev/null @@ -1,32 +0,0 @@ -/* ==================================================================== - 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 GradientPaint extends PaintStyle { - enum GradientType { linear, circular, shape } - - /** - * @return the angle of the gradient - */ - double getGradientAngle(); - ColorStyle[] getGradientColors(); - float[] getGradientFractions(); - boolean isRotatedWithShape(); - GradientType getGradientType(); -} diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/MasterSheet.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/MasterSheet.java index 61792cd5bb..8ba80156bd 100644 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/MasterSheet.java +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/MasterSheet.java @@ -17,6 +17,6 @@ package org.apache.poi.sl.usermodel; -public interface MasterSheet extends Sheet { +public interface MasterSheet extends Sheet { } diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/Notes.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/Notes.java index 5d5ba98e7e..c16774c298 100644 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/Notes.java +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/Notes.java @@ -17,6 +17,6 @@ package org.apache.poi.sl.usermodel; -public interface Notes extends Sheet { +public interface Notes extends Sheet { public TextRun getTextRun(); } diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/PaintStyle.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/PaintStyle.java index e92e650bbf..9dcd495e40 100644 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/PaintStyle.java +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/PaintStyle.java @@ -17,9 +17,42 @@ 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(); + } } diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/Picture.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/Picture.java deleted file mode 100644 index 9a55313963..0000000000 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/Picture.java +++ /dev/null @@ -1,22 +0,0 @@ -/* ==================================================================== - 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(); -} diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/PictureData.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/PictureData.java index e325e5a8db..8697d33965 100644 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/PictureData.java +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/PictureData.java @@ -17,10 +17,11 @@ 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; } diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/PictureShape.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/PictureShape.java new file mode 100644 index 0000000000..970f04353c --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/PictureShape.java @@ -0,0 +1,29 @@ +/* ==================================================================== + 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(); +} diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/PlaceableShape.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/PlaceableShape.java index 0535536d73..a265e869d7 100644 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/PlaceableShape.java +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/PlaceableShape.java @@ -20,11 +20,17 @@ package org.apache.poi.sl.usermodel; import java.awt.geom.Rectangle2D; public interface PlaceableShape { + /** + * @return the position of this shape within the drawing canvas. + * The coordinates are expressed in points + */ Rectangle2D getAnchor(); - FillStyle getFillStyle(); - - StrokeStyle getStrokeStyle(); + /** + * @param anchor the position of this shape within the drawing canvas. + * The coordinates are expressed in points + */ + void setAnchor(Rectangle2D anchor); /** * Rotation angle in degrees @@ -36,4 +42,41 @@ public interface PlaceableShape { * @return rotation angle in degrees */ double getRotation(); + + /** + * Rotate this shape. + *

+ * Positive angles are clockwise (i.e., towards the positive y axis); + * negative angles are counter-clockwise (i.e., towards the negative y axis). + *

+ * + * @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(); } diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/Shadow.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/Shadow.java index 589f095542..430dbe3840 100644 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/Shadow.java +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/Shadow.java @@ -17,10 +17,13 @@ package org.apache.poi.sl.usermodel; -import java.awt.Color; +import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; + public interface Shadow { + SimpleShape getShadowParent(); + /** * @return the offset of this shadow in points */ @@ -43,5 +46,5 @@ public interface Shadow { * @return the color of this shadow. * Depending whether the parent shape is filled or stroked, this color is used to fill or stroke this shadow */ - Color getColor(); + SolidPaint getFillStyle(); } diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/Shape.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/Shape.java index 02cab6dbb3..6ad149b489 100644 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/Shape.java +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/Shape.java @@ -17,63 +17,16 @@ 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. - *

- * Positive angles are clockwise (i.e., towards the positive y axis); - * negative angles are counter-clockwise (i.e., towards the negative y axis). - *

- * - * @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(); } diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/ShapeContainer.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/ShapeContainer.java index faee9a1b89..11a5039c66 100644 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/ShapeContainer.java +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/ShapeContainer.java @@ -18,7 +18,7 @@ package org.apache.poi.sl.usermodel; -public interface ShapeContainer extends Iterable, PlaceableShape { +public interface ShapeContainer extends Iterable { /** * Returns an array containing all of the elements in this container in proper * sequence (from first to last element). @@ -26,9 +26,9 @@ public interface ShapeContainer extends Iterable, PlaceableShape { * @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 @@ -40,5 +40,5 @@ public interface ShapeContainer extends Iterable, PlaceableShape { * @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); } diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/ShapeGroup.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/ShapeGroup.java index 3c2ff6b8cd..8de1dbcb06 100644 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/ShapeGroup.java +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/ShapeGroup.java @@ -17,6 +17,8 @@ package org.apache.poi.sl.usermodel; -public interface ShapeGroup extends ShapeContainer { +import java.awt.geom.Rectangle2D; +public interface ShapeGroup extends ShapeContainer, PlaceableShape { + Rectangle2D getInteriorAnchor(); } diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/Sheet.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/Sheet.java index 4da90a6a36..64b53a3014 100644 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/Sheet.java +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/Sheet.java @@ -21,7 +21,7 @@ package org.apache.poi.sl.usermodel; /** * Common parent of Slides, Notes and Masters */ -public interface Sheet extends ShapeContainer { +public interface Sheet extends ShapeContainer { SlideShow getSlideShow(); /** @@ -31,7 +31,7 @@ public interface Sheet extends ShapeContainer { */ boolean getFollowMasterGraphics(); - MasterSheet getMasterSheet(); + MasterSheet getMasterSheet(); Background getBackground(); } diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/SimpleShape.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/SimpleShape.java index 7de02dbf62..e4e8efe3a1 100644 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/SimpleShape.java +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/SimpleShape.java @@ -17,14 +17,20 @@ 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); } diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/Slide.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/Slide.java index d3c4af25a4..243d9a8174 100644 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/Slide.java +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/Slide.java @@ -17,9 +17,9 @@ package org.apache.poi.sl.usermodel; -public interface Slide extends Sheet { - public Notes getNotes(); - public void setNotes(Notes notes); +public interface Slide extends Sheet { + public Notes getNotes(); + public void setNotes(Notes notes); public boolean getFollowMasterBackground(); public void setFollowMasterBackground(boolean follow); diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/SolidPaint.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/SolidPaint.java deleted file mode 100644 index dd0225d2d9..0000000000 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/SolidPaint.java +++ /dev/null @@ -1,23 +0,0 @@ -/* ==================================================================== - 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 SolidPaint extends PaintStyle { - ColorStyle getSolidColor(); -} diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/TextBox.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/TextBox.java index 5a88815ee7..9ac61d526a 100644 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/TextBox.java +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/TextBox.java @@ -17,5 +17,5 @@ package org.apache.poi.sl.usermodel; -public interface TextBox extends AutoShape { +public interface TextBox extends AutoShape { } diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/TextParagraph.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/TextParagraph.java index e0c0317edb..348cc703d6 100644 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/TextParagraph.java +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/TextParagraph.java @@ -20,7 +20,7 @@ package org.apache.poi.sl.usermodel; import java.awt.Color; -public interface TextParagraph extends Iterable { +public interface TextParagraph extends Iterable { /** * Specified a list of text alignment types */ @@ -128,5 +128,5 @@ public interface TextParagraph extends Iterable { */ BulletStyle getBulletStyle(); - TextShape getParentShape(); + TextShape> getParentShape(); } diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/TextShape.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/TextShape.java index 68fff47937..f9b1833610 100644 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/TextShape.java +++ b/src/scratchpad/src/org/apache/poi/sl/usermodel/TextShape.java @@ -19,7 +19,7 @@ package org.apache.poi.sl.usermodel; -public interface TextShape extends SimpleShape, Iterable { +public interface TextShape> extends SimpleShape, Iterable { /** * Vertical Text Types */ diff --git a/src/scratchpad/src/org/apache/poi/sl/usermodel/TexturePaint.java b/src/scratchpad/src/org/apache/poi/sl/usermodel/TexturePaint.java deleted file mode 100644 index 135b69b263..0000000000 --- a/src/scratchpad/src/org/apache/poi/sl/usermodel/TexturePaint.java +++ /dev/null @@ -1,37 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.sl.usermodel; - -import java.io.InputStream; - -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(); -} diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestBackground.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestBackground.java index 29bd16f8b7..8838561501 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestBackground.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestBackground.java @@ -60,7 +60,7 @@ public final class TestBackground { 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()); } @@ -71,7 +71,7 @@ public final class TestBackground { public void readBackground() throws Exception { SlideShow ppt = new SlideShow(_slTests.openResourceAsStream("backgrounds.ppt")); Fill fill; - Shape shape; + HSLFShape shape; Slide[] slide = ppt.getSlides(); @@ -104,7 +104,7 @@ public final class TestBackground { SlideShow ppt = new SlideShow(); Slide slide; Fill fill; - Shape shape; + HSLFShape shape; int idx; //slide 1 @@ -202,9 +202,9 @@ public final class TestBackground { } - 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(); @@ -212,7 +212,7 @@ public final class TestBackground { 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 lst = bstore.getChildRecords(); return ((EscherBSERecord)lst.get(idx-1)).getRef(); } diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestOleEmbedding.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestOleEmbedding.java index 8ecb14f7ad..249c4ee964 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestOleEmbedding.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestOleEmbedding.java @@ -64,7 +64,7 @@ public final class TestOleEmbedding extends TestCase { 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){ diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestPPGraphics2D.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestPPGraphics2D.java index b89383c302..b58dbadecf 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestPPGraphics2D.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestPPGraphics2D.java @@ -49,7 +49,7 @@ public final class TestPPGraphics2D extends TestCase { 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); @@ -77,12 +77,12 @@ public final class TestPPGraphics2D extends TestCase { 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); } diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java index 10ff88da6b..700b758a1e 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java @@ -101,7 +101,7 @@ public final class TestShapes { 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 @@ -119,7 +119,7 @@ public final class TestShapes { 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]; @@ -241,7 +241,7 @@ public final class TestShapes { } ArrayList lst2 = new ArrayList(); - 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]; @@ -263,7 +263,7 @@ public final class TestShapes { 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); @@ -288,12 +288,12 @@ public final class TestShapes { 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); @@ -313,7 +313,7 @@ public final class TestShapes { 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++) { @@ -352,7 +352,7 @@ public final class TestShapes { 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(); @@ -401,7 +401,7 @@ public final class TestShapes { @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); diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSheet.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSheet.java index 4bed9ee186..a22e7eb3f9 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSheet.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSheet.java @@ -87,7 +87,7 @@ public final class TestSheet extends TestCase { assertNotNull(txt[i].getSheet()); } - Shape[] shape = sheet.getShapes(); + HSLFShape[] shape = sheet.getShapes(); if (shape == null) { throw new AssertionFailedError("no shapes"); } diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java index e8f246bbd6..480fd8ab65 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTable.java @@ -70,7 +70,7 @@ public final class TestTable extends TestCase { 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()); diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTextRun.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTextRun.java index a82e551994..1b0119307a 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTextRun.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTextRun.java @@ -477,7 +477,7 @@ public final class TestTextRun extends TestCase { 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]; @@ -498,7 +498,7 @@ public final class TestTextRun extends TestCase { 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(); @@ -519,7 +519,7 @@ public final class TestTextRun extends TestCase { 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(); diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTextShape.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTextShape.java index 928f1e4508..542d608d8e 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTextShape.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestTextShape.java @@ -89,7 +89,7 @@ public final class TestTextShape { List lst1 = new ArrayList(); 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]; @@ -157,7 +157,7 @@ public final class TestTextShape { 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]; @@ -177,7 +177,7 @@ public final class TestTextShape { Slide slide = ppt.getSlides()[0]; Map map = new HashMap(); - 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]; @@ -188,28 +188,28 @@ public final class TestTextShape { 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 @@ -217,7 +217,7 @@ public final class TestTextShape { 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]; diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java index 6a2f3229c3..b834792d5f 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java @@ -51,8 +51,8 @@ import org.apache.poi.hslf.model.HeadersFooters; 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; @@ -165,11 +165,11 @@ public final class TestBugs { 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]; @@ -188,12 +188,12 @@ public final class TestBugs { 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()); } @@ -233,7 +233,7 @@ public final class TestBugs { 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); @@ -250,12 +250,12 @@ public final class TestBugs { //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()); } @@ -277,20 +277,20 @@ public final class TestBugs { 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(); @@ -355,7 +355,7 @@ public final class TestBugs { // Check the shape based text runs List lst = new ArrayList(); - 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(); @@ -413,7 +413,7 @@ public final class TestBugs { 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]; @@ -492,7 +492,7 @@ public final class TestBugs { // 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 @@ -595,7 +595,7 @@ public final class TestBugs { 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); @@ -640,7 +640,7 @@ public final class TestBugs { 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 }, diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java index 45d0390a74..ff25f34aa1 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java @@ -34,7 +34,7 @@ import org.apache.poi.hslf.blip.PICT; import org.apache.poi.hslf.blip.PNG; import org.apache.poi.hslf.blip.WMF; import org.apache.poi.hslf.model.Picture; -import org.apache.poi.hslf.model.Shape; +import org.apache.poi.hslf.model.HSLFShape; import org.apache.poi.hslf.model.Slide; /** @@ -68,7 +68,7 @@ public final class TestPictures extends TestCase{ 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()); @@ -113,7 +113,7 @@ public final class TestPictures extends TestCase{ 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()); @@ -159,7 +159,7 @@ public final class TestPictures extends TestCase{ 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()); @@ -198,7 +198,7 @@ public final class TestPictures extends TestCase{ 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()); @@ -238,7 +238,7 @@ public final class TestPictures extends TestCase{ 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()); @@ -277,7 +277,7 @@ public final class TestPictures extends TestCase{ 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()); diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTable.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTable.java index 0851ff4be1..24d5d6f554 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTable.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestTable.java @@ -21,7 +21,7 @@ package org.apache.poi.hslf.usermodel; 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; @@ -58,7 +58,7 @@ public final class TestTable extends TestCase { 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);