aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas Beeker <kiwiwings@apache.org>2018-09-24 23:55:52 +0000
committerAndreas Beeker <kiwiwings@apache.org>2018-09-24 23:55:52 +0000
commitb3fc9f49572cb79ffa25f82d45987adb33b09e93 (patch)
tree0f1686a9903852e887395a5aad32e077be7c46cf /src
parent5073f22fce96dcc74529baaa8ee6e7e3c732ee56 (diff)
downloadpoi-b3fc9f49572cb79ffa25f82d45987adb33b09e93.tar.gz
poi-b3fc9f49572cb79ffa25f82d45987adb33b09e93.zip
#60656 - Support export file that contains emf and render it correctly
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/hemf@1841897 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/java/org/apache/poi/sl/draw/DrawPictureShape.java39
-rw-r--r--src/resources/main/META-INF/services/org.apache.poi.sl.draw.ImageRenderer1
-rw-r--r--src/resources/scratchpad/META-INF/services/org.apache.poi.sl.draw.ImageRenderer2
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/draw/HemfDrawProperties.java22
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java58
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java11
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java86
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java3
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java44
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfPalette.java16
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java6
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java48
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java4
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/record/HwmfColorRef.java5
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java56
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java33
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java25
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java13
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java27
-rw-r--r--src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java15
20 files changed, 396 insertions, 118 deletions
diff --git a/src/java/org/apache/poi/sl/draw/DrawPictureShape.java b/src/java/org/apache/poi/sl/draw/DrawPictureShape.java
index 5c42d6fd13..3ccbc9f219 100644
--- a/src/java/org/apache/poi/sl/draw/DrawPictureShape.java
+++ b/src/java/org/apache/poi/sl/draw/DrawPictureShape.java
@@ -33,7 +33,10 @@ import org.apache.poi.util.POILogger;
public class DrawPictureShape extends DrawSimpleShape {
private static final POILogger LOG = POILogFactory.getLogger(DrawPictureShape.class);
- private static final ServiceLoader<ImageRenderer> rendererLoader = ServiceLoader.load(ImageRenderer.class);
+ private static final String[] KNOWN_RENDERER = {
+ "org.apache.poi.hwmf.draw.HwmfImageRenderer",
+ "org.apache.poi.hemf.draw.HemfImageRenderer"
+ };
public DrawPictureShape(PictureShape<?,?> shape) {
super(shape);
@@ -62,24 +65,44 @@ public class DrawPictureShape extends DrawSimpleShape {
* @param graphics the graphics context
* @return the image renderer
*/
- @SuppressWarnings("WeakerAccess")
+ @SuppressWarnings({"WeakerAccess", "unchecked"})
public static ImageRenderer getImageRenderer(Graphics2D graphics, String contentType) {
- ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER);
- if (renderer != null) {
+ final ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER);
+ if (renderer != null && renderer.canRender(contentType)) {
return renderer;
}
- for (ImageRenderer ir : rendererLoader) {
+ // first try with our default image renderer
+ final BitmapImageRenderer bir = new BitmapImageRenderer();
+ if (bir.canRender(contentType)) {
+ return bir;
+ }
+
+ // then iterate through the scratchpad renderers
+ //
+ // this could be nicely implemented via a j.u.ServiceLoader, but OSGi makes things complicated ...
+ // https://blog.osgi.org/2013/02/javautilserviceloader-in-osgi.html
+ // ... therefore falling back to classloading attempts
+ ClassLoader cl = ImageRenderer.class.getClassLoader();
+ for (String kr : KNOWN_RENDERER) {
+ final ImageRenderer ir;
+ try {
+ ir = ((Class<? extends ImageRenderer>)cl.loadClass(kr)).newInstance();
+ } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
+ // scratchpad was not on the path, ignore and continue
+ LOG.log(POILogger.INFO, "Known image renderer '"+kr+" not found/loaded - include poi-scratchpad jar!", e);
+ continue;
+ }
if (ir.canRender(contentType)) {
return ir;
}
}
- LOG.log(POILogger.ERROR, "No suiteable image renderer found for content-type '"+
+ LOG.log(POILogger.WARN, "No suiteable image renderer found for content-type '"+
contentType+"' - include poi-scratchpad jar!");
- // falling back to BitmapImageRenderer although this doesn't make much sense ...
- return new BitmapImageRenderer();
+ // falling back to BitmapImageRenderer, at least it gracefully handles invalid images
+ return bir;
}
@Override
diff --git a/src/resources/main/META-INF/services/org.apache.poi.sl.draw.ImageRenderer b/src/resources/main/META-INF/services/org.apache.poi.sl.draw.ImageRenderer
deleted file mode 100644
index 1e7699fe57..0000000000
--- a/src/resources/main/META-INF/services/org.apache.poi.sl.draw.ImageRenderer
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.poi.sl.draw.BitmapImageRenderer \ No newline at end of file
diff --git a/src/resources/scratchpad/META-INF/services/org.apache.poi.sl.draw.ImageRenderer b/src/resources/scratchpad/META-INF/services/org.apache.poi.sl.draw.ImageRenderer
deleted file mode 100644
index b23f654157..0000000000
--- a/src/resources/scratchpad/META-INF/services/org.apache.poi.sl.draw.ImageRenderer
+++ /dev/null
@@ -1,2 +0,0 @@
-org.apache.poi.hwmf.draw.HwmfImageRenderer
-org.apache.poi.hemf.draw.HemfImageRenderer \ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hemf/draw/HemfDrawProperties.java b/src/scratchpad/src/org/apache/poi/hemf/draw/HemfDrawProperties.java
index 8bb8af33bf..b12a4caa6c 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/draw/HemfDrawProperties.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/draw/HemfDrawProperties.java
@@ -24,16 +24,15 @@ import org.apache.poi.hwmf.draw.HwmfDrawProperties;
public class HemfDrawProperties extends HwmfDrawProperties {
/** Path for path bracket operations */
- protected final Path2D path;
+ protected Path2D path = null;
public HemfDrawProperties() {
- path = new Path2D.Double();
}
public HemfDrawProperties(HemfDrawProperties other) {
super(other);
- path = (Path2D)other.path.clone();
+ path = (other.path != null) ? (Path2D)other.path.clone() : null;
}
/**
@@ -42,4 +41,21 @@ public class HemfDrawProperties extends HwmfDrawProperties {
public Path2D getPath() {
return path;
}
+
+ /**
+ * Un-/Sets the bracket path
+ * @param path the bracket path
+ */
+ public void setPath(Path2D path) {
+ this.path = path;
+ }
+
+ /**
+ * Use path (bracket) or graphics context for drawing operations
+ * @return {@code true}, if the drawing should go to the path bracket,
+ * if {@code false} draw directly to the graphics context
+ */
+ public boolean usePathBracket() {
+ return path != null;
+ }
}
diff --git a/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java b/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java
index 05701ef823..c4783950a6 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java
@@ -19,13 +19,18 @@ package org.apache.poi.hemf.draw;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
+import java.awt.geom.Path2D;
+import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayDeque;
import java.util.Deque;
+import java.util.function.Consumer;
import org.apache.poi.hemf.record.emf.HemfBounded;
import org.apache.poi.hemf.record.emf.HemfRecord;
import org.apache.poi.hwmf.draw.HwmfGraphics;
+import org.apache.poi.hwmf.record.HwmfObjectTableEntry;
+import org.apache.poi.util.Internal;
public class HemfGraphics extends HwmfGraphics {
@@ -80,6 +85,59 @@ public class HemfGraphics extends HwmfGraphics {
}
}
+ @Internal
+ public void draw(Consumer<Path2D> pathConsumer) {
+ final HemfDrawProperties prop = getProperties();
+ final boolean useBracket = prop.usePathBracket();
+
+ final Path2D path;
+ if (useBracket) {
+ path = prop.getPath();
+ } else {
+ path = new Path2D.Double();
+ Point2D pnt = prop.getLocation();
+ path.moveTo(pnt.getX(),pnt.getY());
+ }
+
+ pathConsumer.accept(path);
+
+ prop.setLocation(path.getCurrentPoint());
+ if (!useBracket) {
+ // TODO: when to use draw vs. fill?
+ graphicsCtx.draw(path);
+ }
+
+ }
+
+ /**
+ * Adds or sets an record of type {@link HwmfObjectTableEntry} to the object table.
+ * If the {@code index} is less than 1, the method acts the same as
+ * {@link HwmfGraphics#addObjectTableEntry(HwmfObjectTableEntry)}, otherwise the
+ * index is used to access the object table.
+ * As the table is filled successively, the index must be between 1 and size+1
+ *
+ * @param entry the record to be stored
+ * @param index the index to be overwritten, regardless if its content was unset before
+ *
+ * @see HwmfGraphics#addObjectTableEntry(HwmfObjectTableEntry)
+ */
+ public void addObjectTableEntry(HwmfObjectTableEntry entry, int index) {
+ if (index < 1) {
+ super.addObjectTableEntry(entry);
+ return;
+ }
+
+ if (index > objectTable.size()) {
+ throw new IllegalStateException("object table hasn't grown to this index yet");
+ }
+
+ if (index == objectTable.size()) {
+ objectTable.add(entry);
+ } else {
+ objectTable.set(index, entry);
+ }
+ }
+
/** saves the current affine transform on the stack */
private void saveTransform() {
diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java
index 0a459e3cd0..fe098f2794 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java
@@ -32,6 +32,7 @@ import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.LittleEndianInputStream;
+import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.RecordFormatException;
/**
@@ -97,6 +98,11 @@ public class HemfComment {
public EmfCommentData getCommentData() {
return data;
}
+
+ @Override
+ public String toString() {
+ return "{ data: "+data+" }";
+ }
}
public static class EmfCommentDataIterator implements Iterator<EmfCommentData> {
@@ -208,6 +214,11 @@ public class HemfComment {
leis.readFully(privateData);
return privateData.length;
}
+
+ @Override
+ public String toString() {
+ return "\""+new String(privateData, LocaleUtil.CHARSET_1252)+"\"";
+ }
}
/** The EMR_COMMENT_EMFPLUS record contains embedded EMF+ records. */
diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java
index c2cc9c3de2..f9c6e975a2 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java
@@ -53,6 +53,28 @@ public class HemfDraw {
private static final HwmfColorRef DKGRAY = new HwmfColorRef(new Color(0x00404040));
private static final HwmfColorRef BLACK = new HwmfColorRef(Color.BLACK);
+ private static final String[] STOCK_IDS = {
+ "0x80000000 /* WHITE_BRUSH */",
+ "0x80000001 /* LTGRAY_BRUSH */",
+ "0x80000002 /* GRAY_BRUSH */",
+ "0x80000003 /* DKGRAY_BRUSH */",
+ "0x80000004 /* BLACK_BRUSH */",
+ "0x80000005 /* NULL_BRUSH */",
+ "0x80000006 /* WHITE_PEN */",
+ "0x80000007 /* BLACK_PEN */",
+ "0x80000008 /* NULL_PEN */",
+ "0x8000000A /* OEM_FIXED_FONT */",
+ "0x8000000B /* ANSI_FIXED_FONT */",
+ "0x8000000C /* ANSI_VAR_FONT */",
+ "0x8000000D /* SYSTEM_FONT */",
+ "0x8000000E /* DEVICE_DEFAULT_FONT */",
+ "0x8000000F /* DEFAULT_PALETTE */",
+ "0x80000010 /* SYSTEM_FIXED_FONT */",
+ "0x80000011 /* DEFAULT_GUI_FONT */",
+ "0x80000012 /* DC_BRUSH */",
+ "0x80000013 /* DC_PEN */"
+ };
+
@Override
public HemfRecordType getEmfRecordType() {
return HemfRecordType.selectObject;
@@ -184,6 +206,14 @@ public class HemfDraw {
}
}
+ @Override
+ public String toString() {
+ return "{ index: "+
+ (((objectIndex & 0x80000000) != 0 && (objectIndex & 0x3FFFFFFF) <= 13 )
+ ? STOCK_IDS[objectIndex & 0x3FFFFFFF]
+ : objectIndex)+" }";
+ }
+
}
@@ -220,7 +250,7 @@ public class HemfDraw {
final int points = Math.min(count, 16384);
size += LittleEndianConsts.INT_SIZE;
- poly.reset();
+ poly = new Path2D.Double(Path2D.WIND_EVEN_ODD, points);
/* Cubic Bezier curves are defined using the endpoints and control points
* specified by the points field. The first curve is drawn from the first
@@ -324,6 +354,8 @@ public class HemfDraw {
final int points = Math.min(count, 16384);
size += LittleEndianConsts.INT_SIZE;
+ poly = new Path2D.Double(Path2D.WIND_EVEN_ODD, points);
+
Point2D pnt = new Point2D.Double();
for (int i=0; i<points; i++) {
size += readPoint(leis, pnt);
@@ -541,7 +573,7 @@ public class HemfDraw {
* An array of WMF PointL objects that specifies the points for all polygons in logical units.
* The number of points is specified by the Count field value.
*/
- Path2D poly = new Path2D.Double();
+ Path2D poly = new Path2D.Double(Path2D.WIND_EVEN_ODD, (int)nPoints);
for (int i=0; i<nPoints; i++) {
size += readPoint(leis, pnt);
if (i == 0) {
@@ -659,11 +691,8 @@ public class HemfDraw {
}
@Override
- public void draw(HemfGraphics ctx) {
- HemfDrawProperties prop = ctx.getProperties();
- final Path2D path = prop.getPath();
- path.moveTo(point.getX(), point.getY());
- prop.setLocation(point);
+ public void draw(final HemfGraphics ctx) {
+ ctx.draw((path) -> path.moveTo(point.getX(), point.getY()));
}
}
@@ -802,11 +831,8 @@ public class HemfDraw {
}
@Override
- public void draw(HemfGraphics ctx) {
- final HemfDrawProperties prop = ctx.getProperties();
- final Path2D path = prop.getPath();
- path.lineTo(point.getX(), point.getY());
- prop.setLocation(point);
+ public void draw(final HemfGraphics ctx) {
+ ctx.draw((path) -> path.lineTo(point.getX(), point.getY()));
}
}
@@ -829,11 +855,9 @@ public class HemfDraw {
}
@Override
- public void draw(HemfGraphics ctx) {
- final Path2D path = ctx.getProperties().getPath();
- Arc2D arc = getShape();
- path.append(arc, true);
- ctx.getProperties().setLocation(endPoint);
+ public void draw(final HemfGraphics ctx) {
+ final Arc2D arc = getShape();
+ ctx.draw((path) -> path.append(arc, true));
}
}
@@ -860,7 +884,7 @@ public class HemfDraw {
size += readPoint(leis, points[i]);
}
- poly.reset();
+ poly = new Path2D.Double(Path2D.WIND_EVEN_ODD, count);
for (int i=0; i<count; i++) {
int mode = leis.readUByte();
@@ -958,8 +982,7 @@ public class HemfDraw {
@Override
public void draw(HemfGraphics ctx) {
final HemfDrawProperties prop = ctx.getProperties();
- final Path2D path = prop.getPath();
- path.reset();
+ prop.setPath(new Path2D.Double());
}
}
@@ -996,8 +1019,7 @@ public class HemfDraw {
@Override
public void draw(HemfGraphics ctx) {
final HemfDrawProperties prop = ctx.getProperties();
- final Path2D path = prop.getPath();
- path.reset();
+ prop.setPath(null);
}
}
@@ -1036,8 +1058,10 @@ public class HemfDraw {
public void draw(HemfGraphics ctx) {
final HemfDrawProperties prop = ctx.getProperties();
final Path2D path = prop.getPath();
- path.closePath();
- prop.setLocation(path.getCurrentPoint());
+ if (path != null) {
+ path.closePath();
+ prop.setLocation(path.getCurrentPoint());
+ }
}
}
@@ -1140,16 +1164,12 @@ public class HemfDraw {
return 2*LittleEndianConsts.INT_SIZE;
}
- private static void polyTo(HemfGraphics ctx, Path2D poly) {
- final HemfDrawProperties prop = ctx.getProperties();
- final Path2D path = prop.getPath();
- PathIterator pi = poly.getPathIterator(null);
+ private static void polyTo(final HemfGraphics ctx, final Path2D poly) {
+ final PathIterator pi = poly.getPathIterator(null);
// ignore dummy start point (moveTo)
pi.next();
- assert(!pi.isDone());
- path.append(pi, true);
- prop.setLocation(path.getCurrentPoint());
- }
-
+ assert (!pi.isDone());
+ ctx.draw((path) -> path.append(pi, true));
+ }
}
diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java
index e28a355f0c..5dca14537f 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java
@@ -655,6 +655,9 @@ public class HemfFill {
@Override
public void draw(HemfGraphics ctx) {
final HemfDrawProperties prop = ctx.getProperties();
+ if (!prop.usePathBracket()) {
+ return;
+ }
final Path2D path = (Path2D)prop.getPath().clone();
path.setWindingRule(ctx.getProperties().getWindingRule());
if (prop.getBrushStyle() == HwmfBrushStyle.BS_NULL) {
diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java
index f3424d08d0..291c83d630 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java
@@ -98,7 +98,7 @@ public class HemfMisc {
/**
* The EMF_SAVEDC record saves the playback device context for later retrieval.
*/
- public static class EmfSaveDc implements HemfRecord {
+ public static class EmfSaveDc extends HwmfMisc.WmfSaveDc implements HemfRecord {
@Override
public HemfRecordType getEmfRecordType() {
return HemfRecordType.saveDc;
@@ -108,25 +108,13 @@ public class HemfMisc {
public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
return 0;
}
-
- @Override
- public void draw(HemfGraphics ctx) {
- ctx.saveProperties();
- }
}
/**
* The EMF_RESTOREDC record restores the playback device context from a previously saved device
* context.
*/
- public static class EmfRestoreDc implements HemfRecord {
-
- /**
- * SavedDC (4 bytes): A 32-bit signed integer that specifies the saved state to restore relative to
- * the current state. This value MUST be negative; –1 represents the state that was most
- * recently saved on the stack, –2 the one before that, etc.
- */
- private int nSavedDC;
+ public static class EmfRestoreDc extends HwmfMisc.WmfRestoreDc implements HemfRecord {
@Override
public HemfRecordType getEmfRecordType() {
@@ -135,23 +123,19 @@ public class HemfMisc {
@Override
public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
+ // A 32-bit signed integer that specifies the saved state to restore relative to
+ // the current state. This value MUST be negative; –1 represents the state that was most
+ // recently saved on the stack, –2 the one before that, etc.
nSavedDC = leis.readInt();
return LittleEndianConsts.INT_SIZE;
}
-
- @Override
- public void draw(HemfGraphics ctx) {
- ctx.restoreProperties(nSavedDC);
- }
}
/**
* The META_SETBKCOLOR record sets the background color in the playback device context to a
* specified color, or to the nearest physical color if the device cannot represent the specified color.
*/
- public static class EmfSetBkColor implements HemfRecord {
-
- private HwmfColorRef colorRef;
+ public static class EmfSetBkColor extends HwmfMisc.WmfSetBkColor implements HemfRecord {
@Override
public HemfRecordType getEmfRecordType() {
@@ -160,14 +144,8 @@ public class HemfMisc {
@Override
public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
- colorRef = new HwmfColorRef();
return colorRef.init(leis);
}
-
- @Override
- public void draw(HemfGraphics ctx) {
- ctx.getProperties().setBackgroundColor(colorRef);
- }
}
@@ -287,8 +265,13 @@ public class HemfMisc {
int size = colorRef.init(leis);
brushHatch = HwmfHatchStyle.valueOf((int) leis.readUInt());
return size + 3 * LittleEndianConsts.INT_SIZE;
+ }
+ @Override
+ public void draw(HemfGraphics ctx) {
+ ctx.addObjectTableEntry(this, brushIdx);
}
+
}
/**
@@ -341,6 +324,11 @@ public class HemfMisc {
return size + 4 * LittleEndianConsts.INT_SIZE;
}
+
+ @Override
+ public void draw(HemfGraphics ctx) {
+ ctx.addObjectTableEntry(this, penIndex);
+ }
}
public static class EmfExtCreatePen extends EmfCreatePen {
diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfPalette.java b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfPalette.java
index b9a909991e..9811cb2c3d 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfPalette.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfPalette.java
@@ -19,6 +19,7 @@ package org.apache.poi.hemf.record.emf;
import java.io.IOException;
+import org.apache.poi.hemf.draw.HemfGraphics;
import org.apache.poi.hwmf.record.HwmfPalette;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.LittleEndianInputStream;
@@ -67,6 +68,11 @@ public class HemfPalette {
int size = readPaletteEntries(leis, -1);
return size + LittleEndianConsts.INT_SIZE + LittleEndianConsts.SHORT_SIZE;
}
+
+ @Override
+ public void draw(HemfGraphics ctx) {
+ ctx.addObjectTableEntry(this, paletteIndex);
+ }
}
/**
@@ -93,6 +99,11 @@ public class HemfPalette {
int size = readPaletteEntries(leis, nbrOfEntries);
return size + 3*LittleEndianConsts.INT_SIZE;
}
+
+ @Override
+ public void draw(HemfGraphics ctx) {
+ ctx.addObjectTableEntry(this, paletteIndex);
+ }
}
/**
@@ -118,6 +129,11 @@ public class HemfPalette {
return 2*LittleEndianConsts.INT_SIZE;
}
+
+ @Override
+ public void draw(HemfGraphics ctx) {
+ ctx.addObjectTableEntry(this, paletteIndex);
+ }
}
/**
diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java
index 6c858ccc53..f6584443a1 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java
@@ -47,7 +47,7 @@ public enum HemfRecordType {
setStretchBltMode(0x00000015, HemfMisc.EmfSetStretchBltMode::new),
setTextAlign(0x00000016, HemfText.EmfSetTextAlign::new),
setcoloradjustment(0x00000017, UnimplementedHemfRecord::new),
- setTextColor(0x00000018, HemfText.SetTextColor::new),
+ setTextColor(0x00000018, HemfText.EmfSetTextColor::new),
setBkColor(0x00000019, HemfMisc.EmfSetBkColor::new),
setOffsetClipRgn(0x0000001A, HemfWindowing.EmfSetOffsetClipRgn::new),
setMoveToEx(0x0000001B, HemfDraw.EmfSetMoveToEx::new),
@@ -106,8 +106,8 @@ public enum HemfRecordType {
setDiBitsToDevice(0x00000050, HemfFill.EmfSetDiBitsToDevice::new),
stretchdibits(0x00000051, UnimplementedHemfRecord::new),
extCreateFontIndirectW(0x00000052, HemfText.ExtCreateFontIndirectW::new),
- exttextouta(0x00000053, HemfText.ExtTextOutA::new),
- exttextoutw(0x00000054, HemfText.ExtTextOutW::new),
+ exttextouta(0x00000053, HemfText.EmfExtTextOutA::new),
+ exttextoutw(0x00000054, HemfText.EmfExtTextOutW::new),
polyBezier16(0x00000055, HemfDraw.EmfPolyBezier16::new),
polygon16(0x00000056, HemfDraw.EmfPolygon16::new),
polyline16(0x00000057, HemfDraw.EmfPolyline16::new),
diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java
index 95c110df10..2305aeced8 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java
@@ -29,7 +29,7 @@ import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
-import org.apache.poi.hwmf.record.HwmfColorRef;
+import org.apache.poi.hemf.draw.HemfGraphics;
import org.apache.poi.hwmf.record.HwmfText;
import org.apache.poi.hwmf.record.HwmfText.WmfSetTextAlign;
import org.apache.poi.util.Dimension2DDouble;
@@ -53,9 +53,9 @@ public class HemfText {
GM_COMPATIBLE, GM_ADVANCED
}
- public static class ExtTextOutA implements HemfRecord {
+ public static class EmfExtTextOutA implements HemfRecord {
- protected final Rectangle2D boundsIgnored = new Rectangle2D.Double();
+ protected final Rectangle2D bounds = new Rectangle2D.Double();
protected EmfGraphicsMode graphicsMode;
@@ -67,11 +67,11 @@ public class HemfText {
protected final EmrTextObject textObject;
- public ExtTextOutA() {
+ public EmfExtTextOutA() {
this(false);
}
- protected ExtTextOutA(boolean isUnicode) {
+ protected EmfExtTextOutA(boolean isUnicode) {
textObject = new EmrTextObject(isUnicode);
}
@@ -87,7 +87,7 @@ public class HemfText {
}
// A WMF RectL object. It is not used and MUST be ignored on receipt.
- long size = readRectL(leis, boundsIgnored);
+ long size = readRectL(leis, bounds);
// A 32-bit unsigned integer that specifies the graphics mode from the GraphicsMode enumeration
graphicsMode = EmfGraphicsMode.values()[leis.readInt()-1];
@@ -104,10 +104,10 @@ public class HemfText {
/**
*
* To be implemented! We need to get the current character set
- * from the current font for {@link ExtTextOutA},
+ * from the current font for {@link EmfExtTextOutA},
* which has to be tracked in the playback device.
*
- * For {@link ExtTextOutW}, the charset is "UTF-16LE"
+ * For {@link EmfExtTextOutW}, the charset is "UTF-16LE"
*
* @param charset the charset to be used to decode the character bytes
* @return text from this text element
@@ -132,11 +132,24 @@ public class HemfText {
public Dimension2D getScale() {
return scale;
}
+
+ @Override
+ public String toString() {
+ return
+ "{ bounds: { x: "+bounds.getX()+
+ ", y: "+bounds.getY()+
+ ", w: "+bounds.getWidth()+
+ ", h: "+bounds.getHeight()+
+ "}, graphicsMode: '"+graphicsMode+"'"+
+ ", scale: { w: "+scale.getWidth()+", h: "+scale.getHeight()+" }"+
+ ", textObject: "+textObject+
+ "}";
+ }
}
- public static class ExtTextOutW extends ExtTextOutA {
+ public static class EmfExtTextOutW extends EmfExtTextOutA {
- public ExtTextOutW() {
+ public EmfExtTextOutW() {
super(true);
}
@@ -175,10 +188,7 @@ public class HemfText {
/**
* The EMR_SETTEXTCOLOR record defines the current text color.
*/
- public static class SetTextColor implements HemfRecord {
- /** A WMF ColorRef object that specifies the text color value. */
- private final HwmfColorRef colorRef = new HwmfColorRef();
-
+ public static class EmfSetTextColor extends HwmfText.WmfSetTextColor implements HemfRecord {
@Override
public HemfRecordType getEmfRecordType() {
return HemfRecordType.setTextColor;
@@ -284,6 +294,16 @@ public class HemfText {
int size = font.init(leis, (int)(recordSize-LittleEndianConsts.INT_SIZE));
return size+LittleEndianConsts.INT_SIZE;
}
+
+ @Override
+ public void draw(HemfGraphics ctx) {
+ ctx.addObjectTableEntry(this, fontIdx);
+ }
+
+ @Override
+ public String toString() {
+ return "{ index: "+fontIdx+", font: "+font+" } ";
+ }
}
public static class EmfExtTextOutOptions extends HwmfText.WmfExtTextOutOptions {
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java b/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
index de348480ad..b29c1187e9 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
@@ -55,10 +55,10 @@ public class HwmfGraphics {
protected final List<HwmfDrawProperties> propStack = new LinkedList<>();
protected HwmfDrawProperties prop;
protected final Graphics2D graphicsCtx;
+ protected final List<HwmfObjectTableEntry> objectTable = new ArrayList<>();
private static final Charset DEFAULT_CHARSET = LocaleUtil.CHARSET_1252;
- private final List<HwmfObjectTableEntry> objectTable = new ArrayList<>();
- /** Bounding box from the placeable header */
+ /** Bounding box from the placeable header */
private final Rectangle2D bbox;
private final AffineTransform initialAT;
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfColorRef.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfColorRef.java
index 5b24fbc7e9..12204d61ec 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfColorRef.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfColorRef.java
@@ -69,4 +69,9 @@ public class HwmfColorRef implements Cloneable {
throw new InternalError();
}
}
+
+ @Override
+ public String toString() {
+ return String.format("%#8X", colorRef.getRGB());
+ }
}
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java
index 2f052075b5..64f2dae8c9 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java
@@ -23,6 +23,7 @@ import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
+import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
@@ -57,6 +58,11 @@ public class HwmfDraw {
public void draw(HwmfGraphics ctx) {
ctx.getProperties().setLocation(point);
}
+
+ @Override
+ public String toString() {
+ return "{ x: "+point.getX()+", y: "+point.getY()+" }";
+ }
}
/**
@@ -84,6 +90,11 @@ public class HwmfDraw {
ctx.draw(line);
ctx.getProperties().setLocation(point);
}
+
+ @Override
+ public String toString() {
+ return "{ x: "+point.getX()+", y: "+point.getY()+" }";
+ }
}
/**
@@ -93,7 +104,7 @@ public class HwmfDraw {
*/
public static class WmfPolygon implements HwmfRecord {
- protected Path2D poly = new Path2D.Double();
+ protected Path2D poly;
@Override
public HwmfRecordType getWmfRecordType() {
@@ -107,6 +118,7 @@ public class HwmfDraw {
*/
int numberofPoints = leis.readShort();
+ poly = new Path2D.Double(Path2D.WIND_EVEN_ODD, numberofPoints);
for (int i=0; i<numberofPoints; i++) {
// A 16-bit signed integer that defines the horizontal (x) coordinate of the point.
int x = leis.readShort();
@@ -134,6 +146,11 @@ public class HwmfDraw {
}
}
+ @Override
+ public String toString() {
+ return "{ poly: "+polyToString(poly)+" }";
+ }
+
/**
* @return true, if the shape should be filled
*/
@@ -279,7 +296,7 @@ public class HwmfDraw {
* An array of 16-bit signed integers that define the coordinates of the polygons.
* (Note: MS-WMF wrongly says unsigned integers ...)
*/
- Path2D poly = new Path2D.Double();
+ Path2D poly = new Path2D.Double(Path2D.WIND_EVEN_ODD, nPoints);
for (int i=0; i<nPoints; i++) {
int x = leis.readShort();
int y = leis.readShort();
@@ -556,6 +573,11 @@ public class HwmfDraw {
public void draw(HwmfGraphics ctx) {
ctx.applyObjectTableEntry(objectIndex);
}
+
+ @Override
+ public String toString() {
+ return "{ index: "+objectIndex +" }";
+ }
}
static int readBounds(LittleEndianInputStream leis, Rectangle2D bounds) {
@@ -603,4 +625,34 @@ public class HwmfDraw {
point.setLocation(x, y);
return 2*LittleEndianConsts.SHORT_SIZE;
}
+
+ static String polyToString(Path2D poly) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("[");
+ final PathIterator iter = poly.getPathIterator(null);
+ double[] pnts = new double[6];
+ while (!iter.isDone()) {
+ int segType = iter.currentSegment(pnts);
+ switch (segType) {
+ case PathIterator.SEG_MOVETO:
+ sb.append("{ type: 'move', x: "+pnts[0]+", y: "+pnts[1]+" }, ");
+ break;
+ case PathIterator.SEG_LINETO:
+ sb.append("{ type: 'lineto', x: "+pnts[0]+", y: "+pnts[1]+" }, ");
+ break;
+ case PathIterator.SEG_QUADTO:
+ sb.append("{ type: 'quad', x1: "+pnts[0]+", y1: "+pnts[1]+", x2: "+pnts[2]+", y2: "+pnts[3]+" }, ");
+ break;
+ case PathIterator.SEG_CUBICTO:
+ sb.append("{ type: 'cubic', x1: "+pnts[0]+", y1: "+pnts[1]+", x2: "+pnts[2]+", y2: "+pnts[3]+", x3: "+pnts[4]+", y3: "+pnts[5]+" }, ");
+ break;
+ case PathIterator.SEG_CLOSE:
+ sb.append("{ type: 'close' }, ");
+ break;
+ }
+ iter.next();
+ }
+ sb.append("]");
+ return sb.toString();
+ }
}
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java
index 932358740f..8cb8486771 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java
@@ -146,6 +146,20 @@ public class HwmfFont implements FontInfo {
flag = leis.readUByte();
return LittleEndianConsts.BYTE_SIZE;
}
+
+ @Override
+ public String toString() {
+ return
+ (((flag&0x3) == 0 ? "default " : " ")+
+ (CLIP_CHARACTER_PRECIS.isSet(flag) ? "char " : " ")+
+ (CLIP_STROKE_PRECIS.isSet(flag) ? "stroke " : " ")+
+ (CLIP_LH_ANGLES.isSet(flag) ? "angles " : " ")+
+ (CLIP_TT_ALWAYS.isSet(flag) ? "tt_always " : " ")+
+ (CLIP_DFA_DISABLE.isSet(flag) ? "dfa " : " ")+
+ (CLIP_EMBEDDED.isSet(flag) ? "embedded " : " ")
+ ).trim()
+ ;
+ }
}
/**
@@ -453,6 +467,25 @@ public class HwmfFont implements FontInfo {
throw new UnsupportedOperationException("setCharset not supported by HwmfFont.");
}
+ @Override
+ public String toString() {
+ return "{ height: "+height+
+ ", width: "+width+
+ ", escapment: "+escapement+
+ ", weight: "+weight+
+ ", italic: "+italic+
+ ", underline: "+underline+
+ ", strikeOut: "+strikeOut+
+ ", charset: '"+charSet+"'"+
+ ", outPrecision: '"+outPrecision+"'"+
+ ", clipPrecision: '"+clipPrecision+"'"+
+ ", qualtiy: '"+quality+"'"+
+ ", pitch: '"+getPitch()+"'"+
+ ", family: '"+getFamily()+"'"+
+ ", facename: '"+facename+"'"+
+ "}";
+ }
+
protected int readString(LittleEndianInputStream leis, StringBuilder sb, int limit) throws IOException {
byte buf[] = new byte[limit], b, readBytes = 0;
do {
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java
index 631383d6e4..b774549073 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java
@@ -49,6 +49,11 @@ public class HwmfMisc {
public void draw(HwmfGraphics ctx) {
ctx.saveProperties();
}
+
+ @Override
+ public String toString() {
+ return "{}";
+ }
}
/**
@@ -80,7 +85,7 @@ public class HwmfMisc {
* member is positive, nSavedDC represents a specific instance of the state to be restored. If
* this member is negative, nSavedDC represents an instance relative to the current state.
*/
- private int nSavedDC;
+ protected int nSavedDC;
@Override
public HwmfRecordType getWmfRecordType() {
@@ -97,6 +102,11 @@ public class HwmfMisc {
public void draw(HwmfGraphics ctx) {
ctx.restoreProperties(nSavedDC);
}
+
+ @Override
+ public String toString() {
+ return "{ nSavedDC: "+nSavedDC+" }";
+ }
}
/**
@@ -105,7 +115,7 @@ public class HwmfMisc {
*/
public static class WmfSetBkColor implements HwmfRecord {
- private HwmfColorRef colorRef;
+ protected final HwmfColorRef colorRef = new HwmfColorRef();
@Override
public HwmfRecordType getWmfRecordType() {
@@ -114,7 +124,6 @@ public class HwmfMisc {
@Override
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- colorRef = new HwmfColorRef();
return colorRef.init(leis);
}
@@ -122,6 +131,11 @@ public class HwmfMisc {
public void draw(HwmfGraphics ctx) {
ctx.getProperties().setBackgroundColor(colorRef);
}
+
+ @Override
+ public String toString() {
+ return "{ colorRef: "+colorRef+" }";
+ }
}
/**
@@ -465,6 +479,11 @@ public class HwmfMisc {
ctx.unsetObjectTableEntry(objectIndex);
}
+
+ @Override
+ public String toString() {
+ return "{ index: "+objectIndex+" }";
+ }
}
public static class WmfCreatePatternBrush implements HwmfRecord, HwmfObjectTableEntry {
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
index 787f444beb..e677f9a92f 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
@@ -82,7 +82,7 @@ public class HwmfText {
*/
public static class WmfSetTextColor implements HwmfRecord {
- private HwmfColorRef colorRef;
+ protected final HwmfColorRef colorRef = new HwmfColorRef();
@Override
public HwmfRecordType getWmfRecordType() {
@@ -91,7 +91,6 @@ public class HwmfText {
@Override
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- colorRef = new HwmfColorRef();
return colorRef.init(leis);
}
@@ -99,6 +98,11 @@ public class HwmfText {
public void draw(HwmfGraphics ctx) {
ctx.getProperties().setTextColor(colorRef);
}
+
+ @Override
+ public String toString() {
+ return "{ colorRef: "+colorRef+" }";
+ }
}
/**
@@ -645,5 +649,10 @@ public class HwmfText {
public HwmfFont getFont() {
return font;
}
+
+ @Override
+ public String toString() {
+ return "{ font: "+font+" } ";
+ }
}
}
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java
index 389cfbc7dd..e419157050 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java
@@ -17,6 +17,8 @@
package org.apache.poi.hwmf.record;
+import static org.apache.poi.hwmf.record.HwmfDraw.readBounds;
+
import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
@@ -446,20 +448,7 @@ public class HwmfWindowing {
@Override
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- // A 16-bit signed integer that defines the y-coordinate, in logical units, of the
- // lower-right corner of the rectangle.
- final int bottom = leis.readShort();
- // A 16-bit signed integer that defines the x-coordinate, in logical units, of the
- // lower-right corner of the rectangle.
- final int right = leis.readShort();
- // A 16-bit signed integer that defines the y-coordinate, in logical units, of the
- // upper-left corner of the rectangle.
- final int top = leis.readShort();
- // A 16-bit signed integer that defines the x-coordinate, in logical units, of the
- // upper-left corner of the rectangle.
- final int left = leis.readShort();
- bounds.setRect(left, top, right-left, bottom-top);
- return 4*LittleEndianConsts.SHORT_SIZE;
+ return readBounds(leis, bounds);
}
@Override
@@ -470,6 +459,16 @@ public class HwmfWindowing {
@Override
public void applyObject(HwmfGraphics ctx) {
}
+
+ @Override
+ public String toString() {
+ return
+ "{ x: "+bounds.getX()+
+ ", y: "+bounds.getY()+
+ ", w: "+bounds.getWidth()+
+ ", h: "+bounds.getHeight()+
+ "}";
+ }
}
/**
diff --git a/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java b/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java
index 8d360d9aef..6e88853e16 100644
--- a/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java
+++ b/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java
@@ -32,6 +32,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
@@ -63,7 +64,7 @@ public class HemfPictureTest {
@Test
@Ignore("Only for manual tests")
public void paint() throws IOException {
- File f = sl_samples.getFile("wrench.emf");
+ File f = new File("picture_14.emf"); // sl_samples.getFile("wrench.emf");
try (FileInputStream fis = new FileInputStream(f)) {
HemfPicture emf = new HemfPicture(fis);
@@ -84,6 +85,14 @@ public class HemfPictureTest {
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+ FileWriter fw = new FileWriter("record-list.txt");
+ int i=0;
+ for (HemfRecord r : emf.getRecords()) {
+ fw.write(i + " "+r.getEmfRecordType()+" "+r.toString()+"\n");
+ i++;
+ }
+ fw.close();
+
emf.draw(g, new Rectangle2D.Double(0,0,width,height));
g.dispose();
@@ -160,7 +169,7 @@ public class HemfPictureTest {
StringBuilder sb = new StringBuilder();
for (HemfRecord record : pic) {
if (record.getEmfRecordType().equals(HemfRecordType.exttextoutw)) {
- HemfText.ExtTextOutW extTextOutW = (HemfText.ExtTextOutW) record;
+ HemfText.EmfExtTextOutW extTextOutW = (HemfText.EmfExtTextOutW) record;
Point2D reference = extTextOutW.getTextObject().getReference();
if (lastY > -1 && lastY != reference.getY()) {
sb.append("\n");
@@ -194,7 +203,7 @@ public class HemfPictureTest {
int foundExpected = 0;
for (HemfRecord record : pic) {
if (record.getEmfRecordType().equals(HemfRecordType.exttextoutw)) {
- HemfText.ExtTextOutW extTextOutW = (HemfText.ExtTextOutW) record;
+ HemfText.EmfExtTextOutW extTextOutW = (HemfText.EmfExtTextOutW) record;
Point2D reference = extTextOutW.getTextObject().getReference();
if (lastY > -1 && lastY != reference.getY()) {
sb.append("\n");