poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kiwiwi...@apache.org
Subject svn commit: r1849040 [4/4] - in /poi: site/src/documentation/content/xdocs/ trunk/ trunk/sonar/ trunk/sonar/examples/ trunk/sonar/excelant/ trunk/sonar/main/ trunk/sonar/ooxml-schema-encryption/ trunk/sonar/ooxml-schema-security/ trunk/sonar/ooxml-sche...
Date Sun, 16 Dec 2018 18:17:22 GMT
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java?rev=1849040&r1=1849039&r2=1849040&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java Sun Dec 16 18:17:21 2018
@@ -17,10 +17,19 @@
 
 package org.apache.poi.hwmf.record;
 
+import static org.apache.poi.hwmf.record.HwmfDraw.boundsToString;
+import static org.apache.poi.hwmf.record.HwmfDraw.pointToString;
+import static org.apache.poi.hwmf.record.HwmfDraw.readPointS;
+import static org.apache.poi.hwmf.record.HwmfDraw.readRectS;
+
+import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
 import java.io.IOException;
 import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
 
+import org.apache.commons.codec.Charsets;
 import org.apache.poi.hwmf.draw.HwmfDrawProperties;
 import org.apache.poi.hwmf.draw.HwmfGraphics;
 import org.apache.poi.hwmf.record.HwmfMisc.WmfSetMapMode;
@@ -29,6 +38,7 @@ import org.apache.poi.util.BitFieldFacto
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
+import org.apache.poi.util.LocaleUtil;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 
@@ -52,7 +62,7 @@ public class HwmfText {
         private int charExtra;
         
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setTextCharExtra;
         }
         
@@ -73,16 +83,15 @@ public class HwmfText {
      */
     public static class WmfSetTextColor implements HwmfRecord {
         
-        private HwmfColorRef colorRef;
+        protected final HwmfColorRef colorRef = new HwmfColorRef();
         
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setTextColor;
         }
         
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            colorRef = new HwmfColorRef();
             return colorRef.init(leis);
         }
 
@@ -90,6 +99,11 @@ public class HwmfText {
         public void draw(HwmfGraphics ctx) {
             ctx.getProperties().setTextColor(colorRef);
         }
+
+        @Override
+        public String toString() {
+            return "{ colorRef: "+colorRef+" }";
+        }
     }
     
     /**
@@ -112,7 +126,7 @@ public class HwmfText {
         private int breakExtra;
         
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setBkColor;
         }
         
@@ -147,19 +161,11 @@ public class HwmfText {
          * The string is written at the location specified by the XStart and YStart fields.
          */
         private byte[] rawTextBytes;
-        /**
-         * A 16-bit signed integer that defines the vertical (y-axis) coordinate, in logical
-         * units, of the point where drawing is to start.
-         */
-        private int yStart;
-        /**
-         * A 16-bit signed integer that defines the horizontal (x-axis) coordinate, in
-         * logical units, of the point where drawing is to start.
-         */
-        private int xStart;  
-        
+
+        protected Point2D reference = new Point2D.Double();
+
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.textOut;
         }
         
@@ -168,15 +174,19 @@ public class HwmfText {
             stringLength = leis.readShort();
             rawTextBytes = IOUtils.safelyAllocate(stringLength+(stringLength&1), MAX_RECORD_LENGTH);
             leis.readFully(rawTextBytes);
-            yStart = leis.readShort();
-            xStart = leis.readShort();
+            // A 16-bit signed integer that defines the vertical (y-axis) coordinate, in logical
+            // units, of the point where drawing is to start.
+            int yStart = leis.readShort();
+            // A 16-bit signed integer that defines the horizontal (x-axis) coordinate, in
+            // logical units, of the point where drawing is to start.
+            int xStart = leis.readShort();
+            reference.setLocation(xStart, yStart);
             return 3*LittleEndianConsts.SHORT_SIZE+rawTextBytes.length;
         }
 
         @Override
         public void draw(HwmfGraphics ctx) {
-            Rectangle2D bounds = new Rectangle2D.Double(xStart, yStart, 0, 0);
-            ctx.drawString(getTextBytes(), bounds);
+            ctx.drawString(getTextBytes(), stringLength, reference);
         }
 
         public String getText(Charset charset) {
@@ -195,41 +205,48 @@ public class HwmfText {
             return ret;
         }
     }
