/* ==================================================================== | |
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.hslf.usermodel; | |
import static org.junit.Assert.assertArrayEquals; | |
import static org.junit.Assume.assumeTrue; | |
import java.awt.Color; | |
import java.awt.Dimension; | |
import java.awt.Font; | |
import java.awt.Graphics2D; | |
import java.awt.GraphicsEnvironment; | |
import java.awt.RenderingHints; | |
import java.awt.geom.AffineTransform; | |
import java.awt.geom.Rectangle2D; | |
import java.awt.image.BufferedImage; | |
import java.awt.image.DataBufferByte; | |
import java.io.File; | |
import java.io.InputStream; | |
import java.util.Arrays; | |
import java.util.HashMap; | |
import java.util.Map; | |
import javax.imageio.ImageIO; | |
import org.apache.poi.POIDataSamples; | |
import org.apache.poi.sl.draw.Drawable; | |
import org.apache.poi.util.TempFile; | |
import org.junit.Test; | |
/** | |
* Test font rendering of alternative and fallback fonts | |
*/ | |
public class TestFontRendering { | |
private static POIDataSamples slTests = POIDataSamples.getSlideShowInstance(); | |
// @Ignore2("This fails on some systems because fonts are rendered slightly different") | |
@Test | |
public void bug55902mixedFontWithChineseCharacters() throws Exception { | |
// font files need to be downloaded first via | |
// ant test-scratchpad-download-resources | |
String fontFiles[][] = { | |
// Calibri is not available on *nix systems, so we need to use another similar free font | |
{ "build/scratchpad-test-resources/Cabin-Regular.ttf", "mapped", "Calibri" }, | |
// use "MS PGothic" if available (Windows only) ... | |
// for the junit test not all chars are rendered | |
{ "build/scratchpad-test-resources/mona.ttf", "fallback", "Cabin" } | |
}; | |
// setup fonts (especially needed, when run under *nix systems) | |
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); | |
Map<String,String> fontMap = new HashMap<String,String>(); | |
Map<String,String> fallbackMap = new HashMap<String,String>(); | |
for (String fontFile[] : fontFiles) { | |
File f = new File(fontFile[0]); | |
assumeTrue("necessary font file "+f.getName()+" not downloaded.", f.exists()); | |
Font font = Font.createFont(Font.TRUETYPE_FONT, f); | |
ge.registerFont(font); | |
Map<String,String> map = ("mapped".equals(fontFile[1]) ? fontMap : fallbackMap); | |
map.put(fontFile[2], font.getFamily()); | |
} | |
InputStream is = slTests.openResourceAsStream("bug55902-mixedFontChineseCharacters.ppt"); | |
HSLFSlideShow ss = new HSLFSlideShow(is); | |
is.close(); | |
Dimension pgsize = ss.getPageSize(); | |
HSLFSlide slide = ss.getSlides().get(0); | |
// render it | |
double zoom = 1; | |
AffineTransform at = new AffineTransform(); | |
at.setToScale(zoom, zoom); | |
BufferedImage imgActual = new BufferedImage((int)Math.ceil(pgsize.width*zoom), (int)Math.ceil(pgsize.height*zoom), BufferedImage.TYPE_3BYTE_BGR); | |
Graphics2D graphics = imgActual.createGraphics(); | |
graphics.setRenderingHint(Drawable.FONT_FALLBACK, fallbackMap); | |
graphics.setRenderingHint(Drawable.FONT_MAP, fontMap); | |
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); | |
graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); | |
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); | |
graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); | |
graphics.setTransform(at); | |
graphics.setPaint(Color.white); | |
graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height)); | |
slide.draw(graphics); | |
BufferedImage imgExpected = ImageIO.read(slTests.getFile("bug55902-mixedChars.png")); | |
DataBufferByte expectedDB = (DataBufferByte)imgExpected.getRaster().getDataBuffer(); | |
DataBufferByte actualDB = (DataBufferByte)imgActual.getRaster().getDataBuffer(); | |
byte[] expectedData = expectedDB.getData(0); | |
byte[] actualData = actualDB.getData(0); | |
// allow to find out what the actual difference is in CI where this fails currently | |
if(!Arrays.equals(expectedData, actualData)) { | |
ImageIO.write(imgActual, "PNG", TempFile.createTempFile("TestFontRendering", ".png")); | |
} | |
assertArrayEquals("Expected to have matching raster-arrays, but found differences", expectedData, actualData); | |
} | |
} |