001: /* ====================================================================
002: Licensed to the Apache Software Foundation (ASF) under one or more
003: contributor license agreements. See the NOTICE file distributed with
004: this work for additional information regarding copyright ownership.
005: The ASF licenses this file to You under the Apache License, Version 2.0
006: (the "License"); you may not use this file except in compliance with
007: the License. You may obtain a copy of the License at
008:
009: http://www.apache.org/licenses/LICENSE-2.0
010:
011: Unless required by applicable law or agreed to in writing, software
012: distributed under the License is distributed on an "AS IS" BASIS,
013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: See the License for the specific language governing permissions and
015: limitations under the License.
016: ==================================================================== */
017:
018: package org.apache.poi.hdf.model.hdftypes;
019:
020: import java.util.*;
021:
022: import org.apache.poi.hdf.extractor.*;
023:
024: /**
025: * Comment me
026: *
027: * @author Ryan Ackley
028: */
029:
030: public class ListTables implements HDFType {
031:
032: LFO[] _pllfo;
033: Hashtable _lists = new Hashtable();
034:
035: public ListTables(byte[] plcflst, byte[] plflfo) {
036: initLST(plcflst);
037: initLFO(plflfo);
038: }
039:
040: public LVL getLevel(int list, int level) {
041:
042: LFO override = _pllfo[list - 1];
043:
044: for (int x = 0; x < override._clfolvl; x++) {
045: if (override._levels[x]._ilvl == level) {
046: LFOLVL lfolvl = override._levels[x];
047: if (lfolvl._fFormatting) {
048: LST lst = (LST) _lists.get(new Integer(
049: override._lsid));
050: LVL lvl = lfolvl._override;
051: lvl._istd = Utils.convertBytesToShort(lst._rgistd,
052: level * 2);
053: return lvl;
054: } else if (lfolvl._fStartAt) {
055: LST lst = (LST) _lists.get(new Integer(
056: override._lsid));
057: LVL lvl = lst._levels[level];
058: LVL newLvl = (LVL) lvl.clone();
059: newLvl._istd = Utils.convertBytesToShort(
060: lst._rgistd, level * 2);
061: newLvl._iStartAt = lfolvl._iStartAt;
062: return newLvl;
063: }
064: }
065: }
066:
067: LST lst = (LST) _lists.get(new Integer(override._lsid));
068: LVL lvl = lst._levels[level];
069: lvl._istd = Utils.convertBytesToShort(lst._rgistd, level * 2);
070: return lvl;
071:
072: }
073:
074: private void initLST(byte[] plcflst) {
075: short length = Utils.convertBytesToShort(plcflst, 0);
076: int nextLevelOffset = 0;
077: //LST[] lstArray = new LST[length];
078: for (int x = 0; x < length; x++) {
079: LST lst = new LST();
080: lst._lsid = Utils.convertBytesToInt(plcflst, 2 + (x * 28));
081: lst._tplc = Utils.convertBytesToInt(plcflst,
082: 2 + 4 + (x * 28));
083: System.arraycopy(plcflst, 2 + 8 + (x * 28), lst._rgistd, 0,
084: 18);
085: byte code = plcflst[2 + 26 + (x * 28)];
086: lst._fSimpleList = StyleSheet.getFlag(code & 0x01);
087: //lstArray[x] = lst;
088: _lists.put(new Integer(lst._lsid), lst);
089:
090: if (lst._fSimpleList) {
091: lst._levels = new LVL[1];
092: } else {
093: lst._levels = new LVL[9];
094: }
095:
096: for (int y = 0; y < lst._levels.length; y++) {
097: int offset = 2 + (length * 28) + nextLevelOffset;
098: lst._levels[y] = new LVL();
099: nextLevelOffset += createLVL(plcflst, offset,
100: lst._levels[y]);
101: }
102: }
103:
104: }
105:
106: private void initLFO(byte[] plflfo) {
107: int lfoSize = Utils.convertBytesToInt(plflfo, 0);
108: _pllfo = new LFO[lfoSize];
109: for (int x = 0; x < lfoSize; x++) {
110: LFO nextLFO = new LFO();
111: nextLFO._lsid = Utils.convertBytesToInt(plflfo,
112: 4 + (x * 16));
113: nextLFO._clfolvl = plflfo[4 + 12 + (x * 16)];
114: nextLFO._levels = new LFOLVL[nextLFO._clfolvl];
115: _pllfo[x] = nextLFO;
116: }
117:
118: int lfolvlOffset = (lfoSize * 16) + 4;
119: int lvlOffset = 0;
120: int lfolvlNum = 0;
121: for (int x = 0; x < lfoSize; x++) {
122: if (_pllfo[x]._clfolvl == 0)
123: // If LFO._clfolvl is 0, then it appears that Word writes
124: // out a LFOLVL anyway - however, it's all 0xff. We need
125: // to skip over it.
126: lfolvlNum++;
127: else {
128: for (int y = 0; y < _pllfo[x]._clfolvl; y++) {
129: int offset = lfolvlOffset + (lfolvlNum * 8)
130: + lvlOffset;
131: LFOLVL lfolvl = new LFOLVL();
132: lfolvl._iStartAt = Utils.convertBytesToInt(plflfo,
133: offset);
134: lfolvl._ilvl = Utils.convertBytesToInt(plflfo,
135: offset + 4);
136: lfolvl._fStartAt = StyleSheet
137: .getFlag(lfolvl._ilvl & 0x10);
138: lfolvl._fFormatting = StyleSheet
139: .getFlag(lfolvl._ilvl & 0x20);
140: lfolvl._ilvl = (lfolvl._ilvl & (byte) 0x0f);
141: lfolvlNum++;
142:
143: if (lfolvl._fFormatting) {
144: // The size of a LFOLVL is 8 bytes.
145: offset = lfolvlOffset + (lfolvlNum * 8)
146: + lvlOffset;
147: lfolvl._override = new LVL();
148: lvlOffset += createLVL(plflfo, offset,
149: lfolvl._override);
150: }
151: _pllfo[x]._levels[y] = lfolvl;
152: }
153: }
154: }
155: }
156:
157: private int createLVL(byte[] data, int offset, LVL lvl) {
158: int startingOffset = offset;
159: lvl._iStartAt = Utils.convertBytesToInt(data, offset);
160: offset += 4;
161: lvl._nfc = data[offset++];
162: byte code = data[offset++];
163: lvl._jc = (byte) (code & 0x03);
164: lvl._fLegal = StyleSheet.getFlag(code & 0x04);
165: lvl._fNoRestart = StyleSheet.getFlag(code & 0x08);
166: lvl._fPrev = StyleSheet.getFlag(code & 0x10);
167: lvl._fPrevSpace = StyleSheet.getFlag(code & 0x20);
168: lvl._fWord6 = StyleSheet.getFlag(code & 0x40);
169:
170: // rgbxchNums - This array should be zero terminated unless it is full
171: // (all 9 levels full).
172: System.arraycopy(data, offset, lvl._rgbxchNums, 0, 9);
173: offset += 9;
174:
175: lvl._ixchFollow = data[offset++];
176:
177: if (lvl._fWord6) {
178: lvl._dxaSpace = Utils.convertBytesToInt(data, offset);
179: lvl._dxaIndent = Utils.convertBytesToInt(data, offset + 4);
180: }
181: offset += 8;
182:
183: int chpxSize = data[offset++];
184: int papxSize = data[offset++];
185: lvl._chpx = new byte[chpxSize];
186: lvl._papx = new byte[papxSize];
187:
188: System.arraycopy(data, offset, lvl._chpx, 0, chpxSize);
189: System.arraycopy(data, offset + chpxSize, lvl._papx, 0,
190: papxSize);
191:
192: offset += papxSize + chpxSize + 2; //don't forget to skip reserved word
193: int xstSize = Utils.convertBytesToShort(data, offset);
194: offset += 2;
195: lvl._xst = new char[xstSize];
196:
197: for (int x = 0; x < xstSize; x++) {
198: lvl._xst[x] = (char) Utils.convertBytesToShort(data, offset
199: + (x * 2));
200: }
201: return offset + (xstSize * 2) - startingOffset;
202: }
203: }
|