You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2021/10/12 22:30:30 UTC

svn commit: r1894176 - in /poi/trunk: poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/ poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/ poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/ poi-scratchpad/src/main/java/org/...

Author: kiwiwings
Date: Tue Oct 12 22:30:30 2021
New Revision: 1894176

URL: http://svn.apache.org/viewvc?rev=1894176&view=rev
Log:
#64716 - wmf display error
add anothger heuristic - cumulate the bounding box of the shape records and compare it to window, viewport and emfbounds

Modified:
    poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java
    poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfComment.java
    poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfDraw.java
    poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfRecord.java
    poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfWindowing.java
    poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusHeader.java
    poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusMisc.java
    poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusRecord.java
    poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/usermodel/HemfPicture.java

Modified: poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java?rev=1894176&r1=1894175&r2=1894176&view=diff
==============================================================================
--- poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java (original)
+++ poi/trunk/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestPPTX2PNG.java Tue Oct 12 22:30:30 2021
@@ -23,6 +23,7 @@ import static java.util.Arrays.asList;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assumptions.assumeFalse;
 
+import java.io.Closeable;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -44,12 +45,14 @@ import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
+import org.mockito.internal.util.io.IOUtil;
 
 /**
  * Test class for testing PPTX2PNG utility which renders .ppt and .pptx slideshows
  */
 @SuppressWarnings("ConstantConditions")
 class TestPPTX2PNG {
+    private static Closeable archive;
     private static boolean xslfOnly;
     private static final POIDataSamples samples = POIDataSamples.getSlideShowInstance();
 
@@ -82,15 +85,21 @@ class TestPPTX2PNG {
     @AfterAll
     public static void resetStdin() {
         System.setIn(defStdin);
+        IOUtil.closeQuietly(archive);
     }
 
     public static Stream<Arguments> data() throws IOException {
+        // Junit closes all closable arguments after the usage
+        // therefore we need to wrap the archive in non-closable arrays
+
         if (basedir != null && basedir.getName().endsWith(".zip")) {
             ZipFile zipFile = new ZipFile(basedir);
-            return zipFile.stream().map(f -> Arguments.of(f.getName(), f, zipFile));
+            archive = zipFile;
+            return zipFile.stream().map(f -> Arguments.of(f.getName(), f, new ZipFile[]{zipFile}));
         } else if (basedir != null && basedir.getName().endsWith(".7z")) {
             SevenZFile sevenZFile = new SevenZFile(basedir);
-            return ((ArrayList<SevenZArchiveEntry>)sevenZFile.getEntries()).stream().filter(f -> !f.isDirectory()).map(f -> Arguments.of(f.getName(), f, sevenZFile));
+            archive = sevenZFile;
+            return ((ArrayList<SevenZArchiveEntry>)sevenZFile.getEntries()).stream().filter(f -> !f.isDirectory()).map(f -> Arguments.of(f.getName(), f, new SevenZFile[]{sevenZFile}));
         } else {
             return Stream.of(files.split(", ?")).
                 map(basedir == null ? samples::getFile : f -> new File(basedir, f)).
@@ -127,7 +136,7 @@ class TestPPTX2PNG {
                 "-format", format, // png,gif,jpg,svg,pdf or null for test
                 "-slide", "-1", // -1 for all
                 "-outdir", tmpDir.getCanonicalPath(),
-                // "-dump", new File("build/tmp/", pptFile+".json").getCanonicalPath(),
+                // "-dump", new File("build/tmp/", fileName+".json").getCanonicalPath(),
                 "-dump", "null",
                 "-quiet",
                 "-ignoreParse",
@@ -162,14 +171,14 @@ class TestPPTX2PNG {
 
         if (fileObj instanceof ZipEntry) {
             ZipEntry ze = (ZipEntry)fileObj;
-            ZipFile zf = (ZipFile)fileContainer;
+            ZipFile zf = ((ZipFile[])fileContainer)[0];
             System.setIn(zf.getInputStream(ze));
             args.add("-outpat");
             args.add(basename+"-${slideno}-"+ext+".${format}");
             args.add("stdin");
         } else if (fileObj instanceof SevenZArchiveEntry) {
             SevenZArchiveEntry ze = (SevenZArchiveEntry)fileObj;
-            SevenZFile zf = (SevenZFile)fileContainer;
+            SevenZFile zf = ((SevenZFile[])fileContainer)[0];
             System.setIn(zf.getInputStream(ze));
             args.add("-outpat");
             args.add(basename+"-${slideno}-"+ext+".${format}");

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfComment.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfComment.java?rev=1894176&r1=1894175&r2=1894176&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfComment.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfComment.java Tue Oct 12 22:30:30 2021
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hemf.record.emf;
 
+import static org.apache.logging.log4j.util.Unbox.box;
+
 import java.awt.geom.Rectangle2D;
 import java.io.IOException;
 import java.nio.charset.Charset;
@@ -34,6 +36,7 @@ import org.apache.logging.log4j.Logger;
 import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.hemf.draw.HemfGraphics.EmfRenderState;
+import org.apache.poi.hemf.record.emf.HemfRecord.RenderBounds;
 import org.apache.poi.hemf.record.emfplus.HemfPlusRecord;
 import org.apache.poi.hemf.record.emfplus.HemfPlusRecordIterator;
 import org.apache.poi.hwmf.usermodel.HwmfCharsetAware;
@@ -47,8 +50,6 @@ import org.apache.poi.util.LittleEndianI
 import org.apache.poi.util.LocaleUtil;
 import org.apache.poi.util.RecordFormatException;
 
-import static org.apache.logging.log4j.util.Unbox.box;
-
 /**
  * Contains arbitrary data
  */
@@ -103,7 +104,7 @@ public class HemfComment {
          */
         default void draw(HemfGraphics ctx) {}
 
-        default void calcBounds(Rectangle2D bounds, Rectangle2D viewport, EmfRenderState[] renderState) { }
+        default void calcBounds(RenderBounds holder) { }
 
 
         @Override
@@ -137,8 +138,8 @@ public class HemfComment {
         }
 
         @Override
-        public void calcBounds(Rectangle2D window, Rectangle2D viewport, EmfRenderState[] renderState) {
-            data.calcBounds(window, viewport, renderState);
+        public void calcBounds(RenderBounds holder) {
+            data.calcBounds(holder);
         }
 
         @Override
@@ -343,11 +344,11 @@ public class HemfComment {
         }
 
         @Override
-        public void calcBounds(Rectangle2D window, Rectangle2D viewport, EmfRenderState[] renderState) {
-            renderState[0] = EmfRenderState.EMFPLUS_ONLY;
+        public void calcBounds(RenderBounds holder) {
+            holder.setState(EmfRenderState.EMFPLUS_ONLY);
             for (HemfPlusRecord r : records) {
-                r.calcBounds(window, viewport, renderState);
-                if (!window.isEmpty() && !viewport.isEmpty()) {
+                r.calcBounds(holder);
+                if (!holder.getWindow().isEmpty() && !holder.getViewport().isEmpty()) {
                     break;
                 }
             }

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfDraw.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfDraw.java?rev=1894176&r1=1894175&r2=1894176&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfDraw.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfDraw.java Tue Oct 12 22:30:30 2021
@@ -222,6 +222,16 @@ public final class HemfDraw {
         public HemfRecordType getGenericRecordType() {
             return getEmfRecordType();
         }
+
+        @Override
+        public void calcBounds(RenderBounds holder) {
+            Rectangle2D b = holder.getBounds();
+            if (b.isEmpty()) {
+                b.setRect(bounds);
+            } else {
+                b.add(bounds);
+            }
+        }
     }
 
     /**
@@ -323,6 +333,16 @@ public final class HemfDraw {
         public HemfRecordType getGenericRecordType() {
             return getEmfRecordType();
         }
+
+        @Override
+        public void calcBounds(RenderBounds holder) {
+            Rectangle2D b = holder.getBounds();
+            if (b.isEmpty()) {
+                b.setRect(bounds);
+            } else {
+                b.add(bounds);
+            }
+        }
     }
 
     /**
@@ -775,6 +795,16 @@ public final class HemfDraw {
         public HemfRecordType getGenericRecordType() {
             return getEmfRecordType();
         }
+
+        @Override
+        public void calcBounds(RenderBounds holder) {
+            Rectangle2D b = holder.getBounds();
+            if (b.isEmpty()) {
+                b.setRect(bounds);
+            } else {
+                b.add(bounds);
+            }
+        }
     }
 
     /**
@@ -808,6 +838,16 @@ public final class HemfDraw {
         public HemfRecordType getGenericRecordType() {
             return getEmfRecordType();
         }
+
+        @Override
+        public void calcBounds(RenderBounds holder) {
+            Rectangle2D b = holder.getBounds();
+            if (b.isEmpty()) {
+                b.setRect(bounds);
+            } else {
+                b.add(bounds);
+            }
+        }
     }
 
     /**
@@ -834,6 +874,14 @@ public final class HemfDraw {
         public HemfRecordType getGenericRecordType() {
             return getEmfRecordType();
         }
+
+        @Override
+        public void calcBounds(RenderBounds holder) {
+            Rectangle2D b = holder.getBounds();
+            if (!b.isEmpty()) {
+                b.add(point);
+            }
+        }
     }
 
     /**
@@ -864,6 +912,16 @@ public final class HemfDraw {
         public HemfRecordType getGenericRecordType() {
             return getEmfRecordType();
         }
+
+        @Override
+        public void calcBounds(RenderBounds holder) {
+            Rectangle2D b = holder.getBounds();
+            if (b.isEmpty()) {
+                b.setRect(bounds);
+            } else {
+                b.add(bounds);
+            }
+        }
     }
 
     /** The EMR_POLYDRAW record specifies a set of line segments and Bezier curves. */
@@ -979,6 +1037,16 @@ public final class HemfDraw {
         public HemfRecordType getGenericRecordType() {
             return getEmfRecordType();
         }
+
+        @Override
+        public void calcBounds(RenderBounds holder) {
+            Rectangle2D b = holder.getBounds();
+            if (b.isEmpty()) {
+                b.setRect(bounds);
+            } else {
+                b.add(bounds);
+            }
+        }
     }
 
     public static class EmfPolyDraw16 extends EmfPolyDraw {
@@ -1201,6 +1269,16 @@ public final class HemfDraw {
         public Map<String, Supplier<?>> getGenericProperties() {
             return GenericRecordUtil.getGenericProperties("bounds", this::getBounds);
         }
+
+        @Override
+        public void calcBounds(RenderBounds holder) {
+            Rectangle2D b = holder.getBounds();
+            if (b.isEmpty()) {
+                b.setRect(bounds);
+            } else {
+                b.add(bounds);
+            }
+        }
     }
 
 

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfRecord.java?rev=1894176&r1=1894175&r2=1894176&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfRecord.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfRecord.java Tue Oct 12 22:30:30 2021
@@ -57,7 +57,16 @@ public interface HemfRecord extends Gene
         }
     }
 
-    default void calcBounds(Rectangle2D window, Rectangle2D viewport, HemfGraphics.EmfRenderState[] renderState) {
+    interface RenderBounds {
+        HemfGraphics.EmfRenderState getState();
+        void setState(HemfGraphics.EmfRenderState state);
+
+        Rectangle2D getWindow();
+        Rectangle2D getViewport();
+        Rectangle2D getBounds();
+    }
+
+    default void calcBounds(RenderBounds holder) {
     }
 
     /**

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfWindowing.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfWindowing.java?rev=1894176&r1=1894175&r2=1894176&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfWindowing.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfWindowing.java Tue Oct 12 22:30:30 2021
@@ -59,7 +59,8 @@ public class HemfWindowing {
         }
 
         @Override
-        public void calcBounds(Rectangle2D window, Rectangle2D viewport, HemfGraphics.EmfRenderState[] renderState) {
+        public void calcBounds(RenderBounds holder) {
+            Rectangle2D window = holder.getWindow();
             double x = window.getX();
             double y = window.getY();
             window.setRect(x,y,size.getWidth(),size.getHeight());
@@ -86,7 +87,8 @@ public class HemfWindowing {
         }
 
         @Override
-        public void calcBounds(Rectangle2D window, Rectangle2D viewport, HemfGraphics.EmfRenderState[] renderState) {
+        public void calcBounds(RenderBounds holder) {
+            Rectangle2D window = holder.getWindow();
             double w = window.getWidth();
             double h = window.getHeight();
             window.setRect(origin.getX(),origin.getY(),w,h);
@@ -113,7 +115,8 @@ public class HemfWindowing {
         }
 
         @Override
-        public void calcBounds(Rectangle2D window, Rectangle2D viewport, HemfGraphics.EmfRenderState[] renderState) {
+        public void calcBounds(RenderBounds holder) {
+            Rectangle2D viewport = holder.getViewport();
             double x = viewport.getX();
             double y = viewport.getY();
             viewport.setRect(x,y,extents.getWidth(),extents.getHeight());
@@ -140,7 +143,8 @@ public class HemfWindowing {
         }
 
         @Override
-        public void calcBounds(Rectangle2D window, Rectangle2D viewport, HemfGraphics.EmfRenderState[] renderState) {
+        public void calcBounds(RenderBounds holder) {
+            Rectangle2D viewport = holder.getViewport();
             double w = viewport.getWidth();
             double h = viewport.getHeight();
             viewport.setRect(origin.getX(), origin.getY(), w, h);
@@ -208,6 +212,16 @@ public class HemfWindowing {
         public HemfRecordType getGenericRecordType() {
             return getEmfRecordType();
         }
+
+        @Override
+        public void calcBounds(RenderBounds holder) {
+            Rectangle2D b = holder.getBounds();
+            if (b.isEmpty()) {
+                b.setRect(bounds);
+            } else {
+                b.add(bounds);
+            }
+        }
     }
 
     /**
@@ -231,7 +245,8 @@ public class HemfWindowing {
         }
 
         @Override
-        public void calcBounds(Rectangle2D window, Rectangle2D viewport, HemfGraphics.EmfRenderState[] renderState) {
+        public void calcBounds(RenderBounds holder) {
+            Rectangle2D viewport = holder.getViewport();
             double x = viewport.getX();
             double y = viewport.getY();
             double w = viewport.getWidth();
@@ -262,7 +277,8 @@ public class HemfWindowing {
         }
 
         @Override
-        public void calcBounds(Rectangle2D window, Rectangle2D viewport, HemfGraphics.EmfRenderState[] renderState) {
+        public void calcBounds(RenderBounds holder) {
+            Rectangle2D window = holder.getWindow();
             double x = window.getX();
             double y = window.getY();
             double w = window.getWidth();

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusHeader.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusHeader.java?rev=1894176&r1=1894175&r2=1894176&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusHeader.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusHeader.java Tue Oct 12 22:30:30 2021
@@ -20,7 +20,6 @@ package org.apache.poi.hemf.record.emfpl
 
 import static org.apache.poi.util.GenericRecordUtil.getEnumBitsAsString;
 
-import java.awt.geom.Rectangle2D;
 import java.io.IOException;
 import java.util.Map;
 import java.util.function.Supplier;
@@ -28,6 +27,7 @@ import java.util.function.Supplier;
 import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.hemf.draw.HemfGraphics.EmfRenderState;
+import org.apache.poi.hemf.record.emf.HemfRecord.RenderBounds;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
 import org.apache.poi.util.GenericRecordJsonWriter;
@@ -136,8 +136,8 @@ public class HemfPlusHeader implements H
     }
 
     @Override
-    public void calcBounds(Rectangle2D window, Rectangle2D viewport, EmfRenderState[] renderState) {
-        renderState[0] = EmfRenderState.EMF_DCONTEXT;
+    public void calcBounds(RenderBounds holder) {
+        holder.setState(EmfRenderState.EMF_DCONTEXT);
     }
 
     @Override

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusMisc.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusMisc.java?rev=1894176&r1=1894175&r2=1894176&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusMisc.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusMisc.java Tue Oct 12 22:30:30 2021
@@ -31,6 +31,7 @@ import java.util.function.Supplier;
 import org.apache.poi.hemf.draw.HemfDrawProperties;
 import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.hemf.record.emf.HemfFill;
+import org.apache.poi.hemf.record.emf.HemfRecord.RenderBounds;
 import org.apache.poi.hwmf.record.HwmfRegionMode;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
@@ -165,8 +166,8 @@ public class HemfPlusMisc {
         }
 
         @Override
-        public void calcBounds(Rectangle2D window, Rectangle2D viewport, HemfGraphics.EmfRenderState[] renderState) {
-            renderState[0] = HemfGraphics.EmfRenderState.EMF_DCONTEXT;
+        public void calcBounds(RenderBounds holder) {
+            holder.setState(HemfGraphics.EmfRenderState.EMF_DCONTEXT);
         }
     }
 

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusRecord.java?rev=1894176&r1=1894175&r2=1894176&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusRecord.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusRecord.java Tue Oct 12 22:30:30 2021
@@ -18,11 +18,11 @@
 package org.apache.poi.hemf.record.emfplus;
 
 
-import java.awt.geom.Rectangle2D;
 import java.io.IOException;
 
 import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.hemf.draw.HemfGraphics;
+import org.apache.poi.hemf.record.emf.HemfRecord.RenderBounds;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndianInputStream;
 
@@ -56,7 +56,7 @@ public interface HemfPlusRecord extends
     default void draw(HemfGraphics ctx) {
     }
 
-    default void calcBounds(Rectangle2D window, Rectangle2D viewport, HemfGraphics.EmfRenderState[] renderState) {
+    default void calcBounds(RenderBounds holder) {
     }
 
     @Override

Modified: poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/usermodel/HemfPicture.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/usermodel/HemfPicture.java?rev=1894176&r1=1894175&r2=1894176&view=diff
==============================================================================
--- poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/usermodel/HemfPicture.java (original)
+++ poi/trunk/poi-scratchpad/src/main/java/org/apache/poi/hemf/usermodel/HemfPicture.java Tue Oct 12 22:30:30 2021
@@ -19,6 +19,7 @@ package org.apache.poi.hemf.usermodel;
 
 
 import static java.lang.Math.abs;
+import static java.util.Comparator.comparingDouble;
 import static org.apache.poi.hemf.draw.HemfGraphics.EmfRenderState.EMFPLUS_ONLY;
 import static org.apache.poi.hemf.draw.HemfGraphics.EmfRenderState.EMF_ONLY;
 
@@ -36,12 +37,14 @@ import java.util.Map;
 import java.util.Spliterator;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
+import java.util.stream.Stream;
 
 import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.hemf.record.emf.HemfComment;
 import org.apache.poi.hemf.record.emf.HemfHeader;
 import org.apache.poi.hemf.record.emf.HemfRecord;
+import org.apache.poi.hemf.record.emf.HemfRecord.RenderBounds;
 import org.apache.poi.hemf.record.emf.HemfRecordIterator;
 import org.apache.poi.hwmf.usermodel.HwmfCharsetAware;
 import org.apache.poi.hwmf.usermodel.HwmfEmbedded;
@@ -125,7 +128,7 @@ public class HemfPicture implements Iter
         boolean isInvalid = ReluctantRectangle2D.isEmpty(dim);
         if (isInvalid) {
             Rectangle2D lastDim = new ReluctantRectangle2D();
-            getInnerBounds(lastDim, new ReluctantRectangle2D());
+            getInnerBounds(lastDim, new Rectangle2D.Double(), new Rectangle2D.Double());
             if (!lastDim.isEmpty()) {
                 return lastDim;
             }
@@ -133,24 +136,52 @@ public class HemfPicture implements Iter
         return dim;
     }
 
-    public void getInnerBounds(Rectangle2D window, Rectangle2D viewport) {
-        HemfGraphics.EmfRenderState[] renderState = { HemfGraphics.EmfRenderState.INITIAL };
+    public void getInnerBounds(Rectangle2D window, Rectangle2D viewport, Rectangle2D bounds) {
+        RenderBounds holder = new RenderBounds() {
+            private HemfGraphics.EmfRenderState state = HemfGraphics.EmfRenderState.INITIAL;
+
+            @Override
+            public HemfGraphics.EmfRenderState getState() {
+                return state;
+            }
+
+            @Override
+            public void setState(HemfGraphics.EmfRenderState state) {
+                this.state = state;
+            }
+
+            @Override
+            public Rectangle2D getWindow() {
+                return window;
+            }
+
+            @Override
+            public Rectangle2D getViewport() {
+                return viewport;
+            }
+
+            @Override
+            public Rectangle2D getBounds() {
+                return bounds;
+            }
+        };
+
         for (HemfRecord r : getRecords()) {
             if (
-                (renderState[0] == EMF_ONLY && r instanceof HemfComment.EmfComment) ||
-                (renderState[0] == EMFPLUS_ONLY && !(r instanceof HemfComment.EmfComment))
+                (holder.getState() == EMF_ONLY && r instanceof HemfComment.EmfComment) ||
+                (holder.getState() == EMFPLUS_ONLY && !(r instanceof HemfComment.EmfComment))
             ) {
                 continue;
             }
 
             try {
-                r.calcBounds(window, viewport, renderState);
+                r.calcBounds(holder);
             } catch (RuntimeException ignored) {
             }
 
-            if (!window.isEmpty() && !viewport.isEmpty()) {
-                break;
-            }
+//            if (!window.isEmpty() && !viewport.isEmpty()) {
+//                break;
+//            }
         }
     }
 
@@ -179,20 +210,30 @@ public class HemfPicture implements Iter
             Rectangle2D emfBounds = getHeader().getBoundsRectangle();
             Rectangle2D winBounds = new ReluctantRectangle2D();
             Rectangle2D viewBounds = new ReluctantRectangle2D();
-            getInnerBounds(winBounds, viewBounds);
+            Rectangle2D recBounds = new Rectangle2D.Double();
+            getInnerBounds(winBounds, viewBounds, recBounds);
 
             Boolean forceHeader = (Boolean)ctx.getRenderingHint(Drawable.EMF_FORCE_HEADER_BOUNDS);
             if (forceHeader == null) {
                 forceHeader = false;
             }
-            // this is a compromise ... sometimes winBounds are totally off :(
-            // but mostly they fit better than the header bounds
-            Rectangle2D b =
-                !viewBounds.isEmpty() && !forceHeader
-                ? viewBounds
-                : !winBounds.isEmpty() && !forceHeader
-                ? winBounds
-                : emfBounds;
+
+            Rectangle2D b;
+            if (forceHeader) {
+                b = emfBounds;
+            } else if (recBounds.isEmpty()) {
+                // this is a compromise ... sometimes winBounds are totally off :(
+                // but mostly they fit better than the header bounds
+                b = !viewBounds.isEmpty()
+                        ? viewBounds
+                        : !winBounds.isEmpty()
+                        ? winBounds
+                        : emfBounds;
+            } else {
+                double recHyp = dia(recBounds);
+                b = Stream.of(emfBounds, winBounds, viewBounds).
+                    min(comparingDouble(r -> abs(dia(r) - recHyp))).get();
+            }
 
             ctx.translate(graphicsBounds.getCenterX(), graphicsBounds.getCenterY());
             ctx.scale(
@@ -217,6 +258,10 @@ public class HemfPicture implements Iter
         }
     }
 
+    private static double dia(Rectangle2D bounds) {
+        return Math.sqrt(bounds.getWidth()*bounds.getWidth() + bounds.getHeight()*bounds.getWidth());
+    }
+
     public Iterable<HwmfEmbedded> getEmbeddings() {
         return () -> new HemfEmbeddedIterator(HemfPicture.this);
     }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org