You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2015/07/19 21:00:38 UTC

svn commit: r1691843 [5/30] - in /poi/branches/common_sl: ./ .settings/ legal/ osgi/ osgi/src/ src/examples/src/org/apache/poi/hpsf/examples/ src/examples/src/org/apache/poi/hssf/usermodel/examples/ src/examples/src/org/apache/poi/ss/examples/ src/exam...

Modified: poi/branches/common_sl/src/java/org/apache/poi/hssf/record/cf/CellRangeUtil.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/java/org/apache/poi/hssf/record/cf/CellRangeUtil.java?rev=1691843&r1=1691842&r2=1691843&view=diff
==============================================================================
--- poi/branches/common_sl/src/java/org/apache/poi/hssf/record/cf/CellRangeUtil.java (original)
+++ poi/branches/common_sl/src/java/org/apache/poi/hssf/record/cf/CellRangeUtil.java Sun Jul 19 19:00:32 2015
@@ -23,97 +23,93 @@ import java.util.List;
 import org.apache.poi.ss.util.CellRangeAddress;
 
 /**
- * 
- * @author Dmitriy Kumshayev
+ * TODO Should this move to org.apache.poi.ss.util ?
  */
-public final class CellRangeUtil
-{
-	
-	private CellRangeUtil() {
-		// no instance of this class
-	}
-	
-	public static final int NO_INTERSECTION = 1;
-	public static final int OVERLAP = 2;
-	/** first range is within the second range */
-	public static final int INSIDE = 3;
-	/** first range encloses or is equal to the second */
-	public static final int ENCLOSES = 4;
-	
-	/**
-	 * Intersect this range with the specified range.
-	 * 
-	 * @param crB - the specified range
-	 * @return code which reflects how the specified range is related to this range.<br/>
-	 * Possible return codes are:	
-	 * 		NO_INTERSECTION - the specified range is outside of this range;<br/> 
-	 * 		OVERLAP - both ranges partially overlap;<br/>
-	 * 		INSIDE - the specified range is inside of this one<br/>
-	 * 		ENCLOSES - the specified range encloses (possibly exactly the same as) this range<br/>
-	 */
-	public static int intersect(CellRangeAddress crA, CellRangeAddress crB )
-	{
-		
-		int firstRow = crB.getFirstRow();
-		int lastRow  = crB.getLastRow();
-		int firstCol = crB.getFirstColumn();
-		int lastCol  = crB.getLastColumn();
-		
-		if
-		( 
+public final class CellRangeUtil {
+    private CellRangeUtil() {
+        // no instance of this class
+    }
+
+    public static final int NO_INTERSECTION = 1;
+    public static final int OVERLAP = 2;
+    /** first range is within the second range */
+    public static final int INSIDE = 3;
+    /** first range encloses or is equal to the second */
+    public static final int ENCLOSES = 4;
+
+    /**
+     * Intersect this range with the specified range.
+     * 
+     * @param crB - the specified range
+     * @return code which reflects how the specified range is related to this range.<br/>
+     * Possible return codes are:	
+     * 		NO_INTERSECTION - the specified range is outside of this range;<br/> 
+     * 		OVERLAP - both ranges partially overlap;<br/>
+     * 		INSIDE - the specified range is inside of this one<br/>
+     * 		ENCLOSES - the specified range encloses (possibly exactly the same as) this range<br/>
+     */
+    public static int intersect(CellRangeAddress crA, CellRangeAddress crB )
+    {
+
+        int firstRow = crB.getFirstRow();
+        int lastRow  = crB.getLastRow();
+        int firstCol = crB.getFirstColumn();
+        int lastCol  = crB.getLastColumn();
+
+        if
+        ( 
 				gt(crA.getFirstRow(),lastRow) || 
 				lt(crA.getLastRow(),firstRow) ||
 				gt(crA.getFirstColumn(),lastCol) || 
 				lt(crA.getLastColumn(),firstCol) 
-		)
-		{
-			return NO_INTERSECTION;
-		}
-		else if( contains(crA, crB) )
-		{
-			return INSIDE;
-		}
-		else if( contains(crB, crA))
-		{
-			return ENCLOSES;
-		}
-		else
-		{
-			return OVERLAP;
-		}
-			
-	}
-	
-	/**
-	 * Do all possible cell merges between cells of the list so that:<br>
-	 * 	<li>if a cell range is completely inside of another cell range, it gets removed from the list 
-	 * 	<li>if two cells have a shared border, merge them into one bigger cell range
-	 * @param cellRanges
-	 * @return updated List of cell ranges
-	 */
-	public static CellRangeAddress[] mergeCellRanges(CellRangeAddress[] cellRanges) {
-		if(cellRanges.length < 1) {
-			return cellRanges;
-		}
+        )
+        {
+            return NO_INTERSECTION;
+        }
+        else if( contains(crA, crB) )
+        {
+            return INSIDE;
+        }
+        else if( contains(crB, crA))
+        {
+            return ENCLOSES;
+        }
+        else
+        {
+            return OVERLAP;
+        }
+    }
+
+    /**
+     * Do all possible cell merges between cells of the list so that:<br>
+     * 	<li>if a cell range is completely inside of another cell range, it gets removed from the list 
+     * 	<li>if two cells have a shared border, merge them into one bigger cell range
+     * @param cellRanges
+     * @return updated List of cell ranges
+     */
+    public static CellRangeAddress[] mergeCellRanges(CellRangeAddress[] cellRanges) {
+        if(cellRanges.length < 1) {
+            return cellRanges;
+        }
 
         List<CellRangeAddress> lst = new ArrayList<CellRangeAddress>();
         for(CellRangeAddress cr : cellRanges) {
             lst.add(cr);
         }
         List<CellRangeAddress> temp = mergeCellRanges(lst);
-		return toArray(temp);
-	}
+        return toArray(temp);
+    }
 
-	private static List<CellRangeAddress> mergeCellRanges(List<CellRangeAddress> cellRangeList)
-	{
-	    // loop until either only one item is left or we did not merge anything any more
+    private static List<CellRangeAddress> mergeCellRanges(List<CellRangeAddress> cellRangeList)
+    {
+        // loop until either only one item is left or we did not merge anything any more
         while (cellRangeList.size() > 1) {
             boolean somethingGotMerged = false;
 
             // look at all cell-ranges
             for (int i = 0; i < cellRangeList.size(); i++) {
                 CellRangeAddress range1 = cellRangeList.get(i);
-                
+
                 // compare each cell range to all other cell-ranges
                 for (int j = i + 1; j < cellRangeList.size(); j++) {
                     CellRangeAddress range2 = cellRangeList.get(j);
@@ -139,16 +135,16 @@ public final class CellRangeUtil
             }
         }
 
-		return cellRangeList;
-	}
-	
-	/**
-	 * @return the new range(s) to replace the supplied ones.  <code>null</code> if no merge is possible
-	 */
-	private static CellRangeAddress[] mergeRanges(CellRangeAddress range1, CellRangeAddress range2) {
-		int x = intersect(range1, range2);
-		switch(x)
-		{
+        return cellRangeList;
+    }
+
+    /**
+     * @return the new range(s) to replace the supplied ones.  <code>null</code> if no merge is possible
+     */
+    private static CellRangeAddress[] mergeRanges(CellRangeAddress range1, CellRangeAddress range2) {
+        int x = intersect(range1, range2);
+        switch(x)
+        {
 			case CellRangeUtil.NO_INTERSECTION: 
 			    // nothing in common: at most they could be adjacent to each other and thus form a single bigger area  
 				if(hasExactSharedBorder(range1, range2)) {
@@ -171,108 +167,103 @@ public final class CellRangeUtil
 		throw new RuntimeException("unexpected intersection result (" + x + ")");
 	}
 
-	
-	private static CellRangeAddress[] toArray(List<CellRangeAddress> temp) {
-		CellRangeAddress[] result = new CellRangeAddress[temp.size()];
-		temp.toArray(result);
-		return result;
-	}
-
-
+    private static CellRangeAddress[] toArray(List<CellRangeAddress> temp) {
+        CellRangeAddress[] result = new CellRangeAddress[temp.size()];
+        temp.toArray(result);
+        return result;
+    }
+
+    /**
+     *  Check if the specified range is located inside of this cell range.
+     *  
+     * @param crB
+     * @return true if this cell range contains the argument range inside if it's area
+     */
+    public static boolean contains(CellRangeAddress crA, CellRangeAddress crB)
+    {
+        int firstRow = crB.getFirstRow();
+        int lastRow = crB.getLastRow();
+        int firstCol = crB.getFirstColumn();
+        int lastCol = crB.getLastColumn();
+        return le(crA.getFirstRow(), firstRow) && ge(crA.getLastRow(), lastRow)
+                && le(crA.getFirstColumn(), firstCol) && ge(crA.getLastColumn(), lastCol);
+    }
+
+    /**
+     * Check if the two cell ranges have a shared border.
+     * 
+     * @return <code>true</code> if the ranges have a complete shared border (i.e.
+     * the two ranges together make a simple rectangular region.
+     */
+    public static boolean hasExactSharedBorder(CellRangeAddress crA, CellRangeAddress crB) {
+        int oFirstRow = crB.getFirstRow();
+        int oLastRow  = crB.getLastRow();
+        int oFirstCol = crB.getFirstColumn();
+        int oLastCol  = crB.getLastColumn();
+
+        if (crA.getFirstRow() > 0 && crA.getFirstRow()-1 == oLastRow || 
+                oFirstRow > 0 && oFirstRow-1 == crA.getLastRow()) {
+            // ranges have a horizontal border in common
+            // make sure columns are identical:
+            return crA.getFirstColumn() == oFirstCol && crA.getLastColumn() == oLastCol;
+        }
 
-	/**
-	 *  Check if the specified range is located inside of this cell range.
-	 *  
-	 * @param crB
-	 * @return true if this cell range contains the argument range inside if it's area
-	 */
-   public static boolean contains(CellRangeAddress crA, CellRangeAddress crB)
-   {
-		int firstRow = crB.getFirstRow();
-		int lastRow = crB.getLastRow();
-		int firstCol = crB.getFirstColumn();
-		int lastCol = crB.getLastColumn();
-		return le(crA.getFirstRow(), firstRow) && ge(crA.getLastRow(), lastRow)
-				&& le(crA.getFirstColumn(), firstCol) && ge(crA.getLastColumn(), lastCol);
-	}
-   	
-   /**
-	* Check if the two cell ranges have a shared border.
-	* 
-	* @return <code>true</code> if the ranges have a complete shared border (i.e.
-	* the two ranges together make a simple rectangular region.
-	*/
-   	public static boolean hasExactSharedBorder(CellRangeAddress crA, CellRangeAddress crB) {
-		int oFirstRow = crB.getFirstRow();
-		int oLastRow  = crB.getLastRow();
-		int oFirstCol = crB.getFirstColumn();
-		int oLastCol  = crB.getLastColumn();
-		
-		if (crA.getFirstRow() > 0 && crA.getFirstRow()-1 == oLastRow || 
-			oFirstRow > 0 && oFirstRow-1 == crA.getLastRow()) {
-			// ranges have a horizontal border in common
-			// make sure columns are identical:
-			return crA.getFirstColumn() == oFirstCol && crA.getLastColumn() == oLastCol;
-		}
+        if (crA.getFirstColumn()>0 && crA.getFirstColumn() - 1 == oLastCol ||
+                oFirstCol>0 && crA.getLastColumn() == oFirstCol -1) {
+            // ranges have a vertical border in common
+            // make sure rows are identical:
+            return crA.getFirstRow() == oFirstRow && crA.getLastRow() == oLastRow;
+        }
+        return false;
+    }
 
-		if (crA.getFirstColumn()>0 && crA.getFirstColumn() - 1 == oLastCol ||
-			oFirstCol>0 && crA.getLastColumn() == oFirstCol -1) {
-			// ranges have a vertical border in common
-			// make sure rows are identical:
-			return crA.getFirstRow() == oFirstRow && crA.getLastRow() == oLastRow;
-		}
-		return false;
-   	}
-   	
-	/**
-	 * Create an enclosing CellRange for the two cell ranges.
-	 * 
-	 * @return enclosing CellRange
-	 */
-	public static CellRangeAddress createEnclosingCellRange(CellRangeAddress crA, CellRangeAddress crB) {
-		if( crB == null) {
-			return crA.copy();
-		}
-		
-		return
-			new CellRangeAddress(
-				lt(crB.getFirstRow(),   crA.getFirstRow())   ?crB.getFirstRow()   :crA.getFirstRow(),
-				gt(crB.getLastRow(),    crA.getLastRow())    ?crB.getLastRow()    :crA.getLastRow(),
-				lt(crB.getFirstColumn(),crA.getFirstColumn())?crB.getFirstColumn():crA.getFirstColumn(),
-				gt(crB.getLastColumn(), crA.getLastColumn()) ?crB.getLastColumn() :crA.getLastColumn()
-			);
-		
-	}
-	
-	/**
-	 * @return true if a < b
-	 */
-	private static boolean lt(int a, int b)
-	{
-		return a == -1 ? false : (b == -1 ? true : a < b);
-	}
-	
-	/**
-	 * @return true if a <= b
-	 */
-	private static boolean le(int a, int b)
-	{
-		return a == b || lt(a,b);
-	}
-	
-	/**
-	 * @return true if a > b
-	 */
-	private static boolean gt(int a, int b)
-	{
-		return lt(b,a);
-	}
+    /**
+     * Create an enclosing CellRange for the two cell ranges.
+     * 
+     * @return enclosing CellRange
+     */
+    public static CellRangeAddress createEnclosingCellRange(CellRangeAddress crA, CellRangeAddress crB) {
+        if( crB == null) {
+            return crA.copy();
+        }
 
-	/**
-	 * @return true if a >= b
-	 */
-	private static boolean ge(int a, int b)
-	{
-		return !lt(a,b);
-	}
+        return new CellRangeAddress(
+                   lt(crB.getFirstRow(),   crA.getFirstRow())   ?crB.getFirstRow()   :crA.getFirstRow(),
+                   gt(crB.getLastRow(),    crA.getLastRow())    ?crB.getLastRow()    :crA.getLastRow(),
+                   lt(crB.getFirstColumn(),crA.getFirstColumn())?crB.getFirstColumn():crA.getFirstColumn(),
+                   gt(crB.getLastColumn(), crA.getLastColumn()) ?crB.getLastColumn() :crA.getLastColumn()
+        );
+    }
+
+    /**
+     * @return true if a < b
+     */
+    private static boolean lt(int a, int b)
+    {
+        return a == -1 ? false : (b == -1 ? true : a < b);
+    }
+
+    /**
+     * @return true if a <= b
+     */
+    private static boolean le(int a, int b)
+    {
+        return a == b || lt(a,b);
+    }
+
+    /**
+     * @return true if a > b
+     */
+    private static boolean gt(int a, int b)
+    {
+        return lt(b,a);
+    }
+
+    /**
+     * @return true if a >= b
+     */
+    private static boolean ge(int a, int b)
+    {
+        return !lt(a,b);
+    }
 }

Modified: poi/branches/common_sl/src/java/org/apache/poi/hssf/record/cf/FontFormatting.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/java/org/apache/poi/hssf/record/cf/FontFormatting.java?rev=1691843&r1=1691842&r2=1691843&view=diff
==============================================================================
--- poi/branches/common_sl/src/java/org/apache/poi/hssf/record/cf/FontFormatting.java (original)
+++ poi/branches/common_sl/src/java/org/apache/poi/hssf/record/cf/FontFormatting.java Sun Jul 19 19:00:32 2015
@@ -25,525 +25,523 @@ import org.apache.poi.util.LittleEndian;
 
 /**
  * Font Formatting Block of the Conditional Formatting Rule Record.
- *
- * @author Dmitriy Kumshayev
  */
-public final class FontFormatting
-{
-	private byte[] _rawData;
-
-	private static final int OFFSET_FONT_NAME = 0;
-	private static final int OFFSET_FONT_HEIGHT = 64;
-	private static final int OFFSET_FONT_OPTIONS = 68;
-	private static final int OFFSET_FONT_WEIGHT = 72;
-	private static final int OFFSET_ESCAPEMENT_TYPE = 74;
-	private static final int OFFSET_UNDERLINE_TYPE = 76;
-	private static final int OFFSET_FONT_COLOR_INDEX = 80;
-	private static final int OFFSET_OPTION_FLAGS = 88;
-	private static final int OFFSET_ESCAPEMENT_TYPE_MODIFIED = 92;
-	private static final int OFFSET_UNDERLINE_TYPE_MODIFIED = 96;
-	private static final int OFFSET_FONT_WEIGHT_MODIFIED = 100;
-	private static final int OFFSET_NOT_USED1 = 104;
-	private static final int OFFSET_NOT_USED2 = 108;
-	private static final int OFFSET_NOT_USED3 = 112; // for some reason Excel always writes  0x7FFFFFFF at this offset
-	private static final int OFFSET_FONT_FORMATING_END = 116;
-	private static final int RAW_DATA_SIZE = 118;
-
-
-	public final static int  FONT_CELL_HEIGHT_PRESERVED   = 0xFFFFFFFF;
-
-	// FONT OPTIONS MASKS
-	private static final BitField posture       = BitFieldFactory.getInstance(0x00000002);
-	private static final BitField outline       = BitFieldFactory.getInstance(0x00000008);
-	private static final BitField shadow        = BitFieldFactory.getInstance(0x00000010);
-	private static final BitField cancellation	= BitFieldFactory.getInstance(0x00000080);
-
-	// OPTION FLAGS MASKS
-
-	private static final BitField styleModified        = BitFieldFactory.getInstance(0x00000002);
-	private static final BitField outlineModified      = BitFieldFactory.getInstance(0x00000008);
-	private static final BitField shadowModified       = BitFieldFactory.getInstance(0x00000010);
-	private static final BitField cancellationModified = BitFieldFactory.getInstance(0x00000080);
-
-	/** Escapement type - None */
-	public static final short SS_NONE  = 0;
-	/** Escapement type - Superscript */
-	public static final short SS_SUPER = 1;
-	/** Escapement type - Subscript */
-	public static final short SS_SUB   = 2;
-	/** Underline type - None */
-	public static final byte U_NONE               = 0;
-	/** Underline type - Single */
-	public static final byte U_SINGLE             = 1;
-	/** Underline type - Double */
-	public static final byte U_DOUBLE             = 2;
-	/** Underline type - Single Accounting */
-	public static final byte U_SINGLE_ACCOUNTING  = 0x21;
-	/** Underline type - Double Accounting */
-	public static final byte U_DOUBLE_ACCOUNTING  = 0x22;
-	/** Normal boldness (not bold) */
-	private static final short FONT_WEIGHT_NORMAL = 0x190;
-
-	/**
-	 * Bold boldness (bold)
-	 */
-	private static final short FONT_WEIGHT_BOLD	 = 0x2bc;
-
-	private FontFormatting(byte[] rawData) {
-		_rawData = rawData;
-	}
-
-	public FontFormatting()
-	{
-		this(new byte[RAW_DATA_SIZE]);
-
-		setFontHeight(-1);
-		setItalic(false);
-		setFontWieghtModified(false);
-		setOutline(false);
-		setShadow(false);
-		setStrikeout(false);
-		setEscapementType((short)0);
-		setUnderlineType((byte)0);
-		setFontColorIndex((short)-1);
-
-		setFontStyleModified(false);
-		setFontOutlineModified(false);
-		setFontShadowModified(false);
-		setFontCancellationModified(false);
-
-		setEscapementTypeModified(false);
-		setUnderlineTypeModified(false);
-
-		setShort(OFFSET_FONT_NAME, 0);
-		setInt(OFFSET_NOT_USED1, 0x00000001);
-		setInt(OFFSET_NOT_USED2, 0x00000000);
-		setInt(OFFSET_NOT_USED3, 0x7FFFFFFF);// for some reason Excel always writes  0x7FFFFFFF at this offset
-		setShort(OFFSET_FONT_FORMATING_END, 0x0001);
-	}
-
-	/** Creates new FontFormatting */
-	public FontFormatting(RecordInputStream in)
-	{
-		this(new byte[RAW_DATA_SIZE]);
-		for (int i = 0; i < _rawData.length; i++)
-		{
-			_rawData[i] = in.readByte();
-		}
-	}
-
-	private short getShort(int offset) {
-		return LittleEndian.getShort( _rawData, offset);
-	}
-	private void setShort(int offset, int value) {
-		LittleEndian.putShort( _rawData, offset, (short)value);
-	}
-	private int getInt(int offset) {
-		return LittleEndian.getInt( _rawData, offset);
-	}
-	private void setInt(int offset, int value) {
-		LittleEndian.putInt( _rawData, offset, value);
-	}
-
-	public byte[] getRawRecord()
-	{
-		return _rawData;
-	}
-
-	/**
-	 * sets the height of the font in 1/20th point units
-	 *
-	 *
-	 * @param height  fontheight (in points/20); or -1 to preserve the cell font height
-	 */
-
-	public void setFontHeight(int height)
-	{
-		setInt(OFFSET_FONT_HEIGHT, height);
-	}
-
-	/**
-	 * gets the height of the font in 1/20th point units
-	 *
-	 * @return fontheight (in points/20); or -1 if not modified
-	 */
-	public int getFontHeight()
-	{
-		return getInt(OFFSET_FONT_HEIGHT);
-	}
-
-	private void setFontOption(boolean option, BitField field)
-	{
-		int options = getInt(OFFSET_FONT_OPTIONS);
-		options = field.setBoolean(options, option);
-		setInt(OFFSET_FONT_OPTIONS, options);
-	}
-
-	private boolean getFontOption(BitField field)
-	{
-		int options = getInt(OFFSET_FONT_OPTIONS);
-		return field.isSet(options);
-	}
-
-	/**
-	 * set the font to be italics or not
-	 *
-	 * @param italic - whether the font is italics or not
-	 * @see #setFontOption(boolean, org.apache.poi.util.BitField)
-	 */
-
-	public void setItalic(boolean italic)
-	{
-		setFontOption(italic, posture);
-	}
-
-	/**
-	 * get whether the font is to be italics or not
-	 *
-	 * @return italics - whether the font is italics or not
-	 * @see #getFontOption(org.apache.poi.util.BitField)
-	 */
-
-	public boolean isItalic()
-	{
-		return getFontOption(posture);
-	}
-
-	public void setOutline(boolean on)
-	{
-		setFontOption(on, outline);
-	}
-
-	public boolean isOutlineOn()
-	{
-		return getFontOption(outline);
-	}
-
-	public void setShadow(boolean on)
-	{
-		setFontOption(on, shadow);
-	}
-
-	public boolean isShadowOn()
-	{
-		return getFontOption(shadow);
-	}
-
-	/**
-	 * set the font to be stricken out or not
-	 *
-	 * @param strike - whether the font is stricken out or not
-	 */
-
-	public void setStrikeout(boolean strike)
-	{
-		setFontOption(strike, cancellation);
-	}
-
-	/**
-	 * get whether the font is to be stricken out or not
-	 *
-	 * @return strike - whether the font is stricken out or not
-	 * @see #getFontOption(org.apache.poi.util.BitField)
-	 */
-
-	public boolean isStruckout()
-	{
-		return getFontOption(cancellation);
-	}
-
-	/**
-	 * set the font weight (100-1000dec or 0x64-0x3e8).  Default is
-	 * 0x190 for normal and 0x2bc for bold
-	 *
-	 * @param bw - a number between 100-1000 for the fonts "boldness"
-	 */
-
-	private void setFontWeight(short pbw)
-	{
-		short bw = pbw;
-		if( bw<100) { bw=100; }
-		if( bw>1000){ bw=1000; }
-		setShort(OFFSET_FONT_WEIGHT, bw);
-	}
-
-	/**
-	 * set the font weight to bold (weight=700) or to normal(weight=400) boldness.
-	 *
-	 * @param bold - set font weight to bold if true; to normal otherwise
-	 */
-	public void setBold(boolean bold)
-	{
-		setFontWeight(bold?FONT_WEIGHT_BOLD:FONT_WEIGHT_NORMAL);
-	}
-
-	/**
-	 * get the font weight for this font (100-1000dec or 0x64-0x3e8).  Default is
-	 * 0x190 for normal and 0x2bc for bold
-	 *
-	 * @return bw - a number between 100-1000 for the fonts "boldness"
-	 */
-
-	public short getFontWeight()
-	{
-		return getShort(OFFSET_FONT_WEIGHT);
-	}
-
-	/**
-	 * get whether the font weight is set to bold or not
-	 *
-	 * @return bold - whether the font is bold or not
-	 */
-
-	public boolean isBold()
-	{
-		return getFontWeight()==FONT_WEIGHT_BOLD;
-	}
-
-	/**
-	 * get the type of super or subscript for the font
-	 *
-	 * @return super or subscript option
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_NONE
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUPER
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUB
-	 */
-	public short getEscapementType()
-	{
-		return getShort(OFFSET_ESCAPEMENT_TYPE);
-	}
-
-	/**
-	 * set the escapement type for the font
-	 *
-	 * @param escapementType  super or subscript option
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_NONE
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUPER
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUB
-	 */
-	public void setEscapementType( short escapementType)
-	{
-		setShort(OFFSET_ESCAPEMENT_TYPE, escapementType);
-	}
-
-	/**
-	 * get the type of underlining for the font
-	 *
-	 * @return font underlining type
-	 *
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_NONE
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE_ACCOUNTING
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE_ACCOUNTING
-	 */
-
-	public short getUnderlineType()
-	{
-		return getShort(OFFSET_UNDERLINE_TYPE);
-	}
-
-	/**
-	 * set the type of underlining type for the font
-	 *
-	 * @param underlineType underline option
-	 *
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_NONE
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE_ACCOUNTING
-	 * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE_ACCOUNTING
-	 */
-	public void setUnderlineType( short underlineType)
-	{
-		setShort(OFFSET_UNDERLINE_TYPE, underlineType);
-	}
-
-
-	public short getFontColorIndex()
-	{
-		return (short)getInt(OFFSET_FONT_COLOR_INDEX);
-	}
-
-	public void setFontColorIndex(short fci )
-	{
-		setInt(OFFSET_FONT_COLOR_INDEX,fci);
-	}
-
-	private boolean getOptionFlag(BitField field)
-	{
-		int optionFlags = getInt(OFFSET_OPTION_FLAGS);
-		int value = field.getValue(optionFlags);
-		return value==0? true : false ;
-	}
-
-	private void setOptionFlag(boolean modified, BitField field)
-	{
-		int value = modified? 0 : 1;
-		int optionFlags = getInt(OFFSET_OPTION_FLAGS);
-		optionFlags = field.setValue(optionFlags, value);
-		setInt(OFFSET_OPTION_FLAGS, optionFlags);
-	}
-
-
-	public boolean isFontStyleModified()
-	{
-		return getOptionFlag(styleModified);
-	}
-
-
-	public void setFontStyleModified(boolean modified)
-	{
-		setOptionFlag(modified, styleModified);
-	}
-
-	public boolean isFontOutlineModified()
-	{
-		return getOptionFlag(outlineModified);
-	}
-
-	public void setFontOutlineModified(boolean modified)
-	{
-		setOptionFlag(modified, outlineModified);
-	}
-
-	public boolean isFontShadowModified()
-	{
-		return getOptionFlag(shadowModified);
-	}
-
-	public void setFontShadowModified(boolean modified)
-	{
-		setOptionFlag(modified, shadowModified);
-	}
-	public void setFontCancellationModified(boolean modified)
-	{
-		setOptionFlag(modified, cancellationModified);
-	}
-
-	public boolean isFontCancellationModified()
-	{
-		return getOptionFlag(cancellationModified);
-	}
-
-	public void setEscapementTypeModified(boolean modified)
-	{
-		int value = modified? 0 : 1;
-		setInt(OFFSET_ESCAPEMENT_TYPE_MODIFIED, value);
-	}
-	public boolean isEscapementTypeModified()
-	{
-		int escapementModified = getInt(OFFSET_ESCAPEMENT_TYPE_MODIFIED);
-		return escapementModified == 0;
-	}
-
-	public void setUnderlineTypeModified(boolean modified)
-	{
-		int value = modified? 0 : 1;
-		setInt(OFFSET_UNDERLINE_TYPE_MODIFIED, value);
-	}
-
-	public boolean isUnderlineTypeModified()
-	{
-		int underlineModified = getInt(OFFSET_UNDERLINE_TYPE_MODIFIED);
-		return underlineModified == 0;
-	}
-
-	public void setFontWieghtModified(boolean modified)
-	{
-		int value = modified? 0 : 1;
-		setInt(OFFSET_FONT_WEIGHT_MODIFIED, value);
-	}
-
-	public boolean isFontWeightModified()
-	{
-		int fontStyleModified = getInt(OFFSET_FONT_WEIGHT_MODIFIED);
-		return fontStyleModified == 0;
-	}
-
-	public String toString()
-	{
-		StringBuffer buffer = new StringBuffer();
-		buffer.append("	[Font Formatting]\n");
-
-		buffer.append("	.font height = ").append(getFontHeight()).append(" twips\n");
-
-		if( isFontStyleModified() )
-		{
-			buffer.append("	.font posture = ").append(isItalic()?"Italic":"Normal").append("\n");
-		}
-		else
-		{
-			buffer.append("	.font posture = ]not modified]").append("\n");
-		}
-
-		if( isFontOutlineModified() )
-		{
-			buffer.append("	.font outline = ").append(isOutlineOn()).append("\n");
-		}
-		else
-		{
-			buffer.append("	.font outline is not modified\n");
-		}
-
-		if( isFontShadowModified() )
-		{
-			buffer.append("	.font shadow = ").append(isShadowOn()).append("\n");
-		}
-		else
-		{
-			buffer.append("	.font shadow is not modified\n");
-		}
-
-		if( isFontCancellationModified() )
-		{
-			buffer.append("	.font strikeout = ").append(isStruckout()).append("\n");
-		}
-		else
-		{
-			buffer.append("	.font strikeout is not modified\n");
-		}
-
-		if( isFontStyleModified() )
-		{
-			buffer.append("	.font weight = ").
-				append(getFontWeight()).
-				append(
-					getFontWeight() == FONT_WEIGHT_NORMAL ? "(Normal)"
-							: getFontWeight() == FONT_WEIGHT_BOLD ? "(Bold)" : "0x"+Integer.toHexString(getFontWeight())).
-				append("\n");
-		}
-		else
-		{
-			buffer.append("	.font weight = ]not modified]").append("\n");
-		}
-
-		if( isEscapementTypeModified() )
-		{
-			buffer.append("	.escapement type = ").append(getEscapementType()).append("\n");
-		}
-		else
-		{
-			buffer.append("	.escapement type is not modified\n");
-		}
-
-		if( isUnderlineTypeModified() )
-		{
-			buffer.append("	.underline type = ").append(getUnderlineType()).append("\n");
-		}
-		else
-		{
-			buffer.append("	.underline type is not modified\n");
-		}
-		buffer.append("	.color index = ").append("0x"+Integer.toHexString(getFontColorIndex()).toUpperCase()).append("\n");
-
-		buffer.append("	[/Font Formatting]\n");
-		return buffer.toString();
-	}
-
-	public Object clone()
-	{
-		byte[] rawData = _rawData.clone();
-		return new FontFormatting(rawData);
-	}
+public final class FontFormatting {
+    private byte[] _rawData;
+
+    private static final int OFFSET_FONT_NAME = 0;
+    private static final int OFFSET_FONT_HEIGHT = 64;
+    private static final int OFFSET_FONT_OPTIONS = 68;
+    private static final int OFFSET_FONT_WEIGHT = 72;
+    private static final int OFFSET_ESCAPEMENT_TYPE = 74;
+    private static final int OFFSET_UNDERLINE_TYPE = 76;
+    private static final int OFFSET_FONT_COLOR_INDEX = 80;
+    private static final int OFFSET_OPTION_FLAGS = 88;
+    private static final int OFFSET_ESCAPEMENT_TYPE_MODIFIED = 92;
+    private static final int OFFSET_UNDERLINE_TYPE_MODIFIED = 96;
+    private static final int OFFSET_FONT_WEIGHT_MODIFIED = 100;
+    private static final int OFFSET_NOT_USED1 = 104;
+    private static final int OFFSET_NOT_USED2 = 108;
+    private static final int OFFSET_NOT_USED3 = 112; // for some reason Excel always writes  0x7FFFFFFF at this offset
+    private static final int OFFSET_FONT_FORMATING_END = 116;
+    private static final int RAW_DATA_SIZE = 118;
+
+
+    public final static int  FONT_CELL_HEIGHT_PRESERVED   = 0xFFFFFFFF;
+
+    // FONT OPTIONS MASKS
+    private static final BitField posture       = BitFieldFactory.getInstance(0x00000002);
+    private static final BitField outline       = BitFieldFactory.getInstance(0x00000008);
+    private static final BitField shadow        = BitFieldFactory.getInstance(0x00000010);
+    private static final BitField cancellation	= BitFieldFactory.getInstance(0x00000080);
+
+    // OPTION FLAGS MASKS
+
+    private static final BitField styleModified        = BitFieldFactory.getInstance(0x00000002);
+    private static final BitField outlineModified      = BitFieldFactory.getInstance(0x00000008);
+    private static final BitField shadowModified       = BitFieldFactory.getInstance(0x00000010);
+    private static final BitField cancellationModified = BitFieldFactory.getInstance(0x00000080);
+
+    /** Escapement type - None */
+    public static final short SS_NONE  = 0;
+    /** Escapement type - Superscript */
+    public static final short SS_SUPER = 1;
+    /** Escapement type - Subscript */
+    public static final short SS_SUB   = 2;
+    /** Underline type - None */
+    public static final byte U_NONE               = 0;
+    /** Underline type - Single */
+    public static final byte U_SINGLE             = 1;
+    /** Underline type - Double */
+    public static final byte U_DOUBLE             = 2;
+    /** Underline type - Single Accounting */
+    public static final byte U_SINGLE_ACCOUNTING  = 0x21;
+    /** Underline type - Double Accounting */
+    public static final byte U_DOUBLE_ACCOUNTING  = 0x22;
+    /** Normal boldness (not bold) */
+    private static final short FONT_WEIGHT_NORMAL = 0x190;
+
+    /**
+     * Bold boldness (bold)
+     */
+    private static final short FONT_WEIGHT_BOLD	 = 0x2bc;
+
+    private FontFormatting(byte[] rawData) {
+        _rawData = rawData;
+    }
+
+    public FontFormatting()
+    {
+        this(new byte[RAW_DATA_SIZE]);
+
+        setFontHeight(-1);
+        setItalic(false);
+        setFontWieghtModified(false);
+        setOutline(false);
+        setShadow(false);
+        setStrikeout(false);
+        setEscapementType((short)0);
+        setUnderlineType((byte)0);
+        setFontColorIndex((short)-1);
+
+        setFontStyleModified(false);
+        setFontOutlineModified(false);
+        setFontShadowModified(false);
+        setFontCancellationModified(false);
+
+        setEscapementTypeModified(false);
+        setUnderlineTypeModified(false);
+
+        setShort(OFFSET_FONT_NAME, 0);
+        setInt(OFFSET_NOT_USED1, 0x00000001);
+        setInt(OFFSET_NOT_USED2, 0x00000000);
+        setInt(OFFSET_NOT_USED3, 0x7FFFFFFF);// for some reason Excel always writes  0x7FFFFFFF at this offset
+        setShort(OFFSET_FONT_FORMATING_END, 0x0001);
+    }
+
+    /** Creates new FontFormatting */
+    public FontFormatting(RecordInputStream in)
+    {
+        this(new byte[RAW_DATA_SIZE]);
+        for (int i = 0; i < _rawData.length; i++)
+        {
+            _rawData[i] = in.readByte();
+        }
+    }
+
+    private short getShort(int offset) {
+        return LittleEndian.getShort( _rawData, offset);
+    }
+    private void setShort(int offset, int value) {
+        LittleEndian.putShort( _rawData, offset, (short)value);
+    }
+    private int getInt(int offset) {
+        return LittleEndian.getInt( _rawData, offset);
+    }
+    private void setInt(int offset, int value) {
+        LittleEndian.putInt( _rawData, offset, value);
+    }
+
+    public byte[] getRawRecord()
+    {
+        return _rawData;
+    }
+
+    public int getDataLength() {
+        return RAW_DATA_SIZE;
+    }
+
+    /**
+     * sets the height of the font in 1/20th point units
+     *
+     *
+     * @param height  fontheight (in points/20); or -1 to preserve the cell font height
+     */
+
+    public void setFontHeight(int height)
+    {
+        setInt(OFFSET_FONT_HEIGHT, height);
+    }
+
+    /**
+     * gets the height of the font in 1/20th point units
+     *
+     * @return fontheight (in points/20); or -1 if not modified
+     */
+    public int getFontHeight()
+    {
+        return getInt(OFFSET_FONT_HEIGHT);
+    }
+
+    private void setFontOption(boolean option, BitField field)
+    {
+        int options = getInt(OFFSET_FONT_OPTIONS);
+        options = field.setBoolean(options, option);
+        setInt(OFFSET_FONT_OPTIONS, options);
+    }
+
+    private boolean getFontOption(BitField field)
+    {
+        int options = getInt(OFFSET_FONT_OPTIONS);
+        return field.isSet(options);
+    }
+
+    /**
+     * set the font to be italics or not
+     *
+     * @param italic - whether the font is italics or not
+     * @see #setFontOption(boolean, org.apache.poi.util.BitField)
+     */
+
+    public void setItalic(boolean italic)
+    {
+        setFontOption(italic, posture);
+    }
+
+    /**
+     * get whether the font is to be italics or not
+     *
+     * @return italics - whether the font is italics or not
+     * @see #getFontOption(org.apache.poi.util.BitField)
+     */
+
+    public boolean isItalic()
+    {
+        return getFontOption(posture);
+    }
+
+    public void setOutline(boolean on)
+    {
+        setFontOption(on, outline);
+    }
+
+    public boolean isOutlineOn()
+    {
+        return getFontOption(outline);
+    }
+
+    public void setShadow(boolean on)
+    {
+        setFontOption(on, shadow);
+    }
+
+    public boolean isShadowOn()
+    {
+        return getFontOption(shadow);
+    }
+
+    /**
+     * set the font to be stricken out or not
+     *
+     * @param strike - whether the font is stricken out or not
+     */
+    public void setStrikeout(boolean strike)
+    {
+        setFontOption(strike, cancellation);
+    }
+
+    /**
+     * get whether the font is to be stricken out or not
+     *
+     * @return strike - whether the font is stricken out or not
+     * @see #getFontOption(org.apache.poi.util.BitField)
+     */
+    public boolean isStruckout()
+    {
+        return getFontOption(cancellation);
+    }
+
+    /**
+     * set the font weight (100-1000dec or 0x64-0x3e8).  Default is
+     * 0x190 for normal and 0x2bc for bold
+     *
+     * @param bw - a number between 100-1000 for the fonts "boldness"
+     */
+
+    private void setFontWeight(short pbw)
+    {
+        short bw = pbw;
+        if( bw<100) { bw=100; }
+        if( bw>1000){ bw=1000; }
+        setShort(OFFSET_FONT_WEIGHT, bw);
+    }
+
+    /**
+     * set the font weight to bold (weight=700) or to normal(weight=400) boldness.
+     *
+     * @param bold - set font weight to bold if true; to normal otherwise
+     */
+    public void setBold(boolean bold)
+    {
+        setFontWeight(bold?FONT_WEIGHT_BOLD:FONT_WEIGHT_NORMAL);
+    }
+
+    /**
+     * get the font weight for this font (100-1000dec or 0x64-0x3e8).  Default is
+     * 0x190 for normal and 0x2bc for bold
+     *
+     * @return bw - a number between 100-1000 for the fonts "boldness"
+     */
+
+    public short getFontWeight()
+    {
+        return getShort(OFFSET_FONT_WEIGHT);
+    }
+
+    /**
+     * get whether the font weight is set to bold or not
+     *
+     * @return bold - whether the font is bold or not
+     */
+
+    public boolean isBold()
+    {
+        return getFontWeight()==FONT_WEIGHT_BOLD;
+    }
+
+    /**
+     * get the type of super or subscript for the font
+     *
+     * @return super or subscript option
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_NONE
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUPER
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUB
+     */
+    public short getEscapementType()
+    {
+        return getShort(OFFSET_ESCAPEMENT_TYPE);
+    }
+
+    /**
+     * set the escapement type for the font
+     *
+     * @param escapementType  super or subscript option
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_NONE
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUPER
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#SS_SUB
+     */
+    public void setEscapementType( short escapementType)
+    {
+        setShort(OFFSET_ESCAPEMENT_TYPE, escapementType);
+    }
+
+    /**
+     * get the type of underlining for the font
+     *
+     * @return font underlining type
+     *
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_NONE
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE_ACCOUNTING
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE_ACCOUNTING
+     */
+    public short getUnderlineType()
+    {
+        return getShort(OFFSET_UNDERLINE_TYPE);
+    }
+
+    /**
+     * set the type of underlining type for the font
+     *
+     * @param underlineType underline option
+     *
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_NONE
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_SINGLE_ACCOUNTING
+     * @see org.apache.poi.hssf.usermodel.HSSFFontFormatting#U_DOUBLE_ACCOUNTING
+     */
+    public void setUnderlineType( short underlineType)
+    {
+        setShort(OFFSET_UNDERLINE_TYPE, underlineType);
+    }
+
+
+    public short getFontColorIndex()
+    {
+        return (short)getInt(OFFSET_FONT_COLOR_INDEX);
+    }
+
+    public void setFontColorIndex(short fci )
+    {
+        setInt(OFFSET_FONT_COLOR_INDEX,fci);
+    }
+
+    private boolean getOptionFlag(BitField field) {
+        int optionFlags = getInt(OFFSET_OPTION_FLAGS);
+        int value = field.getValue(optionFlags);
+        return value==0? true : false ;
+    }
+
+    private void setOptionFlag(boolean modified, BitField field)
+    {
+        int value = modified? 0 : 1;
+        int optionFlags = getInt(OFFSET_OPTION_FLAGS);
+        optionFlags = field.setValue(optionFlags, value);
+        setInt(OFFSET_OPTION_FLAGS, optionFlags);
+    }
+
+
+    public boolean isFontStyleModified()
+    {
+        return getOptionFlag(styleModified);
+    }
+
+
+    public void setFontStyleModified(boolean modified)
+    {
+        setOptionFlag(modified, styleModified);
+    }
+
+    public boolean isFontOutlineModified()
+    {
+        return getOptionFlag(outlineModified);
+    }
+
+    public void setFontOutlineModified(boolean modified)
+    {
+        setOptionFlag(modified, outlineModified);
+    }
+
+    public boolean isFontShadowModified()
+    {
+        return getOptionFlag(shadowModified);
+    }
+
+    public void setFontShadowModified(boolean modified)
+    {
+        setOptionFlag(modified, shadowModified);
+    }
+    public void setFontCancellationModified(boolean modified)
+    {
+        setOptionFlag(modified, cancellationModified);
+    }
+
+    public boolean isFontCancellationModified()
+    {
+        return getOptionFlag(cancellationModified);
+    }
+
+    public void setEscapementTypeModified(boolean modified)
+    {
+        int value = modified? 0 : 1;
+        setInt(OFFSET_ESCAPEMENT_TYPE_MODIFIED, value);
+    }
+    public boolean isEscapementTypeModified()
+    {
+        int escapementModified = getInt(OFFSET_ESCAPEMENT_TYPE_MODIFIED);
+        return escapementModified == 0;
+    }
+
+    public void setUnderlineTypeModified(boolean modified)
+    {
+        int value = modified? 0 : 1;
+        setInt(OFFSET_UNDERLINE_TYPE_MODIFIED, value);
+    }
+
+    public boolean isUnderlineTypeModified()
+    {
+        int underlineModified = getInt(OFFSET_UNDERLINE_TYPE_MODIFIED);
+        return underlineModified == 0;
+    }
+
+    public void setFontWieghtModified(boolean modified)
+    {
+        int value = modified? 0 : 1;
+        setInt(OFFSET_FONT_WEIGHT_MODIFIED, value);
+    }
+
+    public boolean isFontWeightModified()
+    {
+        int fontStyleModified = getInt(OFFSET_FONT_WEIGHT_MODIFIED);
+        return fontStyleModified == 0;
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("	[Font Formatting]\n");
+
+        buffer.append("	.font height = ").append(getFontHeight()).append(" twips\n");
+
+        if( isFontStyleModified() )
+        {
+            buffer.append("	.font posture = ").append(isItalic()?"Italic":"Normal").append("\n");
+        }
+        else
+        {
+            buffer.append("	.font posture = ]not modified]").append("\n");
+        }
+
+        if( isFontOutlineModified() )
+        {
+            buffer.append("	.font outline = ").append(isOutlineOn()).append("\n");
+        }
+        else
+        {
+            buffer.append("	.font outline is not modified\n");
+        }
+
+        if( isFontShadowModified() )
+        {
+            buffer.append("	.font shadow = ").append(isShadowOn()).append("\n");
+        }
+        else
+        {
+            buffer.append("	.font shadow is not modified\n");
+        }
+
+        if( isFontCancellationModified() )
+        {
+            buffer.append("	.font strikeout = ").append(isStruckout()).append("\n");
+        }
+        else
+        {
+            buffer.append("	.font strikeout is not modified\n");
+        }
+
+        if( isFontStyleModified() )
+        {
+            buffer.append("	.font weight = ").
+            append(getFontWeight()).
+            append(
+                    getFontWeight() == FONT_WEIGHT_NORMAL ? "(Normal)"
+                    : getFontWeight() == FONT_WEIGHT_BOLD ? "(Bold)" 
+                    : "0x"+Integer.toHexString(getFontWeight())).
+            append("\n");
+        }
+        else
+        {
+            buffer.append("	.font weight = ]not modified]").append("\n");
+        }
+
+        if( isEscapementTypeModified() )
+        {
+            buffer.append("	.escapement type = ").append(getEscapementType()).append("\n");
+        }
+        else
+        {
+            buffer.append("	.escapement type is not modified\n");
+        }
+
+        if( isUnderlineTypeModified() )
+        {
+            buffer.append("	.underline type = ").append(getUnderlineType()).append("\n");
+        }
+        else
+        {
+            buffer.append("	.underline type is not modified\n");
+        }
+        buffer.append("	.color index = ").append("0x"+Integer.toHexString(getFontColorIndex()).toUpperCase()).append("\n");
+
+        buffer.append("	[/Font Formatting]\n");
+        return buffer.toString();
+    }
+
+    public Object clone()
+    {
+        byte[] rawData = _rawData.clone();
+        return new FontFormatting(rawData);
+    }
 }

Modified: poi/branches/common_sl/src/java/org/apache/poi/hssf/record/cf/PatternFormatting.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/java/org/apache/poi/hssf/record/cf/PatternFormatting.java?rev=1691843&r1=1691842&r2=1691843&view=diff
==============================================================================
--- poi/branches/common_sl/src/java/org/apache/poi/hssf/record/cf/PatternFormatting.java (original)
+++ poi/branches/common_sl/src/java/org/apache/poi/hssf/record/cf/PatternFormatting.java Sun Jul 19 19:00:32 2015
@@ -24,8 +24,6 @@ import org.apache.poi.util.LittleEndianO
 
 /**
  * Pattern Formatting Block of the Conditional Formatting Rule Record.
- * 
- * @author Dmitriy Kumshayev
  */
 public final class PatternFormatting implements Cloneable {
     /**  No background */
@@ -89,6 +87,10 @@ public final class PatternFormatting imp
         field_16_pattern_color_indexes    = in.readUShort();
     }
     
+    public int getDataLength() {
+        return 4;
+    }
+    
     /**
      * setting fill pattern
      *

Modified: poi/branches/common_sl/src/java/org/apache/poi/hssf/record/common/FtrHeader.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/java/org/apache/poi/hssf/record/common/FtrHeader.java?rev=1691843&r1=1691842&r2=1691843&view=diff
==============================================================================
--- poi/branches/common_sl/src/java/org/apache/poi/hssf/record/common/FtrHeader.java (original)
+++ poi/branches/common_sl/src/java/org/apache/poi/hssf/record/common/FtrHeader.java Sun Jul 19 19:00:32 2015
@@ -18,6 +18,7 @@
 package org.apache.poi.hssf.record.common;
 
 import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
@@ -28,62 +29,69 @@ import org.apache.poi.util.LittleEndianO
  *  beyond those of a traditional record. 
  */
 public final class FtrHeader {
-	/** This MUST match the type on the containing record */
-	private short recordType;
-	/** This is a FrtFlags */
-	private short grbitFrt;
-	/** MUST be 8 bytes and all zero */
-	private byte[] reserved;
-
-	public FtrHeader() {
-		reserved = new byte[8];
-	}
-
-	public FtrHeader(RecordInputStream in) {
-		recordType = in.readShort();
-		grbitFrt   = in.readShort();
-		
-		reserved = new byte[8];
-		in.read(reserved, 0, 8);
-	}
-
-	public String toString() {
-		StringBuffer buffer = new StringBuffer();
-		buffer.append(" [FUTURE HEADER]\n");
-		buffer.append("   Type " + recordType);
-		buffer.append("   Flags " + grbitFrt);
-		buffer.append(" [/FUTURE HEADER]\n");
-		return buffer.toString();
-	}
-
-	public void serialize(LittleEndianOutput out) {
-		out.writeShort(recordType);
-		out.writeShort(grbitFrt);
-		out.write(reserved);
-	}
-
-	public static int getDataSize() {
-		return 12;
-	}
-
-	public short getRecordType() {
-		return recordType;
-	}
-	public void setRecordType(short recordType) {
-		this.recordType = recordType;
-	}
-
-	public short getGrbitFrt() {
-		return grbitFrt;
-	}
-	public void setGrbitFrt(short grbitFrt) {
-		this.grbitFrt = grbitFrt;
-	}
-
-	public byte[] getReserved() {
-		return reserved;
-	}
-	public void setReserved(byte[] reserved) {
-		this.reserved = reserved;
-	}
+    /** This MUST match the type on the containing record */
+    private short recordType;
+    /** This is a FrtFlags */
+    private short grbitFrt;
+    /** The range of cells the parent record applies to, or 0 if N/A */
+    private CellRangeAddress associatedRange;
+
+    public FtrHeader() {
+        associatedRange = new CellRangeAddress(0, 0, 0, 0);
+    }
+
+    public FtrHeader(RecordInputStream in) {
+        recordType = in.readShort();
+        grbitFrt   = in.readShort();
+
+        associatedRange = new CellRangeAddress(in);
+    }
+
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append(" [FUTURE HEADER]\n");
+        buffer.append("   Type " + recordType);
+        buffer.append("   Flags " + grbitFrt);
+        buffer.append(" [/FUTURE HEADER]\n");
+        return buffer.toString();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(recordType);
+        out.writeShort(grbitFrt);
+        associatedRange.serialize(out);
+    }
+
+    public static int getDataSize() {
+        return 12;
+    }
+
+    public short getRecordType() {
+        return recordType;
+    }
+    public void setRecordType(short recordType) {
+        this.recordType = recordType;
+    }
+
+    public short getGrbitFrt() {
+        return grbitFrt;
+    }
+    public void setGrbitFrt(short grbitFrt) {
+        this.grbitFrt = grbitFrt;
+    }
+
+    public CellRangeAddress getAssociatedRange() {
+        return associatedRange;
+    }
+    public void setAssociatedRange(CellRangeAddress associatedRange) {
+        this.associatedRange = associatedRange;
+    }
+
+    public Object clone() {
+        FtrHeader result = new FtrHeader();
+        result.recordType = recordType;
+        result.grbitFrt = grbitFrt;
+        result.associatedRange = associatedRange.copy();
+        return result;
+    }
 }
\ No newline at end of file

Modified: poi/branches/common_sl/src/java/org/apache/poi/hssf/record/crypto/Biff8DecryptingStream.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/java/org/apache/poi/hssf/record/crypto/Biff8DecryptingStream.java?rev=1691843&r1=1691842&r2=1691843&view=diff
==============================================================================
--- poi/branches/common_sl/src/java/org/apache/poi/hssf/record/crypto/Biff8DecryptingStream.java (original)
+++ poi/branches/common_sl/src/java/org/apache/poi/hssf/record/crypto/Biff8DecryptingStream.java Sun Jul 19 19:00:32 2015
@@ -95,7 +95,7 @@ public final class Biff8DecryptingStream
 
 
 	public int readUByte() {
-		return _cipher.xorByte(_le.readUByte());
+		return readByte() & 0xFF;
 	}
 	public byte readByte() {
 		return (byte) _cipher.xorByte(_le.readUByte());
@@ -103,7 +103,7 @@ public final class Biff8DecryptingStream
 
 
 	public int readUShort() {
-		return _cipher.xorShort(_le.readUShort());
+		return readShort() & 0xFFFF;
 	}
 	public short readShort() {
 		return (short) _cipher.xorShort(_le.readUShort());

Modified: poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java?rev=1691843&r1=1691842&r2=1691843&view=diff
==============================================================================
--- poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java (original)
+++ poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFBorderFormatting.java Sun Jul 19 19:00:32 2015
@@ -17,196 +17,246 @@
 
 package org.apache.poi.hssf.usermodel;
 
-import org.apache.poi.hssf.record.CFRuleRecord;
+import org.apache.poi.hssf.record.CFRuleBase;
 import org.apache.poi.hssf.record.cf.BorderFormatting;
+import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.ss.usermodel.Color;
 
 /**
  * High level representation for Border Formatting component
  * of Conditional Formatting settings
  */
-public final class HSSFBorderFormatting implements org.apache.poi.ss.usermodel.BorderFormatting
-{
-	private final CFRuleRecord cfRuleRecord;
-	private final BorderFormatting borderFormatting;
-	
-	protected HSSFBorderFormatting(CFRuleRecord cfRuleRecord)
-	{
-		this.cfRuleRecord = cfRuleRecord;
-		this.borderFormatting = cfRuleRecord.getBorderFormatting();
-	}
-
-	protected BorderFormatting getBorderFormattingBlock()
-	{
-		return borderFormatting;
-	}
-
-	public short getBorderBottom()
-	{
-		return (short)borderFormatting.getBorderBottom();
-	}
-
-	public short getBorderDiagonal()
-	{
-		return (short)borderFormatting.getBorderDiagonal();
-	}
-
-	public short getBorderLeft()
-	{
-		return (short)borderFormatting.getBorderLeft();
-	}
-
-	public short getBorderRight()
-	{
-		return (short)borderFormatting.getBorderRight();
-	}
-
-	public short getBorderTop()
-	{
-		return (short)borderFormatting.getBorderTop();
-	}
-
-	public short getBottomBorderColor()
-	{
-		return (short)borderFormatting.getBottomBorderColor();
-	}
-
-	public short getDiagonalBorderColor()
-	{
-		return (short)borderFormatting.getDiagonalBorderColor();
-	}
-
-	public short getLeftBorderColor()
-	{
-		return (short)borderFormatting.getLeftBorderColor();
-	}
-
-	public short getRightBorderColor()
-	{
-		return (short)borderFormatting.getRightBorderColor();
-	}
-
-	public short getTopBorderColor()
-	{
-		return (short)borderFormatting.getTopBorderColor();
-	}
-
-	public boolean isBackwardDiagonalOn()
-	{
-		return borderFormatting.isBackwardDiagonalOn();
-	}
-
-	public boolean isForwardDiagonalOn()
-	{
-		return borderFormatting.isForwardDiagonalOn();
-	}
-
-	public void setBackwardDiagonalOn(boolean on)
-	{
-		borderFormatting.setBackwardDiagonalOn(on);
-		if( on )
-		{
-			cfRuleRecord.setTopLeftBottomRightBorderModified(on);
-		}
-	}
-
-	public void setBorderBottom(short border)
-	{
-		borderFormatting.setBorderBottom(border);
-		if( border != 0)
-		{
-			cfRuleRecord.setBottomBorderModified(true);
-		}
-	}
-
-	public void setBorderDiagonal(short border)
-	{
-		borderFormatting.setBorderDiagonal(border);
-		if( border != 0)
-		{
-			cfRuleRecord.setBottomLeftTopRightBorderModified(true);
-			cfRuleRecord.setTopLeftBottomRightBorderModified(true);
-		}
-	}
-
-	public void setBorderLeft(short border)
-	{
-		borderFormatting.setBorderLeft(border);
-		if( border != 0)
-		{
-			cfRuleRecord.setLeftBorderModified(true);
-		}
-	}
-
-	public void setBorderRight(short border)
-	{
-		borderFormatting.setBorderRight(border);
-		if( border != 0)
-		{
-			cfRuleRecord.setRightBorderModified(true);
-		}
-	}
-
-	public void setBorderTop(short border)
-	{
-		borderFormatting.setBorderTop(border);
-		if( border != 0)
-		{
-			cfRuleRecord.setTopBorderModified(true);
-		}
-	}
-
-	public void setBottomBorderColor(short color)
-	{
-		borderFormatting.setBottomBorderColor(color);
-		if( color != 0)
-		{
-			cfRuleRecord.setBottomBorderModified(true);
-		}
-	}
-
-	public void setDiagonalBorderColor(short color)
-	{
-		borderFormatting.setDiagonalBorderColor(color);
-		if( color != 0)
-		{
-			cfRuleRecord.setBottomLeftTopRightBorderModified(true);
-			cfRuleRecord.setTopLeftBottomRightBorderModified(true);
-		}
-	}
-
-	public void setForwardDiagonalOn(boolean on)
-	{
-		borderFormatting.setForwardDiagonalOn(on);
-		if( on )
-		{
-			cfRuleRecord.setBottomLeftTopRightBorderModified(on);
-		}
-	}
-
-	public void setLeftBorderColor(short color)
-	{
-		borderFormatting.setLeftBorderColor(color);
-		if( color != 0)
-		{
-			cfRuleRecord.setLeftBorderModified(true);
-		}
-	}
-
-	public void setRightBorderColor(short color)
-	{
-		borderFormatting.setRightBorderColor(color);
-		if( color != 0)
-		{
-			cfRuleRecord.setRightBorderModified(true);
-		}
-	}
-
-	public void setTopBorderColor(short color)
-	{
-		borderFormatting.setTopBorderColor(color);
-		if( color != 0)
-		{
-			cfRuleRecord.setTopBorderModified(true);
-		}
-	}
+public final class HSSFBorderFormatting implements org.apache.poi.ss.usermodel.BorderFormatting {
+    private final HSSFWorkbook workbook;
+    private final CFRuleBase cfRuleRecord;
+    private final BorderFormatting borderFormatting;
+
+    protected HSSFBorderFormatting(CFRuleBase cfRuleRecord, HSSFWorkbook workbook) {
+        this.workbook = workbook;
+        this.cfRuleRecord = cfRuleRecord;
+        this.borderFormatting = cfRuleRecord.getBorderFormatting();
+    }
+
+    protected BorderFormatting getBorderFormattingBlock() {
+        return borderFormatting;
+    }
+
+    public short getBorderBottom() {
+        return (short)borderFormatting.getBorderBottom();
+    }
+
+    public short getBorderDiagonal() {
+        return (short)borderFormatting.getBorderDiagonal();
+    }
+
+    public short getBorderLeft() {
+        return (short)borderFormatting.getBorderLeft();
+    }
+
+    public short getBorderRight() {
+        return (short)borderFormatting.getBorderRight();
+    }
+
+    public short getBorderTop() {
+        return (short)borderFormatting.getBorderTop();
+    }
+
+    public short getBottomBorderColor() {
+        return (short)borderFormatting.getBottomBorderColor();
+    }
+    public HSSFColor getBottomBorderColorColor() {
+        return workbook.getCustomPalette().getColor(
+                borderFormatting.getBottomBorderColor()
+        );
+    }
+
+    public short getDiagonalBorderColor() {
+        return (short)borderFormatting.getDiagonalBorderColor();
+    }
+    public HSSFColor getDiagonalBorderColorColor() {
+        return workbook.getCustomPalette().getColor(
+                borderFormatting.getDiagonalBorderColor()
+        );
+    }
+
+    public short getLeftBorderColor() {
+        return (short)borderFormatting.getLeftBorderColor();
+    }
+    public HSSFColor getLeftBorderColorColor() {
+        return workbook.getCustomPalette().getColor(
+                borderFormatting.getLeftBorderColor()
+        );
+    }
+
+    public short getRightBorderColor() {
+        return (short)borderFormatting.getRightBorderColor();
+    }
+    public HSSFColor getRightBorderColorColor() {
+        return workbook.getCustomPalette().getColor(
+                borderFormatting.getRightBorderColor()
+        );
+    }
+
+    public short getTopBorderColor() {
+        return (short)borderFormatting.getTopBorderColor();
+    }
+    public HSSFColor getTopBorderColorColor() {
+        return workbook.getCustomPalette().getColor(
+                borderFormatting.getTopBorderColor()
+        );
+    }
+
+    public boolean isBackwardDiagonalOn() {
+        return borderFormatting.isBackwardDiagonalOn();
+    }
+    public boolean isForwardDiagonalOn() {
+        return borderFormatting.isForwardDiagonalOn();
+    }
+
+    public void setBackwardDiagonalOn(boolean on) {
+        borderFormatting.setBackwardDiagonalOn(on);
+        if (on) {
+            cfRuleRecord.setTopLeftBottomRightBorderModified(on);
+        }
+    }
+    public void setForwardDiagonalOn(boolean on) {
+        borderFormatting.setForwardDiagonalOn(on);
+        if (on) {
+            cfRuleRecord.setBottomLeftTopRightBorderModified(on);
+        }
+    }
+
+    public void setBorderBottom(short border) {
+        borderFormatting.setBorderBottom(border);
+        if (border != 0) {
+            cfRuleRecord.setBottomBorderModified(true);
+        } else {
+            cfRuleRecord.setBottomBorderModified(false);
+        }
+    }
+
+    public void setBorderDiagonal(short border) {
+        borderFormatting.setBorderDiagonal(border);
+        if (border != 0) {
+            cfRuleRecord.setBottomLeftTopRightBorderModified(true);
+            cfRuleRecord.setTopLeftBottomRightBorderModified(true);
+        } else {
+            cfRuleRecord.setBottomLeftTopRightBorderModified(false);
+            cfRuleRecord.setTopLeftBottomRightBorderModified(false);
+        }
+    }
+
+    public void setBorderLeft(short border) {
+        borderFormatting.setBorderLeft(border);
+        if (border != 0) {
+            cfRuleRecord.setLeftBorderModified(true);
+        } else {
+            cfRuleRecord.setLeftBorderModified(false);
+        }
+    }
+
+    public void setBorderRight(short border) {
+        borderFormatting.setBorderRight(border);
+        if (border != 0) {
+            cfRuleRecord.setRightBorderModified(true);
+        } else {
+            cfRuleRecord.setRightBorderModified(false);
+        }
+    }
+
+    public void setBorderTop(short border) {
+        borderFormatting.setBorderTop(border);
+        if (border != 0) {
+            cfRuleRecord.setTopBorderModified(true);
+        } else {
+            cfRuleRecord.setTopBorderModified(false);
+        }
+    }
+
+    public void setBottomBorderColor(short color) {
+        borderFormatting.setBottomBorderColor(color);
+        if (color != 0) {
+            cfRuleRecord.setBottomBorderModified(true);
+        } else {
+            cfRuleRecord.setBottomBorderModified(false);
+        }
+    }
+    public void setBottomBorderColor(Color color) {
+        HSSFColor hcolor = HSSFColor.toHSSFColor(color);
+        if (hcolor == null) {
+            setBottomBorderColor((short)0);
+        } else {
+            setBottomBorderColor(hcolor.getIndex());
+        }
+    }
+
+    public void setDiagonalBorderColor(short color) {
+        borderFormatting.setDiagonalBorderColor(color);
+        if (color != 0) {
+            cfRuleRecord.setBottomLeftTopRightBorderModified(true);
+            cfRuleRecord.setTopLeftBottomRightBorderModified(true);
+        } else {
+            cfRuleRecord.setBottomLeftTopRightBorderModified(false);
+            cfRuleRecord.setTopLeftBottomRightBorderModified(false);
+        }
+    }
+    public void setDiagonalBorderColor(Color color) {
+        HSSFColor hcolor = HSSFColor.toHSSFColor(color);
+        if (hcolor == null) {
+            setDiagonalBorderColor((short)0);
+        } else {
+            setDiagonalBorderColor(hcolor.getIndex());
+        }
+    }
+
+    public void setLeftBorderColor(short color) {
+        borderFormatting.setLeftBorderColor(color);
+        if (color != 0) {
+            cfRuleRecord.setLeftBorderModified(true);
+        } else {
+            cfRuleRecord.setLeftBorderModified(false);
+        }
+    }
+    public void setLeftBorderColor(Color color) {
+        HSSFColor hcolor = HSSFColor.toHSSFColor(color);
+        if (hcolor == null) {
+            setLeftBorderColor((short)0);
+        } else {
+            setLeftBorderColor(hcolor.getIndex());
+        }
+    }
+
+    public void setRightBorderColor(short color) {
+        borderFormatting.setRightBorderColor(color);
+        if (color != 0) {
+            cfRuleRecord.setRightBorderModified(true);
+        } else {
+            cfRuleRecord.setRightBorderModified(false);
+        }
+    }
+    public void setRightBorderColor(Color color) {
+        HSSFColor hcolor = HSSFColor.toHSSFColor(color);
+        if (hcolor == null) {
+            setRightBorderColor((short)0);
+        } else {
+            setRightBorderColor(hcolor.getIndex());
+        }
+    }
+
+    public void setTopBorderColor(short color) {
+        borderFormatting.setTopBorderColor(color);
+        if (color != 0) {
+            cfRuleRecord.setTopBorderModified(true);
+        } else {
+            cfRuleRecord.setTopBorderModified(false);
+        }
+    }
+    public void setTopBorderColor(Color color) {
+        HSSFColor hcolor = HSSFColor.toHSSFColor(color);
+        if (hcolor == null) {
+            setTopBorderColor((short)0);
+        } else {
+            setTopBorderColor(hcolor.getIndex());
+        }
+    }
 }

Modified: poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java?rev=1691843&r1=1691842&r2=1691843&view=diff
==============================================================================
--- poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java (original)
+++ poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java Sun Jul 19 19:00:32 2015
@@ -538,18 +538,17 @@ public class HSSFCell implements Cell {
 
     public void setCellValue(RichTextString value)
     {
-        HSSFRichTextString hvalue = (HSSFRichTextString) value;
         int row=_record.getRow();
         short col=_record.getColumn();
         short styleIndex=_record.getXFIndex();
-        if (hvalue == null)
+        if (value == null)
         {
             notifyFormulaChanging();
             setCellType(CELL_TYPE_BLANK, false, row, col, styleIndex);
             return;
         }
 
-        if(hvalue.length() > SpreadsheetVersion.EXCEL97.getMaxTextLength()){
+        if(value.length() > SpreadsheetVersion.EXCEL97.getMaxTextLength()){
             throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters");
         }
 
@@ -557,7 +556,7 @@ public class HSSFCell implements Cell {
             // Set the 'pre-evaluated result' for the formula
             // note - formulas do not preserve text formatting.
             FormulaRecordAggregate fr = (FormulaRecordAggregate) _record;
-            fr.setCachedStringResult(hvalue.getString());
+            fr.setCachedStringResult(value.getString());
             // Update our local cache to the un-formatted version
             _stringValue = new HSSFRichTextString(value.getString());
 
@@ -573,6 +572,7 @@ public class HSSFCell implements Cell {
         }
         int index = 0;
 
+        HSSFRichTextString hvalue = (HSSFRichTextString) value;
         UnicodeString str = hvalue.getUnicodeString();
         index = _book.getWorkbook().addSSTString(str);
         (( LabelSSTRecord ) _record).setSSTIndex(index);

Modified: poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java?rev=1691843&r1=1691842&r2=1691843&view=diff
==============================================================================
--- poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java (original)
+++ poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java Sun Jul 19 19:00:32 2015
@@ -129,10 +129,13 @@ public class HSSFComment extends HSSFTex
 
     @Override
     void setShapeId(int shapeId) {
+    	if(shapeId > 65535) {
+    		throw new IllegalArgumentException("Cannot add more than " + 65535 + " shapes");
+    	}
         super.setShapeId(shapeId);
         CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0);
-        cod.setObjectId((short) (shapeId % 1024));
-        _note.setShapeId(shapeId % 1024);
+        cod.setObjectId(shapeId);
+        _note.setShapeId(shapeId);
     }
 
     /**

Modified: poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java?rev=1691843&r1=1691842&r2=1691843&view=diff
==============================================================================
--- poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java (original)
+++ poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormatting.java Sun Jul 19 19:00:32 2015
@@ -16,7 +16,7 @@
 ==================================================================== */
 package org.apache.poi.hssf.usermodel;
 
-import org.apache.poi.hssf.record.CFRuleRecord;
+import org.apache.poi.hssf.record.CFRuleBase;
 import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate;
 import org.apache.poi.ss.usermodel.ConditionalFormatting;
 import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
@@ -73,91 +73,84 @@ import org.apache.poi.ss.util.CellRangeA
  * sheet.addConditionalFormatting(regions, rule);
  * </PRE>
  */
-public final class HSSFConditionalFormatting  implements ConditionalFormatting
-{
-	private final HSSFWorkbook _workbook;
-	private final CFRecordsAggregate cfAggregate;
-
-	HSSFConditionalFormatting(HSSFWorkbook workbook, CFRecordsAggregate cfAggregate)
-	{
-		if(workbook == null) {
-			throw new IllegalArgumentException("workbook must not be null");
-		}
-		if(cfAggregate == null) {
-			throw new IllegalArgumentException("cfAggregate must not be null");
-		}
-		_workbook = workbook;
-		this.cfAggregate = cfAggregate;
-	}
-	CFRecordsAggregate getCFRecordsAggregate() {
-		return cfAggregate;
-	}
-
-	/**
-	 * @deprecated (Aug-2008) use {@link HSSFConditionalFormatting#getFormattingRanges()}
-	 */
-	public org.apache.poi.ss.util.Region[] getFormattingRegions()
-	{
-		CellRangeAddress[] cellRanges = getFormattingRanges();
-		return org.apache.poi.ss.util.Region.convertCellRangesToRegions(cellRanges);
-	}
-	/**
-	 * @return array of <tt>CellRangeAddress</tt>s. never <code>null</code> 
-	 */
-	public CellRangeAddress[] getFormattingRanges() {
-		return cfAggregate.getHeader().getCellRanges();
-	}
-
-	/**
-	 * Replaces an existing Conditional Formatting rule at position idx. 
-	 * Excel allows to create up to 3 Conditional Formatting rules.
-	 * This method can be useful to modify existing  Conditional Formatting rules.
-	 * 
-	 * @param idx position of the rule. Should be between 0 and 2.
-	 * @param cfRule - Conditional Formatting rule
-	 */
-	public void setRule(int idx, HSSFConditionalFormattingRule cfRule)
-	{
-		cfAggregate.setRule(idx, cfRule.getCfRuleRecord());
-	}
+public final class HSSFConditionalFormatting  implements ConditionalFormatting {
+    private final HSSFSheet sheet;
+    private final CFRecordsAggregate cfAggregate;
+
+    HSSFConditionalFormatting(HSSFSheet sheet, CFRecordsAggregate cfAggregate) {
+        if(sheet == null) {
+            throw new IllegalArgumentException("sheet must not be null");
+        }
+        if(cfAggregate == null) {
+            throw new IllegalArgumentException("cfAggregate must not be null");
+        }
+        this.sheet = sheet; 
+        this.cfAggregate = cfAggregate;
+    }
+    CFRecordsAggregate getCFRecordsAggregate() {
+        return cfAggregate;
+    }
+
+    /**
+     * @deprecated (Aug-2008) use {@link HSSFConditionalFormatting#getFormattingRanges()}
+     */
+    public org.apache.poi.ss.util.Region[] getFormattingRegions() {
+        CellRangeAddress[] cellRanges = getFormattingRanges();
+        return org.apache.poi.ss.util.Region.convertCellRangesToRegions(cellRanges);
+    }
+    /**
+     * @return array of <tt>CellRangeAddress</tt>s. never <code>null</code> 
+     */
+    public CellRangeAddress[] getFormattingRanges() {
+        return cfAggregate.getHeader().getCellRanges();
+    }
+
+    /**
+     * Replaces an existing Conditional Formatting rule at position idx. 
+     * Older versions of Excel only allow up to 3 Conditional Formatting rules,
+     *  and will ignore rules beyond that, while newer versions are fine.
+     * This method can be useful to modify existing  Conditional Formatting rules.
+     * 
+     * @param idx position of the rule. Should be between 0 and 2 for older Excel versions
+     * @param cfRule - Conditional Formatting rule
+     */
+    public void setRule(int idx, HSSFConditionalFormattingRule cfRule) {
+        cfAggregate.setRule(idx, cfRule.getCfRuleRecord());
+    }
 
     public void setRule(int idx, ConditionalFormattingRule cfRule){
         setRule(idx, (HSSFConditionalFormattingRule)cfRule);
     }
 
-	/**
-	 * add a Conditional Formatting rule. 
-	 * Excel allows to create up to 3 Conditional Formatting rules.
-	 * @param cfRule - Conditional Formatting rule
-	 */
-	public void addRule(HSSFConditionalFormattingRule cfRule)
-	{
-		cfAggregate.addRule(cfRule.getCfRuleRecord());
-	}
+    /**
+     * add a Conditional Formatting rule. 
+     * Excel allows to create up to 3 Conditional Formatting rules.
+     * @param cfRule - Conditional Formatting rule
+     */
+    public void addRule(HSSFConditionalFormattingRule cfRule) {
+        cfAggregate.addRule(cfRule.getCfRuleRecord());
+    }
 
     public void addRule(ConditionalFormattingRule cfRule){
         addRule((HSSFConditionalFormattingRule)cfRule);
     }
 
-	/**
-	 * @return the Conditional Formatting rule at position idx.
-	 */
-	public HSSFConditionalFormattingRule getRule(int idx)
-	{
-		CFRuleRecord ruleRecord = cfAggregate.getRule(idx);
-		return new HSSFConditionalFormattingRule(_workbook, ruleRecord);
-	}
-
-	/**
-	 * @return number of Conditional Formatting rules.
-	 */
-	public int getNumberOfRules()
-	{
-		return cfAggregate.getNumberOfRules();
-	}
-
-	public String toString()
-	{
-		return cfAggregate.toString();
-	}
+    /**
+     * @return the Conditional Formatting rule at position idx.
+     */
+    public HSSFConditionalFormattingRule getRule(int idx) {
+        CFRuleBase ruleRecord = cfAggregate.getRule(idx);
+        return new HSSFConditionalFormattingRule(sheet, ruleRecord);
+    }
+
+    /**
+     * @return number of Conditional Formatting rules.
+     */
+    public int getNumberOfRules() {
+        return cfAggregate.getNumberOfRules();
+    }
+
+    public String toString() {
+        return cfAggregate.toString();
+    }
 }

Modified: poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java?rev=1691843&r1=1691842&r2=1691843&view=diff
==============================================================================
--- poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java (original)
+++ poi/branches/common_sl/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java Sun Jul 19 19:00:32 2015
@@ -18,12 +18,16 @@
 package org.apache.poi.hssf.usermodel;
 
 import org.apache.poi.hssf.model.HSSFFormulaParser;
+import org.apache.poi.hssf.record.CFRule12Record;
+import org.apache.poi.hssf.record.CFRuleBase;
+import org.apache.poi.hssf.record.CFRuleBase.ComparisonOperator;
 import org.apache.poi.hssf.record.CFRuleRecord;
-import org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator;
 import org.apache.poi.hssf.record.cf.BorderFormatting;
 import org.apache.poi.hssf.record.cf.FontFormatting;
+import org.apache.poi.hssf.record.cf.IconMultiStateFormatting;
 import org.apache.poi.hssf.record.cf.PatternFormatting;
 import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.usermodel.ConditionType;
 import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
 
 /**
@@ -32,178 +36,224 @@ import org.apache.poi.ss.usermodel.Condi
  * It allows to specify formula based conditions for the Conditional Formatting
  * and the formatting settings such as font, border and pattern.
  */
-public final class HSSFConditionalFormattingRule implements ConditionalFormattingRule
-{
-	private static final byte CELL_COMPARISON = CFRuleRecord.CONDITION_TYPE_CELL_VALUE_IS;
-
-	private final CFRuleRecord cfRuleRecord;
-	private final HSSFWorkbook workbook;
-
-	HSSFConditionalFormattingRule(HSSFWorkbook pWorkbook, CFRuleRecord pRuleRecord) {
-		if (pWorkbook == null) {
-			throw new IllegalArgumentException("pWorkbook must not be null");
-		}
-		if (pRuleRecord == null) {
-			throw new IllegalArgumentException("pRuleRecord must not be null");
-		}
-		workbook = pWorkbook;
-		cfRuleRecord = pRuleRecord;
-	}
-
-	CFRuleRecord getCfRuleRecord()
-	{
-		return cfRuleRecord;
-	}
-
-	private HSSFFontFormatting getFontFormatting(boolean create)
-	{
-		FontFormatting fontFormatting = cfRuleRecord.getFontFormatting();
-		if ( fontFormatting != null)
-		{
-			cfRuleRecord.setFontFormatting(fontFormatting);
-			return new HSSFFontFormatting(cfRuleRecord);
-		}
-		else if( create )
-		{
-			fontFormatting = new FontFormatting();
-			cfRuleRecord.setFontFormatting(fontFormatting);
-			return new HSSFFontFormatting(cfRuleRecord);
-		}
-		else
-		{
-			return null;
-		}
-	}
-
-	/**
-	 * @return - font formatting object  if defined,  <code>null</code> otherwise
-	 */
-	public HSSFFontFormatting getFontFormatting()
-	{
-		return getFontFormatting(false);
-	}
-	/**
-	 * create a new font formatting structure if it does not exist,
-	 * otherwise just return existing object.
-	 * @return - font formatting object, never returns <code>null</code>.
-	 */
-	public HSSFFontFormatting createFontFormatting()
-	{
-		return getFontFormatting(true);
-	}
-
-	private HSSFBorderFormatting getBorderFormatting(boolean create)
-	{
-		BorderFormatting borderFormatting = cfRuleRecord.getBorderFormatting();
-		if ( borderFormatting != null)
-		{
-			cfRuleRecord.setBorderFormatting(borderFormatting);
-			return new HSSFBorderFormatting(cfRuleRecord);
-		}
-		else if( create )
-		{
-			borderFormatting = new BorderFormatting();
-			cfRuleRecord.setBorderFormatting(borderFormatting);
-			return new HSSFBorderFormatting(cfRuleRecord);
-		}
-		else
-		{
-			return null;
-		}
-	}
-	/**
-	 * @return - border formatting object  if defined,  <code>null</code> otherwise
-	 */
-	public HSSFBorderFormatting getBorderFormatting()
-	{
-		return getBorderFormatting(false);
-	}
-	/**
-	 * create a new border formatting structure if it does not exist,
-	 * otherwise just return existing object.
-	 * @return - border formatting object, never returns <code>null</code>.
-	 */
-	public HSSFBorderFormatting createBorderFormatting()
-	{
-		return getBorderFormatting(true);
-	}
-
-	private HSSFPatternFormatting getPatternFormatting(boolean create)
-	{
-		PatternFormatting patternFormatting = cfRuleRecord.getPatternFormatting();
-		if ( patternFormatting != null)
-		{
-			cfRuleRecord.setPatternFormatting(patternFormatting);
-			return new HSSFPatternFormatting(cfRuleRecord);
-		}
-		else if( create )
-		{
-			patternFormatting = new PatternFormatting();
-			cfRuleRecord.setPatternFormatting(patternFormatting);
-			return new HSSFPatternFormatting(cfRuleRecord);
-		}
-		else
-		{
-			return null;
-		}
-	}
-
-	/**
-	 * @return - pattern formatting object  if defined, <code>null</code> otherwise
-	 */
-	public HSSFPatternFormatting getPatternFormatting()
-	{
-		return getPatternFormatting(false);
-	}
-	/**
-	 * create a new pattern formatting structure if it does not exist,
-	 * otherwise just return existing object.
-	 * @return - pattern formatting object, never returns <code>null</code>.
-	 */
-	public HSSFPatternFormatting createPatternFormatting()
-	{
-		return getPatternFormatting(true);
-	}
-
-	/**
-	 * @return -  the conditiontype for the cfrule
-	 */
-	public byte getConditionType() {
-		return cfRuleRecord.getConditionType();
-	}
-
-	/**
-	 * @return - the comparisionoperatation for the cfrule
-	 */
-	public byte getComparisonOperation() {
-		return cfRuleRecord.getComparisonOperation();
-	}
-
-	public String getFormula1()
-	{
-		return toFormulaString(cfRuleRecord.getParsedExpression1());
-	}
-
-	public String getFormula2()
-	{
-		byte conditionType = cfRuleRecord.getConditionType();
-		if (conditionType == CELL_COMPARISON) {
-			byte comparisonOperation = cfRuleRecord.getComparisonOperation();
-			switch(comparisonOperation)
-			{
-				case ComparisonOperator.BETWEEN:
-				case ComparisonOperator.NOT_BETWEEN:
-					return toFormulaString(cfRuleRecord.getParsedExpression2());
-			}
-		}
-		return null;
-	}
-
-	private String toFormulaString(Ptg[] parsedExpression)
-	{
-		if(parsedExpression ==null) {
-			return null;
-		}
-		return HSSFFormulaParser.toFormulaString(workbook, parsedExpression);
-	}
+public final class HSSFConditionalFormattingRule implements ConditionalFormattingRule {
+    private static final byte CELL_COMPARISON = CFRuleRecord.CONDITION_TYPE_CELL_VALUE_IS;
+
+    private final CFRuleBase cfRuleRecord;
+    private final HSSFWorkbook workbook;
+    private final HSSFSheet sheet;
+
+    HSSFConditionalFormattingRule(HSSFSheet pSheet, CFRuleBase pRuleRecord) {
+        if (pSheet == null) {
+            throw new IllegalArgumentException("pSheet must not be null");
+        }
+        if (pRuleRecord == null) {
+            throw new IllegalArgumentException("pRuleRecord must not be null");
+        }
+        sheet = pSheet;
+        workbook = pSheet.getWorkbook();
+        cfRuleRecord = pRuleRecord;
+    }
+
+    CFRuleBase getCfRuleRecord()
+    {
+        return cfRuleRecord;
+    }
+
+    private HSSFFontFormatting getFontFormatting(boolean create)
+    {
+        FontFormatting fontFormatting = cfRuleRecord.getFontFormatting();
+        if ( fontFormatting != null)
+        {
+            cfRuleRecord.setFontFormatting(fontFormatting);
+            return new HSSFFontFormatting(cfRuleRecord, workbook);
+        }
+        else if( create )
+        {
+            fontFormatting = new FontFormatting();
+            cfRuleRecord.setFontFormatting(fontFormatting);
+            return new HSSFFontFormatting(cfRuleRecord, workbook);
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    /**
+     * @return - font formatting object  if defined,  <code>null</code> otherwise
+     */
+    public HSSFFontFormatting getFontFormatting()
+    {
+        return getFontFormatting(false);
+    }
+    /**
+     * create a new font formatting structure if it does not exist,
+     * otherwise just return existing object.
+     * @return - font formatting object, never returns <code>null</code>.
+     */
+    public HSSFFontFormatting createFontFormatting()
+    {
+        return getFontFormatting(true);
+    }
+
+    private HSSFBorderFormatting getBorderFormatting(boolean create)
+    {
+        BorderFormatting borderFormatting = cfRuleRecord.getBorderFormatting();
+        if ( borderFormatting != null)
+        {
+            cfRuleRecord.setBorderFormatting(borderFormatting);
+            return new HSSFBorderFormatting(cfRuleRecord, workbook);
+        }
+        else if( create )
+        {
+            borderFormatting = new BorderFormatting();
+            cfRuleRecord.setBorderFormatting(borderFormatting);
+            return new HSSFBorderFormatting(cfRuleRecord, workbook);
+        }
+        else
+        {
+            return null;
+        }
+    }
+    /**
+     * @return - border formatting object  if defined,  <code>null</code> otherwise
+     */
+    public HSSFBorderFormatting getBorderFormatting()
+    {
+        return getBorderFormatting(false);
+    }
+    /**
+     * create a new border formatting structure if it does not exist,
+     * otherwise just return existing object.
+     * @return - border formatting object, never returns <code>null</code>.
+     */
+    public HSSFBorderFormatting createBorderFormatting()
+    {
+        return getBorderFormatting(true);
+    }
+
+    private HSSFPatternFormatting getPatternFormatting(boolean create)
+    {
+        PatternFormatting patternFormatting = cfRuleRecord.getPatternFormatting();
+        if ( patternFormatting != null)
+        {
+            cfRuleRecord.setPatternFormatting(patternFormatting);
+            return new HSSFPatternFormatting(cfRuleRecord, workbook);
+        }
+        else if( create )
+        {
+            patternFormatting = new PatternFormatting();
+            cfRuleRecord.setPatternFormatting(patternFormatting);
+            return new HSSFPatternFormatting(cfRuleRecord, workbook);
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    /**
+     * @return - pattern formatting object  if defined, <code>null</code> otherwise
+     */
+    public HSSFPatternFormatting getPatternFormatting()
+    {
+        return getPatternFormatting(false);
+    }
+    /**
+     * create a new pattern formatting structure if it does not exist,
+     * otherwise just return existing object.
+     * @return - pattern formatting object, never returns <code>null</code>.
+     */
+    public HSSFPatternFormatting createPatternFormatting()
+    {
+        return getPatternFormatting(true);
+    }
+    
+    private HSSFIconMultiStateFormatting getMultiStateFormatting(boolean create) {
+        if (cfRuleRecord instanceof CFRule12Record) {
+            // Good
+        } else {
+            if (create) throw new IllegalArgumentException("Can't convert a CF into a CF12 record");
+            return null;
+        }
+        CFRule12Record cfRule12Record = (CFRule12Record)cfRuleRecord;
+        IconMultiStateFormatting iconFormatting = cfRule12Record.getMultiStateFormatting();
+        if (iconFormatting != null)
+        {
+            return new HSSFIconMultiStateFormatting(cfRule12Record, sheet);
+        }
+        else if( create )
+        {
+            iconFormatting = cfRule12Record.createMultiStateFormatting();
+            return new HSSFIconMultiStateFormatting(cfRule12Record, sheet);
+        }
+        else
+        {
+            return null;
+        }
+    }
+    
+    /**
+     * @return icon / multi-state formatting object if defined, <code>null</code> otherwise
+     */
+    public HSSFIconMultiStateFormatting getMultiStateFormatting() {
+        return getMultiStateFormatting(false);
+    }
+
+    /**
+     * create a new icon / multi-state formatting object if it does not exist,
+     * otherwise just return the existing object.
+     */
+    public HSSFIconMultiStateFormatting createMultiStateFormatting() {
+        return getMultiStateFormatting(true);
+    }
+    
+    /**
+     * @return -  the conditiontype for the cfrule
+     */
+    public byte getConditionType() {
+        return cfRuleRecord.getConditionType();
+    }
+    /**
+     * @return -  the conditiontype for the cfrule
+     */
+    public ConditionType getConditionTypeType() {
+        return ConditionType.forId(getConditionType());
+    }
+
+    /**
+     * @return - the comparisionoperatation for the cfrule
+     */
+    public byte getComparisonOperation() {
+        return cfRuleRecord.getComparisonOperation();
+    }
+
+    public String getFormula1()
+    {
+        return toFormulaString(cfRuleRecord.getParsedExpression1());
+    }
+
+    public String getFormula2() {
+        byte conditionType = cfRuleRecord.getConditionType();
+        if (conditionType == CELL_COMPARISON) {
+            byte comparisonOperation = cfRuleRecord.getComparisonOperation();
+            switch(comparisonOperation) {
+                case ComparisonOperator.BETWEEN:
+                case ComparisonOperator.NOT_BETWEEN:
+                    return toFormulaString(cfRuleRecord.getParsedExpression2());
+            }
+        }
+        return null;
+    }
+
+    protected String toFormulaString(Ptg[] parsedExpression) {
+        return toFormulaString(parsedExpression, workbook);
+    }
+    protected static String toFormulaString(Ptg[] parsedExpression, HSSFWorkbook workbook) {
+        if(parsedExpression == null || parsedExpression.length == 0) {
+            return null;
+        }
+        return HSSFFormulaParser.toFormulaString(workbook, parsedExpression);
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org