aboutsummaryrefslogtreecommitdiffstats
path: root/src/scratchpad
diff options
context:
space:
mode:
authorAndreas Beeker <kiwiwings@apache.org>2018-02-11 20:39:18 +0000
committerAndreas Beeker <kiwiwings@apache.org>2018-02-11 20:39:18 +0000
commit9968e86b14188b43920f0ef28f68559e3dadf7be (patch)
tree54e5d238df674471154d47f5ed5746bfb92ee782 /src/scratchpad
parent5f71c8013157ee2754dcc3109b79f9873d14a086 (diff)
downloadpoi-9968e86b14188b43920f0ef28f68559e3dadf7be.tar.gz
poi-9968e86b14188b43920f0ef28f68559e3dadf7be.zip
#62096 - Add support for tabstops
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1823893 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/scratchpad')
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/model/textproperties/HSLFTabStop.java116
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/model/textproperties/HSLFTabStopPropCollection.java158
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TabStopPropCollection.java123
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextProp.java6
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java41
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/record/TextRulerAtom.java196
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFMasterSheet.java22
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java59
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java218
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java65
-rw-r--r--src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTitleMaster.java10
-rw-r--r--src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlideMaster.java57
-rw-r--r--src/scratchpad/testcases/org/apache/poi/hslf/record/TestTextRulerAtom.java33
-rw-r--r--src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestHSLFSlideShow.java27
14 files changed, 705 insertions, 426 deletions
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/HSLFTabStop.java b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/HSLFTabStop.java
new file mode 100644
index 0000000000..78cc3fab4d
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/HSLFTabStop.java
@@ -0,0 +1,116 @@
+/* ====================================================================
+ 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.hslf.model.textproperties;
+
+import org.apache.poi.sl.usermodel.TabStop;
+import org.apache.poi.util.Internal;
+import org.apache.poi.util.Units;
+
+@Internal
+public class HSLFTabStop implements TabStop, Cloneable {
+ /**
+ * A signed integer that specifies an offset, in master units, of the tab stop.
+ *
+ * If the TextPFException record that contains this TabStop structure also contains a
+ * leftMargin, then the value of position is relative to the left margin of the paragraph;
+ * otherwise, the value is relative to the left side of the paragraph.
+ *
+ * If a TextRuler record contains this TabStop structure, the value is relative to the
+ * left side of the text ruler.
+ */
+ private int position;
+
+ /**
+ * A enumeration that specifies how text aligns at the tab stop.
+ */
+ private TabStopType type;
+
+ public HSLFTabStop(int position, TabStopType type) {
+ this.position = position;
+ this.type = type;
+ }
+
+ public int getPosition() {
+ return position;
+ }
+
+ public void setPosition(final int position) {
+ this.position = position;
+ }
+
+ @Override
+ public double getPositionInPoints() {
+ return Units.masterToPoints(getPosition());
+ }
+
+ @Override
+ public void setPositionInPoints(final double points) {
+ setPosition(Units.pointsToMaster(points));
+ }
+
+ @Override
+ public TabStopType getType() {
+ return type;
+ }
+
+ @Override
+ public void setType(TabStopType type) {
+ this.type = type;
+ }
+
+ @Override
+ public HSLFTabStop clone() {
+ try {
+ return (HSLFTabStop)super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + position;
+ result = prime * result + ((type == null) ? 0 : type.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof HSLFTabStop)) {
+ return false;
+ }
+ HSLFTabStop other = (HSLFTabStop) obj;
+ if (position != other.position) {
+ return false;
+ }
+ if (type != other.type) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return type + " @ " + position;
+ }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/HSLFTabStopPropCollection.java b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/HSLFTabStopPropCollection.java
new file mode 100644
index 0000000000..7f7f6bd9cf
--- /dev/null
+++ b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/HSLFTabStopPropCollection.java
@@ -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.hslf.model.textproperties;
+
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.sl.usermodel.TabStop.TabStopType;
+import org.apache.poi.util.Internal;
+import org.apache.poi.util.LittleEndianByteArrayInputStream;
+import org.apache.poi.util.LittleEndianConsts;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.LittleEndianOutputStream;
+
+/**
+ * Container for tabstop lists
+ */
+@Internal
+public class HSLFTabStopPropCollection extends TextProp {
+ public static final String NAME = "tabStops";
+
+ private final List<HSLFTabStop> tabStops = new ArrayList<>();
+
+ public HSLFTabStopPropCollection() {
+ super(0, 0x100000, NAME);
+ }
+
+ public HSLFTabStopPropCollection(final HSLFTabStopPropCollection copy) {
+ super(0, copy.getMask(), copy.getName());
+ for (HSLFTabStop ts : copy.tabStops) {
+ tabStops.add(ts.clone());
+ }
+ }
+
+ /**
+ * Parses the tabstops from TxMasterStyle record
+ *
+ * @param data the data stream
+ * @param offset the offset within the data
+ */
+ public void parseProperty(byte data[], int offset) {
+ tabStops.addAll(readTabStops(new LittleEndianByteArrayInputStream(data, offset)));
+ }
+
+ public static List<HSLFTabStop> readTabStops(final LittleEndianInput lei) {
+ final int count = lei.readUShort();
+ final List<HSLFTabStop> tabs = new ArrayList<>(count);
+ for (int i=0; i<count; i++) {
+ final int position = lei.readShort();
+ final TabStopType type = TabStopType.fromNativeId(lei.readShort());
+ tabs.add(new HSLFTabStop(position, type));
+ }
+ return tabs;
+ }
+
+
+ public void writeProperty(OutputStream out) {
+ writeTabStops(new LittleEndianOutputStream(out), tabStops);
+ }
+
+ public static void writeTabStops(final LittleEndianOutput leo, List<HSLFTabStop> tabStops) {
+ final int count = tabStops.size();
+ leo.writeShort(count);
+ for (HSLFTabStop ts : tabStops) {
+ leo.writeShort(ts.getPosition());
+ leo.writeShort(ts.getType().nativeId);
+ }
+
+ }
+
+ @Override
+ public int getValue() { return tabStops.size(); }
+
+
+ @Override
+ public int getSize() {
+ return LittleEndianConsts.SHORT_SIZE + tabStops.size()*LittleEndianConsts.INT_SIZE;
+ }
+
+ public List<HSLFTabStop> getTabStops() {
+ return tabStops;
+ }
+
+ public void clearTabs() {
+ tabStops.clear();
+ }
+
+ public void addTabStop(HSLFTabStop ts) {
+ tabStops.add(ts);
+ }
+
+ @Override
+ public HSLFTabStopPropCollection clone() {
+ return new HSLFTabStopPropCollection(this);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result
+ + ((tabStops == null) ? 0 : tabStops.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof HSLFTabStopPropCollection)) {
+ return false;
+ }
+ HSLFTabStopPropCollection other = (HSLFTabStopPropCollection) obj;
+ if (!super.equals(other)) {
+ return false;
+ }
+
+ return tabStops.equals(other.tabStops);
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder(super.toString());
+ sb.append(" [ ");
+ boolean isFirst = true;
+ for (HSLFTabStop tabStop : tabStops) {
+ if (!isFirst) {
+ sb.append(", ");
+ }
+ sb.append(tabStop.getType());
+ sb.append(" @ ");
+ sb.append(tabStop.getPosition());
+ isFirst = false;
+ }
+ sb.append(" ]");
+
+ return sb.toString();
+ }
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TabStopPropCollection.java b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TabStopPropCollection.java
deleted file mode 100644
index 1934cf8983..0000000000
--- a/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TabStopPropCollection.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/* ====================================================================
- 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.hslf.model.textproperties;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.LittleEndianConsts;
-
-/**
- * Container for tabstop lists
- */
-public class TabStopPropCollection extends TextProp {
- public enum TabStopType {
- LEFT(0), CENTER(1), RIGHT(2), DECIMAL(3);
- private final int val;
- TabStopType(int val) {
- this.val = val;
- }
- public static TabStopType fromRecordVal(int val) {
- for (TabStopType tst : values()) {
- if (tst.val == val) return tst;
- }
- return LEFT;
- }
- }
-
- public static class TabStop {
- /**
- * If the TextPFException record that contains this TabStop structure also contains a
- * leftMargin, then the value of position is relative to the left margin of the paragraph;
- * otherwise, the value is relative to the left side of the paragraph.
- *
- * If a TextRuler record contains this TabStop structure, the value is relative to the
- * left side of the text ruler.
- */
- private int position;
-
- /**
- * A enumeration that specifies how text aligns at the tab stop.
- */
- private TabStopType type;
-
- public TabStop(int position, TabStopType type) {
- this.position = position;
- this.type = type;
- }
-
- public int getPosition() {
- return position;
- }
-
- public void setPosition(int position) {
- this.position = position;
- }
-
- public TabStopType getType() {
- return type;
- }
-
- public void setType(TabStopType type) {
- this.type = type;
- }
- }
-
- private List<TabStop> tabStops = new ArrayList<>();
-
- public TabStopPropCollection() {
- super(0, 0x100000, "tabStops");
- }
-
- /**
- * Parses the tabstops from TxMasterStyle record
- *
- * @param data the data stream
- * @param offset the offset within the data
- */
- public void parseProperty(byte data[], int offset) {
- int count = LittleEndian.getUShort(data, offset);
- int off = offset + LittleEndianConsts.SHORT_SIZE;
- for (int i=0; i<count; i++) {
- int position = LittleEndian.getShort(data, off);
- off += LittleEndianConsts.SHORT_SIZE;
- int recVal = LittleEndian.getShort(data, off);
- TabStopType type = TabStopType.fromRecordVal(recVal);
- off += LittleEndianConsts.SHORT_SIZE;
- tabStops.add(new TabStop(position, type));
-
- }
- }
-
- @Override
- public int getSize() {
- return LittleEndianConsts.SHORT_SIZE + tabStops.size()*LittleEndianConsts.INT_SIZE;
- }
-
- @Override
- public TabStopPropCollection clone() {
- TabStopPropCollection other = (TabStopPropCollection)super.clone();
- other.tabStops = new ArrayList<>();
- for (TabStop ts : tabStops) {
- TabStop tso = new TabStop(ts.getPosition(), ts.getType());
- other.tabStops.add(tso);
- }
- return other;
- }
-}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextProp.java b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextProp.java
index 9333968f07..dfb1a1e544 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextProp.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextProp.java
@@ -96,7 +96,7 @@ public class TextProp implements Cloneable {
try {
return (TextProp)super.clone();
} catch(CloneNotSupportedException e) {
- throw new InternalError(e.getMessage());
+ throw new IllegalStateException(e);
}
}
@@ -145,11 +145,11 @@ public class TextProp implements Cloneable {
@Override
public String toString() {
int len;
- switch (sizeOfDataBlock) {
+ switch (getSize()) {
case 1: len = 4; break;
case 2: len = 6; break;
default: len = 10; break;
}
- return String.format(Locale.ROOT, "%s = %d (%0#"+len+"X mask / %d bytes)", propName, dataValue, maskInHeader, sizeOfDataBlock);
+ return String.format(Locale.ROOT, "%s = %d (%0#"+len+"X mask / %d bytes)", getName(), getValue(), getMask(), getSize());
}
} \ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java
index 93a036fd07..976e8550f5 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java
@@ -58,7 +58,7 @@ public class TextPropCollection {
// 0x200 - Undefined and MUST be ignored
new TextProp(2, 0x400, "bullet.offset"), // indent
new TextProp(2, 0x8000, "defaultTabSize"),
- new TabStopPropCollection(), // tabstops size is variable!
+ new HSLFTabStopPropCollection(), // tabstops size is variable!
new FontAlignmentProp(),
new WrapFlagsTextProp(),
new TextProp(2, 0x200000, "textDirection"),
@@ -130,12 +130,14 @@ public class TextPropCollection {
}
/** Fetch the TextProp with this name, or null if it isn't present */
- public final TextProp findByName(String textPropName) {
- return textProps.get(textPropName);
+ @SuppressWarnings("unchecked")
+ public final <T extends TextProp> T findByName(String textPropName) {
+ return (T)textProps.get(textPropName);
}
- public final TextProp removeByName(String name) {
- return textProps.remove(name);
+ @SuppressWarnings("unchecked")
+ public final <T extends TextProp> T removeByName(String name) {
+ return (T)textProps.remove(name);
}
public final TextPropType getTextPropType() {
@@ -153,10 +155,11 @@ public class TextPropCollection {
* @param name the property name
* @return if found, the property template to copy from
*/
- private TextProp validatePropName(String name) {
+ @SuppressWarnings("unchecked")
+ private <T extends TextProp> T validatePropName(final String name) {
for (TextProp tp : getPotentialProperties()) {
if (tp.getName().equals(name)) {
- return tp;
+ return (T)tp;
}
}
String errStr =
@@ -166,13 +169,14 @@ public class TextPropCollection {
}
/** Add the TextProp with this name to the list */
- public final TextProp addWithName(String name) {
+ @SuppressWarnings("unchecked")
+ public final <T extends TextProp> T addWithName(final String name) {
// Find the base TextProp to base on
- TextProp existing = findByName(name);
+ T existing = findByName(name);
if (existing != null) return existing;
// Add a copy of this property
- TextProp textProp = validatePropName(name).clone();
+ T textProp = (T)validatePropName(name).clone();
textProps.put(name,textProp);
return textProp;
}
@@ -218,11 +222,13 @@ public class TextPropCollection {
// Bingo, data contains this property
TextProp prop = tp.clone();
int val = 0;
- if (prop.getSize() == 2) {
+ if (prop instanceof HSLFTabStopPropCollection) {
+ ((HSLFTabStopPropCollection)prop).parseProperty(data, dataOffset+bytesPassed);
+ } else if (prop.getSize() == 2) {
val = LittleEndian.getShort(data,dataOffset+bytesPassed);
} else if(prop.getSize() == 4) {
val = LittleEndian.getInt(data,dataOffset+bytesPassed);
- } else if (prop.getSize() == 0 && !(prop instanceof TabStopPropCollection)) {
+ } else if (prop.getSize() == 0) {
//remember "special" bits.
maskSpecial |= tp.getMask();
continue;
@@ -230,9 +236,7 @@ public class TextPropCollection {
if (prop instanceof BitMaskTextProp) {
((BitMaskTextProp)prop).setValueWithMask(val, containsField);
- } else if (prop instanceof TabStopPropCollection) {
- ((TabStopPropCollection)prop).parseProperty(data, dataOffset+bytesPassed);
- } else {
+ } else if (!(prop instanceof HSLFTabStopPropCollection)) {
prop.setValue(val);
}
bytesPassed += prop.getSize();
@@ -311,6 +315,8 @@ public class TextPropCollection {
StyleTextPropAtom.writeLittleEndian((short)val,o);
} else if (textProp.getSize() == 4) {
StyleTextPropAtom.writeLittleEndian(val,o);
+ } else if (textProp instanceof HSLFTabStopPropCollection) {
+ ((HSLFTabStopPropCollection)textProp).writeProperty(o);
}
}
}
@@ -359,8 +365,9 @@ public class TextPropCollection {
out.append(" indent level: "+getIndentLevel()+"\n");
}
for(TextProp p : getTextPropList()) {
- out.append(" " + p.getName() + " = " + p.getValue() );
- out.append(" (0x" + HexDump.toHex(p.getValue()) + ")\n");
+ out.append(" ");
+ out.append(p.toString());
+ out.append("\n");
if (p instanceof BitMaskTextProp) {
BitMaskTextProp bm = (BitMaskTextProp)p;
int i = 0;
diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/TextRulerAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/TextRulerAtom.java
index 53666d9184..e0c45a5daf 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/record/TextRulerAtom.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/record/TextRulerAtom.java
@@ -17,11 +17,21 @@
package org.apache.poi.hslf.record;
+import static org.apache.poi.util.BitFieldFactory.getInstance;
+
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
-import org.apache.poi.util.IOUtils;
+import org.apache.poi.hslf.model.textproperties.HSLFTabStop;
+import org.apache.poi.hslf.model.textproperties.HSLFTabStopPropCollection;
+import org.apache.poi.util.BitField;
import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.LittleEndianByteArrayInputStream;
+import org.apache.poi.util.LittleEndianOutputStream;
import org.apache.poi.util.POILogger;
/**
@@ -31,33 +41,38 @@ public final class TextRulerAtom extends RecordAtom {
//arbitrarily selected; may need to increase
private static final int MAX_RECORD_LENGTH = 100_000;
+
+ private static final BitField DEFAULT_TAB_SIZE = getInstance(0x0001);
+ private static final BitField C_LEVELS = getInstance(0x0002);
+ private static final BitField TAB_STOPS = getInstance(0x0004);
+ private static final BitField[] LEFT_MARGIN = {
+ getInstance(0x0008), getInstance(0x0010), getInstance(0x0020),
+ getInstance(0x0040), getInstance(0x0080),
+ };
+ private static final BitField[] INDENT = {
+ getInstance(0x0100), getInstance(0x0200), getInstance(0x0400),
+ getInstance(0x0800), getInstance(0x1000),
+ };
/**
* Record header.
*/
- private byte[] _header;
-
- /**
- * Record data.
- */
- private byte[] _data;
+ private final byte[] _header = new byte[8];
//ruler internals
- private int defaultTabSize;
- private int numLevels;
- private int[] tabStops;
- private int[] bulletOffsets = new int[5];
- private int[] textOffsets = new int[5];
+ private Integer defaultTabSize;
+ private Integer numLevels;
+ private final List<HSLFTabStop> tabStops = new ArrayList<>();
+ //bullet.offset
+ private final Integer[] leftMargin = new Integer[5];
+ //text.offset
+ private final Integer[] indent = new Integer[5];
/**
* Constructs a new empty ruler atom.
*/
public TextRulerAtom() {
- _header = new byte[8];
- _data = new byte[0];
-
LittleEndian.putShort(_header, 2, (short)getRecordType());
- LittleEndian.putInt(_header, 4, _data.length);
}
/**
@@ -68,18 +83,17 @@ public final class TextRulerAtom extends RecordAtom {
* @param start the start offset into the byte array.
* @param len the length of the slice in the byte array.
*/
- protected TextRulerAtom(byte[] source, int start, int len) {
- // Get the header.
- _header = new byte[8];
- System.arraycopy(source,start,_header,0,8);
-
- // Get the record data.
- _data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
- System.arraycopy(source,start+8,_data,0,len-8);
+ protected TextRulerAtom(final byte[] source, final int start, final int len) {
+ final LittleEndianByteArrayInputStream leis = new LittleEndianByteArrayInputStream(source, start, Math.min(len, MAX_RECORD_LENGTH));
+
try {
- read();
- } catch (Exception e){
+ // Get the header.
+ leis.read(_header);
+
+ // Get the record data.
+ read(leis);
+ } catch (IOException e){
logger.log(POILogger.ERROR, "Failed to parse TextRulerAtom: " + e.getMessage());
}
}
@@ -89,6 +103,7 @@ public final class TextRulerAtom extends RecordAtom {
*
* @return the record type.
*/
+ @Override
public long getRecordType() {
return RecordTypes.TextRulerAtom.typeID;
}
@@ -100,109 +115,110 @@ public final class TextRulerAtom extends RecordAtom {
* @param out the output stream to write to.
* @throws java.io.IOException if an error occurs.
*/
- public void writeOut(OutputStream out) throws IOException {
+ @Override
+ public void writeOut(final OutputStream out) throws IOException {
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream(200);
+ final LittleEndianOutputStream lbos = new LittleEndianOutputStream(bos);
+ int mask = 0;
+ mask |= writeIf(lbos, numLevels, C_LEVELS);
+ mask |= writeIf(lbos, defaultTabSize, DEFAULT_TAB_SIZE);
+ mask |= writeIf(lbos, tabStops, TAB_STOPS);
+ for (int i=0; i<5; i++) {
+ mask |= writeIf(lbos, leftMargin[i], LEFT_MARGIN[i]);
+ mask |= writeIf(lbos, indent[i], INDENT[i]);
+ }
+ LittleEndian.putInt(_header, 4, bos.size()+4);
out.write(_header);
- out.write(_data);
+ LittleEndian.putUShort(mask, out);
+ LittleEndian.putUShort(0, out);
+ bos.writeTo(out);
}
+ private static int writeIf(final LittleEndianOutputStream lbos, Integer value, BitField bit) {
+ boolean isSet = false;
+ if (value != null) {
+ lbos.writeShort(value);
+ isSet = true;
+ }
+ return bit.setBoolean(0, isSet);
+ }
+
+ private static int writeIf(final LittleEndianOutputStream lbos, List<HSLFTabStop> value, BitField bit) {
+ boolean isSet = false;
+ if (value != null && !value.isEmpty()) {
+ HSLFTabStopPropCollection.writeTabStops(lbos, value);
+ isSet = true;
+ }
+ return bit.setBoolean(0, isSet);
+ }
+
/**
* Read the record bytes and initialize the internal variables
*/
- private void read(){
- int pos = 0;
- short mask = LittleEndian.getShort(_data); pos += 4;
- short val;
- int[] bits = {1, 0, 2, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12};
- for (int i = 0; i < bits.length; i++) {
- if((mask & 1 << bits[i]) != 0){
- switch (bits[i]){
- case 0:
- //defaultTabSize
- defaultTabSize = LittleEndian.getShort(_data, pos); pos += 2;
- break;
- case 1:
- //numLevels
- numLevels = LittleEndian.getShort(_data, pos); pos += 2;
- break;
- case 2:
- //tabStops
- val = LittleEndian.getShort(_data, pos); pos += 2;
- tabStops = new int[val*2];
- for (int j = 0; j < tabStops.length; j++) {
- tabStops[j] = LittleEndian.getUShort(_data, pos); pos += 2;
- }
- break;
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- //bullet.offset
- val = LittleEndian.getShort(_data, pos); pos += 2;
- bulletOffsets[bits[i]-3] = val;
- break;
- case 8:
- case 9:
- case 10:
- case 11:
- case 12:
- //text.offset
- val = LittleEndian.getShort(_data, pos); pos += 2;
- textOffsets[bits[i]-8] = val;
- break;
- default:
- break;
- }
- }
+ private void read(final LittleEndianByteArrayInputStream leis) {
+ final int mask = leis.readInt();
+ numLevels = readIf(leis, mask, C_LEVELS);
+ defaultTabSize = readIf(leis, mask, DEFAULT_TAB_SIZE);
+ if (TAB_STOPS.isSet(mask)) {
+ tabStops.addAll(HSLFTabStopPropCollection.readTabStops(leis));
+ }
+ for (int i=0; i<5; i++) {
+ leftMargin[i] = readIf(leis, mask, LEFT_MARGIN[i]);
+ indent[i] = readIf(leis, mask, INDENT[i]);
}
}
+ private static Integer readIf(final LittleEndianByteArrayInputStream leis, final int mask, final BitField bit) {
+ return (bit.isSet(mask)) ? (int)leis.readShort() : null;
+ }
+
/**
* Default distance between tab stops, in master coordinates (576 dpi).
*/
public int getDefaultTabSize(){
- return defaultTabSize;
+ return defaultTabSize == null ? 0 : defaultTabSize;
}
/**
* Number of indent levels (maximum 5).
*/
public int getNumberOfLevels(){
- return numLevels;
+ return numLevels == null ? 0 : numLevels;
}
/**
* Default distance between tab stops, in master coordinates (576 dpi).
*/
- public int[] getTabStops(){
+ public List<HSLFTabStop> getTabStops(){
return tabStops;
}
/**
* Paragraph's distance from shape's left margin, in master coordinates (576 dpi).
*/
- public int[] getTextOffsets(){
- return textOffsets;
+ public Integer[] getTextOffsets(){
+ return indent;
}
/**
* First line of paragraph's distance from shape's left margin, in master coordinates (576 dpi).
*/
- public int[] getBulletOffsets(){
- return bulletOffsets;
+ public Integer[] getBulletOffsets(){
+ return leftMargin;
}
public static TextRulerAtom getParagraphInstance(){
- byte[] data = new byte[] {
- 0x00, 0x00, (byte)0xA6, 0x0F, 0x0A, 0x00, 0x00, 0x00,
- 0x10, 0x03, 0x00, 0x00, (byte)0xF9, 0x00, 0x41, 0x01, 0x41, 0x01
- };
- return new TextRulerAtom(data, 0, data.length);
+ final TextRulerAtom tra = new TextRulerAtom();
+ tra.indent[0] = 249;
+ tra.indent[1] = tra.leftMargin[1] = 321;
+ return tra;
}
- public void setParagraphIndent(short tetxOffset, short bulletOffset){
- LittleEndian.putShort(_data, 4, tetxOffset);
- LittleEndian.putShort(_data, 6, bulletOffset);
- LittleEndian.putShort(_data, 8, bulletOffset);
+ public void setParagraphIndent(short leftMargin, short indent) {
+ Arrays.fill(this.leftMargin, null);
+ Arrays.fill(this.indent, null);
+ this.leftMargin[0] = (int)leftMargin;
+ this.indent[0] = (int)indent;
+ this.indent[1] = (int)indent;
}
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFMasterSheet.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFMasterSheet.java
index d73374620d..526a3ceed2 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFMasterSheet.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFMasterSheet.java
@@ -17,16 +17,13 @@
package org.apache.poi.hslf.usermodel;
+import org.apache.poi.hslf.model.textproperties.TextPropCollection;
import org.apache.poi.hslf.record.SheetContainer;
-import org.apache.poi.hslf.model.textproperties.TextProp;
+import org.apache.poi.hslf.record.TextHeaderAtom;
import org.apache.poi.sl.usermodel.MasterSheet;
/**
* The superclass of all master sheets - Slide masters, Notes masters, etc.
- *
- * For now it's empty. When we understand more about masters in ppt we will add the common functionality here.
- *
- * @author Yegor Kozlov
*/
public abstract class HSLFMasterSheet extends HSLFSheet implements MasterSheet<HSLFShape,HSLFTextParagraph> {
public HSLFMasterSheet(SheetContainer container, int sheetNo){
@@ -34,10 +31,19 @@ public abstract class HSLFMasterSheet extends HSLFSheet implements MasterSheet<H
}
/**
- * Pickup a style attribute from the master.
- * This is the "workhorse" which returns the default style attrubutes.
+ * Find the master collection for the given txtype/level/name.
+ * This is the "workhorse" which returns the default style attributes.
+ * If {@code name = "*"} return the current collection, otherwise if the name is not found
+ * in the current selection of txtype/level/name, first try lower levels then try parent types,
+ * if it wasn't found there return {@code null}.
+ *
+ * @param txtype the {@link TextHeaderAtom} type
+ * @param level the indent level of the paragraph, if the level is not defined for the found
+ * collection, the highest existing level will be used
+ * @param name the property name,
+ * @param isCharacter if {@code true} use character styles, otherwise use paragraph styles
*/
- public abstract TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) ;
+ public abstract TextPropCollection getPropCollection(int txtype, int level, String name, boolean isCharacter);
/**
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java
index f6cd41f41d..c7535f709a 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideMaster.java
@@ -74,42 +74,50 @@ public final class HSLFSlideMaster extends HSLFMasterSheet {
}
/**
- * Pickup a style attribute from the master.
+ * Find the master collection for the given txtype/level/name.
* This is the "workhorse" which returns the default style attributes.
+ * If {@code name = "*"} return the current collection, otherwise if the name is not found
+ * in the current selection of txtype/level/name, first try lower levels then try parent types,
+ * if it wasn't found there return {@code null}.
+ *
+ * @param txtype the {@link TextHeaderAtom} type
+ * @param level the indent level of the paragraph, if the level is not defined for the found
+ * collection, the highest existing level will be used
+ * @param name the property name,
+ * @param isCharacter if {@code true} use character styles, otherwise use paragraph styles
*/
@Override
- public TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) {
- if (_txmaster.length <= txtype) {
- return null;
- }
- TxMasterStyleAtom t = _txmaster[txtype];
- List<TextPropCollection> styles = isCharacter ? t.getCharacterStyles() : t.getParagraphStyles();
-
- TextProp prop = null;
- for (int i = Math.min(level, styles.size()-1); prop == null && i >= 0; i--) {
- prop = styles.get(i).findByName(name);
+ public TextPropCollection getPropCollection(final int txtype, final int level, final String name, final boolean isCharacter) {
+ if (txtype < _txmaster.length) {
+ final TxMasterStyleAtom t = _txmaster[txtype];
+ final List<TextPropCollection> styles = isCharacter ? t.getCharacterStyles() : t.getParagraphStyles();
+ // TODO: what is the reaction for readOnly=false and styles.isEmpty()?
+ final int minLevel = Math.min(level, styles.size()-1);
+ if ("*".equals(name)) {
+ return styles.get(minLevel);
+ }
+
+ for (int i=minLevel; i >= 0; i--) {
+ final TextPropCollection col = styles.get(i);
+ final TextProp tp = col.findByName(name);
+ if (tp != null) {
+ return col;
+ }
+ }
}
- if (prop != null) {
- return prop;
- }
-
switch (txtype) {
case TextHeaderAtom.CENTRE_BODY_TYPE:
case TextHeaderAtom.HALF_BODY_TYPE:
case TextHeaderAtom.QUARTER_BODY_TYPE:
- txtype = TextHeaderAtom.BODY_TYPE;
- break;
+ return getPropCollection(TextHeaderAtom.BODY_TYPE, level, name, isCharacter);
case TextHeaderAtom.CENTER_TITLE_TYPE:
- txtype = TextHeaderAtom.TITLE_TYPE;
- break;
+ return getPropCollection(TextHeaderAtom.TITLE_TYPE, level, name, isCharacter);
default:
return null;
}
-
- return getStyleAttribute(txtype, level, name, isCharacter);
}
-
+
/**
* Assign SlideShow for this slide master.
*/
@@ -132,7 +140,7 @@ public final class HSLFSlideMaster extends HSLFMasterSheet {
_txmaster[txType] = txrec[i];
}
}
-
+
for (List<HSLFTextParagraph> paras : getTextParagraphs()) {
for (HSLFTextParagraph htp : paras) {
int txType = htp.getRunType();
@@ -148,11 +156,6 @@ public final class HSLFSlideMaster extends HSLFMasterSheet {
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));
- }
}
}
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
index 695500eb01..4e68c63fed 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
@@ -24,12 +24,16 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
import org.apache.poi.common.usermodel.fonts.FontGroup;
import org.apache.poi.common.usermodel.fonts.FontInfo;
import org.apache.poi.hslf.exceptions.HSLFException;
import org.apache.poi.hslf.model.textproperties.BitMaskTextProp;
import org.apache.poi.hslf.model.textproperties.FontAlignmentProp;
+import org.apache.poi.hslf.model.textproperties.HSLFTabStop;
+import org.apache.poi.hslf.model.textproperties.HSLFTabStopPropCollection;
import org.apache.poi.hslf.model.textproperties.IndentProp;
import org.apache.poi.hslf.model.textproperties.ParagraphFlagsTextProp;
import org.apache.poi.hslf.model.textproperties.TextAlignmentProp;
@@ -37,34 +41,15 @@ import org.apache.poi.hslf.model.textproperties.TextPFException9;
import org.apache.poi.hslf.model.textproperties.TextProp;
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
-import org.apache.poi.hslf.record.ColorSchemeAtom;
-import org.apache.poi.hslf.record.EscherTextboxWrapper;
-import org.apache.poi.hslf.record.InteractiveInfo;
-import org.apache.poi.hslf.record.MasterTextPropAtom;
-import org.apache.poi.hslf.record.OutlineTextRefAtom;
-import org.apache.poi.hslf.record.PPDrawing;
-import org.apache.poi.hslf.record.Record;
-import org.apache.poi.hslf.record.RecordContainer;
-import org.apache.poi.hslf.record.RecordTypes;
-import org.apache.poi.hslf.record.RoundTripHFPlaceholder12;
-import org.apache.poi.hslf.record.SlideListWithText;
-import org.apache.poi.hslf.record.SlidePersistAtom;
-import org.apache.poi.hslf.record.StyleTextProp9Atom;
-import org.apache.poi.hslf.record.StyleTextPropAtom;
-import org.apache.poi.hslf.record.TextBytesAtom;
-import org.apache.poi.hslf.record.TextCharsAtom;
-import org.apache.poi.hslf.record.TextHeaderAtom;
-import org.apache.poi.hslf.record.TextRulerAtom;
-import org.apache.poi.hslf.record.TextSpecInfoAtom;
-import org.apache.poi.hslf.record.TxInteractiveInfoAtom;
+import org.apache.poi.hslf.record.*;
import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.AutoNumberingScheme;
-import org.apache.poi.sl.usermodel.MasterSheet;
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.Placeholder;
+import org.apache.poi.sl.usermodel.TabStop;
+import org.apache.poi.sl.usermodel.TabStop.TabStopType;
import org.apache.poi.sl.usermodel.TextParagraph;
-import org.apache.poi.util.Internal;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.StringUtil;
@@ -93,7 +78,6 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
private TextBytesAtom _byteAtom;
private TextCharsAtom _charAtom;
private TextPropCollection _paragraphStyle = new TextPropCollection(1, TextPropType.paragraph);
- private TextPropCollection _masterStyle;
protected TextRulerAtom _ruler;
protected final List<HSLFTextRun> _runs = new ArrayList<>();
@@ -107,6 +91,33 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
private final List<HSLFTextParagraph> parentList;
+ private class HSLFTabStopDecorator implements TabStop {
+ final HSLFTabStop tabStop;
+
+ HSLFTabStopDecorator(final HSLFTabStop tabStop) {
+ this.tabStop = tabStop;
+ }
+
+ public double getPositionInPoints() {
+ return tabStop.getPositionInPoints();
+ }
+
+ public void setPositionInPoints(double position) {
+ tabStop.setPositionInPoints(position);
+ setDirty();
+ }
+
+ public TabStopType getType() {
+ return tabStop.getType();
+ }
+
+ public void setType(TabStopType type) {
+ tabStop.setType(type);
+ setDirty();
+ }
+ }
+
+
/**
* Constructs a Text Run from a Unicode text block.
* Either a {@link TextCharsAtom} or a {@link TextBytesAtom} needs to be provided.
@@ -161,18 +172,6 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
}
/**
- * Setting a master style reference
- *
- * @param paragraphStyle the master style reference
- *
- * @since POI 3.14-Beta1
- */
- @Internal
- /* package */ void setMasterStyleReference(TextPropCollection masterStyle) {
- _masterStyle = masterStyle;
- }
-
- /**
* Supply the Sheet we belong to, which might have an assigned SlideShow
* Also passes it on to our child RichTextRuns
*/
@@ -341,7 +340,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
@Override
public Double getLeftMargin() {
- TextProp tp = getPropVal(_paragraphStyle, _masterStyle, "text.offset");
+ TextProp tp = getPropVal(_paragraphStyle, "text.offset");
return (tp == null) ? null : Units.masterToPoints(tp.getValue());
}
@@ -364,7 +363,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
@Override
public Double getIndent() {
- TextProp tp = getPropVal(_paragraphStyle, _masterStyle, "bullet.offset");
+ TextProp tp = getPropVal(_paragraphStyle, "bullet.offset");
return (tp == null) ? null : Units.masterToPoints(tp.getValue());
}
@@ -388,7 +387,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
if (fontInfo == null) {
fontInfo = HSLFFontInfoPredefined.ARIAL;
}
-
+
return fontInfo.getTypeface();
}
@@ -422,7 +421,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
@Override
public TextAlign getTextAlign() {
- TextProp tp = getPropVal(_paragraphStyle, _masterStyle, "alignment");
+ TextProp tp = getPropVal(_paragraphStyle, "alignment");
if (tp == null) {
return null;
}
@@ -440,7 +439,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
@Override
public FontAlign getFontAlign() {
- TextProp tp = getPropVal(_paragraphStyle, _masterStyle, FontAlignmentProp.NAME);
+ TextProp tp = getPropVal(_paragraphStyle, FontAlignmentProp.NAME);
if (tp == null) {
return null;
}
@@ -606,7 +605,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
* Returns the bullet character
*/
public Character getBulletChar() {
- TextProp tp = getPropVal(_paragraphStyle, _masterStyle, "bullet.char");
+ TextProp tp = getPropVal(_paragraphStyle, "bullet.char");
return (tp == null) ? null : (char)tp.getValue();
}
@@ -637,7 +636,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
* Returns the bullet color
*/
public Color getBulletColor() {
- TextProp tp = getPropVal(_paragraphStyle, _masterStyle, "bullet.color");
+ TextProp tp = getPropVal(_paragraphStyle, "bullet.color");
boolean hasColor = getFlag(ParagraphFlagsTextProp.BULLET_HARDCOLOR_IDX);
if (tp == null || !hasColor) {
// if bullet color is undefined, return color of first run
@@ -661,7 +660,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
*/
public void setBulletFont(String typeface) {
if (typeface == null) {
- setPropVal(_paragraphStyle, _masterStyle, "bullet.font", null);
+ setPropVal(_paragraphStyle, "bullet.font", null);
setFlag(ParagraphFlagsTextProp.BULLET_HARDFONT_IDX, false);
return;
}
@@ -677,7 +676,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
* Returns the bullet font
*/
public String getBulletFont() {
- TextProp tp = getPropVal(_paragraphStyle, _masterStyle, "bullet.font");
+ TextProp tp = getPropVal(_paragraphStyle, "bullet.font");
boolean hasFont = getFlag(ParagraphFlagsTextProp.BULLET_HARDFONT_IDX);
if (tp == null || !hasFont) {
return getDefaultFontFamily();
@@ -723,8 +722,64 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
return null;
}
+
+ @Override
+ public List<? extends TabStop> getTabStops() {
+ final List<HSLFTabStop> tabStops;
+ final TextRulerAtom textRuler;
+ if (getSheet() instanceof HSLFSlideMaster) {
+ final HSLFTabStopPropCollection tpc = getMasterPropVal(_paragraphStyle, HSLFTabStopPropCollection.NAME);
+ if (tpc == null) {
+ return null;
+ }
+ tabStops = tpc.getTabStops();
+ textRuler = null;
+ } else {
+ textRuler = (TextRulerAtom)_headerAtom.getParentRecord().findFirstOfType(RecordTypes.TextRulerAtom.typeID);
+ if (textRuler == null) {
+ return null;
+ }
+ tabStops = textRuler.getTabStops();
+ }
+
+ return tabStops.stream().map((tabStop) -> new HSLFTabStopDecorator(tabStop)).collect(Collectors.toList());
+ }
+
+ @Override
+ public void addTabStops(final double positionInPoints, final TabStopType tabStopType) {
+ final HSLFTabStop ts = new HSLFTabStop(0, tabStopType);
+ ts.setPositionInPoints(positionInPoints);
+
+ if (getSheet() instanceof HSLFSlideMaster) {
+ final Consumer<HSLFTabStopPropCollection> con = (tp) -> tp.addTabStop(ts);
+ setPropValInner(_paragraphStyle, HSLFTabStopPropCollection.NAME, con);
+ } else {
+ final RecordContainer cont = _headerAtom.getParentRecord();
+ TextRulerAtom textRuler = (TextRulerAtom)cont.findFirstOfType(RecordTypes.TextRulerAtom.typeID);
+ if (textRuler == null) {
+ textRuler = TextRulerAtom.getParagraphInstance();
+ cont.appendChildRecord(textRuler);
+ }
+ textRuler.getTabStops().add(ts);
+ }
+ }
+
+ @Override
+ public void clearTabStops() {
+ if (getSheet() instanceof HSLFSlideMaster) {
+ setPropValInner(_paragraphStyle, HSLFTabStopPropCollection.NAME, null);
+ } else {
+ final RecordContainer cont = _headerAtom.getParentRecord();
+ final TextRulerAtom textRuler = (TextRulerAtom)cont.findFirstOfType(RecordTypes.TextRulerAtom.typeID);
+ if (textRuler == null) {
+ return;
+ }
+ textRuler.getTabStops().clear();
+ }
+ }
+
private Double getPctOrPoints(String propName) {
- TextProp tp = getPropVal(_paragraphStyle, _masterStyle, propName);
+ TextProp tp = getPropVal(_paragraphStyle, propName);
if (tp == null) {
return null;
}
@@ -741,7 +796,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
}
private boolean getFlag(int index) {
- BitMaskTextProp tp = (BitMaskTextProp)getPropVal(_paragraphStyle, _masterStyle, ParagraphFlagsTextProp.NAME);
+ BitMaskTextProp tp = getPropVal(_paragraphStyle, ParagraphFlagsTextProp.NAME);
return (tp == null) ? false : tp.getSubValue(index);
}
@@ -759,56 +814,54 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
* The propName can be a comma-separated list, in case multiple equivalent values
* are queried
*/
- protected TextProp getPropVal(TextPropCollection props, TextPropCollection masterProps, String propName) {
+ protected <T extends TextProp> T getPropVal(TextPropCollection props, String propName) {
String propNames[] = propName.split(",");
for (String pn : propNames) {
- TextProp prop = props.findByName(pn);
+ T prop = props.findByName(pn);
if (isValidProp(prop)) {
return prop;
}
}
- return getMasterPropVal(props, masterProps, propName);
+ return getMasterPropVal(props, propName);
}
- private TextProp getMasterPropVal(TextPropCollection props, TextPropCollection masterProps, String propName) {
+ private <T extends TextProp> T getMasterPropVal(final TextPropCollection props, final String propName) {
boolean isChar = props.getTextPropType() == TextPropType.character;
// check if we can delegate to master for the property
if (!isChar) {
- BitMaskTextProp maskProp = (BitMaskTextProp) props.findByName(ParagraphFlagsTextProp.NAME);
+ BitMaskTextProp maskProp = props.findByName(ParagraphFlagsTextProp.NAME);
boolean hardAttribute = (maskProp != null && maskProp.getValue() == 0);
if (hardAttribute) {
return null;
}
}
- String propNames[] = propName.split(",");
- if (masterProps == null) {
- HSLFSheet sheet = getSheet();
- int txtype = getRunType();
- HSLFMasterSheet master = sheet.getMasterSheet();
+ final String propNames[] = propName.split(",");
+ final HSLFSheet sheet = getSheet();
+ final int txtype = getRunType();
+ final HSLFMasterSheet master;
+ if (sheet instanceof HSLFMasterSheet) {
+ master = (HSLFMasterSheet)sheet;
+ } else {
+ master = sheet.getMasterSheet();
if (master == null) {
logger.log(POILogger.WARN, "MasterSheet is not available");
return null;
}
+ }
- for (String pn : propNames) {
- TextProp prop = master.getStyleAttribute(txtype, getIndentLevel(), pn, isChar);
- if (isValidProp(prop)) {
- return prop;
- }
- }
- } else {
- for (String pn : propNames) {
- TextProp prop = masterProps.findByName(pn);
+ for (String pn : propNames) {
+ TextPropCollection masterProps = master.getPropCollection(txtype, getIndentLevel(), pn, isChar);
+ if (masterProps != null) {
+ T prop = masterProps.findByName(pn);
if (isValidProp(prop)) {
return prop;
}
}
}
-
return null;
}
@@ -826,22 +879,33 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
* @param name the name of the TextProp to fetch/add
* @param val the value, null if unset
*/
- protected void setPropVal(TextPropCollection props, TextPropCollection masterProps, String name, Integer val) {
- TextPropCollection pc = props;
- if (getSheet() instanceof MasterSheet && masterProps != null) {
- pc = masterProps;
+ protected void setPropVal(final TextPropCollection props, final String name, final Integer val) {
+ setPropValInner(props, name, val == null ? null : tp -> tp.setValue(val));
+ }
+
+ private void setPropValInner(final TextPropCollection props, final String name, Consumer<? extends TextProp> handler) {
+ final boolean isChar = props.getTextPropType() == TextPropType.character;
+
+ final TextPropCollection pc;
+ if (_sheet instanceof HSLFMasterSheet) {
+ pc = ((HSLFMasterSheet)_sheet).getPropCollection(getRunType(), getIndentLevel(), "*", isChar);
+ if (pc == null) {
+ throw new HSLFException("Master text property collection can't be determined.");
+ }
+ } else {
+ pc = props;
}
- if (val == null) {
+ if (handler == null) {
pc.removeByName(name);
- return;
+ } else {
+ // Fetch / Add the TextProp
+ handler.accept(pc.addWithName(name));
}
-
- // Fetch / Add the TextProp
- TextProp tp = pc.addWithName(name);
- tp.setValue(val);
+ setDirty();
}
+
/**
* Check and add linebreaks to text runs leading other paragraphs
*
@@ -1595,7 +1659,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
* @param val The value to set for the TextProp
*/
public void setParagraphTextPropVal(String propName, Integer val) {
- setPropVal(_paragraphStyle, _masterStyle, propName, val);
+ setPropVal(_paragraphStyle, propName, val);
setDirty();
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java
index c33272e05b..a444a5b2b6 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java
@@ -36,7 +36,6 @@ import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.sl.usermodel.TextRun;
import org.apache.poi.sl.usermodel.TextShape;
-import org.apache.poi.util.Internal;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
@@ -61,8 +60,6 @@ public final class HSLFTextRun implements TextRun {
*/
private TextPropCollection characterStyle = new TextPropCollection(1, TextPropType.character);
- private TextPropCollection masterStyle;
-
/**
* Create a new wrapper around a rich text string
* @param parentParagraph the parent paragraph
@@ -80,19 +77,6 @@ public final class HSLFTextRun implements TextRun {
this.characterStyle.updateTextSize(_runText.length());
}
- /**
- * Setting a master style reference
- *
- * @param characterStyle the master style reference
- *
- * @since POI 3.14-Beta1
- */
- @Internal
- /* package */ void setMasterStyleReference(TextPropCollection masterStyle) {
- this.masterStyle = masterStyle;
- }
-
-
/**
* Supply the SlideShow we belong to
*/
@@ -149,28 +133,34 @@ public final class HSLFTextRun implements TextRun {
}
protected boolean getFlag(int index) {
- if (characterStyle == null) {
- return false;
- }
-
- BitMaskTextProp prop = (BitMaskTextProp)characterStyle.findByName(CharFlagsTextProp.NAME);
+ BitMaskTextProp prop = (characterStyle == null) ? null : characterStyle.findByName(CharFlagsTextProp.NAME);
if (prop == null || !prop.getSubPropMatches()[index]) {
- int txtype = parentParagraph.getRunType();
- HSLFSheet sheet = parentParagraph.getSheet();
- if (sheet != null) {
- HSLFMasterSheet master = sheet.getMasterSheet();
- if (master != null){
- prop = (BitMaskTextProp)master.getStyleAttribute(txtype, parentParagraph.getIndentLevel(), CharFlagsTextProp.NAME, true);
- }
- } else {
- logger.log(POILogger.WARN, "MasterSheet is not available");
- }
+ prop = getMasterProp(CharFlagsTextProp.NAME);
}
return prop == null ? false : prop.getSubValue(index);
}
+ private <T extends TextProp> T getMasterProp(final String name) {
+ final int txtype = parentParagraph.getRunType();
+ final HSLFSheet sheet = parentParagraph.getSheet();
+ if (sheet == null) {
+ logger.log(POILogger.ERROR, "Sheet is not available");
+ return null;
+ }
+
+ final HSLFMasterSheet master = sheet.getMasterSheet();
+ if (master == null) {
+ logger.log(POILogger.WARN, "MasterSheet is not available");
+ return null;
+ }
+
+ final TextPropCollection col = master.getPropCollection(txtype, parentParagraph.getIndentLevel(), name, true);
+ return (col == null) ? null : col.findByName(name);
+ }
+
+
/**
* Set the value of the given flag in the CharFlagsTextProp, adding
* it if required.
@@ -189,8 +179,7 @@ public final class HSLFTextRun implements TextRun {
* @param val The value to set for the TextProp
*/
public void setCharTextPropVal(String propName, Integer val) {
- getTextParagraph().setPropVal(characterStyle, masterStyle, propName, val);
- getTextParagraph().setDirty();
+ getTextParagraph().setPropVal(characterStyle, propName, val);
}
@@ -270,7 +259,7 @@ public final class HSLFTextRun implements TextRun {
* @return the percentage of the font size. If the value is positive, it is superscript, otherwise it is subscript
*/
public int getSuperscript() {
- TextProp tp = getTextParagraph().getPropVal(characterStyle, masterStyle, "superscript");
+ TextProp tp = getTextParagraph().getPropVal(characterStyle, "superscript");
return tp == null ? 0 : tp.getValue();
}
@@ -285,7 +274,7 @@ public final class HSLFTextRun implements TextRun {
@Override
public Double getFontSize() {
- TextProp tp = getTextParagraph().getPropVal(characterStyle, masterStyle, "font.size");
+ TextProp tp = getTextParagraph().getPropVal(characterStyle, "font.size");
return tp == null ? null : (double)tp.getValue();
}
@@ -300,7 +289,7 @@ public final class HSLFTextRun implements TextRun {
* Gets the font index
*/
public int getFontIndex() {
- TextProp tp = getTextParagraph().getPropVal(characterStyle, masterStyle, "font.index");
+ TextProp tp = getTextParagraph().getPropVal(characterStyle, "font.index");
return tp == null ? -1 : tp.getValue();
}
@@ -401,7 +390,7 @@ public final class HSLFTextRun implements TextRun {
break;
}
- TextProp tp = getTextParagraph().getPropVal(characterStyle, masterStyle, propName);
+ TextProp tp = getTextParagraph().getPropVal(characterStyle, propName);
return (tp != null) ? slideShow.getFont(tp.getValue()) : null;
}
@@ -410,7 +399,7 @@ public final class HSLFTextRun implements TextRun {
*/
@Override
public SolidPaint getFontColor() {
- TextProp tp = getTextParagraph().getPropVal(characterStyle, masterStyle, "font.color");
+ TextProp tp = getTextParagraph().getPropVal(characterStyle, "font.color");
if (tp == null) {
return null;
}
diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTitleMaster.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTitleMaster.java
index b8e3948ccc..59b0e3f287 100644
--- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTitleMaster.java
+++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTitleMaster.java
@@ -20,7 +20,7 @@ package org.apache.poi.hslf.usermodel;
import java.util.ArrayList;
import java.util.List;
-import org.apache.poi.hslf.model.textproperties.TextProp;
+import org.apache.poi.hslf.model.textproperties.TextPropCollection;
import org.apache.poi.hslf.record.SlideAtom;
/**
@@ -55,11 +55,11 @@ public final class HSLFTitleMaster extends HSLFMasterSheet {
* Delegate the call to the underlying slide master.
*/
@Override
- public TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) {
- HSLFMasterSheet master = getMasterSheet();
- return (master == null) ? null : master.getStyleAttribute(txtype, level, name, isCharacter);
+ public TextPropCollection getPropCollection(final int txtype, final int level, final String name, final boolean isCharacter) {
+ final HSLFMasterSheet master = getMasterSheet();
+ return (master == null) ? null : master.getPropCollection(txtype, level, name, isCharacter);
}
-
+
/**
* Returns the slide master for this title master.
*/
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlideMaster.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlideMaster.java
index 80772d3a1c..db56e0e775 100644
--- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlideMaster.java
+++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlideMaster.java
@@ -17,6 +17,10 @@
package org.apache.poi.hslf.model;
+import static org.apache.poi.hslf.record.TextHeaderAtom.BODY_TYPE;
+import static org.apache.poi.hslf.record.TextHeaderAtom.CENTER_TITLE_TYPE;
+import static org.apache.poi.hslf.record.TextHeaderAtom.CENTRE_BODY_TYPE;
+import static org.apache.poi.hslf.record.TextHeaderAtom.TITLE_TYPE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -27,6 +31,7 @@ import java.util.List;
import org.apache.poi.POIDataSamples;
import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;
+import org.apache.poi.hslf.model.textproperties.TextProp;
import org.apache.poi.hslf.record.Environment;
import org.apache.poi.hslf.record.TextHeaderAtom;
import org.apache.poi.hslf.usermodel.HSLFMasterSheet;
@@ -51,62 +56,70 @@ public final class TestSlideMaster {
*/
@Test
public void testSlideMaster() throws IOException {
- HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("slide_master.ppt"));
+ final HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("slide_master.ppt"));
- Environment env = ppt.getDocumentRecord().getEnvironment();
+ final Environment env = ppt.getDocumentRecord().getEnvironment();
- List<HSLFSlideMaster> master = ppt.getSlideMasters();
- assertEquals(2, master.size());
+ assertEquals(2, ppt.getSlideMasters().size());
//character attributes
- assertEquals(40, master.get(0).getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "font.size", true).getValue());
- assertEquals(48, master.get(1).getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "font.size", true).getValue());
+ assertEquals(40, getMasterVal(ppt, 0, TITLE_TYPE, "font.size", true));
+ assertEquals(48, getMasterVal(ppt, 1, TITLE_TYPE, "font.size", true));
- int font1 = master.get(0).getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "font.index", true).getValue();
- int font2 = master.get(1).getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "font.index", true).getValue();
+ int font1 = getMasterVal(ppt, 0, TITLE_TYPE, "font.index", true);
+ int font2 = getMasterVal(ppt, 1, TITLE_TYPE, "font.index", true);
assertEquals("Arial", env.getFontCollection().getFontInfo(font1).getTypeface());
assertEquals("Georgia", env.getFontCollection().getFontInfo(font2).getTypeface());
- CharFlagsTextProp prop1 = (CharFlagsTextProp)master.get(0).getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "char_flags", true);
+ CharFlagsTextProp prop1 = getMasterProp(ppt, 0, TITLE_TYPE, "char_flags", true);
assertEquals(false, prop1.getSubValue(CharFlagsTextProp.BOLD_IDX));
assertEquals(false, prop1.getSubValue(CharFlagsTextProp.ITALIC_IDX));
assertEquals(true, prop1.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));
- CharFlagsTextProp prop2 = (CharFlagsTextProp)master.get(1).getStyleAttribute(TextHeaderAtom.TITLE_TYPE, 0, "char_flags", true);
+ CharFlagsTextProp prop2 = getMasterProp(ppt, 1, TITLE_TYPE, "char_flags", true);
assertEquals(false, prop2.getSubValue(CharFlagsTextProp.BOLD_IDX));
assertEquals(true, prop2.getSubValue(CharFlagsTextProp.ITALIC_IDX));
assertEquals(false, prop2.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));
//now paragraph attributes
- assertEquals(0x266B, master.get(0).getStyleAttribute(TextHeaderAtom.BODY_TYPE, 0, "bullet.char", false).getValue());
- assertEquals(0x2022, master.get(1).getStyleAttribute(TextHeaderAtom.BODY_TYPE, 0, "bullet.char", false).getValue());
+ assertEquals(0x266B, getMasterVal(ppt, 0, BODY_TYPE, "bullet.char", false));
+ assertEquals(0x2022, getMasterVal(ppt, 1, BODY_TYPE, "bullet.char", false));
- int b1 = master.get(0).getStyleAttribute(TextHeaderAtom.BODY_TYPE, 0, "bullet.font", false).getValue();
- int b2 = master.get(1).getStyleAttribute(TextHeaderAtom.BODY_TYPE, 0, "bullet.font", false).getValue();
+ int b1 = getMasterVal(ppt, 0, BODY_TYPE, "bullet.font", false);
+ int b2 = getMasterVal(ppt, 1, BODY_TYPE, "bullet.font", false);
assertEquals("Arial", env.getFontCollection().getFontInfo(b1).getTypeface());
assertEquals("Georgia", env.getFontCollection().getFontInfo(b2).getTypeface());
ppt.close();
}
+ @SuppressWarnings("unchecked")
+ private static <T extends TextProp> T getMasterProp(HSLFSlideShow ppt, int masterIdx, int txtype, String propName, boolean isCharacter) {
+ return (T)ppt.getSlideMasters().get(masterIdx).getPropCollection(txtype, 0, propName, isCharacter).findByName(propName);
+ }
+
+ private static int getMasterVal(HSLFSlideShow ppt, int masterIdx, int txtype, String propName, boolean isCharacter) {
+ return getMasterProp(ppt, masterIdx, txtype, propName, isCharacter).getValue();
+ }
+
+
/**
* Test we can read default text attributes for a title master sheet
*/
@Test
public void testTitleMasterTextAttributes() throws IOException {
HSLFSlideShow ppt = new HSLFSlideShow(_slTests.openResourceAsStream("slide_master.ppt"));
- List<HSLFTitleMaster> master = ppt.getTitleMasters();
- assertEquals(1, master.size());
+ assertEquals(1, ppt.getTitleMasters().size());
- assertEquals(32, master.get(0).getStyleAttribute(TextHeaderAtom.CENTER_TITLE_TYPE, 0, "font.size", true).getValue());
- CharFlagsTextProp prop1 = (CharFlagsTextProp)master.get(0).getStyleAttribute(TextHeaderAtom.CENTER_TITLE_TYPE, 0, "char_flags", true);
- assertEquals(true, prop1.getSubValue(CharFlagsTextProp.BOLD_IDX));
+ assertEquals(40, getMasterVal(ppt, 0, CENTER_TITLE_TYPE, "font.size", true));
+ CharFlagsTextProp prop1 = getMasterProp(ppt, 0, CENTER_TITLE_TYPE, "char_flags", true);
+ assertEquals(false, prop1.getSubValue(CharFlagsTextProp.BOLD_IDX));
assertEquals(false, prop1.getSubValue(CharFlagsTextProp.ITALIC_IDX));
assertEquals(true, prop1.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));
- assertEquals(20, master.get(0).getStyleAttribute(TextHeaderAtom.CENTRE_BODY_TYPE, 0, "font.size", true).getValue());
- CharFlagsTextProp prop2 = (CharFlagsTextProp)master.get(0).getStyleAttribute(TextHeaderAtom.CENTRE_BODY_TYPE, 0, "char_flags", true);
- assertEquals(true, prop2.getSubValue(CharFlagsTextProp.BOLD_IDX));
+ assertEquals(32, getMasterVal(ppt, 0, CENTRE_BODY_TYPE, "font.size", true));
+ CharFlagsTextProp prop2 = getMasterProp(ppt, 0, CENTRE_BODY_TYPE, "char_flags", true);
+ assertEquals(false, prop2.getSubValue(CharFlagsTextProp.BOLD_IDX));
assertEquals(false, prop2.getSubValue(CharFlagsTextProp.ITALIC_IDX));
assertEquals(false, prop2.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTextRulerAtom.java b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTextRulerAtom.java
index 475918cd1c..eee4ffe88c 100644
--- a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTextRulerAtom.java
+++ b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTextRulerAtom.java
@@ -18,17 +18,17 @@
package org.apache.poi.hslf.record;
import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import java.io.ByteArrayOutputStream;
+import java.util.List;
-import junit.framework.TestCase;
+import org.apache.poi.hslf.model.textproperties.HSLFTabStop;
+import org.junit.Test;
-/**
- * Tests TextRulerAtom
- *
- * @author Yegor Kozlov
- */
-public final class TestTextRulerAtom extends TestCase {
+public final class TestTextRulerAtom {
//from a real file
private final byte[] data_1 = new byte[] {
@@ -40,25 +40,27 @@ public final class TestTextRulerAtom extends TestCase {
private final byte[] data_2 = new byte[] {
0x00, 0x00, (byte)0xA6, 0x0F, 0x0A, 0x00, 0x00, 0x00,
- 0x10, 0x03, 0x00, 0x00, (byte)0xF9, 0x00, 0x41, 0x01, 0x41, 0x01
+ 0x08, 0x03, 0x00, 0x00, (byte)0xF9, 0x00, 0x41, 0x01, 0x41, 0x01
};
+ @Test
public void testReadRuler() {
TextRulerAtom ruler = new TextRulerAtom(data_1, 0, data_1.length);
assertEquals(ruler.getNumberOfLevels(), 0);
assertEquals(ruler.getDefaultTabSize(), 0);
- int[] tabStops = ruler.getTabStops();
- assertNull(tabStops);
+ List<HSLFTabStop> tabStops = ruler.getTabStops();
+ assertNotNull(tabStops);
- int[] textOffsets = ruler.getTextOffsets();
- assertArrayEquals(new int[]{226, 451, 903, 1129, 1526}, textOffsets);
+ Integer[] textOffsets = ruler.getTextOffsets();
+ assertArrayEquals(new Integer[]{226, 451, 903, 1129, 1526}, textOffsets);
- int[] bulletOffsets = ruler.getBulletOffsets();
- assertArrayEquals(new int[]{117, 345, 794, 1016, 1526}, bulletOffsets);
+ Integer[] bulletOffsets = ruler.getBulletOffsets();
+ assertArrayEquals(new Integer[]{117, 345, 794, 1016, 1526}, bulletOffsets);
}
+ @Test
public void testWriteRuler() throws Exception {
TextRulerAtom ruler = new TextRulerAtom(data_1, 0, data_1.length);
ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -68,6 +70,7 @@ public final class TestTextRulerAtom extends TestCase {
assertArrayEquals(result, data_1);
}
+ @Test
public void testRead2() throws Exception {
TextRulerAtom ruler = TextRulerAtom.getParagraphInstance();
ruler.setParagraphIndent((short)249, (short)321);
@@ -75,6 +78,6 @@ public final class TestTextRulerAtom extends TestCase {
ruler.writeOut(out);
byte[] result = out.toByteArray();
- assertArrayEquals(result, data_2);
+ assertArrayEquals(data_2, result);
}
}
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestHSLFSlideShow.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestHSLFSlideShow.java
index 7f5385e352..7c2f7fe473 100644
--- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestHSLFSlideShow.java
+++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestHSLFSlideShow.java
@@ -17,8 +17,14 @@
package org.apache.poi.hslf.usermodel;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import org.apache.poi.sl.usermodel.BaseTestSlideShow;
+import org.apache.poi.sl.usermodel.SlideShow;
import org.junit.Test;
public class TestHSLFSlideShow extends BaseTestSlideShow {
@@ -32,4 +38,25 @@ public class TestHSLFSlideShow extends BaseTestSlideShow {
public void dummy() {
assertNotNull(createSlideShow());
}
+
+ public SlideShow<?, ?> reopen(SlideShow<?, ?> show) {
+ return reopen((HSLFSlideShow)show);
+ }
+
+ public static HSLFSlideShow reopen(HSLFSlideShow show) {
+ try {
+ BufAccessBAOS bos = new BufAccessBAOS();
+ show.write(bos);
+ return new HSLFSlideShow(new ByteArrayInputStream(bos.getBuf()));
+ } catch (IOException e) {
+ fail(e.getMessage());
+ return null;
+ }
+ }
+
+ private static class BufAccessBAOS extends ByteArrayOutputStream {
+ public byte[] getBuf() {
+ return buf;
+ }
+ }
}