/** * Standard equals method * @param o the object to compare * @return TRUE if the objects are equal, FALSE otherwise */ public override bool Equals(object o) { if (o == this) { return(true); } if (!(o is FontRecord)) { return(false); } FontRecord font = (FontRecord)o; if (pointHeight == font.pointHeight && colourIndex == font.colourIndex && boldWeight == font.boldWeight && scriptStyle == font.scriptStyle && underlineStyle == font.underlineStyle && italic == font.italic && struckout == font.struckout && fontFamily == font.fontFamily && characterSet == font.characterSet && name.Equals(font.name)) { return(true); } return(false); }
/** * Rationalizes all the fonts, removing any duplicates * * @return the mappings between new indexes and old ones */ public IndexMapping rationalize() { IndexMapping mapping = new IndexMapping(fonts.Count + 1); // allow for skipping record 4 ArrayList newfonts = new ArrayList(); int numremoved = 0; // Preserve the default fonts for (int i = 0; i < numDefaultFonts; i++) { FontRecord fr = (FontRecord)fonts[i]; newfonts.Add(fr); mapping.setMapping(fr.getFontIndex(), fr.getFontIndex()); } // Now do the rest bool duplicate = false; for (int i = numDefaultFonts; i < fonts.Count; i++) { FontRecord fr = (FontRecord)fonts[i]; // Compare to all the fonts currently on the list duplicate = false; foreach (FontRecord fr2 in newfonts) { if (fr.Equals(fr2)) { duplicate = true; mapping.setMapping(fr.getFontIndex(), mapping.getNewIndex(fr2.getFontIndex())); numremoved++; break; } } if (!duplicate) { // Add to the new list newfonts.Add(fr); int newindex = fr.getFontIndex() - numremoved; Assert.verify(newindex > 4); mapping.setMapping(fr.getFontIndex(), newindex); } } // Iterate through the remaining fonts, updating all the font indices foreach (FontRecord fr in newfonts) { fr.initialize(mapping.getNewIndex(fr.getFontIndex())); } fonts = newfonts; return(mapping); }
/** * Adds a font record to this workbook. If the FontRecord passed in has not * been initialized, then its font index is determined based upon the size * of the fonts list. The FontRecord's initialized method is called, and * it is added to the list of fonts. * * @param f the font to add */ public void addFont(FontRecord f) { if (!f.isInitialized()) { int pos = fonts.Count; // Remember that the pos with index 4 is skipped if (pos >= 4) pos++; f.initialize(pos); fonts.Add(f); } }
/** * Adds a font record to this workbook. If the FontRecord passed in has not * been initialized, then its font index is determined based upon the size * of the fonts list. The FontRecord's initialized method is called, and * it is added to the list of fonts. * * @param f the font to add */ public void addFont(FontRecord f) { if (!f.isInitialized()) { int pos = fonts.Count; // Remember that the pos with index 4 is skipped if (pos >= 4) { pos++; } f.initialize(pos); fonts.Add(f); } }
/** * Does the hard work of building up the object graph from the excel bytes * * @exception BiffException * @exception PasswordException if the workbook is password protected */ protected override void parse() { Record r = null; BOFRecord bof = new BOFRecord(excelFile.next()); workbookBof = bof; bofs++; if (!bof.isBiff8() && !bof.isBiff7()) { throw new BiffException(BiffException.unrecognizedBiffVersion); } if (!bof.isWorkbookGlobals()) { throw new BiffException(BiffException.expectedGlobals); } ArrayList continueRecords = new ArrayList(); ArrayList localNames = new ArrayList(); nameTable = new ArrayList(); addInFunctions = new ArrayList(); // Skip to the first worksheet while (bofs == 1) { r = excelFile.next(); if (r.getType() == Type.SST) { continueRecords.Clear(); Record nextrec = excelFile.peek(); while (nextrec.getType() == Type.CONTINUE) { continueRecords.Add(excelFile.next()); nextrec = excelFile.peek(); } // cast the array Record[] records = new Record[continueRecords.Count]; int pos = 0; foreach (Record record in continueRecords) records[pos++] = record; sharedStrings = new SSTRecord(r,records,settings); } else if (r.getType() == Type.FILEPASS) { throw new PasswordException(); } else if (r.getType() == Type.NAME) { NameRecord nr = null; if (bof.isBiff8()) { nr = new NameRecord(r,settings,nameTable.Count); } else { nr = new NameRecord(r,settings,nameTable.Count, NameRecord.biff7); } // Add all local and global names to the name table in order to // preserve the indexing nameTable.Add(nr); if (nr.isGlobal()) namedRecords.Add(nr.getName(),nr); else localNames.Add(nr); } else if (r.getType() == Type.FONT) { FontRecord fr = null; if (bof.isBiff8()) fr = new FontRecord(r,settings); else fr = new FontRecord(r,settings,FontRecord.biff7); fonts.addFont(fr); } else if (r.getType() == Type.PALETTE) { CSharpJExcel.Jxl.Biff.PaletteRecord palette = new CSharpJExcel.Jxl.Biff.PaletteRecord(r); formattingRecords.setPalette(palette); } else if (r.getType() == Type.NINETEENFOUR) { NineteenFourRecord nr = new NineteenFourRecord(r); nineteenFour = nr.is1904(); } else if (r.getType() == Type.FORMAT) { FormatRecord fr = null; if (bof.isBiff8()) fr = new FormatRecord(r,settings,FormatRecord.biff8); else fr = new FormatRecord(r,settings,FormatRecord.biff7); try { formattingRecords.addFormat(fr); } catch (NumFormatRecordsException e) { // This should not happen. Bomb out Assert.verify(false,e.Message); } } else if (r.getType() == Type.XF) { XFRecord xfr = null; if (bof.isBiff8()) xfr = new XFRecord(r,settings,XFRecord.biff8); else xfr = new XFRecord(r,settings,XFRecord.biff7); try { formattingRecords.addStyle(xfr); } catch (NumFormatRecordsException e) { // This should not happen. Bomb out Assert.verify(false,e.Message); } } else if (r.getType() == Type.BOUNDSHEET) { BoundsheetRecord br = null; if (bof.isBiff8()) br = new BoundsheetRecord(r,settings); else br = new BoundsheetRecord(r,BoundsheetRecord.biff7); if (br.isSheet()) boundsheets.Add(br); else if (br.isChart() && !settings.getDrawingsDisabled()) boundsheets.Add(br); } else if (r.getType() == Type.EXTERNSHEET) { if (bof.isBiff8()) externSheet = new ExternalSheetRecord(r,settings); else externSheet = new ExternalSheetRecord(r,settings,ExternalSheetRecord.biff7); } else if (r.getType() == Type.XCT) { XCTRecord xctr = new XCTRecord(r); xctRecords.Add(xctr); } else if (r.getType() == Type.CODEPAGE) { CodepageRecord cr = new CodepageRecord(r); settings.setCharacterSet(cr.getCharacterSet()); } else if (r.getType() == Type.SUPBOOK) { Record nextrec = excelFile.peek(); while (nextrec.getType() == Type.CONTINUE) { r.addContinueRecord(excelFile.next()); nextrec = excelFile.peek(); } SupbookRecord sr = new SupbookRecord(r,settings); supbooks.Add(sr); } else if (r.getType() == Type.EXTERNNAME) { ExternalNameRecord enr = new ExternalNameRecord(r,settings); if (enr.isAddInFunction()) { addInFunctions.Add(enr.getName()); } } else if (r.getType() == Type.PROTECT) { ProtectRecord pr = new ProtectRecord(r); wbProtected = pr.isProtected(); } else if (r.getType() == Type.OBJPROJ) { doesContainMacros = true; } else if (r.getType() == Type.COUNTRY) { countryRecord = new CountryRecord(r); } else if (r.getType() == Type.MSODRAWINGGROUP) { if (!settings.getDrawingsDisabled()) { msoDrawingGroup = new MsoDrawingGroupRecord(r); if (drawingGroup == null) { drawingGroup = new DrawingGroup(Origin.READ); } drawingGroup.add(msoDrawingGroup); Record nextrec = excelFile.peek(); while (nextrec.getType() == Type.CONTINUE) { drawingGroup.add(excelFile.next()); nextrec = excelFile.peek(); } } } else if (r.getType() == Type.BUTTONPROPERTYSET) buttonPropertySet = new ButtonPropertySetRecord(r); else if (r.getType() == Type.EOF) bofs--; else if (r.getType() == Type.REFRESHALL) { RefreshAllRecord rfm = new RefreshAllRecord(r); settings.setRefreshAll(rfm.getRefreshAll()); } else if (r.getType() == Type.TEMPLATE) { TemplateRecord rfm = new TemplateRecord(r); settings.setTemplate(rfm.getTemplate()); } else if (r.getType() == Type.EXCEL9FILE) { Excel9FileRecord e9f = new Excel9FileRecord(r); settings.setExcel9File(e9f.getExcel9File()); } else if (r.getType() == Type.WINDOWPROTECT) { WindowProtectedRecord winp = new WindowProtectedRecord(r); settings.setWindowProtected(winp.getWindowProtected()); } else if (r.getType() == Type.HIDEOBJ) { HideobjRecord hobj = new HideobjRecord(r); settings.setHideobj(hobj.getHideMode()); } else if (r.getType() == Type.WRITEACCESS) { WriteAccessRecord war = new WriteAccessRecord(r,bof.isBiff8(),settings); settings.setWriteAccess(war.getWriteAccess()); } else { // logger.info("Unsupported record type: " + // Integer.toHexString(r.getCode())+"h"); } } bof = null; if (excelFile.hasNext()) { r = excelFile.next(); if (r.getType() == Type.BOF) bof = new BOFRecord(r); } // Only get sheets for which there is a corresponding Boundsheet record while (bof != null && getNumberOfSheets() < boundsheets.Count) { if (!bof.isBiff8() && !bof.isBiff7()) throw new BiffException(BiffException.unrecognizedBiffVersion); if (bof.isWorksheet()) { // Read the sheet in SheetImpl s = new SheetImpl(excelFile, sharedStrings, formattingRecords, bof, workbookBof, nineteenFour, this); BoundsheetRecord br = (BoundsheetRecord)boundsheets[getNumberOfSheets()]; s.setName(br.getName()); s.setHidden(br.isHidden()); addSheet(s); } else if (bof.isChart()) { // Read the sheet in SheetImpl s = new SheetImpl(excelFile, sharedStrings, formattingRecords, bof, workbookBof, nineteenFour, this); BoundsheetRecord br = (BoundsheetRecord)boundsheets[getNumberOfSheets()]; s.setName(br.getName()); s.setHidden(br.isHidden()); addSheet(s); } else { //logger.warn("BOF is unrecognized"); while (excelFile.hasNext() && r.getType() != Type.EOF) r = excelFile.next(); } // The next record will normally be a BOF or empty padding until // the end of the block is reached. In exceptionally unlucky cases, // the last EOF will coincide with a block division, so we have to // check there is more data to retrieve. // Thanks to liamg for spotting this bof = null; if (excelFile.hasNext()) { r = excelFile.next(); if (r.getType() == Type.BOF) bof = new BOFRecord(r); } } // Add all the local names to the specific sheets foreach (NameRecord nr in localNames) { if (nr.getBuiltInName() == null) { //logger.warn("Usage of a local non-builtin name"); } else if (nr.getBuiltInName() == BuiltInName.PRINT_AREA || nr.getBuiltInName() == BuiltInName.PRINT_TITLES) { // appears to use the internal tab number rather than the // external sheet index SheetImpl s = (SheetImpl)sheets[nr.getSheetRef() - 1]; s.addLocalName(nr); } } }
/** * Constructor * * @param fnt the font * @param form the format */ public CellXFRecord(FontRecord fnt, DisplayFormat form) : base(fnt, form) { setXFDetails(XFRecord.cell, 0); }
/** * Constructor * * @param fnt the font for this style * @param form the format of this style */ public StyleXFRecord(FontRecord fnt, DisplayFormat form) : base(fnt, form) { setXFDetails(XFRecord.style, 0xfff0); }
/** * A public copy constructor which can be used for copy formats between * different sheets. Unlike the the other copy constructor, this * version does a deep copy * * @param cellFormat the format to copy */ protected XFRecord(CellFormat cellFormat) : base(Type.XF) { Assert.verify(cellFormat != null); Assert.verify(cellFormat is XFRecord); XFRecord fmt = (XFRecord)cellFormat; if (!fmt.formatInfoInitialized) { fmt.initializeFormatInformation(); } locked = fmt.locked; hidden = fmt.hidden; align = fmt.align; valign = fmt.valign; orientation = fmt.orientation; wrap = fmt.wrap; leftBorder = fmt.leftBorder; rightBorder = fmt.rightBorder; topBorder = fmt.topBorder; bottomBorder = fmt.bottomBorder; leftBorderColour = fmt.leftBorderColour; rightBorderColour = fmt.rightBorderColour; topBorderColour = fmt.topBorderColour; bottomBorderColour = fmt.bottomBorderColour; pattern = fmt.pattern; xfFormatType = fmt.xfFormatType; parentFormat = fmt.parentFormat; indentation = fmt.indentation; shrinkToFit = fmt.shrinkToFit; backgroundColour = fmt.backgroundColour; // Deep copy of the font font = new FontRecord(fmt.getFont()); // Copy the format if (fmt.getFormat() == null) { // format is writable if (fmt.format.isBuiltIn()) { format = fmt.format; } else { // Format is not built in, so do a deep copy format = new FormatRecord((FormatRecord)fmt.format); } } else if (fmt.getFormat() is BuiltInFormat) { // read excel format is built in excelFormat = (BuiltInFormat)fmt.excelFormat; format = (BuiltInFormat)fmt.excelFormat; } else { // read excel format is user defined Assert.verify(fmt.formatInfoInitialized); // in this case FormattingRecords should initialize the excelFormat // field with an instance of FormatRecord Assert.verify(fmt.excelFormat is FormatRecord); // Format is not built in, so do a deep copy FormatRecord fr = new FormatRecord((FormatRecord)fmt.excelFormat); // Set both format fields to be the same object, since // FormatRecord implements all the necessary interfaces excelFormat = fr; format = fr; } biffType = biff8; // The format info should be all OK by virtue of the deep copy formatInfoInitialized = true; // This format was not read in read = false; // Treat this as a new cell record, so set the copied flag to false copied = false; // The font or format indexes need to be set, so set initialized to false initialized = false; }
/** * Copy constructor. Used for copying writable formats, typically * when duplicating formats to handle merged cells * * @param fmt XFRecord */ protected XFRecord(XFRecord fmt) : base(Type.XF) { initialized = false; locked = fmt.locked; hidden = fmt.hidden; align = fmt.align; valign = fmt.valign; orientation = fmt.orientation; wrap = fmt.wrap; leftBorder = fmt.leftBorder; rightBorder = fmt.rightBorder; topBorder = fmt.topBorder; bottomBorder = fmt.bottomBorder; leftBorderColour = fmt.leftBorderColour; rightBorderColour = fmt.rightBorderColour; topBorderColour = fmt.topBorderColour; bottomBorderColour = fmt.bottomBorderColour; pattern = fmt.pattern; xfFormatType = fmt.xfFormatType; indentation = fmt.indentation; shrinkToFit = fmt.shrinkToFit; parentFormat = fmt.parentFormat; backgroundColour = fmt.backgroundColour; // Shallow copy is sufficient for these purposes font = fmt.font; format = fmt.format; fontIndex = fmt.fontIndex; formatIndex = fmt.formatIndex; formatInfoInitialized = fmt.formatInfoInitialized; biffType = biff8; read = false; copied = true; }
/** * A constructor used when creating a writable record * * @param fnt the font * @param form the format */ public XFRecord(FontRecord fnt,DisplayFormat form) : base(Type.XF) { initialized = false; locked = true; hidden = false; align = Alignment.GENERAL; valign = VerticalAlignment.BOTTOM; orientation = Orientation.HORIZONTAL; wrap = false; leftBorder = BorderLineStyle.NONE; rightBorder = BorderLineStyle.NONE; topBorder = BorderLineStyle.NONE; bottomBorder = BorderLineStyle.NONE; leftBorderColour = Colour.AUTOMATIC; rightBorderColour = Colour.AUTOMATIC; topBorderColour = Colour.AUTOMATIC; bottomBorderColour = Colour.AUTOMATIC; pattern = Pattern.NONE; backgroundColour = Colour.DEFAULT_BACKGROUND; indentation = 0; shrinkToFit = false; usedAttributes = (byte)(USE_FONT | USE_FORMAT | USE_BACKGROUND | USE_ALIGNMENT | USE_BORDER); // This will be set by the initialize method and the subclass respectively parentFormat = 0; xfFormatType = null; font = fnt; format = form; biffType = biff8; read = false; copied = false; formatInfoInitialized = true; Assert.verify(font != null); Assert.verify(format != null); }
/** * Initializes the internal format information from the data read in */ private void initializeFormatInformation() { // Initialize the cell format string if (formatIndex < BuiltInFormat.builtIns.Length && BuiltInFormat.builtIns[formatIndex] != null) { excelFormat = BuiltInFormat.builtIns[formatIndex]; } else { excelFormat = formattingRecords.getFormatRecord(formatIndex); } // Initialize the font font = formattingRecords.getFonts().getFont(fontIndex); // Initialize the cell format data from the binary record byte[] data = getRecord().getData(); // Get the parent record int cellAttributes = IntegerHelper.getInt(data[4],data[5]); parentFormat = (cellAttributes & 0xfff0) >> 4; int formatType = cellAttributes & 0x4; xfFormatType = formatType == 0 ? cell : style; locked = ((cellAttributes & 0x1) != 0); hidden = ((cellAttributes & 0x2) != 0); if (xfFormatType == cell && (parentFormat & 0xfff) == 0xfff) { // Something is screwy with the parent format - set to zero parentFormat = 0; //logger.warn("Invalid parent format found - ignoring"); } int alignMask = IntegerHelper.getInt(data[6],data[7]); // Get the wrap if ((alignMask & 0x08) != 0) wrap = true; // Get the horizontal alignment align = Alignment.getAlignment(alignMask & 0x7); // Get the vertical alignment valign = VerticalAlignment.getAlignment((alignMask >> 4) & 0x7); // Get the orientation orientation = Orientation.getOrientation((alignMask >> 8) & 0xff); int attr = IntegerHelper.getInt(data[8],data[9]); // Get the indentation indentation = attr & 0x0F; // Get the shrink to fit flag shrinkToFit = (attr & 0x10) != 0; // Get the used attribute if (biffType == biff8) usedAttributes = data[9]; // Get the borders int borderMask = IntegerHelper.getInt(data[10],data[11]); leftBorder = BorderLineStyle.getStyle(borderMask & 0x7); rightBorder = BorderLineStyle.getStyle((borderMask >> 4) & 0x7); topBorder = BorderLineStyle.getStyle((borderMask >> 8) & 0x7); bottomBorder = BorderLineStyle.getStyle((borderMask >> 12) & 0x7); int borderColourMask = IntegerHelper.getInt(data[12],data[13]); leftBorderColour = Colour.getInternalColour(borderColourMask & 0x7f); rightBorderColour = Colour.getInternalColour ((borderColourMask & 0x3f80) >> 7); borderColourMask = IntegerHelper.getInt(data[14],data[15]); topBorderColour = Colour.getInternalColour(borderColourMask & 0x7f); bottomBorderColour = Colour.getInternalColour ((borderColourMask & 0x3f80) >> 7); if (biffType == biff8) { // Get the background pattern. This is the six most significant bits int patternVal = IntegerHelper.getInt(data[16],data[17]); patternVal = patternVal & 0xfc00; patternVal = patternVal >> 10; pattern = Pattern.getPattern(patternVal); // Get the background colour int colourPaletteMask = IntegerHelper.getInt(data[18],data[19]); backgroundColour = Colour.getInternalColour(colourPaletteMask & 0x3f); if (backgroundColour == Colour.UNKNOWN || backgroundColour == Colour.DEFAULT_BACKGROUND1) { backgroundColour = Colour.DEFAULT_BACKGROUND; } } else { pattern = Pattern.NONE; backgroundColour = Colour.DEFAULT_BACKGROUND; } // Set the lazy initialization flag formatInfoInitialized = true; }
/** * Sets the font object with a workbook specific clone. Called from * the CellValue object when the font has been identified as a statically * shared font * Also called to superimpose a HyperlinkFont on an existing label cell */ public void setFont(FontRecord f) { // This style cannot be initialized, otherwise it would mean it would // have been initialized with shared font // However, sometimes (when setting a row or column format) an initialized // XFRecord may have its font overridden by the column/row font = f; }