Added workarounds to tests for JDK 6 LineBreakMeasurer bug and handle it
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1644806 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
dbfabda346
commit
1460fd33b2
@ -20,6 +20,7 @@ package org.apache.poi.hssf.usermodel;
|
||||
import java.awt.Dimension;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.apache.poi.ddf.DefaultEscherRecordFactory;
|
||||
import org.apache.poi.ddf.EscherBSERecord;
|
||||
@ -218,19 +219,14 @@ public class HSSFPicture extends HSSFSimpleShape implements Picture {
|
||||
}
|
||||
|
||||
/**
|
||||
* The color applied to the lines of this shape.
|
||||
* The filename of the embedded image
|
||||
*/
|
||||
public String getFileName() {
|
||||
EscherComplexProperty propFile = (EscherComplexProperty) getOptRecord().lookup(
|
||||
EscherProperties.BLIP__BLIPFILENAME);
|
||||
try {
|
||||
if (null == propFile){
|
||||
return "";
|
||||
}
|
||||
return new String(propFile.getComplexData(), "UTF-16LE").trim();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return "";
|
||||
}
|
||||
return (null == propFile)
|
||||
? ""
|
||||
: new String(propFile.getComplexData(), Charset.forName("UTF-16LE")).trim();
|
||||
}
|
||||
|
||||
public void setFileName(String data){
|
||||
|
51
src/java/org/apache/poi/util/JvmBugs.java
Normal file
51
src/java/org/apache/poi/util/JvmBugs.java
Normal file
@ -0,0 +1,51 @@
|
||||
/* ====================================================================
|
||||
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.util;
|
||||
|
||||
public class JvmBugs {
|
||||
private static final POILogger LOG = POILogFactory.getLogger(JvmBugs.class);
|
||||
|
||||
/**
|
||||
* The LineBreakMeasurer is used for calculating text bounds.
|
||||
* The last official JDK 6 version (1.6.0_45) and also JDK 7 (1.7.0_21)
|
||||
* for Windows are affected. For JDK 7 - update to a more recent version.
|
||||
* For JDK 6 - replace the fontmanager.dll with the previous release.
|
||||
*
|
||||
* For performance reasons, this method only checks for a windows jvm
|
||||
* with version 1.6.0_45 and 1.7.0_21.
|
||||
*
|
||||
* Set system property "org.apache.poi.JvmBugs.LineBreakMeasurer.ignore" to "true"
|
||||
* to bypass this check and use the normal fonts.
|
||||
*
|
||||
* @return true, if jvm is bugged, caller code should use Lucida Sans
|
||||
* instead of Calibri and Lucida Bright instead of Cambria
|
||||
*
|
||||
* @see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=54904">POI Bug #54904</a>
|
||||
* @see <a href="http://bugs.java.com/view_bug.do?bug_id=6501991">JDK Bug #6501991</a>
|
||||
* @see <a href="https://bitbucket.org/fakraemer/line-break-measurer-test">LineBreakMeasurerTest</a>
|
||||
*/
|
||||
public static boolean hasLineBreakMeasurerBug() {
|
||||
String version = System.getProperty("java.version");
|
||||
String os = System.getProperty("os.name").toLowerCase();
|
||||
boolean ignore = Boolean.getBoolean("org.apache.poi.JvmBugs.LineBreakMeasurer.ignore");
|
||||
boolean hasBug = (!ignore && (os.contains("win") && ("1.6.0_45".equals(version) || "1.7.0_21".equals(version))));
|
||||
if (hasBug) {
|
||||
LOG.log(POILogger.WARN, "JVM has LineBreakMeasurer bug - see POI bug #54904 - caller code might default to Lucida Sans");
|
||||
}
|
||||
return hasBug;
|
||||
}
|
||||
}
|
@ -16,15 +16,6 @@
|
||||
==================================================================== */
|
||||
package org.apache.poi.xslf.usermodel;
|
||||
|
||||
import org.apache.poi.util.Beta;
|
||||
import org.apache.poi.util.Internal;
|
||||
import org.apache.poi.util.Units;
|
||||
import org.apache.poi.xslf.model.ParagraphPropertyFetcher;
|
||||
import org.apache.xmlbeans.XmlObject;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.*;
|
||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
|
||||
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.font.LineBreakMeasurer;
|
||||
@ -36,6 +27,35 @@ import java.text.AttributedString;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.poi.hslf.model.TextPainter;
|
||||
import org.apache.poi.util.Beta;
|
||||
import org.apache.poi.util.Internal;
|
||||
import org.apache.poi.util.Units;
|
||||
import org.apache.poi.xslf.model.ParagraphPropertyFetcher;
|
||||
import org.apache.xmlbeans.XmlObject;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextAutonumberBullet;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePercent;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePoint;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharBullet;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacing;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStop;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStopList;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAutonumberScheme;
|
||||
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
|
||||
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
|
||||
|
||||
/**
|
||||
* Represents a paragraph of text within the containing text body.
|
||||
@ -823,6 +843,11 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
||||
|
||||
// user can pass an custom object to convert fonts
|
||||
String fontFamily = run.getFontFamily();
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(TextPainter.KEY_FONTMAP);
|
||||
if (fontMap != null && fontMap.containsKey(fontFamily)) {
|
||||
fontFamily = fontMap.get(fontFamily);
|
||||
}
|
||||
if(fontHandler != null) {
|
||||
fontFamily = fontHandler.getRendererableFont(fontFamily, run.getPitchAndFamily());
|
||||
}
|
||||
@ -1016,7 +1041,7 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
||||
}
|
||||
}
|
||||
|
||||
private boolean fetchParagraphProperty(ParagraphPropertyFetcher visitor){
|
||||
private <T> boolean fetchParagraphProperty(ParagraphPropertyFetcher<T> visitor){
|
||||
boolean ok = false;
|
||||
|
||||
if(_p.isSetPPr()) ok = visitor.fetch(_p.getPPr());
|
||||
|
@ -19,20 +19,25 @@
|
||||
|
||||
package org.apache.poi.xslf.usermodel;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.poi.xslf.XSLFTestDataSamples;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.poi.hslf.model.TextPainter;
|
||||
import org.apache.poi.util.JvmBugs;
|
||||
import org.apache.poi.xslf.XSLFTestDataSamples;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Date: 10/26/11
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class TestPPTX2PNG extends TestCase {
|
||||
public void testRender(){
|
||||
public class TestPPTX2PNG {
|
||||
@Test
|
||||
public void render(){
|
||||
String[] testFiles = {"layouts.pptx", "sample.pptx", "shapes.pptx",
|
||||
"themes.pptx", "backgrounds.pptx"};
|
||||
for(String sampleFile : testFiles){
|
||||
@ -41,10 +46,20 @@ public class TestPPTX2PNG extends TestCase {
|
||||
for(XSLFSlide slide : pptx.getSlides()){
|
||||
BufferedImage img = new BufferedImage(pg.width, pg.height, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D graphics = img.createGraphics();
|
||||
|
||||
fixFonts(graphics);
|
||||
slide.draw(graphics);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
@ -334,6 +334,7 @@ public abstract class BaseTestBugzillaIssues {
|
||||
@Test
|
||||
public final void bug506819_testAutoSize() {
|
||||
Workbook wb = _testDataProvider.createWorkbook();
|
||||
BaseTestSheetAutosizeColumn.fixFonts(wb);
|
||||
Sheet sheet = wb.createSheet("Sheet1");
|
||||
Row row = sheet.createRow(0);
|
||||
Cell cell0 = row.createCell(0);
|
||||
|
@ -17,9 +17,12 @@
|
||||
|
||||
package org.apache.poi.ss.usermodel;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.apache.poi.ss.ITestDataProvider;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.util.JvmBugs;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
@ -28,7 +31,7 @@ import java.util.Calendar;
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public abstract class BaseTestSheetAutosizeColumn extends TestCase {
|
||||
public abstract class BaseTestSheetAutosizeColumn {
|
||||
|
||||
private final ITestDataProvider _testDataProvider;
|
||||
|
||||
@ -36,23 +39,10 @@ public abstract class BaseTestSheetAutosizeColumn extends TestCase {
|
||||
_testDataProvider = testDataProvider;
|
||||
}
|
||||
|
||||
// TODO should we have this stuff in the FormulaEvaluator?
|
||||
private void evaluateWorkbook(Workbook workbook){
|
||||
FormulaEvaluator eval = workbook.getCreationHelper().createFormulaEvaluator();
|
||||
for(int i=0; i < workbook.getNumberOfSheets(); i++) {
|
||||
Sheet sheet = workbook.getSheetAt(i);
|
||||
for (Row r : sheet) {
|
||||
for (Cell c : r) {
|
||||
if (c.getCellType() == Cell.CELL_TYPE_FORMULA){
|
||||
eval.evaluateFormulaCell(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testNumericCells(){
|
||||
@Test
|
||||
public void numericCells(){
|
||||
Workbook workbook = _testDataProvider.createWorkbook();
|
||||
fixFonts(workbook);
|
||||
DataFormat df = workbook.getCreationHelper().createDataFormat();
|
||||
Sheet sheet = workbook.createSheet();
|
||||
|
||||
@ -89,8 +79,10 @@ public abstract class BaseTestSheetAutosizeColumn extends TestCase {
|
||||
assertEquals(sheet.getColumnWidth(4), sheet.getColumnWidth(5)); // 10.0000 and '10.0000'
|
||||
}
|
||||
|
||||
public void testBooleanCells(){
|
||||
@Test
|
||||
public void booleanCells(){
|
||||
Workbook workbook = _testDataProvider.createWorkbook();
|
||||
fixFonts(workbook);
|
||||
Sheet sheet = workbook.createSheet();
|
||||
|
||||
Row row = sheet.createRow(0);
|
||||
@ -116,8 +108,10 @@ public abstract class BaseTestSheetAutosizeColumn extends TestCase {
|
||||
assertEquals(sheet.getColumnWidth(2), sheet.getColumnWidth(3)); // columns 1, 2 and 3 should have the same width
|
||||
}
|
||||
|
||||
public void testDateCells(){
|
||||
@Test
|
||||
public void dateCells(){
|
||||
Workbook workbook = _testDataProvider.createWorkbook();
|
||||
fixFonts(workbook);
|
||||
Sheet sheet = workbook.createSheet();
|
||||
DataFormat df = workbook.getCreationHelper().createDataFormat();
|
||||
|
||||
@ -180,8 +174,10 @@ public abstract class BaseTestSheetAutosizeColumn extends TestCase {
|
||||
assertEquals(sheet.getColumnWidth(4), sheet.getColumnWidth(7)); // date formula formatted as 'mmm'
|
||||
}
|
||||
|
||||
public void testStringCells(){
|
||||
@Test
|
||||
public void stringCells(){
|
||||
Workbook workbook = _testDataProvider.createWorkbook();
|
||||
fixFonts(workbook);
|
||||
Sheet sheet = workbook.createSheet();
|
||||
Row row = sheet.createRow(0);
|
||||
|
||||
@ -207,11 +203,14 @@ public abstract class BaseTestSheetAutosizeColumn extends TestCase {
|
||||
assertTrue(2*sheet.getColumnWidth(0) < sheet.getColumnWidth(1)); // width is roughly proportional to the number of characters
|
||||
assertTrue(2*sheet.getColumnWidth(1) < sheet.getColumnWidth(2));
|
||||
assertEquals(sheet.getColumnWidth(4), sheet.getColumnWidth(3));
|
||||
assertTrue(sheet.getColumnWidth(5) > sheet.getColumnWidth(4)); //larger font results in a wider column width
|
||||
boolean ignoreFontSizeX2 = JvmBugs.hasLineBreakMeasurerBug();
|
||||
assertTrue(ignoreFontSizeX2 || sheet.getColumnWidth(5) > sheet.getColumnWidth(4)); //larger font results in a wider column width
|
||||
}
|
||||
|
||||
public void testRotatedText(){
|
||||
@Test
|
||||
public void rotatedText(){
|
||||
Workbook workbook = _testDataProvider.createWorkbook();
|
||||
fixFonts(workbook);
|
||||
Sheet sheet = workbook.createSheet();
|
||||
Row row = sheet.createRow(0);
|
||||
|
||||
@ -233,8 +232,10 @@ public abstract class BaseTestSheetAutosizeColumn extends TestCase {
|
||||
assertTrue(w0*5 < w1); // rotated text occupies at least five times less horizontal space than normal text
|
||||
}
|
||||
|
||||
public void testMergedCells(){
|
||||
@Test
|
||||
public void mergedCells(){
|
||||
Workbook workbook = _testDataProvider.createWorkbook();
|
||||
fixFonts(workbook);
|
||||
Sheet sheet = workbook.createSheet();
|
||||
|
||||
Row row = sheet.createRow(0);
|
||||
@ -257,8 +258,10 @@ public abstract class BaseTestSheetAutosizeColumn extends TestCase {
|
||||
* Auto-Sizing a column needs to work when we have rows
|
||||
* passed the 32767 boundary. See bug #48079
|
||||
*/
|
||||
public void testLargeRowNumbers() throws Exception {
|
||||
@Test
|
||||
public void largeRowNumbers() throws Exception {
|
||||
Workbook workbook = _testDataProvider.createWorkbook();
|
||||
fixFonts(workbook);
|
||||
Sheet sheet = workbook.createSheet();
|
||||
|
||||
Row r0 = sheet.createRow(0);
|
||||
@ -291,4 +294,31 @@ public abstract class BaseTestSheetAutosizeColumn extends TestCase {
|
||||
r60708.createCell(0).setCellValue("Near the end");
|
||||
sheet.autoSizeColumn(0);
|
||||
}
|
||||
|
||||
// TODO should we have this stuff in the FormulaEvaluator?
|
||||
private void evaluateWorkbook(Workbook workbook){
|
||||
FormulaEvaluator eval = workbook.getCreationHelper().createFormulaEvaluator();
|
||||
for(int i=0; i < workbook.getNumberOfSheets(); i++) {
|
||||
Sheet sheet = workbook.getSheetAt(i);
|
||||
for (Row r : sheet) {
|
||||
for (Cell c : r) {
|
||||
if (c.getCellType() == Cell.CELL_TYPE_FORMULA){
|
||||
eval.evaluateFormulaCell(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static void fixFonts(Workbook workbook) {
|
||||
if (!JvmBugs.hasLineBreakMeasurerBug()) return;
|
||||
for (int i=workbook.getNumberOfFonts()-1; i>=0; i--) {
|
||||
Font f = workbook.getFontAt((short)0);
|
||||
if ("Calibri".equals(f.getFontName())) {
|
||||
f.setFontName("Lucida Sans");
|
||||
} else if ("Cambria".equals(f.getFontName())) {
|
||||
f.setFontName("Lucida Bright");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user