mirror of
https://github.com/apache/poi.git
synced 2025-02-08 11:04:53 +00:00
#56004 - Support for WMF rendering
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1724897 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
0ba83f7683
commit
50d98918d9
@ -186,6 +186,10 @@ public final class EscherProperties {
|
|||||||
public static final short LINESTYLE__HITLINETEST = 509;
|
public static final short LINESTYLE__HITLINETEST = 509;
|
||||||
public static final short LINESTYLE__LINEFILLSHAPE = 510;
|
public static final short LINESTYLE__LINEFILLSHAPE = 510;
|
||||||
public static final short LINESTYLE__NOLINEDRAWDASH = 511;
|
public static final short LINESTYLE__NOLINEDRAWDASH = 511;
|
||||||
|
public static final short LINESTYLE__NOLINEDRAWDASH_LEFT = 0x057F;
|
||||||
|
public static final short LINESTYLE__NOLINEDRAWDASH_TOP = 0x05BF;
|
||||||
|
public static final short LINESTYLE__NOLINEDRAWDASH_BOTTOM = 0x063F;
|
||||||
|
public static final short LINESTYLE__NOLINEDRAWDASH_RIGHT = 0x05FF;
|
||||||
public static final short SHADOWSTYLE__TYPE = 512;
|
public static final short SHADOWSTYLE__TYPE = 512;
|
||||||
public static final short SHADOWSTYLE__COLOR = 513;
|
public static final short SHADOWSTYLE__COLOR = 513;
|
||||||
public static final short SHADOWSTYLE__HIGHLIGHT = 514;
|
public static final short SHADOWSTYLE__HIGHLIGHT = 514;
|
||||||
@ -488,6 +492,10 @@ public final class EscherProperties {
|
|||||||
addProp(m, LINESTYLE__HITLINETEST, "linestyle.hitlinetest");
|
addProp(m, LINESTYLE__HITLINETEST, "linestyle.hitlinetest");
|
||||||
addProp(m, LINESTYLE__LINEFILLSHAPE, "linestyle.linefillshape");
|
addProp(m, LINESTYLE__LINEFILLSHAPE, "linestyle.linefillshape");
|
||||||
addProp(m, LINESTYLE__NOLINEDRAWDASH, "linestyle.nolinedrawdash", EscherPropertyMetaData.TYPE_BOOLEAN);
|
addProp(m, LINESTYLE__NOLINEDRAWDASH, "linestyle.nolinedrawdash", EscherPropertyMetaData.TYPE_BOOLEAN);
|
||||||
|
addProp(m, LINESTYLE__NOLINEDRAWDASH_LEFT, "linestyle.nolinedrawdash.left", EscherPropertyMetaData.TYPE_BOOLEAN);
|
||||||
|
addProp(m, LINESTYLE__NOLINEDRAWDASH_TOP, "linestyle.nolinedrawdash.top", EscherPropertyMetaData.TYPE_BOOLEAN);
|
||||||
|
addProp(m, LINESTYLE__NOLINEDRAWDASH_BOTTOM, "linestyle.nolinedrawdash.bottom", EscherPropertyMetaData.TYPE_BOOLEAN);
|
||||||
|
addProp(m, LINESTYLE__NOLINEDRAWDASH_RIGHT, "linestyle.nolinedrawdash.right", EscherPropertyMetaData.TYPE_BOOLEAN);
|
||||||
addProp(m, SHADOWSTYLE__TYPE, "shadowstyle.type");
|
addProp(m, SHADOWSTYLE__TYPE, "shadowstyle.type");
|
||||||
addProp(m, SHADOWSTYLE__COLOR, "shadowstyle.color", EscherPropertyMetaData.TYPE_RGB);
|
addProp(m, SHADOWSTYLE__COLOR, "shadowstyle.color", EscherPropertyMetaData.TYPE_RGB);
|
||||||
addProp(m, SHADOWSTYLE__HIGHLIGHT, "shadowstyle.highlight");
|
addProp(m, SHADOWSTYLE__HIGHLIGHT, "shadowstyle.highlight");
|
||||||
|
142
src/java/org/apache/poi/sl/draw/BitmapImageRenderer.java
Normal file
142
src/java/org/apache/poi/sl/draw/BitmapImageRenderer.java
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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.sl.draw;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Insets;
|
||||||
|
import java.awt.Shape;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.awt.image.RescaleOp;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
import org.apache.poi.util.POILogFactory;
|
||||||
|
import org.apache.poi.util.POILogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For now this class renders only images supported by the javax.imageio.ImageIO framework.
|
||||||
|
**/
|
||||||
|
public class BitmapImageRenderer implements ImageRenderer {
|
||||||
|
private final static POILogger LOG = POILogFactory.getLogger(ImageRenderer.class);
|
||||||
|
|
||||||
|
protected BufferedImage img;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadImage(InputStream data, String contentType) throws IOException {
|
||||||
|
img = convertBufferedImage(ImageIO.read(data), contentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadImage(byte data[], String contentType) throws IOException {
|
||||||
|
img = convertBufferedImage(ImageIO.read(new ByteArrayInputStream(data)), contentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add alpha channel to buffered image
|
||||||
|
*/
|
||||||
|
private static BufferedImage convertBufferedImage(BufferedImage img, String contentType) {
|
||||||
|
if (img == null) {
|
||||||
|
LOG.log(POILogger.WARN, "Content-type: "+contentType+" is not support. Image ignored.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferedImage bi = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||||
|
Graphics g = bi.getGraphics();
|
||||||
|
g.drawImage(img, 0, 0, null);
|
||||||
|
g.dispose();
|
||||||
|
return bi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the buffered image
|
||||||
|
*/
|
||||||
|
public BufferedImage getImage() {
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension getDimension() {
|
||||||
|
return (img == null)
|
||||||
|
? new Dimension(0,0)
|
||||||
|
: new Dimension(img.getWidth(),img.getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAlpha(double alpha) {
|
||||||
|
if (img == null) return;
|
||||||
|
|
||||||
|
Dimension dim = getDimension();
|
||||||
|
BufferedImage newImg = new BufferedImage((int)dim.getWidth(), (int)dim.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||||
|
Graphics2D g = newImg.createGraphics();
|
||||||
|
RescaleOp op = new RescaleOp(new float[]{1.0f, 1.0f, 1.0f, (float)alpha}, new float[]{0,0,0,0}, null);
|
||||||
|
g.drawImage(img, op, 0, 0);
|
||||||
|
g.dispose();
|
||||||
|
|
||||||
|
img = newImg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean drawImage(
|
||||||
|
Graphics2D graphics,
|
||||||
|
Rectangle2D anchor) {
|
||||||
|
return drawImage(graphics, anchor, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean drawImage(
|
||||||
|
Graphics2D graphics,
|
||||||
|
Rectangle2D anchor,
|
||||||
|
Insets clip) {
|
||||||
|
if (img == null) return false;
|
||||||
|
|
||||||
|
boolean isClipped = true;
|
||||||
|
if (clip == null) {
|
||||||
|
isClipped = false;
|
||||||
|
clip = new Insets(0,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int iw = img.getWidth();
|
||||||
|
int ih = img.getHeight();
|
||||||
|
|
||||||
|
|
||||||
|
double cw = (100000-clip.left-clip.right) / 100000.0;
|
||||||
|
double ch = (100000-clip.top-clip.bottom) / 100000.0;
|
||||||
|
double sx = anchor.getWidth()/(iw*cw);
|
||||||
|
double sy = anchor.getHeight()/(ih*ch);
|
||||||
|
double tx = anchor.getX()-(iw*sx*clip.left/100000.0);
|
||||||
|
double ty = anchor.getY()-(ih*sy*clip.top/100000.0);
|
||||||
|
|
||||||
|
AffineTransform at = new AffineTransform(sx, 0, 0, sy, tx, ty) ;
|
||||||
|
|
||||||
|
Shape clipOld = graphics.getClip();
|
||||||
|
if (isClipped) graphics.clip(anchor.getBounds2D());
|
||||||
|
graphics.drawRenderedImage(img, at);
|
||||||
|
graphics.setClip(clipOld);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -26,6 +26,7 @@ import java.text.AttributedString;
|
|||||||
import org.apache.poi.sl.usermodel.Background;
|
import org.apache.poi.sl.usermodel.Background;
|
||||||
import org.apache.poi.sl.usermodel.ConnectorShape;
|
import org.apache.poi.sl.usermodel.ConnectorShape;
|
||||||
import org.apache.poi.sl.usermodel.FreeformShape;
|
import org.apache.poi.sl.usermodel.FreeformShape;
|
||||||
|
import org.apache.poi.sl.usermodel.GraphicalFrame;
|
||||||
import org.apache.poi.sl.usermodel.GroupShape;
|
import org.apache.poi.sl.usermodel.GroupShape;
|
||||||
import org.apache.poi.sl.usermodel.MasterSheet;
|
import org.apache.poi.sl.usermodel.MasterSheet;
|
||||||
import org.apache.poi.sl.usermodel.PictureShape;
|
import org.apache.poi.sl.usermodel.PictureShape;
|
||||||
@ -87,6 +88,8 @@ public class DrawFactory {
|
|||||||
return getDrawable((GroupShape<?,?>)shape);
|
return getDrawable((GroupShape<?,?>)shape);
|
||||||
} else if (shape instanceof PictureShape) {
|
} else if (shape instanceof PictureShape) {
|
||||||
return getDrawable((PictureShape<?,?>)shape);
|
return getDrawable((PictureShape<?,?>)shape);
|
||||||
|
} else if (shape instanceof GraphicalFrame) {
|
||||||
|
return getDrawable((GraphicalFrame<?,?>)shape);
|
||||||
} else if (shape instanceof Background) {
|
} else if (shape instanceof Background) {
|
||||||
return getDrawable((Background<?,?>)shape);
|
return getDrawable((Background<?,?>)shape);
|
||||||
} else if (shape instanceof ConnectorShape) {
|
} else if (shape instanceof ConnectorShape) {
|
||||||
@ -144,6 +147,10 @@ public class DrawFactory {
|
|||||||
return new DrawPictureShape(shape);
|
return new DrawPictureShape(shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DrawGraphicalFrame getDrawable(GraphicalFrame<?,?> shape) {
|
||||||
|
return new DrawGraphicalFrame(shape);
|
||||||
|
}
|
||||||
|
|
||||||
public DrawTextParagraph getDrawable(TextParagraph<?,?,?> paragraph) {
|
public DrawTextParagraph getDrawable(TextParagraph<?,?,?> paragraph) {
|
||||||
return new DrawTextParagraph(paragraph);
|
return new DrawTextParagraph(paragraph);
|
||||||
}
|
}
|
||||||
|
40
src/java/org/apache/poi/sl/draw/DrawGraphicalFrame.java
Normal file
40
src/java/org/apache/poi/sl/draw/DrawGraphicalFrame.java
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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.sl.draw;
|
||||||
|
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
|
||||||
|
import org.apache.poi.sl.usermodel.GraphicalFrame;
|
||||||
|
import org.apache.poi.sl.usermodel.PictureShape;
|
||||||
|
|
||||||
|
|
||||||
|
public class DrawGraphicalFrame extends DrawShape {
|
||||||
|
|
||||||
|
public DrawGraphicalFrame(GraphicalFrame<?,?> shape) {
|
||||||
|
super(shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Graphics2D context) {
|
||||||
|
PictureShape<?,?> ps = ((GraphicalFrame<?,?>)getShape()).getFallbackPicture();
|
||||||
|
if (ps == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DrawPictureShape dps = DrawFactory.getInstance(context).getDrawable(ps);
|
||||||
|
dps.draw(context);
|
||||||
|
}
|
||||||
|
}
|
@ -130,8 +130,7 @@ public class DrawPaint {
|
|||||||
if (is == null) return null;
|
if (is == null) return null;
|
||||||
assert(graphics != null);
|
assert(graphics != null);
|
||||||
|
|
||||||
ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER);
|
ImageRenderer renderer = DrawPictureShape.getImageRenderer(graphics, fill.getContentType());
|
||||||
if (renderer == null) renderer = new ImageRenderer();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
renderer.loadImage(is, fill.getContentType());
|
renderer.loadImage(is, fill.getContentType());
|
||||||
|
@ -24,11 +24,17 @@ import java.awt.geom.Rectangle2D;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.poi.sl.usermodel.PictureData;
|
import org.apache.poi.sl.usermodel.PictureData;
|
||||||
|
import org.apache.poi.sl.usermodel.PictureData.PictureType;
|
||||||
|
import org.apache.poi.util.POILogFactory;
|
||||||
|
import org.apache.poi.util.POILogger;
|
||||||
import org.apache.poi.sl.usermodel.PictureShape;
|
import org.apache.poi.sl.usermodel.PictureShape;
|
||||||
import org.apache.poi.sl.usermodel.RectAlign;
|
import org.apache.poi.sl.usermodel.RectAlign;
|
||||||
|
|
||||||
|
|
||||||
public class DrawPictureShape extends DrawSimpleShape {
|
public class DrawPictureShape extends DrawSimpleShape {
|
||||||
|
private static final POILogger LOG = POILogFactory.getLogger(DrawPictureShape.class);
|
||||||
|
private static final String WMF_IMAGE_RENDERER = "org.apache.poi.hwmf.draw.HwmfSLImageRenderer";
|
||||||
|
|
||||||
public DrawPictureShape(PictureShape<?,?> shape) {
|
public DrawPictureShape(PictureShape<?,?> shape) {
|
||||||
super(shape);
|
super(shape);
|
||||||
}
|
}
|
||||||
@ -38,14 +44,11 @@ public class DrawPictureShape extends DrawSimpleShape {
|
|||||||
PictureData data = getShape().getPictureData();
|
PictureData data = getShape().getPictureData();
|
||||||
if(data == null) return;
|
if(data == null) return;
|
||||||
|
|
||||||
ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER);
|
|
||||||
if (renderer == null) renderer = new ImageRenderer();
|
|
||||||
|
|
||||||
Rectangle2D anchor = getAnchor(graphics, getShape());
|
Rectangle2D anchor = getAnchor(graphics, getShape());
|
||||||
|
|
||||||
Insets insets = getShape().getClipping();
|
Insets insets = getShape().getClipping();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
ImageRenderer renderer = getImageRenderer(graphics, data.getContentType());
|
||||||
renderer.loadImage(data.getData(), data.getContentType());
|
renderer.loadImage(data.getData(), data.getContentType());
|
||||||
renderer.drawImage(graphics, anchor, insets);
|
renderer.drawImage(graphics, anchor, insets);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -54,6 +57,34 @@ public class DrawPictureShape extends DrawSimpleShape {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an ImageRenderer for the PictureData
|
||||||
|
*
|
||||||
|
* @param graphics
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static ImageRenderer getImageRenderer(Graphics2D graphics, String contentType) {
|
||||||
|
ImageRenderer renderer = (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER);
|
||||||
|
if (renderer != null) {
|
||||||
|
return renderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PictureType.WMF.contentType.equals(contentType)) {
|
||||||
|
try {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Class<? extends ImageRenderer> irc = (Class<? extends ImageRenderer>)
|
||||||
|
Thread.currentThread().getContextClassLoader().loadClass(WMF_IMAGE_RENDERER);
|
||||||
|
return irc.newInstance();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// WMF image renderer is not on the classpath, continuing with BitmapRenderer
|
||||||
|
// although this doesn't make much sense ...
|
||||||
|
LOG.log(POILogger.ERROR, "WMF image renderer is not on the classpath - include poi-scratchpad jar!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BitmapImageRenderer();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PictureShape<?,?> getShape() {
|
protected PictureShape<?,?> getShape() {
|
||||||
return (PictureShape<?,?>)shape;
|
return (PictureShape<?,?>)shape;
|
||||||
|
@ -98,6 +98,7 @@ public class DrawSimpleShape extends DrawShape {
|
|||||||
// then stroke the shape outline
|
// then stroke the shape outline
|
||||||
if(line != null) {
|
if(line != null) {
|
||||||
graphics.setPaint(line);
|
graphics.setPaint(line);
|
||||||
|
graphics.setStroke(stroke);
|
||||||
for(Outline o : elems){
|
for(Outline o : elems){
|
||||||
if(o.getPath().isStroked()){
|
if(o.getPath().isStroked()){
|
||||||
java.awt.Shape s = o.getOutline();
|
java.awt.Shape s = o.getOutline();
|
||||||
|
@ -31,13 +31,12 @@ import org.apache.poi.util.POILogFactory;
|
|||||||
import org.apache.poi.util.POILogger;
|
import org.apache.poi.util.POILogger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For now this class renders only images supported by the javax.imageio.ImageIO
|
* Classes can implement this interfaces to support other formats, for
|
||||||
* framework. Subclasses can override this class to support other formats, for
|
|
||||||
* example, use Apache Batik to render WMF, PICT can be rendered using Apple QuickTime API for Java:
|
* example, use Apache Batik to render WMF, PICT can be rendered using Apple QuickTime API for Java:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* <code>
|
* <code>
|
||||||
* public class MyImageRendener extends ImageRendener {
|
* public class MyImageRendener implements ImageRendener {
|
||||||
* InputStream data;
|
* InputStream data;
|
||||||
*
|
*
|
||||||
* public boolean drawImage(Graphics2D graphics,Rectangle2D anchor,Insets clip) {
|
* public boolean drawImage(Graphics2D graphics,Rectangle2D anchor,Insets clip) {
|
||||||
@ -79,127 +78,49 @@ import org.apache.poi.util.POILogger;
|
|||||||
* </code>
|
* </code>
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
public class ImageRenderer {
|
public interface ImageRenderer {
|
||||||
private final static POILogger LOG = POILogFactory.getLogger(ImageRenderer.class);
|
|
||||||
|
|
||||||
protected BufferedImage img;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load and buffer the image
|
* Load and buffer the image
|
||||||
*
|
*
|
||||||
* @param data the raw image stream
|
* @param data the raw image stream
|
||||||
* @param contentType the content type
|
* @param contentType the content type
|
||||||
*/
|
*/
|
||||||
public void loadImage(InputStream data, String contentType) throws IOException {
|
void loadImage(InputStream data, String contentType) throws IOException;
|
||||||
img = convertBufferedImage(ImageIO.read(data), contentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load and buffer the image
|
* Load and buffer the image
|
||||||
*
|
*
|
||||||
* @param data the raw image stream
|
* @param data the raw image bytes
|
||||||
* @param contentType the content type
|
* @param contentType the content type
|
||||||
*/
|
*/
|
||||||
public void loadImage(byte data[], String contentType) throws IOException {
|
void loadImage(byte data[], String contentType) throws IOException;
|
||||||
img = convertBufferedImage(ImageIO.read(new ByteArrayInputStream(data)), contentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add alpha channel to buffered image
|
|
||||||
*/
|
|
||||||
private static BufferedImage convertBufferedImage(BufferedImage img, String contentType) {
|
|
||||||
if (img == null) {
|
|
||||||
LOG.log(POILogger.WARN, "Content-type: "+contentType+" is not support. Image ignored.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferedImage bi = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
|
||||||
Graphics g = bi.getGraphics();
|
|
||||||
g.drawImage(img, 0, 0, null);
|
|
||||||
g.dispose();
|
|
||||||
return bi;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the buffered image
|
|
||||||
*/
|
|
||||||
public BufferedImage getImage() {
|
|
||||||
return img;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the dimension of the buffered image
|
* @return the dimension of the buffered image
|
||||||
*/
|
*/
|
||||||
public Dimension getDimension() {
|
Dimension getDimension();
|
||||||
return (img == null)
|
|
||||||
? new Dimension(0,0)
|
|
||||||
: new Dimension(img.getWidth(),img.getHeight());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param alpha the alpha [0..1] to be added to the image (possibly already containing an alpha channel)
|
* @param alpha the alpha [0..1] to be added to the image (possibly already containing an alpha channel)
|
||||||
*/
|
*/
|
||||||
public void setAlpha(double alpha) {
|
void setAlpha(double alpha);
|
||||||
if (img == null) return;
|
|
||||||
|
|
||||||
Dimension dim = getDimension();
|
|
||||||
BufferedImage newImg = new BufferedImage((int)dim.getWidth(), (int)dim.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
|
||||||
Graphics2D g = newImg.createGraphics();
|
|
||||||
RescaleOp op = new RescaleOp(new float[]{1.0f, 1.0f, 1.0f, (float)alpha}, new float[]{0,0,0,0}, null);
|
|
||||||
g.drawImage(img, op, 0, 0);
|
|
||||||
g.dispose();
|
|
||||||
|
|
||||||
img = newImg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the image as buffered image
|
||||||
|
*/
|
||||||
|
BufferedImage getImage();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render picture data into the supplied graphics
|
* Render picture data into the supplied graphics
|
||||||
*
|
*
|
||||||
* @return true if the picture data was successfully rendered
|
* @return true if the picture data was successfully rendered
|
||||||
*/
|
*/
|
||||||
public boolean drawImage(
|
boolean drawImage(Graphics2D graphics, Rectangle2D anchor);
|
||||||
Graphics2D graphics,
|
|
||||||
Rectangle2D anchor) {
|
|
||||||
return drawImage(graphics, anchor, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render picture data into the supplied graphics
|
* Render picture data into the supplied graphics
|
||||||
*
|
*
|
||||||
* @return true if the picture data was successfully rendered
|
* @return true if the picture data was successfully rendered
|
||||||
*/
|
*/
|
||||||
public boolean drawImage(
|
boolean drawImage(Graphics2D graphics, Rectangle2D anchor, Insets clip);
|
||||||
Graphics2D graphics,
|
|
||||||
Rectangle2D anchor,
|
|
||||||
Insets clip) {
|
|
||||||
if (img == null) return false;
|
|
||||||
|
|
||||||
boolean isClipped = true;
|
|
||||||
if (clip == null) {
|
|
||||||
isClipped = false;
|
|
||||||
clip = new Insets(0,0,0,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int iw = img.getWidth();
|
|
||||||
int ih = img.getHeight();
|
|
||||||
|
|
||||||
|
|
||||||
double cw = (100000-clip.left-clip.right) / 100000.0;
|
|
||||||
double ch = (100000-clip.top-clip.bottom) / 100000.0;
|
|
||||||
double sx = anchor.getWidth()/(iw*cw);
|
|
||||||
double sy = anchor.getHeight()/(ih*ch);
|
|
||||||
double tx = anchor.getX()-(iw*sx*clip.left/100000.0);
|
|
||||||
double ty = anchor.getY()-(ih*sy*clip.top/100000.0);
|
|
||||||
|
|
||||||
AffineTransform at = new AffineTransform(sx, 0, 0, sy, tx, ty) ;
|
|
||||||
|
|
||||||
Shape clipOld = graphics.getClip();
|
|
||||||
if (isClipped) graphics.clip(anchor.getBounds2D());
|
|
||||||
graphics.drawRenderedImage(img, at);
|
|
||||||
graphics.setClip(clipOld);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
29
src/java/org/apache/poi/sl/usermodel/GraphicalFrame.java
Normal file
29
src/java/org/apache/poi/sl/usermodel/GraphicalFrame.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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.sl.usermodel;
|
||||||
|
|
||||||
|
public interface GraphicalFrame<
|
||||||
|
S extends Shape<S,P>,
|
||||||
|
P extends TextParagraph<S,P,?>
|
||||||
|
> extends Shape<S,P>, PlaceableShape<S,P> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a fallback representation as picture shape
|
||||||
|
*/
|
||||||
|
PictureShape<S,P> getFallbackPicture();
|
||||||
|
}
|
@ -27,25 +27,26 @@ import org.apache.poi.POIXMLException;
|
|||||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||||
import org.apache.poi.sl.draw.DrawNotImplemented;
|
import org.apache.poi.sl.usermodel.GraphicalFrame;
|
||||||
import org.apache.poi.sl.usermodel.PlaceableShape;
|
|
||||||
import org.apache.poi.sl.usermodel.ShapeType;
|
import org.apache.poi.sl.usermodel.ShapeType;
|
||||||
import org.apache.poi.util.Beta;
|
import org.apache.poi.util.Beta;
|
||||||
|
import org.apache.poi.util.POILogFactory;
|
||||||
|
import org.apache.poi.util.POILogger;
|
||||||
import org.apache.poi.util.Units;
|
import org.apache.poi.util.Units;
|
||||||
import org.apache.xmlbeans.XmlCursor;
|
import org.apache.xmlbeans.XmlCursor;
|
||||||
|
import org.apache.xmlbeans.XmlException;
|
||||||
import org.apache.xmlbeans.XmlObject;
|
import org.apache.xmlbeans.XmlObject;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData;
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
|
||||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
|
||||||
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Yegor Kozlov
|
|
||||||
*/
|
|
||||||
@Beta
|
@Beta
|
||||||
@DrawNotImplemented
|
public class XSLFGraphicFrame extends XSLFShape implements GraphicalFrame<XSLFShape, XSLFTextParagraph> {
|
||||||
public class XSLFGraphicFrame extends XSLFShape implements PlaceableShape<XSLFShape, XSLFTextParagraph> {
|
private static final POILogger LOG = POILogFactory.getLogger(XSLFGraphicFrame.class);
|
||||||
|
|
||||||
/*package*/ XSLFGraphicFrame(CTGraphicalObjectFrame shape, XSLFSheet sheet){
|
/*package*/ XSLFGraphicFrame(CTGraphicalObjectFrame shape, XSLFSheet sheet){
|
||||||
super(shape,sheet);
|
super(shape,sheet);
|
||||||
}
|
}
|
||||||
@ -189,4 +190,30 @@ public class XSLFGraphicFrame extends XSLFShape implements PlaceableShape<XSLFSh
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XSLFPictureShape getFallbackPicture() {
|
||||||
|
String xquery =
|
||||||
|
"declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main'; "
|
||||||
|
+ "declare namespace mc='http://schemas.openxmlformats.org/markup-compatibility/2006' "
|
||||||
|
+ ".//mc:Fallback/*/p:pic"
|
||||||
|
;
|
||||||
|
XmlObject xo = selectProperty(XmlObject.class, xquery);
|
||||||
|
if (xo == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
CTGroupShape gs;
|
||||||
|
try {
|
||||||
|
gs = CTGroupShape.Factory.parse(xo.newDomNode());
|
||||||
|
} catch (XmlException e) {
|
||||||
|
LOG.log(POILogger.WARN, "Can't parse fallback picture stream of graphical frame", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gs.sizeOfPicArray() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new XSLFPictureShape(gs.getPicArray(0), getSheet());
|
||||||
|
}
|
||||||
}
|
}
|
@ -257,7 +257,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
|
|||||||
|
|
||||||
public Placeholder getPlaceholder() {
|
public Placeholder getPlaceholder() {
|
||||||
CTPlaceholder ph = getCTPlaceholder();
|
CTPlaceholder ph = getCTPlaceholder();
|
||||||
if (ph == null || !ph.isSetType()) {
|
if (ph == null || !(ph.isSetType() || ph.isSetIdx())) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return Placeholder.lookupOoxml(ph.getType().intValue());
|
return Placeholder.lookupOoxml(ph.getType().intValue());
|
||||||
|
@ -37,6 +37,7 @@ public class TestPPTX2PNG {
|
|||||||
POIDataSamples samples = POIDataSamples.getSlideShowInstance();
|
POIDataSamples samples = POIDataSamples.getSlideShowInstance();
|
||||||
|
|
||||||
String[] testFiles = {"alterman_security.ppt","alterman_security.pptx","KEY02.pptx","themes.pptx","backgrounds.pptx","layouts.pptx", "sample.pptx", "shapes.pptx",};
|
String[] testFiles = {"alterman_security.ppt","alterman_security.pptx","KEY02.pptx","themes.pptx","backgrounds.pptx","layouts.pptx", "sample.pptx", "shapes.pptx",};
|
||||||
|
// String[] testFiles = {"41246-2.ppt","45543.ppt","53446.ppt","ParagraphStylesShorterThanCharStyles.ppt"};
|
||||||
String[] args = {
|
String[] args = {
|
||||||
"-format", "null", // png,gif,jpg or null for test
|
"-format", "null", // png,gif,jpg or null for test
|
||||||
"-slide", "-1", // -1 for all
|
"-slide", "-1", // -1 for all
|
||||||
|
@ -155,7 +155,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return color of the line. If color is not set returns <code>java.awt.Color.black</code>
|
* @return color of the line. If color is not set returns {@code null}
|
||||||
*/
|
*/
|
||||||
public Color getLineColor(){
|
public Color getLineColor(){
|
||||||
AbstractEscherOptRecord opt = getEscherOptRecord();
|
AbstractEscherOptRecord opt = getEscherOptRecord();
|
||||||
@ -164,7 +164,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
|
|||||||
if(p != null && (p.getPropertyValue() & 0x8) == 0) return null;
|
if(p != null && (p.getPropertyValue() & 0x8) == 0) return null;
|
||||||
|
|
||||||
Color clr = getColor(EscherProperties.LINESTYLE__COLOR, EscherProperties.LINESTYLE__OPACITY, -1);
|
Color clr = getColor(EscherProperties.LINESTYLE__COLOR, EscherProperties.LINESTYLE__OPACITY, -1);
|
||||||
return clr == null ? Color.black : clr;
|
return clr == null ? null : clr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -270,7 +270,6 @@ public class HwmfGraphics {
|
|||||||
* This methods gathers and sets the corresponding graphics transformations.
|
* This methods gathers and sets the corresponding graphics transformations.
|
||||||
*/
|
*/
|
||||||
public void updateWindowMapMode() {
|
public void updateWindowMapMode() {
|
||||||
GraphicsConfiguration gc = graphicsCtx.getDeviceConfiguration();
|
|
||||||
Rectangle2D win = prop.getWindow();
|
Rectangle2D win = prop.getWindow();
|
||||||
HwmfMapMode mapMode = prop.getMapMode();
|
HwmfMapMode mapMode = prop.getMapMode();
|
||||||
graphicsCtx.setTransform(initialAT);
|
graphicsCtx.setTransform(initialAT);
|
||||||
@ -292,12 +291,14 @@ public class HwmfGraphics {
|
|||||||
case MM_HIMETRIC:
|
case MM_HIMETRIC:
|
||||||
case MM_LOENGLISH:
|
case MM_LOENGLISH:
|
||||||
case MM_HIENGLISH:
|
case MM_HIENGLISH:
|
||||||
case MM_TWIPS:
|
case MM_TWIPS: {
|
||||||
// TODO: to be validated ...
|
// TODO: to be validated ...
|
||||||
|
GraphicsConfiguration gc = graphicsCtx.getDeviceConfiguration();
|
||||||
graphicsCtx.transform(gc.getNormalizingTransform());
|
graphicsCtx.transform(gc.getNormalizingTransform());
|
||||||
graphicsCtx.scale(1./mapMode.scale, -1./mapMode.scale);
|
graphicsCtx.scale(1./mapMode.scale, -1./mapMode.scale);
|
||||||
graphicsCtx.translate(-win.getX(), -win.getY());
|
graphicsCtx.translate(-win.getX(), -win.getY());
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case MM_TEXT:
|
case MM_TEXT:
|
||||||
// TODO: to be validated ...
|
// TODO: to be validated ...
|
||||||
break;
|
break;
|
||||||
|
@ -0,0 +1,115 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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.draw;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Insets;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.awt.image.RescaleOp;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.apache.poi.hwmf.usermodel.HwmfPicture;
|
||||||
|
import org.apache.poi.sl.draw.ImageRenderer;
|
||||||
|
import org.apache.poi.sl.usermodel.PictureData;
|
||||||
|
import org.apache.poi.util.Units;
|
||||||
|
|
||||||
|
public class HwmfSLImageRenderer implements ImageRenderer {
|
||||||
|
HwmfPicture image = null;
|
||||||
|
double alpha = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadImage(InputStream data, String contentType) throws IOException {
|
||||||
|
if (!PictureData.PictureType.WMF.contentType.equals(contentType)) {
|
||||||
|
throw new IOException("Invalid picture type");
|
||||||
|
}
|
||||||
|
image = new HwmfPicture(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadImage(byte[] data, String contentType) throws IOException {
|
||||||
|
if (!PictureData.PictureType.WMF.contentType.equals(contentType)) {
|
||||||
|
throw new IOException("Invalid picture type");
|
||||||
|
}
|
||||||
|
image = new HwmfPicture(new ByteArrayInputStream(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension getDimension() {
|
||||||
|
int width = 0, height = 0;
|
||||||
|
if (image != null) {
|
||||||
|
Dimension dim = image.getSize();
|
||||||
|
width = Units.pointsToPixel(dim.getWidth());
|
||||||
|
// keep aspect ratio for height
|
||||||
|
height = Units.pointsToPixel(dim.getHeight());
|
||||||
|
}
|
||||||
|
return new Dimension(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAlpha(double alpha) {
|
||||||
|
this.alpha = alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BufferedImage getImage() {
|
||||||
|
if (image == null) {
|
||||||
|
return new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
}
|
||||||
|
|
||||||
|
Dimension dim = getDimension();
|
||||||
|
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);
|
||||||
|
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||||
|
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
||||||
|
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
|
||||||
|
image.draw(g);
|
||||||
|
g.dispose();
|
||||||
|
|
||||||
|
if (alpha != 0) {
|
||||||
|
BufferedImage newImg = new BufferedImage((int)dim.getWidth(), (int)dim.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||||
|
g = newImg.createGraphics();
|
||||||
|
RescaleOp op = new RescaleOp(new float[]{1.0f, 1.0f, 1.0f, (float)alpha}, new float[]{0,0,0,0}, null);
|
||||||
|
g.drawImage(bufImg, op, 0, 0);
|
||||||
|
g.dispose();
|
||||||
|
bufImg = newImg;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bufImg;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean drawImage(Graphics2D graphics, Rectangle2D anchor) {
|
||||||
|
return drawImage(graphics, anchor, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean drawImage(Graphics2D graphics, Rectangle2D anchor, Insets clip) {
|
||||||
|
if (image == null) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
image.draw(graphics, anchor);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -339,7 +339,7 @@ public class HwmfMisc {
|
|||||||
* The META_DIBCREATEPATTERNBRUSH record creates a Brush Object with a
|
* The META_DIBCREATEPATTERNBRUSH record creates a Brush Object with a
|
||||||
* pattern specified by a DeviceIndependentBitmap (DIB) Object
|
* pattern specified by a DeviceIndependentBitmap (DIB) Object
|
||||||
*/
|
*/
|
||||||
public static class WmfDibCreatePatternBrush implements HwmfRecord, HwmfImageRecord {
|
public static class WmfDibCreatePatternBrush implements HwmfRecord, HwmfImageRecord, HwmfObjectTableEntry {
|
||||||
|
|
||||||
private HwmfBrushStyle style;
|
private HwmfBrushStyle style;
|
||||||
|
|
||||||
@ -388,6 +388,11 @@ public class HwmfMisc {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(HwmfGraphics ctx) {
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
ctx.addObjectTableEntry(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyObject(HwmfGraphics ctx) {
|
||||||
HwmfDrawProperties prop = ctx.getProperties();
|
HwmfDrawProperties prop = ctx.getProperties();
|
||||||
prop.setBrushStyle(style);
|
prop.setBrushStyle(style);
|
||||||
prop.setBrushBitmap(getImage());
|
prop.setBrushBitmap(getImage());
|
||||||
|
@ -102,11 +102,11 @@ public class HwmfPicture {
|
|||||||
try {
|
try {
|
||||||
Rectangle2D wmfBounds = getBounds();
|
Rectangle2D wmfBounds = getBounds();
|
||||||
// scale output bounds to image bounds
|
// scale output bounds to image bounds
|
||||||
|
ctx.translate(graphicsBounds.getX(), graphicsBounds.getY());
|
||||||
ctx.scale(graphicsBounds.getWidth()/wmfBounds.getWidth(), graphicsBounds.getHeight()/wmfBounds.getHeight());
|
ctx.scale(graphicsBounds.getWidth()/wmfBounds.getWidth(), graphicsBounds.getHeight()/wmfBounds.getHeight());
|
||||||
ctx.translate(-wmfBounds.getX(), -wmfBounds.getY());
|
|
||||||
|
|
||||||
HwmfGraphics g = new HwmfGraphics(ctx, wmfBounds);
|
HwmfGraphics g = new HwmfGraphics(ctx, wmfBounds);
|
||||||
for (HwmfRecord r : records) {
|
for (HwmfRecord r : records) {
|
||||||
r.draw(g);
|
r.draw(g);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user