--- src/scratchpad/src/org/apache/poi/hwpf/usermodel/ListEntry.java (revision 1005818) +++ src/scratchpad/src/org/apache/poi/hwpf/usermodel/ListEntry.java (working copy) @@ -22,6 +22,8 @@ import org.apache.poi.hwpf.model.ListLevel; import org.apache.poi.hwpf.model.ListTables; import org.apache.poi.hwpf.model.PAPX; +import org.apache.poi.hwpf.sprm.CharacterSprmUncompressor; +import org.apache.poi.hwpf.sprm.ParagraphSprmUncompressor; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; @@ -32,15 +34,36 @@ ListLevel _level; ListFormatOverrideLevel _overrideLevel; - + + CharacterProperties _numberProps; + ListEntry(PAPX papx, Range parent, ListTables tables) { super(papx, parent); - + if(tables != null) { ListFormatOverride override = tables.getOverride(_props.getIlfo()); _overrideLevel = override.getOverrideLevel(_props.getIlvl()); - _level = tables.getLevel(override.getLsid(), _props.getIlvl()); + if (_overrideLevel != null && _overrideLevel.isFormatting()) + _level = _overrideLevel.getLevel(); + else + _level = tables.getLevel(override.getLsid(), _props.getIlvl()); + + // first process SPRMs from the level, then from papx + _props = ParagraphSprmUncompressor.uncompressPAP(_doc.getStyleSheet().getParagraphStyle(papx.getIstd()), _level.getLevelProperties(), 0); + _props = ParagraphSprmUncompressor.uncompressPAP(_props, papx.getGrpprl(), 2); + + // FIXME Base character properties are taken from the first CharacterRun in the paragraph. This is not fully correct, but + // I don't know a better way. If whole paragraph is formatted some way, the number gets formatted as well, but the SPRM + // is not stored in _level.getNumberProperties(), but is somehow taken from the paragraph. If we base it on StyleSheet, + // we do not take this formatting. But if only the first word is formatted (i.e. the first CharacterRun), we format the number + // incorrectly. + CharacterProperties baseCharacterProperties; + if (numCharacterRuns() > 0) + baseCharacterProperties = getCharacterRun(0).cloneProperties(); + else + baseCharacterProperties = _doc.getStyleSheet().getCharacterStyle(getStyleIndex()); + _numberProps = CharacterSprmUncompressor.uncompressCHP(baseCharacterProperties, _level.getNumberProperties(), 0); } else { log.log(POILogger.WARN, "No ListTables found for ListEntry - document probably partly corrupt, and you may experience problems"); } @@ -50,4 +73,9 @@ { return TYPE_LISTENTRY; } + + public CharacterProperties getNumberProperties() { + return _numberProps; + } + } --- src/scratchpad/src/org/apache/poi/hwpf/model/ListLevel.java (revision 1005818) +++ src/scratchpad/src/org/apache/poi/hwpf/model/ListLevel.java (working copy) @@ -91,7 +91,7 @@ System.arraycopy(buf, offset, _rgbxchNums, 0, RGBXCH_NUMS_SIZE); offset += RGBXCH_NUMS_SIZE; - _ixchFollow = buf[offset++]; + _ixchFollow = buf[offset++]; _dxaSpace = LittleEndian.getInt(buf, offset); offset += LittleEndian.INT_SIZE; _dxaIndent = LittleEndian.getInt(buf, offset); @@ -129,6 +129,71 @@ return _iStartAt; } + /** + * From specification: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
nfc valueNumbering scheme
0Arabic (1, 2, 3)
1Uppercase Roman numeral (I, II, III)
2Lowercase Roman numeral (i, ii, iii)
3Uppercase letter (A, B, C)
4Lowercase letter (a, b, c)
5Ordinal number (1st, 2nd, 3rd)
6Cardinal text number (One, Two Three)
7Ordinal text number (First, Second, Third)
10Kanji numbering without the digit character (dbnum1).
11Kanji numbering with the digit character (dbnum2).
1246 phonetic Katakana characters in "aiueo" order (aiueo).
1346 phonetic katakana characters in "iroha" order (iroha).
14Double Byte character
15Single Byte character
16Kanji numbering 3 (dbnum3).
17Kanji numbering 4 (dbnum4).
18Circle numbering (circlenum).
19Double-byte Arabic numbering
2046 phonetic double-byte Katakana characters (*aiueo*dbchar).
2146 phonetic double-byte katakana characters (*iroha*dbchar).
22Arabic with leading zero (01, 02, 03, ..., 10, 11)
23Bullet (no number at all)
24Korean numbering 2 (ganada).
25Korean numbering 1 (chosung).
26Chinese numbering 1 (gb1).
27Chinese numbering 2 (gb2).
28Chinese numbering 3 (gb3).
29Chinese numbering 4 (gb4).
30Chinese Zodiac numbering 1
31Chinese Zodiac numbering 2
32Chinese Zodiac numbering 3
33Taiwanese double-byte numbering 1
34Taiwanese double-byte numbering 2
35Taiwanese double-byte numbering 3
36Taiwanese double-byte numbering 4
37Chinese double-byte numbering 1
38Chinese double-byte numbering 2
39Chinese double-byte numbering 3
40Chinese double-byte numbering 4
41Korean double-byte numbering 1
42Korean double-byte numbering 2
43Korean double-byte numbering 3
44Korean double-byte numbering 4
45Hebrew non-standard decimal
46Arabic Alif Ba Tah
47Hebrew Biblical standard
48Arabic Abjad style
49Hindi vowels
50Hindi consonants
51Hindi numbers
52Hindi descriptive (cardinals)
53Thai letters
54Thai numbers
55Thai descriptive (cardinals
56Vietnamese descriptive (cardinals)
57Page Number format - # -
58Lower case Russian alphabet
59Upper case Russian alphabet
+ */ public int getNumberFormat() { return _nfc; @@ -162,8 +227,11 @@ public void setNumberProperties(byte[] grpprl) { _grpprlChpx = grpprl; - } + + public byte[] getNumberProperties() { + return _grpprlChpx; + } public void setLevelProperties(byte[] grpprl) {