improved handling of StyleTextPropAtom bit masks, added more read-write roundtrip tests

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@691180 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yegor Kozlov 2008-09-02 09:59:53 +00:00
parent d3f7cc38ef
commit 7c1b5604d9
4 changed files with 677 additions and 681 deletions

View File

@ -35,19 +35,19 @@ public class CharFlagsTextProp extends BitMaskTextProp {
public static String NAME = "char_flags"; public static String NAME = "char_flags";
public CharFlagsTextProp() { public CharFlagsTextProp() {
super(2,0xffff, NAME, new String[] { super(2,0xffff, NAME, new String[] {
"bold", // 0x0001 "bold", // 0x0001 A bit that specifies whether the characters are bold.
"italic", // 0x0002 "italic", // 0x0002 A bit that specifies whether the characters are italicized.
"underline", // 0x0004 "underline", // 0x0004 A bit that specifies whether the characters are underlined.
"char_unknown_1",// 0x0008 "char_unknown_1", // 0x0008 Undefined and MUST be ignored.
"shadow", // 0x0010 "shadow", // 0x0010 A bit that specifies whether the characters have a shadow effect.
"char_unknown_2",// 0x0020 "fehint", // 0x0020 A bit that specifies whether characters originated from double-byte input.
"char_unknown_3",// 0x0040 "char_unknown_2", // 0x0040 Undefined and MUST be ignored.
"char_unknown_4",// 0x0080 "kumi", // 0x0080 A bit that specifies whether Kumimoji are used for vertical text.
"strikethrough", // 0x0100 "strikethrough", // 0x0100 Undefined and MUST be ignored.
"relief", // 0x0200 "emboss", // 0x0200 A bit that specifies whether the characters are embossed.
"reset_numbering", // 0x0400 "char_unknown_3", // 0x0400 Undefined and MUST be ignored.
"enable_numbering_1", // 0x0800 "char_unknown_4", // 0x0800 Undefined and MUST be ignored.
"enable_numbering_2", // 0x1000 "char_unknown_5", // 0x1000 Undefined and MUST be ignored.
} }
); );
} }

View File

@ -34,6 +34,7 @@ public class TextPropCollection {
private int charactersCovered; private int charactersCovered;
private short reservedField; private short reservedField;
private LinkedList textPropList; private LinkedList textPropList;
private int maskSpecial = 0;
/** Fetch the number of characters this styling applies to */ /** Fetch the number of characters this styling applies to */
public int getCharactersCovered() { return charactersCovered; } public int getCharactersCovered() { return charactersCovered; }
@ -94,21 +95,28 @@ public class TextPropCollection {
// If we do, decode that, save it, and shuffle on // If we do, decode that, save it, and shuffle on
for(int i=0; i<potentialProperties.length; i++) { for(int i=0; i<potentialProperties.length; i++) {
// Check there's still data left to read // Check there's still data left to read
if(dataOffset+bytesPassed >= data.length) {
// Out of data, can't be any more properties to go
return bytesPassed;
}
// Check if this property is found in the mask // Check if this property is found in the mask
if((containsField & potentialProperties[i].getMask()) != 0) { if((containsField & potentialProperties[i].getMask()) != 0) {
if(dataOffset+bytesPassed >= data.length) {
// Out of data, can't be any more properties to go
// remember the mask and return
maskSpecial |= potentialProperties[i].getMask();
return bytesPassed;
}
// Bingo, data contains this property // Bingo, data contains this property
TextProp prop = (TextProp)potentialProperties[i].clone(); TextProp prop = (TextProp)potentialProperties[i].clone();
int val = 0; int val = 0;
if(prop.getSize() == 2) { if(prop.getSize() == 2) {
val = LittleEndian.getShort(data,dataOffset+bytesPassed); val = LittleEndian.getShort(data,dataOffset+bytesPassed);
} else { } else if(prop.getSize() == 4){
val = LittleEndian.getInt(data,dataOffset+bytesPassed); val = LittleEndian.getInt(data,dataOffset+bytesPassed);
} } else if (prop.getSize() == 0){
//remember "special" bits.
maskSpecial |= potentialProperties[i].getMask();
continue;
}
prop.setValue(val); prop.setValue(val);
bytesPassed += prop.getSize(); bytesPassed += prop.getSize();
textPropList.add(prop); textPropList.add(prop);
@ -161,15 +169,18 @@ public class TextPropCollection {
} }
// Then the mask field // Then the mask field
int mask = 0; int mask = maskSpecial;
for(int i=0; i<textPropList.size(); i++) { for(int i=0; i<textPropList.size(); i++) {
TextProp textProp = (TextProp)textPropList.get(i); TextProp textProp = (TextProp)textPropList.get(i);
//sometimes header indicates that the bitmask is present but its value is 0 //sometimes header indicates that the bitmask is present but its value is 0
if (textProp instanceof BitMaskTextProp)
mask |= (textProp.getWriteMask() == 0 ? 1 : textProp.getWriteMask()); if (textProp instanceof BitMaskTextProp) {
else if(mask == 0) mask |= textProp.getWriteMask();
}
else {
mask |= textProp.getWriteMask(); mask |= textProp.getWriteMask();
} }
}
StyleTextPropAtom.writeLittleEndian(mask,o); StyleTextPropAtom.writeLittleEndian(mask,o);
// Then the contents of all the properties // Then the contents of all the properties
@ -178,7 +189,7 @@ public class TextPropCollection {
int val = textProp.getValue(); int val = textProp.getValue();
if(textProp.getSize() == 2) { if(textProp.getSize() == 2) {
StyleTextPropAtom.writeLittleEndian((short)val,o); StyleTextPropAtom.writeLittleEndian((short)val,o);
} else { } else if(textProp.getSize() == 4){
StyleTextPropAtom.writeLittleEndian(val,o); StyleTextPropAtom.writeLittleEndian(val,o);
} }
} }

View File

@ -124,47 +124,54 @@ public class StyleTextPropAtom extends RecordAtom
/** All the different kinds of paragraph properties we might handle */ /** All the different kinds of paragraph properties we might handle */
public static TextProp[] paragraphTextPropTypes = new TextProp[] { public static TextProp[] paragraphTextPropTypes = new TextProp[] {
new ParagraphFlagsTextProp(), new TextProp(0, 0x1, "hasBullet"),
new TextProp(0, 0x2, "hasBulletFont"),
new TextProp(0, 0x4, "hasBulletColor"),
new TextProp(0, 0x8, "hasBulletSize"),
new ParagraphFlagsTextProp(),
new TextProp(2, 0x80, "bullet.char"), new TextProp(2, 0x80, "bullet.char"),
new TextProp(2, 0x10, "bullet.font"), new TextProp(2, 0x10, "bullet.font"),
new TextProp(2, 0x40, "bullet.size"), new TextProp(2, 0x40, "bullet.size"),
new TextProp(4, 0x20, "bullet.color"), new TextProp(4, 0x20, "bullet.color"),
new AlignmentTextProp(), new AlignmentTextProp(),
new TextProp(2, 0x100, "text.offset"), new TextProp(2, 0x100, "text.offset"),
new TextProp(2, 0x200, "para_unknown_2"),
new TextProp(2, 0x400, "bullet.offset"), new TextProp(2, 0x400, "bullet.offset"),
new TextProp(2, 0x1000, "linespacing"), new TextProp(2, 0x1000, "linespacing"),
new TextProp(2, 0x2000, "spacebefore"), new TextProp(2, 0x2000, "spacebefore"),
new TextProp(2, 0x4000, "spaceafter"), new TextProp(2, 0x4000, "spaceafter"),
new TextProp(2, 0x8000, "para_unknown_4"), new TextProp(2, 0x8000, "defaultTabSize"),
new TextProp(2, 0x10000, "para_unknown_5"), new TextProp(2, 0x100000, "tabStops"),
new TextProp(2, 0xA0000, "para_unknown_6"), new TextProp(2, 0x10000, "fontAlign"),
new TextProp(2, 0x200000, "para_unknown_7") new TextProp(2, 0xA0000, "wrapFlags"),
new TextProp(2, 0x200000, "textDirection")
}; };
/** All the different kinds of character properties we might handle */ /** All the different kinds of character properties we might handle */
public static TextProp[] characterTextPropTypes = new TextProp[] { public static TextProp[] characterTextPropTypes = new TextProp[] {
new CharFlagsTextProp(), new TextProp(0, 0x1, "bold"),
new TextProp(0, 0x2, "italic"),
new TextProp(0, 0x4, "underline"),
new TextProp(0, 0x8, "unused1"),
new TextProp(0, 0x10, "shadow"),
new TextProp(0, 0x20, "fehint"),
new TextProp(0, 0x40, "unused2"),
new TextProp(0, 0x80, "kumi"),
new TextProp(0, 0x100, "unused3"),
new TextProp(0, 0x200, "emboss"),
new CharFlagsTextProp(),
new TextProp(2, 0x10000, "font.index"), new TextProp(2, 0x10000, "font.index"),
new TextProp(2, 0x200000, "asian_or_complex"), new TextProp(0, 0x100000, "pp10ext"),
new TextProp(2, 0x400000, "char_unknown_2"), new TextProp(2, 0x200000, "asian.font.index"),
new TextProp(2, 0x800000, "symbol"), new TextProp(2, 0x400000, "ansi.font.index"),
new TextProp(2, 0x800000, "symbol.font.index"),
new TextProp(2, 0x20000, "font.size"), new TextProp(2, 0x20000, "font.size"),
new TextProp(4, 0x40000, "font.color"), new TextProp(4, 0x40000, "font.color"),
new TextProp(2, 0x80000, "superscript"), new TextProp(2, 0x80000, "superscript"),
new TextProp(2, 0x100000, "char_unknown_1"),
new TextProp(2, 0x1000000, "char_unknown_3"), };
new TextProp(2, 0x2000000, "char_unknown_4"),
new TextProp(2, 0x4000000, "char_unknown_5"),
new TextProp(2, 0x8000000, "char_unknown_6"),
new TextProp(2, 0x10000000, "char_unknown_7"),
new TextProp(2, 0x20000000, "char_unknown_8"),
new TextProp(2, 0x40000000, "char_unknown_9"),
new TextProp(2, 0x80000000, "char_unknown_10"),
};
/* *************** record code follows ********************** */ /* *************** record code follows ********************** */
/** /**
* For the Text Style Properties (StyleTextProp) Atom * For the Text Style Properties (StyleTextProp) Atom
*/ */
public StyleTextPropAtom(byte[] source, int start, int len) { public StyleTextPropAtom(byte[] source, int start, int len) {
@ -192,7 +199,7 @@ public class StyleTextPropAtom extends RecordAtom
} }
/** /**
* A new set of text style properties for some text without any. * A new set of text style properties for some text without any.
*/ */
public StyleTextPropAtom(int parentTextSize) { public StyleTextPropAtom(int parentTextSize) {
@ -209,11 +216,11 @@ public class StyleTextPropAtom extends RecordAtom
paragraphStyles = new LinkedList(); paragraphStyles = new LinkedList();
charStyles = new LinkedList(); charStyles = new LinkedList();
TextPropCollection defaultParagraphTextProps = TextPropCollection defaultParagraphTextProps =
new TextPropCollection(parentTextSize, (short)0); new TextPropCollection(parentTextSize, (short)0);
paragraphStyles.add(defaultParagraphTextProps); paragraphStyles.add(defaultParagraphTextProps);
TextPropCollection defaultCharacterTextProps = TextPropCollection defaultCharacterTextProps =
new TextPropCollection(parentTextSize); new TextPropCollection(parentTextSize);
charStyles.add(defaultCharacterTextProps); charStyles.add(defaultCharacterTextProps);
@ -269,8 +276,7 @@ public class StyleTextPropAtom extends RecordAtom
textHandled += textLen; textHandled += textLen;
pos += 4; pos += 4;
// Fetch the 2 byte value that is safe to ignore as 0 short indent = LittleEndian.getShort(rawContents,pos);
short paraIgn = LittleEndian.getShort(rawContents,pos);
pos += 2; pos += 2;
// Grab the 4 byte value that tells us what properties follow // Grab the 4 byte value that tells us what properties follow
@ -278,7 +284,7 @@ public class StyleTextPropAtom extends RecordAtom
pos += 4; pos += 4;
// Now make sense of those properties // Now make sense of those properties
TextPropCollection thisCollection = new TextPropCollection(textLen, paraIgn); TextPropCollection thisCollection = new TextPropCollection(textLen, indent);
int plSize = thisCollection.buildTextPropList( int plSize = thisCollection.buildTextPropList(
paraFlags, paragraphTextPropTypes, rawContents, pos); paraFlags, paragraphTextPropTypes, rawContents, pos);
pos += plSize; pos += plSize;