/********************************************************************* * * Copyright (C) 2002 Andrew Khan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ***************************************************************************/ package jxl.biff; import common.Assert; import common.Logger; import jxl.WorkbookSettings; import jxl.format.Colour; import jxl.format.Font; import jxl.format.ScriptStyle; import jxl.format.UnderlineStyle; import jxl.read.biff.Record; /** * A record containing the necessary data for the font information */ public class FontRecord extends WritableRecordData implements Font { /** * The logger */ private static Logger logger = Logger.getLogger(FontRecord.class); /** * The point height of this font */ private int pointHeight; /** * The index into the colour palette */ private int colourIndex; /** * The bold weight for this font (normal or bold) */ private int boldWeight; /** * The style of the script (italic or normal) */ private int scriptStyle; /** * The underline style for this font (none, single, double etc) */ private int underlineStyle; /** * The font family */ private byte fontFamily; /** * The character set */ private byte characterSet; /** * Indicates whether or not this font is italic */ private boolean italic; /** * Indicates whether or not this font is struck out */ private boolean struckout; /** * The name of this font */ private String name; /** * Flag to indicate whether the derived data (such as the font index) has * been initialized or not */ private boolean initialized; /** * The index of this font in the font list */ private int fontIndex; /** * Dummy indicators for overloading the constructor */ private static class Biff7 {}; public static final Biff7 biff7 = new Biff7(); /** * The conversion factor between microsoft internal units and point size */ private static final int EXCEL_UNITS_PER_POINT = 20; /** * Constructor, used when creating a new font for writing out. * * @param bold the bold indicator * @param ps the point size * @param us the underline style * @param fn the name * @param it italicised indicator * @param ss the script style * @param ci the colour index */ protected FontRecord(String fn, int ps, int bold, boolean it, int us, int ci, int ss) { super(Type.FONT); boldWeight = bold; underlineStyle = us; name = fn; pointHeight = ps; italic = it; scriptStyle = ss; colourIndex = ci; initialized = false; struckout = false; } /** * Constructs this object from the raw data. Used when reading in a * format record * * @param t the raw data * @param ws the workbook settings */ public FontRecord(Record t, WorkbookSettings ws) { super(t); byte[] data = getRecord().getData(); pointHeight = IntegerHelper.getInt(data[0], data[1]) / EXCEL_UNITS_PER_POINT; colourIndex = IntegerHelper.getInt(data[4], data[5]); boldWeight = IntegerHelper.getInt(data[6], data[7]); scriptStyle = IntegerHelper.getInt(data[8], data[9]); underlineStyle = data[10]; fontFamily = data[11]; characterSet = data[12]; initialized = false; if ((data[2] & 0x02) != 0) { italic = true; } if ((data[2] & 0x08) != 0) { struckout = true; } int numChars = data[14]; if (data[15] == 0) { name = StringHelper.getString(data, numChars, 16, ws); } else if (data[15] == 1) { name = StringHelper.getUnicodeString(data, numChars, 16); } else { // Some font names don't have the unicode indicator name = StringHelper.getString(data, numChars, 15, ws); } } /** * Constructs this object from the raw data. Used when reading in a * format record * * @param t the raw data * @param ws the workbook settings * @param dummy dummy overload */ public FontRecord(Record t, WorkbookSettings ws, Biff7 dummy) { super(t); byte[] data = getRecord().getData(); pointHeight = IntegerHelper.getInt(data[0], data[1]) / EXCEL_UNITS_PER_POINT; colourIndex = IntegerHelper.getInt(data[4], data[5]); boldWeight = IntegerHelper.getInt(data[6], data[7]); scriptStyle = IntegerHelper.getInt(data[8], data[9]); underlineStyle = data[10]; fontFamily = data[11]; initialized = false; if ((data[2] & 0x02) != 0) { italic = true; } if ((data[2] & 0x08) != 0) { struckout = true; } int numChars = data[14]; name = StringHelper.getString(data, numChars, 15, ws); } /** * Publicly available copy constructor * * @param f the font to copy */ protected FontRecord(Font f) { super(Type.FONT); Assert.verify(f != null); pointHeight = f.getPointSize(); colourIndex = f.getColour().getValue(); boldWeight = f.getBoldWeight(); scriptStyle = f.getScriptStyle().getValue(); underlineStyle = f.getUnderlineStyle().getValue(); italic = f.isItalic(); name = f.getName(); struckout = f.isStruckout(); initialized = false; } /** * Gets the byte data for writing out * * @return the raw data */ public byte[] getData() { byte[] data = new byte[16 + name.length() * 2]; // Excel expects font heights in 1/20ths of a point IntegerHelper.getTwoBytes(pointHeight * EXCEL_UNITS_PER_POINT, data, 0); // Set the font attributes to be zero for now if (italic) { data[2] |= 0x2; } if (struckout) { data[2] |= 0x08; } // Set the index to the colour palette IntegerHelper.getTwoBytes(colourIndex, data, 4); // Bold style IntegerHelper.getTwoBytes(boldWeight, data, 6); // Script style IntegerHelper.getTwoBytes(scriptStyle, data, 8); // Underline style data[10] = (byte) underlineStyle; // Set the font family to be 0 data[11] = fontFamily; // Set the character set to be zero data[12] = characterSet; // Set the reserved bit to be zero data[13] = 0; // Set the length of the font name data[14] = (byte) name.length(); data[15] = (byte) 1; // Copy in the string StringHelper.getUnicodeBytes(name, data, 16); return data; } /** * Accessor to see whether this object is initialized or not. * * @return TRUE if this font record has been initialized, FALSE otherwise */ public final boolean isInitialized() { return initialized; } /** * Sets the font index of this record. Called from the FormattingRecords * object * * @param pos the position of this font in the workbooks font list */ public final void initialize(int pos) { fontIndex = pos; initialized = true; } /** * Resets the initialize flag. This is called by the constructor of * WritableWorkbookImpl to reset the statically declared fonts */ public final void uninitialize() { initialized = false; } /** * Accessor for the font index * * @return the font index */ public final int getFontIndex() { return fontIndex; } /** * Sets the point size for this font, if the font hasn't been initialized * * @param ps the point size */ protected void setFontPointSize(int ps) { Assert.verify(!initialized); pointHeight = ps; } /** * Gets the point size for this font, if the font hasn't been initialized * * @return the point size */ public int getPointSize() { return pointHeight; } /** * Sets the bold style for this font, if the font hasn't been initialized * * @param bs the bold style */ protected void setFontBoldStyle(int bs) { Assert.verify(!initialized); boldWeight = bs; } /** * Gets the bold weight for this font * * @return the bold weight for this font */ public int getBoldWeight() { return boldWeight; } /** * Sets the italic indicator for this font, if the font hasn't been * initialized * * @param i the italic flag */ protected void setFontItalic(boolean i) { Assert.verify(!initialized); italic = i; } /** * Returns the italic flag * * @return TRUE if this font is italic, FALSE otherwise */ public boolean isItalic() { return italic; } /** * Sets the underline style for this font, if the font hasn't been * initialized * * @param us the underline style */ protected void setFontUnderlineStyle(int us) { Assert.verify(!initialized); underlineStyle = us; } /** * Gets the underline style for this font * * @return the underline style */ public UnderlineStyle getUnderlineStyle() { return UnderlineStyle.getStyle(underlineStyle); } /** * Sets the colour for this font, if the font hasn't been * initialized * * @param c the colour */ protected void setFontColour(int c) { Assert.verify(!initialized); colourIndex = c; } /** * Gets the colour for this font * * @return the colour */ public Colour getColour() { return Colour.getInternalColour(colourIndex); } /** * Sets the script style (eg. superscript, subscript) for this font, * if the font hasn't been initialized * * @param ss the colour */ protected void setFontScriptStyle(int ss) { Assert.verify(!initialized); scriptStyle = ss; } /** * Gets the script style * * @return the script style */ public ScriptStyle getScriptStyle() { return ScriptStyle.getStyle(scriptStyle); } /** * Gets the name of this font * * @return the name of this font */ public String getName() { return name; } /** * Standard hash code method * @return the hash code for this object */ public int hashCode() { return name.hashCode(); } /** * Standard equals method * @param o the object to compare * @return TRUE if the objects are equal, FALSE otherwise */ public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof 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; } /** * Accessor for the strike out flag * * @return TRUE if this font is struck out, FALSE otherwise */ public boolean isStruckout() { return struckout; } /** * Sets the struck out flag * * @param os TRUE if the font is struck out, false otherwise */ protected void setFontStruckout(boolean os) { struckout = os; } }