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/09/14 21:37:38 UTC

svn commit: r1840956 [4/5] - in /poi/branches/hemf/src: java/org/apache/poi/util/ ooxml/java/org/apache/poi/xdgf/geom/ ooxml/java/org/apache/poi/xdgf/usermodel/ ooxml/java/org/apache/poi/xdgf/util/ scratchpad/src/org/apache/poi/hemf/draw/ scratchpad/sr...

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java?rev=1840956&r1=1840955&r2=1840956&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java Fri Sep 14 21:37:37 2018
@@ -41,31 +41,21 @@ public class HwmfDraw {
      */
     public static class WmfMoveTo implements HwmfRecord {
 
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units.
-         */
-        private int y;
-
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units.
-         */
-        private int x;
+        protected final Point2D point = new Point2D.Double();
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.moveTo;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            y = leis.readShort();
-            x = leis.readShort();
-            return 2*LittleEndianConsts.SHORT_SIZE;
+            return readPointS(leis, point);
         }
 
         @Override
         public void draw(HwmfGraphics ctx) {
-            ctx.getProperties().setLocation(x, y);
+            ctx.getProperties().setLocation(point);
         }
     }
 
@@ -75,36 +65,24 @@ public class HwmfDraw {
      */
     public static class WmfLineTo implements HwmfRecord {
 
-        /**
-         * A 16-bit signed integer that defines the vertical component of the drawing
-         * destination position, in logical units.
-         */
-        private int y;
-
-        /**
-         * A 16-bit signed integer that defines the horizontal component of the drawing
-         * destination position, in logical units.
-         */
-        private int x;
+        protected final Point2D point = new Point2D.Double();
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.lineTo;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            y = leis.readShort();
-            x = leis.readShort();
-            return 2*LittleEndianConsts.SHORT_SIZE;
+            return readPointS(leis, point);
         }
 
         @Override
         public void draw(HwmfGraphics ctx) {
             Point2D start = ctx.getProperties().getLocation();
-            Line2D line = new Line2D.Double(start.getX(), start.getY(), x, y);
+            Line2D line = new Line2D.Double(start, point);
             ctx.draw(line);
-            ctx.getProperties().setLocation(x, y);
+            ctx.getProperties().setLocation(point);
         }
     }
 
@@ -115,10 +93,10 @@ public class HwmfDraw {
      */
     public static class WmfPolygon implements HwmfRecord {
 
-        private Path2D poly = new Path2D.Double();
+        protected Path2D poly = new Path2D.Double();
         
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.polygon;
         }
 
@@ -146,16 +124,26 @@ public class HwmfDraw {
 
         @Override
         public void draw(HwmfGraphics ctx) {
-            Path2D shape = getShape();
-//            shape.closePath();
-            Path2D p = (Path2D)shape.clone();
+            Path2D p = getShape(ctx);
+            // don't close the path
             p.setWindingRule(getWindingRule(ctx));
-            ctx.fill(p);
+            if (isFill()) {
+                ctx.fill(p);
+            } else {
+                ctx.draw(p);
+            }
         }
 
-        protected Path2D getShape() {
+        protected Path2D getShape(HwmfGraphics ctx) {
             return (Path2D)poly.clone();
         }
+
+        /**
+         * @return true, if the shape should be filled
+         */
+        protected boolean isFill() {
+            return true;
+        }
     }
 
     /**
@@ -165,16 +153,13 @@ public class HwmfDraw {
     public static class WmfPolyline extends WmfPolygon {
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.polyline;
         }
 
         @Override
-        public void draw(HwmfGraphics ctx) {
-            Path2D shape = getShape();
-            Path2D p = (Path2D)shape.clone();
-            p.setWindingRule(getWindingRule(ctx));
-            ctx.draw(p);
+        protected boolean isFill() {
+            return false;
         }
     }
 
@@ -184,48 +169,21 @@ public class HwmfDraw {
      * are defined in the playback device context.
      */
     public static class WmfEllipse implements HwmfRecord {
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of
-         * the lower-right corner of the bounding rectangle.
-         */
-        private int bottomRect;
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of
-         * the lower-right corner of the bounding rectangle.
-         */
-        private int rightRect;
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-         * upper-left corner of the bounding rectangle.
-         */
-        private int topRect;
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of
-         * the upper-left corner of the bounding rectangle.
-         */
-        private int leftRect;
+        protected final Rectangle2D bounds = new Rectangle2D.Double();
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.ellipse;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            bottomRect = leis.readShort();
-            rightRect = leis.readShort();
-            topRect = leis.readShort();
-            leftRect = leis.readShort();
-            return 4*LittleEndianConsts.SHORT_SIZE;
+            return readBounds(leis, bounds);
         }
 
         @Override
         public void draw(HwmfGraphics ctx) {
-            int x = Math.min(leftRect, rightRect);
-            int y = Math.min(topRect, bottomRect);
-            int w = Math.abs(leftRect - rightRect - 1);
-            int h = Math.abs(topRect - bottomRect - 1);
-            Shape s = new Ellipse2D.Double(x, y, w, h);
+            Shape s = new Ellipse2D.Double(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight());
             ctx.fill(s);
         }
     }
@@ -239,25 +197,25 @@ public class HwmfDraw {
          * A 16-bit unsigned integer used to index into the WMF Object Table to get
          * the region to be framed.
          */
-        private int regionIndex;
+        protected int regionIndex;
         /**
          * A 16-bit unsigned integer used to index into the WMF Object Table to get the
          * Brush to use for filling the region.
          */
-        private int brushIndex;
+        protected int brushIndex;
         /**
          * A 16-bit signed integer that defines the height, in logical units, of the
          * region frame.
          */
-        private int height;
+        protected int height;
         /**
          * A 16-bit signed integer that defines the width, in logical units, of the
          * region frame.
          */
-        private int width;
+        protected int width;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.frameRegion;
         }
 
@@ -293,10 +251,10 @@ public class HwmfDraw {
      */
     public static class WmfPolyPolygon implements HwmfRecord {
 
-        private List<Path2D> polyList = new ArrayList<>();
+        protected List<Path2D> polyList = new ArrayList<>();
         
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.polyPolygon;
         }
 
@@ -361,7 +319,20 @@ public class HwmfDraw {
                     area.exclusiveOr(newArea);
                 }
             }
-            ctx.fill(area);
+
+            if (isFill()) {
+                ctx.fill(area);
+            } else {
+                ctx.draw(area);
+            }
+        }
+
+
+        /**
+         * @return true, if the shape should be filled
+         */
+        protected boolean isFill() {
+            return true;
         }
     }
 
@@ -370,92 +341,50 @@ public class HwmfDraw {
      * filled by using the brush that are defined in the playback device context.
      */
     public static class WmfRectangle implements HwmfRecord {
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of
-         * the lower-right corner of the rectangle.
-         */
-        private int bottomRect;
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of
-         * the lower-right corner of the rectangle.
-         */
-        private int rightRect;
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-         * upper-left corner of the rectangle.
-         */
-        private int topRect;
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of
-         * the upper-left corner of the rectangle.
-         */
-        private int leftRect;
+        protected final Rectangle2D bounds = new Rectangle2D.Double();
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.frameRegion;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            bottomRect = leis.readShort();
-            rightRect = leis.readShort();
-            topRect = leis.readShort();
-            leftRect = leis.readShort();
-            return 4*LittleEndianConsts.SHORT_SIZE;
+            return readBounds(leis, bounds);
         }
 
         @Override
         public void draw(HwmfGraphics ctx) {
-            int x = Math.min(leftRect, rightRect);
-            int y = Math.min(topRect, bottomRect);
-            int w = Math.abs(leftRect - rightRect - 1);
-            int h = Math.abs(topRect - bottomRect - 1);
-            Shape s = new Rectangle2D.Double(x, y, w, h);
-            ctx.fill(s);
+            ctx.fill(bounds);
         }
     }
 
     /**
-     * The META_RECTANGLE record paints a rectangle. The rectangle is outlined by using the pen and
-     * filled by using the brush that are defined in the playback device context.
+     * The META_SETPIXEL record sets the pixel at the specified coordinates to the specified color.
      */
     public static class WmfSetPixel implements HwmfRecord {
         /**
          * A ColorRef Object that defines the color value.
          */
-        HwmfColorRef colorRef;
+        protected final HwmfColorRef colorRef = new HwmfColorRef();
 
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the point
-         * to be set.
-         */
-        private int y;
-
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the point
-         * to be set.
-         */
-        private int x;
+        protected final Point2D point = new Point2D.Double();
 
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setPixel;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            colorRef = new HwmfColorRef();
             int size = colorRef.init(leis);
-            y = leis.readShort();
-            x = leis.readShort();
-            return 2*LittleEndianConsts.SHORT_SIZE+size;
+            return size+ readPointS(leis, point);
         }
 
         @Override
         public void draw(HwmfGraphics ctx) {
-            Shape s = new Rectangle2D.Double(x, y, 1, 1);
+            Shape s = new Rectangle2D.Double(point.getX(), point.getY(), 1, 1);
             ctx.fill(s);
         }
     }
