improved support for line breaks in XSLF
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1240026 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
46bc4f45f7
commit
0efe45cb7d
@ -55,7 +55,8 @@ class TextFragment {
|
|||||||
* @return full height of this text run which is sum of ascent, descent and leading
|
* @return full height of this text run which is sum of ascent, descent and leading
|
||||||
*/
|
*/
|
||||||
public float getHeight(){
|
public float getHeight(){
|
||||||
return _layout.getAscent() + _layout.getDescent() + _layout.getLeading();
|
double h = Math.ceil(_layout.getAscent()) + Math.ceil(_layout.getDescent()) + _layout.getLeading();
|
||||||
|
return (float)h;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.xslf.usermodel;
|
||||||
|
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
class XSLFLineBreak extends XSLFTextRun {
|
||||||
|
private final CTTextCharacterProperties _brProps;
|
||||||
|
|
||||||
|
XSLFLineBreak(CTRegularTextRun r, XSLFTextParagraph p, CTTextCharacterProperties brProps){
|
||||||
|
super(r, p);
|
||||||
|
_brProps = brProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CTTextCharacterProperties getRPr(){
|
||||||
|
return _brProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text){
|
||||||
|
throw new IllegalStateException("You cannot change text of a line break, it is always '\\n'");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -115,6 +115,11 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
|||||||
return _runs.iterator();
|
return _runs.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new run of text
|
||||||
|
*
|
||||||
|
* @return a new run of text
|
||||||
|
*/
|
||||||
public XSLFTextRun addNewTextRun(){
|
public XSLFTextRun addNewTextRun(){
|
||||||
CTRegularTextRun r = _p.addNewR();
|
CTRegularTextRun r = _p.addNewR();
|
||||||
CTTextCharacterProperties rPr = r.addNewRPr();
|
CTTextCharacterProperties rPr = r.addNewRPr();
|
||||||
@ -124,8 +129,25 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
|
|||||||
return run;
|
return run;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addLineBreak(){
|
/**
|
||||||
_p.addNewBr();
|
* Insert a line break
|
||||||
|
*
|
||||||
|
* @return text run representing this line break ('\n')
|
||||||
|
*/
|
||||||
|
public XSLFTextRun addLineBreak(){
|
||||||
|
CTTextLineBreak br = _p.addNewBr();
|
||||||
|
CTTextCharacterProperties brProps = br.addNewRPr();
|
||||||
|
if(_runs.size() > 0){
|
||||||
|
// by default line break has the font size of the last text run
|
||||||
|
CTTextCharacterProperties prevRun = _runs.get(_runs.size() - 1).getRPr();
|
||||||
|
brProps.set(prevRun);
|
||||||
|
}
|
||||||
|
CTRegularTextRun r = CTRegularTextRun.Factory.newInstance();
|
||||||
|
r.setRPr(brProps);
|
||||||
|
r.setT("\n");
|
||||||
|
XSLFTextRun run = new XSLFLineBreak(r, this, brProps);
|
||||||
|
_runs.add(run);
|
||||||
|
return run;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -121,7 +121,7 @@ public class XSLFTextRun {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setFontColor(Color color){
|
public void setFontColor(Color color){
|
||||||
CTTextCharacterProperties rPr = getRpR();
|
CTTextCharacterProperties rPr = getRPr();
|
||||||
CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? rPr.getSolidFill() : rPr.addNewSolidFill();
|
CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? rPr.getSolidFill() : rPr.addNewSolidFill();
|
||||||
CTSRgbColor clr = fill.isSetSrgbClr() ? fill.getSrgbClr() : fill.addNewSrgbClr();
|
CTSRgbColor clr = fill.isSetSrgbClr() ? fill.getSrgbClr() : fill.addNewSrgbClr();
|
||||||
clr.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()});
|
clr.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()});
|
||||||
@ -163,7 +163,7 @@ public class XSLFTextRun {
|
|||||||
* The value of <code>-1</code> unsets the Sz attribyte from the underlying xml bean
|
* The value of <code>-1</code> unsets the Sz attribyte from the underlying xml bean
|
||||||
*/
|
*/
|
||||||
public void setFontSize(double fontSize){
|
public void setFontSize(double fontSize){
|
||||||
CTTextCharacterProperties rPr = getRpR();
|
CTTextCharacterProperties rPr = getRPr();
|
||||||
if(fontSize == -1.0) {
|
if(fontSize == -1.0) {
|
||||||
if(rPr.isSetSz()) rPr.unsetSz();
|
if(rPr.isSetSz()) rPr.unsetSz();
|
||||||
} else {
|
} else {
|
||||||
@ -226,7 +226,7 @@ public class XSLFTextRun {
|
|||||||
* @param spc character spacing in points.
|
* @param spc character spacing in points.
|
||||||
*/
|
*/
|
||||||
public void setCharacterSpacing(double spc){
|
public void setCharacterSpacing(double spc){
|
||||||
CTTextCharacterProperties rPr = getRpR();
|
CTTextCharacterProperties rPr = getRPr();
|
||||||
if(spc == 0.0) {
|
if(spc == 0.0) {
|
||||||
if(rPr.isSetSpc()) rPr.unsetSpc();
|
if(rPr.isSetSpc()) rPr.unsetSpc();
|
||||||
} else {
|
} else {
|
||||||
@ -245,7 +245,7 @@ public class XSLFTextRun {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setFontFamily(String typeface, byte charset, byte pictAndFamily, boolean isSymbol){
|
public void setFontFamily(String typeface, byte charset, byte pictAndFamily, boolean isSymbol){
|
||||||
CTTextCharacterProperties rPr = getRpR();
|
CTTextCharacterProperties rPr = getRPr();
|
||||||
|
|
||||||
if(typeface == null){
|
if(typeface == null){
|
||||||
if(rPr.isSetLatin()) rPr.unsetLatin();
|
if(rPr.isSetLatin()) rPr.unsetLatin();
|
||||||
@ -314,8 +314,8 @@ public class XSLFTextRun {
|
|||||||
*
|
*
|
||||||
* @param strike whether a run of text will be formatted as strikethrough text.
|
* @param strike whether a run of text will be formatted as strikethrough text.
|
||||||
*/
|
*/
|
||||||
public void setStrikethrough(boolean strike){
|
public void setStrikethrough(boolean strike) {
|
||||||
getRpR().setStrike(strike ? STTextStrikeType.SNG_STRIKE : STTextStrikeType.NO_STRIKE);
|
getRPr().setStrike(strike ? STTextStrikeType.SNG_STRIKE : STTextStrikeType.NO_STRIKE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -393,7 +393,7 @@ public class XSLFTextRun {
|
|||||||
* @param bold whether this run of text will be formatted as bold text
|
* @param bold whether this run of text will be formatted as bold text
|
||||||
*/
|
*/
|
||||||
public void setBold(boolean bold){
|
public void setBold(boolean bold){
|
||||||
getRpR().setB(bold);
|
getRPr().setB(bold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -417,7 +417,7 @@ public class XSLFTextRun {
|
|||||||
* @param italic whether this run of text is formatted as italic text
|
* @param italic whether this run of text is formatted as italic text
|
||||||
*/
|
*/
|
||||||
public void setItalic(boolean italic){
|
public void setItalic(boolean italic){
|
||||||
getRpR().setI(italic);
|
getRPr().setI(italic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -440,8 +440,8 @@ public class XSLFTextRun {
|
|||||||
/**
|
/**
|
||||||
* @param underline whether this run of text is formatted as underlined text
|
* @param underline whether this run of text is formatted as underlined text
|
||||||
*/
|
*/
|
||||||
public void setUnderline(boolean underline){
|
public void setUnderline(boolean underline) {
|
||||||
getRpR().setU(underline ? STTextUnderlineType.SNG : STTextUnderlineType.NONE);
|
getRPr().setU(underline ? STTextUnderlineType.SNG : STTextUnderlineType.NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -461,7 +461,7 @@ public class XSLFTextRun {
|
|||||||
return fetcher.getValue() == null ? false : fetcher.getValue();
|
return fetcher.getValue() == null ? false : fetcher.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CTTextCharacterProperties getRpR(){
|
protected CTTextCharacterProperties getRPr(){
|
||||||
return _r.isSetRPr() ? _r.getRPr() : _r.addNewRPr();
|
return _r.isSetRPr() ? _r.getRPr() : _r.addNewRPr();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,7 +485,7 @@ public class XSLFTextRun {
|
|||||||
private boolean fetchCharacterProperty(CharacterPropertyFetcher fetcher){
|
private boolean fetchCharacterProperty(CharacterPropertyFetcher fetcher){
|
||||||
boolean ok = false;
|
boolean ok = false;
|
||||||
|
|
||||||
if(_r.isSetRPr()) ok = fetcher.fetch(_r.getRPr());
|
if(_r.isSetRPr()) ok = fetcher.fetch(getRPr());
|
||||||
|
|
||||||
if(!ok) {
|
if(!ok) {
|
||||||
XSLFTextShape shape = _p.getParentShape();
|
XSLFTextShape shape = _p.getParentShape();
|
||||||
|
@ -189,7 +189,7 @@ public class TestXSLFPowerPointExtractor extends TestCase {
|
|||||||
"Theme Master first level\n" +
|
"Theme Master first level\n" +
|
||||||
"And the 2nd level\n" +
|
"And the 2nd level\n" +
|
||||||
"Our 3rd level goes here\n" +
|
"Our 3rd level goes here\n" +
|
||||||
"And onto the 4th, such fun….\n" +
|
"And onto the 4th, such fun....\n" +
|
||||||
"Finally is the Fifth level\n";
|
"Finally is the Fifth level\n";
|
||||||
|
|
||||||
// Check the whole text
|
// Check the whole text
|
||||||
|
@ -290,4 +290,32 @@ public class TestXSLFTextParagraph extends TestCase {
|
|||||||
p.setBullet(false);
|
p.setBullet(false);
|
||||||
assertFalse(p.isBullet());
|
assertFalse(p.isBullet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testLineBreak(){
|
||||||
|
XMLSlideShow ppt = new XMLSlideShow();
|
||||||
|
XSLFSlide slide = ppt.createSlide();
|
||||||
|
XSLFTextShape sh = slide.createAutoShape();
|
||||||
|
|
||||||
|
XSLFTextParagraph p = sh.addNewTextParagraph();
|
||||||
|
XSLFTextRun r1 = p.addNewTextRun();
|
||||||
|
r1.setText("Hello,");
|
||||||
|
XSLFTextRun r2 = p.addLineBreak();
|
||||||
|
assertEquals("\n", r2.getText());
|
||||||
|
r2.setFontSize(10.0);
|
||||||
|
assertEquals(10.0, r2.getFontSize());
|
||||||
|
XSLFTextRun r3 = p.addNewTextRun();
|
||||||
|
r3.setText("World!");
|
||||||
|
r3.setFontSize(20.0);
|
||||||
|
XSLFTextRun r4 = p.addLineBreak();
|
||||||
|
assertEquals(20.0, r4.getFontSize());
|
||||||
|
|
||||||
|
assertEquals("Hello,\nWorld!\n",sh.getText());
|
||||||
|
|
||||||
|
try {
|
||||||
|
r2.setText("aaa");
|
||||||
|
fail("Expected IllegalStateException");
|
||||||
|
} catch (IllegalStateException e){
|
||||||
|
assertEquals("You cannot change text of a line break, it is always '\\n'", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,14 +19,8 @@
|
|||||||
package org.apache.poi.xslf.usermodel;
|
package org.apache.poi.xslf.usermodel;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
import org.apache.poi.util.POILogFactory;
|
|
||||||
import org.apache.poi.util.POILogger;
|
|
||||||
import org.apache.poi.xslf.XSLFTestDataSamples;
|
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.geom.Rectangle2D;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Yegor Kozlov
|
* @author Yegor Kozlov
|
||||||
@ -39,7 +33,7 @@ public class TestXSLFTextRun extends TestCase {
|
|||||||
XSLFTextShape sh = slide.createAutoShape();
|
XSLFTextShape sh = slide.createAutoShape();
|
||||||
|
|
||||||
XSLFTextRun r = sh.addNewTextParagraph().addNewTextRun();
|
XSLFTextRun r = sh.addNewTextParagraph().addNewTextRun();
|
||||||
assertEquals("en-US", r.getRpR().getLang());
|
assertEquals("en-US", r.getRPr().getLang());
|
||||||
|
|
||||||
assertEquals(0., r.getCharacterSpacing());
|
assertEquals(0., r.getCharacterSpacing());
|
||||||
r.setCharacterSpacing(3);
|
r.setCharacterSpacing(3);
|
||||||
@ -48,7 +42,7 @@ public class TestXSLFTextRun extends TestCase {
|
|||||||
assertEquals(-3., r.getCharacterSpacing());
|
assertEquals(-3., r.getCharacterSpacing());
|
||||||
r.setCharacterSpacing(0);
|
r.setCharacterSpacing(0);
|
||||||
assertEquals(0., r.getCharacterSpacing());
|
assertEquals(0., r.getCharacterSpacing());
|
||||||
assertFalse(r.getRpR().isSetSpc());
|
assertFalse(r.getRPr().isSetSpc());
|
||||||
|
|
||||||
assertEquals(Color.black, r.getFontColor());
|
assertEquals(Color.black, r.getFontColor());
|
||||||
r.setFontColor(Color.red);
|
r.setFontColor(Color.red);
|
||||||
|
Loading…
Reference in New Issue
Block a user