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

svn commit: r1843025 - in /poi/branches/hemf/src/scratchpad/src/org/apache/poi: hemf/record/emf/HemfFill.java hemf/record/emf/HemfRecordType.java hwmf/record/HwmfFill.java

Author: kiwiwings
Date: Sat Oct  6 18:23:59 2018
New Revision: 1843025

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

Modified:
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java
    poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java?rev=1843025&r1=1843024&r2=1843025&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java Sat Oct  6 18:23:59 2018
@@ -19,7 +19,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.readRectL;
-import static org.apache.poi.hemf.record.emf.HemfRecordIterator.HEADER_SIZE;
 
 import java.awt.geom.AffineTransform;
 import java.awt.geom.Area;
@@ -114,7 +113,7 @@ public class HemfFill {
      * optionally in combination with a brush pattern, according to a specified raster operation, stretching or
      * compressing the output to fit the dimensions of the destination, if necessary.
      */
-    public static class EmfStretchBlt extends HwmfFill.WmfBitBlt implements HemfRecord {
+    public static class EmfStretchBlt extends HwmfFill.WmfBitBlt implements HemfRecord, HemfBounded {
         protected final Rectangle2D bounds = new Rectangle2D.Double();
 
         /** An XForm object that specifies a world-space to page-space transform to apply to the source bitmap. */
@@ -129,11 +128,7 @@ public class HemfFill {
          */
         protected int usageSrc;
 
-        /** The source bitmap header. */
-        protected byte[] bmiSrc;
-
-        /** The source bitmap bits. */
-        protected byte[] bitsSrc;
+        protected final HwmfBitmapDib bitmap = new HwmfBitmapDib();
 
         @Override
         public HemfRecordType getEmfRecordType() {
@@ -142,6 +137,8 @@ public class HemfFill {
 
         @Override
         public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
+            int startIdx = leis.getReadIndex();
+
             long size = readRectL(leis, bounds);
 
             size += readBounds2(leis, this.dstBounds);
@@ -190,34 +187,104 @@ public class HemfFill {
                 srcBounds.setRect(srcPnt.getX(), srcPnt.getY(), srcWidth, srcHeight);
             }
 
-            // size + type and size field
-            final int undefinedSpace1 = (int)(offBmiSrc - size - HEADER_SIZE);
-            assert(undefinedSpace1 >= 0);
-            leis.skipFully(undefinedSpace1);
-            size += undefinedSpace1;
-
-            bmiSrc = IOUtils.safelyAllocate(cbBmiSrc, MAX_RECORD_LENGTH);
-            leis.readFully(bmiSrc);
-            size += cbBmiSrc;
-
-            final int undefinedSpace2 = (int)(offBitsSrc - size - HEADER_SIZE);
-            assert(undefinedSpace2 >= 0);
-            leis.skipFully(undefinedSpace2);
-            size += undefinedSpace2;
-
-            bitsSrc = IOUtils.safelyAllocate(cbBitsSrc, MAX_RECORD_LENGTH);
-            leis.readFully(bitsSrc);
-            size += cbBitsSrc;
+            size += readBitmap(leis, bitmap, startIdx, offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc);
 
             return size;
         }
 
+        @Override
+        public Rectangle2D getRecordBounds() {
+            return bounds;
+        }
+
+        @Override
+        public Rectangle2D getShapeBounds(HemfGraphics ctx) {
+            return dstBounds;
+        }
+
         protected boolean srcEqualsDstDimension() {
             return false;
         }
     }
 
     /**
+     * The EMR_STRETCHDIBITS record specifies a block transfer of pixels from a source bitmap to a
+     * destination rectangle, optionally in combination with a brush pattern, according to a specified raster
+     * operation, stretching or compressing the output to fit the dimensions of the destination, if necessary.
+     */
+    public static class EmfStretchDiBits extends HwmfFill.WmfStretchDib implements HemfRecord, HemfBounded {
+        protected final Rectangle2D bounds = new Rectangle2D.Double();
+
+        @Override
+        public HemfRecordType getEmfRecordType() {
+            return HemfRecordType.stretchDiBits;
+        }
+
+        @Override
+        public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
+            final int startIdx = leis.getReadIndex();
+
+            long size = readRectL(leis, bounds);
+
+            // A 32-bit signed integer that specifies the logical x-coordinate of the upper-left
+            // corner of the destination rectangle.
+            int xDest = leis.readInt();
+            int yDest = leis.readInt();
+            size += 2*LittleEndianConsts.INT_SIZE;
+
+            size += readBounds2(leis, srcBounds);
+
+            // A 32-bit unsigned integer that specifies the offset, in bytes from the start
+            // of this record to the source bitmap header.
+            int offBmiSrc = (int)leis.readUInt();
+
+            // A 32-bit unsigned integer that specifies the size, in bytes, of the source bitmap header.
+            int cbBmiSrc = (int)leis.readUInt();
+
+            // A 32-bit unsigned integer that specifies the offset, in bytes, from the
+            // start of this record to the source bitmap bits.
+            int offBitsSrc = (int)leis.readUInt();
+
+            // A 32-bit unsigned integer that specifies the size, in bytes, of the source bitmap bits.
+            int cbBitsSrc = (int)leis.readUInt();
+
+            // A 32-bit unsigned integer that specifies how to interpret values in the color table
+            // in the source bitmap header. This value MUST be in the DIBColors enumeration
+            colorUsage = ColorUsage.valueOf(leis.readInt());
+
+            // A 32-bit unsigned integer that specifies a raster operation code.
+            // These codes define how the color data of the source rectangle is to be combined with the color data
+            // of the destination rectangle and optionally a brush pattern, to achieve the final color.
+            // The value MUST be in the WMF Ternary Raster Operation enumeration
+            rasterOperation = HwmfTernaryRasterOp.valueOf(leis.readInt());
+
+            // A 32-bit signed integer that specifies the logical width of the destination rectangle.
+            int cxDest = leis.readInt();
+
+            // A 32-bit signed integer that specifies the logical height of the destination rectangle.
+            int cyDest = leis.readInt();
+
+            dstBounds.setRect(xDest, yDest, cxDest, cyDest);
+
+            size += 8*LittleEndianConsts.INT_SIZE;
+
+            size += readBitmap(leis, dib, startIdx, offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc);
+
+            return size;
+        }
+
+        @Override
+        public Rectangle2D getRecordBounds() {
+            return bounds;
+        }
+
+        @Override
+        public Rectangle2D getShapeBounds(HemfGraphics ctx) {
+            return dstBounds;
+        }
+    }
+
+    /**
      * The EMR_BITBLT record specifies a block transfer of pixels from a source bitmap to a destination rectangle,
      * optionally in combination with a brush pattern, according to a specified raster operation.
      */
@@ -235,7 +302,7 @@ public class HemfFill {
 
 
     /** The EMR_FRAMERGN record draws a border around the specified region using the specified brush. */
-    public static class EmfFrameRgn extends HwmfDraw.WmfFrameRegion implements HemfRecord {
+    public static class EmfFrameRgn extends HwmfDraw.WmfFrameRegion implements HemfRecord, HemfBounded {
         private final Rectangle2D bounds = new Rectangle2D.Double();
         private final List<Rectangle2D> rgnRects = new ArrayList<>();
 
@@ -263,18 +330,23 @@ public class HemfFill {
         @Override
         public void draw(HwmfGraphics ctx) {
             ctx.applyObjectTableEntry(brushIndex);
+            ctx.fill(getShape());
+        }
 
-            Area frame = new Area();
-            for (Rectangle2D rct : rgnRects) {
-                frame.add(new Area(rct));
-            }
-            Rectangle2D frameBounds = frame.getBounds2D();
-            AffineTransform at = new AffineTransform();
-            at.translate(bounds.getX()-frameBounds.getX(), bounds.getY()-frameBounds.getY());
-            at.scale(bounds.getWidth()/frameBounds.getWidth(), bounds.getHeight()/frameBounds.getHeight());
-            frame.transform(at);
+        @Override
+        public Rectangle2D getRecordBounds() {
+            return bounds;
+        }
+
+        @Override
+        public Rectangle2D getShapeBounds(HemfGraphics ctx) {
+            return getShape().getBounds2D();
+        }
 
-            ctx.fill(frame);
+        protected Area getShape() {
+            final Area frame = new Area();
+            rgnRects.forEach((rct) -> frame.add(new Area(rct)));
+            return frame;
         }
     }
 

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java?rev=1843025&r1=1843024&r2=1843025&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordType.java Sat Oct  6 18:23:59 2018
@@ -104,7 +104,7 @@ public enum HemfRecordType {
     maskblt(0x0000004E, UnimplementedHemfRecord::new),
     plgblt(0x0000004F, UnimplementedHemfRecord::new),
     setDiBitsToDevice(0x00000050, HemfFill.EmfSetDiBitsToDevice::new),
-    stretchdibits(0x00000051, UnimplementedHemfRecord::new),
+    stretchDiBits(0x00000051, HemfFill.EmfStretchDiBits::new),
     extCreateFontIndirectW(0x00000052, HemfText.ExtCreateFontIndirectW::new),
     exttextouta(0x00000053, HemfText.EmfExtTextOutA::new),
     exttextoutw(0x00000054, HemfText.EmfExtTextOutW::new),

Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java?rev=1843025&r1=1843024&r2=1843025&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java Sat Oct  6 18:23:59 2018
@@ -430,13 +430,13 @@ public class HwmfFill {
          * the playback device context, and the destination pixels are to be combined to
          * form the new image.
          */
-        private HwmfTernaryRasterOp rasterOperation;
+        protected HwmfTernaryRasterOp rasterOperation;
 
         /**
          * A 16-bit unsigned integer that defines whether the Colors field of the
          * DIB contains explicit RGB values or indexes into a palette.
          */
-        private ColorUsage colorUsage;
+        protected ColorUsage colorUsage;
 
         /** the source rectangle. */
         protected final Rectangle2D srcBounds = new Rectangle2D.Double();
@@ -448,7 +448,7 @@ public class HwmfFill {
          * A variable-sized DeviceIndependentBitmap Object (section 2.2.2.9) that is the 
          * source of the color data.
          */
-        private HwmfBitmapDib dib;
+        protected final HwmfBitmapDib dib = new HwmfBitmapDib();
         
         @Override
         public HwmfRecordType getWmfRecordType() {
@@ -471,7 +471,6 @@ public class HwmfFill {
             size += readBounds2(leis, srcBounds);
             size += readBounds2(leis, dstBounds);
 
-            dib = new HwmfBitmapDib();
             size += dib.init(leis, (int)(recordSize-6-size));
 
             return size;



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