aboutsummaryrefslogtreecommitdiffstats
path: root/poi-scratchpad
diff options
context:
space:
mode:
authorAndreas Beeker <kiwiwings@apache.org>2021-10-12 22:30:30 +0000
committerAndreas Beeker <kiwiwings@apache.org>2021-10-12 22:30:30 +0000
commit24b3dac0c0422bae6ffde7b9d91e939e78e339a5 (patch)
tree60e34a752f21320caccb04d87af8f26dd2075159 /poi-scratchpad
parent91d502732b7e441d2af63120f3ac23e4b71a4b64 (diff)
downloadpoi-24b3dac0c0422bae6ffde7b9d91e939e78e339a5.tar.gz
poi-24b3dac0c0422bae6ffde7b9d91e939e78e339a5.zip
#64716 - wmf display error
add anothger heuristic - cumulate the bounding box of the shape records and compare it to window, viewport and emfbounds git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1894176 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'poi-scratchpad')
-rw-r--r--poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfComment.java19
-rw-r--r--poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfDraw.java78
-rw-r--r--poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfRecord.java11
-rw-r--r--poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfWindowing.java28
-rw-r--r--poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusHeader.java6
-rw-r--r--poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusMisc.java5
-rw-r--r--poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusRecord.java4
-rw-r--r--poi-scratchpad/src/main/java/org/apache/poi/hemf/usermodel/HemfPicture.java81
8 files changed, 191 insertions, 41 deletions
diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfComment.java b/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfComment.java
index 443a7ee4de..69b489927d 100644
--- a/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfComment.java
+++ b/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfComment.java
@@ -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.LittleEndianInputStream;
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;
}
}
diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfDraw.java b/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfDraw.java
index 02366a5b8d..5918158564 100644
--- a/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfDraw.java
+++ b/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfDraw.java
@@ -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);
+ }
+ }
}
diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfRecord.java b/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfRecord.java
index fe6a6ccf68..613b1f028e 100644
--- a/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfRecord.java
+++ b/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfRecord.java
@@ -57,7 +57,16 @@ public interface HemfRecord extends GenericRecord {
}
}
- 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) {
}
/**
diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfWindowing.java b/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfWindowing.java
index 46e28209f8..156d1d2a0a 100644
--- a/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfWindowing.java
+++ b/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emf/HemfWindowing.java
@@ -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();
diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusHeader.java b/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusHeader.java
index a271e77de1..32215fd81e 100644
--- a/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusHeader.java
+++ b/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusHeader.java
@@ -20,7 +20,6 @@ package org.apache.poi.hemf.record.emfplus;
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 HemfPlusRecord {
}
@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
diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusMisc.java b/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusMisc.java
index eaaf0a88f1..eee3d40bb1 100644
--- a/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusMisc.java
+++ b/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusMisc.java
@@ -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);
}
}
diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusRecord.java b/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusRecord.java
index 99210ad7ab..6b943a43d6 100644
--- a/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusRecord.java
+++ b/poi-scratchpad/src/main/java/org/apache/poi/hemf/record/emfplus/HemfPlusRecord.java
@@ -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 GenericRecord {
default void draw(HemfGraphics ctx) {
}
- default void calcBounds(Rectangle2D window, Rectangle2D viewport, HemfGraphics.EmfRenderState[] renderState) {
+ default void calcBounds(RenderBounds holder) {
}
@Override
diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hemf/usermodel/HemfPicture.java b/poi-scratchpad/src/main/java/org/apache/poi/hemf/usermodel/HemfPicture.java
index 6f52414e42..1e81d1be84 100644
--- a/poi-scratchpad/src/main/java/org/apache/poi/hemf/usermodel/HemfPicture.java
+++ b/poi-scratchpad/src/main/java/org/apache/poi/hemf/usermodel/HemfPicture.java
@@ -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 Iterable<HemfRecord>, GenericRecord {
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 Iterable<HemfRecord>, GenericRecord {
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 Iterable<HemfRecord>, GenericRecord {
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 Iterable<HemfRecord>, GenericRecord {
}
}
+ 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);
}