@@ -469,41 +398,19 @@ public class HwmfDraw {
          * A 16-bit signed integer that defines the height, in logical coordinates, of the
          * ellipse used to draw the rounded corners.
          */
-        private int height;
+        protected int height;
 
         /**
          * A 16-bit signed integer that defines the width, in logical coordinates, of the
          * ellipse used to draw the rounded corners.
          */
-        private int width;
+        protected int width;
 
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of
-         * the lower-right corner of the rectangle.
-         */
-        private int bottomRect;
-
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of
-         * the lower-right corner of the rectangle.
-         */
-        private int rightRect;
-
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-         * upper-left corner of the rectangle.
-         */
-        private int topRect;
-
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of
-         * the upper-left corner of the rectangle.
-         */
-        private int leftRect;
+        protected final Rectangle2D bounds = new Rectangle2D.Double();
 
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.roundRect;
         }
 
@@ -511,20 +418,12 @@ public class HwmfDraw {
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             height = leis.readShort();
             width = leis.readShort();
-            bottomRect = leis.readShort();
-            rightRect = leis.readShort();
-            topRect = leis.readShort();
-            leftRect = leis.readShort();
-            return 6*LittleEndianConsts.SHORT_SIZE;
+            return 2*LittleEndianConsts.SHORT_SIZE+readBounds(leis, bounds);
         }
 
         @Override
         public void draw(HwmfGraphics ctx) {
-            int x = Math.min(leftRect, rightRect);
-            int y = Math.min(topRect, bottomRect);
-            int w = Math.abs(leftRect - rightRect - 1);
-            int h = Math.abs(topRect - bottomRect - 1);
-            Shape s = new RoundRectangle2D.Double(x, y, w, h, width, height);
+            Shape s = new RoundRectangle2D.Double(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight(), width, height);
             ctx.fill(s);
         }
     }
