aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java8
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java12
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFont.java37
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfHeader.java2
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java12
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java6
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfWindowing.java3
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java2
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java11
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java50
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java10
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java2
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java17
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java3
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java2
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java2
16 files changed, 158 insertions, 21 deletions
diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java
index d18f0d4119..367d64b084 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfDraw.java
@@ -18,6 +18,7 @@
package org.apache.poi.hemf.record.emf;
import static org.apache.poi.hwmf.record.HwmfDraw.boundsToString;
+import static org.apache.poi.hwmf.record.HwmfDraw.normalizeBounds;
import java.awt.Shape;
import java.awt.geom.Arc2D;
@@ -660,7 +661,7 @@ public class HemfDraw {
@Override
public void draw(HemfGraphics ctx) {
- ctx.draw(path -> path.append(bounds, false), FillDrawStyle.FILL_DRAW);
+ ctx.draw(path -> path.append(normalizeBounds(bounds), false), FillDrawStyle.FILL_DRAW);
}
}
@@ -1127,8 +1128,9 @@ public class HemfDraw {
}
static long readDimensionInt(LittleEndianInputStream leis, Dimension2D dimension) {
- final double width = leis.readUInt();
- final double height = leis.readUInt();
+ // although the spec says "use unsigned ints", there are examples out there using signed ints
+ final double width = leis.readInt();
+ final double height = leis.readInt();
dimension.setSize(width, height);
return 2*LittleEndianConsts.INT_SIZE;
}
diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java
index 810c9325a3..5cd4879b15 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFill.java
@@ -21,6 +21,7 @@ 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 static org.apache.poi.hwmf.record.HwmfDraw.boundsToString;
+import static org.apache.poi.hwmf.record.HwmfDraw.pointToString;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
@@ -588,6 +589,17 @@ public class HemfFill {
return size;
}
+
+ @Override
+ public String toString() {
+ return
+ "{ bounds: " + boundsToString(bounds) +
+ ", dest: " + pointToString(dest) +
+ ", src: " + boundsToString(src) +
+ ", usageSrc: '" + usageSrc + "'" +
+ ", bitmap: " + bitmap +
+ "}";
+ }
}
static long readBitmap(final LittleEndianInputStream leis, final HwmfBitmapDib bitmap,
diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFont.java b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFont.java
index 8690855f16..ea3eb7754e 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFont.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfFont.java
@@ -36,6 +36,11 @@ public class HemfFont extends HwmfFont {
protected static class LogFontExDv implements LogFontDetails {
protected int[] designVector;
+
+ @Override
+ public String toString() {
+ return "{ designVectorLen: " + (designVector == null ? 0 : designVector.length) + " }";
+ }
}
protected static class LogFontPanose implements LogFontDetails {
@@ -195,6 +200,25 @@ public class HemfFont extends HwmfFont {
protected Letterform letterform;
protected MidLine midLine;
protected XHeight xHeight;
+
+ @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 + "'" +
+ "}";
+ }
}
protected String fullname;
@@ -435,13 +459,20 @@ public class HemfFont extends HwmfFont {
size += (2+numAxes)*LittleEndianConsts.INT_SIZE;
}
-
-
-
return size;
}
@Override
+ public String toString() {
+ return
+ "{ fullname: '" + (fullname == null ? "" : fullname) + "'" +
+ ", style: '" + (style == null ? "" : style) + "'" +
+ ", script: '" + (script == null ? "" : script) + "'" +
+ ", details: " + details +
+ "," + super.toString().substring(1);
+ }
+
+ @Override
protected int readString(LittleEndianInputStream leis, StringBuilder sb, int limit) throws IOException {
sb.setLength(0);
byte buf[] = new byte[limit*2];
diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfHeader.java b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfHeader.java
index 4b01a5a256..6c1cf5cadd 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfHeader.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfHeader.java
@@ -126,7 +126,7 @@ public class HemfHeader implements HemfRecord {
", bytes: " + bytes +
", records: " + records +
", handles: " + handles +
- ", description: '" + description + "'" +
+ ", description: '" + (description == null ? "" : description) + "'" +
", nPalEntries: " + nPalEntries +
", hasExtension1: " + hasExtension1 +
", cbPixelFormat: " + cbPixelFormat +
diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java
index 00f77dd689..206b7d3162 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfMisc.java
@@ -745,10 +745,22 @@ public class HemfMisc {
@Override
public void applyObject(HwmfGraphics ctx) {
+ if (!bitmap.isValid()) {
+ return;
+ }
HwmfDrawProperties props = ctx.getProperties();
props.setBrushStyle(HwmfBrushStyle.BS_PATTERN);
BufferedImage bmp = bitmap.getImage();
props.setBrushBitmap(bmp);
}
+
+ @Override
+ public String toString() {
+ return
+ "{ penIndex: " + penIndex +
+ ", colorUsage: " + colorUsage +
+ ", bitmap: " + bitmap +
+ "}";
+ }
}
}
diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java
index fb0d2a79aa..f62155d182 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java
@@ -199,7 +199,11 @@ public class HemfText {
@Override
public void draw(HwmfGraphics ctx) {
- ctx.drawString(rawTextBytes, stringLength, reference, bounds, options, dx, isUnicode());
+ // A 32-bit floating-point value that specifies the scale factor to apply along
+ // the axis to convert from page space units to .01mm units.
+ // This SHOULD be used only if the graphics mode specified by iGraphicsMode is GM_COMPATIBLE.
+ Dimension2D scl = graphicsMode == EmfGraphicsMode.GM_COMPATIBLE ? scale : null;
+ ctx.drawString(rawTextBytes, stringLength, reference, scl, bounds, options, dx, isUnicode());
}
@Override
diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfWindowing.java b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfWindowing.java
index 955bbd9f03..a312dc116e 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfWindowing.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfWindowing.java
@@ -19,6 +19,7 @@ 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.readPointL;
+import static org.apache.poi.hwmf.record.HwmfDraw.normalizeBounds;
import java.io.IOException;
@@ -135,7 +136,7 @@ public class HemfWindowing {
@Override
public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
- return HemfDraw.readRectL(leis, bounds);
+ return HemfDraw.readRectL(leis, normalizeBounds(bounds));
}
}
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java b/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java
index 9a58e57014..8b8358c30f 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java
@@ -93,6 +93,8 @@ public class HwmfDrawProperties {
textVAlignAsian = HwmfTextVerticalAlignment.TOP;
rasterOp = HwmfTernaryRasterOp.PATCOPY;
clip = null;
+ font = new HwmfFont();
+ font.initDefaults();
}
public HwmfDrawProperties(HwmfDrawProperties other) {
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java b/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
index 4ecca1e81a..dadb091699 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
@@ -30,6 +30,7 @@ import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
+import java.awt.geom.Dimension2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
@@ -333,8 +334,9 @@ public class HwmfGraphics {
case MM_ANISOTROPIC:
// scale window bounds to output bounds
if (view != null) {
- graphicsCtx.translate(view.getX() - win.getX(), view.getY() - win.getY());
+ graphicsCtx.translate(view.getCenterX(), view.getCenterY());
graphicsCtx.scale(view.getWidth() / win.getWidth(), view.getHeight() / win.getHeight());
+ graphicsCtx.translate(-win.getCenterX(), -win.getCenterY());
}
break;
case MM_ISOTROPIC:
@@ -362,10 +364,10 @@ public class HwmfGraphics {
}
public void drawString(byte[] text, int length, Point2D reference) {
- drawString(text, length, reference, null, null, null, false);
+ drawString(text, length, reference, null, null, null, null, false);
}
- public void drawString(byte[] text, int length, Point2D reference, Rectangle2D clip, WmfExtTextOutOptions opts, List<Integer> dx, boolean isUnicode) {
+ public void drawString(byte[] text, int length, Point2D reference, Dimension2D scale, Rectangle2D clip, WmfExtTextOutOptions opts, List<Integer> dx, boolean isUnicode) {
final HwmfDrawProperties prop = getProperties();
HwmfFont font = prop.getFont();
@@ -489,6 +491,9 @@ public class HwmfGraphics {
graphicsCtx.translate(reference.getX(), reference.getY());
graphicsCtx.rotate(angle);
+ if (scale != null) {
+ graphicsCtx.scale(scale.getWidth() < 0 ? -1 : 1, scale.getHeight() < 0 ? -1 : 1);
+ }
graphicsCtx.translate(dst.getX(), dst.getY());
graphicsCtx.setColor(prop.getTextColor().getColor());
graphicsCtx.drawString(as.getIterator(), 0, 0);
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java
index 1a7e33ec11..a800bb0e05 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java
@@ -45,9 +45,11 @@ import org.apache.poi.util.RecordFormatException;
*/
public class HwmfBitmapDib {
+ private static final POILogger logger = POILogFactory.getLogger(HwmfBitmapDib.class);
+ private static final int BMP_HEADER_SIZE = 14;
private static final int MAX_RECORD_LENGTH = HwmfPicture.MAX_RECORD_LENGTH;
- public static enum BitCount {
+ public enum BitCount {
/**
* The image SHOULD be in either JPEG or PNG format. <6> Neither of these formats includes
* a color table, so this value specifies that no color table is present. See [JFIF] and [RFC2083]
@@ -129,7 +131,7 @@ public class HwmfBitmapDib {
}
}
- public static enum Compression {
+ public enum Compression {
/**
* The bitmap is in uncompressed red green blue (RGB) format that is not compressed
* and does not use color masks.
@@ -198,9 +200,7 @@ public class HwmfBitmapDib {
}
}
- private final static POILogger logger = POILogFactory.getLogger(HwmfBitmapDib.class);
- private static final int BMP_HEADER_SIZE = 14;
-
+
private int headerSize;
private int headerWidth;
private int headerHeight;
@@ -406,7 +406,27 @@ public class HwmfBitmapDib {
}
public boolean isValid() {
- return (imageData != null);
+ // the recordsize ended before the image data
+ if (imageData == null) {
+ return false;
+ }
+
+ // ignore all black mono-brushes
+ if (this.headerBitCount == BitCount.BI_BITCOUNT_1) {
+ if (colorTable == null) {
+ return false;
+ }
+
+ for (Color c : colorTable) {
+ if (!Color.BLACK.equals(c)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ return true;
}
public InputStream getBMPStream() {
@@ -448,6 +468,24 @@ public class HwmfBitmapDib {
}
}
+ @Override
+ public String toString() {
+ return
+ "{ headerSize: " + headerSize +
+ ", width: " + headerWidth +
+ ", height: " + headerHeight +
+ ", planes: " + headerPlanes +
+ ", bitCount: '" + headerBitCount + "'" +
+ ", compression: '" + headerCompression + "'" +
+ ", imageSize: " + headerImageSize +
+ ", xPelsPerMeter: " + headerXPelsPerMeter +
+ ", yPelsPerMeter: " + headerYPelsPerMeter +
+ ", colorUsed: " + headerColorUsed +
+ ", colorImportant: " + headerColorImportant +
+ ", imageSize: " + (imageData == null ? 0 : imageData.length) +
+ "}";
+ }
+
protected BufferedImage getPlaceholder() {
BufferedImage bi = new BufferedImage(headerWidth, headerHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java
index f71becda8a..17cd3c83d8 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java
@@ -763,5 +763,15 @@ public class HwmfDraw {
return "{ w: "+dim.getWidth()+", h: "+dim.getHeight()+" }";
}
+ @Internal
+ public static Rectangle2D normalizeBounds(Rectangle2D bounds) {
+ return (bounds.getWidth() >= 0 && bounds.getHeight() >= 0) ? bounds
+ : new Rectangle2D.Double(
+ bounds.getWidth() >= 0 ? bounds.getMinX() : bounds.getMaxX(),
+ bounds.getHeight() >= 0 ? bounds.getMinY() : bounds.getMaxY(),
+ Math.abs(bounds.getWidth()),
+ Math.abs(bounds.getHeight())
+ );
+ }
}
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java
index 131699f6b3..e353750bd9 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java
@@ -498,7 +498,7 @@ public class HwmfFill {
prop.setRasterOp(rasterOperation);
if (bitmap.isValid()) {
ctx.drawImage(getImage(), srcBounds, dstBounds);
- } else {
+ } else if (!dstBounds.isEmpty()) {
BufferedImage bi = new BufferedImage((int)dstBounds.getWidth(), (int)dstBounds.getHeight(), BufferedImage.TYPE_INT_ARGB);
ctx.drawImage(bi, dstBounds, dstBounds);
}
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java
index 8cb8486771..4413983ef3 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java
@@ -369,6 +369,21 @@ public class HwmfFont implements FontInfo {
return 5*LittleEndianConsts.SHORT_SIZE+8*LittleEndianConsts.BYTE_SIZE+readBytes;
}
+ public void initDefaults() {
+ height = -12;
+ width = 0;
+ escapement = 0;
+ weight = 400;
+ italic = false;
+ underline = false;
+ strikeOut = false;
+ charSet = FontCharset.ANSI;
+ outPrecision = WmfOutPrecision.OUT_DEFAULT_PRECIS;
+ quality = WmfFontQuality.ANTIALIASED_QUALITY;
+ pitchAndFamily = FontFamily.FF_DONTCARE.getFlag() | (FontPitch.DEFAULT.getNativeId() << 6);
+ facename = "SansSerif";
+ }
+
public int getHeight() {
return height;
}
@@ -479,7 +494,7 @@ public class HwmfFont implements FontInfo {
", charset: '"+charSet+"'"+
", outPrecision: '"+outPrecision+"'"+
", clipPrecision: '"+clipPrecision+"'"+
- ", qualtiy: '"+quality+"'"+
+ ", quality: '"+quality+"'"+
", pitch: '"+getPitch()+"'"+
", family: '"+getFamily()+"'"+
", facename: '"+facename+"'"+
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java
index 7303d2c6fe..eef15e30d7 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java
@@ -454,6 +454,9 @@ public class HwmfMisc {
@Override
public void applyObject(HwmfGraphics ctx) {
+ if (patternDib != null && !patternDib.isValid()) {
+ return;
+ }
HwmfDrawProperties prop = ctx.getProperties();
prop.setBrushStyle(style);
prop.setBrushBitmap(getImage());
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
index 020e6148d4..391215d657 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
@@ -391,7 +391,7 @@ public class HwmfText {
@Override
public void draw(HwmfGraphics ctx) {
- ctx.drawString(rawTextBytes, stringLength, reference, bounds, options, dx, false);
+ ctx.drawString(rawTextBytes, stringLength, reference, null, bounds, options, dx, false);
}
public String getText(Charset charset) throws IOException {
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java
index a3fb60bd1d..34c948df02 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java
@@ -18,6 +18,7 @@
package org.apache.poi.hwmf.record;
import static org.apache.poi.hwmf.record.HwmfDraw.boundsToString;
+import static org.apache.poi.hwmf.record.HwmfDraw.normalizeBounds;
import static org.apache.poi.hwmf.record.HwmfDraw.pointToString;
import static org.apache.poi.hwmf.record.HwmfDraw.readBounds;
import static org.apache.poi.hwmf.record.HwmfDraw.readPointS;
@@ -398,6 +399,7 @@ public class HwmfWindowing {
@Override
public void applyObject(HwmfGraphics ctx) {
+ ctx.setClip(normalizeBounds(bounds), HwmfRegionMode.RGN_DIFF, false);
}
@Override