git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1648335 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_12_BETA1
import org.apache.poi.util.POILogger; | import org.apache.poi.util.POILogger; | ||||
import org.apache.poi.util.POILogFactory; | import org.apache.poi.util.POILogFactory; | ||||
/* ==================================================================== | /* ==================================================================== | ||||
Licensed to the Apache Software Foundation (ASF) under one or more | Licensed to the Apache Software Foundation (ASF) under one or more | ||||
contributor license agreements. See the NOTICE file distributed with | contributor license agreements. See the NOTICE file distributed with | ||||
limitations under the License. | limitations under the License. | ||||
==================================================================== */ | ==================================================================== */ | ||||
import javax.imageio.ImageIO; | import javax.imageio.ImageIO; | ||||
import java.awt.*; | import java.awt.*; | ||||
import java.awt.geom.AffineTransform; | |||||
import java.awt.image.BufferedImage; | import java.awt.image.BufferedImage; | ||||
import java.io.ByteArrayInputStream; | import java.io.ByteArrayInputStream; | ||||
public void paint(Graphics2D graphics, PictureData pict, Picture parent) { | public void paint(Graphics2D graphics, PictureData pict, Picture parent) { | ||||
BufferedImage img; | BufferedImage img; | ||||
try { | try { | ||||
img = ImageIO.read(new ByteArrayInputStream(pict.getData())); | |||||
} | |||||
catch (Exception e){ | |||||
img = ImageIO.read(new ByteArrayInputStream(pict.getData())); | |||||
} catch (Exception e) { | |||||
logger.log(POILogger.WARN, "ImageIO failed to create image. image.type: " + pict.getType()); | logger.log(POILogger.WARN, "ImageIO failed to create image. image.type: " + pict.getType()); | ||||
return; | return; | ||||
} | } | ||||
boolean isClipped = true; | |||||
Insets clip = parent.getBlipClip(); | |||||
if (clip == null) { | |||||
isClipped = false; | |||||
clip = new Insets(0,0,0,0); | |||||
} | |||||
int iw = img.getWidth(); | |||||
int ih = img.getHeight(); | |||||
Rectangle anchor = parent.getLogicalAnchor2D().getBounds(); | Rectangle anchor = parent.getLogicalAnchor2D().getBounds(); | ||||
graphics.drawImage(img, anchor.x, anchor.y, anchor.width, anchor.height, null); | |||||
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); | |||||
} | } | ||||
} | } |
package org.apache.poi.hslf.model; | package org.apache.poi.hslf.model; | ||||
import java.awt.Graphics2D; | import java.awt.Graphics2D; | ||||
import java.awt.Insets; | |||||
import java.awt.geom.AffineTransform; | import java.awt.geom.AffineTransform; | ||||
import java.awt.image.BufferedImage; | import java.awt.image.BufferedImage; | ||||
import java.io.ByteArrayInputStream; | import java.io.ByteArrayInputStream; | ||||
graphics.setTransform(at); | graphics.setTransform(at); | ||||
} | } | ||||
} | |||||
/** | |||||
* Returns the clipping values as percent ratio relatively to the image size. | |||||
* The anchor specified by {@link #getLogicalAnchor2D()} is the displayed size, | |||||
* i.e. the size of the already clipped image | |||||
* | |||||
* @return the clipping as insets converted/scaled to 100000 (=100%) | |||||
*/ | |||||
public Insets getBlipClip() { | |||||
EscherOptRecord opt = getEscherOptRecord(); | |||||
double top = getFractProp(opt, EscherProperties.BLIP__CROPFROMTOP); | |||||
double bottom = getFractProp(opt, EscherProperties.BLIP__CROPFROMBOTTOM); | |||||
double left = getFractProp(opt, EscherProperties.BLIP__CROPFROMLEFT); | |||||
double right = getFractProp(opt, EscherProperties.BLIP__CROPFROMRIGHT); | |||||
// if all crop values are zero (the default) then no crop rectangle is set, return null | |||||
return (top==0 && bottom==0 && left==0 && right==0) | |||||
? null | |||||
: new Insets((int)(top*100000), (int)(left*100000), (int)(bottom*100000), (int)(right*100000)); | |||||
} | |||||
/** | |||||
* @return the fractional property or 0 if not defined | |||||
* | |||||
* @see <a href="http://msdn.microsoft.com/en-us/library/dd910765(v=office.12).aspx">2.2.1.6 FixedPoint</a> | |||||
*/ | |||||
private static double getFractProp(EscherOptRecord opt, short propertyId) { | |||||
EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, propertyId); | |||||
if (prop == null) return 0; | |||||
int fixedPoint = prop.getPropertyValue(); | |||||
int i = (fixedPoint >> 16); | |||||
int f = (fixedPoint >> 0) & 0xFFFF; | |||||
double fp = i + f/65536.0; | |||||
return fp; | |||||
} | |||||
} |
package org.apache.poi.hslf.model; | package org.apache.poi.hslf.model; | ||||
import junit.framework.Test; | |||||
import junit.framework.TestSuite; | |||||
import org.junit.runner.RunWith; | |||||
import org.junit.runners.Suite; | |||||
/** | /** | ||||
* Collects all tests from the package <tt>org.apache.poi.hslf.model</tt>. | * Collects all tests from the package <tt>org.apache.poi.hslf.model</tt>. | ||||
* | |||||
* @author Josh Micich | |||||
*/ | */ | ||||
@RunWith(Suite.class) | |||||
@Suite.SuiteClasses({ | |||||
TestBackground.class, | |||||
TestFreeform.class, | |||||
TestHeadersFooters.class, | |||||
TestHyperlink.class, | |||||
TestImagePainter.class, | |||||
TestLine.class, | |||||
TestMovieShape.class, | |||||
TestOleEmbedding.class, | |||||
TestPPFont.class, | |||||
TestPPGraphics2D.class, | |||||
TestPicture.class, | |||||
TestSetBoldItalic.class, | |||||
TestShapes.class, | |||||
TestSheet.class, | |||||
TestSlideChangeNotes.class, | |||||
TestSlideMaster.class, | |||||
TestSlides.class, | |||||
TestTable.class, | |||||
TestTextRun.class, | |||||
TestTextRunReWrite.class, | |||||
TestTextShape.class | |||||
}) | |||||
public class AllHSLFModelTests { | public class AllHSLFModelTests { | ||||
public static Test suite() { | |||||
TestSuite result = new TestSuite(AllHSLFModelTests.class.getName()); | |||||
result.addTestSuite(TestBackground.class); | |||||
result.addTestSuite(TestFreeform.class); | |||||
result.addTestSuite(TestHeadersFooters.class); | |||||
result.addTestSuite(TestHyperlink.class); | |||||
result.addTestSuite(TestImagePainter.class); | |||||
result.addTestSuite(TestLine.class); | |||||
result.addTestSuite(TestMovieShape.class); | |||||
result.addTestSuite(TestOleEmbedding.class); | |||||
result.addTestSuite(TestPPFont.class); | |||||
result.addTestSuite(TestPPGraphics2D.class); | |||||
result.addTestSuite(TestPicture.class); | |||||
result.addTestSuite(TestSetBoldItalic.class); | |||||
result.addTestSuite(TestShapes.class); | |||||
result.addTestSuite(TestSheet.class); | |||||
result.addTestSuite(TestSlideChangeNotes.class); | |||||
result.addTestSuite(TestSlideMaster.class); | |||||
result.addTestSuite(TestSlides.class); | |||||
result.addTestSuite(TestTable.class); | |||||
result.addTestSuite(TestTextRun.class); | |||||
result.addTestSuite(TestTextRunReWrite.class); | |||||
result.addTestSuite(TestTextShape.class); | |||||
return result; | |||||
} | |||||
} | } |
package org.apache.poi.hslf.model; | package org.apache.poi.hslf.model; | ||||
import static org.junit.Assert.assertEquals; | |||||
import static org.junit.Assert.assertNotNull; | |||||
import static org.junit.Assert.assertNull; | |||||
import static org.junit.Assert.assertSame; | |||||
import java.awt.Dimension; | |||||
import java.awt.Graphics2D; | import java.awt.Graphics2D; | ||||
import java.awt.Rectangle; | import java.awt.Rectangle; | ||||
import java.awt.image.BufferedImage; | import java.awt.image.BufferedImage; | ||||
import java.io.ByteArrayInputStream; | import java.io.ByteArrayInputStream; | ||||
import javax.imageio.ImageIO; | |||||
import java.io.File; | |||||
import java.io.InputStream; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
import junit.framework.TestCase; | |||||
import javax.imageio.ImageIO; | |||||
import org.apache.poi.POIDataSamples; | |||||
import org.apache.poi.ddf.EscherBSERecord; | import org.apache.poi.ddf.EscherBSERecord; | ||||
import org.apache.poi.hslf.HSLFSlideShow; | import org.apache.poi.hslf.HSLFSlideShow; | ||||
import org.apache.poi.hslf.usermodel.PictureData; | import org.apache.poi.hslf.usermodel.PictureData; | ||||
import org.apache.poi.hslf.usermodel.SlideShow; | import org.apache.poi.hslf.usermodel.SlideShow; | ||||
import org.apache.poi.POIDataSamples; | |||||
import org.apache.poi.util.JvmBugs; | |||||
import org.junit.Ignore; | |||||
import org.junit.Test; | |||||
/** | /** | ||||
* Test Picture shape. | * Test Picture shape. | ||||
* | * | ||||
* @author Yegor Kozlov | * @author Yegor Kozlov | ||||
*/ | */ | ||||
public final class TestPicture extends TestCase { | |||||
public final class TestPicture { | |||||
private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance(); | private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance(); | ||||
/** | /** | ||||
* This is important when the same image appears multiple times in a slide show. | * This is important when the same image appears multiple times in a slide show. | ||||
* | * | ||||
*/ | */ | ||||
public void testMultiplePictures() throws Exception { | |||||
@Test | |||||
public void multiplePictures() throws Exception { | |||||
SlideShow ppt = new SlideShow(); | SlideShow ppt = new SlideShow(); | ||||
Slide s = ppt.createSlide(); | Slide s = ppt.createSlide(); | ||||
* Picture#getEscherBSERecord threw NullPointerException if EscherContainerRecord.BSTORE_CONTAINER | * Picture#getEscherBSERecord threw NullPointerException if EscherContainerRecord.BSTORE_CONTAINER | ||||
* was not found. The correct behaviour is to return null. | * was not found. The correct behaviour is to return null. | ||||
*/ | */ | ||||
public void test46122() { | |||||
@Test | |||||
public void bug46122() { | |||||
SlideShow ppt = new SlideShow(); | SlideShow ppt = new SlideShow(); | ||||
Slide slide = ppt.createSlide(); | Slide slide = ppt.createSlide(); | ||||
pict.draw(graphics); | pict.draw(graphics); | ||||
} | } | ||||
public void testMacImages() throws Exception { | |||||
@Test | |||||
public void macImages() throws Exception { | |||||
HSLFSlideShow hss = new HSLFSlideShow(_slTests.openResourceAsStream("53446.ppt")); | HSLFSlideShow hss = new HSLFSlideShow(_slTests.openResourceAsStream("53446.ppt")); | ||||
PictureData[] pictures = hss.getPictures(); | PictureData[] pictures = hss.getPictures(); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
@Test | |||||
@Ignore("Just for visual validation - antialiasing is different on various systems") | |||||
public void bug54541() throws Exception { | |||||
// InputStream xis = _slTests.openResourceAsStream("54542_cropped_bitmap.pptx"); | |||||
// XMLSlideShow xss = new XMLSlideShow(xis); | |||||
// xis.close(); | |||||
// | |||||
// Dimension xpg = xss.getPageSize(); | |||||
// for(XSLFSlide slide : xss.getSlides()) { | |||||
// BufferedImage img = new BufferedImage(xpg.width, xpg.height, BufferedImage.TYPE_INT_RGB); | |||||
// Graphics2D graphics = img.createGraphics(); | |||||
// fixFonts(graphics); | |||||
// slide.draw(graphics); | |||||
// ImageIO.write(img, "PNG", new File("testx.png")); | |||||
// } | |||||
// | |||||
// System.out.println("########################"); | |||||
InputStream is = _slTests.openResourceAsStream("54541_cropped_bitmap.ppt"); | |||||
SlideShow ss = new SlideShow(is); | |||||
is.close(); | |||||
Dimension pg = ss.getPageSize(); | |||||
int i=1; | |||||
for(Slide slide : ss.getSlides()) { | |||||
BufferedImage img = new BufferedImage(pg.width, pg.height, BufferedImage.TYPE_INT_RGB); | |||||
Graphics2D graphics = img.createGraphics(); | |||||
fixFonts(graphics); | |||||
slide.draw(graphics); | |||||
ImageIO.write(img, "PNG", new File("test"+(i++)+".png")); | |||||
} | |||||
} | |||||
@SuppressWarnings("unchecked") | |||||
private void fixFonts(Graphics2D graphics) { | |||||
if (!JvmBugs.hasLineBreakMeasurerBug()) return; | |||||
Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(TextPainter.KEY_FONTMAP); | |||||
if (fontMap == null) fontMap = new HashMap<String,String>(); | |||||
fontMap.put("Calibri", "Lucida Sans"); | |||||
fontMap.put("Cambria", "Lucida Bright"); | |||||
graphics.setRenderingHint(TextPainter.KEY_FONTMAP, fontMap); | |||||
} | |||||
} | } |