poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kiwiwi...@apache.org
Subject svn commit: r1722046 [1/3] - in /poi/trunk/src/scratchpad: src/org/apache/poi/hwmf/draw/ src/org/apache/poi/hwmf/record/ src/org/apache/poi/hwmf/usermodel/ testcases/org/apache/poi/hwmf/
Date Tue, 29 Dec 2015 00:45:59 GMT
Author: kiwiwings
Date: Tue Dec 29 00:45:59 2015
New Revision: 1722046

URL: http://svn.apache.org/viewvc?rev=1722046&view=rev
Log:
WMF fixes

Added:
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMapMode.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfPenStyle.java
Modified:
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmap16.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfColorRef.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfEscape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfHatchStyle.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfPalette.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfRecord.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfTernaryRasterOp.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java

Added: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java?rev=1722046&view=auto
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java (added)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java Tue Dec 29 00:45:59 2015
@@ -0,0 +1,189 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hwmf.draw;
+
+import java.awt.Color;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+
+import org.apache.poi.hwmf.record.HwmfBrushStyle;
+import org.apache.poi.hwmf.record.HwmfColorRef;
+import org.apache.poi.hwmf.record.HwmfFill.WmfSetPolyfillMode.HwmfPolyfillMode;
+import org.apache.poi.hwmf.record.HwmfHatchStyle;
+import org.apache.poi.hwmf.record.HwmfMapMode;
+import org.apache.poi.hwmf.record.HwmfMisc.WmfSetBkMode.HwmfBkMode;
+import org.apache.poi.hwmf.record.HwmfPenStyle;
+
+public class HwmfDrawProperties {
+    private Rectangle2D window = new Rectangle2D.Double(0, 0, 1, 1);
+    private Rectangle2D viewport = new Rectangle2D.Double(0, 0, 1, 1);
+    private Point2D location = new Point2D.Double(0,0);
+    private HwmfMapMode mapMode = HwmfMapMode.MM_ANISOTROPIC;
+    private HwmfColorRef backgroundColor = new HwmfColorRef(Color.BLACK);
+    private HwmfBrushStyle brushStyle = HwmfBrushStyle.BS_SOLID;
+    private HwmfColorRef brushColor = new HwmfColorRef(Color.BLACK);
+    private HwmfHatchStyle brushHatch = HwmfHatchStyle.HS_HORIZONTAL;
+    private BufferedImage brushBitmap = null;
+    private double penWidth = 1;
+    private HwmfPenStyle penStyle = HwmfPenStyle.valueOf(0);
+    private HwmfColorRef penColor = new HwmfColorRef(Color.BLACK);
+    private double penMiterLimit = 10;
+    private HwmfBkMode bkMode = HwmfBkMode.OPAQUE;
+    private HwmfPolyfillMode polyfillMode = HwmfPolyfillMode.WINDING;
+
+    public void setViewportExt(double width, double height) {
+        double x = viewport.getX();
+        double y = viewport.getY();
+        double w = (width != 0) ? width : viewport.getWidth();
+        double h = (height != 0) ? height : viewport.getHeight();
+        viewport.setRect(x, y, w, h);
+    }
+
+    public void setViewportOrg(double x, double y) {
+        double w = viewport.getWidth();
+        double h = viewport.getHeight();
+        viewport.setRect(x, y, w, h);
+    }
+
+    public Rectangle2D getViewport() {
+        return (Rectangle2D)viewport.clone();
+    }
+
+    public void setWindowExt(double width, double height) {
+        double x = window.getX();
+        double y = window.getY();
+        double w = (width != 0) ? width : window.getWidth();
+        double h = (height != 0) ? height : window.getHeight();
+        window.setRect(x, y, w, h);
+    }
+
+    public void setWindowOrg(double x, double y) {
+        double w = window.getWidth();
+        double h = window.getHeight();
+        window.setRect(x, y, w, h);
+    }
+
+    public Rectangle2D getWindow() {
+        return (Rectangle2D)window.clone();
+    }
+
+    public void setLocation(double x, double y) {
+        location.setLocation(x, y);
+    }
+
+    public Point2D getLocation() {
+        return (Point2D)location.clone();
+    }
+
+    public void setMapMode(HwmfMapMode mapMode) {
+        this.mapMode = mapMode;
+    }
+
+    public HwmfMapMode getMapMode() {
+        return mapMode;
+    }
+
+    public HwmfBrushStyle getBrushStyle() {
+        return brushStyle;
+    }
+
+    public void setBrushStyle(HwmfBrushStyle brushStyle) {
+        this.brushStyle = brushStyle;
+    }
+
+    public HwmfHatchStyle getBrushHatch() {
+        return brushHatch;
+    }
+
+    public void setBrushHatch(HwmfHatchStyle brushHatch) {
+        this.brushHatch = brushHatch;
+    }
+
+    public HwmfColorRef getBrushColor() {
+        return brushColor;
+    }
+
+    public void setBrushColor(HwmfColorRef brushColor) {
+        this.brushColor = brushColor;
+    }
+
+    public HwmfBkMode getBkMode() {
+        return bkMode;
+    }
+
+    public void setBkMode(HwmfBkMode bkMode) {
+        this.bkMode = bkMode;
+    }
+
+    public HwmfPenStyle getPenStyle() {
+        return penStyle;
+    }
+
+    public void setPenStyle(HwmfPenStyle penStyle) {
+        this.penStyle = penStyle;
+    }
+
+    public HwmfColorRef getPenColor() {
+        return penColor;
+    }
+
+    public void setPenColor(HwmfColorRef penColor) {
+        this.penColor = penColor;
+    }
+
+    public double getPenWidth() {
+        return penWidth;
+    }
+
+    public void setPenWidth(double penWidth) {
+        this.penWidth = penWidth;
+    }
+
+    public double getPenMiterLimit() {
+        return penMiterLimit;
+    }
+
+    public void setPenMiterLimit(double penMiterLimit) {
+        this.penMiterLimit = penMiterLimit;
+    }
+
+    public HwmfColorRef getBackgroundColor() {
+        return backgroundColor;
+    }
+
+    public void setBackgroundColor(HwmfColorRef backgroundColor) {
+        this.backgroundColor = backgroundColor;
+    }
+
+    public HwmfPolyfillMode getPolyfillMode() {
+        return polyfillMode;
+    }
+
+    public void setPolyfillMode(HwmfPolyfillMode polyfillMode) {
+        this.polyfillMode = polyfillMode;
+    }
+
+    public BufferedImage getBrushBitmap() {
+        return brushBitmap;
+    }
+
+    public void setBrushBitmap(BufferedImage brushBitmap) {
+        this.brushBitmap = brushBitmap;
+    }
+}

