550 lines
14 KiB
Java
550 lines
14 KiB
Java
|
|
/* ====================================================================
|
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
|
contributor license agreements. See the NOTICE file distributed with
|
|
this work for additional information regarding copyright ownership.
|
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
|
(the "License"); you may not use this file except in compliance with
|
|
the License. You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
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;
|
|
import org.apache.poi.util.BitField;
|
|
import org.apache.poi.util.BitFieldFactory;
|
|
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 = (byte[]) _rawData.clone();
|
|
return new FontFormatting(rawData);
|
|
}
|
|
}
|