aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Beeker <kiwiwings@apache.org>2017-07-08 22:20:55 +0000
committerAndreas Beeker <kiwiwings@apache.org>2017-07-08 22:20:55 +0000
commitc82aa1a4bbff606e82fb3c6ac10cbc6597a1c7d2 (patch)
tree27efe66783040df47f4f2ba1c2bd0d4f42bf957d
parent525424a9a20b0eb59a1bb5fb18cf3d0738704558 (diff)
downloadpoi-c82aa1a4bbff606e82fb3c6ac10cbc6597a1c7d2.tar.gz
poi-c82aa1a4bbff606e82fb3c6ac10cbc6597a1c7d2.zip
#61169 - Text with Japanese characters overflows textbox
- add resize methods with Graphics argument git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1801329 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/java/org/apache/poi/sl/draw/DrawTextShape.java2
-rw-r--r--src/java/org/apache/poi/sl/usermodel/TextShape.java36
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java64
-rw-r--r--src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java23
-rw-r--r--src/ooxml/testcases/org/apache/poi/sl/SLCommonUtils.java59
-rw-r--r--src/ooxml/testcases/org/apache/poi/sl/TestFonts.java158
-rw-r--r--src/ooxml/testcases/org/apache/poi/sl/TestHeadersFooters.java20
-rw-r--r--src/ooxml/testcases/org/apache/poi/sl/TestTable.java34
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java27
-rw-r--r--test-data/slideshow/mona.ttfbin0 -> 2828124 bytes
10 files changed, 346 insertions, 77 deletions
diff --git a/src/java/org/apache/poi/sl/draw/DrawTextShape.java b/src/java/org/apache/poi/sl/draw/DrawTextShape.java
index cffffb4a88..ed14653814 100644
--- a/src/java/org/apache/poi/sl/draw/DrawTextShape.java
+++ b/src/java/org/apache/poi/sl/draw/DrawTextShape.java
@@ -207,7 +207,7 @@ public class DrawTextShape extends DrawSimpleShape {
* @param oldGraphics the graphics context, which properties are to be copied, may be null
* @return the height in points
*/
- protected double getTextHeight(Graphics2D oldGraphics) {
+ public double getTextHeight(Graphics2D oldGraphics) {
// dry-run in a 1x1 image and return the vertical advance
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = img.createGraphics();
diff --git a/src/java/org/apache/poi/sl/usermodel/TextShape.java b/src/java/org/apache/poi/sl/usermodel/TextShape.java
index a26db81cc4..e480e5645e 100644
--- a/src/java/org/apache/poi/sl/usermodel/TextShape.java
+++ b/src/java/org/apache/poi/sl/usermodel/TextShape.java
@@ -17,6 +17,8 @@
package org.apache.poi.sl.usermodel;
+import java.awt.Graphics2D;
+import java.awt.geom.Rectangle2D;
import java.util.List;
public interface TextShape<
@@ -173,8 +175,21 @@ public interface TextShape<
/**
* Compute the cumulative height occupied by the text
+ *
+ * @return the cumulative height occupied by the text
*/
double getTextHeight();
+
+ /**
+ * Compute the cumulative height occupied by the text
+ *
+ * @param graphics a customized graphics context, e.g. which contains font mappings
+ *
+ * @return the cumulative height occupied by the text
+ *
+ * @since POI 3.17-beta2
+ */
+ double getTextHeight(Graphics2D graphics);
/**
* Returns the type of vertical alignment for the text.
@@ -255,4 +270,25 @@ public interface TextShape<
* @return the text placeholder
*/
TextPlaceholder getTextPlaceholder();
+
+ /**
+ * Adjust the size of the shape so it encompasses the text inside it.
+ *
+ * @return a {@code Rectangle2D} that is the bounds of this shape.
+ *
+ * @since POI 3.17-beta2
+ */
+ Rectangle2D resizeToFitText();
+
+ /**
+ * Adjust the size of the shape so it encompasses the text inside it.
+ *
+ * @param graphics a customized graphics context, e.g. which contains font mappings
+ *
+ * @return a {@code Rectangle2D} that is the bounds of this shape.
+ *
+ * @since POI 3.17-beta2
+ */
+ Rectangle2D resizeToFitText(Graphics2D graphics);
+
} \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java
index 8048e59b55..353bbbf2b6 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java
@@ -64,6 +64,7 @@ public class XSLFTextRun implements TextRun {
return _p;
}
+ @Override
public String getRawText(){
if (_r instanceof CTTextField) {
return ((CTTextField)_r).getT();
@@ -111,6 +112,7 @@ public class XSLFTextRun implements TextRun {
return buf.toString();
}
+ @Override
public void setText(String text){
if (_r instanceof CTTextField) {
((CTTextField)_r).setT(text);
@@ -157,6 +159,7 @@ public class XSLFTextRun implements TextRun {
public PaintStyle getFontColor(){
final boolean hasPlaceholder = getParentParagraph().getParentShape().getPlaceholder() != null;
CharacterPropertyFetcher<PaintStyle> fetcher = new CharacterPropertyFetcher<PaintStyle>(_p.getIndentLevel()){
+ @Override
public boolean fetch(CTTextCharacterProperties props){
if (props == null) {
return false;
@@ -191,7 +194,9 @@ public class XSLFTextRun implements TextRun {
public void setFontSize(Double fontSize){
CTTextCharacterProperties rPr = getRPr(true);
if(fontSize == null) {
- if (rPr.isSetSz()) rPr.unsetSz();
+ if (rPr.isSetSz()) {
+ rPr.unsetSz();
+ }
} else {
if (fontSize < 1.0) {
throw new IllegalArgumentException("Minimum font size is 1pt but was " + fontSize);
@@ -205,9 +210,12 @@ public class XSLFTextRun implements TextRun {
public Double getFontSize(){
double scale = 1;
CTTextNormalAutofit afit = getParentParagraph().getParentShape().getTextBodyPr().getNormAutofit();
- if(afit != null) scale = (double)afit.getFontScale() / 100000;
+ if(afit != null) {
+ scale = (double)afit.getFontScale() / 100000;
+ }
CharacterPropertyFetcher<Double> fetcher = new CharacterPropertyFetcher<Double>(_p.getIndentLevel()){
+ @Override
public boolean fetch(CTTextCharacterProperties props){
if (props != null && props.isSetSz()) {
setValue(props.getSz()*0.01);
@@ -228,6 +236,7 @@ public class XSLFTextRun implements TextRun {
public double getCharacterSpacing(){
CharacterPropertyFetcher<Double> fetcher = new CharacterPropertyFetcher<Double>(_p.getIndentLevel()){
+ @Override
public boolean fetch(CTTextCharacterProperties props){
if (props != null && props.isSetSpc()) {
setValue(props.getSpc()*0.01);
@@ -252,7 +261,9 @@ public class XSLFTextRun implements TextRun {
public void setCharacterSpacing(double spc){
CTTextCharacterProperties rPr = getRPr(true);
if(spc == 0.0) {
- if(rPr.isSetSpc()) rPr.unsetSpc();
+ if(rPr.isSetSpc()) {
+ rPr.unsetSpc();
+ }
} else {
rPr.setSpc((int)(100*spc));
}
@@ -267,9 +278,15 @@ public class XSLFTextRun implements TextRun {
CTTextCharacterProperties rPr = getRPr(true);
if(typeface == null){
- if(rPr.isSetLatin()) rPr.unsetLatin();
- if(rPr.isSetCs()) rPr.unsetCs();
- if(rPr.isSetSym()) rPr.unsetSym();
+ if(rPr.isSetLatin()) {
+ rPr.unsetLatin();
+ }
+ if(rPr.isSetCs()) {
+ rPr.unsetCs();
+ }
+ if(rPr.isSetSym()) {
+ rPr.unsetSym();
+ }
} else {
if(isSymbol){
CTTextFont font = rPr.isSetSym() ? rPr.getSym() : rPr.addNewSym();
@@ -277,8 +294,12 @@ public class XSLFTextRun implements TextRun {
} else {
CTTextFont latin = rPr.isSetLatin() ? rPr.getLatin() : rPr.addNewLatin();
latin.setTypeface(typeface);
- if(charset != -1) latin.setCharset(charset);
- if(pictAndFamily != -1) latin.setPitchFamily(pictAndFamily);
+ if(charset != -1) {
+ latin.setCharset(charset);
+ }
+ if(pictAndFamily != -1) {
+ latin.setPitchFamily(pictAndFamily);
+ }
}
}
}
@@ -288,6 +309,7 @@ public class XSLFTextRun implements TextRun {
final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();
CharacterPropertyFetcher<String> visitor = new CharacterPropertyFetcher<String>(_p.getIndentLevel()){
+ @Override
public boolean fetch(CTTextCharacterProperties props){
if (props != null) {
CTTextFont font = props.getLatin();
@@ -310,10 +332,12 @@ public class XSLFTextRun implements TextRun {
return visitor.getValue();
}
+ @Override
public byte getPitchAndFamily(){
// final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();
CharacterPropertyFetcher<Byte> visitor = new CharacterPropertyFetcher<Byte>(_p.getIndentLevel()){
+ @Override
public boolean fetch(CTTextCharacterProperties props){
if (props != null) {
CTTextFont font = props.getLatin();
@@ -338,6 +362,7 @@ public class XSLFTextRun implements TextRun {
@Override
public boolean isStrikethrough() {
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
+ @Override
public boolean fetch(CTTextCharacterProperties props){
if(props != null && props.isSetStrike()) {
setValue(props.getStrike() != STTextStrikeType.NO_STRIKE);
@@ -353,6 +378,7 @@ public class XSLFTextRun implements TextRun {
@Override
public boolean isSuperscript() {
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
+ @Override
public boolean fetch(CTTextCharacterProperties props){
if (props != null && props.isSetBaseline()) {
setValue(props.getBaseline() > 0);
@@ -401,6 +427,7 @@ public class XSLFTextRun implements TextRun {
@Override
public boolean isSubscript() {
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
+ @Override
public boolean fetch(CTTextCharacterProperties props){
if (props != null && props.isSetBaseline()) {
setValue(props.getBaseline() < 0);
@@ -416,8 +443,10 @@ public class XSLFTextRun implements TextRun {
/**
* @return whether a run of text will be formatted as a superscript text. Default is false.
*/
+ @Override
public TextCap getTextCap() {
CharacterPropertyFetcher<TextCap> fetcher = new CharacterPropertyFetcher<TextCap>(_p.getIndentLevel()){
+ @Override
public boolean fetch(CTTextCharacterProperties props){
if (props != null && props.isSetCap()) {
int idx = props.getCap().intValue() - 1;
@@ -439,6 +468,7 @@ public class XSLFTextRun implements TextRun {
@Override
public boolean isBold(){
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
+ @Override
public boolean fetch(CTTextCharacterProperties props){
if (props != null && props.isSetB()) {
setValue(props.getB());
@@ -459,6 +489,7 @@ public class XSLFTextRun implements TextRun {
@Override
public boolean isItalic(){
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
+ @Override
public boolean fetch(CTTextCharacterProperties props){
if (props != null && props.isSetI()) {
setValue(props.getI());
@@ -479,6 +510,7 @@ public class XSLFTextRun implements TextRun {
@Override
public boolean isUnderlined(){
CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
+ @Override
public boolean fetch(CTTextCharacterProperties props){
if (props != null && props.isSetU()) {
setValue(props.getU() != STTextUnderlineType.NONE);
@@ -603,16 +635,24 @@ public class XSLFTextRun implements TextRun {
}
boolean bold = r.isBold();
- if(bold != isBold()) setBold(bold);
+ if(bold != isBold()) {
+ setBold(bold);
+ }
boolean italic = r.isItalic();
- if(italic != isItalic()) setItalic(italic);
+ if(italic != isItalic()) {
+ setItalic(italic);
+ }
boolean underline = r.isUnderlined();
- if(underline != isUnderlined()) setUnderlined(underline);
+ if(underline != isUnderlined()) {
+ setUnderlined(underline);
+ }
boolean strike = r.isStrikethrough();
- if(strike != isStrikethrough()) setStrikethrough(strike);
+ if(strike != isStrikethrough()) {
+ setStrikethrough(strike);
+ }
}
diff --git a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
index ad979f1d6d..502d2b6d04 100644
--- a/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
+++ b/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
@@ -19,6 +19,7 @@
package org.apache.poi.xslf.usermodel;
+import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Iterator;
@@ -601,23 +602,29 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
@Override
public double getTextHeight(){
- DrawFactory drawFact = DrawFactory.getInstance(null);
+ return getTextHeight(null);
+ }
+
+ @Override
+ public double getTextHeight(Graphics2D graphics){
+ DrawFactory drawFact = DrawFactory.getInstance(graphics);
DrawTextShape dts = drawFact.getDrawable(this);
- return dts.getTextHeight();
+ return dts.getTextHeight(graphics);
}
- /**
- * Adjust the size of the shape so it encompasses the text inside it.
- *
- * @return a <code>Rectangle2D</code> that is the bounds of this shape.
- */
+ @Override
public Rectangle2D resizeToFitText(){
+ return resizeToFitText(null);
+ }
+
+ @Override
+ public Rectangle2D resizeToFitText(Graphics2D graphics) {
Rectangle2D anchor = getAnchor();
if(anchor.getWidth() == 0.) {
throw new POIXMLException("Anchor of the shape was not set.");
}
- double height = getTextHeight();
+ double height = getTextHeight(graphics);
height += 1; // add a pixel to compensate rounding errors
Insets2D insets = getInsets();
diff --git a/src/ooxml/testcases/org/apache/poi/sl/SLCommonUtils.java b/src/ooxml/testcases/org/apache/poi/sl/SLCommonUtils.java
new file mode 100644
index 0000000000..7fdbaa2f69
--- /dev/null
+++ b/src/ooxml/testcases/org/apache/poi/sl/SLCommonUtils.java
@@ -0,0 +1,59 @@
+/*
+ * ====================================================================
+ * 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;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.sl.usermodel.SlideShow;
+import org.apache.poi.sl.usermodel.SlideShowFactory;
+
+public class SLCommonUtils {
+ private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
+
+ /** a generic way to open a sample slideshow document **/
+ public static SlideShow<?,?> openSampleSlideshow(String sampleName) throws IOException {
+ InputStream is = _slTests.openResourceAsStream(sampleName);
+ try {
+ return SlideShowFactory.create(is);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ is.close();
+ }
+ }
+
+ /**
+ * Tests, if the scratchpad classes are on the classpath
+ *
+ * @return true, if only xslf is on the classpath, and false, if both classpaths
+ * (XSLF and HSLF) can be used/referenced
+ */
+ public static boolean xslfOnly() {
+ try {
+ Class.forName("org.apache.poi.hslf.usermodel.HSLFSlideShow");
+ return false;
+ } catch (Exception e) {
+ return true;
+ }
+ }
+
+}
diff --git a/src/ooxml/testcases/org/apache/poi/sl/TestFonts.java b/src/ooxml/testcases/org/apache/poi/sl/TestFonts.java
new file mode 100644
index 0000000000..7d3872a056
--- /dev/null
+++ b/src/ooxml/testcases/org/apache/poi/sl/TestFonts.java
@@ -0,0 +1,158 @@
+/* ====================================================================
+ 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;
+
+import static org.apache.poi.sl.SLCommonUtils.xslfOnly;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeFalse;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontFormatException;
+import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.sl.draw.DrawFactory;
+import org.apache.poi.sl.draw.Drawable;
+import org.apache.poi.sl.usermodel.Slide;
+import org.apache.poi.sl.usermodel.SlideShow;
+import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
+import org.apache.poi.sl.usermodel.TextBox;
+import org.apache.poi.sl.usermodel.TextParagraph;
+import org.apache.poi.sl.usermodel.TextRun;
+import org.apache.poi.xslf.usermodel.XMLSlideShow;
+import org.apache.poi.xslf.usermodel.XSLFTextRun;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
+
+
+/**
+ * Test rendering - specific to font handling
+ */
+public class TestFonts {
+ private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
+
+ private static final String JPTEXT =
+ "\u3061\u3087\u3063\u3068\u65E9\u3044\u3051\u3069T\u30B7\u30E3\u30C4\u304C\u7740\u305F\u304F\u306A" +
+ "\u308B\u5B63\u7BC0\u2661\u304A\u6BCD\u3055\u3093\u306E\u5F71\u97FF\u304B\u3001\u975E\u5E38\u306B" +
+ "\u6050\u7ADC\u304C\u5927\u597D\u304D\u3067\u3059\u3002\u3082\u3046\u98FC\u3044\u305F\u3044\u304F" +
+ "\u3089\u3044\u5927\u597D\u304D\u3067\u3059\u3002#\u30B8\u30E5\u30E9\u30B7\u30C3\u30AF\u30EF\u30FC" +
+ "\u30EB\u30C9 \u306E\u30E9\u30D7\u30C8\u30EB4\u59C9\u59B9\u3068\u304B\u6FC0\u7684\u306B\u53EF\u611B" +
+ "\u304F\u3066\u53EF\u611B\u304F\u3066\u53EF\u611B\u304F\u3066\u53EF\u611B\u3044\u3067\u3059\u3002" +
+ "\u3081\u308D\u3081\u308D\u3001\u5927\u597D\u304D\u2661\u304A\u6BCD\u3055\u3093\u3082\u6050\u7ADC" +
+ "\u304C\u597D\u304D\u3067\u3001\u5C0F\u3055\u3044\u9803\u3001\u53E4\u4EE3\u751F\u7269\u306E\u56F3" +
+ "\u9451\u3092\u4E00\u7DD2\u306B\u898B\u3066\u305F\u306E\u601D\u3044\u51FA\u3059\u301C\u3068\u3044";
+
+ private static final String INIT_FONTS[] = { "mona.ttf" };
+
+ @BeforeClass
+ public static void initGE() throws FontFormatException, IOException {
+ GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ for (String s : INIT_FONTS) {
+ Font font = Font.createFont(Font.TRUETYPE_FONT, _slTests.getFile(s));
+ ge.registerFont(font);
+ }
+ }
+
+ @Test
+ public void resizeToFitTextHSLF() throws IOException {
+ assumeFalse(xslfOnly());
+ SlideShow<?,?> ppt = new HSLFSlideShow();
+ TextBox<?,?> tb = resizeToFitText(ppt);
+ Rectangle2D anc = tb.getAnchor();
+ // ignore font metrics differences on windows / linux (... hopefully ...)
+ assertEquals(anc.getHeight(), 312d, 5);
+// setFont(tb, "Mona");
+// FileOutputStream fos = new FileOutputStream("bla-hslf.ppt");
+// ppt.write(fos);
+// fos.close();
+ ppt.close();
+ }
+
+ @Test
+ public void resizeToFitTextXSLF() throws IOException {
+ SlideShow<?,?> ppt = new XMLSlideShow();
+ TextBox<?,?> tb = resizeToFitText(ppt);
+ Rectangle2D anc = tb.getAnchor();
+ // ignore font metrics differences on windows / linux (... hopefully ...)
+ assertEquals(anc.getHeight(), 312d, 5);
+// setFont(tb, "Mona");
+// FileOutputStream fos = new FileOutputStream("bla-xslf.ppt");
+// ppt.write(fos);
+// fos.close();
+ ppt.close();
+ }
+
+ private TextBox<?,?> resizeToFitText(SlideShow<?,?> slideshow) throws IOException {
+ Slide<?,?> sld = slideshow.createSlide();
+ TextBox<?,?> tb = sld.createTextBox();
+ tb.setAnchor(new Rectangle(50, 50, 200, 50));
+ tb.setStrokeStyle(Color.black, LineDash.SOLID, 3);
+ tb.setText(JPTEXT);
+
+ setFont(tb, "NoSuchFont");
+
+ Dimension pgsize = slideshow.getPageSize();
+ int width = (int)pgsize.getWidth();
+ int height = (int)pgsize.getHeight();
+
+ BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+ Graphics2D graphics = img.createGraphics();
+
+ Map<String,String> fallbackMap = new HashMap<String,String>();
+ fallbackMap.put("NoSuchFont", "Mona");
+ graphics.setRenderingHint(Drawable.FONT_FALLBACK, fallbackMap);
+ graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+
+ DrawFactory.getInstance(graphics).fixFonts(graphics);
+
+ tb.resizeToFitText(graphics);
+ graphics.dispose();
+
+ return tb;
+ }
+
+ private void setFont(TextBox<?,?> tb, String fontFamily) {
+ // TODO: set east asian font family - MS Office uses "MS Mincho" or "MS Gothic" as a fallback
+ // see https://stackoverflow.com/questions/26063828 for good explanation about the font metrics
+ // differences on different environments
+ for (TextParagraph<?,?,? extends TextRun> p : tb.getTextParagraphs()) {
+ for (TextRun r : p.getTextRuns()) {
+ r.setFontFamily(fontFamily);
+ if (r instanceof XSLFTextRun) {
+ // TODO: provide API for HSLF
+ XSLFTextRun xr = (XSLFTextRun)r;
+ CTRegularTextRun tr = (CTRegularTextRun)xr.getXmlObject();
+ tr.getRPr().addNewEa().setTypeface(fontFamily);
+
+ }
+ }
+ }
+ }
+}
diff --git a/src/ooxml/testcases/org/apache/poi/sl/TestHeadersFooters.java b/src/ooxml/testcases/org/apache/poi/sl/TestHeadersFooters.java
index c51652ff5e..910e153e45 100644
--- a/src/ooxml/testcases/org/apache/poi/sl/TestHeadersFooters.java
+++ b/src/ooxml/testcases/org/apache/poi/sl/TestHeadersFooters.java
@@ -19,7 +19,8 @@
package org.apache.poi.sl;
-import static org.apache.poi.sl.TestTable.openSampleSlideshow;
+import static org.apache.poi.sl.SLCommonUtils.openSampleSlideshow;
+import static org.apache.poi.sl.SLCommonUtils.xslfOnly;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
@@ -37,25 +38,12 @@ import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.sl.usermodel.TextShape;
-import org.junit.BeforeClass;
import org.junit.Test;
public class TestHeadersFooters {
- private static boolean xslfOnly = false;
-
- @BeforeClass
- public static void checkHslf() {
- try {
- Class.forName("org.apache.poi.hslf.usermodel.HSLFSlideShow");
- } catch (Exception e) {
- xslfOnly = true;
- }
- }
-
-
@Test
public void bug58144a() throws IOException {
- assumeFalse(xslfOnly);
+ assumeFalse(xslfOnly());
SlideShow<?,?> ppt = openSampleSlideshow("bug58144-headers-footers-2003.ppt");
HSLFSlide sl = (HSLFSlide)ppt.getSlides().get(0);
HeadersFooters hfs = sl.getHeadersFooters();
@@ -69,7 +57,7 @@ public class TestHeadersFooters {
@Test
public void bug58144b() throws IOException {
- assumeFalse(xslfOnly);
+ assumeFalse(xslfOnly());
SlideShow<?,?> ppt = openSampleSlideshow("bug58144-headers-footers-2007.ppt");
Slide<?,?> sl = ppt.getSlides().get(0);
HeadersFooters hfs2 = ((HSLFSlide)sl).getHeadersFooters();
diff --git a/src/ooxml/testcases/org/apache/poi/sl/TestTable.java b/src/ooxml/testcases/org/apache/poi/sl/TestTable.java
index 6028756626..f55a8a7cbc 100644
--- a/src/ooxml/testcases/org/apache/poi/sl/TestTable.java
+++ b/src/ooxml/testcases/org/apache/poi/sl/TestTable.java
@@ -19,6 +19,8 @@
package org.apache.poi.sl;
+import static org.apache.poi.sl.SLCommonUtils.openSampleSlideshow;
+import static org.apache.poi.sl.SLCommonUtils.xslfOnly;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -32,7 +34,6 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import org.apache.poi.POIDataSamples;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.sl.usermodel.SlideShow;
@@ -41,38 +42,13 @@ import org.apache.poi.sl.usermodel.TableCell;
import org.apache.poi.sl.usermodel.TableShape;
import org.apache.poi.sl.usermodel.TextShape.TextDirection;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
-import org.junit.BeforeClass;
import org.junit.Test;
public class TestTable {
- private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
- private static boolean xslfOnly = false;
-
- @BeforeClass
- public static void checkHslf() {
- try {
- Class.forName("org.apache.poi.hslf.usermodel.HSLFSlideShow");
- } catch (Exception e) {
- xslfOnly = true;
- }
- }
-
-
- /** a generic way to open a sample slideshow document **/
- public static SlideShow<?,?> openSampleSlideshow(String sampleName) throws IOException {
- InputStream is = _slTests.openResourceAsStream(sampleName);
- try {
- return SlideShowFactory.create(is);
- } catch (Exception e) {
- throw new RuntimeException(e);
- } finally {
- is.close();
- }
- }
@Test
public void colWidthRowHeight() throws IOException {
- assumeFalse(xslfOnly);
+ assumeFalse(xslfOnly());
// Test of table dimensions of same slideshow saved as ppt/x
// to check if both return similar (points) value
@@ -121,7 +97,7 @@ public class TestTable {
@Test
public void directionHSLF() throws IOException {
- assumeFalse(xslfOnly);
+ assumeFalse(xslfOnly());
SlideShow<?,?> ppt1 = new HSLFSlideShow();
testTextDirection(ppt1);
ppt1.close();
@@ -173,7 +149,7 @@ public class TestTable {
@Test
public void tableSpan() throws IOException {
- String files[] = (xslfOnly) ? new String[]{ "bug60993.pptx" } : new String[]{ "bug60993.pptx", "bug60993.ppt" };
+ String files[] = (xslfOnly()) ? new String[]{ "bug60993.pptx" } : new String[]{ "bug60993.pptx", "bug60993.ppt" };
for (String f : files) {
SlideShow<?,?> ppt = openSampleSlideshow(f);
Slide<?,?> slide = ppt.getSlides().get(0);
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java
index 96cea80349..9db4afbd90 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java
@@ -20,6 +20,7 @@ package org.apache.poi.hslf.usermodel;
import static org.apache.poi.hslf.record.RecordTypes.OEPlaceholderAtom;
import static org.apache.poi.hslf.record.RecordTypes.RoundTripHFPlaceholder12;
+import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.util.ArrayList;
@@ -312,21 +313,20 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
}
}
-
+ @Override
+ public Rectangle2D resizeToFitText() {
+ return resizeToFitText(null);
+ }
- /**
- * Adjust the size of the shape so it encompasses the text inside it.
- *
- * @return a <code>Rectangle2D</code> that is the bounds of this shape.
- */
- public Rectangle2D resizeToFitText(){
+ @Override
+ public Rectangle2D resizeToFitText(Graphics2D graphics) {
Rectangle2D anchor = getAnchor();
if(anchor.getWidth() == 0.) {
LOG.log(POILogger.WARN, "Width of shape wasn't set. Defaulting to 200px");
anchor.setRect(anchor.getX(), anchor.getY(), 200., anchor.getHeight());
setAnchor(anchor);
}
- double height = getTextHeight();
+ double height = getTextHeight(graphics);
height += 1; // add a pixel to compensate rounding errors
Insets2D insets = getInsets();
@@ -736,10 +736,15 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
}
@Override
- public double getTextHeight(){
- DrawFactory drawFact = DrawFactory.getInstance(null);
+ public double getTextHeight() {
+ return getTextHeight(null);
+ }
+
+ @Override
+ public double getTextHeight(Graphics2D graphics) {
+ DrawFactory drawFact = DrawFactory.getInstance(graphics);
DrawTextShape dts = drawFact.getDrawable(this);
- return dts.getTextHeight();
+ return dts.getTextHeight(graphics);
}
@Override
diff --git a/test-data/slideshow/mona.ttf b/test-data/slideshow/mona.ttf
new file mode 100644
index 0000000000..d19a9ec126
--- /dev/null
+++ b/test-data/slideshow/mona.ttf
Binary files differ