Added: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java?rev=1722046&view=auto
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java (added)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java Tue Dec 29 00:45:59 2015
@@ -0,0 +1,185 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hwmf.draw;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Paint;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.TexturePaint;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.util.ArrayDeque;
+import java.util.Deque;
+
+import org.apache.poi.hwmf.record.HwmfBrushStyle;
+import org.apache.poi.hwmf.record.HwmfHatchStyle;
+import org.apache.poi.hwmf.record.HwmfMisc.WmfSetBkMode.HwmfBkMode;
+import org.apache.poi.hwmf.record.HwmfPenStyle;
+import org.apache.poi.hwmf.record.HwmfPenStyle.HwmfLineDash;
+import org.apache.poi.util.Units;
+
+public class HwmfGraphics {
+    private final Graphics2D graphicsCtx;
+    private final Deque<HwmfDrawProperties> propStack = new ArrayDeque<HwmfDrawProperties>();
+    HwmfDrawProperties prop;
+
+    public HwmfGraphics(Graphics2D graphicsCtx) {
+        this.graphicsCtx = graphicsCtx;
+        prop = new HwmfDrawProperties();
+        propStack.push(prop);
+    }
+
+    public HwmfDrawProperties getProperties() {
+        return prop;
+    }
+
+    public void draw(Shape shape) {
+        HwmfLineDash lineDash = prop.getPenStyle().getLineDash();
+        if (lineDash == HwmfLineDash.NULL) {
+            // line is not drawn
+            return;
+        }
+
+        Shape tshape = fitShapeToView(shape);
+        BasicStroke stroke = getStroke();
+
+        // first draw a solid background line (depending on bkmode)
+        // only makes sense if the line is not solid
+        if (prop.getBkMode() == HwmfBkMode.OPAQUE && (lineDash != HwmfLineDash.SOLID && lineDash != HwmfLineDash.INSIDEFRAME)) {
+            graphicsCtx.setStroke(new BasicStroke(stroke.getLineWidth()));
+            graphicsCtx.setColor(prop.getBackgroundColor().getColor());
+            graphicsCtx.draw(tshape);
+        }
+
+        // then draw the (dashed) line
+        graphicsCtx.setStroke(stroke);
+        graphicsCtx.setColor(prop.getPenColor().getColor());
+        graphicsCtx.draw(tshape);
+    }
+
+    public void fill(Shape shape) {
+        if (prop.getBrushStyle() != HwmfBrushStyle.BS_NULL) {
+            GeneralPath gp = new GeneralPath(shape);
+            gp.setWindingRule(prop.getPolyfillMode().awtFlag);
+            Shape tshape = fitShapeToView(gp);
+            graphicsCtx.setPaint(getFill());
+            graphicsCtx.fill(tshape);
+        }
+
+        draw(shape);
+    }
+
+    protected Shape fitShapeToView(Shape shape) {
+        int scaleUnits = prop.getMapMode().scale;
+        Rectangle2D view = prop.getViewport(), win = prop.getWindow();
+        double scaleX, scaleY;
+        switch (scaleUnits) {
+        case -1:
+            scaleX = view.getWidth() / win.getWidth();
+            scaleY = view.getHeight() / win.getHeight();
+            break;
+        case 0:
+            scaleX = scaleY = 1;
+            break;
+        default:
+            scaleX = scaleY = scaleUnits / (double)Units.POINT_DPI;
+        }
+
+        AffineTransform at = new AffineTransform();
+        at.translate(view.getX(), view.getY());
+        at.scale(scaleX, scaleY);
+        at.translate(-win.getX(), -win.getY());
+        at.translate(-view.getX(), -view.getY());
+
+        return at.createTransformedShape(shape);
+    }
+
+    protected BasicStroke getStroke() {
+        Rectangle2D view = prop.getViewport(), win = prop.getWindow();
+        float width = (float)(prop.getPenWidth() * view.getWidth() / win.getWidth());
+        HwmfPenStyle ps = prop.getPenStyle();
+        int cap = ps.getLineCap().awtFlag;
+        int join = ps.getLineJoin().awtFlag;
+        float miterLimit = (float)prop.getPenMiterLimit();
+        float dashes[] = ps.getLineDash().dashes;
+        boolean dashAlt = ps.isAlternateDash();
+        // This value is not an integer index into the dash pattern array.
+        // Instead, it is a floating-point value that specifies a linear distance.
+        float dashStart = (dashAlt && dashes.length > 1) ? dashes[0] : 0;
+
+        return new BasicStroke(width, cap, join, miterLimit, dashes, dashStart);
+    }
+
+    protected Paint getFill() {
+        switch (prop.getBrushStyle()) {
+        default:
+        case BS_INDEXED:
+        case BS_PATTERN8X8:
+        case BS_DIBPATTERN8X8:
+        case BS_MONOPATTERN:
+        case BS_NULL: return null;
+        case BS_PATTERN:
+        case BS_DIBPATTERN:
+        case BS_DIBPATTERNPT: return getPatternPaint();
+        case BS_SOLID: return getSolidFill();
+        case BS_HATCHED: return getHatchedFill();
+        }
+    }
+
+    protected Paint getSolidFill() {
+        return prop.getBrushColor().getColor();
+    }
+
+    protected Paint getHatchedFill() {
+        int dim = 7, mid = 3;
+        BufferedImage bi = new BufferedImage(dim, dim, BufferedImage.TYPE_4BYTE_ABGR);
+        Graphics2D g = bi.createGraphics();
+        Color c = (prop.getBkMode() == HwmfBkMode.TRANSPARENT)
+            ? new Color(0, true)
+            : prop.getBackgroundColor().getColor();
+        g.setColor(c);
+        g.fillRect(0, 0, dim, dim);
+        g.setColor(prop.getBrushColor().getColor());
+        HwmfHatchStyle h = prop.getBrushHatch();
+        if (h == HwmfHatchStyle.HS_HORIZONTAL || h == HwmfHatchStyle.HS_CROSS) {
+            g.drawLine(0, mid, dim, mid);
+        }
+        if (h == HwmfHatchStyle.HS_VERTICAL || h == HwmfHatchStyle.HS_CROSS) {
+            g.drawLine(mid, 0, mid, dim);
+        }
+        if (h == HwmfHatchStyle.HS_FDIAGONAL || h == HwmfHatchStyle.HS_DIAGCROSS) {
+            g.drawLine(0, 0, dim, dim);
+        }
+        if (h == HwmfHatchStyle.HS_BDIAGONAL || h == HwmfHatchStyle.HS_DIAGCROSS) {
+            g.drawLine(0, dim, dim, 0);
+        }
+        g.dispose();
+        return new TexturePaint(bi, new Rectangle(0,0,dim,dim));
+    }
+
+    protected Paint getPatternPaint() {
+        BufferedImage bi = prop.getBrushBitmap();
+        return (bi == null) ? null
+            : new TexturePaint(bi, new Rectangle(0,0,bi.getWidth(),bi.getHeight()));
+    }
+}

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmap16.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmap16.java?rev=1722046&r1=1722045&r2=1722046&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmap16.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmap16.java Tue Dec 29 00:45:59 2015
@@ -18,12 +18,9 @@
 package org.apache.poi.hwmf.record;
 
 import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 
-import javax.imageio.stream.ImageInputStream;
-import javax.imageio.stream.MemoryCacheImageInputStream;
-
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 
@@ -75,31 +72,45 @@ public class HwmfBitmap16 {
             assert(skipSize == 18);
             size += 18+LittleEndianConsts.INT_SIZE;
         }
-        
-        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
-        
-        int size2 = 0;
-        byte buf[] = new byte[widthBytes];
-        for (int h=0; h<height; h++) {
-            leis.read(buf);
-            size2 += widthBytes;
-
-            ImageInputStream iis = new MemoryCacheImageInputStream(new ByteArrayInputStream(buf));
-
-            for (int w=0; w<width; w++) {
-                long bitsAtPixel = iis.readBits(bitsPixel);
-                // TODO: is bitsPixel a multiple of 3 (r,g,b)
-                // which colortable should be used for the various bit sizes???
-                
-            }
-        }
-        
-        int bytes = (((width * bitsPixel + 15) >> 4) << 1) * height;
-        assert (bytes == size2);
 
