- #47904 - Update text styles in HSLF MasterSlide

- common sl unification for TextParagraph.setTextAlign

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1717351 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2015-11-30 23:34:30 +00:00
parent e772eeecde
commit f0ed3cbbab
12 changed files with 228 additions and 90 deletions

View File

@ -105,7 +105,7 @@ public final class TableDemo {
} else { } else {
rt.getTextParagraph().setBullet(true); rt.getTextParagraph().setBullet(true);
rt.setFontSize(12d); rt.setFontSize(12d);
rt.getTextParagraph().setAlignment(TextAlign.LEFT); rt.getTextParagraph().setTextAlign(TextAlign.LEFT);
cell.setHorizontalCentered(false); cell.setHorizontalCentered(false);
} }
cell.setVerticalAlignment(VerticalAlignment.MIDDLE); cell.setVerticalAlignment(VerticalAlignment.MIDDLE);

View File

@ -312,11 +312,21 @@ public interface TextParagraph<
/** /**
* Returns the alignment that is applied to the paragraph. * Returns the alignment that is applied to the paragraph.
* *
* If this attribute is omitted, then a value of left is implied. * If this attribute is omitted, then null is returned.
* @return ??? alignment that is applied to the paragraph * User code can imply the value {@link org.apache.poi.sl.usermodel.TextParagraph.TextAlign#LEFT} then.
*
* @return alignment that is applied to the paragraph
*/ */
TextAlign getTextAlign(); TextAlign getTextAlign();
/**
* Specifies the alignment that is to be applied to the paragraph.
* Possible values for this include left, right, centered, justified and distributed,
* see {@link org.apache.poi.sl.usermodel.TextParagraph.TextAlign}.
*
* @param align text align
*/
void setTextAlign(TextAlign align);
/** /**
* Returns the font alignment that is applied to the paragraph. * Returns the font alignment that is applied to the paragraph.

View File

@ -163,14 +163,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
return run; return run;
} }
/** @Override
* Returns the alignment that is applied to the paragraph.
*
* If this attribute is omitted, then null is returned.
* User code can imply the value {@link org.apache.poi.sl.usermodel.TextParagraph.TextAlign#LEFT} then.
*
* @return alignment that is applied to the paragraph
*/
public TextAlign getTextAlign(){ public TextAlign getTextAlign(){
ParagraphPropertyFetcher<TextAlign> fetcher = new ParagraphPropertyFetcher<TextAlign>(getIndentLevel()){ ParagraphPropertyFetcher<TextAlign> fetcher = new ParagraphPropertyFetcher<TextAlign>(getIndentLevel()){
public boolean fetch(CTTextParagraphProperties props){ public boolean fetch(CTTextParagraphProperties props){
@ -186,14 +179,8 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
return fetcher.getValue(); return fetcher.getValue();
} }
/** @Override
* Specifies the alignment that is to be applied to the paragraph. public void setTextAlign(TextAlign align) {
* Possible values for this include left, right, centered, justified and distributed,
* see {@link org.apache.poi.sl.usermodel.TextParagraph.TextAlign}.
*
* @param align text align
*/
public void setTextAlign(TextAlign align){
CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr(); CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
if(align == null) { if(align == null) {
if(pr.isSetAlgn()) pr.unsetAlgn(); if(pr.isSetAlgn()) pr.unsetAlgn();
@ -816,6 +803,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
CTPlaceholder ph = shape.getCTPlaceholder(); CTPlaceholder ph = shape.getCTPlaceholder();
if(ph == null){ if(ph == null){
// if it is a plain text box then take defaults from presentation.xml // if it is a plain text box then take defaults from presentation.xml
@SuppressWarnings("resource")
XMLSlideShow ppt = sheet.getSlideShow(); XMLSlideShow ppt = sheet.getSlideShow();
CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(getIndentLevel()); CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(getIndentLevel());
if (themeProps != null) ok = visitor.fetch(themeProps); if (themeProps != null) ok = visitor.fetch(themeProps);

View File

@ -17,8 +17,13 @@
package org.apache.poi.hslf.model.textproperties; package org.apache.poi.hslf.model.textproperties;
import java.io.*; import java.io.ByteArrayOutputStream;
import java.util.*; import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.hslf.exceptions.HSLFException; import org.apache.poi.hslf.exceptions.HSLFException;
import org.apache.poi.hslf.record.StyleTextPropAtom; import org.apache.poi.hslf.record.StyleTextPropAtom;
@ -239,6 +244,9 @@ public class TextPropCollection {
* Clones the given text properties * Clones the given text properties
*/ */
public void copy(TextPropCollection other) { public void copy(TextPropCollection other) {
if (other == null) {
throw new HSLFException("trying to copy null TextPropCollection");
}
if (this == other) return; if (this == other) return;
this.charactersCovered = other.charactersCovered; this.charactersCovered = other.charactersCovered;
this.indentLevel = other.indentLevel; this.indentLevel = other.indentLevel;
@ -260,12 +268,22 @@ public class TextPropCollection {
charactersCovered = textSize; charactersCovered = textSize;
} }
/**
* Writes out to disk the header, and then all the properties
*/
public void writeOut(OutputStream o) throws IOException {
writeOut(o, false);
}
/** /**
* Writes out to disk the header, and then all the properties * Writes out to disk the header, and then all the properties
*/ */
public void writeOut(OutputStream o) throws IOException { public void writeOut(OutputStream o, boolean isMasterStyle) throws IOException {
// First goes the number of characters we affect if (!isMasterStyle) {
StyleTextPropAtom.writeLittleEndian(charactersCovered,o); // First goes the number of characters we affect
// MasterStyles don't have this field
StyleTextPropAtom.writeLittleEndian(charactersCovered,o);
}
// Then we have the indentLevel field if it's a paragraph collection // Then we have the indentLevel field if it's a paragraph collection
if (textPropType == TextPropType.paragraph && indentLevel > -1) { if (textPropType == TextPropType.paragraph && indentLevel > -1) {

View File

@ -17,14 +17,17 @@
package org.apache.poi.hslf.record; package org.apache.poi.hslf.record;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.poi.hslf.exceptions.HSLFException;
import org.apache.poi.hslf.model.textproperties.TextPropCollection; import org.apache.poi.hslf.model.textproperties.TextPropCollection;
import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType; import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianOutputStream;
/** /**
* TxMasterStyleAtom atom (4003). * TxMasterStyleAtom atom (4003).
@ -140,7 +143,7 @@ public final class TxMasterStyleAtom extends RecordAtom {
paragraphStyles = new ArrayList<TextPropCollection>(levels); paragraphStyles = new ArrayList<TextPropCollection>(levels);
charStyles = new ArrayList<TextPropCollection>(levels); charStyles = new ArrayList<TextPropCollection>(levels);
for(short j = 0; j < levels; j++) { for(short i = 0; i < levels; i++) {
TextPropCollection prprops = new TextPropCollection(0, TextPropType.paragraph); // getParagraphProps(type, j) TextPropCollection prprops = new TextPropCollection(0, TextPropType.paragraph); // getParagraphProps(type, j)
if (type >= TextHeaderAtom.CENTRE_BODY_TYPE) { if (type >= TextHeaderAtom.CENTRE_BODY_TYPE) {
// Fetch the 2 byte value, that is safe to ignore for some types of text // Fetch the 2 byte value, that is safe to ignore for some types of text
@ -163,32 +166,44 @@ public final class TxMasterStyleAtom extends RecordAtom {
pos += chprops.buildTextPropList( head, _data, pos); pos += chprops.buildTextPropList( head, _data, pos);
charStyles.add(chprops); charStyles.add(chprops);
} }
} }
/** /**
* Paragraph properties for the specified text type and * Updates the rawdata from the modified paragraph/character styles
* indent level *
* Depending on the level and type, it may be our special * @since 3.14-beta1
* ones, or the standard StyleTextPropAtom ones
*/ */
// protected TextProp[] getParagraphProps(int type, int level){ public void updateStyles() {
// return StyleTextPropAtom.paragraphTextPropTypes; int type = getTextType();
// return (level != 0 || type >= MAX_INDENT)
// ? StyleTextPropAtom.paragraphTextPropTypes try {
// : paragraphSpecialPropTypes; ByteArrayOutputStream bos = new ByteArrayOutputStream();
// } LittleEndianOutputStream leos = new LittleEndianOutputStream(bos);
int levels = paragraphStyles.size();
/** leos.writeShort(levels);
* Character properties for the specified text type and
* indent level. TextPropCollection prdummy = new TextPropCollection(0, TextPropType.paragraph);
* Depending on the level and type, it may be our special TextPropCollection chdummy = new TextPropCollection(0, TextPropType.character);
* ones, or the standard StyleTextPropAtom ones
*/ for (int i=0; i<levels; i++) {
// protected TextProp[] getCharacterProps(int type, int level){ prdummy.copy(paragraphStyles.get(i));
// return StyleTextPropAtom.characterTextPropTypes; chdummy.copy(charStyles.get(i));
// return (level != 0 || type >= MAX_INDENT) if (type >= TextHeaderAtom.CENTRE_BODY_TYPE) {
// ? StyleTextPropAtom.characterTextPropTypes leos.writeShort(prdummy.getIndentLevel());
// : characterSpecialPropTypes; }
// }
// Indent level is not written for master styles
prdummy.setIndentLevel((short)-1);
prdummy.writeOut(bos, true);
chdummy.writeOut(bos, true);
}
_data = bos.toByteArray();
leos.close();
LittleEndian.putInt(_header, 4, _data.length);
} catch (IOException e) {
throw new HSLFException("error in updating master style properties", e);
}
}
} }

View File

@ -27,6 +27,7 @@ import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherDgRecord; import org.apache.poi.ddf.EscherDgRecord;
import org.apache.poi.ddf.EscherDggRecord; import org.apache.poi.ddf.EscherDggRecord;
import org.apache.poi.ddf.EscherRecord; import org.apache.poi.ddf.EscherRecord;
import org.apache.poi.hslf.exceptions.HSLFException;
import org.apache.poi.hslf.record.CString; import org.apache.poi.hslf.record.CString;
import org.apache.poi.hslf.record.ColorSchemeAtom; import org.apache.poi.hslf.record.ColorSchemeAtom;
import org.apache.poi.hslf.record.OEPlaceholderAtom; import org.apache.poi.hslf.record.OEPlaceholderAtom;
@ -40,6 +41,7 @@ import org.apache.poi.sl.draw.Drawable;
import org.apache.poi.sl.usermodel.PictureData; import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.sl.usermodel.ShapeType; import org.apache.poi.sl.usermodel.ShapeType;
import org.apache.poi.sl.usermodel.Sheet; import org.apache.poi.sl.usermodel.Sheet;
import org.apache.poi.util.Internal;
/** /**
* This class defines the common format of "Sheets" in a powerpoint * This class defines the common format of "Sheets" in a powerpoint
@ -119,9 +121,14 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H
/** /**
* Set the SlideShow we're attached to. * Set the SlideShow we're attached to.
* Also passes it on to our child RichTextRuns * Also passes it on to our child text paragraphs
*/ */
public void setSlideShow(HSLFSlideShow ss) { @Internal
protected void setSlideShow(HSLFSlideShow ss) {
if (_slideShow != null) {
throw new HSLFException("Can't change existing slideshow reference");
}
_slideShow = ss; _slideShow = ss;
List<List<HSLFTextParagraph>> trs = getTextParagraphs(); List<List<HSLFTextParagraph>> trs = getTextParagraphs();
if (trs == null) return; if (trs == null) return;

View File

@ -20,9 +20,11 @@ package org.apache.poi.hslf.usermodel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.poi.hslf.exceptions.HSLFException;
import org.apache.poi.hslf.model.textproperties.TextProp; import org.apache.poi.hslf.model.textproperties.TextProp;
import org.apache.poi.hslf.model.textproperties.TextPropCollection; import org.apache.poi.hslf.model.textproperties.TextPropCollection;
import org.apache.poi.hslf.record.*; import org.apache.poi.hslf.record.*;
import org.apache.poi.util.Internal;
/** /**
* SlideMaster determines the graphics, layout, and formatting for all the slides in a given presentation. * SlideMaster determines the graphics, layout, and formatting for all the slides in a given presentation.
@ -73,7 +75,7 @@ public final class HSLFSlideMaster extends HSLFMasterSheet {
/** /**
* Pickup a style attribute from the master. * Pickup a style attribute from the master.
* This is the "workhorse" which returns the default style attrubutes. * This is the "workhorse" which returns the default style attributes.
*/ */
public TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) { public TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) {
if (_txmaster.length <= txtype) return null; if (_txmaster.length <= txtype) return null;
@ -102,25 +104,50 @@ public final class HSLFSlideMaster extends HSLFMasterSheet {
return getStyleAttribute(txtype, level, name, isCharacter); return getStyleAttribute(txtype, level, name, isCharacter);
} }
/** /**
* Assign SlideShow for this slide master. * Assign SlideShow for this slide master.
* (Used interanlly)
*/ */
public void setSlideShow(HSLFSlideShow ss) { @Internal
@Override
protected void setSlideShow(HSLFSlideShow ss) {
super.setSlideShow(ss); super.setSlideShow(ss);
//after the slide show is assigned collect all available style records //after the slide show is assigned collect all available style records
if (_txmaster == null) { assert (_txmaster == null);
_txmaster = new TxMasterStyleAtom[9]; _txmaster = new TxMasterStyleAtom[9];
TxMasterStyleAtom txdoc = getSlideShow().getDocumentRecord().getEnvironment().getTxMasterStyleAtom(); TxMasterStyleAtom txdoc = getSlideShow().getDocumentRecord().getEnvironment().getTxMasterStyleAtom();
_txmaster[txdoc.getTextType()] = txdoc; _txmaster[txdoc.getTextType()] = txdoc;
TxMasterStyleAtom[] txrec = ((MainMaster)getSheetContainer()).getTxMasterStyleAtoms(); TxMasterStyleAtom[] txrec = ((MainMaster)getSheetContainer()).getTxMasterStyleAtoms();
for (int i = 0; i < txrec.length; i++) { for (int i = 0; i < txrec.length; i++) {
int txType = txrec[i].getTextType(); int txType = txrec[i].getTextType();
if(_txmaster[txType] == null) _txmaster[txType] = txrec[i]; if (txType < _txmaster.length && _txmaster[txType] == null) {
_txmaster[txType] = txrec[i];
}
}
for (List<HSLFTextParagraph> paras : getTextParagraphs()) {
for (HSLFTextParagraph htp : paras) {
int txType = htp.getRunType();
if (txType >= _txmaster.length || _txmaster[txType] == null) {
throw new HSLFException("Master styles not initialized");
}
int level = htp.getIndentLevel();
List<TextPropCollection> charStyles = _txmaster[txType].getCharacterStyles();
List<TextPropCollection> paragraphStyles = _txmaster[txType].getParagraphStyles();
if (charStyles == null || paragraphStyles == null ||
charStyles.size() <= level || paragraphStyles.size() <= level) {
throw new HSLFException("Master styles not initialized");
}
htp.setMasterStyleReference(paragraphStyles.get(level));
for (HSLFTextRun htr : htp.getTextRuns()) {
htr.setMasterStyleReference(charStyles.get(level));
}
} }
} }
} }

View File

@ -68,6 +68,7 @@ import org.apache.poi.hslf.record.RecordTypes;
import org.apache.poi.hslf.record.SlideListWithText; import org.apache.poi.hslf.record.SlideListWithText;
import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet; import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet;
import org.apache.poi.hslf.record.SlidePersistAtom; import org.apache.poi.hslf.record.SlidePersistAtom;
import org.apache.poi.hslf.record.TxMasterStyleAtom;
import org.apache.poi.hslf.record.UserEditAtom; import org.apache.poi.hslf.record.UserEditAtom;
import org.apache.poi.poifs.filesystem.DirectoryNode; import org.apache.poi.poifs.filesystem.DirectoryNode;
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
@ -475,6 +476,23 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
for (HSLFSlide sl : getSlides()) { for (HSLFSlide sl : getSlides()) {
writeDirtyParagraphs(sl); writeDirtyParagraphs(sl);
} }
for (HSLFSlideMaster sl : getSlideMasters()) {
boolean isDirty = false;
for (List<HSLFTextParagraph> paras : sl.getTextParagraphs()) {
for (HSLFTextParagraph p : paras) {
isDirty |= p.isDirty();
}
}
if (isDirty) {
for (TxMasterStyleAtom sa : sl.getTxMasterStyleAtoms()) {
if (sa != null) {
// not all master style atoms are set - index 3 is typically null
sa.updateStyles();
}
}
}
}
_hslfSlideShow.write(out); _hslfSlideShow.write(out);
} }

View File

@ -60,6 +60,7 @@ import org.apache.poi.sl.usermodel.AutoNumberingScheme;
import org.apache.poi.sl.usermodel.PaintStyle; import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.TextParagraph; import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
@ -90,7 +91,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
private final TextHeaderAtom _headerAtom; private final TextHeaderAtom _headerAtom;
private TextBytesAtom _byteAtom; private TextBytesAtom _byteAtom;
private TextCharsAtom _charAtom; private TextCharsAtom _charAtom;
private final TextPropCollection _paragraphStyle = new TextPropCollection(1, TextPropType.paragraph); private TextPropCollection _paragraphStyle = new TextPropCollection(1, TextPropType.paragraph);
protected TextRulerAtom _ruler; protected TextRulerAtom _ruler;
protected final List<HSLFTextRun> _runs = new ArrayList<HSLFTextRun>(); protected final List<HSLFTextRun> _runs = new ArrayList<HSLFTextRun>();
@ -151,6 +152,18 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
_paragraphStyle.copy(paragraphStyle); _paragraphStyle.copy(paragraphStyle);
} }
/**
* Setting a master style reference
*
* @param paragraphStyle the master style reference
*
* @since 3.14-Beta1
*/
@Internal
/* package */ void setMasterStyleReference(TextPropCollection paragraphStyle) {
_paragraphStyle = paragraphStyle;
}
/** /**
* Supply the Sheet we belong to, which might have an assigned SlideShow * Supply the Sheet we belong to, which might have an assigned SlideShow
* Also passes it on to our child RichTextRuns * Also passes it on to our child RichTextRuns
@ -344,12 +357,8 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
return (d != null) ? d : 12d; return (d != null) ? d : 12d;
} }
/** @Override
* Sets the type of horizontal alignment for the paragraph. public void setTextAlign(TextAlign align) {
*
* @param align - the type of alignment
*/
public void setAlignment(org.apache.poi.sl.usermodel.TextParagraph.TextAlign align) {
Integer alignInt = null; Integer alignInt = null;
if (align != null) switch (align) { if (align != null) switch (align) {
default: default:
@ -365,7 +374,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
} }
@Override @Override
public org.apache.poi.sl.usermodel.TextParagraph.TextAlign getTextAlign() { public TextAlign getTextAlign() {
TextProp tp = getPropVal(_paragraphStyle, "alignment", this); TextProp tp = getPropVal(_paragraphStyle, "alignment", this);
if (tp == null) return null; if (tp == null) return null;
switch (tp.getValue()) { switch (tp.getValue()) {
@ -398,7 +407,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
if (styleTextProp9Atom == null) return null; if (styleTextProp9Atom == null) return null;
TextPFException9[] ant = styleTextProp9Atom.getAutoNumberTypes(); TextPFException9[] ant = styleTextProp9Atom.getAutoNumberTypes();
int level = getIndentLevel(); int level = getIndentLevel();
if (ant == null || level >= ant.length) return null; if (ant == null || level == -1 || level >= ant.length) return null;
return ant[level].getAutoNumberScheme(); return ant[level].getAutoNumberScheme();
} }
@ -1224,7 +1233,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
HSLFTextParagraph para = paragraphs.get(paraIdx); HSLFTextParagraph para = paragraphs.get(paraIdx);
List<HSLFTextRun> runs = para.getTextRuns(); List<HSLFTextRun> runs = para.getTextRuns();
trun = runs.get(runIdx); trun = runs.get(runIdx);
int len = trun.getLength(); final int len = trun.getLength();
if (ccRun + len <= ccStyle) { if (ccRun + len <= ccStyle) {
ccRun += len; ccRun += len;
@ -1239,11 +1248,8 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
ccRun += ccStyle - ccRun; ccRun += ccStyle - ccRun;
} }
TextPropCollection pCopy = new TextPropCollection(0, TextPropType.character); trun.setCharacterStyle(p);
pCopy.copy(p);
trun.setCharacterStyle(pCopy);
len = trun.getLength();
if (paraIdx == paragraphs.size()-1 && runIdx == runs.size()-1) { if (paraIdx == paragraphs.size()-1 && runIdx == runs.size()-1) {
if (csIdx < charStyles.size() - 1) { if (csIdx < charStyles.size() - 1) {
// special case, empty trailing text run // special case, empty trailing text run
@ -1253,11 +1259,10 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
ccRun++; ccRun++;
} else { } else {
// need to add +1 to the last run of the last paragraph // need to add +1 to the last run of the last paragraph
len++; trun.getCharacterStyle().updateTextSize(trun.getLength()+1);
ccRun++; ccRun++;
} }
} }
pCopy.updateTextSize(len);
// need to compare it again, in case a run has been added after // need to compare it again, in case a run has been added after
if (++runIdx == runs.size()) { if (++runIdx == runs.size()) {

View File

@ -31,6 +31,7 @@ import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.PaintStyle; import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.TextRun; import org.apache.poi.sl.usermodel.TextRun;
import org.apache.poi.util.Internal;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
@ -66,10 +67,23 @@ public final class HSLFTextRun implements TextRun {
} }
public void setCharacterStyle(TextPropCollection characterStyle) { public void setCharacterStyle(TextPropCollection characterStyle) {
assert(characterStyle != null); this.characterStyle.copy(characterStyle);
this.characterStyle = characterStyle; this.characterStyle.updateTextSize(_runText.length());
} }
/**
* Setting a master style reference
*
* @param characterStyle the master style reference
*
* @since 3.14-Beta1
*/
@Internal
/* package */ void setMasterStyleReference(TextPropCollection characterStyle) {
this.characterStyle = characterStyle;
}
/** /**
* Supply the SlideShow we belong to * Supply the SlideShow we belong to
*/ */

View File

@ -23,6 +23,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.awt.Color; import java.awt.Color;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
@ -32,7 +33,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.poi.POIDataSamples;
import org.apache.poi.ddf.AbstractEscherOptRecord; import org.apache.poi.ddf.AbstractEscherOptRecord;
import org.apache.poi.ddf.EscherArrayProperty; import org.apache.poi.ddf.EscherArrayProperty;
import org.apache.poi.ddf.EscherColorRef; import org.apache.poi.ddf.EscherColorRef;
@ -54,6 +54,7 @@ import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.SlideShowFactory; import org.apache.poi.sl.usermodel.SlideShowFactory;
import org.apache.poi.sl.usermodel.TextBox; import org.apache.poi.sl.usermodel.TextBox;
import org.apache.poi.sl.usermodel.TextParagraph; import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
import org.apache.poi.sl.usermodel.TextRun; import org.apache.poi.sl.usermodel.TextRun;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.StringUtil; import org.apache.poi.util.StringUtil;
@ -67,8 +68,6 @@ import org.junit.Test;
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */
public final class TestBugs { public final class TestBugs {
private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
/** /**
* Bug 41384: Array index wrong in record creation * Bug 41384: Array index wrong in record creation
*/ */
@ -680,7 +679,7 @@ public final class TestBugs {
HSLFTextParagraph tp = cell.getTextParagraphs().get(0); HSLFTextParagraph tp = cell.getTextParagraphs().get(0);
tp.setBulletStyle('%', tp0.getBulletColor(), tp0.getBulletFont(), tp0.getBulletSize()); tp.setBulletStyle('%', tp0.getBulletColor(), tp0.getBulletFont(), tp0.getBulletSize());
tp.setIndent(tp0.getIndent()); tp.setIndent(tp0.getIndent());
tp.setAlignment(tp0.getTextAlign()); tp.setTextAlign(tp0.getTextAlign());
tp.setIndentLevel(tp0.getIndentLevel()); tp.setIndentLevel(tp0.getIndentLevel());
tp.setSpaceAfter(tp0.getSpaceAfter()); tp.setSpaceAfter(tp0.getSpaceAfter());
tp.setSpaceBefore(tp0.getSpaceBefore()); tp.setSpaceBefore(tp0.getSpaceBefore());
@ -729,7 +728,37 @@ public final class TestBugs {
ppt2.close(); ppt2.close();
} }
@Test
public void bug47904() throws IOException {
HSLFSlideShow ppt1 = new HSLFSlideShow();
HSLFSlideMaster sm = ppt1.getSlideMasters().get(0);
HSLFAutoShape as = (HSLFAutoShape)sm.getShapes().get(0);
HSLFTextParagraph tp = as.getTextParagraphs().get(0);
HSLFTextRun tr = tp.getTextRuns().get(0);
tr.setFontFamily("Tahoma");
tr.setShadowed(true);
tr.setFontSize(44.);
tr.setFontColor(Color.red);
tp.setTextAlign(TextAlign.RIGHT);
ppt1.createSlide().addTitle().setText("foobaa");
HSLFSlideShow ppt2 = HSLFTestDataSamples.writeOutAndReadBack(ppt1);
ppt1.close();
HSLFTextShape ts = (HSLFTextShape)ppt2.getSlides().get(0).getShapes().get(0);
tp = ts.getTextParagraphs().get(0);
tr = tp.getTextRuns().get(0);
assertEquals(44., tr.getFontSize(), 0);
assertEquals("Tahoma", tr.getFontFamily());
Color colorAct = DrawPaint.applyColorTransform(tr.getFontColor().getSolidColor());
assertEquals(Color.red, colorAct);
assertEquals(TextAlign.RIGHT, tp.getTextAlign());
assertEquals("foobaa", tr.getRawText());
ppt2.close();
}
private static HSLFSlideShow open(String fileName) throws IOException { private static HSLFSlideShow open(String fileName) throws IOException {
return (HSLFSlideShow)SlideShowFactory.create(_slTests.getFile(fileName)); File sample = HSLFTestDataSamples.getSampleFile(fileName);
return (HSLFSlideShow)SlideShowFactory.create(sample);
} }
} }

View File

@ -19,14 +19,20 @@
package org.apache.poi.hslf.usermodel; package org.apache.poi.hslf.usermodel;
import static org.junit.Assert.*; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.List; import java.util.List;
import org.apache.poi.POIDataSamples; import org.apache.poi.POIDataSamples;
import org.apache.poi.hslf.model.textproperties.TextPFException9; import org.apache.poi.hslf.model.textproperties.TextPFException9;
import org.apache.poi.hslf.model.textproperties.TextPropCollection; import org.apache.poi.hslf.model.textproperties.TextPropCollection;
import org.apache.poi.hslf.record.*; import org.apache.poi.hslf.record.EscherTextboxWrapper;
import org.apache.poi.hslf.record.StyleTextProp9Atom;
import org.apache.poi.hslf.record.StyleTextPropAtom;
import org.apache.poi.sl.usermodel.AutoNumberingScheme; import org.apache.poi.sl.usermodel.AutoNumberingScheme;
import org.junit.Test; import org.junit.Test;
@ -43,7 +49,7 @@ public final class TestNumberedList3 {
private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance(); private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
@Test @Test
public void testNumberedList() throws Exception { public void testNumberedList() throws IOException {
HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("numbers3.ppt")); HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("numbers3.ppt"));
assertTrue("No Exceptions while reading file", true); assertTrue("No Exceptions while reading file", true);
@ -51,6 +57,7 @@ public final class TestNumberedList3 {
assertEquals(1, slides.size()); assertEquals(1, slides.size());
final HSLFSlide slide = slides.get(0); final HSLFSlide slide = slides.get(0);
checkSlide(slide); checkSlide(slide);
ppt.close();
} }
private void checkSlide(final HSLFSlide s) { private void checkSlide(final HSLFSlide s) {
final StyleTextProp9Atom[] numberedListArray = s.getNumberedListInfo(); final StyleTextProp9Atom[] numberedListArray = s.getNumberedListInfo();