git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1187328 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_8_BETA5
<changes> | <changes> | ||||
<release version="3.8-beta5" date="2011-??-??"> | <release version="3.8-beta5" date="2011-??-??"> | ||||
<action dev="poi-developers" type="add">support for converting pptx files into images with a PPTX2PNG tool</action> | |||||
<action dev="poi-developers" type="add">52050 - Support for the Excel RATE function</action> | <action dev="poi-developers" type="add">52050 - Support for the Excel RATE function</action> | ||||
<action dev="poi-developers" type="fix">51566 - HSLF fix for finishing parsing the picture stream on the first non-valid type</action> | <action dev="poi-developers" type="fix">51566 - HSLF fix for finishing parsing the picture stream on the first non-valid type</action> | ||||
<action dev="poi-developers" type="fix">51974 - Avoid HWPF issue when identifying the picture type</action> | <action dev="poi-developers" type="fix">51974 - Avoid HWPF issue when identifying the picture type</action> |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
See the License for the specific language governing permissions and | See the License for the specific language governing permissions and | ||||
limitations under the License. | limitations under the License. | ||||
==================================================================== */package org.apache.poi.util; | |||||
==================================================================== */ | |||||
package org.apache.poi.util; | |||||
/** | /** | ||||
* @author Yegor Kozlov | * @author Yegor Kozlov |
/* | |||||
* ==================================================================== | |||||
* 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.model; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; | |||||
/** | |||||
* | |||||
* @author Yegor Kozlov | |||||
*/ | |||||
public abstract class CharacterPropertyFetcher<T> extends ParagraphPropertyFetcher<T> { | |||||
public CharacterPropertyFetcher(int level) { | |||||
super(level); | |||||
} | |||||
public boolean fetch(CTTextParagraphProperties props) { | |||||
if (props.isSetDefRPr()) { | |||||
return fetch(props.getDefRPr()); | |||||
} | |||||
return false; | |||||
} | |||||
public abstract boolean fetch(CTTextCharacterProperties props); | |||||
} |
/* | |||||
* ==================================================================== | |||||
* 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.model; | |||||
import org.apache.poi.xslf.usermodel.XSLFSimpleShape; | |||||
import org.apache.xmlbeans.XmlObject; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; | |||||
/** | |||||
* | |||||
* @author Yegor Kozlov | |||||
*/ | |||||
public abstract class ParagraphPropertyFetcher<T> extends PropertyFetcher<T> { | |||||
int _level; | |||||
public ParagraphPropertyFetcher(int level) { | |||||
_level = level; | |||||
} | |||||
public boolean fetch(XSLFSimpleShape shape) { | |||||
XmlObject[] o = shape.getXmlObject().selectPath( | |||||
"declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " + | |||||
"declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' " + | |||||
".//p:txBody/a:lstStyle/a:lvl" + (_level + 1) + "pPr" | |||||
); | |||||
if (o.length == 1) { | |||||
CTTextParagraphProperties props = (CTTextParagraphProperties) o[0]; | |||||
return fetch(props); | |||||
} | |||||
return false; | |||||
} | |||||
public abstract boolean fetch(CTTextParagraphProperties props); | |||||
} |
/* | |||||
* ==================================================================== | |||||
* 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.model; | |||||
import org.apache.poi.xslf.usermodel.XSLFSimpleShape; | |||||
import org.apache.poi.util.Internal; | |||||
/** | |||||
* Used internally to navigate the PresentationML text style hierarchy and fetch properties | |||||
* | |||||
* @author Yegor Kozlov | |||||
*/ | |||||
@Internal | |||||
public abstract class PropertyFetcher<T> { | |||||
private T _value; | |||||
/** | |||||
* | |||||
* @param shape the shape being examined | |||||
* @return true if the desired property was fetched | |||||
*/ | |||||
public abstract boolean fetch(XSLFSimpleShape shape) ; | |||||
public T getValue(){ | |||||
return _value; | |||||
} | |||||
public void setValue(T val){ | |||||
_value = val; | |||||
} | |||||
} |
/* | |||||
* ==================================================================== | |||||
* 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.model; | |||||
import org.apache.poi.xslf.usermodel.XSLFSimpleShape; | |||||
import org.apache.xmlbeans.XmlObject; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties; | |||||
/** | |||||
* Created by IntelliJ IDEA. | |||||
* User: yegor | |||||
* Date: Oct 21, 2011 | |||||
* Time: 1:18:52 PM | |||||
* To change this template use File | Settings | File Templates. | |||||
*/ | |||||
public abstract class TextBodyPropertyFetcher<T> extends PropertyFetcher<T> { | |||||
public boolean fetch(XSLFSimpleShape shape) { | |||||
XmlObject[] o = shape.getXmlObject().selectPath( | |||||
"declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " + | |||||
"declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' " + | |||||
".//p:txBody/a:bodyPr" | |||||
); | |||||
if (o.length == 1) { | |||||
CTTextBodyProperties props = (CTTextBodyProperties) o[0]; | |||||
return fetch(props); | |||||
} | |||||
return false; | |||||
} | |||||
public abstract boolean fetch(CTTextBodyProperties props); | |||||
} |
import org.apache.poi.util.Beta; | import org.apache.poi.util.Beta; | ||||
import org.apache.poi.util.Units; | import org.apache.poi.util.Units; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuide; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuideList; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; | import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; | import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; | import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; | import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; | ||||
import java.awt.*; | import java.awt.*; | ||||
import java.awt.geom.AffineTransform; | |||||
import java.awt.geom.Rectangle2D; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.regex.Pattern; | |||||
import java.util.regex.Matcher; | |||||
/** | /** | ||||
* Represents a preset geometric shape. | * Represents a preset geometric shape. | ||||
*/ | */ | ||||
@Beta | @Beta | ||||
public class XSLFAutoShape extends XSLFTextShape { | public class XSLFAutoShape extends XSLFTextShape { | ||||
private static final Pattern adjPtrn = Pattern.compile("val\\s+(\\d+)"); | |||||
/*package*/ XSLFAutoShape(CTShape shape, XSLFSheet sheet) { | /*package*/ XSLFAutoShape(CTShape shape, XSLFSheet sheet) { | ||||
super(shape, sheet); | super(shape, sheet); | ||||
return ct; | return ct; | ||||
} | } | ||||
/** | |||||
* Specifies a solid color fill. The shape is filled entirely with the specified color. | |||||
* | |||||
* @param color the solid color fill. | |||||
* The value of <code>null</code> unsets the solidFIll attribute from the underlying xml | |||||
*/ | |||||
public void setFillColor(Color color) { | |||||
CTShapeProperties spPr = getSpPr(); | |||||
if (color == null) { | |||||
if(spPr.isSetSolidFill()) spPr.unsetSolidFill(); | |||||
} | |||||
else { | |||||
CTSolidColorFillProperties fill = spPr.isSetSolidFill() ? spPr.getSolidFill() : spPr.addNewSolidFill(); | |||||
CTSRgbColor rgb = CTSRgbColor.Factory.newInstance(); | |||||
rgb.setVal(new byte[]{(byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()}); | |||||
fill.setSrgbClr(rgb); | |||||
} | |||||
} | |||||
/** | |||||
* | |||||
* @return solid fill color of null if not set | |||||
*/ | |||||
public Color getFillColor(){ | |||||
CTShapeProperties spPr = getSpPr(); | |||||
if(!spPr.isSetSolidFill() ) return null; | |||||
CTSolidColorFillProperties fill = spPr.getSolidFill(); | |||||
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]); | |||||
} | |||||
protected CTTextBody getTextBody(boolean create){ | protected CTTextBody getTextBody(boolean create){ | ||||
CTShape shape = (CTShape) getXmlObject(); | CTShape shape = (CTShape) getXmlObject(); | ||||
CTTextBody txBody = shape.getTxBody(); | CTTextBody txBody = shape.getTxBody(); | ||||
return txBody; | return txBody; | ||||
} | } | ||||
} | |||||
int getAdjustValue(String name, int defaultValue){ | |||||
/* | |||||
CTShape shape = (CTShape) getXmlObject(); | |||||
CTGeomGuideList av = shape.getSpPr().getPrstGeom().getAvLst(); | |||||
if(av != null){ | |||||
for(CTGeomGuide gd : av.getGdList()){ | |||||
if(gd.getName().equals(name)) { | |||||
String fmla = gd.getFmla(); | |||||
Matcher m = adjPtrn.matcher(fmla); | |||||
if(m.matches()){ | |||||
int val = Integer.parseInt(m.group(1)); | |||||
return 21600*val/100000; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
*/ | |||||
return defaultValue; | |||||
} | |||||
@Override | |||||
protected java.awt.Shape getOutline(){ | |||||
java.awt.Shape outline = XSLFPresetGeometry.getOutline(this); | |||||
Rectangle2D anchor = getAnchor(); | |||||
AffineTransform at = new AffineTransform(); | |||||
at.translate(anchor.getX(), anchor.getY()); | |||||
at.scale( | |||||
1.0f/21600*anchor.getWidth(), | |||||
1.0f/21600*anchor.getHeight() | |||||
); | |||||
return outline == null ? anchor : at.createTransformedShape(outline); | |||||
} | |||||
} |
/* ==================================================================== | |||||
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 org.apache.poi.openxml4j.opc.PackagePart; | |||||
import org.apache.poi.openxml4j.opc.PackageRelationship; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties; | |||||
import javax.imageio.ImageIO; | |||||
import java.awt.*; | |||||
import java.awt.image.BufferedImage; | |||||
/** | |||||
* Background shape | |||||
* | |||||
* @author Yegor Kozlov | |||||
*/ | |||||
public class XSLFBackground extends XSLFSimpleShape { | |||||
/* package */XSLFBackground(CTBackground shape, XSLFSheet sheet) { | |||||
super(shape, sheet); | |||||
} | |||||
public void draw(Graphics2D graphics) { | |||||
Dimension pg = getSheet().getSlideShow().getPageSize(); | |||||
Rectangle anchor = new Rectangle(0, 0, pg.width, pg.height); | |||||
CTBackgroundProperties pr = ((CTBackground) getXmlObject()).getBgPr(); | |||||
if (pr == null) return; | |||||
XSLFTheme theme = getSheet().getTheme(); | |||||
if (pr.isSetSolidFill()) { | |||||
Color color = theme.getSolidFillColor(pr.getSolidFill()); | |||||
graphics.setPaint(color); | |||||
graphics.fill(anchor); | |||||
} | |||||
if (pr.isSetBlipFill()) { | |||||
String blipId = pr.getBlipFill().getBlip().getEmbed(); | |||||
PackagePart p = getSheet().getPackagePart(); | |||||
PackageRelationship rel = p.getRelationship(blipId); | |||||
if (rel != null) { | |||||
try { | |||||
BufferedImage img = ImageIO.read(p.getRelatedPart(rel).getInputStream()); | |||||
graphics.drawImage(img, (int) anchor.getX(), (int) anchor.getY(), | |||||
(int) anchor.getWidth(), (int) anchor.getHeight(), null); | |||||
} | |||||
catch (Exception e) { | |||||
return; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} |
/* | |||||
* ==================================================================== | |||||
* 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.Color; | |||||
import org.apache.poi.util.Internal; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTColor; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeStyleSheet; | |||||
public class XSLFColor { | |||||
private final CTColor _ctColor; | |||||
XSLFColor(CTColor ctColor){ | |||||
_ctColor = ctColor; | |||||
} | |||||
@Internal | |||||
public CTColor getXmlObject() { | |||||
return _ctColor; | |||||
} | |||||
public Color getColor(){ | |||||
return getColor(0xFF); | |||||
} | |||||
public Color getColor(int alpha){ | |||||
Color color = Color.black; | |||||
if(_ctColor.isSetSrgbClr()){ | |||||
byte[] val = _ctColor.getSrgbClr().getVal(); | |||||
color = new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2], alpha); | |||||
} else if (_ctColor.isSetSysClr()){ | |||||
byte[] val = _ctColor.getSysClr().getLastClr(); | |||||
color = new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2], alpha); | |||||
} | |||||
return color; | |||||
} | |||||
} |
import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector; | import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTConnectorNonVisual; | import org.openxmlformats.schemas.presentationml.x2006.main.CTConnectorNonVisual; | ||||
import java.awt.*; | |||||
import java.awt.geom.GeneralPath; | |||||
import java.awt.geom.Rectangle2D; | |||||
/** | /** | ||||
* | * | ||||
* Specifies a connection shape. | * Specifies a connection shape. | ||||
return len == null ? null : LineEndLength.values()[len.intValue() - 1]; | return len == null ? null : LineEndLength.values()[len.intValue() - 1]; | ||||
} | } | ||||
@Override | |||||
public void draw(Graphics2D graphics){ | |||||
java.awt.Shape outline = getOutline(); | |||||
// shadow | |||||
XSLFShadow shadow = getShadow(); | |||||
if(shadow != null) shadow.draw(graphics); | |||||
//border | |||||
Color lineColor = getLineColor(); | |||||
if (lineColor != null){ | |||||
graphics.setColor(lineColor); | |||||
applyStroke(graphics); | |||||
graphics.draw(outline); | |||||
} | |||||
} | |||||
@Override | |||||
protected java.awt.Shape getOutline(){ | |||||
Rectangle2D anchor = getAnchor(); | |||||
double x1 = anchor.getX(), | |||||
y1 = anchor.getY(), | |||||
x2 = anchor.getX() + anchor.getWidth(), | |||||
y2 = anchor.getY() + anchor.getHeight(); | |||||
GeneralPath line = new GeneralPath(); | |||||
line.moveTo((float)x1, (float)y1); | |||||
line.lineTo((float)x2, (float)y2); | |||||
return line; | |||||
} | |||||
} | } |
return numPoints; | return numPoints; | ||||
} | } | ||||
/** | |||||
* Gets the shape path. | |||||
* <p> | |||||
* The path is translated in the shape's coordinate system, i.e. | |||||
* freeform.getPath().getBounds2D() equals to freeform.getAnchor() | |||||
* (small discrepancies are possible due to rounding errors) | |||||
* </p> | |||||
* | |||||
* @return the path | |||||
*/ | |||||
public GeneralPath getPath() { | public GeneralPath getPath() { | ||||
GeneralPath path = new GeneralPath(); | GeneralPath path = new GeneralPath(); | ||||
Rectangle2D bounds = getAnchor(); | Rectangle2D bounds = getAnchor(); | ||||
int x0 = Units.toEMU(bounds.getX()); | |||||
int y0 = Units.toEMU(bounds.getY()); | |||||
CTCustomGeometry2D geom = getSpPr().getCustGeom(); | CTCustomGeometry2D geom = getSpPr().getCustGeom(); | ||||
for(CTPath2D spPath : geom.getPathLst().getPathList()){ | for(CTPath2D spPath : geom.getPathLst().getPathList()){ | ||||
double scaleW = bounds.getWidth() / Units.toPoints(spPath.getW()); | |||||
double scaleH = bounds.getHeight() / Units.toPoints(spPath.getH()); | |||||
for(XmlObject ch : spPath.selectPath("*")){ | for(XmlObject ch : spPath.selectPath("*")){ | ||||
if(ch instanceof CTPath2DMoveTo){ | if(ch instanceof CTPath2DMoveTo){ | ||||
CTAdjPoint2D pt = ((CTPath2DMoveTo)ch).getPt(); | CTAdjPoint2D pt = ((CTPath2DMoveTo)ch).getPt(); | ||||
path.moveTo((float)Units.toPoints((Long)pt.getX() + x0), | |||||
(float)Units.toPoints((Long)pt.getY() + y0)); | |||||
path.moveTo((float)Units.toPoints((Long)pt.getX())*scaleW, | |||||
(float)Units.toPoints((Long)pt.getY())*scaleH); | |||||
} else if (ch instanceof CTPath2DLineTo){ | } else if (ch instanceof CTPath2DLineTo){ | ||||
CTAdjPoint2D pt = ((CTPath2DLineTo)ch).getPt(); | CTAdjPoint2D pt = ((CTPath2DLineTo)ch).getPt(); | ||||
path.lineTo((float)Units.toPoints((Long)pt.getX() + x0), | |||||
(float)Units.toPoints((Long)pt.getY() + y0)); | |||||
path.lineTo((float)Units.toPoints((Long)pt.getX()), | |||||
(float)Units.toPoints((Long)pt.getY())); | |||||
} else if (ch instanceof CTPath2DCubicBezierTo){ | } else if (ch instanceof CTPath2DCubicBezierTo){ | ||||
CTPath2DCubicBezierTo bez = ((CTPath2DCubicBezierTo)ch); | CTPath2DCubicBezierTo bez = ((CTPath2DCubicBezierTo)ch); | ||||
CTAdjPoint2D pt1 = bez.getPtArray(0); | CTAdjPoint2D pt1 = bez.getPtArray(0); | ||||
CTAdjPoint2D pt2 = bez.getPtArray(1); | CTAdjPoint2D pt2 = bez.getPtArray(1); | ||||
CTAdjPoint2D pt3 = bez.getPtArray(2); | CTAdjPoint2D pt3 = bez.getPtArray(2); | ||||
path.curveTo( | path.curveTo( | ||||
(float)Units.toPoints((Long) pt1.getX() + x0), | |||||
(float)Units.toPoints((Long) pt1.getY() + y0), | |||||
(float)Units.toPoints((Long) pt2.getX() + x0), | |||||
(float)Units.toPoints((Long) pt2.getY() + y0), | |||||
(float)Units.toPoints((Long) pt3.getX() + x0), | |||||
(float)Units.toPoints((Long) pt3.getY() + y0) | |||||
(float)Units.toPoints((Long) pt1.getX())*scaleW, | |||||
(float)Units.toPoints((Long) pt1.getY())*scaleH, | |||||
(float)Units.toPoints((Long) pt2.getX())*scaleW, | |||||
(float)Units.toPoints((Long) pt2.getY())*scaleH, | |||||
(float)Units.toPoints((Long) pt3.getX())*scaleW, | |||||
(float)Units.toPoints((Long) pt3.getY())*scaleH | |||||
); | ); | ||||
} else if (ch instanceof CTPath2DClose){ | } else if (ch instanceof CTPath2DClose){ | ||||
} | } | ||||
} | } | ||||
return path; | |||||
// the created path starts at (x=0, y=0). | |||||
// The returned path should fit in the bounding rectangle | |||||
AffineTransform at = new AffineTransform(); | |||||
at.translate(bounds.getX(), bounds.getY()); | |||||
return new GeneralPath(at.createTransformedShape(path)); | |||||
} | } | ||||
/** | /** | ||||
* @param shapeId 1-based shapeId | * @param shapeId 1-based shapeId | ||||
return ct; | return ct; | ||||
} | } | ||||
@Override | |||||
protected java.awt.Shape getOutline(){ | |||||
return getPath(); | |||||
} | |||||
} | } |
import org.apache.poi.sl.usermodel.ShapeContainer; | import org.apache.poi.sl.usermodel.ShapeContainer; | ||||
import org.apache.poi.sl.usermodel.ShapeGroup; | import org.apache.poi.sl.usermodel.ShapeGroup; | ||||
import org.apache.poi.util.Beta; | import org.apache.poi.util.Beta; | ||||
import org.apache.poi.util.Units; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame; | import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupTransform2D; | |||||
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.CTShapeProperties; | |||||
import java.awt.Graphics2D; | |||||
import java.awt.geom.AffineTransform; | |||||
import java.awt.geom.Rectangle2D; | import java.awt.geom.Rectangle2D; | ||||
/** | /** | ||||
} | } | ||||
public Rectangle2D getAnchor(){ | public Rectangle2D getAnchor(){ | ||||
throw new RuntimeException("NotImplemented"); | |||||
CTTransform2D xfrm = _shape.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)); | |||||
} | } | ||||
public void setAnchor(Rectangle2D anchor){ | public void setAnchor(Rectangle2D anchor){ | ||||
throw new RuntimeException("NotImplemented"); | |||||
CTTransform2D xfrm = _shape.getXfrm(); | |||||
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); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
/** | |||||
* 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 void setRotation(double theta){ | |||||
throw new IllegalArgumentException("Operation not supported"); | |||||
} | |||||
/** | |||||
* 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 double getRotation(){ | |||||
return 0; | |||||
} | |||||
public void setFlipHorizontal(boolean flip){ | |||||
throw new IllegalArgumentException("Operation not supported"); | |||||
} | |||||
public void setFlipVertical(boolean flip){ | |||||
throw new IllegalArgumentException("Operation not supported"); | |||||
} | |||||
/** | |||||
* Whether the shape is horizontally flipped | |||||
* | |||||
* @return whether the shape is horizontally flipped | |||||
*/ | |||||
public boolean getFlipHorizontal(){ | |||||
return false; | |||||
} | |||||
public boolean getFlipVertical(){ | |||||
return false; | |||||
} | |||||
public void draw(Graphics2D graphics){ | |||||
} | |||||
} | } |
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; | import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; | import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; | import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector; | import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape; | import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShapeNonVisual; | import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShapeNonVisual; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; | import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; | ||||
import java.awt.Graphics2D; | |||||
import java.awt.geom.AffineTransform; | |||||
import java.awt.geom.Rectangle2D; | import java.awt.geom.Rectangle2D; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.regex.Pattern; | import java.util.regex.Pattern; | ||||
return sh; | return sh; | ||||
} | } | ||||
public void setFlipHorizontal(boolean flip){ | |||||
_spPr.getXfrm().setFlipH(flip); | |||||
} | |||||
public void setFlipVertical(boolean flip){ | |||||
_spPr.getXfrm().setFlipV(flip); | |||||
} | |||||
/** | |||||
* Whether the shape is horizontally flipped | |||||
* | |||||
* @return whether the shape is horizontally flipped | |||||
*/ | |||||
public boolean getFlipHorizontal(){ | |||||
return _spPr.getXfrm().getFlipH(); | |||||
} | |||||
public boolean getFlipVertical(){ | |||||
return _spPr.getXfrm().getFlipV(); | |||||
} | |||||
/** | |||||
* 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 void setRotation(double theta){ | |||||
_spPr.getXfrm().setRot((int)(theta*60000)); | |||||
} | |||||
/** | |||||
* 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 double getRotation(){ | |||||
return (double)_spPr.getXfrm().getRot()/60000; | |||||
} | |||||
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(); | |||||
graphics.translate(exterior.getX(), exterior.getY()); | |||||
double scaleX = exterior.getWidth() / interior.getWidth(); | |||||
double scaleY = exterior.getHeight() / interior.getHeight(); | |||||
graphics.scale(scaleX, scaleY); | |||||
graphics.translate(-interior.getX(), -interior.getY()); | |||||
for (XSLFShape shape : getShapes()) { | |||||
// remember the initial transform and restore it after we are done with the drawing | |||||
AffineTransform at0 = graphics.getTransform(); | |||||
graphics.setRenderingHint(XSLFRenderingHint.GSAVE, true); | |||||
// apply rotation and flipping | |||||
shape.applyTransform(graphics); | |||||
shape.draw(graphics); | |||||
// restore the coordinate system | |||||
graphics.setTransform(at0); | |||||
graphics.setRenderingHint(XSLFRenderingHint.GRESTORE, true); | |||||
} | |||||
} | |||||
} | } |
import org.apache.poi.POIXMLDocumentPart; | import org.apache.poi.POIXMLDocumentPart; | ||||
import org.apache.poi.sl.usermodel.ShapeContainer; | import org.apache.poi.sl.usermodel.ShapeContainer; | ||||
import org.apache.poi.util.Beta; | import org.apache.poi.util.Beta; | ||||
import org.apache.poi.util.POILogger; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip; | import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties; | import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; | import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; | import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; | import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; | import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture; | import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPictureNonVisual; | import org.openxmlformats.schemas.presentationml.x2006.main.CTPictureNonVisual; | ||||
import javax.imageio.ImageIO; | import javax.imageio.ImageIO; | ||||
import java.awt.Color; | |||||
import java.awt.Graphics2D; | |||||
import java.awt.Image; | |||||
import java.awt.Rectangle; | |||||
import java.awt.geom.Rectangle2D; | import java.awt.geom.Rectangle2D; | ||||
import java.awt.image.BufferedImage; | import java.awt.image.BufferedImage; | ||||
import java.io.ByteArrayInputStream; | import java.io.ByteArrayInputStream; | ||||
} | } | ||||
return _data; | return _data; | ||||
} | } | ||||
@Override | |||||
public void draw(Graphics2D graphics){ | |||||
java.awt.Shape outline = getOutline(); | |||||
//fill | |||||
Color fillColor = getFillColor(); | |||||
if (fillColor != null) { | |||||
graphics.setColor(fillColor); | |||||
applyFill(graphics); | |||||
graphics.fill(outline); | |||||
} | |||||
// text | |||||
XSLFPictureData data = getPictureData(); | |||||
if(data == null) return; | |||||
BufferedImage img; | |||||
try { | |||||
img = ImageIO.read(new ByteArrayInputStream(data.getData())); | |||||
} | |||||
catch (Exception e){ | |||||
return; | |||||
} | |||||
Rectangle2D anchor = getAnchor(); | |||||
graphics.drawImage(img, (int)anchor.getX(), (int)anchor.getY(), | |||||
(int)anchor.getWidth(), (int)anchor.getHeight(), null); | |||||
//border overlays the image | |||||
Color lineColor = getLineColor(); | |||||
if (lineColor != null){ | |||||
graphics.setColor(lineColor); | |||||
applyStroke(graphics); | |||||
graphics.draw(outline); | |||||
} | |||||
} | |||||
} | } |
/* | |||||
* ==================================================================== | |||||
* 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.*; | |||||
import java.awt.geom.*; | |||||
/** | |||||
* TODO: re-write and initialize from presetShapeDefinitions.xml | |||||
* | |||||
* @author Yegor Kozlov | |||||
*/ | |||||
public class XSLFPresetGeometry { | |||||
public static final int LINE = 1; | |||||
public static final int LINE_INV = 2; | |||||
public static final int TRIANGLE = 3; | |||||
public static final int RT_TRIANGLE = 4; | |||||
public static final int RECT = 5; | |||||
public static final int DIAMOND = 6; | |||||
public static final int PARALLELOGRAM = 7; | |||||
public static final int TRAPEZOID = 8; | |||||
public static final int NON_ISOSCELES_TRAPEZOID = 9; | |||||
public static final int PENTAGON = 10; | |||||
public static final int HEXAGON = 11; | |||||
public static final int HEPTAGON = 12; | |||||
public static final int OCTAGON = 13; | |||||
public static final int DECAGON = 14; | |||||
public static final int DODECAGON = 15; | |||||
public static final int STAR_4 = 16; | |||||
public static final int STAR_5 = 17; | |||||
public static final int STAR_6 = 18; | |||||
public static final int STAR_7 = 19; | |||||
public static final int STAR_8 = 20; | |||||
public static final int STAR_10 = 21; | |||||
public static final int STAR_12 = 22; | |||||
public static final int STAR_16 = 23; | |||||
public static final int STAR_24 = 24; | |||||
public static final int STAR_32 = 25; | |||||
public static final int ROUND_RECT = 26; | |||||
public static final int ROUND_1_RECT = 27; | |||||
public static final int ROUND_2_SAME_RECT = 28; | |||||
public static final int ROUND_2_DIAG_RECT = 29; | |||||
public static final int SNIP_ROUND_RECT = 30; | |||||
public static final int SNIP_1_RECT = 31; | |||||
public static final int SNIP_2_SAME_RECT = 32; | |||||
public static final int SNIP_2_DIAG_RECT = 33; | |||||
public static final int PLAQUE = 34; | |||||
public static final int ELLIPSE = 35; | |||||
public static final int TEARDROP = 36; | |||||
public static final int HOME_PLATE = 37; | |||||
public static final int CHEVRON = 38; | |||||
public static final int PIE_WEDGE = 39; | |||||
public static final int PIE = 40; | |||||
public static final int BLOCK_ARC = 41; | |||||
public static final int DONUT = 42; | |||||
public static final int NO_SMOKING = 43; | |||||
public static final int RIGHT_ARROW = 44; | |||||
public static final int LEFT_ARROW = 45; | |||||
public static final int UP_ARROW = 46; | |||||
public static final int DOWN_ARROW = 47; | |||||
public static final int STRIPED_RIGHT_ARROW = 48; | |||||
public static final int NOTCHED_RIGHT_ARROW = 49; | |||||
public static final int BENT_UP_ARROW = 50; | |||||
public static final int LEFT_RIGHT_ARROW = 51; | |||||
public static final int UP_DOWN_ARROW = 52; | |||||
public static final int LEFT_UP_ARROW = 53; | |||||
public static final int LEFT_RIGHT_UP_ARROW = 54; | |||||
public static final int QUAD_ARROW = 55; | |||||
public static final int LEFT_ARROW_CALLOUT = 56; | |||||
public static final int RIGHT_ARROW_CALLOUT = 57; | |||||
public static final int UP_ARROW_CALLOUT = 58; | |||||
public static final int DOWN_ARROW_CALLOUT = 59; | |||||
public static final int LEFT_RIGHT_ARROW_CALLOUT = 60; | |||||
public static final int UP_DOWN_ARROW_CALLOUT = 61; | |||||
public static final int QUAD_ARROW_CALLOUT = 62; | |||||
public static final int BENT_ARROW = 63; | |||||
public static final int UTURN_ARROW = 64; | |||||
public static final int CIRCULAR_ARROW = 65; | |||||
public static final int LEFT_CIRCULAR_ARROW = 66; | |||||
public static final int LEFT_RIGHT_CIRCULAR_ARROW = 67; | |||||
public static final int CURVED_RIGHT_ARROW = 68; | |||||
public static final int CURVED_LEFT_ARROW = 69; | |||||
public static final int CURVED_UP_ARROW = 70; | |||||
public static final int CURVED_DOWN_ARROW = 71; | |||||
public static final int SWOOSH_ARROW = 72; | |||||
public static final int CUBE = 73; | |||||
public static final int CAN = 74; | |||||
public static final int LIGHTNING_BOLT = 75; | |||||
public static final int HEART = 76; | |||||
public static final int SUN = 77; | |||||
public static final int MOON = 78; | |||||
public static final int SMILEY_FACE = 79; | |||||
public static final int IRREGULAR_SEAL_1 = 80; | |||||
public static final int IRREGULAR_SEAL_2 = 81; | |||||
public static final int FOLDED_CORNER = 82; | |||||
public static final int BEVEL = 83; | |||||
public static final int FRAME = 84; | |||||
public static final int HALF_FRAME = 85; | |||||
public static final int CORNER = 86; | |||||
public static final int DIAG_STRIPE = 87; | |||||
public static final int CHORD = 88; | |||||
public static final int ARC = 89; | |||||
public static final int LEFT_BRACKET = 90; | |||||
public static final int RIGHT_BRACKET = 91; | |||||
public static final int LEFT_BRACE = 92; | |||||
public static final int RIGHT_BRACE = 93; | |||||
public static final int BRACKET_PAIR = 94; | |||||
public static final int BRACE_PAIR = 95; | |||||
public static final int STRAIGHT_CONNECTOR_1 = 96; | |||||
public static final int BENT_CONNECTOR_2 = 97; | |||||
public static final int BENT_CONNECTOR_3 = 98; | |||||
public static final int BENT_CONNECTOR_4 = 99; | |||||
public static final int BENT_CONNECTOR_5 = 100; | |||||
public static final int CURVED_CONNECTOR_2 = 101; | |||||
public static final int CURVED_CONNECTOR_3 = 102; | |||||
public static final int CURVED_CONNECTOR_4 = 103; | |||||
public static final int CURVED_CONNECTOR_5 = 104; | |||||
public static final int CALLOUT_1 = 105; | |||||
public static final int CALLOUT_2 = 106; | |||||
public static final int CALLOUT_3 = 107; | |||||
public static final int ACCENT_CALLOUT_1 = 108; | |||||
public static final int ACCENT_CALLOUT_2 = 109; | |||||
public static final int ACCENT_CALLOUT_3 = 110; | |||||
public static final int BORDER_CALLOUT_1 = 111; | |||||
public static final int BORDER_CALLOUT_2 = 112; | |||||
public static final int BORDER_CALLOUT_3 = 113; | |||||
public static final int ACCENT_BORDER_CALLOUT_1 = 114; | |||||
public static final int ACCENT_BORDER_CALLOUT_2 = 115; | |||||
public static final int ACCENT_BORDER_CALLOUT_3 = 116; | |||||
public static final int WEDGE_RECT_CALLOUT = 117; | |||||
public static final int WEDGE_ROUND_RECT_CALLOUT = 118; | |||||
public static final int WEDGE_ELLIPSE_CALLOUT = 119; | |||||
public static final int CLOUD_CALLOUT = 120; | |||||
public static final int CLOUD = 121; | |||||
public static final int RIBBON = 122; | |||||
public static final int RIBBON_2 = 123; | |||||
public static final int ELLIPSE_RIBBON = 124; | |||||
public static final int ELLIPSE_RIBBON_2 = 125; | |||||
public static final int LEFT_RIGHT_RIBBON = 126; | |||||
public static final int VERTICAL_SCROLL = 127; | |||||
public static final int HORIZONTAL_SCROLL = 128; | |||||
public static final int WAVE = 129; | |||||
public static final int DOUBLE_WAVE = 130; | |||||
public static final int PLUS = 131; | |||||
public static final int FLOW_CHART_PROCESS = 132; | |||||
public static final int FLOW_CHART_DECISION = 133; | |||||
public static final int FLOW_CHART_INPUT_OUTPUT = 134; | |||||
public static final int FLOW_CHART_PREDEFINED_PROCESS = 135; | |||||
public static final int FLOW_CHART_INTERNAL_STORAGE = 136; | |||||
public static final int FLOW_CHART_DOCUMENT = 137; | |||||
public static final int FLOW_CHART_MULTIDOCUMENT = 138; | |||||
public static final int FLOW_CHART_TERMINATOR = 139; | |||||
public static final int FLOW_CHART_PREPARATION = 140; | |||||
public static final int FLOW_CHART_MANUAL_INPUT = 141; | |||||
public static final int FLOW_CHART_MANUAL_OPERATION = 142; | |||||
public static final int FLOW_CHART_CONNECTOR = 143; | |||||
public static final int FLOW_CHART_PUNCHED_CARD = 144; | |||||
public static final int FLOW_CHART_PUNCHED_TAPE = 145; | |||||
public static final int FLOW_CHART_SUMMING_JUNCTION = 146; | |||||
public static final int FLOW_CHART_OR = 147; | |||||
public static final int FLOW_CHART_COLLATE = 148; | |||||
public static final int FLOW_CHART_SORT = 149; | |||||
public static final int FLOW_CHART_EXTRACT = 150; | |||||
public static final int FLOW_CHART_MERGE = 151; | |||||
public static final int FLOW_CHART_OFFLINE_STORAGE = 152; | |||||
public static final int FLOW_CHART_ONLINE_STORAGE = 153; | |||||
public static final int FLOW_CHART_MAGNETIC_TAPE = 154; | |||||
public static final int FLOW_CHART_MAGNETIC_DISK = 155; | |||||
public static final int FLOW_CHART_MAGNETIC_DRUM = 156; | |||||
public static final int FLOW_CHART_DISPLAY = 157; | |||||
public static final int FLOW_CHART_DELAY = 158; | |||||
public static final int FLOW_CHART_ALTERNATE_PROCESS = 159; | |||||
public static final int FLOW_CHART_OFFPAGE_CONNECTOR = 160; | |||||
public static final int ACTION_BUTTON_BLANK = 161; | |||||
public static final int ACTION_BUTTON_HOME = 162; | |||||
public static final int ACTION_BUTTON_HELP = 163; | |||||
public static final int ACTION_BUTTON_INFORMATION = 164; | |||||
public static final int ACTION_BUTTON_FORWARD_NEXT = 165; | |||||
public static final int ACTION_BUTTON_BACK_PREVIOUS = 166; | |||||
public static final int ACTION_BUTTON_END = 167; | |||||
public static final int ACTION_BUTTON_BEGINNING = 168; | |||||
public static final int ACTION_BUTTON_RETURN = 169; | |||||
public static final int ACTION_BUTTON_DOCUMENT = 170; | |||||
public static final int ACTION_BUTTON_SOUND = 171; | |||||
public static final int ACTION_BUTTON_MOVIE = 172; | |||||
public static final int GEAR_6 = 173; | |||||
public static final int GEAR_9 = 174; | |||||
public static final int FUNNEL = 175; | |||||
public static final int MATH_PLUS = 176; | |||||
public static final int MATH_MINUS = 177; | |||||
public static final int MATH_MULTIPLY = 178; | |||||
public static final int MATH_DIVIDE = 179; | |||||
public static final int MATH_EQUAL = 180; | |||||
public static final int MATH_NOT_EQUAL = 181; | |||||
public static final int CORNER_TABS = 182; | |||||
public static final int SQUARE_TABS = 183; | |||||
public static final int PLAQUE_TABS = 184; | |||||
public static final int CHART_X = 185; | |||||
public static final int CHART_STAR = 186; | |||||
public static final int CHART_PLUS = 187; | |||||
private static interface ShapeOutline { | |||||
java.awt.Shape getOutline(XSLFAutoShape shape); | |||||
} | |||||
static ShapeOutline[] shapes; | |||||
static { | |||||
shapes = new ShapeOutline[255]; | |||||
shapes[RECT] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
Rectangle2D path = new Rectangle2D.Float(0, 0, 21600, 21600); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[ROUND_RECT] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
int adjval = shape.getAdjustValue("adj1", 5400); | |||||
RoundRectangle2D path = new RoundRectangle2D.Float(0, 0, 21600, 21600, adjval, adjval); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[ELLIPSE] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
Ellipse2D path = new Ellipse2D.Float(0, 0, 21600, 21600); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[DIAMOND] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(10800, 0); | |||||
path.lineTo(21600, 10800); | |||||
path.lineTo(10800, 21600); | |||||
path.lineTo(0, 10800); | |||||
path.closePath(); | |||||
return path; | |||||
} | |||||
}; | |||||
//m@0,l,21600r21600 | |||||
shapes[TRIANGLE] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
int adjval = shape.getAdjustValue("adj1", 5400); | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(adjval, 0); | |||||
path.lineTo(0, 21600); | |||||
path.lineTo(21600, 21600); | |||||
path.closePath(); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[RT_TRIANGLE] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(0, 0); | |||||
path.lineTo(21600, 21600); | |||||
path.lineTo(0, 21600); | |||||
path.closePath(); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[PARALLELOGRAM] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
int adjval = shape.getAdjustValue("adj1", 5400); | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(adjval, 0); | |||||
path.lineTo(21600, 0); | |||||
path.lineTo(21600 - adjval, 21600); | |||||
path.lineTo(0, 21600); | |||||
path.closePath(); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[TRAPEZOID] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
int adjval = shape.getAdjustValue("adj1", 5400); | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(0, 0); | |||||
path.lineTo(adjval, 21600); | |||||
path.lineTo(21600 - adjval, 21600); | |||||
path.lineTo(21600, 0); | |||||
path.closePath(); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[HEXAGON] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
int adjval = shape.getAdjustValue("adj1", 5400); | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(adjval, 0); | |||||
path.lineTo(21600 - adjval, 0); | |||||
path.lineTo(21600, 10800); | |||||
path.lineTo(21600 - adjval, 21600); | |||||
path.lineTo(adjval, 21600); | |||||
path.lineTo(0, 10800); | |||||
path.closePath(); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[OCTAGON] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
int adjval = shape.getAdjustValue("adj1", 6324); | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(adjval, 0); | |||||
path.lineTo(21600 - adjval, 0); | |||||
path.lineTo(21600, adjval); | |||||
path.lineTo(21600, 21600-adjval); | |||||
path.lineTo(21600-adjval, 21600); | |||||
path.lineTo(adjval, 21600); | |||||
path.lineTo(0, 21600-adjval); | |||||
path.lineTo(0, adjval); | |||||
path.closePath(); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[PLUS] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
int adjval = shape.getAdjustValue("adj1", 5400); | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(adjval, 0); | |||||
path.lineTo(21600 - adjval, 0); | |||||
path.lineTo(21600 - adjval, adjval); | |||||
path.lineTo(21600, adjval); | |||||
path.lineTo(21600, 21600-adjval); | |||||
path.lineTo(21600-adjval, 21600-adjval); | |||||
path.lineTo(21600-adjval, 21600); | |||||
path.lineTo(adjval, 21600); | |||||
path.lineTo(adjval, 21600-adjval); | |||||
path.lineTo(0, 21600-adjval); | |||||
path.lineTo(0, adjval); | |||||
path.lineTo(adjval, adjval); | |||||
path.closePath(); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[PENTAGON] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(10800, 0); | |||||
path.lineTo(21600, 8259); | |||||
path.lineTo(21600 - 4200, 21600); | |||||
path.lineTo(4200, 21600); | |||||
path.lineTo(0, 8259); | |||||
path.closePath(); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[HOME_PLATE] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
GeneralPath path = new GeneralPath(); | |||||
int adjval = shape.getAdjustValue("adj1", 16200); | |||||
path.moveTo(0, 0); | |||||
path.lineTo(adjval, 0 ); | |||||
path.lineTo(21600, 10800); | |||||
path.lineTo(adjval, 21600); | |||||
path.lineTo(0, 21600); | |||||
path.closePath(); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[CHEVRON] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
GeneralPath path = new GeneralPath(); | |||||
int adjval = shape.getAdjustValue("adj1", 16200); | |||||
path.moveTo(0, 0); | |||||
path.lineTo(adjval, 0 ); | |||||
path.lineTo(21600, 10800); | |||||
path.lineTo(adjval, 21600); | |||||
path.lineTo(0, 21600); | |||||
path.lineTo(21600 - adjval, 10800); | |||||
path.closePath(); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[CAN] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
int adjval = shape.getAdjustValue("adj1", 5400); | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(0, 0); | |||||
path.lineTo(21600, 0); | |||||
path.lineTo(21600, 21600); | |||||
path.lineTo(0, 21600); | |||||
//path.lineTo(21600, adjval); | |||||
path.closePath(); | |||||
path.moveTo(10800, 0); | |||||
//path.append(new Arc2D.Float(10800, 0, 10800, adjval, 0, 90, Arc2D.OPEN), true); | |||||
path.moveTo(10800, adjval/2); | |||||
path.append(new Arc2D.Float(10800, adjval/2, 10800, adjval, 90, 180, Arc2D.OPEN), true); | |||||
//path.append(new Arc2D.Float(0, adjval/2, 10800, adjval, 180, 270, Arc2D.OPEN), true); | |||||
//path.append(new Arc2D.Float(0, 0, 10800, adjval, 270, 360, Arc2D.OPEN), true); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[DOWN_ARROW] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
//m0@0 l@1@0 @1,0 @2,0 @2@0,21600@0,10800,21600xe | |||||
int adjval = shape.getAdjustValue("adj1", 16200); | |||||
int adjval2 = shape.getAdjustValue("adj2", 5400); | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(0, adjval); | |||||
path.lineTo(adjval2, adjval); | |||||
path.lineTo(adjval2, 0); | |||||
path.lineTo(21600-adjval2, 0); | |||||
path.lineTo(21600-adjval2, adjval); | |||||
path.lineTo(21600, adjval); | |||||
path.lineTo(10800, 21600); | |||||
path.closePath(); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[UP_ARROW] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
//m0@0 l@1@0 @1,21600@2,21600@2@0,21600@0,10800,xe | |||||
int adjval = shape.getAdjustValue("adj1", 5400); | |||||
int adjval2 = shape.getAdjustValue("adj2", 5400); | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(0, adjval); | |||||
path.lineTo(adjval2, adjval); | |||||
path.lineTo(adjval2, 21600); | |||||
path.lineTo(21600-adjval2, 21600); | |||||
path.lineTo(21600-adjval2, adjval); | |||||
path.lineTo(21600, adjval); | |||||
path.lineTo(10800, 0); | |||||
path.closePath(); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[RIGHT_ARROW] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
//m@0, l@0@1 ,0@1,0@2@0@2@0,21600,21600,10800xe | |||||
int adjval = shape.getAdjustValue("adj1", 16200); | |||||
int adjval2 = shape.getAdjustValue("adj2", 5400); | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(adjval, 0); | |||||
path.lineTo(adjval, adjval2); | |||||
path.lineTo(0, adjval2); | |||||
path.lineTo(0, 21600-adjval2); | |||||
path.lineTo(adjval, 21600-adjval2); | |||||
path.lineTo(adjval, 21600); | |||||
path.lineTo(21600, 10800); | |||||
path.closePath(); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[LEFT_ARROW] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
//m@0, l@0@1,21600@1,21600@2@0@2@0,21600,,10800xe | |||||
int adjval = shape.getAdjustValue("adj1", 5400); | |||||
int adjval2 = shape.getAdjustValue("adj2", 5400); | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(adjval, 0); | |||||
path.lineTo(adjval, adjval2); | |||||
path.lineTo(21600, adjval2); | |||||
path.lineTo(21600, 21600-adjval2); | |||||
path.lineTo(adjval, 21600-adjval2); | |||||
path.lineTo(adjval, 21600); | |||||
path.lineTo(0, 10800); | |||||
path.closePath(); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[LEFT_BRACE] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
//m21600,qx10800@0l10800@2qy0@11,10800@3l10800@1qy21600,21600e | |||||
int adjval = shape.getAdjustValue("adj1", 1800); | |||||
int adjval2 = shape.getAdjustValue("adj2", 10800); | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(21600, 0); | |||||
path.append(new Arc2D.Float(10800, 0, 21600, adjval*2, 90, 90, Arc2D.OPEN), false); | |||||
path.moveTo(10800, adjval); | |||||
path.lineTo(10800, adjval2 - adjval); | |||||
path.append(new Arc2D.Float(-10800, adjval2 - 2*adjval, 21600, adjval*2, 270, 90, Arc2D.OPEN), false); | |||||
path.moveTo(0, adjval2); | |||||
path.append(new Arc2D.Float(-10800, adjval2, 21600, adjval*2, 0, 90, Arc2D.OPEN), false); | |||||
path.moveTo(10800, adjval2 + adjval); | |||||
path.lineTo(10800, 21600 - adjval); | |||||
path.append(new Arc2D.Float(10800, 21600 - 2*adjval, 21600, adjval*2, 180, 90, Arc2D.OPEN), false); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[RIGHT_BRACE] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
//m,qx10800@0 l10800@2qy21600@11,10800@3l10800@1qy,21600e | |||||
int adjval = shape.getAdjustValue("adj1", 1800); | |||||
int adjval2 = shape.getAdjustValue("adj2", 10800); | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(0, 0); | |||||
path.append(new Arc2D.Float(-10800, 0, 21600, adjval*2, 0, 90, Arc2D.OPEN), false); | |||||
path.moveTo(10800, adjval); | |||||
path.lineTo(10800, adjval2 - adjval); | |||||
path.append(new Arc2D.Float(10800, adjval2 - 2*adjval, 21600, adjval*2, 180, 90, Arc2D.OPEN), false); | |||||
path.moveTo(21600, adjval2); | |||||
path.append(new Arc2D.Float(10800, adjval2, 21600, adjval*2, 90, 90, Arc2D.OPEN), false); | |||||
path.moveTo(10800, adjval2 + adjval); | |||||
path.lineTo(10800, 21600 - adjval); | |||||
path.append(new Arc2D.Float(-10800, 21600 - 2*adjval, 21600, adjval*2, 270, 90, Arc2D.OPEN), false); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[LEFT_RIGHT_ARROW] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
//m,10800l@0,21600@0@3@2@3@2,21600,21600,10800@2,0@2@1@0@1@0,xe | |||||
int adjval = shape.getAdjustValue("adj1", 4320); | |||||
int adjval2 = shape.getAdjustValue("adj2", 5400); | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(0, 10800); | |||||
path.lineTo(adjval, 0); | |||||
path.lineTo(adjval, adjval2); | |||||
path.lineTo(21600 - adjval, adjval2); | |||||
path.lineTo(21600 - adjval, 0); | |||||
path.lineTo(21600, 10800); | |||||
path.lineTo(21600 - adjval, 21600); | |||||
path.lineTo(21600 - adjval, 21600 - adjval2); | |||||
path.lineTo(adjval, 21600 - adjval2); | |||||
path.lineTo(adjval, 21600); | |||||
path.closePath(); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[UP_DOWN_ARROW] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
//m10800,l21600@0@3@0@3@2,21600@2,10800,21600,0@2@1@2@1@0,0@0xe | |||||
int adjval1 = shape.getAdjustValue("adj1", 5400); | |||||
int adjval2 = shape.getAdjustValue("adj2", 4320); | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(10800, 0); | |||||
path.lineTo(21600, adjval2); | |||||
path.lineTo(21600 - adjval1, adjval2); | |||||
path.lineTo(21600 - adjval1, 21600 - adjval2); | |||||
path.lineTo(21600, 21600 - adjval2); | |||||
path.lineTo(10800, 21600); | |||||
path.lineTo(0, 21600 - adjval2); | |||||
path.lineTo(adjval1, 21600 - adjval2); | |||||
path.lineTo(adjval1, adjval2); | |||||
path.lineTo(0, adjval2); | |||||
path.closePath(); | |||||
return path; | |||||
} | |||||
}; | |||||
shapes[NOTCHED_RIGHT_ARROW] = new ShapeOutline(){ | |||||
public java.awt.Shape getOutline(XSLFAutoShape shape){ | |||||
//m@0,l@0@1,0@1@5,10800,0@2@0@2@0,21600,21600,10800xe | |||||
int adjval1 = shape.getAdjustValue("adj1", 16200); | |||||
int adjval2 = shape.getAdjustValue("adj2", 5400); | |||||
GeneralPath path = new GeneralPath(); | |||||
path.moveTo(adjval1, 0); | |||||
path.lineTo(adjval1, adjval2); | |||||
path.lineTo(0, adjval2); | |||||
//The notch at the end stays adjusted so that it matches the shape of the arrowhead. | |||||
int notch = (21600-2*adjval2)*(21600-adjval1)/21600; | |||||
path.lineTo(notch, 10800); | |||||
path.lineTo(0, 21600 - adjval2); | |||||
path.lineTo(adjval1, 21600 - adjval2); | |||||
path.lineTo(adjval1, 21600); | |||||
path.lineTo(21600, 10800); | |||||
path.closePath(); | |||||
return path; | |||||
} | |||||
}; | |||||
} | |||||
static Shape getOutline(XSLFAutoShape shape){ | |||||
ShapeOutline outline = shapes[shape.getShapeType()]; | |||||
return outline == null ? null : outline.getOutline(shape); | |||||
} | |||||
} |
/* | |||||
* ==================================================================== | |||||
* 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.*; | |||||
/** | |||||
* | |||||
* @author Yegor Kozlov | |||||
*/ | |||||
public class XSLFRenderingHint extends RenderingHints.Key { | |||||
public XSLFRenderingHint(int i){ | |||||
super(i); | |||||
} | |||||
@Override | |||||
public boolean isCompatibleValue(Object val) { | |||||
return true; | |||||
} | |||||
public static final XSLFRenderingHint GSAVE = new XSLFRenderingHint(1); | |||||
public static final XSLFRenderingHint GRESTORE = new XSLFRenderingHint(2); | |||||
public static final XSLFRenderingHint SKIP_PLACEHOLDERS = new XSLFRenderingHint(3); | |||||
} |
/* ==================================================================== | |||||
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 org.apache.poi.openxml4j.opc.PackagePart; | |||||
import org.apache.poi.openxml4j.opc.PackageRelationship; | |||||
import org.apache.poi.util.Units; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetColor; | |||||
import javax.imageio.ImageIO; | |||||
import java.awt.*; | |||||
import java.awt.geom.Rectangle2D; | |||||
import java.awt.geom.AffineTransform; | |||||
import java.awt.image.BufferedImage; | |||||
/** | |||||
* Represents a shadow of a shape. For now supports only outer shadows. | |||||
* | |||||
* @author Yegor Kozlov | |||||
*/ | |||||
public class XSLFShadow extends XSLFSimpleShape { | |||||
private XSLFSimpleShape _parent; | |||||
/* package */XSLFShadow(CTOuterShadowEffect shape, XSLFSimpleShape parentShape) { | |||||
super(shape, parentShape.getSheet()); | |||||
_parent = parentShape; | |||||
} | |||||
public void draw(Graphics2D graphics) { | |||||
Shape outline = _parent.getOutline(); | |||||
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); | |||||
//fill | |||||
Color fillColor = getFillColor(); | |||||
if (fillColor != null) { | |||||
graphics.setColor(fillColor); | |||||
graphics.fill(outline); | |||||
} | |||||
graphics.translate(-dx, -dy); | |||||
} | |||||
@Override | |||||
public Rectangle2D getAnchor(){ | |||||
return _parent.getAnchor(); | |||||
} | |||||
@Override | |||||
public void setAnchor(Rectangle2D anchor){ | |||||
throw new IllegalStateException("You can't set anchor of a shadow"); | |||||
} | |||||
public double getDistance(){ | |||||
CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject(); | |||||
return ct.isSetDist() ? Units.toPoints(ct.getDist()) : 0; | |||||
} | |||||
public double getAngle(){ | |||||
CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject(); | |||||
return ct.isSetDir() ? (double)ct.getDir() / 60000 : 0; | |||||
} | |||||
public double getBlur(){ | |||||
CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject(); | |||||
return ct.isSetBlurRad() ? Units.toPoints(ct.getBlurRad()) : 0; | |||||
} | |||||
@Override | |||||
public Color getFillColor() { | |||||
XSLFTheme theme = getSheet().getTheme(); | |||||
CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject(); | |||||
if(ct.isSetSchemeClr()) { | |||||
return theme.getSchemeColor(ct.getSchemeClr()); | |||||
} | |||||
else if (ct.isSetPrstClr()) { | |||||
return theme.getPresetColor(ct.getPrstClr()); | |||||
} | |||||
return Color.black; | |||||
} | |||||
} |
package org.apache.poi.xslf.usermodel; | package org.apache.poi.xslf.usermodel; | ||||
import org.apache.poi.sl.usermodel.Shape; | |||||
import org.apache.poi.util.Beta; | import org.apache.poi.util.Beta; | ||||
import org.apache.xmlbeans.XmlObject; | import org.apache.xmlbeans.XmlObject; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; | |||||
import java.awt.Graphics2D; | |||||
import java.awt.geom.Rectangle2D; | import java.awt.geom.Rectangle2D; | ||||
/** | /** | ||||
public abstract String getShapeName(); | public abstract String getShapeName(); | ||||
public abstract int getShapeId(); | 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(); | |||||
public abstract void setFlipHorizontal(boolean flip); | |||||
public abstract void setFlipVertical(boolean flip); | |||||
/** | |||||
* Whether the shape is horizontally flipped | |||||
* | |||||
* @return whether the shape is horizontally flipped | |||||
*/ | |||||
public abstract boolean getFlipHorizontal(); | |||||
public abstract boolean getFlipVertical(); | |||||
public abstract void draw(Graphics2D graphics); | |||||
protected java.awt.Shape getOutline(){ | |||||
return getAnchor(); | |||||
} | |||||
protected void applyTransform(Graphics2D graphics){ | |||||
Rectangle2D anchor = getAnchor(); | |||||
// rotation | |||||
double rotation = getRotation(); | |||||
if(rotation != 0.) { | |||||
// PowerPoint rotates shapes relative to the geometric center | |||||
double centerX = anchor.getX() + anchor.getWidth()/2; | |||||
double centerY = anchor.getY() + anchor.getHeight()/2; | |||||
graphics.translate(centerX, centerY); | |||||
graphics.rotate(Math.toRadians(rotation)); | |||||
graphics.translate(-centerX, -centerY); | |||||
} | |||||
//flip horizontal | |||||
if(getFlipHorizontal()){ | |||||
graphics.translate(anchor.getX() + anchor.getWidth(), anchor.getY()); | |||||
graphics.scale(-1, 1); | |||||
graphics.translate(-anchor.getX() , -anchor.getY()); | |||||
} | |||||
//flip vertical | |||||
if(getFlipVertical()){ | |||||
graphics.translate(anchor.getX(), anchor.getY() + anchor.getHeight()); | |||||
graphics.scale(1, -1); | |||||
graphics.translate(-anchor.getX(), -anchor.getY()); | |||||
} | |||||
} | |||||
} | } |
import org.apache.poi.openxml4j.opc.PackageRelationship; | import org.apache.poi.openxml4j.opc.PackageRelationship; | ||||
import org.apache.poi.openxml4j.opc.TargetMode; | import org.apache.poi.openxml4j.opc.TargetMode; | ||||
import org.apache.poi.util.Beta; | import org.apache.poi.util.Beta; | ||||
import org.apache.poi.util.Internal; | |||||
import org.apache.xmlbeans.XmlObject; | import org.apache.xmlbeans.XmlObject; | ||||
import org.apache.xmlbeans.XmlOptions; | import org.apache.xmlbeans.XmlOptions; | ||||
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; | import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape; | import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture; | import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; | import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle; | |||||
import javax.xml.namespace.QName; | import javax.xml.namespace.QName; | ||||
import java.awt.Graphics2D; | |||||
import java.awt.geom.AffineTransform; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.OutputStream; | import java.io.OutputStream; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
private XSLFDrawing _drawing; | private XSLFDrawing _drawing; | ||||
private List<XSLFShape> _shapes; | private List<XSLFShape> _shapes; | ||||
private CTGroupShape _spTree; | private CTGroupShape _spTree; | ||||
private Map<Integer, XSLFSimpleShape> _placeholderByIdMap; | |||||
private Map<Integer, XSLFSimpleShape> _placeholderByTypeMap; | |||||
public XSLFSheet() { | public XSLFSheet() { | ||||
super(); | super(); | ||||
return getShapeList().remove(xShape); | return getShapeList().remove(xShape); | ||||
} | } | ||||
public XSLFBackground getBackground(){ | |||||
return null; | |||||
} | |||||
protected abstract String getRootElementName(); | protected abstract String getRootElementName(); | ||||
protected CTGroupShape getSpTree(){ | protected CTGroupShape getSpTree(){ | ||||
getXmlObject().set(src.getXmlObject()); | getXmlObject().set(src.getXmlObject()); | ||||
} | } | ||||
public XSLFTheme getTheme(){ | |||||
return null; | |||||
} | |||||
public XSLFSlideMaster getSlideMaster(){ | |||||
return null; | |||||
} | |||||
public XSLFSlideLayout getSlideLayout(){ | |||||
return null; | |||||
} | |||||
protected CTTextListStyle getTextProperties(Placeholder textType) { | |||||
return null; | |||||
} | |||||
protected XSLFTextShape getTextShapeByType(Placeholder type){ | |||||
for(XSLFShape shape : this.getShapes()){ | |||||
if(shape instanceof XSLFTextShape) { | |||||
XSLFTextShape txt = (XSLFTextShape)shape; | |||||
if(txt.getTextType() == type) { | |||||
return txt; | |||||
} | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
XSLFSimpleShape getPlaceholder(CTPlaceholder ph) { | |||||
XSLFSimpleShape shape = null; | |||||
if(ph.isSetIdx()) shape = getPlaceholderById((int)ph.getIdx()); | |||||
if (shape == null && ph.isSetType()) { | |||||
shape = getPlaceholderByType(ph.getType().intValue()); | |||||
} | |||||
return shape; | |||||
} | |||||
XSLFSimpleShape getPlaceholderById(int id) { | |||||
if(_placeholderByIdMap == null) { | |||||
_placeholderByIdMap = new HashMap<Integer, XSLFSimpleShape>(); | |||||
for(XSLFShape sh : getShapes()){ | |||||
if(sh instanceof XSLFSimpleShape){ | |||||
XSLFSimpleShape sShape = (XSLFSimpleShape)sh; | |||||
CTPlaceholder ph = sShape.getCTPlaceholder(); | |||||
if(ph != null && ph.isSetIdx()){ | |||||
int idx = (int)ph.getIdx(); | |||||
_placeholderByIdMap.put(idx, sShape); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return _placeholderByIdMap.get(id); | |||||
} | |||||
XSLFSimpleShape getPlaceholderByType(int ordinal) { | |||||
if(_placeholderByTypeMap == null) { | |||||
_placeholderByTypeMap = new HashMap<Integer, XSLFSimpleShape>(); | |||||
for(XSLFShape sh : getShapes()){ | |||||
if(sh instanceof XSLFSimpleShape){ | |||||
XSLFSimpleShape sShape = (XSLFSimpleShape)sh; | |||||
CTPlaceholder ph = sShape.getCTPlaceholder(); | |||||
if(ph != null && ph.isSetType()){ | |||||
_placeholderByTypeMap.put(ph.getType().intValue(), sShape); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return _placeholderByTypeMap.get(ordinal); | |||||
} | |||||
/** | |||||
* Checks if this <code>sheet</code> displays the specified shape. | |||||
* | |||||
* Subclasses can override it and skip certain shapes from drawings. | |||||
*/ | |||||
protected boolean canDraw(XSLFShape shape){ | |||||
return true; | |||||
} | |||||
/** | |||||
* Render this sheet into the supplied graphics object | |||||
* | |||||
* @param graphics | |||||
*/ | |||||
public void draw(Graphics2D graphics){ | |||||
XSLFBackground bg = getBackground(); | |||||
if(bg != null) bg.draw(graphics); | |||||
for(XSLFShape shape : getShapeList()) { | |||||
if(!canDraw(shape)) continue; | |||||
// remember the initial transform and restore it after we are done with drawing | |||||
AffineTransform at0 = graphics.getTransform(); | |||||
graphics.setRenderingHint(XSLFRenderingHint.GSAVE, true); | |||||
// apply rotation and flipping | |||||
shape.applyTransform(graphics); | |||||
shape.draw(graphics); | |||||
// restore the coordinate system | |||||
graphics.setTransform(at0); | |||||
graphics.setRenderingHint(XSLFRenderingHint.GRESTORE, true); | |||||
} | |||||
} | |||||
} | } |
import org.apache.poi.xslf.usermodel.LineCap; | import org.apache.poi.xslf.usermodel.LineCap; | ||||
import org.apache.poi.xslf.usermodel.LineDash; | import org.apache.poi.xslf.usermodel.LineDash; | ||||
import org.apache.poi.xslf.model.PropertyFetcher; | |||||
import org.apache.poi.util.Beta; | import org.apache.poi.util.Beta; | ||||
import org.apache.poi.util.Units; | import org.apache.poi.util.Units; | ||||
import org.apache.xmlbeans.XmlObject; | import org.apache.xmlbeans.XmlObject; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; | import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; | import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; | import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetLineDashProperties; | import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetLineDashProperties; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; | import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; | import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; | import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; | import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap; | import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal; | import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; | import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleItem; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; | |||||
import java.awt.*; | import java.awt.*; | ||||
import java.awt.geom.Rectangle2D; | import java.awt.geom.Rectangle2D; | ||||
private final XmlObject _shape; | private final XmlObject _shape; | ||||
private final XSLFSheet _sheet; | private final XSLFSheet _sheet; | ||||
private CTShapeProperties _spPr; | private CTShapeProperties _spPr; | ||||
private CTShapeStyle _spStyle; | |||||
private CTNonVisualDrawingProps _nvPr; | private CTNonVisualDrawingProps _nvPr; | ||||
private CTPlaceholder _ph; | |||||
/*package*/ XSLFSimpleShape(XmlObject shape, XSLFSheet sheet){ | |||||
/* package */XSLFSimpleShape(XmlObject shape, XSLFSheet sheet) { | |||||
_shape = shape; | _shape = shape; | ||||
_sheet = sheet; | _sheet = sheet; | ||||
} | } | ||||
public XmlObject getXmlObject(){ | |||||
public XmlObject getXmlObject() { | |||||
return _shape; | return _shape; | ||||
} | } | ||||
public XSLFSheet getSheet(){ | |||||
public XSLFSheet getSheet() { | |||||
return _sheet; | return _sheet; | ||||
} | } | ||||
/** | /** | ||||
* TODO match STShapeType with {@link org.apache.poi.sl.usermodel.ShapeTypes} | |||||
* TODO match STShapeType with | |||||
* {@link org.apache.poi.sl.usermodel.ShapeTypes} | |||||
*/ | */ | ||||
public int getShapeType() { | public int getShapeType() { | ||||
STShapeType.Enum stEnum = getSpPr().getPrstGeom().getPrst(); | |||||
return stEnum.intValue(); | |||||
CTPresetGeometry2D prst = getSpPr().getPrstGeom(); | |||||
STShapeType.Enum stEnum = prst == null ? null : prst.getPrst(); | |||||
return stEnum == null ? 0 : stEnum.intValue(); | |||||
} | } | ||||
public String getShapeName() { | public String getShapeName() { | ||||
} | } | ||||
public int getShapeId() { | public int getShapeId() { | ||||
return (int)getNvPr().getId(); | |||||
return (int) getNvPr().getId(); | |||||
} | } | ||||
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]; | |||||
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; | return _nvPr; | ||||
} | } | ||||
protected CTShapeProperties getSpPr(){ | |||||
if(_spPr == null) { | |||||
for(XmlObject obj : _shape.selectPath("*")){ | |||||
if(obj instanceof CTShapeProperties){ | |||||
_spPr = (CTShapeProperties)obj; | |||||
protected CTShapeProperties getSpPr() { | |||||
if (_spPr == null) { | |||||
for (XmlObject obj : _shape.selectPath("*")) { | |||||
if (obj instanceof CTShapeProperties) { | |||||
_spPr = (CTShapeProperties) obj; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
if(_spPr == null) { | |||||
if (_spPr == null) { | |||||
throw new IllegalStateException("CTShapeProperties was not found."); | throw new IllegalStateException("CTShapeProperties was not found."); | ||||
} | } | ||||
return _spPr; | return _spPr; | ||||
} | } | ||||
public Rectangle2D getAnchor(){ | |||||
CTTransform2D xfrm = getSpPr().getXfrm(); | |||||
protected CTShapeStyle getSpStyle() { | |||||
if (_spStyle == null) { | |||||
for (XmlObject obj : _shape.selectPath("*")) { | |||||
if (obj instanceof CTShapeStyle) { | |||||
_spStyle = (CTShapeStyle) obj; | |||||
} | |||||
} | |||||
} | |||||
return _spStyle; | |||||
} | |||||
protected CTPlaceholder getCTPlaceholder(){ | |||||
if(_ph == null){ | |||||
XmlObject[] obj = _shape.selectPath( | |||||
"declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:nvPr/p:ph"); | |||||
if(obj.length == 1){ | |||||
_ph = (CTPlaceholder)obj[0]; | |||||
} | |||||
} | |||||
return _ph; | |||||
} | |||||
private CTTransform2D getXfrm(){ | |||||
PropertyFetcher<CTTransform2D> fetcher = new PropertyFetcher<CTTransform2D>(){ | |||||
public boolean fetch(XSLFSimpleShape shape){ | |||||
CTShapeProperties pr = shape.getSpPr(); | |||||
if(pr.isSetXfrm()){ | |||||
setValue(pr.getXfrm()); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchShapeProperty(fetcher); | |||||
return fetcher.getValue(); | |||||
} | |||||
public Rectangle2D getAnchor() { | |||||
CTTransform2D xfrm = getXfrm(); | |||||
CTPoint2D off = xfrm.getOff(); | CTPoint2D off = xfrm.getOff(); | ||||
long x = off.getX(); | long x = off.getX(); | ||||
long y = off.getY(); | long y = off.getY(); | ||||
Units.toPoints(cx), Units.toPoints(cy)); | Units.toPoints(cx), Units.toPoints(cy)); | ||||
} | } | ||||
public void setAnchor(Rectangle2D anchor){ | |||||
CTTransform2D xfrm = getSpPr().isSetXfrm() ? getSpPr().getXfrm() : getSpPr().addNewXfrm(); | |||||
public void setAnchor(Rectangle2D anchor) { | |||||
CTShapeProperties spPr = getSpPr(); | |||||
CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm(); | |||||
CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff(); | CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff(); | ||||
long x = Units.toEMU(anchor.getX()); | long x = Units.toEMU(anchor.getX()); | ||||
long y = Units.toEMU(anchor.getY()); | long y = Units.toEMU(anchor.getY()); | ||||
off.setX(x); | off.setX(x); | ||||
off.setY(y); | off.setY(y); | ||||
CTPositiveSize2D ext = xfrm.isSetExt() ? xfrm.getExt() : xfrm.addNewExt(); | |||||
CTPositiveSize2D ext = xfrm.isSetExt() ? xfrm.getExt() : xfrm | |||||
.addNewExt(); | |||||
long cx = Units.toEMU(anchor.getWidth()); | long cx = Units.toEMU(anchor.getWidth()); | ||||
long cy = Units.toEMU(anchor.getHeight()); | long cy = Units.toEMU(anchor.getHeight()); | ||||
ext.setCx(cx); | ext.setCx(cx); | ||||
* Rotate this shape. | * Rotate this shape. | ||||
* <p> | * <p> | ||||
* Positive angles are clockwise (i.e., towards the positive y axis); | * Positive angles are clockwise (i.e., towards the positive y axis); | ||||
* negative angles are counter-clockwise (i.e., towards the negative y axis). | |||||
* negative angles are counter-clockwise (i.e., towards the negative y | |||||
* axis). | |||||
* </p> | * </p> | ||||
* | * | ||||
* @param theta the rotation angle in degrees. | * @param theta the rotation angle in degrees. | ||||
*/ | */ | ||||
public void setRotation(double theta){ | |||||
CTTransform2D xfrm = getSpPr().getXfrm(); | |||||
xfrm.setRot((int)(theta*60000)); | |||||
public void setRotation(double theta) { | |||||
CTShapeProperties spPr = getSpPr(); | |||||
CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm(); | |||||
xfrm.setRot((int) (theta * 60000)); | |||||
} | } | ||||
/** | /** | ||||
* Rotation angle in degrees | * Rotation angle in degrees | ||||
* <p> | * <p> | ||||
* Positive angles are clockwise (i.e., towards the positive y axis); | * Positive angles are clockwise (i.e., towards the positive y axis); | ||||
* negative angles are counter-clockwise (i.e., towards the negative y axis). | |||||
* negative angles are counter-clockwise (i.e., towards the negative y | |||||
* axis). | |||||
* </p> | * </p> | ||||
* | * | ||||
* @return rotation angle in degrees | * @return rotation angle in degrees | ||||
*/ | */ | ||||
public double getRotation(){ | |||||
CTTransform2D xfrm = getSpPr().getXfrm(); | |||||
return (double)xfrm.getRot()/60000; | |||||
public double getRotation() { | |||||
CTTransform2D xfrm = getXfrm(); | |||||
return (double) xfrm.getRot() / 60000; | |||||
} | } | ||||
public void setFlipHorizontal(boolean flip){ | |||||
CTTransform2D xfrm = getSpPr().getXfrm(); | |||||
public void setFlipHorizontal(boolean flip) { | |||||
CTShapeProperties spPr = getSpPr(); | |||||
CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm(); | |||||
xfrm.setFlipH(flip); | xfrm.setFlipH(flip); | ||||
} | } | ||||
public void setFlipVertical(boolean flip){ | |||||
CTTransform2D xfrm = getSpPr().getXfrm(); | |||||
public void setFlipVertical(boolean flip) { | |||||
CTShapeProperties spPr = getSpPr(); | |||||
CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm(); | |||||
xfrm.setFlipV(flip); | xfrm.setFlipV(flip); | ||||
} | } | ||||
/** | /** | ||||
* Whether the shape is horizontally flipped | * Whether the shape is horizontally flipped | ||||
* | * | ||||
* @return whether the shape is horizontally flipped | * @return whether the shape is horizontally flipped | ||||
*/ | */ | ||||
public boolean getFlipHorizontal(){ | |||||
return getSpPr().getXfrm().getFlipH(); | |||||
public boolean getFlipHorizontal() { | |||||
return getXfrm().getFlipH(); | |||||
} | } | ||||
public boolean getFlipVertical(){ | |||||
return getSpPr().getXfrm().getFlipV(); | |||||
public boolean getFlipVertical() { | |||||
return getXfrm().getFlipV(); | |||||
} | } | ||||
public void setLineColor(Color color){ | |||||
CTShapeProperties spPr = getSpPr(); | |||||
if(color == null) { | |||||
if(spPr.isSetLn() && spPr.getLn().isSetSolidFill()) spPr.getLn().unsetSolidFill(); | |||||
/** | |||||
* Get line properties defined in the theme (if any) | |||||
* | |||||
* @return line propeties from the theme of null | |||||
*/ | |||||
CTLineProperties getDefaultLineProperties() { | |||||
CTLineProperties ln = null; | |||||
CTShapeStyle style = getSpStyle(); | |||||
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(); | |||||
ln = styleMatrix.getLnStyleLst().getLnArray(idx - 1); | |||||
} | } | ||||
else { | |||||
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn(); | |||||
return ln; | |||||
} | |||||
public void setLineColor(Color color) { | |||||
CTShapeProperties spPr = getSpPr(); | |||||
if (color == null) { | |||||
if (spPr.isSetLn() && spPr.getLn().isSetSolidFill()) | |||||
spPr.getLn().unsetSolidFill(); | |||||
} else { | |||||
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr | |||||
.addNewLn(); | |||||
CTSRgbColor rgb = CTSRgbColor.Factory.newInstance(); | CTSRgbColor rgb = CTSRgbColor.Factory.newInstance(); | ||||
rgb.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()}); | |||||
rgb.setVal(new byte[]{(byte) color.getRed(), | |||||
(byte) color.getGreen(), (byte) color.getBlue()}); | |||||
CTSolidColorFillProperties fill = ln.isSetSolidFill() ? ln.getSolidFill() : ln.addNewSolidFill(); | |||||
CTSolidColorFillProperties fill = ln.isSetSolidFill() ? ln | |||||
.getSolidFill() : ln.addNewSolidFill(); | |||||
fill.setSrgbClr(rgb); | fill.setSrgbClr(rgb); | ||||
} | } | ||||
} | } | ||||
public Color getLineColor(){ | |||||
CTShapeProperties spPr = getSpPr(); | |||||
if(!spPr.isSetLn() || !spPr.getLn().isSetSolidFill()) return null; | |||||
CTSRgbColor rgb = spPr.getLn().getSolidFill().getSrgbClr(); | |||||
byte[] val = rgb.getVal(); | |||||
return new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]); | |||||
public Color getLineColor() { | |||||
final XSLFTheme theme = _sheet.getTheme(); | |||||
PropertyFetcher<Color> fetcher = new PropertyFetcher<Color>(){ | |||||
public boolean fetch(XSLFSimpleShape shape){ | |||||
CTShapeProperties spPr = shape.getSpPr(); | |||||
CTLineProperties ln = spPr.getLn(); | |||||
if (ln != null) { | |||||
if (ln.isSetNoFill()) { | |||||
setValue(null); | |||||
return true; | |||||
} | |||||
CTSolidColorFillProperties solidLine = ln.getSolidFill(); | |||||
if (solidLine != null) { | |||||
setValue( theme.getSolidFillColor(ln.getSolidFill()) ); | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchShapeProperty(fetcher); | |||||
Color color = fetcher.getValue(); | |||||
if(color == null){ | |||||
// line color was not found, check if it is defined in the theme | |||||
CTShapeStyle style = getSpStyle(); | |||||
if (style != null) { | |||||
CTSchemeColor schemeColor = style.getLnRef().getSchemeClr(); | |||||
if (schemeColor != null) { | |||||
color = theme.getSchemeColor(schemeColor); | |||||
} | |||||
} | |||||
} | |||||
return color; | |||||
} | } | ||||
public void setLineWidth(double width){ | |||||
public void setLineWidth(double width) { | |||||
CTShapeProperties spPr = getSpPr(); | CTShapeProperties spPr = getSpPr(); | ||||
if(width == 0.) { | |||||
if(spPr.isSetLn()) spPr.getLn().unsetW(); | |||||
} | |||||
else { | |||||
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn(); | |||||
if (width == 0.) { | |||||
if (spPr.isSetLn()) | |||||
spPr.getLn().unsetW(); | |||||
} else { | |||||
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr | |||||
.addNewLn(); | |||||
ln.setW(Units.toEMU(width)); | ln.setW(Units.toEMU(width)); | ||||
} | } | ||||
} | } | ||||
public double getLineWidth(){ | |||||
CTShapeProperties spPr = getSpPr(); | |||||
CTLineProperties ln = spPr.getLn(); | |||||
if(ln == null || !ln.isSetW()) return 0; | |||||
public double getLineWidth() { | |||||
PropertyFetcher<Double> fetcher = new PropertyFetcher<Double>(){ | |||||
public boolean fetch(XSLFSimpleShape shape){ | |||||
CTShapeProperties spPr = shape.getSpPr(); | |||||
CTLineProperties ln = spPr.getLn(); | |||||
if (ln != null) { | |||||
if (ln.isSetNoFill()) { | |||||
setValue(0.); | |||||
return true; | |||||
} | |||||
if (ln.isSetW()) { | |||||
setValue( Units.toPoints(ln.getW()) ); | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchShapeProperty(fetcher); | |||||
double lineWidth = 0; | |||||
if(fetcher.getValue() == null) { | |||||
CTLineProperties defaultLn = getDefaultLineProperties(); | |||||
if (defaultLn != null) { | |||||
if (defaultLn.isSetW()) lineWidth = Units.toPoints(defaultLn.getW()); | |||||
} | |||||
} else { | |||||
lineWidth = fetcher.getValue(); | |||||
} | |||||
return Units.toPoints(ln.getW()); | |||||
return lineWidth; | |||||
} | } | ||||
public void setLineDash(LineDash dash){ | |||||
public void setLineDash(LineDash dash) { | |||||
CTShapeProperties spPr = getSpPr(); | CTShapeProperties spPr = getSpPr(); | ||||
if(dash == null) { | |||||
if(spPr.isSetLn()) spPr.getLn().unsetPrstDash(); | |||||
} | |||||
else { | |||||
CTPresetLineDashProperties val = CTPresetLineDashProperties.Factory.newInstance(); | |||||
if (dash == null) { | |||||
if (spPr.isSetLn()) | |||||
spPr.getLn().unsetPrstDash(); | |||||
} else { | |||||
CTPresetLineDashProperties val = CTPresetLineDashProperties.Factory | |||||
.newInstance(); | |||||
val.setVal(STPresetLineDashVal.Enum.forInt(dash.ordinal() + 1)); | val.setVal(STPresetLineDashVal.Enum.forInt(dash.ordinal() + 1)); | ||||
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn(); | |||||
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr | |||||
.addNewLn(); | |||||
ln.setPrstDash(val); | ln.setPrstDash(val); | ||||
} | } | ||||
} | } | ||||
public LineDash getLineDash(){ | |||||
public LineDash getLineDash() { | |||||
PropertyFetcher<LineDash> fetcher = new PropertyFetcher<LineDash>(){ | |||||
public boolean fetch(XSLFSimpleShape shape){ | |||||
CTShapeProperties spPr = shape.getSpPr(); | |||||
CTLineProperties ln = spPr.getLn(); | |||||
if (ln != null) { | |||||
CTPresetLineDashProperties ctDash = ln.getPrstDash(); | |||||
if (ctDash != null) { | |||||
setValue( LineDash.values()[ctDash.getVal().intValue() - 1] ); | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchShapeProperty(fetcher); | |||||
LineDash dash = fetcher.getValue(); | |||||
if(dash == null){ | |||||
CTLineProperties defaultLn = getDefaultLineProperties(); | |||||
if (defaultLn != null) { | |||||
CTPresetLineDashProperties ctDash = defaultLn.getPrstDash(); | |||||
if (ctDash != null) { | |||||
dash = LineDash.values()[ctDash.getVal().intValue() - 1]; | |||||
} | |||||
} | |||||
} | |||||
return dash; | |||||
} | |||||
public void setLineCap(LineCap cap) { | |||||
CTShapeProperties spPr = getSpPr(); | CTShapeProperties spPr = getSpPr(); | ||||
CTLineProperties ln = spPr.getLn(); | |||||
if(ln == null || !ln.isSetPrstDash()) return null; | |||||
if (cap == null) { | |||||
if (spPr.isSetLn()) | |||||
spPr.getLn().unsetCap(); | |||||
} else { | |||||
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr | |||||
.addNewLn(); | |||||
ln.setCap(STLineCap.Enum.forInt(cap.ordinal() + 1)); | |||||
} | |||||
} | |||||
CTPresetLineDashProperties dash = ln.getPrstDash(); | |||||
return LineDash.values()[dash.getVal().intValue() - 1]; | |||||
public LineCap getLineCap() { | |||||
PropertyFetcher<LineCap> fetcher = new PropertyFetcher<LineCap>(){ | |||||
public boolean fetch(XSLFSimpleShape shape){ | |||||
CTShapeProperties spPr = shape.getSpPr(); | |||||
CTLineProperties ln = spPr.getLn(); | |||||
if (ln != null) { | |||||
STLineCap.Enum stCap = ln.getCap(); | |||||
if (stCap != null) { | |||||
setValue( LineCap.values()[stCap.intValue() - 1] ); | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchShapeProperty(fetcher); | |||||
LineCap cap = fetcher.getValue(); | |||||
if(cap == null){ | |||||
CTLineProperties defaultLn = getDefaultLineProperties(); | |||||
if (defaultLn != null) { | |||||
STLineCap.Enum stCap = defaultLn.getCap(); | |||||
if (stCap != null) { | |||||
cap = LineCap.values()[stCap.intValue() - 1]; | |||||
} | |||||
} | |||||
} | |||||
return cap; | |||||
} | } | ||||
public void setLineCap(LineCap cap){ | |||||
/** | |||||
* Specifies a solid color fill. The shape is filled entirely with the | |||||
* specified color. | |||||
* | |||||
* @param color the solid color fill. The value of <code>null</code> unsets | |||||
* the solidFIll attribute from the underlying xml | |||||
*/ | |||||
public void setFillColor(Color color) { | |||||
CTShapeProperties spPr = getSpPr(); | CTShapeProperties spPr = getSpPr(); | ||||
if(cap == null) { | |||||
if(spPr.isSetLn()) spPr.getLn().unsetCap(); | |||||
if (color == null) { | |||||
if (spPr.isSetSolidFill()) spPr.unsetSolidFill(); | |||||
if(!spPr.isSetNoFill()) spPr.addNewNoFill(); | |||||
} else { | |||||
if(spPr.isSetNoFill()) spPr.unsetNoFill(); | |||||
CTSolidColorFillProperties fill = spPr.isSetSolidFill() ? spPr | |||||
.getSolidFill() : spPr.addNewSolidFill(); | |||||
CTSRgbColor rgb = CTSRgbColor.Factory.newInstance(); | |||||
rgb.setVal(new byte[]{(byte) color.getRed(), | |||||
(byte) color.getGreen(), (byte) color.getBlue()}); | |||||
fill.setSrgbClr(rgb); | |||||
} | } | ||||
else { | |||||
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn(); | |||||
ln.setCap(STLineCap.Enum.forInt(cap.ordinal() + 1)); | |||||
} | |||||
/** | |||||
* @return solid fill color of null if not set | |||||
*/ | |||||
public Color getFillColor() { | |||||
final XSLFTheme theme = _sheet.getTheme(); | |||||
PropertyFetcher<Color> fetcher = new PropertyFetcher<Color>(){ | |||||
public boolean fetch(XSLFSimpleShape shape){ | |||||
CTShapeProperties spPr = shape.getSpPr(); | |||||
if (spPr.isSetNoFill()) { | |||||
setValue(null); | |||||
return true; | |||||
} | |||||
if (spPr.isSetSolidFill()) { | |||||
setValue( theme.getSolidFillColor(spPr.getSolidFill()) ); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchShapeProperty(fetcher); | |||||
Color color = fetcher.getValue(); | |||||
if(color == null){ | |||||
// fill color was not found, check if it is defined in the theme | |||||
CTShapeStyle style = getSpStyle(); | |||||
if (style != null) { | |||||
CTSchemeColor schemeColor = style.getFillRef().getSchemeClr(); | |||||
if (schemeColor != null) { | |||||
color = theme.getSchemeColor(schemeColor); | |||||
} | |||||
} | |||||
} | } | ||||
return color; | |||||
} | } | ||||
public LineCap getLineCap(){ | |||||
CTShapeProperties spPr = getSpPr(); | |||||
CTLineProperties ln = spPr.getLn(); | |||||
if(ln == null || !ln.isSetCap()) return null; | |||||
public XSLFShadow getShadow(){ | |||||
PropertyFetcher<CTOuterShadowEffect> fetcher = new PropertyFetcher<CTOuterShadowEffect>(){ | |||||
public boolean fetch(XSLFSimpleShape shape){ | |||||
CTShapeProperties spPr = shape.getSpPr(); | |||||
if (spPr.isSetEffectLst()) { | |||||
CTOuterShadowEffect obj = spPr.getEffectLst().getOuterShdw(); | |||||
setValue(obj); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchShapeProperty(fetcher); | |||||
CTOuterShadowEffect obj = fetcher.getValue(); | |||||
if(obj == null){ | |||||
// fill color was not found, check if it is defined in the theme | |||||
CTShapeStyle style = getSpStyle(); | |||||
if (style != null) { | |||||
// 1-based index of a shadow style within the style matrix | |||||
int idx = (int) style.getEffectRef().getIdx(); | |||||
CTStyleMatrix styleMatrix = _sheet.getTheme().getXmlObject().getThemeElements().getFmtScheme(); | |||||
CTEffectStyleItem ef = styleMatrix.getEffectStyleLst().getEffectStyleArray(idx - 1); | |||||
obj = ef.getEffectLst().getOuterShdw(); | |||||
} | |||||
} | |||||
return obj == null ? null : new XSLFShadow(obj, this); | |||||
} | |||||
public void draw(Graphics2D graphics) { | |||||
} | |||||
protected void applyFill(Graphics2D graphics) { | |||||
} | |||||
protected 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; | |||||
} | |||||
protected void applyStroke(Graphics2D graphics) { | |||||
float lineWidth = (float) getLineWidth(); | |||||
LineDash lineDash = getLineDash(); | |||||
float[] dash = null; | |||||
float dash_phase = 0; | |||||
if (lineDash != null) { | |||||
dash = getDashPattern(lineDash, lineWidth); | |||||
} | |||||
int cap = BasicStroke.CAP_BUTT; | |||||
LineCap lineCap = 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, 0.0f, dash, | |||||
dash_phase); | |||||
graphics.setStroke(stroke); | |||||
} | |||||
/** | |||||
* Walk up the inheritance tree and fetch properties. | |||||
* | |||||
* slide <-- slideLayout <-- slideMaster | |||||
* | |||||
* | |||||
* @param visitor the object that collects the desired property | |||||
* @return true if the property was fetched | |||||
*/ | |||||
boolean fetchShapeProperty(PropertyFetcher visitor){ | |||||
boolean ok = visitor.fetch(this); | |||||
XSLFSimpleShape masterShape; | |||||
if(!ok){ | |||||
// first try to fetch from the slide layout | |||||
XSLFSlideLayout layout = getSheet().getSlideLayout(); | |||||
if(layout != null) { | |||||
CTPlaceholder ph = getCTPlaceholder(); | |||||
if (ph != null) { | |||||
masterShape = layout.getPlaceholder(ph); | |||||
if (masterShape != null) { | |||||
ok = visitor.fetch(masterShape); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
// try slide master | |||||
if (!ok) { | |||||
int textType; | |||||
CTPlaceholder ph = getCTPlaceholder(); | |||||
if(ph == null || !ph.isSetType()) textType = STPlaceholderType.INT_BODY; | |||||
else { | |||||
switch(ph.getType().intValue()){ | |||||
case STPlaceholderType.INT_TITLE: | |||||
case STPlaceholderType.INT_CTR_TITLE: | |||||
textType = STPlaceholderType.INT_TITLE; | |||||
break; | |||||
case STPlaceholderType.INT_FTR: | |||||
case STPlaceholderType.INT_SLD_NUM: | |||||
case STPlaceholderType.INT_DT: | |||||
textType = ph.getType().intValue(); | |||||
break; | |||||
default: | |||||
textType = STPlaceholderType.INT_BODY; | |||||
break; | |||||
} | |||||
} | |||||
XSLFSlideMaster master = getSheet().getSlideMaster(); | |||||
if(master != null) { | |||||
masterShape = master.getPlaceholderByType(textType); | |||||
if (masterShape != null) { | |||||
ok = visitor.fetch(masterShape); | |||||
} | |||||
} | |||||
} | |||||
return LineCap.values()[ln.getCap().intValue() - 1]; | |||||
return ok; | |||||
} | } | ||||
} | } |
==================================================================== */ | ==================================================================== */ | ||||
package org.apache.poi.xslf.usermodel; | package org.apache.poi.xslf.usermodel; | ||||
import java.awt.*; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import org.apache.poi.POIXMLDocumentPart; | import org.apache.poi.POIXMLDocumentPart; | ||||
import org.apache.poi.openxml4j.opc.PackageRelationship; | import org.apache.poi.openxml4j.opc.PackageRelationship; | ||||
import org.apache.poi.util.Beta; | import org.apache.poi.util.Beta; | ||||
import org.apache.xmlbeans.XmlException; | import org.apache.xmlbeans.XmlException; | ||||
import org.apache.xmlbeans.XmlObject; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties; | import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupTransform2D; | import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupTransform2D; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; | import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; | import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; | import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTCommonSlideData; | import org.openxmlformats.schemas.presentationml.x2006.main.CTCommonSlideData; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape; | import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShapeNonVisual; | import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShapeNonVisual; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide; | import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.SldDocument; | import org.openxmlformats.schemas.presentationml.x2006.main.SldDocument; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; | |||||
@Beta | @Beta | ||||
public final class XSLFSlide extends XSLFSheet { | public final class XSLFSlide extends XSLFSheet { | ||||
return getSlideLayout().getSlideMaster(); | return getSlideLayout().getSlideMaster(); | ||||
} | } | ||||
@Override | |||||
public XSLFSlideLayout getSlideLayout(){ | public XSLFSlideLayout getSlideLayout(){ | ||||
if(_layout == null){ | if(_layout == null){ | ||||
for (POIXMLDocumentPart p : getRelations()) { | for (POIXMLDocumentPart p : getRelations()) { | ||||
} | } | ||||
return _layout; | return _layout; | ||||
} | } | ||||
@Override | |||||
public XSLFSlideMaster getSlideMaster(){ | |||||
return getSlideLayout().getSlideMaster(); | |||||
} | |||||
public XSLFComments getComments() { | public XSLFComments getComments() { | ||||
if(_comments == null) { | if(_comments == null) { | ||||
for (POIXMLDocumentPart p : getRelations()) { | for (POIXMLDocumentPart p : getRelations()) { | ||||
public boolean getFollowMasterBackground(){ | public boolean getFollowMasterBackground(){ | ||||
return !_slide.isSetShowMasterSp() || _slide.getShowMasterSp(); | return !_slide.isSetShowMasterSp() || _slide.getShowMasterSp(); | ||||
} | } | ||||
/** | |||||
* | |||||
* @return title of this slide or empty string if title is not set | |||||
*/ | |||||
public String getTitle(){ | |||||
XSLFTextShape txt = getTextShapeByType(Placeholder.TITLE); | |||||
return txt == null ? "" : txt.getText(); | |||||
} | |||||
public XSLFTheme getTheme(){ | |||||
return getSlideLayout().getSlideMaster().getTheme(); | |||||
} | |||||
@Override | |||||
public void draw(Graphics2D graphics){ | |||||
if (getFollowMasterBackground()){ | |||||
XSLFSlideLayout layout = getSlideLayout(); | |||||
layout.draw(graphics); | |||||
} | |||||
super.draw(graphics); | |||||
} | |||||
@Override | |||||
public XSLFBackground getBackground(){ | |||||
if(_slide.getCSld().isSetBg()) { | |||||
return new XSLFBackground(_slide.getCSld().getBg(), this); | |||||
} | |||||
return null; | |||||
} | |||||
} | } |
import org.apache.poi.util.Beta; | import org.apache.poi.util.Beta; | ||||
import org.apache.poi.util.Internal; | import org.apache.poi.util.Internal; | ||||
import org.apache.xmlbeans.XmlException; | import org.apache.xmlbeans.XmlException; | ||||
import org.apache.xmlbeans.XmlObject; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideLayout; | import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideLayout; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.SldLayoutDocument; | import org.openxmlformats.schemas.presentationml.x2006.main.SldLayoutDocument; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMaster; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.util.Map; | |||||
import java.util.HashMap; | |||||
import java.awt.*; | |||||
import java.awt.geom.AffineTransform; | |||||
@Beta | @Beta | ||||
public class XSLFSlideLayout extends XSLFSheet { | public class XSLFSlideLayout extends XSLFSheet { | ||||
* @return slide master. Never null. | * @return slide master. Never null. | ||||
* @throws IllegalStateException if slide master was not found | * @throws IllegalStateException if slide master was not found | ||||
*/ | */ | ||||
@Override | |||||
public XSLFSlideMaster getSlideMaster(){ | public XSLFSlideMaster getSlideMaster(){ | ||||
if(_master == null){ | if(_master == null){ | ||||
for (POIXMLDocumentPart p : getRelations()) { | for (POIXMLDocumentPart p : getRelations()) { | ||||
public XMLSlideShow getSlideShow() { | public XMLSlideShow getSlideShow() { | ||||
return (XMLSlideShow)getParent().getParent(); | return (XMLSlideShow)getParent().getParent(); | ||||
} | } | ||||
public XSLFTheme getTheme(){ | |||||
return getSlideMaster().getTheme(); | |||||
} | |||||
@Override | |||||
protected CTTextListStyle getTextProperties(Placeholder textType) { | |||||
XSLFTextShape lp = getTextShapeByType(textType); | |||||
CTTextListStyle props = lp.getTextBody(false).getLstStyle(); | |||||
return props; | |||||
} | |||||
/** | |||||
* Render this sheet into the supplied graphics object | |||||
* | |||||
*/ | |||||
@Override | |||||
protected boolean canDraw(XSLFShape shape){ | |||||
if(shape instanceof XSLFSimpleShape){ | |||||
XSLFSimpleShape txt = (XSLFSimpleShape)shape; | |||||
CTPlaceholder ph = txt.getCTPlaceholder(); | |||||
if(ph != null) { | |||||
return false; | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
@Override | |||||
public XSLFBackground getBackground(){ | |||||
if(_layout.getCSld().isSetBg()) { | |||||
return new XSLFBackground(_layout.getCSld().getBg(), this); | |||||
} | |||||
return null; | |||||
} | |||||
} | } |
import org.apache.xmlbeans.XmlException; | import org.apache.xmlbeans.XmlException; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMaster; | import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMaster; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.SldMasterDocument; | import org.openxmlformats.schemas.presentationml.x2006.main.SldMasterDocument; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterTextStyles; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||
} | } | ||||
return _theme; | return _theme; | ||||
} | } | ||||
protected CTTextListStyle getTextProperties(Placeholder textType) { | |||||
CTTextListStyle props; | |||||
CTSlideMasterTextStyles txStyles = getXmlObject().getTxStyles(); | |||||
switch (textType){ | |||||
case TITLE: | |||||
case CENTERED_TITLE: | |||||
case SUBTITLE: | |||||
props = txStyles.getTitleStyle(); | |||||
break; | |||||
case BODY: | |||||
props = txStyles.getBodyStyle(); | |||||
break; | |||||
default: | |||||
props = txStyles.getOtherStyle(); | |||||
break; | |||||
} | |||||
return props; | |||||
} | |||||
} | } |
gr.setUri(TABLE_URI); | gr.setUri(TABLE_URI); | ||||
return frame; | return frame; | ||||
} | } | ||||
public Rectangle2D getAnchor(){ | |||||
CTTransform2D xfrm = getXmlObject().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)); | |||||
} | |||||
public void setAnchor(Rectangle2D anchor){ | |||||
CTTransform2D xfrm = getXmlObject().getXfrm(); | |||||
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); | |||||
} | |||||
} | } |
import org.apache.poi.sl.usermodel.ShapeContainer; | import org.apache.poi.sl.usermodel.ShapeContainer; | ||||
import org.apache.poi.util.Beta; | import org.apache.poi.util.Beta; | ||||
import org.apache.poi.util.Units; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; | import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; | import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; | import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; | import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; | import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps; | import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; | import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; | import org.openxmlformats.schemas.presentationml.x2006.main.CTShape; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual; | import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; | import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; | ||||
import java.awt.geom.Rectangle2D; | |||||
/** | /** | ||||
* @author Yegor Kozlov | * @author Yegor Kozlov | ||||
nv.addNewPh().setType(STPlaceholderType.Enum.forInt(placeholder.ordinal() + 1)); | nv.addNewPh().setType(STPlaceholderType.Enum.forInt(placeholder.ordinal() + 1)); | ||||
} | } | ||||
} | } | ||||
public Placeholder getPlaceholder(){ | |||||
CTShape sh = (CTShape)getXmlObject(); | |||||
CTPlaceholder ph = sh.getNvSpPr().getNvPr().getPh(); | |||||
if(ph == null) return null; | |||||
else { | |||||
int val = ph.getType().intValue(); | |||||
return Placeholder.values()[val - 1]; | |||||
} | |||||
} | |||||
} | } |
import org.apache.poi.util.Beta; | import org.apache.poi.util.Beta; | ||||
import org.apache.poi.util.Internal; | import org.apache.poi.util.Internal; | ||||
import org.apache.poi.util.Units; | import org.apache.poi.util.Units; | ||||
import org.apache.poi.xslf.model.PropertyFetcher; | |||||
import org.apache.poi.xslf.model.ParagraphPropertyFetcher; | |||||
import org.apache.xmlbeans.XmlObject; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; | import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; | import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; | import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacing; | import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacing; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType; | import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import java.util.List; | import java.util.List; | ||||
import java.awt.*; | |||||
import java.awt.geom.Rectangle2D; | |||||
import java.awt.font.TextLayout; | |||||
import java.awt.font.TextAttribute; | |||||
import java.awt.font.LineBreakMeasurer; | |||||
import java.text.AttributedString; | |||||
import java.text.AttributedCharacterIterator; | |||||
/** | /** | ||||
* Represents a paragraph of text within the containing text body. | * Represents a paragraph of text within the containing text body. | ||||
private final CTTextParagraph _p; | private final CTTextParagraph _p; | ||||
private final List<XSLFTextRun> _runs; | private final List<XSLFTextRun> _runs; | ||||
private final XSLFTextShape _shape; | private final XSLFTextShape _shape; | ||||
private List<TextFragment> _lines; | |||||
private TextFragment _bullet; | |||||
XSLFTextParagraph(CTTextParagraph p, XSLFTextShape shape){ | XSLFTextParagraph(CTTextParagraph p, XSLFTextShape shape){ | ||||
_p = p; | _p = p; | ||||
_runs = new ArrayList<XSLFTextRun>(); | _runs = new ArrayList<XSLFTextRun>(); | ||||
_shape = shape; | _shape = shape; | ||||
for (CTRegularTextRun r : _p.getRList()) { | for (CTRegularTextRun r : _p.getRList()) { | ||||
_runs.add(new XSLFTextRun(r, this)); | _runs.add(new XSLFTextRun(r, this)); | ||||
} | } | ||||
for (CTTextField f : _p.getFldList()) { | |||||
CTRegularTextRun r = CTRegularTextRun.Factory.newInstance(); | |||||
r.setT(f.getT()); | |||||
_runs.add(new XSLFTextRun(r, this)); | |||||
} | |||||
} | } | ||||
public String getText(){ | public String getText(){ | ||||
StringBuilder out = new StringBuilder(); | StringBuilder out = new StringBuilder(); | ||||
for (CTRegularTextRun r : _p.getRList()) { | |||||
out.append(r.getT()); | |||||
for (XSLFTextRun r : _runs) { | |||||
out.append(r.getText()); | |||||
} | } | ||||
return out.toString(); | return out.toString(); | ||||
} | } | ||||
* @return ??? alignment that is applied to the paragraph | * @return ??? alignment that is applied to the paragraph | ||||
*/ | */ | ||||
public TextAlign getTextAlign(){ | public TextAlign getTextAlign(){ | ||||
CTTextParagraphProperties pr = _p.getPPr(); | |||||
if(pr == null || !pr.isSetAlgn()) return TextAlign.LEFT; | |||||
return TextAlign.values()[pr.getAlgn().intValue() - 1]; | |||||
ParagraphPropertyFetcher<TextAlign> fetcher = new ParagraphPropertyFetcher<TextAlign>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetAlgn()){ | |||||
TextAlign val = TextAlign.values()[props.getAlgn().intValue() - 1]; | |||||
setValue(val); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue() == null ? TextAlign.LEFT : fetcher.getValue(); | |||||
} | } | ||||
/** | /** | ||||
} | } | ||||
} | } | ||||
/** | |||||
* @return the font to be used on bullet characters within a given paragraph | |||||
*/ | |||||
public String getBulletFont(){ | |||||
ParagraphPropertyFetcher<String> fetcher = new ParagraphPropertyFetcher<String>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetBuFont()){ | |||||
setValue(props.getBuFont().getTypeface()); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue(); | |||||
} | |||||
/** | |||||
* @return the character to be used in place of the standard bullet point | |||||
*/ | |||||
public String getBulletCharacter(){ | |||||
ParagraphPropertyFetcher<String> fetcher = new ParagraphPropertyFetcher<String>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetBuChar()){ | |||||
setValue(props.getBuChar().getChar()); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue(); | |||||
} | |||||
public Color getBulletFontColor(){ | |||||
final XSLFTheme theme = getParentShape().getSheet().getTheme(); | |||||
ParagraphPropertyFetcher<Color> fetcher = new ParagraphPropertyFetcher<Color>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetBuClr()){ | |||||
setValue(theme.getColor(props.getBuClr())); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue(); | |||||
} | |||||
public double getBulletFontSize(){ | |||||
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetBuSzPct()){ | |||||
setValue(props.getBuSzPct().getVal() * 0.001); | |||||
return true; | |||||
} | |||||
if(props.isSetBuSzPts()){ | |||||
setValue( - props.getBuSzPts().getVal() * 0.01); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue() == null ? 100 : fetcher.getValue(); | |||||
} | |||||
/** | /** | ||||
* Specifies the indent size that will be applied to the first line of text in the paragraph. | * Specifies the indent size that will be applied to the first line of text in the paragraph. | ||||
* | * | ||||
* @return the indent applied to the first line of text in the paragraph. | * @return the indent applied to the first line of text in the paragraph. | ||||
*/ | */ | ||||
public double getIndent(){ | public double getIndent(){ | ||||
CTTextParagraphProperties pr = _p.getPPr(); | |||||
if(pr == null || !pr.isSetIndent()) return 0; | |||||
return Units.toPoints(pr.getIndent()); | |||||
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetIndent()){ | |||||
setValue(Units.toPoints(props.getIndent())); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue() == null ? 0 : fetcher.getValue(); | |||||
} | } | ||||
/** | /** | ||||
* @return the left margin of the paragraph | * @return the left margin of the paragraph | ||||
*/ | */ | ||||
public double getLeftMargin(){ | public double getLeftMargin(){ | ||||
CTTextParagraphProperties pr = _p.getPPr(); | |||||
if(pr == null || !pr.isSetMarL()) return 0; | |||||
return Units.toPoints(pr.getMarL()); | |||||
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetMarL()){ | |||||
double val = Units.toPoints(props.getMarL()); | |||||
setValue(val); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue() == null ? 0 : fetcher.getValue(); | |||||
} | } | ||||
/** | /** | ||||
* @return the vertical line spacing. | * @return the vertical line spacing. | ||||
*/ | */ | ||||
public double getLineSpacing(){ | public double getLineSpacing(){ | ||||
CTTextParagraphProperties pr = _p.getPPr(); | |||||
if(pr == null || !pr.isSetLnSpc()) return 100; // TODO fetch from master | |||||
CTTextSpacing spc = pr.getLnSpc(); | |||||
if(spc.isSetSpcPct()) return spc.getSpcPct().getVal()*0.001; | |||||
else if (spc.isSetSpcPts()) return -spc.getSpcPts().getVal()*0.01; | |||||
else return 100; | |||||
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetLnSpc()){ | |||||
CTTextSpacing spc = props.getLnSpc(); | |||||
if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 ); | |||||
else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 ); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue() == null ? 100 : fetcher.getValue(); | |||||
} | } | ||||
/** | /** | ||||
* @return the vertical white space before the paragraph | * @return the vertical white space before the paragraph | ||||
*/ | */ | ||||
public double getSpaceBefore(){ | public double getSpaceBefore(){ | ||||
CTTextParagraphProperties pr = _p.getPPr(); | |||||
if(pr == null || !pr.isSetSpcBef()) return 0; // TODO fetch from master | |||||
CTTextSpacing spc = pr.getSpcBef(); | |||||
if(spc.isSetSpcPct()) return spc.getSpcPct().getVal()*0.001; | |||||
else if (spc.isSetSpcPts()) return -spc.getSpcPts().getVal()*0.01; | |||||
else return 0; | |||||
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetSpcBef()){ | |||||
CTTextSpacing spc = props.getSpcBef(); | |||||
if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 ); | |||||
else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 ); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue() == null ? 0 : fetcher.getValue(); | |||||
} | } | ||||
/** | /** | ||||
* @return the vertical white space after the paragraph | * @return the vertical white space after the paragraph | ||||
*/ | */ | ||||
public double getSpaceAfter(){ | public double getSpaceAfter(){ | ||||
CTTextParagraphProperties pr = _p.getPPr(); | |||||
if(pr == null || !pr.isSetSpcAft()) return 0; // TODO fetch from master | |||||
CTTextSpacing spc = pr.getSpcAft(); | |||||
if(spc.isSetSpcPct()) return spc.getSpcPct().getVal()*0.001; | |||||
else if (spc.isSetSpcPts()) return -spc.getSpcPts().getVal()*0.01; | |||||
else return 0; | |||||
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetSpcAft()){ | |||||
CTTextSpacing spc = props.getSpcAft(); | |||||
if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 ); | |||||
else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 ); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue() == null ? 0 : fetcher.getValue(); | |||||
} | } | ||||
/** | /** | ||||
} | } | ||||
/** | |||||
* Returns whether this paragraph has bullets | |||||
*/ | |||||
public boolean isBullet() { | |||||
ParagraphPropertyFetcher<Boolean> fetcher = new ParagraphPropertyFetcher<Boolean>(getLevel()){ | |||||
public boolean fetch(CTTextParagraphProperties props){ | |||||
if(props.isSetBuNone()) { | |||||
setValue(false); | |||||
return true; | |||||
} | |||||
if(props.isSetBuFont()){ | |||||
setValue(true); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchParagraphProperty(fetcher); | |||||
return fetcher.getValue() == null ? false : fetcher.getValue(); | |||||
} | |||||
@Override | @Override | ||||
public String toString(){ | public String toString(){ | ||||
return "[" + getClass() + "]" + getText(); | return "[" + getClass() + "]" + getText(); | ||||
} | } | ||||
public List<TextFragment> getTextLines(){ | |||||
return _lines; | |||||
} | |||||
public double draw(Graphics2D graphics, double x, double y){ | |||||
double marginLeft = _shape.getMarginLeft(); | |||||
double marginRight = _shape.getMarginRight(); | |||||
Rectangle2D anchor = _shape.getAnchor(); | |||||
double penY = y; | |||||
double textOffset = getLeftMargin(); | |||||
for(TextFragment line : _lines){ | |||||
double penX = x; | |||||
switch (getTextAlign()) { | |||||
case CENTER: | |||||
penX += textOffset + (anchor.getWidth() - textOffset - line.getWidth() - marginLeft - marginRight) / 2; | |||||
break; | |||||
case RIGHT: | |||||
penX += (anchor.getWidth() - line.getWidth() - marginLeft - marginRight); | |||||
break; | |||||
default: | |||||
penX = x + textOffset; | |||||
break; | |||||
} | |||||
if(_bullet != null){ | |||||
_bullet.draw(graphics, penX + getIndent(), penY); | |||||
} | |||||
line.draw(graphics, penX, penY); | |||||
//The vertical line spacing | |||||
double spacing = getLineSpacing(); | |||||
if(spacing > 0) { | |||||
// If linespacing >= 0, then linespacing is a percentage of normal line height. | |||||
penY += spacing*0.01*line.getHeight(); | |||||
} else { | |||||
// positive value means absolute spacing in points | |||||
penY += -spacing; | |||||
} | |||||
} | |||||
return penY - y; | |||||
} | |||||
static class TextFragment { | |||||
private TextLayout _layout; | |||||
private AttributedString _str; | |||||
TextFragment(TextLayout layout, AttributedString str){ | |||||
_layout = layout; | |||||
_str = str; | |||||
} | |||||
void draw(Graphics2D graphics, double x, double y){ | |||||
double yBaseline = y + _layout.getAscent(); | |||||
graphics.drawString(_str.getIterator(), (float)x, (float)yBaseline ); | |||||
} | |||||
public float getHeight(){ | |||||
return _layout.getAscent() + _layout.getDescent() + _layout.getLeading(); | |||||
} | |||||
public float getWidth(){ | |||||
return _layout.getAdvance(); | |||||
} | |||||
} | |||||
public AttributedString getAttributedString(){ | |||||
String text = getText(); | |||||
AttributedString string = new AttributedString(text); | |||||
int startIndex = 0; | |||||
for (XSLFTextRun run : _runs){ | |||||
int length = run.getText().length(); | |||||
if(length == 0) { | |||||
// skip empty runs | |||||
continue; | |||||
} | |||||
int endIndex = startIndex + length; | |||||
string.addAttribute(TextAttribute.FOREGROUND, run.getFontColor(), startIndex, endIndex); | |||||
string.addAttribute(TextAttribute.FAMILY, run.getFontFamily(), startIndex, endIndex); | |||||
string.addAttribute(TextAttribute.SIZE, run.getFontSize(), startIndex, endIndex); | |||||
if(run.isBold()) { | |||||
string.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, startIndex, endIndex); | |||||
} | |||||
if(run.isItalic()) { | |||||
string.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, startIndex, endIndex); | |||||
} | |||||
if(run.isUnderline()) { | |||||
string.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, startIndex, endIndex); | |||||
} | |||||
if(run.isStrikethrough()) { | |||||
string.addAttribute(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON, startIndex, endIndex); | |||||
} | |||||
startIndex = endIndex; | |||||
} | |||||
return string; | |||||
} | |||||
void breakText(Graphics2D graphics){ | |||||
_lines = new ArrayList<TextFragment>(); | |||||
AttributedString at = getAttributedString(); | |||||
AttributedCharacterIterator it = at.getIterator(); | |||||
if(it.getBeginIndex() == it.getEndIndex()) { | |||||
return; | |||||
} | |||||
LineBreakMeasurer measurer = new LineBreakMeasurer(it, graphics.getFontRenderContext()); | |||||
for (;;) { | |||||
int startIndex = measurer.getPosition(); | |||||
double wrappingWidth = getWrappingWidth() + 1; // add a pixel to compensate rounding errors | |||||
TextLayout layout = measurer.nextLayout((float)wrappingWidth, it.getEndIndex(), true); | |||||
if (layout == null) { | |||||
// layout can be null if the entire word at the current position | |||||
// does not fit within the wrapping width. Try with requireNextWord=false. | |||||
layout = measurer.nextLayout((float)wrappingWidth, it.getEndIndex(), false); | |||||
} | |||||
int endIndex = measurer.getPosition(); | |||||
if(getTextAlign() == TextAlign.JUSTIFY) { | |||||
layout = layout.getJustifiedLayout((float)wrappingWidth); | |||||
} | |||||
AttributedString str = new AttributedString(it, startIndex, endIndex); | |||||
TextFragment line = new TextFragment(layout, str); | |||||
_lines.add(line); | |||||
if(endIndex == it.getEndIndex()) break; | |||||
} | |||||
if(isBullet()) { | |||||
String buCharacter = getBulletCharacter(); | |||||
String buFont = getBulletFont(); | |||||
if(buCharacter != null && buFont != null && _lines.size() > 0) { | |||||
AttributedString str = new AttributedString(buCharacter); | |||||
TextFragment firstLine = _lines.get(0); | |||||
AttributedCharacterIterator bit = firstLine._str.getIterator(); | |||||
Color buColor = getBulletFontColor(); | |||||
str.addAttribute(TextAttribute.FOREGROUND, buColor == null ? | |||||
bit.getAttribute(TextAttribute.FOREGROUND) : buColor); | |||||
str.addAttribute(TextAttribute.FAMILY, buFont); | |||||
double fontSize = (Double)bit.getAttribute(TextAttribute.SIZE); | |||||
double buSz = getBulletFontSize(); | |||||
if(buSz > 0) fontSize *= buSz* 0.01; | |||||
else fontSize = -buSz; | |||||
str.addAttribute(TextAttribute.SIZE, fontSize); | |||||
TextLayout layout = new TextLayout(str.getIterator(), graphics.getFontRenderContext()); | |||||
_bullet = new TextFragment(layout, str); | |||||
} | |||||
} | |||||
} | |||||
double getWrappingWidth(){ | |||||
double width; | |||||
if(!_shape.getWordWrap()) { | |||||
width = _shape.getSheet().getSlideShow().getPageSize().getWidth(); | |||||
} else { | |||||
width = _shape.getAnchor().getWidth() - | |||||
_shape.getMarginLeft() - _shape.getMarginRight() - getLeftMargin(); | |||||
} | |||||
return width; | |||||
} | |||||
CTTextParagraphProperties getDefaultStyle(){ | |||||
CTPlaceholder ph = _shape.getCTPlaceholder(); | |||||
String defaultStyleSelector; | |||||
if(ph == null) defaultStyleSelector = "otherStyle"; | |||||
else { | |||||
switch(ph.getType().intValue()){ | |||||
case STPlaceholderType.INT_TITLE: | |||||
case STPlaceholderType.INT_CTR_TITLE: | |||||
defaultStyleSelector = "titleStyle"; | |||||
break; | |||||
case STPlaceholderType.INT_FTR: | |||||
case STPlaceholderType.INT_SLD_NUM: | |||||
case STPlaceholderType.INT_DT: | |||||
defaultStyleSelector = "otherStyle"; | |||||
break; | |||||
default: | |||||
defaultStyleSelector = "bodyStyle"; | |||||
break; | |||||
} | |||||
} | |||||
int level = getLevel(); | |||||
XmlObject[] o = _shape.getSheet().getSlideMaster().getXmlObject().selectPath( | |||||
"declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " + | |||||
"declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' " + | |||||
".//p:txStyles/p:" + defaultStyleSelector +"/a:lvl" +(level+1)+ "pPr"); | |||||
if(o.length == 1){ | |||||
return (CTTextParagraphProperties)o[0]; | |||||
} | |||||
throw new IllegalArgumentException("Failed to fetch default style for " + | |||||
defaultStyleSelector + " and level=" + level); | |||||
} | |||||
private boolean fetchParagraphProperty(ParagraphPropertyFetcher visitor){ | |||||
boolean ok = false; | |||||
if(_p.isSetPPr()) ok = visitor.fetch(_p.getPPr()); | |||||
if(!ok) { | |||||
XSLFTextShape shape = getParentShape(); | |||||
ok = shape.fetchShapeProperty(visitor); | |||||
if(!ok) { | |||||
CTTextParagraphProperties defaultProps = getDefaultStyle(); | |||||
if(defaultProps != null) ok = visitor.fetch(defaultProps); | |||||
} | |||||
} | |||||
return ok; | |||||
} | |||||
} | } |
package org.apache.poi.xslf.usermodel; | package org.apache.poi.xslf.usermodel; | ||||
import org.apache.poi.util.Beta; | import org.apache.poi.util.Beta; | ||||
import org.apache.poi.xslf.model.CharacterPropertyFetcher; | |||||
import org.apache.xmlbeans.XmlObject; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; | import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; | import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; | import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont; | import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType; | import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType; | import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; | |||||
import java.awt.*; | import java.awt.*; | ||||
clr.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()}); | clr.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()}); | ||||
} | } | ||||
public Color getFontColor(){ | |||||
final XSLFTheme theme = _p.getParentShape().getSheet().getTheme(); | |||||
CharacterPropertyFetcher<Color> fetcher = new CharacterPropertyFetcher<Color>(_p.getLevel()){ | |||||
public boolean fetch(CTTextCharacterProperties props){ | |||||
CTSolidColorFillProperties solidFill = props.getSolidFill(); | |||||
if(solidFill != null){ | |||||
setValue(theme.getSolidFillColor(solidFill)); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchCharacterProperty(fetcher); | |||||
return fetcher.getValue(); | |||||
} | |||||
/** | /** | ||||
* | * | ||||
* @param fontSize font size in points. | * @param fontSize font size in points. | ||||
* @return font size in points or -1 if font size is not set. | * @return font size in points or -1 if font size is not set. | ||||
*/ | */ | ||||
public double getFontSize(){ | public double getFontSize(){ | ||||
if(!_r.isSetRPr() || !_r.getRPr().isSetSz()) return -1; | |||||
return _r.getRPr().getSz()*0.01; | |||||
CharacterPropertyFetcher<Double> fetcher = new CharacterPropertyFetcher<Double>(_p.getLevel()){ | |||||
public boolean fetch(CTTextCharacterProperties props){ | |||||
if(props.isSetSz()){ | |||||
setValue(props.getSz()*0.01); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchCharacterProperty(fetcher); | |||||
return fetcher.getValue() == null ? -1 : fetcher.getValue(); | |||||
} | } | ||||
/** | /** | ||||
} | } | ||||
/** | /** | ||||
* @return font family or null if niot set | |||||
* @return font family or null if not set | |||||
*/ | */ | ||||
public String getFontFamily(){ | public String getFontFamily(){ | ||||
if(!_r.isSetRPr() || !_r.getRPr().isSetLatin()) return null; | |||||
final XSLFTheme theme = _p.getParentShape().getSheet().getTheme(); | |||||
CharacterPropertyFetcher<String> visitor = new CharacterPropertyFetcher<String>(_p.getLevel()){ | |||||
public boolean fetch(CTTextCharacterProperties props){ | |||||
CTTextFont font = props.getLatin(); | |||||
if(font != null){ | |||||
String typeface = font.getTypeface(); | |||||
if("+mj-lt".equals(typeface)) { | |||||
typeface = theme.getMajorFont(); | |||||
} else if ("+mn-lt".equals(typeface)){ | |||||
typeface = theme.getMinorFont(); | |||||
} | |||||
setValue(typeface); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchCharacterProperty(visitor); | |||||
return _r.getRPr().getLatin().getTypeface(); | |||||
return visitor.getValue(); | |||||
} | } | ||||
/** | /** | ||||
/** | /** | ||||
* @return whether a run of text will be formatted as strikethrough text. Default is false. | * @return whether a run of text will be formatted as strikethrough text. Default is false. | ||||
*/ | */ | ||||
public boolean isStrikethrough(){ | |||||
if(!_r.isSetRPr()) return false; | |||||
return _r.getRPr().getStrike() == STTextStrikeType.SNG_STRIKE; | |||||
public boolean isStrikethrough() { | |||||
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getLevel()){ | |||||
public boolean fetch(CTTextCharacterProperties props){ | |||||
if(props.isSetStrike()){ | |||||
setValue(props.getStrike() != STTextStrikeType.NO_STRIKE); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchCharacterProperty(fetcher); | |||||
return fetcher.getValue() == null ? false : fetcher.getValue(); | |||||
} | } | ||||
/** | /** | ||||
* @return whether this run of text is formatted as bold text | * @return whether this run of text is formatted as bold text | ||||
*/ | */ | ||||
public boolean isBold(){ | public boolean isBold(){ | ||||
if(!_r.isSetRPr()) return false; | |||||
return _r.getRPr().getB(); | |||||
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getLevel()){ | |||||
public boolean fetch(CTTextCharacterProperties props){ | |||||
if(props.isSetB()){ | |||||
setValue(props.getB()); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchCharacterProperty(fetcher); | |||||
return fetcher.getValue() == null ? false : fetcher.getValue(); | |||||
} | } | ||||
/** | /** | ||||
* @return whether this run of text is formatted as italic text | * @return whether this run of text is formatted as italic text | ||||
*/ | */ | ||||
public boolean isItalic(){ | public boolean isItalic(){ | ||||
if(!_r.isSetRPr()) return false; | |||||
return _r.getRPr().getI(); | |||||
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getLevel()){ | |||||
public boolean fetch(CTTextCharacterProperties props){ | |||||
if(props.isSetI()){ | |||||
setValue(props.getI()); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchCharacterProperty(fetcher); | |||||
return fetcher.getValue() == null ? false : fetcher.getValue(); | |||||
} | } | ||||
/** | /** | ||||
* @return whether this run of text is formatted as underlined text | * @return whether this run of text is formatted as underlined text | ||||
*/ | */ | ||||
public boolean isUnderline(){ | public boolean isUnderline(){ | ||||
if(!_r.isSetRPr() || !_r.getRPr().isSetU()) return false; | |||||
return _r.getRPr().getU() != STTextUnderlineType.NONE; | |||||
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getLevel()){ | |||||
public boolean fetch(CTTextCharacterProperties props){ | |||||
if(props.isSetU()){ | |||||
setValue(props.getU() != STTextUnderlineType.NONE); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchCharacterProperty(fetcher); | |||||
return fetcher.getValue() == null ? false : fetcher.getValue(); | |||||
} | } | ||||
protected CTTextCharacterProperties getRpR(){ | protected CTTextCharacterProperties getRpR(){ | ||||
return new XSLFHyperlink(_r.getRPr().getHlinkClick(), this); | return new XSLFHyperlink(_r.getRPr().getHlinkClick(), this); | ||||
} | } | ||||
private boolean fetchCharacterProperty(CharacterPropertyFetcher fetcher){ | |||||
boolean ok = false; | |||||
if(_r.isSetRPr()) ok = fetcher.fetch(_r.getRPr()); | |||||
if(!ok) { | |||||
XSLFTextShape shape = _p.getParentShape(); | |||||
ok = shape.fetchShapeProperty(fetcher); | |||||
if(!ok) { | |||||
CTTextParagraphProperties defaultProps = _p.getDefaultStyle(); | |||||
if(defaultProps != null) ok = fetcher.fetch(defaultProps); | |||||
} | |||||
} | |||||
return ok; | |||||
} | |||||
} | } |
import org.apache.poi.util.Beta; | import org.apache.poi.util.Beta; | ||||
import org.apache.poi.util.Units; | import org.apache.poi.util.Units; | ||||
import org.apache.poi.xslf.model.PropertyFetcher; | |||||
import org.apache.poi.xslf.model.TextBodyPropertyFetcher; | |||||
import org.apache.xmlbeans.XmlObject; | import org.apache.xmlbeans.XmlObject; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; | import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties; | import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; | import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType; | import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.STTextVerticalType; | import org.openxmlformats.schemas.drawingml.x2006.main.STTextVerticalType; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.STTextWrappingType; | import org.openxmlformats.schemas.drawingml.x2006.main.STTextWrappingType; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; | |||||
import java.awt.*; | import java.awt.*; | ||||
import java.awt.image.BufferedImage; | |||||
import java.awt.geom.Rectangle2D; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.List; | import java.util.List; | ||||
return paragraph; | return paragraph; | ||||
} | } | ||||
/** | |||||
* Specifies a solid color fill. The shape is filled entirely with the specified color. | |||||
* | |||||
* @param color the solid color fill. | |||||
* The value of <code>null</code> unsets the solidFIll attribute from the underlying xml | |||||
*/ | |||||
public void setFillColor(Color color) { | |||||
CTShapeProperties spPr = getSpPr(); | |||||
if (color == null) { | |||||
if(spPr.isSetSolidFill()) spPr.unsetSolidFill(); | |||||
} | |||||
else { | |||||
CTSolidColorFillProperties fill = spPr.isSetSolidFill() ? spPr.getSolidFill() : spPr.addNewSolidFill(); | |||||
CTSRgbColor rgb = CTSRgbColor.Factory.newInstance(); | |||||
rgb.setVal(new byte[]{(byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()}); | |||||
fill.setSrgbClr(rgb); | |||||
} | |||||
} | |||||
/** | |||||
* | |||||
* @return solid fill color of null if not set | |||||
*/ | |||||
public Color getFillColor(){ | |||||
CTShapeProperties spPr = getSpPr(); | |||||
if(!spPr.isSetSolidFill() ) return null; | |||||
CTSolidColorFillProperties fill = spPr.getSolidFill(); | |||||
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]); | |||||
} | |||||
/** | /** | ||||
* Sets the type of vertical alignment for the text. | * Sets the type of vertical alignment for the text. | ||||
* @return the type of alignment | * @return the type of alignment | ||||
*/ | */ | ||||
public VerticalAlignment getVerticalAlignment(){ | public VerticalAlignment getVerticalAlignment(){ | ||||
CTTextBodyProperties bodyPr = getTextBodyPr(); | |||||
if (bodyPr != null) { | |||||
STTextAnchoringType.Enum val = bodyPr.getAnchor(); | |||||
if(val != null){ | |||||
return VerticalAlignment.values()[val.intValue() - 1]; | |||||
PropertyFetcher<VerticalAlignment> fetcher = new TextBodyPropertyFetcher<VerticalAlignment>(){ | |||||
public boolean fetch(CTTextBodyProperties props){ | |||||
if(props.isSetAnchor()){ | |||||
int val = props.getAnchor().intValue(); | |||||
setValue(VerticalAlignment.values()[val - 1]); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | } | ||||
} | |||||
return VerticalAlignment.TOP; | |||||
}; | |||||
fetchShapeProperty(fetcher); | |||||
return fetcher.getValue() == null ? VerticalAlignment.TOP : fetcher.getValue(); | |||||
} | } | ||||
/** | /** | ||||
* @return the bottom margin or -1 if not set | * @return the bottom margin or -1 if not set | ||||
*/ | */ | ||||
public double getMarginBottom(){ | public double getMarginBottom(){ | ||||
CTTextBodyProperties bodyPr = getTextBodyPr(); | |||||
if (bodyPr != null) { | |||||
return bodyPr.isSetBIns() ? Units.toPoints(bodyPr.getBIns()) : -1; | |||||
} | |||||
return -1; | |||||
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){ | |||||
public boolean fetch(CTTextBodyProperties props){ | |||||
if(props.isSetBIns()){ | |||||
double val = Units.toPoints(props.getBIns()); | |||||
setValue(val); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchShapeProperty(fetcher); | |||||
return fetcher.getValue() == null ? 0 : fetcher.getValue(); | |||||
} | } | ||||
/** | /** | ||||
* @return the left margin | * @return the left margin | ||||
*/ | */ | ||||
public double getMarginLeft(){ | public double getMarginLeft(){ | ||||
CTTextBodyProperties bodyPr = getTextBodyPr(); | |||||
if (bodyPr != null) { | |||||
return bodyPr.isSetLIns() ? Units.toPoints(bodyPr.getLIns()) : -1; | |||||
} | |||||
return -1; | |||||
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){ | |||||
public boolean fetch(CTTextBodyProperties props){ | |||||
if(props.isSetLIns()){ | |||||
double val = Units.toPoints(props.getLIns()); | |||||
setValue(val); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchShapeProperty(fetcher); | |||||
return fetcher.getValue() == null ? 0 : fetcher.getValue(); | |||||
} | } | ||||
/** | /** | ||||
* @return the right margin | * @return the right margin | ||||
*/ | */ | ||||
public double getMarginRight(){ | public double getMarginRight(){ | ||||
CTTextBodyProperties bodyPr = getTextBodyPr(); | |||||
if (bodyPr != null) { | |||||
return bodyPr.isSetRIns() ? Units.toPoints(bodyPr.getRIns()) : -1; | |||||
} | |||||
return -1; | |||||
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){ | |||||
public boolean fetch(CTTextBodyProperties props){ | |||||
if(props.isSetRIns()){ | |||||
double val = Units.toPoints(props.getRIns()); | |||||
setValue(val); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchShapeProperty(fetcher); | |||||
return fetcher.getValue() == null ? 0 : fetcher.getValue(); | |||||
} | } | ||||
/** | /** | ||||
* @return the top margin | * @return the top margin | ||||
*/ | */ | ||||
public double getMarginTop(){ | public double getMarginTop(){ | ||||
CTTextBodyProperties bodyPr = getTextBodyPr(); | |||||
if (bodyPr != null) { | |||||
return bodyPr.isSetTIns() ? Units.toPoints(bodyPr.getTIns()) : -1; | |||||
} | |||||
return -1; | |||||
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){ | |||||
public boolean fetch(CTTextBodyProperties props){ | |||||
if(props.isSetTIns()){ | |||||
double val = Units.toPoints(props.getTIns()); | |||||
setValue(val); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchShapeProperty(fetcher); | |||||
return fetcher.getValue() == null ? 0 : fetcher.getValue(); | |||||
} | } | ||||
/** | /** | ||||
* @return the value indicating word wrap | * @return the value indicating word wrap | ||||
*/ | */ | ||||
public boolean getWordWrap(){ | public boolean getWordWrap(){ | ||||
CTTextBodyProperties bodyPr = getTextBodyPr(); | |||||
if (bodyPr != null) { | |||||
return bodyPr.getWrap() == STTextWrappingType.SQUARE; | |||||
} | |||||
return false; | |||||
PropertyFetcher<Boolean> fetcher = new TextBodyPropertyFetcher<Boolean>(){ | |||||
public boolean fetch(CTTextBodyProperties props){ | |||||
if(props.isSetWrap()){ | |||||
setValue(props.getWrap() == STTextWrappingType.SQUARE); | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
}; | |||||
fetchShapeProperty(fetcher); | |||||
return fetcher.getValue() == null ? true : fetcher.getValue(); | |||||
} | } | ||||
/** | /** | ||||
protected abstract CTTextBody getTextBody(boolean create); | 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; | |||||
} | |||||
} | |||||
@Override | |||||
public void draw(Graphics2D graphics){ | |||||
java.awt.Shape outline = getOutline(); | |||||
// shadow | |||||
XSLFShadow shadow = getShadow(); | |||||
if(shadow != null) shadow.draw(graphics); | |||||
//fill | |||||
Color fillColor = getFillColor(); | |||||
if (fillColor != null) { | |||||
graphics.setColor(fillColor); | |||||
applyFill(graphics); | |||||
graphics.fill(outline); | |||||
} | |||||
//border | |||||
Color lineColor = getLineColor(); | |||||
if (lineColor != null){ | |||||
graphics.setColor(lineColor); | |||||
applyStroke(graphics); | |||||
graphics.draw(outline); | |||||
} | |||||
// text | |||||
if(getText().length() > 0) drawText(graphics); | |||||
} | |||||
/** | |||||
* Compute the cumulative height occupied by the text | |||||
*/ | |||||
private double getTextHeight(){ | |||||
// dry-run in a 1x1 image and return the vertical advance | |||||
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); | |||||
return drawParagraphs(img.createGraphics(), 0, 0); | |||||
} | |||||
void breakText(Graphics2D graphics){ | |||||
for(XSLFTextParagraph p : _paragraphs) p.breakText(graphics); | |||||
} | |||||
public void drawText(Graphics2D graphics) { | |||||
breakText(graphics); | |||||
Rectangle2D anchor = getAnchor(); | |||||
double x = anchor.getX() + getMarginLeft(); | |||||
double y = anchor.getY(); | |||||
// first dry-run to calculate the total height of the text | |||||
double textHeight = getTextHeight(); | |||||
switch (getVerticalAlignment()){ | |||||
case TOP: | |||||
y += getMarginTop(); | |||||
break; | |||||
case BOTTOM: | |||||
y += anchor.getHeight() - textHeight - getMarginBottom(); | |||||
break; | |||||
default: | |||||
case MIDDLE: | |||||
double delta = anchor.getHeight() - textHeight - | |||||
getMarginTop() - getMarginBottom(); | |||||
y += getMarginTop() + delta/2; | |||||
break; | |||||
} | |||||
drawParagraphs(graphics, x, y); | |||||
} | |||||
/** | |||||
* pain the paragraphs starting from top left (x,y) | |||||
* | |||||
* @return the vertical advance, i.e. the cumulative space occupied by the text | |||||
*/ | |||||
private double drawParagraphs(Graphics2D graphics, double x, double y) { | |||||
double y0 = y; | |||||
for(int i = 0; i < _paragraphs.size(); i++){ | |||||
XSLFTextParagraph p = _paragraphs.get(i); | |||||
java.util.List<XSLFTextParagraph.TextFragment> lines = p.getTextLines(); | |||||
if(i > 0 && lines.size() > 0) { | |||||
// the amount of vertical white space before the paragraph | |||||
double spaceBefore = p.getSpaceBefore(); | |||||
if(spaceBefore > 0) { | |||||
// positive value means percentage spacing of the height of the first line, e.g. | |||||
// the higher the first line, the bigger the space before the paragraph | |||||
y += spaceBefore*0.01*lines.get(0).getHeight(); | |||||
} else { | |||||
// negative value means the absolute spacing in points | |||||
y += -spaceBefore; | |||||
} | |||||
} | |||||
y += p.draw(graphics, x, y); | |||||
if(i < _paragraphs.size() - 1) { | |||||
double spaceAfter = p.getSpaceAfter(); | |||||
if(spaceAfter > 0) { | |||||
// positive value means percentage spacing of the height of the last line, e.g. | |||||
// the higher the last line, the bigger the space after the paragraph | |||||
y += spaceAfter*0.01*lines.get(lines.size() - 1).getHeight(); | |||||
} else { | |||||
// negative value means the absolute spacing in points | |||||
y += -spaceAfter; | |||||
} | |||||
} | |||||
} | |||||
return y - y0; | |||||
} | |||||
} | } |
import org.apache.poi.util.Beta; | import org.apache.poi.util.Beta; | ||||
import org.apache.poi.util.Internal; | import org.apache.poi.util.Internal; | ||||
import org.apache.xmlbeans.XmlException; | import org.apache.xmlbeans.XmlException; | ||||
import org.apache.xmlbeans.XmlObject; | |||||
import org.apache.xmlbeans.XmlOptions; | import org.apache.xmlbeans.XmlOptions; | ||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideLayout; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.SldLayoutDocument; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMaster; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTBaseStyles; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTColor; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTColorScheme; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument; | import org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeStyleSheet; | import org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeStyleSheet; | ||||
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetColor; | |||||
import javax.xml.namespace.QName; | import javax.xml.namespace.QName; | ||||
import java.awt.Color; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.io.OutputStream; | import java.io.OutputStream; | ||||
import java.util.Map; | import java.util.Map; | ||||
@Beta | @Beta | ||||
public class XSLFTheme extends POIXMLDocumentPart { | public class XSLFTheme extends POIXMLDocumentPart { | ||||
private CTOfficeStyleSheet _theme; | private CTOfficeStyleSheet _theme; | ||||
private Map<String, XSLFColor> _schemeColors; | |||||
XSLFTheme() { | XSLFTheme() { | ||||
super(); | super(); | ||||
_theme = CTOfficeStyleSheet.Factory.newInstance(); | _theme = CTOfficeStyleSheet.Factory.newInstance(); | ||||
ThemeDocument doc = | ThemeDocument doc = | ||||
ThemeDocument.Factory.parse(getPackagePart().getInputStream()); | ThemeDocument.Factory.parse(getPackagePart().getInputStream()); | ||||
_theme = doc.getTheme(); | _theme = doc.getTheme(); | ||||
initialize(); | |||||
} | } | ||||
private void initialize(){ | |||||
CTBaseStyles elems = _theme.getThemeElements(); | |||||
CTColorScheme scheme = elems.getClrScheme(); | |||||
// The color scheme is responsible for defining a list of twelve colors. | |||||
_schemeColors = new HashMap<String, XSLFColor>(12); | |||||
for(XmlObject o : scheme.selectPath("*")){ | |||||
CTColor c = (CTColor)o; | |||||
String name = c.getDomNode().getLocalName(); | |||||
_schemeColors.put(name, new XSLFColor(c)); | |||||
} | |||||
_schemeColors.put("bg1", _schemeColors.get("lt1")); | |||||
_schemeColors.put("bg2", _schemeColors.get("lt2")); | |||||
_schemeColors.put("tx1", _schemeColors.get("dk1")); | |||||
_schemeColors.put("tx2", _schemeColors.get("dk2")); | |||||
} | |||||
public String getName(){ | public String getName(){ | ||||
return _theme.getName(); | return _theme.getName(); | ||||
} | } | ||||
/** | /** | ||||
* Get a color from the theme's color scheme by name | |||||
* | |||||
* @return a theme color or <code>null</code> if not found | |||||
*/ | |||||
public XSLFColor getColor(String name){ | |||||
return _schemeColors.get(name); | |||||
} | |||||
Color getSchemeColor(CTSchemeColor schemeColor){ | |||||
String colorRef = schemeColor.getVal().toString(); | |||||
int alpha = 0xFF; | |||||
if(schemeColor.sizeOfAlphaArray() > 0){ | |||||
int aval = schemeColor.getAlphaArray(0).getVal(); | |||||
alpha = Math.round(255 * aval / 100000f); | |||||
} | |||||
Color themeColor = _schemeColors.get(colorRef).getColor(alpha); | |||||
int lumMod = 100, lumOff = 0; | |||||
if (schemeColor.sizeOfLumModArray() > 0) { | |||||
lumMod = schemeColor.getLumModArray(0).getVal() / 1000; | |||||
} | |||||
if (schemeColor.sizeOfLumOffArray() > 0) { | |||||
lumOff = schemeColor.getLumOffArray(0).getVal() / 1000; | |||||
} | |||||
if(schemeColor.sizeOfShadeArray() > 0) { | |||||
lumMod = schemeColor.getShadeArray(0).getVal() / 1000; | |||||
} | |||||
Color color = modulateLuminanace(themeColor, lumMod, lumOff); | |||||
if(schemeColor.sizeOfTintArray() > 0) { | |||||
float tint = schemeColor.getTintArray(0).getVal() / 100000f; | |||||
int red = Math.round(tint * themeColor.getRed() + (1 - tint) * 255); | |||||
int green = Math.round(tint * themeColor.getGreen() + (1 - tint) * 255); | |||||
int blue = Math.round(tint * themeColor.getBlue() + (1 - tint) * 255); | |||||
color = new Color(red, green, blue); | |||||
} | |||||
return color; | |||||
} | |||||
/** | |||||
* TODO get rid of code duplication. Re-write to use xpath instead of beans | |||||
*/ | |||||
Color getPresetColor(CTPresetColor presetColor){ | |||||
String colorName = presetColor.getVal().toString(); | |||||
Color color; | |||||
try { | |||||
color = (Color)Color.class.getField(colorName).get(null); | |||||
} catch (Exception e){ | |||||
color = Color.black; | |||||
} | |||||
if(presetColor.sizeOfAlphaArray() > 0){ | |||||
int aval = presetColor.getAlphaArray(0).getVal(); | |||||
int alpha = Math.round(255 * aval / 100000f); | |||||
color = new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha); | |||||
} | |||||
int lumMod = 100, lumOff = 0; | |||||
if (presetColor.sizeOfLumModArray() > 0) { | |||||
lumMod = presetColor.getLumModArray(0).getVal() / 1000; | |||||
} | |||||
if (presetColor.sizeOfLumOffArray() > 0) { | |||||
lumOff = presetColor.getLumOffArray(0).getVal() / 1000; | |||||
} | |||||
if(presetColor.sizeOfShadeArray() > 0) { | |||||
lumMod = presetColor.getShadeArray(0).getVal() / 1000; | |||||
} | |||||
color = modulateLuminanace(color, lumMod, lumOff); | |||||
if(presetColor.sizeOfTintArray() > 0) { | |||||
float tint = presetColor.getTintArray(0).getVal() / 100000f; | |||||
int red = Math.round(tint * color.getRed() + (1 - tint) * 255); | |||||
int green = Math.round(tint * color.getGreen() + (1 - tint) * 255); | |||||
int blue = Math.round(tint * color.getBlue() + (1 - tint) * 255); | |||||
color = new Color(red, green, blue); | |||||
} | |||||
return color; | |||||
} | |||||
public Color brighter(Color color, double tint) { | |||||
int r = color.getRed(); | |||||
int g = color.getGreen(); | |||||
int b = color.getBlue(); | |||||
/* From 2D group: | |||||
* 1. black.brighter() should return grey | |||||
* 2. applying brighter to blue will always return blue, brighter | |||||
* 3. non pure color (non zero rgb) will eventually return white | |||||
*/ | |||||
int i = (int)(1.0/(1.0-tint)); | |||||
if ( r == 0 && g == 0 && b == 0) { | |||||
return new Color(i, i, i); | |||||
} | |||||
if ( r > 0 && r < i ) r = i; | |||||
if ( g > 0 && g < i ) g = i; | |||||
if ( b > 0 && b < i ) b = i; | |||||
return new Color(Math.min((int)(r/tint), 255), | |||||
Math.min((int)(g/tint), 255), | |||||
Math.min((int)(b/tint), 255)); | |||||
} | |||||
Color getSrgbColor(CTSRgbColor srgb){ | |||||
byte[] val = srgb.getVal(); | |||||
int alpha = 0xFF; | |||||
if(srgb.sizeOfAlphaArray() > 0){ | |||||
int aval = srgb.getAlphaArray(0).getVal(); | |||||
alpha = Math.round(255 * aval / 100000f); | |||||
} | |||||
return new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2], alpha); | |||||
} | |||||
Color getSolidFillColor(CTSolidColorFillProperties solidFill){ | |||||
Color color; | |||||
if (solidFill.isSetSrgbClr()) { | |||||
color = getSrgbColor(solidFill.getSrgbClr()); | |||||
} else if (solidFill.isSetSchemeClr()) { | |||||
color = getSchemeColor(solidFill.getSchemeClr()); | |||||
} else { | |||||
// TODO support other types | |||||
color = Color.black; | |||||
} | |||||
return color; | |||||
} | |||||
Color getColor(CTColor solidFill){ | |||||
Color color; | |||||
if (solidFill.isSetSrgbClr()) { | |||||
color = getSrgbColor(solidFill.getSrgbClr()); | |||||
} else if (solidFill.isSetSchemeClr()) { | |||||
color = getSchemeColor(solidFill.getSchemeClr()); | |||||
} else { | |||||
// TODO support other types | |||||
color = Color.black; | |||||
} | |||||
return color; | |||||
} | |||||
/** | |||||
* While developing only! | * While developing only! | ||||
*/ | */ | ||||
@Internal | @Internal | ||||
out.close(); | out.close(); | ||||
} | } | ||||
} | |||||
public static Color modulateLuminanace(Color c, int lumMod, int lumOff) { | |||||
Color color; | |||||
if (lumOff > 0) { | |||||
color = new Color( | |||||
(int) (Math.round((255 - c.getRed()) * (100.0 - lumMod) / 100.0 + c.getRed())), | |||||
(int) (Math.round((255 - c.getGreen()) * lumOff / 100.0 + c.getGreen())), | |||||
(int) (Math.round((255 - c.getBlue()) * lumOff / 100.0 + c.getBlue())), | |||||
c.getAlpha() | |||||
); | |||||
} else { | |||||
color = new Color( | |||||
(int) (Math.round(c.getRed() * lumMod / 100.0)), | |||||
(int) (Math.round(c.getGreen() * lumMod / 100.0)), | |||||
(int) (Math.round(c.getBlue() * lumMod / 100.0)), | |||||
c.getAlpha() | |||||
); | |||||
} | |||||
return color; | |||||
} | |||||
public String getMajorFont(){ | |||||
return _theme.getThemeElements().getFontScheme().getMajorFont().getLatin().getTypeface(); | |||||
} | |||||
public String getMinorFont(){ | |||||
return _theme.getThemeElements().getFontScheme().getMinorFont().getLatin().getTypeface(); | |||||
} | |||||
} |
/* | |||||
* ==================================================================== | |||||
* 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.util; | |||||
import org.apache.poi.openxml4j.opc.OPCPackage; | |||||
import org.apache.poi.xslf.usermodel.XMLSlideShow; | |||||
import org.apache.poi.xslf.usermodel.XSLFSlide; | |||||
import javax.imageio.ImageIO; | |||||
import java.awt.Color; | |||||
import java.awt.Dimension; | |||||
import java.awt.Graphics2D; | |||||
import java.awt.RenderingHints; | |||||
import java.awt.geom.AffineTransform; | |||||
import java.awt.geom.Rectangle2D; | |||||
import java.awt.image.BufferedImage; | |||||
import java.io.File; | |||||
import java.io.FileOutputStream; | |||||
/** | |||||
* Date: 10/11/11 | |||||
* | |||||
* @author Yegor Kozlov | |||||
*/ | |||||
public class PPTX2PNG { | |||||
public static void main(String[] args) throws Exception { | |||||
if (args.length == 0) { | |||||
System.out.println("Usage: PPTX2PNG [options] <pptx file>"); | |||||
return; | |||||
} | |||||
int slidenum = -1; | |||||
float scale = 1; | |||||
String file = null; | |||||
for (int i = 0; i < args.length; i++) { | |||||
if (args[i].startsWith("-")) { | |||||
if ("-scale".equals(args[i])) { | |||||
scale = Float.parseFloat(args[++i]); | |||||
} else if ("-slide".equals(args[i])) { | |||||
slidenum = Integer.parseInt(args[++i]); | |||||
} | |||||
} else { | |||||
file = args[i]; | |||||
} | |||||
} | |||||
System.out.println("Processing " + file); | |||||
XMLSlideShow ppt = new XMLSlideShow(OPCPackage.open(file)); | |||||
Dimension pgsize = ppt.getPageSize(); | |||||
int width = (int) (pgsize.width * scale); | |||||
int height = (int) (pgsize.height * scale); | |||||
XSLFSlide[] slide = ppt.getSlides(); | |||||
for (int i = 0; i < slide.length; i++) { | |||||
if (slidenum != -1 && slidenum != (i + 1)) continue; | |||||
String title = slide[i].getTitle(); | |||||
System.out.println("Rendering slide " + (i + 1) + (title == null ? "" : ": " + title)); | |||||
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); | |||||
Graphics2D graphics = img.createGraphics(); | |||||
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); | |||||
graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); | |||||
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); | |||||
graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); | |||||
graphics.setPaint(Color.white); | |||||
graphics.fill(new Rectangle2D.Float(0, 0, width, height)); | |||||
graphics.scale((double) width / pgsize.width, (double) height / pgsize.height); | |||||
slide[i].draw(graphics); | |||||
String fname = file.replaceAll("\\.pptx", "-" + (i + 1) + ".png"); | |||||
FileOutputStream out = new FileOutputStream(fname); | |||||
ImageIO.write(img, "png", out); | |||||
out.close(); | |||||
} | |||||
System.out.println("Done"); | |||||
} | |||||
} |
if(part.getContentType().equals(XSLFRelation.MAIN.getContentType())) { | if(part.getContentType().equals(XSLFRelation.MAIN.getContentType())) { | ||||
found = true; | found = true; | ||||
} | } | ||||
//System.out.println(part); | |||||
} | } | ||||
assertTrue(found); | assertTrue(found); | ||||
} | } |
XSLFAutoShape shape = slide.createAutoShape(); | XSLFAutoShape shape = slide.createAutoShape(); | ||||
shape.addNewTextParagraph().addNewTextRun().setText("POI"); | shape.addNewTextParagraph().addNewTextRun().setText("POI"); | ||||
// margins | |||||
assertEquals(-1., shape.getMarginBottom()); | |||||
assertEquals(-1., shape.getMarginTop()); | |||||
assertEquals(-1., shape.getMarginLeft()); | |||||
assertEquals(-1., shape.getMarginRight()); | |||||
// default margins from slide master | |||||
assertEquals(3.6, shape.getMarginBottom()); | |||||
assertEquals(3.6, shape.getMarginTop()); | |||||
assertEquals(7.2, shape.getMarginLeft()); | |||||
assertEquals(7.2, shape.getMarginRight()); | |||||
shape.setMarginBottom(1.0); | shape.setMarginBottom(1.0); | ||||
assertEquals(1.0, shape.getMarginBottom()); | assertEquals(1.0, shape.getMarginBottom()); | ||||
shape.setMarginRight(0.0); | shape.setMarginRight(0.0); | ||||
assertEquals(0.0, shape.getMarginRight()); | assertEquals(0.0, shape.getMarginRight()); | ||||
// unset to defauls | |||||
shape.setMarginBottom(-1); | shape.setMarginBottom(-1); | ||||
assertEquals(-1., shape.getMarginBottom()); | |||||
assertEquals(3.6, shape.getMarginBottom()); | |||||
shape.setMarginTop(-1); | shape.setMarginTop(-1); | ||||
assertEquals(-1.0, shape.getMarginTop()); | |||||
assertEquals(3.6, shape.getMarginTop()); | |||||
shape.setMarginLeft(-1); | shape.setMarginLeft(-1); | ||||
assertEquals(-1.0, shape.getMarginLeft()); | |||||
assertEquals(7.2, shape.getMarginLeft()); | |||||
shape.setMarginRight(-1); | shape.setMarginRight(-1); | ||||
assertEquals(-1.0, shape.getMarginRight()); | |||||
assertEquals(7.2, shape.getMarginRight()); | |||||
// shape | // shape | ||||
assertFalse(shape.getWordWrap()); | |||||
shape.setWordWrap(true); | |||||
assertTrue(shape.getWordWrap()); | assertTrue(shape.getWordWrap()); | ||||
shape.setWordWrap(false); | shape.setWordWrap(false); | ||||
assertFalse(shape.getWordWrap()); | assertFalse(shape.getWordWrap()); | ||||
shape.setWordWrap(true); | |||||
assertTrue(shape.getWordWrap()); | |||||
// shape | // shape | ||||
assertEquals(TextAutofit.NORMAL, shape.getTextAutofit()); | assertEquals(TextAutofit.NORMAL, shape.getTextAutofit()); | ||||
assertEquals(1, p.getTextRuns().size()); | assertEquals(1, p.getTextRuns().size()); | ||||
assertSame(r, p.getTextRuns().get(0)); | assertSame(r, p.getTextRuns().get(0)); | ||||
assertEquals(-1.0, r.getFontSize()); | |||||
assertEquals(18.0, r.getFontSize()); // default font size for text boxes | |||||
assertFalse(r.getXmlObject().getRPr().isSetSz()); | assertFalse(r.getXmlObject().getRPr().isSetSz()); | ||||
r.setFontSize(10.0); | r.setFontSize(10.0); | ||||
assertTrue(r.getXmlObject().isSetRPr()); | assertTrue(r.getXmlObject().isSetRPr()); | ||||
assertFalse(r.getXmlObject().getRPr().isSetSz()); | assertFalse(r.getXmlObject().getRPr().isSetSz()); | ||||
assertFalse(r.getXmlObject().getRPr().isSetLatin()); | assertFalse(r.getXmlObject().getRPr().isSetLatin()); | ||||
assertNull(r.getFontFamily()); | |||||
assertEquals("Calibri", r.getFontFamily()); // comes from the slide master | |||||
r.setFontFamily(null); | r.setFontFamily(null); | ||||
assertNull(r.getFontFamily()); | |||||
assertEquals("Calibri", r.getFontFamily()); // comes from the slide master | |||||
r.setFontFamily("Arial"); | r.setFontFamily("Arial"); | ||||
assertEquals("Arial", r.getFontFamily()); | assertEquals("Arial", r.getFontFamily()); | ||||
assertEquals("Arial", r.getXmlObject().getRPr().getLatin().getTypeface()); | assertEquals("Arial", r.getXmlObject().getRPr().getLatin().getTypeface()); | ||||
assertEquals("Symbol", r.getFontFamily()); | assertEquals("Symbol", r.getFontFamily()); | ||||
assertEquals("Symbol", r.getXmlObject().getRPr().getLatin().getTypeface()); | assertEquals("Symbol", r.getXmlObject().getRPr().getLatin().getTypeface()); | ||||
r.setFontFamily(null); | r.setFontFamily(null); | ||||
assertNull(r.getFontFamily()); | |||||
assertEquals("Calibri", r.getFontFamily()); // comes from the slide master | |||||
assertFalse(r.getXmlObject().getRPr().isSetLatin()); | assertFalse(r.getXmlObject().getRPr().isSetLatin()); | ||||
assertFalse(r.isStrikethrough()); | assertFalse(r.isStrikethrough()); |
import org.apache.poi.util.Units; | import org.apache.poi.util.Units; | ||||
import org.apache.poi.xslf.usermodel.LineCap; | import org.apache.poi.xslf.usermodel.LineCap; | ||||
import org.apache.poi.xslf.usermodel.LineDash; | import org.apache.poi.xslf.usermodel.LineDash; | ||||
import org.apache.poi.xslf.XSLFTestDataSamples; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap; | import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal; | import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal; | ||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; | |||||
import java.awt.*; | import java.awt.*; | ||||
assertFalse(shape.getSpPr().isSetSolidFill()); | assertFalse(shape.getSpPr().isSetSolidFill()); | ||||
} | } | ||||
public void testDefaultProperties() { | |||||
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx"); | |||||
XSLFSlide slide6 = ppt.getSlides()[5]; | |||||
XSLFShape[] shapes = slide6.getShapes(); | |||||
for(int i = 1; i < shapes.length; i++){ | |||||
XSLFSimpleShape s = (XSLFSimpleShape) shapes[i]; | |||||
// all shapes have a theme color="accent1" | |||||
assertEquals("accent1", s.getSpStyle().getFillRef().getSchemeClr().getVal().toString()); | |||||
assertEquals(2.0, s.getLineWidth()); | |||||
assertEquals(LineCap.FLAT, s.getLineCap()); | |||||
// YK: calculated color is slightly different from PowerPoint | |||||
assertEquals(new Color(40, 65, 95), s.getLineColor()); | |||||
} | |||||
XSLFSimpleShape s0 = (XSLFSimpleShape) shapes[0]; | |||||
// fill is not set | |||||
assertNull(s0.getSpPr().getSolidFill()); | |||||
assertEquals(slide6.getTheme().getColor("accent1").getColor(), s0.getFillColor()); | |||||
assertEquals(new Color(79, 129, 189), s0.getFillColor()); | |||||
// lighter 80% | |||||
XSLFSimpleShape s1 = (XSLFSimpleShape)shapes[1]; | |||||
CTSchemeColor ref1 = s1.getSpPr().getSolidFill().getSchemeClr(); | |||||
assertEquals(1, ref1.sizeOfLumModArray()); | |||||
assertEquals(1, ref1.sizeOfLumOffArray()); | |||||
assertEquals(20000, ref1.getLumModArray(0).getVal()); | |||||
assertEquals(80000, ref1.getLumOffArray(0).getVal()); | |||||
assertEquals("accent1", ref1.getVal().toString()); | |||||
assertEquals(new Color(220, 230, 242), s1.getFillColor()); | |||||
// lighter 60% | |||||
XSLFSimpleShape s2 = (XSLFSimpleShape)shapes[2]; | |||||
CTSchemeColor ref2 = s2.getSpPr().getSolidFill().getSchemeClr(); | |||||
assertEquals(1, ref2.sizeOfLumModArray()); | |||||
assertEquals(1, ref2.sizeOfLumOffArray()); | |||||
assertEquals(40000, ref2.getLumModArray(0).getVal()); | |||||
assertEquals(60000, ref2.getLumOffArray(0).getVal()); | |||||
assertEquals("accent1", ref2.getVal().toString()); | |||||
assertEquals(new Color(185, 205, 229), s2.getFillColor()); | |||||
// lighter 40% | |||||
XSLFSimpleShape s3 = (XSLFSimpleShape)shapes[3]; | |||||
CTSchemeColor ref3 = s3.getSpPr().getSolidFill().getSchemeClr(); | |||||
assertEquals(1, ref3.sizeOfLumModArray()); | |||||
assertEquals(1, ref3.sizeOfLumOffArray()); | |||||
assertEquals(60000, ref3.getLumModArray(0).getVal()); | |||||
assertEquals(40000, ref3.getLumOffArray(0).getVal()); | |||||
assertEquals("accent1", ref3.getVal().toString()); | |||||
assertEquals(new Color(149, 179, 215), s3.getFillColor()); | |||||
// darker 25% | |||||
XSLFSimpleShape s4 = (XSLFSimpleShape)shapes[4]; | |||||
CTSchemeColor ref4 = s4.getSpPr().getSolidFill().getSchemeClr(); | |||||
assertEquals(1, ref4.sizeOfLumModArray()); | |||||
assertEquals(0, ref4.sizeOfLumOffArray()); | |||||
assertEquals(75000, ref4.getLumModArray(0).getVal()); | |||||
assertEquals("accent1", ref3.getVal().toString()); | |||||
// YK: calculated color is slightly different from PowerPoint | |||||
assertEquals(new Color(59, 97, 142), s4.getFillColor()); | |||||
XSLFSimpleShape s5 = (XSLFSimpleShape)shapes[5]; | |||||
CTSchemeColor ref5 = s5.getSpPr().getSolidFill().getSchemeClr(); | |||||
assertEquals(1, ref5.sizeOfLumModArray()); | |||||
assertEquals(0, ref5.sizeOfLumOffArray()); | |||||
assertEquals(50000, ref5.getLumModArray(0).getVal()); | |||||
assertEquals("accent1", ref5.getVal().toString()); | |||||
// YK: calculated color is slightly different from PowerPoint | |||||
assertEquals(new Color(40, 65, 95), s5.getFillColor()); | |||||
} | |||||
public void testAnchor(){ | |||||
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx"); | |||||
XSLFSlide[] slide = ppt.getSlides(); | |||||
XSLFSlide slide2 = slide[1]; | |||||
XSLFSlideLayout layout2 = slide2.getSlideLayout(); | |||||
XSLFShape[] shapes2 = slide2.getShapes(); | |||||
XSLFTextShape sh1 = (XSLFTextShape)shapes2[0]; | |||||
assertEquals(Placeholder.CENTERED_TITLE, sh1.getTextType()); | |||||
assertEquals("PPTX Title", sh1.getText()); | |||||
assertNull(sh1.getSpPr().getXfrm()); // xfrm is not set, the query is delegated to the slide layout | |||||
assertEquals(sh1.getAnchor(), layout2.getTextShapeByType(Placeholder.CENTERED_TITLE).getAnchor()); | |||||
XSLFTextShape sh2 = (XSLFTextShape)shapes2[1]; | |||||
assertEquals("Subtitle\nAnd second line", sh2.getText()); | |||||
assertEquals(Placeholder.SUBTITLE, sh2.getTextType()); | |||||
assertNull(sh2.getSpPr().getXfrm()); // xfrm is not set, the query is delegated to the slide layout | |||||
assertEquals(sh2.getAnchor(), layout2.getTextShapeByType(Placeholder.SUBTITLE).getAnchor()); | |||||
XSLFSlide slide5 = slide[4]; | |||||
XSLFSlideLayout layout5 = slide5.getSlideLayout(); | |||||
XSLFTextShape shTitle = slide5.getTextShapeByType(Placeholder.TITLE); | |||||
assertEquals("Hyperlinks", shTitle.getText()); | |||||
// xfrm is not set, the query is delegated to the slide layout | |||||
assertNull(shTitle.getSpPr().getXfrm()); | |||||
// xfrm is not set, the query is delegated to the slide master | |||||
assertNull(layout5.getTextShapeByType(Placeholder.TITLE).getSpPr().getXfrm()); | |||||
assertNotNull(layout5.getSlideMaster().getTextShapeByType(Placeholder.TITLE).getSpPr().getXfrm()); | |||||
assertEquals(shTitle.getAnchor(), layout5.getSlideMaster().getTextShapeByType(Placeholder.TITLE).getAnchor()); | |||||
} | |||||
} | } |
XSLFSlide slide = ppt.createSlide(); | XSLFSlide slide = ppt.createSlide(); | ||||
XSLFTextBox shape = slide.createTextBox(); | XSLFTextBox shape = slide.createTextBox(); | ||||
assertNull(shape.getPlaceholder()); | |||||
assertNull(shape.getTextType()); | |||||
shape.setPlaceholder(Placeholder.TITLE); | shape.setPlaceholder(Placeholder.TITLE); | ||||
assertEquals(Placeholder.TITLE, shape.getPlaceholder()); | |||||
assertEquals(Placeholder.TITLE, shape.getTextType()); | |||||
shape.setPlaceholder(null); | shape.setPlaceholder(null); | ||||
assertNull(shape.getPlaceholder()); | |||||
assertNull(shape.getTextType()); | |||||
} | } | ||||
} | } |
/* ==================================================================== | |||||
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 junit.framework.TestCase; | |||||
import org.apache.poi.xslf.XSLFTestDataSamples; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType; | |||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; | |||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties; | |||||
import java.awt.*; | |||||
/** | |||||
* @author Yegor Kozlov | |||||
*/ | |||||
public class TestXSLFTextShape extends TestCase { | |||||
public void testLayouts(){ | |||||
XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("layouts.pptx"); | |||||
XSLFSlide[] slide = ppt.getSlides(); | |||||
verifySlide1(slide[0]); | |||||
verifySlide2(slide[1]); | |||||
verifySlide3(slide[2]); | |||||
verifySlide4(slide[3]); | |||||
verifySlide7(slide[6]); | |||||
verifySlide8(slide[7]); | |||||
verifySlide10(slide[9]); | |||||
} | |||||
void verifySlide1(XSLFSlide slide){ | |||||
XSLFSlideLayout layout = slide.getSlideLayout(); | |||||
XSLFShape[] shapes = slide.getShapes(); | |||||
assertEquals("Title Slide",layout.getName()); | |||||
XSLFTextShape shape1 = (XSLFTextShape)shapes[0]; | |||||
CTPlaceholder ph1 = shape1.getCTPlaceholder(); | |||||
assertEquals(STPlaceholderType.CTR_TITLE, ph1.getType()); | |||||
// anchor is not defined in the shape | |||||
assertNull(shape1.getSpPr().getXfrm()); | |||||
XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1); | |||||
assertNotNull(masterShape1.getSpPr().getXfrm()); | |||||
assertEquals(masterShape1.getAnchor(), shape1.getAnchor()); | |||||
CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr(); | |||||
// none of the following properties are set in the shapes and fetched from the master shape | |||||
assertTrue( | |||||
!bodyPr1.isSetLIns() && !bodyPr1.isSetRIns() && | |||||
!bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() && | |||||
!bodyPr1.isSetAnchor() | |||||
); | |||||
assertEquals(7.2, shape1.getMarginLeft()); // 0.1" | |||||
assertEquals(7.2, shape1.getMarginRight()); // 0.1" | |||||
assertEquals(3.6, shape1.getMarginTop()); // 0.05" | |||||
assertEquals(3.6, shape1.getMarginBottom()); // 0.05" | |||||
assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment()); | |||||
// now check text properties | |||||
assertEquals("Centered Title", shape1.getText()); | |||||
XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0); | |||||
assertEquals("Calibri", r1.getFontFamily()); | |||||
assertEquals(44.0, r1.getFontSize()); | |||||
assertEquals(Color.black, r1.getFontColor()); | |||||
XSLFTextShape shape2 = (XSLFTextShape)shapes[1]; | |||||
CTPlaceholder ph2 = shape2.getCTPlaceholder(); | |||||
assertEquals(STPlaceholderType.SUB_TITLE, ph2.getType()); | |||||
// anchor is not defined in the shape | |||||
assertNull(shape2.getSpPr().getXfrm()); | |||||
XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2); | |||||
assertNotNull(masterShape2.getSpPr().getXfrm()); | |||||
assertEquals(masterShape2.getAnchor(), shape2.getAnchor()); | |||||
CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr(); | |||||
// none of the following properties are set in the shapes and fetched from the master shape | |||||
assertTrue( | |||||
!bodyPr2.isSetLIns() && !bodyPr2.isSetRIns() && | |||||
!bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() && | |||||
!bodyPr2.isSetAnchor() | |||||
); | |||||
assertEquals(7.2, shape2.getMarginLeft()); // 0.1" | |||||
assertEquals(7.2, shape2.getMarginRight()); // 0.1" | |||||
assertEquals(3.6, shape2.getMarginTop()); // 0.05" | |||||
assertEquals(3.6, shape2.getMarginBottom()); // 0.05" | |||||
assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment()); | |||||
assertEquals("subtitle", shape2.getText()); | |||||
XSLFTextRun r2 = shape2.getTextParagraphs().get(0).getTextRuns().get(0); | |||||
assertEquals("Calibri", r2.getFontFamily()); | |||||
assertEquals(32.0, r2.getFontSize()); | |||||
// TODO fix calculation of tint | |||||
//assertEquals(new Color(137, 137, 137), r2.getFontColor()); | |||||
} | |||||
void verifySlide2(XSLFSlide slide){ | |||||
XSLFSlideLayout layout = slide.getSlideLayout(); | |||||
XSLFShape[] shapes = slide.getShapes(); | |||||
assertEquals("Title and Content",layout.getName()); | |||||
XSLFTextShape shape1 = (XSLFTextShape)shapes[0]; | |||||
CTPlaceholder ph1 = shape1.getCTPlaceholder(); | |||||
assertEquals(STPlaceholderType.TITLE, ph1.getType()); | |||||
// anchor is not defined in the shape | |||||
assertNull(shape1.getSpPr().getXfrm()); | |||||
XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1); | |||||
// layout does not have anchor info either, it is in the slide master | |||||
assertNull(masterShape1.getSpPr().getXfrm()); | |||||
masterShape1 = (XSLFTextShape)layout.getSlideMaster().getPlaceholder(ph1); | |||||
assertNotNull(masterShape1.getSpPr().getXfrm()); | |||||
assertEquals(masterShape1.getAnchor(), shape1.getAnchor()); | |||||
CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr(); | |||||
// none of the following properties are set in the shapes and fetched from the master shape | |||||
assertTrue( | |||||
!bodyPr1.isSetLIns() && !bodyPr1.isSetRIns() && | |||||
!bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() && | |||||
!bodyPr1.isSetAnchor() | |||||
); | |||||
assertEquals(7.2, shape1.getMarginLeft()); // 0.1" | |||||
assertEquals(7.2, shape1.getMarginRight()); // 0.1" | |||||
assertEquals(3.6, shape1.getMarginTop()); // 0.05" | |||||
assertEquals(3.6, shape1.getMarginBottom()); // 0.05" | |||||
assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment()); | |||||
// now check text properties | |||||
assertEquals("Title", shape1.getText()); | |||||
XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0); | |||||
assertEquals("Calibri", r1.getFontFamily()); | |||||
assertEquals(44.0, r1.getFontSize()); | |||||
assertEquals(Color.black, r1.getFontColor()); | |||||
XSLFTextShape shape2 = (XSLFTextShape)shapes[1]; | |||||
CTPlaceholder ph2 = shape2.getCTPlaceholder(); | |||||
assertFalse(ph2.isSetType()); // <p:ph idx="1"/> | |||||
assertTrue(ph2.isSetIdx()); | |||||
assertEquals(1, ph2.getIdx()); | |||||
// anchor is not defined in the shape | |||||
assertNull(shape2.getSpPr().getXfrm()); | |||||
XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2); | |||||
// anchor of the body text is missing in the slide layout, llokup in the slide master | |||||
assertNull(masterShape2.getSpPr().getXfrm()); | |||||
masterShape2 = (XSLFTextShape)layout.getSlideMaster().getPlaceholder(ph2); | |||||
assertNotNull(masterShape2.getSpPr().getXfrm()); | |||||
assertEquals(masterShape2.getAnchor(), shape2.getAnchor()); | |||||
CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr(); | |||||
// none of the following properties are set in the shapes and fetched from the master shape | |||||
assertTrue( | |||||
!bodyPr2.isSetLIns() && !bodyPr2.isSetRIns() && | |||||
!bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() && | |||||
!bodyPr2.isSetAnchor() | |||||
); | |||||
assertEquals(7.2, shape2.getMarginLeft()); // 0.1" | |||||
assertEquals(7.2, shape2.getMarginRight()); // 0.1" | |||||
assertEquals(3.6, shape2.getMarginTop()); // 0.05" | |||||
assertEquals(3.6, shape2.getMarginBottom()); // 0.05" | |||||
assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment()); | |||||
XSLFTextRun pr1 = shape2.getTextParagraphs().get(0).getTextRuns().get(0); | |||||
assertEquals(0, pr1.getParentParagraph().getLevel()); | |||||
assertEquals("Content", pr1.getText()); | |||||
assertEquals("Calibri", pr1.getFontFamily()); | |||||
assertEquals(32.0, pr1.getFontSize()); | |||||
assertEquals(27.0, pr1.getParentParagraph().getLeftMargin()); | |||||
assertEquals("\u2022", pr1.getParentParagraph().getBulletCharacter()); | |||||
assertEquals("Arial", pr1.getParentParagraph().getBulletFont()); | |||||
XSLFTextRun pr2 = shape2.getTextParagraphs().get(1).getTextRuns().get(0); | |||||
assertEquals(1, pr2.getParentParagraph().getLevel()); | |||||
assertEquals("Level 2", pr2.getText()); | |||||
assertEquals("Calibri", pr2.getFontFamily()); | |||||
assertEquals(28.0, pr2.getFontSize()); | |||||
assertEquals(58.5, pr2.getParentParagraph().getLeftMargin()); | |||||
assertEquals("\u2013", pr2.getParentParagraph().getBulletCharacter()); | |||||
assertEquals("Arial", pr2.getParentParagraph().getBulletFont()); | |||||
XSLFTextRun pr3 = shape2.getTextParagraphs().get(2).getTextRuns().get(0); | |||||
assertEquals(2, pr3.getParentParagraph().getLevel()); | |||||
assertEquals("Level 3", pr3.getText()); | |||||
assertEquals("Calibri", pr3.getFontFamily()); | |||||
assertEquals(24.0, pr3.getFontSize()); | |||||
assertEquals(90.0, pr3.getParentParagraph().getLeftMargin()); | |||||
assertEquals("\u2022", pr3.getParentParagraph().getBulletCharacter()); | |||||
assertEquals("Arial", pr3.getParentParagraph().getBulletFont()); | |||||
XSLFTextRun pr4 = shape2.getTextParagraphs().get(3).getTextRuns().get(0); | |||||
assertEquals(3, pr4.getParentParagraph().getLevel()); | |||||
assertEquals("Level 4", pr4.getText()); | |||||
assertEquals("Calibri", pr4.getFontFamily()); | |||||
assertEquals(20.0, pr4.getFontSize()); | |||||
assertEquals(126.0, pr4.getParentParagraph().getLeftMargin()); | |||||
assertEquals("\u2013", pr4.getParentParagraph().getBulletCharacter()); | |||||
assertEquals("Arial", pr4.getParentParagraph().getBulletFont()); | |||||
XSLFTextRun pr5 = shape2.getTextParagraphs().get(4).getTextRuns().get(0); | |||||
assertEquals(4, pr5.getParentParagraph().getLevel()); | |||||
assertEquals("Level 5", pr5.getText()); | |||||
assertEquals("Calibri", pr5.getFontFamily()); | |||||
assertEquals(20.0, pr5.getFontSize()); | |||||
assertEquals(162.0, pr5.getParentParagraph().getLeftMargin()); | |||||
assertEquals("\u00bb", pr5.getParentParagraph().getBulletCharacter()); | |||||
assertEquals("Arial", pr5.getParentParagraph().getBulletFont()); | |||||
} | |||||
void verifySlide3(XSLFSlide slide){ | |||||
XSLFSlideLayout layout = slide.getSlideLayout(); | |||||
XSLFShape[] shapes = slide.getShapes(); | |||||
assertEquals("Section Header",layout.getName()); | |||||
XSLFTextShape shape1 = (XSLFTextShape)shapes[0]; | |||||
CTPlaceholder ph1 = shape1.getCTPlaceholder(); | |||||
assertEquals(STPlaceholderType.TITLE, ph1.getType()); | |||||
// anchor is not defined in the shape | |||||
assertNull(shape1.getSpPr().getXfrm()); | |||||
XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1); | |||||
assertNotNull(masterShape1.getSpPr().getXfrm()); | |||||
assertEquals(masterShape1.getAnchor(), shape1.getAnchor()); | |||||
CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr(); | |||||
// none of the following properties are set in the shapes and fetched from the master shape | |||||
assertTrue( | |||||
!bodyPr1.isSetLIns() && !bodyPr1.isSetRIns() && | |||||
!bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() && | |||||
!bodyPr1.isSetAnchor() | |||||
); | |||||
assertEquals(7.2, shape1.getMarginLeft()); // 0.1" | |||||
assertEquals(7.2, shape1.getMarginRight()); // 0.1" | |||||
assertEquals(3.6, shape1.getMarginTop()); // 0.05" | |||||
assertEquals(3.6, shape1.getMarginBottom()); // 0.05" | |||||
assertEquals(VerticalAlignment.TOP, shape1.getVerticalAlignment()); | |||||
// now check text properties | |||||
assertEquals("Section Title", shape1.getText()); | |||||
XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0); | |||||
assertEquals(TextAlign.LEFT, r1.getParentParagraph().getTextAlign()); | |||||
assertEquals("Calibri", r1.getFontFamily()); | |||||
assertEquals(40.0, r1.getFontSize()); | |||||
assertEquals(Color.black, r1.getFontColor()); | |||||
assertTrue(r1.isBold()); | |||||
assertFalse(r1.isItalic()); | |||||
assertFalse(r1.isUnderline()); | |||||
XSLFTextShape shape2 = (XSLFTextShape)shapes[1]; | |||||
CTPlaceholder ph2 = shape2.getCTPlaceholder(); | |||||
assertEquals(STPlaceholderType.BODY, ph2.getType()); | |||||
// anchor is not defined in the shape | |||||
assertNull(shape2.getSpPr().getXfrm()); | |||||
XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2); | |||||
assertNotNull(masterShape2.getSpPr().getXfrm()); | |||||
assertEquals(masterShape2.getAnchor(), shape2.getAnchor()); | |||||
CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr(); | |||||
// none of the following properties are set in the shapes and fetched from the master shape | |||||
assertTrue( | |||||
!bodyPr2.isSetLIns() && !bodyPr2.isSetRIns() && | |||||
!bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() && | |||||
!bodyPr2.isSetAnchor() | |||||
); | |||||
assertEquals(7.2, shape2.getMarginLeft()); // 0.1" | |||||
assertEquals(7.2, shape2.getMarginRight()); // 0.1" | |||||
assertEquals(3.6, shape2.getMarginTop()); // 0.05" | |||||
assertEquals(3.6, shape2.getMarginBottom()); // 0.05" | |||||
assertEquals(VerticalAlignment.BOTTOM, shape2.getVerticalAlignment()); | |||||
assertEquals("Section Header", shape2.getText()); | |||||
XSLFTextRun r2 = shape2.getTextParagraphs().get(0).getTextRuns().get(0); | |||||
assertEquals(TextAlign.LEFT, r2.getParentParagraph().getTextAlign()); | |||||
assertEquals("Calibri", r2.getFontFamily()); | |||||
assertEquals(20.0, r2.getFontSize()); | |||||
// TODO fix calculation of tint | |||||
//assertEquals(new Color(137, 137, 137), r2.getFontColor()); | |||||
} | |||||
void verifySlide4(XSLFSlide slide){ | |||||
XSLFSlideLayout layout = slide.getSlideLayout(); | |||||
XSLFShape[] shapes = slide.getShapes(); | |||||
assertEquals("Two Content",layout.getName()); | |||||
XSLFTextShape shape1 = (XSLFTextShape)shapes[0]; | |||||
CTPlaceholder ph1 = shape1.getCTPlaceholder(); | |||||
assertEquals(STPlaceholderType.TITLE, ph1.getType()); | |||||
// anchor is not defined in the shape | |||||
assertNull(shape1.getSpPr().getXfrm()); | |||||
XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1); | |||||
// layout does not have anchor info either, it is in the slide master | |||||
assertNull(masterShape1.getSpPr().getXfrm()); | |||||
masterShape1 = (XSLFTextShape)layout.getSlideMaster().getPlaceholder(ph1); | |||||
assertNotNull(masterShape1.getSpPr().getXfrm()); | |||||
assertEquals(masterShape1.getAnchor(), shape1.getAnchor()); | |||||
CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr(); | |||||
// none of the following properties are set in the shapes and fetched from the master shape | |||||
assertTrue( | |||||
!bodyPr1.isSetLIns() && !bodyPr1.isSetRIns() && | |||||
!bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() && | |||||
!bodyPr1.isSetAnchor() | |||||
); | |||||
assertEquals(7.2, shape1.getMarginLeft()); // 0.1" | |||||
assertEquals(7.2, shape1.getMarginRight()); // 0.1" | |||||
assertEquals(3.6, shape1.getMarginTop()); // 0.05" | |||||
assertEquals(3.6, shape1.getMarginBottom()); // 0.05" | |||||
assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment()); | |||||
// now check text properties | |||||
assertEquals("Title", shape1.getText()); | |||||
XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0); | |||||
assertEquals(TextAlign.CENTER, r1.getParentParagraph().getTextAlign()); | |||||
assertEquals("Calibri", r1.getFontFamily()); | |||||
assertEquals(44.0, r1.getFontSize()); | |||||
assertEquals(Color.black, r1.getFontColor()); | |||||
XSLFTextShape shape2 = (XSLFTextShape)shapes[1]; | |||||
CTPlaceholder ph2 = shape2.getCTPlaceholder(); | |||||
assertFalse(ph2.isSetType()); | |||||
assertTrue(ph2.isSetIdx()); | |||||
assertEquals(1, ph2.getIdx()); //<p:ph sz="half" idx="1"/> | |||||
// anchor is not defined in the shape | |||||
assertNull(shape2.getSpPr().getXfrm()); | |||||
XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2); | |||||
assertNotNull(masterShape2.getSpPr().getXfrm()); | |||||
assertEquals(masterShape2.getAnchor(), shape2.getAnchor()); | |||||
CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr(); | |||||
// none of the following properties are set in the shapes and fetched from the master shape | |||||
assertTrue( | |||||
!bodyPr2.isSetLIns() && !bodyPr2.isSetRIns() && | |||||
!bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() && | |||||
!bodyPr2.isSetAnchor() | |||||
); | |||||
assertEquals(7.2, shape2.getMarginLeft()); // 0.1" | |||||
assertEquals(7.2, shape2.getMarginRight()); // 0.1" | |||||
assertEquals(3.6, shape2.getMarginTop()); // 0.05" | |||||
assertEquals(3.6, shape2.getMarginBottom()); // 0.05" | |||||
assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment()); | |||||
XSLFTextRun pr1 = shape2.getTextParagraphs().get(0).getTextRuns().get(0); | |||||
assertEquals(0, pr1.getParentParagraph().getLevel()); | |||||
assertEquals("Left", pr1.getText()); | |||||
assertEquals("Calibri", pr1.getFontFamily()); | |||||
assertEquals(28.0, pr1.getFontSize()); | |||||
assertEquals(27.0, pr1.getParentParagraph().getLeftMargin()); | |||||
assertEquals("\u2022", pr1.getParentParagraph().getBulletCharacter()); | |||||
assertEquals("Arial", pr1.getParentParagraph().getBulletFont()); | |||||
XSLFTextRun pr2 = shape2.getTextParagraphs().get(1).getTextRuns().get(0); | |||||
assertEquals(1, pr2.getParentParagraph().getLevel()); | |||||
assertEquals("Level 2", pr2.getParentParagraph().getText()); | |||||
assertEquals("Calibri", pr2.getFontFamily()); | |||||
assertEquals(24.0, pr2.getFontSize()); | |||||
assertEquals(58.5, pr2.getParentParagraph().getLeftMargin()); | |||||
assertEquals("\u2013", pr2.getParentParagraph().getBulletCharacter()); | |||||
assertEquals("Arial", pr2.getParentParagraph().getBulletFont()); | |||||
XSLFTextRun pr3 = shape2.getTextParagraphs().get(2).getTextRuns().get(0); | |||||
assertEquals(2, pr3.getParentParagraph().getLevel()); | |||||
assertEquals("Level 3", pr3.getParentParagraph().getText()); | |||||
assertEquals("Calibri", pr3.getFontFamily()); | |||||
assertEquals(20.0, pr3.getFontSize()); | |||||
assertEquals(90.0, pr3.getParentParagraph().getLeftMargin()); | |||||
assertEquals("\u2022", pr3.getParentParagraph().getBulletCharacter()); | |||||
assertEquals("Arial", pr3.getParentParagraph().getBulletFont()); | |||||
XSLFTextRun pr4 = shape2.getTextParagraphs().get(3).getTextRuns().get(0); | |||||
assertEquals(3, pr4.getParentParagraph().getLevel()); | |||||
assertEquals("Level 4", pr4.getParentParagraph().getText()); | |||||
assertEquals("Calibri", pr4.getFontFamily()); | |||||
assertEquals(18.0, pr4.getFontSize()); | |||||
assertEquals(126.0, pr4.getParentParagraph().getLeftMargin()); | |||||
assertEquals("\u2013", pr4.getParentParagraph().getBulletCharacter()); | |||||
assertEquals("Arial", pr4.getParentParagraph().getBulletFont()); | |||||
XSLFTextShape shape3 = (XSLFTextShape)shapes[2]; | |||||
XSLFTextRun pr5 = shape3.getTextParagraphs().get(0).getTextRuns().get(0); | |||||
assertEquals(0, pr5.getParentParagraph().getLevel()); | |||||
assertEquals("Right", pr5.getText()); | |||||
assertEquals("Calibri", pr5.getFontFamily()); | |||||
assertEquals(Color.black, pr5.getFontColor()); | |||||
} | |||||
void verifySlide5(XSLFSlide slide){ | |||||
XSLFSlideLayout layout = slide.getSlideLayout(); | |||||
XSLFShape[] shapes = slide.getShapes(); | |||||
// TODO | |||||
} | |||||
void verifySlide7(XSLFSlide slide){ | |||||
XSLFSlideLayout layout = slide.getSlideLayout(); | |||||
XSLFShape[] shapes = slide.getShapes(); | |||||
assertEquals("Blank",layout.getName()); | |||||
XSLFTextShape shape1 = (XSLFTextShape)shapes[0]; | |||||
CTPlaceholder ph1 = shape1.getCTPlaceholder(); | |||||
assertEquals(STPlaceholderType.TITLE, ph1.getType()); | |||||
// anchor is not defined in the shape | |||||
assertNull(shape1.getSpPr().getXfrm()); | |||||
CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr(); | |||||
// none of the following properties are set in the shapes and fetched from the master shape | |||||
assertTrue( | |||||
!bodyPr1.isSetLIns() && !bodyPr1.isSetRIns() && | |||||
!bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() && | |||||
!bodyPr1.isSetAnchor() | |||||
); | |||||
assertEquals(7.2, shape1.getMarginLeft()); // 0.1" | |||||
assertEquals(7.2, shape1.getMarginRight()); // 0.1" | |||||
assertEquals(3.6, shape1.getMarginTop()); // 0.05" | |||||
assertEquals(3.6, shape1.getMarginBottom()); // 0.05" | |||||
assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment()); | |||||
// now check text properties | |||||
assertEquals("Blank with Default Title", shape1.getText()); | |||||
XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0); | |||||
assertEquals(TextAlign.CENTER, r1.getParentParagraph().getTextAlign()); | |||||
assertEquals("Calibri", r1.getFontFamily()); | |||||
assertEquals(44.0, r1.getFontSize()); | |||||
assertEquals(Color.black, r1.getFontColor()); | |||||
assertFalse(r1.isBold()); | |||||
XSLFTextShape shape2 = (XSLFTextShape)shapes[1]; | |||||
CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr(); | |||||
// none of the following properties are set in the shapes and fetched from the master shape | |||||
assertTrue( | |||||
!bodyPr2.isSetLIns() && !bodyPr2.isSetRIns() && | |||||
!bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() && | |||||
!bodyPr2.isSetAnchor() | |||||
); | |||||
assertEquals(7.2, shape2.getMarginLeft()); // 0.1" | |||||
assertEquals(7.2, shape2.getMarginRight()); // 0.1" | |||||
assertEquals(3.6, shape2.getMarginTop()); // 0.05" | |||||
assertEquals(3.6, shape2.getMarginBottom()); // 0.05" | |||||
assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment()); | |||||
XSLFTextRun pr1 = shape2.getTextParagraphs().get(0).getTextRuns().get(0); | |||||
assertEquals(0, pr1.getParentParagraph().getLevel()); | |||||
assertEquals("Default Text", pr1.getText()); | |||||
assertEquals("Calibri", pr1.getFontFamily()); | |||||
assertEquals(18.0, pr1.getFontSize()); | |||||
XSLFTextShape shape3 = (XSLFTextShape)shapes[2]; | |||||
assertEquals("Default", shape3.getTextParagraphs().get(0).getText()); | |||||
assertEquals("Text with levels", shape3.getTextParagraphs().get(1).getText()); | |||||
assertEquals("Level 1", shape3.getTextParagraphs().get(2).getText()); | |||||
assertEquals("Level 2", shape3.getTextParagraphs().get(3).getText()); | |||||
assertEquals("Level 3", shape3.getTextParagraphs().get(4).getText()); | |||||
for(int p = 0; p < 5; p++) { | |||||
XSLFTextParagraph pr = shape3.getTextParagraphs().get(p); | |||||
assertEquals("Calibri", pr.getTextRuns().get(0).getFontFamily()); | |||||
assertEquals(18.0, pr.getTextRuns().get(0).getFontSize()); | |||||
} | |||||
} | |||||
void verifySlide8(XSLFSlide slide){ | |||||
XSLFSlideLayout layout = slide.getSlideLayout(); | |||||
XSLFShape[] shapes = slide.getShapes(); | |||||
assertEquals("Content with Caption",layout.getName()); | |||||
XSLFTextShape shape1 = (XSLFTextShape)shapes[0]; | |||||
CTPlaceholder ph1 = shape1.getCTPlaceholder(); | |||||
assertEquals(STPlaceholderType.TITLE, ph1.getType()); | |||||
// anchor is not defined in the shape | |||||
assertNull(shape1.getSpPr().getXfrm()); | |||||
XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1); | |||||
// layout does not have anchor info either, it is in the slide master | |||||
assertNotNull(masterShape1.getSpPr().getXfrm()); | |||||
assertEquals(masterShape1.getAnchor(), shape1.getAnchor()); | |||||
CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr(); | |||||
// none of the following properties are set in the shapes and fetched from the master shape | |||||
assertTrue( | |||||
!bodyPr1.isSetLIns() && !bodyPr1.isSetRIns() && | |||||
!bodyPr1.isSetBIns() && !bodyPr1.isSetTIns() && | |||||
!bodyPr1.isSetAnchor() | |||||
); | |||||
assertEquals(7.2, shape1.getMarginLeft()); // 0.1" | |||||
assertEquals(7.2, shape1.getMarginRight()); // 0.1" | |||||
assertEquals(3.6, shape1.getMarginTop()); // 0.05" | |||||
assertEquals(3.6, shape1.getMarginBottom()); // 0.05" | |||||
assertEquals(VerticalAlignment.BOTTOM, shape1.getVerticalAlignment()); | |||||
// now check text properties | |||||
assertEquals("Caption", shape1.getText()); | |||||
XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0); | |||||
assertEquals(TextAlign.LEFT, r1.getParentParagraph().getTextAlign()); | |||||
assertEquals("Calibri", r1.getFontFamily()); | |||||
assertEquals(20.0, r1.getFontSize()); | |||||
assertEquals(Color.black, r1.getFontColor()); | |||||
assertTrue(r1.isBold()); | |||||
XSLFTextShape shape2 = (XSLFTextShape)shapes[1]; | |||||
CTPlaceholder ph2 = shape2.getCTPlaceholder(); | |||||
assertFalse(ph2.isSetType()); | |||||
assertTrue(ph2.isSetIdx()); | |||||
assertEquals(1, ph2.getIdx()); | |||||
// anchor is not defined in the shape | |||||
assertNull(shape2.getSpPr().getXfrm()); | |||||
XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2); | |||||
assertNotNull(masterShape2.getSpPr().getXfrm()); | |||||
assertEquals(masterShape2.getAnchor(), shape2.getAnchor()); | |||||
CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr(); | |||||
// none of the following properties are set in the shapes and fetched from the master shape | |||||
assertTrue( | |||||
!bodyPr2.isSetLIns() && !bodyPr2.isSetRIns() && | |||||
!bodyPr2.isSetBIns() && !bodyPr2.isSetTIns() && | |||||
!bodyPr2.isSetAnchor() | |||||
); | |||||
assertEquals(7.2, shape2.getMarginLeft()); // 0.1" | |||||
assertEquals(7.2, shape2.getMarginRight()); // 0.1" | |||||
assertEquals(3.6, shape2.getMarginTop()); // 0.05" | |||||
assertEquals(3.6, shape2.getMarginBottom()); // 0.05" | |||||
assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment()); | |||||
XSLFTextRun pr1 = shape2.getTextParagraphs().get(0).getTextRuns().get(0); | |||||
assertEquals(0, pr1.getParentParagraph().getLevel()); | |||||
assertEquals("Level 1", pr1.getText()); | |||||
assertEquals("Calibri", pr1.getFontFamily()); | |||||
assertEquals(32.0, pr1.getFontSize()); | |||||
assertEquals(27.0, pr1.getParentParagraph().getLeftMargin()); | |||||
assertEquals("\u2022", pr1.getParentParagraph().getBulletCharacter()); | |||||
assertEquals("Arial", pr1.getParentParagraph().getBulletFont()); | |||||
XSLFTextRun pr2 = shape2.getTextParagraphs().get(1).getTextRuns().get(0); | |||||
assertEquals(1, pr2.getParentParagraph().getLevel()); | |||||
assertEquals("Level 2", pr2.getParentParagraph().getText()); | |||||
assertEquals("Calibri", pr2.getFontFamily()); | |||||
assertEquals(28.0, pr2.getFontSize()); | |||||
assertEquals(58.5, pr2.getParentParagraph().getLeftMargin()); | |||||
assertEquals("\u2013", pr2.getParentParagraph().getBulletCharacter()); | |||||
assertEquals("Arial", pr2.getParentParagraph().getBulletFont()); | |||||
XSLFTextRun pr3 = shape2.getTextParagraphs().get(2).getTextRuns().get(0); | |||||
assertEquals(2, pr3.getParentParagraph().getLevel()); | |||||
assertEquals("Level 3", pr3.getParentParagraph().getText()); | |||||
assertEquals("Calibri", pr3.getFontFamily()); | |||||
assertEquals(24.0, pr3.getFontSize()); | |||||
assertEquals(90.0, pr3.getParentParagraph().getLeftMargin()); | |||||
assertEquals("\u2022", pr3.getParentParagraph().getBulletCharacter()); | |||||
assertEquals("Arial", pr3.getParentParagraph().getBulletFont()); | |||||
XSLFTextRun pr4 = shape2.getTextParagraphs().get(3).getTextRuns().get(0); | |||||
assertEquals(3, pr4.getParentParagraph().getLevel()); | |||||
assertEquals("Level 4", pr4.getParentParagraph().getText()); | |||||
assertEquals("Calibri", pr4.getFontFamily()); | |||||
assertEquals(20.0, pr4.getFontSize()); | |||||
assertEquals(126.0, pr4.getParentParagraph().getLeftMargin()); | |||||
assertEquals("\u2013", pr4.getParentParagraph().getBulletCharacter()); | |||||
assertEquals("Arial", pr4.getParentParagraph().getBulletFont()); | |||||
XSLFTextShape shape3 = (XSLFTextShape)shapes[2]; | |||||
assertEquals(VerticalAlignment.TOP, shape3.getVerticalAlignment()); | |||||
assertEquals("Content with caption", shape3.getText()); | |||||
pr1 = shape3.getTextParagraphs().get(0).getTextRuns().get(0); | |||||
assertEquals(0, pr1.getParentParagraph().getLevel()); | |||||
assertEquals("Content with caption", pr1.getText()); | |||||
assertEquals("Calibri", pr1.getFontFamily()); | |||||
assertEquals(14.0, pr1.getFontSize()); | |||||
} | |||||
void verifySlide10(XSLFSlide slide){ | |||||
XSLFTextShape footer = (XSLFTextShape)slide.getPlaceholderByType(STPlaceholderType.INT_FTR); | |||||
// now check text properties | |||||
assertEquals("Apache Software Foundation", footer.getText()); | |||||
assertEquals(VerticalAlignment.MIDDLE, footer.getVerticalAlignment()); | |||||
XSLFTextRun r1 = footer.getTextParagraphs().get(0).getTextRuns().get(0); | |||||
assertEquals(TextAlign.CENTER, r1.getParentParagraph().getTextAlign()); | |||||
assertEquals("Calibri", r1.getFontFamily()); | |||||
assertEquals(12.0, r1.getFontSize()); | |||||
// TODO calculation of tint is incorrect | |||||
assertEquals(new Color(64,64,64), r1.getFontColor()); | |||||
XSLFTextShape dt = (XSLFTextShape)slide.getPlaceholderByType(STPlaceholderType.INT_DT); | |||||
assertEquals("Friday, October 21, 2011", dt.getText()); | |||||
XSLFTextShape sldNum = (XSLFTextShape)slide.getPlaceholderByType(STPlaceholderType.INT_SLD_NUM); | |||||
assertEquals("10", sldNum.getText()); | |||||
} | |||||
} |
/* ==================================================================== | |||||
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 junit.framework.TestCase; | |||||
import org.apache.poi.xslf.XSLFTestDataSamples; | |||||
/** | |||||
* test common properties for sheets (slides, masters, layouts, etc.) | |||||
* | |||||
* @author Yegor Kozlov | |||||
*/ | |||||
public class TestXSLFTheme extends TestCase { | |||||
public void testRead(){ | |||||
XMLSlideShow ppt = new XMLSlideShow(); | |||||
XSLFSlide slide = ppt.createSlide(); | |||||
XSLFTheme theme = slide.getSlideLayout().getSlideMaster().getTheme(); | |||||
assertNotNull(theme); | |||||
assertEquals("Office Theme", theme.getName()); | |||||
XSLFColor accent1 = theme.getColor("accent1"); | |||||
assertNotNull(accent1); | |||||
} | |||||
} |