#64876 - Unable to convert pptx to pdf

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1884578 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2020-12-17 23:42:26 +00:00
parent fcc808d17d
commit bfade7c591
9 changed files with 874 additions and 639 deletions

View File

@ -254,6 +254,6 @@ public class DrawShape implements Drawable {
int lineJoin = BasicStroke.JOIN_ROUND;
return new BasicStroke(lineWidth, lineCap, lineJoin, lineWidth, dashPatF, dash_phase);
return new BasicStroke(lineWidth, lineCap, lineJoin, 10, dashPatF, dash_phase);
}
}

View File

@ -28,6 +28,8 @@ import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
import com.microsoft.schemas.office.visio.x2012.main.ShapeSheetType;
import com.microsoft.schemas.office.visio.x2012.main.TextType;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.util.Internal;
import org.apache.poi.xdgf.exceptions.XDGFException;
@ -37,9 +39,6 @@ import org.apache.poi.xdgf.usermodel.section.XDGFSection;
import org.apache.poi.xdgf.usermodel.shape.ShapeVisitor;
import org.apache.poi.xdgf.usermodel.shape.exceptions.StopVisitingThisBranch;
import com.microsoft.schemas.office.visio.x2012.main.ShapeSheetType;
import com.microsoft.schemas.office.visio.x2012.main.TextType;
/**
* A shape is a collection of Geometry Visualization, Format, Text, Images, and
* Shape Data in a Drawing Page.
@ -723,7 +722,6 @@ public class XDGFShape extends XDGFSheet {
float lineWeight = getLineWeight().floatValue();
int cap;
int join = BasicStroke.JOIN_MITER;
float miterlimit = 10.0f;
switch (getLineCap()) {
case 0:
@ -826,7 +824,7 @@ public class XDGFShape extends XDGFSheet {
}
}
return new BasicStroke(lineWeight, cap, join, miterlimit, dash, 0);
return new BasicStroke(lineWeight, cap, join, 10, dash, 0);
}
//

View File

@ -0,0 +1,49 @@
package org.apache.poi.xslf.util;
import java.awt.Graphics2D;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
public class DummyFormat implements OutputFormat {
private final ByteArrayOutputStream bos;
private final DummyGraphics2d dummy2d;
public DummyFormat() {
try {
bos = new ByteArrayOutputStream();
dummy2d = new DummyGraphics2d(new PrintStream(bos, true, StandardCharsets.UTF_8.name()));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
@Override
public Graphics2D addSlide(double width, double height) throws IOException {
bos.reset();
return dummy2d;
}
@Override
public void writeSlide(MFProxy proxy, File outFile) throws IOException {
try (FileOutputStream fos = new FileOutputStream(outFile)) {
bos.writeTo(fos);
bos.reset();
}
}
@Override
public void writeDocument(MFProxy proxy, File outFile) throws IOException {
}
@Override
public void close() throws IOException {
bos.reset();
}
}

View File

@ -16,8 +16,9 @@
==================================================================== */
package org.apache.poi.hssf.usermodel;
package org.apache.poi.xslf.util;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
@ -35,7 +36,10 @@ import java.awt.Shape;
import java.awt.Stroke;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.TextAttribute;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ImageObserver;
@ -43,7 +47,11 @@ import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderableImage;
import java.io.PrintStream;
import java.text.AttributedCharacterIterator;
import java.text.AttributedCharacterIterator.Attribute;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import org.apache.poi.util.Internal;
@ -84,11 +92,42 @@ public class DummyGraphics2d extends Graphics2D {
g2D.clip( s );
}
private void pathToString(StringBuilder sb, Path2D p) {
sb.append("Path2D p = new Path2D.Double("+p.getWindingRule()+");\n");
double[] coords = new double[6];
for (PathIterator pi = p.getPathIterator(null); !pi.isDone(); pi.next()) {
// The type will be SEG_LINETO, SEG_MOVETO, or SEG_CLOSE
// Because the Area is composed of straight lines
switch (pi.currentSegment(coords)) {
case PathIterator.SEG_MOVETO:
sb.append("p.moveTo("+coords[0]+","+coords[1]+");\n");
break;
case PathIterator.SEG_LINETO:
sb.append("p.lineTo("+coords[0]+","+coords[1]+");\n");
break;
case PathIterator.SEG_QUADTO:
sb.append("p.quadTo("+coords[0]+","+coords[1]+","+coords[2]+","+coords[3]+");\n");
break;
case PathIterator.SEG_CUBICTO:
sb.append("p.curveTo("+coords[0]+","+coords[1]+","+coords[2]+","+coords[3]+","+coords[4]+","+coords[5]+");\n");
break;
case PathIterator.SEG_CLOSE:
sb.append("p.closePath();\n");
break;
}
}
}
public void draw(Shape s) {
String l =
"draw(Shape):" +
"\n s = " + s;
log.println( l );
if (s instanceof Path2D) {
StringBuilder sb = new StringBuilder();
pathToString(sb, (Path2D)s);
sb.append("g.draw(p);");
log.println( sb.toString() );
} else {
log.println( "g.draw("+ s + ")" );
}
g2D.draw( s );
}
@ -141,16 +180,6 @@ public class DummyGraphics2d extends Graphics2D {
g2D.drawRenderedImage( img, xform );
}
public void drawString(AttributedCharacterIterator iterator, float x, float y) {
String l =
"drawString(AttributedCharacterIterator):" +
"\n iterator = " + iterator +
"\n x = " + x +
"\n y = " + y;
log.println( l );
g2D.drawString( iterator, x, y );
}
public void drawString(String s, float x, float y) {
String l =
"drawString(s,x,y):" +
@ -162,10 +191,14 @@ public class DummyGraphics2d extends Graphics2D {
}
public void fill(Shape s) {
String l =
"fill(Shape):" +
"\n s = " + s;
log.println( l );
if (s instanceof Path2D) {
StringBuilder sb = new StringBuilder();
pathToString(sb, (Path2D)s);
sb.append("g.fill(p);");
log.println( sb.toString() );
} else {
log.println( "g.fill("+ s + ")" );
}
g2D.fill( s );
}
@ -195,10 +228,7 @@ public class DummyGraphics2d extends Graphics2D {
}
public Object getRenderingHint(RenderingHints.Key hintKey) {
String l =
"getRenderingHint(RenderingHints.Key):" +
"\n hintKey = " + hintKey;
log.println( l );
log.println( "getRenderingHint(\""+hintKey+"\")" );
return g2D.getRenderingHint( hintKey );
}
@ -246,47 +276,66 @@ public class DummyGraphics2d extends Graphics2D {
}
public void scale(double sx, double sy) {
String l =
"scale(double,double):" +
"\n sx = " + sx +
"\n sy";
log.println( l );
log.println( "g.scale("+sx+","+sy+");" );
g2D.scale( sx, sy );
}
public void setBackground(Color color) {
String l =
"setBackground(Color):" +
"\n color = " + color;
log.println( l );
log.println(String.format(Locale.ROOT, "setBackground(new Color(0x%08X))", color.getRGB()));
g2D.setBackground( color );
}
private static final String[] COMPOSITE_RULES = {
"CLEAR", "SRC", "SRC_OVER", "DST_OVER", "SRC_IN", "DST_IN", "SRC_OUT", "DST_OUT", "DST", "SRC_ATOP", "DST_ATOP", "XOR"
};
public void setComposite(Composite comp) {
String l =
"setComposite(Composite):" +
"\n comp = " + comp;
String l = "g.setComposite(";
if (comp instanceof AlphaComposite) {
AlphaComposite ac = (AlphaComposite)comp;
l += "AlphaComposite.getInstance(AlphaComposite."
+ COMPOSITE_RULES[Math.max(0,Math.min(COMPOSITE_RULES.length-1,ac.getRule()))]
+ ", " + ac.getAlpha() + "f));";
} else {
l += comp.toString() + ");";
}
log.println( l );
g2D.setComposite( comp );
}
public void setPaint( Paint paint ) {
String l =
"setPaint(Paint):" +
"\n paint = " + paint;
String l = "g.setPaint(";
if (paint instanceof Color) {
l += String.format(Locale.ROOT, "new Color(0x%08X));", ((Color)paint).getRGB());
} else {
l += paint.toString() + ");";
}
log.println( l );
g2D.setPaint( paint );
}
public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) {
String l =
"setRenderingHint(RenderingHints.Key, Object):" +
"\n hintKey = " + hintKey +
"\n hintValue = " + hintValue;
log.println( l );
log.println( "g.setRenderingHint("+mapHint(hintKey)+", " + mapHint(hintValue) + ");" );
g2D.setRenderingHint( hintKey, hintValue );
}
private static String mapHint(Object hint) {
if (hint == null) {
return "null";
}
if (hint instanceof AffineTransform) {
return mapTransform((AffineTransform) hint);
}
for (int i=0; i<HINTS.length; i+=2) {
if (hint == HINTS[i]) {
return (String)HINTS[i+1];
}
}
return "\"" + hint.toString() + "\"";
}
public void setRenderingHints(Map<?,?> hints) {
String l =
"setRenderingHints(Map):" +
@ -299,28 +348,24 @@ public class DummyGraphics2d extends Graphics2D {
String l;
if (s instanceof BasicStroke) {
BasicStroke bs = (BasicStroke)s;
l = "setStroke(Stoke):" +
"\n s = BasicStroke(" +
"\n dash[]: "+Arrays.toString(bs.getDashArray()) +
"\n dashPhase: "+bs.getDashPhase() +
"\n endCap: "+bs.getEndCap() +
"\n lineJoin: "+bs.getLineJoin() +
"\n width: "+bs.getLineWidth() +
"\n miterLimit: "+bs.getMiterLimit() +
"\n )";
String cap = new String[]{"BUTT","ROUND","SQUARE"}[bs.getEndCap()];
String join = new String[]{"MITER","ROUND","BEVEL"}[bs.getLineJoin()];
l = "g.setStroke(new BasicStroke(" + bs.getLineWidth() + "f, BasicStroke.CAP_" + cap + ", BasicStroke.JOIN_" + join + ", " +
bs.getMiterLimit() + "f, " + Arrays.toString(bs.getDashArray()) + ", " + bs.getDashPhase() + "f));";
} else {
l = "setStroke(Stoke):" +
"\n s = " + s;
l = "g.setStroke(" + s + ");";
}
log.println( l );
g2D.setStroke( s );
}
private static String mapTransform(AffineTransform tx) {
return tx.isIdentity() ? "new AffineTransform()"
: "new AffineTransform("+tx.getScaleX()+"f,"+tx.getShearY()+"f,"+tx.getShearX()+"f,"+tx.getScaleY()+"f,"+tx.getTranslateX()+"f,"+tx.getTranslateY()+"f)";
}
public void setTransform(AffineTransform Tx) {
String l =
"setTransform():" +
"\n Tx = " + Tx;
log.println( l );
log.println( "g.setTransform("+mapTransform(Tx)+");" );
g2D.setTransform( Tx );
}
@ -612,16 +657,75 @@ public class DummyGraphics2d extends Graphics2D {
g2D.drawRoundRect( x, y, width, height, arcWidth, arcHeight );
}
public void drawString(AttributedCharacterIterator iterator, int x, int y) {
String l =
"drawString(AttributedCharacterIterator,int,int):" +
"\n iterator = " + iterator +
"\n x = " + x +
"\n y = " + y;
log.println( l );
private static String mapAttribute(Object attr) {
if (attr == null) {
return "null";
}
if (attr instanceof Font) {
Font f = (Font)attr;
final String[] STYLE = { "Font.PLAIN", "Font.BOLD", "Font.ITALIC", "Font.BOLD | Font.ITALIC" };
return "new Font(\"" + f.getFamily(Locale.ROOT) + "\"," + STYLE[f.getStyle()] + "," + f.getSize() + ")";
}
if (attr instanceof Color) {
return String.format(Locale.ROOT, "new Color(0x%08X)", ((Color)attr).getRGB());
}
for (int i=0; i<ATTRS.length; i+=2) {
if (attr == ATTRS[i]) {
return (String)ATTRS[i+1];
}
}
return "\""+attr.toString()+"\"";
}
public void drawString(AttributedCharacterIterator iterator, float x, float y) {
final int startIdx = iterator.getIndex();
final Map<Attribute, Map<Integer,Object>> attMap = new HashMap<>();
StringBuilder sb = new StringBuilder();
for (char ch = iterator.current(); ch != AttributedCharacterIterator.DONE; ch = iterator.next()) {
sb.append(ch);
iterator.getAttributes().forEach((k,v) ->
attMap.computeIfAbsent(k, (k2) -> new LinkedHashMap<>()).put(iterator.getIndex(), v)
);
}
String l = "AttributedString as = new AttributedString(\""+sb+"\");\n";
sb.setLength(0);
sb.append(l);
for (Map.Entry<Attribute, Map<Integer,Object>> me : attMap.entrySet()) {
int startPos = -2, lastPos = -2;
Object lastObj = null;
for (Map.Entry<Integer,Object> mo : me.getValue().entrySet()) {
int pos = mo.getKey();
Object obj = mo.getValue();
if (lastPos < pos-1 || obj != lastObj) {
if (startPos >= 0) {
Attribute at = me.getKey();
sb.append("as.addAttribute("+mapAttribute(me.getKey())+","+mapAttribute(lastObj)+","+startPos+","+(lastPos+1)+");\n");
}
startPos = pos;
}
lastPos = pos;
lastObj = obj;
}
if (lastObj != null) {
sb.append("as.addAttribute("+mapAttribute(me.getKey())+","+mapAttribute(lastObj)+","+startPos+","+(lastPos+1)+");\n");
}
}
sb.append("g.drawString(as.getIterator(),"+x+"f,"+y+"f);");
log.println( sb.toString() );
iterator.setIndex(startIdx);
g2D.drawString( iterator, x, y );
}
public void drawString(AttributedCharacterIterator iterator, int x, int y) {
drawString(iterator, (float)x, (float)y);
}
public void drawString(String str, int x, int y) {
String l =
"drawString(str,int,int):" +
@ -687,24 +791,12 @@ public class DummyGraphics2d extends Graphics2D {
}
public void fillRect(int x, int y, int width, int height) {
String l =
"fillRect(int,int,int,int):" +
"\n x = " + x +
"\n y = " + y +
"\n width = " + width +
"\n height = " + height;
log.println( l );
log.println( "g.fillRect(" + x + "," + y + "," + width + "," + height + ");" );
g2D.fillRect( x, y, width, height );
}
public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
String l =
"fillRoundRect(int,int,int,int,int,int):" +
"\n x = " + x +
"\n y = " + y +
"\n width = " + width +
"\n height = " + height;
log.println( l );
log.println( "fillRoundRect(" + x + "," + y + "," + width + "," + height + "," + arcWidth + "," + arcHeight + ")" );
g2D.fillRoundRect( x, y, width, height, arcWidth, arcHeight );
}
@ -788,10 +880,7 @@ public class DummyGraphics2d extends Graphics2D {
}
public void setColor(Color c) {
String l =
"setColor():" +
"\n c = " + c;
log.println( l );
log.println( String.format(Locale.ROOT, "g.setColor(new Color(0x%08X));", c.getRGB()));
g2D.setColor( c );
}
@ -829,4 +918,112 @@ public class DummyGraphics2d extends Graphics2D {
log.println( l );
g2D.translate( x, y );
}
private static final Object[] HINTS = {
RenderingHints.KEY_ANTIALIASING, "RenderingHints.KEY_ANTIALIASING",
RenderingHints.VALUE_ANTIALIAS_ON, "RenderingHints.VALUE_ANTIALIAS_ON",
RenderingHints.VALUE_ANTIALIAS_OFF, "RenderingHints.VALUE_ANTIALIAS_OFF",
RenderingHints.VALUE_ANTIALIAS_DEFAULT, "RenderingHints.VALUE_ANTIALIAS_DEFAULT",
RenderingHints.KEY_RENDERING, "RenderingHints.KEY_RENDERING",
RenderingHints.VALUE_RENDER_SPEED, "RenderingHints.VALUE_RENDER_SPEED",
RenderingHints.VALUE_RENDER_QUALITY, "RenderingHints.VALUE_RENDER_QUALITY",
RenderingHints.VALUE_RENDER_DEFAULT, "RenderingHints.VALUE_RENDER_DEFAULT",
RenderingHints.KEY_DITHERING, "RenderingHints.KEY_DITHERING",
RenderingHints.VALUE_DITHER_DISABLE, "RenderingHints.VALUE_DITHER_DISABLE",
RenderingHints.VALUE_DITHER_ENABLE, "RenderingHints.VALUE_DITHER_ENABLE",
RenderingHints.VALUE_DITHER_DEFAULT, "RenderingHints.VALUE_DITHER_DEFAULT",
RenderingHints.KEY_TEXT_ANTIALIASING, "RenderingHints.KEY_TEXT_ANTIALIASING",
RenderingHints.VALUE_TEXT_ANTIALIAS_ON, "RenderingHints.VALUE_TEXT_ANTIALIAS_ON",
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF, "RenderingHints.VALUE_TEXT_ANTIALIAS_OFF",
RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT, "RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT",
RenderingHints.VALUE_TEXT_ANTIALIAS_GASP, "RenderingHints.VALUE_TEXT_ANTIALIAS_GASP",
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB, "RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB",
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR, "RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR",
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VRGB, "RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VRGB",
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR, "RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR",
RenderingHints.KEY_TEXT_LCD_CONTRAST, "RenderingHints.KEY_TEXT_LCD_CONTRAST",
RenderingHints.KEY_FRACTIONALMETRICS, "RenderingHints.KEY_FRACTIONALMETRICS",
RenderingHints.VALUE_FRACTIONALMETRICS_OFF, "RenderingHints.VALUE_FRACTIONALMETRICS_OFF",
RenderingHints.VALUE_FRACTIONALMETRICS_ON, "RenderingHints.VALUE_FRACTIONALMETRICS_ON",
RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT, "RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT",
RenderingHints.KEY_INTERPOLATION, "RenderingHints.KEY_INTERPOLATION",
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR, "RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR",
RenderingHints.VALUE_INTERPOLATION_BILINEAR, "RenderingHints.VALUE_INTERPOLATION_BILINEAR",
RenderingHints.VALUE_INTERPOLATION_BICUBIC, "RenderingHints.VALUE_INTERPOLATION_BICUBIC",
RenderingHints.KEY_ALPHA_INTERPOLATION, "RenderingHints.KEY_ALPHA_INTERPOLATION",
RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED, "RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED",
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY, "RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY",
RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT, "RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT",
RenderingHints.KEY_COLOR_RENDERING, "RenderingHints.KEY_COLOR_RENDERING",
RenderingHints.VALUE_COLOR_RENDER_SPEED, "RenderingHints.VALUE_COLOR_RENDER_SPEED",
RenderingHints.VALUE_COLOR_RENDER_QUALITY, "RenderingHints.VALUE_COLOR_RENDER_QUALITY",
RenderingHints.VALUE_COLOR_RENDER_DEFAULT, "RenderingHints.VALUE_COLOR_RENDER_DEFAULT",
RenderingHints.KEY_STROKE_CONTROL, "RenderingHints.KEY_STROKE_CONTROL",
RenderingHints.VALUE_STROKE_DEFAULT, "RenderingHints.VALUE_STROKE_DEFAULT",
RenderingHints.VALUE_STROKE_NORMALIZE, "RenderingHints.VALUE_STROKE_NORMALIZE",
RenderingHints.VALUE_STROKE_PURE, "RenderingHints.VALUE_STROKE_PURE"
};
private static final Object[] ATTRS = {
TextAttribute.FAMILY, "TextAttribute.FAMILY",
TextAttribute.WEIGHT, "TextAttribute.WEIGHT",
TextAttribute.WEIGHT_EXTRA_LIGHT, "TextAttribute.WEIGHT_EXTRA_LIGHT",
TextAttribute.WEIGHT_LIGHT, "TextAttribute.WEIGHT_LIGHT",
TextAttribute.WEIGHT_DEMILIGHT, "TextAttribute.WEIGHT_DEMILIGHT",
TextAttribute.WEIGHT_REGULAR, "TextAttribute.WEIGHT_REGULAR",
TextAttribute.WEIGHT_SEMIBOLD, "TextAttribute.WEIGHT_SEMIBOLD",
TextAttribute.WEIGHT_MEDIUM, "TextAttribute.WEIGHT_MEDIUM",
TextAttribute.WEIGHT_DEMIBOLD, "TextAttribute.WEIGHT_DEMIBOLD",
TextAttribute.WEIGHT_BOLD, "TextAttribute.WEIGHT_BOLD",
TextAttribute.WEIGHT_HEAVY, "TextAttribute.WEIGHT_HEAVY",
TextAttribute.WEIGHT_EXTRABOLD, "TextAttribute.WEIGHT_EXTRABOLD",
TextAttribute.WEIGHT_ULTRABOLD, "TextAttribute.WEIGHT_ULTRABOLD",
TextAttribute.WIDTH, "TextAttribute.WIDTH",
TextAttribute.WIDTH_CONDENSED, "TextAttribute.WIDTH_CONDENSED",
TextAttribute.WIDTH_SEMI_CONDENSED, "TextAttribute.WIDTH_SEMI_CONDENSED",
TextAttribute.WIDTH_REGULAR, "TextAttribute.WIDTH_REGULAR",
TextAttribute.WIDTH_SEMI_EXTENDED, "TextAttribute.WIDTH_SEMI_EXTENDED",
TextAttribute.WIDTH_EXTENDED, "TextAttribute.WIDTH_EXTENDED",
TextAttribute.POSTURE, "TextAttribute.POSTURE",
TextAttribute.POSTURE_REGULAR, "TextAttribute.POSTURE_REGULAR",
TextAttribute.POSTURE_OBLIQUE, "TextAttribute.POSTURE_OBLIQUE",
TextAttribute.SIZE, "TextAttribute.SIZE",
TextAttribute.TRANSFORM, "TextAttribute.TRANSFORM",
TextAttribute.SUPERSCRIPT, "TextAttribute.SUPERSCRIPT",
TextAttribute.SUPERSCRIPT_SUPER, "TextAttribute.SUPERSCRIPT_SUPER",
TextAttribute.SUPERSCRIPT_SUB, "TextAttribute.SUPERSCRIPT_SUB",
TextAttribute.FONT, "TextAttribute.FONT",
TextAttribute.CHAR_REPLACEMENT, "TextAttribute.CHAR_REPLACEMENT",
TextAttribute.FOREGROUND, "TextAttribute.FOREGROUND",
TextAttribute.BACKGROUND, "TextAttribute.BACKGROUND",
TextAttribute.UNDERLINE, "TextAttribute.UNDERLINE",
TextAttribute.UNDERLINE_ON, "TextAttribute.UNDERLINE_ON",
TextAttribute.STRIKETHROUGH, "TextAttribute.STRIKETHROUGH",
TextAttribute.STRIKETHROUGH_ON, "TextAttribute.STRIKETHROUGH_ON",
TextAttribute.RUN_DIRECTION, "TextAttribute.RUN_DIRECTION",
TextAttribute.RUN_DIRECTION_LTR, "TextAttribute.RUN_DIRECTION_LTR",
TextAttribute.RUN_DIRECTION_RTL, "TextAttribute.RUN_DIRECTION_RTL",
TextAttribute.BIDI_EMBEDDING, "TextAttribute.BIDI_EMBEDDING",
TextAttribute.JUSTIFICATION, "TextAttribute.JUSTIFICATION",
TextAttribute.JUSTIFICATION_FULL, "TextAttribute.JUSTIFICATION_FULL",
TextAttribute.JUSTIFICATION_NONE, "TextAttribute.JUSTIFICATION_NONE",
TextAttribute.INPUT_METHOD_HIGHLIGHT, "TextAttribute.INPUT_METHOD_HIGHLIGHT",
TextAttribute.INPUT_METHOD_UNDERLINE, "TextAttribute.INPUT_METHOD_UNDERLINE",
TextAttribute.UNDERLINE_LOW_ONE_PIXEL, "TextAttribute.UNDERLINE_LOW_ONE_PIXEL",
TextAttribute.UNDERLINE_LOW_TWO_PIXEL, "TextAttribute.UNDERLINE_LOW_TWO_PIXEL",
TextAttribute.UNDERLINE_LOW_DOTTED, "TextAttribute.UNDERLINE_LOW_DOTTED",
TextAttribute.UNDERLINE_LOW_GRAY, "TextAttribute.UNDERLINE_LOW_GRAY",
TextAttribute.UNDERLINE_LOW_DASHED, "TextAttribute.UNDERLINE_LOW_DASHED",
TextAttribute.SWAP_COLORS, "TextAttribute.SWAP_COLORS",
TextAttribute.SWAP_COLORS_ON, "TextAttribute.SWAP_COLORS_ON",
TextAttribute.NUMERIC_SHAPING, "TextAttribute.NUMERIC_SHAPING",
TextAttribute.KERNING, "TextAttribute.KERNING",
TextAttribute.KERNING_ON, "TextAttribute.KERNING_ON",
TextAttribute.LIGATURES, "TextAttribute.LIGATURES",
TextAttribute.LIGATURES_ON, "TextAttribute.LIGATURES_ON",
TextAttribute.TRACKING, "TextAttribute.TRACKING",
TextAttribute.TRACKING_TIGHT, "TextAttribute.TRACKING_TIGHT",
TextAttribute.TRACKING_LOOSE, "TextAttribute.TRACKING_LOOSE"
};
}

View File

@ -63,7 +63,7 @@ public final class PPTX2PNG {
" -scale <float> scale factor\n" +
" -fixSide <side> specify side (long,short,width,height) to fix - use <scale> as amount of pixels\n" +
" -slide <integer> 1-based index of a slide to render\n" +
" -format <type> png,gif,jpg,svg,pdf (,null for testing)\n" +
" -format <type> png,gif,jpg,svg,pdf (,log,null for testing)\n" +
" -outdir <dir> output directory, defaults to origin of the ppt/pptx file\n" +
" -outfile <file> output filename, defaults to '"+OUTPUT_PAT_REGEX+"'\n" +
" -outpat <pattern> output filename pattern, defaults to '"+OUTPUT_PAT_REGEX+"'\n" +
@ -239,7 +239,7 @@ public final class PPTX2PNG {
return false;
}
if (format == null || !format.matches("^(png|gif|jpg|null|svg|pdf)$")) {
if (format == null || !format.matches("^(png|gif|jpg|null|svg|pdf|log)$")) {
usage("Invalid format given");
return false;
}
@ -354,6 +354,8 @@ public final class PPTX2PNG {
return new SVGFormat(textAsShapes);
case "pdf":
return new PDFFormat(textAsShapes,fontDir,fontTtf);
case "log":
return new DummyFormat();
default:
return new BitmapFormat(format);
}

View File

@ -17,6 +17,8 @@
package org.apache.poi.xslf;
import static org.apache.poi.POITestCase.assertContains;
import static org.apache.poi.sl.draw.DrawTextParagraph.HYPERLINK_HREF;
import static org.apache.poi.sl.draw.DrawTextParagraph.HYPERLINK_LABEL;
import static org.apache.poi.xslf.XSLFTestDataSamples.openSampleDocument;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@ -25,6 +27,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeFalse;
import java.awt.Color;
import java.awt.Dimension;
@ -39,16 +42,23 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.text.AttributedCharacterIterator;
import java.text.AttributedCharacterIterator.Attribute;
import java.text.CharacterIterator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.imageio.ImageIO;
import org.apache.poi.POIDataSamples;
import org.apache.poi.common.usermodel.HyperlinkType;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.POIXMLDocumentPart.RelationPart;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
@ -57,6 +67,7 @@ import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.extractor.SlideShowExtractor;
import org.apache.poi.sl.usermodel.Hyperlink;
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
@ -66,8 +77,13 @@ import org.apache.poi.sl.usermodel.PictureShape;
import org.apache.poi.sl.usermodel.Shape;
import org.apache.poi.sl.usermodel.ShapeType;
import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.SlideShowFactory;
import org.apache.poi.sl.usermodel.TextRun;
import org.apache.poi.sl.usermodel.TextShape;
import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.NullPrintStream;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFAutoShape;
import org.apache.poi.xslf.usermodel.XSLFGroupShape;
@ -87,6 +103,8 @@ import org.apache.poi.xslf.usermodel.XSLFTableRow;
import org.apache.poi.xslf.usermodel.XSLFTextBox;
import org.apache.poi.xslf.usermodel.XSLFTextParagraph;
import org.apache.poi.xslf.usermodel.XSLFTextRun;
import org.apache.poi.xslf.util.DummyGraphics2d;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect;
@ -95,6 +113,17 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
public class TestXSLFBugs {
private static final POIDataSamples slTests = POIDataSamples.getSlideShowInstance();
private static boolean xslfOnly;
@BeforeClass
public static void checkHslf() {
try {
Class.forName("org.apache.poi.hslf.usermodel.HSLFSlideShow");
} catch (Exception e) {
xslfOnly = true;
}
}
@Test
public void bug62929() throws Exception {
try(XMLSlideShow ss1 = openSampleDocument("missing-blip-fill.pptx")) {
@ -247,9 +276,9 @@ public class TestXSLFBugs {
public void bug62587() throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try (XMLSlideShow ppt = new XMLSlideShow()) {
Slide slide = ppt.createSlide();
Slide<?,?> slide = ppt.createSlide();
XSLFPictureData pd = ppt.addPicture(slTests.getFile("wrench.emf"), PictureType.EMF);
PictureShape ps = slide.createPicture(pd);
PictureShape<?,?> ps = slide.createPicture(pd);
ps.setAnchor(new Rectangle2D.Double(100,100,100,100));
ppt.write(bos);
}
@ -584,9 +613,7 @@ public class TestXSLFBugs {
// Some dummy pictures
byte[][] pics = new byte[15][3];
for (int i=0; i<pics.length; i++) {
for (int j=0; j<pics[i].length; j++) {
pics[i][j] = (byte)i;
}
Arrays.fill(pics[i], (byte) i);
}
// Add a few pictures
@ -1011,4 +1038,53 @@ public class TestXSLFBugs {
assertEquals("Picture 5", ps.getShapeName());
}
}
@Test
public void bug57796() throws IOException {
assumeFalse(xslfOnly);
try (SlideShow<?,?> ppt = SlideShowFactory.create(slTests.getFile("WithLinks.ppt"))) {
Slide<?,?> slide = ppt.getSlides().get(0);
TextShape<?,?> shape = (TextShape<?,?>) slide.getShapes().get(1);
TextRun r = shape.getTextParagraphs().get(1).getTextRuns().get(0);
Hyperlink<?,?> hlRun = r.getHyperlink();
assertNotNull(hlRun);
assertEquals("http://jakarta.apache.org/poi/", hlRun.getAddress());
assertEquals("http://jakarta.apache.org/poi/", hlRun.getLabel());
assertEquals(HyperlinkType.URL, hlRun.getType());
final List<Object> strings = new ArrayList<>();
DummyGraphics2d dgfx = new DummyGraphics2d(new NullPrintStream()) {
@Override
public void drawString(AttributedCharacterIterator iterator, float x, float y) {
// For the test file, common sl draws textruns one by one and not mixed
// so we evaluate the whole iterator
Map<Attribute, Object> attributes = null;
StringBuilder sb = new StringBuilder();
for (char c = iterator.first();
c != CharacterIterator.DONE;
c = iterator.next()) {
sb.append(c);
attributes = iterator.getAttributes();
}
if ("Jakarta HSSF".equals(sb.toString())) {
// this is a test for a manually modified ppt, for real hyperlink label
// one would need to access the screen tip record
Attribute[] obj = { HYPERLINK_HREF, HYPERLINK_LABEL };
assertNotNull(attributes);
Stream.of(obj).map(attributes::get).forEach(strings::add);
}
}
};
ppt.getSlides().get(1).draw(dgfx);
assertEquals(2, strings.size());
assertEquals("http://jakarta.apache.org/poi/hssf/", strings.get(0));
assertEquals("Open Jakarta POI HSSF module test ", strings.get(1));
}
}
}

View File

@ -24,7 +24,7 @@
</Match>
<Match>
<Class name="org.apache.poi.hssf.usermodel.DummyGraphics2d"/>
<Class name="org.apache.poi.xslf.util.DummyGraphics2d"/>
<Bug code="FI" />
</Match>
@ -119,7 +119,7 @@
<Method name="readData" params="java.io.InputStream,int" />
<Bug pattern="SF_SWITCH_FALLTHROUGH" />
</Match>
<!-- invalid performance issues - e.g. see #57840 -->
<Match>

View File

@ -225,7 +225,7 @@ public class HwmfGraphics implements HwmfCharsetAware {
// Instead, it is a floating-point value that specifies a linear distance.
float dashStart = (dashAlt && dashes != null && dashes.length > 1) ? dashes[0] : 0;
return new BasicStroke(width, cap, join, miterLimit, dashes, dashStart);
return new BasicStroke(width, cap, join, Math.max(1,miterLimit), dashes, dashStart);
}
protected Paint getFill() {