initial support for rendering pptx slides into images with a PPTX2PNG command-line utility
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1187328 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
cf1c5ee9e1
commit
3c6ce72dda
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
<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>
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
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
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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);
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
}
|
@ -21,6 +21,8 @@ package org.apache.poi.xslf.usermodel;
|
|||||||
|
|
||||||
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;
|
||||||
@ -39,8 +41,12 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
|
|||||||
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.
|
||||||
@ -49,6 +55,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
@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);
|
||||||
@ -83,44 +90,6 @@ public class XSLFAutoShape extends XSLFTextShape {
|
|||||||
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();
|
||||||
@ -132,4 +101,38 @@ public class XSLFAutoShape extends XSLFTextShape {
|
|||||||
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
54
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java
Normal file
54
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
@ -32,6 +32,10 @@ import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndLength;
|
|||||||
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.
|
||||||
@ -192,4 +196,36 @@ public class XSLFConnectorShape extends XSLFSimpleShape {
|
|||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -111,34 +111,45 @@ public class XSLFFreeformShape extends XSLFAutoShape {
|
|||||||
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),
|
path.moveTo((float)Units.toPoints((Long)pt.getX())*scaleW,
|
||||||
(float)Units.toPoints((Long)pt.getY() + y0));
|
(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),
|
path.lineTo((float)Units.toPoints((Long)pt.getX()),
|
||||||
(float)Units.toPoints((Long)pt.getY() + y0));
|
(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.getX())*scaleW,
|
||||||
(float)Units.toPoints((Long) pt1.getY() + y0),
|
(float)Units.toPoints((Long) pt1.getY())*scaleH,
|
||||||
(float)Units.toPoints((Long) pt2.getX() + x0),
|
(float)Units.toPoints((Long) pt2.getX())*scaleW,
|
||||||
(float)Units.toPoints((Long) pt2.getY() + y0),
|
(float)Units.toPoints((Long) pt2.getY())*scaleH,
|
||||||
(float)Units.toPoints((Long) pt3.getX() + x0),
|
(float)Units.toPoints((Long) pt3.getX())*scaleW,
|
||||||
(float)Units.toPoints((Long) pt3.getY() + y0)
|
(float)Units.toPoints((Long) pt3.getY())*scaleH
|
||||||
);
|
);
|
||||||
|
|
||||||
} else if (ch instanceof CTPath2DClose){
|
} else if (ch instanceof CTPath2DClose){
|
||||||
@ -147,7 +158,11 @@ public class XSLFFreeformShape extends XSLFAutoShape {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
@ -175,4 +190,9 @@ public class XSLFFreeformShape extends XSLFAutoShape {
|
|||||||
return ct;
|
return ct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected java.awt.Shape getOutline(){
|
||||||
|
return getPath();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,16 @@ import org.apache.poi.sl.usermodel.Shape;
|
|||||||
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,11 +69,31 @@ public class XSLFGraphicFrame extends XSLFShape {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -78,4 +106,56 @@ public class XSLFGraphicFrame extends XSLFShape {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -33,11 +33,14 @@ 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.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;
|
||||||
@ -217,4 +220,80 @@ public class XSLFGroupShape extends XSLFShape {
|
|||||||
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -22,16 +22,24 @@ package org.apache.poi.xslf.usermodel;
|
|||||||
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;
|
||||||
@ -104,4 +112,43 @@ public class XSLFPictureShape extends XSLFSimpleShape {
|
|||||||
}
|
}
|
||||||
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,637 @@
|
|||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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);
|
||||||
|
}
|
106
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java
Normal file
106
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFShadow.java
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -19,10 +19,11 @@
|
|||||||
|
|
||||||
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,4 +42,76 @@ public abstract class XSLFShape {
|
|||||||
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -21,6 +21,7 @@ import org.apache.poi.openxml4j.opc.PackagePart;
|
|||||||
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;
|
||||||
@ -30,9 +31,13 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFra
|
|||||||
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;
|
||||||
@ -47,6 +52,8 @@ public abstract class XSLFSheet extends POIXMLDocumentPart {
|
|||||||
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();
|
||||||
@ -187,6 +194,10 @@ public abstract class XSLFSheet extends POIXMLDocumentPart {
|
|||||||
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(){
|
||||||
@ -232,4 +243,112 @@ public abstract class XSLFSheet extends POIXMLDocumentPart {
|
|||||||
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -21,6 +21,7 @@ package org.apache.poi.xslf.usermodel;
|
|||||||
|
|
||||||
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;
|
||||||
@ -28,14 +29,22 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;
|
|||||||
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;
|
||||||
@ -48,26 +57,31 @@ public abstract class XSLFSimpleShape extends XSLFShape {
|
|||||||
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();
|
CTPresetGeometry2D prst = getSpPr().getPrstGeom();
|
||||||
return stEnum.intValue();
|
STShapeType.Enum stEnum = prst == null ? null : prst.getPrst();
|
||||||
|
return stEnum == null ? 0 : stEnum.intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getShapeName() {
|
public String getShapeName() {
|
||||||
@ -75,36 +89,75 @@ public abstract class XSLFSimpleShape extends XSLFShape {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getShapeId() {
|
public int getShapeId() {
|
||||||
return (int)getNvPr().getId();
|
return (int) getNvPr().getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CTNonVisualDrawingProps getNvPr(){
|
protected CTNonVisualDrawingProps getNvPr() {
|
||||||
if(_nvPr == null){
|
if (_nvPr == null) {
|
||||||
XmlObject[] rs = _shape.selectPath(
|
XmlObject[] rs = _shape
|
||||||
"declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr");
|
.selectPath("declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr");
|
||||||
if(rs.length != 0) {
|
if (rs.length != 0) {
|
||||||
_nvPr = (CTNonVisualDrawingProps)rs[0];
|
_nvPr = (CTNonVisualDrawingProps) rs[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return _nvPr;
|
return _nvPr;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CTShapeProperties getSpPr(){
|
protected CTShapeProperties getSpPr() {
|
||||||
if(_spPr == null) {
|
if (_spPr == null) {
|
||||||
for(XmlObject obj : _shape.selectPath("*")){
|
for (XmlObject obj : _shape.selectPath("*")) {
|
||||||
if(obj instanceof CTShapeProperties){
|
if (obj instanceof CTShapeProperties) {
|
||||||
_spPr = (CTShapeProperties)obj;
|
_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(){
|
protected CTShapeStyle getSpStyle() {
|
||||||
CTTransform2D xfrm = getSpPr().getXfrm();
|
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();
|
||||||
@ -116,14 +169,16 @@ public abstract class XSLFSimpleShape extends XSLFShape {
|
|||||||
Units.toPoints(cx), Units.toPoints(cy));
|
Units.toPoints(cx), Units.toPoints(cy));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAnchor(Rectangle2D anchor){
|
public void setAnchor(Rectangle2D anchor) {
|
||||||
CTTransform2D xfrm = getSpPr().isSetXfrm() ? getSpPr().getXfrm() : getSpPr().addNewXfrm();
|
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);
|
||||||
@ -134,135 +189,489 @@ public abstract class XSLFSimpleShape extends XSLFShape {
|
|||||||
* 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){
|
public void setRotation(double theta) {
|
||||||
CTTransform2D xfrm = getSpPr().getXfrm();
|
CTShapeProperties spPr = getSpPr();
|
||||||
xfrm.setRot((int)(theta*60000));
|
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(){
|
public double getRotation() {
|
||||||
CTTransform2D xfrm = getSpPr().getXfrm();
|
CTTransform2D xfrm = getXfrm();
|
||||||
return (double)xfrm.getRot()/60000;
|
return (double) xfrm.getRot() / 60000;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFlipHorizontal(boolean flip){
|
public void setFlipHorizontal(boolean flip) {
|
||||||
CTTransform2D xfrm = getSpPr().getXfrm();
|
CTShapeProperties spPr = getSpPr();
|
||||||
|
CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();
|
||||||
xfrm.setFlipH(flip);
|
xfrm.setFlipH(flip);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFlipVertical(boolean flip){
|
public void setFlipVertical(boolean flip) {
|
||||||
CTTransform2D xfrm = getSpPr().getXfrm();
|
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(){
|
public boolean getFlipHorizontal() {
|
||||||
return getSpPr().getXfrm().getFlipH();
|
return getXfrm().getFlipH();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getFlipVertical(){
|
public boolean getFlipVertical() {
|
||||||
return getSpPr().getXfrm().getFlipV();
|
return getXfrm().getFlipV();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLineColor(Color color){
|
/**
|
||||||
CTShapeProperties spPr = getSpPr();
|
* Get line properties defined in the theme (if any)
|
||||||
if(color == null) {
|
*
|
||||||
if(spPr.isSetLn() && spPr.getLn().isSetSolidFill()) spPr.getLn().unsetSolidFill();
|
* @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 {
|
return ln;
|
||||||
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn();
|
}
|
||||||
|
|
||||||
|
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(){
|
public Color getLineColor() {
|
||||||
CTShapeProperties spPr = getSpPr();
|
final XSLFTheme theme = _sheet.getTheme();
|
||||||
if(!spPr.isSetLn() || !spPr.getLn().isSetSolidFill()) return null;
|
|
||||||
|
|
||||||
CTSRgbColor rgb = spPr.getLn().getSolidFill().getSrgbClr();
|
PropertyFetcher<Color> fetcher = new PropertyFetcher<Color>(){
|
||||||
byte[] val = rgb.getVal();
|
public boolean fetch(XSLFSimpleShape shape){
|
||||||
return new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]);
|
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 (width == 0.) {
|
||||||
if(spPr.isSetLn()) spPr.getLn().unsetW();
|
if (spPr.isSetLn())
|
||||||
}
|
spPr.getLn().unsetW();
|
||||||
else {
|
} else {
|
||||||
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn();
|
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr
|
||||||
|
.addNewLn();
|
||||||
ln.setW(Units.toEMU(width));
|
ln.setW(Units.toEMU(width));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getLineWidth(){
|
public double getLineWidth() {
|
||||||
CTShapeProperties spPr = getSpPr();
|
PropertyFetcher<Double> fetcher = new PropertyFetcher<Double>(){
|
||||||
CTLineProperties ln = spPr.getLn();
|
public boolean fetch(XSLFSimpleShape shape){
|
||||||
if(ln == null || !ln.isSetW()) return 0;
|
CTShapeProperties spPr = shape.getSpPr();
|
||||||
|
CTLineProperties ln = spPr.getLn();
|
||||||
|
if (ln != null) {
|
||||||
|
if (ln.isSetNoFill()) {
|
||||||
|
setValue(0.);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return Units.toPoints(ln.getW());
|
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 lineWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLineDash(LineDash dash){
|
public void setLineDash(LineDash dash) {
|
||||||
CTShapeProperties spPr = getSpPr();
|
CTShapeProperties spPr = getSpPr();
|
||||||
if(dash == null) {
|
if (dash == null) {
|
||||||
if(spPr.isSetLn()) spPr.getLn().unsetPrstDash();
|
if (spPr.isSetLn())
|
||||||
}
|
spPr.getLn().unsetPrstDash();
|
||||||
else {
|
} else {
|
||||||
CTPresetLineDashProperties val = CTPresetLineDashProperties.Factory.newInstance();
|
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() {
|
||||||
CTShapeProperties spPr = getSpPr();
|
|
||||||
CTLineProperties ln = spPr.getLn();
|
|
||||||
if(ln == null || !ln.isSetPrstDash()) return null;
|
|
||||||
|
|
||||||
CTPresetLineDashProperties dash = ln.getPrstDash();
|
PropertyFetcher<LineDash> fetcher = new PropertyFetcher<LineDash>(){
|
||||||
return LineDash.values()[dash.getVal().intValue() - 1];
|
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){
|
public void setLineCap(LineCap cap) {
|
||||||
CTShapeProperties spPr = getSpPr();
|
CTShapeProperties spPr = getSpPr();
|
||||||
if(cap == null) {
|
if (cap == null) {
|
||||||
if(spPr.isSetLn()) spPr.getLn().unsetCap();
|
if (spPr.isSetLn())
|
||||||
}
|
spPr.getLn().unsetCap();
|
||||||
else {
|
} else {
|
||||||
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn();
|
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr
|
||||||
|
.addNewLn();
|
||||||
ln.setCap(STLineCap.Enum.forInt(cap.ordinal() + 1));
|
ln.setCap(STLineCap.Enum.forInt(cap.ordinal() + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public LineCap getLineCap(){
|
public LineCap getLineCap() {
|
||||||
CTShapeProperties spPr = getSpPr();
|
PropertyFetcher<LineCap> fetcher = new PropertyFetcher<LineCap>(){
|
||||||
CTLineProperties ln = spPr.getLn();
|
public boolean fetch(XSLFSimpleShape shape){
|
||||||
if(ln == null || !ln.isSetCap()) return null;
|
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);
|
||||||
|
|
||||||
return LineCap.values()[ln.getCap().intValue() - 1];
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 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 ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
==================================================================== */
|
==================================================================== */
|
||||||
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;
|
||||||
@ -23,16 +24,20 @@ import org.apache.poi.openxml4j.opc.PackagePart;
|
|||||||
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 {
|
||||||
@ -112,6 +117,7 @@ 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()) {
|
||||||
@ -125,7 +131,12 @@ public final class XSLFSlide extends XSLFSheet {
|
|||||||
}
|
}
|
||||||
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()) {
|
||||||
@ -165,4 +176,37 @@ public final class XSLFSlide extends XSLFSheet {
|
|||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,11 +22,18 @@ import org.apache.poi.openxml4j.opc.PackageRelationship;
|
|||||||
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 {
|
||||||
@ -84,6 +91,7 @@ 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()) {
|
||||||
@ -101,4 +109,40 @@ public class XSLFSlideLayout extends XSLFSheet {
|
|||||||
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;
|
||||||
|
}
|
||||||
}
|
}
|
@ -24,6 +24,8 @@ import org.apache.poi.util.Beta;
|
|||||||
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;
|
||||||
@ -101,4 +103,24 @@ import java.util.Map;
|
|||||||
}
|
}
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -126,32 +126,4 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
|
|||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,17 +21,23 @@ package org.apache.poi.xslf.usermodel;
|
|||||||
|
|
||||||
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
|
||||||
@ -84,14 +90,4 @@ public class XSLFTextBox extends XSLFAutoShape {
|
|||||||
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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -19,15 +19,28 @@ package org.apache.poi.xslf.usermodel;
|
|||||||
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.
|
||||||
@ -41,20 +54,29 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
|||||||
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()) {
|
for (XSLFTextRun r : _runs) {
|
||||||
out.append(r.getT());
|
out.append(r.getText());
|
||||||
}
|
}
|
||||||
return out.toString();
|
return out.toString();
|
||||||
}
|
}
|
||||||
@ -95,10 +117,18 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
|||||||
* @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();
|
ParagraphPropertyFetcher<TextAlign> fetcher = new ParagraphPropertyFetcher<TextAlign>(getLevel()){
|
||||||
if(pr == null || !pr.isSetAlgn()) return TextAlign.LEFT;
|
public boolean fetch(CTTextParagraphProperties props){
|
||||||
|
if(props.isSetAlgn()){
|
||||||
return TextAlign.values()[pr.getAlgn().intValue() - 1];
|
TextAlign val = TextAlign.values()[props.getAlgn().intValue() - 1];
|
||||||
|
setValue(val);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchParagraphProperty(fetcher);
|
||||||
|
return fetcher.getValue() == null ? TextAlign.LEFT : fetcher.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -117,6 +147,74 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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.
|
||||||
*
|
*
|
||||||
@ -137,10 +235,19 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
|||||||
* @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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -160,10 +267,18 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
|||||||
* @return the left margin of the paragraph
|
* @return the left margin of the paragraph
|
||||||
*/
|
*/
|
||||||
public double getLeftMargin(){
|
public double getLeftMargin(){
|
||||||
CTTextParagraphProperties pr = _p.getPPr();
|
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
|
||||||
if(pr == null || !pr.isSetMarL()) return 0;
|
public boolean fetch(CTTextParagraphProperties props){
|
||||||
|
if(props.isSetMarL()){
|
||||||
return Units.toPoints(pr.getMarL());
|
double val = Units.toPoints(props.getMarL());
|
||||||
|
setValue(val);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchParagraphProperty(fetcher);
|
||||||
|
return fetcher.getValue() == null ? 0 : fetcher.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -206,13 +321,20 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
|||||||
* @return the vertical line spacing.
|
* @return the vertical line spacing.
|
||||||
*/
|
*/
|
||||||
public double getLineSpacing(){
|
public double getLineSpacing(){
|
||||||
CTTextParagraphProperties pr = _p.getPPr();
|
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
|
||||||
if(pr == null || !pr.isSetLnSpc()) return 100; // TODO fetch from master
|
public boolean fetch(CTTextParagraphProperties props){
|
||||||
|
if(props.isSetLnSpc()){
|
||||||
|
CTTextSpacing spc = props.getLnSpc();
|
||||||
|
|
||||||
CTTextSpacing spc = pr.getLnSpc();
|
if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 );
|
||||||
if(spc.isSetSpcPct()) return spc.getSpcPct().getVal()*0.001;
|
else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 );
|
||||||
else if (spc.isSetSpcPts()) return -spc.getSpcPts().getVal()*0.01;
|
return true;
|
||||||
else return 100;
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchParagraphProperty(fetcher);
|
||||||
|
return fetcher.getValue() == null ? 100 : fetcher.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -253,13 +375,20 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
|||||||
* @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();
|
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
|
||||||
if(pr == null || !pr.isSetSpcBef()) return 0; // TODO fetch from master
|
public boolean fetch(CTTextParagraphProperties props){
|
||||||
|
if(props.isSetSpcBef()){
|
||||||
|
CTTextSpacing spc = props.getSpcBef();
|
||||||
|
|
||||||
CTTextSpacing spc = pr.getSpcBef();
|
if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 );
|
||||||
if(spc.isSetSpcPct()) return spc.getSpcPct().getVal()*0.001;
|
else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 );
|
||||||
else if (spc.isSetSpcPts()) return -spc.getSpcPts().getVal()*0.01;
|
return true;
|
||||||
else return 0;
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchParagraphProperty(fetcher);
|
||||||
|
return fetcher.getValue() == null ? 0 : fetcher.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -300,13 +429,20 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
|||||||
* @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();
|
ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
|
||||||
if(pr == null || !pr.isSetSpcAft()) return 0; // TODO fetch from master
|
public boolean fetch(CTTextParagraphProperties props){
|
||||||
|
if(props.isSetSpcAft()){
|
||||||
|
CTTextSpacing spc = props.getSpcAft();
|
||||||
|
|
||||||
CTTextSpacing spc = pr.getSpcAft();
|
if(spc.isSetSpcPct()) setValue( spc.getSpcPct().getVal()*0.001 );
|
||||||
if(spc.isSetSpcPct()) return spc.getSpcPct().getVal()*0.001;
|
else if (spc.isSetSpcPts()) setValue( -spc.getSpcPts().getVal()*0.01 );
|
||||||
else if (spc.isSetSpcPts()) return -spc.getSpcPts().getVal()*0.01;
|
return true;
|
||||||
else return 0;
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchParagraphProperty(fetcher);
|
||||||
|
return fetcher.getValue() == null ? 0 : fetcher.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -334,8 +470,256 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
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;
|
||||||
@ -24,6 +26,9 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties
|
|||||||
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.*;
|
||||||
|
|
||||||
@ -66,6 +71,23 @@ public class XSLFTextRun {
|
|||||||
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.
|
||||||
@ -84,9 +106,17 @@ public class XSLFTextRun {
|
|||||||
* @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;
|
CharacterPropertyFetcher<Double> fetcher = new CharacterPropertyFetcher<Double>(_p.getLevel()){
|
||||||
|
public boolean fetch(CTTextCharacterProperties props){
|
||||||
return _r.getRPr().getSz()*0.01;
|
if(props.isSetSz()){
|
||||||
|
setValue(props.getSz()*0.01);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchCharacterProperty(fetcher);
|
||||||
|
return fetcher.getValue() == null ? -1 : fetcher.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -120,12 +150,30 @@ public class XSLFTextRun {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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();
|
||||||
|
|
||||||
return _r.getRPr().getLatin().getTypeface();
|
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 visitor.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -140,10 +188,18 @@ public class XSLFTextRun {
|
|||||||
/**
|
/**
|
||||||
* @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(){
|
public boolean isStrikethrough() {
|
||||||
if(!_r.isSetRPr()) return false;
|
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getLevel()){
|
||||||
|
public boolean fetch(CTTextCharacterProperties props){
|
||||||
return _r.getRPr().getStrike() == STTextStrikeType.SNG_STRIKE;
|
if(props.isSetStrike()){
|
||||||
|
setValue(props.getStrike() != STTextStrikeType.NO_STRIKE);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchCharacterProperty(fetcher);
|
||||||
|
return fetcher.getValue() == null ? false : fetcher.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -159,9 +215,17 @@ public class XSLFTextRun {
|
|||||||
* @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;
|
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getLevel()){
|
||||||
|
public boolean fetch(CTTextCharacterProperties props){
|
||||||
return _r.getRPr().getB();
|
if(props.isSetB()){
|
||||||
|
setValue(props.getB());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchCharacterProperty(fetcher);
|
||||||
|
return fetcher.getValue() == null ? false : fetcher.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -175,9 +239,17 @@ public class XSLFTextRun {
|
|||||||
* @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;
|
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getLevel()){
|
||||||
|
public boolean fetch(CTTextCharacterProperties props){
|
||||||
return _r.getRPr().getI();
|
if(props.isSetI()){
|
||||||
|
setValue(props.getI());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchCharacterProperty(fetcher);
|
||||||
|
return fetcher.getValue() == null ? false : fetcher.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -191,9 +263,17 @@ public class XSLFTextRun {
|
|||||||
* @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;
|
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getLevel()){
|
||||||
|
public boolean fetch(CTTextCharacterProperties props){
|
||||||
return _r.getRPr().getU() != STTextUnderlineType.NONE;
|
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(){
|
||||||
@ -216,4 +296,22 @@ public class XSLFTextRun {
|
|||||||
|
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -21,18 +21,20 @@ package org.apache.poi.xslf.usermodel;
|
|||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@ -79,43 +81,6 @@ public abstract class XSLFTextShape extends XSLFSimpleShape {
|
|||||||
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.
|
||||||
@ -140,14 +105,18 @@ public abstract class XSLFTextShape extends XSLFSimpleShape {
|
|||||||
* @return the type of alignment
|
* @return the type of alignment
|
||||||
*/
|
*/
|
||||||
public VerticalAlignment getVerticalAlignment(){
|
public VerticalAlignment getVerticalAlignment(){
|
||||||
CTTextBodyProperties bodyPr = getTextBodyPr();
|
PropertyFetcher<VerticalAlignment> fetcher = new TextBodyPropertyFetcher<VerticalAlignment>(){
|
||||||
if (bodyPr != null) {
|
public boolean fetch(CTTextBodyProperties props){
|
||||||
STTextAnchoringType.Enum val = bodyPr.getAnchor();
|
if(props.isSetAnchor()){
|
||||||
if(val != null){
|
int val = props.getAnchor().intValue();
|
||||||
return VerticalAlignment.values()[val.intValue() - 1];
|
setValue(VerticalAlignment.values()[val - 1]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
return VerticalAlignment.TOP;
|
fetchShapeProperty(fetcher);
|
||||||
|
return fetcher.getValue() == null ? VerticalAlignment.TOP : fetcher.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -185,11 +154,18 @@ public abstract class XSLFTextShape extends XSLFSimpleShape {
|
|||||||
* @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();
|
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){
|
||||||
if (bodyPr != null) {
|
public boolean fetch(CTTextBodyProperties props){
|
||||||
return bodyPr.isSetBIns() ? Units.toPoints(bodyPr.getBIns()) : -1;
|
if(props.isSetBIns()){
|
||||||
}
|
double val = Units.toPoints(props.getBIns());
|
||||||
return -1;
|
setValue(val);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchShapeProperty(fetcher);
|
||||||
|
return fetcher.getValue() == null ? 0 : fetcher.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -200,11 +176,18 @@ public abstract class XSLFTextShape extends XSLFSimpleShape {
|
|||||||
* @return the left margin
|
* @return the left margin
|
||||||
*/
|
*/
|
||||||
public double getMarginLeft(){
|
public double getMarginLeft(){
|
||||||
CTTextBodyProperties bodyPr = getTextBodyPr();
|
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){
|
||||||
if (bodyPr != null) {
|
public boolean fetch(CTTextBodyProperties props){
|
||||||
return bodyPr.isSetLIns() ? Units.toPoints(bodyPr.getLIns()) : -1;
|
if(props.isSetLIns()){
|
||||||
}
|
double val = Units.toPoints(props.getLIns());
|
||||||
return -1;
|
setValue(val);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchShapeProperty(fetcher);
|
||||||
|
return fetcher.getValue() == null ? 0 : fetcher.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -215,11 +198,18 @@ public abstract class XSLFTextShape extends XSLFSimpleShape {
|
|||||||
* @return the right margin
|
* @return the right margin
|
||||||
*/
|
*/
|
||||||
public double getMarginRight(){
|
public double getMarginRight(){
|
||||||
CTTextBodyProperties bodyPr = getTextBodyPr();
|
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){
|
||||||
if (bodyPr != null) {
|
public boolean fetch(CTTextBodyProperties props){
|
||||||
return bodyPr.isSetRIns() ? Units.toPoints(bodyPr.getRIns()) : -1;
|
if(props.isSetRIns()){
|
||||||
}
|
double val = Units.toPoints(props.getRIns());
|
||||||
return -1;
|
setValue(val);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchShapeProperty(fetcher);
|
||||||
|
return fetcher.getValue() == null ? 0 : fetcher.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -229,11 +219,18 @@ public abstract class XSLFTextShape extends XSLFSimpleShape {
|
|||||||
* @return the top margin
|
* @return the top margin
|
||||||
*/
|
*/
|
||||||
public double getMarginTop(){
|
public double getMarginTop(){
|
||||||
CTTextBodyProperties bodyPr = getTextBodyPr();
|
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){
|
||||||
if (bodyPr != null) {
|
public boolean fetch(CTTextBodyProperties props){
|
||||||
return bodyPr.isSetTIns() ? Units.toPoints(bodyPr.getTIns()) : -1;
|
if(props.isSetTIns()){
|
||||||
}
|
double val = Units.toPoints(props.getTIns());
|
||||||
return -1;
|
setValue(val);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchShapeProperty(fetcher);
|
||||||
|
return fetcher.getValue() == null ? 0 : fetcher.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -300,11 +297,17 @@ public abstract class XSLFTextShape extends XSLFSimpleShape {
|
|||||||
* @return the value indicating word wrap
|
* @return the value indicating word wrap
|
||||||
*/
|
*/
|
||||||
public boolean getWordWrap(){
|
public boolean getWordWrap(){
|
||||||
CTTextBodyProperties bodyPr = getTextBodyPr();
|
PropertyFetcher<Boolean> fetcher = new TextBodyPropertyFetcher<Boolean>(){
|
||||||
if (bodyPr != null) {
|
public boolean fetch(CTTextBodyProperties props){
|
||||||
return bodyPr.getWrap() == STTextWrappingType.SQUARE;
|
if(props.isSetWrap()){
|
||||||
}
|
setValue(props.getWrap() == STTextWrappingType.SQUARE);
|
||||||
return false;
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchShapeProperty(fetcher);
|
||||||
|
return fetcher.getValue() == null ? true : fetcher.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -362,4 +365,132 @@ public abstract class XSLFTextShape extends XSLFSimpleShape {
|
|||||||
|
|
||||||
|
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -22,15 +22,21 @@ import org.apache.poi.openxml4j.opc.PackageRelationship;
|
|||||||
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.drawingml.x2006.main.CTSchemeColor;
|
||||||
import org.openxmlformats.schemas.presentationml.x2006.main.SldLayoutDocument;
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTBaseStyles;
|
||||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMaster;
|
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;
|
||||||
@ -39,7 +45,8 @@ import java.util.HashMap;
|
|||||||
@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();
|
||||||
@ -50,8 +57,24 @@ public class XSLFTheme extends POIXMLDocumentPart {
|
|||||||
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();
|
||||||
@ -62,6 +85,146 @@ public class XSLFTheme extends POIXMLDocumentPart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* 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
|
||||||
@ -84,4 +247,31 @@ public class XSLFTheme extends POIXMLDocumentPart {
|
|||||||
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
101
src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java
Normal file
101
src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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");
|
||||||
|
}
|
||||||
|
}
|
@ -41,7 +41,6 @@ public class TestXMLSlideShow extends TestCase {
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -33,11 +33,11 @@ public class TestXSLFAutoShape extends TestCase {
|
|||||||
XSLFAutoShape shape = slide.createAutoShape();
|
XSLFAutoShape shape = slide.createAutoShape();
|
||||||
shape.addNewTextParagraph().addNewTextRun().setText("POI");
|
shape.addNewTextParagraph().addNewTextRun().setText("POI");
|
||||||
|
|
||||||
// margins
|
// default margins from slide master
|
||||||
assertEquals(-1., shape.getMarginBottom());
|
assertEquals(3.6, shape.getMarginBottom());
|
||||||
assertEquals(-1., shape.getMarginTop());
|
assertEquals(3.6, shape.getMarginTop());
|
||||||
assertEquals(-1., shape.getMarginLeft());
|
assertEquals(7.2, shape.getMarginLeft());
|
||||||
assertEquals(-1., shape.getMarginRight());
|
assertEquals(7.2, shape.getMarginRight());
|
||||||
|
|
||||||
shape.setMarginBottom(1.0);
|
shape.setMarginBottom(1.0);
|
||||||
assertEquals(1.0, shape.getMarginBottom());
|
assertEquals(1.0, shape.getMarginBottom());
|
||||||
@ -57,21 +57,22 @@ public class TestXSLFAutoShape extends TestCase {
|
|||||||
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());
|
||||||
@ -209,7 +210,7 @@ public class TestXSLFAutoShape extends TestCase {
|
|||||||
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());
|
||||||
@ -220,9 +221,9 @@ public class TestXSLFAutoShape extends TestCase {
|
|||||||
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());
|
||||||
@ -230,7 +231,7 @@ public class TestXSLFAutoShape extends TestCase {
|
|||||||
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());
|
||||||
|
@ -21,8 +21,10 @@ import junit.framework.TestCase;
|
|||||||
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.*;
|
||||||
|
|
||||||
@ -129,4 +131,107 @@ public class TestXSLFSimpleShape extends TestCase {
|
|||||||
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());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -28,10 +28,10 @@ public class TestXSLFTextBox extends TestCase {
|
|||||||
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,609 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
19915
src/resources/scratchpad/org/apache/poi/xslf/usermodel/presetShapeDefinitions.xml
Executable file
19915
src/resources/scratchpad/org/apache/poi/xslf/usermodel/presetShapeDefinitions.xml
Executable file
File diff suppressed because it is too large
Load Diff
BIN
test-data/slideshow/layouts.pptx
Executable file
BIN
test-data/slideshow/layouts.pptx
Executable file
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user