KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > poi > hwpf > model > StyleSheet


1
2 /* ====================================================================
3    Copyright 2002-2004 Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16 ==================================================================== */

17         
18
19
20 package org.apache.poi.hwpf.model;
21
22 import java.util.*;
23 import java.io.IOException JavaDoc;
24
25 import org.apache.poi.util.LittleEndian;
26 import org.apache.poi.hwpf.model.io.HWPFOutputStream;
27 import org.apache.poi.hwpf.usermodel.CharacterProperties;
28 import org.apache.poi.hwpf.usermodel.ParagraphProperties;
29 import org.apache.poi.hwpf.sprm.ParagraphSprmUncompressor;
30 import org.apache.poi.hwpf.sprm.CharacterSprmUncompressor;
31
32 /**
33  * Represents a document's stylesheet. A word documents formatting is stored as
34  * compressed styles that are based on styles contained in the stylesheet. This
35  * class also contains static utility functions to uncompress different
36  * formatting properties.
37  *
38  * @author Ryan Ackley
39  */

40
41 public class StyleSheet implements HDFType
42 {
43
44   public static final int NIL_STYLE = 4095;
45   private static final int PAP_TYPE = 1;
46   private static final int CHP_TYPE = 2;
47   private static final int SEP_TYPE = 4;
48   private static final int TAP_TYPE = 5;
49
50
51   private final static ParagraphProperties NIL_PAP = new ParagraphProperties();
52   private final static CharacterProperties NIL_CHP = new CharacterProperties();
53
54   private int _stshiLength;
55   private int _baseLength;
56   private int _flags;
57   private int _maxIndex;
58   private int _maxFixedIndex;
59   private int _stylenameVersion;
60   private int[] _rgftc;
61
62   StyleDescription[] _styleDescriptions;
63
64   /**
65    * StyleSheet constructor. Loads a document's stylesheet information,
66    *
67    * @param tableStream A byte array containing a document's raw stylesheet
68    * info. Found by using FileInformationBlock.getFcStshf() and
69    * FileInformationBLock.getLcbStshf()
70    */

71   public StyleSheet(byte[] tableStream, int offset)
72   {
73       _stshiLength = LittleEndian.getShort(tableStream, offset);
74       offset += LittleEndian.SHORT_SIZE;
75       int stdCount = LittleEndian.getShort(tableStream, offset);
76       offset += LittleEndian.SHORT_SIZE;
77       _baseLength = LittleEndian.getShort(tableStream, offset);
78       offset += LittleEndian.SHORT_SIZE;
79       _flags = LittleEndian.getShort(tableStream, offset);
80       offset += LittleEndian.SHORT_SIZE;
81       _maxIndex = LittleEndian.getShort(tableStream, offset);
82       offset += LittleEndian.SHORT_SIZE;
83       _maxFixedIndex = LittleEndian.getShort(tableStream, offset);
84       offset += LittleEndian.SHORT_SIZE;
85       _stylenameVersion = LittleEndian.getShort(tableStream, offset);
86       offset += LittleEndian.SHORT_SIZE;
87
88       _rgftc = new int[3];
89       _rgftc[0] = LittleEndian.getShort(tableStream, offset);
90       offset += LittleEndian.SHORT_SIZE;
91       _rgftc[1] = LittleEndian.getShort(tableStream, offset);
92       offset += LittleEndian.SHORT_SIZE;
93       _rgftc[2] = LittleEndian.getShort(tableStream, offset);
94       offset += LittleEndian.SHORT_SIZE;
95
96       offset = (LittleEndian.SHORT_SIZE + _stshiLength);
97       _styleDescriptions = new StyleDescription[stdCount];
98       for(int x = 0; x < stdCount; x++)
99       {
100           int stdSize = LittleEndian.getShort(tableStream, offset);
101           //get past the size
102
offset += 2;
103           if(stdSize > 0)
104           {
105               //byte[] std = new byte[stdSize];
106

107               StyleDescription aStyle = new StyleDescription(tableStream,
108                 _baseLength, offset, true);
109
110               _styleDescriptions[x] = aStyle;
111           }
112
113           offset += stdSize;
114
115       }
116       for(int x = 0; x < _styleDescriptions.length; x++)
117       {
118           if(_styleDescriptions[x] != null)
119           {
120               createPap(x);
121               createChp(x);
122           }
123       }
124   }
125
126   public void writeTo(HWPFOutputStream out)
127     throws IOException JavaDoc
128   {
129     int offset = 0;
130     // add two bytes so we can prepend the stylesheet w/ its size
131
byte[] buf = new byte[_stshiLength + 2];
132     LittleEndian.putShort(buf, offset, (short)_stshiLength);
133     offset += LittleEndian.SHORT_SIZE;
134     LittleEndian.putShort(buf, offset, (short)_styleDescriptions.length);
135     offset += LittleEndian.SHORT_SIZE;
136     LittleEndian.putShort(buf, offset, (short)_baseLength);
137     offset += LittleEndian.SHORT_SIZE;
138     LittleEndian.putShort(buf, offset, (short)_flags);
139     offset += LittleEndian.SHORT_SIZE;
140     LittleEndian.putShort(buf, offset, (short)_maxIndex);
141     offset += LittleEndian.SHORT_SIZE;
142     LittleEndian.putShort(buf, offset, (short)_maxFixedIndex);
143     offset += LittleEndian.SHORT_SIZE;
144     LittleEndian.putShort(buf, offset, (short)_stylenameVersion);
145     offset += LittleEndian.SHORT_SIZE;
146
147     LittleEndian.putShort(buf, offset, (short)_rgftc[0]);
148     offset += LittleEndian.SHORT_SIZE;
149     LittleEndian.putShort(buf, offset, (short)_rgftc[1]);
150     offset += LittleEndian.SHORT_SIZE;
151     LittleEndian.putShort(buf, offset, (short)_rgftc[2]);
152
153     out.write(buf);
154
155     byte[] sizeHolder = new byte[2];
156     for (int x = 0; x < _styleDescriptions.length; x++)
157     {
158       if(_styleDescriptions[x] != null)
159       {
160           byte[] std = _styleDescriptions[x].toByteArray();
161
162           // adjust the size so it is always on a word boundary
163
LittleEndian.putShort(sizeHolder, (short)((std.length) + (std.length % 2)));
164           out.write(sizeHolder);
165           out.write(std);
166
167           // Must always start on a word boundary.
168
if (std.length % 2 == 1)
169           {
170             out.write('\0');
171           }
172       }
173       else
174       {
175         sizeHolder[0] = 0;
176         sizeHolder[1] = 0;
177         out.write(sizeHolder);
178       }
179     }
180   }
181   public boolean equals(Object JavaDoc o)
182   {
183     StyleSheet ss = (StyleSheet)o;
184
185     if (ss._baseLength == _baseLength && ss._flags == _flags &&
186         ss._maxFixedIndex ==_maxFixedIndex && ss._maxIndex == _maxIndex &&
187         ss._rgftc[0] == _rgftc[0] && ss._rgftc[1] == _rgftc[1] &&
188         ss._rgftc[2] == _rgftc[2] && ss._stshiLength == _stshiLength &&
189         ss._stylenameVersion == _stylenameVersion)
190     {
191       if (ss._styleDescriptions.length == _styleDescriptions.length)
192       {
193         for (int x = 0; x < _styleDescriptions.length; x++)
194         {
195           // check for null
196
if (ss._styleDescriptions[x] != _styleDescriptions[x])
197           {
198             // check for equality
199
if (!ss._styleDescriptions[x].equals(_styleDescriptions[x]))
200             {
201               return false;
202             }
203           }
204         }
205         return true;
206       }
207     }
208     return false;
209   }
210   /**
211    * Creates a PartagraphProperties object from a papx stored in the
212    * StyleDescription at the index istd in the StyleDescription array. The PAP
213    * is placed in the StyleDescription at istd after its been created. Not
214    * every StyleDescription will contain a papx. In these cases this function
215    * does nothing
216    *
217    * @param istd The index of the StyleDescription to create the
218    * ParagraphProperties from (and also place the finished PAP in)
219    */

220   private void createPap(int istd)
221   {
222       StyleDescription sd = _styleDescriptions[istd];
223       ParagraphProperties pap = sd.getPAP();
224       byte[] papx = sd.getPAPX();
225       int baseIndex = sd.getBaseStyle();
226       if(pap == null && papx != null)
227       {
228           ParagraphProperties parentPAP = new ParagraphProperties();
229           if(baseIndex != NIL_STYLE)
230           {
231
232               parentPAP = _styleDescriptions[baseIndex].getPAP();
233               if(parentPAP == null)
234               {
235                   createPap(baseIndex);
236                   parentPAP = _styleDescriptions[baseIndex].getPAP();
237               }
238
239           }
240
241           pap = (ParagraphProperties)ParagraphSprmUncompressor.uncompressPAP(parentPAP, papx, 2);
242           sd.setPAP(pap);
243       }
244   }
245   /**
246    * Creates a CharacterProperties object from a chpx stored in the
247    * StyleDescription at the index istd in the StyleDescription array. The
248    * CharacterProperties object is placed in the StyleDescription at istd after
249    * its been created. Not every StyleDescription will contain a chpx. In these
250    * cases this function does nothing.
251    *
252    * @param istd The index of the StyleDescription to create the
253    * CharacterProperties object from.
254    */

255   private void createChp(int istd)
256   {
257       StyleDescription sd = _styleDescriptions[istd];
258       CharacterProperties chp = sd.getCHP();
259       byte[] chpx = sd.getCHPX();
260       int baseIndex = sd.getBaseStyle();
261       if(chp == null && chpx != null)
262       {
263           CharacterProperties parentCHP = new CharacterProperties();
264           if(baseIndex != NIL_STYLE)
265           {
266
267               parentCHP = _styleDescriptions[baseIndex].getCHP();
268               if(parentCHP == null)
269               {
270                   createChp(baseIndex);
271                   parentCHP = _styleDescriptions[baseIndex].getCHP();
272               }
273
274           }
275
276           chp = (CharacterProperties)CharacterSprmUncompressor.uncompressCHP(parentCHP, chpx, 0);
277           sd.setCHP(chp);
278       }
279   }
280
281   /**
282    * Gets the StyleDescription at index x.
283    *
284    * @param x the index of the desired StyleDescription.
285    */

286   public StyleDescription getStyleDescription(int x)
287   {
288       return _styleDescriptions[x];
289   }
290
291   public CharacterProperties getCharacterStyle(int x)
292   {
293     if (x == NIL_STYLE)
294     {
295       return NIL_CHP;
296     }
297     return (_styleDescriptions[x] != null ? _styleDescriptions[x].getCHP() : null);
298   }
299
300   public ParagraphProperties getParagraphStyle(int x)
301   {
302     if (x == NIL_STYLE)
303     {
304       return NIL_PAP;
305     }
306     return (_styleDescriptions[x] != null ? _styleDescriptions[x].getPAP() : null);
307   }
308
309 }
310
Popular Tags