Copied: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java (from r1840955, poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/HemfRecordType.java) URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java?p2=poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java&p1=poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/HemfRecordType.java&r1=1840955&r2=1840956&rev=1840956&view=diff ============================================================================== --- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/HemfRecordType.java (original) +++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java Fri Sep 14 21:37:37 2018 @@ -15,139 +15,145 @@ limitations under the License. ==================================================================== */ -package org.apache.poi.hemf.record; +package org.apache.poi.hemf.record.emf; + +import java.util.function.Supplier; import org.apache.poi.util.Internal; @Internal public enum HemfRecordType { - header(0x00000001, UnimplementedHemfRecord.class), - polybeizer(0x00000002, UnimplementedHemfRecord.class), - polygon(0x00000003, UnimplementedHemfRecord.class), - polyline(0x00000004, UnimplementedHemfRecord.class), - polybezierto(0x00000005, UnimplementedHemfRecord.class), - polylineto(0x00000006, UnimplementedHemfRecord.class), - polypolyline(0x00000007, UnimplementedHemfRecord.class), - polypolygon(0x00000008, UnimplementedHemfRecord.class), - setwindowextex(0x00000009, UnimplementedHemfRecord.class), - setwindoworgex(0x0000000A, UnimplementedHemfRecord.class), - setviewportextex(0x0000000B, UnimplementedHemfRecord.class), - setviewportorgex(0x0000000C, UnimplementedHemfRecord.class), - setbrushorgex(0x0000000D, UnimplementedHemfRecord.class), - eof(0x0000000E, UnimplementedHemfRecord.class), - setpixelv(0x0000000F, UnimplementedHemfRecord.class), - setmapperflags(0x00000010, UnimplementedHemfRecord.class), - setmapmode(0x00000011, UnimplementedHemfRecord.class), - setbkmode(0x00000012, UnimplementedHemfRecord.class), - setpolyfillmode(0x00000013, UnimplementedHemfRecord.class), - setrop2(0x00000014, UnimplementedHemfRecord.class), - setstretchbltmode(0x00000015, UnimplementedHemfRecord.class), - settextalign(0x00000016, HemfText.SetTextAlign.class), - setcoloradjustment(0x00000017, UnimplementedHemfRecord.class), - settextcolor(0x00000018, HemfText.SetTextColor.class), - setbkcolor(0x00000019, UnimplementedHemfRecord.class), - setoffsetcliprgn(0x0000001A, UnimplementedHemfRecord.class), - setmovetoex(0x0000001B, UnimplementedHemfRecord.class), - setmetargn(0x0000001C, UnimplementedHemfRecord.class), - setexcludecliprect(0x0000001D, UnimplementedHemfRecord.class), - setintersectcliprect(0x0000001E, UnimplementedHemfRecord.class), - scaleviewportextex(0x0000001F, UnimplementedHemfRecord.class), - scalewindowextex(0x00000020, UnimplementedHemfRecord.class), - savedc(0x00000021, UnimplementedHemfRecord.class), - restoredc(0x00000022, UnimplementedHemfRecord.class), - setworldtransform(0x00000023, UnimplementedHemfRecord.class), - modifyworldtransform(0x00000024, UnimplementedHemfRecord.class), - selectobject(0x00000025, UnimplementedHemfRecord.class), - createpen(0x00000026, UnimplementedHemfRecord.class), - createbrushindirect(0x00000027, UnimplementedHemfRecord.class), - deleteobject(0x00000028, UnimplementedHemfRecord.class), - anglearc(0x00000029, UnimplementedHemfRecord.class), - ellipse(0x0000002A, UnimplementedHemfRecord.class), - rectangle(0x0000002B, UnimplementedHemfRecord.class), - roundirect(0x0000002C, UnimplementedHemfRecord.class), - arc(0x0000002D, UnimplementedHemfRecord.class), - chord(0x0000002E, UnimplementedHemfRecord.class), - pie(0x0000002F, UnimplementedHemfRecord.class), - selectpalette(0x00000030, UnimplementedHemfRecord.class), - createpalette(0x00000031, UnimplementedHemfRecord.class), - setpaletteentries(0x00000032, UnimplementedHemfRecord.class), - resizepalette(0x00000033, UnimplementedHemfRecord.class), - realizepalette(0x0000034, UnimplementedHemfRecord.class), - extfloodfill(0x00000035, UnimplementedHemfRecord.class), - lineto(0x00000036, UnimplementedHemfRecord.class), - arcto(0x00000037, UnimplementedHemfRecord.class), - polydraw(0x00000038, UnimplementedHemfRecord.class), - setarcdirection(0x00000039, UnimplementedHemfRecord.class), - setmiterlimit(0x0000003A, UnimplementedHemfRecord.class), - beginpath(0x0000003B, UnimplementedHemfRecord.class), - endpath(0x0000003C, UnimplementedHemfRecord.class), - closefigure(0x0000003D, UnimplementedHemfRecord.class), - fillpath(0x0000003E, UnimplementedHemfRecord.class), - strokeandfillpath(0x0000003F, UnimplementedHemfRecord.class), - strokepath(0x00000040, UnimplementedHemfRecord.class), - flattenpath(0x00000041, UnimplementedHemfRecord.class), - widenpath(0x00000042, UnimplementedHemfRecord.class), - selectclippath(0x00000043, UnimplementedHemfRecord.class), - abortpath(0x00000044, UnimplementedHemfRecord.class), //no 45?! - comment(0x00000046, HemfCommentRecord.class), - fillrgn(0x00000047, UnimplementedHemfRecord.class), - framergn(0x00000048, UnimplementedHemfRecord.class), - invertrgn(0x00000049, UnimplementedHemfRecord.class), - paintrgn(0x0000004A, UnimplementedHemfRecord.class), - extselectciprrgn(0x0000004B, UnimplementedHemfRecord.class), - bitblt(0x0000004C, UnimplementedHemfRecord.class), - stretchblt(0x0000004D, UnimplementedHemfRecord.class), - maskblt(0x0000004E, UnimplementedHemfRecord.class), - plgblt(0x0000004F, UnimplementedHemfRecord.class), - setbitstodevice(0x00000050, UnimplementedHemfRecord.class), - stretchdibits(0x00000051, UnimplementedHemfRecord.class), - extcreatefontindirectw(0x00000052, HemfText.ExtCreateFontIndirectW.class), - exttextouta(0x00000053, HemfText.ExtTextOutA.class), - exttextoutw(0x00000054, HemfText.ExtTextOutW.class), - polybezier16(0x00000055, UnimplementedHemfRecord.class), - polygon16(0x00000056, UnimplementedHemfRecord.class), - polyline16(0x00000057, UnimplementedHemfRecord.class), - polybezierto16(0x00000058, UnimplementedHemfRecord.class), - polylineto16(0x00000059, UnimplementedHemfRecord.class), - polypolyline16(0x0000005A, UnimplementedHemfRecord.class), - polypolygon16(0x0000005B, UnimplementedHemfRecord.class), - polydraw16(0x0000005C, UnimplementedHemfRecord.class), - createmonobrush16(0x0000005D, UnimplementedHemfRecord.class), - createdibpatternbrushpt(0x0000005E, UnimplementedHemfRecord.class), - extcreatepen(0x0000005F, UnimplementedHemfRecord.class), - polytextouta(0x00000060, HemfText.PolyTextOutA.class), - polytextoutw(0x00000061, HemfText.PolyTextOutW.class), - seticmmode(0x00000062, UnimplementedHemfRecord.class), - createcolorspace(0x00000063, UnimplementedHemfRecord.class), - setcolorspace(0x00000064, UnimplementedHemfRecord.class), - deletecolorspace(0x00000065, UnimplementedHemfRecord.class), - glsrecord(0x00000066, UnimplementedHemfRecord.class), - glsboundedrecord(0x00000067, UnimplementedHemfRecord.class), - pixelformat(0x00000068, UnimplementedHemfRecord.class), - drawescape(0x00000069, UnimplementedHemfRecord.class), - extescape(0x0000006A, UnimplementedHemfRecord.class),//no 6b?! - smalltextout(0x0000006C, UnimplementedHemfRecord.class), - forceufimapping(0x0000006D, UnimplementedHemfRecord.class), - namedescape(0x0000006E, UnimplementedHemfRecord.class), - colorcorrectpalette(0x0000006F, UnimplementedHemfRecord.class), - seticmprofilea(0x00000070, UnimplementedHemfRecord.class), - seticmprofilew(0x00000071, UnimplementedHemfRecord.class), - alphablend(0x00000072, UnimplementedHemfRecord.class), - setlayout(0x00000073, UnimplementedHemfRecord.class), - transparentblt(0x00000074, UnimplementedHemfRecord.class), - gradientfill(0x00000076, UnimplementedHemfRecord.class), //no 75?! - setlinkdufis(0x00000077, UnimplementedHemfRecord.class), - settextjustification(0x00000078, HemfText.SetTextJustification.class), - colormatchtargetw(0x00000079, UnimplementedHemfRecord.class), - createcolorspacew(0x0000007A, UnimplementedHemfRecord.class); + header(0x00000001, HemfHeader::new), + polyBezier(0x00000002, HemfDraw.EmfPolyBezier::new), + polygon(0x00000003, HemfDraw.EmfPolygon::new), + polyline(0x00000004, HemfDraw.EmfPolyline::new), + polyBezierTo(0x00000005, HemfDraw.EmfPolyBezierTo::new), + polylineTo(0x00000006, HemfDraw.EmfPolylineTo::new), + polyPolyline(0x00000007, HemfDraw.EmfPolyPolyline::new), + polyPolygon(0x00000008, HemfDraw.EmfPolyPolygon::new), + setWindowExtEx(0x00000009, HemfWindowing.EmfSetWindowExtEx::new), + setWindowOrgEx(0x0000000A, HemfWindowing.EmfSetWindowOrgEx::new), + setViewportExtEx(0x0000000B, HemfWindowing.EmfSetViewportExtEx::new), + setViewportOrgEx(0x0000000C, HemfWindowing.EmfSetViewportOrgEx::new), + setbrushorgex(0x0000000D, UnimplementedHemfRecord::new), + eof(0x0000000E, HemfMisc.EmfEof::new), + setPixelV(0x0000000F, HemfDraw.EmfSetPixelV::new), + setMapperFlags(0x00000010, HemfMisc.EmfSetMapperFlags::new), + setMapMode(0x00000011, HemfMisc.EmfSetMapMode::new), + setBkMode(0x00000012, HemfMisc.EmfSetBkMode::new), + setPolyfillMode(0x00000013, HemfFill.EmfSetPolyfillMode::new), + setRop2(0x00000014, HemfMisc.EmfSetRop2::new), + setStretchBltMode(0x00000015, HemfMisc.EmfSetStretchBltMode::new), + setTextAlign(0x00000016, HemfText.EmfSetTextAlign::new), + setcoloradjustment(0x00000017, UnimplementedHemfRecord::new), + setTextColor(0x00000018, HemfText.SetTextColor::new), + setBkColor(0x00000019, HemfMisc.EmfSetBkColor::new), + setOffsetClipRgn(0x0000001A, HemfWindowing.EmfSetOffsetClipRgn::new), + setMoveToEx(0x0000001B, HemfDraw.EmfSetMoveToEx::new), + setmetargn(0x0000001C, UnimplementedHemfRecord::new), + setExcludeClipRect(0x0000001D, HemfWindowing.EmfSetExcludeClipRect::new), + setIntersectClipRect(0x0000001E, HemfWindowing.EmfSetIntersectClipRect::new), + scaleViewportExtEx(0x0000001F, HemfWindowing.EmfScaleViewportExtEx::new), + scaleWindowExtEx(0x00000020, HemfWindowing.EmfScaleWindowExtEx::new), + saveDc(0x00000021, HemfMisc.EmfSaveDc::new), + restoreDc(0x00000022, HemfMisc.EmfRestoreDc::new), + setworldtransform(0x00000023, UnimplementedHemfRecord::new), + modifyworldtransform(0x00000024, UnimplementedHemfRecord::new), + selectObject(0x00000025, HemfDraw.EmfSelectObject::new), + createPen(0x00000026, HemfMisc.EmfCreatePen::new), + createBrushIndirect(0x00000027, HemfMisc.EmfCreateBrushIndirect::new), + deleteobject(0x00000028, HemfMisc.EmfDeleteObject::new), + anglearc(0x00000029, UnimplementedHemfRecord::new), + ellipse(0x0000002A, HemfDraw.EmfEllipse::new), + rectangle(0x0000002B, HemfDraw.EmfRectangle::new), + roundRect(0x0000002C, HemfDraw.EmfRoundRect::new), + arc(0x0000002D, HemfDraw.EmfArc::new), + chord(0x0000002E, HemfDraw.EmfChord::new), + pie(0x0000002F, HemfDraw.EmfPie::new), + selectPalette(0x00000030, HemfPalette.EmfSelectPalette::new), + createPalette(0x00000031, HemfPalette.EmfCreatePalette::new), + setPaletteEntries(0x00000032, HemfPalette.EmfSetPaletteEntries::new), + resizePalette(0x00000033, HemfPalette.EmfResizePalette::new), + realizePalette(0x0000034, HemfPalette.EmfRealizePalette::new), + extFloodFill(0x00000035, HemfFill.EmfExtFloodFill::new), + lineTo(0x00000036, HemfDraw.EmfLineTo::new), + arcTo(0x00000037, HemfDraw.EmfArcTo::new), + polyDraw(0x00000038, HemfDraw.EmfPolyDraw::new), + setarcdirection(0x00000039, UnimplementedHemfRecord::new), + setMiterLimit(0x0000003A, HemfMisc.EmfSetMiterLimit::new), + beginpath(0x0000003B, UnimplementedHemfRecord::new), + endpath(0x0000003C, UnimplementedHemfRecord::new), + closefigure(0x0000003D, UnimplementedHemfRecord::new), + fillpath(0x0000003E, UnimplementedHemfRecord::new), + strokeandfillpath(0x0000003F, UnimplementedHemfRecord::new), + strokepath(0x00000040, UnimplementedHemfRecord::new), + flattenpath(0x00000041, UnimplementedHemfRecord::new), + widenpath(0x00000042, UnimplementedHemfRecord::new), + selectclippath(0x00000043, UnimplementedHemfRecord::new), + abortpath(0x00000044, UnimplementedHemfRecord::new), + // no 45 ?! + comment(0x00000046, HemfComment.EmfComment::new), + fillRgn(0x00000047, HemfFill.EmfFillRgn::new), + frameRgn(0x00000048, HemfFill.EmfFrameRgn::new), + invertRgn(0x00000049, HemfFill.EmfInvertRgn::new), + paintRgn(0x0000004A, HemfFill.EmfPaintRgn::new), + extSelectClipRgn(0x0000004B, HemfFill.EmfExtSelectClipRgn::new), + bitBlt(0x0000004C, HemfFill.EmfBitBlt::new), + stretchBlt(0x0000004D, HemfFill.EmfStretchBlt::new), + maskblt(0x0000004E, UnimplementedHemfRecord::new), + plgblt(0x0000004F, UnimplementedHemfRecord::new), + setDiBitsToDevice(0x00000050, HemfFill.EmfSetDiBitsToDevice::new), + stretchdibits(0x00000051, UnimplementedHemfRecord::new), + extCreateFontIndirectW(0x00000052, HemfText.ExtCreateFontIndirectW::new), + exttextouta(0x00000053, HemfText.ExtTextOutA::new), + exttextoutw(0x00000054, HemfText.ExtTextOutW::new), + polyBezier16(0x00000055, HemfDraw.EmfPolyBezier16::new), + polygon16(0x00000056, HemfDraw.EmfPolygon16::new), + polyline16(0x00000057, HemfDraw.EmfPolyline16::new), + polyBezierTo16(0x00000058, HemfDraw.EmfPolyBezierTo16::new), + polylineTo16(0x00000059, HemfDraw.EmfPolylineTo16::new), + polyPolyline16(0x0000005A, HemfDraw.EmfPolyPolyline16::new), + polyPolygon16(0x0000005B, HemfDraw.EmfPolyPolygon16::new), + polyDraw16(0x0000005C, HemfDraw.EmfPolyDraw16::new), + createmonobrush16(0x0000005D, UnimplementedHemfRecord::new), + createdibpatternbrushpt(0x0000005E, UnimplementedHemfRecord::new), + extCreatePen(0x0000005F, HemfMisc.EmfExtCreatePen::new), + polytextouta(0x00000060, HemfText.PolyTextOutA::new), + polytextoutw(0x00000061, HemfText.PolyTextOutW::new), + seticmmode(0x00000062, UnimplementedHemfRecord::new), + createcolorspace(0x00000063, UnimplementedHemfRecord::new), + setcolorspace(0x00000064, UnimplementedHemfRecord::new), + deletecolorspace(0x00000065, UnimplementedHemfRecord::new), + glsrecord(0x00000066, UnimplementedHemfRecord::new), + glsboundedrecord(0x00000067, UnimplementedHemfRecord::new), + pixelformat(0x00000068, UnimplementedHemfRecord::new), + drawescape(0x00000069, UnimplementedHemfRecord::new), + extescape(0x0000006A, UnimplementedHemfRecord::new), + // no 6b ?! + smalltextout(0x0000006C, UnimplementedHemfRecord::new), + forceufimapping(0x0000006D, UnimplementedHemfRecord::new), + namedescape(0x0000006E, UnimplementedHemfRecord::new), + colorcorrectpalette(0x0000006F, UnimplementedHemfRecord::new), + seticmprofilea(0x00000070, UnimplementedHemfRecord::new), + seticmprofilew(0x00000071, UnimplementedHemfRecord::new), + alphaBlend(0x00000072, HemfFill.EmfAlphaBlend::new), + setlayout(0x00000073, UnimplementedHemfRecord::new), + transparentblt(0x00000074, UnimplementedHemfRecord::new), + // no 75 ?! + gradientfill(0x00000076, UnimplementedHemfRecord::new), + setlinkdufis(0x00000077, UnimplementedHemfRecord::new), + settextjustification(0x00000078, HemfText.SetTextJustification::new), + colormatchtargetw(0x00000079, UnimplementedHemfRecord::new), + createcolorspacew(0x0000007A, UnimplementedHemfRecord::new); + public final long id; - public final Class<? extends HemfRecord> clazz; + public final Supplier<? extends HemfRecord> constructor; - HemfRecordType(long id, Class<? extends HemfRecord> clazz) { + HemfRecordType(long id, Supplier<? extends HemfRecord> constructor) { this.id = id; - this.clazz = clazz; + this.constructor = constructor; } public static HemfRecordType getById(long id) {
Copied: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java (from r1840955, poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/HemfText.java) URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java?p2=poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java&p1=poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/HemfText.java&r1=1840955&r2=1840956&rev=1840956&view=diff ============================================================================== --- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/HemfText.java (original) +++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java Fri Sep 14 21:37:37 2018 @@ -15,20 +15,27 @@ limitations under the License. ==================================================================== */ -package org.apache.poi.hemf.record; +package org.apache.poi.hemf.record.emf; import static java.nio.charset.StandardCharsets.UTF_16LE; +import static org.apache.poi.hemf.record.emf.HemfDraw.readRectL; +import static org.apache.poi.hemf.record.emf.HemfDraw.readDimensionFloat; +import static org.apache.poi.hemf.record.emf.HemfDraw.readPointL; -import java.io.ByteArrayInputStream; -import java.io.EOFException; +import java.awt.geom.Dimension2D; +import java.awt.geom.Rectangle2D; import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import org.apache.poi.hwmf.record.HwmfColorRef; +import org.apache.poi.hwmf.record.HwmfText; +import org.apache.poi.hwmf.record.HwmfText.WmfSetTextAlign; +import org.apache.poi.util.Dimension2DDouble; import org.apache.poi.util.IOUtils; import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.LittleEndianConsts; import org.apache.poi.util.LittleEndianInputStream; import org.apache.poi.util.RecordFormatException; @@ -42,53 +49,56 @@ public class HemfText { private static final int MAX_RECORD_LENGTH = 1_000_000; - public static class ExtCreateFontIndirectW extends UnimplementedHemfRecord { + public enum EmfGraphicsMode { + GM_COMPATIBLE, GM_ADVANCED } public static class ExtTextOutA implements HemfRecord { - private long left,top,right,bottom; + protected final Rectangle2D boundsIgnored = new Rectangle2D.Double(); - //TODO: translate this to a graphicsmode enum - private long graphicsMode; + protected EmfGraphicsMode graphicsMode; - private long exScale; - private long eyScale; - EmrTextObject textObject; + /** + * The scale factor to apply along the X/Y axis to convert from page space units to .01mm units. + * This SHOULD be used only if the graphics mode specified by iGraphicsMode is GM_COMPATIBLE. + */ + protected final Dimension2D scale = new Dimension2DDouble(); + + protected final EmrTextObject textObject; + + public ExtTextOutA() { + this(false); + } + + protected ExtTextOutA(boolean isUnicode) { + textObject = new EmrTextObject(isUnicode); + } @Override - public HemfRecordType getRecordType() { + public HemfRecordType getEmfRecordType() { return HemfRecordType.exttextouta; } @Override - public long init(LittleEndianInputStream leis, long recordId, long recordSize) throws IOException { - //note that the first 2 uInts have been read off and the recordsize has - //been decreased by 8 - left = leis.readInt(); - top = leis.readInt(); - right = leis.readInt(); - bottom = leis.readInt(); - graphicsMode = leis.readUInt(); - exScale = leis.readUInt(); - eyScale = leis.readUInt(); - - int recordSizeInt = -1; - if (recordSize < Integer.MAX_VALUE) { - recordSizeInt = (int)recordSize; - } else { - throw new RecordFormatException("can't have text length > Integer.MAX_VALUE"); + public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException { + if (recordSize < 0 || Integer.MAX_VALUE <= recordSize) { + throw new RecordFormatException("recordSize must be a positive integer (0-0x7FFFFFFF)"); } - //guarantee to read the rest of the EMRTextObjectRecord - //emrtextbytes start after 7*4 bytes read above - byte[] emrTextBytes = IOUtils.safelyAllocate(recordSizeInt-(7*LittleEndian.INT_SIZE), MAX_RECORD_LENGTH); - IOUtils.readFully(leis, emrTextBytes); - textObject = new EmrTextObject(emrTextBytes, getEncodingHint(), 20);//should be 28, but recordSizeInt has already subtracted 8 - return recordSize; - } - protected Charset getEncodingHint() { - return null; + // A WMF RectL object. It is not used and MUST be ignored on receipt. + long size = readRectL(leis, boundsIgnored); + + // A 32-bit unsigned integer that specifies the graphics mode from the GraphicsMode enumeration + graphicsMode = EmfGraphicsMode.values()[leis.readInt()-1]; + size += LittleEndianConsts.INT_SIZE; + + size += readDimensionFloat(leis, scale); + + // guarantee to read the rest of the EMRTextObjectRecord + size += textObject.init(leis, recordSize, (int)size); + + return size; } /** @@ -111,58 +121,28 @@ public class HemfText { * * @return the x offset for the EmrTextObject */ - public long getX() { - return textObject.x; - } - - /** - * - * @return the y offset for the EmrTextObject - */ - public long getY() { - return textObject.y; - } - - public long getLeft() { - return left; - } - - public long getTop() { - return top; + public EmrTextObject getTextObject() { + return textObject; } - public long getRight() { - return right; - } - - public long getBottom() { - return bottom; - } - - public long getGraphicsMode() { + public EmfGraphicsMode getGraphicsMode() { return graphicsMode; } - public long getExScale() { - return exScale; - } - - public long getEyScale() { - return eyScale; + public Dimension2D getScale() { + return scale; } - } public static class ExtTextOutW extends ExtTextOutA { - @Override - public HemfRecordType getRecordType() { - return HemfRecordType.exttextoutw; + public ExtTextOutW() { + super(true); } @Override - protected Charset getEncodingHint() { - return UTF_16LE; + public HemfRecordType getEmfRecordType() { + return HemfRecordType.exttextoutw; } public String getText() throws IOException { @@ -171,92 +151,167 @@ public class HemfText { } /** - * Needs to be implemented. Couldn't find example. + * The EMR_SETTEXTALIGN record specifies text alignment. */ - public static class PolyTextOutA extends UnimplementedHemfRecord { + public static class EmfSetTextAlign extends WmfSetTextAlign implements HemfRecord { + @Override + public HemfRecordType getEmfRecordType() { + return HemfRecordType.setTextAlign; + } + @Override + public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException { + /** + * A 32-bit unsigned integer that specifies text alignment by using a mask of text alignment flags. + * These are either WMF TextAlignmentMode Flags for text with a horizontal baseline, + * or WMF VerticalTextAlignmentMode Flags for text with a vertical baseline. + * Only one value can be chosen from those that affect horizontal and vertical alignment. + */ + textAlignmentMode = (int)leis.readUInt(); + return LittleEndianConsts.INT_SIZE; + } } /** - * Needs to be implemented. Couldn't find example. + * The EMR_SETTEXTCOLOR record defines the current text color. */ - public static class PolyTextOutW extends UnimplementedHemfRecord { + public static class SetTextColor implements HemfRecord { + /** A WMF ColorRef object that specifies the text color value. */ + private final HwmfColorRef colorRef = new HwmfColorRef(); - } + @Override + public HemfRecordType getEmfRecordType() { + return HemfRecordType.setTextColor; + } - public static class SetTextAlign extends UnimplementedHemfRecord { + @Override + public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException { + return colorRef.init(leis); + } } - public static class SetTextColor extends UnimplementedHemfRecord { - } + public static class EmrTextObject extends HwmfText.WmfExtTextOut { + protected final boolean isUnicode; + protected final List<Integer> outputDx = new ArrayList<>(); + + public EmrTextObject(boolean isUnicode) { + super(new EmfExtTextOutOptions()); + this.isUnicode = isUnicode; + } + @Override + public int init(LittleEndianInputStream leis, final long recordSize, final int offset) throws IOException { + // A WMF PointL object that specifies the coordinates of the reference point used to position the string. + // The reference point is defined by the last EMR_SETTEXTALIGN record. + // If no such record has been set, the default alignment is TA_LEFT,TA_TOP. + long size = readPointL(leis, reference); + // A 32-bit unsigned integer that specifies the number of characters in the string. + stringLength = (int)leis.readUInt(); + // A 32-bit unsigned integer that specifies the offset to the output string, in bytes, + // from the start of the record in which this object is contained. + // This value MUST be 8- or 16-bit aligned, according to the character format. + int offString = (int)leis.readUInt(); + size += 2*LittleEndianConsts.INT_SIZE; + + size += options.init(leis); + // An optional WMF RectL object that defines a clipping and/or opaquing rectangle in logical units. + // This rectangle is applied to the text output performed by the containing record. + if (options.isClipped() || options.isOpaque()) { + size += readRectL(leis, bounds); + } - public static class SetTextJustification extends UnimplementedHemfRecord { + // A 32-bit unsigned integer that specifies the offset to an intercharacter spacing array, in bytes, + // from the start of the record in which this object is contained. This value MUST be 32-bit aligned. + int offDx = (int)leis.readUInt(); + size += LittleEndianConsts.INT_SIZE; + + int undefinedSpace1 = (int)(offString-offset-size-2*LittleEndianConsts.INT_SIZE); + assert (undefinedSpace1 >= 0); + leis.skipFully(undefinedSpace1); + size += undefinedSpace1; + + rawTextBytes = IOUtils.safelyAllocate(stringLength*(isUnicode?2:1), MAX_RECORD_LENGTH); + leis.readFully(rawTextBytes); + size += rawTextBytes.length; + + outputDx.clear(); + if (offDx > 0) { + int undefinedSpace2 = (int) (offDx - offset - size - 2 * LittleEndianConsts.INT_SIZE); + assert (undefinedSpace2 >= 0); + leis.skipFully(undefinedSpace2); + size += undefinedSpace2; + + // An array of 32-bit unsigned integers that specify the output spacing between the origins of adjacent + // character cells in logical units. The location of this field is specified by the value of offDx + // in bytes from the start of this record. If spacing is defined, this field contains the same number + // of values as characters in the output string. + // + // If the Options field of the EmrText object contains the ETO_PDY flag, then this buffer + // contains twice as many values as there are characters in the output string, one + // horizontal and one vertical offset for each, in that order. + // + // If ETO_RTLREADING is specified, characters are laid right to left instead of left to right. + // No other options affect the interpretation of this field. + while (size < recordSize) { + outputDx.add((int) leis.readUInt()); + size += LittleEndianConsts.INT_SIZE; + } + } + return (int)size; + } } - private static class EmrTextObject { - long x; - long y; - int numChars; - byte[] rawTextBytes;//this stores _all_ of the bytes to the end of the EMRTextObject record. - //Because of potential variable length encodings, must - //carefully read only the numChars from this byte array. - - EmrTextObject(byte[] emrTextObjBytes, Charset charsetHint, int readSoFar) throws IOException { - - int offset = 0; - x = LittleEndian.getUInt(emrTextObjBytes, offset); offset+= LittleEndian.INT_SIZE; - y = LittleEndian.getUInt(emrTextObjBytes, offset); offset+= LittleEndian.INT_SIZE; - long numCharsLong = LittleEndian.getUInt(emrTextObjBytes, offset); offset += LittleEndian.INT_SIZE; - long offString = LittleEndian.getUInt(emrTextObjBytes, offset); offset += LittleEndian.INT_SIZE; - int start = (int)offString-offset-readSoFar; - - if (numCharsLong == 0) { - rawTextBytes = new byte[0]; - numChars = 0; - return; - } - if (numCharsLong > Integer.MAX_VALUE) { - throw new RecordFormatException("Number of characters can't be > Integer.MAX_VALUE"); - } else if (numCharsLong < 0) { - throw new RecordFormatException("Number of characters can't be < 0"); - } - numChars = (int)numCharsLong; - rawTextBytes = IOUtils.safelyAllocate(emrTextObjBytes.length-start, MAX_RECORD_LENGTH); - System.arraycopy(emrTextObjBytes, start, rawTextBytes, 0, emrTextObjBytes.length-start); + public static class ExtCreateFontIndirectW extends HwmfText.WmfCreateFontIndirect + implements HemfRecord { + int fontIdx; + + public ExtCreateFontIndirectW() { + super(new HemfFont()); } - String getText(Charset charset) throws IOException { - StringBuilder sb = new StringBuilder(); - try (Reader r = new InputStreamReader(new ByteArrayInputStream(rawTextBytes), charset)) { - for (int i = 0; i < numChars; i++) { - sb.appendCodePoint(readCodePoint(r)); - } - } - return sb.toString(); + @Override + public HemfRecordType getEmfRecordType() { + return HemfRecordType.extCreateFontIndirectW; } - //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); + @Override + public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException { + // A 32-bit unsigned integer that specifies the index of the logical font object + // in the EMF Object Table + fontIdx = (int)leis.readUInt(); + int size = font.init(leis, (int)(recordSize-LittleEndianConsts.INT_SIZE)); + return size+LittleEndianConsts.INT_SIZE; } } + public static class EmfExtTextOutOptions extends HwmfText.WmfExtTextOutOptions { + @Override + public int init(LittleEndianInputStream leis) { + // A 32-bit unsigned integer that specifies how to use the rectangle specified in the Rectangle field. + // This field can be a combination of more than one ExtTextOutOptions enumeration + flag = (int)leis.readUInt(); + return LittleEndianConsts.INT_SIZE; + } + } + + public static class SetTextJustification extends UnimplementedHemfRecord { + + } + + /** + * Needs to be implemented. Couldn't find example. + */ + public static class PolyTextOutA extends UnimplementedHemfRecord { + + } + + /** + * Needs to be implemented. Couldn't find example. + */ + public static class PolyTextOutW extends UnimplementedHemfRecord { + + } } Added: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfWindowing.java URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfWindowing.java?rev=1840956&view=auto ============================================================================== --- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfWindowing.java (added) +++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfWindowing.java Fri Sep 14 21:37:37 2018 @@ -0,0 +1,200 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hemf.record.emf; + +import java.io.IOException; + +import org.apache.poi.hwmf.record.HwmfWindowing; +import org.apache.poi.util.LittleEndianConsts; +import org.apache.poi.util.LittleEndianInputStream; + +public class HemfWindowing { + + /** + * The EMR_SETWINDOWEXTEX record defines the window extent. + */ + public static class EmfSetWindowExtEx extends HwmfWindowing.WmfSetWindowExt implements HemfRecord { + @Override + public HemfRecordType getEmfRecordType() { + return HemfRecordType.setWindowExtEx; + } + + @Override + public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException { + // cx (4 bytes): A 32-bit unsigned integer that defines the x-coordinate of the point. + width = (int)leis.readUInt(); + // cy (4 bytes): A 32-bit unsigned integer that defines the y-coordinate of the point. + height = (int)leis.readUInt(); + + return 2*LittleEndianConsts.INT_SIZE; + } + } + + /** + * The EMR_SETWINDOWORGEX record defines the window origin. + */ + public static class EmfSetWindowOrgEx extends HwmfWindowing.WmfSetWindowOrg implements HemfRecord { + @Override + public HemfRecordType getEmfRecordType() { + return HemfRecordType.setWindowOrgEx; + } + + @Override + public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException { + // x (4 bytes): A 32-bit signed integer that defines the horizontal (x) coordinate of the point. + x = leis.readInt(); + // y (4 bytes): A 32-bit signed integer that defines the vertical (y) coordinate of the point. + y = leis.readInt(); + + return 2*LittleEndianConsts.INT_SIZE; + } + } + + /** + * The EMR_SETVIEWPORTEXTEX record defines the viewport extent. + */ + public static class EmfSetViewportExtEx extends HwmfWindowing.WmfSetViewportExt implements HemfRecord { + @Override + public HemfRecordType getEmfRecordType() { + return HemfRecordType.setViewportExtEx; + } + + @Override + public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException { + // cx (4 bytes): A 32-bit unsigned integer that defines the x-coordinate of the point. + width = (int)leis.readUInt(); + // cy (4 bytes): A 32-bit unsigned integer that defines the y-coordinate of the point. + height = (int)leis.readUInt(); + + return 2*LittleEndianConsts.INT_SIZE; + } + } + + /** + * The EMR_SETVIEWPORTORGEX record defines the viewport origin. + */ + public static class EmfSetViewportOrgEx extends HwmfWindowing.WmfSetViewportOrg implements HemfRecord { + @Override + public HemfRecordType getEmfRecordType() { + return HemfRecordType.setViewportOrgEx; + } + + @Override + public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException { + // x (4 bytes): A 32-bit signed integer that defines the horizontal (x) coordinate of the point. + x = leis.readInt(); + // y (4 bytes): A 32-bit signed integer that defines the vertical (y) coordinate of the point. + y = leis.readInt(); + + return 2*LittleEndianConsts.INT_SIZE; + } + } + + /** + * The EMR_OFFSETCLIPRGN record moves the current clipping region in the playback device context + * by the specified offsets. + */ + public static class EmfSetOffsetClipRgn extends HwmfWindowing.WmfOffsetClipRgn implements HemfRecord { + @Override + public HemfRecordType getEmfRecordType() { + return HemfRecordType.setOffsetClipRgn; + } + + @Override + public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException { + // x (4 bytes): A 32-bit signed integer that defines the horizontal (x) coordinate of the point. + xOffset = leis.readInt(); + // y (4 bytes): A 32-bit signed integer that defines the vertical (y) coordinate of the point. + yOffset = leis.readInt(); + + return 2*LittleEndianConsts.INT_SIZE; + } + } + + /** + * The EMR_EXCLUDECLIPRECT record specifies a new clipping region that consists of the existing + * clipping region minus the specified rectangle. + */ + public static class EmfSetExcludeClipRect extends HwmfWindowing.WmfExcludeClipRect implements HemfRecord { + @Override + public HemfRecordType getEmfRecordType() { + return HemfRecordType.setExcludeClipRect; + } + + @Override + public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException { + return HemfDraw.readRectL(leis, bounds); + } + } + + /** + * The EMR_INTERSECTCLIPRECT record specifies a new clipping region from the intersection of the + * current clipping region and the specified rectangle. + */ + public static class EmfSetIntersectClipRect extends HwmfWindowing.WmfIntersectClipRect implements HemfRecord { + @Override + public HemfRecordType getEmfRecordType() { + return HemfRecordType.setIntersectClipRect; + } + + @Override + public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException { + return HemfDraw.readRectL(leis, bounds); + } + } + + /** + * The EMR_SCALEVIEWPORTEXTEX record respecifies the viewport for a device context by using the + * ratios formed by the specified multiplicands and divisors. + */ + public static class EmfScaleViewportExtEx extends HwmfWindowing.WmfScaleViewportExt implements HemfRecord { + @Override + public HemfRecordType getEmfRecordType() { + return HemfRecordType.scaleViewportExtEx; + } + + @Override + public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException { + xNum = leis.readInt(); + xDenom = leis.readInt(); + yNum = leis.readInt(); + yDenom = leis.readInt(); + return 4*LittleEndianConsts.INT_SIZE; + } + } + + /** + * The EMR_SCALEWINDOWEXTEX record respecifies the window for a playback device context by + * using the ratios formed by the specified multiplicands and divisors. + */ + public static class EmfScaleWindowExtEx extends HwmfWindowing.WmfScaleWindowExt implements HemfRecord { + @Override + public HemfRecordType getEmfRecordType() { + return HemfRecordType.scaleWindowExtEx; + } + + @Override + public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException { + xNum = leis.readInt(); + xDenom = leis.readInt(); + yNum = leis.readInt(); + yDenom = leis.readInt(); + return 4*LittleEndianConsts.INT_SIZE; + } + } +} Propchange: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfWindowing.java ------------------------------------------------------------------------------ svn:eol-style = native Copied: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/UnimplementedHemfRecord.java (from r1840955, poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/UnimplementedHemfRecord.java) URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/UnimplementedHemfRecord.java?p2=poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/UnimplementedHemfRecord.java&p1=poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/UnimplementedHemfRecord.java&r1=1840955&r2=1840956&rev=1840956&view=diff ============================================================================== --- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/UnimplementedHemfRecord.java (original) +++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/UnimplementedHemfRecord.java Fri Sep 14 21:37:37 2018 @@ -15,7 +15,7 @@ limitations under the License. ==================================================================== */ -package org.apache.poi.hemf.record; +package org.apache.poi.hemf.record.emf; import java.io.IOException; @@ -33,12 +33,12 @@ public class UnimplementedHemfRecord imp } @Override - public HemfRecordType getRecordType() { + public HemfRecordType getEmfRecordType() { return HemfRecordType.getById(recordId); } @Override - public long init(LittleEndianInputStream leis, long recordId, long recordSize) throws IOException { + public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException { this.recordId = recordId; long skipped = IOUtils.skipFully(leis, recordSize); if (skipped < recordSize) { Copied: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusHeader.java (from r1840955, poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/hemfplus/record/HemfPlusHeader.java) URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusHeader.java?p2=poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusHeader.java&p1=poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/hemfplus/record/HemfPlusHeader.java&r1=1840955&r2=1840956&rev=1840956&view=diff ============================================================================== --- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/hemfplus/record/HemfPlusHeader.java (original) +++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusHeader.java Fri Sep 14 21:37:37 2018 @@ -15,13 +15,14 @@ limitations under the License. ==================================================================== */ -package org.apache.poi.hemf.hemfplus.record; +package org.apache.poi.hemf.record.emfplus; import java.io.IOException; import org.apache.poi.util.Internal; -import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.LittleEndianConsts; +import org.apache.poi.util.LittleEndianInputStream; @Internal public class HemfPlusHeader implements HemfPlusRecord { @@ -42,15 +43,19 @@ public class HemfPlusHeader implements H } @Override - public void init(byte[] dataBytes, int recordId, int flags) throws IOException { - //assert record id == header + public long init(LittleEndianInputStream leis, long dataSize, long recordId, int flags) throws IOException { this.flags = flags; - int offset = 0; - this.version = LittleEndian.getUInt(dataBytes, offset); offset += LittleEndian.INT_SIZE; - this.emfPlusFlags = LittleEndian.getUInt(dataBytes, offset); offset += LittleEndian.INT_SIZE; - this.logicalDpiX = LittleEndian.getUInt(dataBytes, offset); offset += LittleEndian.INT_SIZE; - this.logicalDpiY = LittleEndian.getUInt(dataBytes, offset); + version = leis.readUInt(); + // verify MetafileSignature (20 bits) == 0xDBC01 and + // GraphicsVersion (12 bits) in (1 or 2) + assert((version & 0xFFFFFA00) == 0xDBC01000L && ((version & 0x3FF) == 1 || (version & 0x3FF) == 2)); + + emfPlusFlags = leis.readUInt(); + + logicalDpiX = leis.readUInt(); + logicalDpiY = leis.readUInt(); + return 4* LittleEndianConsts.INT_SIZE; } public long getVersion() { @@ -79,4 +84,4 @@ public class HemfPlusHeader implements H ", logicalDpiY=" + logicalDpiY + '}'; } -} +} \ No newline at end of file Copied: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecord.java (from r1840955, poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/hemfplus/record/HemfPlusRecord.java) URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecord.java?p2=poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecord.java&p1=poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/hemfplus/record/HemfPlusRecord.java&r1=1840955&r2=1840956&rev=1840956&view=diff ============================================================================== --- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/hemfplus/record/HemfPlusRecord.java (original) +++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecord.java Fri Sep 14 21:37:37 2018 @@ -15,12 +15,14 @@ limitations under the License. ==================================================================== */ -package org.apache.poi.hemf.hemfplus.record; +package org.apache.poi.hemf.record.emfplus; import java.io.IOException; +import org.apache.poi.hemf.record.emf.HemfRecordType; import org.apache.poi.util.Internal; +import org.apache.poi.util.LittleEndianInputStream; @Internal public interface HemfPlusRecord { @@ -30,15 +32,17 @@ public interface HemfPlusRecord { int getFlags(); /** + * Init record from stream * - * @param dataBytes these are the bytes that start after the id, flags, record size - * and go to the end of the record; they do not include any required padding - * at the end. - * @param recordId record type id - * @param flags flags - * @throws IOException, RecordFormatException + * @param leis the little endian input stream + * @param dataSize the size limit for this record + * @param recordId the id of the {@link HemfPlusRecordType} + * @param flags the record flags + * + * @return count of processed bytes + * + * @throws IOException when the inputstream is malformed */ - void init(byte[] dataBytes, int recordId, int flags) throws IOException; - + long init(LittleEndianInputStream leis, long dataSize, long recordId, int flags) throws IOException; } Added: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecordIterator.java URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecordIterator.java?rev=1840956&view=auto ============================================================================== --- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecordIterator.java (added) +++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecordIterator.java Fri Sep 14 21:37:37 2018 @@ -0,0 +1,98 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hemf.record.emfplus; + +import java.io.IOException; +import java.util.Iterator; + +import org.apache.poi.util.LittleEndianInputStream; +import org.apache.poi.util.RecordFormatException; + +public class HemfPlusRecordIterator implements Iterator<HemfPlusRecord> { + + private final LittleEndianInputStream leis; + private final int startIdx; + private final int limit; + private HemfPlusRecord currentRecord; + + public HemfPlusRecordIterator(LittleEndianInputStream leis) { + this(leis, -1); + } + + public HemfPlusRecordIterator(LittleEndianInputStream leis, int limit) { + this.leis = leis; + this.limit = limit; + startIdx = leis.getReadIndex(); + //queue the first non-header record + currentRecord = _next(); + } + + @Override + public boolean hasNext() { + return currentRecord != null; + } + + @Override + public HemfPlusRecord next() { + HemfPlusRecord toReturn = currentRecord; + final boolean isEOF = (limit == -1 || leis.getReadIndex()-startIdx >= limit); + // (currentRecord instanceof HemfPlusMisc.EmfEof) + currentRecord = isEOF ? null : _next(); + return toReturn; + } + + private HemfPlusRecord _next() { + if (currentRecord != null && HemfPlusRecordType.eof == currentRecord.getRecordType()) { + return null; + } + // A 16-bit unsigned integer that identifies this record type + int recordId = leis.readUShort(); + // A 16-bit unsigned integer that provides information about how the operation is + // to be performed, and about the structure of the record. + int flags = leis.readUShort(); + // A 32-bit unsigned integer that specifies the 32-bit-aligned size of the entire + // record in bytes, including the 12-byte record header and record-specific data. + int recordSize = (int)leis.readUInt(); + // A 32-bit unsigned integer that specifies the 32-bit-aligned number of bytes of data + // in the record-specific data that follows. This number does not include the size of + // the invariant part of this record. + int dataSize = (int)leis.readUInt(); + + HemfPlusRecordType type = HemfPlusRecordType.getById(recordId); + if (type == null) { + throw new RecordFormatException("Undefined record of type:"+recordId); + } + final HemfPlusRecord record = type.constructor.get(); + + try { + long readBytes = record.init(leis, dataSize, recordId, flags); + assert (readBytes <= recordSize-12); + leis.skipFully((int)(recordSize-12-readBytes)); + } catch (IOException e) { + throw new RecordFormatException(e); + } + + return record; + } + + @Override + public void remove() { + throw new UnsupportedOperationException("Remove not supported"); + } + +} Propchange: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecordIterator.java ------------------------------------------------------------------------------ svn:eol-style = native Copied: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecordType.java (from r1840955, poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/hemfplus/record/HemfPlusRecordType.java) URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecordType.java?p2=poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecordType.java&p1=poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/hemfplus/record/HemfPlusRecordType.java&r1=1840955&r2=1840956&rev=1840956&view=diff ============================================================================== --- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/hemfplus/record/HemfPlusRecordType.java (original) +++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecordType.java Fri Sep 14 21:37:37 2018 @@ -15,77 +15,80 @@ limitations under the License. ==================================================================== */ -package org.apache.poi.hemf.hemfplus.record; +package org.apache.poi.hemf.record.emfplus; + +import java.util.function.Supplier; import org.apache.poi.util.Internal; @Internal public enum HemfPlusRecordType { - header(0x4001, HemfPlusHeader.class), - endOfFile(0x4002, UnimplementedHemfPlusRecord.class), - comment(0x4003, UnimplementedHemfPlusRecord.class), - getDC(0x4004, UnimplementedHemfPlusRecord.class), - multiFormatStart(0x4005, UnimplementedHemfPlusRecord.class), - multiFormatSection(0x4006, UnimplementedHemfPlusRecord.class), - multiFormatEnd(0x4007, UnimplementedHemfPlusRecord.class), - object(0x4008, UnimplementedHemfPlusRecord.class), - clear(0x4009, UnimplementedHemfPlusRecord.class), - fillRects(0x400A, UnimplementedHemfPlusRecord.class), - drawRects(0x400B, UnimplementedHemfPlusRecord.class), - fillPolygon(0x400C, UnimplementedHemfPlusRecord.class), - drawLines(0x400D, UnimplementedHemfPlusRecord.class), - fillEllipse(0x400E, UnimplementedHemfPlusRecord.class), - drawEllipse(0x400F, UnimplementedHemfPlusRecord.class), - fillPie(0x4010, UnimplementedHemfPlusRecord.class), - drawPie(0x4011, UnimplementedHemfPlusRecord.class), - drawArc(0x4012, UnimplementedHemfPlusRecord.class), - fillRegion(0x4013, UnimplementedHemfPlusRecord.class), - fillPath(0x4014, UnimplementedHemfPlusRecord.class), - drawPath(0x4015, UnimplementedHemfPlusRecord.class), - fillClosedCurve(0x4016, UnimplementedHemfPlusRecord.class), - drawClosedCurve(0x4017, UnimplementedHemfPlusRecord.class), - drawCurve(0x4018, UnimplementedHemfPlusRecord.class), - drawBeziers(0x4019, UnimplementedHemfPlusRecord.class), - drawImage(0x401A, UnimplementedHemfPlusRecord.class), - drawImagePoints(0x401B, UnimplementedHemfPlusRecord.class), - drawString(0x401C, UnimplementedHemfPlusRecord.class), - setRenderingOrigin(0x401D, UnimplementedHemfPlusRecord.class), - setAntiAliasMode(0x401E, UnimplementedHemfPlusRecord.class), - setTextRenderingHint(0x401F, UnimplementedHemfPlusRecord.class), - setTextContrast(0x4020, UnimplementedHemfPlusRecord.class), - setInterpolationMode(0x4021, UnimplementedHemfPlusRecord.class), - setPixelOffsetMode(0x4022, UnimplementedHemfPlusRecord.class), - setComositingMode(0x4023, UnimplementedHemfPlusRecord.class), - setCompositingQuality(0x4024, UnimplementedHemfPlusRecord.class), - save(0x4025, UnimplementedHemfPlusRecord.class), - restore(0x4026, UnimplementedHemfPlusRecord.class), - beginContainer(0x4027, UnimplementedHemfPlusRecord.class), - beginContainerNoParams(0x428, UnimplementedHemfPlusRecord.class), - endContainer(0x4029, UnimplementedHemfPlusRecord.class), - setWorldTransform(0x402A, UnimplementedHemfPlusRecord.class), - resetWorldTransform(0x402B, UnimplementedHemfPlusRecord.class), - multiplyWorldTransform(0x402C, UnimplementedHemfPlusRecord.class), - translateWorldTransform(0x402D, UnimplementedHemfPlusRecord.class), - scaleWorldTransform(0x402E, UnimplementedHemfPlusRecord.class), - rotateWorldTransform(0x402F, UnimplementedHemfPlusRecord.class), - setPageTransform(0x4030, UnimplementedHemfPlusRecord.class), - resetClip(0x4031, UnimplementedHemfPlusRecord.class), - setClipRect(0x4032, UnimplementedHemfPlusRecord.class), - setClipRegion(0x4033, UnimplementedHemfPlusRecord.class), - setClipPath(0x4034, UnimplementedHemfPlusRecord.class), - offsetClip(0x4035, UnimplementedHemfPlusRecord.class), - drawDriverstring(0x4036, UnimplementedHemfPlusRecord.class), - strokeFillPath(0x4037, UnimplementedHemfPlusRecord.class), - serializableObject(0x4038, UnimplementedHemfPlusRecord.class), - setTSGraphics(0x4039, UnimplementedHemfPlusRecord.class), - setTSClip(0x403A, UnimplementedHemfPlusRecord.class); + header(0x4001, HemfPlusHeader::new), + eof(0x4002, UnimplementedHemfPlusRecord::new), + comment(0x4003, UnimplementedHemfPlusRecord::new), + getDC(0x4004, UnimplementedHemfPlusRecord::new), + multiFormatStart(0x4005, UnimplementedHemfPlusRecord::new), + multiFormatSection(0x4006, UnimplementedHemfPlusRecord::new), + multiFormatEnd(0x4007, UnimplementedHemfPlusRecord::new), + object(0x4008, UnimplementedHemfPlusRecord::new), + clear(0x4009, UnimplementedHemfPlusRecord::new), + fillRects(0x400A, UnimplementedHemfPlusRecord::new), + drawRects(0x400B, UnimplementedHemfPlusRecord::new), + fillPolygon(0x400C, UnimplementedHemfPlusRecord::new), + drawLines(0x400D, UnimplementedHemfPlusRecord::new), + fillEllipse(0x400E, UnimplementedHemfPlusRecord::new), + drawEllipse(0x400F, UnimplementedHemfPlusRecord::new), + fillPie(0x4010, UnimplementedHemfPlusRecord::new), + drawPie(0x4011, UnimplementedHemfPlusRecord::new), + drawArc(0x4012, UnimplementedHemfPlusRecord::new), + fillRegion(0x4013, UnimplementedHemfPlusRecord::new), + fillPath(0x4014, UnimplementedHemfPlusRecord::new), + drawPath(0x4015, UnimplementedHemfPlusRecord::new), + fillClosedCurve(0x4016, UnimplementedHemfPlusRecord::new), + drawClosedCurve(0x4017, UnimplementedHemfPlusRecord::new), + drawCurve(0x4018, UnimplementedHemfPlusRecord::new), + drawBeziers(0x4019, UnimplementedHemfPlusRecord::new), + drawImage(0x401A, UnimplementedHemfPlusRecord::new), + drawImagePoints(0x401B, UnimplementedHemfPlusRecord::new), + drawString(0x401C, UnimplementedHemfPlusRecord::new), + setRenderingOrigin(0x401D, UnimplementedHemfPlusRecord::new), + setAntiAliasMode(0x401E, UnimplementedHemfPlusRecord::new), + setTextRenderingHint(0x401F, UnimplementedHemfPlusRecord::new), + setTextContrast(0x4020, UnimplementedHemfPlusRecord::new), + setInterpolationMode(0x4021, UnimplementedHemfPlusRecord::new), + setPixelOffsetMode(0x4022, UnimplementedHemfPlusRecord::new), + setComositingMode(0x4023, UnimplementedHemfPlusRecord::new), + setCompositingQuality(0x4024, UnimplementedHemfPlusRecord::new), + save(0x4025, UnimplementedHemfPlusRecord::new), + restore(0x4026, UnimplementedHemfPlusRecord::new), + beginContainer(0x4027, UnimplementedHemfPlusRecord::new), + beginContainerNoParams(0x428, UnimplementedHemfPlusRecord::new), + endContainer(0x4029, UnimplementedHemfPlusRecord::new), + setWorldTransform(0x402A, UnimplementedHemfPlusRecord::new), + resetWorldTransform(0x402B, UnimplementedHemfPlusRecord::new), + multiplyWorldTransform(0x402C, UnimplementedHemfPlusRecord::new), + translateWorldTransform(0x402D, UnimplementedHemfPlusRecord::new), + scaleWorldTransform(0x402E, UnimplementedHemfPlusRecord::new), + rotateWorldTransform(0x402F, UnimplementedHemfPlusRecord::new), + setPageTransform(0x4030, UnimplementedHemfPlusRecord::new), + resetClip(0x4031, UnimplementedHemfPlusRecord::new), + setClipRect(0x4032, UnimplementedHemfPlusRecord::new), + setClipRegion(0x4033, UnimplementedHemfPlusRecord::new), + setClipPath(0x4034, UnimplementedHemfPlusRecord::new), + offsetClip(0x4035, UnimplementedHemfPlusRecord::new), + drawDriverstring(0x4036, UnimplementedHemfPlusRecord::new), + strokeFillPath(0x4037, UnimplementedHemfPlusRecord::new), + serializableObject(0x4038, UnimplementedHemfPlusRecord::new), + setTSGraphics(0x4039, UnimplementedHemfPlusRecord::new), + setTSClip(0x403A, UnimplementedHemfPlusRecord::new); + public final long id; - public final Class<? extends HemfPlusRecord> clazz; + public final Supplier<? extends HemfPlusRecord> constructor; - HemfPlusRecordType(long id, Class<? extends HemfPlusRecord> clazz) { + HemfPlusRecordType(long id, Supplier<? extends HemfPlusRecord> constructor) { this.id = id; - this.clazz = clazz; + this.constructor = constructor; } public static HemfPlusRecordType getById(long id) { Copied: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/UnimplementedHemfPlusRecord.java (from r1840955, poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/hemfplus/record/UnimplementedHemfPlusRecord.java) URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/UnimplementedHemfPlusRecord.java?p2=poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/UnimplementedHemfPlusRecord.java&p1=poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/hemfplus/record/UnimplementedHemfPlusRecord.java&r1=1840955&r2=1840956&rev=1840956&view=diff ============================================================================== --- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/hemfplus/record/UnimplementedHemfPlusRecord.java (original) +++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/UnimplementedHemfPlusRecord.java Fri Sep 14 21:37:37 2018 @@ -15,17 +15,21 @@ limitations under the License. ==================================================================== */ -package org.apache.poi.hemf.hemfplus.record; +package org.apache.poi.hemf.record.emfplus; import java.io.IOException; +import org.apache.poi.util.IOUtils; import org.apache.poi.util.Internal; +import org.apache.poi.util.LittleEndianInputStream; @Internal public class UnimplementedHemfPlusRecord implements HemfPlusRecord { - private int recordId; + private static final int MAX_RECORD_LENGTH = 1_000_000; + + private long recordId; private int flags; private byte[] recordBytes; @@ -40,14 +44,16 @@ public class UnimplementedHemfPlusRecord } @Override - public void init(byte[] recordBytes, int recordId, int flags) throws IOException { + public long init(LittleEndianInputStream leis, long dataSize, long recordId, int flags) throws IOException { this.recordId = recordId; this.flags = flags; - this.recordBytes = recordBytes; + recordBytes = IOUtils.safelyAllocate(dataSize, MAX_RECORD_LENGTH); + leis.readFully(recordBytes); + return recordBytes.length; } public byte[] getRecordBytes() { //should probably defensively return a copy. return recordBytes; } -} +} \ No newline at end of file Copied: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/usermodel/HemfPicture.java (from r1840385, poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/extractor/HemfExtractor.java) URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/usermodel/HemfPicture.java?p2=poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/usermodel/HemfPicture.java&p1=poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/extractor/HemfExtractor.java&r1=1840385&r2=1840956&rev=1840956&view=diff ============================================================================== --- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/extractor/HemfExtractor.java (original) +++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/usermodel/HemfPicture.java Fri Sep 14 21:37:37 2018 @@ -15,101 +15,63 @@ limitations under the License. ==================================================================== */ -package org.apache.poi.hemf.extractor; +package org.apache.poi.hemf.usermodel; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.Iterator; - -import org.apache.poi.hemf.record.HemfHeader; -import org.apache.poi.hemf.record.HemfRecord; -import org.apache.poi.hemf.record.HemfRecordType; +import java.util.List; +import java.util.Spliterator; +import java.util.function.Consumer; + +import org.apache.poi.hemf.record.emf.HemfHeader; +import org.apache.poi.hemf.record.emf.HemfRecord; +import org.apache.poi.hemf.record.emf.HemfRecordIterator; import org.apache.poi.util.Internal; import org.apache.poi.util.LittleEndianInputStream; -import org.apache.poi.util.RecordFormatException; /** * Read-only EMF extractor. Lots remain */ @Internal -public class HemfExtractor implements Iterable<HemfRecord> { +public class HemfPicture implements Iterable<HemfRecord> { - private HemfHeader header; private final LittleEndianInputStream stream; + private final List<HemfRecord> records = new ArrayList<>(); - public HemfExtractor(InputStream is) throws IOException { - stream = new LittleEndianInputStream(is); - header = new HemfHeader(); - long recordId = stream.readUInt(); - long recordSize = stream.readUInt(); - - header = new HemfHeader(); - header.init(stream, recordId, recordSize-8); + public HemfPicture(InputStream is) throws IOException { + this(new LittleEndianInputStream(is)); } - @Override - public Iterator<HemfRecord> iterator() { - return new HemfRecordIterator(); + public HemfPicture(LittleEndianInputStream is) throws IOException { + stream = is; } public HemfHeader getHeader() { - return header; + return (HemfHeader)getRecords().get(0); } - private class HemfRecordIterator implements Iterator<HemfRecord> { - - private HemfRecord currentRecord; - - HemfRecordIterator() { - //queue the first non-header record - currentRecord = _next(); - } - - @Override - public boolean hasNext() { - return currentRecord != null; - } - - @Override - public HemfRecord next() { - HemfRecord toReturn = currentRecord; - currentRecord = _next(); - return toReturn; + public List<HemfRecord> getRecords() { + if (records.isEmpty()) { + new HemfRecordIterator(stream).forEachRemaining(records::add); } + return records; + } - private HemfRecord _next() { - if (currentRecord != null && currentRecord.getRecordType().equals(HemfRecordType.eof)) { - return null; - } - long recordId = stream.readUInt(); - long recordSize = stream.readUInt(); - - HemfRecord record = null; - HemfRecordType type = HemfRecordType.getById(recordId); - if (type == null) { - throw new RuntimeException("Undefined record of type:"+recordId); - } - try { - record = type.clazz.newInstance(); - } catch (InstantiationException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - try { - record.init(stream, recordId, recordSize-8); - } catch (IOException e) { - throw new RecordFormatException(e); - } - - return record; - } + @Override + public Iterator<HemfRecord> iterator() { + return getRecords().iterator(); + } - @Override - public void remove() { - throw new UnsupportedOperationException("Remove not supported"); - } + @Override + public Spliterator<HemfRecord> spliterator() { + return getRecords().spliterator(); + } + @Override + public void forEach(Consumer<? super HemfRecord> action) { + getRecords().forEach(action); } } Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java?rev=1840956&r1=1840955&r2=1840956&view=diff ============================================================================== --- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java (original) +++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java Fri Sep 14 21:37:37 2018 @@ -43,32 +43,48 @@ public class HwmfDrawProperties { private final Rectangle2D window; private Rectangle2D viewport; private final Point2D location; - private HwmfMapMode mapMode = HwmfMapMode.MM_ANISOTROPIC; - private HwmfColorRef backgroundColor = new HwmfColorRef(Color.BLACK); - private HwmfBrushStyle brushStyle = HwmfBrushStyle.BS_SOLID; - private HwmfColorRef brushColor = new HwmfColorRef(Color.BLACK); - private HwmfHatchStyle brushHatch = HwmfHatchStyle.HS_HORIZONTAL; + private HwmfMapMode mapMode; + private HwmfColorRef backgroundColor; + private HwmfBrushStyle brushStyle; + private HwmfColorRef brushColor; + private HwmfHatchStyle brushHatch; private BufferedImage brushBitmap; - private double penWidth = 1; - private HwmfPenStyle penStyle = HwmfPenStyle.valueOf(0); - private HwmfColorRef penColor = new HwmfColorRef(Color.BLACK); - private double penMiterLimit = 10; - private HwmfBkMode bkMode = HwmfBkMode.OPAQUE; - private HwmfPolyfillMode polyfillMode = HwmfPolyfillMode.WINDING; + private double penWidth; + private HwmfPenStyle penStyle; + private HwmfColorRef penColor; + private double penMiterLimit; + private HwmfBkMode bkMode; + private HwmfPolyfillMode polyfillMode; private Shape region; private List<PaletteEntry> palette; private int paletteOffset; private HwmfFont font; - private HwmfColorRef textColor = new HwmfColorRef(Color.BLACK); - private HwmfTextAlignment textAlignLatin = HwmfTextAlignment.LEFT; - private HwmfTextVerticalAlignment textVAlignLatin = HwmfTextVerticalAlignment.TOP; - private HwmfTextAlignment textAlignAsian = HwmfTextAlignment.RIGHT; - private HwmfTextVerticalAlignment textVAlignAsian = HwmfTextVerticalAlignment.TOP; + private HwmfColorRef textColor; + private HwmfTextAlignment textAlignLatin; + private HwmfTextVerticalAlignment textVAlignLatin; + private HwmfTextAlignment textAlignAsian; + private HwmfTextVerticalAlignment textVAlignAsian; public HwmfDrawProperties() { window = new Rectangle2D.Double(0, 0, 1, 1); viewport = null; location = new Point2D.Double(0,0); + mapMode = HwmfMapMode.MM_ANISOTROPIC; + backgroundColor = new HwmfColorRef(Color.BLACK); + brushStyle = HwmfBrushStyle.BS_SOLID; + brushColor = new HwmfColorRef(Color.BLACK); + brushHatch = HwmfHatchStyle.HS_HORIZONTAL; + penWidth = 1; + penStyle = HwmfPenStyle.valueOf(0); + penColor = new HwmfColorRef(Color.BLACK); + penMiterLimit = 10; + bkMode = HwmfBkMode.OPAQUE; + polyfillMode = HwmfPolyfillMode.WINDING; + textColor = new HwmfColorRef(Color.BLACK); + textAlignLatin = HwmfTextAlignment.LEFT; + textVAlignLatin = HwmfTextVerticalAlignment.TOP; + textAlignAsian = HwmfTextAlignment.RIGHT; + textVAlignAsian = HwmfTextVerticalAlignment.TOP; } public HwmfDrawProperties(HwmfDrawProperties other) { @@ -86,7 +102,7 @@ public class HwmfDrawProperties { WritableRaster raster = other.brushBitmap.copyData(null); this.brushBitmap = new BufferedImage(cm, raster, isAlphaPremultiplied, null); } - this.penWidth = 1; + this.penWidth = other.penWidth; this.penStyle = (other.penStyle == null) ? null : other.penStyle.clone(); this.penColor = (other.penColor == null) ? null : other.penColor.clone(); this.penMiterLimit = other.penMiterLimit; @@ -101,6 +117,10 @@ public class HwmfDrawProperties { this.paletteOffset = other.paletteOffset; this.font = other.font; this.textColor = (other.textColor == null) ? null : other.textColor.clone(); + this.textAlignLatin = other.textAlignLatin; + this.textVAlignLatin = other.textVAlignLatin; + this.textAlignAsian = other.textAlignAsian; + this.textVAlignAsian = other.textVAlignAsian; } public void setViewportExt(double width, double height) { @@ -149,6 +169,10 @@ public class HwmfDrawProperties { location.setLocation(x, y); } + public void setLocation(Point2D point) { + location.setLocation(point); + } + public Point2D getLocation() { return (Point2D)location.clone(); } Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBrushStyle.java URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBrushStyle.java?rev=1840956&r1=1840955&r2=1840956&view=diff ============================================================================== --- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBrushStyle.java (original) +++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBrushStyle.java Fri Sep 14 21:37:37 2018 @@ -71,7 +71,7 @@ public enum HwmfBrushStyle { this.flag = flag; } - static HwmfBrushStyle valueOf(int flag) { + public static HwmfBrushStyle valueOf(int flag) { for (HwmfBrushStyle bs : values()) { if (bs.flag == flag) return bs; } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
