You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2019/09/11 21:24:08 UTC

svn commit: r1866808 [3/7] - in /poi: site/src/documentation/content/xdocs/ trunk/src/java/org/apache/poi/common/usermodel/ trunk/src/java/org/apache/poi/common/usermodel/fonts/ trunk/src/java/org/apache/poi/ddf/ trunk/src/java/org/apache/poi/hssf/user...

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFont.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFont.java?rev=1866808&r1=1866807&r2=1866808&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFont.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFont.java Wed Sep 11 21:24:06 2019
@@ -19,10 +19,17 @@ package org.apache.poi.hemf.record.emf;
 
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.function.Supplier;
 
-import org.apache.poi.util.IOUtils;
+import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.common.usermodel.fonts.FontCharset;
 import org.apache.poi.hwmf.record.HwmfFont;
+import org.apache.poi.util.GenericRecordJsonWriter;
+import org.apache.poi.util.GenericRecordUtil;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 
@@ -41,7 +48,7 @@ public class HemfFont extends HwmfFont {
         }
     }
 
-    protected static class LogFontPanose implements LogFontDetails {
+    protected static class LogFontPanose implements LogFontDetails, GenericRecord {
         enum FamilyType {
             PAN_ANY,
             PAN_NO_FIT,
@@ -201,21 +208,26 @@ public class HemfFont extends HwmfFont {
 
         @Override
         public String toString() {
-            return
-                "{ styleSize: " + styleSize +
-                ", vendorId: " + vendorId +
-                ", culture: " +  culture +
-                ", familyType: '" + familyType + "'" +
-                ", serifStyle: '" + serifStyle + "'" +
-                ", weight: '" + weight + "'" +
-                ", proportion: '" + proportion + "'" +
-                ", contrast: '" + contrast + "'" +
-                ", strokeVariation: '" + strokeVariation + "'" +
-                ", armStyle: '" + armStyle + "'" +
-                ", letterform: '" + letterform + "'" +
-                ", midLine: '" + midLine + "'" +
-                ", xHeight: '" + xHeight + "'" +
-                "}";
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            final Map<String,Supplier<?>> m = new LinkedHashMap<>();
+            m.put("styleSize", () -> styleSize);
+            m.put("vendorId", () -> vendorId);
+            m.put("culture", () -> culture);
+            m.put("familyType", () -> familyType);
+            m.put("serifStyle", () -> serifStyle);
+            m.put("weight", () -> weight);
+            m.put("proportion", () -> proportion);
+            m.put("contrast", () -> contrast);
+            m.put("strokeVariation", () -> strokeVariation);
+            m.put("armStyle", () -> armStyle);
+            m.put("letterform", () -> letterform);
+            m.put("midLine", () -> midLine);
+            m.put("xHeight", () -> xHeight);
+            return Collections.unmodifiableMap(m);
         }
     }
 
@@ -466,12 +478,18 @@ public class HemfFont extends HwmfFont {
 
     @Override
     public String toString() {
-        return
-            "{ fullname: '" + (fullname == null ? "" : fullname) + "'" +
-            ", style: '" + (style == null ? "" : style) + "'" +
-            ", script: '" + (script == null ? "" : script) + "'" +
-            ", details: " + details +
-            "," + super.toString().substring(1);
+        return GenericRecordJsonWriter.marshal(this);
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "base", super::getGenericProperties,
+            "fullname", () -> fullname,
+            "style", () -> style,
+            "script", () -> script,
+            "details", () -> details
+        );
     }
 
     @Override

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfHeader.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfHeader.java?rev=1866808&r1=1866807&r2=1866808&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfHeader.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfHeader.java Wed Sep 11 21:24:06 2019
@@ -20,15 +20,18 @@ package org.apache.poi.hemf.record.emf;
 import static org.apache.poi.hemf.record.emf.HemfDraw.readDimensionInt;
 import static org.apache.poi.hemf.record.emf.HemfDraw.readRectL;
 import static org.apache.poi.hemf.record.emf.HemfRecordIterator.HEADER_SIZE;
-import static org.apache.poi.hwmf.record.HwmfDraw.boundsToString;
-import static org.apache.poi.hwmf.record.HwmfDraw.dimToString;
 
 import java.awt.geom.Dimension2D;
 import java.awt.geom.Rectangle2D;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.function.Supplier;
 
 import org.apache.poi.util.Dimension2DDouble;
+import org.apache.poi.util.GenericRecordJsonWriter;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
@@ -82,7 +85,7 @@ public class HemfHeader implements HemfR
 
     public String getDescription() { return description; }
 
-    public long getnPalEntries() {
+    public long getNPalEntries() {
         return nPalEntries;
     }
 
@@ -120,23 +123,7 @@ public class HemfHeader implements HemfR
 
     @Override
     public String toString() {
-        return "HemfHeader{" +
-                "boundsRectangle: " + boundsToString(boundsRectangle) +
-                ", frameRectangle: " + boundsToString(frameRectangle) +
-                ", bytes: " + bytes +
-                ", records: " + records +
-                ", handles: " + handles +
-                ", description: '" + (description == null ? "" : description) + "'" +
-                ", nPalEntries: " + nPalEntries +
-                ", hasExtension1: " + hasExtension1 +
-                ", cbPixelFormat: " + cbPixelFormat +
-                ", offPixelFormat: " + offPixelFormat +
-                ", bOpenGL: " + bOpenGL +
-                ", hasExtension2: " + hasExtension2 +
-                ", deviceDimension: " + dimToString(deviceDimension) +
-                ", microDimension: " + dimToString(microDimension) +
-                ", milliDimension: " + dimToString(milliDimension) +
-                '}';
+        return GenericRecordJsonWriter.marshal(this);
     }
 
     @Override
@@ -204,4 +191,25 @@ public class HemfHeader implements HemfR
 
         return size;
     }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        final Map<String,Supplier<?>> m = new LinkedHashMap<>();
+        m.put("boundsRectangle", this::getBoundsRectangle);
+        m.put("frameRectangle", this::getFrameRectangle);
+        m.put("bytes", this::getBytes);
+        m.put("records", this::getRecords);
+        m.put("handles", this::getHandles);
+        m.put("description", this::getDescription);
+        m.put("nPalEntries", this::getNPalEntries);
+        m.put("hasExtension1", this::isHasExtension1);
+        m.put("cbPixelFormat", this::getCbPixelFormat);
+        m.put("offPixelFormat", this::getOffPixelFormat);
+        m.put("bOpenGL", this::getbOpenGL);
+        m.put("hasExtension2", this::isHasExtension2);
+        m.put("deviceDimension", this::getDeviceDimension);
+        m.put("milliDimension", this::getMilliDimension);
+        m.put("microDimension", this::getMicroDimension);
+        return Collections.unmodifiableMap(m);
+    }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java?rev=1866808&r1=1866807&r2=1866808&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java Wed Sep 11 21:24:06 2019
@@ -18,7 +18,6 @@
 package org.apache.poi.hemf.record.emf;
 
 import static org.apache.poi.hemf.record.emf.HemfDraw.readPointL;
-import static org.apache.poi.hemf.record.emf.HemfDraw.xformToString;
 import static org.apache.poi.hemf.record.emf.HemfFill.readBitmap;
 import static org.apache.poi.hemf.record.emf.HemfFill.readXForm;
 import static org.apache.poi.hemf.record.emf.HemfRecordIterator.HEADER_SIZE;
@@ -28,9 +27,10 @@ import java.awt.geom.Point2D;
 import java.awt.image.BufferedImage;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 import java.util.function.Function;
+import java.util.function.Supplier;
 
 import org.apache.poi.hemf.draw.HemfDrawProperties;
 import org.apache.poi.hemf.draw.HemfGraphics;
@@ -49,9 +49,12 @@ import org.apache.poi.hwmf.record.HwmfOb
 import org.apache.poi.hwmf.record.HwmfPalette.PaletteEntry;
 import org.apache.poi.hwmf.record.HwmfPenStyle;
 import org.apache.poi.hwmf.record.HwmfPenStyle.HwmfLineDash;
+import org.apache.poi.util.GenericRecordJsonWriter;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 
+@SuppressWarnings("WeakerAccess")
 public class HemfMisc {
 
     public enum HemfModifyWorldTransformMode {
@@ -138,12 +141,21 @@ public class HemfMisc {
 
             return size;
         }
+
+        public List<PaletteEntry> getPalette() {
+            return palette;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties("palette", this::getPalette);
+        }
     }
 
     /**
      * The EMF_SAVEDC record saves the playback device context for later retrieval.
      */
-    public static class EmfSaveDc extends HwmfMisc.WmfSaveDc implements HemfRecord {
+    public static class EmfSaveDc extends HwmfMisc.WmfSaveDc implements HemfRecordWithoutProperties {
         @Override
         public HemfRecordType getEmfRecordType() {
             return HemfRecordType.saveDc;
@@ -153,6 +165,11 @@ public class HemfMisc {
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
             return 0;
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -174,6 +191,11 @@ public class HemfMisc {
             nSavedDC = leis.readInt();
             return LittleEndianConsts.INT_SIZE;
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -191,6 +213,11 @@ public class HemfMisc {
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
             return colorRef.init(leis);
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
 
@@ -213,6 +240,11 @@ public class HemfMisc {
             bkMode = HwmfBkMode.valueOf((int) leis.readUInt());
             return LittleEndianConsts.INT_SIZE;
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -228,6 +260,11 @@ public class HemfMisc {
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
             return super.init(leis, recordSize, (int) recordId);
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -246,6 +283,11 @@ public class HemfMisc {
             mapMode = HwmfMapMode.valueOf((int) leis.readUInt());
             return LittleEndianConsts.INT_SIZE;
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -264,6 +306,11 @@ public class HemfMisc {
             drawMode = HwmfBinaryRasterOp.valueOf((int) leis.readUInt());
             return LittleEndianConsts.INT_SIZE;
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
 
@@ -284,6 +331,11 @@ public class HemfMisc {
             stretchBltMode = StretchBltMode.valueOf((int) leis.readUInt());
             return LittleEndianConsts.INT_SIZE;
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -317,14 +369,26 @@ public class HemfMisc {
             ctx.addObjectTableEntry(this, brushIdx);
         }
 
+        public int getBrushIdx() {
+            return brushIdx;
+        }
 
         @Override
         public String toString() {
-            return
-                "{ brushIndex: "+brushIdx+
-                ", brushStyle: '"+brushStyle+"'"+
-                ", colorRef: "+colorRef+
-                ", brushHatch: '"+brushHatch+"' }";
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "base", super::getGenericProperties,
+                "brushIdx", this::getBrushIdx
+            );
+        }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
         }
     }
 
@@ -379,6 +443,22 @@ public class HemfMisc {
             ctx.addObjectTableEntry(this, brushIdx);
         }
 
+        public int getBrushIdx() {
+            return brushIdx;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "base", super::getGenericProperties,
+                "brushIdx", this::getBrushIdx
+            );
+        }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -397,6 +477,11 @@ public class HemfMisc {
             objectIndex = (int) leis.readUInt();
             return LittleEndianConsts.INT_SIZE;
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -439,7 +524,24 @@ public class HemfMisc {
 
         @Override
         public String toString() {
-            return super.toString().replaceFirst("\\{", "{ penIndex: "+penIndex+", ");
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        public int getPenIndex() {
+            return penIndex;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "base", super::getGenericProperties,
+                "penIndex", this::getPenIndex
+            );
+        }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
         }
     }
 
@@ -539,12 +641,34 @@ public class HemfMisc {
 
         @Override
         public String toString() {
-            // TODO: add style entries + bmp
-            return
-                "{ brushStyle: '"+brushStyle+"'"+
-                ", hatchStyle: '"+hatchStyle+"'"+
-                ", dashPattern: "+ Arrays.toString(penStyle.getLineDashes())+
-                ", "+super.toString().substring(1);
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        public HwmfBrushStyle getBrushStyle() {
+            return brushStyle;
+        }
+
+        public HwmfHatchStyle getHatchStyle() {
+            return hatchStyle;
+        }
+
+        public HwmfBitmapDib getBitmap() {
+            return bitmap;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "base", super::getGenericProperties,
+                "brushStyle", this::getBrushStyle,
+                "hatchStyle", this::getHatchStyle,
+                "bitmap", this::getBitmap
+            );
+        }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
         }
     }
 
@@ -573,7 +697,16 @@ public class HemfMisc {
 
         @Override
         public String toString() {
-            return "{ miterLimit: "+miterLimit+" }";
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        public int getMiterLimit() {
+            return miterLimit;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties("miterLimit", this::getMiterLimit);
         }
     }
 
@@ -593,7 +726,16 @@ public class HemfMisc {
 
         @Override
         public String toString() {
-            return "{ x: "+origin.getX()+", y: "+origin.getY()+" }";
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        public Point2D getOrigin() {
+            return origin;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties("origin", this::getOrigin);
         }
     }
 
@@ -620,7 +762,16 @@ public class HemfMisc {
 
         @Override
         public String toString() {
-            return "{ xForm: " + xformToString(xForm)+" }";
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        public AffineTransform getXForm() {
+            return xForm;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties("xForm", this::getXForm);
         }
     }
 
@@ -687,9 +838,23 @@ public class HemfMisc {
 
         @Override
         public String toString() {
-            return
-                "{ xForm: " + xformToString(xForm) +
-                ", modifyWorldTransformMode: '"+modifyWorldTransformMode+"' }";
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        public AffineTransform getXForm() {
+            return xForm;
+        }
+
+        public HemfModifyWorldTransformMode getModifyWorldTransformMode() {
+            return modifyWorldTransformMode;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "xForm", this::getXForm,
+                "modifyWorldTransformMode", this::getModifyWorldTransformMode
+            );
         }
     }
 
@@ -760,11 +925,28 @@ public class HemfMisc {
 
         @Override
         public String toString() {
-            return
-                "{ penIndex: " + penIndex +
-                ", colorUsage: " + colorUsage +
-                ", bitmap: " + bitmap +
-                "}";
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        public int getPenIndex() {
+            return penIndex;
+        }
+
+        public HwmfFill.ColorUsage getColorUsage() {
+            return colorUsage;
+        }
+
+        public HwmfBitmapDib getBitmap() {
+            return bitmap;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "penIndex", this::getPenIndex,
+                "colorUsage", this::getColorUsage,
+                "bitmap", this::getBitmap
+            );
         }
     }
 

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfPalette.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfPalette.java?rev=1866808&r1=1866807&r2=1866808&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfPalette.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfPalette.java Wed Sep 11 21:24:06 2019
@@ -18,12 +18,16 @@
 package org.apache.poi.hemf.record.emf;
 
 import java.io.IOException;
+import java.util.Map;
+import java.util.function.Supplier;
 
 import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.hwmf.record.HwmfPalette;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 
+@SuppressWarnings("WeakerAccess")
 public class HemfPalette {
     /** The EMR_SELECTPALETTE record specifies a logical palette for the playback device context. */
     public static class EmfSelectPalette extends HwmfPalette.WmfSelectPalette implements HemfRecord {
@@ -42,6 +46,11 @@ public class HemfPalette {
             paletteIndex = (int)leis.readUInt();
             return LittleEndianConsts.INT_SIZE;
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /** The EMR_CREATEPALETTE record defines a logical palette for graphics operations. */
@@ -73,6 +82,23 @@ public class HemfPalette {
         public void draw(HemfGraphics ctx) {
             ctx.addObjectTableEntry(this, paletteIndex);
         }
+
+        public int getPaletteIndex() {
+            return paletteIndex;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "base", super::getGenericProperties,
+                "paletteIndex", this::getPaletteIndex
+            );
+        }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -104,6 +130,23 @@ public class HemfPalette {
         public void draw(HemfGraphics ctx) {
             ctx.addObjectTableEntry(this, paletteIndex);
         }
+
+        public int getPaletteIndex() {
+            return paletteIndex;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "base", super::getGenericProperties,
+                "paletteIndex", this::getPaletteIndex
+            );
+        }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -134,6 +177,23 @@ public class HemfPalette {
         public void draw(HemfGraphics ctx) {
             ctx.addObjectTableEntry(this, paletteIndex);
         }
+
+        public int getPaletteIndex() {
+            return paletteIndex;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "base", super::getGenericProperties,
+                "paletteIndex", this::getPaletteIndex
+            );
+        }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -150,6 +210,11 @@ public class HemfPalette {
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
             return 0;
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -205,5 +270,14 @@ public class HemfPalette {
             icmMode = ICMMode.valueOf(leis.readInt());
             return LittleEndianConsts.INT_SIZE;
         }
+
+        public ICMMode getIcmMode() {
+            return icmMode;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties("icmMode", this::getIcmMode);
+        }
     }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecord.java?rev=1866808&r1=1866807&r2=1866808&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecord.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecord.java Wed Sep 11 21:24:06 2019
@@ -19,14 +19,17 @@ package org.apache.poi.hemf.record.emf;
 
 
 import java.io.IOException;
+import java.util.Map;
+import java.util.function.Supplier;
 
+import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.hwmf.record.HwmfRecord;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndianInputStream;
 
 @Internal
-public interface HemfRecord {
+public interface HemfRecord extends GenericRecord {
 
     HemfRecordType getEmfRecordType();
 
@@ -58,4 +61,16 @@ public interface HemfRecord {
      * @param header the emf header
      */
     default void setHeader(HemfHeader header) {}
+
+    @Override
+    default Enum getGenericRecordType() {
+        return getEmfRecordType();
+    }
+}
+
+interface HemfRecordWithoutProperties extends HemfRecord {
+    default Map<String, Supplier<?>> getGenericProperties() {
+        return null;
+    }
+
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java?rev=1866808&r1=1866807&r2=1866808&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java Wed Sep 11 21:24:06 2019
@@ -27,12 +27,16 @@ import java.awt.geom.Dimension2D;
 import java.awt.geom.Rectangle2D;
 import java.io.IOException;
 import java.nio.charset.Charset;
+import java.util.Map;
+import java.util.function.Supplier;
 
 import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.hwmf.draw.HwmfGraphics;
 import org.apache.poi.hwmf.record.HwmfText;
 import org.apache.poi.hwmf.record.HwmfText.WmfSetTextAlign;
 import org.apache.poi.util.Dimension2DDouble;
+import org.apache.poi.util.GenericRecordJsonWriter;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndianConsts;
@@ -45,6 +49,7 @@ import org.apache.poi.util.RecordFormatE
  * implemented at this point!
  */
 @Internal
+@SuppressWarnings("WeakerAccess")
 public class HemfText {
 
     private static final int MAX_RECORD_LENGTH = 1_000_000;
@@ -181,7 +186,7 @@ public class HemfText {
          *
          * @param charset the charset to be used to decode the character bytes
          * @return text from this text element
-         * @throws IOException
+         * @throws IOException if the charset is not compatible to the underlying bytes
          */
         public String getText(Charset charset) throws IOException {
             return super.getText(charset);
@@ -206,10 +211,21 @@ public class HemfText {
 
         @Override
         public String toString() {
-            return
-                "{ graphicsMode: '"+graphicsMode+"'"+
-                ", scale: { w: "+scale.getWidth()+", h: "+scale.getHeight()+" },"+
-                super.toString().substring(1);
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "base", super::getGenericProperties,
+                "boundsIgnored", () -> boundsIgnored,
+                "graphicsMode", this::getGraphicsMode
+            );
+        }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
         }
     }
 
@@ -240,15 +256,18 @@ public class HemfText {
 
         @Override
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
-            /**
-             * A 32-bit unsigned integer that specifies text alignment by using a mask of text alignment flags.
-             * These are either WMF TextAlignmentMode Flags for text with a horizontal baseline,
-             * or WMF VerticalTextAlignmentMode Flags for text with a vertical baseline.
-             * Only one value can be chosen from those that affect horizontal and vertical alignment.
-             */
+            // A 32-bit unsigned integer that specifies text alignment by using a mask of text alignment flags.
+            // These are either WMF TextAlignmentMode Flags for text with a horizontal baseline,
+            // or WMF VerticalTextAlignmentMode Flags for text with a vertical baseline.
+            // Only one value can be chosen from those that affect horizontal and vertical alignment.
             textAlignmentMode = (int)leis.readUInt();
             return LittleEndianConsts.INT_SIZE;
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -264,6 +283,11 @@ public class HemfText {
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
             return colorRef.init(leis);
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
 
@@ -297,7 +321,24 @@ public class HemfText {
 
         @Override
         public String toString() {
-            return "{ index: "+fontIdx+", font: "+font+" } ";
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        public int getFontIdx() {
+            return fontIdx;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "base", super::getGenericProperties,
+                "fontIdx", this::getFontIdx
+            );
+        }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
         }
     }
 
@@ -306,7 +347,7 @@ public class HemfText {
         public int init(LittleEndianInputStream leis) {
             // A 32-bit unsigned integer that specifies how to use the rectangle specified in the Rectangle field.
             // This field can be a combination of more than one ExtTextOutOptions enumeration
-            flag = (int)leis.readUInt();
+            flags = (int)leis.readUInt();
             return LittleEndianConsts.INT_SIZE;
         }
     }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfWindowing.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfWindowing.java?rev=1866808&r1=1866807&r2=1866808&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfWindowing.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfWindowing.java Wed Sep 11 21:24:06 2019
@@ -21,15 +21,21 @@ import static org.apache.poi.hemf.record
 import static org.apache.poi.hemf.record.emf.HemfDraw.readPointL;
 import static org.apache.poi.hwmf.record.HwmfDraw.normalizeBounds;
 
+import java.awt.geom.Dimension2D;
 import java.io.IOException;
+import java.util.Map;
+import java.util.function.Supplier;
 
 import org.apache.poi.hemf.draw.HemfDrawProperties;
 import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.hwmf.record.HwmfRegionMode;
 import org.apache.poi.hwmf.record.HwmfWindowing;
+import org.apache.poi.util.GenericRecordJsonWriter;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 
+@SuppressWarnings("WeakerAccess")
 public class HemfWindowing {
 
     /**
@@ -45,6 +51,11 @@ public class HemfWindowing {
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
             return readDimensionInt(leis, size);
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -60,6 +71,11 @@ public class HemfWindowing {
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
             return readPointL(leis, origin);
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -75,6 +91,11 @@ public class HemfWindowing {
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
             return readDimensionInt(leis, extents);
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -90,6 +111,11 @@ public class HemfWindowing {
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
             return readPointL(leis, origin);
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -106,6 +132,11 @@ public class HemfWindowing {
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
             return readPointL(leis, offset);
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -122,6 +153,11 @@ public class HemfWindowing {
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
             return HemfDraw.readRectL(leis, bounds);
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -138,6 +174,11 @@ public class HemfWindowing {
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
             return HemfDraw.readRectL(leis, normalizeBounds(bounds));
         }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
+        }
     }
 
     /**
@@ -152,12 +193,12 @@ public class HemfWindowing {
 
         @Override
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
-            double xNum = leis.readInt();
-            double xDenom = leis.readInt();
-            double yNum = leis.readInt();
-            double yDenom = leis.readInt();
-            scale.setSize(xNum / xDenom, yNum / yDenom);
-            return 4*LittleEndianConsts.INT_SIZE;
+            return readScale(leis, scale);
+        }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
         }
     }
 
@@ -173,14 +214,12 @@ public class HemfWindowing {
 
         @Override
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
-            double xNum = leis.readInt();
-            double xDenom = leis.readInt();
-            double yNum = leis.readInt();
-            double yDenom = leis.readInt();
-
-            scale.setSize(xNum / xDenom, yNum / yDenom);
+            return readScale(leis, scale);
+        }
 
-            return 4*LittleEndianConsts.INT_SIZE;
+        @Override
+        public Enum getGenericRecordType() {
+            return getEmfRecordType();
         }
     }
 
@@ -213,8 +252,25 @@ public class HemfWindowing {
 
         @Override
         public String toString() {
-            return "{ regionMode: '"+regionMode+"' }";
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        public HwmfRegionMode getRegionMode() {
+            return regionMode;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties("regionMode", this::getRegionMode);
         }
     }
 
+    private static int readScale(LittleEndianInputStream leis, Dimension2D scale) {
+        double xNum = leis.readInt();
+        double xDenom = leis.readInt();
+        double yNum = leis.readInt();
+        double yDenom = leis.readInt();
+        scale.setSize(xNum / xDenom, yNum / yDenom);
+        return 4*LittleEndianConsts.INT_SIZE;
+    }
 }
\ No newline at end of file

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/UnimplementedHemfRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/UnimplementedHemfRecord.java?rev=1866808&r1=1866807&r2=1866808&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/UnimplementedHemfRecord.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emf/UnimplementedHemfRecord.java Wed Sep 11 21:24:06 2019
@@ -25,7 +25,7 @@ import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndianInputStream;
 
 @Internal
-public class UnimplementedHemfRecord implements HemfRecord {
+public class UnimplementedHemfRecord implements HemfRecordWithoutProperties {
 
     private HemfRecordType recordType;
 

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusBrush.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusBrush.java?rev=1866808&r1=1866807&r2=1866808&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusBrush.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusBrush.java Wed Sep 11 21:24:06 2019
@@ -17,26 +17,24 @@
 
 package org.apache.poi.hemf.record.emfplus;
 
-import static java.util.stream.Collectors.joining;
-import static org.apache.poi.hemf.record.emf.HemfDraw.xformToString;
 import static org.apache.poi.hemf.record.emf.HemfFill.readXForm;
 import static org.apache.poi.hemf.record.emfplus.HemfPlusDraw.readARGB;
 import static org.apache.poi.hemf.record.emfplus.HemfPlusDraw.readPointF;
 import static org.apache.poi.hemf.record.emfplus.HemfPlusDraw.readRectF;
-import static org.apache.poi.hwmf.record.HwmfDraw.boundsToString;
-import static org.apache.poi.hwmf.record.HwmfDraw.pointToString;
 
 import java.awt.Color;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
 import java.io.IOException;
-import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
-import java.util.stream.Stream;
 
+import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.hemf.draw.HemfDrawProperties;
 import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.hemf.record.emfplus.HemfPlusHeader.EmfPlusGraphicsVersion;
@@ -47,10 +45,10 @@ import org.apache.poi.hemf.record.emfplu
 import org.apache.poi.hemf.record.emfplus.HemfPlusPath.EmfPlusPath;
 import org.apache.poi.hwmf.record.HwmfBrushStyle;
 import org.apache.poi.hwmf.record.HwmfColorRef;
-import org.apache.poi.hwmf.record.HwmfDraw;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
-import org.apache.poi.util.Internal;
+import org.apache.poi.util.GenericRecordJsonWriter;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 
@@ -243,7 +241,7 @@ public class HemfPlusBrush {
 
     }
 
-    public interface EmfPlusBrushData {
+    public interface EmfPlusBrushData extends GenericRecord {
         /**
          * This flag is meaningful in EmfPlusPathGradientBrushData objects.
          *
@@ -343,9 +341,24 @@ public class HemfPlusBrush {
 
         @Override
         public String toString() {
-            return
-                "{ brushType: '"+brushType+"'" +
-                ", brushData: "+brushData+" }";
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        public EmfPlusBrushData getBrushData() {
+            return brushData;
+        }
+
+        @Override
+        public EmfPlusBrushType getGenericRecordType() {
+            return brushType;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "graphicsVersion", this::getGraphicsVersion,
+                "brushData", this::getBrushData
+            );
         }
     }
 
@@ -366,7 +379,17 @@ public class HemfPlusBrush {
 
         @Override
         public String toString() {
-            return "{ solidColor: "+new HwmfColorRef(solidColor)+" }";
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return EmfPlusBrushType.SOLID_COLOR;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties("solidColor", () -> solidColor);
         }
     }
 
@@ -392,10 +415,21 @@ public class HemfPlusBrush {
 
         @Override
         public String toString() {
-            return
-                "{ style: '"+style+"'" +
-                ", foreColor: "+new HwmfColorRef(foreColor) +
-                ", backColor: "+new HwmfColorRef(backColor) + " }";
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return EmfPlusBrushType.HATCH_FILL;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "style", () -> style,
+                "foreColor", () -> foreColor,
+                "backColor", () -> backColor
+            );
         }
     }
 
@@ -462,23 +496,31 @@ public class HemfPlusBrush {
 
         @Override
         public String toString() {
-            return
-                "{ flags: "+dataFlags+
-                ", wrapMode: '"+wrapMode+"'"+
-                ", rect: "+boundsToString(rect)+
-                ", startColor: "+new HwmfColorRef(startColor)+
-                ", endColor: "+new HwmfColorRef(endColor)+
-                ", transform: "+xformToString(transform)+
-                ", positions: "+ Arrays.toString(positions)+
-                ", blendColors: "+ colorsToString(blendColors)+
-                ", positionsV: "+ Arrays.toString(positionsV)+
-                ", blendFactorsV: "+ Arrays.toString(blendFactorsV)+
-                ", positionsH: "+ Arrays.toString(positionsH)+
-                ", blendFactorsH: "+ Arrays.toString(blendFactorsH)+
-                "}";
+            return GenericRecordJsonWriter.marshal(this);
         }
 
+        @Override
+        public Enum getGenericRecordType() {
+            return EmfPlusBrushType.LINEAR_GRADIENT;
+        }
 
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            final Map<String,Supplier<?>> m = new LinkedHashMap<>();
+            m.put("flags", () -> dataFlags);
+            m.put("wrapMode", () -> wrapMode);
+            m.put("rect", () -> rect);
+            m.put("startColor", () -> startColor);
+            m.put("endColor", () -> endColor);
+            m.put("transform", () -> transform);
+            m.put("positions", () -> positions);
+            m.put("blendColors", () -> blendColors);
+            m.put("positionsV", () -> positionsV);
+            m.put("blendFactorsV", () -> blendFactorsV);
+            m.put("positionsH", () -> positionsH);
+            m.put("blendFactorsH", () -> blendFactorsH);
+            return Collections.unmodifiableMap(m);
+        }
     }
 
     /** The EmfPlusPathGradientBrushData object specifies a path gradient for a graphics brush. */
@@ -593,22 +635,32 @@ public class HemfPlusBrush {
 
         @Override
         public String toString() {
-            return
-                "{ flags: "+dataFlags+
-                ", wrapMode: '"+wrapMode+"'"+
-                ", centerColor: "+new HwmfColorRef(centerColor)+
-                ", centerPoint: "+pointToString(centerPoint)+
-                ", surroundingColor: "+colorsToString(surroundingColor)+
-                ", boundaryPath: "+(boundaryPath == null ? "null" : boundaryPath)+
-                ", boundaryPoints: "+pointsToString(boundaryPoints)+
-                ", transform: "+xformToString(transform)+
-                ", positions: "+Arrays.toString(positions)+
-                ", blendColors: "+colorsToString(blendColors)+
-                ", blendFactorsH: "+Arrays.toString(blendFactorsH)+
-                ", focusScaleX: "+focusScaleX+
-                ", focusScaleY: "+focusScaleY+
-                "}"
-                ;
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+
+        @Override
+        public Enum getGenericRecordType() {
+            return EmfPlusBrushType.PATH_GRADIENT;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            final Map<String,Supplier<?>> m = new LinkedHashMap<>();
+            m.put("flags", () -> dataFlags);
+            m.put("wrapMode", () -> wrapMode);
+            m.put("centerColor", () -> centerColor);
+            m.put("centerPoint", () -> centerPoint);
+            m.put("surroundingColor", () -> surroundingColor);
+            m.put("boundaryPath", () -> boundaryPath);
+            m.put("boundaryPoints", () -> boundaryPoints);
+            m.put("transform", () -> transform);
+            m.put("positions", () -> positions);
+            m.put("blendColors", () -> blendColors);
+            m.put("blendFactorsH", () -> blendFactorsH);
+            m.put("focusScaleX", () -> focusScaleX);
+            m.put("focusScaleY", () -> focusScaleY);
+            return Collections.unmodifiableMap(m);
         }
     }
 
@@ -652,12 +704,22 @@ public class HemfPlusBrush {
 
         @Override
         public String toString() {
-            return
-                "{ flags: "+dataFlags+
-                ", wrapMode: '"+wrapMode+"'"+
-                ", transform: "+xformToString(transform)+
-                ", image: "+image+
-                "]";
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        @Override
+        public Enum getGenericRecordType() {
+            return EmfPlusBrushType.TEXTURE_FILL;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "dataFlags", () -> dataFlags,
+                "wrapMode", () -> wrapMode,
+                "transform", () -> transform,
+                "image", () -> image
+            );
         }
     }
 
@@ -696,18 +758,4 @@ public class HemfPlusBrush {
         facs.accept(factors);
         return size + factors.length * LittleEndianConsts.INT_SIZE;
     }
-
-    @Internal
-    public static String colorsToString(Color[] colors) {
-        return (colors == null ? "null" :
-            Stream.of(colors).map(HwmfColorRef::new).map(Object::toString).
-            collect(joining(",", "{", "}")));
-    }
-
-    @Internal
-    public static String pointsToString(Point2D[] points) {
-        return (points == null ? "null" :
-            Stream.of(points).map(HwmfDraw::pointToString).
-            collect(joining(",", "{", "}")));
-    }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusDraw.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusDraw.java?rev=1866808&r1=1866807&r2=1866808&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusDraw.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusDraw.java Wed Sep 11 21:24:06 2019
@@ -17,10 +17,7 @@
 
 package org.apache.poi.hemf.record.emfplus;
 
-import static java.util.stream.Collectors.joining;
-import static org.apache.poi.hemf.record.emf.HemfDraw.xformToString;
-import static org.apache.poi.hwmf.record.HwmfDraw.boundsToString;
-import static org.apache.poi.hwmf.record.HwmfDraw.pointToString;
+import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
 
 import java.awt.Color;
 import java.awt.geom.AffineTransform;
@@ -32,8 +29,12 @@ import java.awt.image.BufferedImage;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.function.BiFunction;
+import java.util.function.Supplier;
 
 import org.apache.commons.math3.linear.LUDecomposition;
 import org.apache.commons.math3.linear.MatrixUtils;
@@ -46,16 +47,18 @@ import org.apache.poi.hemf.record.emfplu
 import org.apache.poi.hemf.record.emfplus.HemfPlusObject.EmfPlusObject;
 import org.apache.poi.hwmf.record.HwmfBrushStyle;
 import org.apache.poi.hwmf.record.HwmfColorRef;
-import org.apache.poi.hwmf.record.HwmfDraw;
 import org.apache.poi.hwmf.record.HwmfMisc.WmfSetBkMode.HwmfBkMode;
 import org.apache.poi.hwmf.record.HwmfTernaryRasterOp;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.GenericRecordJsonWriter;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 import org.apache.poi.util.StringUtil;
 
+@SuppressWarnings("WeakerAccess")
 public class HemfPlusDraw {
     private static final int MAX_OBJECT_SIZE = 1_000_000;
 
@@ -185,6 +188,10 @@ public class HemfPlusDraw {
             return flags;
         }
 
+        public int getPenId() {
+            return penId;
+        }
+
         @Override
         public long init(LittleEndianInputStream leis, long dataSize, long recordId, int flags) throws IOException {
             this.flags = flags;
@@ -213,9 +220,20 @@ public class HemfPlusDraw {
 
         @Override
         public String toString() {
-            return
-                "{ flags: "+flags+
-                ", penId: "+penId+" }";
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        @Override
+        public HemfPlusRecordType getGenericRecordType() {
+            return getEmfPlusRecordType();
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "flags", this::getFlags,
+                "penId", this::getPenId
+            );
         }
     }
 
@@ -278,11 +296,25 @@ public class HemfPlusDraw {
 
         @Override
         public String toString() {
-            return
-                "{ flags: "+flags+
-                ", brushId: "+brushId+
-                ", rectData: "+rectData.stream().map(HwmfDraw::boundsToString).collect(joining(",", "{", "}"))+
-                "}";
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        @Override
+        public HemfPlusRecordType getGenericRecordType() {
+            return getEmfPlusRecordType();
+        }
+
+        public List<Rectangle2D> getRectData() {
+            return rectData;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "flags", this::getFlags,
+                "brushId", this::getBrushId,
+                "rectData", this::getRectData
+            );
         }
     }
 
@@ -428,17 +460,21 @@ public class HemfPlusDraw {
 
         @Override
         public String toString() {
-            return
-                "{ flags: "+flags+
-                ", imageAttributesID: "+imageAttributesID+
-                ", srcUnit: '"+srcUnit+"'"+
-                ", srcRect: "+boundsToString(srcRect)+
-                ", upperLeft: "+pointToString(upperLeft)+
-                ", lowerLeft: "+pointToString(lowerLeft)+
-                ", lowerRight: "+pointToString(lowerRight)+
-                ", transform: "+xformToString(trans)+
-                "}"
-                ;
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            final Map<String,Supplier<?>> m = new LinkedHashMap<>();
+            m.put("flags", this::getFlags);
+            m.put("imageAttributesID", () -> imageAttributesID);
+            m.put("srcUnit", () -> srcUnit);
+            m.put("srcRect", () -> srcRect);
+            m.put("upperLeft", () -> upperLeft);
+            m.put("lowerLeft", () -> lowerLeft);
+            m.put("lowerRight", () -> lowerRight);
+            m.put("transform", () -> trans);
+            return Collections.unmodifiableMap(m);
         }
     }
 
@@ -500,14 +536,18 @@ public class HemfPlusDraw {
 
         @Override
         public String toString() {
-            return
-                "{ flags: "+flags+
-                ", imageAttributesID: "+imageAttributesID+
-                ", srcUnit: '"+srcUnit+"'"+
-                ", srcRect: "+boundsToString(srcRect)+
-                ", rectData: "+boundsToString(rectData)+
-                "}"
-                ;
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "flags", this::getFlags,
+                "imageAttributesID", () -> imageAttributesID,
+                "srcUnit", () -> srcUnit,
+                "srcRect", () -> srcRect,
+                "rectData", () -> rectData
+            );
         }
     }
 
@@ -554,9 +594,15 @@ public class HemfPlusDraw {
 
         @Override
         public String toString() {
-            return
-                "{ flags: "+flags+
-                ", brushId: "+brushId+" }";
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "flags", this::getFlags,
+                "brushId", () -> brushId
+            );
         }
     }
 
@@ -596,7 +642,11 @@ public class HemfPlusDraw {
          */
         private static final BitField LIMIT_SUBPIXEL = BitFieldFactory.getInstance(0x0008);
 
+        private static final int[] OPTIONS_MASK = { 0x0001, 0x0002, 0x0004, 0x0008 };
 
+        private static final String[] OPTIONS_NAMES = {
+            "CMAP_LOOKUP", "VERTICAL", "REALIZED_ADVANCE", "LIMIT_SUBPIXEL"
+        };
 
         private int flags;
         private int brushId;
@@ -671,6 +721,23 @@ public class HemfPlusDraw {
 
             return size;
         }
+
+        @Override
+        public String toString() {
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "flags", this::getFlags,
+                "brushId", this::getBrushId,
+                "optionsFlags", getBitsAsString(() -> optionsFlags, OPTIONS_MASK, OPTIONS_NAMES),
+                "glyphs", () -> glyphs,
+                "glyphPos", () -> glpyhPos,
+                "transform", () -> transformMatrix
+            );
+        }
     }
 
     /** The EmfPlusDrawRects record specifies drawing a series of rectangles. */
@@ -705,6 +772,19 @@ public class HemfPlusDraw {
 
             return size;
         }
+
+        @Override
+        public String toString() {
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "flags", this::getFlags,
+                "rectData", () -> rectData
+            );
+        }
     }
 
 

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusFont.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusFont.java?rev=1866808&r1=1866807&r2=1866808&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusFont.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusFont.java Wed Sep 11 21:24:06 2019
@@ -19,13 +19,18 @@ package org.apache.poi.hemf.record.emfpl
 
 import java.io.IOException;
 import java.util.List;
+import java.util.Map;
+import java.util.function.Supplier;
 
 import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.hemf.record.emfplus.HemfPlusDraw.EmfPlusUnitType;
 import org.apache.poi.hemf.record.emfplus.HemfPlusHeader.EmfPlusGraphicsVersion;
 import org.apache.poi.hemf.record.emfplus.HemfPlusObject.EmfPlusObjectData;
+import org.apache.poi.hemf.record.emfplus.HemfPlusObject.EmfPlusObjectType;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.GenericRecordJsonWriter;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 import org.apache.poi.util.StringUtil;
@@ -69,7 +74,7 @@ public class HemfPlusFont {
         private String family;
 
         @Override
-        public long init(LittleEndianInputStream leis, long dataSize, HemfPlusObject.EmfPlusObjectType objectType, int flags) throws IOException {
+        public long init(LittleEndianInputStream leis, long dataSize, EmfPlusObjectType objectType, int flags) throws IOException {
             // An EmfPlusGraphicsVersion object that specifies the version of operating system graphics that was used
             // to create this object.
             long size = graphicsVersion.init(leis);
@@ -108,5 +113,26 @@ public class HemfPlusFont {
         public EmfPlusGraphicsVersion getGraphicsVersion() {
             return graphicsVersion;
         }
+
+        @Override
+        public String toString() {
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "graphicsVersion", () -> graphicsVersion,
+                "emSize", () -> emSize,
+                "sizeUnit", () -> sizeUnit,
+                "styleFlags", () -> styleFlags,
+                "family", () -> family
+            );
+        }
+
+        @Override
+        public EmfPlusObjectType getGenericRecordType() {
+            return EmfPlusObjectType.FONT;
+        }
     }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusHeader.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusHeader.java?rev=1866808&r1=1866807&r2=1866808&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusHeader.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusHeader.java Wed Sep 11 21:24:06 2019
@@ -18,12 +18,18 @@
 package org.apache.poi.hemf.record.emfplus;
 
 
+import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
+
 import java.io.IOException;
+import java.util.Map;
+import java.util.function.Supplier;
 
 import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.hemf.draw.HemfGraphics.EmfRenderState;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.GenericRecordJsonWriter;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
@@ -53,6 +59,8 @@ public class HemfPlusHeader implements H
         }
     }
 
+    private static final int[] FLAGS_MASK = { 0x0001 };
+    private static final String[] FLAGS_NAMES = { "DUAL_MODE" };
 
     private int flags;
     private final EmfPlusGraphicsVersion version = new EmfPlusGraphicsVersion();
@@ -121,13 +129,18 @@ public class HemfPlusHeader implements H
 
     @Override
     public String toString() {
-        return "HemfPlusHeader{" +
-                "flags=" + flags +
-                ", version=" + version +
-                ", emfPlusFlags=" + emfPlusFlags +
-                ", logicalDpiX=" + logicalDpiX +
-                ", logicalDpiY=" + logicalDpiY +
-                '}';
+        return GenericRecordJsonWriter.marshal(this);
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "flags", this::getFlags,
+            "version", this::getVersion,
+            "emfPlusFlags", getBitsAsString(this::getEmfPlusFlags, FLAGS_MASK, FLAGS_NAMES),
+            "logicalDpiX", this::getLogicalDpiX,
+            "logicalDpiY", this::getLogicalDpiY
+        );
     }
 
     public static class EmfPlusGraphicsVersion {

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusImage.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusImage.java?rev=1866808&r1=1866807&r2=1866808&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusImage.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusImage.java Wed Sep 11 21:24:06 2019
@@ -36,8 +36,12 @@ import java.awt.image.WritableRaster;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.function.BiConsumer;
+import java.util.function.Supplier;
 
 import javax.imageio.ImageIO;
 
@@ -50,6 +54,8 @@ import org.apache.poi.hemf.usermodel.Hem
 import org.apache.poi.hwmf.usermodel.HwmfPicture;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.GenericRecordJsonWriter;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
@@ -280,7 +286,6 @@ public class HemfPlusImage {
     public static class EmfPlusImage implements EmfPlusObjectData {
         private static final int MAX_OBJECT_SIZE = 50_000_000;
 
-
         private final EmfPlusGraphicsVersion graphicsVersion = new EmfPlusGraphicsVersion();
         private EmfPlusImageDataType imageDataType;
         private int bitmapWidth;
@@ -595,9 +600,35 @@ public class HemfPlusImage {
 
             return bufImg;
         }
-    }
 
+        @Override
+        public String toString() {
+            return GenericRecordJsonWriter.marshal(this);
+        }
 
+        @Override
+        public EmfPlusObjectType getGenericRecordType() {
+            return EmfPlusObjectType.IMAGE;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            final Map<String,Supplier<?>> m = new LinkedHashMap<>();
+
+            m.put("graphicsVersion", this::getGraphicsVersion);
+            m.put("imageDataType", this::getImageDataType);
+            m.put("bitmapWidth", this::getBitmapWidth);
+            m.put("bitmapHeight", this::getBitmapHeight);
+            m.put("bitmapStride", this::getBitmapStride);
+            m.put("pixelFormat", this::getPixelFormat);
+            m.put("bitmapType", this::getBitmapType);
+            m.put("imageData", this::getImageData);
+            m.put("metafileType", this::getMetafileType);
+            m.put("metafileDataSize", () -> metafileDataSize);
+
+            return Collections.unmodifiableMap(m);
+        }
+    }
 
     public static class EmfPlusImageAttributes implements EmfPlusObjectData {
         private final EmfPlusGraphicsVersion graphicsVersion = new EmfPlusGraphicsVersion();
@@ -650,6 +681,26 @@ public class HemfPlusImage {
         @Override
         public void applyObject(HemfGraphics ctx, List<? extends EmfPlusObjectData> continuedObjectData) {
         }
+
+        @Override
+        public String toString() {
+            return GenericRecordJsonWriter.marshal(this);
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "graphicsVersion", this::getGraphicsVersion,
+                "wrapMode", this::getWrapMode,
+                "clampColor", this::getClampColor,
+                "objectClamp", this::getObjectClamp
+            );
+        }
+
+        @Override
+        public EmfPlusObjectType getGenericRecordType() {
+            return EmfPlusObjectType.IMAGE_ATTRIBUTES;
+        }
     }
 
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusMisc.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusMisc.java?rev=1866808&r1=1866807&r2=1866808&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusMisc.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusMisc.java Wed Sep 11 21:24:06 2019
@@ -19,19 +19,24 @@ package org.apache.poi.hemf.record.emfpl
 
 import static org.apache.poi.hemf.record.emf.HemfMisc.adaptXForm;
 import static org.apache.poi.hemf.record.emfplus.HemfPlusDraw.readRectF;
+import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
 
 import java.awt.geom.AffineTransform;
 import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
 import java.io.IOException;
+import java.util.Map;
+import java.util.function.Supplier;
 
 import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.hemf.record.emf.HemfFill;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 
+@SuppressWarnings("WeakerAccess")
 public class HemfPlusMisc {
     public interface EmfPlusObjectId {
         BitField OBJECT_ID = BitFieldFactory.getInstance(0x00FF);
@@ -75,6 +80,9 @@ public class HemfPlusMisc {
         private int flags;
         private HemfPlusRecordType recordType;
 
+        private static final int[] FLAGS_MASK = { 0x0F00 };
+        private static final String[] FLAGS_NAMES = { "COMBINE_MODE" };
+
         @Override
         public int getFlags() {
             return flags;
@@ -92,6 +100,18 @@ public class HemfPlusMisc {
             recordType = HemfPlusRecordType.getById(recordId);
             return 0;
         }
+
+        @Override
+        public HemfPlusRecordType getGenericRecordType() {
+            return getEmfPlusRecordType();
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "flags", getBitsAsString(this::getFlags,FLAGS_MASK,FLAGS_NAMES)
+            );
+        }
     }
 
     public static class EmfPlusEOF extends EmfPlusFlagOnly {
@@ -193,6 +213,14 @@ public class HemfPlusMisc {
             tx.concatenate(getMatrixData());
             ctx.setTransform(tx);
         }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "flags", this::getFlags,
+                "matrixData", this::getMatrixData
+            );
+        }
     }
 
     /**
@@ -239,6 +267,18 @@ public class HemfPlusMisc {
             pageScale = leis.readFloat();
             return LittleEndianConsts.INT_SIZE;
         }
+
+        public double getPageScale() {
+            return pageScale;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "flags", this::getFlags,
+                "pageScale", this::getPageScale
+            );
+        }
     }
 
     /**
@@ -264,6 +304,9 @@ public class HemfPlusMisc {
     public static class EmfPlusSetClipRect implements HemfPlusRecord {
         private static final BitField COMBINE_MODE = BitFieldFactory.getInstance(0x0F00);
 
+        private static final int[] FLAGS_MASK = { 0x0F00 };
+        private static final String[] FLAGS_NAMES = { "COMBINE_MODE" };
+
         private int flags;
         private final Rectangle2D clipRect = new Rectangle2D.Double();
 
@@ -288,6 +331,18 @@ public class HemfPlusMisc {
             // An EmfPlusRectF object that defines the rectangle to use in the CombineMode operation.
             return readRectF(leis, clipRect);
         }
+
+        public Rectangle2D getClipRect() {
+            return clipRect;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "flags", getBitsAsString(this::getFlags, FLAGS_MASK, FLAGS_NAMES),
+                "clipRect", this::getClipRect
+            );
+        }
     }
 
 
@@ -314,6 +369,10 @@ public class HemfPlusMisc {
             return flags;
         }
 
+        public int getStackIndex() {
+            return stackIndex;
+        }
+
         @Override
         public long init(LittleEndianInputStream leis, long dataSize, long recordId, int flags) throws IOException {
             this.flags = flags;
@@ -324,6 +383,14 @@ public class HemfPlusMisc {
 
             return LittleEndianConsts.INT_SIZE;
         }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "flags", this::getFlags,
+                "stackIndex", this::getStackIndex
+            );
+        }
     }
 
     /**
@@ -369,6 +436,14 @@ public class HemfPlusMisc {
 
             return LittleEndianConsts.INT_SIZE*2;
         }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "flags", this::getFlags,
+                "origin", this::getOrigin
+            );
+        }
     }
 
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusObject.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusObject.java?rev=1866808&r1=1866807&r2=1866808&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusObject.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusObject.java Wed Sep 11 21:24:06 2019
@@ -17,11 +17,15 @@
 
 package org.apache.poi.hemf.record.emfplus;
 
+import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.function.Supplier;
 
+import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.hemf.record.emfplus.HemfPlusBrush.EmfPlusBrush;
 import org.apache.poi.hemf.record.emfplus.HemfPlusFont.EmfPlusFont;
@@ -36,6 +40,7 @@ import org.apache.poi.hwmf.draw.HwmfGrap
 import org.apache.poi.hwmf.record.HwmfObjectTableEntry;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
@@ -113,8 +118,6 @@ public class HemfPlusObject {
      * can span multiple records), which is indicated by the value of the Flags field.
      */
     public static class EmfPlusObject implements HemfPlusRecord, EmfPlusObjectId, HwmfObjectTableEntry {
-
-
         /**
          * Indicates that the object definition continues on in the next EmfPlusObject
          * record. This flag is never set in the final record that defines the object.
@@ -127,6 +130,10 @@ public class HemfPlusObject {
          */
         private static final BitField OBJECT_TYPE = BitFieldFactory.getInstance(0x7F00);
 
+        private static final int[] FLAGS_MASKS = { 0x7F00, 0x8000 };
+
+        private static final String[] FLAGS_NAMES = { "OBJECT_TYPE", "CONTINUABLE" };
+
         private int flags;
         // for debugging
         private int objectId;
@@ -211,9 +218,20 @@ public class HemfPlusObject {
         List<EmfPlusObjectData> getContinuedObject() {
             return continuedObjectData;
         }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "flags", getBitsAsString(this::getFlags, FLAGS_MASKS, FLAGS_NAMES),
+                "objectId", this::getObjectId,
+                "continuedObjectData", this::getContinuedObject,
+                "totalObjectSize", () -> totalObjectSize
+            );
+        }
+
     }
 
-    public interface EmfPlusObjectData {
+    public interface EmfPlusObjectData extends GenericRecord {
         long init(LittleEndianInputStream leis, long dataSize, EmfPlusObjectType objectType, int flags) throws IOException;
 
         void applyObject(HemfGraphics ctx, List<? extends EmfPlusObjectData> continuedObjectData);
@@ -251,5 +269,18 @@ public class HemfPlusObject {
         public EmfPlusGraphicsVersion getGraphicsVersion() {
             return graphicsVersion;
         }
+
+        @Override
+        public EmfPlusObjectType getGenericRecordType() {
+            return objectType;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "graphicsVersion", this::getGraphicsVersion,
+                "objectDataBytes", () -> objectDataBytes
+            );
+        }
     }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusPath.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusPath.java?rev=1866808&r1=1866807&r2=1866808&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusPath.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusPath.java Wed Sep 11 21:24:06 2019
@@ -17,13 +17,20 @@
 
 package org.apache.poi.hemf.record.emfplus;
 
+import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
+
 import java.awt.geom.Path2D;
 import java.awt.geom.Point2D;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 import java.util.function.BiFunction;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
+import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.hemf.draw.HemfDrawProperties;
 import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.hemf.record.emfplus.HemfPlusDraw.EmfPlusCompressed;
@@ -32,6 +39,7 @@ import org.apache.poi.hemf.record.emfplu
 import org.apache.poi.hemf.record.emfplus.HemfPlusObject.EmfPlusObjectType;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 
@@ -73,6 +81,12 @@ public class HemfPlusPath {
 
         private static final BitField POINT_RLE_COUNT = BitFieldFactory.getInstance(0x3F);
 
+        private static final int[] FLAGS_MASKS = { 0x0800, 0x1000, 0x4000 };
+        private static final String[] FLAGS_NAMES = { "RELATIVE_POSITION", "RLE_COMPRESSED", "FORMAT_COMPRESSED" };
+
+        private static final int[] TYPE_MASKS = { 0x10, 0x20, 0x80 };
+        private static final String[] TYPE_NAMES = { "DASHED", "MARKER", "CLOSE" };
+
         private final HemfPlusHeader.EmfPlusGraphicsVersion graphicsVersion = new HemfPlusHeader.EmfPlusGraphicsVersion();
         private int pointFlags;
         private Point2D[] pathPoints;
@@ -154,7 +168,9 @@ public class HemfPlusPath {
             return pointFlags;
         }
 
-
+        public Point2D getPoint(int index) {
+            return pathPoints[index];
+        }
 
         @Override
         public void applyObject(HemfGraphics ctx, List<? extends EmfPlusObjectData> continuedObjectData) {
@@ -184,8 +200,32 @@ public class HemfPlusPath {
             }
         }
 
+        @Override
+        public EmfPlusObjectType getGenericRecordType() {
+            return EmfPlusObjectType.PATH;
+        }
 
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "graphicsVersion", this::getGraphicsVersion,
+                "flags", getBitsAsString(this::getFlags, FLAGS_MASKS, FLAGS_NAMES),
+                "points", this::getGenericPoints
+            );
+        }
+
+        private List<GenericRecord> getGenericPoints() {
+            return IntStream.range(0, pathPoints.length).
+                mapToObj(this::getGenericPoint).
+                collect(Collectors.toList());
+        }
+
+        private GenericRecord getGenericPoint(final int idx) {
+            return () -> GenericRecordUtil.getGenericProperties(
+                "flags", getBitsAsString(() -> pointTypes[idx], TYPE_MASKS, TYPE_NAMES),
+                "type", () -> getPointType(idx),
+                "point", () -> getPoint(idx)
+            );
+        }
     }
-
-
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusPen.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusPen.java?rev=1866808&r1=1866807&r2=1866808&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusPen.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusPen.java Wed Sep 11 21:24:06 2019
@@ -19,13 +19,19 @@ package org.apache.poi.hemf.record.emfpl
 
 import static org.apache.poi.hemf.record.emf.HemfFill.readXForm;
 import static org.apache.poi.hemf.record.emfplus.HemfPlusDraw.readPointF;
+import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
 
 import java.awt.geom.AffineTransform;
 import java.awt.geom.Point2D;
 import java.io.IOException;
+import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.function.Consumer;
+import java.util.function.Supplier;
 
+import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.hemf.draw.HemfDrawProperties;
 import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.hemf.record.emfplus.HemfPlusDraw.EmfPlusUnitType;
@@ -40,6 +46,7 @@ import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndianConsts;
 import org.apache.poi.util.LittleEndianInputStream;
 
+@SuppressWarnings("WeakerAccess")
 public class HemfPlusPen {
     /**
      * The LineCapType enumeration defines types of line caps to use at the ends of lines that are drawn
@@ -222,7 +229,7 @@ public class HemfPlusPen {
 
 
     @Internal
-    public interface EmfPlusCustomLineCap {
+    public interface EmfPlusCustomLineCap extends GenericRecord {
         long init(LittleEndianInputStream leis) throws IOException;
     }
 
@@ -290,6 +297,18 @@ public class HemfPlusPen {
          */
         private final static BitField CUSTOM_END_CAP = BitFieldFactory.getInstance(0x00001000);
 
+        private static final int[] FLAGS_MASKS = {
+            0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
+            0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200,
+            0x00000400, 0x00000800, 0x00001000
+        };
+
+        private static final String[] FLAGS_NAMES = {
+            "TRANSFORM", "START_CAP", "END_CAP", "JOIN", "MITER_LIMIT",
+            "LINE_STYLE", "DASHED_LINE_CAP", "DASHED_LINE_OFFSET", "DASHED_LINE", "NON_CENTER",
+            "COMPOUND_LINE", "CUSTOM_START_CAP", "CUSTOM_END_CAP"
+        };
+
         private final EmfPlusGraphicsVersion graphicsVersion = new EmfPlusGraphicsVersion();
 
 
@@ -528,6 +547,34 @@ public class HemfPlusPen {
                 }
             });
         }
+
+        @Override
+        public EmfPlusObjectType getGenericRecordType() {
+            return EmfPlusObjectType.PEN;
+        }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            final Map<String,Supplier<?>> m = new LinkedHashMap<>();
+            m.put("type", () -> type);
+            m.put("flags", getBitsAsString(() -> penDataFlags, FLAGS_MASKS, FLAGS_NAMES));
+            m.put("unitType", () -> unitType);
+            m.put("penWidth", () -> penWidth);
+            m.put("trans", () -> trans);
+            m.put("startCap", () -> startCap);
+            m.put("endCap", () -> endCap);
+            m.put("join", () -> join);
+            m.put("miterLimit", () -> miterLimit);
+            m.put("style", () -> style);
+            m.put("dashedLineCapType", () -> dashedLineCapType);
+            m.put("dashOffset", () -> dashOffset);
+            m.put("dashedLineData", () -> dashedLineData);
+            m.put("penAlignment", () -> penAlignment);
+            m.put("compoundLineData", () -> compoundLineData);
+            m.put("customStartCap", () -> customStartCap);
+            m.put("customEndCap", () -> customEndCap);
+            return Collections.unmodifiableMap(m);
+        }
     }
 
     public static class EmfPlusPathArrowCap implements EmfPlusCustomLineCap {
@@ -542,6 +589,9 @@ public class HemfPlusPen {
          */
         private static final BitField LINE_PATH = BitFieldFactory.getInstance(0x00000002);
 
+        private static final int[] FLAGS_MASKS = { 0x00000001, 0x00000002 };
+
+        private static final String[] FLAGS_NAMES = { "FILL_PATH", "LINE_PATH" };
 
         private int dataFlags;
         private EmfPlusLineCapType baseCap;
@@ -549,7 +599,7 @@ public class HemfPlusPen {
         private EmfPlusLineCapType startCap;
         private EmfPlusLineCapType endCap;
         private EmfPlusLineJoin join;
-        private double mitterLimit;
+        private double miterLimit;
         private double widthScale;
         private final Point2D fillHotSpot = new Point2D.Double();
         private final Point2D lineHotSpot = new Point2D.Double();
@@ -582,7 +632,7 @@ public class HemfPlusPen {
 
             // A 32-bit floating-point value that contains the limit of the thickness of the join on a mitered corner
             // by setting the maximum allowed ratio of miter length to line width.
-            mitterLimit = leis.readFloat();
+            miterLimit = leis.readFloat();
 
             // A 32-bit floating-point value that specifies the amount by which to scale the custom line cap with
             // respect to the width of the EmfPlusPen object that is used to draw the lines.
@@ -606,6 +656,24 @@ public class HemfPlusPen {
 
             return size;
         }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            final Map<String,Supplier<?>> m = new LinkedHashMap<>();
+            m.put("flags", getBitsAsString(() -> dataFlags, FLAGS_MASKS, FLAGS_NAMES));
+            m.put("baseCap", () -> baseCap);
+            m.put("baseInset", () -> baseInset);
+            m.put("startCap", () -> startCap);
+            m.put("endCap", () -> endCap);
+            m.put("join", () -> join);
+            m.put("miterLimit", () -> miterLimit);
+            m.put("widthScale", () -> widthScale);
+            m.put("fillHotSpot", () -> fillHotSpot);
+            m.put("lineHotSpot", () -> lineHotSpot);
+            m.put("fillPath", () -> fillPath);
+            m.put("outlinePath", () -> outlinePath);
+            return Collections.unmodifiableMap(m);
+        }
     }
 
     public static class EmfPlusAdjustableArrowCap implements EmfPlusCustomLineCap {
@@ -616,7 +684,7 @@ public class HemfPlusPen {
         private EmfPlusLineCapType startCap;
         private EmfPlusLineCapType endCap;
         private EmfPlusLineJoin join;
-        private double mitterLimit;
+        private double miterLimit;
         private double widthScale;
         private final Point2D fillHotSpot = new Point2D.Double();
         private final Point2D lineHotSpot = new Point2D.Double();
@@ -655,7 +723,7 @@ public class HemfPlusPen {
 
             // A 32-bit floating-point value that specifies the limit of the thickness of the join on a mitered
             // corner by setting the maximum allowed ratio of miter length to line width.
-            mitterLimit = leis.readFloat();
+            miterLimit = leis.readFloat();
 
             // A 32-bit floating-point value that specifies the amount by which to scale an EmfPlusCustomLineCap
             // object with respect to the width of the graphics pen that is used to draw the lines.
@@ -671,5 +739,23 @@ public class HemfPlusPen {
 
             return size;
         }
+
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            final Map<String,Supplier<?>> m = new LinkedHashMap<>();
+            m.put("width", () -> width);
+            m.put("height", () -> height);
+            m.put("middleInset", () -> middleInset);
+            m.put("isFilled", () -> isFilled);
+            m.put("startCap", () -> startCap);
+            m.put("endCap", () -> endCap);
+            m.put("join", () -> join);
+            m.put("miterLimit", () -> miterLimit);
+            m.put("widthScale", () -> widthScale);
+            m.put("fillHotSpot", () -> fillHotSpot);
+            m.put("lineHotSpot", () -> lineHotSpot);
+            return Collections.unmodifiableMap(m);
+        }
     }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecord.java?rev=1866808&r1=1866807&r2=1866808&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecord.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecord.java Wed Sep 11 21:24:06 2019
@@ -20,12 +20,13 @@ package org.apache.poi.hemf.record.emfpl
 
 import java.io.IOException;
 
+import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.hemf.draw.HemfGraphics;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndianInputStream;
 
 @Internal
-public interface HemfPlusRecord {
+public interface HemfPlusRecord extends GenericRecord {
 
     HemfPlusRecordType getEmfPlusRecordType();
 



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