-        size += size2;
+        int bytes = (((width * bitsPixel + 15) >> 4) << 1) * height;
+        byte buf[] = new byte[bytes];
+        leis.read(buf);
+        
+        FileOutputStream fos = new FileOutputStream("bla16.bmp");
+        fos.write(buf);
+        fos.close();
+        
+        
+//        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+//        
+//        int size2 = 0;
+//        byte buf[] = new byte[widthBytes];
+//        for (int h=0; h<height; h++) {
+//            leis.read(buf);
+//            size2 += widthBytes;
+//
+//            ImageInputStream iis = new MemoryCacheImageInputStream(new ByteArrayInputStream(buf));
+//
+//            for (int w=0; w<width; w++) {
+//                long bitsAtPixel = iis.readBits(bitsPixel);
+//                // TODO: is bitsPixel a multiple of 3 (r,g,b)
+//                // which colortable should be used for the various bit sizes???
+//                
+//            }
+//        }
+//        
+//        assert (bytes == size2);
+//
+//        size += size2;
         
         
         return size;
     }
+
+    public BufferedImage getImage() {
+        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
+        return bi;
+    }
+
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java?rev=1722046&r1=1722045&r2=1722046&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java Tue Dec 29 00:45:59 2015
@@ -19,12 +19,16 @@ package org.apache.poi.hwmf.record;
 
 import java.awt.Color;
 import java.awt.image.BufferedImage;
