| /************************************************************** |
| * |
| * 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. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include "oox/xls/stylesbuffer.hxx" |
| |
| #include <com/sun/star/awt/FontDescriptor.hpp> |
| #include <com/sun/star/awt/FontFamily.hpp> |
| #include <com/sun/star/awt/FontPitch.hpp> |
| #include <com/sun/star/awt/FontSlant.hpp> |
| #include <com/sun/star/awt/FontStrikeout.hpp> |
| #include <com/sun/star/awt/FontType.hpp> |
| #include <com/sun/star/awt/FontWeight.hpp> |
| #include <com/sun/star/awt/FontUnderline.hpp> |
| #include <com/sun/star/awt/XDevice.hpp> |
| #include <com/sun/star/awt/XFont2.hpp> |
| #include <com/sun/star/container/XIndexAccess.hpp> |
| #include <com/sun/star/container/XNameAccess.hpp> |
| #include <com/sun/star/style/XStyle.hpp> |
| #include <com/sun/star/text/WritingMode2.hpp> |
| #include <com/sun/star/text/XText.hpp> |
| #include <rtl/tencinfo.h> |
| #include <rtl/ustrbuf.hxx> |
| #include "oox/core/filterbase.hxx" |
| #include "oox/helper/attributelist.hxx" |
| #include "oox/helper/containerhelper.hxx" |
| #include "oox/helper/propertymap.hxx" |
| #include "oox/helper/propertyset.hxx" |
| #include "oox/xls/biffinputstream.hxx" |
| #include "oox/xls/condformatbuffer.hxx" |
| #include "oox/xls/excelhandlers.hxx" |
| #include "oox/xls/themebuffer.hxx" |
| #include "oox/xls/unitconverter.hxx" |
| |
| namespace oox { |
| namespace xls { |
| |
| // ============================================================================ |
| |
| using namespace ::com::sun::star::awt; |
| using namespace ::com::sun::star::container; |
| using namespace ::com::sun::star::style; |
| using namespace ::com::sun::star::table; |
| using namespace ::com::sun::star::text; |
| using namespace ::com::sun::star::uno; |
| |
| using ::oox::core::FilterBase; |
| using ::rtl::OUString; |
| using ::rtl::OUStringBuffer; |
| |
| // ============================================================================ |
| |
| namespace { |
| |
| // OOXML constants ------------------------------------------------------------ |
| |
| // OOXML predefined color indexes (also used in BIFF3-BIFF8) |
| const sal_Int32 OOX_COLOR_USEROFFSET = 0; /// First user defined color in palette (OOXML/BIFF12). |
| const sal_Int32 BIFF_COLOR_USEROFFSET = 8; /// First user defined color in palette (BIFF3-BIFF8). |
| |
| // OOXML font family (also used in BIFF) |
| const sal_Int32 OOX_FONTFAMILY_NONE = 0; |
| const sal_Int32 OOX_FONTFAMILY_ROMAN = 1; |
| const sal_Int32 OOX_FONTFAMILY_SWISS = 2; |
| const sal_Int32 OOX_FONTFAMILY_MODERN = 3; |
| const sal_Int32 OOX_FONTFAMILY_SCRIPT = 4; |
| const sal_Int32 OOX_FONTFAMILY_DECORATIVE = 5; |
| |
| // OOXML cell text direction (also used in BIFF) |
| const sal_Int32 OOX_XF_TEXTDIR_CONTEXT = 0; |
| const sal_Int32 OOX_XF_TEXTDIR_LTR = 1; |
| const sal_Int32 OOX_XF_TEXTDIR_RTL = 2; |
| |
| // OOXML cell rotation (also used in BIFF) |
| const sal_Int32 OOX_XF_ROTATION_NONE = 0; |
| const sal_Int32 OOX_XF_ROTATION_90CCW = 90; |
| const sal_Int32 OOX_XF_ROTATION_90CW = 180; |
| const sal_Int32 OOX_XF_ROTATION_STACKED = 255; |
| |
| // OOXML cell indentation |
| const sal_Int32 OOX_XF_INDENT_NONE = 0; |
| |
| // OOXML built-in cell styles (also used in BIFF) |
| const sal_Int32 OOX_STYLE_NORMAL = 0; /// Default cell style. |
| const sal_Int32 OOX_STYLE_ROWLEVEL = 1; /// RowLevel_x cell style. |
| const sal_Int32 OOX_STYLE_COLLEVEL = 2; /// ColLevel_x cell style. |
| |
| const sal_Int32 OOX_STYLE_LEVELCOUNT = 7; /// Number of outline level styles. |
| |
| // BIFF12 constants ----------------------------------------------------------- |
| |
| // BIFF12 color types |
| const sal_uInt8 BIFF12_COLOR_AUTO = 0; |
| const sal_uInt8 BIFF12_COLOR_INDEXED = 1; |
| const sal_uInt8 BIFF12_COLOR_RGB = 2; |
| const sal_uInt8 BIFF12_COLOR_THEME = 3; |
| |
| // BIFF12 diagonal borders |
| const sal_uInt8 BIFF12_BORDER_DIAG_TLBR = 0x01; /// Top-left to bottom-right. |
| const sal_uInt8 BIFF12_BORDER_DIAG_BLTR = 0x02; /// Bottom-left to top-right. |
| |
| // BIFF12 gradient fill |
| const sal_Int32 BIFF12_FILL_GRADIENT = 40; |
| |
| // BIFF12 XF flags |
| const sal_uInt32 BIFF12_XF_WRAPTEXT = 0x00400000; |
| const sal_uInt32 BIFF12_XF_JUSTLASTLINE = 0x00800000; |
| const sal_uInt32 BIFF12_XF_SHRINK = 0x01000000; |
| const sal_uInt32 BIFF12_XF_LOCKED = 0x10000000; |
| const sal_uInt32 BIFF12_XF_HIDDEN = 0x20000000; |
| |
| // BIFF12 XF attribute used flags |
| const sal_uInt16 BIFF12_XF_NUMFMT_USED = 0x0001; |
| const sal_uInt16 BIFF12_XF_FONT_USED = 0x0002; |
| const sal_uInt16 BIFF12_XF_ALIGN_USED = 0x0004; |
| const sal_uInt16 BIFF12_XF_BORDER_USED = 0x0008; |
| const sal_uInt16 BIFF12_XF_AREA_USED = 0x0010; |
| const sal_uInt16 BIFF12_XF_PROT_USED = 0x0020; |
| |
| // BIFF12 DXF constants |
| const sal_uInt16 BIFF12_DXF_FILL_PATTERN = 0; |
| const sal_uInt16 BIFF12_DXF_FILL_FGCOLOR = 1; |
| const sal_uInt16 BIFF12_DXF_FILL_BGCOLOR = 2; |
| const sal_uInt16 BIFF12_DXF_FILL_GRADIENT = 3; |
| const sal_uInt16 BIFF12_DXF_FILL_STOP = 4; |
| const sal_uInt16 BIFF12_DXF_FONT_COLOR = 5; |
| const sal_uInt16 BIFF12_DXF_BORDER_TOP = 6; |
| const sal_uInt16 BIFF12_DXF_BORDER_BOTTOM = 7; |
| const sal_uInt16 BIFF12_DXF_BORDER_LEFT = 8; |
| const sal_uInt16 BIFF12_DXF_BORDER_RIGHT = 9; |
| const sal_uInt16 BIFF12_DXF_BORDER_DIAG = 10; |
| const sal_uInt16 BIFF12_DXF_BORDER_VERT = 11; |
| const sal_uInt16 BIFF12_DXF_BORDER_HOR = 12; |
| const sal_uInt16 BIFF12_DXF_BORDER_DIAGUP = 13; |
| const sal_uInt16 BIFF12_DXF_BORDER_DIAGDOWN = 14; |
| const sal_uInt16 BIFF12_DXF_FONT_NAME = 24; |
| const sal_uInt16 BIFF12_DXF_FONT_WEIGHT = 25; |
| const sal_uInt16 BIFF12_DXF_FONT_UNDERLINE = 26; |
| const sal_uInt16 BIFF12_DXF_FONT_ESCAPEMENT = 27; |
| const sal_uInt16 BIFF12_DXF_FONT_ITALIC = 28; |
| const sal_uInt16 BIFF12_DXF_FONT_STRIKE = 29; |
| const sal_uInt16 BIFF12_DXF_FONT_OUTLINE = 30; |
| const sal_uInt16 BIFF12_DXF_FONT_SHADOW = 31; |
| const sal_uInt16 BIFF12_DXF_FONT_CONDENSE = 32; |
| const sal_uInt16 BIFF12_DXF_FONT_EXTEND = 33; |
| const sal_uInt16 BIFF12_DXF_FONT_CHARSET = 34; |
| const sal_uInt16 BIFF12_DXF_FONT_FAMILY = 35; |
| const sal_uInt16 BIFF12_DXF_FONT_HEIGHT = 36; |
| const sal_uInt16 BIFF12_DXF_FONT_SCHEME = 37; |
| const sal_uInt16 BIFF12_DXF_NUMFMT_CODE = 38; |
| const sal_uInt16 BIFF12_DXF_NUMFMT_ID = 41; |
| |
| // BIFF12 CELLSTYLE flags |
| const sal_uInt16 BIFF12_CELLSTYLE_BUILTIN = 0x0001; |
| const sal_uInt16 BIFF12_CELLSTYLE_HIDDEN = 0x0002; |
| const sal_uInt16 BIFF12_CELLSTYLE_CUSTOM = 0x0004; |
| |
| // BIFF constants ------------------------------------------------------------- |
| |
| // BIFF predefined color indexes |
| const sal_uInt16 BIFF2_COLOR_BLACK = 0; /// Black (text) in BIFF2. |
| const sal_uInt16 BIFF2_COLOR_WHITE = 1; /// White (background) in BIFF2. |
| |
| // BIFF font flags, also used in BIFF12 |
| const sal_uInt16 BIFF_FONTFLAG_BOLD = 0x0001; |
| const sal_uInt16 BIFF_FONTFLAG_ITALIC = 0x0002; |
| const sal_uInt16 BIFF_FONTFLAG_UNDERLINE = 0x0004; |
| const sal_uInt16 BIFF_FONTFLAG_STRIKEOUT = 0x0008; |
| const sal_uInt16 BIFF_FONTFLAG_OUTLINE = 0x0010; |
| const sal_uInt16 BIFF_FONTFLAG_SHADOW = 0x0020; |
| const sal_uInt16 BIFF_FONTFLAG_CONDENSE = 0x0040; |
| |
| // BIFF font weight |
| const sal_uInt16 BIFF_FONTWEIGHT_BOLD = 450; |
| |
| // BIFF font underline, also used in BIFF12 |
| const sal_uInt8 BIFF_FONTUNDERL_NONE = 0; |
| const sal_uInt8 BIFF_FONTUNDERL_SINGLE = 1; |
| const sal_uInt8 BIFF_FONTUNDERL_DOUBLE = 2; |
| const sal_uInt8 BIFF_FONTUNDERL_SINGLE_ACC = 33; |
| const sal_uInt8 BIFF_FONTUNDERL_DOUBLE_ACC = 34; |
| |
| // BIFF XF flags |
| const sal_uInt16 BIFF_XF_LOCKED = 0x0001; |
| const sal_uInt16 BIFF_XF_HIDDEN = 0x0002; |
| const sal_uInt16 BIFF_XF_STYLE = 0x0004; |
| const sal_uInt16 BIFF_XF_STYLEPARENT = 0x0FFF; /// Syles don't have a parent. |
| const sal_uInt16 BIFF_XF_WRAPTEXT = 0x0008; /// Automatic line break. |
| const sal_uInt16 BIFF_XF_JUSTLASTLINE = 0x0080; |
| const sal_uInt16 BIFF_XF_SHRINK = 0x0010; /// Shrink to fit into cell. |
| const sal_uInt16 BIFF_XF_MERGE = 0x0020; |
| |
| // BIFF XF attribute used flags |
| const sal_uInt8 BIFF_XF_NUMFMT_USED = 0x01; |
| const sal_uInt8 BIFF_XF_FONT_USED = 0x02; |
| const sal_uInt8 BIFF_XF_ALIGN_USED = 0x04; |
| const sal_uInt8 BIFF_XF_BORDER_USED = 0x08; |
| const sal_uInt8 BIFF_XF_AREA_USED = 0x10; |
| const sal_uInt8 BIFF_XF_PROT_USED = 0x20; |
| |
| // BIFF XF text orientation |
| const sal_uInt8 BIFF_XF_ORIENT_NONE = 0; |
| const sal_uInt8 BIFF_XF_ORIENT_STACKED = 1; /// Stacked top to bottom. |
| const sal_uInt8 BIFF_XF_ORIENT_90CCW = 2; /// 90 degr. counterclockwise. |
| const sal_uInt8 BIFF_XF_ORIENT_90CW = 3; /// 90 degr. clockwise. |
| |
| // BIFF XF line styles |
| const sal_uInt8 BIFF_LINE_NONE = 0; |
| const sal_uInt8 BIFF_LINE_THIN = 1; |
| |
| // BIFF XF patterns |
| const sal_uInt8 BIFF_PATT_NONE = 0; |
| const sal_uInt8 BIFF_PATT_125 = 17; |
| |
| // BIFF2 XF flags |
| const sal_uInt8 BIFF2_XF_VALFMT_MASK = 0x3F; |
| const sal_uInt8 BIFF2_XF_LOCKED = 0x40; |
| const sal_uInt8 BIFF2_XF_HIDDEN = 0x80; |
| const sal_uInt8 BIFF2_XF_LEFTLINE = 0x08; |
| const sal_uInt8 BIFF2_XF_RIGHTLINE = 0x10; |
| const sal_uInt8 BIFF2_XF_TOPLINE = 0x20; |
| const sal_uInt8 BIFF2_XF_BOTTOMLINE = 0x40; |
| const sal_uInt8 BIFF2_XF_BACKGROUND = 0x80; |
| |
| // BIFF8 diagonal borders |
| const sal_uInt32 BIFF_XF_DIAG_TLBR = 0x40000000; /// Top-left to bottom-right. |
| const sal_uInt32 BIFF_XF_DIAG_BLTR = 0x80000000; /// Bottom-left to top-right. |
| |
| // BIFF STYLE flags |
| const sal_uInt16 BIFF_STYLE_BUILTIN = 0x8000; |
| const sal_uInt16 BIFF_STYLE_XFMASK = 0x0FFF; |
| |
| // BIFF STYLEEXT flags |
| const sal_uInt8 BIFF_STYLEEXT_BUILTIN = 0x01; |
| const sal_uInt8 BIFF_STYLEEXT_HIDDEN = 0x02; |
| const sal_uInt8 BIFF_STYLEEXT_CUSTOM = 0x04; |
| |
| // BIFF conditional formatting |
| const sal_uInt32 BIFF_CFRULE_BORDER_LEFT = 0x00000400; |
| const sal_uInt32 BIFF_CFRULE_BORDER_RIGHT = 0x00000800; |
| const sal_uInt32 BIFF_CFRULE_BORDER_TOP = 0x00001000; |
| const sal_uInt32 BIFF_CFRULE_BORDER_BOTTOM = 0x00002000; |
| const sal_uInt32 BIFF_CFRULE_FILL_PATTERN = 0x00010000; |
| const sal_uInt32 BIFF_CFRULE_FILL_PATTCOLOR = 0x00020000; |
| const sal_uInt32 BIFF_CFRULE_FILL_FILLCOLOR = 0x00040000; |
| const sal_uInt32 BIFF_CFRULE_FONTBLOCK = 0x04000000; |
| const sal_uInt32 BIFF_CFRULE_ALIGNBLOCK = 0x08000000; |
| const sal_uInt32 BIFF_CFRULE_BORDERBLOCK = 0x10000000; |
| const sal_uInt32 BIFF_CFRULE_FILLBLOCK = 0x20000000; |
| const sal_uInt32 BIFF_CFRULE_PROTBLOCK = 0x40000000; |
| |
| const sal_uInt32 BIFF_CFRULE_FONT_STYLE = 0x00000002; /// Font posture or weight modified? |
| const sal_uInt32 BIFF_CFRULE_FONT_OUTLINE = 0x00000008; /// Font outline modified? |
| const sal_uInt32 BIFF_CFRULE_FONT_SHADOW = 0x00000010; /// Font shadow modified? |
| const sal_uInt32 BIFF_CFRULE_FONT_STRIKEOUT = 0x00000080; /// Font cancellation modified? |
| const sal_uInt32 BIFF_CFRULE_FONT_UNDERL = 0x00000001; /// Font underline type modified? |
| const sal_uInt32 BIFF_CFRULE_FONT_ESCAPEM = 0x00000001; /// Font escapement type modified? |
| |
| // ---------------------------------------------------------------------------- |
| |
| sal_Int32 lclReadRgbColor( BinaryInputStream& rStrm ) |
| { |
| sal_uInt8 nR, nG, nB, nA; |
| rStrm >> nR >> nG >> nB >> nA; |
| sal_Int32 nValue = nA; |
| nValue <<= 8; |
| nValue |= nR; |
| nValue <<= 8; |
| nValue |= nG; |
| nValue <<= 8; |
| nValue |= nB; |
| return nValue; |
| } |
| |
| } // namespace |
| |
| // ============================================================================ |
| |
| ExcelGraphicHelper::ExcelGraphicHelper( const WorkbookHelper& rHelper ) : |
| GraphicHelper( rHelper.getBaseFilter().getComponentContext(), rHelper.getBaseFilter().getTargetFrame(), rHelper.getBaseFilter().getStorage() ), |
| WorkbookHelper( rHelper ) |
| { |
| } |
| |
| sal_Int32 ExcelGraphicHelper::getSchemeColor( sal_Int32 nToken ) const |
| { |
| if( getFilterType() == FILTER_OOXML ) |
| return getTheme().getColorByToken( nToken ); |
| return GraphicHelper::getSchemeColor( nToken ); |
| } |
| |
| sal_Int32 ExcelGraphicHelper::getPaletteColor( sal_Int32 nPaletteIdx ) const |
| { |
| return getStyles().getPaletteColor( nPaletteIdx ); |
| } |
| |
| // ============================================================================ |
| |
| void Color::setAuto() |
| { |
| clearTransformations(); |
| setSchemeClr( XML_phClr ); |
| } |
| |
| void Color::setRgb( sal_Int32 nRgbValue, double fTint ) |
| { |
| clearTransformations(); |
| setSrgbClr( nRgbValue & 0xFFFFFF ); |
| if( fTint != 0.0 ) addExcelTintTransformation( fTint ); |
| } |
| |
| void Color::setTheme( sal_Int32 nThemeIdx, double fTint ) |
| { |
| clearTransformations(); |
| static const sal_Int32 spnColorTokens[] = { |
| XML_lt1, XML_dk1, XML_lt2, XML_dk2, XML_accent1, XML_accent2, |
| XML_accent3, XML_accent4, XML_accent5, XML_accent6, XML_hlink, XML_folHlink }; |
| setSchemeClr( STATIC_ARRAY_SELECT( spnColorTokens, nThemeIdx, XML_TOKEN_INVALID ) ); |
| if( fTint != 0.0 ) addExcelTintTransformation( fTint ); |
| } |
| |
| void Color::setIndexed( sal_Int32 nPaletteIdx, double fTint ) |
| { |
| clearTransformations(); |
| setPaletteClr( nPaletteIdx ); |
| if( fTint != 0.0 ) addExcelTintTransformation( fTint ); |
| } |
| |
| void Color::importColor( const AttributeList& rAttribs ) |
| { |
| if( rAttribs.getBool( XML_auto, false ) ) |
| setAuto(); |
| else if( rAttribs.hasAttribute( XML_rgb ) ) |
| setRgb( rAttribs.getIntegerHex( XML_rgb, API_RGB_TRANSPARENT ), rAttribs.getDouble( XML_tint, 0.0 ) ); |
| else if( rAttribs.hasAttribute( XML_theme ) ) |
| setTheme( rAttribs.getInteger( XML_theme, -1 ), rAttribs.getDouble( XML_tint, 0.0 ) ); |
| else if( rAttribs.hasAttribute( XML_indexed ) ) |
| setIndexed( rAttribs.getInteger( XML_indexed, -1 ), rAttribs.getDouble( XML_tint, 0.0 ) ); |
| else |
| { |
| OSL_ENSURE( false, "Color::importColor - unknown color type" ); |
| setAuto(); |
| } |
| } |
| |
| void Color::importColor( SequenceInputStream& rStrm ) |
| { |
| sal_uInt8 nFlags, nIndex; |
| sal_Int16 nTint; |
| rStrm >> nFlags >> nIndex >> nTint; |
| |
| // scale tint from signed 16-bit to double range -1.0 ... 1.0 |
| double fTint = nTint; |
| if( nTint < 0 ) |
| fTint /= -SAL_MIN_INT16; |
| else if( nTint > 0 ) |
| fTint /= SAL_MAX_INT16; |
| |
| switch( extractValue< sal_uInt8 >( nFlags, 1, 7 ) ) |
| { |
| case BIFF12_COLOR_AUTO: |
| setAuto(); |
| rStrm.skip( 4 ); |
| break; |
| case BIFF12_COLOR_INDEXED: |
| setIndexed( nIndex, fTint ); |
| rStrm.skip( 4 ); |
| break; |
| case BIFF12_COLOR_RGB: |
| setRgb( lclReadRgbColor( rStrm ), fTint ); |
| break; |
| case BIFF12_COLOR_THEME: |
| setTheme( nIndex, fTint ); |
| rStrm.skip( 4 ); |
| break; |
| default: |
| OSL_ENSURE( false, "Color::importColor - unknown color type" ); |
| setAuto(); |
| rStrm.skip( 4 ); |
| } |
| } |
| |
| void Color::importColorId( SequenceInputStream& rStrm ) |
| { |
| setIndexed( rStrm.readInt32() ); |
| } |
| |
| void Color::importColorRgb( SequenceInputStream& rStrm ) |
| { |
| setRgb( lclReadRgbColor( rStrm ) ); |
| } |
| |
| void Color::importColorId( BiffInputStream& rStrm, bool b16Bit ) |
| { |
| setIndexed( b16Bit ? rStrm.readuInt16() : rStrm.readuInt8() ); |
| } |
| |
| void Color::importColorRgb( BiffInputStream& rStrm ) |
| { |
| setRgb( lclReadRgbColor( rStrm ) ); |
| } |
| |
| SequenceInputStream& operator>>( SequenceInputStream& rStrm, Color& orColor ) |
| { |
| orColor.importColor( rStrm ); |
| return rStrm; |
| } |
| |
| // ============================================================================ |
| |
| namespace { |
| |
| /** Standard EGA colors, bright. */ |
| #define PALETTE_EGA_COLORS_LIGHT \ |
| 0x000000, 0xFFFFFF, 0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF |
| /** Standard EGA colors, dark. */ |
| #define PALETTE_EGA_COLORS_DARK \ |
| 0x800000, 0x008000, 0x000080, 0x808000, 0x800080, 0x008080, 0xC0C0C0, 0x808080 |
| |
| /** Default color table for BIFF2. */ |
| static const sal_Int32 spnDefColors2[] = |
| { |
| /* 0 */ PALETTE_EGA_COLORS_LIGHT |
| }; |
| |
| /** Default color table for BIFF3/BIFF4. */ |
| static const sal_Int32 spnDefColors3[] = |
| { |
| /* 0 */ PALETTE_EGA_COLORS_LIGHT, |
| /* 8 */ PALETTE_EGA_COLORS_LIGHT, |
| /* 16 */ PALETTE_EGA_COLORS_DARK |
| }; |
| |
| /** Default color table for BIFF5. */ |
| static const sal_Int32 spnDefColors5[] = |
| { |
| /* 0 */ PALETTE_EGA_COLORS_LIGHT, |
| /* 8 */ PALETTE_EGA_COLORS_LIGHT, |
| /* 16 */ PALETTE_EGA_COLORS_DARK, |
| /* 24 */ 0x8080FF, 0x802060, 0xFFFFC0, 0xA0E0E0, 0x600080, 0xFF8080, 0x0080C0, 0xC0C0FF, |
| /* 32 */ 0x000080, 0xFF00FF, 0xFFFF00, 0x00FFFF, 0x800080, 0x800000, 0x008080, 0x0000FF, |
| /* 40 */ 0x00CFFF, 0x69FFFF, 0xE0FFE0, 0xFFFF80, 0xA6CAF0, 0xDD9CB3, 0xB38FEE, 0xE3E3E3, |
| /* 48 */ 0x2A6FF9, 0x3FB8CD, 0x488436, 0x958C41, 0x8E5E42, 0xA0627A, 0x624FAC, 0x969696, |
| /* 56 */ 0x1D2FBE, 0x286676, 0x004500, 0x453E01, 0x6A2813, 0x85396A, 0x4A3285, 0x424242 |
| }; |
| |
| /** Default color table for BIFF8/BIFF12/OOXML. */ |
| static const sal_Int32 spnDefColors8[] = |
| { |
| /* 0 */ PALETTE_EGA_COLORS_LIGHT, |
| /* 8 */ PALETTE_EGA_COLORS_LIGHT, |
| /* 16 */ PALETTE_EGA_COLORS_DARK, |
| /* 24 */ 0x9999FF, 0x993366, 0xFFFFCC, 0xCCFFFF, 0x660066, 0xFF8080, 0x0066CC, 0xCCCCFF, |
| /* 32 */ 0x000080, 0xFF00FF, 0xFFFF00, 0x00FFFF, 0x800080, 0x800000, 0x008080, 0x0000FF, |
| /* 40 */ 0x00CCFF, 0xCCFFFF, 0xCCFFCC, 0xFFFF99, 0x99CCFF, 0xFF99CC, 0xCC99FF, 0xFFCC99, |
| /* 48 */ 0x3366FF, 0x33CCCC, 0x99CC00, 0xFFCC00, 0xFF9900, 0xFF6600, 0x666699, 0x969696, |
| /* 56 */ 0x003366, 0x339966, 0x003300, 0x333300, 0x993300, 0x993366, 0x333399, 0x333333 |
| }; |
| |
| #undef PALETTE_EGA_COLORS_LIGHT |
| #undef PALETTE_EGA_COLORS_DARK |
| |
| } // namespace |
| |
| // ---------------------------------------------------------------------------- |
| |
| ColorPalette::ColorPalette( const WorkbookHelper& rHelper ) : |
| WorkbookHelper( rHelper ) |
| { |
| // default colors |
| switch( getFilterType() ) |
| { |
| case FILTER_OOXML: |
| maColors.insert( maColors.begin(), spnDefColors8, STATIC_ARRAY_END( spnDefColors8 ) ); |
| mnAppendIndex = OOX_COLOR_USEROFFSET; |
| break; |
| case FILTER_BIFF: |
| switch( getBiff() ) |
| { |
| case BIFF2: maColors.insert( maColors.begin(), spnDefColors2, STATIC_ARRAY_END( spnDefColors2 ) ); break; |
| case BIFF3: |
| case BIFF4: maColors.insert( maColors.begin(), spnDefColors3, STATIC_ARRAY_END( spnDefColors3 ) ); break; |
| case BIFF5: maColors.insert( maColors.begin(), spnDefColors5, STATIC_ARRAY_END( spnDefColors5 ) ); break; |
| case BIFF8: maColors.insert( maColors.begin(), spnDefColors8, STATIC_ARRAY_END( spnDefColors8 ) ); break; |
| case BIFF_UNKNOWN: break; |
| } |
| mnAppendIndex = BIFF_COLOR_USEROFFSET; |
| break; |
| case FILTER_UNKNOWN: break; |
| } |
| } |
| |
| void ColorPalette::importPaletteColor( const AttributeList& rAttribs ) |
| { |
| appendColor( rAttribs.getIntegerHex( XML_rgb, API_RGB_WHITE ) ); |
| } |
| |
| void ColorPalette::importPaletteColor( SequenceInputStream& rStrm ) |
| { |
| sal_Int32 nRgb = lclReadRgbColor( rStrm ); |
| appendColor( nRgb & 0xFFFFFF ); |
| } |
| |
| void ColorPalette::importPalette( BiffInputStream& rStrm ) |
| { |
| sal_uInt16 nCount; |
| rStrm >> nCount; |
| OSL_ENSURE( rStrm.getRemaining() == 4 * nCount, "ColorPalette::importPalette - wrong palette size" ); |
| |
| // fill palette from BIFF_COLOR_USEROFFSET |
| mnAppendIndex = BIFF_COLOR_USEROFFSET; |
| for( sal_uInt16 nIndex = 0; !rStrm.isEof() && (nIndex < nCount); ++nIndex ) |
| { |
| sal_Int32 nRgb = lclReadRgbColor( rStrm ); |
| appendColor( nRgb & 0xFFFFFF ); |
| } |
| } |
| |
| void ColorPalette::importPalette( const Any& rPalette ) |
| { |
| Sequence< sal_Int32 > rColorSeq; |
| if( (rPalette >>= rColorSeq) && rColorSeq.hasElements() ) |
| { |
| const sal_Int32* pnColor = rColorSeq.getConstArray(); |
| const sal_Int32* pnColorEnd = pnColor + rColorSeq.getLength(); |
| for( ; pnColor < pnColorEnd; ++pnColor ) |
| appendColor( *pnColor & 0xFFFFFF ); |
| } |
| } |
| |
| sal_Int32 ColorPalette::getColor( sal_Int32 nPaletteIdx ) const |
| { |
| sal_Int32 nColor = API_RGB_TRANSPARENT; |
| if( const sal_Int32* pnPaletteColor = ContainerHelper::getVectorElement( maColors, nPaletteIdx ) ) |
| { |
| nColor = *pnPaletteColor; |
| } |
| else switch( nPaletteIdx ) |
| { |
| case OOX_COLOR_WINDOWTEXT3: |
| case OOX_COLOR_WINDOWTEXT: |
| case OOX_COLOR_CHWINDOWTEXT: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_windowText ); break; |
| case OOX_COLOR_WINDOWBACK3: |
| case OOX_COLOR_WINDOWBACK: |
| case OOX_COLOR_CHWINDOWBACK: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_window ); break; |
| case OOX_COLOR_BUTTONBACK: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_btnFace ); break; |
| case OOX_COLOR_CHBORDERAUTO: nColor = API_RGB_BLACK; /* really always black? */ break; |
| case OOX_COLOR_NOTEBACK: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_infoBk ); break; |
| case OOX_COLOR_NOTETEXT: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_infoText ); break; |
| case OOX_COLOR_FONTAUTO: nColor = API_RGB_TRANSPARENT; break; |
| default: OSL_ENSURE( false, "ColorPalette::getColor - unknown color index" ); |
| } |
| return nColor; |
| } |
| |
| void ColorPalette::appendColor( sal_Int32 nRGBValue ) |
| { |
| if( mnAppendIndex < maColors.size() ) |
| maColors[ mnAppendIndex ] = nRGBValue; |
| else |
| maColors.push_back( nRGBValue ); |
| ++mnAppendIndex; |
| } |
| |
| // ============================================================================ |
| |
| namespace { |
| |
| void lclSetFontName( ApiScriptFontName& rFontName, const FontDescriptor& rFontDesc, bool bHasGlyphs ) |
| { |
| if( bHasGlyphs ) |
| { |
| rFontName.maName = rFontDesc.Name; |
| rFontName.mnFamily = rFontDesc.Family; |
| // API font descriptor contains rtl_TextEncoding constants |
| rFontName.mnTextEnc = rFontDesc.CharSet; |
| } |
| else |
| { |
| rFontName = ApiScriptFontName(); |
| } |
| } |
| |
| } // namespace |
| |
| // ---------------------------------------------------------------------------- |
| |
| FontModel::FontModel() : |
| mnScheme( XML_none ), |
| mnFamily( OOX_FONTFAMILY_NONE ), |
| mnCharSet( WINDOWS_CHARSET_DEFAULT ), |
| mfHeight( 0.0 ), |
| mnUnderline( XML_none ), |
| mnEscapement( XML_baseline ), |
| mbBold( false ), |
| mbItalic( false ), |
| mbStrikeout( false ), |
| mbOutline( false ), |
| mbShadow( false ) |
| { |
| } |
| |
| void FontModel::setBiff12Scheme( sal_uInt8 nScheme ) |
| { |
| static const sal_Int32 spnSchemes[] = { XML_none, XML_major, XML_minor }; |
| mnScheme = STATIC_ARRAY_SELECT( spnSchemes, nScheme, XML_none ); |
| } |
| |
| void FontModel::setBiffHeight( sal_uInt16 nHeight ) |
| { |
| mfHeight = nHeight / 20.0; // convert twips to points |
| } |
| |
| void FontModel::setBiffWeight( sal_uInt16 nWeight ) |
| { |
| mbBold = nWeight >= BIFF_FONTWEIGHT_BOLD; |
| } |
| |
| void FontModel::setBiffUnderline( sal_uInt16 nUnderline ) |
| { |
| switch( nUnderline ) |
| { |
| case BIFF_FONTUNDERL_NONE: mnUnderline = XML_none; break; |
| case BIFF_FONTUNDERL_SINGLE: mnUnderline = XML_single; break; |
| case BIFF_FONTUNDERL_DOUBLE: mnUnderline = XML_double; break; |
| case BIFF_FONTUNDERL_SINGLE_ACC: mnUnderline = XML_singleAccounting; break; |
| case BIFF_FONTUNDERL_DOUBLE_ACC: mnUnderline = XML_doubleAccounting; break; |
| default: mnUnderline = XML_none; |
| } |
| } |
| |
| void FontModel::setBiffEscapement( sal_uInt16 nEscapement ) |
| { |
| static const sal_Int32 spnEscapes[] = { XML_baseline, XML_superscript, XML_subscript }; |
| mnEscapement = STATIC_ARRAY_SELECT( spnEscapes, nEscapement, XML_baseline ); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| ApiFontUsedFlags::ApiFontUsedFlags( bool bAllUsed ) : |
| mbNameUsed( bAllUsed ), |
| mbColorUsed( bAllUsed ), |
| mbSchemeUsed( bAllUsed ), |
| mbHeightUsed( bAllUsed ), |
| mbUnderlineUsed( bAllUsed ), |
| mbEscapementUsed( bAllUsed ), |
| mbWeightUsed( bAllUsed ), |
| mbPostureUsed( bAllUsed ), |
| mbStrikeoutUsed( bAllUsed ), |
| mbOutlineUsed( bAllUsed ), |
| mbShadowUsed( bAllUsed ) |
| { |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| ApiScriptFontName::ApiScriptFontName() : |
| mnFamily( ::com::sun::star::awt::FontFamily::DONTKNOW ), |
| mnTextEnc( RTL_TEXTENCODING_DONTKNOW ) |
| { |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| ApiFontData::ApiFontData() : |
| maDesc( |
| CREATE_OUSTRING( "Calibri" ), |
| 220, // height 11 points |
| 0, |
| OUString(), |
| ::com::sun::star::awt::FontFamily::DONTKNOW, |
| RTL_TEXTENCODING_DONTKNOW, |
| ::com::sun::star::awt::FontPitch::DONTKNOW, |
| 100.0, |
| ::com::sun::star::awt::FontWeight::NORMAL, |
| ::com::sun::star::awt::FontSlant_NONE, |
| ::com::sun::star::awt::FontUnderline::NONE, |
| ::com::sun::star::awt::FontStrikeout::NONE, |
| 0.0, |
| sal_False, |
| sal_False, |
| ::com::sun::star::awt::FontType::DONTKNOW ), |
| mnColor( API_RGB_TRANSPARENT ), |
| mnEscapement( API_ESCAPE_NONE ), |
| mnEscapeHeight( API_ESCAPEHEIGHT_NONE ), |
| mbOutline( false ), |
| mbShadow( false ) |
| { |
| maLatinFont.maName = maDesc.Name; |
| } |
| |
| // ============================================================================ |
| |
| Font::Font( const WorkbookHelper& rHelper, bool bDxf ) : |
| WorkbookHelper( rHelper ), |
| maModel( rHelper.getTheme().getDefaultFontModel() ), |
| maUsedFlags( !bDxf ), |
| mbDxf( bDxf ) |
| { |
| } |
| |
| Font::Font( const WorkbookHelper& rHelper, const FontModel& rModel ) : |
| WorkbookHelper( rHelper ), |
| maModel( rModel ), |
| maUsedFlags( true ), |
| mbDxf( false ) |
| { |
| } |
| |
| void Font::importAttribs( sal_Int32 nElement, const AttributeList& rAttribs ) |
| { |
| const FontModel& rDefModel = getTheme().getDefaultFontModel(); |
| switch( nElement ) |
| { |
| case XLS_TOKEN( name ): // when in <font> element |
| case XLS_TOKEN( rFont ): // when in <rPr> element |
| if( rAttribs.hasAttribute( XML_val ) ) |
| { |
| maModel.maName = rAttribs.getXString( XML_val, OUString() ); |
| maUsedFlags.mbNameUsed = true; |
| } |
| break; |
| case XLS_TOKEN( scheme ): |
| maModel.mnScheme = rAttribs.getToken( XML_val, rDefModel.mnScheme ); |
| break; |
| case XLS_TOKEN( family ): |
| maModel.mnFamily = rAttribs.getInteger( XML_val, rDefModel.mnFamily ); |
| break; |
| case XLS_TOKEN( charset ): |
| maModel.mnCharSet = rAttribs.getInteger( XML_val, rDefModel.mnCharSet ); |
| break; |
| case XLS_TOKEN( sz ): |
| maModel.mfHeight = rAttribs.getDouble( XML_val, rDefModel.mfHeight ); |
| maUsedFlags.mbHeightUsed = true; |
| break; |
| case XLS_TOKEN( color ): |
| maModel.maColor.importColor( rAttribs ); |
| maUsedFlags.mbColorUsed = true; |
| break; |
| case XLS_TOKEN( u ): |
| maModel.mnUnderline = rAttribs.getToken( XML_val, XML_single ); |
| maUsedFlags.mbUnderlineUsed = true; |
| break; |
| case XLS_TOKEN( vertAlign ): |
| maModel.mnEscapement = rAttribs.getToken( XML_val, XML_baseline ); |
| maUsedFlags.mbEscapementUsed = true; |
| break; |
| case XLS_TOKEN( b ): |
| maModel.mbBold = rAttribs.getBool( XML_val, true ); |
| maUsedFlags.mbWeightUsed = true; |
| break; |
| case XLS_TOKEN( i ): |
| maModel.mbItalic = rAttribs.getBool( XML_val, true ); |
| maUsedFlags.mbPostureUsed = true; |
| break; |
| case XLS_TOKEN( strike ): |
| maModel.mbStrikeout = rAttribs.getBool( XML_val, true ); |
| maUsedFlags.mbStrikeoutUsed = true; |
| break; |
| case XLS_TOKEN( outline ): |
| maModel.mbOutline = rAttribs.getBool( XML_val, true ); |
| maUsedFlags.mbOutlineUsed = true; |
| break; |
| case XLS_TOKEN( shadow ): |
| maModel.mbShadow = rAttribs.getBool( XML_val, true ); |
| maUsedFlags.mbShadowUsed = true; |
| break; |
| } |
| } |
| |
| void Font::importFont( SequenceInputStream& rStrm ) |
| { |
| OSL_ENSURE( !mbDxf, "Font::importFont - unexpected conditional formatting flag" ); |
| |
| sal_uInt16 nHeight, nFlags, nWeight, nEscapement; |
| sal_uInt8 nUnderline, nFamily, nCharSet, nScheme; |
| rStrm >> nHeight >> nFlags >> nWeight >> nEscapement >> nUnderline >> nFamily >> nCharSet; |
| rStrm.skip( 1 ); |
| rStrm >> maModel.maColor >> nScheme >> maModel.maName; |
| |
| // equal constants in all BIFFs for weight, underline, and escapement |
| maModel.setBiff12Scheme( nScheme ); |
| maModel.setBiffHeight( nHeight ); |
| maModel.setBiffWeight( nWeight ); |
| maModel.setBiffUnderline( nUnderline ); |
| maModel.setBiffEscapement( nEscapement ); |
| maModel.mnFamily = nFamily; |
| maModel.mnCharSet = nCharSet; |
| // equal flags in all BIFFs |
| maModel.mbItalic = getFlag( nFlags, BIFF_FONTFLAG_ITALIC ); |
| maModel.mbStrikeout = getFlag( nFlags, BIFF_FONTFLAG_STRIKEOUT ); |
| maModel.mbOutline = getFlag( nFlags, BIFF_FONTFLAG_OUTLINE ); |
| maModel.mbShadow = getFlag( nFlags, BIFF_FONTFLAG_SHADOW ); |
| } |
| |
| void Font::importDxfName( SequenceInputStream& rStrm ) |
| { |
| OSL_ENSURE( mbDxf, "Font::importDxfName - missing conditional formatting flag" ); |
| maModel.maName = BiffHelper::readString( rStrm, false ); |
| maUsedFlags.mbColorUsed = true; |
| } |
| |
| void Font::importDxfColor( SequenceInputStream& rStrm ) |
| { |
| OSL_ENSURE( mbDxf, "Font::importDxfColor - missing conditional formatting flag" ); |
| rStrm >> maModel.maColor; |
| maUsedFlags.mbColorUsed = true; |
| } |
| |
| void Font::importDxfScheme( SequenceInputStream& rStrm ) |
| { |
| OSL_ENSURE( mbDxf, "Font::importDxfScheme - missing conditional formatting flag" ); |
| maModel.setBiff12Scheme( rStrm.readuInt8() ); |
| maUsedFlags.mbSchemeUsed = true; |
| } |
| |
| void Font::importDxfHeight( SequenceInputStream& rStrm ) |
| { |
| OSL_ENSURE( mbDxf, "Font::importDxfHeight - missing conditional formatting flag" ); |
| maModel.setBiffHeight( rStrm.readuInt16() ); |
| maUsedFlags.mbHeightUsed = true; |
| } |
| |
| void Font::importDxfWeight( SequenceInputStream& rStrm ) |
| { |
| OSL_ENSURE( mbDxf, "Font::importDxfWeight - missing conditional formatting flag" ); |
| maModel.setBiffWeight( rStrm.readuInt16() ); |
| maUsedFlags.mbWeightUsed = true; |
| } |
| |
| void Font::importDxfUnderline( SequenceInputStream& rStrm ) |
| { |
| OSL_ENSURE( mbDxf, "Font::importDxfUnderline - missing conditional formatting flag" ); |
| maModel.setBiffUnderline( rStrm.readuInt16() ); |
| maUsedFlags.mbUnderlineUsed = true; |
| } |
| |
| void Font::importDxfEscapement( SequenceInputStream& rStrm ) |
| { |
| OSL_ENSURE( mbDxf, "Font::importDxfEscapement - missing conditional formatting flag" ); |
| maModel.setBiffEscapement( rStrm.readuInt16() ); |
| maUsedFlags.mbEscapementUsed = true; |
| } |
| |
| void Font::importDxfFlag( sal_Int32 nElement, SequenceInputStream& rStrm ) |
| { |
| OSL_ENSURE( mbDxf, "Font::importDxfFlag - missing conditional formatting flag" ); |
| bool bFlag = rStrm.readuInt8() != 0; |
| switch( nElement ) |
| { |
| case XML_i: |
| maModel.mbItalic = bFlag; |
| maUsedFlags.mbPostureUsed = true; |
| break; |
| case XML_strike: |
| maModel.mbStrikeout = bFlag; |
| maUsedFlags.mbStrikeoutUsed = true; |
| break; |
| case XML_outline: |
| maModel.mbOutline = bFlag; |
| maUsedFlags.mbOutlineUsed = true; |
| break; |
| case XML_shadow: |
| maModel.mbShadow = bFlag; |
| maUsedFlags.mbShadowUsed = true; |
| break; |
| default: |
| OSL_ENSURE( false, "Font::importDxfFlag - unexpected element identifier" ); |
| } |
| } |
| |
| void Font::importFont( BiffInputStream& rStrm ) |
| { |
| OSL_ENSURE( !mbDxf, "Font::importFont - unexpected conditional formatting flag" ); |
| switch( getBiff() ) |
| { |
| case BIFF2: |
| importFontData2( rStrm ); |
| importFontName2( rStrm ); |
| break; |
| case BIFF3: |
| case BIFF4: |
| importFontData2( rStrm ); |
| importFontColor( rStrm ); |
| importFontName2( rStrm ); |
| break; |
| case BIFF5: |
| importFontData2( rStrm ); |
| importFontColor( rStrm ); |
| importFontData5( rStrm ); |
| importFontName2( rStrm ); |
| break; |
| case BIFF8: |
| importFontData2( rStrm ); |
| importFontColor( rStrm ); |
| importFontData5( rStrm ); |
| importFontName8( rStrm ); |
| break; |
| case BIFF_UNKNOWN: break; |
| } |
| } |
| |
| void Font::importFontColor( BiffInputStream& rStrm ) |
| { |
| OSL_ENSURE( !mbDxf, "Font::importFontColor - unexpected conditional formatting flag" ); |
| maModel.maColor.importColorId( rStrm ); |
| } |
| |
| void Font::importCfRule( BiffInputStream& rStrm ) |
| { |
| OSL_ENSURE( mbDxf, "Font::importCfRule - missing conditional formatting flag" ); |
| |
| sal_Int32 nHeight, nColor; |
| sal_uInt32 nStyle, nFontFlags1, nFontFlags2, nFontFlags3; |
| sal_uInt16 nWeight, nEscapement; |
| sal_uInt8 nUnderline; |
| |
| OSL_ENSURE( rStrm.getRemaining() >= 118, "Font::importCfRule - missing record data" ); |
| sal_Int64 nRecPos = rStrm.tell(); |
| maModel.maName = rStrm.readUniStringBody( rStrm.readuInt8() ); |
| maUsedFlags.mbNameUsed = maModel.maName.getLength() > 0; |
| OSL_ENSURE( !rStrm.isEof() && (rStrm.tell() <= nRecPos + 64), "Font::importCfRule - font name too long" ); |
| rStrm.seek( nRecPos + 64 ); |
| rStrm >> nHeight >> nStyle >> nWeight >> nEscapement >> nUnderline; |
| rStrm.skip( 3 ); |
| rStrm >> nColor; |
| rStrm.skip( 4 ); |
| rStrm >> nFontFlags1 >> nFontFlags2 >> nFontFlags3; |
| rStrm.skip( 18 ); |
| |
| if( (maUsedFlags.mbColorUsed = (0 <= nColor) && (nColor <= 0x7FFF)) == true ) |
| maModel.maColor.setIndexed( nColor ); |
| if( (maUsedFlags.mbHeightUsed = (0 < nHeight) && (nHeight <= 0x7FFF)) == true ) |
| maModel.setBiffHeight( static_cast< sal_uInt16 >( nHeight ) ); |
| if( (maUsedFlags.mbUnderlineUsed = !getFlag( nFontFlags3, BIFF_CFRULE_FONT_UNDERL )) == true ) |
| maModel.setBiffUnderline( nUnderline ); |
| if( (maUsedFlags.mbEscapementUsed = !getFlag( nFontFlags2, BIFF_CFRULE_FONT_ESCAPEM )) == true ) |
| maModel.setBiffEscapement( nEscapement ); |
| if( (maUsedFlags.mbWeightUsed = maUsedFlags.mbPostureUsed = !getFlag( nFontFlags1, BIFF_CFRULE_FONT_STYLE )) == true ) |
| { |
| maModel.setBiffWeight( nWeight ); |
| maModel.mbItalic = getFlag( nStyle, BIFF_CFRULE_FONT_STYLE ); |
| } |
| if( (maUsedFlags.mbStrikeoutUsed = !getFlag( nFontFlags1, BIFF_CFRULE_FONT_STRIKEOUT )) == true ) |
| maModel.mbStrikeout = getFlag( nStyle, BIFF_CFRULE_FONT_STRIKEOUT ); |
| if( (maUsedFlags.mbOutlineUsed = !getFlag( nFontFlags1, BIFF_CFRULE_FONT_OUTLINE )) == true ) |
| maModel.mbOutline = getFlag( nStyle, BIFF_CFRULE_FONT_OUTLINE ); |
| if( (maUsedFlags.mbShadowUsed = !getFlag( nFontFlags1, BIFF_CFRULE_FONT_SHADOW )) == true ) |
| maModel.mbShadow = getFlag( nStyle, BIFF_CFRULE_FONT_SHADOW ); |
| } |
| |
| rtl_TextEncoding Font::getFontEncoding() const |
| { |
| // #i63105# cells use text encoding from FONT record character set |
| // #i67768# BIFF2-BIFF4 FONT records do not contain character set |
| // #i71033# do not use maApiData, this function is used before finalizeImport() |
| rtl_TextEncoding eFontEnc = RTL_TEXTENCODING_DONTKNOW; |
| if( (0 <= maModel.mnCharSet) && (maModel.mnCharSet <= SAL_MAX_UINT8) ) |
| eFontEnc = rtl_getTextEncodingFromWindowsCharset( static_cast< sal_uInt8 >( maModel.mnCharSet ) ); |
| return (eFontEnc == RTL_TEXTENCODING_DONTKNOW) ? getTextEncoding() : eFontEnc; |
| } |
| |
| void Font::finalizeImport() |
| { |
| namespace cssawt = ::com::sun::star::awt; |
| |
| // font name |
| maApiData.maDesc.Name = maModel.maName; |
| |
| // font family |
| switch( maModel.mnFamily ) |
| { |
| case OOX_FONTFAMILY_NONE: maApiData.maDesc.Family = cssawt::FontFamily::DONTKNOW; break; |
| case OOX_FONTFAMILY_ROMAN: maApiData.maDesc.Family = cssawt::FontFamily::ROMAN; break; |
| case OOX_FONTFAMILY_SWISS: maApiData.maDesc.Family = cssawt::FontFamily::SWISS; break; |
| case OOX_FONTFAMILY_MODERN: maApiData.maDesc.Family = cssawt::FontFamily::MODERN; break; |
| case OOX_FONTFAMILY_SCRIPT: maApiData.maDesc.Family = cssawt::FontFamily::SCRIPT; break; |
| case OOX_FONTFAMILY_DECORATIVE: maApiData.maDesc.Family = cssawt::FontFamily::DECORATIVE; break; |
| } |
| |
| // character set (API font descriptor uses rtl_TextEncoding in member CharSet!) |
| if( (0 <= maModel.mnCharSet) && (maModel.mnCharSet <= SAL_MAX_UINT8) ) |
| maApiData.maDesc.CharSet = static_cast< sal_Int16 >( |
| rtl_getTextEncodingFromWindowsCharset( static_cast< sal_uInt8 >( maModel.mnCharSet ) ) ); |
| |
| // color, height, weight, slant, strikeout, outline, shadow |
| maApiData.mnColor = maModel.maColor.getColor( getBaseFilter().getGraphicHelper() ); |
| maApiData.maDesc.Height = static_cast< sal_Int16 >( maModel.mfHeight * 20.0 ); |
| maApiData.maDesc.Weight = maModel.mbBold ? cssawt::FontWeight::BOLD : cssawt::FontWeight::NORMAL; |
| maApiData.maDesc.Slant = maModel.mbItalic ? cssawt::FontSlant_ITALIC : cssawt::FontSlant_NONE; |
| maApiData.maDesc.Strikeout = maModel.mbStrikeout ? cssawt::FontStrikeout::SINGLE : cssawt::FontStrikeout::NONE; |
| maApiData.mbOutline = maModel.mbOutline; |
| maApiData.mbShadow = maModel.mbShadow; |
| |
| // underline |
| switch( maModel.mnUnderline ) |
| { |
| case XML_double: maApiData.maDesc.Underline = cssawt::FontUnderline::DOUBLE; break; |
| case XML_doubleAccounting: maApiData.maDesc.Underline = cssawt::FontUnderline::DOUBLE; break; |
| case XML_none: maApiData.maDesc.Underline = cssawt::FontUnderline::NONE; break; |
| case XML_single: maApiData.maDesc.Underline = cssawt::FontUnderline::SINGLE; break; |
| case XML_singleAccounting: maApiData.maDesc.Underline = cssawt::FontUnderline::SINGLE; break; |
| } |
| |
| // escapement |
| switch( maModel.mnEscapement ) |
| { |
| case XML_baseline: |
| maApiData.mnEscapement = API_ESCAPE_NONE; |
| maApiData.mnEscapeHeight = API_ESCAPEHEIGHT_NONE; |
| break; |
| case XML_superscript: |
| maApiData.mnEscapement = API_ESCAPE_SUPERSCRIPT; |
| maApiData.mnEscapeHeight = API_ESCAPEHEIGHT_DEFAULT; |
| break; |
| case XML_subscript: |
| maApiData.mnEscapement = API_ESCAPE_SUBSCRIPT; |
| maApiData.mnEscapeHeight = API_ESCAPEHEIGHT_DEFAULT; |
| break; |
| } |
| |
| // supported script types |
| if( maUsedFlags.mbNameUsed ) |
| { |
| PropertySet aDocProps( getDocument() ); |
| Reference< XDevice > xDevice( aDocProps.getAnyProperty( PROP_ReferenceDevice ), UNO_QUERY ); |
| if( xDevice.is() ) |
| { |
| Reference< XFont2 > xFont( xDevice->getFont( maApiData.maDesc ), UNO_QUERY ); |
| if( xFont.is() ) |
| { |
| // #91658# CJK fonts |
| bool bHasAsian = |
| xFont->hasGlyphs( OUString( sal_Unicode( 0x3041 ) ) ) || // 3040-309F: Hiragana |
| xFont->hasGlyphs( OUString( sal_Unicode( 0x30A1 ) ) ) || // 30A0-30FF: Katakana |
| xFont->hasGlyphs( OUString( sal_Unicode( 0x3111 ) ) ) || // 3100-312F: Bopomofo |
| xFont->hasGlyphs( OUString( sal_Unicode( 0x3131 ) ) ) || // 3130-318F: Hangul Compatibility Jamo |
| xFont->hasGlyphs( OUString( sal_Unicode( 0x3301 ) ) ) || // 3300-33FF: CJK Compatibility |
| xFont->hasGlyphs( OUString( sal_Unicode( 0x3401 ) ) ) || // 3400-4DBF: CJK Unified Ideographs Extension A |
| xFont->hasGlyphs( OUString( sal_Unicode( 0x4E01 ) ) ) || // 4E00-9FAF: CJK Unified Ideographs |
| xFont->hasGlyphs( OUString( sal_Unicode( 0x7E01 ) ) ) || // 4E00-9FAF: CJK unified ideographs |
| xFont->hasGlyphs( OUString( sal_Unicode( 0xA001 ) ) ) || // A001-A48F: Yi Syllables |
| xFont->hasGlyphs( OUString( sal_Unicode( 0xAC01 ) ) ) || // AC00-D7AF: Hangul Syllables |
| xFont->hasGlyphs( OUString( sal_Unicode( 0xCC01 ) ) ) || // AC00-D7AF: Hangul Syllables |
| xFont->hasGlyphs( OUString( sal_Unicode( 0xF901 ) ) ) || // F900-FAFF: CJK Compatibility Ideographs |
| xFont->hasGlyphs( OUString( sal_Unicode( 0xFF71 ) ) ); // FF00-FFEF: Halfwidth/Fullwidth Forms |
| // #113783# CTL fonts |
| bool bHasCmplx = |
| xFont->hasGlyphs( OUString( sal_Unicode( 0x05D1 ) ) ) || // 0590-05FF: Hebrew |
| xFont->hasGlyphs( OUString( sal_Unicode( 0x0631 ) ) ) || // 0600-06FF: Arabic |
| xFont->hasGlyphs( OUString( sal_Unicode( 0x0721 ) ) ) || // 0700-074F: Syriac |
| xFont->hasGlyphs( OUString( sal_Unicode( 0x0911 ) ) ) || // 0900-0DFF: Indic scripts |
| xFont->hasGlyphs( OUString( sal_Unicode( 0x0E01 ) ) ) || // 0E00-0E7F: Thai |
| xFont->hasGlyphs( OUString( sal_Unicode( 0xFB21 ) ) ) || // FB1D-FB4F: Hebrew Presentation Forms |
| xFont->hasGlyphs( OUString( sal_Unicode( 0xFB51 ) ) ) || // FB50-FDFF: Arabic Presentation Forms-A |
| xFont->hasGlyphs( OUString( sal_Unicode( 0xFE71 ) ) ); // FE70-FEFF: Arabic Presentation Forms-B |
| // Western fonts |
| bool bHasLatin = |
| (!bHasAsian && !bHasCmplx) || |
| xFont->hasGlyphs( OUString( sal_Unicode( 'A' ) ) ); |
| |
| lclSetFontName( maApiData.maLatinFont, maApiData.maDesc, bHasLatin ); |
| lclSetFontName( maApiData.maAsianFont, maApiData.maDesc, bHasAsian ); |
| lclSetFontName( maApiData.maCmplxFont, maApiData.maDesc, bHasCmplx ); |
| } |
| } |
| } |
| } |
| |
| const FontDescriptor& Font::getFontDescriptor() const |
| { |
| return maApiData.maDesc; |
| } |
| |
| bool Font::needsRichTextFormat() const |
| { |
| return maApiData.mnEscapement != API_ESCAPE_NONE; |
| } |
| |
| void Font::writeToPropertyMap( PropertyMap& rPropMap, FontPropertyType ePropType ) const |
| { |
| // font name properties |
| if( maUsedFlags.mbNameUsed ) |
| { |
| if( maApiData.maLatinFont.maName.getLength() > 0 ) |
| { |
| rPropMap[ PROP_CharFontName ] <<= maApiData.maLatinFont.maName; |
| rPropMap[ PROP_CharFontFamily ] <<= maApiData.maLatinFont.mnFamily; |
| rPropMap[ PROP_CharFontCharSet ] <<= maApiData.maLatinFont.mnTextEnc; |
| } |
| if( maApiData.maAsianFont.maName.getLength() > 0 ) |
| { |
| rPropMap[ PROP_CharFontNameAsian ] <<= maApiData.maAsianFont.maName; |
| rPropMap[ PROP_CharFontFamilyAsian ] <<= maApiData.maAsianFont.mnFamily; |
| rPropMap[ PROP_CharFontCharSetAsian ] <<= maApiData.maAsianFont.mnTextEnc; |
| } |
| if( maApiData.maCmplxFont.maName.getLength() > 0 ) |
| { |
| rPropMap[ PROP_CharFontNameComplex ] <<= maApiData.maCmplxFont.maName; |
| rPropMap[ PROP_CharFontFamilyComplex ] <<= maApiData.maCmplxFont.mnFamily; |
| rPropMap[ PROP_CharFontCharSetComplex ] <<= maApiData.maCmplxFont.mnTextEnc; |
| } |
| } |
| // font height |
| if( maUsedFlags.mbHeightUsed ) |
| { |
| float fHeight = static_cast< float >( maApiData.maDesc.Height / 20.0 ); // twips to points |
| rPropMap[ PROP_CharHeight ] <<= fHeight; |
| rPropMap[ PROP_CharHeightAsian ] <<= fHeight; |
| rPropMap[ PROP_CharHeightComplex ] <<= fHeight; |
| } |
| // font weight |
| if( maUsedFlags.mbWeightUsed ) |
| { |
| float fWeight = maApiData.maDesc.Weight; |
| rPropMap[ PROP_CharWeight ] <<= fWeight; |
| rPropMap[ PROP_CharWeightAsian ] <<= fWeight; |
| rPropMap[ PROP_CharWeightComplex ] <<= fWeight; |
| } |
| // font posture |
| if( maUsedFlags.mbPostureUsed ) |
| { |
| rPropMap[ PROP_CharPosture ] <<= maApiData.maDesc.Slant; |
| rPropMap[ PROP_CharPostureAsian ] <<= maApiData.maDesc.Slant; |
| rPropMap[ PROP_CharPostureComplex ] <<= maApiData.maDesc.Slant; |
| } |
| // character color |
| if( maUsedFlags.mbColorUsed ) |
| rPropMap[ PROP_CharColor ] <<= maApiData.mnColor; |
| // underline style |
| if( maUsedFlags.mbUnderlineUsed ) |
| rPropMap[ PROP_CharUnderline ] <<= maApiData.maDesc.Underline; |
| // strike out style |
| if( maUsedFlags.mbStrikeoutUsed ) |
| rPropMap[ PROP_CharStrikeout ] <<= maApiData.maDesc.Strikeout; |
| // outline style |
| if( maUsedFlags.mbOutlineUsed ) |
| rPropMap[ PROP_CharContoured ] <<= maApiData.mbOutline; |
| // shadow style |
| if( maUsedFlags.mbShadowUsed ) |
| rPropMap[ PROP_CharShadowed ] <<= maApiData.mbShadow; |
| // escapement |
| if( maUsedFlags.mbEscapementUsed && (ePropType == FONT_PROPTYPE_TEXT) ) |
| { |
| rPropMap[ PROP_CharEscapement ] <<= maApiData.mnEscapement; |
| rPropMap[ PROP_CharEscapementHeight ] <<= maApiData.mnEscapeHeight; |
| } |
| } |
| |
| void Font::writeToPropertySet( PropertySet& rPropSet, FontPropertyType ePropType ) const |
| { |
| PropertyMap aPropMap; |
| writeToPropertyMap( aPropMap, ePropType ); |
| rPropSet.setProperties( aPropMap ); |
| } |
| |
| void Font::importFontData2( BiffInputStream& rStrm ) |
| { |
| sal_uInt16 nHeight, nFlags; |
| rStrm >> nHeight >> nFlags; |
| |
| maModel.setBiffHeight( nHeight ); |
| maModel.mnFamily = OOX_FONTFAMILY_NONE; |
| maModel.mnCharSet = -1; // ensure to not use font charset in byte string import |
| maModel.mnUnderline = getFlagValue( nFlags, BIFF_FONTFLAG_UNDERLINE, XML_single, XML_none ); |
| maModel.mnEscapement = XML_none; |
| maModel.mbBold = getFlag( nFlags, BIFF_FONTFLAG_BOLD ); |
| maModel.mbItalic = getFlag( nFlags, BIFF_FONTFLAG_ITALIC ); |
| maModel.mbStrikeout = getFlag( nFlags, BIFF_FONTFLAG_STRIKEOUT ); |
| maModel.mbOutline = getFlag( nFlags, BIFF_FONTFLAG_OUTLINE ); |
| maModel.mbShadow = getFlag( nFlags, BIFF_FONTFLAG_SHADOW ); |
| } |
| |
| void Font::importFontData5( BiffInputStream& rStrm ) |
| { |
| sal_uInt16 nWeight, nEscapement; |
| sal_uInt8 nUnderline, nFamily, nCharSet; |
| rStrm >> nWeight >> nEscapement >> nUnderline >> nFamily >> nCharSet; |
| rStrm.skip( 1 ); |
| |
| maModel.setBiffWeight( nWeight ); |
| maModel.setBiffUnderline( nUnderline ); |
| maModel.setBiffEscapement( nEscapement ); |
| // equal constants in XML and BIFF for family and charset |
| maModel.mnFamily = nFamily; |
| maModel.mnCharSet = nCharSet; |
| } |
| |
| void Font::importFontName2( BiffInputStream& rStrm ) |
| { |
| maModel.maName = rStrm.readByteStringUC( false, getTextEncoding() ); |
| } |
| |
| void Font::importFontName8( BiffInputStream& rStrm ) |
| { |
| maModel.maName = rStrm.readUniStringBody( rStrm.readuInt8() ); |
| } |
| |
| // ============================================================================ |
| |
| AlignmentModel::AlignmentModel() : |
| mnHorAlign( XML_general ), |
| mnVerAlign( XML_bottom ), |
| mnTextDir( OOX_XF_TEXTDIR_CONTEXT ), |
| mnRotation( OOX_XF_ROTATION_NONE ), |
| mnIndent( OOX_XF_INDENT_NONE ), |
| mbWrapText( false ), |
| mbShrink( false ), |
| mbJustLastLine( false ) |
| { |
| } |
| |
| void AlignmentModel::setBiffHorAlign( sal_uInt8 nHorAlign ) |
| { |
| static const sal_Int32 spnHorAligns[] = { |
| XML_general, XML_left, XML_center, XML_right, |
| XML_fill, XML_justify, XML_centerContinuous, XML_distributed }; |
| mnHorAlign = STATIC_ARRAY_SELECT( spnHorAligns, nHorAlign, XML_general ); |
| } |
| |
| void AlignmentModel::setBiffVerAlign( sal_uInt8 nVerAlign ) |
| { |
| static const sal_Int32 spnVerAligns[] = { |
| XML_top, XML_center, XML_bottom, XML_justify, XML_distributed }; |
| mnVerAlign = STATIC_ARRAY_SELECT( spnVerAligns, nVerAlign, XML_bottom ); |
| } |
| |
| void AlignmentModel::setBiffTextOrient( sal_uInt8 nTextOrient ) |
| { |
| static const sal_Int32 spnRotations[] = { |
| OOX_XF_ROTATION_NONE, OOX_XF_ROTATION_STACKED, |
| OOX_XF_ROTATION_90CCW, OOX_XF_ROTATION_90CW }; |
| mnRotation = STATIC_ARRAY_SELECT( spnRotations, nTextOrient, OOX_XF_ROTATION_NONE ); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| ApiAlignmentData::ApiAlignmentData() : |
| meHorJustify( ::com::sun::star::table::CellHoriJustify_STANDARD ), |
| meVerJustify( ::com::sun::star::table::CellVertJustify_STANDARD ), |
| meOrientation( ::com::sun::star::table::CellOrientation_STANDARD ), |
| mnRotation( 0 ), |
| mnWritingMode( ::com::sun::star::text::WritingMode2::PAGE ), |
| mnIndent( 0 ), |
| mbWrapText( false ), |
| mbShrink( false ) |
| { |
| } |
| |
| bool operator==( const ApiAlignmentData& rLeft, const ApiAlignmentData& rRight ) |
| { |
| return |
| (rLeft.meHorJustify == rRight.meHorJustify) && |
| (rLeft.meVerJustify == rRight.meVerJustify) && |
| (rLeft.meOrientation == rRight.meOrientation) && |
| (rLeft.mnRotation == rRight.mnRotation) && |
| (rLeft.mnWritingMode == rRight.mnWritingMode) && |
| (rLeft.mnIndent == rRight.mnIndent) && |
| (rLeft.mbWrapText == rRight.mbWrapText) && |
| (rLeft.mbShrink == rRight.mbShrink); |
| } |
| |
| // ============================================================================ |
| |
| Alignment::Alignment( const WorkbookHelper& rHelper ) : |
| WorkbookHelper( rHelper ) |
| { |
| } |
| |
| void Alignment::importAlignment( const AttributeList& rAttribs ) |
| { |
| maModel.mnHorAlign = rAttribs.getToken( XML_horizontal, XML_general ); |
| maModel.mnVerAlign = rAttribs.getToken( XML_vertical, XML_bottom ); |
| maModel.mnTextDir = rAttribs.getInteger( XML_readingOrder, OOX_XF_TEXTDIR_CONTEXT ); |
| maModel.mnRotation = rAttribs.getInteger( XML_textRotation, OOX_XF_ROTATION_NONE ); |
| maModel.mnIndent = rAttribs.getInteger( XML_indent, OOX_XF_INDENT_NONE ); |
| maModel.mbWrapText = rAttribs.getBool( XML_wrapText, false ); |
| maModel.mbShrink = rAttribs.getBool( XML_shrinkToFit, false ); |
| maModel.mbJustLastLine = rAttribs.getBool( XML_justifyLastLine, false ); |
| } |
| |
| void Alignment::setBiff12Data( sal_uInt32 nFlags ) |
| { |
| maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nFlags, 16, 3 ) ); |
| maModel.setBiffVerAlign( extractValue< sal_uInt8 >( nFlags, 19, 3 ) ); |
| maModel.mnTextDir = extractValue< sal_Int32 >( nFlags, 26, 2 ); |
| maModel.mnRotation = extractValue< sal_Int32 >( nFlags, 0, 8 ); |
| maModel.mnIndent = extractValue< sal_uInt8 >( nFlags, 8, 8 ); |
| maModel.mbWrapText = getFlag( nFlags, BIFF12_XF_WRAPTEXT ); |
| maModel.mbShrink = getFlag( nFlags, BIFF12_XF_SHRINK ); |
| maModel.mbJustLastLine = getFlag( nFlags, BIFF12_XF_JUSTLASTLINE ); |
| } |
| |
| void Alignment::setBiff2Data( sal_uInt8 nFlags ) |
| { |
| maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nFlags, 0, 3 ) ); |
| } |
| |
| void Alignment::setBiff3Data( sal_uInt16 nAlign ) |
| { |
| maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nAlign, 0, 3 ) ); |
| maModel.mbWrapText = getFlag( nAlign, BIFF_XF_WRAPTEXT ); // new in BIFF3 |
| } |
| |
| void Alignment::setBiff4Data( sal_uInt16 nAlign ) |
| { |
| maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nAlign, 0, 3 ) ); |
| maModel.setBiffVerAlign( extractValue< sal_uInt8 >( nAlign, 4, 2 ) ); // new in BIFF4 |
| maModel.setBiffTextOrient( extractValue< sal_uInt8 >( nAlign, 6, 2 ) ); // new in BIFF4 |
| maModel.mbWrapText = getFlag( nAlign, BIFF_XF_WRAPTEXT ); |
| } |
| |
| void Alignment::setBiff5Data( sal_uInt16 nAlign ) |
| { |
| maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nAlign, 0, 3 ) ); |
| maModel.setBiffVerAlign( extractValue< sal_uInt8 >( nAlign, 4, 3 ) ); |
| maModel.setBiffTextOrient( extractValue< sal_uInt8 >( nAlign, 8, 2 ) ); |
| maModel.mbWrapText = getFlag( nAlign, BIFF_XF_WRAPTEXT ); |
| } |
| |
| void Alignment::setBiff8Data( sal_uInt16 nAlign, sal_uInt16 nMiscAttrib ) |
| { |
| maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nAlign, 0, 3 ) ); |
| maModel.setBiffVerAlign( extractValue< sal_uInt8 >( nAlign, 4, 3 ) ); |
| maModel.mnTextDir = extractValue< sal_Int32 >( nMiscAttrib, 6, 2 ); // new in BIFF8 |
| maModel.mnRotation = extractValue< sal_Int32 >( nAlign, 8, 8 ); // new in BIFF8 |
| maModel.mnIndent = extractValue< sal_uInt8 >( nMiscAttrib, 0, 4 ); // new in BIFF8 |
| maModel.mbWrapText = getFlag( nAlign, BIFF_XF_WRAPTEXT ); |
| maModel.mbShrink = getFlag( nMiscAttrib, BIFF_XF_SHRINK ); // new in BIFF8 |
| maModel.mbJustLastLine = getFlag( nAlign, BIFF_XF_JUSTLASTLINE ); // new in BIFF8(?) |
| } |
| |
| void Alignment::finalizeImport() |
| { |
| namespace csstab = ::com::sun::star::table; |
| namespace csstxt = ::com::sun::star::text; |
| |
| // horizontal alignment |
| switch( maModel.mnHorAlign ) |
| { |
| case XML_center: maApiData.meHorJustify = csstab::CellHoriJustify_CENTER; break; |
| case XML_centerContinuous: maApiData.meHorJustify = csstab::CellHoriJustify_CENTER; break; |
| case XML_distributed: maApiData.meHorJustify = csstab::CellHoriJustify_BLOCK; break; |
| case XML_fill: maApiData.meHorJustify = csstab::CellHoriJustify_REPEAT; break; |
| case XML_general: maApiData.meHorJustify = csstab::CellHoriJustify_STANDARD; break; |
| case XML_justify: maApiData.meHorJustify = csstab::CellHoriJustify_BLOCK; break; |
| case XML_left: maApiData.meHorJustify = csstab::CellHoriJustify_LEFT; break; |
| case XML_right: maApiData.meHorJustify = csstab::CellHoriJustify_RIGHT; break; |
| } |
| |
| // vertical alignment |
| switch( maModel.mnVerAlign ) |
| { |
| case XML_bottom: maApiData.meVerJustify = csstab::CellVertJustify_BOTTOM; break; |
| case XML_center: maApiData.meVerJustify = csstab::CellVertJustify_CENTER; break; |
| case XML_distributed: maApiData.meVerJustify = csstab::CellVertJustify_TOP; break; |
| case XML_justify: maApiData.meVerJustify = csstab::CellVertJustify_TOP; break; |
| case XML_top: maApiData.meVerJustify = csstab::CellVertJustify_TOP; break; |
| } |
| |
| /* indentation: expressed as number of blocks of 3 space characters in |
| OOXML/BIFF12, and as multiple of 10 points in BIFF8. */ |
| sal_Int32 nIndent = 0; |
| switch( getFilterType() ) |
| { |
| case FILTER_OOXML: nIndent = getUnitConverter().scaleToMm100( 3.0 * maModel.mnIndent, UNIT_SPACE ); break; |
| case FILTER_BIFF: nIndent = getUnitConverter().scaleToMm100( 10.0 * maModel.mnIndent, UNIT_POINT ); break; |
| case FILTER_UNKNOWN: break; |
| } |
| if( (0 <= nIndent) && (nIndent <= SAL_MAX_INT16) ) |
| maApiData.mnIndent = static_cast< sal_Int16 >( nIndent ); |
| |
| // complex text direction |
| switch( maModel.mnTextDir ) |
| { |
| case OOX_XF_TEXTDIR_CONTEXT: maApiData.mnWritingMode = csstxt::WritingMode2::PAGE; break; |
| case OOX_XF_TEXTDIR_LTR: maApiData.mnWritingMode = csstxt::WritingMode2::LR_TB; break; |
| case OOX_XF_TEXTDIR_RTL: maApiData.mnWritingMode = csstxt::WritingMode2::RL_TB; break; |
| } |
| |
| // rotation: 0-90 means 0 to 90 degrees ccw, 91-180 means 1 to 90 degrees cw, 255 means stacked |
| sal_Int32 nOoxRot = maModel.mnRotation; |
| maApiData.mnRotation = ((0 <= nOoxRot) && (nOoxRot <= 90)) ? |
| (100 * nOoxRot) : |
| (((91 <= nOoxRot) && (nOoxRot <= 180)) ? (100 * (450 - nOoxRot)) : 0); |
| |
| // "Orientation" property used for character stacking |
| maApiData.meOrientation = (nOoxRot == OOX_XF_ROTATION_STACKED) ? |
| csstab::CellOrientation_STACKED : csstab::CellOrientation_STANDARD; |
| |
| // alignment flags (#i84960 automatic line break, if vertically justified/distributed) |
| maApiData.mbWrapText = maModel.mbWrapText || (maModel.mnVerAlign == XML_distributed) || (maModel.mnVerAlign == XML_justify); |
| maApiData.mbShrink = maModel.mbShrink; |
| |
| } |
| |
| void Alignment::writeToPropertyMap( PropertyMap& rPropMap ) const |
| { |
| rPropMap[ PROP_HoriJustify ] <<= maApiData.meHorJustify; |
| rPropMap[ PROP_VertJustify ] <<= maApiData.meVerJustify; |
| rPropMap[ PROP_WritingMode ] <<= maApiData.mnWritingMode; |
| rPropMap[ PROP_RotateAngle ] <<= maApiData.mnRotation; |
| rPropMap[ PROP_Orientation ] <<= maApiData.meOrientation; |
| rPropMap[ PROP_ParaIndent ] <<= maApiData.mnIndent; |
| rPropMap[ PROP_IsTextWrapped ] <<= maApiData.mbWrapText; |
| rPropMap[ PROP_ShrinkToFit ] <<= maApiData.mbShrink; |
| } |
| |
| // ============================================================================ |
| |
| ProtectionModel::ProtectionModel() : |
| mbLocked( true ), // default in Excel and Calc |
| mbHidden( false ) |
| { |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| ApiProtectionData::ApiProtectionData() : |
| maCellProt( sal_True, sal_False, sal_False, sal_False ) |
| { |
| } |
| |
| bool operator==( const ApiProtectionData& rLeft, const ApiProtectionData& rRight ) |
| { |
| return |
| (rLeft.maCellProt.IsLocked == rRight.maCellProt.IsLocked) && |
| (rLeft.maCellProt.IsFormulaHidden == rRight.maCellProt.IsFormulaHidden) && |
| (rLeft.maCellProt.IsHidden == rRight.maCellProt.IsHidden) && |
| (rLeft.maCellProt.IsPrintHidden == rRight.maCellProt.IsPrintHidden); |
| } |
| |
| // ============================================================================ |
| |
| Protection::Protection( const WorkbookHelper& rHelper ) : |
| WorkbookHelper( rHelper ) |
| { |
| } |
| |
| void Protection::importProtection( const AttributeList& rAttribs ) |
| { |
| maModel.mbLocked = rAttribs.getBool( XML_locked, true ); |
| maModel.mbHidden = rAttribs.getBool( XML_hidden, false ); |
| } |
| |
| void Protection::setBiff12Data( sal_uInt32 nFlags ) |
| { |
| maModel.mbLocked = getFlag( nFlags, BIFF12_XF_LOCKED ); |
| maModel.mbHidden = getFlag( nFlags, BIFF12_XF_HIDDEN ); |
| } |
| |
| void Protection::setBiff2Data( sal_uInt8 nNumFmt ) |
| { |
| maModel.mbLocked = getFlag( nNumFmt, BIFF2_XF_LOCKED ); |
| maModel.mbHidden = getFlag( nNumFmt, BIFF2_XF_HIDDEN ); |
| } |
| |
| void Protection::setBiff3Data( sal_uInt16 nProt ) |
| { |
| maModel.mbLocked = getFlag( nProt, BIFF_XF_LOCKED ); |
| maModel.mbHidden = getFlag( nProt, BIFF_XF_HIDDEN ); |
| } |
| |
| void Protection::finalizeImport() |
| { |
| maApiData.maCellProt.IsLocked = maModel.mbLocked; |
| maApiData.maCellProt.IsFormulaHidden = maModel.mbHidden; |
| } |
| |
| void Protection::writeToPropertyMap( PropertyMap& rPropMap ) const |
| { |
| rPropMap[ PROP_CellProtection ] <<= maApiData.maCellProt; |
| } |
| |
| // ============================================================================ |
| |
| BorderLineModel::BorderLineModel( bool bDxf ) : |
| mnStyle( XML_none ), |
| mbUsed( !bDxf ) |
| { |
| maColor.setIndexed( OOX_COLOR_WINDOWTEXT ); |
| } |
| |
| void BorderLineModel::setBiffStyle( sal_Int32 nLineStyle ) |
| { |
| static const sal_Int32 spnStyleIds[] = { |
| XML_none, XML_thin, XML_medium, XML_dashed, |
| XML_dotted, XML_thick, XML_double, XML_hair, |
| XML_mediumDashed, XML_dashDot, XML_mediumDashDot, XML_dashDotDot, |
| XML_mediumDashDotDot, XML_slantDashDot }; |
| mnStyle = STATIC_ARRAY_SELECT( spnStyleIds, nLineStyle, XML_none ); |
| } |
| |
| void BorderLineModel::setBiffData( sal_uInt8 nLineStyle, sal_uInt16 nLineColor ) |
| { |
| maColor.setIndexed( nLineColor ); |
| setBiffStyle( nLineStyle ); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| BorderModel::BorderModel( bool bDxf ) : |
| maLeft( bDxf ), |
| maRight( bDxf ), |
| maTop( bDxf ), |
| maBottom( bDxf ), |
| maDiagonal( bDxf ), |
| mbDiagTLtoBR( false ), |
| mbDiagBLtoTR( false ) |
| { |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| ApiBorderData::ApiBorderData() : |
| mbBorderUsed( false ), |
| mbDiagUsed( false ) |
| { |
| } |
| |
| bool ApiBorderData::hasAnyOuterBorder() const |
| { |
| return |
| (maBorder.IsTopLineValid && (maBorder.TopLine.OuterLineWidth > 0)) || |
| (maBorder.IsBottomLineValid && (maBorder.BottomLine.OuterLineWidth > 0)) || |
| (maBorder.IsLeftLineValid && (maBorder.LeftLine.OuterLineWidth > 0)) || |
| (maBorder.IsRightLineValid && (maBorder.RightLine.OuterLineWidth > 0)); |
| } |
| |
| namespace { |
| |
| bool operator==( const BorderLine& rLeft, const BorderLine& rRight ) |
| { |
| return |
| (rLeft.Color == rRight.Color) && |
| (rLeft.InnerLineWidth == rRight.InnerLineWidth) && |
| (rLeft.OuterLineWidth == rRight.OuterLineWidth) && |
| (rLeft.LineDistance == rRight.LineDistance); |
| } |
| |
| bool operator==( const TableBorder& rLeft, const TableBorder& rRight ) |
| { |
| return |
| (rLeft.TopLine == rRight.TopLine) && |
| (rLeft.IsTopLineValid == rRight.IsTopLineValid) && |
| (rLeft.BottomLine == rRight.BottomLine) && |
| (rLeft.IsBottomLineValid == rRight.IsBottomLineValid) && |
| (rLeft.LeftLine == rRight.LeftLine) && |
| (rLeft.IsLeftLineValid == rRight.IsLeftLineValid) && |
| (rLeft.RightLine == rRight.RightLine) && |
| (rLeft.IsRightLineValid == rRight.IsRightLineValid) && |
| (rLeft.HorizontalLine == rRight.HorizontalLine) && |
| (rLeft.IsHorizontalLineValid == rRight.IsHorizontalLineValid) && |
| (rLeft.VerticalLine == rRight.VerticalLine) && |
| (rLeft.IsVerticalLineValid == rRight.IsVerticalLineValid) && |
| (rLeft.Distance == rRight.Distance) && |
| (rLeft.IsDistanceValid == rRight.IsDistanceValid); |
| } |
| |
| } // namespace |
| |
| bool operator==( const ApiBorderData& rLeft, const ApiBorderData& rRight ) |
| { |
| return |
| (rLeft.maBorder == rRight.maBorder) && |
| (rLeft.maTLtoBR == rRight.maTLtoBR) && |
| (rLeft.maBLtoTR == rRight.maBLtoTR) && |
| (rLeft.mbBorderUsed == rRight.mbBorderUsed) && |
| (rLeft.mbDiagUsed == rRight.mbDiagUsed); |
| } |
| |
| // ============================================================================ |
| |
| namespace { |
| |
| inline void lclSetBorderLineWidth( BorderLine& rBorderLine, |
| sal_Int16 nOuter, sal_Int16 nDist = API_LINE_NONE, sal_Int16 nInner = API_LINE_NONE ) |
| { |
| rBorderLine.OuterLineWidth = nOuter; |
| rBorderLine.LineDistance = nDist; |
| rBorderLine.InnerLineWidth = nInner; |
| } |
| |
| inline sal_Int32 lclGetBorderLineWidth( const BorderLine& rBorderLine ) |
| { |
| return rBorderLine.OuterLineWidth + rBorderLine.LineDistance + rBorderLine.InnerLineWidth; |
| } |
| |
| const BorderLine* lclGetThickerLine( const BorderLine& rBorderLine1, sal_Bool bValid1, const BorderLine& rBorderLine2, sal_Bool bValid2 ) |
| { |
| if( bValid1 && bValid2 ) |
| return (lclGetBorderLineWidth( rBorderLine1 ) < lclGetBorderLineWidth( rBorderLine2 )) ? &rBorderLine2 : &rBorderLine1; |
| if( bValid1 ) |
| return &rBorderLine1; |
| if( bValid2 ) |
| return &rBorderLine2; |
| return 0; |
| } |
| |
| } // namespace |
| |
| // ---------------------------------------------------------------------------- |
| |
| Border::Border( const WorkbookHelper& rHelper, bool bDxf ) : |
| WorkbookHelper( rHelper ), |
| maModel( bDxf ), |
| mbDxf( bDxf ) |
| { |
| } |
| |
| void Border::importBorder( const AttributeList& rAttribs ) |
| { |
| maModel.mbDiagTLtoBR = rAttribs.getBool( XML_diagonalDown, false ); |
| maModel.mbDiagBLtoTR = rAttribs.getBool( XML_diagonalUp, false ); |
| } |
| |
| void Border::importStyle( sal_Int32 nElement, const AttributeList& rAttribs ) |
| { |
| if( BorderLineModel* pBorderLine = getBorderLine( nElement ) ) |
| { |
| pBorderLine->mnStyle = rAttribs.getToken( XML_style, XML_none ); |
| pBorderLine->mbUsed = true; |
| } |
| } |
| |
| void Border::importColor( sal_Int32 nElement, const AttributeList& rAttribs ) |
| { |
| if( BorderLineModel* pBorderLine = getBorderLine( nElement ) ) |
| pBorderLine->maColor.importColor( rAttribs ); |
| } |
| |
| void Border::importBorder( SequenceInputStream& rStrm ) |
| { |
| sal_uInt8 nFlags = rStrm.readuInt8(); |
| maModel.mbDiagTLtoBR = getFlag( nFlags, BIFF12_BORDER_DIAG_TLBR ); |
| maModel.mbDiagBLtoTR = getFlag( nFlags, BIFF12_BORDER_DIAG_BLTR ); |
| maModel.maTop.setBiffStyle( rStrm.readuInt16() ); |
| rStrm >> maModel.maTop.maColor; |
| maModel.maBottom.setBiffStyle( rStrm.readuInt16() ); |
| rStrm >> maModel.maBottom.maColor; |
| maModel.maLeft.setBiffStyle( rStrm.readuInt16() ); |
| rStrm >> maModel.maLeft.maColor; |
| maModel.maRight.setBiffStyle( rStrm.readuInt16() ); |
| rStrm >> maModel.maRight.maColor; |
| maModel.maDiagonal.setBiffStyle( rStrm.readuInt16() ); |
| rStrm >> maModel.maDiagonal.maColor; |
| } |
| |
| void Border::importDxfBorder( sal_Int32 nElement, SequenceInputStream& rStrm ) |
| { |
| OSL_ENSURE( mbDxf, "Border::importDxfBorder - missing conditional formatting flag" ); |
| if( BorderLineModel* pBorderLine = getBorderLine( nElement ) ) |
| { |
| sal_uInt16 nStyle; |
| rStrm >> pBorderLine->maColor >> nStyle; |
| pBorderLine->setBiffStyle( nStyle ); |
| pBorderLine->mbUsed = true; |
| } |
| } |
| |
| void Border::setBiff2Data( sal_uInt8 nFlags ) |
| { |
| OSL_ENSURE( !mbDxf, "Border::setBiff2Data - unexpected conditional formatting flag" ); |
| maModel.maLeft.setBiffData( getFlagValue( nFlags, BIFF2_XF_LEFTLINE, BIFF_LINE_THIN, BIFF_LINE_NONE ), BIFF2_COLOR_BLACK ); |
| maModel.maRight.setBiffData( getFlagValue( nFlags, BIFF2_XF_RIGHTLINE, BIFF_LINE_THIN, BIFF_LINE_NONE ), BIFF2_COLOR_BLACK ); |
| maModel.maTop.setBiffData( getFlagValue( nFlags, BIFF2_XF_TOPLINE, BIFF_LINE_THIN, BIFF_LINE_NONE ), BIFF2_COLOR_BLACK ); |
| maModel.maBottom.setBiffData( getFlagValue( nFlags, BIFF2_XF_BOTTOMLINE, BIFF_LINE_THIN, BIFF_LINE_NONE ), BIFF2_COLOR_BLACK ); |
| maModel.maDiagonal.mbUsed = false; |
| } |
| |
| void Border::setBiff3Data( sal_uInt32 nBorder ) |
| { |
| OSL_ENSURE( !mbDxf, "Border::setBiff3Data - unexpected conditional formatting flag" ); |
| maModel.maLeft.setBiffData( extractValue< sal_uInt8 >( nBorder, 8, 3 ), extractValue< sal_uInt16 >( nBorder, 11, 5 ) ); |
| maModel.maRight.setBiffData( extractValue< sal_uInt8 >( nBorder, 24, 3 ), extractValue< sal_uInt16 >( nBorder, 27, 5 ) ); |
| maModel.maTop.setBiffData( extractValue< sal_uInt8 >( nBorder, 0, 3 ), extractValue< sal_uInt16 >( nBorder, 3, 5 ) ); |
| maModel.maBottom.setBiffData( extractValue< sal_uInt8 >( nBorder, 16, 3 ), extractValue< sal_uInt16 >( nBorder, 19, 5 ) ); |
| maModel.maDiagonal.mbUsed = false; |
| } |
| |
| void Border::setBiff5Data( sal_uInt32 nBorder, sal_uInt32 nArea ) |
| { |
| OSL_ENSURE( !mbDxf, "Border::setBiff5Data - unexpected conditional formatting flag" ); |
| maModel.maLeft.setBiffData( extractValue< sal_uInt8 >( nBorder, 3, 3 ), extractValue< sal_uInt16 >( nBorder, 16, 7 ) ); |
| maModel.maRight.setBiffData( extractValue< sal_uInt8 >( nBorder, 6, 3 ), extractValue< sal_uInt16 >( nBorder, 23, 7 ) ); |
| maModel.maTop.setBiffData( extractValue< sal_uInt8 >( nBorder, 0, 3 ), extractValue< sal_uInt16 >( nBorder, 9, 7 ) ); |
| maModel.maBottom.setBiffData( extractValue< sal_uInt8 >( nArea, 22, 3 ), extractValue< sal_uInt16 >( nArea, 25, 7 ) ); |
| maModel.maDiagonal.mbUsed = false; |
| } |
| |
| void Border::setBiff8Data( sal_uInt32 nBorder1, sal_uInt32 nBorder2 ) |
| { |
| OSL_ENSURE( !mbDxf, "Border::setBiff8Data - unexpected conditional formatting flag" ); |
| maModel.maLeft.setBiffData( extractValue< sal_uInt8 >( nBorder1, 0, 4 ), extractValue< sal_uInt16 >( nBorder1, 16, 7 ) ); |
| maModel.maRight.setBiffData( extractValue< sal_uInt8 >( nBorder1, 4, 4 ), extractValue< sal_uInt16 >( nBorder1, 23, 7 ) ); |
| maModel.maTop.setBiffData( extractValue< sal_uInt8 >( nBorder1, 8, 4 ), extractValue< sal_uInt16 >( nBorder2, 0, 7 ) ); |
| maModel.maBottom.setBiffData( extractValue< sal_uInt8 >( nBorder1, 12, 4 ), extractValue< sal_uInt16 >( nBorder2, 7, 7 ) ); |
| maModel.mbDiagTLtoBR = getFlag( nBorder1, BIFF_XF_DIAG_TLBR ); |
| maModel.mbDiagBLtoTR = getFlag( nBorder1, BIFF_XF_DIAG_BLTR ); |
| if( maModel.mbDiagTLtoBR || maModel.mbDiagBLtoTR ) |
| maModel.maDiagonal.setBiffData( extractValue< sal_uInt8 >( nBorder2, 21, 4 ), extractValue< sal_uInt16 >( nBorder2, 14, 7 ) ); |
| } |
| |
| void Border::importCfRule( BiffInputStream& rStrm, sal_uInt32 nFlags ) |
| { |
| OSL_ENSURE( mbDxf, "Border::importCfRule - missing conditional formatting flag" ); |
| OSL_ENSURE( getFlag( nFlags, BIFF_CFRULE_BORDERBLOCK ), "Border::importCfRule - missing border block flag" ); |
| sal_uInt16 nStyle; |
| sal_uInt32 nColor; |
| rStrm >> nStyle >> nColor; |
| rStrm.skip( 2 ); |
| maModel.maLeft.setBiffData( extractValue< sal_uInt8 >( nStyle, 0, 4 ), extractValue< sal_uInt16 >( nColor, 0, 7 ) ); |
| maModel.maRight.setBiffData( extractValue< sal_uInt8 >( nStyle, 4, 4 ), extractValue< sal_uInt16 >( nColor, 7, 7 ) ); |
| maModel.maTop.setBiffData( extractValue< sal_uInt8 >( nStyle, 8, 4 ), extractValue< sal_uInt16 >( nColor, 16, 7 ) ); |
| maModel.maBottom.setBiffData( extractValue< sal_uInt8 >( nStyle, 12, 4 ), extractValue< sal_uInt16 >( nColor, 23, 7 ) ); |
| maModel.maLeft.mbUsed = !getFlag( nFlags, BIFF_CFRULE_BORDER_LEFT ); |
| maModel.maRight.mbUsed = !getFlag( nFlags, BIFF_CFRULE_BORDER_RIGHT ); |
| maModel.maTop.mbUsed = !getFlag( nFlags, BIFF_CFRULE_BORDER_TOP ); |
| maModel.maBottom.mbUsed = !getFlag( nFlags, BIFF_CFRULE_BORDER_BOTTOM ); |
| } |
| |
| void Border::finalizeImport() |
| { |
| maApiData.mbBorderUsed = maModel.maLeft.mbUsed || maModel.maRight.mbUsed || maModel.maTop.mbUsed || maModel.maBottom.mbUsed; |
| maApiData.mbDiagUsed = maModel.maDiagonal.mbUsed; |
| |
| maApiData.maBorder.IsLeftLineValid = convertBorderLine( maApiData.maBorder.LeftLine, maModel.maLeft ); |
| maApiData.maBorder.IsRightLineValid = convertBorderLine( maApiData.maBorder.RightLine, maModel.maRight ); |
| maApiData.maBorder.IsTopLineValid = convertBorderLine( maApiData.maBorder.TopLine, maModel.maTop ); |
| maApiData.maBorder.IsBottomLineValid = convertBorderLine( maApiData.maBorder.BottomLine, maModel.maBottom ); |
| |
| if( !mbDxf ) |
| { |
| maApiData.maBorder.IsVerticalLineValid = maApiData.maBorder.IsLeftLineValid || maApiData.maBorder.IsRightLineValid; |
| if( const BorderLine* pVertLine = lclGetThickerLine( maApiData.maBorder.LeftLine, maApiData.maBorder.IsLeftLineValid, maApiData.maBorder.RightLine, maApiData.maBorder.IsRightLineValid ) ) |
| maApiData.maBorder.VerticalLine = *pVertLine; |
| |
| maApiData.maBorder.IsHorizontalLineValid = maApiData.maBorder.IsTopLineValid || maApiData.maBorder.IsBottomLineValid; |
| if( const BorderLine* pHorLine = lclGetThickerLine( maApiData.maBorder.TopLine, maApiData.maBorder.IsTopLineValid, maApiData.maBorder.BottomLine, maApiData.maBorder.IsBottomLineValid ) ) |
| maApiData.maBorder.HorizontalLine = *pHorLine; |
| } |
| |
| if( maModel.mbDiagTLtoBR ) |
| convertBorderLine( maApiData.maTLtoBR, maModel.maDiagonal ); |
| if( maModel.mbDiagBLtoTR ) |
| convertBorderLine( maApiData.maBLtoTR, maModel.maDiagonal ); |
| } |
| |
| void Border::writeToPropertyMap( PropertyMap& rPropMap ) const |
| { |
| if( maApiData.mbBorderUsed ) |
| rPropMap[ PROP_TableBorder ] <<= maApiData.maBorder; |
| if( maApiData.mbDiagUsed ) |
| { |
| rPropMap[ PROP_DiagonalTLBR ] <<= maApiData.maTLtoBR; |
| rPropMap[ PROP_DiagonalBLTR ] <<= maApiData.maBLtoTR; |
| } |
| } |
| |
| BorderLineModel* Border::getBorderLine( sal_Int32 nElement ) |
| { |
| switch( nElement ) |
| { |
| case XLS_TOKEN( left ): return &maModel.maLeft; |
| case XLS_TOKEN( right ): return &maModel.maRight; |
| case XLS_TOKEN( top ): return &maModel.maTop; |
| case XLS_TOKEN( bottom ): return &maModel.maBottom; |
| case XLS_TOKEN( diagonal ): return &maModel.maDiagonal; |
| } |
| return 0; |
| } |
| |
| bool Border::convertBorderLine( BorderLine& rBorderLine, const BorderLineModel& rModel ) |
| { |
| rBorderLine.Color = rModel.maColor.getColor( getBaseFilter().getGraphicHelper(), API_RGB_BLACK ); |
| switch( rModel.mnStyle ) |
| { |
| case XML_dashDot: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break; |
| case XML_dashDotDot: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break; |
| case XML_dashed: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break; |
| case XML_dotted: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break; |
| case XML_double: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN, API_LINE_THIN, API_LINE_THIN ); break; |
| case XML_hair: lclSetBorderLineWidth( rBorderLine, API_LINE_HAIR ); break; |
| case XML_medium: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break; |
| case XML_mediumDashDot: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break; |
| case XML_mediumDashDotDot: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break; |
| case XML_mediumDashed: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break; |
| case XML_none: lclSetBorderLineWidth( rBorderLine, API_LINE_NONE ); break; |
| case XML_slantDashDot: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break; |
| case XML_thick: lclSetBorderLineWidth( rBorderLine, API_LINE_THICK ); break; |
| case XML_thin: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break; |
| default: lclSetBorderLineWidth( rBorderLine, API_LINE_NONE ); break; |
| } |
| return rModel.mbUsed; |
| } |
| |
| |
| // ============================================================================ |
| |
| PatternFillModel::PatternFillModel( bool bDxf ) : |
| mnPattern( XML_none ), |
| mbPattColorUsed( !bDxf ), |
| mbFillColorUsed( !bDxf ), |
| mbPatternUsed( !bDxf ) |
| { |
| maPatternColor.setIndexed( OOX_COLOR_WINDOWTEXT ); |
| maFillColor.setIndexed( OOX_COLOR_WINDOWBACK ); |
| } |
| |
| void PatternFillModel::setBiffPattern( sal_Int32 nPattern ) |
| { |
| static const sal_Int32 spnPatternIds[] = { |
| XML_none, XML_solid, XML_mediumGray, XML_darkGray, |
| XML_lightGray, XML_darkHorizontal, XML_darkVertical, XML_darkDown, |
| XML_darkUp, XML_darkGrid, XML_darkTrellis, XML_lightHorizontal, |
| XML_lightVertical, XML_lightDown, XML_lightUp, XML_lightGrid, |
| XML_lightTrellis, XML_gray125, XML_gray0625 }; |
| mnPattern = STATIC_ARRAY_SELECT( spnPatternIds, nPattern, XML_none ); |
| } |
| |
| void PatternFillModel::setBiffData( sal_uInt16 nPatternColor, sal_uInt16 nFillColor, sal_uInt8 nPattern ) |
| { |
| maPatternColor.setIndexed( nPatternColor ); |
| maFillColor.setIndexed( nFillColor ); |
| // patterns equal in all BIFFs |
| setBiffPattern( nPattern ); |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| GradientFillModel::GradientFillModel() : |
| mnType( XML_linear ), |
| mfAngle( 0.0 ), |
| mfLeft( 0.0 ), |
| mfRight( 0.0 ), |
| mfTop( 0.0 ), |
| mfBottom( 0.0 ) |
| { |
| } |
| |
| void GradientFillModel::readGradient( SequenceInputStream& rStrm ) |
| { |
| sal_Int32 nType; |
| rStrm >> nType >> mfAngle >> mfLeft >> mfRight >> mfTop >> mfBottom; |
| static const sal_Int32 spnTypes[] = { XML_linear, XML_path }; |
| mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_TOKEN_INVALID ); |
| } |
| |
| void GradientFillModel::readGradientStop( SequenceInputStream& rStrm, bool bDxf ) |
| { |
| Color aColor; |
| double fPosition; |
| if( bDxf ) |
| { |
| rStrm.skip( 2 ); |
| rStrm >> fPosition >> aColor; |
| } |
| else |
| { |
| rStrm >> aColor >> fPosition; |
| } |
| if( !rStrm.isEof() && (fPosition >= 0.0) ) |
| maColors[ fPosition ] = aColor; |
| } |
| |
| // ---------------------------------------------------------------------------- |
| |
| ApiSolidFillData::ApiSolidFillData() : |
| mnColor( API_RGB_TRANSPARENT ), |
| mbTransparent( true ), |
| mbUsed( false ) |
| { |
| } |
| |
| bool operator==( const ApiSolidFillData& rLeft, const ApiSolidFillData& rRight ) |
| { |
| return |
| (rLeft.mnColor == rRight.mnColor) && |
| (rLeft.mbTransparent == rRight.mbTransparent) && |
| (rLeft.mbUsed == rRight.mbUsed); |
| } |
| |
| // ============================================================================ |
| |
| namespace { |
| |
| inline sal_Int32 lclGetMixedColorComp( sal_Int32 nPatt, sal_Int32 nFill, sal_Int32 nAlpha ) |
| { |
| return ((nPatt - nFill) * nAlpha) / 0x80 + nFill; |
| } |
| |
| sal_Int32 lclGetMixedColor( sal_Int32 nPattColor, sal_Int32 nFillColor, sal_Int32 nAlpha ) |
| { |
| return |
| (lclGetMixedColorComp( nPattColor & 0xFF0000, nFillColor & 0xFF0000, nAlpha ) & 0xFF0000) | |
| (lclGetMixedColorComp( nPattColor & 0x00FF00, nFillColor & 0x00FF00, nAlpha ) & 0x00FF00) | |
| (lclGetMixedColorComp( nPattColor & 0x0000FF, nFillColor & 0x0000FF, nAlpha ) & 0x0000FF); |
| } |
| |
| } // namespace |
| |
| // ---------------------------------------------------------------------------- |
| |
| Fill::Fill( const WorkbookHelper& rHelper, bool bDxf ) : |
| WorkbookHelper( rHelper ), |
| mbDxf( bDxf ) |
| { |
| } |
| |
| void Fill::importPatternFill( const AttributeList& rAttribs ) |
| { |
| mxPatternModel.reset( new PatternFillModel( mbDxf ) ); |
| mxPatternModel->mnPattern = rAttribs.getToken( XML_patternType, XML_none ); |
| if( mbDxf ) |
| mxPatternModel->mbPatternUsed = rAttribs.hasAttribute( XML_patternType ); |
| } |
| |
| void Fill::importFgColor( const AttributeList& rAttribs ) |
| { |
| OSL_ENSURE( mxPatternModel.get(), "Fill::importFgColor - missing pattern data" ); |
| if( mxPatternModel.get() ) |
| { |
| mxPatternModel->maPatternColor.importColor( rAttribs ); |
| mxPatternModel->mbPattColorUsed = true; |
| } |
| } |
| |
| void Fill::importBgColor( const AttributeList& rAttribs ) |
| { |
| OSL_ENSURE( mxPatternModel.get(), "Fill::importBgColor - missing pattern data" ); |
| if( mxPatternModel.get() ) |
| { |
| mxPatternModel->maFillColor.importColor( rAttribs ); |
| mxPatternModel->mbFillColorUsed = true; |
| } |
| } |
| |
| void Fill::importGradientFill( const AttributeList& rAttribs ) |
| { |
| mxGradientModel.reset( new GradientFillModel ); |
| mxGradientModel->mnType = rAttribs.getToken( XML_type, XML_linear ); |
| mxGradientModel->mfAngle = rAttribs.getDouble( XML_degree, 0.0 ); |
| mxGradientModel->mfLeft = rAttribs.getDouble( XML_left, 0.0 ); |
| mxGradientModel->mfRight = rAttribs.getDouble( XML_right, 0.0 ); |
| mxGradientModel->mfTop = rAttribs.getDouble( XML_top, 0.0 ); |
| mxGradientModel->mfBottom = rAttribs.getDouble( XML_bottom, 0.0 ); |
| } |
| |
| void Fill::importColor( const AttributeList& rAttribs, double fPosition ) |
| { |
| OSL_ENSURE( mxGradientModel.get(), "Fill::importColor - missing gradient data" ); |
| if( mxGradientModel.get() && (fPosition >= 0.0) ) |
| mxGradientModel->maColors[ fPosition ].importColor( rAttribs ); |
| } |
| |
| void Fill::importFill( SequenceInputStream& rStrm ) |
| { |
| OSL_ENSURE( !mbDxf, "Fill::importFill - unexpected conditional formatting flag" ); |
| sal_Int32 nPattern = rStrm.readInt32(); |
| if( nPattern == BIFF12_FILL_GRADIENT ) |
| { |
| mxGradientModel.reset( new GradientFillModel ); |
| sal_Int32 nStopCount; |
| rStrm.skip( 16 ); |
| mxGradientModel->readGradient( rStrm ); |
| rStrm >> nStopCount; |
| for( sal_Int32 nStop = 0; (nStop < nStopCount) && !rStrm.isEof(); ++nStop ) |
| mxGradientModel->readGradientStop( rStrm, false ); |
| } |
| else |
| { |
| mxPatternModel.reset( new PatternFillModel( mbDxf ) ); |
| mxPatternModel->setBiffPattern( nPattern ); |
| rStrm >> mxPatternModel->maPatternColor >> mxPatternModel->maFillColor; |
| } |
| } |
| |
| void Fill::importDxfPattern( SequenceInputStream& rStrm ) |
| { |
| OSL_ENSURE( mbDxf, "Fill::importDxfPattern - missing conditional formatting flag" ); |
| if( !mxPatternModel ) |
| mxPatternModel.reset( new PatternFillModel( mbDxf ) ); |
| mxPatternModel->setBiffPattern( rStrm.readuInt8() ); |
| mxPatternModel->mbPatternUsed = true; |
| } |
| |
| void Fill::importDxfFgColor( SequenceInputStream& rStrm ) |
| { |
| OSL_ENSURE( mbDxf, "Fill::importDxfFgColor - missing conditional formatting flag" ); |
| if( !mxPatternModel ) |
| mxPatternModel.reset( new PatternFillModel( mbDxf ) ); |
| mxPatternModel->maPatternColor.importColor( rStrm ); |
| mxPatternModel->mbPattColorUsed = true; |
| } |
| |
| void Fill::importDxfBgColor( SequenceInputStream& rStrm ) |
| { |
| OSL_ENSURE( mbDxf, "Fill::importDxfBgColor - missing conditional formatting flag" ); |
| if( !mxPatternModel ) |
| mxPatternModel.reset( new PatternFillModel( mbDxf ) ); |
| mxPatternModel->maFillColor.importColor( rStrm ); |
| mxPatternModel->mbFillColorUsed = true; |
| } |
| |
| void Fill::importDxfGradient( SequenceInputStream& rStrm ) |
| { |
| OSL_ENSURE( mbDxf, "Fill::importDxfGradient - missing conditional formatting flag" ); |
| if( !mxGradientModel ) |
| mxGradientModel.reset( new GradientFillModel ); |
| mxGradientModel->readGradient( rStrm ); |
| } |
| |
| void Fill::importDxfStop( SequenceInputStream& rStrm ) |
| { |
| OSL_ENSURE( mbDxf, "Fill::importDxfStop - missing conditional formatting flag" ); |
| if( !mxGradientModel ) |
| mxGradientModel.reset( new GradientFillModel ); |
| mxGradientModel->readGradientStop( rStrm, true ); |
| } |
| |
| void Fill::setBiff2Data( sal_uInt8 nFlags ) |
| { |
| OSL_ENSURE( !mbDxf, "Fill::setBiff2Data - unexpected conditional formatting flag" ); |
| mxPatternModel.reset( new PatternFillModel( mbDxf ) ); |
| mxPatternModel->setBiffData( |
| BIFF2_COLOR_BLACK, |
| BIFF2_COLOR_WHITE, |
| getFlagValue( nFlags, BIFF2_XF_BACKGROUND, BIFF_PATT_125, BIFF_PATT_NONE ) ); |
| } |
| |
| void Fill::setBiff3Data( sal_uInt16 nArea ) |
| { |
| OSL_ENSURE( !mbDxf, "Fill::setBiff3Data - unexpected conditional formatting flag" ); |
| mxPatternModel.reset( new PatternFillModel( mbDxf ) ); |
| mxPatternModel->setBiffData( |
| extractValue< sal_uInt16 >( nArea, 6, 5 ), |
| extractValue< sal_uInt16 >( nArea, 11, 5 ), |
| extractValue< sal_uInt8 >( nArea, 0, 6 ) ); |
| } |
| |
| void Fill::setBiff5Data( sal_uInt32 nArea ) |
| { |
| OSL_ENSURE( !mbDxf, "Fill::setBiff5Data - unexpected conditional formatting flag" ); |
| mxPatternModel.reset( new PatternFillModel( mbDxf ) ); |
| mxPatternModel->setBiffData( |
| extractValue< sal_uInt16 >( nArea, 0, 7 ), |
| extractValue< sal_uInt16 >( nArea, 7, 7 ), |
| extractValue< sal_uInt8 >( nArea, 16, 6 ) ); |
| } |
| |
| void Fill::setBiff8Data( sal_uInt32 nBorder2, sal_uInt16 nArea ) |
| { |
| OSL_ENSURE( !mbDxf, "Fill::setBiff8Data - unexpected conditional formatting flag" ); |
| mxPatternModel.reset( new PatternFillModel( mbDxf ) ); |
| mxPatternModel->setBiffData( |
| extractValue< sal_uInt16 >( nArea, 0, 7 ), |
| extractValue< sal_uInt16 >( nArea, 7, 7 ), |
| extractValue< sal_uInt8 >( nBorder2, 26, 6 ) ); |
| } |
| |
| void Fill::importCfRule( BiffInputStream& rStrm, sal_uInt32 nFlags ) |
| { |
| OSL_ENSURE( mbDxf, "Fill::importCfRule - missing conditional formatting flag" ); |
| OSL_ENSURE( getFlag( nFlags, BIFF_CFRULE_FILLBLOCK ), "Fill::importCfRule - missing fill block flag" ); |
| mxPatternModel.reset( new PatternFillModel( mbDxf ) ); |
| sal_uInt32 nFillData; |
| rStrm >> nFillData; |
| mxPatternModel->setBiffData( |
| extractValue< sal_uInt16 >( nFillData, 16, 7 ), |
| extractValue< sal_uInt16 >( nFillData, 23, 7 ), |
| extractValue< sal_uInt8 >( nFillData, 10, 6 ) ); |
| mxPatternModel->mbPattColorUsed = !getFlag( nFlags, BIFF_CFRULE_FILL_PATTCOLOR ); |
| mxPatternModel->mbFillColorUsed = !getFlag( nFlags, BIFF_CFRULE_FILL_FILLCOLOR ); |
| mxPatternModel->mbPatternUsed = !getFlag( nFlags, BIFF_CFRULE_FILL_PATTERN ); |
| } |
| |
| void Fill::finalizeImport() |
| { |
| const GraphicHelper& rGraphicHelper = getBaseFilter().getGraphicHelper(); |
| |
| if( mxPatternModel.get() ) |
| { |
| // finalize the OOXML data struct |
| PatternFillModel& rModel = *mxPatternModel; |
| if( mbDxf ) |
| { |
| if( rModel.mbFillColorUsed && (!rModel.mbPatternUsed || (rModel.mnPattern == XML_solid)) ) |
| { |
| rModel.maPatternColor = rModel.maFillColor; |
| rModel.mnPattern = XML_solid; |
| rModel.mbPattColorUsed = rModel.mbPatternUsed = true; |
| } |
| else if( !rModel.mbFillColorUsed && rModel.mbPatternUsed && (rModel.mnPattern == XML_solid) ) |
| { |
| rModel.mbPatternUsed = false; |
| } |
| } |
| |
| // convert to API fill settings |
| maApiData.mbUsed = rModel.mbPatternUsed; |
| if( rModel.mnPattern == XML_none ) |
| { |
| maApiData.mnColor = API_RGB_TRANSPARENT; |
| maApiData.mbTransparent = true; |
| } |
| else |
| { |
| sal_Int32 nAlpha = 0x80; |
| switch( rModel.mnPattern ) |
| { |
| case XML_darkDown: nAlpha = 0x40; break; |
| case XML_darkGray: nAlpha = 0x60; break; |
| case XML_darkGrid: nAlpha = 0x40; break; |
| case XML_darkHorizontal: nAlpha = 0x40; break; |
| case XML_darkTrellis: nAlpha = 0x60; break; |
| case XML_darkUp: nAlpha = 0x40; break; |
| case XML_darkVertical: nAlpha = 0x40; break; |
| case XML_gray0625: nAlpha = 0x08; break; |
| case XML_gray125: nAlpha = 0x10; break; |
| case XML_lightDown: nAlpha = 0x20; break; |
| case XML_lightGray: nAlpha = 0x20; break; |
| case XML_lightGrid: nAlpha = 0x38; break; |
| case XML_lightHorizontal: nAlpha = 0x20; break; |
| case XML_lightTrellis: nAlpha = 0x30; break; |
| case XML_lightUp: nAlpha = 0x20; break; |
| case XML_lightVertical: nAlpha = 0x20; break; |
| case XML_mediumGray: nAlpha = 0x40; break; |
| case XML_solid: nAlpha = 0x80; break; |
| } |
| |
| sal_Int32 nWinTextColor = rGraphicHelper.getSystemColor( XML_windowText ); |
| sal_Int32 nWinColor = rGraphicHelper.getSystemColor( XML_window ); |
| |
| if( !rModel.mbPattColorUsed ) |
| rModel.maPatternColor.setAuto(); |
| sal_Int32 nPattColor = rModel.maPatternColor.getColor( rGraphicHelper, nWinTextColor ); |
| |
| if( !rModel.mbFillColorUsed ) |
| rModel.maFillColor.setAuto(); |
| sal_Int32 nFillColor = rModel.maFillColor.getColor( rGraphicHelper, nWinColor ); |
| |
| maApiData.mnColor = lclGetMixedColor( nPattColor, nFillColor, nAlpha ); |
| maApiData.mbTransparent = false; |
| } |
| } |
| else if( mxGradientModel.get() && !mxGradientModel->maColors.empty() ) |
| { |
| GradientFillModel& rModel = *mxGradientModel; |
| maApiData.mbUsed = true; // no support for differential attributes |
| GradientFillModel::ColorMap::const_iterator aIt = rModel.maColors.begin(); |
| OSL_ENSURE( !aIt->second.isAuto(), "Fill::finalizeImport - automatic gradient color" ); |
| maApiData.mnColor = aIt->second.getColor( rGraphicHelper, API_RGB_WHITE ); |
| if( ++aIt != rModel.maColors.end() ) |
| { |
| OSL_ENSURE( !aIt->second.isAuto(), "Fill::finalizeImport - automatic gradient color" ); |
| sal_Int32 nEndColor = aIt->second.getColor( rGraphicHelper, API_RGB_WHITE ); |
| maApiData.mnColor = lclGetMixedColor( maApiData.mnColor, nEndColor, 0x40 ); |
| maApiData.mbTransparent = false; |
| } |
| } |
| } |
| |
| void Fill::writeToPropertyMap( PropertyMap& rPropMap ) const |
| { |
| if( maApiData.mbUsed ) |
| { |
| rPropMap[ PROP_CellBackColor ] <<= maApiData.mnColor; |
| rPropMap[ PROP_IsCellBackgroundTransparent ] <<= maApiData.mbTransparent; |
| } |
| } |
| |
| // ============================================================================ |
| |
| XfModel::XfModel() : |
| mnStyleXfId( -1 ), |
| mnFontId( -1 ), |
| mnNumFmtId( -1 ), |
| mnBorderId( -1 ), |
| mnFillId( -1 ), |
| mbCellXf( true ), |
| mbFontUsed( false ), |
| mbNumFmtUsed( false ), |
| mbAlignUsed( false ), |
| mbProtUsed( false ), |
| mbBorderUsed( false ), |
| mbAreaUsed( false ) |
| { |
| } |
| |
| // ============================================================================ |
| |
| Xf::Xf( const WorkbookHelper& rHelper ) : |
| WorkbookHelper( rHelper ), |
| maAlignment( rHelper ), |
| maProtection( rHelper ), |
| meRotationRef( ::com::sun::star::table::CellVertJustify_STANDARD ) |
| { |
| } |
| |
| void Xf::setAllUsedFlags( bool bUsed ) |
| { |
| maModel.mbAlignUsed = maModel.mbProtUsed = maModel.mbFontUsed = |
| maModel.mbNumFmtUsed = maModel.mbBorderUsed = maModel.mbAreaUsed = bUsed; |
| } |
| |
| void Xf::importXf( const AttributeList& rAttribs, bool bCellXf ) |
| { |
| maModel.mbCellXf = bCellXf; |
| maModel.mnStyleXfId = rAttribs.getInteger( XML_xfId, -1 ); |
| maModel.mnFontId = rAttribs.getInteger( XML_fontId, -1 ); |
| maModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, -1 ); |
| maModel.mnBorderId = rAttribs.getInteger( XML_borderId, -1 ); |
| maModel.mnFillId = rAttribs.getInteger( XML_fillId, -1 ); |
| |
| /* Default value of the apply*** attributes is dependent on context: |
| true in cellStyleXfs element, false in cellXfs element... */ |
| maModel.mbAlignUsed = rAttribs.getBool( XML_applyAlignment, !maModel.mbCellXf ); |
| maModel.mbProtUsed = rAttribs.getBool( XML_applyProtection, !maModel.mbCellXf ); |
| maModel.mbFontUsed = rAttribs.getBool( XML_applyFont, !maModel.mbCellXf ); |
| maModel.mbNumFmtUsed = rAttribs.getBool( XML_applyNumberFormat, !maModel.mbCellXf ); |
| maModel.mbBorderUsed = rAttribs.getBool( XML_applyBorder, !maModel.mbCellXf ); |
| maModel.mbAreaUsed = rAttribs.getBool( XML_applyFill, !maModel.mbCellXf ); |
| } |
| |
| void Xf::importAlignment( const AttributeList& rAttribs ) |
| { |
| maAlignment.importAlignment( rAttribs ); |
| } |
| |
| void Xf::importProtection( const AttributeList& rAttribs ) |
| { |
| maProtection.importProtection( rAttribs ); |
| } |
| |
| void Xf::importXf( SequenceInputStream& rStrm, bool bCellXf ) |
| { |
| maModel.mbCellXf = bCellXf; |
| maModel.mnStyleXfId = rStrm.readuInt16(); |
| maModel.mnNumFmtId = rStrm.readuInt16(); |
| maModel.mnFontId = rStrm.readuInt16(); |
| maModel.mnFillId = rStrm.readuInt16(); |
| maModel.mnBorderId = rStrm.readuInt16(); |
| sal_uInt32 nFlags = rStrm.readuInt32(); |
| maAlignment.setBiff12Data( nFlags ); |
| maProtection.setBiff12Data( nFlags ); |
| // used flags, see comments in Xf::setBiffUsedFlags() |
| sal_uInt16 nUsedFlags = rStrm.readuInt16(); |
| maModel.mbFontUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_FONT_USED ); |
| maModel.mbNumFmtUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_NUMFMT_USED ); |
| maModel.mbAlignUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_ALIGN_USED ); |
| maModel.mbProtUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_PROT_USED ); |
| maModel.mbBorderUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_BORDER_USED ); |
| maModel.mbAreaUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_AREA_USED ); |
| } |
| |
| void Xf::importXf( BiffInputStream& rStrm ) |
| { |
| BorderRef xBorder = getStyles().createBorder( &maModel.mnBorderId ); |
| FillRef xFill = getStyles().createFill( &maModel.mnFillId ); |
| |
| switch( getBiff() ) |
| { |
| case BIFF2: |
| { |
| sal_uInt8 nFontId, nNumFmtId, nFlags; |
| rStrm >> nFontId; |
| rStrm.skip( 1 ); |
| rStrm >> nNumFmtId >> nFlags; |
| |
| // only cell XFs in BIFF2, no parent style, used flags always true |
| setAllUsedFlags( true ); |
| |
| // attributes |
| maAlignment.setBiff2Data( nFlags ); |
| maProtection.setBiff2Data( nNumFmtId ); |
| xBorder->setBiff2Data( nFlags ); |
| xFill->setBiff2Data( nFlags ); |
| maModel.mnFontId = static_cast< sal_Int32 >( nFontId ); |
| maModel.mnNumFmtId = static_cast< sal_Int32 >( nNumFmtId & BIFF2_XF_VALFMT_MASK ); |
| } |
| break; |
| |
| case BIFF3: |
| { |
| sal_uInt32 nBorder; |
| sal_uInt16 nTypeProt, nAlign, nArea; |
| sal_uInt8 nFontId, nNumFmtId; |
| rStrm >> nFontId >> nNumFmtId >> nTypeProt >> nAlign >> nArea >> nBorder; |
| |
| // XF type/parent |
| maModel.mbCellXf = !getFlag( nTypeProt, BIFF_XF_STYLE ); // new in BIFF3 |
| maModel.mnStyleXfId = extractValue< sal_Int32 >( nAlign, 4, 12 ); // new in BIFF3 |
| // attribute used flags |
| setBiffUsedFlags( extractValue< sal_uInt8 >( nTypeProt, 10, 6 ) ); // new in BIFF3 |
| |
| // attributes |
| maAlignment.setBiff3Data( nAlign ); |
| maProtection.setBiff3Data( nTypeProt ); |
| xBorder->setBiff3Data( nBorder ); |
| xFill->setBiff3Data( nArea ); |
| maModel.mnFontId = static_cast< sal_Int32 >( nFontId ); |
| maModel.mnNumFmtId = static_cast< sal_Int32 >( nNumFmtId ); |
| } |
| break; |
| |
| case BIFF4: |
| { |
| sal_uInt32 nBorder; |
| sal_uInt16 nTypeProt, nAlign, nArea; |
| sal_uInt8 nFontId, nNumFmtId; |
| rStrm >> nFontId >> nNumFmtId >> nTypeProt >> nAlign >> nArea >> nBorder; |
| |
| // XF type/parent |
| maModel.mbCellXf = !getFlag( nTypeProt, BIFF_XF_STYLE ); |
| maModel.mnStyleXfId = extractValue< sal_Int32 >( nTypeProt, 4, 12 ); |
| // attribute used flags |
| setBiffUsedFlags( extractValue< sal_uInt8 >( nAlign, 10, 6 ) ); |
| |
| // attributes |
| maAlignment.setBiff4Data( nAlign ); |
| maProtection.setBiff3Data( nTypeProt ); |
| xBorder->setBiff3Data( nBorder ); |
| xFill->setBiff3Data( nArea ); |
| maModel.mnFontId = static_cast< sal_Int32 >( nFontId ); |
| maModel.mnNumFmtId = static_cast< sal_Int32 >( nNumFmtId ); |
| } |
| break; |
| |
| case BIFF5: |
| { |
| sal_uInt32 nArea, nBorder; |
| sal_uInt16 nFontId, nNumFmtId, nTypeProt, nAlign; |
| rStrm >> nFontId >> nNumFmtId >> nTypeProt >> nAlign >> nArea >> nBorder; |
| |
| // XF type/parent |
| maModel.mbCellXf = !getFlag( nTypeProt, BIFF_XF_STYLE ); |
| maModel.mnStyleXfId = extractValue< sal_Int32 >( nTypeProt, 4, 12 ); |
| // attribute used flags |
| setBiffUsedFlags( extractValue< sal_uInt8 >( nAlign, 10, 6 ) ); |
| |
| // attributes |
| maAlignment.setBiff5Data( nAlign ); |
| maProtection.setBiff3Data( nTypeProt ); |
| xBorder->setBiff5Data( nBorder, nArea ); |
| xFill->setBiff5Data( nArea ); |
| maModel.mnFontId = static_cast< sal_Int32 >( nFontId ); |
| maModel.mnNumFmtId = static_cast< sal_Int32 >( nNumFmtId ); |
| } |
| break; |
| |
| case BIFF8: |
| { |
| sal_uInt32 nBorder1, nBorder2; |
| sal_uInt16 nFontId, nNumFmtId, nTypeProt, nAlign, nMiscAttrib, nArea; |
| rStrm >> nFontId >> nNumFmtId >> nTypeProt >> nAlign >> nMiscAttrib >> nBorder1 >> nBorder2 >> nArea; |
| |
| // XF type/parent |
| maModel.mbCellXf = !getFlag( nTypeProt, BIFF_XF_STYLE ); |
| maModel.mnStyleXfId = extractValue< sal_Int32 >( nTypeProt, 4, 12 ); |
| // attribute used flags |
| setBiffUsedFlags( extractValue< sal_uInt8 >( nMiscAttrib, 10, 6 ) ); |
| |
| // attributes |
| maAlignment.setBiff8Data( nAlign, nMiscAttrib ); |
| maProtection.setBiff3Data( nTypeProt ); |
| xBorder->setBiff8Data( nBorder1, nBorder2 ); |
| xFill->setBiff8Data( nBorder2, nArea ); |
| maModel.mnFontId = static_cast< sal_Int32 >( nFontId ); |
| maModel.mnNumFmtId = static_cast< sal_Int32 >( nNumFmtId ); |
| } |
| break; |
| |
| case BIFF_UNKNOWN: break; |
| } |
| } |
| |
| void Xf::finalizeImport() |
| { |
| StylesBuffer& rStyles = getStyles(); |
| |
| // alignment and protection |
| maAlignment.finalizeImport(); |
| maProtection.finalizeImport(); |
| |
| /* Enables the used flags, if the formatting attributes differ from the |
| style XF. In cell XFs Excel uses the cell attributes, if they differ |
| from the parent style XF (even if the used flag is switched off). |
| #109899# ...or if the respective flag is not set in parent style XF. |
| */ |
| const Xf* pStyleXf = isCellXf() ? rStyles.getStyleXf( maModel.mnStyleXfId ).get() : 0; |
| if( pStyleXf ) |
| { |
| const XfModel& rStyleData = pStyleXf->maModel; |
| if( !maModel.mbFontUsed ) |
| maModel.mbFontUsed = !rStyleData.mbFontUsed || (maModel.mnFontId != rStyleData.mnFontId); |
| if( !maModel.mbNumFmtUsed ) |
| maModel.mbNumFmtUsed = !rStyleData.mbNumFmtUsed || (maModel.mnNumFmtId != rStyleData.mnNumFmtId); |
| if( !maModel.mbAlignUsed ) |
| maModel.mbAlignUsed = !rStyleData.mbAlignUsed || !(maAlignment.getApiData() == pStyleXf->maAlignment.getApiData()); |
| if( !maModel.mbProtUsed ) |
| maModel.mbProtUsed = !rStyleData.mbProtUsed || !(maProtection.getApiData() == pStyleXf->maProtection.getApiData()); |
| if( !maModel.mbBorderUsed ) |
| maModel.mbBorderUsed = !rStyleData.mbBorderUsed || !rStyles.equalBorders( maModel.mnBorderId, rStyleData.mnBorderId ); |
| if( !maModel.mbAreaUsed ) |
| maModel.mbAreaUsed = !rStyleData.mbAreaUsed || !rStyles.equalFills( maModel.mnFillId, rStyleData.mnFillId ); |
| } |
| |
| /* #i38709# Decide which rotation reference mode to use. If any outer |
| border line of the cell is set (either explicitly or via cell style), |
| and the cell contents are rotated, set rotation reference to bottom of |
| cell. This causes the borders to be painted rotated with the text. */ |
| if( const Alignment* pAlignment = maModel.mbAlignUsed ? &maAlignment : (pStyleXf ? &pStyleXf->maAlignment : 0) ) |
| { |
| sal_Int32 nBorderId = maModel.mbBorderUsed ? maModel.mnBorderId : (pStyleXf ? pStyleXf->maModel.mnBorderId : -1); |
| if( const Border* pBorder = rStyles.getBorder( nBorderId ).get() ) |
| if( (pAlignment->getApiData().mnRotation != 0) && pBorder->getApiData().hasAnyOuterBorder() ) |
| meRotationRef = ::com::sun::star::table::CellVertJustify_BOTTOM; |
| } |
| } |
| |
| FontRef Xf::getFont() const |
| { |
| return getStyles().getFont( maModel.mnFontId ); |
| } |
| |
| bool Xf::hasAnyUsedFlags() const |
| { |
| return |
| maModel.mbAlignUsed || maModel.mbProtUsed || maModel.mbFontUsed || |
| maModel.mbNumFmtUsed || maModel.mbBorderUsed || maModel.mbAreaUsed; |
| } |
| |
| void Xf::writeToPropertyMap( PropertyMap& rPropMap ) const |
| { |
| StylesBuffer& rStyles = getStyles(); |
| |
| // create and set cell style |
| if( isCellXf() ) |
| rPropMap[ PROP_CellStyle ] <<= rStyles.createCellStyle( maModel.mnStyleXfId ); |
| |
| if( maModel.mbFontUsed ) |
| rStyles.writeFontToPropertyMap( rPropMap, maModel.mnFontId ); |
| if( maModel.mbNumFmtUsed ) |
| rStyles.writeNumFmtToPropertyMap( rPropMap, maModel.mnNumFmtId ); |
| if( maModel.mbAlignUsed ) |
| maAlignment.writeToPropertyMap( rPropMap ); |
| if( maModel.mbProtUsed ) |
| maProtection.writeToPropertyMap( rPropMap ); |
| if( maModel.mbBorderUsed ) |
| rStyles.writeBorderToPropertyMap( rPropMap, maModel.mnBorderId ); |
| if( maModel.mbAreaUsed ) |
| rStyles.writeFillToPropertyMap( rPropMap, maModel.mnFillId ); |
| if( maModel.mbAlignUsed || maModel.mbBorderUsed ) |
| rPropMap[ PROP_RotateReference ] <<= meRotationRef; |
| } |
| |
| void Xf::writeToPropertySet( PropertySet& rPropSet ) const |
| { |
| PropertyMap aPropMap; |
| writeToPropertyMap( aPropMap ); |
| rPropSet.setProperties( aPropMap ); |
| } |
| |
| /*static*/ void Xf::writeBiff2CellFormatToPropertySet( const WorkbookHelper& rHelper, |
| PropertySet& rPropSet, sal_uInt8 nFlags1, sal_uInt8 nFlags2, sal_uInt8 nFlags3 ) |
| { |
| /* Create an XF object and let it do the work. We will have access to its |
| private members here. Also, create temporary border and fill objects, |
| this prevents polluting the border and fill buffers with new temporary |
| objects per imported cell. */ |
| Xf aXf( rHelper ); |
| Border aBorder( rHelper, false ); |
| Fill aFill( rHelper, false ); |
| |
| // no used flags available in BIFF2 (always true) |
| aXf.setAllUsedFlags( true ); |
| |
| // set the attributes |
| aXf.maModel.mnFontId = extractValue< sal_Int32 >( nFlags2, 6, 2 ); |
| aXf.maModel.mnNumFmtId = extractValue< sal_Int32 >( nFlags2, 0, 6 ); |
| aXf.maAlignment.setBiff2Data( nFlags3 ); |
| aXf.maProtection.setBiff2Data( nFlags1 ); |
| aBorder.setBiff2Data( nFlags3 ); |
| aFill.setBiff2Data( nFlags3 ); |
| |
| // finalize the objects (convert model to API attributes) |
| aXf.finalizeImport(); |
| aBorder.finalizeImport(); |
| aFill.finalizeImport(); |
| |
| // write the properties to the property set |
| PropertyMap aPropMap; |
| aXf.writeToPropertyMap( aPropMap ); |
| aBorder.writeToPropertyMap( aPropMap ); |
| aFill.writeToPropertyMap( aPropMap ); |
| rPropSet.setProperties( aPropMap ); |
| } |
| |
| void Xf::setBiffUsedFlags( sal_uInt8 nUsedFlags ) |
| { |
| /* Notes about finding the used flags: |
| - In cell XFs a *set* bit means a used attribute. |
| - In style XFs a *cleared* bit means a used attribute. |
| The boolean flags always store true, if the attribute is used. |
| The "isCellXf() == getFlag(...)" construct evaluates to true in both |
| mentioned cases: cell XF and set bit; or style XF and cleared bit. |
| */ |
| maModel.mbFontUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_FONT_USED ); |
| maModel.mbNumFmtUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_NUMFMT_USED ); |
| maModel.mbAlignUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_ALIGN_USED ); |
| maModel.mbProtUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_PROT_USED ); |
| maModel.mbBorderUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_BORDER_USED ); |
| maModel.mbAreaUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_AREA_USED ); |
| } |
| |
| // ============================================================================ |
| |
| Dxf::Dxf( const WorkbookHelper& rHelper ) : |
| WorkbookHelper( rHelper ) |
| { |
| } |
| |
| FontRef Dxf::createFont( bool bAlwaysNew ) |
| { |
| if( bAlwaysNew || !mxFont ) |
| mxFont.reset( new Font( *this, true ) ); |
| return mxFont; |
| } |
| |
| BorderRef Dxf::createBorder( bool bAlwaysNew ) |
| { |
| if( bAlwaysNew || !mxBorder ) |
| mxBorder.reset( new Border( *this, true ) ); |
| return mxBorder; |
| } |
| |
| FillRef Dxf::createFill( bool bAlwaysNew ) |
| { |
| if( bAlwaysNew || !mxFill ) |
| mxFill.reset( new Fill( *this, true ) ); |
| return mxFill; |
| } |
| |
| void Dxf::importNumFmt( const AttributeList& rAttribs ) |
| { |
| mxNumFmt = getStyles().importNumFmt( rAttribs ); |
| } |
| |
| void Dxf::importAlignment( const AttributeList& rAttribs ) |
| { |
| mxAlignment.reset( new Alignment( *this ) ); |
| mxAlignment->importAlignment( rAttribs ); |
| } |
| |
| void Dxf::importProtection( const AttributeList& rAttribs ) |
| { |
| mxProtection.reset( new Protection( *this ) ); |
| mxProtection->importProtection( rAttribs ); |
| } |
| |
| void Dxf::importDxf( SequenceInputStream& rStrm ) |
| { |
| sal_Int32 nNumFmtId = -1; |
| OUString aFmtCode; |
| sal_uInt16 nRecCount; |
| rStrm.skip( 4 ); // flags |
| rStrm >> nRecCount; |
| for( sal_uInt16 nRec = 0; !rStrm.isEof() && (nRec < nRecCount); ++nRec ) |
| { |
| sal_uInt16 nSubRecId, nSubRecSize; |
| sal_Int64 nRecEnd = rStrm.tell(); |
| rStrm >> nSubRecId >> nSubRecSize; |
| nRecEnd += nSubRecSize; |
| switch( nSubRecId ) |
| { |
| case BIFF12_DXF_FILL_PATTERN: createFill( false )->importDxfPattern( rStrm ); break; |
| case BIFF12_DXF_FILL_FGCOLOR: createFill( false )->importDxfFgColor( rStrm ); break; |
| case BIFF12_DXF_FILL_BGCOLOR: createFill( false )->importDxfBgColor( rStrm ); break; |
| case BIFF12_DXF_FILL_GRADIENT: createFill( false )->importDxfGradient( rStrm ); break; |
| case BIFF12_DXF_FILL_STOP: createFill( false )->importDxfStop( rStrm ); break; |
| case BIFF12_DXF_FONT_COLOR: createFont( false )->importDxfColor( rStrm ); break; |
| case BIFF12_DXF_BORDER_TOP: createBorder( false )->importDxfBorder( XLS_TOKEN( top ), rStrm ); break; |
| case BIFF12_DXF_BORDER_BOTTOM: createBorder( false )->importDxfBorder( XLS_TOKEN( bottom ), rStrm ); break; |
| case BIFF12_DXF_BORDER_LEFT: createBorder( false )->importDxfBorder( XLS_TOKEN( left ), rStrm ); break; |
| case BIFF12_DXF_BORDER_RIGHT: createBorder( false )->importDxfBorder( XLS_TOKEN( right ), rStrm ); break; |
| case BIFF12_DXF_FONT_NAME: createFont( false )->importDxfName( rStrm ); break; |
| case BIFF12_DXF_FONT_WEIGHT: createFont( false )->importDxfWeight( rStrm ); break; |
| case BIFF12_DXF_FONT_UNDERLINE: createFont( false )->importDxfUnderline( rStrm ); break; |
| case BIFF12_DXF_FONT_ESCAPEMENT: createFont( false )->importDxfEscapement( rStrm ); break; |
| case BIFF12_DXF_FONT_ITALIC: createFont( false )->importDxfFlag( XML_i, rStrm ); break; |
| case BIFF12_DXF_FONT_STRIKE: createFont( false )->importDxfFlag( XML_strike, rStrm ); break; |
| case BIFF12_DXF_FONT_OUTLINE: createFont( false )->importDxfFlag( XML_outline, rStrm ); break; |
| case BIFF12_DXF_FONT_SHADOW: createFont( false )->importDxfFlag( XML_shadow, rStrm ); break; |
| case BIFF12_DXF_FONT_HEIGHT: createFont( false )->importDxfHeight( rStrm ); break; |
| case BIFF12_DXF_FONT_SCHEME: createFont( false )->importDxfScheme( rStrm ); break; |
| case BIFF12_DXF_NUMFMT_CODE: aFmtCode = BiffHelper::readString( rStrm, false ); break; |
| case BIFF12_DXF_NUMFMT_ID: nNumFmtId = rStrm.readuInt16(); break; |
| } |
| rStrm.seek( nRecEnd ); |
| } |
| OSL_ENSURE( !rStrm.isEof() && (rStrm.getRemaining() == 0), "Dxf::importDxf - unexpected remaining data" ); |
| mxNumFmt = getStyles().createNumFmt( nNumFmtId, aFmtCode ); |
| } |
| |
| void Dxf::importCfRule( BiffInputStream& rStrm, sal_uInt32 nFlags ) |
| { |
| if( getFlag( nFlags, BIFF_CFRULE_FONTBLOCK ) ) |
| createFont()->importCfRule( rStrm ); |
| if( getFlag( nFlags, BIFF_CFRULE_ALIGNBLOCK ) ) |
| rStrm.skip( 8 ); |
| if( getFlag( nFlags, BIFF_CFRULE_BORDERBLOCK ) ) |
| createBorder()->importCfRule( rStrm, nFlags ); |
| if( getFlag( nFlags, BIFF_CFRULE_FILLBLOCK ) ) |
| createFill()->importCfRule( rStrm, nFlags ); |
| if( getFlag( nFlags, BIFF_CFRULE_PROTBLOCK ) ) |
| rStrm.skip( 2 ); |
| } |
| |
| void Dxf::finalizeImport() |
| { |
| if( mxFont.get() ) |
| mxFont->finalizeImport(); |
| // number format already finalized by the number formats buffer |
| if( mxAlignment.get() ) |
| mxAlignment->finalizeImport(); |
| if( mxProtection.get() ) |
| mxProtection->finalizeImport(); |
| if( mxBorder.get() ) |
| mxBorder->finalizeImport(); |
| if( mxFill.get() ) |
| mxFill->finalizeImport(); |
| } |
| |
| void Dxf::writeToPropertyMap( PropertyMap& rPropMap ) const |
| { |
| if( mxFont.get() ) |
| mxFont->writeToPropertyMap( rPropMap, FONT_PROPTYPE_CELL ); |
| if( mxNumFmt.get() ) |
| mxNumFmt->writeToPropertyMap( rPropMap ); |
| if( mxAlignment.get() ) |
| mxAlignment->writeToPropertyMap( rPropMap ); |
| if( mxProtection.get() ) |
| mxProtection->writeToPropertyMap( rPropMap ); |
| if( mxBorder.get() ) |
| mxBorder->writeToPropertyMap( rPropMap ); |
| if( mxFill.get() ) |
| mxFill->writeToPropertyMap( rPropMap ); |
| } |
| |
| void Dxf::writeToPropertySet( PropertySet& rPropSet ) const |
| { |
| PropertyMap aPropMap; |
| writeToPropertyMap( aPropMap ); |
| rPropSet.setProperties( aPropMap ); |
| } |
| |
| // ============================================================================ |
| |
| namespace { |
| |
| const sal_Char* const spcLegacyStyleNamePrefix = "Excel_BuiltIn_"; |
| const sal_Char* const sppcLegacyStyleNames[] = |
| { |
| "Normal", |
| "RowLevel_", // outline level will be appended |
| "ColumnLevel_", // outline level will be appended |
| "Comma", |
| "Currency", |
| "Percent", |
| "Comma_0", // new in BIFF4 |
| "Currency_0", |
| "Hyperlink", // new in BIFF8 |
| "Followed_Hyperlink" |
| }; |
| const sal_Int32 snLegacyStyleNamesCount = static_cast< sal_Int32 >( STATIC_ARRAY_SIZE( sppcLegacyStyleNames ) ); |
| |
| const sal_Char* const spcStyleNamePrefix = "Excel Built-in "; |
| const sal_Char* const sppcStyleNames[] = |
| { |
| "Normal", |
| "RowLevel_", // outline level will be appended |
| "ColLevel_", // outline level will be appended |
| "Comma", |
| "Currency", |
| "Percent", |
| "Comma [0]", // new in BIFF4 |
| "Currency [0]", |
| "Hyperlink", // new in BIFF8 |
| "Followed Hyperlink", |
| "Note", // new in OOX |
| "Warning Text", |
| 0, |
| 0, |
| 0, |
| "Title", |
| "Heading 1", |
| "Heading 2", |
| "Heading 3", |
| "Heading 4", |
| "Input", |
| "Output", |
| "Calculation", |
| "Check Cell", |
| "Linked Cell", |
| "Total", |
| "Good", |
| "Bad", |
| "Neutral", |
| "Accent1", |
| "20% - Accent1", |
| "40% - Accent1", |
| "60% - Accent1", |
| "Accent2", |
| "20% - Accent2", |
| "40% - Accent2", |
| "60% - Accent2", |
| "Accent3", |
| "20% - Accent3", |
| "40% - Accent3", |
| "60% - Accent3", |
| "Accent4", |
| "20% - Accent4", |
| "40% - Accent4", |
| "60% - Accent4", |
| "Accent5", |
| "20% - Accent5", |
| "40% - Accent5", |
| "60% - Accent5", |
| "Accent6", |
| "20% - Accent6", |
| "40% - Accent6", |
| "60% - Accent6", |
| "Explanatory Text" |
| }; |
| const sal_Int32 snStyleNamesCount = static_cast< sal_Int32 >( STATIC_ARRAY_SIZE( sppcStyleNames ) ); |
| |
| OUString lclGetBuiltinStyleName( sal_Int32 nBuiltinId, const OUString& rName, sal_Int32 nLevel = 0 ) |
| { |
| OSL_ENSURE( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount), "lclGetBuiltinStyleName - unknown built-in style" ); |
| OUStringBuffer aStyleName; |
| aStyleName.appendAscii( spcStyleNamePrefix ); |
| if( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount) && (sppcStyleNames[ nBuiltinId ] != 0) ) |
| aStyleName.appendAscii( sppcStyleNames[ nBuiltinId ] ); |
| else if( rName.getLength() > 0 ) |
| aStyleName.append( rName ); |
| else |
| aStyleName.append( nBuiltinId ); |
| if( (nBuiltinId == OOX_STYLE_ROWLEVEL) || (nBuiltinId == OOX_STYLE_COLLEVEL) ) |
| aStyleName.append( nLevel ); |
| return aStyleName.makeStringAndClear(); |
| } |
| |
| OUString lclCreateStyleName( const CellStyleModel& rModel ) |
| { |
| return rModel.mbBuiltin ? lclGetBuiltinStyleName( rModel.mnBuiltinId, rModel.maName, rModel.mnLevel ) : rModel.maName; |
| } |
| |
| bool lclIsBuiltinStyleName( const OUString& rStyleName, sal_Int32* pnBuiltinId, sal_Int32* pnNextChar ) |
| { |
| // try the other built-in styles |
| OUString aPrefix = OUString::createFromAscii( spcStyleNamePrefix ); |
| sal_Int32 nPrefixLen = aPrefix.getLength(); |
| sal_Int32 nFoundId = 0; |
| sal_Int32 nNextChar = 0; |
| if( rStyleName.matchIgnoreAsciiCase( aPrefix ) ) |
| { |
| OUString aShortName; |
| for( sal_Int32 nId = 0; nId < snStyleNamesCount; ++nId ) |
| { |
| if( sppcStyleNames[ nId ] != 0 ) |
| { |
| aShortName = OUString::createFromAscii( sppcStyleNames[ nId ] ); |
| if( rStyleName.matchIgnoreAsciiCase( aShortName, nPrefixLen ) && |
| (nNextChar < nPrefixLen + aShortName.getLength()) ) |
| { |
| nFoundId = nId; |
| nNextChar = nPrefixLen + aShortName.getLength(); |
| } |
| } |
| } |
| } |
| |
| if( nNextChar > 0 ) |
| { |
| if( pnBuiltinId ) *pnBuiltinId = nFoundId; |
| if( pnNextChar ) *pnNextChar = nNextChar; |
| return true; |
| } |
| |
| if( pnBuiltinId ) *pnBuiltinId = -1; |
| if( pnNextChar ) *pnNextChar = 0; |
| return false; |
| } |
| |
| bool lclGetBuiltinStyleId( sal_Int32& rnBuiltinId, sal_Int32& rnLevel, const OUString& rStyleName ) |
| { |
| sal_Int32 nBuiltinId; |
| sal_Int32 nNextChar; |
| if( lclIsBuiltinStyleName( rStyleName, &nBuiltinId, &nNextChar ) ) |
| { |
| if( (nBuiltinId == OOX_STYLE_ROWLEVEL) || (nBuiltinId == OOX_STYLE_COLLEVEL) ) |
| { |
| OUString aLevel = rStyleName.copy( nNextChar ); |
| sal_Int32 nLevel = aLevel.toInt32(); |
| if( (0 < nLevel) && (nLevel <= OOX_STYLE_LEVELCOUNT) ) |
| { |
| rnBuiltinId = nBuiltinId; |
| rnLevel = nLevel; |
| return true; |
| } |
| } |
| else if( rStyleName.getLength() == nNextChar ) |
| { |
| rnBuiltinId = nBuiltinId; |
| rnLevel = 0; |
| return true; |
| } |
| } |
| rnBuiltinId = -1; |
| rnLevel = 0; |
| return false; |
| } |
| |
| } // namespace |
| |
| // ---------------------------------------------------------------------------- |
| |
| CellStyleModel::CellStyleModel() : |
| mnXfId( -1 ), |
| mnBuiltinId( -1 ), |
| mnLevel( 0 ), |
| mbBuiltin( false ), |
| mbCustom( false ), |
| mbHidden( false ) |
| { |
| } |
| |
| bool CellStyleModel::isBuiltin() const |
| { |
| return mbBuiltin && (mnBuiltinId >= 0); |
| } |
| |
| bool CellStyleModel::isDefaultStyle() const |
| { |
| return mbBuiltin && (mnBuiltinId == OOX_STYLE_NORMAL); |
| } |
| |
| // ============================================================================ |
| |
| CellStyle::CellStyle( const WorkbookHelper& rHelper ) : |
| WorkbookHelper( rHelper ), |
| mbCreated( false ) |
| { |
| } |
| |
| void CellStyle::importCellStyle( const AttributeList& rAttribs ) |
| { |
| maModel.maName = rAttribs.getXString( XML_name, OUString() ); |
| maModel.mnXfId = rAttribs.getInteger( XML_xfId, -1 ); |
| maModel.mnBuiltinId = rAttribs.getInteger( XML_builtinId, -1 ); |
| maModel.mnLevel = rAttribs.getInteger( XML_iLevel, 0 ); |
| maModel.mbBuiltin = rAttribs.hasAttribute( XML_builtinId ); |
| maModel.mbCustom = rAttribs.getBool( XML_customBuiltin, false ); |
| maModel.mbHidden = rAttribs.getBool( XML_hidden, false ); |
| } |
| |
| void CellStyle::importCellStyle( SequenceInputStream& rStrm ) |
| { |
| sal_uInt16 nFlags; |
| rStrm >> maModel.mnXfId >> nFlags; |
| maModel.mnBuiltinId = rStrm.readInt8(); |
| maModel.mnLevel = rStrm.readInt8(); |
| rStrm >> maModel.maName; |
| maModel.mbBuiltin = getFlag( nFlags, BIFF12_CELLSTYLE_BUILTIN ); |
| maModel.mbCustom = getFlag( nFlags, BIFF12_CELLSTYLE_CUSTOM ); |
| maModel.mbHidden = getFlag( nFlags, BIFF12_CELLSTYLE_HIDDEN ); |
| } |
| |
| void CellStyle::importStyle( BiffInputStream& rStrm ) |
| { |
| sal_uInt16 nStyleXf; |
| rStrm >> nStyleXf; |
| maModel.mnXfId = static_cast< sal_Int32 >( nStyleXf & BIFF_STYLE_XFMASK ); |
| maModel.mbBuiltin = getFlag( nStyleXf, BIFF_STYLE_BUILTIN ); |
| if( maModel.mbBuiltin ) |
| { |
| maModel.mnBuiltinId = rStrm.readInt8(); |
| maModel.mnLevel = rStrm.readInt8(); |
| } |
| else |
| { |
| maModel.maName = (getBiff() == BIFF8) ? |
| rStrm.readUniString() : rStrm.readByteStringUC( false, getTextEncoding() ); |
| // #i103281# check if this is a new built-in style introduced in XL2007 |
| if( (getBiff() == BIFF8) && (rStrm.getNextRecId() == BIFF_ID_STYLEEXT) && rStrm.startNextRecord() ) |
| { |
| sal_uInt8 nExtFlags; |
| rStrm.skip( 12 ); |
| rStrm >> nExtFlags; |
| maModel.mbBuiltin = getFlag( nExtFlags, BIFF_STYLEEXT_BUILTIN ); |
| maModel.mbCustom = getFlag( nExtFlags, BIFF_STYLEEXT_CUSTOM ); |
| maModel.mbHidden = getFlag( nExtFlags, BIFF_STYLEEXT_HIDDEN ); |
| if( maModel.mbBuiltin ) |
| { |
| maModel.mnBuiltinId = rStrm.readInt8(); |
| maModel.mnLevel = rStrm.readInt8(); |
| } |
| } |
| } |
| } |
| |
| void CellStyle::createCellStyle() |
| { |
| // #i1624# #i1768# ignore unnamed user styles |
| if( !mbCreated ) |
| mbCreated = maFinalName.getLength() == 0; |
| |
| /* #i103281# do not create another style of the same name, if it exists |
| already. This is needed to prevent that styles pasted from clipboard |
| get duplicated over and over. */ |
| if( !mbCreated ) try |
| { |
| Reference< XNameAccess > xCellStylesNA( getStyleFamily( false ), UNO_QUERY_THROW ); |
| mbCreated = xCellStylesNA->hasByName( maFinalName ); |
| } |
| catch( Exception& ) |
| { |
| } |
| |
| // create the style object in the document |
| if( !mbCreated ) try |
| { |
| mbCreated = true; |
| Reference< XStyle > xStyle( createStyleObject( maFinalName, false ), UNO_SET_THROW ); |
| // write style formatting properties |
| PropertySet aPropSet( xStyle ); |
| getStyles().writeStyleXfToPropertySet( aPropSet, maModel.mnXfId ); |
| if( !maModel.isDefaultStyle() ) |
| xStyle->setParentStyle( getStyles().getDefaultStyleName() ); |
| } |
| catch( Exception& ) |
| { |
| } |
| } |
| |
| void CellStyle::finalizeImport( const OUString& rFinalName ) |
| { |
| maFinalName = rFinalName; |
| if( !maModel.isBuiltin() || maModel.mbCustom ) |
| createCellStyle(); |
| } |
| |
| // ============================================================================ |
| |
| CellStyleBuffer::CellStyleBuffer( const WorkbookHelper& rHelper ) : |
| WorkbookHelper( rHelper ) |
| { |
| } |
| |
| CellStyleRef CellStyleBuffer::importCellStyle( const AttributeList& rAttribs ) |
| { |
| CellStyleRef xCellStyle( new CellStyle( *this ) ); |
| xCellStyle->importCellStyle( rAttribs ); |
| insertCellStyle( xCellStyle ); |
| return xCellStyle; |
| } |
| |
| CellStyleRef CellStyleBuffer::importCellStyle( SequenceInputStream& rStrm ) |
| { |
| CellStyleRef xCellStyle( new CellStyle( *this ) ); |
| xCellStyle->importCellStyle( rStrm ); |
| insertCellStyle( xCellStyle ); |
| return xCellStyle; |
| } |
| |
| CellStyleRef CellStyleBuffer::importStyle( BiffInputStream& rStrm ) |
| { |
| CellStyleRef xCellStyle( new CellStyle( *this ) ); |
| xCellStyle->importStyle( rStrm ); |
| insertCellStyle( xCellStyle ); |
| return xCellStyle; |
| } |
| |
| void CellStyleBuffer::finalizeImport() |
| { |
| // calculate final names of all styles |
| typedef RefMap< OUString, CellStyle, IgnoreCaseCompare > CellStyleNameMap; |
| CellStyleNameMap aCellStyles; |
| CellStyleVector aConflictNameStyles; |
| |
| /* First, reserve style names that are built-in in Calc. This causes that |
| imported cell styles get different unused names and thus do not try to |
| overwrite these built-in styles. For BIFF4 workbooks (which contain a |
| separate list of cell styles per sheet), reserve all existing styles if |
| current sheet is not the first sheet (this styles buffer will be |
| constructed again for every new sheet). This will create unique names |
| for styles in different sheets with the same name. Assuming that the |
| BIFF4W import filter is never used to import from clipboard... */ |
| bool bReserveAll = (getFilterType() == FILTER_BIFF) && (getBiff() == BIFF4) && isWorkbookFile() && (getCurrentSheetIndex() > 0); |
| try |
| { |
| // unfortunately, com.sun.star.style.StyleFamily does not implement XEnumerationAccess... |
| Reference< XIndexAccess > xStyleFamilyIA( getStyleFamily( false ), UNO_QUERY_THROW ); |
| for( sal_Int32 nIndex = 0, nCount = xStyleFamilyIA->getCount(); nIndex < nCount; ++nIndex ) |
| { |
| Reference< XStyle > xStyle( xStyleFamilyIA->getByIndex( nIndex ), UNO_QUERY_THROW ); |
| if( bReserveAll || !xStyle->isUserDefined() ) |
| { |
| Reference< XNamed > xStyleName( xStyle, UNO_QUERY_THROW ); |
| // create an empty entry by using ::std::map<>::operator[] |
| aCellStyles[ xStyleName->getName() ]; |
| } |
| } |
| } |
| catch( Exception& ) |
| { |
| } |
| |
| /* Calculate names of built-in styles. Store styles with reserved names |
| in the aConflictNameStyles list. */ |
| for( CellStyleVector::iterator aIt = maBuiltinStyles.begin(), aEnd = maBuiltinStyles.end(); aIt != aEnd; ++aIt ) |
| { |
| const CellStyleModel& rModel = (*aIt)->getModel(); |
| OUString aStyleName = lclCreateStyleName( rModel ); |
| /* If a builtin style entry already exists, and we do not reserve all |
| existing styles, we just stick with the last definition and ignore |
| the preceding ones. */ |
| if( bReserveAll && (aCellStyles.count( aStyleName ) > 0) ) |
| aConflictNameStyles.push_back( *aIt ); |
| else |
| aCellStyles[ aStyleName ] = *aIt; |
| } |
| |
| /* Calculate names of user defined styles. Store styles with reserved |
| names in the aConflictNameStyles list. */ |
| for( CellStyleVector::iterator aIt = maUserStyles.begin(), aEnd = maUserStyles.end(); aIt != aEnd; ++aIt ) |
| { |
| const CellStyleModel& rModel = (*aIt)->getModel(); |
| OUString aStyleName = lclCreateStyleName( rModel ); |
| // #i1624# #i1768# ignore unnamed user styles |
| if( aStyleName.getLength() > 0 ) |
| { |
| if( aCellStyles.count( aStyleName ) > 0 ) |
| aConflictNameStyles.push_back( *aIt ); |
| else |
| aCellStyles[ aStyleName ] = *aIt; |
| } |
| } |
| |
| // find unused names for all styles with conflicting names |
| for( CellStyleVector::iterator aIt = aConflictNameStyles.begin(), aEnd = aConflictNameStyles.end(); aIt != aEnd; ++aIt ) |
| { |
| const CellStyleModel& rModel = (*aIt)->getModel(); |
| OUString aStyleName = lclCreateStyleName( rModel ); |
| OUString aUnusedName; |
| sal_Int32 nIndex = 0; |
| do |
| { |
| aUnusedName = OUStringBuffer( aStyleName ).append( sal_Unicode( ' ' ) ).append( ++nIndex ).makeStringAndClear(); |
| } |
| while( aCellStyles.count( aUnusedName ) > 0 ); |
| aCellStyles[ aUnusedName ] = *aIt; |
| } |
| |
| // set final names and create user-defined and modified built-in cell styles |
| aCellStyles.forEachMemWithKey( &CellStyle::finalizeImport ); |
| } |
| |
| sal_Int32 CellStyleBuffer::getDefaultXfId() const |
| { |
| return mxDefStyle.get() ? mxDefStyle->getModel().mnXfId : -1; |
| } |
| |
| OUString CellStyleBuffer::getDefaultStyleName() const |
| { |
| return createCellStyle( mxDefStyle ); |
| } |
| |
| OUString CellStyleBuffer::createCellStyle( sal_Int32 nXfId ) const |
| { |
| return createCellStyle( maStylesByXf.get( nXfId ) ); |
| } |
| |
| // private -------------------------------------------------------------------- |
| |
| void CellStyleBuffer::insertCellStyle( CellStyleRef xCellStyle ) |
| { |
| const CellStyleModel& rModel = xCellStyle->getModel(); |
| if( rModel.mnXfId >= 0 ) |
| { |
| // insert into the built-in map or user defined map |
| (rModel.isBuiltin() ? maBuiltinStyles : maUserStyles).push_back( xCellStyle ); |
| |
| // insert into the XF identifier map |
| OSL_ENSURE( maStylesByXf.count( rModel.mnXfId ) == 0, "CellStyleBuffer::insertCellStyle - multiple styles with equal XF identifier" ); |
| maStylesByXf[ rModel.mnXfId ] = xCellStyle; |
| |
| // remember default cell style |
| if( rModel.isDefaultStyle() ) |
| mxDefStyle = xCellStyle; |
| } |
| } |
| |
| OUString CellStyleBuffer::createCellStyle( const CellStyleRef& rxCellStyle ) const |
| { |
| if( rxCellStyle.get() ) |
| { |
| rxCellStyle->createCellStyle(); |
| const OUString& rStyleName = rxCellStyle->getFinalStyleName(); |
| if( rStyleName.getLength() > 0 ) |
| return rStyleName; |
| } |
| // on error: fallback to default style |
| return lclGetBuiltinStyleName( OOX_STYLE_NORMAL, OUString() ); |
| } |
| |
| // ============================================================================ |
| |
| AutoFormatModel::AutoFormatModel() : |
| mnAutoFormatId( 0 ), |
| mbApplyNumFmt( false ), |
| mbApplyFont( false ), |
| mbApplyAlignment( false ), |
| mbApplyBorder( false ), |
| mbApplyFill( false ), |
| mbApplyProtection( false ) |
| { |
| } |
| |
| // ============================================================================ |
| |
| StylesBuffer::StylesBuffer( const WorkbookHelper& rHelper ) : |
| WorkbookHelper( rHelper ), |
| maPalette( rHelper ), |
| maNumFmts( rHelper ), |
| maCellStyles( rHelper ) |
| { |
| } |
| |
| FontRef StylesBuffer::createFont( sal_Int32* opnFontId ) |
| { |
| if( opnFontId ) *opnFontId = static_cast< sal_Int32 >( maFonts.size() ); |
| FontRef xFont( new Font( *this, false ) ); |
| maFonts.push_back( xFont ); |
| return xFont; |
| } |
| |
| NumberFormatRef StylesBuffer::createNumFmt( sal_Int32 nNumFmtId, const OUString& rFmtCode ) |
| { |
| return maNumFmts.createNumFmt( nNumFmtId, rFmtCode ); |
| } |
| |
| BorderRef StylesBuffer::createBorder( sal_Int32* opnBorderId ) |
| { |
| if( opnBorderId ) *opnBorderId = static_cast< sal_Int32 >( maBorders.size() ); |
| BorderRef xBorder( new Border( *this, false ) ); |
| maBorders.push_back( xBorder ); |
| return xBorder; |
| } |
| |
| FillRef StylesBuffer::createFill( sal_Int32* opnFillId ) |
| { |
| if( opnFillId ) *opnFillId = static_cast< sal_Int32 >( maFills.size() ); |
| FillRef xFill( new Fill( *this, false ) ); |
| maFills.push_back( xFill ); |
| return xFill; |
| } |
| |
| XfRef StylesBuffer::createCellXf( sal_Int32* opnXfId ) |
| { |
| if( opnXfId ) *opnXfId = static_cast< sal_Int32 >( maCellXfs.size() ); |
| XfRef xXf( new Xf( *this ) ); |
| maCellXfs.push_back( xXf ); |
| return xXf; |
| } |
| |
| XfRef StylesBuffer::createStyleXf( sal_Int32* opnXfId ) |
| { |
| if( opnXfId ) *opnXfId = static_cast< sal_Int32 >( maStyleXfs.size() ); |
| XfRef xXf( new Xf( *this ) ); |
| maStyleXfs.push_back( xXf ); |
| return xXf; |
| } |
| |
| DxfRef StylesBuffer::createDxf( sal_Int32* opnDxfId ) |
| { |
| if( opnDxfId ) *opnDxfId = static_cast< sal_Int32 >( maDxfs.size() ); |
| DxfRef xDxf( new Dxf( *this ) ); |
| maDxfs.push_back( xDxf ); |
| return xDxf; |
| } |
| |
| void StylesBuffer::importPaletteColor( const AttributeList& rAttribs ) |
| { |
| maPalette.importPaletteColor( rAttribs ); |
| } |
| |
| NumberFormatRef StylesBuffer::importNumFmt( const AttributeList& rAttribs ) |
| { |
| return maNumFmts.importNumFmt( rAttribs ); |
| } |
| |
| CellStyleRef StylesBuffer::importCellStyle( const AttributeList& rAttribs ) |
| { |
| return maCellStyles.importCellStyle( rAttribs ); |
| } |
| |
| void StylesBuffer::importPaletteColor( SequenceInputStream& rStrm ) |
| { |
| maPalette.importPaletteColor( rStrm ); |
| } |
| |
| void StylesBuffer::importNumFmt( SequenceInputStream& rStrm ) |
| { |
| maNumFmts.importNumFmt( rStrm ); |
| } |
| |
| void StylesBuffer::importCellStyle( SequenceInputStream& rStrm ) |
| { |
| maCellStyles.importCellStyle( rStrm ); |
| } |
| |
| void StylesBuffer::importPalette( BiffInputStream& rStrm ) |
| { |
| maPalette.importPalette( rStrm ); |
| } |
| |
| void StylesBuffer::importFont( BiffInputStream& rStrm ) |
| { |
| /* Font with index 4 is not stored in BIFF. This means effectively, first |
| font in the BIFF file has index 0, fourth font has index 3, and fifth |
| font has index 5. Insert a dummy font to correctly map passed font |
| identifiers. */ |
| if( maFonts.size() == 4 ) |
| maFonts.push_back( maFonts.front() ); |
| |
| FontRef xFont = createFont(); |
| xFont->importFont( rStrm ); |
| |
| /* #i71033# Set stream text encoding from application font, if CODEPAGE |
| record is missing. Must be done now (not while finalizeImport() runs), |
| to be able to read all following byte strings correctly (e.g. cell |
| style names). */ |
| if( maFonts.size() == 1 ) |
| setAppFontEncoding( xFont->getFontEncoding() ); |
| } |
| |
| void StylesBuffer::importFontColor( BiffInputStream& rStrm ) |
| { |
| if( !maFonts.empty() ) |
| maFonts.back()->importFontColor( rStrm ); |
| } |
| |
| void StylesBuffer::importFormat( BiffInputStream& rStrm ) |
| { |
| maNumFmts.importFormat( rStrm ); |
| } |
| |
| void StylesBuffer::importXf( BiffInputStream& rStrm ) |
| { |
| XfRef xXf( new Xf( *this ) ); |
| xXf->importXf( rStrm ); |
| |
| XfRef xCellXf, xStyleXf; |
| (xXf->isCellXf() ? xCellXf : xStyleXf) = xXf; |
| maCellXfs.push_back( xCellXf ); |
| maStyleXfs.push_back( xStyleXf ); |
| } |
| |
| void StylesBuffer::importStyle( BiffInputStream& rStrm ) |
| { |
| maCellStyles.importStyle( rStrm ); |
| } |
| |
| void StylesBuffer::importPalette( const Any& rPalette ) |
| { |
| maPalette.importPalette( rPalette ); |
| } |
| |
| void StylesBuffer::finalizeImport() |
| { |
| // fonts first, are needed to finalize unit converter and XFs below |
| maFonts.forEachMem( &Font::finalizeImport ); |
| // finalize unit coefficients after default font is known |
| getUnitConverter().finalizeImport(); |
| // number formats |
| maNumFmts.finalizeImport(); |
| // borders and fills |
| maBorders.forEachMem( &Border::finalizeImport ); |
| maFills.forEachMem( &Fill::finalizeImport ); |
| // style XFs and cell XFs |
| maStyleXfs.forEachMem( &Xf::finalizeImport ); |
| maCellXfs.forEachMem( &Xf::finalizeImport ); |
| // built-in and user defined cell styles |
| maCellStyles.finalizeImport(); |
| // differential formatting (for conditional formatting) |
| maDxfs.forEachMem( &Dxf::finalizeImport ); |
| } |
| |
| sal_Int32 StylesBuffer::getPaletteColor( sal_Int32 nPaletteIdx ) const |
| { |
| return maPalette.getColor( nPaletteIdx ); |
| } |
| |
| FontRef StylesBuffer::getFont( sal_Int32 nFontId ) const |
| { |
| return maFonts.get( nFontId ); |
| } |
| |
| BorderRef StylesBuffer::getBorder( sal_Int32 nBorderId ) const |
| { |
| return maBorders.get( nBorderId ); |
| } |
| |
| XfRef StylesBuffer::getCellXf( sal_Int32 nXfId ) const |
| { |
| return maCellXfs.get( nXfId ); |
| } |
| |
| XfRef StylesBuffer::getStyleXf( sal_Int32 nXfId ) const |
| { |
| return maStyleXfs.get( nXfId ); |
| } |
| |
| DxfRef StylesBuffer::getDxf( sal_Int32 nDxfId ) const |
| { |
| return maDxfs.get( nDxfId ); |
| } |
| |
| FontRef StylesBuffer::getFontFromCellXf( sal_Int32 nXfId ) const |
| { |
| FontRef xFont; |
| if( const Xf* pXf = getCellXf( nXfId ).get() ) |
| xFont = pXf->getFont(); |
| return xFont; |
| } |
| |
| FontRef StylesBuffer::getDefaultFont() const |
| { |
| FontRef xDefFont; |
| if( const Xf* pXf = getStyleXf( maCellStyles.getDefaultXfId() ).get() ) |
| xDefFont = pXf->getFont(); |
| // no font from styles - try first loaded font (e.g. BIFF2) |
| if( !xDefFont ) |
| xDefFont = maFonts.get( 0 ); |
| OSL_ENSURE( xDefFont.get(), "StylesBuffer::getDefaultFont - no default font found" ); |
| return xDefFont; |
| } |
| |
| const FontModel& StylesBuffer::getDefaultFontModel() const |
| { |
| FontRef xDefFont = getDefaultFont(); |
| return xDefFont.get() ? xDefFont->getModel() : getTheme().getDefaultFontModel(); |
| } |
| |
| bool StylesBuffer::equalBorders( sal_Int32 nBorderId1, sal_Int32 nBorderId2 ) const |
| { |
| if( nBorderId1 == nBorderId2 ) |
| return true; |
| |
| switch( getFilterType() ) |
| { |
| case FILTER_OOXML: |
| // in OOXML, borders are assumed to be unique |
| return false; |
| |
| case FILTER_BIFF: |
| { |
| // in BIFF, a new border entry has been created for every XF |
| const Border* pBorder1 = maBorders.get( nBorderId1 ).get(); |
| const Border* pBorder2 = maBorders.get( nBorderId2 ).get(); |
| return pBorder1 && pBorder2 && (pBorder1->getApiData() == pBorder2->getApiData()); |
| } |
| |
| case FILTER_UNKNOWN: |
| break; |
| } |
| return false; |
| } |
| |
| bool StylesBuffer::equalFills( sal_Int32 nFillId1, sal_Int32 nFillId2 ) const |
| { |
| if( nFillId1 == nFillId2 ) |
| return true; |
| |
| switch( getFilterType() ) |
| { |
| case FILTER_OOXML: |
| // in OOXML, fills are assumed to be unique |
| return false; |
| |
| case FILTER_BIFF: |
| { |
| // in BIFF, a new fill entry has been created for every XF |
| const Fill* pFill1 = maFills.get( nFillId1 ).get(); |
| const Fill* pFill2 = maFills.get( nFillId2 ).get(); |
| return pFill1 && pFill2 && (pFill1->getApiData() == pFill2->getApiData()); |
| } |
| |
| case FILTER_UNKNOWN: |
| break; |
| } |
| return false; |
| } |
| |
| OUString StylesBuffer::getDefaultStyleName() const |
| { |
| return maCellStyles.getDefaultStyleName(); |
| } |
| |
| OUString StylesBuffer::createCellStyle( sal_Int32 nXfId ) const |
| { |
| return maCellStyles.createCellStyle( nXfId ); |
| } |
| |
| OUString StylesBuffer::createDxfStyle( sal_Int32 nDxfId ) const |
| { |
| OUString& rStyleName = maDxfStyles[ nDxfId ]; |
| if( rStyleName.getLength() == 0 ) |
| { |
| if( Dxf* pDxf = maDxfs.get( nDxfId ).get() ) |
| { |
| rStyleName = OUStringBuffer( CREATE_OUSTRING( "ConditionalStyle_" ) ).append( nDxfId + 1 ).makeStringAndClear(); |
| // create the style sheet (this may change rStyleName if such a style already exists) |
| Reference< XStyle > xStyle = createStyleObject( rStyleName, false ); |
| // write style formatting properties |
| PropertySet aPropSet( xStyle ); |
| pDxf->writeToPropertySet( aPropSet ); |
| } |
| // on error: fallback to default style |
| if( rStyleName.getLength() == 0 ) |
| rStyleName = maCellStyles.getDefaultStyleName(); |
| } |
| return rStyleName; |
| } |
| |
| void StylesBuffer::writeFontToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFontId ) const |
| { |
| if( Font* pFont = maFonts.get( nFontId ).get() ) |
| pFont->writeToPropertyMap( rPropMap, FONT_PROPTYPE_CELL ); |
| } |
| |
| void StylesBuffer::writeNumFmtToPropertyMap( PropertyMap& rPropMap, sal_Int32 nNumFmtId ) const |
| { |
| maNumFmts.writeToPropertyMap( rPropMap, nNumFmtId ); |
| } |
| |
| void StylesBuffer::writeBorderToPropertyMap( PropertyMap& rPropMap, sal_Int32 nBorderId ) const |
| { |
| if( Border* pBorder = maBorders.get( nBorderId ).get() ) |
| pBorder->writeToPropertyMap( rPropMap ); |
| } |
| |
| void StylesBuffer::writeFillToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFillId ) const |
| { |
| if( Fill* pFill = maFills.get( nFillId ).get() ) |
| pFill->writeToPropertyMap( rPropMap ); |
| } |
| |
| void StylesBuffer::writeCellXfToPropertyMap( PropertyMap& rPropMap, sal_Int32 nXfId ) const |
| { |
| if( Xf* pXf = maCellXfs.get( nXfId ).get() ) |
| pXf->writeToPropertyMap( rPropMap ); |
| } |
| |
| void StylesBuffer::writeStyleXfToPropertyMap( PropertyMap& rPropMap, sal_Int32 nXfId ) const |
| { |
| if( Xf* pXf = maStyleXfs.get( nXfId ).get() ) |
| pXf->writeToPropertyMap( rPropMap ); |
| } |
| |
| void StylesBuffer::writeCellXfToPropertySet( PropertySet& rPropSet, sal_Int32 nXfId ) const |
| { |
| if( Xf* pXf = maCellXfs.get( nXfId ).get() ) |
| pXf->writeToPropertySet( rPropSet ); |
| } |
| |
| void StylesBuffer::writeStyleXfToPropertySet( PropertySet& rPropSet, sal_Int32 nXfId ) const |
| { |
| if( Xf* pXf = maStyleXfs.get( nXfId ).get() ) |
| pXf->writeToPropertySet( rPropSet ); |
| } |
| |
| // ============================================================================ |
| |
| } // namespace xls |
| } // namespace oox |