mirror of https://github.com/apache/poi.git
#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
This commit is contained in:
parent
f89528addc
commit
b00ca445b2
|
@ -48,6 +48,7 @@ public interface Drawable {
|
||||||
case 11: return "GRESTORE";
|
case 11: return "GRESTORE";
|
||||||
case 12: return "CURRENT_SLIDE";
|
case 12: return "CURRENT_SLIDE";
|
||||||
case 13: return "BUFFERED_IMAGE";
|
case 13: return "BUFFERED_IMAGE";
|
||||||
|
case 14: return "DEFAULT_CHARSET";
|
||||||
default: return "UNKNOWN_ID "+intKey();
|
default: return "UNKNOWN_ID "+intKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,6 +146,14 @@ public interface Drawable {
|
||||||
*/
|
*/
|
||||||
DrawableHint BUFFERED_IMAGE = new DrawableHint(13);
|
DrawableHint BUFFERED_IMAGE = new DrawableHint(13);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the default charset to render text elements.
|
||||||
|
* Opposed to other windows libraries in POI this simply defaults to Windows-1252.
|
||||||
|
* The rendering value is of type {@link java.nio.charset.Charset}
|
||||||
|
*/
|
||||||
|
DrawableHint DEFAULT_CHARSET = new DrawableHint(14);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply 2-D transforms before drawing this shape. This includes rotation and flipping.
|
* Apply 2-D transforms before drawing this shape. This includes rotation and flipping.
|
||||||
*
|
*
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.awt.geom.Rectangle2D;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
import org.apache.poi.common.usermodel.GenericRecord;
|
import org.apache.poi.common.usermodel.GenericRecord;
|
||||||
import org.apache.poi.util.Dimension2DDouble;
|
import org.apache.poi.util.Dimension2DDouble;
|
||||||
|
@ -154,4 +155,11 @@ public interface ImageRenderer {
|
||||||
|
|
||||||
default GenericRecord getGenericRecord() { return null; }
|
default GenericRecord getGenericRecord() { return null; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the default charset to render text elements.
|
||||||
|
* Opposed to other windows libraries in POI this simply defaults to Windows-1252.
|
||||||
|
*
|
||||||
|
* @param defaultCharset the default charset
|
||||||
|
*/
|
||||||
|
default void setDefaultCharset(Charset defaultCharset) {}
|
||||||
}
|
}
|
|
@ -26,6 +26,12 @@ import java.awt.geom.Path2D;
|
||||||
import java.awt.geom.PathIterator;
|
import java.awt.geom.PathIterator;
|
||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.awt.image.ColorModel;
|
||||||
|
import java.awt.image.ComponentColorModel;
|
||||||
|
import java.awt.image.DirectColorModel;
|
||||||
|
import java.awt.image.IndexColorModel;
|
||||||
|
import java.awt.image.PackedColorModel;
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
@ -58,6 +64,7 @@ public class GenericRecordJsonWriter implements Closeable {
|
||||||
private static final Pattern ESC_CHARS = Pattern.compile("[\"\\p{Cntrl}\\\\]");
|
private static final Pattern ESC_CHARS = Pattern.compile("[\"\\p{Cntrl}\\\\]");
|
||||||
private static final String NL = System.getProperty("line.separator");
|
private static final String NL = System.getProperty("line.separator");
|
||||||
|
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
protected interface GenericRecordHandler {
|
protected interface GenericRecordHandler {
|
||||||
/**
|
/**
|
||||||
|
@ -92,6 +99,7 @@ public class GenericRecordJsonWriter implements Closeable {
|
||||||
handler(Path2D.class, GenericRecordJsonWriter::printPath);
|
handler(Path2D.class, GenericRecordJsonWriter::printPath);
|
||||||
handler(AffineTransform.class, GenericRecordJsonWriter::printAffineTransform);
|
handler(AffineTransform.class, GenericRecordJsonWriter::printAffineTransform);
|
||||||
handler(Color.class, GenericRecordJsonWriter::printColor);
|
handler(Color.class, GenericRecordJsonWriter::printColor);
|
||||||
|
handler(BufferedImage.class, GenericRecordJsonWriter::printImage);
|
||||||
handler(Array.class, GenericRecordJsonWriter::printArray);
|
handler(Array.class, GenericRecordJsonWriter::printArray);
|
||||||
handler(Object.class, GenericRecordJsonWriter::printObject);
|
handler(Object.class, GenericRecordJsonWriter::printObject);
|
||||||
}
|
}
|
||||||
|
@ -483,6 +491,40 @@ public class GenericRecordJsonWriter implements Closeable {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean printImage(String name, Object o) {
|
||||||
|
BufferedImage img = (BufferedImage)o;
|
||||||
|
|
||||||
|
final String[] COLOR_SPACES = {
|
||||||
|
"XYZ","Lab","Luv","YCbCr","Yxy","RGB","GRAY","HSV","HLS","CMYK","Unknown","CMY","Unknown"
|
||||||
|
};
|
||||||
|
|
||||||
|
final String[] IMAGE_TYPES = {
|
||||||
|
"CUSTOM","INT_RGB","INT_ARGB","INT_ARGB_PRE","INT_BGR","3BYTE_BGR","4BYTE_ABGR","4BYTE_ABGR_PRE",
|
||||||
|
"USHORT_565_RGB","USHORT_555_RGB","BYTE_GRAY","USHORT_GRAY","BYTE_BINARY","BYTE_INDEXED"
|
||||||
|
};
|
||||||
|
|
||||||
|
printName(name);
|
||||||
|
ColorModel cm = img.getColorModel();
|
||||||
|
String colorType =
|
||||||
|
(cm instanceof IndexColorModel) ? "indexed" :
|
||||||
|
(cm instanceof ComponentColorModel) ? "component" :
|
||||||
|
(cm instanceof DirectColorModel) ? "direct" :
|
||||||
|
(cm instanceof PackedColorModel) ? "packed" : "unknown";
|
||||||
|
fw.write(
|
||||||
|
"{ \"width\": "+img.getWidth()+
|
||||||
|
", \"height\": "+img.getHeight()+
|
||||||
|
", \"type\": \""+IMAGE_TYPES[img.getType()]+"\""+
|
||||||
|
", \"colormodel\": \""+colorType+"\""+
|
||||||
|
", \"pixelBits\": "+cm.getPixelSize()+
|
||||||
|
", \"numComponents\": "+cm.getNumComponents()+
|
||||||
|
", \"colorSpace\": \""+COLOR_SPACES[Math.min(cm.getColorSpace().getType(),12)]+"\""+
|
||||||
|
", \"transparency\": "+cm.getTransparency()+
|
||||||
|
", \"alpha\": "+cm.hasAlpha()+
|
||||||
|
"}"
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static String trimHex(final long l, final int size) {
|
static String trimHex(final long l, final int size) {
|
||||||
final String b = Long.toHexString(l);
|
final String b = Long.toHexString(l);
|
||||||
int len = b.length();
|
int len = b.length();
|
||||||
|
|
|
@ -738,7 +738,9 @@ public class XSLFTextRun implements TextRun {
|
||||||
// SYMBOL is missing
|
// SYMBOL is missing
|
||||||
|
|
||||||
if (font == null || !font.isSetTypeface() || "".equals(font.getTypeface())) {
|
if (font == null || !font.isSetTypeface() || "".equals(font.getTypeface())) {
|
||||||
font = coll.getLatin();
|
// don't fallback to latin but bubble up in the style hierarchy (slide -> layout -> master -> theme)
|
||||||
|
return null;
|
||||||
|
// font = coll.getLatin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.awt.geom.Rectangle2D;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import org.apache.poi.common.usermodel.GenericRecord;
|
import org.apache.poi.common.usermodel.GenericRecord;
|
||||||
|
@ -111,4 +112,9 @@ class EMFHandler extends MFProxy {
|
||||||
? ((EmbeddedExtractor) imgr).getEmbeddings()
|
? ((EmbeddedExtractor) imgr).getEmbeddings()
|
||||||
: Collections.emptyList();
|
: Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void setDefaultCharset(Charset charset) {
|
||||||
|
imgr.setDefaultCharset(charset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.io.Closeable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -64,4 +65,6 @@ abstract class MFProxy implements Closeable {
|
||||||
abstract GenericRecord getRoot();
|
abstract GenericRecord getRoot();
|
||||||
|
|
||||||
abstract Iterable<EmbeddedPart> getEmbeddings(int slideNo);
|
abstract Iterable<EmbeddedPart> getEmbeddings(int slideNo);
|
||||||
|
|
||||||
|
abstract void setDefaultCharset(Charset charset);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.awt.geom.Dimension2D;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Spliterator;
|
import java.util.Spliterator;
|
||||||
import java.util.Spliterators;
|
import java.util.Spliterators;
|
||||||
|
@ -49,12 +50,14 @@ import org.apache.poi.sl.usermodel.SlideShow;
|
||||||
import org.apache.poi.sl.usermodel.SlideShowFactory;
|
import org.apache.poi.sl.usermodel.SlideShowFactory;
|
||||||
import org.apache.poi.util.IOUtils;
|
import org.apache.poi.util.IOUtils;
|
||||||
import org.apache.poi.util.Internal;
|
import org.apache.poi.util.Internal;
|
||||||
|
import org.apache.poi.util.LocaleUtil;
|
||||||
|
|
||||||
/** Handler for ppt and pptx files */
|
/** Handler for ppt and pptx files */
|
||||||
@Internal
|
@Internal
|
||||||
class PPTHandler extends MFProxy {
|
class PPTHandler extends MFProxy {
|
||||||
private SlideShow<?,?> ppt;
|
private SlideShow<?,?> ppt;
|
||||||
private Slide<?,?> slide;
|
private Slide<?,?> slide;
|
||||||
|
private Charset defaultCharset = LocaleUtil.CHARSET_1252;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void parse(File file) throws IOException {
|
public void parse(File file) throws IOException {
|
||||||
|
@ -67,6 +70,9 @@ class PPTHandler extends MFProxy {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ppt == null) {
|
||||||
|
throw new IOException("Unknown file format or missing poi-scratchpad.jar / poi-ooxml.jar");
|
||||||
|
}
|
||||||
slide = ppt.getSlides().get(0);
|
slide = ppt.getSlides().get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +87,9 @@ class PPTHandler extends MFProxy {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ppt == null) {
|
||||||
|
throw new IOException("Unknown file format or missing poi-scratchpad.jar / poi-ooxml.jar");
|
||||||
|
}
|
||||||
slide = ppt.getSlides().get(0);
|
slide = ppt.getSlides().get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,8 +171,8 @@ class PPTHandler extends MFProxy {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static EmbeddedPart fromObjectShape(Shape s) {
|
private static EmbeddedPart fromObjectShape(Shape<?,?> s) {
|
||||||
final ObjectShape os = (ObjectShape)s;
|
final ObjectShape<?,?> os = (ObjectShape<?,?>)s;
|
||||||
final ObjectData od = os.getObjectData();
|
final ObjectData od = os.getObjectData();
|
||||||
EmbeddedPart embed = new EmbeddedPart();
|
EmbeddedPart embed = new EmbeddedPart();
|
||||||
embed.setName(od.getFileName());
|
embed.setName(od.getFileName());
|
||||||
|
@ -177,4 +186,8 @@ class PPTHandler extends MFProxy {
|
||||||
});
|
});
|
||||||
return embed;
|
return embed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void setDefaultCharset(Charset charset) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,15 +27,18 @@ import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.apache.poi.common.usermodel.GenericRecord;
|
import org.apache.poi.common.usermodel.GenericRecord;
|
||||||
import org.apache.poi.poifs.filesystem.FileMagic;
|
import org.apache.poi.poifs.filesystem.FileMagic;
|
||||||
|
import org.apache.poi.sl.draw.Drawable;
|
||||||
import org.apache.poi.sl.draw.EmbeddedExtractor.EmbeddedPart;
|
import org.apache.poi.sl.draw.EmbeddedExtractor.EmbeddedPart;
|
||||||
import org.apache.poi.util.Dimension2DDouble;
|
import org.apache.poi.util.Dimension2DDouble;
|
||||||
import org.apache.poi.util.GenericRecordJsonWriter;
|
import org.apache.poi.util.GenericRecordJsonWriter;
|
||||||
|
import org.apache.poi.util.LocaleUtil;
|
||||||
import org.apache.poi.xslf.util.OutputFormat.BitmapFormat;
|
import org.apache.poi.xslf.util.OutputFormat.BitmapFormat;
|
||||||
import org.apache.poi.xslf.util.OutputFormat.SVGFormat;
|
import org.apache.poi.xslf.util.OutputFormat.SVGFormat;
|
||||||
|
|
||||||
|
@ -71,7 +74,8 @@ public final class PPTX2PNG {
|
||||||
" -inputType <type> default input file type (OLE2,WMF,EMF), default is OLE2 = Powerpoint\n" +
|
" -inputType <type> default input file type (OLE2,WMF,EMF), default is OLE2 = Powerpoint\n" +
|
||||||
" some files (usually wmf) don't have a header, i.e. an identifiable file magic\n" +
|
" some files (usually wmf) don't have a header, i.e. an identifiable file magic\n" +
|
||||||
" -textAsShapes text elements are saved as shapes in SVG, necessary for variable spacing\n" +
|
" -textAsShapes text elements are saved as shapes in SVG, necessary for variable spacing\n" +
|
||||||
" often found in math formulas";
|
" often found in math formulas\n" +
|
||||||
|
" -charset sets the default charset to be used, defaults to Windows-1252";
|
||||||
|
|
||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
// no System.exit here, as we also run in junit tests!
|
// no System.exit here, as we also run in junit tests!
|
||||||
|
@ -99,6 +103,7 @@ public final class PPTX2PNG {
|
||||||
private boolean extractEmbedded = false;
|
private boolean extractEmbedded = false;
|
||||||
private FileMagic defaultFileType = FileMagic.OLE2;
|
private FileMagic defaultFileType = FileMagic.OLE2;
|
||||||
private boolean textAsShapes = false;
|
private boolean textAsShapes = false;
|
||||||
|
private Charset charset = LocaleUtil.CHARSET_1252;
|
||||||
|
|
||||||
private PPTX2PNG() {
|
private PPTX2PNG() {
|
||||||
}
|
}
|
||||||
|
@ -176,6 +181,15 @@ public final class PPTX2PNG {
|
||||||
case "-extractEmbedded":
|
case "-extractEmbedded":
|
||||||
extractEmbedded = true;
|
extractEmbedded = true;
|
||||||
break;
|
break;
|
||||||
|
case "-charset":
|
||||||
|
if (opt != null) {
|
||||||
|
charset = Charset.forName(opt);
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
charset = LocaleUtil.CHARSET_1252;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
file = new File(args[i]);
|
file = new File(args[i]);
|
||||||
break;
|
break;
|
||||||
|
@ -264,6 +278,7 @@ public final class PPTX2PNG {
|
||||||
graphics.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_SPEED);
|
graphics.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_SPEED);
|
||||||
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
||||||
graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
|
graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
|
||||||
|
graphics.setRenderingHint(Drawable.DEFAULT_CHARSET, getDefaultCharset());
|
||||||
|
|
||||||
graphics.scale(scale / lenSide, scale / lenSide);
|
graphics.scale(scale / lenSide, scale / lenSide);
|
||||||
|
|
||||||
|
@ -315,7 +330,7 @@ public final class PPTX2PNG {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dumpRecords(MFProxy proxy) throws IOException {
|
private void dumpRecords(MFProxy proxy) throws IOException {
|
||||||
if (dumpfile == null) {
|
if (dumpfile == null || "null".equals(dumpfile.getPath())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GenericRecord gr = proxy.getRoot();
|
GenericRecord gr = proxy.getRoot();
|
||||||
|
@ -387,6 +402,7 @@ public final class PPTX2PNG {
|
||||||
proxy.setQuite(quiet);
|
proxy.setQuite(quiet);
|
||||||
proxy.parse(file);
|
proxy.parse(file);
|
||||||
}
|
}
|
||||||
|
proxy.setDefaultCharset(charset);
|
||||||
|
|
||||||
return proxy;
|
return proxy;
|
||||||
}
|
}
|
||||||
|
@ -400,6 +416,10 @@ public final class PPTX2PNG {
|
||||||
return INPUT_PATTERN.matcher(inname).replaceAll(outpat);
|
return INPUT_PATTERN.matcher(inname).replaceAll(outpat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Charset getDefaultCharset() {
|
||||||
|
return charset;
|
||||||
|
}
|
||||||
|
|
||||||
static class NoScratchpadException extends IOException {
|
static class NoScratchpadException extends IOException {
|
||||||
NoScratchpadException() {
|
NoScratchpadException() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,13 @@
|
||||||
|
|
||||||
package org.apache.poi.xslf.usermodel;
|
package org.apache.poi.xslf.usermodel;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
import static org.junit.Assume.assumeFalse;
|
import static org.junit.Assume.assumeFalse;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
@ -39,13 +42,14 @@ import org.junit.runners.Parameterized.Parameters;
|
||||||
/**
|
/**
|
||||||
* Test class for testing PPTX2PNG utility which renders .ppt and .pptx slideshows
|
* Test class for testing PPTX2PNG utility which renders .ppt and .pptx slideshows
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class TestPPTX2PNG {
|
public class TestPPTX2PNG {
|
||||||
private static boolean xslfOnly;
|
private static boolean xslfOnly;
|
||||||
private static final POIDataSamples samples = POIDataSamples.getSlideShowInstance();
|
private static final POIDataSamples samples = POIDataSamples.getSlideShowInstance();
|
||||||
private static final File basedir = null;
|
private static final File basedir = null;
|
||||||
private static final String files =
|
private static final String files =
|
||||||
"53446.ppt, alterman_security.ppt, alterman_security.pptx, KEY02.pptx, themes.pptx, " +
|
"bug64693.pptx, 53446.ppt, alterman_security.ppt, alterman_security.pptx, KEY02.pptx, themes.pptx, " +
|
||||||
"backgrounds.pptx, layouts.pptx, sample.pptx, shapes.pptx, 54880_chinese.ppt, keyframes.pptx," +
|
"backgrounds.pptx, layouts.pptx, sample.pptx, shapes.pptx, 54880_chinese.ppt, keyframes.pptx," +
|
||||||
"customGeo.pptx, customGeo.ppt, wrench.emf, santa.wmf, missing-moveto.ppt";
|
"customGeo.pptx, customGeo.ppt, wrench.emf, santa.wmf, missing-moveto.ppt";
|
||||||
|
|
||||||
|
@ -62,7 +66,6 @@ public class TestPPTX2PNG {
|
||||||
@Parameter
|
@Parameter
|
||||||
public String pptFile;
|
public String pptFile;
|
||||||
|
|
||||||
@SuppressWarnings("ConstantConditions")
|
|
||||||
@Parameters(name="{0}")
|
@Parameters(name="{0}")
|
||||||
public static Collection<String> data() {
|
public static Collection<String> data() {
|
||||||
Function<String, Stream<String>> fun = (basedir == null) ? Stream::of :
|
Function<String, Stream<String>> fun = (basedir == null) ? Stream::of :
|
||||||
|
@ -75,7 +78,9 @@ public class TestPPTX2PNG {
|
||||||
public void render() throws Exception {
|
public void render() throws Exception {
|
||||||
assumeFalse("ignore HSLF (.ppt) / HEMF (.emf) / HWMF (.wmf) files in no-scratchpad run", xslfOnly && pptFile.matches(".*\\.(ppt|emf|wmf)$"));
|
assumeFalse("ignore HSLF (.ppt) / HEMF (.emf) / HWMF (.wmf) files in no-scratchpad run", xslfOnly && pptFile.matches(".*\\.(ppt|emf|wmf)$"));
|
||||||
|
|
||||||
String[] args = {
|
// bug64693.pptx
|
||||||
|
|
||||||
|
final List<String> args = new ArrayList<>(asList(
|
||||||
"-format", "null", // png,gif,jpg,svg or null for test
|
"-format", "null", // png,gif,jpg,svg or null for test
|
||||||
"-slide", "-1", // -1 for all
|
"-slide", "-1", // -1 for all
|
||||||
"-outdir", new File("build/tmp/").getCanonicalPath(),
|
"-outdir", new File("build/tmp/").getCanonicalPath(),
|
||||||
|
@ -84,10 +89,17 @@ public class TestPPTX2PNG {
|
||||||
"-dump", "null",
|
"-dump", "null",
|
||||||
"-quiet",
|
"-quiet",
|
||||||
"-fixside", "long",
|
"-fixside", "long",
|
||||||
"-scale", "800",
|
"-scale", "800"
|
||||||
// "-scale", "1.333333333",
|
));
|
||||||
(basedir == null ? samples.getFile(pptFile) : new File(basedir, pptFile)).getAbsolutePath()
|
|
||||||
};
|
if ("bug64693.pptx".equals(pptFile)) {
|
||||||
PPTX2PNG.main(args);
|
args.addAll(asList(
|
||||||
|
"-charset", "GBK"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
args.add((basedir == null ? samples.getFile(pptFile) : new File(basedir, pptFile)).getAbsolutePath());
|
||||||
|
|
||||||
|
PPTX2PNG.main(args.toArray(new String[0]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,3 +140,6 @@ javax.xml.bind.DatatypeConverter
|
||||||
|
|
||||||
@defaultMessage don't rely on the threads ContextClassLoader - provide the classloader via load(Class, Classloader)
|
@defaultMessage don't rely on the threads ContextClassLoader - provide the classloader via load(Class, Classloader)
|
||||||
java.util.ServiceLoader#load(java.lang.Class)
|
java.util.ServiceLoader#load(java.lang.Class)
|
||||||
|
|
||||||
|
@defaultMessage use java.nio.charset.StandardCharsets instead
|
||||||
|
org.apache.commons.codec.Charsets
|
|
@ -28,12 +28,14 @@ import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
import org.apache.poi.common.usermodel.GenericRecord;
|
import org.apache.poi.common.usermodel.GenericRecord;
|
||||||
import org.apache.poi.hemf.usermodel.HemfPicture;
|
import org.apache.poi.hemf.usermodel.HemfPicture;
|
||||||
import org.apache.poi.hwmf.draw.HwmfGraphicsState;
|
import org.apache.poi.hwmf.draw.HwmfGraphicsState;
|
||||||
import org.apache.poi.hwmf.draw.HwmfImageRenderer;
|
import org.apache.poi.hwmf.draw.HwmfImageRenderer;
|
||||||
import org.apache.poi.sl.draw.BitmapImageRenderer;
|
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.EmbeddedExtractor;
|
||||||
import org.apache.poi.sl.draw.ImageRenderer;
|
import org.apache.poi.sl.draw.ImageRenderer;
|
||||||
import org.apache.poi.sl.usermodel.PictureData;
|
import org.apache.poi.sl.usermodel.PictureData;
|
||||||
|
@ -43,6 +45,7 @@ import org.apache.poi.util.Units;
|
||||||
public class HemfImageRenderer implements ImageRenderer, EmbeddedExtractor {
|
public class HemfImageRenderer implements ImageRenderer, EmbeddedExtractor {
|
||||||
HemfPicture image;
|
HemfPicture image;
|
||||||
double alpha;
|
double alpha;
|
||||||
|
boolean charsetInitialized = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canRender(String contentType) {
|
public boolean canRender(String contentType) {
|
||||||
|
@ -104,6 +107,11 @@ public class HemfImageRenderer implements ImageRenderer, EmbeddedExtractor {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Charset cs = (Charset)graphics.getRenderingHint(Drawable.DEFAULT_CHARSET);
|
||||||
|
if (cs != null && !charsetInitialized) {
|
||||||
|
setDefaultCharset(cs);
|
||||||
|
}
|
||||||
|
|
||||||
HwmfGraphicsState graphicsState = new HwmfGraphicsState();
|
HwmfGraphicsState graphicsState = new HwmfGraphicsState();
|
||||||
graphicsState.backup(graphics);
|
graphicsState.backup(graphics);
|
||||||
|
|
||||||
|
@ -141,4 +149,10 @@ public class HemfImageRenderer implements ImageRenderer, EmbeddedExtractor {
|
||||||
public Rectangle2D getBounds() {
|
public Rectangle2D getBounds() {
|
||||||
return Units.pointsToPixel(image == null ? new Rectangle2D.Double() : image.getBoundsInPoints());
|
return Units.pointsToPixel(image == null ? new Rectangle2D.Double() : image.getBoundsInPoints());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDefaultCharset(Charset defaultCharset) {
|
||||||
|
image.setDefaultCharset(defaultCharset);
|
||||||
|
charsetInitialized = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.poi.hemf.record.emf;
|
||||||
|
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
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.draw.HemfGraphics.EmfRenderState;
|
||||||
import org.apache.poi.hemf.record.emfplus.HemfPlusRecord;
|
import org.apache.poi.hemf.record.emfplus.HemfPlusRecord;
|
||||||
import org.apache.poi.hemf.record.emfplus.HemfPlusRecordIterator;
|
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.hwmf.usermodel.HwmfPicture;
|
||||||
import org.apache.poi.util.GenericRecordJsonWriter;
|
import org.apache.poi.util.GenericRecordJsonWriter;
|
||||||
import org.apache.poi.util.GenericRecordUtil;
|
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;
|
private EmfCommentData data;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -146,6 +148,13 @@ public class HemfComment {
|
||||||
}
|
}
|
||||||
assert(commentIdentifier == commentType.id);
|
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> {
|
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
|
* 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.
|
* 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 byte[] privateData;
|
||||||
|
private Supplier<Charset> charsetProvider = () -> LocaleUtil.CHARSET_1252;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HemfCommentRecordType getCommentRecordType() {
|
public HemfCommentRecordType getCommentRecordType() {
|
||||||
|
@ -275,7 +285,7 @@ public class HemfComment {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPrivateDataAsString() {
|
public String getPrivateDataAsString() {
|
||||||
return new String(privateData, LocaleUtil.CHARSET_1252);
|
return new String(privateData, charsetProvider.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -285,6 +295,11 @@ public class HemfComment {
|
||||||
"privateDataAsString", this::getPrivateDataAsString
|
"privateDataAsString", this::getPrivateDataAsString
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCharsetProvider(Supplier<Charset> provider) {
|
||||||
|
charsetProvider = provider;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The EMR_COMMENT_EMFPLUS record contains embedded EMF+ records. */
|
/** The EMR_COMMENT_EMFPLUS record contains embedded EMF+ records. */
|
||||||
|
|
|
@ -206,6 +206,7 @@ public class HemfText {
|
||||||
// the axis to convert from page space units to .01mm units.
|
// 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.
|
// This SHOULD be used only if the graphics mode specified by iGraphicsMode is GM_COMPATIBLE.
|
||||||
Dimension2D scl = graphicsMode == EmfGraphicsMode.GM_COMPATIBLE ? scale : null;
|
Dimension2D scl = graphicsMode == EmfGraphicsMode.GM_COMPATIBLE ? scale : null;
|
||||||
|
ctx.setCharsetProvider(charsetProvider);
|
||||||
ctx.drawString(rawTextBytes, stringLength, reference, scl, bounds, options, dx, isUnicode());
|
ctx.drawString(rawTextBytes, stringLength, reference, scl, bounds, options, dx, isUnicode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import java.awt.geom.Rectangle2D;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
@ -37,7 +38,6 @@ import java.util.PrimitiveIterator.OfInt;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.apache.commons.codec.Charsets;
|
|
||||||
import org.apache.commons.math3.linear.LUDecomposition;
|
import org.apache.commons.math3.linear.LUDecomposition;
|
||||||
import org.apache.commons.math3.linear.MatrixUtils;
|
import org.apache.commons.math3.linear.MatrixUtils;
|
||||||
import org.apache.commons.math3.linear.RealMatrix;
|
import org.apache.commons.math3.linear.RealMatrix;
|
||||||
|
@ -748,12 +748,12 @@ public final class HemfPlusDraw {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (REALIZED_ADVANCE.isSet(optionsFlags)) {
|
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);
|
ctx.drawString(buf, buf.length, glyphPos.get(0), null, null, null, null, true);
|
||||||
} else {
|
} else {
|
||||||
final OfInt glyphIter = glyphs.codePoints().iterator();
|
final OfInt glyphIter = glyphs.codePoints().iterator();
|
||||||
glyphPos.forEach(p -> {
|
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);
|
ctx.drawString(buf, buf.length, p, null, null, null, null, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import java.awt.geom.AffineTransform;
|
||||||
import java.awt.geom.Dimension2D;
|
import java.awt.geom.Dimension2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
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.HemfRecord;
|
||||||
import org.apache.poi.hemf.record.emf.HemfRecordIterator;
|
import org.apache.poi.hemf.record.emf.HemfRecordIterator;
|
||||||
import org.apache.poi.hemf.record.emf.HemfWindowing;
|
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.hwmf.usermodel.HwmfEmbedded;
|
||||||
import org.apache.poi.util.Dimension2DDouble;
|
import org.apache.poi.util.Dimension2DDouble;
|
||||||
import org.apache.poi.util.Internal;
|
import org.apache.poi.util.Internal;
|
||||||
import org.apache.poi.util.LittleEndianInputStream;
|
import org.apache.poi.util.LittleEndianInputStream;
|
||||||
|
import org.apache.poi.util.LocaleUtil;
|
||||||
import org.apache.poi.util.Units;
|
import org.apache.poi.util.Units;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,6 +58,7 @@ public class HemfPicture implements Iterable<HemfRecord>, GenericRecord {
|
||||||
private final LittleEndianInputStream stream;
|
private final LittleEndianInputStream stream;
|
||||||
private final List<HemfRecord> records = new ArrayList<>();
|
private final List<HemfRecord> records = new ArrayList<>();
|
||||||
private boolean isParsed = false;
|
private boolean isParsed = false;
|
||||||
|
private Charset defaultCharset = LocaleUtil.CHARSET_1252;
|
||||||
|
|
||||||
public HemfPicture(InputStream is) {
|
public HemfPicture(InputStream is) {
|
||||||
this(new LittleEndianInputStream(is));
|
this(new LittleEndianInputStream(is));
|
||||||
|
@ -79,6 +83,9 @@ public class HemfPicture implements Iterable<HemfRecord>, GenericRecord {
|
||||||
header[0] = (HemfHeader) r;
|
header[0] = (HemfHeader) r;
|
||||||
}
|
}
|
||||||
r.setHeader(header[0]);
|
r.setHeader(header[0]);
|
||||||
|
if (r instanceof HwmfCharsetAware) {
|
||||||
|
((HwmfCharsetAware)r).setCharsetProvider(this::getDefaultCharset);
|
||||||
|
}
|
||||||
records.add(r);
|
records.add(r);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -199,4 +206,12 @@ public class HemfPicture implements Iterable<HemfRecord>, GenericRecord {
|
||||||
public Map<String, Supplier<?>> getGenericProperties() {
|
public Map<String, Supplier<?>> getGenericProperties() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDefaultCharset(Charset defaultCharset) {
|
||||||
|
this.defaultCharset = defaultCharset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Charset getDefaultCharset() {
|
||||||
|
return defaultCharset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ import java.awt.geom.Point2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.text.AttributedString;
|
import java.text.AttributedString;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
|
@ -51,8 +52,9 @@ import java.util.NoSuchElementException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.function.BiConsumer;
|
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.common.usermodel.fonts.FontInfo;
|
||||||
import org.apache.poi.hwmf.record.HwmfBrushStyle;
|
import org.apache.poi.hwmf.record.HwmfBrushStyle;
|
||||||
import org.apache.poi.hwmf.record.HwmfFont;
|
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.HwmfPenStyle.HwmfLineDash;
|
||||||
import org.apache.poi.hwmf.record.HwmfRegionMode;
|
import org.apache.poi.hwmf.record.HwmfRegionMode;
|
||||||
import org.apache.poi.hwmf.record.HwmfText.WmfExtTextOutOptions;
|
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.BitmapImageRenderer;
|
||||||
import org.apache.poi.sl.draw.DrawFactory;
|
import org.apache.poi.sl.draw.DrawFactory;
|
||||||
import org.apache.poi.sl.draw.DrawFontManager;
|
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.Internal;
|
||||||
import org.apache.poi.util.LocaleUtil;
|
import org.apache.poi.util.LocaleUtil;
|
||||||
|
|
||||||
public class HwmfGraphics {
|
public class HwmfGraphics implements HwmfCharsetAware {
|
||||||
|
|
||||||
public enum FillDrawStyle {
|
public enum FillDrawStyle {
|
||||||
NONE(FillDrawStyle::fillNone),
|
NONE(FillDrawStyle::fillNone),
|
||||||
|
@ -128,9 +131,9 @@ public class HwmfGraphics {
|
||||||
private final AffineTransform initialAT = new AffineTransform();
|
private final AffineTransform initialAT = new AffineTransform();
|
||||||
|
|
||||||
|
|
||||||
private static final Charset DEFAULT_CHARSET = LocaleUtil.CHARSET_1252;
|
|
||||||
/** Bounding box from the placeable header */
|
/** Bounding box from the placeable header */
|
||||||
private final Rectangle2D bbox;
|
private final Rectangle2D bbox;
|
||||||
|
private Supplier<Charset> charsetProvider = () -> LocaleUtil.CHARSET_1252;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize a graphics context for wmf rendering
|
* 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) {
|
if (isUnicode) {
|
||||||
return Charsets.UTF_16LE;
|
return StandardCharsets.UTF_16LE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Charset charset = font.getCharset().getCharset();
|
FontCharset fc = font.getCharset();
|
||||||
return (charset == null) ? DEFAULT_CHARSET : charset;
|
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);
|
final Charset charset = getCharset(font, isUnicode);
|
||||||
|
|
||||||
int trimLen;
|
int trimLen;
|
||||||
|
@ -717,7 +730,9 @@ public class HwmfGraphics {
|
||||||
graphicsCtx.fill(dstBounds);
|
graphicsCtx.fill(dstBounds);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
case SRCAND:
|
||||||
case SRCCOPY:
|
case SRCCOPY:
|
||||||
|
case SRCINVERT:
|
||||||
if (img == null) {
|
if (img == null) {
|
||||||
return;
|
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
|
// 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
|
// of the referenced image and can be also negative
|
||||||
Composite old = graphicsCtx.getComposite();
|
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);
|
boolean useDeviceBounds = (img instanceof HwmfImageRenderer);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.apache.poi.common.usermodel.GenericRecord;
|
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.hwmf.usermodel.HwmfPicture;
|
||||||
import org.apache.poi.sl.draw.BitmapImageRenderer;
|
import org.apache.poi.sl.draw.BitmapImageRenderer;
|
||||||
import org.apache.poi.sl.draw.DrawPictureShape;
|
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.EmbeddedExtractor;
|
||||||
import org.apache.poi.sl.draw.ImageRenderer;
|
import org.apache.poi.sl.draw.ImageRenderer;
|
||||||
import org.apache.poi.sl.usermodel.PictureData.PictureType;
|
import org.apache.poi.sl.usermodel.PictureData.PictureType;
|
||||||
|
@ -47,6 +49,7 @@ import org.apache.poi.util.Units;
|
||||||
public class HwmfImageRenderer implements ImageRenderer, EmbeddedExtractor {
|
public class HwmfImageRenderer implements ImageRenderer, EmbeddedExtractor {
|
||||||
HwmfPicture image;
|
HwmfPicture image;
|
||||||
double alpha;
|
double alpha;
|
||||||
|
boolean charsetInitialized = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canRender(String contentType) {
|
public boolean canRender(String contentType) {
|
||||||
|
@ -113,6 +116,11 @@ public class HwmfImageRenderer implements ImageRenderer, EmbeddedExtractor {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Charset cs = (Charset)graphics.getRenderingHint(Drawable.DEFAULT_CHARSET);
|
||||||
|
if (cs != null && !charsetInitialized) {
|
||||||
|
setDefaultCharset(cs);
|
||||||
|
}
|
||||||
|
|
||||||
HwmfGraphicsState graphicsState = new HwmfGraphicsState();
|
HwmfGraphicsState graphicsState = new HwmfGraphicsState();
|
||||||
graphicsState.backup(graphics);
|
graphicsState.backup(graphics);
|
||||||
|
|
||||||
|
@ -185,4 +193,10 @@ public class HwmfImageRenderer implements ImageRenderer, EmbeddedExtractor {
|
||||||
public Rectangle2D getBounds() {
|
public Rectangle2D getBounds() {
|
||||||
return Units.pointsToPixel(image == null ? new Rectangle2D.Double() : image.getBoundsInPoints());
|
return Units.pointsToPixel(image == null ? new Rectangle2D.Double() : image.getBoundsInPoints());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDefaultCharset(Charset defaultCharset) {
|
||||||
|
image.setDefaultCharset(defaultCharset);
|
||||||
|
charsetInitialized = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -485,11 +485,14 @@ public class HwmfBitmapDib implements GenericRecord {
|
||||||
|
|
||||||
if (foreground != null && background != null && headerBitCount == HwmfBitmapDib.BitCount.BI_BITCOUNT_1) {
|
if (foreground != null && background != null && headerBitCount == HwmfBitmapDib.BitCount.BI_BITCOUNT_1) {
|
||||||
IndexColorModel cmOld = (IndexColorModel)bi.getColorModel();
|
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 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, 2, cmap, 0, hasAlpha, transPixel, transferType);
|
||||||
IndexColorModel cmNew = new IndexColorModel(1, cmap.length, cmap, 0, hasAlpha, transPixel, transferType);
|
|
||||||
bi = new BufferedImage(cmNew, bi.getRaster(), false, null);
|
bi = new BufferedImage(cmNew, bi.getRaster(), false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.apache.poi.common.usermodel.GenericRecord;
|
||||||
import org.apache.poi.hwmf.draw.HwmfDrawProperties;
|
import org.apache.poi.hwmf.draw.HwmfDrawProperties;
|
||||||
import org.apache.poi.hwmf.draw.HwmfGraphics;
|
import org.apache.poi.hwmf.draw.HwmfGraphics;
|
||||||
import org.apache.poi.hwmf.record.HwmfMisc.WmfSetMapMode;
|
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.BitField;
|
||||||
import org.apache.poi.util.BitFieldFactory;
|
import org.apache.poi.util.BitFieldFactory;
|
||||||
import org.apache.poi.util.GenericRecordJsonWriter;
|
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.IOUtils;
|
||||||
import org.apache.poi.util.LittleEndianConsts;
|
import org.apache.poi.util.LittleEndianConsts;
|
||||||
import org.apache.poi.util.LittleEndianInputStream;
|
import org.apache.poi.util.LittleEndianInputStream;
|
||||||
|
import org.apache.poi.util.LocaleUtil;
|
||||||
import org.apache.poi.util.POILogFactory;
|
import org.apache.poi.util.POILogFactory;
|
||||||
import org.apache.poi.util.POILogger;
|
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,
|
* 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.
|
* 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.
|
* 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 Point2D reference = new Point2D.Double();
|
||||||
|
|
||||||
|
protected Supplier<Charset> charsetProvider = () -> LocaleUtil.CHARSET_1252;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HwmfRecordType getWmfRecordType() {
|
public HwmfRecordType getWmfRecordType() {
|
||||||
return HwmfRecordType.textOut;
|
return HwmfRecordType.textOut;
|
||||||
|
@ -211,6 +215,7 @@ public class HwmfText {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(HwmfGraphics ctx) {
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
ctx.setCharsetProvider(charsetProvider);
|
||||||
ctx.drawString(getTextBytes(), stringLength, reference);
|
ctx.drawString(getTextBytes(), stringLength, reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,6 +240,11 @@ public class HwmfText {
|
||||||
"reference", () -> reference
|
"reference", () -> reference
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCharsetProvider(Supplier<Charset> provider) {
|
||||||
|
charsetProvider = provider;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
@ -343,7 +353,7 @@ public class HwmfText {
|
||||||
* are defined in the playback device context. Optionally, dimensions can be provided for clipping,
|
* are defined in the playback device context. Optionally, dimensions can be provided for clipping,
|
||||||
* opaquing, or both.
|
* 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.
|
* 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 final List<Integer> dx = new ArrayList<>();
|
||||||
|
|
||||||
|
protected Supplier<Charset> charsetProvider = () -> LocaleUtil.CHARSET_1252;
|
||||||
|
|
||||||
public WmfExtTextOut() {
|
public WmfExtTextOut() {
|
||||||
this(new WmfExtTextOutOptions());
|
this(new WmfExtTextOutOptions());
|
||||||
}
|
}
|
||||||
|
@ -437,6 +449,7 @@ public class HwmfText {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(HwmfGraphics ctx) {
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
ctx.setCharsetProvider(charsetProvider);
|
||||||
ctx.drawString(rawTextBytes, stringLength, reference, null, bounds, options, dx, false);
|
ctx.drawString(rawTextBytes, stringLength, reference, null, bounds, options, dx, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,8 +458,7 @@ public class HwmfText {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
String ret = new String(rawTextBytes, charset);
|
String ret = new String(rawTextBytes, charset);
|
||||||
return ret.substring(0,
|
return ret.substring(0, Math.min(ret.length(), stringLength));
|
||||||
Math.min(ret.length(), stringLength));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Point2D getReference() {
|
public Point2D getReference() {
|
||||||
|
@ -468,7 +480,7 @@ public class HwmfText {
|
||||||
|
|
||||||
private String getGenericText() {
|
private String getGenericText() {
|
||||||
try {
|
try {
|
||||||
return getText(isUnicode() ? StandardCharsets.UTF_16LE : StandardCharsets.US_ASCII);
|
return getText(isUnicode() ? StandardCharsets.UTF_16LE : charsetProvider.get());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -483,6 +495,11 @@ public class HwmfText {
|
||||||
"dx", () -> dx
|
"dx", () -> dx
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCharsetProvider(Supplier<Charset> provider) {
|
||||||
|
charsetProvider = provider;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum HwmfTextAlignment {
|
public enum HwmfTextAlignment {
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ import java.awt.geom.Dimension2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
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.Dimension2DDouble;
|
||||||
import org.apache.poi.util.IOUtils;
|
import org.apache.poi.util.IOUtils;
|
||||||
import org.apache.poi.util.LittleEndianInputStream;
|
import org.apache.poi.util.LittleEndianInputStream;
|
||||||
|
import org.apache.poi.util.LocaleUtil;
|
||||||
import org.apache.poi.util.POILogFactory;
|
import org.apache.poi.util.POILogFactory;
|
||||||
import org.apache.poi.util.POILogger;
|
import org.apache.poi.util.POILogger;
|
||||||
import org.apache.poi.util.RecordFormatException;
|
import org.apache.poi.util.RecordFormatException;
|
||||||
|
@ -60,6 +62,8 @@ public class HwmfPicture implements Iterable<HwmfRecord>, GenericRecord {
|
||||||
final List<HwmfRecord> records = new ArrayList<>();
|
final List<HwmfRecord> records = new ArrayList<>();
|
||||||
final HwmfPlaceableHeader placeableHeader;
|
final HwmfPlaceableHeader placeableHeader;
|
||||||
final HwmfHeader header;
|
final HwmfHeader header;
|
||||||
|
/** The default charset */
|
||||||
|
private Charset defaultCharset = LocaleUtil.CHARSET_1252;
|
||||||
|
|
||||||
public HwmfPicture(InputStream inputStream) throws IOException {
|
public HwmfPicture(InputStream inputStream) throws IOException {
|
||||||
|
|
||||||
|
@ -110,6 +114,10 @@ public class HwmfPicture implements Iterable<HwmfRecord>, GenericRecord {
|
||||||
throw new RecordFormatException("Tried to skip "+remainingSize + " but skipped: "+skipped);
|
throw new RecordFormatException("Tried to skip "+remainingSize + " but skipped: "+skipped);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wr instanceof HwmfCharsetAware) {
|
||||||
|
((HwmfCharsetAware)wr).setCharsetProvider(this::getDefaultCharset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,7 +206,7 @@ public class HwmfPicture implements Iterable<HwmfRecord>, GenericRecord {
|
||||||
}
|
}
|
||||||
if (wOrg != null && wExt != null) {
|
if (wOrg != null && wExt != null) {
|
||||||
return new Rectangle2D.Double(wOrg.getX(), wOrg.getY(), wExt.getSize().getWidth(), wExt.getSize().getHeight());
|
return new Rectangle2D.Double(wOrg.getX(), wOrg.getY(), wExt.getSize().getWidth(), wExt.getSize().getHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -260,4 +268,12 @@ public class HwmfPicture implements Iterable<HwmfRecord>, GenericRecord {
|
||||||
public List<? extends GenericRecord> getGenericChildren() {
|
public List<? extends GenericRecord> getGenericChildren() {
|
||||||
return getRecords();
|
return getRecords();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDefaultCharset(Charset defaultCharset) {
|
||||||
|
this.defaultCharset = defaultCharset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Charset getDefaultCharset() {
|
||||||
|
return defaultCharset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,13 @@
|
||||||
|
|
||||||
package org.apache.poi.poifs.filesystem;
|
package org.apache.poi.poifs.filesystem;
|
||||||
|
|
||||||
import org.apache.commons.codec.Charsets;
|
import static org.junit.Assert.assertEquals;
|
||||||
import org.apache.poi.POIDataSamples;
|
import static org.junit.Assert.assertFalse;
|
||||||
import org.apache.poi.util.TempFile;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import org.junit.Test;
|
import static org.junit.Assert.assertNotSame;
|
||||||
|
import static org.junit.Assert.assertSame;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -28,32 +31,35 @@ import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import org.apache.poi.POIDataSamples;
|
||||||
|
import org.apache.poi.util.TempFile;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
public class TestFileMagic {
|
public class TestFileMagic {
|
||||||
@Test
|
@Test
|
||||||
public void testFileMagic() {
|
public void testFileMagic() {
|
||||||
assertEquals(FileMagic.XML, FileMagic.valueOf("XML"));
|
assertEquals(FileMagic.XML, FileMagic.valueOf("XML"));
|
||||||
assertEquals(FileMagic.XML, FileMagic.valueOf("<?xml".getBytes(Charsets.UTF_8)));
|
assertEquals(FileMagic.XML, FileMagic.valueOf("<?xml".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
|
||||||
assertEquals(FileMagic.HTML, FileMagic.valueOf("HTML"));
|
assertEquals(FileMagic.HTML, FileMagic.valueOf("HTML"));
|
||||||
assertEquals(FileMagic.HTML, FileMagic.valueOf("<!DOCTYP".getBytes(Charsets.UTF_8)));
|
assertEquals(FileMagic.HTML, FileMagic.valueOf("<!DOCTYP".getBytes(StandardCharsets.UTF_8)));
|
||||||
assertEquals(FileMagic.HTML, FileMagic.valueOf("<!DOCTYPE".getBytes(Charsets.UTF_8)));
|
assertEquals(FileMagic.HTML, FileMagic.valueOf("<!DOCTYPE".getBytes(StandardCharsets.UTF_8)));
|
||||||
assertEquals(FileMagic.HTML, FileMagic.valueOf("<html".getBytes(Charsets.UTF_8)));
|
assertEquals(FileMagic.HTML, FileMagic.valueOf("<html".getBytes(StandardCharsets.UTF_8)));
|
||||||
assertEquals(FileMagic.HTML, FileMagic.valueOf("\n\r<html".getBytes(Charsets.UTF_8)));
|
assertEquals(FileMagic.HTML, FileMagic.valueOf("\n\r<html".getBytes(StandardCharsets.UTF_8)));
|
||||||
assertEquals(FileMagic.HTML, FileMagic.valueOf("\n<html".getBytes(Charsets.UTF_8)));
|
assertEquals(FileMagic.HTML, FileMagic.valueOf("\n<html".getBytes(StandardCharsets.UTF_8)));
|
||||||
assertEquals(FileMagic.HTML, FileMagic.valueOf("\r\n<html".getBytes(Charsets.UTF_8)));
|
assertEquals(FileMagic.HTML, FileMagic.valueOf("\r\n<html".getBytes(StandardCharsets.UTF_8)));
|
||||||
assertEquals(FileMagic.HTML, FileMagic.valueOf("\r<html".getBytes(Charsets.UTF_8)));
|
assertEquals(FileMagic.HTML, FileMagic.valueOf("\r<html".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
|
||||||
assertEquals(FileMagic.JPEG, FileMagic.valueOf(new byte[]{ (byte)0xFF, (byte)0xD8, (byte)0xFF, (byte)0xDB }));
|
assertEquals(FileMagic.JPEG, FileMagic.valueOf(new byte[]{ (byte)0xFF, (byte)0xD8, (byte)0xFF, (byte)0xDB }));
|
||||||
assertEquals(FileMagic.JPEG, FileMagic.valueOf(new byte[]{ (byte)0xFF, (byte)0xD8, (byte)0xFF, (byte)0xE0, 'a', 'b', 'J', 'F', 'I', 'F', 0x00, 0x01 }));
|
assertEquals(FileMagic.JPEG, FileMagic.valueOf(new byte[]{ (byte)0xFF, (byte)0xD8, (byte)0xFF, (byte)0xE0, 'a', 'b', 'J', 'F', 'I', 'F', 0x00, 0x01 }));
|
||||||
assertEquals(FileMagic.JPEG, FileMagic.valueOf(new byte[]{ (byte)0xFF, (byte)0xD8, (byte)0xFF, (byte)0xEE }));
|
assertEquals(FileMagic.JPEG, FileMagic.valueOf(new byte[]{ (byte)0xFF, (byte)0xD8, (byte)0xFF, (byte)0xEE }));
|
||||||
assertEquals(FileMagic.JPEG, FileMagic.valueOf(new byte[]{ (byte)0xFF, (byte)0xD8, (byte)0xFF, (byte)0xE1, 'd', 'c', 'E', 'x', 'i', 'f', 0x00, 0x00 }));
|
assertEquals(FileMagic.JPEG, FileMagic.valueOf(new byte[]{ (byte)0xFF, (byte)0xD8, (byte)0xFF, (byte)0xE1, 'd', 'c', 'E', 'x', 'i', 'f', 0x00, 0x00 }));
|
||||||
|
|
||||||
assertEquals(FileMagic.UNKNOWN, FileMagic.valueOf("something".getBytes(Charsets.UTF_8)));
|
assertEquals(FileMagic.UNKNOWN, FileMagic.valueOf("something".getBytes(StandardCharsets.UTF_8)));
|
||||||
assertEquals(FileMagic.UNKNOWN, FileMagic.valueOf(new byte[0]));
|
assertEquals(FileMagic.UNKNOWN, FileMagic.valueOf(new byte[0]));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue