You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2018/10/09 20:51:15 UTC

svn commit: r1843342 - in /poi/branches/hemf/src/scratchpad: src/org/apache/poi/hemf/draw/ src/org/apache/poi/hemf/record/emf/ src/org/apache/poi/hemf/usermodel/ src/org/apache/poi/hwmf/draw/ src/org/apache/poi/hwmf/record/ testcases/org/apache/poi/hem...

Author: kiwiwings
Date: Tue Oct  9 20:51:14 2018
New Revision: 1843342

URL: http://svn.apache.org/viewvc?rev=1843342&view=rev
Log:
#60656 - Support export file that contains emf and render it correctly

Modified:
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/usermodel/HemfPicture.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
    poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java?rev=1843342&r1=1843341&r2=1843342&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java Tue Oct  9 20:51:14 2018
@@ -17,6 +17,10 @@
 
 package org.apache.poi.hemf.draw;
 
+import static org.apache.poi.hwmf.record.HwmfBrushStyle.BS_NULL;
+import static org.apache.poi.hwmf.record.HwmfBrushStyle.BS_SOLID;
+
+import java.awt.Color;
 import java.awt.Graphics2D;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.Path2D;
@@ -29,11 +33,20 @@ import java.util.function.Consumer;
 import org.apache.poi.hemf.record.emf.HemfBounded;
 import org.apache.poi.hemf.record.emf.HemfRecord;
 import org.apache.poi.hwmf.draw.HwmfGraphics;
+import org.apache.poi.hwmf.record.HwmfColorRef;
 import org.apache.poi.hwmf.record.HwmfObjectTableEntry;
+import org.apache.poi.hwmf.record.HwmfPenStyle;
 import org.apache.poi.util.Internal;
 
 public class HemfGraphics extends HwmfGraphics {
 
+    private static final HwmfColorRef WHITE = new HwmfColorRef(Color.WHITE);
+    private static final HwmfColorRef LTGRAY = new HwmfColorRef(new Color(0x00C0C0C0));
+    private static final HwmfColorRef GRAY = new HwmfColorRef(new Color(0x00808080));
+    private static final HwmfColorRef DKGRAY = new HwmfColorRef(new Color(0x00404040));
+    private static final HwmfColorRef BLACK = new HwmfColorRef(Color.BLACK);
+
+
     private final Deque<AffineTransform> transforms = new ArrayDeque<>();
 
     public HemfGraphics(Graphics2D graphicsCtx, Rectangle2D bbox) {
@@ -52,8 +65,7 @@ public class HemfGraphics extends HwmfGr
 
     @Override
     public void saveProperties() {
-        assert(prop != null);
-        propStack.add(prop);
+        propStack.add(getProperties());
         prop = new HemfDrawProperties((HemfDrawProperties)prop);
     }
 
@@ -138,6 +150,125 @@ public class HemfGraphics extends HwmfGr
         }
     }
 
