KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jxl > biff > XFRecord


1 /*********************************************************************
2 *
3 * Copyright (C) 2002 Andrew Khan
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 ***************************************************************************/

19
20
21 package jxl.biff;
22
23 import java.text.DateFormat JavaDoc;
24 import java.text.SimpleDateFormat JavaDoc;
25 import java.text.NumberFormat JavaDoc;
26 import java.text.DecimalFormat JavaDoc;
27 import java.text.DecimalFormatSymbols JavaDoc;
28
29 import common.Assert;
30 import common.Logger;
31
32 import jxl.WorkbookSettings;
33 import jxl.format.CellFormat;
34 import jxl.format.Format;
35 import jxl.format.Font;
36 import jxl.format.Alignment;
37 import jxl.format.VerticalAlignment;
38 import jxl.format.BorderLineStyle;
39 import jxl.format.Border;
40 import jxl.format.Colour;
41 import jxl.format.Pattern;
42 import jxl.format.Orientation;
43 import jxl.read.biff.Record;
44
45 /**
46  * Holds an extended formatting record
47  */

48 public class XFRecord extends WritableRecordData implements CellFormat
49 {
50   /**
51    * The logger
52    */

53   private static Logger logger = Logger.getLogger(XFRecord.class);
54
55   /**
56    * The index to the format record
57    */

58   public int formatIndex;
59
60   /**
61    * The index of the parent format
62    */

63   private int parentFormat;
64
65   /**
66    * The format type
67    */

68   private XFType xfFormatType;
69
70   /**
71    * Indicates whether this is a date formatting record
72    */

73   private boolean date;
74
75   /**
76    * Indicates whether this is a number formatting record
77    */

78   private boolean number;
79
80   /**
81    * The date format for this record. Deduced when the record is
82    * read in from a spreadsheet
83    */

84   private DateFormat JavaDoc dateFormat;
85
86   /**
87    * The number format for this record. Deduced when the record is read in
88    * from a spreadsheet
89    */

90   private NumberFormat JavaDoc numberFormat;
91
92   /**
93    * The used attribute. Needs to be preserved in order to get accurate
94    * rationalization
95    */

96   private byte usedAttributes;
97   /**
98    * The index to the font record used by this XF record
99    */

100   private int fontIndex;
101   /**
102    * Flag to indicate whether this XF record represents a locked cell
103    */

104   private boolean locked;
105   /**
106    * Flag to indicate whether this XF record is hidden
107    */

108   private boolean hidden;
109   /**
110    * The alignment for this cell (left, right, centre)
111    */

112   private Alignment align;
113   /**
114    * The vertical alignment for the cell (top, bottom, centre)
115    */

116   private VerticalAlignment valign;
117   /**
118    * The orientation of the cell
119    */

120   private Orientation orientation;
121   /**
122    * Flag to indicates whether the data (normally text) in the cell will be
123    * wrapped around to fit in the cell width
124    */

125   private boolean wrap;
126
127   /**
128    * Indentation of the cell text
129    */

130   private int indentation;
131
132   /**
133    * Flag to indicate that this format is shrink to fit
134    */

135   private boolean shrinkToFit;
136
137   /**
138    * The border indicator for the left of this cell
139    */

140   private BorderLineStyle leftBorder;
141   /**
142    * The border indicator for the right of the cell
143    */

144   private BorderLineStyle rightBorder;
145   /**
146    * The border indicator for the top of the cell
147    */

148   private BorderLineStyle topBorder;
149   /**
150    * The border indicator for the bottom of the cell
151    */

152   private BorderLineStyle bottomBorder;
153
154   /**
155    * The border colour for the left of the cell
156    */

157   private Colour leftBorderColour;
158   /**
159    * The border colour for the right of the cell
160    */

161   private Colour rightBorderColour;
162   /**
163    * The border colour for the top of the cell
164    */

165   private Colour topBorderColour;
166   /**
167    * The border colour for the bottom of the cell
168    */

169   private Colour bottomBorderColour;
170
171   /**
172    * The background colour
173    */

174   private Colour backgroundColour;
175   /**
176    * The background pattern
177    */

178   private Pattern pattern;
179   /**
180    * The options mask which is used to store the processed cell options (such
181    * as alignment, borders etc)
182    */

183   private int options;
184   /**
185    * The index of this XF record within the workbook
186    */

187   private int xfIndex;
188   /**
189    * The font object for this XF record
190    */

191   private FontRecord font;
192   /**
193    * The format object for this XF record. This is used when creating
194    * a writable record
195    */

196   private DisplayFormat format;
197   /**
198    * Flag to indicate whether this XF record has been initialized
199    */

200   private boolean initialized;
201
202   /**
203    * Indicates whether this cell was constructed by an API or read
204    * from an existing Excel file
205    */

206   private boolean read;
207
208   /**
209    * The excel format for this record. This is used to display the actual
210    * excel format string back to the user (eg. when generating certain
211    * types of XML document) as opposed to the java equivalent
212    */

213   private Format JavaDoc excelFormat;
214
215   /**
216    * Flag to indicate whether the format information has been initialized.
217    * This is false if the xf record has been read in, but true if it
218    * has been written
219    */

220   private boolean formatInfoInitialized;
221
222   /**
223    * Flag to indicate whether this cell was copied. If it was copied, then
224    * it can be set to uninitialized, allowing us to change certain format
225    * information
226    */

227   private boolean copied;
228
229   /**
230    * A handle to the formatting records. The purpose of this is
231    * to read the formatting information back, for the purposes of
232    * output eg. to some form of XML
233    */

234   private FormattingRecords formattingRecords;
235
236   /**
237    * The list of built in date format values
238    */

239   private static final int[] dateFormats = new int[]
240     {0xe,
241      0xf,
242      0x10,
243      0x11,
244      0x12,
245      0x13,
246      0x14,
247      0x15,
248      0x16,
249      0x2d,
250      0x2e,
251      0x2f};
252
253   /**
254    * The list of java date format equivalents
255    */

256   private static final DateFormat JavaDoc[] javaDateFormats = new DateFormat JavaDoc[]
257     {new SimpleDateFormat JavaDoc("dd/MM/yyyy"),
258      new SimpleDateFormat JavaDoc("d-MMM-yy"),
259      new SimpleDateFormat JavaDoc("d-MMM"),
260      new SimpleDateFormat JavaDoc("MMM-yy"),
261      new SimpleDateFormat JavaDoc("h:mm a"),
262      new SimpleDateFormat JavaDoc("h:mm:ss a"),
263      new SimpleDateFormat JavaDoc("H:mm"),
264      new SimpleDateFormat JavaDoc("H:mm:ss"),
265      new SimpleDateFormat JavaDoc("M/d/yy H:mm"),
266      new SimpleDateFormat JavaDoc("mm:ss"),
267      new SimpleDateFormat JavaDoc("H:mm:ss"),
268      new SimpleDateFormat JavaDoc("mm:ss.S")};
269
270   /**
271    * The list of built in number format values
272    */

273   private static int[] numberFormats = new int[]
274     {0x1,
275      0x2,
276      0x3,
277      0x4,
278      0x5,
279      0x6,
280      0x7,
281      0x8,
282      0x9,
283      0xa,
284      0xb,
285      0x25,
286      0x26,
287      0x27,
288      0x28,
289      0x29,
290      0x2a,
291      0x2b,
292      0x2c,
293      0x30};
294
295   /**
296    * The list of java number format equivalents
297    */

298   private static NumberFormat JavaDoc[] javaNumberFormats = new NumberFormat JavaDoc[]
299     {new DecimalFormat JavaDoc("0"),
300      new DecimalFormat JavaDoc("0.00"),
301      new DecimalFormat JavaDoc("#,##0"),
302      new DecimalFormat JavaDoc("#,##0.00"),
303      new DecimalFormat JavaDoc("$#,##0;($#,##0)"),
304      new DecimalFormat JavaDoc("$#,##0;($#,##0)"),
305      new DecimalFormat JavaDoc("$#,##0.00;($#,##0.00)"),
306      new DecimalFormat JavaDoc("$#,##0.00;($#,##0.00)"),
307      new DecimalFormat JavaDoc("0%"),
308      new DecimalFormat JavaDoc("0.00%"),
309      new DecimalFormat JavaDoc("0.00E00"),
310      new DecimalFormat JavaDoc("#,##0;(#,##0)"),
311      new DecimalFormat JavaDoc("#,##0;(#,##0)"),
312      new DecimalFormat JavaDoc("#,##0.00;(#,##0.00)"),
313      new DecimalFormat JavaDoc("#,##0.00;(#,##0.00)"),
314      new DecimalFormat JavaDoc("#,##0;(#,##0)"),
315      new DecimalFormat JavaDoc("$#,##0;($#,##0)"),
316      new DecimalFormat JavaDoc("#,##0.00;(#,##0.00)"),
317      new DecimalFormat JavaDoc("$#,##0.00;($#,##0.00)"),
318      new DecimalFormat JavaDoc("##0.0E0")};
319
320   // Type to distinguish between biff7 and biff8
321
private static class BiffType {};
322
323   public static final BiffType biff8 = new BiffType();
324   public static final BiffType biff7 = new BiffType();
325
326   /**
327    * The biff type
328    */

329   private BiffType biffType;
330
331   // Type to distinguish between cell and style records
332
private static class XFType
333   {
334   }
335   protected static final XFType cell = new XFType();
336   protected static final XFType style = new XFType();
337
338   /**
339    * Constructs this object from the raw data
340    *
341    * @param t the raw data
342    * @param bt the biff type
343    */

344   public XFRecord(Record t, WorkbookSettings ws, BiffType bt)
345   {
346     super(t);
347
348     biffType = bt;
349
350     byte[] data = getRecord().getData();
351
352     fontIndex = IntegerHelper.getInt(data[0], data[1]);
353     formatIndex = IntegerHelper.getInt(data[2], data[3]);
354     date = false;
355     number = false;
356
357
358     // Compare against the date formats
359
for (int i = 0; i < dateFormats.length && date == false; i++)
360     {
361       if (formatIndex == dateFormats[i])
362       {
363         date = true;
364         dateFormat = javaDateFormats[i];
365       }
366     }
367
368     // Compare against the number formats
369
for (int i = 0; i < numberFormats.length && number == false; i++)
370     {
371       if (formatIndex == numberFormats[i])
372       {
373         number = true;
374         DecimalFormat JavaDoc df = (DecimalFormat JavaDoc) javaNumberFormats[i].clone();
375         DecimalFormatSymbols JavaDoc symbols =
376           new DecimalFormatSymbols JavaDoc(ws.getLocale());
377         df.setDecimalFormatSymbols(symbols);
378         numberFormat = df;
379         //numberFormat = javaNumberFormats[i];
380
}
381     }
382
383     // Initialize the parent format and the type
384
int cellAttributes = IntegerHelper.getInt(data[4], data[5]);
385     parentFormat = (cellAttributes & 0xfff0) >> 4;
386
387     int formatType = cellAttributes & 0x4;
388     xfFormatType = formatType == 0 ? cell : style;
389     locked = ((cellAttributes & 0x1) != 0);
390     hidden = ((cellAttributes & 0x2) != 0);
391
392     if (xfFormatType == cell &&
393         (parentFormat & 0xfff) == 0xfff)
394     {
395       // Something is screwy with the parent format - set to zero
396
parentFormat = 0;
397       logger.warn("Invalid parent format found - ignoring");
398     }
399
400     initialized = false;
401     read = true;
402     formatInfoInitialized = false;
403     copied = false;
404   }
405
406   /**
407    * A constructor used when creating a writable record
408    *
409    * @param fnt the font
410    * @param form the format
411    */

412   public XFRecord(FontRecord fnt, DisplayFormat form)
413   {
414     super(Type.XF);
415
416     initialized = false;
417     locked = true;
418     hidden = false;
419     align = Alignment.GENERAL;
420     valign = VerticalAlignment.BOTTOM;
421     orientation = Orientation.HORIZONTAL;
422     wrap = false;
423     leftBorder = BorderLineStyle.NONE;
424     rightBorder = BorderLineStyle.NONE;
425     topBorder = BorderLineStyle.NONE;
426     bottomBorder = BorderLineStyle.NONE;
427     leftBorderColour = Colour.AUTOMATIC;
428     rightBorderColour = Colour.AUTOMATIC;
429     topBorderColour = Colour.AUTOMATIC;
430     bottomBorderColour = Colour.AUTOMATIC;
431     pattern = Pattern.NONE;
432     backgroundColour = Colour.DEFAULT_BACKGROUND;
433     indentation = 0;
434     shrinkToFit = false;
435
436     // This will be set by the initialize method and the subclass respectively
437
parentFormat = 0;
438     xfFormatType = null;
439
440     font = fnt;
441     format = form;
442     biffType = biff8;
443     read = false;
444     copied = false;
445     formatInfoInitialized = true;
446
447     Assert.verify(font != null);
448     Assert.verify(format != null);
449   }
450
451   /**
452    * Copy constructor. Used for copying writable formats, typically
453    * when duplicating formats to handle merged cells
454    *
455    * @param fmt XFRecord
456    */

457   protected XFRecord(XFRecord fmt)
458   {
459     super(Type.XF);
460
461     initialized = false;
462     locked = fmt.locked;
463     hidden = fmt.hidden;
464     align = fmt.align;
465     valign = fmt.valign;
466     orientation = fmt.orientation;
467     wrap = fmt.wrap;
468     leftBorder = fmt.leftBorder;
469     rightBorder = fmt.rightBorder;
470     topBorder = fmt.topBorder;
471     bottomBorder = fmt.bottomBorder;
472     leftBorderColour = fmt.leftBorderColour;
473     rightBorderColour = fmt.rightBorderColour;
474     topBorderColour = fmt.topBorderColour;
475     bottomBorderColour = fmt.bottomBorderColour;
476     pattern = fmt.pattern;
477     xfFormatType = fmt.xfFormatType;
478     indentation = fmt.indentation;
479     shrinkToFit = fmt.shrinkToFit;
480     parentFormat = fmt.parentFormat;
481     backgroundColour = fmt.backgroundColour;
482
483     // Shallow copy is sufficient for these purposes
484
font = fmt.font;
485     format = fmt.format;
486
487     fontIndex = fmt.fontIndex;
488     formatIndex = fmt.formatIndex;
489
490     formatInfoInitialized = fmt.formatInfoInitialized;
491
492     biffType = biff8;
493     read = false;
494     copied = true;
495   }
496
497   /**
498    * A public copy constructor which can be used for copy formats between
499    * different sheets. Unlike the the other copy constructor, this
500    * version does a deep copy
501    *
502    * @param cellFormat the format to copy
503    */

504   protected XFRecord(CellFormat cellFormat)
505   {
506     super(Type.XF);
507
508     Assert.verify(cellFormat != null);
509     Assert.verify(cellFormat instanceof XFRecord);
510     XFRecord fmt = (XFRecord) cellFormat;
511
512     if (!fmt.formatInfoInitialized)
513     {
514       fmt.initializeFormatInformation();
515     }
516
517     locked = fmt.locked;
518     hidden = fmt.hidden;
519     align = fmt.align;
520     valign = fmt.valign;
521     orientation = fmt.orientation;
522     wrap = fmt.wrap;
523     leftBorder = fmt.leftBorder;
524     rightBorder = fmt.rightBorder;
525     topBorder = fmt.topBorder;
526     bottomBorder = fmt.bottomBorder;
527     leftBorderColour = fmt.leftBorderColour;
528     rightBorderColour = fmt.rightBorderColour;
529     topBorderColour = fmt.topBorderColour;
530     bottomBorderColour = fmt.bottomBorderColour;
531     pattern = fmt.pattern;
532     xfFormatType = fmt.xfFormatType;
533     parentFormat = fmt.parentFormat;
534     indentation = fmt.indentation;
535     shrinkToFit = fmt.shrinkToFit;
536     backgroundColour = fmt.backgroundColour;
537
538     // Deep copy of the font
539
font = new FontRecord(fmt.getFont());
540
541     // Copy the format
542
if (fmt.getFormat() == null)
543     {
544       // format is writable
545
if (fmt.format.isBuiltIn())
546       {
547         format = fmt.format;
548       }
549       else
550       {
551         // Format is not built in, so do a deep copy
552
format = new FormatRecord((FormatRecord) fmt.format);
553       }
554     }
555     else if (fmt.getFormat() instanceof BuiltInFormat)
556     {
557       // read excel format is built in
558
excelFormat = (BuiltInFormat) fmt.excelFormat;
559       format = (BuiltInFormat) fmt.excelFormat;
560     }
561     else
562     {
563       // read excel format is user defined
564
Assert.verify(fmt.formatInfoInitialized);
565
566       // in this case FormattingRecords should initialize the excelFormat
567
// field with an instance of FormatRecord
568
Assert.verify(fmt.excelFormat instanceof FormatRecord);
569
570       // Format is not built in, so do a deep copy
571
FormatRecord fr = new FormatRecord((FormatRecord) fmt.excelFormat);
572
573       // Set both format fields to be the same object, since
574
// FormatRecord implements all the necessary interfaces
575
excelFormat = fr;
576       format = fr;
577     }
578
579     biffType = biff8;
580
581     // The format info should be all OK by virtue of the deep copy
582
formatInfoInitialized = true;
583     
584
585     // This format was not read in
586
read = false;
587
588     // Treat this as a new cell record, so set the copied flag to false
589
copied = false;
590
591     // The font or format indexes need to be set, so set initialized to false
592
initialized = false;
593   }
594
595   /**
596    * Gets the java date format for this format record
597    *
598    * @return returns the date format
599    */

600   public DateFormat JavaDoc getDateFormat()
601   {
602     return dateFormat;
603   }
604
605   /**
606    * Gets the java number format for this format record
607    *
608    * @return returns the number format
609    */

610   public NumberFormat JavaDoc getNumberFormat()
611   {
612     return numberFormat;
613   }
614
615   /**
616    * Gets the lookup number of the format record
617    *
618    * @return returns the lookup number of the format record
619    */

620   public int getFormatRecord()
621   {
622     return formatIndex;
623   }
624
625   /**
626    * Sees if this format is a date format
627    *
628    * @return TRUE if this refers to a built in date format
629    */

630   public boolean isDate()
631   {
632     return date;
633   }
634
635   /**
636    * Sees if this format is a number format
637    *
638    * @return TRUE if this refers to a built in date format
639    */

640   public boolean isNumber()
641   {
642     return number;
643   }
644
645   /**
646    * Converts the various fields into binary data. If this object has
647    * been read from an Excel file rather than being requested by a user (ie.
648    * if the read flag is TRUE) then
649    * no processing takes place and the raw data is simply returned.
650    *
651    * @return the raw data for writing
652    */

653   public byte[] getData()
654   {
655     // Format rationalization process means that we always want to
656
// regenerate the format info - even if the spreadsheet was
657
// read in
658
if (!formatInfoInitialized)
659     {
660       initializeFormatInformation();
661     }
662
663     byte[] data = new byte[20];
664
665     IntegerHelper.getTwoBytes(fontIndex, data, 0);
666     IntegerHelper.getTwoBytes(formatIndex, data, 2);
667
668     // Do the cell attributes
669
int cellAttributes = 0;
670
671     if (getLocked())
672     {
673       cellAttributes |= 0x01;
674     }
675
676     if (getHidden())
677     {
678       cellAttributes |= 0x02;
679     }
680
681     if (xfFormatType == style)
682     {
683       cellAttributes |= 0x04;
684       parentFormat = 0xffff;
685     }
686
687     cellAttributes |= (parentFormat << 4);
688
689     IntegerHelper.getTwoBytes(cellAttributes, data, 4);
690
691     int alignMask = align.getValue();
692
693     if (wrap)
694     {
695       alignMask |= 0x08;
696     }
697
698     alignMask |= (valign.getValue() << 4);
699
700     alignMask |= (orientation.getValue() << 8);
701
702     IntegerHelper.getTwoBytes(alignMask, data, 6);
703
704     data[9] = (byte) 0x10;
705
706     // Set the borders
707
int borderMask = leftBorder.getValue();
708     borderMask |= (rightBorder.getValue() << 4);
709     borderMask |= (topBorder.getValue() << 8);
710     borderMask |= (bottomBorder.getValue() << 12);
711
712     IntegerHelper.getTwoBytes(borderMask, data, 10);
713
714     // Set the border palette information if border mask is non zero
715
// Hard code the colours to be black
716
if (borderMask != 0)
717     {
718         byte lc = (byte)leftBorderColour.getValue();
719         byte rc = (byte)rightBorderColour.getValue();
720         byte tc = (byte)topBorderColour.getValue();
721         byte bc = (byte)bottomBorderColour.getValue();
722
723       int sideColourMask = (lc & 0x7f) | ((rc & 0x7f) << 7);
724       int topColourMask = (tc & 0x7f) | ((bc & 0x7f) << 7);
725
726       IntegerHelper.getTwoBytes(sideColourMask, data, 12);
727       IntegerHelper.getTwoBytes(topColourMask, data, 14);
728     }
729
730     // Set the background pattern
731
int patternVal = pattern.getValue() << 10;
732     IntegerHelper.getTwoBytes(patternVal, data, 16);
733
734     // Set the colour palette
735
int colourPaletteMask = backgroundColour.getValue();
736     colourPaletteMask |= (0x40 << 7);
737     IntegerHelper.getTwoBytes(colourPaletteMask, data, 18);
738
739     // Set the cell options
740
options |= indentation & 0x0f;
741
742     if (shrinkToFit)
743     {
744       options |= 0x10;
745     }
746     else
747     {
748       options &= 0xef;
749     }
750
751     data[8] = (byte) options;
752
753     if (biffType == biff8)
754     {
755       // usedAttributes = 0x4 << 2;
756
data[9] = usedAttributes;
757     }
758
759     return data;
760   }
761
762   /**
763    * Accessor for the locked flag
764    *
765    * @return TRUE if this XF record locks cells, FALSE otherwise
766    */

767   protected final boolean getLocked()
768   {
769     return locked;
770   }
771
772   /**
773    * Accessor for the hidden flag
774    *
775    * @return TRUE if this XF record hides the cell, FALSE otherwise
776    */

777   protected final boolean getHidden()
778   {
779     return hidden;
780   }
781
782   /**
783    * Sets whether or not this XF record locks the cell
784    *
785    * @param l the locked flag
786    */

787   protected final void setXFLocked(boolean l)
788   {
789     locked = l;
790   }
791
792   /**
793    * Sets the cell options
794    *
795    * @param opt the cell options
796    */

797   protected final void setXFCellOptions(int opt)
798   {
799     options |= opt;
800   }
801
802   /**
803    * Sets the horizontal alignment for the data in this cell.
804    * This method should only be called from its writable subclass
805    * CellXFRecord
806    *
807    * @param a the alignment
808    */

809   protected void setXFAlignment(Alignment a)
810   {
811     Assert.verify(!initialized);
812     align = a;
813   }
814
815   /**
816    * Sets the indentation
817    *
818    * @param i the indentation
819    */

820   protected void setXFIndentation(int i)
821   {
822     Assert.verify(!initialized);
823     indentation = i;
824   }
825
826   /**
827    * Sets the shrink to fit flag
828    *
829    * @param s the shrink to fit flag
830    */

831   protected void setXFShrinkToFit(boolean s)
832   {
833     Assert.verify(!initialized);
834     shrinkToFit = s;
835   }
836
837   /**
838    * Gets the horizontal cell alignment
839    *
840    * @return the alignment
841    */

842   public Alignment getAlignment()
843   {
844     if (!formatInfoInitialized)
845     {
846       initializeFormatInformation();
847     }
848
849     return align;
850   }
851
852   /**
853    * Gets the indentation
854    *
855    * @return the indentation
856    */

857   public int getIndentation()
858   {
859     if (!formatInfoInitialized)
860     {
861       initializeFormatInformation();
862     }
863
864     return indentation;
865   }
866
867   /**
868    * Gets the shrink to fit flag
869    *
870    * @return TRUE if this format is shrink to fit, FALSE otherise
871    */

872   public boolean isShrinkToFit()
873   {
874     if (!formatInfoInitialized)
875     {
876       initializeFormatInformation();
877     }
878
879     return shrinkToFit;
880   }
881
882   /**
883    * Accessor for whether a particular cell is locked
884    *
885    * @return TRUE if this cell is locked, FALSE otherwise
886    */

887   public boolean isLocked()
888   {
889     if (!formatInfoInitialized)
890     {
891       initializeFormatInformation();
892     }
893
894     return locked;
895   }
896
897
898   /**
899    * Gets the vertical cell alignment
900    *
901    * @return the alignment
902    */

903   public VerticalAlignment getVerticalAlignment()
904   {
905     if (!formatInfoInitialized)
906     {
907       initializeFormatInformation();
908     }
909
910     return valign;
911   }
912
913   /**
914    * Gets the orientation
915    *
916    * @return the orientation
917    */

918   public Orientation getOrientation()
919   {
920     if (!formatInfoInitialized)
921     {
922       initializeFormatInformation();
923     }
924
925     return orientation;
926   }
927
928   /**
929    * Sets the horizontal alignment for the data in this cell.
930    * This method should only be called from its writable subclass
931    * CellXFRecord
932    *
933    * @param c the background colour
934    * @param p the background pattern
935    */

936   protected void setXFBackground(Colour c, Pattern p)
937   {
938     Assert.verify(!initialized);
939     backgroundColour = c;
940     pattern = p;
941   }
942
943   /**
944    * Gets the background colour used by this cell
945    *
946    * @return the foreground colour
947    */

948   public Colour getBackgroundColour()
949   {
950     if (!formatInfoInitialized)
951     {
952       initializeFormatInformation();
953     }
954
955     return backgroundColour;
956   }
957
958   /**
959    * Gets the pattern used by this cell format
960    *
961    * @return the background pattern
962    */

963   public Pattern getPattern()
964   {
965     if (!formatInfoInitialized)
966     {
967       initializeFormatInformation();
968     }
969
970     return pattern;
971   }
972
973   /**
974    * Sets the vertical alignment for the data in this cell
975    * This method should only be called from its writable subclass
976    * CellXFRecord
977
978    *
979    * @param va the vertical alignment
980    */

981   protected void setXFVerticalAlignment(VerticalAlignment va)
982   {
983     Assert.verify(!initialized);
984     valign = va;
985   }
986
987   /**
988    * Sets the vertical alignment for the data in this cell
989    * This method should only be called from its writable subclass
990    * CellXFRecord
991
992    *
993    * @param o the orientation
994    */

995   protected void setXFOrientation(Orientation o)
996   {
997     Assert.verify(!initialized);
998     orientation = o;
999   }
1000
1001  /**
1002   * Sets whether the data in this cell is wrapped
1003   * This method should only be called from its writable subclass
1004   * CellXFRecord
1005   *
1006   * @param w the wrap flag
1007   */

1008  protected void setXFWrap(boolean w)
1009  {
1010    Assert.verify(!initialized);
1011    wrap = w;
1012  }
1013
1014  /**
1015   * Gets whether or not the contents of this cell are wrapped
1016   *
1017   * @return TRUE if this cell's contents are wrapped, FALSE otherwise
1018   */

1019  public boolean getWrap()
1020  {
1021    if (!formatInfoInitialized)
1022    {
1023      initializeFormatInformation();
1024    }
1025
1026    return wrap;
1027  }
1028
1029  /**
1030   * Sets the border for this cell
1031   * This method should only be called from its writable subclass
1032   * CellXFRecord
1033   *
1034   * @param b the border
1035   * @param ls the border line style
1036   */

1037  protected void setXFBorder(Border b, BorderLineStyle ls, Colour c)
1038  {
1039    Assert.verify(!initialized);
1040    
1041    if (c==Colour.BLACK)
1042    {
1043      c = Colour.PALETTE_BLACK;
1044    }
1045
1046    if (b == Border.LEFT)
1047    {
1048      leftBorder = ls;
1049      leftBorderColour = c;
1050    }
1051    else if (b == Border.RIGHT)
1052    {
1053      rightBorder = ls;
1054      rightBorderColour = c;
1055    }
1056    else if (b == Border.TOP)
1057    {
1058      topBorder = ls;
1059      topBorderColour = c;
1060    }
1061    else if (b == Border.BOTTOM)
1062    {
1063      bottomBorder = ls;
1064      bottomBorderColour = c;
1065    }
1066    return;
1067  }
1068
1069
1070  /**
1071   * Gets the line style for the given cell border
1072   * If a border type of ALL or NONE is specified, then a line style of
1073   * NONE is returned
1074   *
1075   * @param border the cell border we are interested in
1076   * @return the line style of the specified border
1077   */

1078  public BorderLineStyle getBorder(Border border)
1079  {
1080    return getBorderLine(border);
1081  }
1082
1083  /**
1084   * Gets the line style for the given cell border
1085   * If a border type of ALL or NONE is specified, then a line style of
1086   * NONE is returned
1087   *
1088   * @param border the cell border we are interested in
1089   * @return the line style of the specified border
1090   */

1091  public BorderLineStyle getBorderLine(Border border)
1092  {
1093    // Don't bother with the short cut records
1094
if (border == Border.NONE ||
1095        border == Border.ALL)
1096    {
1097      return BorderLineStyle.NONE;
1098    }
1099
1100    if (!formatInfoInitialized)
1101    {
1102      initializeFormatInformation();
1103    }
1104
1105    if (border == Border.LEFT)
1106    {
1107      return leftBorder;
1108    }
1109    else if (border == Border.RIGHT)
1110    {
1111      return rightBorder;
1112    }
1113    else if (border == Border.TOP)
1114    {
1115      return topBorder;
1116    }
1117    else if (border == Border.BOTTOM)
1118    {
1119      return bottomBorder;
1120    }
1121
1122    return BorderLineStyle.NONE;
1123  }
1124
1125  /**
1126   * Gets the line style for the given cell border
1127   * If a border type of ALL or NONE is specified, then a line style of
1128   * NONE is returned
1129   *
1130   * @param border the cell border we are interested in
1131   * @return the line style of the specified border
1132   */

1133  public Colour getBorderColour(Border border)
1134  {
1135    // Don't bother with the short cut records
1136
if (border == Border.NONE ||
1137        border == Border.ALL)
1138    {
1139      return Colour.PALETTE_BLACK;
1140    }
1141
1142    if (!formatInfoInitialized)
1143    {
1144      initializeFormatInformation();
1145    }
1146
1147    if (border == Border.LEFT)
1148    {
1149      return leftBorderColour;
1150    }
1151    else if (border == Border.RIGHT)
1152    {
1153      return rightBorderColour;
1154    }
1155    else if (border == Border.TOP)
1156    {
1157      return topBorderColour;
1158    }
1159    else if (border == Border.BOTTOM)
1160    {
1161      return bottomBorderColour;
1162    }
1163
1164    return Colour.BLACK;
1165  }
1166
1167
1168  /**
1169   * Determines if this cell format has any borders at all. Used to
1170   * set the new borders when merging a group of cells
1171   *
1172   * @return TRUE if this cell has any borders, FALSE otherwise
1173   */

1174  public final boolean hasBorders()
1175  {
1176    if (!formatInfoInitialized)
1177    {
1178      initializeFormatInformation();