-import java.awt.image.IndexColorModel;
-import java.awt.image.WritableRaster;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.imageio.ImageIO;
+
+import org.apache.poi.hssf.record.RecordFormatException;
+import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 
@@ -59,25 +63,25 @@ public class HwmfBitmapDib {
          * Each pixel in the bitmap is represented by a 16-bit value.
          * <br/>
          * If the Compression field of the BitmapInfoHeader Object is BI_RGB, the Colors field of DIB
-         *  is NULL. Each WORD in the bitmap array represents a single pixel. The relative intensities of 
-         *  red, green, and blue are represented with 5 bits for each color component. The value for blue 
-         *  is in the least significant 5 bits, followed by 5 bits each for green and red. The most significant 
-         *  bit is not used. The color table is used for optimizing colors on palette-based devices, and 
-         *  contains the number of entries specified by the ColorUsed field of the BitmapInfoHeader 
+         *  is NULL. Each WORD in the bitmap array represents a single pixel. The relative intensities of
+         *  red, green, and blue are represented with 5 bits for each color component. The value for blue
+         *  is in the least significant 5 bits, followed by 5 bits each for green and red. The most significant
+         *  bit is not used. The color table is used for optimizing colors on palette-based devices, and
+         *  contains the number of entries specified by the ColorUsed field of the BitmapInfoHeader
          *  Object.
          * <br/>
-         * If the Compression field of the BitmapInfoHeader Object is BI_BITFIELDS, the Colors field 
+         * If the Compression field of the BitmapInfoHeader Object is BI_BITFIELDS, the Colors field
          *  contains three DWORD color masks that specify the red, green, and blue components,
          *  respectively, of each pixel. Each WORD in the bitmap array represents a single pixel.
          * <br/>
-         * When the Compression field is set to BI_BITFIELDS, bits set in each DWORD mask MUST be 
+         * When the Compression field is set to BI_BITFIELDS, bits set in each DWORD mask MUST be
          *  contiguous and SHOULD NOT overlap the bits of another mask.
          */
         BI_BITCOUNT_4(0x0010),
         /**
-         * The bitmap has a maximum of 2^24 colors, and the Colors field of DIB is 
-         *  NULL. Each 3-byte triplet in the bitmap array represents the relative intensities of blue, green, 
-         *  and red, respectively, for a pixel. The Colors color table is used for optimizing colors used on 
+         * The bitmap has a maximum of 2^24 colors, and the Colors field of DIB is
+         *  NULL. Each 3-byte triplet in the bitmap array represents the relative intensities of blue, green,
+         *  and red, respectively, for a pixel. The Colors color table is used for optimizing colors used on
          *  palette-based devices, and MUST contain the number of entries specified by the ColorUsed
          *  field of the BitmapInfoHeader Object.
          */
@@ -85,23 +89,23 @@ public class HwmfBitmapDib {
         /**
          * The bitmap has a maximum of 2^24 colors.
          * <br/>
-         * If the Compression field of the BitmapInfoHeader Object is set to BI_RGB, the Colors field 
-         *  of DIB is set to NULL. Each DWORD in the bitmap array represents the relative intensities of 
-         *  blue, green, and red, respectively, for a pixel. The high byte in each DWORD is not used. The 
-         *  Colors color table is used for optimizing colors used on palette-based devices, and MUST 
-         *  contain the number of entries specified by the ColorUsed field of the BitmapInfoHeader 
+         * If the Compression field of the BitmapInfoHeader Object is set to BI_RGB, the Colors field
+         *  of DIB is set to NULL. Each DWORD in the bitmap array represents the relative intensities of
+         *  blue, green, and red, respectively, for a pixel. The high byte in each DWORD is not used. The
+         *  Colors color table is used for optimizing colors used on palette-based devices, and MUST
+         *  contain the number of entries specified by the ColorUsed field of the BitmapInfoHeader
          *  Object.
          * <br/>
          * If the Compression field of the BitmapInfoHeader Object is set to BI_BITFIELDS, the Colors
-         *  field contains three DWORD color masks that specify the red, green, and blue components, 
+         *  field contains three DWORD color masks that specify the red, green, and blue components,
          *  respectively, of each pixel. Each DWORD in the bitmap array represents a single pixel.
          * <br/>
-         * When the Compression field is set to BI_BITFIELDS, bits set in each DWORD mask must be 
-         *  contiguous and should not overlap the bits of another mask. All the bits in the pixel do not 
+         * When the Compression field is set to BI_BITFIELDS, bits set in each DWORD mask must be
+         *  contiguous and should not overlap the bits of another mask. All the bits in the pixel do not
          *  need to be used.
          */
         BI_BITCOUNT_6(0x0020);
-        
+
         int flag;
         BitCount(int flag) {
             this.flag = flag;
@@ -139,18 +143,18 @@ public class HwmfBitmapDib {
          */
         BI_BITFIELDS(0x0003),
         /**
-         * The image is a JPEG image, as specified in [JFIF]. This value SHOULD only be used in 
-         * certain bitmap operations, such as JPEG pass-through. The application MUST query for the 
-         * pass-through support, since not all devices support JPEG pass-through. Using non-RGB 
-         * bitmaps MAY limit the portability of the metafile to other devices. For instance, display device 
+         * The image is a JPEG image, as specified in [JFIF]. This value SHOULD only be used in
+         * certain bitmap operations, such as JPEG pass-through. The application MUST query for the
+         * pass-through support, since not all devices support JPEG pass-through. Using non-RGB
+         * bitmaps MAY limit the portability of the metafile to other devices. For instance, display device
          * contexts generally do not support this pass-through.
          */
         BI_JPEG(0x0004),
         /**
-         * The image is a PNG image, as specified in [RFC2083]. This value SHOULD only be 
-         * used certain bitmap operations, such as JPEG/PNG pass-through. The application MUST query 
-         * for the pass-through support, because not all devices support JPEG/PNG pass-through. Using 
-         * non-RGB bitmaps MAY limit the portability of the metafile to other devices. For instance, 
+         * The image is a PNG image, as specified in [RFC2083]. This value SHOULD only be
+         * used certain bitmap operations, such as JPEG/PNG pass-through. The application MUST query
+         * for the pass-through support, because not all devices support JPEG/PNG pass-through. Using
+         * non-RGB bitmaps MAY limit the portability of the metafile to other devices. For instance,
          * display device contexts generally do not support this pass-through.
          */
         BI_PNG(0x0005),
@@ -170,7 +174,7 @@ public class HwmfBitmapDib {
          * color indexes.
          */
         BI_CMYKRLE4(0x000D);
-        
+
         int flag;
         Compression(int flag) {
             this.flag = flag;
@@ -180,93 +184,113 @@ public class HwmfBitmapDib {
                 if (c.flag == flag) return c;
             }
             return null;
-        }        
+        }
     }
+
+    private static final int BMP_HEADER_SIZE = 14;
     
-    
-    int headerSize;
-    int headerWidth;
-    int headerHeight;
-    int headerPlanes;
-    BitCount headerBitCount;
-    Compression headerCompression;
-    long headerImageSize = -1;
-    int headerXPelsPerMeter = -1;
-    int headerYPelsPerMeter = -1;
-    long headerColorUsed = -1;
-    long headerColorImportant = -1;
-    
-    Color colorTable[];
-    int colorMaskRed=0,colorMaskGreen=0,colorMaskBlue=0;
-    
-    public int init(LittleEndianInputStream leis) throws IOException {
-        int size = 0;
-        size += readHeader(leis);
-        size += readColors(leis);
-        int size2;
-        switch (headerBitCount) {
-            default:
-            case BI_BITCOUNT_0:
-                throw new RuntimeException("JPG and PNG formats aren't supported yet.");
-            case BI_BITCOUNT_1:
-            case BI_BITCOUNT_2:
-            case BI_BITCOUNT_3:
-                size2 = readBitmapIndexed(leis);
-                break;
-            case BI_BITCOUNT_4:
-            case BI_BITCOUNT_5:
-            case BI_BITCOUNT_6:
-                size2 = readBitmapDirect(leis);
-                break;
-        }
+    private int headerSize;
+    private int headerWidth;
+    private int headerHeight;
+    private int headerPlanes;
+    private BitCount headerBitCount;
+    private Compression headerCompression;
+    private long headerImageSize = -1;
+    @SuppressWarnings("unused")
+    private int headerXPelsPerMeter = -1;
+    @SuppressWarnings("unused")
+    private int headerYPelsPerMeter = -1;
+    private long headerColorUsed = -1;
+    @SuppressWarnings("unused")
+    private long headerColorImportant = -1;
+
+    @SuppressWarnings("unused")
+    private Color colorTable[];
+    @SuppressWarnings("unused")
+    private int colorMaskRed=0,colorMaskGreen=0,colorMaskBlue=0;
+
+    // size of header and color table, for start of image data calculation
+    private int introSize;
+    private byte imageData[];
+
+    public int init(LittleEndianInputStream leis, int recordSize) throws IOException {
+        leis.mark(10000);
         
-        assert( headerSize != 0x0C || ((((headerWidth * headerPlanes * headerBitCount.flag + 31) & ~31) / 8) * Math.abs(headerHeight)) == size2);
-        assert ( headerSize == 0x0C || headerImageSize == size2 );
+        // need to read the header to calculate start of bitmap data correct
+        introSize = readHeader(leis);
+        assert(introSize == headerSize);
+        introSize += readColors(leis);
+        assert(introSize < 10000);
+
+        int fileSize = (headerImageSize != 0) ? (int)(introSize+headerImageSize) : recordSize;
         
-        size += size2;
+        imageData = new byte[fileSize];
+        leis.reset();
+        leis.read(imageData, 0, fileSize);
         
-        return size;
+        assert( headerSize != 0x0C || ((((headerWidth * headerPlanes * headerBitCount.flag + 31) & ~31) / 8) * Math.abs(headerHeight)) == headerImageSize);
+
+        return fileSize;
     }
 
     protected int readHeader(LittleEndianInputStream leis) throws IOException {
         int size = 0;
-        
+
         /**
          * DIBHeaderInfo (variable): Either a BitmapCoreHeader Object or a
          * BitmapInfoHeader Object that specifies information about the image.
-         * 
+         *
          * The first 32 bits of this field is the HeaderSize value.
          * If it is 0x0000000C, then this is a BitmapCoreHeader; otherwise, this is a BitmapInfoHeader.
          */
         headerSize = leis.readInt();
         size += LittleEndianConsts.INT_SIZE;
-        
-        // BitmapCoreHeader
-        // A 16-bit unsigned integer that defines the width of the DIB, in pixels.
-        headerWidth = leis.readUShort();
-        // A 16-bit unsigned integer that defines the height of the DIB, in pixels.
-        headerHeight = leis.readUShort();
-        // A 16-bit unsigned integer that defines the number of planes for the target
-        // device. This value MUST be 0x0001.
-        headerPlanes = leis.readUShort();
-        // A 16-bit unsigned integer that defines the format of each pixel, and the
-        // maximum number of colors in the DIB.
-        headerBitCount = BitCount.valueOf(leis.readUShort());
-        size += 4*LittleEndianConsts.SHORT_SIZE;
 
-        if (headerSize > 0x0C) {
+        if (headerSize == 0x0C) {
+            // BitmapCoreHeader
+            // A 16-bit unsigned integer that defines the width of the DIB, in pixels.
+            headerWidth = leis.readUShort();
+            // A 16-bit unsigned integer that defines the height of the DIB, in pixels.
+            headerHeight = leis.readUShort();
+            // A 16-bit unsigned integer that defines the number of planes for the target
+            // device. This value MUST be 0x0001.
+            headerPlanes = leis.readUShort();
+            // A 16-bit unsigned integer that defines the format of each pixel, and the
+            // maximum number of colors in the DIB.
+            headerBitCount = BitCount.valueOf(leis.readUShort());
+            size += 4*LittleEndianConsts.SHORT_SIZE;
+        } else {
             // BitmapInfoHeader
-            // A 32-bit unsigned integer that defines the compression mode of the 
-            // DIB. 
+            // A 32-bit signed integer that defines the width of the DIB, in pixels.
+            // This value MUST be positive.
+            // This field SHOULD specify the width of the decompressed image file,
+            // if the Compression value specifies JPEG or PNG format.
+            headerWidth = leis.readInt();
+            // A 32-bit signed integer that defines the height of the DIB, in pixels.
+            // This value MUST NOT be zero.
+            // - If this value is positive, the DIB is a bottom-up bitmap,
+            //   and its origin is the lower-left corner.
+            //   This field SHOULD specify the height of the decompressed image file,
+            //   if the Compression value specifies JPEG or PNG format.
+            // - If this value is negative, the DIB is a top-down bitmap,
+            //   and its origin is the upper-left corner. Top-down bitmaps do not support compression.
+            headerHeight = leis.readInt();
+            // A 16-bit unsigned integer that defines the number of planes for the target
+            // device. This value MUST be 0x0001.
+            headerPlanes = leis.readUShort();
+            // A 16-bit unsigned integer that defines the format of each pixel, and the
+            // maximum number of colors in the DIB.
+            headerBitCount = BitCount.valueOf(leis.readUShort());
+            // A 32-bit unsigned integer that defines the compression mode of the DIB.
             // This value MUST NOT specify a compressed format if the DIB is a top-down bitmap,
             // as indicated by the Height value.
             headerCompression = Compression.valueOf((int)leis.readUInt());
             // A 32-bit unsigned integer that defines the size, in bytes, of the image.
             // If the Compression value is BI_RGB, this value SHOULD be zero and MUST be ignored.
-            // If the Compression value is BI_JPEG or BI_PNG, this value MUST specify the size of the JPEG 
+            // If the Compression value is BI_JPEG or BI_PNG, this value MUST specify the size of the JPEG
             // or PNG image buffer, respectively.
             headerImageSize = leis.readUInt();
-            // A 32-bit signed integer that defines the horizontal resolution, 
+            // A 32-bit signed integer that defines the horizontal resolution,
             // in pixels-per-meter, of the target device for the DIB.
             headerXPelsPerMeter = leis.readInt();
             // A 32-bit signed integer that defines the vertical resolution,
@@ -278,8 +302,9 @@ public class HwmfBitmapDib {
             // A 32-bit unsigned integer that defines the number of color indexes that are
             // required for displaying the DIB. If this value is zero, all color indexes are required.
             headerColorImportant = leis.readUInt();
-            size += 6*LittleEndianConsts.INT_SIZE;
+            size += 8*LittleEndianConsts.INT_SIZE+2*LittleEndianConsts.SHORT_SIZE;
         }
+        assert(size == headerSize);
         return size;
     }
 
@@ -297,7 +322,7 @@ public class HwmfBitmapDib {
             return readRGBQuad(leis, 16);
         case BI_BITCOUNT_3:
             // 256 colors
-            return readRGBQuad(leis, 256);
+            return readRGBQuad(leis, (int)headerColorUsed);
         case BI_BITCOUNT_5:
             colorMaskRed=0xFF;
             colorMaskGreen=0xFF;
@@ -316,7 +341,7 @@ public class HwmfBitmapDib {
                 colorMaskRed = leis.readInt();
                 return 3*LittleEndianConsts.INT_SIZE;
             }
-        case BI_BITCOUNT_6:    
+        case BI_BITCOUNT_6:
             if (headerCompression == Compression.BI_RGB) {
                 colorMaskBlue = colorMaskGreen = colorMaskRed = 0xFF;
                 return 0;
@@ -329,7 +354,7 @@ public class HwmfBitmapDib {
             }
         }
     }
-    
+
     protected int readRGBQuad(LittleEndianInputStream leis, int count) throws IOException {
         int size = 0;
         List<Color> colorList = new ArrayList<Color>();
@@ -346,96 +371,32 @@ public class HwmfBitmapDib {
         colorTable = colorList.toArray(new Color[colorList.size()]);
         return size;
     }
-    
-    protected int readBitmapIndexed(LittleEndianInputStream leis) throws IOException {
-        assert(colorTable != null);
-        byte r[] = new byte[colorTable.length];
-        byte g[] = new byte[colorTable.length];
-        byte b[] = new byte[colorTable.length];
-        for (int i=0; i<colorTable.length; i++) {
-            r[i] = (byte)colorTable[i].getRed();
-            g[i] = (byte)colorTable[i].getGreen();
-            b[i] = (byte)colorTable[i].getBlue();
-        }
-        int bits = 32-Integer.numberOfLeadingZeros(colorTable.length);
-        IndexColorModel cm = new IndexColorModel(bits,colorTable.length,r,g,b);
-        
-        BufferedImage bi = new BufferedImage(headerWidth, headerHeight, BufferedImage.TYPE_BYTE_INDEXED, cm);
-        WritableRaster wr = bi.getRaster();
-        
-        int pixelCount = headerWidth*headerHeight;
-        int size = 0;
-        for (int pixel=0; pixel<pixelCount; size++) {
-            int v = leis.readUByte();
-            switch (headerBitCount) {
-            default:
-                throw new RuntimeException("invalid bitcount for indexed image");
-            case BI_BITCOUNT_1:
-                for (int j=0; j<8 && pixel<pixelCount; j++,pixel++) {
-                    wr.setSample(pixel/headerWidth,pixel%headerWidth,0,(v>>(7-j))&1);
-                }
-                break;
-            case BI_BITCOUNT_2:
-                wr.setSample(pixel/headerWidth, pixel%headerWidth, 0, (v>>4)&15);
-                pixel++;
-                if (pixel<pixelCount) {
-                    wr.setSample(pixel/headerWidth, pixel%headerWidth, 0, v&15);
-                    pixel++;
-                }
-                break;
-            case BI_BITCOUNT_3:
-                wr.setSample(pixel/headerWidth, pixel%headerWidth, 0, v);
-                pixel++;
-                break;
-            }
-        }
-        return size;
-    }
-    
-    protected int readBitmapDirect(LittleEndianInputStream leis) throws IOException {
-        assert(colorTable == null);
-        
-        BufferedImage bi = new BufferedImage(headerWidth, headerHeight, BufferedImage.TYPE_INT_RGB);
-        WritableRaster wr = bi.getRaster();
-        
-        int bitShiftRed=0,bitShiftGreen=0,bitShiftBlue=0;
-        if (headerCompression == Compression.BI_BITFIELDS) {
-            bitShiftGreen = 32-Integer.numberOfLeadingZeros(this.colorMaskBlue);
-            bitShiftRed = 32-Integer.numberOfLeadingZeros(this.colorMaskGreen);
+
+    public BufferedImage getImage() {
+        if (imageData == null) {
+            throw new RecordFormatException("bitmap not initialized ... need to call init() before");
         }
-        
-        int pixelCount = headerWidth*headerHeight;
-        int size = 0;
-        int rgb[] = new int[3];
-        for (int pixel=0; pixel<pixelCount; pixel++) {
-            int v;
-            switch (headerBitCount) {
-            default:
-                throw new RuntimeException("invalid bitcount for indexed image");
-            case BI_BITCOUNT_4:
-                v = leis.readUShort();
-                rgb[0] = (v & colorMaskRed) >> bitShiftRed;
-                rgb[1] = (v & colorMaskGreen) >> bitShiftGreen;
-                rgb[2] = (v & colorMaskBlue) >> bitShiftBlue;
-                size += LittleEndianConsts.SHORT_SIZE;
-                break;
-            case BI_BITCOUNT_5:
-                rgb[2] = leis.readUByte();
-                rgb[1] = leis.readUByte();
-                rgb[0] = leis.readUByte();
-                size += 3*LittleEndianConsts.BYTE_SIZE;
-                break;
-            case BI_BITCOUNT_6:
-                v = leis.readInt();
-                rgb[0] = (v & colorMaskRed) >> bitShiftRed;
-                rgb[1] = (v & colorMaskGreen) >> bitShiftGreen;
-                rgb[2] = (v & colorMaskBlue) >> bitShiftBlue;
-                size += LittleEndianConsts.INT_SIZE;
-                break;
-            }
-            wr.setPixel(pixel/headerWidth,pixel%headerWidth,rgb);
+
+        // create the image data and leave the parsing to the ImageIO api
+        byte buf[] = new byte[BMP_HEADER_SIZE+imageData.length];
+
+        // https://en.wikipedia.org/wiki/BMP_file_format #  Bitmap file header
+        buf[0] = (byte)'B';
+        buf[1] = (byte)'M';
+        // the full size of the bmp
+        LittleEndian.putInt(buf, 2, (int)(BMP_HEADER_SIZE + introSize + headerImageSize));
+        // the next 4 bytes are unused
+        LittleEndian.putInt(buf, 6, 0);
+        // start of image = BMP header length + dib header length + color tables length
+        LittleEndian.putInt(buf, 10, BMP_HEADER_SIZE + introSize);
+        
+        System.arraycopy(imageData, 0, buf, BMP_HEADER_SIZE, imageData.length);
+        
+        try {
+            return ImageIO.read(new ByteArrayInputStream(buf));
+        } catch (IOException e) {
+            // ... shouldn't happen
+            throw new RecordFormatException("invalid bitmap data", e);
         }
-        
-        return size;
     }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfColorRef.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfColorRef.java?rev=1722046&r1=1722045&r2=1722046&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfColorRef.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfColorRef.java Tue Dec 29 00:45:59 2015
@@ -23,15 +23,21 @@ import java.io.IOException;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 
+/**
+ * A 32-bit ColorRef Object that defines the color value.
+ * Red (1 byte):  An 8-bit unsigned integer that defines the relative intensity of red.
+ * Green (1 byte):  An 8-bit unsigned integer that defines the relative intensity of green.
+ * Blue (1 byte):  An 8-bit unsigned integer that defines the relative intensity of blue.
+ * Reserved (1 byte):  An 8-bit unsigned integer that MUST be 0x00.
+ */
 public class HwmfColorRef {
-    /**
-     * A 32-bit ColorRef Object that defines the color value.
-     * Red (1 byte):  An 8-bit unsigned integer that defines the relative intensity of red.
-     * Green (1 byte):  An 8-bit unsigned integer that defines the relative intensity of green.
-     * Blue (1 byte):  An 8-bit unsigned integer that defines the relative intensity of blue.
-     * Reserved (1 byte):  An 8-bit unsigned integer that MUST be 0x00.
-     */
-    Color colorRef;
+    private Color colorRef = Color.BLACK;
+    
+    public HwmfColorRef() {}
+    
+    public HwmfColorRef(Color colorRef) {
+        this.colorRef = colorRef;
+    }
     
     public int init(LittleEndianInputStream leis) throws IOException {
         int red = leis.readUByte();
@@ -44,4 +50,7 @@ public class HwmfColorRef {
         return 4*LittleEndianConsts.BYTE_SIZE;
     }
 
+    public Color getColor() {
+        return colorRef;
+    }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java?rev=1722046&r1=1722045&r2=1722046&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java Tue Dec 29 00:45:59 2015
@@ -17,8 +17,13 @@
 
 package org.apache.poi.hwmf.record;
 
+import java.awt.Polygon;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.geom.Point2D;
 import java.io.IOException;
 
+import org.apache.poi.hwmf.draw.HwmfGraphics;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 
@@ -28,102 +33,140 @@ public class HwmfDraw {
      * point.
      */
     public static class WmfMoveTo implements HwmfRecord {
-        
+
         /**
          * A 16-bit signed integer that defines the y-coordinate, in logical units.
          */
-        int y;
-        
+        private int y;
+
         /**
          * A 16-bit signed integer that defines the x-coordinate, in logical units.
          */
-        int x;
-        
+        private int x;
+
+        @Override
         public HwmfRecordType getRecordType() {
             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;
         }
+        
+        @Override
+        public void draw(HwmfGraphics ctx) {
+            ctx.getProperties().setLocation(x, y);
+        }
     }
-    
+
     /**
      * The META_LINETO record draws a line from the drawing position that is defined in the playback
      * device context up to, but not including, the specified point.
      */
     public static class WmfLineTo implements HwmfRecord {
-        
+
         /**
          * A 16-bit signed integer that defines the vertical component of the drawing
          * destination position, in logical units.
          */
-        int y;
-        
+        private int y;
+
         /**
          * A 16-bit signed integer that defines the horizontal component of the drawing
          * destination position, in logical units.
          */
-        int x;
-        
+        private int x;
+
+        @Override
         public HwmfRecordType getRecordType() {
             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;
         }
+        
+        @Override
+        public void draw(HwmfGraphics ctx) {
+            Point2D start = ctx.getProperties().getLocation();
+            Line2D line = new Line2D.Double(start.getX(), start.getY(), x, y);
+            ctx.draw(line);
+            ctx.getProperties().setLocation(x, y);
+        }
     }
-    
+
     /**
      * The META_POLYGON record paints a polygon consisting of two or more vertices connected by
      * straight lines. The polygon is outlined by using the pen and filled by using the brush and polygon fill
      * mode that are defined in the playback device context.
      */
     public static class WmfPolygon implements HwmfRecord {
-        
+
         /**
          * A 16-bit signed integer that defines the number of points in the array.
          */
-        int numberofPoints;
-        
+        private int numberofPoints;
+
         short xPoints[], yPoints[];
-        
+
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.polygon;
         }
-        
+
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             numberofPoints = leis.readShort();
             xPoints = new short[numberofPoints];
             yPoints = new short[numberofPoints];
-            
+
             for (int i=0; i<numberofPoints; i++) {
                 // A 16-bit signed integer that defines the horizontal (x) coordinate of the point.
                 xPoints[i] = leis.readShort();
                 // A 16-bit signed integer that defines the vertical (y) coordinate of the point.
                 yPoints[i] = leis.readShort();
             }
-            
+
             return LittleEndianConsts.SHORT_SIZE+numberofPoints*LittleEndianConsts.INT_SIZE;
         }
+        
+        @Override
+        public void draw(HwmfGraphics ctx) {
+            ctx.fill(getShape());
+        }
+        
+        protected Polygon getShape() {
+            Polygon polygon = new Polygon();
+            for(int i = 0; i < numberofPoints; i++) {
+                polygon.addPoint(xPoints[i], yPoints[i]);
+            }
+            return polygon;
+        }
     }
-    
+
     /**
      * The META_POLYLINE record draws a series of line segments by connecting the points in the
      * specified array.
      */
     public static class WmfPolyline extends WmfPolygon {
-        
+
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.polyline;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+            ctx.draw(getShape());
+        }
     }
-    
+
     /**
      * The META_ELLIPSE record draws an ellipse. The center of the ellipse is the center of the specified
      * bounding rectangle. The ellipse is outlined by using the pen and is filled by using the brush; these
@@ -134,27 +177,29 @@ public class HwmfDraw {
          * A 16-bit signed integer that defines the y-coordinate, in logical units, of
          * the lower-right corner of the bounding rectangle.
          */
-        int bottomRect;
+        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.
          */
-        int rightRect;
+        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.
          */
-        int topRect;
+        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.
          */
-        int leftRect;
-        
+        private int leftRect;
+
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.ellipse;
         }
-        
+
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             bottomRect = leis.readShort();
             rightRect = leis.readShort();
@@ -162,6 +207,11 @@ public class HwmfDraw {
             leftRect = leis.readShort();
             return 4*LittleEndianConsts.SHORT_SIZE;
         }
+        
+        @Override
+        public void draw(HwmfGraphics ctx) {
+            
+        }
     }
 
 
@@ -173,27 +223,29 @@ public class HwmfDraw {
          * A 16-bit unsigned integer used to index into the WMF Object Table to get
          * the region to be framed.
          */
-        int region;  
+        private int region;
         /**
          * A 16-bit unsigned integer used to index into the WMF Object Table to get the
          * Brush to use for filling the region.
          */
-        int brush;
+        private int brush;
         /**
          * A 16-bit signed integer that defines the height, in logical units, of the
          * region frame.
          */
-        int height;
+        private int height;
         /**
          * A 16-bit signed integer that defines the width, in logical units, of the
          * region frame.
          */
-        int width;
-        
+        private int width;
+
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.frameRegion;
         }
-        
+
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             region = leis.readUShort();
             brush = leis.readUShort();
@@ -201,6 +253,11 @@ public class HwmfDraw {
             width = leis.readShort();
             return 4*LittleEndianConsts.SHORT_SIZE;
         }
+        
+        @Override
+        public void draw(HwmfGraphics ctx) {
+            
+        }
     }
 
     /**
@@ -209,33 +266,35 @@ public class HwmfDraw {
      * device context. The polygons drawn by this function can overlap.
      */
     public static class WmfPolyPolygon implements HwmfRecord {
-        
+
         /**
          * A 16-bit unsigned integer that defines the number of polygons in the object.
          */
-        int numberOfPolygons;
-        
+        private int numberOfPolygons;
+
         /**
          * A NumberOfPolygons array of 16-bit unsigned integers that define the number of
          * points for each polygon in the object.
          */
-        int pointsPerPolygon[];
-        
+        private int pointsPerPolygon[];
+
         /**
          * An array of 16-bit unsigned integers that define the coordinates of the polygons.
          */
-        int xPoints[][];
+        private int xPoints[][];
 
         /**
          * An array of 16-bit unsigned integers that define the coordinates of the polygons.
          */
-        int yPoints[][];
-        
-        
+        private int yPoints[][];
+
+
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.polyPolygon;
         }
-        
+
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             // see http://secunia.com/gfx/pdf/SA31675_BA.pdf ;)
             numberOfPolygons = leis.readUShort();
@@ -244,26 +303,31 @@ public class HwmfDraw {
             yPoints = new int[numberOfPolygons][];
 
             int size = LittleEndianConsts.SHORT_SIZE;
-            
+
             for (int i=0; i<numberOfPolygons; i++) {
                 pointsPerPolygon[i] = leis.readUShort();
                 size += LittleEndianConsts.SHORT_SIZE;
             }
-            
+
             for (int i=0; i<numberOfPolygons; i++) {
-                
+
                 xPoints[i] = new int[pointsPerPolygon[i]];
                 yPoints[i] = new int[pointsPerPolygon[i]];
-                
+
                 for (int j=0; j<pointsPerPolygon[i]; j++) {
                     xPoints[i][j] = leis.readUShort();
                     yPoints[i][j] = leis.readUShort();
                     size += 2*LittleEndianConsts.SHORT_SIZE;
                 }
             }
-            
+
             return size;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+
+        }
     }
 
     /**
@@ -275,27 +339,29 @@ public class HwmfDraw {
          * A 16-bit signed integer that defines the y-coordinate, in logical units, of
          * the lower-right corner of the rectangle.
          */
-        int bottomRect;
+        private int bottomRect;
         /**
          * A 16-bit signed integer that defines the x-coordinate, in logical units, of
          * the lower-right corner of the rectangle.
          */
-        int rightRect;
+        private int rightRect;
         /**
          * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
          * upper-left corner of the rectangle.
          */
-        int topRect;
+        private int topRect;
         /**
          * A 16-bit signed integer that defines the x-coordinate, in logical units, of
          * the upper-left corner of the rectangle.
          */
-        int leftRect;
-        
+        private int leftRect;
+
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.frameRegion;
         }
-        
+
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             bottomRect = leis.readShort();
             rightRect = leis.readShort();
@@ -303,6 +369,11 @@ public class HwmfDraw {
             leftRect = leis.readShort();
             return 4*LittleEndianConsts.SHORT_SIZE;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+
+        }
     }
 
     /**
@@ -313,25 +384,27 @@ public class HwmfDraw {
         /**
          * A ColorRef Object that defines the color value.
          */
-        HwmfColorRef colorRef; 
+        HwmfColorRef colorRef;
 
         /**
          * A 16-bit signed integer that defines the y-coordinate, in logical units, of the point
          * to be set.
          */
-        int y;
-        
+        private int y;
+
         /**
          * A 16-bit signed integer that defines the x-coordinate, in logical units, of the point
          * to be set.
          */
-        int x;
-        
-        
+        private int x;
+
+
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.setPixel;
         }
-        
+
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             colorRef = new HwmfColorRef();
             int size = colorRef.init(leis);
@@ -339,6 +412,11 @@ public class HwmfDraw {
             x = leis.readShort();
             return 2*LittleEndianConsts.SHORT_SIZE+size;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+
+        }
     }
 
     /**
@@ -350,43 +428,45 @@ public class HwmfDraw {
          * A 16-bit signed integer that defines the height, in logical coordinates, of the
          * ellipse used to draw the rounded corners.
          */
-        int height;
-        
+        private int height;
+
         /**
          * A 16-bit signed integer that defines the width, in logical coordinates, of the
          * ellipse used to draw the rounded corners.
          */
-        int width;
-        
+        private int width;
+
         /**
          * A 16-bit signed integer that defines the y-coordinate, in logical units, of
          * the lower-right corner of the rectangle.
          */
-        int bottomRect;
-        
+        private int bottomRect;
+
         /**
          * A 16-bit signed integer that defines the x-coordinate, in logical units, of
          * the lower-right corner of the rectangle.
          */
-        int rightRect;
-        
+        private int rightRect;
+
         /**
          * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
          * upper-left corner of the rectangle.
          */
-        int topRect;
-        
+        private int topRect;
+
         /**
          * A 16-bit signed integer that defines the x-coordinate, in logical units, of
          * the upper-left corner of the rectangle.
          */
-        int leftRect;
-        
-        
+        private int leftRect;
+
+
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.roundRect;
         }
-        
+
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             height = leis.readShort();
             width = leis.readShort();
@@ -396,8 +476,13 @@ public class HwmfDraw {
             leftRect = leis.readShort();
             return 6*LittleEndianConsts.SHORT_SIZE;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+
+        }
     }
