| /* ==================================================================== |
| 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.xssf.usermodel; |
| |
| import org.apache.poi.POIXMLException; |
| import org.apache.poi.util.Internal; |
| import org.apache.poi.ss.usermodel.Font; |
| import org.apache.poi.ss.usermodel.FontCharset; |
| import org.apache.poi.ss.usermodel.FontFamily; |
| import org.apache.poi.ss.usermodel.FontScheme; |
| import org.apache.poi.ss.usermodel.FontUnderline; |
| import org.apache.poi.ss.usermodel.IndexedColors; |
| import org.apache.poi.xssf.model.StylesTable; |
| import org.apache.poi.xssf.model.ThemesTable; |
| import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBooleanProperty; |
| import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; |
| import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont; |
| import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontName; |
| import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontScheme; |
| import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontSize; |
| import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTIntProperty; |
| import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTUnderlineProperty; |
| import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTVerticalAlignFontProperty; |
| import org.openxmlformats.schemas.spreadsheetml.x2006.main.STFontScheme; |
| import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnderlineValues; |
| import org.openxmlformats.schemas.spreadsheetml.x2006.main.STVerticalAlignRun; |
| |
| /** |
| * Represents a font used in a workbook. |
| * |
| * @author Gisella Bronzetti |
| */ |
| public class XSSFFont implements Font { |
| |
| /** |
| * By default, Microsoft Office Excel 2007 uses the Calibry font in font size 11 |
| */ |
| public static final String DEFAULT_FONT_NAME = "Calibri"; |
| /** |
| * By default, Microsoft Office Excel 2007 uses the Calibry font in font size 11 |
| */ |
| public static final short DEFAULT_FONT_SIZE = 11; |
| /** |
| * Default font color is black |
| * @see org.apache.poi.ss.usermodel.IndexedColors#BLACK |
| */ |
| public static final short DEFAULT_FONT_COLOR = IndexedColors.BLACK.getIndex(); |
| |
| private ThemesTable _themes; |
| private CTFont _ctFont; |
| private short _index; |
| |
| /** |
| * Create a new XSSFFont |
| * |
| * @param font the underlying CTFont bean |
| */ |
| public XSSFFont(CTFont font) { |
| _ctFont = font; |
| _index = 0; |
| } |
| |
| public XSSFFont(CTFont font, int index) { |
| _ctFont = font; |
| _index = (short)index; |
| } |
| |
| /** |
| * Create a new XSSFont. This method is protected to be used only by XSSFWorkbook |
| */ |
| protected XSSFFont() { |
| this._ctFont = CTFont.Factory.newInstance(); |
| setFontName(DEFAULT_FONT_NAME); |
| setFontHeight((double)DEFAULT_FONT_SIZE); |
| } |
| |
| /** |
| * get the underlying CTFont font |
| */ |
| @Internal |
| public CTFont getCTFont() { |
| return _ctFont; |
| } |
| |
| /** |
| * get a boolean value for the boldness to use. |
| * |
| * @return boolean - bold |
| */ |
| public boolean getBold() { |
| CTBooleanProperty bold = _ctFont.sizeOfBArray() == 0 ? null : _ctFont.getBArray(0); |
| return (bold != null && bold.getVal()); |
| } |
| |
| /** |
| * get character-set to use. |
| * |
| * @return int - character-set (0-255) |
| * @see org.apache.poi.ss.usermodel.FontCharset |
| */ |
| public int getCharSet() { |
| CTIntProperty charset = _ctFont.sizeOfCharsetArray() == 0 ? null : _ctFont.getCharsetArray(0); |
| int val = charset == null ? FontCharset.ANSI.getValue() : FontCharset.valueOf(charset.getVal()).getValue(); |
| return val; |
| } |
| |
| |
| /** |
| * get the indexed color value for the font |
| * References a color defined in IndexedColors. |
| * |
| * @return short - indexed color to use |
| * @see IndexedColors |
| */ |
| public short getColor() { |
| CTColor color = _ctFont.sizeOfColorArray() == 0 ? null : _ctFont.getColorArray(0); |
| if (color == null) return IndexedColors.BLACK.getIndex(); |
| |
| long index = color.getIndexed(); |
| if (index == XSSFFont.DEFAULT_FONT_COLOR) { |
| return IndexedColors.BLACK.getIndex(); |
| } else if (index == IndexedColors.RED.getIndex()) { |
| return IndexedColors.RED.getIndex(); |
| } else { |
| return (short)index; |
| } |
| } |
| |
| |
| /** |
| * get the color value for the font |
| * References a color defined as Standard Alpha Red Green Blue color value (ARGB). |
| * |
| * @return XSSFColor - rgb color to use |
| */ |
| public XSSFColor getXSSFColor() { |
| CTColor ctColor = _ctFont.sizeOfColorArray() == 0 ? null : _ctFont.getColorArray(0); |
| if(ctColor != null) { |
| XSSFColor color = new XSSFColor(ctColor); |
| if(_themes != null) { |
| _themes.inheritFromThemeAsRequired(color); |
| } |
| return color; |
| } else { |
| return null; |
| } |
| } |
| |
| |
| /** |
| * get the color value for the font |
| * References a color defined in theme. |
| * |
| * @return short - theme defined to use |
| */ |
| public short getThemeColor() { |
| CTColor color = _ctFont.sizeOfColorArray() == 0 ? null : _ctFont.getColorArray(0); |
| long index = color == null ? 0 : color.getTheme(); |
| return (short) index; |
| } |
| |
| /** |
| * Get the font height in unit's of 1/20th of a point. |
| * <p> |
| * For many users, the related {@link #getFontHeightInPoints()} |
| * will be more helpful, as that returns font heights in the |
| * more familiar points units, eg 10, 12, 14. |
| |
| * @return short - height in 1/20ths of a point |
| * @see #getFontHeightInPoints() |
| */ |
| public short getFontHeight() { |
| return (short)(getFontHeightRaw()*20); |
| } |
| |
| /** |
| * Get the font height in points. |
| * <p> |
| * This will return the same font height that is shown in Excel, |
| * such as 10 or 14 or 28. |
| * @return short - height in the familiar unit of measure - points |
| * @see #getFontHeight() |
| */ |
| public short getFontHeightInPoints() { |
| return (short)getFontHeightRaw(); |
| } |
| |
| /** |
| * Return the raw font height, in points, but also |
| * including fractions. |
| */ |
| private double getFontHeightRaw() { |
| CTFontSize size = _ctFont.sizeOfSzArray() == 0 ? null : _ctFont.getSzArray(0); |
| if (size != null) { |
| double fontHeight = size.getVal(); |
| return fontHeight; |
| } |
| return DEFAULT_FONT_SIZE; |
| } |
| |
| /** |
| * get the name of the font (i.e. Arial) |
| * |
| * @return String - a string representing the name of the font to use |
| */ |
| public String getFontName() { |
| CTFontName name = _ctFont.sizeOfNameArray() == 0 ? null : _ctFont.getNameArray(0); |
| return name == null ? DEFAULT_FONT_NAME : name.getVal(); |
| } |
| |
| /** |
| * get a boolean value that specify whether to use italics or not |
| * |
| * @return boolean - value for italic |
| */ |
| public boolean getItalic() { |
| CTBooleanProperty italic = _ctFont.sizeOfIArray() == 0 ? null : _ctFont.getIArray(0); |
| return italic != null && italic.getVal(); |
| } |
| |
| /** |
| * get a boolean value that specify whether to use a strikeout horizontal line through the text or not |
| * |
| * @return boolean - value for strikeout |
| */ |
| public boolean getStrikeout() { |
| CTBooleanProperty strike = _ctFont.sizeOfStrikeArray() == 0 ? null : _ctFont.getStrikeArray(0); |
| return strike != null && strike.getVal(); |
| } |
| |
| /** |
| * get normal,super or subscript. |
| * |
| * @return short - offset type to use (none,super,sub) |
| * @see Font#SS_NONE |
| * @see Font#SS_SUPER |
| * @see Font#SS_SUB |
| */ |
| public short getTypeOffset() { |
| CTVerticalAlignFontProperty vAlign = _ctFont.sizeOfVertAlignArray() == 0 ? null : _ctFont.getVertAlignArray(0); |
| if (vAlign == null) { |
| return Font.SS_NONE; |
| } |
| int val = vAlign.getVal().intValue(); |
| switch (val) { |
| case STVerticalAlignRun.INT_BASELINE: |
| return Font.SS_NONE; |
| case STVerticalAlignRun.INT_SUBSCRIPT: |
| return Font.SS_SUB; |
| case STVerticalAlignRun.INT_SUPERSCRIPT: |
| return Font.SS_SUPER; |
| default: |
| throw new POIXMLException("Wrong offset value " + val); |
| } |
| } |
| |
| /** |
| * get type of text underlining to use |
| * |
| * @return byte - underlining type |
| * @see org.apache.poi.ss.usermodel.FontUnderline |
| */ |
| public byte getUnderline() { |
| CTUnderlineProperty underline = _ctFont.sizeOfUArray() == 0 ? null : _ctFont.getUArray(0); |
| if (underline != null) { |
| FontUnderline val = FontUnderline.valueOf(underline.getVal().intValue()); |
| return val.getByteValue(); |
| } |
| return Font.U_NONE; |
| } |
| |
| /** |
| * set a boolean value for the boldness to use. If omitted, the default value is true. |
| * |
| * @param bold - boldness to use |
| */ |
| public void setBold(boolean bold) { |
| if(bold){ |
| CTBooleanProperty ctBold = _ctFont.sizeOfBArray() == 0 ? _ctFont.addNewB() : _ctFont.getBArray(0); |
| ctBold.setVal(bold); |
| } else { |
| _ctFont.setBArray(null); |
| } |
| } |
| |
| /** |
| * @deprecated 3.15 beta 2. Scheduled for removal in 3.17. Use {@link #setBold(boolean)} instead. |
| */ |
| public void setBoldweight(short boldweight) |
| { |
| setBold(boldweight == BOLDWEIGHT_BOLD); |
| } |
| |
| /** |
| * get the boldness to use |
| * @return boldweight |
| * @see #BOLDWEIGHT_NORMAL |
| * @see #BOLDWEIGHT_BOLD |
| * @deprecated 3.15 beta 2. Scheduled for removal in 3.17. Use {@link #getBold} instead. |
| */ |
| public short getBoldweight() |
| { |
| return getBold() ? BOLDWEIGHT_BOLD : BOLDWEIGHT_NORMAL; |
| } |
| |
| /** |
| * set character-set to use. |
| * |
| * @param charset - charset |
| * @see FontCharset |
| */ |
| public void setCharSet(byte charset) { |
| int cs = charset & 0xff; |
| setCharSet(cs); |
| } |
| /** |
| * set character-set to use. |
| * |
| * @param charset - charset |
| * @see FontCharset |
| */ |
| public void setCharSet(int charset) { |
| FontCharset fontCharset = FontCharset.valueOf(charset); |
| if(fontCharset != null) { |
| setCharSet(fontCharset); |
| } else { |
| throw new POIXMLException("Attention: an attempt to set a type of unknow charset and charset"); |
| } |
| } |
| |
| /** |
| * set character-set to use. |
| * |
| * @param charSet |
| */ |
| public void setCharSet(FontCharset charSet) { |
| CTIntProperty charsetProperty; |
| if(_ctFont.sizeOfCharsetArray() == 0) { |
| charsetProperty = _ctFont.addNewCharset(); |
| } else { |
| charsetProperty = _ctFont.getCharsetArray(0); |
| } |
| // We know that FontCharset only has valid entries in it, |
| // so we can just set the int value from it |
| charsetProperty.setVal( charSet.getValue() ); |
| } |
| |
| /** |
| * set the indexed color for the font |
| * |
| * @param color - color to use |
| * @see #DEFAULT_FONT_COLOR - Note: default font color |
| * @see IndexedColors |
| */ |
| public void setColor(short color) { |
| CTColor ctColor = _ctFont.sizeOfColorArray() == 0 ? _ctFont.addNewColor() : _ctFont.getColorArray(0); |
| switch (color) { |
| case Font.COLOR_NORMAL: { |
| ctColor.setIndexed(XSSFFont.DEFAULT_FONT_COLOR); |
| break; |
| } |
| case Font.COLOR_RED: { |
| ctColor.setIndexed(IndexedColors.RED.getIndex()); |
| break; |
| } |
| default: |
| ctColor.setIndexed(color); |
| } |
| } |
| |
| /** |
| * set the color for the font in Standard Alpha Red Green Blue color value |
| * |
| * @param color - color to use |
| */ |
| public void setColor(XSSFColor color) { |
| if(color == null) _ctFont.setColorArray(null); |
| else { |
| CTColor ctColor = _ctFont.sizeOfColorArray() == 0 ? _ctFont.addNewColor() : _ctFont.getColorArray(0); |
| if (ctColor.isSetIndexed()) { |
| ctColor.unsetIndexed(); |
| } |
| ctColor.setRgb(color.getRGB()); |
| } |
| } |
| |
| /** |
| * set the font height in points. |
| * |
| * @param height - height in points |
| */ |
| public void setFontHeight(short height) { |
| setFontHeight((double) height/20); |
| } |
| |
| /** |
| * set the font height in points. |
| * |
| * @param height - height in points |
| */ |
| public void setFontHeight(double height) { |
| CTFontSize fontSize = _ctFont.sizeOfSzArray() == 0 ? _ctFont.addNewSz() : _ctFont.getSzArray(0); |
| fontSize.setVal(height); |
| } |
| |
| /** |
| * set the font height in points. |
| * |
| * @link #setFontHeight |
| */ |
| public void setFontHeightInPoints(short height) { |
| setFontHeight((double)height); |
| } |
| |
| /** |
| * set the theme color for the font to use |
| * |
| * @param theme - theme color to use |
| */ |
| public void setThemeColor(short theme) { |
| CTColor ctColor = _ctFont.sizeOfColorArray() == 0 ? _ctFont.addNewColor() : _ctFont.getColorArray(0); |
| ctColor.setTheme(theme); |
| } |
| |
| /** |
| * set the name for the font (i.e. Arial). |
| * If the font doesn't exist (because it isn't installed on the system), |
| * or the charset is invalid for that font, then another font should |
| * be substituted. |
| * The string length for this attribute shall be 0 to 31 characters. |
| * Default font name is Calibri. |
| * |
| * @param name - value representing the name of the font to use |
| * @see #DEFAULT_FONT_NAME |
| */ |
| public void setFontName(String name) { |
| CTFontName fontName = _ctFont.sizeOfNameArray() == 0 ? _ctFont.addNewName() : _ctFont.getNameArray(0); |
| fontName.setVal(name == null ? DEFAULT_FONT_NAME : name); |
| } |
| |
| |
| /** |
| * set a boolean value for the property specifying whether to use italics or not |
| * If omitted, the default value is true. |
| * |
| * @param italic - value for italics or not |
| */ |
| public void setItalic(boolean italic) { |
| if(italic){ |
| CTBooleanProperty bool = _ctFont.sizeOfIArray() == 0 ? _ctFont.addNewI() : _ctFont.getIArray(0); |
| bool.setVal(italic); |
| } else { |
| _ctFont.setIArray(null); |
| } |
| } |
| |
| |
| /** |
| * set a boolean value for the property specifying whether to use a strikeout horizontal line through the text or not |
| * If omitted, the default value is true. |
| * |
| * @param strikeout - value for strikeout or not |
| */ |
| public void setStrikeout(boolean strikeout) { |
| if(!strikeout) _ctFont.setStrikeArray(null); |
| else { |
| CTBooleanProperty strike = _ctFont.sizeOfStrikeArray() == 0 ? _ctFont.addNewStrike() : _ctFont.getStrikeArray(0); |
| strike.setVal(strikeout); |
| } |
| } |
| |
| /** |
| * set normal,super or subscript, that representing the vertical-alignment setting. |
| * Setting this to either subscript or superscript shall make the font size smaller if a |
| * smaller font size is available. |
| * |
| * @param offset - offset type to use (none,super,sub) |
| * @see #SS_NONE |
| * @see #SS_SUPER |
| * @see #SS_SUB |
| */ |
| public void setTypeOffset(short offset) { |
| if(offset == Font.SS_NONE){ |
| _ctFont.setVertAlignArray(null); |
| } else { |
| CTVerticalAlignFontProperty offsetProperty = _ctFont.sizeOfVertAlignArray() == 0 ? _ctFont.addNewVertAlign() : _ctFont.getVertAlignArray(0); |
| switch (offset) { |
| case Font.SS_NONE: |
| offsetProperty.setVal(STVerticalAlignRun.BASELINE); |
| break; |
| case Font.SS_SUB: |
| offsetProperty.setVal(STVerticalAlignRun.SUBSCRIPT); |
| break; |
| case Font.SS_SUPER: |
| offsetProperty.setVal(STVerticalAlignRun.SUPERSCRIPT); |
| break; |
| default: |
| throw new IllegalStateException("Invalid type offset: " + offset); |
| } |
| } |
| } |
| |
| /** |
| * set the style of underlining that is used. |
| * The none style is equivalent to not using underlining at all. |
| * |
| * @param underline - underline type to use |
| * @see FontUnderline |
| */ |
| public void setUnderline(byte underline) { |
| setUnderline(FontUnderline.valueOf(underline)); |
| } |
| |
| /** |
| * set an enumeration representing the style of underlining that is used. |
| * The none style is equivalent to not using underlining at all. |
| * The possible values for this attribute are defined by the FontUnderline |
| * |
| * @param underline - FontUnderline enum value |
| */ |
| public void setUnderline(FontUnderline underline) { |
| if(underline == FontUnderline.NONE && _ctFont.sizeOfUArray() > 0){ |
| _ctFont.setUArray(null); |
| } else { |
| CTUnderlineProperty ctUnderline = _ctFont.sizeOfUArray() == 0 ? _ctFont.addNewU() : _ctFont.getUArray(0); |
| STUnderlineValues.Enum val = STUnderlineValues.Enum.forInt(underline.getValue()); |
| ctUnderline.setVal(val); |
| } |
| } |
| |
| |
| public String toString() { |
| return _ctFont.toString(); |
| } |
| |
| |
| /** |
| * Perform a registration of ourselves |
| * to the style table |
| */ |
| public long registerTo(StylesTable styles) { |
| this._themes = styles.getTheme(); |
| short idx = (short)styles.putFont(this, true); |
| this._index = idx; |
| return idx; |
| } |
| /** |
| * Records the Themes Table that is associated with |
| * the current font, used when looking up theme |
| * based colours and properties. |
| */ |
| public void setThemesTable(ThemesTable themes) { |
| this._themes = themes; |
| } |
| |
| /** |
| * get the font scheme property. |
| * is used only in StylesTable to create the default instance of font |
| * |
| * @return FontScheme |
| * @see org.apache.poi.xssf.model.StylesTable#createDefaultFont() |
| */ |
| public FontScheme getScheme() { |
| CTFontScheme scheme = _ctFont.sizeOfSchemeArray() == 0 ? null : _ctFont.getSchemeArray(0); |
| return scheme == null ? FontScheme.NONE : FontScheme.valueOf(scheme.getVal().intValue()); |
| } |
| |
| /** |
| * set font scheme property |
| * |
| * @param scheme - FontScheme enum value |
| * @see FontScheme |
| */ |
| public void setScheme(FontScheme scheme) { |
| CTFontScheme ctFontScheme = _ctFont.sizeOfSchemeArray() == 0 ? _ctFont.addNewScheme() : _ctFont.getSchemeArray(0); |
| STFontScheme.Enum val = STFontScheme.Enum.forInt(scheme.getValue()); |
| ctFontScheme.setVal(val); |
| } |
| |
| /** |
| * get the font family to use. |
| * |
| * @return the font family to use |
| * @see org.apache.poi.ss.usermodel.FontFamily |
| */ |
| public int getFamily() { |
| CTIntProperty family = _ctFont.sizeOfFamilyArray() == 0 ? _ctFont.addNewFamily() : _ctFont.getFamilyArray(0); |
| return family == null ? FontFamily.NOT_APPLICABLE.getValue() : FontFamily.valueOf(family.getVal()).getValue(); |
| } |
| |
| /** |
| * Set the font family this font belongs to. |
| * A font family is a set of fonts having common stroke width and serif characteristics. |
| * The font name overrides when there are conflicting values. |
| * |
| * @param value - font family |
| * @see FontFamily |
| */ |
| public void setFamily(int value) { |
| CTIntProperty family = _ctFont.sizeOfFamilyArray() == 0 ? _ctFont.addNewFamily() : _ctFont.getFamilyArray(0); |
| family.setVal(value); |
| } |
| |
| /** |
| * set an enumeration representing the font family this font belongs to. |
| * A font family is a set of fonts having common stroke width and serif characteristics. |
| * |
| * @param family font family |
| * @link #setFamily(int value) |
| */ |
| public void setFamily(FontFamily family) { |
| setFamily(family.getValue()); |
| } |
| |
| /** |
| * get the index within the XSSFWorkbook (sequence within the collection of Font objects) |
| * @return unique index number of the underlying record this Font represents (probably you don't care |
| * unless you're comparing which one is which) |
| */ |
| public short getIndex() |
| { |
| return _index; |
| } |
| |
| public int hashCode(){ |
| return _ctFont.toString().hashCode(); |
| } |
| |
| public boolean equals(Object o){ |
| if(!(o instanceof XSSFFont)) return false; |
| |
| XSSFFont cf = (XSSFFont)o; |
| return _ctFont.toString().equals(cf.getCTFont().toString()); |
| } |
| |
| } |