Author: kiwiwings Date: Thu Dec 17 23:42:26 2020 New Revision: 1884578 URL: http://svn.apache.org/viewvc?rev=1884578&view=rev Log: #64876 - Unable to convert pptx to pdf
Added: poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/DummyFormat.java (with props) poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/DummyGraphics2d.java - copied, changed from r1884577, poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/DummyGraphics2d.java Removed: poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/DummyGraphics2d.java Modified: poi/site/src/documentation/content/xdocs/changes.xml poi/site/src/documentation/content/xdocs/components/slideshow/ppt-wmf-emf-renderer.xml poi/trunk/src/java/org/apache/poi/sl/draw/DrawShape.java poi/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFShape.java poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java poi/trunk/src/resources/devtools/findbugs-filters.xml poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java Modified: poi/site/src/documentation/content/xdocs/changes.xml URL: http://svn.apache.org/viewvc/poi/site/src/documentation/content/xdocs/changes.xml?rev=1884578&r1=1884577&r2=1884578&view=diff ============================================================================== --- poi/site/src/documentation/content/xdocs/changes.xml (original) +++ poi/site/src/documentation/content/xdocs/changes.xml Thu Dec 17 23:42:26 2020 @@ -124,6 +124,7 @@ <action type="fix" fixes-bug="56205" context="OOXML" breaks-compatibility="true">Upgrade OOXML schema to 3rd edition (transitional)</action> <action type="fix" fixes-bug="64979" context="OOXML">Change artifact names of poi-/ooxml-schemas</action> <action type="fix" fixes-bug="64981" context="OOXML" breaks-compatibility="true">Upgrade OOXML schema to 5th edition (transitional)</action> + <action type="fix" fixes-bug="64876" context="XSLF">Unable to convert pptx to pdf</action> </actions> </release> Modified: poi/site/src/documentation/content/xdocs/components/slideshow/ppt-wmf-emf-renderer.xml URL: http://svn.apache.org/viewvc/poi/site/src/documentation/content/xdocs/components/slideshow/ppt-wmf-emf-renderer.xml?rev=1884578&r1=1884577&r2=1884578&view=diff ============================================================================== --- poi/site/src/documentation/content/xdocs/components/slideshow/ppt-wmf-emf-renderer.xml (original) +++ poi/site/src/documentation/content/xdocs/components/slideshow/ppt-wmf-emf-renderer.xml Thu Dec 17 23:42:26 2020 @@ -42,7 +42,7 @@ -scale <float> scale factor -fixSide <side> specify side (long,short,width,height) to fix - use <scale> as amount of pixels -slide <integer> 1-based index of a slide to render - -format <type> png,gif,jpg,svg,pdf (,null for testing) + -format <type> png,gif,jpg,svg,pdf (log,null for testing) -outdir <dir> output directory, defaults to origin of the ppt/pptx file -outfile <file> output filename, defaults to "${basename}-${slideno}.${format}" -outpat <pattern> output filename pattern, defaults to "${basename}-${slideno}.${format}" Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawShape.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawShape.java?rev=1884578&r1=1884577&r2=1884578&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/sl/draw/DrawShape.java (original) +++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawShape.java Thu Dec 17 23:42:26 2020 @@ -254,6 +254,6 @@ public class DrawShape implements Drawab 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); } } Modified: poi/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFShape.java URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFShape.java?rev=1884578&r1=1884577&r2=1884578&view=diff ============================================================================== --- poi/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFShape.java (original) +++ poi/trunk/src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFShape.java Thu Dec 17 23:42:26 2020 @@ -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.sec 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); } // Added: poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/DummyFormat.java URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/DummyFormat.java?rev=1884578&view=auto ============================================================================== --- poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/DummyFormat.java (added) +++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/DummyFormat.java Thu Dec 17 23:42:26 2020 @@ -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(); + } +} Propchange: poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/DummyFormat.java ------------------------------------------------------------------------------ svn:eol-style = native Copied: poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/DummyGraphics2d.java (from r1884577, poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/DummyGraphics2d.java) URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/DummyGraphics2d.java?p2=poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/DummyGraphics2d.java&p1=poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/DummyGraphics2d.java&r1=1884577&r2=1884578&rev=1884578&view=diff ============================================================================== --- poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/DummyGraphics2d.java (original) +++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/DummyGraphics2d.java Thu Dec 17 23:42:26 2020 @@ -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 Gra 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 Gra 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 Gra } 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 Gra } 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 Gra } 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 Gra 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 Gra 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 Gra } 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 Gra } 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 Gra 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" + }; } Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java?rev=1884578&r1=1884577&r2=1884578&view=diff ============================================================================== --- poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java (original) +++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/util/PPTX2PNG.java Thu Dec 17 23:42:26 2020 @@ -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); } Modified: poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java?rev=1884578&r1=1884577&r2=1884578&view=diff ============================================================================== --- poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java (original) +++ poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java Thu Dec 17 23:42:26 2020 @@ -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.assertNot 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.Pack 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.Pictu 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.XSL 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.presen 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)); + } + } } Modified: poi/trunk/src/resources/devtools/findbugs-filters.xml URL: http://svn.apache.org/viewvc/poi/trunk/src/resources/devtools/findbugs-filters.xml?rev=1884578&r1=1884577&r2=1884578&view=diff ============================================================================== --- poi/trunk/src/resources/devtools/findbugs-filters.xml (original) +++ poi/trunk/src/resources/devtools/findbugs-filters.xml Thu Dec 17 23:42:26 2020 @@ -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> Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java?rev=1884578&r1=1884577&r2=1884578&view=diff ============================================================================== --- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java (original) +++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java Thu Dec 17 23:42:26 2020 @@ -225,7 +225,7 @@ public class HwmfGraphics implements Hwm // 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() { --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@poi.apache.org For additional commands, e-mail: commits-h...@poi.apache.org