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;
}
/**
- * 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){
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.util;\r
+\r
+public class JvmBugs {\r
+ private static final POILogger LOG = POILogFactory.getLogger(JvmBugs.class);\r
+ \r
+ /**\r
+ * The LineBreakMeasurer is used for calculating text bounds.\r
+ * The last official JDK 6 version (1.6.0_45) and also JDK 7 (1.7.0_21)\r
+ * for Windows are affected. For JDK 7 - update to a more recent version.\r
+ * For JDK 6 - replace the fontmanager.dll with the previous release.\r
+ * \r
+ * For performance reasons, this method only checks for a windows jvm\r
+ * with version 1.6.0_45 and 1.7.0_21.\r
+ * \r
+ * Set system property "org.apache.poi.JvmBugs.LineBreakMeasurer.ignore" to "true"\r
+ * to bypass this check and use the normal fonts.\r
+ * \r
+ * @return true, if jvm is bugged, caller code should use Lucida Sans\r
+ * instead of Calibri and Lucida Bright instead of Cambria\r
+ * \r
+ * @see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=54904">POI Bug #54904</a>\r
+ * @see <a href="http://bugs.java.com/view_bug.do?bug_id=6501991">JDK Bug #6501991</a>\r
+ * @see <a href="https://bitbucket.org/fakraemer/line-break-measurer-test">LineBreakMeasurerTest</a>\r
+ */\r
+ public static boolean hasLineBreakMeasurerBug() {\r
+ String version = System.getProperty("java.version");\r
+ String os = System.getProperty("os.name").toLowerCase();\r
+ boolean ignore = Boolean.getBoolean("org.apache.poi.JvmBugs.LineBreakMeasurer.ignore");\r
+ boolean hasBug = (!ignore && (os.contains("win") && ("1.6.0_45".equals(version) || "1.7.0_21".equals(version))));\r
+ if (hasBug) {\r
+ LOG.log(POILogger.WARN, "JVM has LineBreakMeasurer bug - see POI bug #54904 - caller code might default to Lucida Sans");\r
+ }\r
+ return hasBug;\r
+ }\r
+}\r
==================================================================== */\r
package org.apache.poi.xslf.usermodel;\r
\r
-import org.apache.poi.util.Beta;\r
-import org.apache.poi.util.Internal;\r
-import org.apache.poi.util.Units;\r
-import org.apache.poi.xslf.model.ParagraphPropertyFetcher;\r
-import org.apache.xmlbeans.XmlObject;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.*;\r
-import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;\r
-import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;\r
-\r
import java.awt.Color;\r
import java.awt.Graphics2D;\r
import java.awt.font.LineBreakMeasurer;\r
import java.util.ArrayList;\r
import java.util.Iterator;\r
import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.apache.poi.hslf.model.TextPainter;\r
+import org.apache.poi.util.Beta;\r
+import org.apache.poi.util.Internal;\r
+import org.apache.poi.util.Units;\r
+import org.apache.poi.xslf.model.ParagraphPropertyFetcher;\r
+import org.apache.xmlbeans.XmlObject;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextAutonumberBullet;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePercent;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePoint;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharBullet;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacing;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStop;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStopList;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.STTextAutonumberScheme;\r
+import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;\r
+import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;\r
\r
/**\r
* Represents a paragraph of text within the containing text body.\r
\r
// user can pass an custom object to convert fonts\r
String fontFamily = run.getFontFamily();\r
+ @SuppressWarnings("unchecked")\r
+ Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(TextPainter.KEY_FONTMAP);\r
+ if (fontMap != null && fontMap.containsKey(fontFamily)) {\r
+ fontFamily = fontMap.get(fontFamily);\r
+ }\r
if(fontHandler != null) {\r
fontFamily = fontHandler.getRendererableFont(fontFamily, run.getPitchAndFamily());\r
}\r
}\r
}\r
\r
- private boolean fetchParagraphProperty(ParagraphPropertyFetcher visitor){\r
+ private <T> boolean fetchParagraphProperty(ParagraphPropertyFetcher<T> visitor){\r
boolean ok = false;\r
\r
if(_p.isSetPPr()) ok = visitor.fetch(_p.getPPr());\r
\r
package org.apache.poi.xslf.usermodel;\r
\r
-import junit.framework.TestCase;\r
-import org.apache.poi.xslf.XSLFTestDataSamples;\r
-\r
import java.awt.Dimension;\r
import java.awt.Graphics2D;\r
import java.awt.image.BufferedImage;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.apache.poi.hslf.model.TextPainter;\r
+import org.apache.poi.util.JvmBugs;\r
+import org.apache.poi.xslf.XSLFTestDataSamples;\r
+import org.junit.Test;\r
\r
/**\r
* Date: 10/26/11\r
*\r
* @author Yegor Kozlov\r
*/\r
-public class TestPPTX2PNG extends TestCase {\r
- public void testRender(){\r
+public class TestPPTX2PNG {\r
+ @Test\r
+ public void render(){\r
String[] testFiles = {"layouts.pptx", "sample.pptx", "shapes.pptx",\r
"themes.pptx", "backgrounds.pptx"};\r
for(String sampleFile : testFiles){\r
for(XSLFSlide slide : pptx.getSlides()){\r
BufferedImage img = new BufferedImage(pg.width, pg.height, BufferedImage.TYPE_INT_RGB);\r
Graphics2D graphics = img.createGraphics();\r
-\r
+ fixFonts(graphics);\r
slide.draw(graphics);\r
\r
}\r
}\r
}\r
+ \r
+ @SuppressWarnings("unchecked")\r
+ private void fixFonts(Graphics2D graphics) {\r
+ if (!JvmBugs.hasLineBreakMeasurerBug()) return;\r
+ Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(TextPainter.KEY_FONTMAP);\r
+ if (fontMap == null) fontMap = new HashMap<String,String>();\r
+ fontMap.put("Calibri", "Lucida Sans");\r
+ fontMap.put("Cambria", "Lucida Bright");\r
+ graphics.setRenderingHint(TextPainter.KEY_FONTMAP, fontMap); \r
+ }\r
}\r
@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);
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;
*
* @author Yegor Kozlov
*/
-public abstract class BaseTestSheetAutosizeColumn extends TestCase {
+public abstract class BaseTestSheetAutosizeColumn {
private final ITestDataProvider _testDataProvider;
_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();
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);
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();
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);
-
+
Font defaultFont = workbook.getFontAt((short)0);
CellStyle style1 = workbook.createCellStyle();
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);
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);
* 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);
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");
+ }
+ }
+ }
}
\ No newline at end of file