+    @Override
+    public void applyObjectTableEntry(int index) {
+        if ((index & 0x80000000) != 0) {
+            selectStockObject(index);
+        } else {
+            super.applyObjectTableEntry(index);
+        }
+    }
+
+    private void selectStockObject(int objectIndex) {
+        final HemfDrawProperties prop = getProperties();
+        switch (objectIndex) {
+            case 0x80000000:
+                // WHITE_BRUSH - A white, solid-color brush
+                // BrushStyle: BS_SOLID
+                // Color: 0x00FFFFFF
+                prop.setBrushColor(WHITE);
+                prop.setBrushStyle(BS_SOLID);
+                break;
+            case 0x80000001:
+                // LTGRAY_BRUSH - A light gray, solid-color brush
+                // BrushStyle: BS_SOLID
+                // Color: 0x00C0C0C0
+                prop.setBrushColor(LTGRAY);
+                prop.setBrushStyle(BS_SOLID);
+                break;
+            case 0x80000002:
+                // GRAY_BRUSH - A gray, solid-color brush
+                // BrushStyle: BS_SOLID
+                // Color: 0x00808080
+                prop.setBrushColor(GRAY);
+                prop.setBrushStyle(BS_SOLID);
+                break;
+            case 0x80000003:
+                // DKGRAY_BRUSH - A dark gray, solid color brush
+                // BrushStyle: BS_SOLID
+                // Color: 0x00404040
+                prop.setBrushColor(DKGRAY);
+                prop.setBrushStyle(BS_SOLID);
+                break;
+            case 0x80000004:
+                // BLACK_BRUSH - A black, solid color brush
+                // BrushStyle: BS_SOLID
+                // Color: 0x00000000
+                prop.setBrushColor(BLACK);
+                prop.setBrushStyle(BS_SOLID);
+                break;
+            case 0x80000005:
+                // NULL_BRUSH - A null brush
+                // BrushStyle: BS_NULL
+                prop.setBrushStyle(BS_NULL);
+                break;
+            case 0x80000006:
+                // WHITE_PEN - A white, solid-color pen
+                // PenStyle: PS_COSMETIC + PS_SOLID
+                // ColorRef: 0x00FFFFFF
+                prop.setPenStyle(HwmfPenStyle.valueOf(0));
+                prop.setPenWidth(1);
+                prop.setPenColor(WHITE);
+                break;
+            case 0x80000007:
+                // BLACK_PEN - A black, solid-color pen
+                // PenStyle: PS_COSMETIC + PS_SOLID
+                // ColorRef: 0x00000000
+                prop.setPenStyle(HwmfPenStyle.valueOf(0));
+                prop.setPenWidth(1);
+                prop.setPenColor(BLACK);
+                break;
+            case 0x80000008:
+                // NULL_PEN - A null pen
+                // PenStyle: PS_NULL
+                prop.setPenStyle(HwmfPenStyle.valueOf(HwmfPenStyle.HwmfLineDash.NULL.wmfFlag));
+                break;
+            case 0x8000000A:
+                // OEM_FIXED_FONT - A fixed-width, OEM character set
+                // Charset: OEM_CHARSET
+                // PitchAndFamily: FF_DONTCARE + FIXED_PITCH
+                break;
+            case 0x8000000B:
+                // ANSI_FIXED_FONT - A fixed-width font
+                // Charset: ANSI_CHARSET
+                // PitchAndFamily: FF_DONTCARE + FIXED_PITCH
+                break;
+            case 0x8000000C:
+                // ANSI_VAR_FONT - A variable-width font
+                // Charset: ANSI_CHARSET
+                // PitchAndFamily: FF_DONTCARE + VARIABLE_PITCH
+                break;
+            case 0x8000000D:
+                // SYSTEM_FONT - A font that is guaranteed to be available in the operating system
+                break;
+            case 0x8000000E:
+                // DEVICE_DEFAULT_FONT
+                // The default font that is provided by the graphics device driver for the current output device
+                break;
+            case 0x8000000F:
+                // DEFAULT_PALETTE
+                // The default palette that is defined for the current output device.
+                break;
+            case 0x80000010:
+                // SYSTEM_FIXED_FONT
+                // A fixed-width font that is guaranteed to be available in the operating system.
+                break;
+            case 0x80000011:
+                // DEFAULT_GUI_FONT
+                // The default font that is used for user interface objects such as menus and dialog boxes.
+                break;
+            case 0x80000012:
+                // DC_BRUSH
+                // The solid-color brush that is currently selected in the playback device context.
+                break;
+            case 0x80000013:
+                // DC_PEN
+                // The solid-color pen that is currently selected in the playback device context.
+                break;
+        }
+    }
+
+
 
     /** saves the current affine transform on the stack */
     private void saveTransform() {

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java?rev=1843342&r1=1843341&r2=1843342&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java Tue Oct  9 20:51:14 2018
@@ -40,7 +40,7 @@ import org.apache.poi.util.RecordFormatE
  */
 @Internal
 public class HemfComment {
-    private static final int MAX_RECORD_LENGTH = 1_000_000;
+    private static final int MAX_RECORD_LENGTH = 2_000_000;
 
     public enum HemfCommentRecordType {
         emfGeneric(-1, EmfCommentDataGeneric::new, false),

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java?rev=1843342&r1=1843341&r2=1843342&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java Tue Oct  9 20:51:14 2018
@@ -47,12 +47,6 @@ public class HemfDraw {
      */
     public static class EmfSelectObject extends WmfSelectObject implements HemfRecord {
 
-        private static final HwmfColorRef WHITE = new HwmfColorRef(Color.WHITE);
-        private static final HwmfColorRef LTGRAY = new HwmfColorRef(new Color(0x00C0C0C0));
-        private static final HwmfColorRef GRAY = new HwmfColorRef(new Color(0x00808080));
-        private static final HwmfColorRef DKGRAY = new HwmfColorRef(new Color(0x00404040));
-        private static final HwmfColorRef BLACK = new HwmfColorRef(Color.BLACK);
-
         private static final String[] STOCK_IDS = {
             "0x80000000 /* WHITE_BRUSH */",
             "0x80000001 /* LTGRAY_BRUSH */",
@@ -89,124 +83,6 @@ public class HemfDraw {
         }
 
         @Override
-        public void draw(HemfGraphics ctx) {
-            if ((objectIndex & 0x80000000) != 0) {
-                selectStockObject(ctx);
-            } else {
-                super.draw(ctx);
-            }
-        }
-
-        private void selectStockObject(HemfGraphics ctx) {
-            final HemfDrawProperties prop = ctx.getProperties();
-            switch (objectIndex) {
-                case 0x80000000:
-                    // WHITE_BRUSH - A white, solid-color brush
-                    // BrushStyle: BS_SOLID
-                    // Color: 0x00FFFFFF
-                    prop.setBrushColor(WHITE);
-                    prop.setBrushStyle(BS_SOLID);
-                    break;
-                case 0x80000001:
-                    // LTGRAY_BRUSH - A light gray, solid-color brush
-                    // BrushStyle: BS_SOLID
-                    // Color: 0x00C0C0C0
-                    prop.setBrushColor(LTGRAY);
-                    prop.setBrushStyle(BS_SOLID);
-                    break;
-                case 0x80000002:
-                    // GRAY_BRUSH - A gray, solid-color brush
-                    // BrushStyle: BS_SOLID
-                    // Color: 0x00808080
-                    prop.setBrushColor(GRAY);
-                    prop.setBrushStyle(BS_SOLID);
-                    break;
-                case 0x80000003:
-                    // DKGRAY_BRUSH - A dark gray, solid color brush
-                    // BrushStyle: BS_SOLID
-                    // Color: 0x00404040
-                    prop.setBrushColor(DKGRAY);
-                    prop.setBrushStyle(BS_SOLID);
-                    break;
-                case 0x80000004:
-                    // BLACK_BRUSH - A black, solid color brush
-                    // BrushStyle: BS_SOLID
-                    // Color: 0x00000000
-                    prop.setBrushColor(BLACK);
-                    prop.setBrushStyle(BS_SOLID);
-                    break;
-                case 0x80000005:
-                    // NULL_BRUSH - A null brush
-                    // BrushStyle: BS_NULL
-                    prop.setBrushStyle(BS_NULL);
-                    break;
-                case 0x80000006:
-                    // WHITE_PEN - A white, solid-color pen
-                    // PenStyle: PS_COSMETIC + PS_SOLID
-                    // ColorRef: 0x00FFFFFF
-                    prop.setPenStyle(HwmfPenStyle.valueOf(0));
-                    prop.setPenWidth(1);
-                    prop.setPenColor(WHITE);
-                    break;
-                case 0x80000007:
-                    // BLACK_PEN - A black, solid-color pen
-                    // PenStyle: PS_COSMETIC + PS_SOLID
-                    // ColorRef: 0x00000000
-                    prop.setPenStyle(HwmfPenStyle.valueOf(0));
-                    prop.setPenWidth(1);
-                    prop.setPenColor(BLACK);
-                    break;
-                case 0x80000008:
-                    // NULL_PEN - A null pen
-                    // PenStyle: PS_NULL
-                    prop.setPenStyle(HwmfPenStyle.valueOf(HwmfPenStyle.HwmfLineDash.NULL.wmfFlag));
-                    break;
-                case 0x8000000A:
-                    // OEM_FIXED_FONT - A fixed-width, OEM character set
-                    // Charset: OEM_CHARSET
-                    // PitchAndFamily: FF_DONTCARE + FIXED_PITCH
-                    break;
-                case 0x8000000B:
-                    // ANSI_FIXED_FONT - A fixed-width font
-                    // Charset: ANSI_CHARSET
-                    // PitchAndFamily: FF_DONTCARE + FIXED_PITCH
-                    break;
-                case 0x8000000C:
-                    // ANSI_VAR_FONT - A variable-width font
-                    // Charset: ANSI_CHARSET
-                    // PitchAndFamily: FF_DONTCARE + VARIABLE_PITCH
-                    break;
-                case 0x8000000D:
-                    // SYSTEM_FONT - A font that is guaranteed to be available in the operating system
-                    break;
-                case 0x8000000E:
-                    // DEVICE_DEFAULT_FONT
-                    // The default font that is provided by the graphics device driver for the current output device
-                    break;
-                case 0x8000000F:
-                    // DEFAULT_PALETTE
-                    // The default palette that is defined for the current output device.
-                    break;
-                case 0x80000010:
-                    // SYSTEM_FIXED_FONT
-                    // A fixed-width font that is guaranteed to be available in the operating system.
-                    break;
-                case 0x80000011:
-                    // DEFAULT_GUI_FONT
-                    // The default font that is used for user interface objects such as menus and dialog boxes.
-                    break;
-                case 0x80000012:
-                    // DC_BRUSH
-                    // The solid-color brush that is currently selected in the playback device context.
-                    break;
-                case 0x80000013:
-                    // DC_PEN
-                    // The solid-color pen that is currently selected in the playback device context.
-                    break;
-            }
-        }
-
-        @Override
         public String toString() {
             return "{ index: "+
                 (((objectIndex & 0x80000000) != 0 && (objectIndex & 0x3FFFFFFF) <= 13 )
@@ -1166,6 +1042,11 @@ public class HemfDraw {
 
     private static void polyTo(final HemfGraphics ctx, final Path2D poly) {
         final PathIterator pi = poly.getPathIterator(null);
+        if (pi.isDone()) {
+            // ignore empty polys
+            return;
+        }
+
         // ignore dummy start point (moveTo)
         pi.next();
         assert (!pi.isDone());

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java?rev=1843342&r1=1843341&r2=1843342&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java Tue Oct  9 20:51:14 2018
@@ -19,6 +19,7 @@ package org.apache.poi.hemf.record.emf;
 
 import static org.apache.poi.hemf.record.emf.HemfDraw.readPointL;
 import static org.apache.poi.hemf.record.emf.HemfDraw.readRectL;
+import static org.apache.poi.hemf.record.emf.HemfRecordIterator.HEADER_SIZE;
 
 import java.awt.geom.AffineTransform;
 import java.awt.geom.Area;
@@ -100,7 +101,7 @@ public class HemfFill {
         @Override
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
             long size = readPointL(leis, start);
-            size = colorRef.init(leis);
+            size += colorRef.init(leis);
             // A 32-bit unsigned integer that specifies how to use the Color value to determine the area for
             // the flood fill operation. The value MUST be in the FloodFill enumeration
             mode = (int)leis.readUInt();
@@ -117,7 +118,7 @@ public class HemfFill {
         protected final Rectangle2D bounds = new Rectangle2D.Double();
 
         /** An XForm object that specifies a world-space to page-space transform to apply to the source bitmap. */
-        protected final byte[] xformSrc = new byte[24];
+        protected final AffineTransform xFormSrc = new AffineTransform();
 
         /** A WMF ColorRef object that specifies the background color of the source bitmap. */
         protected final HwmfColorRef bkColorSrc = new HwmfColorRef();
@@ -155,8 +156,7 @@ public class HemfFill {
             final Point2D srcPnt = new Point2D.Double();
             size += readPointL(leis, srcPnt);
 
-            leis.readFully(xformSrc);
-            size += 24;
+            size += readXForm(leis, xFormSrc);
 
             size += bkColorSrc.init(leis);
 
@@ -168,6 +168,10 @@ public class HemfFill {
 
             // A 32-bit unsigned integer that specifies the size, in bytes, of the source bitmap header.
             final int cbBmiSrc = (int)leis.readUInt();
+            size += 3*LittleEndianConsts.INT_SIZE;
+            if (size <= recordSize) {
+                return size;
+            }
 
             // A 32-bit unsigned integer that specifies the offset, in bytes, from the
             // start of this record to the source bitmap bits in the BitmapBuffer field.
@@ -176,7 +180,7 @@ public class HemfFill {
             // A 32-bit unsigned integer that specifies the size, in bytes, of the source bitmap bits.
             final int cbBitsSrc = (int)leis.readUInt();
 
-            size += 5*LittleEndianConsts.INT_SIZE;
+            size += 2*LittleEndianConsts.INT_SIZE;
 
             if (srcEqualsDstDimension()) {
                 srcBounds.setRect(srcPnt.getX(), srcPnt.getY(), dstBounds.getWidth(), dstBounds.getHeight());
@@ -205,6 +209,16 @@ public class HemfFill {
         protected boolean srcEqualsDstDimension() {
             return false;
         }
+
+        @Override
+        public String toString() {
+            return
+                "{ bounds: { x: "+bounds.getX()+", y: "+bounds.getY()+", w: "+bounds.getWidth()+", h: "+bounds.getHeight()+"}"+
+                ", xFormSrc: { scaleX: "+xFormSrc.getScaleX()+", shearX: "+xFormSrc.getShearX()+", transX: "+xFormSrc.getTranslateX()+", scaleY: "+xFormSrc.getScaleY()+", shearY: "+xFormSrc.getShearY()+", transY: "+xFormSrc.getTranslateY()+" }"+
+                ", bkColorSrc: "+bkColorSrc+
+                ", usageSrc: "+usageSrc+", "
+                + super.toString().substring(1);
+        }
     }
 
     /**
@@ -589,18 +603,24 @@ public class HemfFill {
     }
 
     static long readBitmap(final LittleEndianInputStream leis, final HwmfBitmapDib bitmap,
-            final int startIdx, final int offBmiSrc, final int cbBmiSrc, final int offBitsSrc, int cbBitsSrc)
+            final int startIdx, final int offBmi, final int cbBmi, final int offBits, int cbBits)
     throws IOException {
-        final int offCurr = leis.getReadIndex()-startIdx;
-        final int undefinedSpace1 = offBmiSrc-offCurr;
-        assert(undefinedSpace1 >= 0);
+        if (offBmi == 0) {
+            return 0;
+        }
+
+        final int offCurr = leis.getReadIndex()-(startIdx-HEADER_SIZE);
+        final int undefinedSpace1 = offBmi-offCurr;
+        if (undefinedSpace1 < 0) {
+            return 0;
+        }
 
-        final int undefinedSpace2 = offBitsSrc-offCurr-cbBmiSrc-undefinedSpace1;
+        final int undefinedSpace2 = offBits-offCurr-cbBmi-undefinedSpace1;
         assert(undefinedSpace2 >= 0);
 
         leis.skipFully(undefinedSpace1);
 
-        if (cbBmiSrc == 0 || cbBitsSrc == 0) {
+        if (cbBmi == 0 || cbBits == 0) {
             return undefinedSpace1;
         }
 
@@ -608,18 +628,18 @@ public class HemfFill {
         if (undefinedSpace2 == 0) {
             leisDib = leis;
         } else {
-            final ByteArrayOutputStream bos = new ByteArrayOutputStream(cbBmiSrc+cbBitsSrc);
-            final long cbBmiSrcAct = IOUtils.copy(leis, bos, cbBmiSrc);
-            assert (cbBmiSrcAct == cbBmiSrc);
+            final ByteArrayOutputStream bos = new ByteArrayOutputStream(cbBmi+cbBits);
+            final long cbBmiSrcAct = IOUtils.copy(leis, bos, cbBmi);
+            assert (cbBmiSrcAct == cbBmi);
             leis.skipFully(undefinedSpace2);
-            final long cbBitsSrcAct = IOUtils.copy(leis, bos, cbBitsSrc);
-            assert (cbBitsSrcAct == cbBitsSrc);
+            final long cbBitsSrcAct = IOUtils.copy(leis, bos, cbBits);
+            assert (cbBitsSrcAct == cbBits);
             leisDib = new LittleEndianInputStream(new ByteArrayInputStream(bos.toByteArray()));
         }
-        final int dibSize = cbBmiSrc+cbBitsSrc;
+        final int dibSize = cbBmi+cbBits;
         final int dibSizeAct = bitmap.init(leisDib, dibSize);
         assert (dibSizeAct <= dibSize);
-        return undefinedSpace1 + cbBmiSrc + undefinedSpace2 + cbBitsSrc;
+        return undefinedSpace1 + cbBmi + undefinedSpace2 + cbBits;
     }
 
 

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java?rev=1843342&r1=1843341&r2=1843342&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java Tue Oct  9 20:51:14 2018
@@ -33,6 +33,7 @@ import org.apache.poi.hwmf.record.HwmfBi
 import org.apache.poi.hwmf.record.HwmfBitmapDib;
 import org.apache.poi.hwmf.record.HwmfBrushStyle;
 import org.apache.poi.hwmf.record.HwmfColorRef;
+import org.apache.poi.hwmf.record.HwmfFill;
 import org.apache.poi.hwmf.record.HwmfHatchStyle;
 import org.apache.poi.hwmf.record.HwmfMapMode;
 import org.apache.poi.hwmf.record.HwmfMisc;
@@ -65,8 +66,8 @@ public class HemfMisc {
 
             int size = 2 * LittleEndianConsts.INT_SIZE;
 
-            if (offPalEntries > 0) {
-                int undefinedSpace1 = (int) (offPalEntries - size - HEADER_SIZE);
+            if (nPalEntries > 0 && offPalEntries > 0) {
+                int undefinedSpace1 = (int) (offPalEntries - (size + HEADER_SIZE));
                 assert (undefinedSpace1 >= 0);
                 leis.skipFully(undefinedSpace1);
                 size += undefinedSpace1;
@@ -284,6 +285,59 @@ public class HemfMisc {
     }
 
     /**
+     * The EMR_CREATEDIBPATTERNBRUSHPT record defines a pattern brush for graphics operations.
+     * The pattern is specified by a DIB.
+     */
+    public static class EmfCreateDibPatternBrushPt extends HwmfMisc.WmfDibCreatePatternBrush implements HemfRecord {
+        protected int brushIdx;
+
+        @Override
+        public HemfRecordType getEmfRecordType() {
+            return HemfRecordType.createDibPatternBrushPt;
+        }
+
+        @Override
+        public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
+            final int startIdx = leis.getReadIndex();
+
+            style = HwmfBrushStyle.BS_DIBPATTERNPT;
+
+            // A 32-bit unsigned integer that specifies the index of the pattern brush
+            // object in the EMF Object Table
+            brushIdx = (int)leis.readUInt();
+
+            // A 32-bit unsigned integer that specifies how to interpret values in the color
+            // table in the DIB header. This value MUST be in the DIBColors enumeration
+            colorUsage = HwmfFill.ColorUsage.valueOf((int)leis.readUInt());
+
+            // A 32-bit unsigned integer that specifies the offset from the start of this
+            // record to the DIB header.
+            final int offBmi = leis.readInt();
+
+            // A 32-bit unsigned integer that specifies the size of the DIB header.
+            final int cbBmi = leis.readInt();
+
+            // A 32-bit unsigned integer that specifies the offset from the start of this record to the DIB bits.
+            final int offBits = leis.readInt();
+
+            // A 32-bit unsigned integer that specifies the size of the DIB bits.
+            final int cbBits = leis.readInt();
+
+            int size = 6*LittleEndianConsts.INT_SIZE;
+
+            patternDib = new HwmfBitmapDib();
+            size += readBitmap(leis, patternDib, startIdx, offBmi, cbBmi, offBits, cbBits);
+            return size;
+        }
+
+        @Override
+        public void draw(HemfGraphics ctx) {
+            ctx.addObjectTableEntry(this, brushIdx);
+        }
+
+    }
+
+    /**
      * The EMR_DELETEOBJECT record deletes a graphics object, which is specified by its index
      * in the EMF Object Table
      */
@@ -519,5 +573,12 @@ public class HemfMisc {
 
             return size + LittleEndianConsts.INT_SIZE;
         }
+
+        @Override
+        public String toString() {
+            return
+                "{ xForm: { scaleX: "+xForm.getScaleX()+", shearX: "+xForm.getShearX()+", transX: "+xForm.getTranslateX()+", scaleY: "+xForm.getScaleY()+", shearY: "+xForm.getShearY()+", transY: "+xForm.getTranslateY()+" }"+
+                ", modifyWorldTransformMode: "+modifyWorldTransformMode+" }";
+        }
     }
 }

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java?rev=1843342&r1=1843341&r2=1843342&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java Tue Oct  9 20:51:14 2018
@@ -117,7 +117,7 @@ public enum HemfRecordType {
     polyPolygon16(0x0000005B, HemfDraw.EmfPolyPolygon16::new),
     polyDraw16(0x0000005C, HemfDraw.EmfPolyDraw16::new),
     createmonobrush16(0x0000005D, UnimplementedHemfRecord::new),
-    createdibpatternbrushpt(0x0000005E, UnimplementedHemfRecord::new),
+    createDibPatternBrushPt(0x0000005E, HemfMisc.EmfCreateDibPatternBrushPt::new),
     extCreatePen(0x0000005F, HemfMisc.EmfExtCreatePen::new),
     polytextouta(0x00000060, HemfText.PolyTextOutA::new),
     polytextoutw(0x00000061, HemfText.PolyTextOutW::new),

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java?rev=1843342&r1=1843341&r2=1843342&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java Tue Oct  9 20:51:14 2018
@@ -113,7 +113,7 @@ public class HemfText {
             int offDx = (int)leis.readUInt();
             size += LittleEndianConsts.INT_SIZE;
 
-            int undefinedSpace1 = (int)(offString - size - HEADER_SIZE);
+            int undefinedSpace1 = (int)(offString - (size + HEADER_SIZE));
             assert (undefinedSpace1 >= 0);
             leis.skipFully(undefinedSpace1);
             size += undefinedSpace1;
@@ -124,7 +124,7 @@ public class HemfText {
 
             dx.clear();
             if (offDx > 0) {
-                int undefinedSpace2 = (int) (offDx - size - HEADER_SIZE);
+                int undefinedSpace2 = (int) (offDx - (size + HEADER_SIZE));
                 assert (undefinedSpace2 >= 0);
                 leis.skipFully(undefinedSpace2);
                 size += undefinedSpace2;
@@ -149,10 +149,6 @@ public class HemfText {
             return size;
         }
 
-        protected boolean isUnicode() {
-            return false;
-        }
-
         /**
          *
          * To be implemented!  We need to get the current character set
@@ -185,21 +181,10 @@ public class HemfText {
 
         @Override
         public String toString() {
-            String text = "";
-            try {
-                text = getText(isUnicode() ? Charsets.UTF_16LE : LocaleUtil.CHARSET_1252);
-            } catch (IOException ignored) {
-            }
-
             return
-                "{ bounds: { x: "+bounds.getX()+
-                ", y: "+bounds.getY()+
-                ", w: "+bounds.getWidth()+
-                ", h: "+bounds.getHeight()+
-                "}, graphicsMode: '"+graphicsMode+"'"+
-                ", scale: { w: "+scale.getWidth()+", h: "+scale.getHeight()+" }"+
-                ", text: '"+text.replaceAll("\\p{Cntrl}",".")+"'"+
-                "}";
+                "{ graphicsMode: '"+graphicsMode+"'"+
+                ", scale: { w: "+scale.getWidth()+", h: "+scale.getHeight()+" },"+
+                super.toString().substring(1);
         }
     }
 

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/usermodel/HemfPicture.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/usermodel/HemfPicture.java?rev=1843342&r1=1843341&r2=1843342&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/usermodel/HemfPicture.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/usermodel/HemfPicture.java Tue Oct  9 20:51:14 2018
@@ -108,11 +108,11 @@ public class HemfPicture implements Iter
             ctx.scale(graphicsBounds.getWidth()/emfBounds.getWidth(), graphicsBounds.getHeight()/emfBounds.getHeight());
             ctx.translate(-emfBounds.getCenterX(), -emfBounds.getCenterY());
 
-
-
+            int idx = 0;
             HemfGraphics g = new HemfGraphics(ctx, emfBounds);
             for (HemfRecord r : getRecords()) {
                 g.draw(r);
+                idx++;
             }
         } finally {
             ctx.setTransform(at);

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java?rev=1843342&r1=1843341&r2=1843342&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java Tue Oct  9 20:51:14 2018
@@ -323,11 +323,7 @@ public class HwmfGraphics {
     }
 
     public void drawString(byte[] text, Rectangle2D bounds) {
-        drawString(text, bounds, null);
-    }
-
-    public void drawString(byte[] text, Rectangle2D bounds, List<Integer> dx) {
-        drawString(text, bounds, dx, false);
+        drawString(text, bounds, null, false);
     }
 
     public void drawString(byte[] text, Rectangle2D bounds, List<Integer> dx, boolean isUnicode) {
@@ -352,10 +348,12 @@ public class HwmfGraphics {
         }
 
         String textString = new String(text, charset).trim();
+        if (textString.isEmpty()) {
+            return;
+        }
         AttributedString as = new AttributedString(textString);
-        if (dx == null || dx.isEmpty()) {
-            addAttributes(as, font);
-        } else {
+        addAttributes(as, font);
+        if (dx != null && !dx.isEmpty()) {
             //for multi-byte encodings (e.g. Shift_JIS), the byte length
             //might not equal the string length().
             //The x information is stored in dx[], an array parallel to the
@@ -371,31 +369,21 @@ public class HwmfGraphics {
             //dxNormed[0] = 13 textString.get(0) = U+30D7
             //dxNormed[1] = 14 textString.get(1) = U+30ED
 
-            final List<Integer> dxNormed;
-            if (textString.length() == text.length) {
-                dxNormed = new ArrayList<>(dx);
-            } else {
-                dxNormed = new ArrayList<>(dx.size());
-                int dxPosition = 0;
-                int[] chars = {0};
-                for (int offset = 0; offset < textString.length(); ) {
-                    dxNormed.add(dx.get(dxPosition));
-                    chars[0] = textString.codePointAt(offset);
-                    //now figure out how many bytes it takes to encode that
-                    //code point in the charset
-                    int byteLength = new String(chars, 0, chars.length).getBytes(charset).length;
-                    dxPosition += byteLength;
-                    offset += Character.charCount(chars[0]);
+            final int cps = textString.codePointCount(0, textString.length());
+            final int unicodeSteps = Math.max(dx.size()/cps, 1);
+            int dxPosition = 0;
+            int beginIndex = 0;
+            int[] chars = {0};
+            while (beginIndex < textString.length() && dxPosition < dx.size()) {
+                int endIndex = textString.offsetByCodePoints(beginIndex, 1);
+                if (beginIndex > 0) {
+                    // Tracking works as a prefix/advance space on characters whereas
+                    // dx[...] is the complete width of the current char
+                    // therefore we need to add the additional/suffix width to the next char
+                    as.addAttribute(TextAttribute.TRACKING, (float)((dx.get(dxPosition) - fontW) / fontH), beginIndex, endIndex);
                 }
-            }
-
-            int cps = textString.codePointCount(0, textString.length());
-            for (int i = 0; i < Math.min(dxNormed.size(),cps-1); i++) {
-                addAttributes(as, font);
-                // Tracking works as a prefix/advance space on characters whereas
-                // dx[...] is the complete width of the current char
-                // therefore we need to add the additional/suffix width to the next char
-                as.addAttribute(TextAttribute.TRACKING, (dxNormed.get(i) - fontW) / fontH, i + 1, i + 2);
+                dxPosition += (isUnicode) ? unicodeSteps : (endIndex-beginIndex);
+                beginIndex = endIndex;
             }
         }
         
@@ -413,7 +401,7 @@ public class HwmfGraphics {
                 graphicsCtx.fill(new Rectangle2D.Double(0, 0, bounds.getWidth(), bounds.getHeight()));
             }
             graphicsCtx.setColor(getProperties().getTextColor().getColor());
-            graphicsCtx.drawString(as.getIterator(), 0, 0); // (float)bounds.getX(), (float)bounds.getY());
+            graphicsCtx.drawString(as.getIterator(), 0, 0);
         } finally {
             graphicsCtx.setTransform(at);
         }
@@ -425,7 +413,9 @@ public class HwmfGraphics {
         
         as.addAttribute(TextAttribute.FAMILY, fontInfo.getTypeface());
         as.addAttribute(TextAttribute.SIZE, getFontHeight(font));
-        as.addAttribute(TextAttribute.STRIKETHROUGH, font.isStrikeOut());
+        if (font.isStrikeOut()) {
+            as.addAttribute(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
+        }
         if (font.isUnderline()) {
             as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
         }

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java?rev=1843342&r1=1843341&r2=1843342&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java Tue Oct  9 20:51:14 2018
@@ -415,6 +415,15 @@ public class HwmfFill {
         public void draw(HwmfGraphics ctx) {
             
         }
+
+        @Override
+        public String toString() {
+            return
+                "{ rasterOperation: '"+rasterOperation+"'"+
+                ", srcBounds: { x: "+srcBounds.getX()+", y: "+srcBounds.getY()+", w: "+srcBounds.getWidth()+", h: "+srcBounds.getHeight()+" }"+
+                ", dstBounds: { x: "+dstBounds.getX()+", y: "+dstBounds.getY()+", w: "+dstBounds.getWidth()+", h: "+dstBounds.getHeight()+" }"+
+                "}";
+        }
     }
 
     /**

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java?rev=1843342&r1=1843341&r2=1843342&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java Tue Oct  9 20:51:14 2018
@@ -377,7 +377,7 @@ public class HwmfMisc {
      */
     public static class WmfDibCreatePatternBrush implements HwmfRecord, HwmfImageRecord, HwmfObjectTableEntry {
 
-        private HwmfBrushStyle style;
+        protected HwmfBrushStyle style;
 
         /**
          * A 16-bit unsigned integer that defines whether the Colors field of a DIB
@@ -388,9 +388,9 @@ public class HwmfMisc {
          *
          * If the Style field specified anything but BS_PATTERN, this field MUST be one of the ColorUsage values.
          */
-        private ColorUsage colorUsage;
+        protected ColorUsage colorUsage;
 
-        private HwmfBitmapDib patternDib;
+        protected HwmfBitmapDib patternDib;
         private HwmfBitmap16 pattern16;
 
         @Override

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=1843342&r1=1843341&r2=1843342&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 Tue Oct  9 20:51:14 2018
@@ -31,6 +31,7 @@ import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.commons.codec.Charsets;
 import org.apache.poi.hwmf.draw.HwmfDrawProperties;
 import org.apache.poi.hwmf.draw.HwmfGraphics;
 import org.apache.poi.hwmf.record.HwmfMisc.WmfSetMapMode;
@@ -39,6 +40,7 @@ import org.apache.poi.util.BitFieldFacto
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
+import org.apache.poi.util.LocaleUtil;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 import org.apache.poi.util.RecordFormatException;
@@ -291,6 +293,10 @@ public class HwmfText {
         public boolean isClipped() {
             return ETO_CLIPPED.isSet(flag);
         }
+
+        public boolean isYDisplaced() {
+            return ETO_PDY.isSet(flag);
+        }
     }
 
     /**
@@ -393,37 +399,11 @@ public class HwmfText {
         @Override
         public void draw(HwmfGraphics ctx) {
             Rectangle2D bounds = new Rectangle2D.Double(reference.getX(), reference.getY(), 0, 0);
-            ctx.drawString(rawTextBytes, bounds, dx);
+            ctx.drawString(rawTextBytes, bounds, dx, false);
         }
 
-
         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);
+            return new String(rawTextBytes, charset);
         }
 
         public Point2D getReference() {
@@ -433,6 +413,25 @@ public class HwmfText {
         public Rectangle2D getBounds() {
             return bounds;
         }
+
+        protected boolean isUnicode() {
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            String text = "";
+            try {
+                text = getText(isUnicode() ? Charsets.UTF_16LE : LocaleUtil.CHARSET_1252);
+            } catch (IOException ignored) {
+            }
+
+            return
+                "{ reference: { x: "+reference.getX()+", y: "+reference.getY()+" }"+
+                ", bounds: { x: "+bounds.getX()+", y: "+bounds.getY()+", w: "+bounds.getWidth()+", h: "+bounds.getHeight()+"}"+
+                ", text: '"+text.replaceAll("\\p{Cntrl}",".")+"'"+
+                "}";
+        }
     }
     
     public enum HwmfTextAlignment {

Modified: poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java?rev=1843342&r1=1843341&r2=1843342&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java (original)
+++ poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java Tue Oct  9 20:51:14 2018
@@ -38,6 +38,8 @@ import java.io.InputStream;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
 
 import javax.imageio.ImageIO;
 
@@ -64,42 +66,61 @@ public class HemfPictureTest {
     @Test
     @Ignore("Only for manual tests")
     public void paint() throws IOException {
-        File f = new File("picture_14.emf"); // sl_samples.getFile("wrench.emf");
-        try (FileInputStream fis = new FileInputStream(f)) {
-            HemfPicture emf = new HemfPicture(fis);
-
-            Dimension2D dim = emf.getSize();
-            int width = Units.pointsToPixel(dim.getWidth());
-            // keep aspect ratio for height
-            int height = Units.pointsToPixel(dim.getHeight());
-            double max = Math.max(width, height);
-            if (max > 1500) {
-                width *= 1500 / max;
-                height *= 1500 / max;
-            }
+//        File f = new File("picture_14.emf"); // sl_samples.getFile("wrench.emf");
+//        try (FileInputStream fis = new FileInputStream(f)) {
 
-            BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
-            Graphics2D g = bufImg.createGraphics();
-            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-            g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
-            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
-            g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
-
-            FileWriter fw = new FileWriter("record-list.txt");
-            int i=0;
-            for (HemfRecord r : emf.getRecords())  {
-                if (r.getEmfRecordType() != HemfRecordType.comment) {
-                    fw.write(i + " " + r.getEmfRecordType() + " " + r.toString() + "\n");
+        try (ZipInputStream zis = new ZipInputStream(new FileInputStream("tmp/emf.zip"))) {
+            for (;;) {
+                ZipEntry ze = zis.getNextEntry();
+                if (ze == null) {
+                    break;
                 }
-                i++;
-            }
-            fw.close();
+                final File pngName = new File("build/tmp",ze.getName().replaceFirst( ".*/","").replace(".emf", ".png"));
+                if (pngName.exists()) {
+                    continue;
+                }
+
+
+                // 263/263282_000.emf
+//                if (!ze.getName().contains("298/298837_000.emf")) continue;
+                HemfPicture emf = new HemfPicture(zis);
+                System.out.println(ze.getName());
+
+                Dimension2D dim = emf.getSize();
+                int width = Units.pointsToPixel(dim.getWidth());
+                // keep aspect ratio for height
+                int height = Units.pointsToPixel(dim.getHeight());
+                double max = Math.max(width, height);
+                if (max > 1500) {
+                    width *= 1500 / max;
+                    height *= 1500 / max;
+                }
+
+                BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+                Graphics2D g = bufImg.createGraphics();
+                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+                g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+                g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
+                g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+
+                FileWriter fw = new FileWriter("record-list.txt");
+                int i = 0;
+                for (HemfRecord r : emf.getRecords()) {
+                    if (r.getEmfRecordType() != HemfRecordType.comment) {
+                        fw.write(i + " " + r.getEmfRecordType() + " " + r.toString() + "\n");
+                    }
+                    i++;
+                }
+                fw.close();
 
-            emf.draw(g, new Rectangle2D.Double(0,0,width,height));
+                emf.draw(g, new Rectangle2D.Double(0, 0, width, height));
 
-            g.dispose();
+                g.dispose();
 
-            ImageIO.write(bufImg, "PNG", new File("bla.png"));
+                ImageIO.write(bufImg, "PNG", pngName);
+
+//                break;
+            }
         }
     }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org