From: Nick Burch Date: Wed, 9 Apr 2008 09:17:58 +0000 (+0000) Subject: Merged revisions 638786-638802,638805-638811,638813-638814,638816-639230,639233-63924... X-Git-Tag: REL_3_5_BETA2~110 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=626b75ac7e8f61682f931ee3862277831ce72bce;p=poi.git Merged revisions 638786-638802,638805-638811,638813-638814,638816-639230,639233-639241,639243-639253,639255-639486,639488-639601,639603-639835,639837-639917,639919-640056,640058-640710,640712-641156,641158-641184,641186-641795,641797-641798,641800-641933,641935-641963,641965-641966,641968-641995,641997-642230,642232-642562,642564-642565,642568-642570,642572-642573,642576-642736,642739-642877,642879,642881-642890,642892-642903,642905-642945,642947-643624,643626-643653,643655-643669,643671,643673-643830,643832-643833,643835-644342,644344-644472,644474-644508,644510-645347,645349-645351,645353-645559,645561-645565,645568-646236 via svnmerge from https://svn.apache.org:443/repos/asf/poi/trunk ........ r645952 | yegor | 2008-04-08 15:49:59 +0100 (Tue, 08 Apr 2008) | 1 line fix bug #44770: RuntimeException: Couldn't instantiate the class for type with id 1036 on class class org.apache.poi.hslf.record.PPDrawing ........ r646194 | josh | 2008-04-09 06:56:50 +0100 (Wed, 09 Apr 2008) | 1 line some more tweaks for bug 30311. Set some (unused) bits in FontFormatting to match Excel. ........ git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@646237 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/java/org/apache/poi/hssf/record/cf/FontFormatting.java b/src/java/org/apache/poi/hssf/record/cf/FontFormatting.java index eaae02de30..e932beb9ae 100644 --- a/src/java/org/apache/poi/hssf/record/cf/FontFormatting.java +++ b/src/java/org/apache/poi/hssf/record/cf/FontFormatting.java @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. ==================================================================== */ - + package org.apache.poi.hssf.record.cf; import org.apache.poi.hssf.record.RecordInputStream; @@ -26,580 +26,524 @@ import org.apache.poi.util.LittleEndian; /** * Font Formatting Block of the Conditional Formatting Rule Record. * - * Created on January 22, 2008, 10:05 PM - * * @author Dmitriy Kumshayev */ - -public class FontFormatting +public final class FontFormatting { - private byte [] record; - - 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_USED = 104; - private static final int OFFSET_FONT_FORMATING_END = 116; - - - 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 final static short SS_NONE = 0; - - /** - * Escapement type - Superscript - */ - public final static short SS_SUPER = 1; - - /** - * Escapement type - Subscript - */ - public final static short SS_SUB = 2; - - /** - * Underline type - None - */ - public final static byte U_NONE = 0; - - /** - * Underline type - Single - */ - public final static byte U_SINGLE = 1; - - /** - * Underline type - Double - */ - public final static byte U_DOUBLE = 2; - - /** - * Underline type - Single Accounting - */ - public final static byte U_SINGLE_ACCOUNTING = 0x21; - - /** - * Underline type - Double Accounting - */ - public final static byte U_DOUBLE_ACCOUNTING = 0x22; - - /** - * Normal boldness (not bold) - */ - - protected final static short FONT_WEIGHT_NORMAL = 0x190; - - /** - * Bold boldness (bold) - */ - - protected final static short FONT_WEIGHT_BOLD = 0x2bc; - - public FontFormatting() - { - this(new byte[118]); - - this.setFontHeight((short)-1); - this.setItalic(false); - this.setFontWieghtModified(false); - this.setOutline(false); - this.setShadow(false); - this.setStrikeout(false); - this.setEscapementType((short)0); - this.setUnderlineType((byte)0); - this.setFontColorIndex((short)-1); - - this.setFontStyleModified(false); - this.setFontOutlineModified(false); - this.setFontShadowModified(false); - this.setFontCancellationModified(false); - - this.setEscapementTypeModified(false); - this.setUnderlineTypeModified(false); - - LittleEndian.putShort(record, OFFSET_FONT_NAME, (short)0); - LittleEndian.putInt(record, OFFSET_NOT_USED, 0x00000001); - LittleEndian.putShort(record, OFFSET_FONT_FORMATING_END, (short)0x0001); - } - - /** Creates new FontFormatting */ - private FontFormatting(byte[] record) - { - this.record = record; - } - - /** Creates new FontFormatting */ - public FontFormatting(RecordInputStream in) - { - record = new byte[118]; - for (int i = 0; i != record.length; i++) + 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++) { - record[i] = in.readByte(); + _rawData[i] = in.readByte(); } } - - public byte[] getRawRecord() - { - return record; - } - - /** - * 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(short height) - { - LittleEndian.putInt(record, 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 short getFontHeight() - { - return (short) LittleEndian.getInt(record, OFFSET_FONT_HEIGHT); - } + + 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 = LittleEndian.getInt(record,OFFSET_FONT_OPTIONS); - options = field.setBoolean(options, option); - LittleEndian.putInt(record,OFFSET_FONT_OPTIONS, options); + int options = getInt(OFFSET_FONT_OPTIONS); + options = field.setBoolean(options, option); + setInt(OFFSET_FONT_OPTIONS, options); } - + private boolean getFontOption(BitField field) { - int options = LittleEndian.getInt(record,OFFSET_FONT_OPTIONS); - return field.isSet(options); + int options = getInt(OFFSET_FONT_OPTIONS); + return field.isSet(options); } - - /** - * set the font to be italics or not - * - * @param italics - whether the font is italics or not - * @see #setAttributes(short) - */ - - 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 #getAttributes() - */ - - 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 #getAttributes() - */ - - 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 bw) - { - if( bw<100) { bw=100; } - if( bw>1000){ bw=1000; } - LittleEndian.putShort(record,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 LittleEndian.getShort(record,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 LittleEndian.getShort(record,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) - { - LittleEndian.putShort(record,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 LittleEndian.getShort(record,OFFSET_UNDERLINE_TYPE); - } - - /** - * set the type of underlining type for the font - * - * @param u super or subscript 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) - { - LittleEndian.putShort(record,OFFSET_UNDERLINE_TYPE, underlineType); - } - - - public short getFontColorIndex() - { - return (short)LittleEndian.getInt(record,OFFSET_FONT_COLOR_INDEX); - } - - public void setFontColorIndex(short fci ) - { - LittleEndian.putInt(record,OFFSET_FONT_COLOR_INDEX,fci); - } - - private boolean getOptionFlag(BitField field) - { - int optionFlags = LittleEndian.getInt(record,OFFSET_OPTION_FLAGS); - int value = field.getValue(optionFlags); - return value==0? true : false ; + + /** + * set the font to be italics or not + * + * @param italics - whether the font is italics or not + * @see #setAttributes(short) + */ + + 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 #getAttributes() + */ + + 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 #getAttributes() + */ + + 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 = LittleEndian.getInt(record,OFFSET_OPTION_FLAGS); - optionFlags = field.setValue(optionFlags, value); - LittleEndian.putInt(record,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; - LittleEndian.putInt(record,OFFSET_ESCAPEMENT_TYPE_MODIFIED, value); - } - public boolean isEscapementTypeModified() - { - int escapementModified = LittleEndian.getInt(record,OFFSET_ESCAPEMENT_TYPE_MODIFIED); - return escapementModified == 0; - } - - public void setUnderlineTypeModified(boolean modified) - { - int value = modified? 0 : 1; - LittleEndian.putInt(record,OFFSET_UNDERLINE_TYPE_MODIFIED, value); - } - - public boolean isUnderlineTypeModified() - { - int underlineModified = LittleEndian.getInt(record,OFFSET_UNDERLINE_TYPE_MODIFIED); - return underlineModified == 0; - } - - public void setFontWieghtModified(boolean modified) - { - int value = modified? 0 : 1; - LittleEndian.putInt(record,OFFSET_FONT_WEIGHT_MODIFIED, value); - } - - public boolean isFontWeightModified() - { - int fontStyleModified = LittleEndian.getInt(record,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( + 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(" ====\n"); - buffer.append(" ["+OFFSET_FONT_HEIGHT+"] FONT HEIGHT: "+intToHex(OFFSET_FONT_HEIGHT)+"\n"); - buffer.append(" ["+OFFSET_FONT_OPTIONS+"] FONT OPTIONS: "+intToHex(OFFSET_FONT_OPTIONS)+"\n"); - buffer.append(" ["+OFFSET_FONT_WEIGHT+"] FONT WEIGHT: "+shortToHex(OFFSET_FONT_WEIGHT)+"\n"); - buffer.append(" ["+OFFSET_ESCAPEMENT_TYPE+"] FONT ESCAPEMENT: "+shortToHex(OFFSET_ESCAPEMENT_TYPE)+"\n"); - buffer.append(" ["+OFFSET_UNDERLINE_TYPE+"] FONT UNDERLINE: "+byteToHex(OFFSET_UNDERLINE_TYPE)+"\n"); - buffer.append(" ["+(OFFSET_UNDERLINE_TYPE+1)+"] FONT NOT USED: "+byteToHex(OFFSET_UNDERLINE_TYPE+1)+"\n"); - buffer.append(" ["+(OFFSET_UNDERLINE_TYPE+2)+"] FONT NOT USED: "+byteToHex(OFFSET_UNDERLINE_TYPE+2)+"\n"); - buffer.append(" ["+(OFFSET_UNDERLINE_TYPE+3)+"] FONT NOT USED: "+byteToHex(OFFSET_UNDERLINE_TYPE+3)+"\n"); - buffer.append(" ["+OFFSET_FONT_COLOR_INDEX+"] FONT COLIDX: "+intToHex(OFFSET_FONT_COLOR_INDEX)+"\n"); - buffer.append(" ["+(OFFSET_FONT_COLOR_INDEX+4)+"] FONT NOT USED: "+intToHex(OFFSET_FONT_COLOR_INDEX+4)+"\n"); - buffer.append(" ["+OFFSET_OPTION_FLAGS+"] FONT OPTIONS: "+intToHex(OFFSET_OPTION_FLAGS)+"\n"); - buffer.append(" ["+OFFSET_ESCAPEMENT_TYPE_MODIFIED+"] FONT ESC MOD: "+intToHex(OFFSET_ESCAPEMENT_TYPE_MODIFIED)+"\n"); - buffer.append(" ["+OFFSET_UNDERLINE_TYPE_MODIFIED+"] FONT UND MOD: "+intToHex(OFFSET_UNDERLINE_TYPE_MODIFIED)+"\n"); - buffer.append(" ["+OFFSET_FONT_WEIGHT+"] FONT WGH MOD: "+intToHex(OFFSET_FONT_WEIGHT)+"\n"); - buffer.append(" ["+OFFSET_NOT_USED+"] FONT NOT USED: "+intToHex(OFFSET_NOT_USED)+"\n"); - buffer.append(" ["+(OFFSET_NOT_USED+4)+"] FONT NOT USED: "+intToHex(OFFSET_NOT_USED+4)+"\n"); - buffer.append(" ["+(OFFSET_NOT_USED+8)+"] FONT NOT USED: "+intToHex(OFFSET_NOT_USED+8)+"\n"); - buffer.append(" ["+OFFSET_FONT_FORMATING_END+"] FONT FORMATTING END: "+shortToHex(OFFSET_FONT_FORMATING_END)+"\n"); - buffer.append(" ====\n"); - - buffer.append(" [/Font Formatting]\n"); - return buffer.toString(); - } - - public Object clone() - { - FontFormatting rec = new FontFormatting(); - if( record != null) - { - byte[] clone = new byte[record.length]; - System.arraycopy(record, 0, clone, 0, record.length); - rec.record = clone; - } - return rec; - } - - private String intToHex(int offset) - { - return Integer.toHexString(LittleEndian.getInt(record, offset)); - } - private String shortToHex(int offset) - { - return Integer.toHexString(LittleEndian.getShort(record, offset)&0xFFFF); - } - private String byteToHex(int offset) - { - return Integer.toHexString(record[offset]&0xFF); + 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 = (byte[]) _rawData.clone(); + return new FontFormatting(rawData); } - } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFFontFormatting.java b/src/java/org/apache/poi/hssf/usermodel/HSSFFontFormatting.java index 12ea90698f..a701eb63af 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFFontFormatting.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFFontFormatting.java @@ -88,7 +88,7 @@ public final class HSSFFontFormatting * * @return fontheight (in points/20); or -1 if not modified */ - public short getFontHeight() + public int getFontHeight() { return fontFormatting.getFontHeight(); } @@ -308,7 +308,7 @@ public final class HSSFFontFormatting * @param height * @see org.apache.poi.hssf.record.cf.FontFormatting#setFontHeight(short) */ - public void setFontHeight(short height) + public void setFontHeight(int height) { fontFormatting.setFontHeight(height); } diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java b/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java index db0d434aee..e42b358b89 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java @@ -119,6 +119,9 @@ public class PPDrawing extends RecordAtom * Tree walking way of finding Escher Child Records */ private void findEscherChildren(DefaultEscherRecordFactory erf, byte[] source, int startPos, int lenToGo, Vector found) { + + int escherBytes = LittleEndian.getInt( source, startPos + 4 ) + 8; + // Find the record EscherRecord r = erf.createRecord(source,startPos); // Fill it in @@ -131,6 +134,17 @@ public class PPDrawing extends RecordAtom if(size < 8) { logger.log(POILogger.WARN, "Hit short DDF record at " + startPos + " - " + size); } + + /** + * Sanity check. Always advance the cursor by the correct value. + * + * getRecordSize() must return exatcly the same number of bytes that was written in fillFields. + * Sometimes it is not so, see an example in bug #44770. Most likely reason is that one of ddf records calculates wrong size. + */ + if(size != escherBytes){ + logger.log(POILogger.WARN, "Record length=" + escherBytes + " but getRecordSize() returned " + r.getRecordSize() + "; record: " + r.getClass()); + size = escherBytes; + } startPos += size; lenToGo -= size; if(lenToGo >= 8) { diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/Record.java b/src/scratchpad/src/org/apache/poi/hslf/record/Record.java index 79d08ea65e..1aface94cd 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/Record.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/Record.java @@ -185,13 +185,13 @@ public abstract class Record // Instantiate toReturn = (Record)(con.newInstance(new Object[] { b, new Integer(start), new Integer(len) })); } catch(InstantiationException ie) { - throw new RuntimeException("Couldn't instantiate the class for type with id " + type + " on class " + c + " : " + ie); + throw new RuntimeException("Couldn't instantiate the class for type with id " + type + " on class " + c + " : " + ie, ie); } catch(java.lang.reflect.InvocationTargetException ite) { - throw new RuntimeException("Couldn't instantiate the class for type with id " + type + " on class " + c + " : " + ite + "\nCause was : " + ite.getCause()); + throw new RuntimeException("Couldn't instantiate the class for type with id " + type + " on class " + c + " : " + ite + "\nCause was : " + ite.getCause(), ite); } catch(IllegalAccessException iae) { - throw new RuntimeException("Couldn't access the constructor for type with id " + type + " on class " + c + " : " + iae); + throw new RuntimeException("Couldn't access the constructor for type with id " + type + " on class " + c + " : " + iae, iae); } catch(NoSuchMethodException nsme) { - throw new RuntimeException("Couldn't access the constructor for type with id " + type + " on class " + c + " : " + nsme); + throw new RuntimeException("Couldn't access the constructor for type with id " + type + " on class " + c + " : " + nsme, nsme); } // Handling for special kinds of records follow diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/data/44770.ppt b/src/scratchpad/testcases/org/apache/poi/hslf/data/44770.ppt new file mode 100755 index 0000000000..d7ae12b569 Binary files /dev/null and b/src/scratchpad/testcases/org/apache/poi/hslf/data/44770.ppt differ diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java index f3f5f8e7ee..36e45501ec 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java @@ -350,4 +350,14 @@ public class TestBugs extends TestCase { assertEquals(Picture.JPEG, pict.getType()); } + /** + * Bug 44770: java.lang.RuntimeException: Couldn't instantiate the class for type with id 1036 on class class org.apache.poi.hslf.record.PPDrawing + */ + public void test44770() throws Exception { + FileInputStream is = new FileInputStream(new File(cwd, "44770.ppt")); + SlideShow ppt = new SlideShow(is); + is.close(); + + assertTrue("No Exceptions while reading file", true); + } } diff --git a/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java b/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java index c068f29a67..8f7593f09f 100644 --- a/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java +++ b/src/testcases/org/apache/poi/hssf/record/TestCFRuleRecord.java @@ -230,7 +230,7 @@ public final class TestCFRuleRecord extends TestCase fontFormatting.setFontColorIndex((short)10); assertEquals(10,fontFormatting.getFontColorIndex()); - fontFormatting.setFontHeight((short)100); + fontFormatting.setFontHeight(100); assertEquals(100,fontFormatting.getFontHeight()); fontFormatting.setFontOutlineModified(false);