mirror of
https://github.com/apache/poi.git
synced 2026-02-27 20:40:08 +08:00
#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
This commit is contained in:
parent
91d502732b
commit
24b3dac0c0
@ -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}");
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user