From 38b415e26af27aa7a22d1d1ea13eb87f445a9066 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Sun, 1 Nov 2020 15:37:20 +0000 Subject: #64716 - wmf display error EMF: workaround for invalid EMF header bounds EMF: add option to PPTX2PNG / DrawableHint to fallback to force EMF header bounds EMF: use RGB instead of HSL gradiants git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1883051 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/common/usermodel/PictureType.java | 35 ++++++++++++++++++++++ .../org/apache/poi/sl/draw/DrawPictureShape.java | 17 ++++++----- src/java/org/apache/poi/sl/draw/Drawable.java | 12 ++++++++ 3 files changed, 56 insertions(+), 8 deletions(-) (limited to 'src/java') diff --git a/src/java/org/apache/poi/common/usermodel/PictureType.java b/src/java/org/apache/poi/common/usermodel/PictureType.java index 4aceb624a0..d3ed67fc2e 100644 --- a/src/java/org/apache/poi/common/usermodel/PictureType.java +++ b/src/java/org/apache/poi/common/usermodel/PictureType.java @@ -17,6 +17,8 @@ package org.apache.poi.common.usermodel; +import org.apache.poi.poifs.filesystem.FileMagic; + /** * General enum class to define a picture format/type * @@ -65,4 +67,37 @@ public enum PictureType { this.contentType = contentType; this.extension = extension; } + + public String getContentType() { + return contentType; + } + + public String getExtension() { + return extension; + } + + public static PictureType valueOf(FileMagic fm) { + switch (fm) { + case BMP: + return PictureType.BMP; + case GIF: + return PictureType.GIF; + case JPEG: + return PictureType.JPEG; + case PNG: + return PictureType.PNG; + case XML: + // this is quite fuzzy, to suppose all XMLs are SVGs when handling pictures ... + return PictureType.SVG; + case WMF: + return PictureType.WMF; + case EMF: + return PictureType.EMF; + case TIFF: + return PictureType.TIFF; + default: + case UNKNOWN: + return PictureType.UNKNOWN; + } + } } diff --git a/src/java/org/apache/poi/sl/draw/DrawPictureShape.java b/src/java/org/apache/poi/sl/draw/DrawPictureShape.java index 695f4ec708..2e25d75a6a 100644 --- a/src/java/org/apache/poi/sl/draw/DrawPictureShape.java +++ b/src/java/org/apache/poi/sl/draw/DrawPictureShape.java @@ -27,6 +27,8 @@ import java.util.ServiceLoader; import java.util.function.Supplier; import java.util.stream.StreamSupport; +import org.apache.poi.common.usermodel.PictureType; +import org.apache.poi.poifs.filesystem.FileMagic; import org.apache.poi.sl.usermodel.PictureData; import org.apache.poi.sl.usermodel.PictureShape; import org.apache.poi.sl.usermodel.RectAlign; @@ -36,11 +38,6 @@ import org.apache.poi.util.POILogger; public class DrawPictureShape extends DrawSimpleShape { private static final POILogger LOG = POILogFactory.getLogger(DrawPictureShape.class); - private static final String[] KNOWN_RENDERER = { - "org.apache.poi.hwmf.draw.HwmfImageRenderer", - "org.apache.poi.hemf.draw.HemfImageRenderer", - "org.apache.poi.xslf.draw.SVGImageRenderer" - }; public DrawPictureShape(PictureShape shape) { super(shape); @@ -60,10 +57,14 @@ public class DrawPictureShape extends DrawSimpleShape { } try { - String ct = data.getContentType(); + byte[] dataBytes = data.getData(); + + PictureType type = PictureType.valueOf(FileMagic.valueOf(dataBytes)); + String ct = (type == PictureType.UNKNOWN) ? data.getContentType() : type.getContentType(); + ImageRenderer renderer = getImageRenderer(graphics, ct); if (renderer.canRender(ct)) { - renderer.loadImage(data.getData(), ct); + renderer.loadImage(dataBytes, ct); renderer.drawImage(graphics, anchor, insets); return; } @@ -92,7 +93,7 @@ public class DrawPictureShape extends DrawSimpleShape { // the fallback is the BitmapImageRenderer, at least it gracefully handles invalid images final Supplier getFallback = () -> { - LOG.log(POILogger.WARN, "No suiteable image renderer found for content-type '"+ + LOG.log(POILogger.WARN, "No suitable image renderer found for content-type '"+ contentType+"' - include poi-scratchpad (for wmf/emf) or poi-ooxml (for svg) jars!"); return fallback; }; diff --git a/src/java/org/apache/poi/sl/draw/Drawable.java b/src/java/org/apache/poi/sl/draw/Drawable.java index 919e1a6f25..cb5f8592f9 100644 --- a/src/java/org/apache/poi/sl/draw/Drawable.java +++ b/src/java/org/apache/poi/sl/draw/Drawable.java @@ -49,6 +49,7 @@ public interface Drawable { case 12: return "CURRENT_SLIDE"; case 13: return "BUFFERED_IMAGE"; case 14: return "DEFAULT_CHARSET"; + case 15: return "EMF_FORCE_HEADER_BOUNDS"; default: return "UNKNOWN_ID "+intKey(); } } @@ -153,6 +154,17 @@ public interface Drawable { */ DrawableHint DEFAULT_CHARSET = new DrawableHint(14); + /** + * A boolean value to force the usage of the bounding box, which is specified in the EMF header. + * Defaults to {@code FALSE} - in this case the records are scanned for window and + * viewport records to determine the initial bounding box by using the following + * condition: {@code isValid(viewport) ? viewport : isValid(window) ? window : headerBounds } + *

+ * This is a workaround switch, which might be removed in future releases, when the bounding box + * determination for the special cases is fixed. + * In most cases it's recommended to leave the default value. + */ + DrawableHint EMF_FORCE_HEADER_BOUNDS = new DrawableHint(15); /** * Apply 2-D transforms before drawing this shape. This includes rotation and flipping. -- cgit v1.2.3