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.hwpf.sprm;
019:
020: import org.apache.poi.hwpf.usermodel.TableProperties;
021: import org.apache.poi.hwpf.usermodel.TableCellDescriptor;
022: import org.apache.poi.hwpf.usermodel.BorderCode;
023:
024: import org.apache.poi.util.LittleEndian;
025:
026: public class TableSprmUncompressor extends SprmUncompressor {
027: public TableSprmUncompressor() {
028: }
029:
030: public static TableProperties uncompressTAP(byte[] grpprl,
031: int offset) {
032: TableProperties newProperties = new TableProperties();
033:
034: SprmIterator sprmIt = new SprmIterator(grpprl, offset);
035:
036: while (sprmIt.hasNext()) {
037: SprmOperation sprm = (SprmOperation) sprmIt.next();
038:
039: //TAPXs are actually PAPXs so we have to make sure we are only trying to
040: //uncompress the right type of sprm.
041: if (sprm.getType() == SprmOperation.TAP_TYPE) {
042: unCompressTAPOperation(newProperties, sprm);
043: }
044: }
045:
046: return newProperties;
047: }
048:
049: /**
050: * Used to uncompress a table property. Performs an operation defined
051: * by a sprm stored in a tapx.
052: *
053: * @param newTAP The TableProperties object to perform the operation on.
054: * @param operand The operand that defines this operation.
055: * @param param The parameter for this operation.
056: * @param varParam Variable length parameter for this operation.
057: */
058: static void unCompressTAPOperation(TableProperties newTAP,
059: SprmOperation sprm) {
060: switch (sprm.getOperation()) {
061: case 0:
062: newTAP.setJc((short) sprm.getOperand());
063: break;
064: case 0x01: {
065: short[] rgdxaCenter = newTAP.getRgdxaCenter();
066: short itcMac = newTAP.getItcMac();
067: int adjust = sprm.getOperand()
068: - (rgdxaCenter[0] + newTAP.getDxaGapHalf());
069: for (int x = 0; x < itcMac; x++) {
070: rgdxaCenter[x] += adjust;
071: }
072: break;
073: }
074: case 0x02: {
075: short[] rgdxaCenter = newTAP.getRgdxaCenter();
076: if (rgdxaCenter != null) {
077: int adjust = newTAP.getDxaGapHalf() - sprm.getOperand();
078: rgdxaCenter[0] += adjust;
079: }
080: newTAP.setDxaGapHalf(sprm.getOperand());
081: break;
082: }
083: case 0x03:
084: newTAP.setFCantSplit(getFlag(sprm.getOperand()));
085: break;
086: case 0x04:
087: newTAP.setFTableHeader(getFlag(sprm.getOperand()));
088: break;
089: case 0x05: {
090: byte[] buf = sprm.getGrpprl();
091: int offset = sprm.getGrpprlOffset();
092: newTAP.setBrcTop(new BorderCode(buf, offset));
093: offset += BorderCode.SIZE;
094: newTAP.setBrcLeft(new BorderCode(buf, offset));
095: offset += BorderCode.SIZE;
096: newTAP.setBrcBottom(new BorderCode(buf, offset));
097: offset += BorderCode.SIZE;
098: newTAP.setBrcRight(new BorderCode(buf, offset));
099: offset += BorderCode.SIZE;
100: newTAP.setBrcHorizontal(new BorderCode(buf, offset));
101: offset += BorderCode.SIZE;
102: newTAP.setBrcVertical(new BorderCode(buf, offset));
103: break;
104: }
105: case 0x06:
106:
107: //obsolete, used in word 1.x
108: break;
109: case 0x07:
110: newTAP.setDyaRowHeight(sprm.getOperand());
111: break;
112: case 0x08: {
113: byte[] grpprl = sprm.getGrpprl();
114: int offset = sprm.getGrpprlOffset();
115: short itcMac = grpprl[offset];
116: short[] rgdxaCenter = new short[itcMac + 1];
117: TableCellDescriptor[] rgtc = new TableCellDescriptor[itcMac];
118: //I use varParam[0] and newTAP._itcMac interchangably
119: newTAP.setItcMac(itcMac);
120: newTAP.setRgdxaCenter(rgdxaCenter);
121: newTAP.setRgtc(rgtc);
122:
123: // get the rgdxaCenters
124: for (int x = 0; x < itcMac; x++) {
125: rgdxaCenter[x] = LittleEndian.getShort(grpprl, offset
126: + (1 + (x * 2)));
127: }
128:
129: // only try to get the TC entries if they exist...
130: int endOfSprm = offset + sprm.size() - 6; // -2 bytes for sprm - 2 for size short - 2 to correct offsets being 0 based
131: int startOfTCs = offset + (1 + (itcMac + 1) * 2);
132:
133: boolean hasTCs = startOfTCs < endOfSprm;
134:
135: for (int x = 0; x < itcMac; x++) {
136: // Sometimes, the grpprl does not contain data at every offset. I have no idea why this happens.
137: if (hasTCs
138: && offset + (1 + ((itcMac + 1) * 2) + (x * 20)) < grpprl.length)
139: rgtc[x] = TableCellDescriptor
140: .convertBytesToTC(
141: grpprl,
142: offset
143: + (1 + ((itcMac + 1) * 2) + (x * 20)));
144: else
145: rgtc[x] = new TableCellDescriptor();
146: }
147:
148: rgdxaCenter[itcMac] = LittleEndian.getShort(grpprl, offset
149: + (1 + (itcMac * 2)));
150: break;
151: }
152: case 0x09:
153:
154: /** @todo handle cell shading*/
155: break;
156: case 0x0a:
157:
158: /** @todo handle word defined table styles*/
159: break;
160: case 0x20:
161: // {
162: // TableCellDescriptor[] rgtc = newTAP.getRgtc();
163: //
164: // for (int x = varParam[0]; x < varParam[1]; x++)
165: // {
166: //
167: // if ((varParam[2] & 0x08) > 0)
168: // {
169: // short[] brcRight = rgtc[x].getBrcRight ();
170: // brcRight[0] = LittleEndian.getShort (varParam, 6);
171: // brcRight[1] = LittleEndian.getShort (varParam, 8);
172: // }
173: // else if ((varParam[2] & 0x04) > 0)
174: // {
175: // short[] brcBottom = rgtc[x].getBrcBottom ();
176: // brcBottom[0] = LittleEndian.getShort (varParam, 6);
177: // brcBottom[1] = LittleEndian.getShort (varParam, 8);
178: // }
179: // else if ((varParam[2] & 0x02) > 0)
180: // {
181: // short[] brcLeft = rgtc[x].getBrcLeft ();
182: // brcLeft[0] = LittleEndian.getShort (varParam, 6);
183: // brcLeft[1] = LittleEndian.getShort (varParam, 8);
184: // }
185: // else if ((varParam[2] & 0x01) > 0)
186: // {
187: // short[] brcTop = rgtc[x].getBrcTop ();
188: // brcTop[0] = LittleEndian.getShort (varParam, 6);
189: // brcTop[1] = LittleEndian.getShort (varParam, 8);
190: // }
191: // }
192: // break;
193: // }
194: break;
195: case 0x21: {
196: int param = sprm.getOperand();
197: int index = (param & 0xff000000) >> 24;
198: int count = (param & 0x00ff0000) >> 16;
199: int width = (param & 0x0000ffff);
200: int itcMac = newTAP.getItcMac();
201:
202: short[] rgdxaCenter = new short[itcMac + count + 1];
203: TableCellDescriptor[] rgtc = new TableCellDescriptor[itcMac
204: + count];
205: if (index >= itcMac) {
206: index = itcMac;
207: System.arraycopy(newTAP.getRgdxaCenter(), 0,
208: rgdxaCenter, 0, itcMac + 1);
209: System.arraycopy(newTAP.getRgtc(), 0, rgtc, 0, itcMac);
210: } else {
211: //copy rgdxaCenter
212: System.arraycopy(newTAP.getRgdxaCenter(), 0,
213: rgdxaCenter, 0, index + 1);
214: System.arraycopy(newTAP.getRgdxaCenter(), index + 1,
215: rgdxaCenter, index + count, itcMac - (index));
216: //copy rgtc
217: System.arraycopy(newTAP.getRgtc(), 0, rgtc, 0, index);
218: System.arraycopy(newTAP.getRgtc(), index, rgtc, index
219: + count, itcMac - index);
220: }
221:
222: for (int x = index; x < index + count; x++) {
223: rgtc[x] = new TableCellDescriptor();
224: rgdxaCenter[x] = (short) (rgdxaCenter[x - 1] + width);
225: }
226: rgdxaCenter[index + count] = (short) (rgdxaCenter[(index + count) - 1] + width);
227: break;
228: }
229: /**@todo handle table sprms from complex files*/
230: case 0x22:
231: case 0x23:
232: case 0x24:
233: case 0x25:
234: case 0x26:
235: case 0x27:
236: case 0x28:
237: case 0x29:
238: case 0x2a:
239: case 0x2b:
240: case 0x2c:
241: break;
242: default:
243: break;
244: }
245: }
246:
247: }
|