aboutsummaryrefslogtreecommitdiffstats
path: root/src/scratchpad
diff options
context:
space:
mode:
authorAndreas Beeker <kiwiwings@apache.org>2020-08-30 11:18:21 +0000
committerAndreas Beeker <kiwiwings@apache.org>2020-08-30 11:18:21 +0000
commitb00ca445b2eee110df17fba5f8afd64260c16174 (patch)
tree049f6ecfd3b8dd02bc15f53b04679b7210c8a295 /src/scratchpad
parentf89528addc51729a438eb5732129b87c2d87b4b9 (diff)
downloadpoi-b00ca445b2eee110df17fba5f8afd64260c16174.tar.gz
poi-b00ca445b2eee110df17fba5f8afd64260c16174.zip
#64693 - POI HwmfGraphics cannot read the embedded document title
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1881322 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/scratchpad')
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/draw/HemfImageRenderer.java14
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java21
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfText.java1
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusDraw.java6
-rw-r--r--src/scratchpad/src/org/apache/poi/hemf/usermodel/HemfPicture.java15
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java46
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfImageRenderer.java20
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java11
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java27
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfCharsetAware.java30
-rw-r--r--src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java24
11 files changed, 184 insertions, 31 deletions
diff --git a/src/scratchpad/src/org/apache/poi/hemf/draw/HemfImageRenderer.java b/src/scratchpad/src/org/apache/poi/hemf/draw/HemfImageRenderer.java
index 42cef834a9..95d3b7e70a 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/draw/HemfImageRenderer.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/draw/HemfImageRenderer.java
@@ -28,12 +28,14 @@ import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.charset.Charset;
import org.apache.poi.common.usermodel.GenericRecord;
import org.apache.poi.hemf.usermodel.HemfPicture;
import org.apache.poi.hwmf.draw.HwmfGraphicsState;
import org.apache.poi.hwmf.draw.HwmfImageRenderer;
import org.apache.poi.sl.draw.BitmapImageRenderer;
+import org.apache.poi.sl.draw.Drawable;
import org.apache.poi.sl.draw.EmbeddedExtractor;
import org.apache.poi.sl.draw.ImageRenderer;
import org.apache.poi.sl.usermodel.PictureData;
@@ -43,6 +45,7 @@ import org.apache.poi.util.Units;
public class HemfImageRenderer implements ImageRenderer, EmbeddedExtractor {
HemfPicture image;
double alpha;
+ boolean charsetInitialized = false;
@Override
public boolean canRender(String contentType) {
@@ -104,6 +107,11 @@ public class HemfImageRenderer implements ImageRenderer, EmbeddedExtractor {
return false;
}
+ Charset cs = (Charset)graphics.getRenderingHint(Drawable.DEFAULT_CHARSET);
+ if (cs != null && !charsetInitialized) {
+ setDefaultCharset(cs);
+ }
+
HwmfGraphicsState graphicsState = new HwmfGraphicsState();
graphicsState.backup(graphics);
@@ -141,4 +149,10 @@ public class HemfImageRenderer implements ImageRenderer, EmbeddedExtractor {
public Rectangle2D getBounds() {
return Units.pointsToPixel(image == null ? new Rectangle2D.Double() : image.getBoundsInPoints());
}
+
+ @Override
+ public void setDefaultCharset(Charset defaultCharset) {
+ image.setDefaultCharset(defaultCharset);
+ charsetInitialized = true;
+ }
}
diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java
index 4b1060b7bd..0d055d340f 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java
@@ -19,6 +19,7 @@ package org.apache.poi.hemf.record.emf;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
+import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
@@ -33,6 +34,7 @@ import org.apache.poi.hemf.draw.HemfGraphics;
import org.apache.poi.hemf.draw.HemfGraphics.EmfRenderState;
import org.apache.poi.hemf.record.emfplus.HemfPlusRecord;
import org.apache.poi.hemf.record.emfplus.HemfPlusRecordIterator;
+import org.apache.poi.hwmf.usermodel.HwmfCharsetAware;
import org.apache.poi.hwmf.usermodel.HwmfPicture;
import org.apache.poi.util.GenericRecordJsonWriter;
import org.apache.poi.util.GenericRecordUtil;
@@ -105,7 +107,7 @@ public class HemfComment {
}
}
- public static class EmfComment implements HemfRecord {
+ public static class EmfComment implements HemfRecord, HwmfCharsetAware {
private EmfCommentData data;
@Override
@@ -146,6 +148,13 @@ public class HemfComment {
}
assert(commentIdentifier == commentType.id);
}
+
+ @Override
+ public void setCharsetProvider(Supplier<Charset> provider) {
+ if (data instanceof HwmfCharsetAware) {
+ ((HwmfCharsetAware)data).setCharsetProvider(provider);
+ }
+ }
}
public static class EmfCommentDataIterator implements Iterator<EmfCommentData> {
@@ -250,8 +259,9 @@ public class HemfComment {
* Private data is unknown to EMF; it is meaningful only to applications that know the format of the
* data and how to use it. EMR_COMMENT private data records MAY be ignored.
*/
- public static class EmfCommentDataGeneric implements EmfCommentData {
+ public static class EmfCommentDataGeneric implements EmfCommentData, HwmfCharsetAware {
private byte[] privateData;
+ private Supplier<Charset> charsetProvider = () -> LocaleUtil.CHARSET_1252;
@Override
public HemfCommentRecordType getCommentRecordType() {
@@ -275,7 +285,7 @@ public class HemfComment {
}
public String getPrivateDataAsString() {
- return new String(privateData, LocaleUtil.CHARSET_1252);
+ return new String(privateData, charsetProvider.get());
}
@Override
@@ -285,6 +295,11 @@ public class HemfComment {
"privateDataAsString", this::getPrivateDataAsString
);
}
+
+ @Override
+ public void setCharsetProvider(Supplier<Charset> provider) {
+ charsetProvider = provider;
+ }
}
/** The EMR_COMMENT_EMFPLUS record contains embedded EMF+ records. */
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 e7d9947b72..c10c004f51 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
@@ -206,6 +206,7 @@ public class HemfText {
// 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.setCharsetProvider(charsetProvider);
ctx.drawString(rawTextBytes, stringLength, reference, scl, bounds, options, dx, isUnicode());
}
diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusDraw.java b/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusDraw.java
index 5df76bde68..9f45de5e8a 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusDraw.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusDraw.java
@@ -28,6 +28,7 @@ import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
@@ -37,7 +38,6 @@ import java.util.PrimitiveIterator.OfInt;
import java.util.function.BiFunction;
import java.util.function.Supplier;
-import org.apache.commons.codec.Charsets;
import org.apache.commons.math3.linear.LUDecomposition;
import org.apache.commons.math3.linear.MatrixUtils;
import org.apache.commons.math3.linear.RealMatrix;
@@ -748,12 +748,12 @@ public final class HemfPlusDraw {
}
if (REALIZED_ADVANCE.isSet(optionsFlags)) {
- byte[] buf = glyphs.getBytes(Charsets.UTF_16LE);
+ byte[] buf = glyphs.getBytes(StandardCharsets.UTF_16LE);
ctx.drawString(buf, buf.length, glyphPos.get(0), null, null, null, null, true);
} else {
final OfInt glyphIter = glyphs.codePoints().iterator();
glyphPos.forEach(p -> {
- byte[] buf = new String(new int[]{glyphIter.next()}, 0, 1).getBytes(Charsets.UTF_16LE);
+ byte[] buf = new String(new int[]{glyphIter.next()}, 0, 1).getBytes(StandardCharsets.UTF_16LE);
ctx.drawString(buf, buf.length, p, null, null, null, null, true);
});
}
diff --git a/src/scratchpad/src/org/apache/poi/hemf/usermodel/HemfPicture.java b/src/scratchpad/src/org/apache/poi/hemf/usermodel/HemfPicture.java
index b9ae90f0af..c94fb8ac4b 100644
--- a/src/scratchpad/src/org/apache/poi/hemf/usermodel/HemfPicture.java
+++ b/src/scratchpad/src/org/apache/poi/hemf/usermodel/HemfPicture.java
@@ -26,6 +26,7 @@ import java.awt.geom.AffineTransform;
import java.awt.geom.Dimension2D;
import java.awt.geom.Rectangle2D;
import java.io.InputStream;
+import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -41,10 +42,12 @@ import org.apache.poi.hemf.record.emf.HemfHeader;
import org.apache.poi.hemf.record.emf.HemfRecord;
import org.apache.poi.hemf.record.emf.HemfRecordIterator;
import org.apache.poi.hemf.record.emf.HemfWindowing;
+import org.apache.poi.hwmf.usermodel.HwmfCharsetAware;
import org.apache.poi.hwmf.usermodel.HwmfEmbedded;
import org.apache.poi.util.Dimension2DDouble;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LittleEndianInputStream;
+import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.Units;
/**
@@ -55,6 +58,7 @@ public class HemfPicture implements Iterable<HemfRecord>, GenericRecord {
private final LittleEndianInputStream stream;
private final List<HemfRecord> records = new ArrayList<>();
private boolean isParsed = false;
+ private Charset defaultCharset = LocaleUtil.CHARSET_1252;
public HemfPicture(InputStream is) {
this(new LittleEndianInputStream(is));
@@ -79,6 +83,9 @@ public class HemfPicture implements Iterable<HemfRecord>, GenericRecord {
header[0] = (HemfHeader) r;
}
r.setHeader(header[0]);
+ if (r instanceof HwmfCharsetAware) {
+ ((HwmfCharsetAware)r).setCharsetProvider(this::getDefaultCharset);
+ }
records.add(r);
});
}
@@ -199,4 +206,12 @@ public class HemfPicture implements Iterable<HemfRecord>, GenericRecord {
public Map<String, Supplier<?>> getGenericProperties() {
return null;
}
+
+ public void setDefaultCharset(Charset defaultCharset) {
+ this.defaultCharset = defaultCharset;
+ }
+
+ public Charset getDefaultCharset() {
+ return defaultCharset;
+ }
}
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 cf35b716ae..38b473da03 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
@@ -40,6 +40,7 @@ import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.text.AttributedString;
import java.util.ArrayList;
import java.util.BitSet;
@@ -51,8 +52,9 @@ import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.TreeMap;
import java.util.function.BiConsumer;
+import java.util.function.Supplier;
-import org.apache.commons.codec.Charsets;
+import org.apache.poi.common.usermodel.fonts.FontCharset;
import org.apache.poi.common.usermodel.fonts.FontInfo;
import org.apache.poi.hwmf.record.HwmfBrushStyle;
import org.apache.poi.hwmf.record.HwmfFont;
@@ -64,6 +66,7 @@ import org.apache.poi.hwmf.record.HwmfPenStyle;
import org.apache.poi.hwmf.record.HwmfPenStyle.HwmfLineDash;
import org.apache.poi.hwmf.record.HwmfRegionMode;
import org.apache.poi.hwmf.record.HwmfText.WmfExtTextOutOptions;
+import org.apache.poi.hwmf.usermodel.HwmfCharsetAware;
import org.apache.poi.sl.draw.BitmapImageRenderer;
import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.DrawFontManager;
@@ -72,7 +75,7 @@ import org.apache.poi.sl.draw.ImageRenderer;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LocaleUtil;
-public class HwmfGraphics {
+public class HwmfGraphics implements HwmfCharsetAware {
public enum FillDrawStyle {
NONE(FillDrawStyle::fillNone),
@@ -128,9 +131,9 @@ public class HwmfGraphics {
private final AffineTransform initialAT = new AffineTransform();
- private static final Charset DEFAULT_CHARSET = LocaleUtil.CHARSET_1252;
/** Bounding box from the placeable header */
private final Rectangle2D bbox;
+ private Supplier<Charset> charsetProvider = () -> LocaleUtil.CHARSET_1252;
/**
* Initialize a graphics context for wmf rendering
@@ -595,16 +598,26 @@ public class HwmfGraphics {
}
}
- private static Charset getCharset(HwmfFont font, boolean isUnicode) {
+ private Charset getCharset(HwmfFont font, boolean isUnicode) {
if (isUnicode) {
- return Charsets.UTF_16LE;
+ return StandardCharsets.UTF_16LE;
}
- Charset charset = font.getCharset().getCharset();
- return (charset == null) ? DEFAULT_CHARSET : charset;
+ FontCharset fc = font.getCharset();
+ if (fc == FontCharset.DEFAULT) {
+ return charsetProvider.get();
+ }
+
+ Charset charset = fc.getCharset();
+ return (charset == null) ? charsetProvider.get() : charset;
}
- private static String trimText(HwmfFont font, boolean isUnicode, byte[] text, int length) {
+ @Override
+ public void setCharsetProvider(Supplier<Charset> provider) {
+ charsetProvider = provider;
+ }
+
+ private String trimText(HwmfFont font, boolean isUnicode, byte[] text, int length) {
final Charset charset = getCharset(font, isUnicode);
int trimLen;
@@ -717,7 +730,9 @@ public class HwmfGraphics {
graphicsCtx.fill(dstBounds);
break;
default:
+ case SRCAND:
case SRCCOPY:
+ case SRCINVERT:
if (img == null) {
return;
}
@@ -746,7 +761,20 @@ public class HwmfGraphics {
// the difference is, that clippings are 0-based, whereas the srcBounds are absolute in the user-space
// of the referenced image and can be also negative
Composite old = graphicsCtx.getComposite();
- graphicsCtx.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
+ int newComp;
+ switch (prop.getRasterOp()) {
+ default:
+ case SRCCOPY:
+ newComp = AlphaComposite.SRC_OVER;
+ break;
+ case SRCINVERT:
+ newComp = AlphaComposite.SRC_IN;
+ break;
+ case SRCAND:
+ newComp = AlphaComposite.SRC;
+ break;
+ }
+ graphicsCtx.setComposite(AlphaComposite.getInstance(newComp));
boolean useDeviceBounds = (img instanceof HwmfImageRenderer);
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfImageRenderer.java b/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfImageRenderer.java
index 68abb2432c..9a44028f07 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfImageRenderer.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfImageRenderer.java
@@ -27,6 +27,7 @@ import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.charset.Charset;
import java.util.Iterator;
import org.apache.poi.common.usermodel.GenericRecord;
@@ -34,6 +35,7 @@ import org.apache.poi.hwmf.usermodel.HwmfEmbedded;
import org.apache.poi.hwmf.usermodel.HwmfPicture;
import org.apache.poi.sl.draw.BitmapImageRenderer;
import org.apache.poi.sl.draw.DrawPictureShape;
+import org.apache.poi.sl.draw.Drawable;
import org.apache.poi.sl.draw.EmbeddedExtractor;
import org.apache.poi.sl.draw.ImageRenderer;
import org.apache.poi.sl.usermodel.PictureData.PictureType;
@@ -47,6 +49,7 @@ import org.apache.poi.util.Units;
public class HwmfImageRenderer implements ImageRenderer, EmbeddedExtractor {
HwmfPicture image;
double alpha;
+ boolean charsetInitialized = false;
@Override
public boolean canRender(String contentType) {
@@ -87,9 +90,9 @@ public class HwmfImageRenderer implements ImageRenderer, EmbeddedExtractor {
@Override
public BufferedImage getImage(Dimension2D dim) {
if (image == null) {
- return new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
+ return new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
}
-
+
BufferedImage bufImg = new BufferedImage((int)dim.getWidth(), (int)dim.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bufImg.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
@@ -101,7 +104,7 @@ public class HwmfImageRenderer implements ImageRenderer, EmbeddedExtractor {
return BitmapImageRenderer.setAlpha(bufImg, alpha);
}
-
+
@Override
public boolean drawImage(Graphics2D graphics, Rectangle2D anchor) {
return drawImage(graphics, anchor, null);
@@ -113,6 +116,11 @@ public class HwmfImageRenderer implements ImageRenderer, EmbeddedExtractor {
return false;
}
+ Charset cs = (Charset)graphics.getRenderingHint(Drawable.DEFAULT_CHARSET);
+ if (cs != null && !charsetInitialized) {
+ setDefaultCharset(cs);
+ }
+
HwmfGraphicsState graphicsState = new HwmfGraphicsState();
graphicsState.backup(graphics);
@@ -185,4 +193,10 @@ public class HwmfImageRenderer implements ImageRenderer, EmbeddedExtractor {
public Rectangle2D getBounds() {
return Units.pointsToPixel(image == null ? new Rectangle2D.Double() : image.getBoundsInPoints());
}
+
+ @Override
+ public void setDefaultCharset(Charset defaultCharset) {
+ image.setDefaultCharset(defaultCharset);
+ charsetInitialized = true;
+ }
}
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 bca708b7f7..85c2d4efe9 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java
@@ -485,11 +485,14 @@ public class HwmfBitmapDib implements GenericRecord {
if (foreground != null && background != null && headerBitCount == HwmfBitmapDib.BitCount.BI_BITCOUNT_1) {
IndexColorModel cmOld = (IndexColorModel)bi.getColorModel();
- int transPixel = hasAlpha ? (((cmOld.getRGB(0) & 0xFFFFFF) == 0) ? 0 : 1) : -1;
+ int fg = foreground.getRGB();
+ int bg = background.getRGB() & (hasAlpha ? 0xFFFFFF : 0xFFFFFFFF);
+ boolean ordered = (cmOld.getRGB(0) & 0xFFFFFF) == (bg & 0xFFFFFF);
+ int transPixel = ordered ? 0 : 1;
+ int[] cmap = ordered ? new int[]{ bg, fg } : new int[]{ fg, bg };
int transferType = bi.getData().getTransferType();
- int fg = foreground.getRGB(), bg = background.getRGB();
- int[] cmap = { (transPixel == 0 ? bg : fg), (transPixel == 1 ? bg : fg) };
- IndexColorModel cmNew = new IndexColorModel(1, cmap.length, cmap, 0, hasAlpha, transPixel, transferType);
+
+ IndexColorModel cmNew = new IndexColorModel(1, 2, cmap, 0, hasAlpha, transPixel, transferType);
bi = new BufferedImage(cmNew, bi.getRaster(), false, null);
}
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 15f88d5e6f..cc29087c69 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
@@ -35,6 +35,7 @@ import org.apache.poi.common.usermodel.GenericRecord;
import org.apache.poi.hwmf.draw.HwmfDrawProperties;
import org.apache.poi.hwmf.draw.HwmfGraphics;
import org.apache.poi.hwmf.record.HwmfMisc.WmfSetMapMode;
+import org.apache.poi.hwmf.usermodel.HwmfCharsetAware;
import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.GenericRecordJsonWriter;
@@ -42,6 +43,7 @@ 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.LocaleUtil;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
@@ -172,7 +174,7 @@ public class HwmfText {
* The META_TEXTOUT record outputs a character string at the specified location by using the font,
* background color, and text color that are defined in the playback device context.
*/
- public static class WmfTextOut implements HwmfRecord {
+ public static class WmfTextOut implements HwmfRecord, HwmfCharsetAware {
/**
* A 16-bit signed integer that defines the length of the string, in bytes, pointed to by String.
*/
@@ -189,6 +191,8 @@ public class HwmfText {
protected Point2D reference = new Point2D.Double();
+ protected Supplier<Charset> charsetProvider = () -> LocaleUtil.CHARSET_1252;
+
@Override
public HwmfRecordType getWmfRecordType() {
return HwmfRecordType.textOut;
@@ -211,6 +215,7 @@ public class HwmfText {
@Override
public void draw(HwmfGraphics ctx) {
+ ctx.setCharsetProvider(charsetProvider);
ctx.drawString(getTextBytes(), stringLength, reference);
}
@@ -235,6 +240,11 @@ public class HwmfText {
"reference", () -> reference
);
}
+
+ @Override
+ public void setCharsetProvider(Supplier<Charset> provider) {
+ charsetProvider = provider;
+ }
}
@SuppressWarnings("unused")
@@ -343,7 +353,7 @@ public class HwmfText {
* are defined in the playback device context. Optionally, dimensions can be provided for clipping,
* opaquing, or both.
*/
- public static class WmfExtTextOut implements HwmfRecord {
+ public static class WmfExtTextOut implements HwmfRecord, HwmfCharsetAware {
/**
* The location, in logical units, where the text string is to be placed.
*/
@@ -383,6 +393,8 @@ public class HwmfText {
*/
protected final List<Integer> dx = new ArrayList<>();
+ protected Supplier<Charset> charsetProvider = () -> LocaleUtil.CHARSET_1252;
+
public WmfExtTextOut() {
this(new WmfExtTextOutOptions());
}
@@ -437,6 +449,7 @@ public class HwmfText {
@Override
public void draw(HwmfGraphics ctx) {
+ ctx.setCharsetProvider(charsetProvider);
ctx.drawString(rawTextBytes, stringLength, reference, null, bounds, options, dx, false);
}
@@ -445,8 +458,7 @@ public class HwmfText {
return "";
}
String ret = new String(rawTextBytes, charset);
- return ret.substring(0,
- Math.min(ret.length(), stringLength));
+ return ret.substring(0, Math.min(ret.length(), stringLength));
}
public Point2D getReference() {
@@ -468,7 +480,7 @@ public class HwmfText {
private String getGenericText() {
try {
- return getText(isUnicode() ? StandardCharsets.UTF_16LE : StandardCharsets.US_ASCII);
+ return getText(isUnicode() ? StandardCharsets.UTF_16LE : charsetProvider.get());
} catch (IOException e) {
return "";
}
@@ -483,6 +495,11 @@ public class HwmfText {
"dx", () -> dx
);
}
+
+ @Override
+ public void setCharsetProvider(Supplier<Charset> provider) {
+ charsetProvider = provider;
+ }
}
public enum HwmfTextAlignment {
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfCharsetAware.java b/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfCharsetAware.java
new file mode 100644
index 0000000000..1897278420
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfCharsetAware.java
@@ -0,0 +1,30 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.hwmf.usermodel;
+
+import java.nio.charset.Charset;
+import java.util.function.Supplier;
+
+/**
+ * Helper interface to provide a default charset to records which would depend on a system charset
+ */
+public interface HwmfCharsetAware {
+ void setCharsetProvider(Supplier<Charset> provider);
+}
diff --git a/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java b/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java
index a33ea0ff1d..3eccdb6800 100644
--- a/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java
+++ b/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java
@@ -24,6 +24,7 @@ import java.awt.geom.Dimension2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
@@ -46,6 +47,7 @@ import org.apache.poi.hwmf.record.HwmfWindowing.WmfSetWindowOrg;
import org.apache.poi.util.Dimension2DDouble;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LittleEndianInputStream;
+import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.RecordFormatException;
@@ -56,11 +58,13 @@ public class HwmfPicture implements Iterable<HwmfRecord>, GenericRecord {
public static final int MAX_RECORD_LENGTH = 50_000_000;
private static final POILogger logger = POILogFactory.getLogger(HwmfPicture.class);
-
+
final List<HwmfRecord> records = new ArrayList<>();
final HwmfPlaceableHeader placeableHeader;
final HwmfHeader header;
-
+ /** The default charset */
+ private Charset defaultCharset = LocaleUtil.CHARSET_1252;
+
public HwmfPicture(InputStream inputStream) throws IOException {
try (LittleEndianInputStream leis = new LittleEndianInputStream(inputStream)) {
@@ -110,6 +114,10 @@ public class HwmfPicture implements Iterable<HwmfRecord>, GenericRecord {
throw new RecordFormatException("Tried to skip "+remainingSize + " but skipped: "+skipped);
}
}
+
+ if (wr instanceof HwmfCharsetAware) {
+ ((HwmfCharsetAware)wr).setCharsetProvider(this::getDefaultCharset);
+ }
}
}
}
@@ -126,7 +134,7 @@ public class HwmfPicture implements Iterable<HwmfRecord>, GenericRecord {
Rectangle2D bounds = new Rectangle2D.Double(0,0,width,height);
draw(ctx, bounds);
}
-
+
public void draw(Graphics2D ctx, Rectangle2D graphicsBounds) {
HwmfGraphicsState state = new HwmfGraphicsState();
state.backup(ctx);
@@ -198,7 +206,7 @@ public class HwmfPicture implements Iterable<HwmfRecord>, GenericRecord {
}
if (wOrg != null && wExt != null) {
return new Rectangle2D.Double(wOrg.getX(), wOrg.getY(), wExt.getSize().getWidth(), wExt.getSize().getHeight());
- }
+ }
}
return null;
}
@@ -260,4 +268,12 @@ public class HwmfPicture implements Iterable<HwmfRecord>, GenericRecord {
public List<? extends GenericRecord> getGenericChildren() {
return getRecords();
}
+
+ public void setDefaultCharset(Charset defaultCharset) {
+ this.defaultCharset = defaultCharset;
+ }
+
+ public Charset getDefaultCharset() {
+ return defaultCharset;
+ }
}