-    
+
 
 
     /**
@@ -410,47 +495,49 @@ public class HwmfDraw {
          * A 16-bit signed integer that defines the y-coordinate, in logical
          * coordinates, of the endpoint of the second radial.
          */
-        int yRadial2;
+        private int yRadial2;
         /**
          * A 16-bit signed integer that defines the x-coordinate, in logical
          * coordinates, of the endpoint of the second radial.
          */
-        int xRadial2;
+        private int xRadial2;
         /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical 
+         * A 16-bit signed integer that defines the y-coordinate, in logical
          * coordinates, of the endpoint of the first radial.
          */
-        int yRadial1;
+        private int yRadial1;
         /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical 
+         * A 16-bit signed integer that defines the x-coordinate, in logical
          * coordinates, of the endpoint of the first radial.
          */
-        int xRadial1;  
+        private int xRadial1;
         /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of 
+         * A 16-bit signed integer that defines the y-coordinate, in logical units, of
          * the lower-right corner of the bounding rectangle.
          */
-        int bottomRect;
+        private int bottomRect;
         /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of 
+         * A 16-bit signed integer that defines the x-coordinate, in logical units, of
          * the lower-right corner of the bounding rectangle.
          */
-        int rightRect;
+        private int rightRect;
         /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the 
+         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
          * upper-left corner of the bounding rectangle.
          */
