mirror of https://github.com/apache/poi.git
#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:
parent
525424a9a2
commit
c82aa1a4bb
|
@ -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,9 +175,22 @@ 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);
|
||||
DrawTextShape dts = drawFact.getDrawable(this);
|
||||
return dts.getTextHeight();
|
||||
return getTextHeight(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.
|
||||
*/
|
||||
@Override
|
||||
public double getTextHeight(Graphics2D graphics){
|
||||
DrawFactory drawFact = DrawFactory.getInstance(graphics);
|
||||
DrawTextShape dts = drawFact.getDrawable(this);
|
||||
return dts.getTextHeight(graphics);
|
||||
}
|
||||
|
||||
@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
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue