- add resize methods with Graphics argument git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1801329 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_17_FINAL
@@ -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(); |
@@ -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); | |||
} |
@@ -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); | |||
} | |||
} | |||
@@ -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(); |
@@ -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; | |||
} | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -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(); |
@@ -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); |
@@ -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 |