-        int topRect;
+        private int topRect;
         /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of 
+         * A 16-bit signed integer that defines the x-coordinate, in logical units, of
          * the upper-left corner of the bounding rectangle.
          */
-        int leftRect;
-        
+        private int leftRect;
+
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.pie;
         }
-        
+
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             yRadial2 = leis.readShort();
             xRadial2 = leis.readShort();
@@ -462,6 +549,12 @@ public class HwmfDraw {
             leftRect = leis.readShort();
             return 8*LittleEndianConsts.SHORT_SIZE;
         }
+
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+
+        }
     }
 
     /**
@@ -472,47 +565,49 @@ public class HwmfDraw {
          * 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.
          */
-        int yEndArc; 
+        private int yEndArc;
         /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of 
+         * 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.
          */
-        int xEndArc; 
+        private int xEndArc;
         /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of 
+         * 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.
          */
-        int yStartArc;
+        private int yStartArc;
         /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of 
+         * 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.
          */
-        int xStartArc;
+        private int xStartArc;
         /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of 
+         * A 16-bit signed integer that defines the y-coordinate, in logical units, of
          * the lower-right corner of the bounding rectangle.
          */
-        int bottomRect;
+        private int bottomRect;
         /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of 
+         * A 16-bit signed integer that defines the x-coordinate, in logical units, of
          * the lower-right corner of the bounding rectangle.
          */
