diff options
author | Andreas Beeker <kiwiwings@apache.org> | 2020-08-30 11:18:21 +0000 |
---|---|---|
committer | Andreas Beeker <kiwiwings@apache.org> | 2020-08-30 11:18:21 +0000 |
commit | b00ca445b2eee110df17fba5f8afd64260c16174 (patch) | |
tree | 049f6ecfd3b8dd02bc15f53b04679b7210c8a295 /src/scratchpad | |
parent | f89528addc51729a438eb5732129b87c2d87b4b9 (diff) | |
download | poi-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')
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; + } } |