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/21 20:49:03 UTC
svn commit: r1844522 - in /poi/branches/hemf/src/scratchpad:
src/org/apache/poi/hemf/draw/ src/org/apache/poi/hemf/record/emf/
src/org/apache/poi/hwmf/draw/ src/org/apache/poi/hwmf/record/
testcases/org/apache/poi/hemf/usermodel/
Author: kiwiwings
Date: Sun Oct 21 20:49:03 2018
New Revision: 1844522
URL: http://svn.apache.org/viewvc?rev=1844522&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/draw/HemfGraphics.java
poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java
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/HemfMisc.java
poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java
poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java
poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java
poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java
Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java?rev=1844522&r1=1844521&r2=1844522&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java Sun Oct 21 20:49:03 2018
@@ -53,6 +53,7 @@ public class HemfGraphics extends HwmfGr
super(graphicsCtx,bbox);
// add dummy entry for object index 0, as emf is 1-based
objectIndexes.set(0);
+ saveTransform();
}
@Override
@@ -82,10 +83,10 @@ public class HemfGraphics extends HwmfGr
if (tgt != null && !tgt.isEmpty()) {
final Rectangle2D src = bounded.getShapeBounds(this);
if (src != null && !src.isEmpty()) {
- graphicsCtx.translate(tgt.getCenterX() - src.getCenterX(), tgt.getCenterY() - src.getCenterY());
- graphicsCtx.translate(src.getCenterX(), src.getCenterY());
- graphicsCtx.scale(tgt.getWidth() / src.getWidth(), tgt.getHeight() / src.getHeight());
- graphicsCtx.translate(-src.getCenterX(), -src.getCenterY());
+// graphicsCtx.translate(tgt.getCenterX() - src.getCenterX(), tgt.getCenterY() - src.getCenterY());
+// graphicsCtx.translate(src.getCenterX(), src.getCenterY());
+// graphicsCtx.scale(tgt.getWidth() / src.getWidth(), tgt.getHeight() / src.getHeight());
+// graphicsCtx.translate(-src.getCenterX(), -src.getCenterY());
}
}
}
@@ -266,7 +267,27 @@ public class HemfGraphics extends HwmfGr
}
}
+ /**
+ * @return the initial AffineTransform, when this graphics context was created
+ */
+ public AffineTransform getInitTransform() {
+ return new AffineTransform(transforms.peekFirst());
+ }
+
+ /**
+ * @return the current AffineTransform
+ */
+ public AffineTransform getTransform() {
+ return new AffineTransform(graphicsCtx.getTransform());
+ }
+ /**
+ * Set the current AffineTransform
+ * @param tx the current AffineTransform
+ */
+ public void setTransform(AffineTransform tx) {
+ graphicsCtx.setTransform(tx);
+ }
/** saves the current affine transform on the stack */
private void saveTransform() {
Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java?rev=1844522&r1=1844521&r2=1844522&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java Sun Oct 21 20:49:03 2018
@@ -860,6 +860,11 @@ public class HemfDraw {
final HemfDrawProperties prop = ctx.getProperties();
prop.setPath(new Path2D.Double());
}
+
+ @Override
+ public String toString() {
+ return "{}";
+ }
}
/**
@@ -876,6 +881,11 @@ public class HemfDraw {
public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
return 0;
}
+
+ @Override
+ public String toString() {
+ return "{}";
+ }
}
/**
@@ -897,6 +907,11 @@ public class HemfDraw {
final HemfDrawProperties prop = ctx.getProperties();
prop.setPath(null);
}
+
+ @Override
+ public String toString() {
+ return "{}";
+ }
}
/**
@@ -929,7 +944,6 @@ public class HemfDraw {
return 0;
}
-
@Override
public void draw(HemfGraphics ctx) {
final HemfDrawProperties prop = ctx.getProperties();
@@ -940,6 +954,11 @@ public class HemfDraw {
}
}
+
+ @Override
+ public String toString() {
+ return "{}";
+ }
}
/**
@@ -972,12 +991,17 @@ public class HemfDraw {
public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
return 0;
}
+
+ @Override
+ public String toString() {
+ return "{}";
+ }
}
/**
* The EMR_STROKEPATH record renders the specified path by using the current pen.
*/
- public static class EmfStrokePath implements HemfRecord {
+ public static class EmfStrokePath implements HemfRecord, HemfBounded {
protected final Rectangle2D bounds = new Rectangle2D.Double();
@Override
@@ -990,6 +1014,28 @@ public class HemfDraw {
// A 128-bit WMF RectL object, which specifies bounding rectangle, in device units
return readRectL(leis, bounds);
}
+
+ @Override
+ public void draw(HemfGraphics ctx) {
+ HemfDrawProperties props = ctx.getProperties();
+ ctx.draw(props.getPath());
+ }
+
+ @Override
+ public Rectangle2D getRecordBounds() {
+ return bounds;
+ }
+
+ @Override
+ public Rectangle2D getShapeBounds(HemfGraphics ctx) {
+ HemfDrawProperties props = ctx.getProperties();
+ return props.getPath().getBounds2D();
+ }
+
+ @Override
+ public String toString() {
+ return "{ bounds: { x: "+bounds.getX()+", y: "+bounds.getY()+", w: "+bounds.getWidth()+", h: "+bounds.getHeight()+" }";
+ }
}
static long readRectL(LittleEndianInputStream leis, Rectangle2D bounds) {
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=1844522&r1=1844521&r2=1844522&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 Sun Oct 21 20:49:03 2018
@@ -358,14 +358,12 @@ public class HemfFill {
}
protected Area getShape() {
- final Area frame = new Area();
- rgnRects.forEach((rct) -> frame.add(new Area(rct)));
- return frame;
+ return getRgnShape(rgnRects);
}
}
/** The EMR_INVERTRGN record inverts the colors in the specified region. */
- public static class EmfInvertRgn implements HemfRecord {
+ public static class EmfInvertRgn implements HemfRecord, HemfBounded {
protected final Rectangle2D bounds = new Rectangle2D.Double();
protected final List<Rectangle2D> rgnRects = new ArrayList<>();
@@ -383,6 +381,20 @@ public class HemfFill {
size += readRgnData(leis, rgnRects);
return size;
}
+
+ @Override
+ public Rectangle2D getRecordBounds() {
+ return bounds;
+ }
+
+ @Override
+ public Rectangle2D getShapeBounds(HemfGraphics ctx) {
+ return getShape().getBounds2D();
+ }
+
+ protected Area getShape() {
+ return getRgnShape(rgnRects);
+ }
}
/**
@@ -397,7 +409,7 @@ public class HemfFill {
}
/** The EMR_FILLRGN record fills the specified region by using the specified brush. */
- public static class EmfFillRgn extends HwmfFill.WmfFillRegion implements HemfRecord {
+ public static class EmfFillRgn extends HwmfFill.WmfFillRegion implements HemfRecord, HemfBounded {
protected final Rectangle2D bounds = new Rectangle2D.Double();
protected final List<Rectangle2D> rgnRects = new ArrayList<>();
@@ -416,6 +428,20 @@ public class HemfFill {
size += readRgnData(leis, rgnRects);
return size;
}
+
+ @Override
+ public Rectangle2D getRecordBounds() {
+ return bounds;
+ }
+
+ @Override
+ public Rectangle2D getShapeBounds(HemfGraphics ctx) {
+ return getShape().getBounds2D();
+ }
+
+ protected Area getShape() {
+ return getRgnShape(rgnRects);
+ }
}
public static class EmfExtSelectClipRgn implements HemfRecord {
@@ -442,9 +468,13 @@ public class HemfFill {
}
return size;
}
+
+ protected Area getShape() {
+ return getRgnShape(rgnRects);
+ }
}
- public static class EmfAlphaBlend implements HemfRecord {
+ public static class EmfAlphaBlend implements HemfRecord, HemfBounded {
/** the destination bounding rectangle in device units */
protected final Rectangle2D bounds = new Rectangle2D.Double();
/** the destination rectangle */
@@ -553,9 +583,24 @@ public class HemfFill {
return size;
}
+
+
+ @Override
+ public Rectangle2D getRecordBounds() {
+ return bounds;
+ }
+
+ @Override
+ public Rectangle2D getShapeBounds(HemfGraphics ctx) {
+ return destRect;
+ }
}
- public static class EmfSetDiBitsToDevice implements HemfRecord {
+ /**
+ * The EMR_SETDIBITSTODEVICE record specifies a block transfer of pixels from specified scanlines of
+ * a source bitmap to a destination rectangle.
+ */
+ public static class EmfSetDiBitsToDevice implements HemfRecord, HemfBounded {
protected final Rectangle2D bounds = new Rectangle2D.Double();
protected final Point2D dest = new Point2D.Double();
protected final Rectangle2D src = new Rectangle2D.Double();
@@ -600,6 +645,16 @@ public class HemfFill {
return size;
}
+
+ @Override
+ public Rectangle2D getRecordBounds() {
+ return bounds;
+ }
+
+ @Override
+ public Rectangle2D getShapeBounds(HemfGraphics ctx) {
+ return new Rectangle2D.Double(dest.getX(), dest.getY(), src.getWidth(), src.getHeight());
+ }
}
static long readBitmap(final LittleEndianInputStream leis, final HwmfBitmapDib bitmap,
@@ -759,4 +814,10 @@ public class HemfFill {
}
}
}
+
+ protected static Area getRgnShape(List<Rectangle2D> rgnRects) {
+ 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/HemfMisc.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java?rev=1844522&r1=1844521&r2=1844522&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java Sun Oct 21 20:49:03 2018
@@ -29,6 +29,8 @@ import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hemf.draw.HemfGraphics;
+import org.apache.poi.hwmf.draw.HwmfDrawProperties;
+import org.apache.poi.hwmf.draw.HwmfGraphics;
import org.apache.poi.hwmf.record.HwmfBinaryRasterOp;
import org.apache.poi.hwmf.record.HwmfBitmapDib;
import org.apache.poi.hwmf.record.HwmfBrushStyle;
@@ -45,6 +47,44 @@ import org.apache.poi.util.LittleEndianC
import org.apache.poi.util.LittleEndianInputStream;
public class HemfMisc {
+
+ public enum HemfModifyWorldTransformMode {
+ /**
+ * Reset the current transform using the identity matrix.
+ * In this mode, the specified transform data is ignored.
+ */
+ MWT_IDENTITY(1),
+ /**
+ * Multiply the current transform. In this mode, the specified transform data is the left multiplicand,
+ * and the transform that is currently defined in the playback device context is the right multiplicand.
+ */
+ MWT_LEFTMULTIPLY(2),
+ /**
+ * Multiply the current transform. In this mode, the specified transform data is the right multiplicand,
+ * and the transform that is currently defined in the playback device context is the left multiplicand.
+ */
+ MWT_RIGHTMULTIPLY(3),
+ /**
+ * Perform the function of an EMR_SETWORLDTRANSFORM record
+ */
+ MWT_SET(4)
+ ;
+
+ public final int id;
+
+ HemfModifyWorldTransformMode(int id) {
+ this.id = id;
+ }
+
+ public static HemfModifyWorldTransformMode valueOf(int id) {
+ for (HemfModifyWorldTransformMode wrt : values()) {
+ if (wrt.id == id) return wrt;
+ }
+ return null;
+ }
+ }
+
+
public static class EmfEof implements HemfRecord {
protected final List<PaletteEntry> palette = new ArrayList<>();
@@ -518,6 +558,11 @@ public class HemfMisc {
public void draw(HemfGraphics ctx) {
ctx.getProperties().setPenMiterLimit(miterLimit);
}
+
+ @Override
+ public String toString() {
+ return "{ miterLimit: "+miterLimit+" }";
+ }
}
@@ -552,11 +597,30 @@ public class HemfMisc {
public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
return readXForm(leis, xForm);
}
+
+ @Override
+ public void draw(HemfGraphics ctx) {
+ AffineTransform tx = ctx.getInitTransform();
+ tx.concatenate(xForm);
+ ctx.setTransform(tx);
+ }
+
+ @Override
+ public String toString() {
+ return
+ "{ xForm: " +
+ "{ scaleX: "+xForm.getScaleX()+
+ ", shearX: "+xForm.getShearX()+
+ ", transX: "+xForm.getTranslateX()+
+ ", scaleY: "+xForm.getScaleY()+
+ ", shearY: "+xForm.getShearY()+
+ ", transY: "+xForm.getTranslateY()+" } }";
+ }
}
public static class EmfModifyWorldTransform implements HemfRecord {
protected final AffineTransform xForm = new AffineTransform();
- protected int modifyWorldTransformMode;
+ protected HemfModifyWorldTransformMode modifyWorldTransformMode;
@Override
public HemfRecordType getEmfRecordType() {
@@ -572,16 +636,54 @@ public class HemfMisc {
// A 32-bit unsigned integer that specifies how the transform specified in Xform is used.
// This value MUST be in the ModifyWorldTransformMode enumeration
- modifyWorldTransformMode = (int)leis.readUInt();
+ modifyWorldTransformMode = HemfModifyWorldTransformMode.valueOf((int)leis.readUInt());
return size + LittleEndianConsts.INT_SIZE;
}
@Override
+ public void draw(HemfGraphics ctx) {
+ if (modifyWorldTransformMode == null) {
+ return;
+ }
+
+ switch (modifyWorldTransformMode) {
+ case MWT_IDENTITY:
+ ctx.setTransform(ctx.getInitTransform());
+ break;
+ case MWT_LEFTMULTIPLY: {
+ AffineTransform tx = new AffineTransform(xForm);
+ tx.concatenate(ctx.getTransform());
+ ctx.setTransform(tx);
+ break;
+ }
+ case MWT_RIGHTMULTIPLY: {
+ AffineTransform tx = new AffineTransform(xForm);
+ tx.preConcatenate(ctx.getTransform());
+ ctx.setTransform(tx);
+ break;
+ }
+ default:
+ case MWT_SET: {
+ AffineTransform tx = ctx.getInitTransform();
+ tx.concatenate(xForm);
+ ctx.setTransform(tx);
+ break;
+ }
+ }
+ }
+
+ @Override
public String toString() {
return
- "{ xForm: { scaleX: "+xForm.getScaleX()+", shearX: "+xForm.getShearX()+", transX: "+xForm.getTranslateX()+", scaleY: "+xForm.getScaleY()+", shearY: "+xForm.getShearY()+", transY: "+xForm.getTranslateY()+" }"+
- ", modifyWorldTransformMode: "+modifyWorldTransformMode+" }";
+ "{ xForm: " +
+ "{ scaleX: "+xForm.getScaleX()+
+ ", shearX: "+xForm.getShearX()+
+ ", transX: "+xForm.getTranslateX()+
+ ", scaleY: "+xForm.getScaleY()+
+ ", shearY: "+xForm.getShearY()+
+ ", transY: "+xForm.getTranslateY()+" }"+
+ ", modifyWorldTransformMode: '"+modifyWorldTransformMode+"' }";
}
}
@@ -626,5 +728,13 @@ public class HemfMisc {
return size;
}
+
+ @Override
+ public void applyObject(HwmfGraphics ctx) {
+ super.applyObject(ctx);
+ HwmfDrawProperties props = ctx.getProperties();
+ props.setBrushStyle(HwmfBrushStyle.BS_PATTERN);
+ props.setBrushBitmap(bitmap.getImage());
+ }
}
}
Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java?rev=1844522&r1=1844521&r2=1844522&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java Sun Oct 21 20:49:03 2018
@@ -57,6 +57,7 @@ public class HemfText {
public static class EmfExtTextOutA extends HwmfText.WmfExtTextOut implements HemfRecord {
+ protected Rectangle2D boundsIgnored = new Rectangle2D.Double();
protected EmfGraphicsMode graphicsMode;
/**
@@ -81,7 +82,7 @@ public class HemfText {
}
// A WMF RectL object. It is not used and MUST be ignored on receipt.
- long size = readRectL(leis, bounds);
+ long size = readRectL(leis, boundsIgnored);
// A 32-bit unsigned integer that specifies the graphics mode from the GraphicsMode enumeration
graphicsMode = EmfGraphicsMode.values()[leis.readInt()-1];
@@ -192,8 +193,7 @@ public class HemfText {
@Override
public void draw(HwmfGraphics ctx) {
- Rectangle2D bounds = new Rectangle2D.Double(reference.getX(), reference.getY(), 0, 0);
- ctx.drawString(rawTextBytes, bounds, dx, isUnicode());
+ ctx.drawString(rawTextBytes, reference, bounds, dx, isUnicode());
}
@Override
Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java?rev=1844522&r1=1844521&r2=1844522&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java Sun Oct 21 20:49:03 2018
@@ -25,8 +25,11 @@ import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.TexturePaint;
+import java.awt.font.FontRenderContext;
import java.awt.font.TextAttribute;
+import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.nio.charset.Charset;
@@ -47,6 +50,7 @@ import org.apache.poi.hwmf.record.HwmfMi
import org.apache.poi.hwmf.record.HwmfObjectTableEntry;
import org.apache.poi.hwmf.record.HwmfPenStyle;
import org.apache.poi.hwmf.record.HwmfPenStyle.HwmfLineDash;
+import org.apache.poi.hwmf.record.HwmfText;
import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.DrawFontManager;
import org.apache.poi.util.LocaleUtil;
@@ -327,11 +331,11 @@ public class HwmfGraphics {
}
}
- public void drawString(byte[] text, Rectangle2D bounds) {
- drawString(text, bounds, null, false);
+ public void drawString(byte[] text, Point2D reference, Rectangle2D clip) {
+ drawString(text, reference, clip, null, false);
}
- public void drawString(byte[] text, Rectangle2D bounds, List<Integer> dx, boolean isUnicode) {
+ public void drawString(byte[] text, Point2D reference, Rectangle2D clip, List<Integer> dx, boolean isUnicode) {
HwmfFont font = getProperties().getFont();
if (font == null || text == null || text.length == 0) {
@@ -396,18 +400,55 @@ public class HwmfGraphics {
}
}
*/
-
+
double angle = Math.toRadians(-font.getEscapement()/10.);
+ final HwmfText.HwmfTextAlignment align = prop.getTextAlignLatin();
+ final HwmfText.HwmfTextVerticalAlignment valign = prop.getTextVAlignLatin();
+ final FontRenderContext frc = graphicsCtx.getFontRenderContext();
+ final TextLayout layout = new TextLayout(as.getIterator(), frc);
+
+ final Rectangle2D pixelBounds = layout.getBounds();
+
+ AffineTransform tx = new AffineTransform();
+ switch (align) {
+ default:
+ case LEFT:
+ break;
+ case CENTER:
+ tx.translate(-pixelBounds.getWidth() / 2., 0);
+ break;
+ case RIGHT:
+ tx.translate(-pixelBounds.getWidth(), 0);
+ break;
+ }
+
+ // TODO: check min/max orientation
+ switch (valign) {
+ case TOP:
+ tx.translate(0, layout.getAscent());
+ default:
+ case BASELINE:
+ break;
+ case BOTTOM:
+ tx.translate(0, pixelBounds.getHeight());
+ break;
+ }
+ tx.rotate(angle);
+ Point2D src = new Point2D.Double();
+ Point2D dst = new Point2D.Double();
+ tx.transform(src, dst);
+
+ // TODO: implement clipping on bounds
final AffineTransform at = graphicsCtx.getTransform();
try {
- graphicsCtx.translate(bounds.getX(), bounds.getY());
+ graphicsCtx.translate(reference.getX(), reference.getY());
graphicsCtx.rotate(angle);
- graphicsCtx.translate(0, fontH);
- if (getProperties().getBkMode() == HwmfBkMode.OPAQUE) {
+ graphicsCtx.translate(dst.getX(), dst.getY());
+ if (getProperties().getBkMode() == HwmfBkMode.OPAQUE && clip != null) {
// TODO: validate bounds
graphicsCtx.setBackground(getProperties().getBackgroundColor().getColor());
- graphicsCtx.fill(new Rectangle2D.Double(0, 0, bounds.getWidth(), bounds.getHeight()));
+ graphicsCtx.fill(new Rectangle2D.Double(0, 0, clip.getWidth(), clip.getHeight()));
}
graphicsCtx.setColor(getProperties().getTextColor().getColor());
graphicsCtx.drawString(as.getIterator(), 0, 0);
@@ -415,11 +456,11 @@ public class HwmfGraphics {
graphicsCtx.setTransform(at);
}
}
-
+
private void addAttributes(AttributedString as, HwmfFont font) {
DrawFontManager fontHandler = DrawFactory.getInstance(graphicsCtx).getFontManager(graphicsCtx);
FontInfo fontInfo = fontHandler.getMappedFont(graphicsCtx, font);
-
+
as.addAttribute(TextAttribute.FAMILY, fontInfo.getTypeface());
as.addAttribute(TextAttribute.SIZE, getFontHeight(font));
if (font.isStrikeOut()) {
Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java?rev=1844522&r1=1844521&r2=1844522&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java Sun Oct 21 20:49:03 2018
@@ -374,6 +374,16 @@ public class HwmfDraw {
public void draw(HwmfGraphics ctx) {
ctx.fill(bounds);
}
+
+ @Override
+ public String toString() {
+ return
+ "{ bounds: " +
+ "{ x: "+bounds.getX()+
+ ", y: "+bounds.getY()+
+ ", w: "+bounds.getWidth()+
+ ", h: "+bounds.getHeight()+" } }";
+ }
}
/**
Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java?rev=1844522&r1=1844521&r2=1844522&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java Sun Oct 21 20:49:03 2018
@@ -302,6 +302,11 @@ public class HwmfMisc {
public void draw(HwmfGraphics ctx) {
}
+
+ @Override
+ public String toString() {
+ return "{ drawMode: '"+drawMode+"' }";
+ }
}
/**
Modified: poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java?rev=1844522&r1=1844521&r2=1844522&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java (original)
+++ poi/branches/hemf/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java Sun Oct 21 20:49:03 2018
@@ -164,17 +164,9 @@ public class HwmfText {
* The string is written at the location specified by the XStart and YStart fields.
*/
private byte[] rawTextBytes;
- /**
- * A 16-bit signed integer that defines the vertical (y-axis) coordinate, in logical
- * units, of the point where drawing is to start.
- */
- private int yStart;
- /**
- * A 16-bit signed integer that defines the horizontal (x-axis) coordinate, in
- * logical units, of the point where drawing is to start.
- */
- private int xStart;
-
+
+ protected Point2D reference = new Point2D.Double();
+
@Override
public HwmfRecordType getWmfRecordType() {
return HwmfRecordType.textOut;
@@ -185,15 +177,19 @@ public class HwmfText {
stringLength = leis.readShort();
rawTextBytes = IOUtils.safelyAllocate(stringLength+(stringLength&1), MAX_RECORD_LENGTH);
leis.readFully(rawTextBytes);
- yStart = leis.readShort();
- xStart = leis.readShort();
+ // A 16-bit signed integer that defines the vertical (y-axis) coordinate, in logical
+ // units, of the point where drawing is to start.
+ int yStart = leis.readShort();
+ // A 16-bit signed integer that defines the horizontal (x-axis) coordinate, in
+ // logical units, of the point where drawing is to start.
+ int xStart = leis.readShort();
+ reference.setLocation(xStart, yStart);
return 3*LittleEndianConsts.SHORT_SIZE+rawTextBytes.length;
}
@Override
public void draw(HwmfGraphics ctx) {
- Rectangle2D bounds = new Rectangle2D.Double(xStart, yStart, 0, 0);
- ctx.drawString(getTextBytes(), bounds);
+ ctx.drawString(getTextBytes(), reference, null);
}
public String getText(Charset charset) {
@@ -398,8 +394,7 @@ public class HwmfText {
@Override
public void draw(HwmfGraphics ctx) {
- Rectangle2D bounds = new Rectangle2D.Double(reference.getX(), reference.getY(), 0, 0);
- ctx.drawString(rawTextBytes, bounds, dx, false);
+ ctx.drawString(rawTextBytes, reference, bounds, dx, false);
}
public String getText(Charset charset) throws IOException {
Modified: poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java?rev=1844522&r1=1844521&r2=1844522&view=diff
==============================================================================
--- poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java (original)
+++ poi/branches/hemf/src/scratchpad/testcases/org/apache/poi/hemf/usermodel/HemfPictureTest.java Sun Oct 21 20:49:03 2018
@@ -63,7 +63,8 @@ public class HemfPictureTest {
public void paint() throws IOException {
byte buf[] = new byte[50_000_000];
- final boolean writeLog = true;
+ final boolean writeLog = false;
+ final boolean dumpRecords = false;
final boolean savePng = true;
Set<String> passed = new HashSet<>();
@@ -101,6 +102,10 @@ public class HemfPictureTest {
}
}
+ if (dumpRecords) {
+ dumpRecords(emf);
+ }
+
Graphics2D g = null;
try {
Dimension2D dim = emf.getSize();
@@ -112,17 +117,23 @@ public class HemfPictureTest {
width *= 1500. / max;
height *= 1500. / max;
}
+ width = Math.ceil(width);
+ height = Math.ceil(height);
- BufferedImage bufImg = new BufferedImage((int)Math.ceil(width), (int)Math.ceil(height), BufferedImage.TYPE_INT_ARGB);
+ BufferedImage bufImg = new BufferedImage((int)width, (int)height, BufferedImage.TYPE_INT_ARGB);
g = bufImg.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+ g.setComposite(AlphaComposite.Clear);
+ g.fillRect(0, 0, (int)width, (int)height);
+ g.setComposite(AlphaComposite.Src);
+
emf.draw(g, new Rectangle2D.Double(0, 0, width, height));
- final File pngName = new File("build/tmp", etName.replaceFirst(".*"+"/", "").replace(".emf", ".png"));
+ final File pngName = new File("build/tmp", etName.replaceFirst(".+/", "").replace(".emf", ".png"));
if (savePng) {
ImageIO.write(bufImg, "PNG", pngName);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org