-        int rightRect;
+        private int rightRect;
         /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the 
+         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
          * upper-left corner of the bounding rectangle.
          */
-        int topRect;
+        private int topRect;
         /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of 
+         * A 16-bit signed integer that defines the x-coordinate, in logical units, of
          * the upper-left corner of the bounding rectangle.
          */
-        int leftRect;
-        
+        private int leftRect;
+
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.arc;
         }
-        
+
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             yEndArc = leis.readShort();
             xEndArc = leis.readShort();
@@ -524,6 +619,11 @@ public class HwmfDraw {
             leftRect = leis.readShort();
             return 8*LittleEndianConsts.SHORT_SIZE;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+
+        }
     }
 
     /**
@@ -533,51 +633,53 @@ public class HwmfDraw {
      */
     public static class WmfChord implements HwmfRecord {
         /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical 
+         * A 16-bit signed integer that defines the y-coordinate, in logical
          * coordinates, of the endpoint of the second radial.
          */
-        int yRadial2;
+        private int yRadial2;
         /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical 
+         * A 16-bit signed integer that defines the x-coordinate, in logical
          * coordinates, of the endpoint of the second radial.
          */
-        int xRadial2;
+        private int xRadial2;
         /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical 
+         * A 16-bit signed integer that defines the y-coordinate, in logical
          * coordinates, of the endpoint of the first radial.
          */
-        int yRadial1;
+        private int yRadial1;
         /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical 
+         * A 16-bit signed integer that defines the x-coordinate, in logical
          * coordinates, of the endpoint of the first radial.
          */
-        int xRadial1;
+        private int xRadial1;
         /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of 
+         * A 16-bit signed integer that defines the y-coordinate, in logical units, of
          * the lower-right corner of the bounding rectangle.
          */
-        int bottomRect;
+        private int bottomRect;
         /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of 
+         * A 16-bit signed integer that defines the x-coordinate, in logical units, of
          * the lower-right corner of the bounding rectangle.
          */
-        int rightRect;
+        private int rightRect;
         /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the 
+         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
          * upper-left corner of the bounding rectangle.
          */
-        int topRect;
+        private int topRect;
         /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of 
+         * A 16-bit signed integer that defines the x-coordinate, in logical units, of
          * the upper-left corner of the bounding rectangle.
          */
-        int leftRect;
-        
-        
+        private int leftRect;
+
+
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.chord;
         }
