more improvements in slide rendering
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@650129 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7d67735404
commit
f5d6d1d2db
@ -83,6 +83,11 @@ public class PPT2PNG {
|
|||||||
|
|
||||||
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||||
Graphics2D graphics = img.createGraphics();
|
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.setPaint(Color.white);
|
||||||
graphics.fill(new Rectangle2D.Float(0, 0, width, height));
|
graphics.fill(new Rectangle2D.Float(0, 0, width, height));
|
||||||
|
|
||||||
|
@ -108,9 +108,9 @@ public class AutoShape extends TextShape {
|
|||||||
|
|
||||||
public java.awt.Shape getOutline(){
|
public java.awt.Shape getOutline(){
|
||||||
ShapeOutline outline = AutoShapes.getShapeOutline(getShapeType());
|
ShapeOutline outline = AutoShapes.getShapeOutline(getShapeType());
|
||||||
Rectangle2D anchor = getAnchor2D();
|
Rectangle2D anchor = getLogicalAnchor2D();
|
||||||
if(outline == null){
|
if(outline == null){
|
||||||
logger.log(POILogger.WARN, "getOutline() is not implemented for " + ShapeTypes.typeName(getShapeType()));
|
logger.log(POILogger.WARN, "Outline not found for " + ShapeTypes.typeName(getShapeType()));
|
||||||
return anchor;
|
return anchor;
|
||||||
} else {
|
} else {
|
||||||
java.awt.Shape shape = outline.getOutline(this);
|
java.awt.Shape shape = outline.getOutline(this);
|
||||||
|
@ -288,6 +288,86 @@ public class AutoShapes {
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
shapes[ShapeTypes.Can] = new ShapeOutline(){
|
||||||
|
public java.awt.Shape getOutline(Shape shape){
|
||||||
|
//m10800,qx0@1l0@2qy10800,21600,21600@2l21600@1qy10800,xem0@1qy10800@0,21600@1nfe
|
||||||
|
int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 5400);
|
||||||
|
|
||||||
|
GeneralPath path = new GeneralPath();
|
||||||
|
|
||||||
|
path.append(new Arc2D.Float(0, 0, 21600, adjval, 0, 180, Arc2D.OPEN), false);
|
||||||
|
path.moveTo(0, adjval/2);
|
||||||
|
|
||||||
|
path.lineTo(0, 21600 - adjval/2);
|
||||||
|
path.closePath();
|
||||||
|
|
||||||
|
path.append(new Arc2D.Float(0, 21600 - adjval, 21600, adjval, 180, 180, Arc2D.OPEN), false);
|
||||||
|
path.moveTo(21600, 21600 - adjval/2);
|
||||||
|
|
||||||
|
path.lineTo(21600, adjval/2);
|
||||||
|
path.append(new Arc2D.Float(0, 0, 21600, adjval, 180, 180, Arc2D.OPEN), false);
|
||||||
|
path.moveTo(0, adjval/2);
|
||||||
|
path.closePath();
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
shapes[ShapeTypes.LeftBrace] = new ShapeOutline(){
|
||||||
|
public java.awt.Shape getOutline(Shape shape){
|
||||||
|
//m21600,qx10800@0l10800@2qy0@11,10800@3l10800@1qy21600,21600e
|
||||||
|
int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 1800);
|
||||||
|
int adjval2 = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUST2VALUE, 10800);
|
||||||
|
|
||||||
|
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[ShapeTypes.RightBrace] = new ShapeOutline(){
|
||||||
|
public java.awt.Shape getOutline(Shape shape){
|
||||||
|
//m,qx10800@0 l10800@2qy21600@11,10800@3l10800@1qy,21600e
|
||||||
|
int adjval = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUSTVALUE, 1800);
|
||||||
|
int adjval2 = shape.getEscherProperty(EscherProperties.GEOMETRY__ADJUST2VALUE, 10800);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ public class Line extends SimpleShape {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public java.awt.Shape getOutline(){
|
public java.awt.Shape getOutline(){
|
||||||
Rectangle2D anchor = getAnchor2D();
|
Rectangle2D anchor = getLogicalAnchor2D();
|
||||||
return new Line2D.Double(anchor.getX(), anchor.getY(), anchor.getX() + anchor.getWidth(), anchor.getY() + anchor.getHeight());
|
return new Line2D.Double(anchor.getX(), anchor.getY(), anchor.getX() + anchor.getWidth(), anchor.getY() + anchor.getHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,6 +198,10 @@ public abstract class Shape {
|
|||||||
return anchor;
|
return anchor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Rectangle2D getLogicalAnchor2D(){
|
||||||
|
return getAnchor2D();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the anchor (the bounding box rectangle) of this shape.
|
* Sets the anchor (the bounding box rectangle) of this shape.
|
||||||
* All coordinates should be expressed in points (72 dpi).
|
* All coordinates should be expressed in points (72 dpi).
|
||||||
@ -466,6 +470,6 @@ public abstract class Shape {
|
|||||||
* @return the shape outline
|
* @return the shape outline
|
||||||
*/
|
*/
|
||||||
public java.awt.Shape getOutline(){
|
public java.awt.Shape getOutline(){
|
||||||
return getAnchor2D();
|
return getLogicalAnchor2D();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -237,7 +237,7 @@ public class ShapeGroup extends Shape{
|
|||||||
EscherClientAnchorRecord clientAnchor = (EscherClientAnchorRecord)getEscherChild(spContainer, EscherClientAnchorRecord.RECORD_ID);
|
EscherClientAnchorRecord clientAnchor = (EscherClientAnchorRecord)getEscherChild(spContainer, EscherClientAnchorRecord.RECORD_ID);
|
||||||
Rectangle2D.Float anchor = new Rectangle2D.Float();
|
Rectangle2D.Float anchor = new Rectangle2D.Float();
|
||||||
if(clientAnchor == null){
|
if(clientAnchor == null){
|
||||||
logger.log(POILogger.WARN, "EscherClientAnchorRecord was not found for the shape group");
|
logger.log(POILogger.INFO, "EscherClientAnchorRecord was not found for shape group. Searching for EscherChildAnchorRecord.");
|
||||||
EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(spContainer, EscherChildAnchorRecord.RECORD_ID);
|
EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(spContainer, EscherChildAnchorRecord.RECORD_ID);
|
||||||
anchor = new Rectangle2D.Float(
|
anchor = new Rectangle2D.Float(
|
||||||
(float)rec.getDx1()*POINT_DPI/MASTER_DPI,
|
(float)rec.getDx1()*POINT_DPI/MASTER_DPI,
|
||||||
@ -282,7 +282,7 @@ public class ShapeGroup extends Shape{
|
|||||||
|
|
||||||
//transform coordinates
|
//transform coordinates
|
||||||
AffineTransform at = graphics.getTransform();
|
AffineTransform at = graphics.getTransform();
|
||||||
|
/*
|
||||||
if(!anchor.equals(coords)){
|
if(!anchor.equals(coords)){
|
||||||
graphics.scale(anchor.getWidth()/coords.getWidth(), anchor.getHeight()/coords.getHeight());
|
graphics.scale(anchor.getWidth()/coords.getWidth(), anchor.getHeight()/coords.getHeight());
|
||||||
|
|
||||||
@ -290,7 +290,7 @@ public class ShapeGroup extends Shape{
|
|||||||
anchor.getX()*coords.getWidth()/anchor.getWidth() - coords.getX(),
|
anchor.getX()*coords.getWidth()/anchor.getWidth() - coords.getX(),
|
||||||
anchor.getY()*coords.getHeight()/anchor.getHeight() - coords.getY());
|
anchor.getY()*coords.getHeight()/anchor.getHeight() - coords.getY());
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
Shape[] sh = getShapes();
|
Shape[] sh = getShapes();
|
||||||
for (int i = 0; i < sh.length; i++) {
|
for (int i = 0; i < sh.length; i++) {
|
||||||
sh[i].draw(graphics);
|
sh[i].draw(graphics);
|
||||||
|
@ -32,7 +32,7 @@ public class ShapePainter {
|
|||||||
protected static POILogger logger = POILogFactory.getLogger(ShapePainter.class);
|
protected static POILogger logger = POILogFactory.getLogger(ShapePainter.class);
|
||||||
|
|
||||||
public static void paint(SimpleShape shape, Graphics2D graphics){
|
public static void paint(SimpleShape shape, Graphics2D graphics){
|
||||||
Rectangle2D anchor = shape.getAnchor2D();
|
Rectangle2D anchor = shape.getLogicalAnchor2D();
|
||||||
java.awt.Shape outline = shape.getOutline();
|
java.awt.Shape outline = shape.getOutline();
|
||||||
|
|
||||||
//flip vertical
|
//flip vertical
|
||||||
|
@ -23,6 +23,7 @@ import org.apache.poi.hslf.record.ColorSchemeAtom;
|
|||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.geom.AffineTransform;
|
import java.awt.geom.AffineTransform;
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract simple (non-group) shape.
|
* An abstract simple (non-group) shape.
|
||||||
@ -232,6 +233,52 @@ public class SimpleShape extends Shape {
|
|||||||
return angle;
|
return angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Rectangle2D getLogicalAnchor2D(){
|
||||||
|
Rectangle2D anchor = getAnchor2D();
|
||||||
|
|
||||||
|
//if it is a groupped shape see if we need to transform the coordinates
|
||||||
|
if (_parent != null){
|
||||||
|
Shape top = _parent;
|
||||||
|
while(top.getParent() != null) top = top.getParent();
|
||||||
|
|
||||||
|
Rectangle2D clientAnchor = top.getAnchor2D();
|
||||||
|
Rectangle2D spgrAnchor = ((ShapeGroup)top).getCoordinates();
|
||||||
|
|
||||||
|
double scalex = (double)spgrAnchor.getWidth()/clientAnchor.getWidth();
|
||||||
|
double scaley = (double)spgrAnchor.getHeight()/clientAnchor.getHeight();
|
||||||
|
|
||||||
|
double x = clientAnchor.getX() + (anchor.getX() - spgrAnchor.getX())/scalex;
|
||||||
|
double y = clientAnchor.getY() + (anchor.getY() - spgrAnchor.getY())/scaley;
|
||||||
|
double width = anchor.getWidth()/scalex;
|
||||||
|
double height = anchor.getHeight()/scaley;
|
||||||
|
|
||||||
|
anchor = new Rectangle2D.Double(x, y, width, height);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int angle = getRotation();
|
||||||
|
if(angle != 0){
|
||||||
|
double centerX = anchor.getX() + anchor.getWidth()/2;
|
||||||
|
double centerY = anchor.getY() + anchor.getHeight()/2;
|
||||||
|
|
||||||
|
AffineTransform trans = new AffineTransform();
|
||||||
|
trans.translate(centerX, centerY);
|
||||||
|
trans.rotate(Math.toRadians(angle));
|
||||||
|
trans.translate(-centerX, -centerY);
|
||||||
|
|
||||||
|
Rectangle2D rect = trans.createTransformedShape(anchor).getBounds2D();
|
||||||
|
if((anchor.getWidth() < anchor.getHeight() && rect.getWidth() > rect.getHeight()) ||
|
||||||
|
(anchor.getWidth() > anchor.getHeight() && rect.getWidth() < rect.getHeight()) ){
|
||||||
|
trans = new AffineTransform();
|
||||||
|
trans.translate(centerX, centerY);
|
||||||
|
trans.rotate(Math.PI/2);
|
||||||
|
trans.translate(-centerX, -centerY);
|
||||||
|
anchor = trans.createTransformedShape(anchor).getBounds2D();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return anchor;
|
||||||
|
}
|
||||||
|
|
||||||
public void draw(Graphics2D graphics){
|
public void draw(Graphics2D graphics){
|
||||||
AffineTransform at = graphics.getTransform();
|
AffineTransform at = graphics.getTransform();
|
||||||
ShapePainter.paint(this, graphics);
|
ShapePainter.paint(this, graphics);
|
||||||
|
@ -54,7 +54,10 @@ public class TextPainter {
|
|||||||
for (int i = 0; i < rt.length; i++) {
|
for (int i = 0; i < rt.length; i++) {
|
||||||
int start = rt[i].getStartIndex();
|
int start = rt[i].getStartIndex();
|
||||||
int end = rt[i].getEndIndex();
|
int end = rt[i].getEndIndex();
|
||||||
if(start == end) continue;
|
if(start == end) {
|
||||||
|
logger.log(POILogger.INFO, "Skipping RichTextRun with zero length");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
at.addAttribute(TextAttribute.FAMILY, rt[i].getFontName(), start, end);
|
at.addAttribute(TextAttribute.FAMILY, rt[i].getFontName(), start, end);
|
||||||
at.addAttribute(TextAttribute.SIZE, new Float(rt[i].getFontSize()), start, end);
|
at.addAttribute(TextAttribute.SIZE, new Float(rt[i].getFontSize()), start, end);
|
||||||
@ -86,7 +89,7 @@ public class TextPainter {
|
|||||||
int paragraphStart = it.getBeginIndex();
|
int paragraphStart = it.getBeginIndex();
|
||||||
int paragraphEnd = it.getEndIndex();
|
int paragraphEnd = it.getEndIndex();
|
||||||
|
|
||||||
Rectangle2D anchor = _shape.getAnchor2D();
|
Rectangle2D anchor = _shape.getLogicalAnchor2D();
|
||||||
|
|
||||||
float textHeight = 0;
|
float textHeight = 0;
|
||||||
ArrayList lines = new ArrayList();
|
ArrayList lines = new ArrayList();
|
||||||
@ -115,7 +118,7 @@ public class TextPainter {
|
|||||||
TextLayout textLayout = measurer.nextLayout(wrappingWidth + 1,
|
TextLayout textLayout = measurer.nextLayout(wrappingWidth + 1,
|
||||||
nextBreak == -1 ? paragraphEnd : nextBreak, true);
|
nextBreak == -1 ? paragraphEnd : nextBreak, true);
|
||||||
if (textLayout == null) {
|
if (textLayout == null) {
|
||||||
textLayout = measurer.nextLayout(wrappingWidth,
|
textLayout = measurer.nextLayout((float)anchor.getWidth(),
|
||||||
nextBreak == -1 ? paragraphEnd : nextBreak, false);
|
nextBreak == -1 ? paragraphEnd : nextBreak, false);
|
||||||
}
|
}
|
||||||
if(textLayout == null){
|
if(textLayout == null){
|
||||||
@ -175,9 +178,12 @@ public class TextPainter {
|
|||||||
if(rt.isBullet() && (prStart || startIndex == 0)){
|
if(rt.isBullet() && (prStart || startIndex == 0)){
|
||||||
it.setIndex(startIndex);
|
it.setIndex(startIndex);
|
||||||
|
|
||||||
AttributedString bat = new AttributedString(Character.toString(rt.getBulletChar()), it.getAttributes());
|
AttributedString bat = new AttributedString(Character.toString(rt.getBulletChar()));
|
||||||
Color clr = rt.getBulletColor();
|
Color clr = rt.getBulletColor();
|
||||||
if (clr != null) bat.addAttribute(TextAttribute.FOREGROUND, clr);
|
if (clr != null) bat.addAttribute(TextAttribute.FOREGROUND, clr);
|
||||||
|
else bat.addAttribute(TextAttribute.FOREGROUND, it.getAttribute(TextAttribute.FOREGROUND));
|
||||||
|
bat.addAttribute(TextAttribute.FAMILY, it.getAttribute(TextAttribute.FAMILY));
|
||||||
|
bat.addAttribute(TextAttribute.SIZE, it.getAttribute(TextAttribute.SIZE));
|
||||||
|
|
||||||
TextLayout bulletLayout = new TextLayout(bat.getIterator(), graphics.getFontRenderContext());
|
TextLayout bulletLayout = new TextLayout(bat.getIterator(), graphics.getFontRenderContext());
|
||||||
if(text.substring(startIndex, endIndex).length() > 1){
|
if(text.substring(startIndex, endIndex).length() > 1){
|
||||||
|
Loading…
Reference in New Issue
Block a user