/// <summary> /// Initializes a new instance of the <see cref="HSSFFont"/> class. /// </summary> /// <param name="index">The index.</param> /// <param name="rec">The record.</param> public HSSFFont(short index, FontRecord rec) { font = rec; this.index = index; }
/** * Does this FontRecord have all the same font * properties as the supplied FontRecord? * Note that {@link #equals(Object)} will check * for exact objects, while this will check * for exact contents, because normally the * font record's position makes a big * difference too. */ public bool SameProperties(FontRecord other) { return field_1_font_height == other.field_1_font_height && field_2_attributes == other.field_2_attributes && field_3_color_palette_index == other.field_3_color_palette_index && field_4_bold_weight == other.field_4_bold_weight && field_5_base_sub_script == other.field_5_base_sub_script && field_6_underline == other.field_6_underline && field_7_family == other.field_7_family && field_8_charset == other.field_8_charset && field_9_zero == other.field_9_zero && field_11_font_name.Equals(other.field_11_font_name); }
/// <summary> /// Goes through the Workbook, optimising the fonts by /// removing duplicate ones. /// For now, only works on fonts used in HSSFCellStyle /// and HSSFRichTextString. Any other font uses /// (eg charts, pictures) may well end up broken! /// This can be a slow operation, especially if you have /// lots of cells, cell styles or rich text strings /// </summary> /// <param name="workbook">The workbook in which to optimise the fonts</param> public static void OptimiseFonts(HSSFWorkbook workbook) { // Where each font has ended up, and if we need to // delete the record for it. Start off with no change short[] newPos = new short[workbook.Workbook.NumberOfFontRecords + 1]; bool[] zapRecords = new bool[newPos.Length]; for (int i = 0; i < newPos.Length; i++) { newPos[i] = (short)i; zapRecords[i] = false; } // Get each font record, so we can do deletes // without Getting confused FontRecord[] frecs = new FontRecord[newPos.Length]; for (int i = 0; i < newPos.Length; i++) { // There is no 4! if (i == 4) continue; frecs[i] = workbook.Workbook.GetFontRecordAt(i); } // Loop over each font, seeing if it is the same // as an earlier one. If it is, point users of the // later duplicate copy to the earlier one, and // mark the later one as needing deleting // Note - don't change built in fonts (those before 5) for (int i = 5; i < newPos.Length; i++) { // Check this one for being a duplicate // of an earlier one int earlierDuplicate = -1; for (int j = 0; j < i && earlierDuplicate == -1; j++) { if (j == 4) continue; FontRecord frCheck = workbook.Workbook.GetFontRecordAt(j); if (frCheck.SameProperties(frecs[i])) { earlierDuplicate = j; } } // If we got a duplicate, mark it as such if (earlierDuplicate != -1) { newPos[i] = (short)earlierDuplicate; zapRecords[i] = true; } } // Update the new positions based on // deletes that have occurred between // the start and them // Only need to worry about user fonts for (int i = 5; i < newPos.Length; i++) { // Find the number deleted to that // point, and adjust short preDeletePos = newPos[i]; short newPosition = preDeletePos; for (int j = 0; j < preDeletePos; j++) { if (zapRecords[j]) newPosition--; } // Update the new position newPos[i] = newPosition; } // Zap the un-needed user font records for (int i = 5; i < newPos.Length; i++) { if (zapRecords[i]) { workbook.Workbook.RemoveFontRecord( frecs[i] ); } } // Tell HSSFWorkbook that it needs to // re-start its HSSFFontCache workbook.ResetFontCache(); // Update the cell styles to point at the // new locations of the fonts for (int i = 0; i < workbook.Workbook.NumExFormats; i++) { ExtendedFormatRecord xfr = workbook.Workbook.GetExFormatAt(i); xfr.FontIndex = ( newPos[xfr.FontIndex] ); } // Update the rich text strings to point at // the new locations of the fonts // Remember that one underlying unicode string // may be shared by multiple RichTextStrings! ArrayList doneUnicodeStrings = new ArrayList(); for (int sheetNum = 0; sheetNum < workbook.NumberOfSheets; sheetNum++) { LF.Utils.NPOI.SS.UserModel.ISheet s = workbook.GetSheetAt(sheetNum); IEnumerator rIt = s.GetRowEnumerator(); while (rIt.MoveNext()) { HSSFRow row = (HSSFRow)rIt.Current; IEnumerator cIt = row.GetEnumerator(); while (cIt.MoveNext()) { ICell cell = (HSSFCell)cIt.Current; if (cell.CellType == LF.Utils.NPOI.SS.UserModel.CellType.STRING) { HSSFRichTextString rtr = (HSSFRichTextString)cell.RichStringCellValue; UnicodeString u = rtr.RawUnicodeString; // Have we done this string already? if (!doneUnicodeStrings.Contains(u)) { // Update for each new position for (short i = 5; i < newPos.Length; i++) { if (i != newPos[i]) { u.SwapFontUse(i, newPos[i]); } } // Mark as done doneUnicodeStrings.Add(u); } } } } } }
/** * Clones all the font style information from another * FontRecord, onto this one. This * will then hold all the same font style options. */ public void CloneStyleFrom(FontRecord source) { field_1_font_height = source.field_1_font_height; field_2_attributes = source.field_2_attributes; field_3_color_palette_index = source.field_3_color_palette_index; field_4_bold_weight = source.field_4_bold_weight; field_5_base_sub_script = source.field_5_base_sub_script; field_6_underline = source.field_6_underline; field_7_family = source.field_7_family; field_8_charset = source.field_8_charset; field_9_zero = source.field_9_zero; field_11_font_name = source.field_11_font_name; }