-        
+
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             yRadial2 = leis.readShort();
             xRadial2 = leis.readShort();
@@ -589,31 +691,43 @@ public class HwmfDraw {
             leftRect = leis.readShort();
             return 8*LittleEndianConsts.SHORT_SIZE;
         }
-    }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+
+        }
+}
 
 
     /**
-     * The META_SELECTOBJECT record specifies a graphics object for the playback device context. The 
-     * new object replaces the previous object of the same type, unless if the previous object is a palette 
-     * object. If the previous object is a palette object, then the META_SELECTPALETTE record must be 
-     * used instead of the META_SELECTOBJECT record, as the META_SELECTOBJECT record does not 
+     * The META_SELECTOBJECT record specifies a graphics object for the playback device context. The
+     * new object replaces the previous object of the same type, unless if the previous object is a palette
+     * object. If the previous object is a palette object, then the META_SELECTPALETTE record must be
+     * used instead of the META_SELECTOBJECT record, as the META_SELECTOBJECT record does not
      * support replacing the palette object type.
      */
     public static class WmfSelectObject implements HwmfRecord {
-        
+
         /**
          * A 16-bit unsigned integer used to index into the WMF Object Table to
          * get the object to be selected.
          */
-        int objectIndex;
-        
+        private int objectIndex;
+
+        @Override
         public HwmfRecordType getRecordType() {
             return HwmfRecordType.selectObject;
         }
-        
+
+        @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             objectIndex = leis.readUShort();
             return LittleEndianConsts.SHORT_SIZE;
         }
+
+        @Override
+        public void draw(HwmfGraphics ctx) {
+
+        }
     }
  }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfEscape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfEscape.java?rev=1722046&r1=1722045&r2=1722046&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfEscape.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfEscape.java Tue Dec 29 00:45:59 2015
@@ -19,6 +19,8 @@ package org.apache.poi.hwmf.record;
 
 import java.io.IOException;
 
+import org.apache.poi.hwmf.draw.HwmfGraphics;
+import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 
@@ -28,21 +30,23 @@ public class HwmfEscape implements HwmfR
      * A 16-bit unsigned integer that defines the escape function. The 
      * value MUST be from the MetafileEscapes enumeration.
      */
-    int escapeFunction;
+    private int escapeFunction;
     /**
      * A 16-bit unsigned integer that specifies the size, in bytes, of the 
      * EscapeData field.
      */
-    int byteCount;
+    private int byteCount;
     /**
      * An array of bytes of size ByteCount.
      */
-    byte escapeData[];
+    private byte escapeData[];
     
+    @Override
     public HwmfRecordType getRecordType() {
         return HwmfRecordType.escape;
     }
     
+    @Override
     public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
         escapeFunction = leis.readUShort();
         byteCount = leis.readUShort();
@@ -50,4 +54,16 @@ public class HwmfEscape implements HwmfR
         leis.read(escapeData);
         return 2*LittleEndianConsts.SHORT_SIZE+byteCount;
     }
+
+    @Override
+    public void draw(HwmfGraphics ctx) {
+        
+    }
+    
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("escape - function: "+escapeFunction+"\n");
+        sb.append(HexDump.dump(escapeData, 0, 0));
+        return sb.toString();
+    }
 }



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


Mime
View raw message