#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
This commit is contained in:
Andreas Beeker 2017-07-08 22:20:55 +00:00
parent 525424a9a2
commit c82aa1a4bb
10 changed files with 346 additions and 77 deletions

View File

@ -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();

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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;
}
}
}

View File

@ -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);
}
}
}
}
}

View File

@ -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();

View File

@ -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);

View File

@ -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

Binary file not shown.