diff --git a/src/integrationtest/org/apache/poi/TestAllFiles.java b/src/integrationtest/org/apache/poi/TestAllFiles.java index 0a68579c1..51accdc31 100644 --- a/src/integrationtest/org/apache/poi/TestAllFiles.java +++ b/src/integrationtest/org/apache/poi/TestAllFiles.java @@ -252,6 +252,12 @@ public class TestAllFiles { EXPECTED_FAILURES.add("ddf/47143.dat"); } + private static final Set IGNORED = new HashSet(); + static { + // need JDK8+ - https://bugs.openjdk.java.net/browse/JDK-8038081 + IGNORED.add("slideshow/42474-2.ppt"); + } + @Parameters(name="{index}: {0} using {1}") public static Iterable files() { DirectoryScanner scanner = new DirectoryScanner(); @@ -265,6 +271,7 @@ public class TestAllFiles { List files = new ArrayList(); for(String file : scanner.getIncludedFiles()) { file = file.replace('\\', '/'); // ... failures/handlers lookup doesn't work on windows otherwise + if (IGNORED.contains(file)) continue; files.add(new Object[] { file, HANDLERS.get(getExtension(file)) }); } diff --git a/src/integrationtest/org/apache/poi/stress/HSLFFileHandler.java b/src/integrationtest/org/apache/poi/stress/HSLFFileHandler.java index a946b18c1..838bbf726 100644 --- a/src/integrationtest/org/apache/poi/stress/HSLFFileHandler.java +++ b/src/integrationtest/org/apache/poi/stress/HSLFFileHandler.java @@ -23,10 +23,11 @@ import java.io.FileInputStream; import java.io.InputStream; import org.apache.poi.hslf.record.Record; +import org.apache.poi.hslf.usermodel.HSLFSlideShow; import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl; import org.junit.Test; -public class HSLFFileHandler extends POIFSFileHandler { +public class HSLFFileHandler extends SlideShowHandler { @Override public void handleFile(InputStream stream) throws Exception { HSLFSlideShowImpl slide = new HSLFSlideShowImpl(stream); @@ -41,6 +42,9 @@ public class HSLFFileHandler extends POIFSFileHandler { } handlePOIDocument(slide); + + HSLFSlideShow ss = new HSLFSlideShow(slide); + handleSlideShow(ss); } // a test-case to test this locally without executing the full TestAllFiles diff --git a/src/integrationtest/org/apache/poi/stress/SlideShowHandler.java b/src/integrationtest/org/apache/poi/stress/SlideShowHandler.java new file mode 100644 index 000000000..a4de13e40 --- /dev/null +++ b/src/integrationtest/org/apache/poi/stress/SlideShowHandler.java @@ -0,0 +1,135 @@ +/* ==================================================================== + 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.stress; + +import static org.junit.Assert.assertNotNull; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.sl.SlideShowFactory; +import org.apache.poi.sl.draw.Drawable; +import org.apache.poi.sl.usermodel.Notes; +import org.apache.poi.sl.usermodel.Shape; +import org.apache.poi.sl.usermodel.ShapeContainer; +import org.apache.poi.sl.usermodel.Slide; +import org.apache.poi.sl.usermodel.SlideShow; +import org.apache.poi.sl.usermodel.TextParagraph; +import org.apache.poi.sl.usermodel.TextRun; +import org.apache.poi.sl.usermodel.TextShape; +import org.apache.poi.util.JvmBugs; + +public abstract class SlideShowHandler extends POIFSFileHandler { + public void handleSlideShow(SlideShow ss) throws IOException { + renderSlides(ss); + + readContent(ss); + + // write out the file + ByteArrayOutputStream out = writeToArray(ss); + + readContent(ss); + + // read in the writen file + SlideShow read; + try { + read = SlideShowFactory.create(new ByteArrayInputStream(out.toByteArray())); + } catch (InvalidFormatException e) { + throw new IllegalStateException(e); + } + assertNotNull(read); + + readContent(read); + + } + + private ByteArrayOutputStream writeToArray(SlideShow ss) throws IOException { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + try { + ss.write(stream); + } finally { + stream.close(); + } + + return stream; + } + + + private void readContent(SlideShow ss) { + for (Slide> s : ss.getSlides()) { + s.getTitle(); + readText(s); + readText(s.getNotes()); + readText(s.getMasterSheet()); + } + } + + @SuppressWarnings("unchecked") + private void readText(ShapeContainer sc) { + if (sc == null) return; + for (Shape s : sc) { + if (s instanceof TextShape) { + for (TextParagraph tp : (TextShape>)s) { + for (TextRun tr : tp) { + tr.getRawText(); + } + } + } + } + } + + private void renderSlides(SlideShow ss) { + Dimension pgsize = ss.getPageSize(); + + for (Slide s : ss.getSlides()) { + BufferedImage img = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_ARGB); + Graphics2D graphics = img.createGraphics(); + fixFonts(graphics); + + // default rendering options + 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); + + // draw stuff + s.draw(graphics); + + graphics.dispose(); + img.flush(); + } + } + + @SuppressWarnings("unchecked") + private static void fixFonts(Graphics2D graphics) { + if (!JvmBugs.hasLineBreakMeasurerBug()) return; + Map fontMap = (Map)graphics.getRenderingHint(Drawable.FONT_MAP); + if (fontMap == null) fontMap = new HashMap(); + fontMap.put("Calibri", "Lucida Sans"); + fontMap.put("Cambria", "Lucida Bright"); + graphics.setRenderingHint(Drawable.FONT_MAP, fontMap); + } + +} \ No newline at end of file diff --git a/src/integrationtest/org/apache/poi/stress/XSLFFileHandler.java b/src/integrationtest/org/apache/poi/stress/XSLFFileHandler.java index ba33ad589..e65c1225c 100644 --- a/src/integrationtest/org/apache/poi/stress/XSLFFileHandler.java +++ b/src/integrationtest/org/apache/poi/stress/XSLFFileHandler.java @@ -18,82 +18,31 @@ package org.apache.poi.stress; import static org.junit.Assert.assertNotNull; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; -import java.io.IOException; import java.io.InputStream; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.sl.draw.DrawFactory; -import org.apache.poi.sl.draw.Drawable; import org.apache.poi.xslf.XSLFSlideShow; import org.apache.poi.xslf.usermodel.XMLSlideShow; -import org.apache.poi.xslf.usermodel.XSLFNotes; -import org.apache.poi.xslf.usermodel.XSLFShape; -import org.apache.poi.xslf.usermodel.XSLFSlide; -import org.apache.poi.xslf.usermodel.XSLFTextParagraph; -import org.apache.poi.xslf.usermodel.XSLFTextShape; import org.junit.Test; -public class XSLFFileHandler extends AbstractFileHandler { +public class XSLFFileHandler extends SlideShowHandler { @Override public void handleFile(InputStream stream) throws Exception { - XSLFSlideShow slide = new XSLFSlideShow(OPCPackage.open(stream)); - assertNotNull(slide.getPresentation()); - assertNotNull(slide.getSlideMasterReferences()); - assertNotNull(slide.getSlideReferences()); + XMLSlideShow slide = new XMLSlideShow(stream); + XSLFSlideShow slideInner = new XSLFSlideShow(slide.getPackage()); + assertNotNull(slideInner.getPresentation()); + assertNotNull(slideInner.getSlideMasterReferences()); + assertNotNull(slideInner.getSlideReferences()); new POIXMLDocumentHandler().handlePOIXMLDocument(slide); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - try { - slide.write(out); - } finally { - out.close(); - } + handleSlideShow(slide); - createBitmaps(out); + slideInner.close(); + slide.close(); } - private void createBitmaps(ByteArrayOutputStream out) throws IOException { - XMLSlideShow ppt = new XMLSlideShow(new ByteArrayInputStream(out.toByteArray())); - Dimension pgsize = ppt.getPageSize(); - for (XSLFSlide xmlSlide : ppt.getSlides()) { -// System.out.println("slide-" + (i + 1)); -// System.out.println("" + xmlSlide[i].getTitle()); - - BufferedImage img = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_RGB); - Graphics2D graphics = img.createGraphics(); - - // draw stuff - xmlSlide.draw(graphics); - - // Also try to read notes - XSLFNotes notes = xmlSlide.getNotes(); - if(notes != null) { - for (XSLFShape note : notes) { - DrawFactory df = DrawFactory.getInstance(graphics); - Drawable d = df.getDrawable(note); - d.draw(graphics); - - if (note instanceof XSLFTextShape) { - XSLFTextShape txShape = (XSLFTextShape) note; - for (XSLFTextParagraph xslfParagraph : txShape.getTextParagraphs()) { - xslfParagraph.getText(); - } - } - } - } - } - - ppt.close(); - } - // a test-case to test this locally without executing the full TestAllFiles @Test public void test() throws Exception { diff --git a/src/java/org/apache/poi/sl/usermodel/SlideShow.java b/src/java/org/apache/poi/sl/usermodel/SlideShow.java index e8f442821..ac2a7a7d9 100644 --- a/src/java/org/apache/poi/sl/usermodel/SlideShow.java +++ b/src/java/org/apache/poi/sl/usermodel/SlideShow.java @@ -19,6 +19,7 @@ package org.apache.poi.sl.usermodel; import java.awt.Dimension; import java.io.IOException; +import java.io.OutputStream; import java.util.List; import org.apache.poi.sl.usermodel.PictureData.PictureType; @@ -55,4 +56,16 @@ public interface SlideShow { * @return the new picture reference */ PictureData addPicture(byte[] pictureData, PictureType format) throws IOException; + + /** + * Writes out the slideshow file the is represented by an instance of this + * class + * + * @param out + * The OutputStream to write to. + * @throws IOException + * If there is an unexpected IOException from the passed in + * OutputStream + */ + void write(OutputStream out) throws IOException; } diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java index c90452dda..c6feb514e 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java @@ -30,6 +30,7 @@ import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound; import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.POILogger; import org.apache.poi.util.Units; /** @@ -346,11 +347,15 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape { } public Guide getAdjustValue(String name) { - if (name == null || !name.matches("adj([1-9]|10)")) { + if (name == null || !name.matches("adj([1-9]|10)?")) { throw new IllegalArgumentException("Adjust value '"+name+"' not supported."); } + + name = name.replace("adj", ""); + if ("".equals(name)) name = "1"; + short escherProp; - switch (Integer.parseInt(name.substring(3))) { + switch (Integer.parseInt(name)) { case 1: escherProp = EscherProperties.GEOMETRY__ADJUSTVALUE; break; case 2: escherProp = EscherProperties.GEOMETRY__ADJUST2VALUE; break; case 3: escherProp = EscherProperties.GEOMETRY__ADJUST3VALUE; break; @@ -369,13 +374,14 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape { } public CustomGeometry getGeometry() { + PresetGeometries dict = PresetGeometries.getInstance(); ShapeType st = getShapeType(); String name = st.getOoxmlName(); - - PresetGeometries dict = PresetGeometries.getInstance(); CustomGeometry geom = dict.get(name); if(geom == null) { - throw new IllegalStateException("Unknown shape geometry: " + name); + if (name == null && st != null) name = st.toString(); + logger.log(POILogger.WARN, "No preset shape definition for shapeType: "+name); + return null; } return geom; diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java index 86604bf09..c1deea844 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java @@ -431,16 +431,7 @@ public final class HSLFSlideShow implements SlideShow { } } - /** - * Writes out the slideshow file the is represented by an instance of this - * class - * - * @param out - * The OutputStream to write to. - * @throws IOException - * If there is an unexpected IOException from the passed in - * OutputStream - */ + @Override public void write(OutputStream out) throws IOException { // check for text paragraph modifications for (HSLFSlide sl : getSlides()) { diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java index e0f7479d6..4b8b5dc2c 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java @@ -416,6 +416,7 @@ public final class HSLFSlideShowImpl extends POIDocument { // Build the PictureData object from the data try { HSLFPictureData pict = HSLFPictureData.create(pt); + pict.setSignature(signature); // Copy the data, ready to pass to PictureData byte[] imgdata = new byte[imgsize];