diff --git a/src/java/org/apache/poi/sl/draw/DrawTextShape.java b/src/java/org/apache/poi/sl/draw/DrawTextShape.java index cffffb4a8..ed1465381 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 a26db81cc..e480e5645 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 8048e59b5..353bbbf2b 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 fetcher = new CharacterPropertyFetcher(_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 fetcher = new CharacterPropertyFetcher(_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 fetcher = new CharacterPropertyFetcher(_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 visitor = new CharacterPropertyFetcher(_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 visitor = new CharacterPropertyFetcher(_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 fetcher = new CharacterPropertyFetcher(_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 fetcher = new CharacterPropertyFetcher(_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 fetcher = new CharacterPropertyFetcher(_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 fetcher = new CharacterPropertyFetcher(_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 fetcher = new CharacterPropertyFetcher(_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 fetcher = new CharacterPropertyFetcher(_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 fetcher = new CharacterPropertyFetcher(_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 ad979f1d6..502d2b6d0 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 Rectangle2D 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 000000000..7fdbaa2f6 --- /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 000000000..7d3872a05 --- /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 fallbackMap = new HashMap(); + 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 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 c51652ff5..910e153e4 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 602875662..f55a8a7cb 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 96cea8034..9db4afbd9 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 { } } - + @Override + public Rectangle2D resizeToFitText() { + return resizeToFitText(null); + } - /** - * Adjust the size of the shape so it encompasses the text inside it. - * - * @return a Rectangle2D 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 { } @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 000000000..d19a9ec12 Binary files /dev/null and b/test-data/slideshow/mona.ttf differ