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
This commit is contained in:
Andreas Beeker 2015-03-07 23:35:40 +00:00
parent 996c9dd93c
commit a0070048fe
112 changed files with 1460 additions and 2370 deletions

View File

@ -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);

View File

@ -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];

View File

@ -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);

View File

@ -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) {

View File

@ -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();

View File

@ -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<T> extends PropertyFetcher<T> {
_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' " +

View File

@ -36,7 +36,7 @@ public abstract class PropertyFetcher<T> {
* @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;

View File

@ -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<T> extends PropertyFetcher<T> {
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' " +

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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:
* <code>
* 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
* </code>
*
* @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<CTGradientStop>() {
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<CTGradientStop>() {
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<CTGradientStop>() {
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<Paint> fetcher = new PropertyFetcher<Paint>() {
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<Paint> fetcher = new PropertyFetcher<Paint>() {
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<Outline> 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<Outline> computeOutlines(Graphics2D graphics) {
Collection<Outline> lst = new ArrayList<Outline>();
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;
}
}

View File

@ -496,11 +496,11 @@ public class XMLSlideShow extends POIXMLDocument implements SlideShow {
return null;
}
public MasterSheet<XSLFShape>[] getMasterSheet() {
public XSLFSlideMaster[] getMasterSheet() {
return getSlideMasters();
}
public MasterSheet<XSLFShape> createMasterSheet() throws IOException {
public MasterSheet createMasterSheet() throws IOException {
// TODO: implement!
throw new UnsupportedOperationException();
}

View File

@ -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<XSLFTextParagraph> {
/*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();

View File

@ -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();
}
}

View File

@ -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);

View File

@ -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<XSLFShape> _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<PackagePart> pics = _sheet.getPackagePart().getPackage()
List<PackagePart> 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");
}
}

View File

@ -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();
}
}

View File

@ -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);

View File

@ -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;
}
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();
}
};
}
}

View File

@ -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.
* <p>
* Positive angles are clockwise (i.e., towards the positive y axis);
* negative angles are counter-clockwise (i.e., towards the negative y axis).
* </p>
*
* @param theta the rotation angle in degrees.
*/
public abstract void setRotation(double theta);
/**
* Rotation angle in degrees
* <p>
* Positive angles are clockwise (i.e., towards the positive y axis);
* negative angles are counter-clockwise (i.e., towards the negative y axis).
* </p>
*
* @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<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {
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<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {
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 extends XmlObject> T selectProperty(Class<T> 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];
}
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 _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.");
}
return _spPr;
}
CTTransform2D getXfrm() {
PropertyFetcher<CTTransform2D> fetcher = new PropertyFetcher<CTTransform2D>() {
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();
}
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 String getContentType() {
/* TOOD: map content-type */
return getPart().getContentType();
}
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();
Arrays.sort(gs, new Comparator<CTGradientStop>() {
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];
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;
}
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);
return new GradientPaint() {
public double getGradientAngle() {
return (gradFill.isSetLin())
? gradFill.getLin().getAng() / 60000.d
: 0;
}
public ColorStyle[] getGradientColors() {
return cs;
}
public float[] getGradientFractions() {
return fractions;
}
public boolean isRotatedWithShape() {
// TODO: is this correct???
return (gradFill.isSetRotWithShape() || !gradFill.getRotWithShape());
}
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;
}
}
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 int getAlpha() {
return (blip.sizeOfAlphaModFixArray() > 0)
? blip.getAlphaModFixArray(0).getAmt()
: 0;
}
};
}
if (obj instanceof CTGradientFillProperties) {
final CTGradientFillProperties gradFill = (CTGradientFillProperties) obj;
@SuppressWarnings("deprecation")
final CTGradientStop[] gs = gradFill.getGsLst().getGsArray();
Arrays.sort(gs, new Comparator<CTGradientStop>() {
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;
return GradientType.linear;
}
return new GradientPaint() {
public double getGradientAngle() {
return (gradFill.isSetLin())
? gradFill.getLin().getAng() / 60000.d
: 0;
}
public ColorStyle[] getGradientColors() {
return cs;
}
public float[] getGradientFractions() {
return fractions;
}
public boolean isRotatedWithShape() {
// TODO: is this correct???
return (gradFill.isSetRotWithShape() || !gradFill.getRotWithShape());
}
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;
}
}
return GradientType.linear;
}
};
}
return TRANSPARENT_PAINT;
};
}
}

View File

@ -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<XSLFShape> {
/**
* create a new shape with a predefined geometry and add it to this shape container

View File

@ -16,47 +16,28 @@
==================================================================== */
package org.apache.poi.xslf.usermodel;
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.sl.usermodel.Sheet;
import org.apache.poi.util.Beta;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Internal;
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 java.awt.Graphics2D;
import java.io.*;
import java.util.*;
import java.util.regex.Pattern;
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.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
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.*;
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.*;
@Beta
public abstract class XSLFSheet extends POIXMLDocumentPart implements XSLFShapeContainer, Sheet {
public abstract class XSLFSheet extends POIXMLDocumentPart implements XSLFShapeContainer, Sheet<XSLFShape> {
private XSLFCommonSlideData _commonSlideData;
private XSLFDrawing _drawing;
private List<XSLFShape> _shapes;
@ -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);
}
/**

View File

@ -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);
}
@Override
public String getShapeName() {
return getNvPr().getName();
protected CTTransform2D getSafeXfrm() {
CTTransform2D xfrm = getXfrm();
return (xfrm == null ? getSpPr().addNewXfrm() : xfrm);
}
protected CTTransform2D getXfrm() {
PropertyFetcher<CTTransform2D> fetcher = new PropertyFetcher<CTTransform2D>() {
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 int getShapeId() {
return (int) getNvPr().getId();
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 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<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {
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. <code>0</code> 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<Outline> getDecorationOutlines(Graphics2D graphics){
List<Outline> lst = new ArrayList<Outline>();
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
return null;
}
public void setHyperlink(Hyperlink hyperlink) {
// TODO Auto-generated method stub
}
@SuppressWarnings("deprecation")
public Guide getAdjustValue(String name) {
// TODO Auto-generated method stub
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 org.apache.poi.sl.usermodel.LineDecoration getLineDecoration() {
// TODO Auto-generated method stub
return null;
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();
}
};
}
/**
* 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 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();
}
};
}
}

View File

@ -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<XSLFShape> {
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);

View File

@ -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<XSLFShape> {
private CTSlideLayout _layout;
private XSLFSlideMaster _master;

View File

@ -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<XSLFShape> {
private CTSlideMaster _slide;
private Map<String, XSLFSlideLayout> _layouts;
private XSLFTheme _theme;

View File

@ -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();
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;
}
}
private void setBorderWidth(char bltr, double width) {
CTLineProperties ln = getCTLine(bltr, true);
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());
private double getBorderWidth(char bltr) {
CTLineProperties ln = getCTLine(bltr, false);
return (ln == null) ? 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);
}
private void setBorderColor(char bltr, Color color) {
CTLineProperties ln = getCTLine(bltr, true);
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());
}
public void setBorderBottom(double width){
CTTableCellProperties pr = getXmlObject().getTcPr();
CTLineProperties ln = pr.isSetLnB() ? pr.getLnB() : pr.addNewLnB();
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());
}
public void setBorderBottomColor(Color color){
CTTableCellProperties pr = getXmlObject().getTcPr();
CTLineProperties ln = pr.isSetLnB() ? pr.getLnB() : pr.addNewLnB();
setLineColor(ln, color);
}
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()) {

View File

@ -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<XSLFTextRun> {
private final CTTextParagraph _p;
private final List<XSLFTextRun> _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();

View File

@ -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<XSLFTextParagraph> {
private final List<XSLFTextParagraph> _paragraphs;
/**
* whether the text was broken into lines.
*/
private boolean _isTextBroken;
@SuppressWarnings("deprecation")
/*package*/ XSLFTextShape(XmlObject shape, XSLFSheet sheet) {
super(shape, sheet);
@ -66,7 +55,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape implements TextShape
}
public Iterator<XSLFTextParagraph> 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<XSLFTextShape> 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;
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -65,7 +65,7 @@ public final class ActiveXShape extends Picture {
* this picture in the <code>Slide</code>
* @param parent the parent shape of this picture
*/
protected ActiveXShape(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
protected ActiveXShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}

View File

@ -35,13 +35,13 @@ import java.awt.geom.Rectangle2D;
*/
public class AutoShape extends TextShape {
protected AutoShape(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
protected AutoShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
public AutoShape(ShapeType type, ShapeContainer<Shape> parent){
public AutoShape(ShapeType type, ShapeContainer<HSLFShape> parent){
super(null, parent);
_escherContainer = createSpContainer(type, parent instanceof ShapeGroup);
_escherContainer = createSpContainer(type, parent instanceof HSLFGroupShape);
}
public AutoShape(ShapeType type){

View File

@ -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);
}
};

View File

@ -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<Shape> parent) {
protected Background(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent) {
super(escherRecord, parent);
}

View File

@ -98,7 +98,7 @@ public final class Fill {
/**
* The shape this background applies to
*/
protected Shape shape;
protected HSLFShape shape;
/**
* Construct a <code>Fill</code> 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<EscherRecord> 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);

View File

@ -62,7 +62,7 @@ public final class Freeform extends AutoShape {
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
* @param parent the parent of the shape
*/
protected Freeform(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
protected Freeform(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
@ -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<Shape> parent){
public Freeform(ShapeContainer<HSLFShape> parent){
super((EscherContainerRecord)null, parent);
_escherContainer = createSpContainer(ShapeType.NOT_PRIMITIVE, parent instanceof ShapeGroup);
_escherContainer = createSpContainer(ShapeType.NOT_PRIMITIVE, parent instanceof HSLFGroupShape);
}
/**

View File

@ -40,13 +40,13 @@ import org.apache.poi.util.POILogger;
*
* @author Yegor Kozlov
*/
public class ShapeGroup extends Shape implements ShapeContainer<Shape> {
public class HSLFGroupShape extends HSLFShape implements ShapeContainer<HSLFShape> {
/**
* Create a new ShapeGroup. This constructor is used when a new shape is created.
*
*/
public ShapeGroup(){
public HSLFGroupShape(){
this(null, null);
_escherContainer = createSpContainer(false);
}
@ -57,16 +57,16 @@ public class ShapeGroup extends Shape implements ShapeContainer<Shape> {
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
* @param parent the parent of the shape
*/
protected ShapeGroup(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
protected HSLFGroupShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
/**
* @return the shapes contained in this group container
*/
public Shape[] getShapes() {
List<Shape> shapeList = getShapeList();
Shape[] shapes = shapeList.toArray(new Shape[shapeList.size()]);
public HSLFShape[] getShapes() {
List<HSLFShape> shapeList = getShapeList();
HSLFShape[] shapes = shapeList.toArray(new HSLFShape[shapeList.size()]);
return shapes;
}
@ -174,7 +174,7 @@ public class ShapeGroup extends Shape implements ShapeContainer<Shape> {
*
* @param shape - the Shape to add
*/
public void addShape(Shape shape){
public void addShape(HSLFShape shape){
_escherContainer.addChildRecord(shape.getSpContainer());
Sheet sheet = getSheet();
@ -196,7 +196,7 @@ public class ShapeGroup extends Shape implements ShapeContainer<Shape> {
anchor.translate(dx, dy);
setAnchor(anchor);
Shape[] shape = getShapes();
HSLFShape[] shape = getShapes();
for (int i = 0; i < shape.length; i++) {
java.awt.Rectangle chanchor = shape[i].getAnchor();
chanchor.translate(dx, dy);
@ -257,7 +257,7 @@ public class ShapeGroup extends Shape implements ShapeContainer<Shape> {
AffineTransform at = graphics.getTransform();
Shape[] sh = getShapes();
HSLFShape[] sh = getShapes();
for (int i = 0; i < sh.length; i++) {
sh[i].draw(graphics);
}
@ -271,11 +271,11 @@ public class ShapeGroup extends Shape implements ShapeContainer<Shape> {
return groupInfoContainer.getChildById((short)recordId);
}
public Iterator<Shape> iterator() {
public Iterator<HSLFShape> iterator() {
return getShapeList().iterator();
}
public boolean removeShape(Shape shape) {
public boolean removeShape(HSLFShape shape) {
// TODO: implement!
throw new UnsupportedOperationException();
}
@ -283,7 +283,7 @@ public class ShapeGroup extends Shape implements ShapeContainer<Shape> {
/**
* @return the shapes contained in this group container
*/
protected List<Shape> getShapeList() {
protected List<HSLFShape> getShapeList() {
// Out escher container record should contain several
// SpContainers, the first of which is the group shape itself
Iterator<EscherRecord> iter = _escherContainer.getChildIterator();
@ -292,13 +292,13 @@ public class ShapeGroup extends Shape implements ShapeContainer<Shape> {
if (iter.hasNext()) {
iter.next();
}
List<Shape> shapeList = new ArrayList<Shape>();
List<HSLFShape> shapeList = new ArrayList<HSLFShape>();
while (iter.hasNext()) {
EscherRecord r = iter.next();
if(r instanceof EscherContainerRecord) {
// Create the Shape for it
EscherContainerRecord container = (EscherContainerRecord)r;
Shape shape = ShapeFactory.createShape(container, this);
HSLFShape shape = ShapeFactory.createShape(container, this);
shape.setSheet(getSheet());
shapeList.add( shape );
} else {

View File

@ -45,7 +45,7 @@ import java.awt.geom.Rectangle2D;
*
* @author Yegor Kozlov
*/
public abstract class Shape implements org.apache.poi.sl.usermodel.Shape<Shape> {
public abstract class HSLFShape implements org.apache.poi.sl.usermodel.Shape<HSLFShape> {
// For logging
protected POILogger logger = POILogFactory.getLogger(this.getClass());
@ -85,7 +85,7 @@ public abstract class Shape implements org.apache.poi.sl.usermodel.Shape<Shape>
* Parent of this shape.
* <code>null</code> for the topmost shapes.
*/
protected ShapeContainer<Shape> _parent;
protected ShapeContainer<HSLFShape> _parent;
/**
* The <code>Sheet</code> this shape belongs to
@ -103,7 +103,7 @@ public abstract class Shape implements org.apache.poi.sl.usermodel.Shape<Shape>
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
* @param parent the parent of this Shape
*/
protected Shape(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
protected HSLFShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
_escherContainer = escherRecord;
_parent = parent;
}
@ -116,7 +116,7 @@ public abstract class Shape implements org.apache.poi.sl.usermodel.Shape<Shape>
/**
* @return the parent of this shape
*/
public ShapeContainer<Shape> getParent(){
public ShapeContainer<HSLFShape> getParent(){
return _parent;
}

View File

@ -176,7 +176,7 @@ public final class Hyperlink {
* @param shape <code>Shape</code> to lookup hyperlink in
* @return found hyperlink or <code>null</code>
*/
protected static Hyperlink find(Shape shape){
protected static Hyperlink find(HSLFShape shape){
List<Hyperlink> lst = new ArrayList<Hyperlink>();
SlideShow ppt = shape.getSheet().getSlideShow();
//document-level container which stores info about all links in a presentation

View File

@ -97,13 +97,13 @@ public final class Line extends SimpleShape {
public static final int LINE_TRIPLE = 4;
protected Line(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
protected Line(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
public Line(ShapeContainer<Shape> parent){
public Line(ShapeContainer<HSLFShape> parent){
super(null, parent);
_escherContainer = createSpContainer(parent instanceof ShapeGroup);
_escherContainer = createSpContainer(parent instanceof HSLFGroupShape);
}
public Line(){

View File

@ -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;

View File

@ -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<Shape> parent) {
public MovieShape(int movieIdx, int idx, ShapeContainer<HSLFShape> parent) {
super(idx, parent);
setMovieIndex(movieIdx);
}
@ -67,7 +67,7 @@ public final class MovieShape extends Picture {
* this picture in the <code>Slide</code>
* @param parent the parent shape of this picture
*/
protected MovieShape(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
protected MovieShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}

View File

@ -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<Shape> parent) {
public OLEShape(int idx, ShapeContainer<HSLFShape> parent) {
super(idx, parent);
}
@ -63,7 +63,7 @@ public final class OLEShape extends Picture {
* this picture in the <code>Slide</code>
* @param parent the parent shape of this picture
*/
protected OLEShape(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
protected OLEShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}

View File

@ -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;
}

View File

@ -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<Shape> parent) {
public Picture(int idx, ShapeContainer<HSLFShape> 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 <code>Slide</code>
* @param parent the parent shape of this picture
*/
protected Picture(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
protected Picture(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
@ -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;

View File

@ -31,11 +31,11 @@ import java.io.ByteArrayOutputStream;
*/
public final class Placeholder extends TextBox {
protected Placeholder(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
protected Placeholder(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
public Placeholder(ShapeContainer<Shape> parent){
public Placeholder(ShapeContainer<HSLFShape> parent){
super(parent);
}

View File

@ -36,7 +36,7 @@ public final class Polygon extends AutoShape {
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
* @param parent the parent of the shape
*/
protected Polygon(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
protected Polygon(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
@ -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<Shape> parent){
public Polygon(ShapeContainer<HSLFShape> parent){
super((EscherContainerRecord)null, parent);
_escherContainer = createSpContainer(ShapeType.NOT_PRIMITIVE, parent instanceof ShapeGroup);
_escherContainer = createSpContainer(ShapeType.NOT_PRIMITIVE, parent instanceof HSLFGroupShape);
}
/**

View File

@ -51,16 +51,16 @@ public final class ShapeFactory {
/**
* Create a new shape from the data provided.
*/
public static Shape createShape(EscherContainerRecord spContainer, ShapeContainer<Shape> parent){
public static HSLFShape createShape(EscherContainerRecord spContainer, ShapeContainer<HSLFShape> parent){
if (spContainer.getRecordId() == EscherContainerRecord.SPGR_CONTAINER){
return createShapeGroup(spContainer, parent);
}
return createSimpeShape(spContainer, parent);
}
public static ShapeGroup createShapeGroup(EscherContainerRecord spContainer, ShapeContainer<Shape> parent){
ShapeGroup group = null;
EscherRecord opt = Shape.getEscherChild((EscherContainerRecord)spContainer.getChild(0), (short)0xF122);
public static HSLFGroupShape createShapeGroup(EscherContainerRecord spContainer, ShapeContainer<HSLFShape> parent){
HSLFGroupShape group = null;
EscherRecord opt = HSLFShape.getEscherChild((EscherContainerRecord)spContainer.getChild(0), (short)0xF122);
if(opt != null){
try {
EscherPropertyFactory f = new EscherPropertyFactory();
@ -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<Shape> parent){
Shape shape = null;
public static HSLFShape createSimpeShape(EscherContainerRecord spContainer, ShapeContainer<HSLFShape> parent){
HSLFShape shape = null;
EscherSpRecord spRecord = spContainer.getChildById(EscherSpRecord.RECORD_ID);
ShapeType type = ShapeType.forId(spRecord.getShapeType(), false);
@ -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 {

View File

@ -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);
}

View File

@ -57,7 +57,7 @@ import org.apache.poi.util.POILogger;
* @author Yegor Kozlov
*/
public abstract class Sheet implements ShapeContainer<Shape> {
public abstract class Sheet implements ShapeContainer<HSLFShape> {
private static POILogger logger = POILogFactory.getLogger(Sheet.class);
/**
@ -272,9 +272,9 @@ public abstract class Sheet implements ShapeContainer<Shape> {
*
* @return all shapes contained in this Sheet (Slide or Notes)
*/
public Shape[] getShapes() {
List<Shape> shapeList = getShapeList();
return shapeList.toArray(new Shape[shapeList.size()]);
public HSLFShape[] getShapes() {
List<HSLFShape> shapeList = getShapeList();
return shapeList.toArray(new HSLFShape[shapeList.size()]);
}
/**
@ -282,11 +282,11 @@ public abstract class Sheet implements ShapeContainer<Shape> {
*
* @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<Shape> {
* @param shape shape to be removed from this sheet, if present.
* @return <tt>true</tt> if the shape was deleted.
*/
public boolean removeShape(Shape shape) {
public boolean removeShape(HSLFShape shape) {
PPDrawing ppdrawing = getPPDrawing();
EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
@ -427,7 +427,7 @@ public abstract class Sheet implements ShapeContainer<Shape> {
* @return <code>TextShape</code> or <code>null</code>
*/
public TextShape getPlaceholderByTextType(int type){
Shape[] shape = getShapes();
HSLFShape[] shape = getShapes();
for (int i = 0; i < shape.length; i++) {
if(shape[i] instanceof TextShape){
TextShape tx = (TextShape)shape[i];
@ -447,7 +447,7 @@ public abstract class Sheet implements ShapeContainer<Shape> {
* @return <code>TextShape</code> or <code>null</code>
*/
public TextShape getPlaceholder(int type){
Shape[] shape = getShapes();
HSLFShape[] shape = getShapes();
for (int i = 0; i < shape.length; i++) {
if(shape[i] instanceof TextShape){
TextShape tx = (TextShape)shape[i];
@ -497,7 +497,7 @@ public abstract class Sheet implements ShapeContainer<Shape> {
}
public Iterator<Shape> iterator() {
public Iterator<HSLFShape> iterator() {
return getShapeList().iterator();
}
@ -507,7 +507,7 @@ public abstract class Sheet implements ShapeContainer<Shape> {
*
* @return all shapes contained in this Sheet (Slide or Notes)
*/
protected List<Shape> getShapeList() {
protected List<HSLFShape> getShapeList() {
PPDrawing ppdrawing = getPPDrawing();
EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
@ -524,7 +524,7 @@ public abstract class Sheet implements ShapeContainer<Shape> {
throw new IllegalStateException("spgr not found");
}
List<Shape> shapeList = new ArrayList<Shape>();
List<HSLFShape> shapeList = new ArrayList<HSLFShape>();
Iterator<EscherRecord> it = spgr.getChildIterator();
if (it.hasNext()) {
// skip first item
@ -532,7 +532,7 @@ public abstract class Sheet implements ShapeContainer<Shape> {
}
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);
}

View File

@ -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 <code>EscherSpContainer</code> container which holds information about this shape
* @param parent the parent of the shape
*/
protected SimpleShape(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
protected SimpleShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
@ -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<ShapeGroup> lst = new ArrayList<ShapeGroup>();
for (ShapeContainer<Shape> parent=this.getParent();
parent instanceof ShapeGroup;
parent = ((ShapeGroup)parent).getParent()) {
lst.add(0, (ShapeGroup)parent);
ArrayList<HSLFGroupShape> lst = new ArrayList<HSLFGroupShape>();
for (ShapeContainer<HSLFShape> parent=this.getParent();
parent instanceof HSLFGroupShape;
parent = ((HSLFGroupShape)parent).getParent()) {
lst.add(0, (HSLFGroupShape)parent);
}
AffineTransform tx = new AffineTransform();
for(ShapeGroup prnt : lst) {
for(HSLFGroupShape prnt : lst) {
Rectangle2D exterior = prnt.getAnchor2D();
Rectangle2D interior = prnt.getCoordinates();

View File

@ -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);
}

View File

@ -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 <code>EscherSpContainer</code> container which holds information about this shape
* @param parent the parent of the shape
*/
public Table(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent) {
public Table(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent) {
super(escherRecord, parent);
}
@ -150,9 +150,9 @@ public final class Table extends ShapeGroup {
}
protected void initTable(){
List<Shape> shapeList = getShapeList();
Collections.sort(shapeList, new Comparator<Shape>(){
public int compare( Shape o1, Shape o2 ) {
List<HSLFShape> shapeList = getShapeList();
Collections.sort(shapeList, new Comparator<HSLFShape>(){
public int compare( HSLFShape o1, HSLFShape o2 ) {
Rectangle anchor1 = o1.getAnchor();
Rectangle anchor2 = o2.getAnchor();
int delta = anchor1.y - anchor2.y;
@ -162,14 +162,14 @@ public final class Table extends ShapeGroup {
});
int y0 = -1;
int maxrowlen = 0;
List<List<Shape>> lst = new ArrayList<List<Shape>>();
List<Shape> row = null;
for (Shape sh : shapeList) {
List<List<HSLFShape>> lst = new ArrayList<List<HSLFShape>>();
List<HSLFShape> row = null;
for (HSLFShape sh : shapeList) {
if(sh instanceof TextShape){
Rectangle anchor = sh.getAnchor();
if(anchor.y != y0){
y0 = anchor.y;
row = new ArrayList<Shape>();
row = new ArrayList<HSLFShape>();
lst.add(row);
}
row.add(sh);

View File

@ -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<Shape> parent){
protected TableCell(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> 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<Shape> parent){
public TableCell(ShapeContainer<HSLFShape> parent){
super(parent);
setShapeType(ShapeType.RECT);

View File

@ -38,7 +38,7 @@ public class TextBox extends TextShape {
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
* @param parent the parent of the shape
*/
protected TextBox(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
protected TextBox(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
@ -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<Shape> parent){
public TextBox(ShapeContainer<HSLFShape> parent){
super(parent);
}

View File

@ -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;
}

View File

@ -111,7 +111,7 @@ public abstract class TextShape extends SimpleShape {
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
* @param parent the parent of the shape
*/
protected TextShape(EscherContainerRecord escherRecord, ShapeContainer<Shape> parent){
protected TextShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape> parent){
super(escherRecord, parent);
}
@ -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<Shape> parent){
public TextShape(ShapeContainer<HSLFShape> parent){
super(null, parent);
_escherContainer = createSpContainer(parent instanceof ShapeGroup);
_escherContainer = createSpContainer(parent instanceof HSLFGroupShape);
}
/**

View File

@ -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;
}
/**

View File

@ -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();

View File

@ -3,7 +3,7 @@ package org.apache.poi.sl.draw;
import org.apache.poi.sl.usermodel.*;
public class DrawAutoShape<T extends AutoShape> extends DrawTextShape<T> {
public class DrawAutoShape<T extends AutoShape<? extends TextParagraph>> extends DrawTextShape<T> {
public DrawAutoShape(T shape) {
super(shape);
}

View File

@ -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<T extends Background> extends DrawShape<T> {
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);
}
}
}

View File

@ -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<? extends TextParagraph<? extends TextRun>>)shape);
} else if (shape instanceof FreeformShape) {
return getDrawable((FreeformShape)shape);
return getDrawable((FreeformShape<? extends TextParagraph<? extends TextRun>>)shape);
} else if (shape instanceof TextShape) {
return getDrawable((TextShape<? extends TextParagraph<? extends TextRun>>)shape);
} else if (shape instanceof ShapeGroup) {
return getDrawable((ShapeGroup<? extends Shape>)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<? extends Shape>)shape);
} else if (shape instanceof MasterSheet) {
return getDrawable((MasterSheet<? extends Shape>)shape);
} else if (shape instanceof Sheet) {
return getDrawable((Sheet<? extends Shape>)shape);
}
throw new IllegalArgumentException("Unsupported shape type: "+shape.getClass());
}
public <T extends TextBox> DrawTextBox<T> getDrawable(T shape) {
public <T extends Slide<? extends Shape>> DrawSlide<T> getDrawable(T sheet) {
return new DrawSlide<T>(sheet);
}
public <T extends Sheet<? extends Shape>> DrawSheet<T> getDrawable(T sheet) {
return new DrawSheet<T>(sheet);
}
public <T extends MasterSheet<? extends Shape>> DrawMasterSheet<T> getDrawable(T sheet) {
return new DrawMasterSheet<T>(sheet);
}
public <T extends TextBox<? extends TextParagraph<?>>> DrawTextBox<T> getDrawable(T shape) {
return new DrawTextBox<T>(shape);
}
public <T extends FreeformShape> DrawFreeformShape<T> getDrawable(T shape) {
public <T extends FreeformShape<? extends TextParagraph<? extends TextRun>>> DrawFreeformShape<T> getDrawable(T shape) {
return new DrawFreeformShape<T>(shape);
}
public DrawTextParagraph getDrawable(TextParagraph paragraph) {
return new DrawTextParagraph(paragraph);
public <T extends TextShape<? extends TextParagraph<? extends TextRun>>> DrawTextShape<T> getDrawable(T shape) {
return new DrawTextShape<T>(shape);
}
public <T extends ShapeGroup<? extends Shape>> DrawShapeGroup<T> getDrawable(T shape) {
return new DrawShapeGroup<T>(shape);
}
public <T extends PictureShape> DrawPictureShape<T> getDrawable(T shape) {
return new DrawPictureShape<T>(shape);
}
public <T extends TextRun> DrawTextParagraph<T> getDrawable(TextParagraph<T> paragraph) {
return new DrawTextParagraph<T>(paragraph);
}
public <T extends Background> DrawBackground<T> getDrawable(T shape) {
return new DrawBackground<T>(shape);
}
public DrawTextFragment getTextFragment(TextLayout layout, AttributedString str) {
return new DrawTextFragment(layout, str);
}

View File

@ -2,7 +2,7 @@ package org.apache.poi.sl.draw;
import org.apache.poi.sl.usermodel.*;
public class DrawFreeformShape<T extends FreeformShape> extends DrawAutoShape<T> {
public class DrawFreeformShape<T extends FreeformShape<? extends TextParagraph<? extends TextRun>>> extends DrawAutoShape<T> {
public DrawFreeformShape(T shape) {
super(shape);
}

View File

@ -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<T extends MasterSheet<? extends Shape>> extends DrawSheet<T> {
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();
}
}

View File

@ -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());
}

View File

@ -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<T extends PictureShape> extends DrawSimpleShape<T> {
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);
}
}
}

View File

@ -22,14 +22,17 @@ public class DrawShape<T extends Shape> 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<T extends Shape> 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<T extends Shape> 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<T extends Shape> 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;
}

View File

@ -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<T extends ShapeGroup<? extends Shape>> 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) {
}
}

View File

@ -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<T extends Sheet<? extends Shape>> 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<? extends Shape> master = sheet.getMasterSheet();
if(sheet.getFollowMasterGraphics() && master != null) {
Drawable drawer = drawFact.getDrawable(master);

View File

@ -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<T extends SimpleShape> extends DrawShape<T> {
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<T extends SimpleShape> extends DrawShape<T> {
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);
}
}

View File

@ -0,0 +1,24 @@
package org.apache.poi.sl.draw;
import java.awt.Graphics2D;
import org.apache.poi.sl.usermodel.*;
public class DrawSlide<T extends Slide<? extends Shape>> extends DrawSheet<T> {
public DrawSlide(T slide) {
super(slide);
}
public void draw(Graphics2D graphics) {
Background bg = sheet.getBackground();
if(bg != null) {
DrawFactory drawFact = DrawFactory.getInstance(graphics);
DrawBackground<Background> db = drawFact.getDrawable(bg);
db.draw(graphics);
}
super.draw(graphics);
}
}

View File

@ -2,7 +2,7 @@ package org.apache.poi.sl.draw;
import org.apache.poi.sl.usermodel.*;
public class DrawTextBox<T extends TextBox> extends DrawAutoShape<T> {
public class DrawTextBox<T extends TextBox<? extends TextParagraph<? extends TextRun>>> extends DrawAutoShape<T> {
public DrawTextBox(T shape) {
super(shape);
}

View File

@ -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<T extends TextRun> implements Drawable {
protected TextParagraph<T> paragraph;
double x, y;
protected Insets2D insets = new Insets2D(0,0,0,0);
protected List<DrawTextFragment> lines = new ArrayList<DrawTextFragment>();
@ -26,7 +26,7 @@ public class DrawTextParagraph implements Drawable {
*/
protected double maxLineHeight;
public DrawTextParagraph(TextParagraph paragraph) {
public DrawTextParagraph(TextParagraph<T> paragraph) {
this.paragraph = paragraph;
}
@ -275,7 +275,7 @@ public class DrawTextParagraph implements Drawable {
double indent = paragraph.getIndent();
double width;
TextShape ts = paragraph.getParentShape();
TextShape<? extends TextParagraph<T>> 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();

View File

@ -8,7 +8,7 @@ import java.util.Iterator;
import org.apache.poi.sl.usermodel.*;
public class DrawTextShape<T extends TextShape> extends DrawSimpleShape<T> {
public class DrawTextShape<T extends TextShape<? extends TextParagraph>> extends DrawSimpleShape<T> {
public DrawTextShape(T shape) {
super(shape);
@ -84,7 +84,7 @@ public class DrawTextShape<T extends TextShape> extends DrawSimpleShape<T> {
Insets2D shapePadding = shape.getInsets();
double y0 = y;
Iterator<TextParagraph> paragraphs = shape.iterator();
Iterator<? extends TextParagraph> paragraphs = shape.iterator();
boolean isFirstLine = true;
while (paragraphs.hasNext()){
@ -129,12 +129,10 @@ public class DrawTextShape<T extends TextShape> extends DrawSimpleShape<T> {
/**
* 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);
}
}

View File

@ -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
*/

View File

@ -17,6 +17,5 @@
package org.apache.poi.sl.usermodel;
public interface AutoShape extends TextShape {
public TextRun getTextRun();
public interface AutoShape<T extends TextParagraph> extends TextShape<T> {
}

View File

@ -18,5 +18,5 @@
package org.apache.poi.sl.usermodel;
public interface Background extends Shape {
FillStyle getFillStyle();
}

View File

@ -17,6 +17,6 @@
package org.apache.poi.sl.usermodel;
public interface FreeformShape extends AutoShape {
public interface FreeformShape<T extends TextParagraph> extends AutoShape<T> {
}

View File

@ -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();
}

View File

@ -17,6 +17,6 @@
package org.apache.poi.sl.usermodel;
public interface MasterSheet extends Sheet {
public interface MasterSheet<T extends Shape> extends Sheet<T> {
}

View File

@ -17,6 +17,6 @@
package org.apache.poi.sl.usermodel;
public interface Notes extends Sheet {
public interface Notes<T extends Shape> extends Sheet<T> {
public TextRun getTextRun();
}

View File

@ -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();
}
}

View File

@ -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();
}

View File

@ -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;
}

View File

@ -1,23 +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;
public interface SolidPaint extends PaintStyle {
ColorStyle getSolidColor();
}
/* ====================================================================
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();
}

View File

@ -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.
* <p>
* Positive angles are clockwise (i.e., towards the positive y axis);
* negative angles are counter-clockwise (i.e., towards the negative y axis).
* </p>
*
* @param theta the rotation angle in degrees.
*/
void setRotation(double theta);
/**
* @param flip whether the shape is horizontally flipped
*/
void setFlipHorizontal(boolean flip);
/**
* Whether the shape is vertically flipped
*
* @param flip whether the shape is vertically flipped
*/
void setFlipVertical(boolean flip);
/**
* Whether the shape is horizontally flipped
*
* @return whether the shape is horizontally flipped
*/
boolean getFlipHorizontal();
/**
* Whether the shape is vertically flipped
*
* @return whether the shape is vertically flipped
*/
boolean getFlipVertical();
}

View File

@ -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();
}

View File

@ -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.
* <p>
* Positive angles are clockwise (i.e., towards the positive y axis);
* negative angles are counter-clockwise (i.e., towards the negative y axis).
* </p>
*
* @param theta the rotation angle in degrees.
*/
void setRotation(double theta);
/**
* @param flip whether the shape is horizontally flipped
*/
void setFlipHorizontal(boolean flip);
/**
* Whether the shape is vertically flipped
*
* @param flip whether the shape is vertically flipped
*/
void setFlipVertical(boolean flip);
/**
* Whether the shape is horizontally flipped
*
* @return whether the shape is horizontally flipped
*/
boolean getFlipHorizontal();
/**
* Whether the shape is vertically flipped
*
* @return whether the shape is vertically flipped
*/
boolean getFlipVertical();
}

View File

@ -18,7 +18,7 @@
package org.apache.poi.sl.usermodel;
public interface ShapeContainer extends Iterable<Shape>, PlaceableShape {
public interface ShapeContainer<T extends Shape> extends Iterable<T> {
/**
* Returns an array containing all of the elements in this container in proper
* sequence (from first to last element).
@ -26,9 +26,9 @@ public interface ShapeContainer extends Iterable<Shape>, 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<Shape>, 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);
}

View File

@ -17,6 +17,8 @@
package org.apache.poi.sl.usermodel;
public interface ShapeGroup extends ShapeContainer {
import java.awt.geom.Rectangle2D;
public interface ShapeGroup<T extends Shape> extends ShapeContainer<T>, PlaceableShape {
Rectangle2D getInteriorAnchor();
}

View File

@ -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<T extends Shape> extends ShapeContainer<T> {
SlideShow getSlideShow();
/**
@ -31,7 +31,7 @@ public interface Sheet extends ShapeContainer {
*/
boolean getFollowMasterGraphics();
MasterSheet getMasterSheet();
MasterSheet<T> getMasterSheet();
Background getBackground();
}

View File

@ -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);
}

View File

@ -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<T extends Shape> extends Sheet<T> {
public Notes<T> getNotes();
public void setNotes(Notes<T> notes);
public boolean getFollowMasterBackground();
public void setFollowMasterBackground(boolean follow);

View File

@ -17,5 +17,5 @@
package org.apache.poi.sl.usermodel;
public interface TextBox extends AutoShape {
public interface TextBox<T extends TextParagraph> extends AutoShape<T> {
}

View File

@ -20,7 +20,7 @@ package org.apache.poi.sl.usermodel;
import java.awt.Color;
public interface TextParagraph extends Iterable<TextRun> {
public interface TextParagraph<T extends TextRun> extends Iterable<T> {
/**
* Specified a list of text alignment types
*/
@ -128,5 +128,5 @@ public interface TextParagraph extends Iterable<TextRun> {
*/
BulletStyle getBulletStyle();
TextShape getParentShape();
TextShape<? extends TextParagraph<T>> getParentShape();
}

View File

@ -19,7 +19,7 @@ package org.apache.poi.sl.usermodel;
public interface TextShape extends SimpleShape, Iterable<TextParagraph> {
public interface TextShape<T extends TextParagraph<?>> extends SimpleShape, Iterable<T> {
/**
* Vertical Text Types
*/

Some files were not shown because too many files have changed in this diff Show More