more progress with PPTX2PNG
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1188091 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
a15034b281
commit
f1a2673950
@ -33,19 +33,17 @@ 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.*;
|
||||||
import java.awt.geom.GeneralPath;
|
import java.awt.geom.*;
|
||||||
import java.awt.geom.Rectangle2D;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Specifies a connection shape.
|
||||||
* Specifies a connection shape.
|
|
||||||
*
|
*
|
||||||
* @author Yegor Kozlov
|
* @author Yegor Kozlov
|
||||||
*/
|
*/
|
||||||
@Beta
|
@Beta
|
||||||
public class XSLFConnectorShape extends XSLFSimpleShape {
|
public class XSLFConnectorShape extends XSLFSimpleShape {
|
||||||
|
|
||||||
/*package*/ XSLFConnectorShape(CTConnector shape, XSLFSheet sheet){
|
/*package*/ XSLFConnectorShape(CTConnector shape, XSLFSheet sheet) {
|
||||||
super(shape, sheet);
|
super(shape, sheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,19 +69,19 @@ public class XSLFConnectorShape extends XSLFSimpleShape {
|
|||||||
/**
|
/**
|
||||||
* Specifies the line end decoration, such as a triangle or arrowhead.
|
* Specifies the line end decoration, such as a triangle or arrowhead.
|
||||||
*/
|
*/
|
||||||
public void setLineHeadDecoration(LineDecoration style){
|
public void setLineHeadDecoration(LineDecoration style) {
|
||||||
CTLineProperties ln = getSpPr().getLn();
|
CTLineProperties ln = getSpPr().getLn();
|
||||||
CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
|
CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
|
||||||
if(style == null){
|
if (style == null) {
|
||||||
if(lnEnd.isSetType()) lnEnd.unsetType();
|
if (lnEnd.isSetType()) lnEnd.unsetType();
|
||||||
} else {
|
} else {
|
||||||
lnEnd.setType(STLineEndType.Enum.forInt(style.ordinal() + 1));
|
lnEnd.setType(STLineEndType.Enum.forInt(style.ordinal() + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public LineDecoration getLineHeadDecoration(){
|
public LineDecoration getLineHeadDecoration() {
|
||||||
CTLineProperties ln = getSpPr().getLn();
|
CTLineProperties ln = getSpPr().getLn();
|
||||||
if(!ln.isSetHeadEnd()) return LineDecoration.NONE;
|
if (ln == null || !ln.isSetHeadEnd()) return LineDecoration.NONE;
|
||||||
|
|
||||||
STLineEndType.Enum end = ln.getHeadEnd().getType();
|
STLineEndType.Enum end = ln.getHeadEnd().getType();
|
||||||
return end == null ? LineDecoration.NONE : LineDecoration.values()[end.intValue() - 1];
|
return end == null ? LineDecoration.NONE : LineDecoration.values()[end.intValue() - 1];
|
||||||
@ -92,62 +90,62 @@ public class XSLFConnectorShape extends XSLFSimpleShape {
|
|||||||
/**
|
/**
|
||||||
* specifies decorations which can be added to the head of a line.
|
* specifies decorations which can be added to the head of a line.
|
||||||
*/
|
*/
|
||||||
public void setLineHeadWidth(LineEndWidth style){
|
public void setLineHeadWidth(LineEndWidth style) {
|
||||||
CTLineProperties ln = getSpPr().getLn();
|
CTLineProperties ln = getSpPr().getLn();
|
||||||
CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
|
CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
|
||||||
if(style == null){
|
if (style == null) {
|
||||||
if(lnEnd.isSetW()) lnEnd.unsetW();
|
if (lnEnd.isSetW()) lnEnd.unsetW();
|
||||||
} else {
|
} else {
|
||||||
lnEnd.setW(STLineEndWidth.Enum.forInt(style.ordinal() + 1));
|
lnEnd.setW(STLineEndWidth.Enum.forInt(style.ordinal() + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public LineEndWidth getLineHeadWidth(){
|
public LineEndWidth getLineHeadWidth() {
|
||||||
CTLineProperties ln = getSpPr().getLn();
|
CTLineProperties ln = getSpPr().getLn();
|
||||||
if(!ln.isSetHeadEnd()) return null;
|
if (ln == null || !ln.isSetHeadEnd()) return LineEndWidth.MEDIUM;
|
||||||
|
|
||||||
STLineEndWidth.Enum w = ln.getHeadEnd().getW();
|
STLineEndWidth.Enum w = ln.getHeadEnd().getW();
|
||||||
return w == null ? null : LineEndWidth.values()[w.intValue() - 1];
|
return w == null ? LineEndWidth.MEDIUM : LineEndWidth.values()[w.intValue() - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies the line end width in relation to the line width.
|
* Specifies the line end width in relation to the line width.
|
||||||
*/
|
*/
|
||||||
public void setLineHeadLength(LineEndLength style){
|
public void setLineHeadLength(LineEndLength style) {
|
||||||
CTLineProperties ln = getSpPr().getLn();
|
CTLineProperties ln = getSpPr().getLn();
|
||||||
CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
|
CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
|
||||||
|
|
||||||
if(style == null){
|
if (style == null) {
|
||||||
if(lnEnd.isSetLen()) lnEnd.unsetLen();
|
if (lnEnd.isSetLen()) lnEnd.unsetLen();
|
||||||
} else {
|
} else {
|
||||||
lnEnd.setLen(STLineEndLength.Enum.forInt(style.ordinal() + 1));
|
lnEnd.setLen(STLineEndLength.Enum.forInt(style.ordinal() + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public LineEndLength getLineHeadLength(){
|
public LineEndLength getLineHeadLength() {
|
||||||
CTLineProperties ln = getSpPr().getLn();
|
CTLineProperties ln = getSpPr().getLn();
|
||||||
if(!ln.isSetHeadEnd()) return null;
|
if (ln == null || !ln.isSetHeadEnd()) return LineEndLength.MEDIUM;
|
||||||
|
|
||||||
STLineEndLength.Enum len = ln.getHeadEnd().getLen();
|
STLineEndLength.Enum len = ln.getHeadEnd().getLen();
|
||||||
return len == null ? null : LineEndLength.values()[len.intValue() - 1];
|
return len == null ? LineEndLength.MEDIUM : LineEndLength.values()[len.intValue() - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies the line end decoration, such as a triangle or arrowhead.
|
* Specifies the line end decoration, such as a triangle or arrowhead.
|
||||||
*/
|
*/
|
||||||
public void setLineTailDecoration(LineDecoration style){
|
public void setLineTailDecoration(LineDecoration style) {
|
||||||
CTLineProperties ln = getSpPr().getLn();
|
CTLineProperties ln = getSpPr().getLn();
|
||||||
CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
|
CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
|
||||||
if(style == null){
|
if (style == null) {
|
||||||
if(lnEnd.isSetType()) lnEnd.unsetType();
|
if (lnEnd.isSetType()) lnEnd.unsetType();
|
||||||
} else {
|
} else {
|
||||||
lnEnd.setType(STLineEndType.Enum.forInt(style.ordinal() + 1));
|
lnEnd.setType(STLineEndType.Enum.forInt(style.ordinal() + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public LineDecoration getLineTailDecoration(){
|
public LineDecoration getLineTailDecoration() {
|
||||||
CTLineProperties ln = getSpPr().getLn();
|
CTLineProperties ln = getSpPr().getLn();
|
||||||
if(!ln.isSetTailEnd()) return LineDecoration.NONE;
|
if (ln == null || !ln.isSetTailEnd()) return LineDecoration.NONE;
|
||||||
|
|
||||||
STLineEndType.Enum end = ln.getTailEnd().getType();
|
STLineEndType.Enum end = ln.getTailEnd().getType();
|
||||||
return end == null ? LineDecoration.NONE : LineDecoration.values()[end.intValue() - 1];
|
return end == null ? LineDecoration.NONE : LineDecoration.values()[end.intValue() - 1];
|
||||||
@ -156,76 +154,193 @@ public class XSLFConnectorShape extends XSLFSimpleShape {
|
|||||||
/**
|
/**
|
||||||
* specifies decorations which can be added to the tail of a line.
|
* specifies decorations which can be added to the tail of a line.
|
||||||
*/
|
*/
|
||||||
public void setLineTailWidth(LineEndWidth style){
|
public void setLineTailWidth(LineEndWidth style) {
|
||||||
CTLineProperties ln = getSpPr().getLn();
|
CTLineProperties ln = getSpPr().getLn();
|
||||||
CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
|
CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
|
||||||
if(style == null){
|
if (style == null) {
|
||||||
if(lnEnd.isSetW()) lnEnd.unsetW();
|
if (lnEnd.isSetW()) lnEnd.unsetW();
|
||||||
} else {
|
} else {
|
||||||
lnEnd.setW(STLineEndWidth.Enum.forInt(style.ordinal() + 1));
|
lnEnd.setW(STLineEndWidth.Enum.forInt(style.ordinal() + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public LineEndWidth getLineTailWidth(){
|
public LineEndWidth getLineTailWidth() {
|
||||||
CTLineProperties ln = getSpPr().getLn();
|
CTLineProperties ln = getSpPr().getLn();
|
||||||
if(!ln.isSetTailEnd()) return null;
|
if (ln == null || !ln.isSetTailEnd()) return LineEndWidth.MEDIUM;
|
||||||
|
|
||||||
STLineEndWidth.Enum w = ln.getTailEnd().getW();
|
STLineEndWidth.Enum w = ln.getTailEnd().getW();
|
||||||
return w == null ? null : LineEndWidth.values()[w.intValue() - 1];
|
return w == null ? LineEndWidth.MEDIUM : LineEndWidth.values()[w.intValue() - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies the line end width in relation to the line width.
|
* Specifies the line end width in relation to the line width.
|
||||||
*/
|
*/
|
||||||
public void setLineTailLength(LineEndLength style){
|
public void setLineTailLength(LineEndLength style) {
|
||||||
CTLineProperties ln = getSpPr().getLn();
|
CTLineProperties ln = getSpPr().getLn();
|
||||||
CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
|
CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
|
||||||
|
|
||||||
if(style == null){
|
if (style == null) {
|
||||||
if(lnEnd.isSetLen()) lnEnd.unsetLen();
|
if (lnEnd.isSetLen()) lnEnd.unsetLen();
|
||||||
} else {
|
} else {
|
||||||
lnEnd.setLen(STLineEndLength.Enum.forInt(style.ordinal() + 1));
|
lnEnd.setLen(STLineEndLength.Enum.forInt(style.ordinal() + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public LineEndLength getLineTailLength(){
|
public LineEndLength getLineTailLength() {
|
||||||
CTLineProperties ln = getSpPr().getLn();
|
CTLineProperties ln = getSpPr().getLn();
|
||||||
if(!ln.isSetTailEnd()) return null;
|
if (ln == null || !ln.isSetTailEnd()) return LineEndLength.MEDIUM;
|
||||||
|
|
||||||
STLineEndLength.Enum len = ln.getTailEnd().getLen();
|
STLineEndLength.Enum len = ln.getTailEnd().getLen();
|
||||||
return len == null ? null : LineEndLength.values()[len.intValue() - 1];
|
return len == null ? LineEndLength.MEDIUM : LineEndLength.values()[len.intValue() - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Graphics2D graphics){
|
public void draw(Graphics2D graphics) {
|
||||||
java.awt.Shape outline = getOutline();
|
java.awt.Shape outline = getOutline();
|
||||||
|
|
||||||
// shadow
|
// shadow
|
||||||
XSLFShadow shadow = getShadow();
|
XSLFShadow shadow = getShadow();
|
||||||
if(shadow != null) shadow.draw(graphics);
|
|
||||||
|
|
||||||
//border
|
//border
|
||||||
Color lineColor = getLineColor();
|
Color lineColor = getLineColor();
|
||||||
if (lineColor != null){
|
if (lineColor != null) {
|
||||||
|
if (shadow != null) shadow.draw(graphics);
|
||||||
|
|
||||||
graphics.setColor(lineColor);
|
graphics.setColor(lineColor);
|
||||||
applyStroke(graphics);
|
applyStroke(graphics);
|
||||||
graphics.draw(outline);
|
graphics.draw(outline);
|
||||||
|
|
||||||
|
Shape tailDecoration = getTailDecoration();
|
||||||
|
if (tailDecoration != null) {
|
||||||
|
graphics.draw(tailDecoration);
|
||||||
|
}
|
||||||
|
|
||||||
|
Shape headDecoration = getHeadDecoration();
|
||||||
|
if (headDecoration != null) {
|
||||||
|
graphics.draw(headDecoration);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected java.awt.Shape getOutline(){
|
protected java.awt.Shape getOutline() {
|
||||||
Rectangle2D anchor = getAnchor();
|
Rectangle2D anchor = getAnchor();
|
||||||
double x1 = anchor.getX(),
|
double x1 = anchor.getX(),
|
||||||
y1 = anchor.getY(),
|
y1 = anchor.getY(),
|
||||||
x2 = anchor.getX() + anchor.getWidth(),
|
x2 = anchor.getX() + anchor.getWidth(),
|
||||||
y2 = anchor.getY() + anchor.getHeight();
|
y2 = anchor.getY() + anchor.getHeight();
|
||||||
|
|
||||||
GeneralPath line = new GeneralPath();
|
|
||||||
line.moveTo((float)x1, (float)y1);
|
|
||||||
line.lineTo((float)x2, (float)y2);
|
|
||||||
|
|
||||||
return line;
|
return new Line2D.Double(x1, y1, x2, y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
Shape getTailDecoration() {
|
||||||
|
LineEndLength tailLength = getLineTailLength();
|
||||||
|
LineEndWidth tailWidth = getLineTailWidth();
|
||||||
|
|
||||||
|
double lineWidth = getLineWidth();
|
||||||
|
Rectangle2D anchor = getAnchor();
|
||||||
|
double x2 = anchor.getX() + anchor.getWidth(),
|
||||||
|
y2 = anchor.getY() + anchor.getHeight();
|
||||||
|
|
||||||
|
double alpha = Math.atan(anchor.getHeight() / anchor.getWidth());
|
||||||
|
|
||||||
|
AffineTransform at = new AffineTransform();
|
||||||
|
Shape shape = null;
|
||||||
|
Rectangle2D bounds;
|
||||||
|
double scaleY = Math.pow(2, tailWidth.ordinal());
|
||||||
|
double scaleX = Math.pow(2, tailLength.ordinal());
|
||||||
|
switch (getLineHeadDecoration()) {
|
||||||
|
case OVAL:
|
||||||
|
shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);
|
||||||
|
bounds = shape.getBounds2D();
|
||||||
|
at.translate(x2 - bounds.getWidth() / 2, y2 - bounds.getHeight() / 2);
|
||||||
|
at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2);
|
||||||
|
break;
|
||||||
|
case ARROW:
|
||||||
|
GeneralPath arrow = new GeneralPath();
|
||||||
|
arrow.moveTo(-lineWidth * 3, -lineWidth * 2);
|
||||||
|
arrow.lineTo(0, 0);
|
||||||
|
arrow.lineTo(-lineWidth * 3, lineWidth * 2);
|
||||||
|
shape = arrow;
|
||||||
|
at.translate(x2, y2);
|
||||||
|
at.rotate(alpha);
|
||||||
|
break;
|
||||||
|
case TRIANGLE:
|
||||||
|
scaleY = tailWidth.ordinal() + 1;
|
||||||
|
scaleX = tailLength.ordinal() + 1;
|
||||||
|
GeneralPath triangle = new GeneralPath();
|
||||||
|
triangle.moveTo(-lineWidth * scaleX, -lineWidth * scaleY/2);
|
||||||
|
triangle.lineTo(0, 0);
|
||||||
|
triangle.lineTo(-lineWidth * scaleX, lineWidth * scaleY/2);
|
||||||
|
triangle.closePath();
|
||||||
|
shape = triangle;
|
||||||
|
at.translate(x2, y2);
|
||||||
|
at.rotate(alpha);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shape != null) {
|
||||||
|
shape = at.createTransformedShape(shape);
|
||||||
|
}
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shape getHeadDecoration() {
|
||||||
|
LineEndLength headLength = getLineHeadLength();
|
||||||
|
LineEndWidth headWidth = getLineHeadWidth();
|
||||||
|
|
||||||
|
double lineWidth = getLineWidth();
|
||||||
|
Rectangle2D anchor = getAnchor();
|
||||||
|
double x1 = anchor.getX(),
|
||||||
|
y1 = anchor.getY();
|
||||||
|
|
||||||
|
double alpha = Math.atan(anchor.getHeight() / anchor.getWidth());
|
||||||
|
|
||||||
|
AffineTransform at = new AffineTransform();
|
||||||
|
Shape shape = null;
|
||||||
|
Rectangle2D bounds;
|
||||||
|
double scaleY = 1;
|
||||||
|
double scaleX = 1;
|
||||||
|
switch (getLineHeadDecoration()) {
|
||||||
|
case OVAL:
|
||||||
|
scaleY = Math.pow(2, headWidth.ordinal());
|
||||||
|
scaleX = Math.pow(2, headLength.ordinal());
|
||||||
|
shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);
|
||||||
|
break;
|
||||||
|
case STEALTH:
|
||||||
|
case ARROW:
|
||||||
|
GeneralPath arrow = new GeneralPath();
|
||||||
|
arrow.moveTo(lineWidth * 3 * scaleX, -lineWidth * scaleY * 2);
|
||||||
|
arrow.lineTo(0, 0);
|
||||||
|
arrow.lineTo(lineWidth * 3 * scaleX, lineWidth * scaleY * 2);
|
||||||
|
shape = arrow;
|
||||||
|
at.translate(x1, y1);
|
||||||
|
at.rotate(alpha);
|
||||||
|
break;
|
||||||
|
case TRIANGLE:
|
||||||
|
scaleY = headWidth.ordinal() + 1;
|
||||||
|
scaleX = headLength.ordinal() + 1;
|
||||||
|
GeneralPath triangle = new GeneralPath();
|
||||||
|
triangle.moveTo(lineWidth * scaleX, -lineWidth * scaleY/2);
|
||||||
|
triangle.lineTo(0, 0);
|
||||||
|
triangle.lineTo(lineWidth * scaleX, lineWidth * scaleY/2);
|
||||||
|
triangle.closePath();
|
||||||
|
shape = triangle;
|
||||||
|
at.translate(x1, y1);
|
||||||
|
at.rotate(alpha);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shape != null) {
|
||||||
|
shape = at.createTransformedShape(shape);
|
||||||
|
}
|
||||||
|
return shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.util.Beta;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For now this class renders only images supported by the javax.imageio.ImageIO
|
||||||
|
* framework. Subclasses can override this class to support other formats, for
|
||||||
|
* example, Use Apache batik to render WMF:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* <code>
|
||||||
|
* @Override
|
||||||
|
* public class MyImageRendener extends XSLFImageRendener{
|
||||||
|
* public boolean drawImage(Graphics2D graphics, XSLFPictureData data, Rectangle2D anchor){
|
||||||
|
* boolean ok = super.drawImage(graphics, data, anchor);
|
||||||
|
* if(!ok){
|
||||||
|
* // see what type of image we are
|
||||||
|
* String contentType = data.getPackagePart().getContentType();
|
||||||
|
* if(contentType.equals("image/wmf")){
|
||||||
|
* // use Apache Batik to handle WMF
|
||||||
|
* // see http://xmlgraphics.apache.org/batik/
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* }
|
||||||
|
* return ok;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* </code>
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* and then pass this class to your instance of java.awt.Graphics2D:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* <code>
|
||||||
|
* graphics.setRenderingHint(XSLFRenderingHint.IMAGE_RENDERER, new MyImageRendener());
|
||||||
|
* </code>
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
public class XSLFImageRendener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render picture data into the supplied graphics
|
||||||
|
*
|
||||||
|
* @return true if the picture data was succesfully renderered
|
||||||
|
*/
|
||||||
|
public boolean drawImage(Graphics2D graphics, XSLFPictureData data,
|
||||||
|
Rectangle2D anchor) {
|
||||||
|
try {
|
||||||
|
BufferedImage img = ImageIO.read(new ByteArrayInputStream(data
|
||||||
|
.getData()));
|
||||||
|
graphics.drawImage(img, (int) anchor.getX(), (int) anchor.getY(),
|
||||||
|
(int) anchor.getWidth(), (int) anchor.getHeight(), null);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -117,30 +117,26 @@ public class XSLFPictureShape extends XSLFSimpleShape {
|
|||||||
public void draw(Graphics2D graphics){
|
public void draw(Graphics2D graphics){
|
||||||
java.awt.Shape outline = getOutline();
|
java.awt.Shape outline = getOutline();
|
||||||
|
|
||||||
|
// shadow
|
||||||
|
XSLFShadow shadow = getShadow();
|
||||||
|
|
||||||
//fill
|
//fill
|
||||||
Color fillColor = getFillColor();
|
Color fillColor = getFillColor();
|
||||||
if (fillColor != null) {
|
if (fillColor != null) {
|
||||||
graphics.setColor(fillColor);
|
if(shadow != null) shadow.draw(graphics);
|
||||||
|
|
||||||
|
graphics.setColor(fillColor);
|
||||||
applyFill(graphics);
|
applyFill(graphics);
|
||||||
graphics.fill(outline);
|
graphics.fill(outline);
|
||||||
}
|
}
|
||||||
|
|
||||||
// text
|
XSLFPictureData data = getPictureData();
|
||||||
|
|
||||||
XSLFPictureData data = getPictureData();
|
|
||||||
if(data == null) return;
|
if(data == null) return;
|
||||||
|
|
||||||
BufferedImage img;
|
XSLFImageRendener renderer = (XSLFImageRendener)graphics.getRenderingHint(XSLFRenderingHint.IMAGE_RENDERER);
|
||||||
try {
|
if(renderer == null) renderer = new XSLFImageRendener();
|
||||||
img = ImageIO.read(new ByteArrayInputStream(data.getData()));
|
|
||||||
}
|
renderer.drawImage(graphics, data, getAnchor());
|
||||||
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
|
//border overlays the image
|
||||||
Color lineColor = getLineColor();
|
Color lineColor = getLineColor();
|
||||||
|
@ -38,5 +38,5 @@ public class XSLFRenderingHint extends RenderingHints.Key {
|
|||||||
|
|
||||||
public static final XSLFRenderingHint GSAVE = new XSLFRenderingHint(1);
|
public static final XSLFRenderingHint GSAVE = new XSLFRenderingHint(1);
|
||||||
public static final XSLFRenderingHint GRESTORE = new XSLFRenderingHint(2);
|
public static final XSLFRenderingHint GRESTORE = new XSLFRenderingHint(2);
|
||||||
public static final XSLFRenderingHint SKIP_PLACEHOLDERS = new XSLFRenderingHint(3);
|
public static final XSLFRenderingHint IMAGE_RENDERER = new XSLFRenderingHint(3);
|
||||||
}
|
}
|
@ -45,9 +45,13 @@ public class XSLFShadow extends XSLFSimpleShape {
|
|||||||
_parent = parentShape;
|
_parent = parentShape;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void draw(Graphics2D graphics) {
|
public void draw(Graphics2D graphics) {
|
||||||
Shape outline = _parent.getOutline();
|
Shape outline = _parent.getOutline();
|
||||||
|
|
||||||
|
Color parentFillColor = _parent.getFillColor();
|
||||||
|
Color parentLineColor = _parent.getLineColor();
|
||||||
|
|
||||||
double angle = getAngle();
|
double angle = getAngle();
|
||||||
double dist = getDistance();
|
double dist = getDistance();
|
||||||
double dx = dist * Math.cos( Math.toRadians(angle));
|
double dx = dist * Math.cos( Math.toRadians(angle));
|
||||||
@ -55,13 +59,19 @@ public class XSLFShadow extends XSLFSimpleShape {
|
|||||||
|
|
||||||
graphics.translate(dx, dy);
|
graphics.translate(dx, dy);
|
||||||
|
|
||||||
//fill
|
|
||||||
Color fillColor = getFillColor();
|
Color fillColor = getFillColor();
|
||||||
if (fillColor != null) {
|
if (fillColor != null) {
|
||||||
graphics.setColor(fillColor);
|
graphics.setColor(fillColor);
|
||||||
graphics.fill(outline);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(parentFillColor != null) {
|
||||||
|
graphics.fill(outline);
|
||||||
|
}
|
||||||
|
if(parentLineColor != null) {
|
||||||
|
_parent.applyStroke(graphics);
|
||||||
|
graphics.draw(outline);
|
||||||
|
}
|
||||||
|
|
||||||
graphics.translate(-dx, -dy);
|
graphics.translate(-dx, -dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,21 +85,37 @@ public class XSLFShadow extends XSLFSimpleShape {
|
|||||||
throw new IllegalStateException("You can't set anchor of a shadow");
|
throw new IllegalStateException("You can't set anchor of a shadow");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the offset of this shadow in points
|
||||||
|
*/
|
||||||
public double getDistance(){
|
public double getDistance(){
|
||||||
CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject();
|
CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject();
|
||||||
return ct.isSetDist() ? Units.toPoints(ct.getDist()) : 0;
|
return ct.isSetDist() ? Units.toPoints(ct.getDist()) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return the direction to offset the shadow in angles
|
||||||
|
*/
|
||||||
public double getAngle(){
|
public double getAngle(){
|
||||||
CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject();
|
CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject();
|
||||||
return ct.isSetDir() ? (double)ct.getDir() / 60000 : 0;
|
return ct.isSetDir() ? (double)ct.getDir() / 60000 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return the blur radius of the shadow
|
||||||
|
* TODO: figure out how to make sense of this property when rendering shadows
|
||||||
|
*/
|
||||||
public double getBlur(){
|
public double getBlur(){
|
||||||
CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject();
|
CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject();
|
||||||
return ct.isSetBlurRad() ? Units.toPoints(ct.getBlurRad()) : 0;
|
return ct.isSetBlurRad() ? Units.toPoints(ct.getBlurRad()) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the color of this shadow.
|
||||||
|
* Depending whether the parent shape is filled or stroked, this color is used to fill or stroke this shadow
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Color getFillColor() {
|
public Color getFillColor() {
|
||||||
XSLFTheme theme = getSheet().getTheme();
|
XSLFTheme theme = getSheet().getTheme();
|
||||||
@ -100,7 +126,10 @@ public class XSLFShadow extends XSLFSimpleShape {
|
|||||||
else if (ct.isSetPrstClr()) {
|
else if (ct.isSetPrstClr()) {
|
||||||
return theme.getPresetColor(ct.getPrstClr());
|
return theme.getPresetColor(ct.getPrstClr());
|
||||||
}
|
}
|
||||||
|
else if (ct.isSetSrgbClr()) {
|
||||||
|
return theme.getSrgbColor(ct.getSrgbClr());
|
||||||
|
}
|
||||||
|
|
||||||
return Color.black;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -279,14 +279,14 @@ public abstract class XSLFSimpleShape extends XSLFShape {
|
|||||||
|
|
||||||
public Color getLineColor() {
|
public Color getLineColor() {
|
||||||
final XSLFTheme theme = _sheet.getTheme();
|
final XSLFTheme theme = _sheet.getTheme();
|
||||||
|
final Color noline = new Color(0,0,0,0);
|
||||||
PropertyFetcher<Color> fetcher = new PropertyFetcher<Color>(){
|
PropertyFetcher<Color> fetcher = new PropertyFetcher<Color>(){
|
||||||
public boolean fetch(XSLFSimpleShape shape){
|
public boolean fetch(XSLFSimpleShape shape){
|
||||||
CTShapeProperties spPr = shape.getSpPr();
|
CTShapeProperties spPr = shape.getSpPr();
|
||||||
CTLineProperties ln = spPr.getLn();
|
CTLineProperties ln = spPr.getLn();
|
||||||
if (ln != null) {
|
if (ln != null) {
|
||||||
if (ln.isSetNoFill()) {
|
if (ln.isSetNoFill()) {
|
||||||
setValue(null);
|
setValue(noline);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
CTSolidColorFillProperties solidLine = ln.getSolidFill();
|
CTSolidColorFillProperties solidLine = ln.getSolidFill();
|
||||||
@ -311,7 +311,7 @@ public abstract class XSLFSimpleShape extends XSLFShape {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return color;
|
return color == noline ? null : color;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLineWidth(double width) {
|
public void setLineWidth(double width) {
|
||||||
@ -480,12 +480,12 @@ public abstract class XSLFSimpleShape extends XSLFShape {
|
|||||||
*/
|
*/
|
||||||
public Color getFillColor() {
|
public Color getFillColor() {
|
||||||
final XSLFTheme theme = _sheet.getTheme();
|
final XSLFTheme theme = _sheet.getTheme();
|
||||||
|
final Color nofill = new Color(0,0,0,0);
|
||||||
PropertyFetcher<Color> fetcher = new PropertyFetcher<Color>(){
|
PropertyFetcher<Color> fetcher = new PropertyFetcher<Color>(){
|
||||||
public boolean fetch(XSLFSimpleShape shape){
|
public boolean fetch(XSLFSimpleShape shape){
|
||||||
CTShapeProperties spPr = shape.getSpPr();
|
CTShapeProperties spPr = shape.getSpPr();
|
||||||
if (spPr.isSetNoFill()) {
|
if (spPr.isSetNoFill()) {
|
||||||
setValue(null);
|
setValue(nofill); // use it as 'nofill' value
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (spPr.isSetSolidFill()) {
|
if (spPr.isSetSolidFill()) {
|
||||||
@ -508,7 +508,7 @@ public abstract class XSLFSimpleShape extends XSLFShape {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return color;
|
return color == nofill ? null : color;
|
||||||
}
|
}
|
||||||
|
|
||||||
public XSLFShadow getShadow(){
|
public XSLFShadow getShadow(){
|
||||||
@ -608,7 +608,7 @@ public abstract class XSLFSimpleShape extends XSLFShape {
|
|||||||
|
|
||||||
int meter = BasicStroke.JOIN_ROUND;
|
int meter = BasicStroke.JOIN_ROUND;
|
||||||
|
|
||||||
Stroke stroke = new BasicStroke(lineWidth, cap, meter, 0.0f, dash,
|
Stroke stroke = new BasicStroke(lineWidth, cap, meter, Math.max(1, lineWidth), dash,
|
||||||
dash_phase);
|
dash_phase);
|
||||||
graphics.setStroke(stroke);
|
graphics.setStroke(stroke);
|
||||||
}
|
}
|
||||||
|
@ -387,18 +387,19 @@ public abstract class XSLFTextShape extends XSLFSimpleShape {
|
|||||||
|
|
||||||
// shadow
|
// shadow
|
||||||
XSLFShadow shadow = getShadow();
|
XSLFShadow shadow = getShadow();
|
||||||
if(shadow != null) shadow.draw(graphics);
|
|
||||||
|
|
||||||
//fill
|
|
||||||
Color fillColor = getFillColor();
|
Color fillColor = getFillColor();
|
||||||
|
Color lineColor = getLineColor();
|
||||||
|
if(shadow != null) {
|
||||||
|
shadow.draw(graphics);
|
||||||
|
}
|
||||||
|
|
||||||
if (fillColor != null) {
|
if (fillColor != null) {
|
||||||
graphics.setColor(fillColor);
|
graphics.setColor(fillColor);
|
||||||
applyFill(graphics);
|
applyFill(graphics);
|
||||||
graphics.fill(outline);
|
graphics.fill(outline);
|
||||||
}
|
}
|
||||||
|
|
||||||
//border
|
|
||||||
Color lineColor = getLineColor();
|
|
||||||
if (lineColor != null){
|
if (lineColor != null){
|
||||||
graphics.setColor(lineColor);
|
graphics.setColor(lineColor);
|
||||||
applyStroke(graphics);
|
applyStroke(graphics);
|
||||||
|
@ -69,12 +69,12 @@ public class TestXSLFConnectorShape extends TestCase {
|
|||||||
assertEquals(STLineEndType.ARROW, shape.getSpPr().getLn().getTailEnd().getType());
|
assertEquals(STLineEndType.ARROW, shape.getSpPr().getLn().getTailEnd().getType());
|
||||||
|
|
||||||
// line end width
|
// line end width
|
||||||
assertEquals(null, shape.getLineHeadWidth());
|
assertEquals(LineEndWidth.MEDIUM, shape.getLineHeadWidth());
|
||||||
assertEquals(null, shape.getLineTailWidth());
|
assertEquals(LineEndWidth.MEDIUM, shape.getLineTailWidth());
|
||||||
shape.setLineHeadWidth(null);
|
shape.setLineHeadWidth(null);
|
||||||
shape.setLineHeadWidth(null);
|
shape.setLineHeadWidth(null);
|
||||||
assertEquals(null, shape.getLineHeadWidth());
|
assertEquals(LineEndWidth.MEDIUM, shape.getLineHeadWidth());
|
||||||
assertEquals(null, shape.getLineTailWidth());
|
assertEquals(LineEndWidth.MEDIUM, shape.getLineTailWidth());
|
||||||
assertFalse(shape.getSpPr().getLn().getHeadEnd().isSetW());
|
assertFalse(shape.getSpPr().getLn().getHeadEnd().isSetW());
|
||||||
assertFalse(shape.getSpPr().getLn().getTailEnd().isSetW());
|
assertFalse(shape.getSpPr().getLn().getTailEnd().isSetW());
|
||||||
shape.setLineHeadWidth(LineEndWidth.LARGE);
|
shape.setLineHeadWidth(LineEndWidth.LARGE);
|
||||||
@ -91,12 +91,12 @@ public class TestXSLFConnectorShape extends TestCase {
|
|||||||
assertEquals(STLineEndWidth.LG, shape.getSpPr().getLn().getTailEnd().getW());
|
assertEquals(STLineEndWidth.LG, shape.getSpPr().getLn().getTailEnd().getW());
|
||||||
|
|
||||||
// line end length
|
// line end length
|
||||||
assertEquals(null, shape.getLineHeadLength());
|
assertEquals(LineEndLength.MEDIUM, shape.getLineHeadLength());
|
||||||
assertEquals(null, shape.getLineTailLength());
|
assertEquals(LineEndLength.MEDIUM, shape.getLineTailLength());
|
||||||
shape.setLineHeadLength(null);
|
shape.setLineHeadLength(null);
|
||||||
shape.setLineTailLength(null);
|
shape.setLineTailLength(null);
|
||||||
assertEquals(null, shape.getLineHeadLength());
|
assertEquals(LineEndLength.MEDIUM, shape.getLineHeadLength());
|
||||||
assertEquals(null, shape.getLineTailLength());
|
assertEquals(LineEndLength.MEDIUM, shape.getLineTailLength());
|
||||||
assertFalse(shape.getSpPr().getLn().getHeadEnd().isSetLen());
|
assertFalse(shape.getSpPr().getLn().getHeadEnd().isSetLen());
|
||||||
assertFalse(shape.getSpPr().getLn().getTailEnd().isSetLen());
|
assertFalse(shape.getSpPr().getLn().getTailEnd().isSetLen());
|
||||||
shape.setLineHeadLength(LineEndLength.LARGE);
|
shape.setLineHeadLength(LineEndLength.LARGE);
|
||||||
|
Loading…
Reference in New Issue
Block a user