-    
-    /**
-     * The META_EXTTEXTOUT record outputs text by using the font, background color, and text color that
-     * are defined in the playback device context. Optionally, dimensions can be provided for clipping,
-     * opaquing, or both.
-     */
-    public static class WmfExtTextOut implements HwmfRecord {
 
+    public static class WmfExtTextOutOptions {
         /**
-         * Indicates that the background color that is defined in the playback device context 
+         * Indicates that the background color that is defined in the playback device context
          * SHOULD be used to fill the rectangle.
-         */ 
+         */
         private static final BitField ETO_OPAQUE = BitFieldFactory.getInstance(0x0002);
-        
+
         /**
          * Indicates that the text SHOULD be clipped to the rectangle.
          */
         private static final BitField ETO_CLIPPED = BitFieldFactory.getInstance(0x0004);
 
         /**
-         * Indicates that the string to be output SHOULD NOT require further processing 
-         * with respect to the placement of the characters, and an array of character 
-         * placement values SHOULD be provided. This character placement process is 
+         * Indicates that the string to be output SHOULD NOT require further processing
+         * with respect to the placement of the characters, and an array of character
+         * placement values SHOULD be provided. This character placement process is
          * useful for fonts in which diacritical characters affect character spacing.
          */
         private static final BitField ETO_GLYPH_INDEX = BitFieldFactory.getInstance(0x0010);
 
         /**
-         * Indicates that the text MUST be laid out in right-to-left reading order, instead of 
-         * the default left-to-right order. This SHOULD be applied only when the font that is 
+         * Indicates that the text MUST be laid out in right-to-left reading order, instead of
+         * the default left-to-right order. This SHOULD be applied only when the font that is
          * defined in the playback device context is either Hebrew or Arabic.
          */
         private static final BitField ETO_RTLREADING = BitFieldFactory.getInstance(0x0080);
 
         /**
+         * This bit indicates that the record does not specify a bounding rectangle for the
+         * text output.
+         */
+        private static final BitField ETO_NO_RECT = BitFieldFactory.getInstance(0x0100);
+
+        /**
+         * This bit indicates that the codes for characters in an output text string are 8 bits,
+         * derived from the low bytes of 16-bit Unicode UTF16-LE character codes, in which
+         * the high byte is assumed to be 0.
+         */
+        private static final BitField ETO_SMALL_CHARS = BitFieldFactory.getInstance(0x0200);
+
+        /**
          * Indicates that to display numbers, digits appropriate to the locale SHOULD be used.
          */
         private static final BitField ETO_NUMERICSLOCAL = BitFieldFactory.getInstance(0x0400);
@@ -240,32 +257,62 @@ public class HwmfText {
         private static final BitField ETO_NUMERICSLATIN = BitFieldFactory.getInstance(0x0800);
 
         /**
-         * Indicates that both horizontal and vertical character displacement values 
+         * This bit indicates that no special operating system processing for glyph placement
+         * should be performed on right-to-left strings; that is, all glyph positioning
+         * SHOULD be taken care of by drawing and state records in the metafile
+         */
+        private static final BitField ETO_IGNORELANGUAGE = BitFieldFactory.getInstance(0x1000);
+
+        /**
+         * Indicates that both horizontal and vertical character displacement values
          * SHOULD be provided.
          */
         private static final BitField ETO_PDY = BitFieldFactory.getInstance(0x2000);
 
+        /** This bit is reserved and SHOULD NOT be used. */
+        private static final BitField ETO_REVERSE_INDEX_MAP = BitFieldFactory.getInstance(0x10000);
+
+        protected int flag;
+
+        public int init(LittleEndianInputStream leis) {
+            flag = leis.readUShort();
+            return LittleEndianConsts.SHORT_SIZE;
+        }
+
+        public boolean isOpaque() {
+            return ETO_OPAQUE.isSet(flag);
+        }
+
+        public boolean isClipped() {
+            return ETO_CLIPPED.isSet(flag);
+        }
+
+        public boolean isYDisplaced() {
+            return ETO_PDY.isSet(flag);
+        }
+    }
+
+    /**
+     * The META_EXTTEXTOUT record outputs text by using the font, background color, and text color that
+     * are defined in the playback device context. Optionally, dimensions can be provided for clipping,
+     * opaquing, or both.
+     */
+    public static class WmfExtTextOut implements HwmfRecord {
         /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, where the 
-        text string is to be located.
+         * The location, in logical units, where the text string is to be placed.
          */
-        private int y;  
+        protected final Point2D reference = new Point2D.Double();
+
         /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, where the 
-        text string is to be located.
+         * A 16-bit signed integer that defines the length of the string.
          */
-        private int x;  
+        protected int stringLength;
         /**
-         * A 16-bit signed integer that defines the length of the string.
+         * A 16-bit unsigned integer that defines the use of the application-defined
+         * rectangle. This member can be a combination of one or more values in the
+         * ExtTextOutOptions Flags (ETO_*)
          */
-        private int stringLength;
-
-         /**
-          * A 16-bit unsigned integer that defines the use of the application-defined 
-          * rectangle. This member can be a combination of one or more values in the 
-          * ExtTextOutOptions Flags (ETO_*)
-          */
-        private int fwOpts;
+        protected final WmfExtTextOutOptions options;
         /**
          * An optional 8-byte Rect Object (section 2.2.2.18) that defines the 
          * dimensions, in logical coordinates, of a rectangle that is used for clipping, opaquing, or both.
@@ -274,24 +321,32 @@ public class HwmfText {
          * Each value is a 16-bit signed integer that defines the coordinate, in logical coordinates, of 
          * the upper-left corner of the rectangle
          */
-        private int left,top,right,bottom;
+        protected final Rectangle2D bounds = new Rectangle2D.Double();
         /**
          * A variable-length string that specifies the text to be drawn. The string does 
          * not need to be null-terminated, because StringLength specifies the length of the string. If 
          * the length is odd, an extra byte is placed after it so that the following member (optional Dx) is 
          * aligned on a 16-bit boundary.
          */
-        private byte[] rawTextBytes;
+        protected byte[] rawTextBytes;
         /**
          * An optional array of 16-bit signed integers that indicate the distance between 
          * origins of adjacent character cells. For example, Dx[i] logical units separate the origins of 
          * character cell i and character cell i + 1. If this field is present, there MUST be the same 
          * number of values as there are characters in the string.
          */
-        private int dx[];
-        
+        protected final List<Integer> dx = new ArrayList<>();
+
+        public WmfExtTextOut() {
+            this(new WmfExtTextOutOptions());
+        }
+
+        protected WmfExtTextOut(WmfExtTextOutOptions options) {
+            this.options = options;
+        }
+
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.extTextOut;
         }
         
@@ -299,22 +354,17 @@ public class HwmfText {
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
             // -6 bytes of record function and length header
             final int remainingRecordSize = (int)(recordSize-6);
-            
-            y = leis.readShort();
-            x = leis.readShort();
+
+            int size = readPointS(leis, reference);
+
             stringLength = leis.readShort();
-            fwOpts = leis.readUShort();
-            
-            int size = 4*LittleEndianConsts.SHORT_SIZE;
-            
+            size += LittleEndianConsts.SHORT_SIZE;
+            size += options.init(leis);
+
             // Check if we have a rectangle
-            if ((ETO_OPAQUE.isSet(fwOpts) || ETO_CLIPPED.isSet(fwOpts)) && size+8<=remainingRecordSize) {
-                // the bounding rectangle is optional and only read when fwOpts are given
-                left = leis.readShort();
-                top = leis.readShort();
-                right = leis.readShort();
-                bottom = leis.readShort();
-                size += 4*LittleEndianConsts.SHORT_SIZE;
+            if ((options.isOpaque() || options.isClipped()) && size+8<=remainingRecordSize) {
+                // the bounding rectangle is optional and only read when options are given
+                size += readRectS(leis, bounds);
             }
             
             rawTextBytes = IOUtils.safelyAllocate(stringLength+(stringLength&1), MAX_RECORD_LENGTH);
@@ -331,9 +381,8 @@ public class HwmfText {
                 logger.log(POILogger.WARN, "META_EXTTEXTOUT tracking info doesn't cover all characters");
             }
 
-            dx = new int[stringLength]; 
             for (int i=0; i<dxLen; i++) {
-                dx[i] = leis.readShort();
+                dx.add((int)leis.readShort());
                 size += LittleEndianConsts.SHORT_SIZE;
             }
             
@@ -342,24 +391,38 @@ public class HwmfText {
 
         @Override
         public void draw(HwmfGraphics ctx) {
-            Rectangle2D bounds = new Rectangle2D.Double(x, y, 0, 0);
-            ctx.drawString(getTextBytes(), bounds, dx);
+            ctx.drawString(rawTextBytes, stringLength, reference, null, bounds, options, dx, false);
         }
 
-        public String getText(Charset charset) {
-            return new String(getTextBytes(), charset);
+        public String getText(Charset charset) throws IOException {
+            return new String(rawTextBytes, charset).substring(0, stringLength);
         }
 
-        /**
-         *
-         * @return a copy of a trimmed byte array of rawTextBytes bytes.
-         * This includes only the bytes from 0..stringLength.
-         * This does not include the extra optional padding on the byte array.
-         */
-        private byte[] getTextBytes() {
-            byte[] ret = IOUtils.safelyAllocate(stringLength, MAX_RECORD_LENGTH);
-            System.arraycopy(rawTextBytes, 0, ret, 0, stringLength);
-            return ret;
+        public Point2D getReference() {
+            return reference;
+        }
+
+        public Rectangle2D getBounds() {
+            return bounds;
+        }
+
+        protected boolean isUnicode() {
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            String text = "";
+            try {
+                text = getText(isUnicode() ? Charsets.UTF_16LE : LocaleUtil.CHARSET_1252);
+            } catch (IOException ignored) {
+            }
+
+            return
+                "{ reference: " + pointToString(reference) +
+                ", bounds: " + boundsToString(bounds) +
+                ", text: '"+text.replaceAll("\\p{Cntrl}",".")+"'"+
+                "}";
         }
     }
     
@@ -380,57 +443,17 @@ public class HwmfText {
      */
     public static class WmfSetTextAlign implements HwmfRecord {
         
-        // ***********************************************************************************
-        // TextAlignmentMode Flags:
-        // ***********************************************************************************
-        
-        /** 
-         * The drawing position in the playback device context MUST NOT be updated after each
-         * text output call. The reference point MUST be passed to the text output function.
-         */
-        @SuppressWarnings("unused")
-        private static final BitField TA_NOUPDATECP = BitFieldFactory.getInstance(0x0000);
-        
-        /**
-         * The reference point MUST be on the left edge of the bounding rectangle.
-         */
-        @SuppressWarnings("unused")
-        private static final BitField TA_LEFT = BitFieldFactory.getInstance(0x0000);
-        
-        /**
-         * The reference point MUST be on the top edge of the bounding rectangle.
-         */
-        @SuppressWarnings("unused")
-        private static final BitField TA_TOP = BitFieldFactory.getInstance(0x0000);
-        
         /**
          * The drawing position in the playback device context MUST be updated after each text
-         * output call. It MUST be used as the reference point.
+         * output call. It MUST be used as the reference point.<p>
+         *
+         * If the flag is not set, the option TA_NOUPDATECP is active, i.e. the drawing position
+         * in the playback device context MUST NOT be updated after each text output call.
+         * The reference point MUST be passed to the text output function.
          */
         @SuppressWarnings("unused")
         private static final BitField TA_UPDATECP = BitFieldFactory.getInstance(0x0001);
-        
-        /**
-         * The reference point MUST be on the right edge of the bounding rectangle.
-         */
-        private static final BitField TA_RIGHT = BitFieldFactory.getInstance(0x0002);
-        
-        /**
-         * The reference point MUST be aligned horizontally with the center of the bounding
-         * rectangle.
-         */
-        private static final BitField TA_CENTER = BitFieldFactory.getInstance(0x0006);
-        
-        /**
-         * The reference point MUST be on the bottom edge of the bounding rectangle.
-         */
-        private static final BitField TA_BOTTOM = BitFieldFactory.getInstance(0x0008);
-        
-        /**
-         * The reference point MUST be on the baseline of the text.
-         */
-        private static final BitField TA_BASELINE = BitFieldFactory.getInstance(0x0018);
-        
+
         /**
          * The text MUST be laid out in right-to-left reading order, instead of the default
          * left-to-right order. This SHOULD be applied only when the font that is defined in the
@@ -438,43 +461,64 @@ public class HwmfText {
          */
         @SuppressWarnings("unused")
         private static final BitField TA_RTLREADING = BitFieldFactory.getInstance(0x0100);
-        
-        // ***********************************************************************************
-        // VerticalTextAlignmentMode Flags (e.g. for Kanji fonts)
-        // ***********************************************************************************
-        
+
+
+        private static final BitField ALIGN_MASK = BitFieldFactory.getInstance(0x0006);
+
         /**
-         * The reference point MUST be on the top edge of the bounding rectangle.
+         * Flag TA_LEFT (0x0000):
+         * The reference point MUST be on the left edge of the bounding rectangle,
+         * if all bits of the align mask (latin mode) are unset.
+         *
+         * Flag VTA_TOP (0x0000):
+         * The reference point MUST be on the top edge of the bounding rectangle,
+         * if all bits of the valign mask are unset.
          */
-        @SuppressWarnings("unused")
-        private static final BitField VTA_TOP = BitFieldFactory.getInstance(0x0000);
-        
+        private static final int ALIGN_LEFT = 0;
+
         /**
+         * Flag TA_RIGHT (0x0002):
          * The reference point MUST be on the right edge of the bounding rectangle.
-         */
-        @SuppressWarnings("unused")
-        private static final BitField VTA_RIGHT = BitFieldFactory.getInstance(0x0000);
-        
-        /**
+         *
+         * Flag VTA_BOTTOM (0x0002):
          * The reference point MUST be on the bottom edge of the bounding rectangle.
          */
-        private static final BitField VTA_BOTTOM = BitFieldFactory.getInstance(0x0002);
-        
+        private static final int ALIGN_RIGHT = 1;
+
         /**
-         * The reference point MUST be aligned vertically with the center of the bounding
+         * Flag TA_CENTER (0x0006) / VTA_CENTER (0x0006):
+         * The reference point MUST be aligned horizontally with the center of the bounding
          * rectangle.
          */
-        private static final BitField VTA_CENTER = BitFieldFactory.getInstance(0x0006);
-        
+        private static final int ALIGN_CENTER = 3;
+
+        private static final BitField VALIGN_MASK = BitFieldFactory.getInstance(0x0018);
+
+        /**
+         * Flag TA_TOP (0x0000):
+         * The reference point MUST be on the top edge of the bounding rectangle,
+         * if all bits of the valign mask are unset.
+         *
+         * Flag VTA_RIGHT (0x0000):
+         * The reference point MUST be on the right edge of the bounding rectangle,
+         * if all bits of the align mask (asian mode) are unset.
+         */
+        private static final int VALIGN_TOP = 0;
+
         /**
+         * Flag TA_BOTTOM (0x0008):
+         * The reference point MUST be on the bottom edge of the bounding rectangle.
+         *
+         * Flag VTA_LEFT (0x0008):
          * The reference point MUST be on the left edge of the bounding rectangle.
          */
-        private static final BitField VTA_LEFT = BitFieldFactory.getInstance(0x0008);
+        private static final int VALIGN_BOTTOM = 1;
         
         /**
+         * Flag TA_BASELINE (0x0018) / VTA_BASELINE (0x0018):
          * The reference point MUST be on the baseline of the text.
          */
-        private static final BitField VTA_BASELINE = BitFieldFactory.getInstance(0x0018);
+        private static final int VALIGN_BASELINE = 3;
         
         /**
          * A 16-bit unsigned integer that defines text alignment.
@@ -482,10 +526,10 @@ public class HwmfText {
          * for text with a horizontal baseline, and VerticalTextAlignmentMode Flags
          * for text with a vertical baseline.
          */
-        private int textAlignmentMode;
+        protected int textAlignmentMode;
         
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setTextAlign;
         }
         
@@ -498,52 +542,90 @@ public class HwmfText {
         @Override
         public void draw(HwmfGraphics ctx) {
             HwmfDrawProperties props = ctx.getProperties();
-            if (TA_CENTER.isSet(textAlignmentMode)) {
-                props.setTextAlignLatin(HwmfTextAlignment.CENTER);
-            } else if (TA_RIGHT.isSet(textAlignmentMode)) {
-                props.setTextAlignLatin(HwmfTextAlignment.RIGHT);
-            } else {
-                props.setTextAlignLatin(HwmfTextAlignment.LEFT);
+            props.setTextAlignLatin(getAlignLatin());
+            props.setTextVAlignLatin(getVAlignLatin());
+            props.setTextAlignAsian(getAlignAsian());
+            props.setTextVAlignAsian(getVAlignAsian());
+        }
+
+        @Override
+        public String toString() {
+            return
+                "{ align: '"+ getAlignLatin() + "'" +
+                ", valign: '"+ getVAlignLatin() + "'" +
+                ", alignAsian: '"+ getAlignAsian() + "'" +
+                ", valignAsian: '"+ getVAlignAsian() + "'" +
+                "}";
+        }
+
+        private HwmfTextAlignment getAlignLatin() {
+            switch (ALIGN_MASK.getValue(textAlignmentMode)) {
+                default:
+                case ALIGN_LEFT:
+                    return HwmfTextAlignment.LEFT;
+                case ALIGN_CENTER:
+                    return HwmfTextAlignment.CENTER;
+                case ALIGN_RIGHT:
+                    return HwmfTextAlignment.RIGHT;
             }
+        }
 
-            if (VTA_CENTER.isSet(textAlignmentMode)) {
-                props.setTextAlignAsian(HwmfTextAlignment.CENTER);
-            } else if (VTA_LEFT.isSet(textAlignmentMode)) {
-                props.setTextAlignAsian(HwmfTextAlignment.LEFT);
-            } else {
-                props.setTextAlignAsian(HwmfTextAlignment.RIGHT);
+        private HwmfTextVerticalAlignment getVAlignLatin() {
+            switch (VALIGN_MASK.getValue(textAlignmentMode)) {
+                default:
+                case VALIGN_TOP:
+                    return HwmfTextVerticalAlignment.TOP;
+                case VALIGN_BASELINE:
+                    return HwmfTextVerticalAlignment.BASELINE;
+                case VALIGN_BOTTOM:
+                    return HwmfTextVerticalAlignment.BOTTOM;
             }
+        }
 
-            if (TA_BASELINE.isSet(textAlignmentMode)) {
-                props.setTextVAlignLatin(HwmfTextVerticalAlignment.BASELINE);
-            } else if (TA_BOTTOM.isSet(textAlignmentMode)) {
-                props.setTextVAlignLatin(HwmfTextVerticalAlignment.BOTTOM);
-            } else {
-                props.setTextVAlignLatin(HwmfTextVerticalAlignment.TOP);
+        private HwmfTextAlignment getAlignAsian() {
+            switch (getVAlignLatin()) {
+                default:
+                case TOP:
+                    return HwmfTextAlignment.RIGHT;
+                case BASELINE:
+                    return HwmfTextAlignment.CENTER;
+                case BOTTOM:
+                    return HwmfTextAlignment.LEFT;
             }
+        }
 
-            if (VTA_BASELINE.isSet(textAlignmentMode)) {
-                props.setTextVAlignAsian(HwmfTextVerticalAlignment.BASELINE);
-            } else if (VTA_BOTTOM.isSet(textAlignmentMode)) {
-                props.setTextVAlignAsian(HwmfTextVerticalAlignment.BOTTOM);
-            } else {
-                props.setTextVAlignAsian(HwmfTextVerticalAlignment.TOP);
+        private HwmfTextVerticalAlignment getVAlignAsian() {
+            switch (getAlignLatin()) {
+                default:
+                case LEFT:
+                    return HwmfTextVerticalAlignment.TOP;
+                case CENTER:
+                    return HwmfTextVerticalAlignment.BASELINE;
+                case RIGHT:
+                    return HwmfTextVerticalAlignment.BOTTOM;
             }
         }
     }
     
     public static class WmfCreateFontIndirect implements HwmfRecord, HwmfObjectTableEntry {
-        private HwmfFont font;
-        
+        protected final HwmfFont font;
+
+        public WmfCreateFontIndirect() {
+            this(new HwmfFont());
+        }
+
+        protected WmfCreateFontIndirect(HwmfFont font) {
+            this.font = font;
+        }
+
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.createFontIndirect;
         }
         
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            font = new HwmfFont();
-            return font.init(leis);
+            return font.init(leis, recordSize);
         }
 
         @Override
@@ -559,5 +641,10 @@ public class HwmfText {
         public HwmfFont getFont() {
             return font;
         }
+
+        @Override
+        public String toString() {
+            return "{ font: "+font+" } ";
+        }
     }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java?rev=1849040&r1=1849039&r2=1849040&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java Sun Dec 16 18:17:21 2018
@@ -17,12 +17,23 @@
 
 package org.apache.poi.hwmf.record;
 
+import static org.apache.poi.hwmf.record.HwmfDraw.boundsToString;
+import static org.apache.poi.hwmf.record.HwmfDraw.dimToString;
+import static org.apache.poi.hwmf.record.HwmfDraw.normalizeBounds;
+import static org.apache.poi.hwmf.record.HwmfDraw.pointToString;
+import static org.apache.poi.hwmf.record.HwmfDraw.readBounds;
+import static org.apache.poi.hwmf.record.HwmfDraw.readPointS;
+
 import java.awt.Shape;
 import java.awt.geom.Area;
+import java.awt.geom.Dimension2D;
+import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
 import java.io.IOException;
 
+import org.apache.poi.hwmf.draw.HwmfDrawProperties;
 import org.apache.poi.hwmf.draw.HwmfGraphics;
+import org.apache.poi.util.Dimension2DDouble;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 
@@ -33,31 +44,33 @@ public class HwmfWindowing {
      */
     public static class WmfSetViewportOrg implements HwmfRecord {
 
-        /**
-         * A 16-bit signed integer that defines the vertical offset, in device units.
-         */
-        private int y;
-
-        /**
-         * A 16-bit signed integer that defines the horizontal offset, in device units.
-         */
-        private int x;
+        protected final Point2D origin = new Point2D.Double();
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setViewportOrg;
         }
 
         @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, origin);
         }
 
         @Override
         public void draw(HwmfGraphics ctx) {
-            ctx.getProperties().setViewportOrg(x, y);
+            final HwmfDrawProperties prop = ctx.getProperties();
+            Rectangle2D old = prop.getViewport();
+            double oldX = (old == null ? 0 : old.getX());
+            double oldY = (old == null ? 0 : old.getY());
+            if (oldX != origin.getX() || oldY != origin.getY()) {
+                prop.setViewportOrg(origin.getX(), origin.getY());
+                ctx.updateWindowMapMode();
+            }
+        }
+
+        @Override
+        public String toString() {
+            return pointToString(origin);
         }
     }
 
@@ -67,33 +80,38 @@ public class HwmfWindowing {
      */
     public static class WmfSetViewportExt implements HwmfRecord {
 
-        /**
-         * A 16-bit signed integer that defines the vertical extent
-         * of the viewport in device units.
-         */
-        private int height;
-
-        /**
-         * A 16-bit signed integer that defines the horizontal extent
-         * of the viewport in device units.
-         */
-        private int width;
+        protected final Dimension2D extents = new Dimension2DDouble();
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setViewportExt;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            height = leis.readShort();
-            width = leis.readShort();
+            // A signed integer that defines the vertical extent of the viewport in device units.
+            int height = leis.readShort();
+            // A signed integer that defines the horizontal extent of the viewport in device units.
+            int width = leis.readShort();
+            extents.setSize(width, height);
             return 2*LittleEndianConsts.SHORT_SIZE;
         }
 
         @Override
         public void draw(HwmfGraphics ctx) {
-            ctx.getProperties().setViewportExt(width, height);
+            final HwmfDrawProperties prop = ctx.getProperties();
+            Rectangle2D old = prop.getViewport();
+            double oldW = (old == null ? 0 : old.getWidth());
+            double oldH = (old == null ? 0 : old.getHeight());
+            if (oldW != extents.getWidth() || oldH != extents.getHeight()) {
+                prop.setViewportExt(extents.getWidth(), extents.getHeight());
+                ctx.updateWindowMapMode();
+            }
+        }
+
+        @Override
+        public String toString() {
+            return dimToString(extents);
         }
     }
 
@@ -103,34 +121,33 @@ public class HwmfWindowing {
      */
     public static class WmfOffsetViewportOrg implements HwmfRecord {
 
-        /**
-         * A 16-bit signed integer that defines the vertical offset, in device units.
-         */
-        private int yOffset;
-
-        /**
-         * A 16-bit signed integer that defines the horizontal offset, in device units.
-         */
-        private int xOffset;
+        protected final Point2D offset = new Point2D.Double();
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.offsetViewportOrg;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            yOffset = leis.readShort();
-            xOffset = leis.readShort();
-            return 2*LittleEndianConsts.SHORT_SIZE;
+            return readPointS(leis, offset);
         }
 
         @Override
         public void draw(HwmfGraphics ctx) {
-            Rectangle2D viewport = ctx.getProperties().getViewport();
-            double x = (viewport == null) ? 0 : viewport.getX();
-            double y = (viewport == null) ? 0 : viewport.getY();
-            ctx.getProperties().setViewportOrg(x+xOffset, y+yOffset);
+            final HwmfDrawProperties prop = ctx.getProperties();
+            Rectangle2D viewport = prop.getViewport();
+            if (offset.getX() != 0 || offset.getY() != 0) {
+                double x = (viewport == null) ? 0 : viewport.getX();
+                double y = (viewport == null) ? 0 : viewport.getY();
+                prop.setViewportOrg(x + offset.getX(), y + offset.getY());
+                ctx.updateWindowMapMode();
+            }
+        }
+
+        @Override
+        public String toString() {
+            return pointToString(offset);
         }
     }
 
@@ -139,40 +156,41 @@ public class HwmfWindowing {
      */
     public static class WmfSetWindowOrg implements HwmfRecord {
 
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units.
-         */
-        private int y;
-
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units.
-         */
-        private int x;
+        protected final Point2D origin = new Point2D.Double();
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setWindowOrg;
         }
 
         @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, origin);
         }
 
         @Override
         public void draw(HwmfGraphics ctx) {
-            ctx.getProperties().setWindowOrg(x, y);
-            ctx.updateWindowMapMode();
+            final HwmfDrawProperties prop = ctx.getProperties();
+            final Rectangle2D old = prop.getWindow();
+            double oldX = (old == null ? 0 : old.getX());
+            double oldY = (old == null ? 0 : old.getY());
+            if (oldX != getX() || oldY != getY()) {
+                prop.setWindowOrg(getX(), getY());
+                ctx.updateWindowMapMode();
+            }
         }
 
-        public int getY() {
-            return y;
+        public double getY() {
+            return origin.getY();
         }
 
-        public int getX() {
-            return x;
+        public double getX() {
+            return origin.getX();
+        }
+
+        @Override
+        public String toString() {
+            return pointToString(origin);
         }
     }
 
@@ -182,42 +200,42 @@ public class HwmfWindowing {
      */
     public static class WmfSetWindowExt implements HwmfRecord {
 
-        /**
-         * A 16-bit signed integer that defines the vertical extent of
-         * the window in logical units.
-         */
-        private int height;
-
-        /**
-         * A 16-bit signed integer that defines the horizontal extent of
-         * the window in logical units.
-         */
-        private int width;
+        protected final Dimension2D size = new Dimension2DDouble();
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.setWindowExt;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            height = leis.readShort();
-            width = leis.readShort();
+            // A signed integer that defines the vertical extent of the window in logical units.
+            int height = leis.readShort();
+            // A signed integer that defines the horizontal extent of the window in logical units.
+            int width = leis.readShort();
+            size.setSize(width, height);
             return 2*LittleEndianConsts.SHORT_SIZE;
         }
 
         @Override
         public void draw(HwmfGraphics ctx) {
-            ctx.getProperties().setWindowExt(width, height);
-            ctx.updateWindowMapMode();
+            final HwmfDrawProperties prop = ctx.getProperties();
+            Rectangle2D old = prop.getWindow();
+            double oldW = (old == null ? 0 : old.getWidth());
+            double oldH = (old == null ? 0 : old.getHeight());
+            if (oldW != size.getWidth() || oldH != size.getHeight()) {
+                prop.setWindowExt(size.getWidth(), size.getHeight());
+                ctx.updateWindowMapMode();
+            }
         }
 
-        public int getHeight() {
-            return height;
+        public Dimension2D getSize() {
+            return size;
         }
 
-        public int getWidth() {
-            return width;
+        @Override
+        public String toString() {
+            return dimToString(size);
         }
     }
 
@@ -227,33 +245,31 @@ public class HwmfWindowing {
      */
     public static class WmfOffsetWindowOrg implements HwmfRecord {
 
-        /**
-         * A 16-bit signed integer that defines the vertical offset, in device units.
-         */
-        private int yOffset;
-
-        /**
-         * A 16-bit signed integer that defines the horizontal offset, in device units.
-         */
-        private int xOffset;
+        protected final Point2D offset = new Point2D.Double();
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.offsetWindowOrg;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            yOffset = leis.readShort();
-            xOffset = leis.readShort();
-            return 2*LittleEndianConsts.SHORT_SIZE;
+            return readPointS(leis, offset);
         }
 
         @Override
         public void draw(HwmfGraphics ctx) {
-            Rectangle2D window = ctx.getProperties().getWindow();
-            ctx.getProperties().setWindowOrg(window.getX()+xOffset, window.getY()+yOffset);
-            ctx.updateWindowMapMode();
+            final HwmfDrawProperties prop = ctx.getProperties();
+            Rectangle2D old = prop.getWindow();
+            if (offset.getX() != 0 || offset.getY() != 0) {
+                prop.setWindowOrg(old.getX() + offset.getX(), old.getY() + offset.getY());
+                ctx.updateWindowMapMode();
+            }
+        }
+
+        @Override
+        public String toString() {
+            return pointToString(offset);
         }
     }
 
@@ -263,51 +279,48 @@ public class HwmfWindowing {
      */
     public static class WmfScaleWindowExt implements HwmfRecord {
 
-        /**
-         * A 16-bit signed integer that defines the amount by which to divide the
-         * result of multiplying the current y-extent by the value of the yNum member.
-         */
-        private int yDenom;
-
-        /**
-         * A 16-bit signed integer that defines the amount by which to multiply the
-         * current y-extent.
-         */
-        private int yNum;
-
-        /**
-         * A 16-bit signed integer that defines the amount by which to divide the
-         * result of multiplying the current x-extent by the value of the xNum member.
-         */
-        private int xDenom;
-
-        /**
-         * A 16-bit signed integer that defines the amount by which to multiply the
-         * current x-extent.
-         */
-        private int xNum;
+        protected final Dimension2D scale = new Dimension2DDouble();
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.scaleWindowExt;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            yDenom = leis.readShort();
-            yNum = leis.readShort();
-            xDenom = leis.readShort();
-            xNum = leis.readShort();
+            // A signed integer that defines the amount by which to divide the
+            // result of multiplying the current y-extent by the value of the yNum member.
+            double yDenom = leis.readShort();
+            // A signed integer that defines the amount by which to multiply the
+            // current y-extent.
+            double yNum = leis.readShort();
+            // A signed integer that defines the amount by which to divide the
+            // result of multiplying the current x-extent by the value of the xNum member.
+            double xDenom = leis.readShort();
+            // A signed integer that defines the amount by which to multiply the
+            // current x-extent.
+            double xNum = leis.readShort();
+
+            scale.setSize(xNum / xDenom, yNum / yDenom);
+
             return 4*LittleEndianConsts.SHORT_SIZE;
         }
 
         @Override
         public void draw(HwmfGraphics ctx) {
-            Rectangle2D window = ctx.getProperties().getWindow();
-            double width = window.getWidth() * xNum / xDenom;
-            double height = window.getHeight() * yNum / yDenom;
-            ctx.getProperties().setWindowExt(width, height);
-            ctx.updateWindowMapMode();
+            final HwmfDrawProperties prop = ctx.getProperties();
+            Rectangle2D old = prop.getWindow();
+            if (scale.getWidth() != 1.0 || scale.getHeight() != 1.0) {
+                double width = old.getWidth() * scale.getWidth();
+                double height = old.getHeight() * scale.getHeight();
+                ctx.getProperties().setWindowExt(width, height);
+                ctx.updateWindowMapMode();
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "{ scaleX: "+scale.getWidth()+", scaleY: "+scale.getHeight()+" }";
         }
     }
 
@@ -319,53 +332,49 @@ public class HwmfWindowing {
      */
     public static class WmfScaleViewportExt implements HwmfRecord {
 
-        /**
-         * A 16-bit signed integer that defines the amount by which to divide the
-         * result of multiplying the current y-extent by the value of the yNum member.
-         */
-        private int yDenom;
-
-        /**
-         * A 16-bit signed integer that defines the amount by which to multiply the
-         * current y-extent.
-         */
-        private int yNum;
-
-        /**
-         * A 16-bit signed integer that defines the amount by which to divide the
-         * result of multiplying the current x-extent by the value of the xNum member.
-         */
-        private int xDenom;
-
-        /**
-         * A 16-bit signed integer that defines the amount by which to multiply the
-         * current x-extent.
-         */
-        private int xNum;
+        protected final Dimension2D scale = new Dimension2DDouble();
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.scaleViewportExt;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            yDenom = leis.readShort();
-            yNum = leis.readShort();
-            xDenom = leis.readShort();
-            xNum = leis.readShort();
+            // A signed integer that defines the amount by which to divide the
+            // result of multiplying the current y-extent by the value of the yNum member.
+            double yDenom = leis.readShort();
+            // A signed integer that defines the amount by which to multiply the
+            // current y-extent.
+            double yNum = leis.readShort();
+            // A signed integer that defines the amount by which to divide the
+            // result of multiplying the current x-extent by the value of the xNum member.
+            double xDenom = leis.readShort();
+            // A signed integer that defines the amount by which to multiply the
+            // current x-extent.
+            double xNum = leis.readShort();
+
+            scale.setSize(xNum / xDenom, yNum / yDenom);
+
             return 4*LittleEndianConsts.SHORT_SIZE;
         }
 
         @Override
         public void draw(HwmfGraphics ctx) {
-            Rectangle2D viewport = ctx.getProperties().getViewport();
-            if (viewport == null) {
-                viewport = ctx.getProperties().getWindow();
+            final HwmfDrawProperties prop = ctx.getProperties();
+            final Rectangle2D old = prop.getViewport() == null ? prop.getWindow() : prop.getViewport();
+
+            if (scale.getWidth() != 1.0 || scale.getHeight() != 1.0) {
+                double width = old.getWidth() * scale.getWidth();
+                double height = old.getHeight() * scale.getHeight();
+                prop.setViewportExt(width, height);
+                ctx.updateWindowMapMode();
             }
-            double width = viewport.getWidth() * xNum / xDenom;
-            double height = viewport.getHeight() * yNum / yDenom;
-            ctx.getProperties().setViewportExt(width, height);
+        }
+
+        @Override
+        public String toString() {
+            return "{ scaleX: "+scale.getWidth()+", scaleY: "+scale.getHeight()+" }";
         }
     }
 
@@ -375,26 +384,16 @@ public class HwmfWindowing {
      */
     public static class WmfOffsetClipRgn implements HwmfRecord, HwmfObjectTableEntry {
 
-        /**
-         * A 16-bit signed integer that defines the number of logical units to move up or down.
-         */
-        private int yOffset;
-
-        /**
-         * A 16-bit signed integer that defines the number of logical units to move left or right.
-         */
-        private int xOffset;
+        protected final Point2D offset = new Point2D.Double();
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.offsetClipRgn;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            yOffset = leis.readShort();
-            xOffset = leis.readShort();
-            return 2*LittleEndianConsts.SHORT_SIZE;
+            return readPointS(leis, offset);
         }
 
         @Override
@@ -405,6 +404,11 @@ public class HwmfWindowing {
         @Override
         public void applyObject(HwmfGraphics ctx) {
         }
+
+        @Override
+        public String toString() {
+            return pointToString(offset);
+        }
     }
 
     /**
@@ -413,42 +417,17 @@ public class HwmfWindowing {
      */
     public static class WmfExcludeClipRect implements HwmfRecord, HwmfObjectTableEntry {
 
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-         * lower-right corner of the rectangle.
-         */
-        private int bottom;
-
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
-         * lower-right corner of the rectangle.
-         */
-        private int right;
-
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-         * upper-left corner of the rectangle.
-         */
-        private int top;
-
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
-         * upper-left corner of the rectangle.
-         */
-        private int left;
+        /** a rectangle in logical units */
+        protected final Rectangle2D bounds = new Rectangle2D.Double();
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.excludeClipRect;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            bottom = leis.readShort();
-            right = leis.readShort();
-            top = leis.readShort();
-            left = leis.readShort();
-            return 4*LittleEndianConsts.SHORT_SIZE;
+            return readBounds(leis, bounds);
         }
 
         @Override
@@ -458,6 +437,12 @@ public class HwmfWindowing {
         
         @Override
         public void applyObject(HwmfGraphics ctx) {
+            ctx.setClip(normalizeBounds(bounds), HwmfRegionMode.RGN_DIFF, false);
+        }
+
+        @Override
+        public String toString() {
+            return boundsToString(bounds);
         }
     }
 
@@ -468,42 +453,17 @@ public class HwmfWindowing {
      */
     public static class WmfIntersectClipRect implements HwmfRecord, HwmfObjectTableEntry {
 
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-         * lower-right corner of the rectangle.
-         */
-        private int bottom;
-
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
-         * lower-right corner of the rectangle.
-         */
-        private int right;
-
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-         * upper-left corner of the rectangle.
-         */
-        private int top;
-
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
-         * upper-left corner of the rectangle.
-         */
-        private int left;
+        /** a rectangle in logical units */
+        protected final Rectangle2D bounds = new Rectangle2D.Double();
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.intersectClipRect;
         }
 
         @Override
         public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
-            bottom = leis.readShort();
-            right = leis.readShort();
-            top = leis.readShort();
-            left = leis.readShort();
-            return 4*LittleEndianConsts.SHORT_SIZE;
+            return readBounds(leis, bounds);
         }
 
         @Override
@@ -513,6 +473,12 @@ public class HwmfWindowing {
         
         @Override
         public void applyObject(HwmfGraphics ctx) {
+            ctx.setClip(bounds, HwmfRegionMode.RGN_AND, true);
+        }
+
+        @Override
+        public String toString() {
+            return boundsToString(bounds);
         }
     }
 
@@ -528,7 +494,7 @@ public class HwmfWindowing {
         private int region;
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.selectClipRegion;
         }
 
@@ -620,29 +586,7 @@ public class HwmfWindowing {
          */
         private int maxScan;
 
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-         * lower-right corner of the rectangle.
-         */
-        private int bottom;
-
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
-         * lower-right corner of the rectangle.
-         */
-        private int right;
-
-        /**
-         * A 16-bit signed integer that defines the y-coordinate, in logical units, of the
-         * upper-left corner of the rectangle.
-         */
-        private int top;
-
-        /**
-         * A 16-bit signed integer that defines the x-coordinate, in logical units, of the
-         * upper-left corner of the rectangle.
-         */
-        private int left;
+        private Rectangle2D bounds = new Rectangle2D.Double();
 
         /**
          * An array of Scan objects that define the scanlines in the region.
@@ -650,7 +594,7 @@ public class HwmfWindowing {
         private WmfScanObject scanObjects[];
 
         @Override
-        public HwmfRecordType getRecordType() {
+        public HwmfRecordType getWmfRecordType() {
             return HwmfRecordType.createRegion;
         }
 
@@ -662,10 +606,19 @@ public class HwmfWindowing {
             regionSize = leis.readShort();
             scanCount = leis.readShort();
             maxScan = leis.readShort();
-            left = leis.readShort();
-            top = leis.readShort();
-            right = leis.readShort();
-            bottom = leis.readShort();
+            // A 16-bit signed integer that defines the x-coordinate, in logical units, of the
+            // upper-left corner of the rectangle.
+            double left = leis.readShort();
+            // A 16-bit signed integer that defines the y-coordinate, in logical units, of the
+            // upper-left corner of the rectangle.
+            double top = leis.readShort();
+            // A 16-bit signed integer that defines the x-coordinate, in logical units, of the
+            // lower-right corner of the rectangle.
+            double right = leis.readShort();
+            // A 16-bit signed integer that defines the y-coordinate, in logical units, of the
+            // lower-right corner of the rectangle.
+            double bottom = leis.readShort();
+            bounds.setRect(left, top, right-left, bottom-top);
             
             int size = 9*LittleEndianConsts.SHORT_SIZE+LittleEndianConsts.INT_SIZE;
 

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java?rev=1849040&r1=1849039&r2=1849040&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java Sun Dec 16 18:17:21 2018
@@ -43,6 +43,9 @@ import org.apache.poi.util.RecordFormatE
 import org.apache.poi.util.Units;
 
 public class HwmfPicture {
+    /** Max. record length - processing longer records will throw an exception */
+    public static final int MAX_RECORD_LENGTH = 50_000_000;
+
     private static final POILogger logger = POILogFactory.getLogger(HwmfPicture.class);
     
     final List<HwmfRecord> records = new ArrayList<>();
@@ -51,8 +54,7 @@ public class HwmfPicture {
     
     public HwmfPicture(InputStream inputStream) throws IOException {
 
-        try (BufferedInputStream bis = new BufferedInputStream(inputStream, 10000);
-             LittleEndianInputStream leis = new LittleEndianInputStream(bis)) {
+        try (LittleEndianInputStream leis = new LittleEndianInputStream(inputStream)) {
             placeableHeader = HwmfPlaceableHeader.readHeader(leis);
             header = new HwmfHeader(leis);
 
@@ -82,17 +84,12 @@ public class HwmfPicture {
                 if (wrt == HwmfRecordType.eof) {
                     break;
                 }
-                if (wrt.clazz == null) {
+                if (wrt.constructor == null) {
                     throw new IOException("unsupported record type: "+recordFunction);
                 }
 
-                HwmfRecord wr;
-                try {
-                    wr = wrt.clazz.newInstance();
-                    records.add(wr);
-                } catch (Exception e) {
-                    throw (IOException)new IOException("can't create wmf record").initCause(e);
-                }
+                final HwmfRecord wr = wrt.constructor.get();
+                records.add(wr);
 
                 consumedSize += wr.init(leis, recordSize, recordFunction);
                 int remainingSize = (int)(recordSize - consumedSize);
@@ -162,7 +159,7 @@ public class HwmfPicture {
             if (wOrg == null || wExt == null) {
                 throw new RuntimeException("invalid wmf file - window records are incomplete.");
             }
-            return new Rectangle2D.Double(wOrg.getX(), wOrg.getY(), wExt.getWidth(), wExt.getHeight());
+            return new Rectangle2D.Double(wOrg.getX(), wOrg.getY(), wExt.getSize().getWidth(), wExt.getSize().getHeight());
         }        
     }
     

Modified: poi/trunk/src/scratchpad/testcases/org/apache/poi/hemf/hemfplus/extractor/HemfPlusExtractorTest.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hemf/hemfplus/extractor/HemfPlusExtractorTest.java?rev=1849040&r1=1849039&r2=1849040&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hemf/hemfplus/extractor/HemfPlusExtractorTest.java (original)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hemf/hemfplus/extractor/HemfPlusExtractorTest.java Sun Dec 16 18:17:21 2018
@@ -25,13 +25,13 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.poi.POIDataSamples;
-import org.apache.poi.hemf.extractor.HemfExtractor;
-import org.apache.poi.hemf.hemfplus.record.HemfPlusHeader;
-import org.apache.poi.hemf.hemfplus.record.HemfPlusRecord;
-import org.apache.poi.hemf.hemfplus.record.HemfPlusRecordType;
-import org.apache.poi.hemf.record.HemfCommentEMFPlus;
-import org.apache.poi.hemf.record.HemfCommentRecord;
-import org.apache.poi.hemf.record.HemfRecord;
+import org.apache.poi.hemf.record.emf.HemfComment.EmfComment;
+import org.apache.poi.hemf.record.emf.HemfComment.EmfCommentDataPlus;
+import org.apache.poi.hemf.record.emf.HemfRecord;
+import org.apache.poi.hemf.record.emfplus.HemfPlusHeader;
+import org.apache.poi.hemf.record.emfplus.HemfPlusRecord;
+import org.apache.poi.hemf.record.emfplus.HemfPlusRecordType;
+import org.apache.poi.hemf.usermodel.HemfPicture;
 import org.junit.Test;
 
 public class HemfPlusExtractorTest {
@@ -39,10 +39,10 @@ public class HemfPlusExtractorTest {
     @Test
     public void testBasic() throws Exception {
         //test header
-        HemfCommentEMFPlus emfPlus = getCommentRecord("SimpleEMF_windows.emf", 0);
+        EmfCommentDataPlus emfPlus = getCommentRecord("SimpleEMF_windows.emf", 0);
         List<HemfPlusRecord> records = emfPlus.getRecords();
         assertEquals(1, records.size());
-        assertEquals(HemfPlusRecordType.header, records.get(0).getRecordType());
+        assertEquals(HemfPlusRecordType.header, records.get(0).getEmfPlusRecordType());
 
         HemfPlusHeader header = (HemfPlusHeader)records.get(0);
         assertEquals(240, header.getLogicalDpiX());
@@ -67,29 +67,25 @@ public class HemfPlusExtractorTest {
         assertEquals(expected.size(), records.size());
 
         for (int i = 0; i < expected.size(); i++) {
-            assertEquals(expected.get(i), records.get(i).getRecordType());
+            assertEquals(expected.get(i), records.get(i).getEmfPlusRecordType());
         }
     }
 
 
-    private HemfCommentEMFPlus getCommentRecord(String testFileName, int recordIndex) throws Exception {
-        InputStream is = null;
-        HemfCommentEMFPlus returnRecord = null;
-
-        try {
-            is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream(testFileName);
-            HemfExtractor ex = new HemfExtractor(is);
+    private EmfCommentDataPlus getCommentRecord(String testFileName, int recordIndex) throws Exception {
+        EmfCommentDataPlus returnRecord = null;
+
+        try (InputStream is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream(testFileName)) {
+            HemfPicture ex = new HemfPicture(is);
             int i = 0;
             for (HemfRecord record : ex) {
                 if (i == recordIndex) {
-                    HemfCommentRecord commentRecord = ((HemfCommentRecord) record);
-                    returnRecord = (HemfCommentEMFPlus) commentRecord.getComment();
+                    EmfComment commentRecord = ((EmfComment) record);
+                    returnRecord = (EmfCommentDataPlus) commentRecord.getCommentData();
                     break;
                 }
                 i++;
             }
-        } finally {
-            is.close();
         }
         return returnRecord;
     }

Modified: poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java?rev=1849040&r1=1849039&r2=1849040&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java (original)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java Sun Dec 16 18:17:21 2018
@@ -210,7 +210,6 @@ public final class TestPicture {
                 } else {
                     BufferedImage img = new BufferedImage(pg.width, pg.height, BufferedImage.TYPE_INT_ARGB);
                     Graphics2D graphics = img.createGraphics();
-                    DrawFactory.getInstance(graphics).fixFonts(graphics);
                     slide.draw(graphics);
                     graphics.setColor(Color.BLACK);
                     graphics.setStroke(new BasicStroke(1));

Modified: poi/trunk/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java?rev=1849040&r1=1849039&r2=1849040&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java (original)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java Sun Dec 16 18:17:21 2018
@@ -222,11 +222,11 @@ public class TestHwmfParsing {
         //this happens to work on this test file, but you need to
         //do what Graphics does by maintaining the stack, etc.!
         for (HwmfRecord r : wmf.getRecords()) {
-            if (r.getRecordType().equals(HwmfRecordType.createFontIndirect)) {
+            if (r.getWmfRecordType().equals(HwmfRecordType.createFontIndirect)) {
                 HwmfFont font = ((HwmfText.WmfCreateFontIndirect)r).getFont();
                 charset = (font.getCharset().getCharset() == null) ? LocaleUtil.CHARSET_1252 : font.getCharset().getCharset();
             }
-            if (r.getRecordType().equals(HwmfRecordType.extTextOut)) {
+            if (r.getWmfRecordType().equals(HwmfRecordType.extTextOut)) {
                 HwmfText.WmfExtTextOut textOut = (HwmfText.WmfExtTextOut)r;
                 sb.append(textOut.getText(charset)).append("\n");
             }
@@ -250,11 +250,11 @@ public class TestHwmfParsing {
         //this happens to work on this test file, but you need to
         //do what Graphics does by maintaining the stack, etc.!
         for (HwmfRecord r : wmf.getRecords()) {
-            if (r.getRecordType().equals(HwmfRecordType.createFontIndirect)) {
+            if (r.getWmfRecordType().equals(HwmfRecordType.createFontIndirect)) {
                 HwmfFont font = ((HwmfText.WmfCreateFontIndirect)r).getFont();
                 charset = (font.getCharset().getCharset() == null) ? LocaleUtil.CHARSET_1252 : font.getCharset().getCharset();
             }
-            if (r.getRecordType().equals(HwmfRecordType.extTextOut)) {
+            if (r.getWmfRecordType().equals(HwmfRecordType.extTextOut)) {
                 HwmfText.WmfExtTextOut textOut = (HwmfText.WmfExtTextOut)r;
                 sb.append(textOut.getText(charset)).append("\n");
             }



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


Mime
View raw message