use of org.apache.poi.hslf.record.TextHeaderAtom in project poi by apache.
the class HSLFTextParagraph method findTextParagraphs.
/**
* Scans through the supplied record array, looking for
* a TextHeaderAtom followed by one of a TextBytesAtom or
* a TextCharsAtom. Builds up TextRuns from these
*
* @param records the records to build from
*/
protected static List<List<HSLFTextParagraph>> findTextParagraphs(Record[] records) {
List<List<HSLFTextParagraph>> paragraphCollection = new ArrayList<List<HSLFTextParagraph>>();
int[] recordIdx = { 0 };
for (int slwtIndex = 0; recordIdx[0] < records.length; slwtIndex++) {
TextHeaderAtom header = null;
TextBytesAtom tbytes = null;
TextCharsAtom tchars = null;
TextRulerAtom ruler = null;
MasterTextPropAtom indents = null;
for (Record r : getRecords(records, recordIdx, null)) {
long rt = r.getRecordType();
if (RecordTypes.TextHeaderAtom.typeID == rt) {
header = (TextHeaderAtom) r;
} else if (RecordTypes.TextBytesAtom.typeID == rt) {
tbytes = (TextBytesAtom) r;
} else if (RecordTypes.TextCharsAtom.typeID == rt) {
tchars = (TextCharsAtom) r;
} else if (RecordTypes.TextRulerAtom.typeID == rt) {
ruler = (TextRulerAtom) r;
} else if (RecordTypes.MasterTextPropAtom.typeID == rt) {
indents = (MasterTextPropAtom) r;
}
// don't search for RecordTypes.StyleTextPropAtom.typeID here ... see findStyleAtomPresent below
}
if (header == null) {
break;
}
if (header.getParentRecord() instanceof SlideListWithText) {
// runs found in PPDrawing are not linked with SlideListWithTexts
header.setIndex(slwtIndex);
}
if (tbytes == null && tchars == null) {
tbytes = new TextBytesAtom();
// don't add record yet - set it in storeText
logger.log(POILogger.INFO, "bytes nor chars atom doesn't exist. Creating dummy record for later saving.");
}
String rawText = (tchars != null) ? tchars.getText() : tbytes.getText();
StyleTextPropAtom styles = findStyleAtomPresent(header, rawText.length());
List<HSLFTextParagraph> paragraphs = new ArrayList<HSLFTextParagraph>();
paragraphCollection.add(paragraphs);
// split, but keep delimiter
for (String para : rawText.split("(?<=\r)")) {
HSLFTextParagraph tpara = new HSLFTextParagraph(header, tbytes, tchars, paragraphs);
paragraphs.add(tpara);
tpara._ruler = ruler;
tpara.getParagraphStyle().updateTextSize(para.length());
HSLFTextRun trun = new HSLFTextRun(tpara);
tpara.addTextRun(trun);
trun.setText(para);
}
applyCharacterStyles(paragraphs, styles.getCharacterStyles());
applyParagraphStyles(paragraphs, styles.getParagraphStyles());
if (indents != null) {
applyParagraphIndents(paragraphs, indents.getIndents());
}
}
if (paragraphCollection.isEmpty()) {
logger.log(POILogger.DEBUG, "No text records found.");
}
return paragraphCollection;
}
use of org.apache.poi.hslf.record.TextHeaderAtom in project poi by apache.
the class HSLFTextParagraph method updateTextAtom.
/**
* Set the correct text atom depending on the multibyte usage
*/
private static void updateTextAtom(List<HSLFTextParagraph> paragraphs) {
final String rawText = toInternalString(getRawText(paragraphs));
// Will it fit in a 8 bit atom?
boolean isUnicode = StringUtil.hasMultibyte(rawText);
// isUnicode = true;
TextHeaderAtom headerAtom = paragraphs.get(0)._headerAtom;
TextBytesAtom byteAtom = paragraphs.get(0)._byteAtom;
TextCharsAtom charAtom = paragraphs.get(0)._charAtom;
StyleTextPropAtom styleAtom = findStyleAtomPresent(headerAtom, rawText.length());
// Store in the appropriate record
Record oldRecord = null, newRecord = null;
if (isUnicode) {
if (byteAtom != null || charAtom == null) {
oldRecord = byteAtom;
charAtom = new TextCharsAtom();
}
newRecord = charAtom;
charAtom.setText(rawText);
} else {
if (charAtom != null || byteAtom == null) {
oldRecord = charAtom;
byteAtom = new TextBytesAtom();
}
newRecord = byteAtom;
byte[] byteText = new byte[rawText.length()];
StringUtil.putCompressedUnicode(rawText, byteText, 0);
byteAtom.setText(byteText);
}
assert (newRecord != null);
RecordContainer _txtbox = headerAtom.getParentRecord();
Record[] cr = _txtbox.getChildRecords();
int /* headerIdx = -1, */
textIdx = -1, styleIdx = -1;
for (int i = 0; i < cr.length; i++) {
Record r = cr[i];
if (r == headerAtom) {
// headerIdx = i;
} else if (r == oldRecord || r == newRecord) {
textIdx = i;
} else if (r == styleAtom) {
styleIdx = i;
}
}
if (textIdx == -1) {
// the old record was never registered, ignore it
_txtbox.addChildAfter(newRecord, headerAtom);
// textIdx = headerIdx + 1;
} else {
// swap not appropriated records - noop if unchanged
cr[textIdx] = newRecord;
}
if (styleIdx == -1) {
// Add the new StyleTextPropAtom after the TextCharsAtom / TextBytesAtom
_txtbox.addChildAfter(styleAtom, newRecord);
}
for (HSLFTextParagraph p : paragraphs) {
if (newRecord == byteAtom) {
p._byteAtom = byteAtom;
p._charAtom = null;
} else {
p._byteAtom = null;
p._charAtom = charAtom;
}
}
}
use of org.apache.poi.hslf.record.TextHeaderAtom in project poi by apache.
the class HSLFTextParagraph method updateStyles.
/**
* Update paragraph and character styles - merges them when subsequential styles match
*/
private static void updateStyles(List<HSLFTextParagraph> paragraphs) {
final String rawText = toInternalString(getRawText(paragraphs));
TextHeaderAtom headerAtom = paragraphs.get(0)._headerAtom;
StyleTextPropAtom styleAtom = findStyleAtomPresent(headerAtom, rawText.length());
// Update the text length for its Paragraph and Character stylings
// * reset the length, to the new string's length
// * add on +1 if the last block
styleAtom.clearStyles();
TextPropCollection lastPTPC = null, lastRTPC = null, ptpc = null, rtpc = null;
for (HSLFTextParagraph para : paragraphs) {
ptpc = para.getParagraphStyle();
ptpc.updateTextSize(0);
if (!ptpc.equals(lastPTPC)) {
lastPTPC = styleAtom.addParagraphTextPropCollection(0);
lastPTPC.copy(ptpc);
}
for (HSLFTextRun tr : para.getTextRuns()) {
rtpc = tr.getCharacterStyle();
rtpc.updateTextSize(0);
if (!rtpc.equals(lastRTPC)) {
lastRTPC = styleAtom.addCharacterTextPropCollection(0);
lastRTPC.copy(rtpc);
}
int len = tr.getLength();
ptpc.updateTextSize(ptpc.getCharactersCovered() + len);
rtpc.updateTextSize(len);
lastPTPC.updateTextSize(lastPTPC.getCharactersCovered() + len);
lastRTPC.updateTextSize(lastRTPC.getCharactersCovered() + len);
}
}
if (lastPTPC == null || lastRTPC == null || ptpc == null || rtpc == null) {
// NOSONAR
throw new HSLFException("Not all TextPropCollection could be determined.");
}
ptpc.updateTextSize(ptpc.getCharactersCovered() + 1);
rtpc.updateTextSize(rtpc.getCharactersCovered() + 1);
lastPTPC.updateTextSize(lastPTPC.getCharactersCovered() + 1);
lastRTPC.updateTextSize(lastRTPC.getCharactersCovered() + 1);
/**
* If TextSpecInfoAtom is present, we must update the text size in it,
* otherwise the ppt will be corrupted
*/
for (Record r : paragraphs.get(0).getRecords()) {
if (r instanceof TextSpecInfoAtom) {
((TextSpecInfoAtom) r).setParentSize(rawText.length() + 1);
break;
}
}
}
use of org.apache.poi.hslf.record.TextHeaderAtom in project poi by apache.
the class HSLFTextParagraph method getRecords.
private static Record[] getRecords(Record[] records, int[] startIdx, TextHeaderAtom headerAtom) {
if (records == null) {
throw new NullPointerException("records need to be set.");
}
for (; startIdx[0] < records.length; startIdx[0]++) {
Record r = records[startIdx[0]];
if (r instanceof TextHeaderAtom && (headerAtom == null || r == headerAtom)) {
break;
}
}
if (startIdx[0] >= records.length) {
logger.log(POILogger.INFO, "header atom wasn't found - container might contain only an OutlineTextRefAtom");
return new Record[0];
}
int length;
for (length = 1; startIdx[0] + length < records.length; length++) {
Record r = records[startIdx[0] + length];
if (r instanceof TextHeaderAtom || r instanceof SlidePersistAtom) {
break;
}
}
Record[] result = new Record[length];
System.arraycopy(records, startIdx[0], result, 0, length);
startIdx[0] += length;
return result;
}
use of org.apache.poi.hslf.record.TextHeaderAtom in project poi by apache.
the class TestBugs method bug56260.
@Test
public void bug56260() throws IOException {
HSLFSlideShow ppt = open("56260.ppt");
List<HSLFSlide> _slides = ppt.getSlides();
assertEquals(13, _slides.size());
// Check the number of TextHeaderAtoms on Slide 1
Document dr = ppt.getDocumentRecord();
SlideListWithText slidesSLWT = dr.getSlideSlideListWithText();
SlideAtomsSet s1 = slidesSLWT.getSlideAtomsSets()[0];
int tha = 0;
for (Record r : s1.getSlideRecords()) {
if (r instanceof TextHeaderAtom) {
tha++;
}
}
assertEquals(2, tha);
// Check to see that we have a pair next to each other
assertEquals(TextHeaderAtom.class, s1.getSlideRecords()[0].getClass());
assertEquals(TextHeaderAtom.class, s1.getSlideRecords()[1].getClass());
// Check the number of text runs based on the slide (not textbox)
// Will have skipped the empty one
int str = 0;
for (List<HSLFTextParagraph> tr : _slides.get(0).getTextParagraphs()) {
if (!tr.get(0).isDrawingBased()) {
str++;
}
}
assertEquals(2, str);
ppt.close();
}
Aggregations