@@ -534,73 +433,34 @@ public class HwmfDraw {
      * The META_ARC record draws an elliptical arc.
      */
     public static class WmfArc implements HwmfRecord {
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of
-         * the ending point of the radial line defining the ending point of the arc.
-         */
-        private int yEndArc;
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of
-         * the ending point of the radial line defining the ending point of the arc.
-         */
-        private int xEndArc;
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of
-         * the ending point of the radial line defining the starting point of the arc.
-         */
-        private int yStartArc;
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of
-         * the ending point of the radial line defining the starting point of the arc.
-         */
-        private int xStartArc;
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of
-         * the lower-right corner of the bounding rectangle.
-         */
-        private int bottomRect;
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of
-         * the lower-right corner of the bounding rectangle.
-         */
-        private int rightRect;
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-         * upper-left corner of the bounding rectangle.
-         */
-        private int topRect;
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of
-         * the upper-left corner of the bounding rectangle.
-         */
-        private int leftRect;
+        /** starting point of the arc */
+        protected final Point2D startPoint = new Point2D.Double();
+
+        /** ending point of the arc */
+        protected final Point2D endPoint = new Point2D.Double();
+
+        /** the bounding rectangle */
+        protected final Rectangle2D bounds = new Rectangle2D.Double();
+
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.arc;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            yEndArc = leis.readShort();
-            xEndArc = leis.readShort();
-            yStartArc = leis.readShort();
-            xStartArc = leis.readShort();
-            bottomRect = leis.readShort();
-            rightRect = leis.readShort();
-            topRect = leis.readShort();
-            leftRect = leis.readShort();
+            readPointS(leis, endPoint);
+            readPointS(leis, startPoint);
+            readBounds(leis, bounds);
+
             return 8*LittleEndianConsts.SHORT_SIZE;
         }
 
         @Override
         public void draw(HwmfGraphics ctx) {
-            int x = Math.min(leftRect, rightRect);
-            int y = Math.min(topRect, bottomRect);
-            int w = Math.abs(leftRect - rightRect - 1);
-            int h = Math.abs(topRect - bottomRect - 1);
-            double startAngle = Math.toDegrees(Math.atan2(-(yStartArc - (topRect + h / 2.)), xStartArc - (leftRect + w / 2.)));
-            double endAngle =   Math.toDegrees(Math.atan2(-(yEndArc - (topRect + h / 2.)), xEndArc - (leftRect + w / 2.)));
+            double startAngle = Math.toDegrees(Math.atan2(-(startPoint.getY() - bounds.getCenterY()), startPoint.getX() - bounds.getCenterX()));
+            double endAngle =   Math.toDegrees(Math.atan2(-(endPoint.getY() - bounds.getCenterY()), endPoint.getX() - bounds.getCenterX()));
             double arcAngle = (endAngle - startAngle) + (endAngle - startAngle > 0 ? 0 : 360);
             if (startAngle < 0) {
                 startAngle += 360;
@@ -608,7 +468,7 @@ public class HwmfDraw {
 
             boolean fillShape;
             int arcClosure;
-            switch (getRecordType()) {
+            switch (getWmfRecordType()) {
                 default:
                 case arc:
                     arcClosure = Arc2D.OPEN;
@@ -624,7 +484,7 @@ public class HwmfDraw {
                     break;
             }
             
-            Shape s = new Arc2D.Double(x, y, w, h, startAngle, arcAngle, arcClosure);
+            Shape s = new Arc2D.Double(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight(), startAngle, arcAngle, arcClosure);
             if (fillShape) {
                 ctx.fill(s);
             } else {
@@ -641,7 +501,7 @@ public class HwmfDraw {
     public static class WmfPie extends WmfArc {
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.pie;
         }
     }
@@ -654,7 +514,7 @@ public class HwmfDraw {
     public static class WmfChord extends WmfArc {
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.chord;
         }
     }
@@ -673,10 +533,10 @@ public class HwmfDraw {
          * A 16-bit unsigned integer used to index into the WMF Object Table to
          * get the object to be selected.
          */
-        private int objectIndex;
+        protected int objectIndex;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.selectObject;
         }
 
@@ -695,4 +555,50 @@ public class HwmfDraw {
     private static int getWindingRule(HwmfGraphics ctx) {
         return ctx.getProperties().getPolyfillMode().awtFlag;
     }
- }
+
+    static int readBounds(LittleEndianInputStream leis, Rectangle2D bounds) {
+        /**
+         * The 16-bit signed integers that defines the corners of the bounding rectangle.
+         */
+        int bottom = leis.readShort();
+        int right = leis.readShort();
+        int top = leis.readShort();
+        int left = leis.readShort();
+
+        int x = Math.min(left, right);
+        int y = Math.min(top, bottom);
+        int w = Math.abs(left - right - 1);
+        int h = Math.abs(top - bottom - 1);
+
+        bounds.setRect(x, y, w, h);
+
+        return 4 * LittleEndianConsts.SHORT_SIZE;
+    }
+
+    static int readRectS(LittleEndianInputStream leis, Rectangle2D bounds) {
+        /**
+         * The 16-bit signed integers that defines the corners of the bounding rectangle.
+         */
+        int left = leis.readShort();
+        int top = leis.readShort();
+        int right = leis.readShort();
+        int bottom = leis.readShort();
+
+        int x = Math.min(left, right);
+        int y = Math.min(top, bottom);
+        int w = Math.abs(left - right - 1);
+        int h = Math.abs(top - bottom - 1);
+
+        bounds.setRect(x, y, w, h);
+
+        return 4 * LittleEndianConsts.SHORT_SIZE;
+    }
+
+    static int readPointS(LittleEndianInputStream leis, Point2D point) {
+        /** a signed integer that defines the x/y-coordinate, in logical units. */
+        int y = leis.readShort();
+        int x = leis.readShort();
+        point.setLocation(x, y);
+        return 2*LittleEndianConsts.SHORT_SIZE;
+    }
+}

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfEscape.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfEscape.java?rev=1840956&r1=1840955&r2=1840956&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfEscape.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfEscape.java Fri Sep 14 21:37:37 2018
@@ -185,7 +185,7 @@ public class HwmfEscape implements HwmfR
     private byte escapeData[];
     
     @Override
-    public HwmfRecordType getRecordType() {
+    public HwmfRecordType getWmfRecordType() {
         return HwmfRecordType.escape;
     }
     

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=1840956&r1=1840955&r2=1840956&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 Fri Sep 14 21:37:37 2018
@@ -17,8 +17,12 @@
 
 package org.apache.poi.hwmf.record;
 
+import static org.apache.poi.hwmf.record.HwmfDraw.readPointS;
+
 import java.awt.Shape;
 import java.awt.geom.Path2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
 import java.awt.image.BufferedImage;
 import java.io.IOException;
 
@@ -62,7 +66,7 @@ public class HwmfFill {
             this.flag = flag;
         }
 
-        static ColorUsage valueOf(int flag) {
+        public static ColorUsage valueOf(int flag) {
             for (ColorUsage bs : values()) {
                 if (bs.flag == flag) return bs;
             }
@@ -80,16 +84,16 @@ public class HwmfFill {
          * A 16-bit unsigned integer used to index into the WMF Object Table to get
          * the region to be filled.
          */
-        private int regionIndex;
+        protected int regionIndex;
 
         /**
          * A 16-bit unsigned integer used to index into the WMF Object Table to get the
          * brush to use for filling the region.
          */
-        private int brushIndex;
+        protected int brushIndex;
         
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.fillRegion;
         }
         
@@ -125,7 +129,7 @@ public class HwmfFill {
          */
         int regionIndex;
 
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.paintRegion;
         }
         
@@ -155,31 +159,21 @@ public class HwmfFill {
         /**
          * A 32-bit ColorRef Object that defines the color value.
          */
-        private HwmfColorRef colorRef;
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-         * point where filling is to start.
-         */
-        private int yStart;
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
-         * point where filling is to start.
-         */
-        private int xStart;
-        
-        
+        protected final HwmfColorRef colorRef = new HwmfColorRef();
+
+        /** the point where filling is to start. */
+        protected final Point2D start = new Point2D.Double();
+
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.floodFill;
         }
         
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            colorRef = new HwmfColorRef();
             int size = colorRef.init(leis);
-            yStart = leis.readShort();
-            xStart = leis.readShort();
-            return size+2*LittleEndianConsts.SHORT_SIZE;
+            size += readPointS(leis, start);
+            return size;
         }
 
         @Override
@@ -215,22 +209,22 @@ public class HwmfFill {
                 this.awtFlag = awtFlag;
             }
 
-            static HwmfPolyfillMode valueOf(int wmfFlag) {
+            public static HwmfPolyfillMode valueOf(int wmfFlag) {
                 for (HwmfPolyfillMode pm : values()) {
                     if (pm.wmfFlag == wmfFlag) return pm;
                 }
                 return null;
             }
         }
-        
+
         /**
-         * A 16-bit unsigned integer that defines polygon fill mode.
+         * An unsigned integer that defines polygon fill mode.
          * This MUST be one of the values: ALTERNATE = 0x0001, WINDING = 0x0002
          */
-        private HwmfPolyfillMode polyfillMode;
+        protected HwmfPolyfillMode polyfillMode;
         
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setPolyFillMode;
         }
         
@@ -251,7 +245,7 @@ public class HwmfFill {
      * The META_EXTFLOODFILL record fills an area with the brush that is defined in
      * the playback device context.
      */
-    public static class WmfExtFloodFill implements HwmfRecord {
+    public static class WmfExtFloodFill extends WmfFloodFill {
         
         /**
          * A 16-bit unsigned integer that defines the fill operation to be performed. This
@@ -266,38 +260,17 @@ public class HwmfFill {
          * Filling continues outward in all directions as long as the color is encountered.
          * This style is useful for filling areas with multicolored boundaries.
          */
-        private int mode;
-        
-        /**
-         * A 32-bit ColorRef Object that defines the color value.
-         */
-        private HwmfColorRef colorRef;
-        
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the point
-         * to be set.
-         */
-        private int y;
-        
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the point
-         * to be set.
-         */
-        private int x;  
+        protected int mode;
         
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.extFloodFill;
         }
         
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             mode = leis.readUShort();
-            colorRef = new HwmfColorRef();
-            int size = colorRef.init(leis);
-            y = leis.readShort();
-            x = leis.readShort();
-            return size+3*LittleEndianConsts.SHORT_SIZE;
+            return super.init(leis, recordSize, recordFunction)+LittleEndianConsts.SHORT_SIZE;
         }
 
         @Override
@@ -318,7 +291,7 @@ public class HwmfFill {
         private int region;
         
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.invertRegion;
         }
         
@@ -348,30 +321,10 @@ public class HwmfFill {
          */
         private HwmfTernaryRasterOp rasterOperation;
         
-        /**
-         * A 16-bit signed integer that defines the height, in logical units, of the rectangle.
-         */
-        private int height;
-        
-        /**
-         * A 16-bit signed integer that defines the width, in logical units, of the rectangle.
-         */
-        private int width;
-        
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-         * upper-left corner of the rectangle to be filled.
-         */
-        private int yLeft;
-        
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
-         * upper-left corner of the rectangle to be filled.
-         */
-        private int xLeft;
-        
+        private final Rectangle2D bounds = new Rectangle2D.Double();
+
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.patBlt;
         }
         
@@ -383,12 +336,7 @@ public class HwmfFill {
             rasterOperation = HwmfTernaryRasterOp.valueOf(rasterOpIndex);
             assert(rasterOpCode == rasterOperation.opCode);
             
-            height = leis.readShort();
-            width = leis.readShort();
-            yLeft = leis.readShort();
-            xLeft = leis.readShort();
-
-            return 6*LittleEndianConsts.SHORT_SIZE;
+            return readBounds2(leis, bounds)+2*LittleEndianConsts.SHORT_SIZE;
         }
 
         @Override
@@ -414,53 +362,22 @@ public class HwmfFill {
          * in the playback device context, and the destination pixels are to be combined to form the new 
          * image. This code MUST be one of the values in the Ternary Raster Operation Enumeration
          */
-        private HwmfTernaryRasterOp rasterOperation;
-        
-        /**
-         * A 16-bit signed integer that defines the height, in logical units, of the source rectangle.
-         */
-        private int srcHeight; 
-        /**
-         * A 16-bit signed integer that defines the width, in logical units, of the source rectangle.
-         */
-        private int srcWidth; 
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the upper-left corner 
-         * of the source rectangle.
-         */
-        private int ySrc;
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the upper-left corner 
-         * of the source rectangle.
-         */
-        private int xSrc;
-        /**
-         * A 16-bit signed integer that defines the height, in logical units, of the destination rectangle.
-         */
-        private int destHeight;
-        /**
-         * A 16-bit signed integer that defines the width, in logical units, of the destination rectangle.
-         */
-        private int destWidth;
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the upper-left 
-         * corner of the destination rectangle.
-         */
-        private int yDest;
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the upper-left 
-         * corner of the destination rectangle.
-         */
-        private int xDest;
-        
+        protected HwmfTernaryRasterOp rasterOperation;
+
+        /** the source rectangle */
+        protected final Rectangle2D srcBounds = new Rectangle2D.Double();
+
+        /** the destination rectangle */
+        protected final Rectangle2D dstBounds = new Rectangle2D.Double();
+
         /**
          * A variable-sized Bitmap16 Object that defines source image content.
          * This object MUST be specified, even if the raster operation does not require a source.
          */
-        HwmfBitmap16 target;
+        protected HwmfBitmap16 target;
         
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.stretchBlt;
         }
         
@@ -469,27 +386,23 @@ public class HwmfFill {
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             boolean hasBitmap = (recordSize > ((recordFunction >> 8) + 3));
 
-            int size = 0;
             int rasterOpCode = leis.readUShort();
             int rasterOpIndex = leis.readUShort();
             
             rasterOperation = HwmfTernaryRasterOp.valueOf(rasterOpIndex);
             assert(rasterOpCode == rasterOperation.opCode);
 
-            srcHeight = leis.readShort();
-            srcWidth = leis.readShort();
-            ySrc = leis.readShort();
-            xSrc = leis.readShort();
-            size = 6*LittleEndianConsts.SHORT_SIZE;
+            int size = 2*LittleEndianConsts.SHORT_SIZE;
+
+            size += readBounds2(leis, srcBounds);
+
             if (!hasBitmap) {
                 /*int reserved =*/ leis.readShort();
                 size += LittleEndianConsts.SHORT_SIZE;
             }
-            destHeight = leis.readShort();
-            destWidth = leis.readShort();
-            yDest = leis.readShort();
-            xDest = leis.readShort();
-            size += 4*LittleEndianConsts.SHORT_SIZE;
+
+            size += readBounds2(leis, dstBounds);
+
             if (hasBitmap) {
                 target = new HwmfBitmap16();
                 size += target.init(leis);
@@ -524,46 +437,13 @@ public class HwmfFill {
          * DIB contains explicit RGB values or indexes into a palette.
          */
         private ColorUsage colorUsage;
-        /**
-         * A 16-bit signed integer that defines the height, in logical units, of the
-         * source rectangle.
-         */
-        private int srcHeight;
-        /**
-         * A 16-bit signed integer that defines the width, in logical units, of the
-         * source rectangle.
-         */
-        private int srcWidth; 
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-         * source rectangle.
-         */
-        private int ySrc;
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the 
-         * source rectangle.
-         */
-        private int xSrc;
-        /**
-         * A 16-bit signed integer that defines the height, in logical units, of the 
-         * destination rectangle.
-         */
-        private int destHeight;
-        /**
-         * A 16-bit signed integer that defines the width, in logical units, of the 
-         * destination rectangle.
-         */
-        private int destWidth;
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the 
-         * upper-left corner of the destination rectangle.
-         */
-        private int yDst;
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the 
-         * upper-left corner of the destination rectangle.
-         */
-        private int xDst;
+
+        /** the source rectangle. */
+        protected final Rectangle2D srcBounds = new Rectangle2D.Double();
+
+        /** the destination rectangle. */
+        protected final Rectangle2D dstBounds = new Rectangle2D.Double();
+
         /**
          * A variable-sized DeviceIndependentBitmap Object (section 2.2.2.9) that is the 
          * source of the color data.
@@ -571,7 +451,7 @@ public class HwmfFill {
         private HwmfBitmapDib dib;
         
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.stretchDib;
         }
         
@@ -585,16 +465,12 @@ public class HwmfFill {
             assert(rasterOpCode == rasterOperation.opCode);
 
             colorUsage = ColorUsage.valueOf(leis.readUShort());
-            srcHeight = leis.readShort();
-            srcWidth = leis.readShort();
-            ySrc = leis.readShort();
-            xSrc = leis.readShort();
-            destHeight = leis.readShort();
-            destWidth = leis.readShort();
-            yDst = leis.readShort();
-            xDst = leis.readShort();
-            
-            int size = 11*LittleEndianConsts.SHORT_SIZE;
+
+            int size = 3*LittleEndianConsts.SHORT_SIZE;
+
+            size += readBounds2(leis, srcBounds);
+            size += readBounds2(leis, dstBounds);
+
             dib = new HwmfBitmapDib();
             size += dib.init(leis, (int)(recordSize-6-size));
 
@@ -617,53 +493,10 @@ public class HwmfFill {
         }
     }
     
-    public static class WmfBitBlt implements HwmfRecord {
-
-        /**
-         * A 32-bit unsigned integer that defines how the source pixels, the current brush in the playback 
-         * device context, and the destination pixels are to be combined to form the new image.
-         */
-        private HwmfTernaryRasterOp rasterOperation;
-        
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the upper-left corner 
-        of the source rectangle.
-         */
-        private int ySrc; 
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the upper-left corner 
-        of the source rectangle.
-         */
-        private int xSrc; 
-        /**
-         * A 16-bit signed integer that defines the height, in logical units, of the source and 
-        destination rectangles.
-         */
-        private int height;
-        /**
-         * A 16-bit signed integer that defines the width, in logical units, of the source and destination 
-        rectangles.
-         */
-        private int width;
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the upper-left 
-        corner of the destination rectangle.
-         */
-        private int yDest;
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the upper-left 
-        corner of the destination rectangle.
-         */
-        private int xDest;
-        
-        /**
-         * A variable-sized Bitmap16 Object that defines source image content.
-         * This object MUST be specified, even if the raster operation does not require a source.
-         */
-        private HwmfBitmap16 target;
+    public static class WmfBitBlt extends WmfStretchBlt {
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.bitBlt;
         }
         
@@ -671,40 +504,32 @@ public class HwmfFill {
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             boolean hasBitmap = (recordSize/2 != ((recordFunction >> 8) + 3));
 
-            int size = 0;
             int rasterOpCode = leis.readUShort();
             int rasterOpIndex = leis.readUShort();
             
             rasterOperation = HwmfTernaryRasterOp.valueOf(rasterOpIndex);
             assert(rasterOpCode == rasterOperation.opCode);
 
-            ySrc = leis.readShort();
-            xSrc = leis.readShort();
+            int size = 2*LittleEndianConsts.SHORT_SIZE;
+
+            final Point2D srcPnt = new Point2D.Double();
+            size += readPointS(leis, srcPnt);
 
-            size = 4*LittleEndianConsts.SHORT_SIZE;
-            
             if (!hasBitmap) {
                 /*int reserved =*/ leis.readShort();
                 size += LittleEndianConsts.SHORT_SIZE;
             }
-            
-            height = leis.readShort();
-            width = leis.readShort();
-            yDest = leis.readShort();
-            xDest = leis.readShort();
 
-            size += 4*LittleEndianConsts.SHORT_SIZE;
+            size += readBounds2(leis, dstBounds);
+
             if (hasBitmap) {
                 target = new HwmfBitmap16();
                 size += target.init(leis);
             }
-            
-            return size;
-        }
 
-        @Override
-        public void draw(HwmfGraphics ctx) {
+            srcBounds.setRect(srcPnt.getX(), srcPnt.getY(), dstBounds.getWidth(), dstBounds.getHeight());
             
+            return size;
         }
     }
 
@@ -729,36 +554,13 @@ public class HwmfFill {
          * A 16-bit unsigned integer that defines the starting scan line in the source.
          */
         private int startScan;  
-        /**
-         * A 16-bit unsigned integer that defines the y-coordinate, in logical units, of the
-         * source rectangle.
-         */
-        private int yDib;  
-        /**
-         * A 16-bit unsigned integer that defines the x-coordinate, in logical units, of the
-         * source rectangle.
-         */
-        private int xDib;  
-        /**
-         * A 16-bit unsigned integer that defines the height, in logical units, of the
-         * source and destination rectangles.
-         */
-        private int height;
-        /**
-         * A 16-bit unsigned integer that defines the width, in logical units, of the
-         * source and destination rectangles.
-         */
-        private int width;
-        /**
-         * A 16-bit unsigned integer that defines the y-coordinate, in logical units, of the
-         * upper-left corner of the destination rectangle.
-         */
-        private int yDest;
-        /**
-         * A 16-bit unsigned integer that defines the x-coordinate, in logical units, of the
-         * upper-left corner of the destination rectangle.
-         */
-        private int xDest;
+
+        /** the source rectangle */
+        protected final Rectangle2D srcBounds = new Rectangle2D.Double();
+
+        /** the destination rectangle, having the same dimension as the source rectangle */
+        protected final Rectangle2D dstBounds = new Rectangle2D.Double();
+
         /**
          * A variable-sized DeviceIndependentBitmap Object that is the source of the color data.
          */
@@ -766,7 +568,7 @@ public class HwmfFill {
         
         
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setDibToDev;
         }
         
@@ -775,17 +577,19 @@ public class HwmfFill {
             colorUsage = ColorUsage.valueOf(leis.readUShort());
             scanCount = leis.readUShort();
             startScan = leis.readUShort();
-            yDib = leis.readUShort();
-            xDib = leis.readUShort();
-            height = leis.readUShort();
-            width = leis.readUShort();
-            yDest = leis.readUShort();
-            xDest = leis.readUShort();
-            
-            int size = 9*LittleEndianConsts.SHORT_SIZE;
+
+            int size = 3*LittleEndianConsts.SHORT_SIZE;
+
+            final Point2D srcPnt = new Point2D.Double();
+            size += readPointS(leis, srcPnt);
+
+            size += readBounds2(leis, dstBounds);
+
             dib = new HwmfBitmapDib();
             size += dib.init(leis, (int)(recordSize-6-size));
-            
+
+            srcBounds.setRect(srcPnt.getX(), srcPnt.getY(), dstBounds.getWidth(), dstBounds.getHeight());
+
             return size;
         }        
 
@@ -806,52 +610,9 @@ public class HwmfFill {
     }
 
 
-    public static class WmfDibBitBlt implements HwmfRecord, HwmfImageRecord, HwmfObjectTableEntry {
-
-        /**
-         * A 32-bit unsigned integer that defines how the source pixels, the current brush
-         * in the playback device context, and the destination pixels are to be combined to form the
-         * new image. This code MUST be one of the values in the Ternary Raster Operation Enumeration.
-         */
-        HwmfTernaryRasterOp rasterOperation;  
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the source rectangle.
-         */
-        private int ySrc;
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the source rectangle.
-         */
-        private int xSrc;
-        /**
-         * A 16-bit signed integer that defines the height, in logical units, of the source and 
-         * destination rectangles.
-         */
-        private int height;
-        /**
-         * A 16-bit signed integer that defines the width, in logical units, of the source and destination
-         * rectangles.
-         */
-        private int width;
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the upper-left
-         * corner of the destination rectangle.
-         */
-        private int yDest;
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the upper-left 
-         * corner of the destination rectangle.
-         */
-        private int xDest;
-        
-        /**
-         * A variable-sized DeviceIndependentBitmap Object that defines image content.
-         * This object MUST be specified, even if the raster operation does not require a source.
-         */
-        private HwmfBitmapDib target;
-        
-        
+    public static class WmfDibBitBlt extends WmfDibStretchBlt {
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.dibBitBlt;
         }
         
@@ -859,47 +620,31 @@ public class HwmfFill {
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             boolean hasBitmap = (recordSize/2 != ((recordFunction >> 8) + 3));
 
-            int size = 0;
             int rasterOpCode = leis.readUShort();
             int rasterOpIndex = leis.readUShort();
             
             rasterOperation = HwmfTernaryRasterOp.valueOf(rasterOpIndex);
             assert(rasterOpCode == rasterOperation.opCode);
 
-            ySrc = leis.readShort();
-            xSrc = leis.readShort();
-            size = 4*LittleEndianConsts.SHORT_SIZE;
+            int size = 2*LittleEndianConsts.SHORT_SIZE;
+
+            final Point2D srcPnt = new Point2D.Double();
+            size += readPointS(leis, srcPnt);
             if (!hasBitmap) {
                 /*int reserved =*/ leis.readShort();
                 size += LittleEndianConsts.SHORT_SIZE;
             }
-            height = leis.readShort();
-            width = leis.readShort();
-            yDest = leis.readShort();
-            xDest = leis.readShort();
-            
-            size += 4*LittleEndianConsts.SHORT_SIZE;
+
+            size += readBounds2(leis, dstBounds);
             if (hasBitmap) {
                 target = new HwmfBitmapDib();
                 size += target.init(leis, (int)(recordSize-6-size));
             }
-            
-            return size;
-        }
 
-        @Override
-        public void draw(HwmfGraphics ctx) {
-            ctx.addObjectTableEntry(this);
-        }
-        
-        @Override
-        public void applyObject(HwmfGraphics ctx) {
-            
-        }
+            // the destination rectangle, having the same dimension as the source rectangle
+            srcBounds.setRect(srcPnt.getX(), srcPnt.getY(), dstBounds.getWidth(), dstBounds.getHeight());
 
-        @Override
-        public BufferedImage getImage() {
-            return (target == null) ? null : target.getImage();
+            return size;
         }
     }
 
@@ -909,53 +654,22 @@ public class HwmfFill {
          * in the playback device context, and the destination pixels are to be combined to form the
          * new image. This code MUST be one of the values in the Ternary Raster Operation Enumeration.
          */
-        private HwmfTernaryRasterOp rasterOperation;
-        /**
-         * A 16-bit signed integer that defines the height, in logical units, of the source rectangle.
-         */
-        private int srcHeight;
-        /**
-         * A 16-bit signed integer that defines the width, in logical units, of the source rectangle.
-         */
-        private int srcWidth;
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-         * upper-left corner of the source rectangle.
-         */
-        private int ySrc;
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
-         * upper-left corner of the source rectangle.
-         */
-        private int xSrc;
-        /**
-         * A 16-bit signed integer that defines the height, in logical units, of the
-         * destination rectangle.
-         */
-        private int destHeight;
-        /**
-         * A 16-bit signed integer that defines the width, in logical units, of the
-         * destination rectangle.
-         */
-        private int destWidth;
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units,
-         * of the upper-left corner of the destination rectangle.
-         */
-        private int yDest;
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units,
-         * of the upper-left corner of the destination rectangle.
-         */
-        private int xDest;
+        protected HwmfTernaryRasterOp rasterOperation;
+
+        /** the source rectangle */
+        protected final Rectangle2D srcBounds = new Rectangle2D.Double();
+
+        /** the destination rectangle */
+        protected final Rectangle2D dstBounds = new Rectangle2D.Double();
+
         /**
          * A variable-sized DeviceIndependentBitmap Object that defines image content.
          * This object MUST be specified, even if the raster operation does not require a source.
          */
-        HwmfBitmapDib target;
-        
+        protected HwmfBitmapDib target;
+
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.dibStretchBlt;
         }
         
@@ -963,27 +677,21 @@ public class HwmfFill {
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             boolean hasBitmap = (recordSize > ((recordFunction >> 8) + 3));
 
-            int size = 0;
             int rasterOpCode = leis.readUShort();
             int rasterOpIndex = leis.readUShort();
             
             rasterOperation = HwmfTernaryRasterOp.valueOf(rasterOpIndex);
             assert(rasterOpCode == rasterOperation.opCode);
 
-            srcHeight = leis.readShort();
-            srcWidth = leis.readShort();
-            ySrc = leis.readShort();
-            xSrc = leis.readShort();
-            size = 6*LittleEndianConsts.SHORT_SIZE;
+            int size = 2*LittleEndianConsts.SHORT_SIZE;
+
+            size += readBounds2(leis, srcBounds);
             if (!hasBitmap) {
                 /*int reserved =*/ leis.readShort();
                 size += LittleEndianConsts.SHORT_SIZE;
             }
-            destHeight = leis.readShort();
-            destWidth = leis.readShort();
-            yDest = leis.readShort();
-            xDest = leis.readShort();
-            size += 4*LittleEndianConsts.SHORT_SIZE;
+
+            size += readBounds2(leis, dstBounds);
             if (hasBitmap) {
                 target = new HwmfBitmapDib();
                 size += target.init(leis, (int)(recordSize-6-size));
@@ -996,15 +704,30 @@ public class HwmfFill {
         public void draw(HwmfGraphics ctx) {
             ctx.addObjectTableEntry(this);
         }
-        
+
         @Override
         public void applyObject(HwmfGraphics ctx) {
-            
+
         }
 
         @Override
         public BufferedImage getImage() {
-            return target.getImage();
+            return (target == null) ? null : target.getImage();
         }
     }
+
+    static int readBounds2(LittleEndianInputStream leis, Rectangle2D bounds) {
+        /**
+         * The 16-bit signed integers that defines the corners of the bounding rectangle.
+         */
+        int h = leis.readShort();
+        int w = leis.readShort();
+        int y = leis.readShort();
+        int x = leis.readShort();
+
+        bounds.setRect(x, y, w, h);
+
+        return 4 * LittleEndianConsts.SHORT_SIZE;
+    }
+
 }

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java?rev=1840956&r1=1840955&r2=1840956&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java Fri Sep 14 21:37:37 2018
@@ -24,6 +24,8 @@ import org.apache.poi.common.usermodel.f
 import org.apache.poi.common.usermodel.fonts.FontFamily;
 import org.apache.poi.common.usermodel.fonts.FontInfo;
 import org.apache.poi.common.usermodel.fonts.FontPitch;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 
@@ -90,7 +92,7 @@ public class HwmfFont implements FontInf
             this.flag = flag;
         }
 
-        static WmfOutPrecision valueOf(int flag) {
+        public static WmfOutPrecision valueOf(int flag) {
             for (WmfOutPrecision op : values()) {
                 if (op.flag == flag) {
                     return op;
@@ -104,22 +106,17 @@ public class HwmfFont implements FontInf
      * ClipPrecision Flags specify clipping precision, which defines how to clip characters that are
      * partially outside a clipping region. These flags can be combined to specify multiple options.
      */
-    public enum WmfClipPrecision {
+    public static class WmfClipPrecision {
 
-        /**
-         * Specifies that default clipping MUST be used.
-         */
-        CLIP_DEFAULT_PRECIS (0x00000000),
+        /** Specifies that default clipping MUST be used. */
+        private static final BitField CLIP_DEFAULT_PRECIS = BitFieldFactory.getInstance(0x0000);
 
-        /**
-         * This value SHOULD NOT be used.
-         */
-        CLIP_CHARACTER_PRECIS (0x00000001),
 
-        /**
-         * This value MAY be returned when enumerating rasterized, TrueType and vector fonts.
-         */
-        CLIP_STROKE_PRECIS (0x00000002),
+        /** This value SHOULD NOT be used. */
+        private static final BitField CLIP_CHARACTER_PRECIS = BitFieldFactory.getInstance(0x0001);
+
+        /** This value MAY be returned when enumerating rasterized, TrueType and vector fonts. */
+        private static final BitField CLIP_STROKE_PRECIS = BitFieldFactory.getInstance(0x0002);
 
         /**
          * This value is used to control font rotation, as follows:
@@ -129,37 +126,25 @@ public class HwmfFont implements FontInf
          * If clear, device fonts SHOULD rotate counterclockwise, but the rotation of other fonts
          * SHOULD be determined by the orientation of the coordinate system.
          */
-        CLIP_LH_ANGLES (0x00000010),
+        private static final BitField CLIP_LH_ANGLES = BitFieldFactory.getInstance(0x0010);
 
-        /**
-         * This value SHOULD NOT be used.
-         */
-        CLIP_TT_ALWAYS (0x00000020),
+        /** This value SHOULD NOT be used. */
+        private static final BitField CLIP_TT_ALWAYS = BitFieldFactory.getInstance(0x0020);
 
-        /**
-         * This value specifies that font association SHOULD< be turned off.
-         */
-        CLIP_DFA_DISABLE (0x00000040),
+        /** This value specifies that font association SHOULD< be turned off. */
+        private static final BitField CLIP_DFA_DISABLE = BitFieldFactory.getInstance(0x0040);
 
         /**
          * This value specifies that font embedding MUST be used to render document content;
          * embedded fonts are read-only.
          */
-        CLIP_EMBEDDED (0x00000080);
-
+        private static final BitField CLIP_EMBEDDED = BitFieldFactory.getInstance(0x0080);
 
         int flag;
-        WmfClipPrecision(int flag) {
-            this.flag = flag;
-        }
 
-        static WmfClipPrecision valueOf(int flag) {
-            for (WmfClipPrecision cp : values()) {
-                if (cp.flag == flag) {
-                    return cp;
-                }
-            }
-            return null;
+        public int init(LittleEndianInputStream leis) {
+            flag = leis.readUByte();
+            return LittleEndianConsts.BYTE_SIZE;
         }
     }
 
@@ -210,7 +195,7 @@ public class HwmfFont implements FontInf
             this.flag = flag;
         }
 
-        static WmfFontQuality valueOf(int flag) {
+        public static WmfFontQuality valueOf(int flag) {
             for (WmfFontQuality fq : values()) {
                 if (fq.flag == flag) {
                     return fq;
@@ -240,7 +225,7 @@ public class HwmfFont implements FontInf
      * For all height comparisons, the font mapper SHOULD find the largest physical
      * font that does not exceed the requested size.
      */
-    int height;
+    protected int height;
 
     /**
      * A 16-bit signed integer that defines the average width, in logical units, of
@@ -248,45 +233,45 @@ public class HwmfFont implements FontInf
      * against the digitization aspect ratio of the available fonts to find the closest match,
      * determined by the absolute value of the difference.
      */
-    int width;
+    protected int width;
 
     /**
      * A 16-bit signed integer that defines the angle, in tenths of degrees, between the
      * escapement vector and the x-axis of the device. The escapement vector is parallel
      * to the base line of a row of text.
      */
-    int escapement;
+    protected int escapement;
 
     /**
      * A 16-bit signed integer that defines the angle, in tenths of degrees,
      * between each character's base line and the x-axis of the device.
      */
-    int orientation;
+    protected int orientation;
 
     /**
      * A 16-bit signed integer that defines the weight of the font in the range 0
      * through 1000. For example, 400 is normal and 700 is bold. If this value is 0x0000,
      * a default weight SHOULD be used.
      */
-    int weight;
+    protected int weight;
 
     /**
      * A 8-bit Boolean value that specifies the italic attribute of the font.
      * 0 = not italic / 1 = italic.
      */
-    boolean italic;
+    protected boolean italic;
 
     /**
      * An 8-bit Boolean value that specifies the underline attribute of the font.
      * 0 = not underlined / 1 = underlined
      */
-    boolean underline;
+    protected boolean underline;
 
     /**
      * An 8-bit Boolean value that specifies the strike out attribute of the font.
      * 0 = not striked out / 1 = striked out
      */
-    boolean strikeOut;
+    protected boolean strikeOut;
 
     /**
      * An 8-bit unsigned integer that defines the character set.
@@ -299,12 +284,12 @@ public class HwmfFont implements FontInf
      * If a typeface name in the FaceName field is specified, the CharSet value MUST match the
      * character set of that typeface.
      */
-    FontCharset charSet;
+    protected FontCharset charSet;
 
     /**
      * An 8-bit unsigned integer that defines the output precision.
      */
-    WmfOutPrecision outPrecision;
+    protected WmfOutPrecision outPrecision;
 
     /**
      * An 8-bit unsigned integer that defines the clipping precision.
@@ -312,40 +297,40 @@ public class HwmfFont implements FontInf
      *
      * @see WmfClipPrecision
      */
-    WmfClipPrecision clipPrecision;
+    protected final WmfClipPrecision clipPrecision = new WmfClipPrecision();
 
     /**
      * An 8-bit unsigned integer that defines the output quality.
      */
-    WmfFontQuality quality;
+    protected WmfFontQuality quality;
 
     /**
      * A PitchAndFamily object that defines the pitch and the family of the font.
      * Font families specify the look of fonts in a general way and are intended for
      * specifying fonts when the exact typeface wanted is not available.
      */
-    int pitchAndFamily;
+    protected int pitchAndFamily;
     
     /**
      * Font families specify the look of fonts in a general way and are
      * intended for specifying fonts when the exact typeface wanted is not available.
      * (LSB 4 bits)
      */
-    FontFamily family;
+    protected FontFamily family;
     
     /**
      * A property of a font that describes the pitch (MSB 2 bits)
      */
-    FontPitch pitch;
+    protected FontPitch pitch;
 
     /**
      * A null-terminated string of 8-bit Latin-1 [ISO/IEC-8859-1] ANSI
      * characters that specifies the typeface name of the font. The length of this string MUST NOT
      * exceed 32 8-bit characters, including the terminating null.
      */
-    String facename;
+    protected String facename;
 
-    public int init(LittleEndianInputStream leis) throws IOException {
+    public int init(LittleEndianInputStream leis, long recordSize) throws IOException {
         height = leis.readShort();
         width = leis.readShort();
         escapement = leis.readShort();
@@ -356,21 +341,17 @@ public class HwmfFont implements FontInf
         strikeOut = leis.readByte() != 0;
         charSet = FontCharset.valueOf(leis.readUByte());
         outPrecision = WmfOutPrecision.valueOf(leis.readUByte());
-        clipPrecision = WmfClipPrecision.valueOf(leis.readUByte());
+        clipPrecision.init(leis);
         quality = WmfFontQuality.valueOf(leis.readUByte());
         pitchAndFamily = leis.readUByte();
-        
-        byte buf[] = new byte[32], b, readBytes = 0;
-        do {
-            if (readBytes == 32) {
-                throw new IOException("Font facename can't be determined.");
-            }
 
-            buf[readBytes++] = b = leis.readByte();
-        } while (b != 0 && b != -1 && readBytes <= 32);
-        
-        facename = new String(buf, 0, readBytes-1, StandardCharsets.ISO_8859_1);
-        
+        StringBuilder sb = new StringBuilder();
+        int readBytes = readString(leis, sb, 32);
+        if (readBytes == -1) {
+            throw new IOException("Font facename can't be determined.");
+        }
+        facename = sb.toString();
+
         return 5*LittleEndianConsts.SHORT_SIZE+8*LittleEndianConsts.BYTE_SIZE+readBytes;
     }
 
@@ -471,4 +452,19 @@ public class HwmfFont implements FontInf
     public void setCharset(FontCharset charset) {
         throw new UnsupportedOperationException("setCharset not supported by HwmfFont.");
     }
+
+    protected int readString(LittleEndianInputStream leis, StringBuilder sb, int limit) throws IOException {
+        byte buf[] = new byte[limit], b, readBytes = 0;
+        do {
+            if (readBytes == limit) {
+                return -1;
+            }
+
+            buf[readBytes++] = b = leis.readByte();
+        } while (b != 0 && b != -1 && readBytes <= limit);
+
+        sb.append(new String(buf, 0, readBytes-1, StandardCharsets.ISO_8859_1));
+
+        return readBytes;
+    }
 }

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfHatchStyle.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfHatchStyle.java?rev=1840956&r1=1840955&r2=1840956&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfHatchStyle.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfHatchStyle.java Fri Sep 14 21:37:37 2018
@@ -39,7 +39,7 @@ public enum HwmfHatchStyle {
         this.flag = flag;
     }
 
-    static HwmfHatchStyle valueOf(int flag) {
+    public static HwmfHatchStyle valueOf(int flag) {
         for (HwmfHatchStyle hs : values()) {
             if (hs.flag == flag) return hs;
         }

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMapMode.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMapMode.java?rev=1840956&r1=1840955&r2=1840956&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMapMode.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMapMode.java Fri Sep 14 21:37:37 2018
@@ -105,7 +105,7 @@ public enum HwmfMapMode {
         this.scale = scale;
     }
 
-    static HwmfMapMode valueOf(int flag) {
+    public static HwmfMapMode valueOf(int flag) {
         for (HwmfMapMode mm : values()) {
             if (mm.flag == flag) return mm;
         }

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=1840956&r1=1840955&r2=1840956&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 Fri Sep 14 21:37:37 2018
@@ -17,6 +17,7 @@
 
 package org.apache.poi.hwmf.record;
 
+import java.awt.geom.Dimension2D;
 import java.awt.image.BufferedImage;
 import java.io.IOException;
 
@@ -24,6 +25,7 @@ import org.apache.poi.hwmf.draw.HwmfDraw
 import org.apache.poi.hwmf.draw.HwmfGraphics;
 import org.apache.poi.hwmf.record.HwmfFill.ColorUsage;
 import org.apache.poi.hwmf.record.HwmfFill.HwmfImageRecord;
+import org.apache.poi.util.Dimension2DDouble;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 
@@ -34,7 +36,7 @@ public class HwmfMisc {
      */
     public static class WmfSaveDc implements HwmfRecord {
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.saveDc;
         }
 
@@ -53,7 +55,7 @@ public class HwmfMisc {
      * The META_SETRELABS record is reserved and not supported.
      */
     public static class WmfSetRelabs implements HwmfRecord {
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setRelabs;
         }
 
@@ -81,7 +83,7 @@ public class HwmfMisc {
         private int nSavedDC;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.restoreDc;
         }
 
@@ -106,7 +108,7 @@ public class HwmfMisc {
         private HwmfColorRef colorRef;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setBkColor;
         }
 
@@ -140,7 +142,7 @@ public class HwmfMisc {
                 this.flag = flag;
             }
 
-            static HwmfBkMode valueOf(int flag) {
+            public static HwmfBkMode valueOf(int flag) {
                 for (HwmfBkMode bs : values()) {
                     if (bs.flag == flag) return bs;
                 }
@@ -148,9 +150,9 @@ public class HwmfMisc {
             }
         }
 
-        private HwmfBkMode bkMode;
+        protected HwmfBkMode bkMode;
 
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setBkMode;
         }
 
@@ -180,7 +182,7 @@ public class HwmfMisc {
         private int layout;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setLayout;
         }
 
@@ -205,10 +207,10 @@ public class HwmfMisc {
      */
     public static class WmfSetMapMode implements HwmfRecord {
 
-        private HwmfMapMode mapMode;
+        protected HwmfMapMode mapMode;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setMapMode;
         }
 
@@ -234,12 +236,13 @@ public class HwmfMisc {
         /**
          * A 32-bit unsigned integer that defines whether the font mapper should attempt to
          * match a font's aspect ratio to the current device's aspect ratio. If bit 0 is
-         * set, the mapper selects only matching fonts.
+         * set, the font mapper SHOULD select only fonts that match the aspect ratio of the
+         * output device, as it is currently defined in the playback device context.
          */
         private long mapperValues;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setMapperFlags;
         }
 
@@ -262,14 +265,11 @@ public class HwmfMisc {
      */
     public static class WmfSetRop2 implements HwmfRecord {
 
-        /**
-         * A 16-bit unsigned integer that defines the foreground binary raster
-         * operation mixing mode
-         */
-        private HwmfBinaryRasterOp drawMode;
+        /** An unsigned integer that defines the foreground binary raster operation mixing mode */
+        protected HwmfBinaryRasterOp drawMode;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setRop2;
         }
 
@@ -291,24 +291,63 @@ public class HwmfMisc {
      */
     public static class WmfSetStretchBltMode implements HwmfRecord {
 
-        /**
-         * A 16-bit unsigned integer that defines bitmap stretching mode.
-         * This MUST be one of the values:
-         * BLACKONWHITE = 0x0001,
-         * WHITEONBLACK = 0x0002,
-         * COLORONCOLOR = 0x0003,
-         * HALFTONE = 0x0004
-         */
-        private int setStretchBltMode;
+        public enum StretchBltMode {
+            /**
+             * Performs a Boolean AND operation by using the color values for the eliminated and existing pixels.
+             * If the bitmap is a monochrome bitmap, this mode preserves black pixels at the expense of white pixels.
+             *
+             * EMF name: STRETCH_ANDSCANS
+             */
+            BLACKONWHITE(0x0001),
+            /**
+             * Performs a Boolean OR operation by using the color values for the eliminated and existing pixels.
+             * If the bitmap is a monochrome bitmap, this mode preserves white pixels at the expense of black pixels.
+             *
+             * EMF name: STRETCH_ORSCANS
+             */
+            WHITEONBLACK(0x0002),
+            /**
+             * Deletes the pixels. This mode deletes all eliminated lines of pixels without trying
+             * to preserve their information.
+             *
+             * EMF name: STRETCH_DELETESCANS
+             */
+            COLORONCOLOR(0x0003),
+            /**
+             * Maps pixels from the source rectangle into blocks of pixels in the destination rectangle.
+             * The average color over the destination block of pixels approximates the color of the source
+             * pixels.
+             *
+             * After setting the HALFTONE stretching mode, the brush origin MUST be set to avoid misalignment
+             * artifacts - in EMF this is done via EmfSetBrushOrgEx
+             *
+             * EMF name: STRETCH_HALFTONE
+             */
+            HALFTONE(0x0004);
+
+            public final int flag;
+            StretchBltMode(int flag) {
+                this.flag = flag;
+            }
+
+            public static StretchBltMode valueOf(int flag) {
+                for (StretchBltMode bs : values()) {
+                    if (bs.flag == flag) return bs;
+                }
+                return null;
+            }
+        }
+
+        protected StretchBltMode stretchBltMode;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setStretchBltMode;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            setStretchBltMode = leis.readUShort();
+            stretchBltMode = StretchBltMode.valueOf(leis.readUShort());
             return LittleEndianConsts.SHORT_SIZE;
         }
 
@@ -341,7 +380,7 @@ public class HwmfMisc {
         private HwmfBitmap16 pattern16;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.dibCreatePatternBrush;
         }
 
@@ -403,10 +442,10 @@ public class HwmfMisc {
          * A 16-bit unsigned integer used to index into the WMF Object Table to
          * get the object to be deleted.
          */
-        private int objectIndex;
+        protected int objectIndex;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.deleteObject;
         }
 
@@ -418,6 +457,12 @@ public class HwmfMisc {
 
         @Override
         public void draw(HwmfGraphics ctx) {
+            /* TODO:
+             * The object specified by this record MUST be deleted from the EMF Object Table.
+             * If the deleted object is currently selected in the playback device context,
+             * the default object for that graphics property MUST be restored.
+             */
+
             ctx.unsetObjectTableEntry(objectIndex);
         }
     }
@@ -427,7 +472,7 @@ public class HwmfMisc {
         private HwmfBitmap16 pattern;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.createPatternBrush;
         }
 
@@ -452,30 +497,28 @@ public class HwmfMisc {
 
     public static class WmfCreatePenIndirect implements HwmfRecord, HwmfObjectTableEntry {
 
-        private HwmfPenStyle penStyle;
-        /**
-         * A 32-bit PointS Object that specifies a point for the object dimensions.
-         * The x-coordinate is the pen width. The y-coordinate is ignored.
-         */
-        private int xWidth;
-        @SuppressWarnings("unused")
-        private int yWidth;
+        protected HwmfPenStyle penStyle;
+
+        protected final Dimension2D dimension = new Dimension2DDouble();
         /**
          * A 32-bit ColorRef Object that specifies the pen color value.
          */
-        private HwmfColorRef colorRef;
+        protected final HwmfColorRef colorRef = new HwmfColorRef();
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.createPenIndirect;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             penStyle = HwmfPenStyle.valueOf(leis.readUShort());
-            xWidth = leis.readShort();
-            yWidth = leis.readShort();
-            colorRef = new HwmfColorRef();
+            // A 32-bit PointS Object that specifies a point for the object dimensions.
+            // The x-coordinate is the pen width. The y-coordinate is ignored.
+            int xWidth = leis.readShort();
+            int yWidth = leis.readShort();
+            dimension.setSize(xWidth, yWidth);
+
             int size = colorRef.init(leis);
             return size+3*LittleEndianConsts.SHORT_SIZE;
         }
@@ -490,7 +533,7 @@ public class HwmfMisc {
             HwmfDrawProperties p = ctx.getProperties();
             p.setPenStyle(penStyle);
             p.setPenColor(colorRef);
-            p.setPenWidth(xWidth);
+            p.setPenWidth(dimension.getWidth());
         }
     }
 
@@ -540,19 +583,14 @@ public class HwmfMisc {
      * </table>
      */
     public static class WmfCreateBrushIndirect implements HwmfRecord, HwmfObjectTableEntry {
-        private HwmfBrushStyle brushStyle;
+        protected HwmfBrushStyle brushStyle;
 
-        private HwmfColorRef colorRef;
+        protected HwmfColorRef colorRef;
 
-        /**
-         * A 16-bit field that specifies the brush hatch type.
-         * Its interpretation depends on the value of BrushStyle.
-         *
-         */
-        private HwmfHatchStyle brushHatch;
+        protected HwmfHatchStyle brushHatch;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.createBrushIndirect;
         }
 

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfPalette.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfPalette.java?rev=1840956&r1=1840955&r2=1840956&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfPalette.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfPalette.java Fri Sep 14 21:37:37 2018
@@ -39,12 +39,12 @@ public class HwmfPalette {
         private int values;
         private Color colorRef;
 
-        private PaletteEntry() {
+        public PaletteEntry() {
             this.values = PC_RESERVED.set(0);
             this.colorRef = Color.BLACK;
         }
 
-        private PaletteEntry(PaletteEntry other) {
+        public PaletteEntry(PaletteEntry other) {
             this.values = other.values;
             this.colorRef = other.colorRef;
         }
@@ -100,19 +100,24 @@ public class HwmfPalette {
          * used with the META_SETPALENTRIES and META_ANIMATEPALETTE record types.
          * When used with META_CREATEPALETTE, it MUST be 0x0300
          */
-        private int start;
+        protected int start;
 
-        private List<PaletteEntry> palette = new ArrayList<>();
+        protected final List<PaletteEntry> palette = new ArrayList<>();
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             start = leis.readUShort();
+            int size = readPaletteEntries(leis, -1);
+            return size + LittleEndianConsts.SHORT_SIZE;
+        }
+
+        protected int readPaletteEntries(LittleEndianInputStream leis, int nbrOfEntries) throws IOException {
             /**
              * NumberOfEntries (2 bytes):  A 16-bit unsigned integer that defines the number of objects in
              * aPaletteEntries.
              */
-            int numberOfEntries = leis.readUShort();
-            int size = 2*LittleEndianConsts.SHORT_SIZE;
+            final int numberOfEntries = (nbrOfEntries > -1) ? nbrOfEntries : leis.readUShort();
+            int size = (nbrOfEntries > -1) ? 0 : LittleEndianConsts.SHORT_SIZE;
             for (int i=0; i<numberOfEntries; i++) {
                 PaletteEntry pe = new PaletteEntry();
                 size += pe.init(leis);
@@ -144,7 +149,7 @@ public class HwmfPalette {
      */
     public static class WmfCreatePalette extends WmfPaletteParent implements HwmfObjectTableEntry {
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.createPalette;
         }
 
@@ -160,7 +165,7 @@ public class HwmfPalette {
      */
     public static class WmfSetPaletteEntries extends WmfPaletteParent {
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setPalEntries;
         }
 
@@ -197,10 +202,10 @@ public class HwmfPalette {
          * A 16-bit unsigned integer that defines the number of entries in
          * the logical palette.
          */
-        int numberOfEntries;
+        protected int numberOfEntries;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.resizePalette;
         }
 
@@ -238,10 +243,10 @@ public class HwmfPalette {
          * A 16-bit unsigned integer used to index into the WMF Object Table to get
          * the Palette Object to be selected.
          */
-        private int paletteIndex;
+        protected int paletteIndex;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.selectPalette;
         }
 
@@ -263,7 +268,7 @@ public class HwmfPalette {
      */
     public static class WmfRealizePalette implements HwmfRecord {
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.realizePalette;
         }
 
@@ -292,7 +297,7 @@ public class HwmfPalette {
      */
     public static class WmfAnimatePalette extends WmfPaletteParent {
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.animatePalette;
         }
 

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfPenStyle.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfPenStyle.java?rev=1840956&r1=1840955&r2=1840956&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfPenStyle.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfPenStyle.java Fri Sep 14 21:37:37 2018
@@ -136,11 +136,12 @@ public class HwmfPenStyle implements Clo
         }    
     }
     
-    private static final BitField SUBSECTION_DASH      = BitFieldFactory.getInstance(0x0007);
-    private static final BitField SUBSECTION_ALTERNATE = BitFieldFactory.getInstance(0x0008);
-    private static final BitField SUBSECTION_ENDCAP    = BitFieldFactory.getInstance(0x0300);
-    private static final BitField SUBSECTION_JOIN      = BitFieldFactory.getInstance(0x3000);
-    
+    private static final BitField SUBSECTION_DASH      = BitFieldFactory.getInstance(0x00007);
+    private static final BitField SUBSECTION_ALTERNATE = BitFieldFactory.getInstance(0x00008);
+    private static final BitField SUBSECTION_ENDCAP    = BitFieldFactory.getInstance(0x00300);
+    private static final BitField SUBSECTION_JOIN      = BitFieldFactory.getInstance(0x03000);
+    private static final BitField SUBSECTION_GEOMETRIC = BitFieldFactory.getInstance(0x10000);
+
     private int flag;
     
     public static HwmfPenStyle valueOf(int flag) {
@@ -169,6 +170,14 @@ public class HwmfPenStyle implements Clo
         return SUBSECTION_ALTERNATE.isSet(flag);
     }
 
+    /**
+     * A pen type that specifies a line with a width that is measured in logical units
+     * and a style that can contain any of the attributes of a brush.
+     */
+    public boolean isGeometric()  {
+        return SUBSECTION_GEOMETRIC.isSet(flag);
+    }
+
 
     /**
      * Creates a new object of the same class and with the

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfRecord.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfRecord.java?rev=1840956&r1=1840955&r2=1840956&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfRecord.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfRecord.java Fri Sep 14 21:37:37 2018
@@ -23,7 +23,7 @@ import org.apache.poi.hwmf.draw.HwmfGrap
 import org.apache.poi.util.LittleEndianInputStream;
 
 public interface HwmfRecord {
-    HwmfRecordType getRecordType();
+    HwmfRecordType getWmfRecordType();
 
     /**
      * Init record from stream



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