Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfRecordType.java URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfRecordType.java?rev=1840956&r1=1840955&r2=1840956&view=diff ============================================================================== --- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfRecordType.java (original) +++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfRecordType.java Fri Sep 14 21:37:37 2018 @@ -17,6 +17,8 @@ package org.apache.poi.hwmf.record; +import java.util.function.Supplier; + /** * Available record types for WMF * @@ -24,83 +26,83 @@ package org.apache.poi.hwmf.record; */ public enum HwmfRecordType { eof(0x0000, null) - ,animatePalette(0x0436, HwmfPalette.WmfAnimatePalette.class) - ,arc(0x0817, HwmfDraw.WmfArc.class) - ,bitBlt(0x0922, HwmfFill.WmfBitBlt.class) - ,chord(0x0830, HwmfDraw.WmfChord.class) - ,createBrushIndirect(0x02fc, HwmfMisc.WmfCreateBrushIndirect.class) - ,createFontIndirect(0x02fb, HwmfText.WmfCreateFontIndirect.class) - ,createPalette(0x00f7, HwmfPalette.WmfCreatePalette.class) - ,createPatternBrush(0x01f9, HwmfMisc.WmfCreatePatternBrush.class) - ,createPenIndirect(0x02fa, HwmfMisc.WmfCreatePenIndirect.class) - ,createRegion(0x06ff, HwmfWindowing.WmfCreateRegion.class) - ,deleteObject(0x01f0, HwmfMisc.WmfDeleteObject.class) - ,dibBitBlt(0x0940, HwmfFill.WmfDibBitBlt.class) - ,dibCreatePatternBrush(0x0142, HwmfMisc.WmfDibCreatePatternBrush.class) - ,dibStretchBlt(0x0b41, HwmfFill.WmfDibStretchBlt.class) - ,ellipse(0x0418, HwmfDraw.WmfEllipse.class) - ,escape(0x0626, HwmfEscape.class) - ,excludeClipRect(0x0415, HwmfWindowing.WmfExcludeClipRect.class) - ,extFloodFill(0x0548, HwmfFill.WmfExtFloodFill.class) - ,extTextOut(0x0a32, HwmfText.WmfExtTextOut.class) - ,fillRegion(0x0228, HwmfFill.WmfFillRegion.class) - ,floodFill(0x0419, HwmfFill.WmfFloodFill.class) - ,frameRegion(0x0429, HwmfDraw.WmfFrameRegion.class) - ,intersectClipRect(0x0416, HwmfWindowing.WmfIntersectClipRect.class) - ,invertRegion(0x012a, HwmfFill.WmfInvertRegion.class) - ,lineTo(0x0213, HwmfDraw.WmfLineTo.class) - ,moveTo(0x0214, HwmfDraw.WmfMoveTo.class) - ,offsetClipRgn(0x0220, HwmfWindowing.WmfOffsetClipRgn.class) - ,offsetViewportOrg(0x0211, HwmfWindowing.WmfOffsetViewportOrg.class) - ,offsetWindowOrg(0x020f, HwmfWindowing.WmfOffsetWindowOrg.class) - ,paintRegion(0x012b, HwmfFill.WmfPaintRegion.class) - ,patBlt(0x061d, HwmfFill.WmfPatBlt.class) - ,pie(0x081a, HwmfDraw.WmfPie.class) - ,polygon(0x0324, HwmfDraw.WmfPolygon.class) - ,polyline(0x0325, HwmfDraw.WmfPolyline.class) - ,polyPolygon(0x0538, HwmfDraw.WmfPolyPolygon.class) - ,realizePalette(0x0035, HwmfPalette.WmfRealizePalette.class) - ,rectangle(0x041b, HwmfDraw.WmfRectangle.class) - ,resizePalette(0x0139, HwmfPalette.WmfResizePalette.class) - ,restoreDc(0x0127, HwmfMisc.WmfRestoreDc.class) - ,roundRect(0x061c, HwmfDraw.WmfRoundRect.class) - ,saveDc(0x001e, HwmfMisc.WmfSaveDc.class) - ,scaleViewportExt(0x0412, HwmfWindowing.WmfScaleViewportExt.class) - ,scaleWindowExt(0x0410, HwmfWindowing.WmfScaleWindowExt.class) - ,selectClipRegion(0x012c, HwmfWindowing.WmfSelectClipRegion.class) - ,selectObject(0x012d, HwmfDraw.WmfSelectObject.class) - ,selectPalette(0x0234, HwmfPalette.WmfSelectPalette.class) - ,setBkColor(0x0201, HwmfMisc.WmfSetBkColor.class) - ,setBkMode(0x0102, HwmfMisc.WmfSetBkMode.class) - ,setDibToDev(0x0d33, HwmfFill.WmfSetDibToDev.class) - ,setLayout(0x0149, HwmfMisc.WmfSetLayout.class) - ,setMapMode(0x0103, HwmfMisc.WmfSetMapMode.class) - ,setMapperFlags(0x0231, HwmfMisc.WmfSetMapperFlags.class) - ,setPalEntries(0x0037, HwmfPalette.WmfSetPaletteEntries.class) - ,setPixel(0x041f, HwmfDraw.WmfSetPixel.class) - ,setPolyFillMode(0x0106, HwmfFill.WmfSetPolyfillMode.class) - ,setRelabs(0x0105, HwmfMisc.WmfSetRelabs.class) - ,setRop2(0x0104, HwmfMisc.WmfSetRop2.class) - ,setStretchBltMode(0x0107, HwmfMisc.WmfSetStretchBltMode.class) - ,setTextAlign(0x012e, HwmfText.WmfSetTextAlign.class) - ,setTextCharExtra(0x0108, HwmfText.WmfSetTextCharExtra.class) - ,setTextColor(0x0209, HwmfText.WmfSetTextColor.class) - ,setTextJustification(0x020a, HwmfText.WmfSetTextJustification.class) - ,setViewportExt(0x020e, HwmfWindowing.WmfSetViewportExt.class) - ,setViewportOrg(0x020d, HwmfWindowing.WmfSetViewportOrg.class) - ,setWindowExt(0x020c, HwmfWindowing.WmfSetWindowExt.class) - ,setWindowOrg(0x020b, HwmfWindowing.WmfSetWindowOrg.class) - ,stretchBlt(0x0b23, HwmfFill.WmfStretchBlt.class) - ,stretchDib(0x0f43, HwmfFill.WmfStretchDib.class) - ,textOut(0x0521, HwmfText.WmfTextOut.class) + ,animatePalette(0x0436, HwmfPalette.WmfAnimatePalette::new) + ,arc(0x0817, HwmfDraw.WmfArc::new) + ,bitBlt(0x0922, HwmfFill.WmfBitBlt::new) + ,chord(0x0830, HwmfDraw.WmfChord::new) + ,createBrushIndirect(0x02fc, HwmfMisc.WmfCreateBrushIndirect::new) + ,createFontIndirect(0x02fb, HwmfText.WmfCreateFontIndirect::new) + ,createPalette(0x00f7, HwmfPalette.WmfCreatePalette::new) + ,createPatternBrush(0x01f9, HwmfMisc.WmfCreatePatternBrush::new) + ,createPenIndirect(0x02fa, HwmfMisc.WmfCreatePenIndirect::new) + ,createRegion(0x06ff, HwmfWindowing.WmfCreateRegion::new) + ,deleteObject(0x01f0, HwmfMisc.WmfDeleteObject::new) + ,dibBitBlt(0x0940, HwmfFill.WmfDibBitBlt::new) + ,dibCreatePatternBrush(0x0142, HwmfMisc.WmfDibCreatePatternBrush::new) + ,dibStretchBlt(0x0b41, HwmfFill.WmfDibStretchBlt::new) + ,ellipse(0x0418, HwmfDraw.WmfEllipse::new) + ,escape(0x0626, HwmfEscape::new) + ,excludeClipRect(0x0415, HwmfWindowing.WmfExcludeClipRect::new) + ,extFloodFill(0x0548, HwmfFill.WmfExtFloodFill::new) + ,extTextOut(0x0a32, HwmfText.WmfExtTextOut::new) + ,fillRegion(0x0228, HwmfFill.WmfFillRegion::new) + ,floodFill(0x0419, HwmfFill.WmfFloodFill::new) + ,frameRegion(0x0429, HwmfDraw.WmfFrameRegion::new) + ,intersectClipRect(0x0416, HwmfWindowing.WmfIntersectClipRect::new) + ,invertRegion(0x012a, HwmfFill.WmfInvertRegion::new) + ,lineTo(0x0213, HwmfDraw.WmfLineTo::new) + ,moveTo(0x0214, HwmfDraw.WmfMoveTo::new) + ,offsetClipRgn(0x0220, HwmfWindowing.WmfOffsetClipRgn::new) + ,offsetViewportOrg(0x0211, HwmfWindowing.WmfOffsetViewportOrg::new) + ,offsetWindowOrg(0x020f, HwmfWindowing.WmfOffsetWindowOrg::new) + ,paintRegion(0x012b, HwmfFill.WmfPaintRegion::new) + ,patBlt(0x061d, HwmfFill.WmfPatBlt::new) + ,pie(0x081a, HwmfDraw.WmfPie::new) + ,polygon(0x0324, HwmfDraw.WmfPolygon::new) + ,polyline(0x0325, HwmfDraw.WmfPolyline::new) + ,polyPolygon(0x0538, HwmfDraw.WmfPolyPolygon::new) + ,realizePalette(0x0035, HwmfPalette.WmfRealizePalette::new) + ,rectangle(0x041b, HwmfDraw.WmfRectangle::new) + ,resizePalette(0x0139, HwmfPalette.WmfResizePalette::new) + ,restoreDc(0x0127, HwmfMisc.WmfRestoreDc::new) + ,roundRect(0x061c, HwmfDraw.WmfRoundRect::new) + ,saveDc(0x001e, HwmfMisc.WmfSaveDc::new) + ,scaleViewportExt(0x0412, HwmfWindowing.WmfScaleViewportExt::new) + ,scaleWindowExt(0x0410, HwmfWindowing.WmfScaleWindowExt::new) + ,selectClipRegion(0x012c, HwmfWindowing.WmfSelectClipRegion::new) + ,selectObject(0x012d, HwmfDraw.WmfSelectObject::new) + ,selectPalette(0x0234, HwmfPalette.WmfSelectPalette::new) + ,setBkColor(0x0201, HwmfMisc.WmfSetBkColor::new) + ,setBkMode(0x0102, HwmfMisc.WmfSetBkMode::new) + ,setDibToDev(0x0d33, HwmfFill.WmfSetDibToDev::new) + ,setLayout(0x0149, HwmfMisc.WmfSetLayout::new) + ,setMapMode(0x0103, HwmfMisc.WmfSetMapMode::new) + ,setMapperFlags(0x0231, HwmfMisc.WmfSetMapperFlags::new) + ,setPalEntries(0x0037, HwmfPalette.WmfSetPaletteEntries::new) + ,setPixel(0x041f, HwmfDraw.WmfSetPixel::new) + ,setPolyFillMode(0x0106, HwmfFill.WmfSetPolyfillMode::new) + ,setRelabs(0x0105, HwmfMisc.WmfSetRelabs::new) + ,setRop2(0x0104, HwmfMisc.WmfSetRop2::new) + ,setStretchBltMode(0x0107, HwmfMisc.WmfSetStretchBltMode::new) + ,setTextAlign(0x012e, HwmfText.WmfSetTextAlign::new) + ,setTextCharExtra(0x0108, HwmfText.WmfSetTextCharExtra::new) + ,setTextColor(0x0209, HwmfText.WmfSetTextColor::new) + ,setTextJustification(0x020a, HwmfText.WmfSetTextJustification::new) + ,setViewportExt(0x020e, HwmfWindowing.WmfSetViewportExt::new) + ,setViewportOrg(0x020d, HwmfWindowing.WmfSetViewportOrg::new) + ,setWindowExt(0x020c, HwmfWindowing.WmfSetWindowExt::new) + ,setWindowOrg(0x020b, HwmfWindowing.WmfSetWindowOrg::new) + ,stretchBlt(0x0b23, HwmfFill.WmfStretchBlt::new) + ,stretchDib(0x0f43, HwmfFill.WmfStretchDib::new) + ,textOut(0x0521, HwmfText.WmfTextOut::new) ; public final int id; - public final Class<? extends HwmfRecord> clazz; + public final Supplier<? extends HwmfRecord> constructor; - HwmfRecordType(int id, Class<? extends HwmfRecord> clazz) { + HwmfRecordType(int id, Supplier<? extends HwmfRecord> constructor) { this.id = id; - this.clazz = clazz; + this.constructor = constructor; } public static HwmfRecordType getById(int id) {
Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java?rev=1840956&r1=1840955&r2=1840956&view=diff ============================================================================== --- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java (original) +++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java Fri Sep 14 21:37:37 2018 @@ -17,8 +17,16 @@ package org.apache.poi.hwmf.record; +import static org.apache.poi.hwmf.record.HwmfDraw.readPointS; +import static org.apache.poi.hwmf.record.HwmfDraw.readRectS; + +import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; +import java.io.ByteArrayInputStream; +import java.io.EOFException; import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; import java.nio.charset.Charset; import org.apache.poi.hwmf.draw.HwmfDrawProperties; @@ -31,6 +39,7 @@ import org.apache.poi.util.LittleEndianC import org.apache.poi.util.LittleEndianInputStream; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; +import org.apache.poi.util.RecordFormatException; public class HwmfText { private static final POILogger logger = POILogFactory.getLogger(HwmfText.class); @@ -52,7 +61,7 @@ public class HwmfText { private int charExtra; @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.setTextCharExtra; } @@ -76,7 +85,7 @@ public class HwmfText { private HwmfColorRef colorRef; @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.setTextColor; } @@ -112,7 +121,7 @@ public class HwmfText { private int breakExtra; @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.setBkColor; } @@ -159,7 +168,7 @@ public class HwmfText { private int xStart; @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.textOut; } @@ -195,41 +204,48 @@ public class HwmfText { return ret; } } - - /** - * The META_EXTTEXTOUT record outputs text by using the font, background color, and text color that - * are defined in the playback device context. Optionally, dimensions can be provided for clipping, - * opaquing, or both. - */ - public static class WmfExtTextOut implements HwmfRecord { + public static class WmfExtTextOutOptions { /** - * Indicates that the background color that is defined in the playback device context + * Indicates that the background color that is defined in the playback device context * SHOULD be used to fill the rectangle. - */ + */ private static final BitField ETO_OPAQUE = BitFieldFactory.getInstance(0x0002); - + /** * Indicates that the text SHOULD be clipped to the rectangle. */ private static final BitField ETO_CLIPPED = BitFieldFactory.getInstance(0x0004); /** - * Indicates that the string to be output SHOULD NOT require further processing - * with respect to the placement of the characters, and an array of character - * placement values SHOULD be provided. This character placement process is + * Indicates that the string to be output SHOULD NOT require further processing + * with respect to the placement of the characters, and an array of character + * placement values SHOULD be provided. This character placement process is * useful for fonts in which diacritical characters affect character spacing. */ private static final BitField ETO_GLYPH_INDEX = BitFieldFactory.getInstance(0x0010); /** - * Indicates that the text MUST be laid out in right-to-left reading order, instead of - * the default left-to-right order. This SHOULD be applied only when the font that is + * Indicates that the text MUST be laid out in right-to-left reading order, instead of + * the default left-to-right order. This SHOULD be applied only when the font that is * defined in the playback device context is either Hebrew or Arabic. */ private static final BitField ETO_RTLREADING = BitFieldFactory.getInstance(0x0080); /** + * This bit indicates that the record does not specify a bounding rectangle for the + * text output. + */ + private static final BitField ETO_NO_RECT = BitFieldFactory.getInstance(0x0100); + + /** + * This bit indicates that the codes for characters in an output text string are 8 bits, + * derived from the low bytes of 16-bit Unicode UTF16-LE character codes, in which + * the high byte is assumed to be 0. + */ + private static final BitField ETO_SMALL_CHARS = BitFieldFactory.getInstance(0x0200); + + /** * Indicates that to display numbers, digits appropriate to the locale SHOULD be used. */ private static final BitField ETO_NUMERICSLOCAL = BitFieldFactory.getInstance(0x0400); @@ -240,32 +256,58 @@ public class HwmfText { private static final BitField ETO_NUMERICSLATIN = BitFieldFactory.getInstance(0x0800); /** - * Indicates that both horizontal and vertical character displacement values + * This bit indicates that no special operating system processing for glyph placement + * should be performed on right-to-left strings; that is, all glyph positioning + * SHOULD be taken care of by drawing and state records in the metafile + */ + private static final BitField ETO_IGNORELANGUAGE = BitFieldFactory.getInstance(0x1000); + + /** + * Indicates that both horizontal and vertical character displacement values * SHOULD be provided. */ private static final BitField ETO_PDY = BitFieldFactory.getInstance(0x2000); + /** This bit is reserved and SHOULD NOT be used. */ + private static final BitField ETO_REVERSE_INDEX_MAP = BitFieldFactory.getInstance(0x10000); + + protected int flag; + + public int init(LittleEndianInputStream leis) { + flag = leis.readUShort(); + return LittleEndianConsts.SHORT_SIZE; + } + + public boolean isOpaque() { + return ETO_OPAQUE.isSet(flag); + } + + public boolean isClipped() { + return ETO_CLIPPED.isSet(flag); + } + } + + /** + * The META_EXTTEXTOUT record outputs text by using the font, background color, and text color that + * are defined in the playback device context. Optionally, dimensions can be provided for clipping, + * opaquing, or both. + */ + public static class WmfExtTextOut implements HwmfRecord { /** - * A 16-bit signed integer that defines the y-coordinate, in logical units, where the - text string is to be located. + * The location, in logical units, where the text string is to be placed. */ - private int y; + protected final Point2D reference = new Point2D.Double(); + /** - * A 16-bit signed integer that defines the x-coordinate, in logical units, where the - text string is to be located. + * A 16-bit signed integer that defines the length of the string. */ - private int x; + protected int stringLength; /** - * A 16-bit signed integer that defines the length of the string. + * A 16-bit unsigned integer that defines the use of the application-defined + * rectangle. This member can be a combination of one or more values in the + * ExtTextOutOptions Flags (ETO_*) */ - private int stringLength; - - /** - * A 16-bit unsigned integer that defines the use of the application-defined - * rectangle. This member can be a combination of one or more values in the - * ExtTextOutOptions Flags (ETO_*) - */ - private int fwOpts; + protected final WmfExtTextOutOptions options; /** * An optional 8-byte Rect Object (section 2.2.2.18) that defines the * dimensions, in logical coordinates, of a rectangle that is used for clipping, opaquing, or both. @@ -274,14 +316,14 @@ public class HwmfText { * Each value is a 16-bit signed integer that defines the coordinate, in logical coordinates, of * the upper-left corner of the rectangle */ - private int left,top,right,bottom; + protected final Rectangle2D bounds = new Rectangle2D.Double(); /** * A variable-length string that specifies the text to be drawn. The string does * not need to be null-terminated, because StringLength specifies the length of the string. If * the length is odd, an extra byte is placed after it so that the following member (optional Dx) is * aligned on a 16-bit boundary. */ - private byte[] rawTextBytes; + protected byte[] rawTextBytes; /** * An optional array of 16-bit signed integers that indicate the distance between * origins of adjacent character cells. For example, Dx[i] logical units separate the origins of @@ -289,9 +331,17 @@ public class HwmfText { * number of values as there are characters in the string. */ private int dx[]; - + + public WmfExtTextOut() { + this(new WmfExtTextOutOptions()); + } + + protected WmfExtTextOut(WmfExtTextOutOptions options) { + this.options = options; + } + @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.extTextOut; } @@ -299,22 +349,17 @@ public class HwmfText { public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException { // -6 bytes of record function and length header final int remainingRecordSize = (int)(recordSize-6); - - y = leis.readShort(); - x = leis.readShort(); + + int size = readPointS(leis, reference); + stringLength = leis.readShort(); - fwOpts = leis.readUShort(); - - int size = 4*LittleEndianConsts.SHORT_SIZE; - + size += LittleEndianConsts.SHORT_SIZE; + size += options.init(leis); + // Check if we have a rectangle - if ((ETO_OPAQUE.isSet(fwOpts) || ETO_CLIPPED.isSet(fwOpts)) && size+8<=remainingRecordSize) { - // the bounding rectangle is optional and only read when fwOpts are given - left = leis.readShort(); - top = leis.readShort(); - right = leis.readShort(); - bottom = leis.readShort(); - size += 4*LittleEndianConsts.SHORT_SIZE; + if ((options.isOpaque() || options.isClipped()) && size+8<=remainingRecordSize) { + // the bounding rectangle is optional and only read when options are given + size += readRectS(leis, bounds); } rawTextBytes = IOUtils.safelyAllocate(stringLength+(stringLength&1), MAX_RECORD_LENGTH); @@ -342,12 +387,46 @@ public class HwmfText { @Override public void draw(HwmfGraphics ctx) { - Rectangle2D bounds = new Rectangle2D.Double(x, y, 0, 0); + Rectangle2D bounds = new Rectangle2D.Double(reference.getX(), reference.getY(), 0, 0); ctx.drawString(getTextBytes(), bounds, dx); } - public String getText(Charset charset) { - return new String(getTextBytes(), charset); + + public String getText(Charset charset) throws IOException { + StringBuilder sb = new StringBuilder(); + try (Reader r = new InputStreamReader(new ByteArrayInputStream(rawTextBytes), charset)) { + for (int i = 0; i < stringLength; i++) { + sb.appendCodePoint(readCodePoint(r)); + } + } + return sb.toString(); + } + + //TODO: move this to IOUtils? + private int readCodePoint(Reader r) throws IOException { + int c1 = r.read(); + if (c1 == -1) { + throw new EOFException("Tried to read beyond byte array"); + } + if (!Character.isHighSurrogate((char)c1)) { + return c1; + } + int c2 = r.read(); + if (c2 == -1) { + throw new EOFException("Tried to read beyond byte array"); + } + if (!Character.isLowSurrogate((char)c2)) { + throw new RecordFormatException("Expected low surrogate after high surrogate"); + } + return Character.toCodePoint((char)c1, (char)c2); + } + + public Point2D getReference() { + return reference; + } + + public Rectangle2D getBounds() { + return bounds; } /** @@ -482,10 +561,10 @@ public class HwmfText { * for text with a horizontal baseline, and VerticalTextAlignmentMode Flags * for text with a vertical baseline. */ - private int textAlignmentMode; + protected int textAlignmentMode; @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.setTextAlign; } @@ -533,17 +612,24 @@ public class HwmfText { } public static class WmfCreateFontIndirect implements HwmfRecord, HwmfObjectTableEntry { - private HwmfFont font; - + protected final HwmfFont font; + + public WmfCreateFontIndirect() { + this(new HwmfFont()); + } + + protected WmfCreateFontIndirect(HwmfFont font) { + this.font = font; + } + @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.createFontIndirect; } @Override public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException { - font = new HwmfFont(); - return font.init(leis); + return font.init(leis, recordSize); } @Override Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java?rev=1840956&r1=1840955&r2=1840956&view=diff ============================================================================== --- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java (original) +++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java Fri Sep 14 21:37:37 2018 @@ -33,18 +33,14 @@ public class HwmfWindowing { */ public static class WmfSetViewportOrg implements HwmfRecord { - /** - * A 16-bit signed integer that defines the vertical offset, in device units. - */ - private int y; + /** A signed integer that defines the vertical offset, in device units. */ + protected int y; - /** - * A 16-bit signed integer that defines the horizontal offset, in device units. - */ - private int x; + /** A signed integer that defines the horizontal offset, in device units. */ + protected int x; @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.setViewportOrg; } @@ -67,20 +63,14 @@ public class HwmfWindowing { */ public static class WmfSetViewportExt implements HwmfRecord { - /** - * A 16-bit signed integer that defines the vertical extent - * of the viewport in device units. - */ - private int height; + /** A signed integer that defines the vertical extent of the viewport in device units. */ + protected int height; - /** - * A 16-bit signed integer that defines the horizontal extent - * of the viewport in device units. - */ - private int width; + /** A signed integer that defines the horizontal extent of the viewport in device units. */ + protected int width; @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.setViewportExt; } @@ -114,7 +104,7 @@ public class HwmfWindowing { private int xOffset; @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.offsetViewportOrg; } @@ -139,18 +129,14 @@ public class HwmfWindowing { */ public static class WmfSetWindowOrg implements HwmfRecord { - /** - * A 16-bit signed integer that defines the y-coordinate, in logical units. - */ - private int y; + /** A signed integer that defines the y-coordinate, in logical units. */ + protected int y; - /** - * A 16-bit signed integer that defines the x-coordinate, in logical units. - */ - private int x; + /** A signed integer that defines the x-coordinate, in logical units. */ + protected int x; @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.setWindowOrg; } @@ -182,20 +168,14 @@ public class HwmfWindowing { */ public static class WmfSetWindowExt implements HwmfRecord { - /** - * A 16-bit signed integer that defines the vertical extent of - * the window in logical units. - */ - private int height; + /** A signed integer that defines the vertical extent of the window in logical units. */ + protected int height; - /** - * A 16-bit signed integer that defines the horizontal extent of - * the window in logical units. - */ - private int width; + /** A signed integer that defines the horizontal extent of the window in logical units. */ + protected int width; @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.setWindowExt; } @@ -238,7 +218,7 @@ public class HwmfWindowing { private int xOffset; @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.offsetWindowOrg; } @@ -264,31 +244,31 @@ public class HwmfWindowing { public static class WmfScaleWindowExt implements HwmfRecord { /** - * A 16-bit signed integer that defines the amount by which to divide the + * A signed integer that defines the amount by which to divide the * result of multiplying the current y-extent by the value of the yNum member. */ - private int yDenom; + protected int yDenom; /** - * A 16-bit signed integer that defines the amount by which to multiply the + * A signed integer that defines the amount by which to multiply the * current y-extent. */ - private int yNum; + protected int yNum; /** - * A 16-bit signed integer that defines the amount by which to divide the + * A signed integer that defines the amount by which to divide the * result of multiplying the current x-extent by the value of the xNum member. */ - private int xDenom; + protected int xDenom; /** - * A 16-bit signed integer that defines the amount by which to multiply the + * A signed integer that defines the amount by which to multiply the * current x-extent. */ - private int xNum; + protected int xNum; @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.scaleWindowExt; } @@ -320,31 +300,31 @@ public class HwmfWindowing { public static class WmfScaleViewportExt implements HwmfRecord { /** - * A 16-bit signed integer that defines the amount by which to divide the + * A signed integer that defines the amount by which to divide the * result of multiplying the current y-extent by the value of the yNum member. */ - private int yDenom; + protected int yDenom; /** - * A 16-bit signed integer that defines the amount by which to multiply the + * A signed integer that defines the amount by which to multiply the * current y-extent. */ - private int yNum; + protected int yNum; /** - * A 16-bit signed integer that defines the amount by which to divide the + * A signed integer that defines the amount by which to divide the * result of multiplying the current x-extent by the value of the xNum member. */ - private int xDenom; + protected int xDenom; /** - * A 16-bit signed integer that defines the amount by which to multiply the + * A signed integer that defines the amount by which to multiply the * current x-extent. */ - private int xNum; + protected int xNum; @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.scaleViewportExt; } @@ -376,17 +356,17 @@ public class HwmfWindowing { public static class WmfOffsetClipRgn implements HwmfRecord, HwmfObjectTableEntry { /** - * A 16-bit signed integer that defines the number of logical units to move up or down. + * A signed integer that defines the number of logical units to move up or down. */ - private int yOffset; + protected int yOffset; /** - * A 16-bit signed integer that defines the number of logical units to move left or right. + * A signed integer that defines the number of logical units to move left or right. */ - private int xOffset; + protected int xOffset; @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.offsetClipRgn; } @@ -413,41 +393,29 @@ public class HwmfWindowing { */ public static class WmfExcludeClipRect implements HwmfRecord, HwmfObjectTableEntry { - /** - * A 16-bit signed integer that defines the y-coordinate, in logical units, of the - * lower-right corner of the rectangle. - */ - private int bottom; - - /** - * A 16-bit signed integer that defines the x-coordinate, in logical units, of the - * lower-right corner of the rectangle. - */ - private int right; - - /** - * A 16-bit signed integer that defines the y-coordinate, in logical units, of the - * upper-left corner of the rectangle. - */ - private int top; - - /** - * A 16-bit signed integer that defines the x-coordinate, in logical units, of the - * upper-left corner of the rectangle. - */ - private int left; + /** a rectangle in logical units */ + protected final Rectangle2D bounds = new Rectangle2D.Double(); @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.excludeClipRect; } @Override public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException { - bottom = leis.readShort(); - right = leis.readShort(); - top = leis.readShort(); - left = leis.readShort(); + // 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; } @@ -468,41 +436,29 @@ public class HwmfWindowing { */ public static class WmfIntersectClipRect implements HwmfRecord, HwmfObjectTableEntry { - /** - * A 16-bit signed integer that defines the y-coordinate, in logical units, of the - * lower-right corner of the rectangle. - */ - private int bottom; - - /** - * A 16-bit signed integer that defines the x-coordinate, in logical units, of the - * lower-right corner of the rectangle. - */ - private int right; - - /** - * A 16-bit signed integer that defines the y-coordinate, in logical units, of the - * upper-left corner of the rectangle. - */ - private int top; - - /** - * A 16-bit signed integer that defines the x-coordinate, in logical units, of the - * upper-left corner of the rectangle. - */ - private int left; + /** a rectangle in logical units */ + protected final Rectangle2D bounds = new Rectangle2D.Double(); @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.intersectClipRect; } @Override public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException { - bottom = leis.readShort(); - right = leis.readShort(); - top = leis.readShort(); - left = leis.readShort(); + // 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; } @@ -528,7 +484,7 @@ public class HwmfWindowing { private int region; @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.selectClipRegion; } @@ -650,7 +606,7 @@ public class HwmfWindowing { private WmfScanObject scanObjects[]; @Override - public HwmfRecordType getRecordType() { + public HwmfRecordType getWmfRecordType() { return HwmfRecordType.createRegion; } Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java?rev=1840956&r1=1840955&r2=1840956&view=diff ============================================================================== --- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java (original) +++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java Fri Sep 14 21:37:37 2018 @@ -51,8 +51,7 @@ public class HwmfPicture { public HwmfPicture(InputStream inputStream) throws IOException { - try (BufferedInputStream bis = new BufferedInputStream(inputStream, 10000); - LittleEndianInputStream leis = new LittleEndianInputStream(bis)) { + try (LittleEndianInputStream leis = new LittleEndianInputStream(inputStream)) { placeableHeader = HwmfPlaceableHeader.readHeader(leis); header = new HwmfHeader(leis); @@ -82,17 +81,12 @@ public class HwmfPicture { if (wrt == HwmfRecordType.eof) { break; } - if (wrt.clazz == null) { + if (wrt.constructor == null) { throw new IOException("unsupported record type: "+recordFunction); } - HwmfRecord wr; - try { - wr = wrt.clazz.newInstance(); - records.add(wr); - } catch (Exception e) { - throw (IOException)new IOException("can't create wmf record").initCause(e); - } + final HwmfRecord wr = wrt.constructor.get(); + records.add(wr); consumedSize += wr.init(leis, recordSize, recordFunction); int remainingSize = (int)(recordSize - consumedSize); Modified: poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/hemfplus/extractor/HemfPlusExtractorTest.java URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/hemfplus/extractor/HemfPlusExtractorTest.java?rev=1840956&r1=1840955&r2=1840956&view=diff ============================================================================== --- poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/hemfplus/extractor/HemfPlusExtractorTest.java (original) +++ poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/hemfplus/extractor/HemfPlusExtractorTest.java Fri Sep 14 21:37:37 2018 @@ -25,13 +25,13 @@ import java.util.ArrayList; import java.util.List; import org.apache.poi.POIDataSamples; -import org.apache.poi.hemf.extractor.HemfExtractor; -import org.apache.poi.hemf.hemfplus.record.HemfPlusHeader; -import org.apache.poi.hemf.hemfplus.record.HemfPlusRecord; -import org.apache.poi.hemf.hemfplus.record.HemfPlusRecordType; -import org.apache.poi.hemf.record.HemfCommentEMFPlus; -import org.apache.poi.hemf.record.HemfCommentRecord; -import org.apache.poi.hemf.record.HemfRecord; +import org.apache.poi.hemf.record.emf.HemfComment.EmfComment; +import org.apache.poi.hemf.record.emf.HemfComment.EmfCommentDataPlus; +import org.apache.poi.hemf.record.emf.HemfRecord; +import org.apache.poi.hemf.record.emfplus.HemfPlusHeader; +import org.apache.poi.hemf.record.emfplus.HemfPlusRecord; +import org.apache.poi.hemf.record.emfplus.HemfPlusRecordType; +import org.apache.poi.hemf.usermodel.HemfPicture; import org.junit.Test; public class HemfPlusExtractorTest { @@ -39,7 +39,7 @@ public class HemfPlusExtractorTest { @Test public void testBasic() throws Exception { //test header - HemfCommentEMFPlus emfPlus = getCommentRecord("SimpleEMF_windows.emf", 0); + EmfCommentDataPlus emfPlus = getCommentRecord("SimpleEMF_windows.emf", 0); List<HemfPlusRecord> records = emfPlus.getRecords(); assertEquals(1, records.size()); assertEquals(HemfPlusRecordType.header, records.get(0).getRecordType()); @@ -72,24 +72,20 @@ public class HemfPlusExtractorTest { } - private HemfCommentEMFPlus getCommentRecord(String testFileName, int recordIndex) throws Exception { - InputStream is = null; - HemfCommentEMFPlus returnRecord = null; - - try { - is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream(testFileName); - HemfExtractor ex = new HemfExtractor(is); + private EmfCommentDataPlus getCommentRecord(String testFileName, int recordIndex) throws Exception { + EmfCommentDataPlus returnRecord = null; + + try (InputStream is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream(testFileName)) { + HemfPicture ex = new HemfPicture(is); int i = 0; for (HemfRecord record : ex) { if (i == recordIndex) { - HemfCommentRecord commentRecord = ((HemfCommentRecord) record); - returnRecord = (HemfCommentEMFPlus) commentRecord.getComment(); + EmfComment commentRecord = ((EmfComment) record); + returnRecord = (EmfCommentDataPlus) commentRecord.getCommentData(); break; } i++; } - } finally { - is.close(); } return returnRecord; } Copied: poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java (from r1840385, poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/extractor/HemfExtractorTest.java) URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java?p2=poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java&p1=poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/extractor/HemfExtractorTest.java&r1=1840385&r2=1840956&rev=1840956&view=diff ============================================================================== --- poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/extractor/HemfExtractorTest.java (original) +++ poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java Fri Sep 14 21:37:37 2018 @@ -16,179 +16,182 @@ ==================================================================== */ -package org.apache.poi.hemf.extractor; +package org.apache.poi.hemf.usermodel; import static org.apache.poi.POITestCase.assertContains; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import java.awt.geom.Point2D; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.util.HashSet; +import java.util.List; import java.util.Set; import org.apache.poi.POIDataSamples; -import org.apache.poi.hemf.record.AbstractHemfComment; -import org.apache.poi.hemf.record.HemfCommentPublic; -import org.apache.poi.hemf.record.HemfCommentRecord; -import org.apache.poi.hemf.record.HemfHeader; -import org.apache.poi.hemf.record.HemfRecord; -import org.apache.poi.hemf.record.HemfRecordType; -import org.apache.poi.hemf.record.HemfText; +import org.apache.poi.hemf.record.emf.HemfComment; +import org.apache.poi.hemf.record.emf.HemfComment.EmfComment; +import org.apache.poi.hemf.record.emf.HemfComment.EmfCommentDataFormat; +import org.apache.poi.hemf.record.emf.HemfComment.EmfCommentDataMultiformats; +import org.apache.poi.hemf.record.emf.HemfHeader; +import org.apache.poi.hemf.record.emf.HemfRecord; +import org.apache.poi.hemf.record.emf.HemfRecordType; +import org.apache.poi.hemf.record.emf.HemfText; import org.apache.poi.util.IOUtils; import org.apache.poi.util.RecordFormatException; import org.junit.Test; -public class HemfExtractorTest { +public class HemfPictureTest { + + private POIDataSamples samples = POIDataSamples.getSpreadSheetInstance(); @Test public void testBasicWindows() throws Exception { - InputStream is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream("SimpleEMF_windows.emf"); - HemfExtractor ex = new HemfExtractor(is); - HemfHeader header = ex.getHeader(); - assertEquals(27864, header.getBytes()); - assertEquals(31, header.getRecords()); - assertEquals(3, header.getHandles()); - assertEquals(346000, header.getMicrometersX()); - assertEquals(194000, header.getMicrometersY()); - - int records = 0; - for (HemfRecord record : ex) { - records++; - } + try (InputStream is = samples.openResourceAsStream("SimpleEMF_windows.emf")) { + HemfPicture pic = new HemfPicture(is); + HemfHeader header = pic.getHeader(); + assertEquals(27864, header.getBytes()); + assertEquals(31, header.getRecords()); + assertEquals(3, header.getHandles()); + assertEquals(346000, header.getMicrometersX()); + assertEquals(194000, header.getMicrometersY()); - assertEquals(header.getRecords() - 1, records); + List<HemfRecord> records = pic.getRecords(); + + assertEquals(31, records.size()); + } } @Test public void testBasicMac() throws Exception { - InputStream is = - POIDataSamples.getSpreadSheetInstance().openResourceAsStream("SimpleEMF_mac.emf"); - HemfExtractor ex = new HemfExtractor(is); - HemfHeader header = ex.getHeader(); - - int records = 0; - boolean extractedData = false; - for (HemfRecord record : ex) { - if (record.getRecordType() == HemfRecordType.comment) { - AbstractHemfComment comment = ((HemfCommentRecord) record).getComment(); - if (comment instanceof HemfCommentPublic.MultiFormats) { - for (HemfCommentPublic.HemfMultiFormatsData d : ((HemfCommentPublic.MultiFormats) comment).getData()) { - byte[] data = d.getData(); - //make sure header starts at 0 - assertEquals('%', data[0]); - assertEquals('P', data[1]); - assertEquals('D', data[2]); - assertEquals('F', data[3]); - - //make sure byte array ends at EOF\n - assertEquals('E', data[data.length - 4]); - assertEquals('O', data[data.length - 3]); - assertEquals('F', data[data.length - 2]); - assertEquals('\n', data[data.length - 1]); - extractedData = true; + try (InputStream is = samples.openResourceAsStream("SimpleEMF_mac.emf")) { + HemfPicture pic = new HemfPicture(is); + HemfHeader header = pic.getHeader(); + + int records = 0; + boolean extractedData = false; + for (HemfRecord record : pic) { + if (record.getEmfRecordType() == HemfRecordType.comment) { + HemfComment.EmfCommentData comment = ((EmfComment) record).getCommentData(); + if (comment instanceof EmfCommentDataMultiformats) { + for (EmfCommentDataFormat d : ((EmfCommentDataMultiformats) comment).getFormats()) { + byte[] data = d.getRawData(); + //make sure header starts at 0 + assertEquals('%', data[0]); + assertEquals('P', data[1]); + assertEquals('D', data[2]); + assertEquals('F', data[3]); + + //make sure byte array ends at EOF\n + assertEquals('E', data[data.length - 4]); + assertEquals('O', data[data.length - 3]); + assertEquals('F', data[data.length - 2]); + assertEquals('\n', data[data.length - 1]); + extractedData = true; + } } } + records++; } - records++; + assertTrue(extractedData); + assertEquals(header.getRecords(), records); } - assertTrue(extractedData); - assertEquals(header.getRecords() - 1, records); } @Test public void testMacText() throws Exception { - InputStream is = - POIDataSamples.getSpreadSheetInstance().openResourceAsStream("SimpleEMF_mac.emf"); - HemfExtractor ex = new HemfExtractor(is); - - long lastY = -1; - long lastX = -1; - long fudgeFactorX = 1000;//derive this from the font information! - StringBuilder sb = new StringBuilder(); - for (HemfRecord record : ex) { - if (record.getRecordType().equals(HemfRecordType.exttextoutw)) { - HemfText.ExtTextOutW extTextOutW = (HemfText.ExtTextOutW) record; - if (lastY > -1 && lastY != extTextOutW.getY()) { - sb.append("\n"); - lastX = -1; - } - if (lastX > -1 && extTextOutW.getX() - lastX > fudgeFactorX) { - sb.append(" "); + try (InputStream is = samples.openResourceAsStream("SimpleEMF_mac.emf")) { + HemfPicture pic = new HemfPicture(is); + + double lastY = -1; + double lastX = -1; + //derive this from the font information! + long fudgeFactorX = 1000; + StringBuilder sb = new StringBuilder(); + for (HemfRecord record : pic) { + if (record.getEmfRecordType().equals(HemfRecordType.exttextoutw)) { + HemfText.ExtTextOutW extTextOutW = (HemfText.ExtTextOutW) record; + Point2D reference = extTextOutW.getTextObject().getReference(); + if (lastY > -1 && lastY != reference.getY()) { + sb.append("\n"); + lastX = -1; + } + if (lastX > -1 && reference.getX() - lastX > fudgeFactorX) { + sb.append(" "); + } + sb.append(extTextOutW.getText()); + lastY = reference.getY(); + lastX = reference.getX(); } - sb.append(extTextOutW.getText()); - lastY = extTextOutW.getY(); - lastX = extTextOutW.getX(); } + String txt = sb.toString(); + assertContains(txt, "Tika http://incubator.apache.org"); + assertContains(txt, "Latest News\n"); } - String txt = sb.toString(); - assertContains(txt, "Tika http://incubator.apache.org"); - assertContains(txt, "Latest News\n"); } @Test public void testWindowsText() throws Exception { - InputStream is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream("SimpleEMF_windows.emf"); - HemfExtractor ex = new HemfExtractor(is); - long lastY = -1; - long lastX = -1; - long fudgeFactorX = 1000;//derive this from the font or frame/bounds information - StringBuilder sb = new StringBuilder(); - Set<String> expectedParts = new HashSet<>(); - expectedParts.add("C:\\Users\\tallison\\"); - expectedParts.add("testPDF.pdf"); - int foundExpected = 0; - for (HemfRecord record : ex) { - if (record.getRecordType().equals(HemfRecordType.exttextoutw)) { - HemfText.ExtTextOutW extTextOutW = (HemfText.ExtTextOutW) record; - if (lastY > -1 && lastY != extTextOutW.getY()) { - sb.append("\n"); - lastX = -1; - } - if (lastX > -1 && extTextOutW.getX() - lastX > fudgeFactorX) { - sb.append(" "); - } - String txt = extTextOutW.getText(); - if (expectedParts.contains(txt)) { - foundExpected++; + try (InputStream is = samples.openResourceAsStream("SimpleEMF_windows.emf")) { + HemfPicture pic = new HemfPicture(is); + double lastY = -1; + double lastX = -1; + long fudgeFactorX = 1000;//derive this from the font or frame/bounds information + StringBuilder sb = new StringBuilder(); + Set<String> expectedParts = new HashSet<>(); + expectedParts.add("C:\\Users\\tallison\\"); + expectedParts.add("testPDF.pdf"); + int foundExpected = 0; + for (HemfRecord record : pic) { + if (record.getEmfRecordType().equals(HemfRecordType.exttextoutw)) { + HemfText.ExtTextOutW extTextOutW = (HemfText.ExtTextOutW) record; + Point2D reference = extTextOutW.getTextObject().getReference(); + if (lastY > -1 && lastY != reference.getY()) { + sb.append("\n"); + lastX = -1; + } + if (lastX > -1 && reference.getX() - lastX > fudgeFactorX) { + sb.append(" "); + } + String txt = extTextOutW.getText(); + if (expectedParts.contains(txt)) { + foundExpected++; + } + sb.append(txt); + lastY = reference.getY(); + lastX = reference.getX(); } - sb.append(txt); - lastY = extTextOutW.getY(); - lastX = extTextOutW.getX(); } + String txt = sb.toString(); + assertContains(txt, "C:\\Users\\tallison\\\n"); + assertContains(txt, "asf2-git-1.x\\tika-\n"); + assertEquals(expectedParts.size(), foundExpected); } - String txt = sb.toString(); - assertContains(txt, "C:\\Users\\tallison\\\n"); - assertContains(txt, "asf2-git-1.x\\tika-\n"); - assertEquals(expectedParts.size(), foundExpected); } @Test(expected = RecordFormatException.class) public void testInfiniteLoopOnFile() throws Exception { - InputStream is = null; - try { - is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream("61294.emf"); - - HemfExtractor ex = new HemfExtractor(is); - for (HemfRecord record : ex) { + try (InputStream is = samples.openResourceAsStream("61294.emf")) { + HemfPicture pic = new HemfPicture(is); + for (HemfRecord record : pic) { } - } finally { - IOUtils.closeQuietly(is); } } @Test(expected = RecordFormatException.class) public void testInfiniteLoopOnByteArray() throws Exception { - InputStream is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream("61294.emf"); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - IOUtils.copy(is, bos); - is.close(); + try (InputStream is = samples.openResourceAsStream("61294.emf")) { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + IOUtils.copy(is, bos); + is.close(); - HemfExtractor ex = new HemfExtractor(new ByteArrayInputStream(bos.toByteArray())); - for (HemfRecord record : ex) { + HemfPicture pic = new HemfPicture(new ByteArrayInputStream(bos.toByteArray())); + for (HemfRecord record : pic) { + } } } Modified: poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java?rev=1840956&r1=1840955&r2=1840956&view=diff ============================================================================== --- poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java (original) +++ poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java Fri Sep 14 21:37:37 2018 @@ -222,11 +222,11 @@ public class TestHwmfParsing { //this happens to work on this test file, but you need to //do what Graphics does by maintaining the stack, etc.! for (HwmfRecord r : wmf.getRecords()) { - if (r.getRecordType().equals(HwmfRecordType.createFontIndirect)) { + if (r.getWmfRecordType().equals(HwmfRecordType.createFontIndirect)) { HwmfFont font = ((HwmfText.WmfCreateFontIndirect)r).getFont(); charset = (font.getCharset().getCharset() == null) ? LocaleUtil.CHARSET_1252 : font.getCharset().getCharset(); } - if (r.getRecordType().equals(HwmfRecordType.extTextOut)) { + if (r.getWmfRecordType().equals(HwmfRecordType.extTextOut)) { HwmfText.WmfExtTextOut textOut = (HwmfText.WmfExtTextOut)r; sb.append(textOut.getText(charset)).append("\n"); } @@ -250,11 +250,11 @@ public class TestHwmfParsing { //this happens to work on this test file, but you need to //do what Graphics does by maintaining the stack, etc.! for (HwmfRecord r : wmf.getRecords()) { - if (r.getRecordType().equals(HwmfRecordType.createFontIndirect)) { + if (r.getWmfRecordType().equals(HwmfRecordType.createFontIndirect)) { HwmfFont font = ((HwmfText.WmfCreateFontIndirect)r).getFont(); charset = (font.getCharset().getCharset() == null) ? LocaleUtil.CHARSET_1252 : font.getCharset().getCharset(); } - if (r.getRecordType().equals(HwmfRecordType.extTextOut)) { + if (r.getWmfRecordType().equals(HwmfRecordType.extTextOut)) { HwmfText.WmfExtTextOut textOut = (HwmfText.WmfExtTextOut)r; sb.append(textOut.getText(charset)).append("\n"); } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
