1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "oox/xls/stylesbuffer.hxx" 29 30 #include <com/sun/star/awt/FontDescriptor.hpp> 31 #include <com/sun/star/awt/FontFamily.hpp> 32 #include <com/sun/star/awt/FontPitch.hpp> 33 #include <com/sun/star/awt/FontSlant.hpp> 34 #include <com/sun/star/awt/FontStrikeout.hpp> 35 #include <com/sun/star/awt/FontType.hpp> 36 #include <com/sun/star/awt/FontWeight.hpp> 37 #include <com/sun/star/awt/FontUnderline.hpp> 38 #include <com/sun/star/awt/XDevice.hpp> 39 #include <com/sun/star/awt/XFont2.hpp> 40 #include <com/sun/star/container/XIndexAccess.hpp> 41 #include <com/sun/star/container/XNameAccess.hpp> 42 #include <com/sun/star/style/XStyle.hpp> 43 #include <com/sun/star/text/WritingMode2.hpp> 44 #include <com/sun/star/text/XText.hpp> 45 #include <rtl/tencinfo.h> 46 #include <rtl/ustrbuf.hxx> 47 #include "oox/core/filterbase.hxx" 48 #include "oox/helper/attributelist.hxx" 49 #include "oox/helper/containerhelper.hxx" 50 #include "oox/helper/propertymap.hxx" 51 #include "oox/helper/propertyset.hxx" 52 #include "oox/xls/biffinputstream.hxx" 53 #include "oox/xls/condformatbuffer.hxx" 54 #include "oox/xls/excelhandlers.hxx" 55 #include "oox/xls/themebuffer.hxx" 56 #include "oox/xls/unitconverter.hxx" 57 58 namespace oox { 59 namespace xls { 60 61 // ============================================================================ 62 63 using namespace ::com::sun::star::awt; 64 using namespace ::com::sun::star::container; 65 using namespace ::com::sun::star::style; 66 using namespace ::com::sun::star::table; 67 using namespace ::com::sun::star::text; 68 using namespace ::com::sun::star::uno; 69 70 using ::oox::core::FilterBase; 71 using ::rtl::OUString; 72 using ::rtl::OUStringBuffer; 73 74 // ============================================================================ 75 76 namespace { 77 78 // OOXML constants ------------------------------------------------------------ 79 80 // OOXML predefined color indexes (also used in BIFF3-BIFF8) 81 const sal_Int32 OOX_COLOR_USEROFFSET = 0; /// First user defined color in palette (OOXML/BIFF12). 82 const sal_Int32 BIFF_COLOR_USEROFFSET = 8; /// First user defined color in palette (BIFF3-BIFF8). 83 84 // OOXML font family (also used in BIFF) 85 const sal_Int32 OOX_FONTFAMILY_NONE = 0; 86 const sal_Int32 OOX_FONTFAMILY_ROMAN = 1; 87 const sal_Int32 OOX_FONTFAMILY_SWISS = 2; 88 const sal_Int32 OOX_FONTFAMILY_MODERN = 3; 89 const sal_Int32 OOX_FONTFAMILY_SCRIPT = 4; 90 const sal_Int32 OOX_FONTFAMILY_DECORATIVE = 5; 91 92 // OOXML cell text direction (also used in BIFF) 93 const sal_Int32 OOX_XF_TEXTDIR_CONTEXT = 0; 94 const sal_Int32 OOX_XF_TEXTDIR_LTR = 1; 95 const sal_Int32 OOX_XF_TEXTDIR_RTL = 2; 96 97 // OOXML cell rotation (also used in BIFF) 98 const sal_Int32 OOX_XF_ROTATION_NONE = 0; 99 const sal_Int32 OOX_XF_ROTATION_90CCW = 90; 100 const sal_Int32 OOX_XF_ROTATION_90CW = 180; 101 const sal_Int32 OOX_XF_ROTATION_STACKED = 255; 102 103 // OOXML cell indentation 104 const sal_Int32 OOX_XF_INDENT_NONE = 0; 105 106 // OOXML built-in cell styles (also used in BIFF) 107 const sal_Int32 OOX_STYLE_NORMAL = 0; /// Default cell style. 108 const sal_Int32 OOX_STYLE_ROWLEVEL = 1; /// RowLevel_x cell style. 109 const sal_Int32 OOX_STYLE_COLLEVEL = 2; /// ColLevel_x cell style. 110 111 const sal_Int32 OOX_STYLE_LEVELCOUNT = 7; /// Number of outline level styles. 112 113 // BIFF12 constants ----------------------------------------------------------- 114 115 // BIFF12 color types 116 const sal_uInt8 BIFF12_COLOR_AUTO = 0; 117 const sal_uInt8 BIFF12_COLOR_INDEXED = 1; 118 const sal_uInt8 BIFF12_COLOR_RGB = 2; 119 const sal_uInt8 BIFF12_COLOR_THEME = 3; 120 121 // BIFF12 diagonal borders 122 const sal_uInt8 BIFF12_BORDER_DIAG_TLBR = 0x01; /// Top-left to bottom-right. 123 const sal_uInt8 BIFF12_BORDER_DIAG_BLTR = 0x02; /// Bottom-left to top-right. 124 125 // BIFF12 gradient fill 126 const sal_Int32 BIFF12_FILL_GRADIENT = 40; 127 128 // BIFF12 XF flags 129 const sal_uInt32 BIFF12_XF_WRAPTEXT = 0x00400000; 130 const sal_uInt32 BIFF12_XF_JUSTLASTLINE = 0x00800000; 131 const sal_uInt32 BIFF12_XF_SHRINK = 0x01000000; 132 const sal_uInt32 BIFF12_XF_LOCKED = 0x10000000; 133 const sal_uInt32 BIFF12_XF_HIDDEN = 0x20000000; 134 135 // BIFF12 XF attribute used flags 136 const sal_uInt16 BIFF12_XF_NUMFMT_USED = 0x0001; 137 const sal_uInt16 BIFF12_XF_FONT_USED = 0x0002; 138 const sal_uInt16 BIFF12_XF_ALIGN_USED = 0x0004; 139 const sal_uInt16 BIFF12_XF_BORDER_USED = 0x0008; 140 const sal_uInt16 BIFF12_XF_AREA_USED = 0x0010; 141 const sal_uInt16 BIFF12_XF_PROT_USED = 0x0020; 142 143 // BIFF12 DXF constants 144 const sal_uInt16 BIFF12_DXF_FILL_PATTERN = 0; 145 const sal_uInt16 BIFF12_DXF_FILL_FGCOLOR = 1; 146 const sal_uInt16 BIFF12_DXF_FILL_BGCOLOR = 2; 147 const sal_uInt16 BIFF12_DXF_FILL_GRADIENT = 3; 148 const sal_uInt16 BIFF12_DXF_FILL_STOP = 4; 149 const sal_uInt16 BIFF12_DXF_FONT_COLOR = 5; 150 const sal_uInt16 BIFF12_DXF_BORDER_TOP = 6; 151 const sal_uInt16 BIFF12_DXF_BORDER_BOTTOM = 7; 152 const sal_uInt16 BIFF12_DXF_BORDER_LEFT = 8; 153 const sal_uInt16 BIFF12_DXF_BORDER_RIGHT = 9; 154 const sal_uInt16 BIFF12_DXF_BORDER_DIAG = 10; 155 const sal_uInt16 BIFF12_DXF_BORDER_VERT = 11; 156 const sal_uInt16 BIFF12_DXF_BORDER_HOR = 12; 157 const sal_uInt16 BIFF12_DXF_BORDER_DIAGUP = 13; 158 const sal_uInt16 BIFF12_DXF_BORDER_DIAGDOWN = 14; 159 const sal_uInt16 BIFF12_DXF_FONT_NAME = 24; 160 const sal_uInt16 BIFF12_DXF_FONT_WEIGHT = 25; 161 const sal_uInt16 BIFF12_DXF_FONT_UNDERLINE = 26; 162 const sal_uInt16 BIFF12_DXF_FONT_ESCAPEMENT = 27; 163 const sal_uInt16 BIFF12_DXF_FONT_ITALIC = 28; 164 const sal_uInt16 BIFF12_DXF_FONT_STRIKE = 29; 165 const sal_uInt16 BIFF12_DXF_FONT_OUTLINE = 30; 166 const sal_uInt16 BIFF12_DXF_FONT_SHADOW = 31; 167 const sal_uInt16 BIFF12_DXF_FONT_CONDENSE = 32; 168 const sal_uInt16 BIFF12_DXF_FONT_EXTEND = 33; 169 const sal_uInt16 BIFF12_DXF_FONT_CHARSET = 34; 170 const sal_uInt16 BIFF12_DXF_FONT_FAMILY = 35; 171 const sal_uInt16 BIFF12_DXF_FONT_HEIGHT = 36; 172 const sal_uInt16 BIFF12_DXF_FONT_SCHEME = 37; 173 const sal_uInt16 BIFF12_DXF_NUMFMT_CODE = 38; 174 const sal_uInt16 BIFF12_DXF_NUMFMT_ID = 41; 175 176 // BIFF12 CELLSTYLE flags 177 const sal_uInt16 BIFF12_CELLSTYLE_BUILTIN = 0x0001; 178 const sal_uInt16 BIFF12_CELLSTYLE_HIDDEN = 0x0002; 179 const sal_uInt16 BIFF12_CELLSTYLE_CUSTOM = 0x0004; 180 181 // BIFF constants ------------------------------------------------------------- 182 183 // BIFF predefined color indexes 184 const sal_uInt16 BIFF2_COLOR_BLACK = 0; /// Black (text) in BIFF2. 185 const sal_uInt16 BIFF2_COLOR_WHITE = 1; /// White (background) in BIFF2. 186 187 // BIFF font flags, also used in BIFF12 188 const sal_uInt16 BIFF_FONTFLAG_BOLD = 0x0001; 189 const sal_uInt16 BIFF_FONTFLAG_ITALIC = 0x0002; 190 const sal_uInt16 BIFF_FONTFLAG_UNDERLINE = 0x0004; 191 const sal_uInt16 BIFF_FONTFLAG_STRIKEOUT = 0x0008; 192 const sal_uInt16 BIFF_FONTFLAG_OUTLINE = 0x0010; 193 const sal_uInt16 BIFF_FONTFLAG_SHADOW = 0x0020; 194 const sal_uInt16 BIFF_FONTFLAG_CONDENSE = 0x0040; 195 196 // BIFF font weight 197 const sal_uInt16 BIFF_FONTWEIGHT_BOLD = 450; 198 199 // BIFF font underline, also used in BIFF12 200 const sal_uInt8 BIFF_FONTUNDERL_NONE = 0; 201 const sal_uInt8 BIFF_FONTUNDERL_SINGLE = 1; 202 const sal_uInt8 BIFF_FONTUNDERL_DOUBLE = 2; 203 const sal_uInt8 BIFF_FONTUNDERL_SINGLE_ACC = 33; 204 const sal_uInt8 BIFF_FONTUNDERL_DOUBLE_ACC = 34; 205 206 // BIFF XF flags 207 const sal_uInt16 BIFF_XF_LOCKED = 0x0001; 208 const sal_uInt16 BIFF_XF_HIDDEN = 0x0002; 209 const sal_uInt16 BIFF_XF_STYLE = 0x0004; 210 const sal_uInt16 BIFF_XF_STYLEPARENT = 0x0FFF; /// Syles don't have a parent. 211 const sal_uInt16 BIFF_XF_WRAPTEXT = 0x0008; /// Automatic line break. 212 const sal_uInt16 BIFF_XF_JUSTLASTLINE = 0x0080; 213 const sal_uInt16 BIFF_XF_SHRINK = 0x0010; /// Shrink to fit into cell. 214 const sal_uInt16 BIFF_XF_MERGE = 0x0020; 215 216 // BIFF XF attribute used flags 217 const sal_uInt8 BIFF_XF_NUMFMT_USED = 0x01; 218 const sal_uInt8 BIFF_XF_FONT_USED = 0x02; 219 const sal_uInt8 BIFF_XF_ALIGN_USED = 0x04; 220 const sal_uInt8 BIFF_XF_BORDER_USED = 0x08; 221 const sal_uInt8 BIFF_XF_AREA_USED = 0x10; 222 const sal_uInt8 BIFF_XF_PROT_USED = 0x20; 223 224 // BIFF XF text orientation 225 const sal_uInt8 BIFF_XF_ORIENT_NONE = 0; 226 const sal_uInt8 BIFF_XF_ORIENT_STACKED = 1; /// Stacked top to bottom. 227 const sal_uInt8 BIFF_XF_ORIENT_90CCW = 2; /// 90 degr. counterclockwise. 228 const sal_uInt8 BIFF_XF_ORIENT_90CW = 3; /// 90 degr. clockwise. 229 230 // BIFF XF line styles 231 const sal_uInt8 BIFF_LINE_NONE = 0; 232 const sal_uInt8 BIFF_LINE_THIN = 1; 233 234 // BIFF XF patterns 235 const sal_uInt8 BIFF_PATT_NONE = 0; 236 const sal_uInt8 BIFF_PATT_125 = 17; 237 238 // BIFF2 XF flags 239 const sal_uInt8 BIFF2_XF_VALFMT_MASK = 0x3F; 240 const sal_uInt8 BIFF2_XF_LOCKED = 0x40; 241 const sal_uInt8 BIFF2_XF_HIDDEN = 0x80; 242 const sal_uInt8 BIFF2_XF_LEFTLINE = 0x08; 243 const sal_uInt8 BIFF2_XF_RIGHTLINE = 0x10; 244 const sal_uInt8 BIFF2_XF_TOPLINE = 0x20; 245 const sal_uInt8 BIFF2_XF_BOTTOMLINE = 0x40; 246 const sal_uInt8 BIFF2_XF_BACKGROUND = 0x80; 247 248 // BIFF8 diagonal borders 249 const sal_uInt32 BIFF_XF_DIAG_TLBR = 0x40000000; /// Top-left to bottom-right. 250 const sal_uInt32 BIFF_XF_DIAG_BLTR = 0x80000000; /// Bottom-left to top-right. 251 252 // BIFF STYLE flags 253 const sal_uInt16 BIFF_STYLE_BUILTIN = 0x8000; 254 const sal_uInt16 BIFF_STYLE_XFMASK = 0x0FFF; 255 256 // BIFF STYLEEXT flags 257 const sal_uInt8 BIFF_STYLEEXT_BUILTIN = 0x01; 258 const sal_uInt8 BIFF_STYLEEXT_HIDDEN = 0x02; 259 const sal_uInt8 BIFF_STYLEEXT_CUSTOM = 0x04; 260 261 // BIFF conditional formatting 262 const sal_uInt32 BIFF_CFRULE_BORDER_LEFT = 0x00000400; 263 const sal_uInt32 BIFF_CFRULE_BORDER_RIGHT = 0x00000800; 264 const sal_uInt32 BIFF_CFRULE_BORDER_TOP = 0x00001000; 265 const sal_uInt32 BIFF_CFRULE_BORDER_BOTTOM = 0x00002000; 266 const sal_uInt32 BIFF_CFRULE_FILL_PATTERN = 0x00010000; 267 const sal_uInt32 BIFF_CFRULE_FILL_PATTCOLOR = 0x00020000; 268 const sal_uInt32 BIFF_CFRULE_FILL_FILLCOLOR = 0x00040000; 269 const sal_uInt32 BIFF_CFRULE_FONTBLOCK = 0x04000000; 270 const sal_uInt32 BIFF_CFRULE_ALIGNBLOCK = 0x08000000; 271 const sal_uInt32 BIFF_CFRULE_BORDERBLOCK = 0x10000000; 272 const sal_uInt32 BIFF_CFRULE_FILLBLOCK = 0x20000000; 273 const sal_uInt32 BIFF_CFRULE_PROTBLOCK = 0x40000000; 274 275 const sal_uInt32 BIFF_CFRULE_FONT_STYLE = 0x00000002; /// Font posture or weight modified? 276 const sal_uInt32 BIFF_CFRULE_FONT_OUTLINE = 0x00000008; /// Font outline modified? 277 const sal_uInt32 BIFF_CFRULE_FONT_SHADOW = 0x00000010; /// Font shadow modified? 278 const sal_uInt32 BIFF_CFRULE_FONT_STRIKEOUT = 0x00000080; /// Font cancellation modified? 279 const sal_uInt32 BIFF_CFRULE_FONT_UNDERL = 0x00000001; /// Font underline type modified? 280 const sal_uInt32 BIFF_CFRULE_FONT_ESCAPEM = 0x00000001; /// Font escapement type modified? 281 282 // ---------------------------------------------------------------------------- 283 284 sal_Int32 lclReadRgbColor( BinaryInputStream& rStrm ) 285 { 286 sal_uInt8 nR, nG, nB, nA; 287 rStrm >> nR >> nG >> nB >> nA; 288 sal_Int32 nValue = nA; 289 nValue <<= 8; 290 nValue |= nR; 291 nValue <<= 8; 292 nValue |= nG; 293 nValue <<= 8; 294 nValue |= nB; 295 return nValue; 296 } 297 298 } // namespace 299 300 // ============================================================================ 301 302 ExcelGraphicHelper::ExcelGraphicHelper( const WorkbookHelper& rHelper ) : 303 GraphicHelper( rHelper.getBaseFilter().getComponentContext(), rHelper.getBaseFilter().getTargetFrame(), rHelper.getBaseFilter().getStorage() ), 304 WorkbookHelper( rHelper ) 305 { 306 } 307 308 sal_Int32 ExcelGraphicHelper::getSchemeColor( sal_Int32 nToken ) const 309 { 310 if( getFilterType() == FILTER_OOXML ) 311 return getTheme().getColorByToken( nToken ); 312 return GraphicHelper::getSchemeColor( nToken ); 313 } 314 315 sal_Int32 ExcelGraphicHelper::getPaletteColor( sal_Int32 nPaletteIdx ) const 316 { 317 return getStyles().getPaletteColor( nPaletteIdx ); 318 } 319 320 // ============================================================================ 321 322 void Color::setAuto() 323 { 324 clearTransformations(); 325 setSchemeClr( XML_phClr ); 326 } 327 328 void Color::setRgb( sal_Int32 nRgbValue, double fTint ) 329 { 330 clearTransformations(); 331 setSrgbClr( nRgbValue & 0xFFFFFF ); 332 if( fTint != 0.0 ) addExcelTintTransformation( fTint ); 333 } 334 335 void Color::setTheme( sal_Int32 nThemeIdx, double fTint ) 336 { 337 clearTransformations(); 338 static const sal_Int32 spnColorTokens[] = { 339 XML_lt1, XML_dk1, XML_lt2, XML_dk2, XML_accent1, XML_accent2, 340 XML_accent3, XML_accent4, XML_accent5, XML_accent6, XML_hlink, XML_folHlink }; 341 setSchemeClr( STATIC_ARRAY_SELECT( spnColorTokens, nThemeIdx, XML_TOKEN_INVALID ) ); 342 if( fTint != 0.0 ) addExcelTintTransformation( fTint ); 343 } 344 345 void Color::setIndexed( sal_Int32 nPaletteIdx, double fTint ) 346 { 347 clearTransformations(); 348 setPaletteClr( nPaletteIdx ); 349 if( fTint != 0.0 ) addExcelTintTransformation( fTint ); 350 } 351 352 void Color::importColor( const AttributeList& rAttribs ) 353 { 354 if( rAttribs.getBool( XML_auto, false ) ) 355 setAuto(); 356 else if( rAttribs.hasAttribute( XML_rgb ) ) 357 setRgb( rAttribs.getIntegerHex( XML_rgb, API_RGB_TRANSPARENT ), rAttribs.getDouble( XML_tint, 0.0 ) ); 358 else if( rAttribs.hasAttribute( XML_theme ) ) 359 setTheme( rAttribs.getInteger( XML_theme, -1 ), rAttribs.getDouble( XML_tint, 0.0 ) ); 360 else if( rAttribs.hasAttribute( XML_indexed ) ) 361 setIndexed( rAttribs.getInteger( XML_indexed, -1 ), rAttribs.getDouble( XML_tint, 0.0 ) ); 362 else 363 { 364 OSL_ENSURE( false, "Color::importColor - unknown color type" ); 365 setAuto(); 366 } 367 } 368 369 void Color::importColor( SequenceInputStream& rStrm ) 370 { 371 sal_uInt8 nFlags, nIndex; 372 sal_Int16 nTint; 373 rStrm >> nFlags >> nIndex >> nTint; 374 375 // scale tint from signed 16-bit to double range -1.0 ... 1.0 376 double fTint = nTint; 377 if( nTint < 0 ) 378 fTint /= -SAL_MIN_INT16; 379 else if( nTint > 0 ) 380 fTint /= SAL_MAX_INT16; 381 382 switch( extractValue< sal_uInt8 >( nFlags, 1, 7 ) ) 383 { 384 case BIFF12_COLOR_AUTO: 385 setAuto(); 386 rStrm.skip( 4 ); 387 break; 388 case BIFF12_COLOR_INDEXED: 389 setIndexed( nIndex, fTint ); 390 rStrm.skip( 4 ); 391 break; 392 case BIFF12_COLOR_RGB: 393 setRgb( lclReadRgbColor( rStrm ), fTint ); 394 break; 395 case BIFF12_COLOR_THEME: 396 setTheme( nIndex, fTint ); 397 rStrm.skip( 4 ); 398 break; 399 default: 400 OSL_ENSURE( false, "Color::importColor - unknown color type" ); 401 setAuto(); 402 rStrm.skip( 4 ); 403 } 404 } 405 406 void Color::importColorId( SequenceInputStream& rStrm ) 407 { 408 setIndexed( rStrm.readInt32() ); 409 } 410 411 void Color::importColorRgb( SequenceInputStream& rStrm ) 412 { 413 setRgb( lclReadRgbColor( rStrm ) ); 414 } 415 416 void Color::importColorId( BiffInputStream& rStrm, bool b16Bit ) 417 { 418 setIndexed( b16Bit ? rStrm.readuInt16() : rStrm.readuInt8() ); 419 } 420 421 void Color::importColorRgb( BiffInputStream& rStrm ) 422 { 423 setRgb( lclReadRgbColor( rStrm ) ); 424 } 425 426 SequenceInputStream& operator>>( SequenceInputStream& rStrm, Color& orColor ) 427 { 428 orColor.importColor( rStrm ); 429 return rStrm; 430 } 431 432 // ============================================================================ 433 434 namespace { 435 436 /** Standard EGA colors, bright. */ 437 #define PALETTE_EGA_COLORS_LIGHT \ 438 0x000000, 0xFFFFFF, 0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF 439 /** Standard EGA colors, dark. */ 440 #define PALETTE_EGA_COLORS_DARK \ 441 0x800000, 0x008000, 0x000080, 0x808000, 0x800080, 0x008080, 0xC0C0C0, 0x808080 442 443 /** Default color table for BIFF2. */ 444 static const sal_Int32 spnDefColors2[] = 445 { 446 /* 0 */ PALETTE_EGA_COLORS_LIGHT 447 }; 448 449 /** Default color table for BIFF3/BIFF4. */ 450 static const sal_Int32 spnDefColors3[] = 451 { 452 /* 0 */ PALETTE_EGA_COLORS_LIGHT, 453 /* 8 */ PALETTE_EGA_COLORS_LIGHT, 454 /* 16 */ PALETTE_EGA_COLORS_DARK 455 }; 456 457 /** Default color table for BIFF5. */ 458 static const sal_Int32 spnDefColors5[] = 459 { 460 /* 0 */ PALETTE_EGA_COLORS_LIGHT, 461 /* 8 */ PALETTE_EGA_COLORS_LIGHT, 462 /* 16 */ PALETTE_EGA_COLORS_DARK, 463 /* 24 */ 0x8080FF, 0x802060, 0xFFFFC0, 0xA0E0E0, 0x600080, 0xFF8080, 0x0080C0, 0xC0C0FF, 464 /* 32 */ 0x000080, 0xFF00FF, 0xFFFF00, 0x00FFFF, 0x800080, 0x800000, 0x008080, 0x0000FF, 465 /* 40 */ 0x00CFFF, 0x69FFFF, 0xE0FFE0, 0xFFFF80, 0xA6CAF0, 0xDD9CB3, 0xB38FEE, 0xE3E3E3, 466 /* 48 */ 0x2A6FF9, 0x3FB8CD, 0x488436, 0x958C41, 0x8E5E42, 0xA0627A, 0x624FAC, 0x969696, 467 /* 56 */ 0x1D2FBE, 0x286676, 0x004500, 0x453E01, 0x6A2813, 0x85396A, 0x4A3285, 0x424242 468 }; 469 470 /** Default color table for BIFF8/BIFF12/OOXML. */ 471 static const sal_Int32 spnDefColors8[] = 472 { 473 /* 0 */ PALETTE_EGA_COLORS_LIGHT, 474 /* 8 */ PALETTE_EGA_COLORS_LIGHT, 475 /* 16 */ PALETTE_EGA_COLORS_DARK, 476 /* 24 */ 0x9999FF, 0x993366, 0xFFFFCC, 0xCCFFFF, 0x660066, 0xFF8080, 0x0066CC, 0xCCCCFF, 477 /* 32 */ 0x000080, 0xFF00FF, 0xFFFF00, 0x00FFFF, 0x800080, 0x800000, 0x008080, 0x0000FF, 478 /* 40 */ 0x00CCFF, 0xCCFFFF, 0xCCFFCC, 0xFFFF99, 0x99CCFF, 0xFF99CC, 0xCC99FF, 0xFFCC99, 479 /* 48 */ 0x3366FF, 0x33CCCC, 0x99CC00, 0xFFCC00, 0xFF9900, 0xFF6600, 0x666699, 0x969696, 480 /* 56 */ 0x003366, 0x339966, 0x003300, 0x333300, 0x993300, 0x993366, 0x333399, 0x333333 481 }; 482 483 #undef PALETTE_EGA_COLORS_LIGHT 484 #undef PALETTE_EGA_COLORS_DARK 485 486 } // namespace 487 488 // ---------------------------------------------------------------------------- 489 490 ColorPalette::ColorPalette( const WorkbookHelper& rHelper ) : 491 WorkbookHelper( rHelper ) 492 { 493 // default colors 494 switch( getFilterType() ) 495 { 496 case FILTER_OOXML: 497 maColors.insert( maColors.begin(), spnDefColors8, STATIC_ARRAY_END( spnDefColors8 ) ); 498 mnAppendIndex = OOX_COLOR_USEROFFSET; 499 break; 500 case FILTER_BIFF: 501 switch( getBiff() ) 502 { 503 case BIFF2: maColors.insert( maColors.begin(), spnDefColors2, STATIC_ARRAY_END( spnDefColors2 ) ); break; 504 case BIFF3: 505 case BIFF4: maColors.insert( maColors.begin(), spnDefColors3, STATIC_ARRAY_END( spnDefColors3 ) ); break; 506 case BIFF5: maColors.insert( maColors.begin(), spnDefColors5, STATIC_ARRAY_END( spnDefColors5 ) ); break; 507 case BIFF8: maColors.insert( maColors.begin(), spnDefColors8, STATIC_ARRAY_END( spnDefColors8 ) ); break; 508 case BIFF_UNKNOWN: break; 509 } 510 mnAppendIndex = BIFF_COLOR_USEROFFSET; 511 break; 512 case FILTER_UNKNOWN: break; 513 } 514 } 515 516 void ColorPalette::importPaletteColor( const AttributeList& rAttribs ) 517 { 518 appendColor( rAttribs.getIntegerHex( XML_rgb, API_RGB_WHITE ) ); 519 } 520 521 void ColorPalette::importPaletteColor( SequenceInputStream& rStrm ) 522 { 523 sal_Int32 nRgb = lclReadRgbColor( rStrm ); 524 appendColor( nRgb & 0xFFFFFF ); 525 } 526 527 void ColorPalette::importPalette( BiffInputStream& rStrm ) 528 { 529 sal_uInt16 nCount; 530 rStrm >> nCount; 531 OSL_ENSURE( rStrm.getRemaining() == 4 * nCount, "ColorPalette::importPalette - wrong palette size" ); 532 533 // fill palette from BIFF_COLOR_USEROFFSET 534 mnAppendIndex = BIFF_COLOR_USEROFFSET; 535 for( sal_uInt16 nIndex = 0; !rStrm.isEof() && (nIndex < nCount); ++nIndex ) 536 { 537 sal_Int32 nRgb = lclReadRgbColor( rStrm ); 538 appendColor( nRgb & 0xFFFFFF ); 539 } 540 } 541 542 void ColorPalette::importPalette( const Any& rPalette ) 543 { 544 Sequence< sal_Int32 > rColorSeq; 545 if( (rPalette >>= rColorSeq) && rColorSeq.hasElements() ) 546 { 547 const sal_Int32* pnColor = rColorSeq.getConstArray(); 548 const sal_Int32* pnColorEnd = pnColor + rColorSeq.getLength(); 549 for( ; pnColor < pnColorEnd; ++pnColor ) 550 appendColor( *pnColor & 0xFFFFFF ); 551 } 552 } 553 554 sal_Int32 ColorPalette::getColor( sal_Int32 nPaletteIdx ) const 555 { 556 sal_Int32 nColor = API_RGB_TRANSPARENT; 557 if( const sal_Int32* pnPaletteColor = ContainerHelper::getVectorElement( maColors, nPaletteIdx ) ) 558 { 559 nColor = *pnPaletteColor; 560 } 561 else switch( nPaletteIdx ) 562 { 563 case OOX_COLOR_WINDOWTEXT3: 564 case OOX_COLOR_WINDOWTEXT: 565 case OOX_COLOR_CHWINDOWTEXT: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_windowText ); break; 566 case OOX_COLOR_WINDOWBACK3: 567 case OOX_COLOR_WINDOWBACK: 568 case OOX_COLOR_CHWINDOWBACK: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_window ); break; 569 case OOX_COLOR_BUTTONBACK: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_btnFace ); break; 570 case OOX_COLOR_CHBORDERAUTO: nColor = API_RGB_BLACK; /* really always black? */ break; 571 case OOX_COLOR_NOTEBACK: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_infoBk ); break; 572 case OOX_COLOR_NOTETEXT: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_infoText ); break; 573 case OOX_COLOR_FONTAUTO: nColor = API_RGB_TRANSPARENT; break; 574 default: OSL_ENSURE( false, "ColorPalette::getColor - unknown color index" ); 575 } 576 return nColor; 577 } 578 579 void ColorPalette::appendColor( sal_Int32 nRGBValue ) 580 { 581 if( mnAppendIndex < maColors.size() ) 582 maColors[ mnAppendIndex ] = nRGBValue; 583 else 584 maColors.push_back( nRGBValue ); 585 ++mnAppendIndex; 586 } 587 588 // ============================================================================ 589 590 namespace { 591 592 void lclSetFontName( ApiScriptFontName& rFontName, const FontDescriptor& rFontDesc, bool bHasGlyphs ) 593 { 594 if( bHasGlyphs ) 595 { 596 rFontName.maName = rFontDesc.Name; 597 rFontName.mnFamily = rFontDesc.Family; 598 // API font descriptor contains rtl_TextEncoding constants 599 rFontName.mnTextEnc = rFontDesc.CharSet; 600 } 601 else 602 { 603 rFontName = ApiScriptFontName(); 604 } 605 } 606 607 } // namespace 608 609 // ---------------------------------------------------------------------------- 610 611 FontModel::FontModel() : 612 mnScheme( XML_none ), 613 mnFamily( OOX_FONTFAMILY_NONE ), 614 mnCharSet( WINDOWS_CHARSET_DEFAULT ), 615 mfHeight( 0.0 ), 616 mnUnderline( XML_none ), 617 mnEscapement( XML_baseline ), 618 mbBold( false ), 619 mbItalic( false ), 620 mbStrikeout( false ), 621 mbOutline( false ), 622 mbShadow( false ) 623 { 624 } 625 626 void FontModel::setBiff12Scheme( sal_uInt8 nScheme ) 627 { 628 static const sal_Int32 spnSchemes[] = { XML_none, XML_major, XML_minor }; 629 mnScheme = STATIC_ARRAY_SELECT( spnSchemes, nScheme, XML_none ); 630 } 631 632 void FontModel::setBiffHeight( sal_uInt16 nHeight ) 633 { 634 mfHeight = nHeight / 20.0; // convert twips to points 635 } 636 637 void FontModel::setBiffWeight( sal_uInt16 nWeight ) 638 { 639 mbBold = nWeight >= BIFF_FONTWEIGHT_BOLD; 640 } 641 642 void FontModel::setBiffUnderline( sal_uInt16 nUnderline ) 643 { 644 switch( nUnderline ) 645 { 646 case BIFF_FONTUNDERL_NONE: mnUnderline = XML_none; break; 647 case BIFF_FONTUNDERL_SINGLE: mnUnderline = XML_single; break; 648 case BIFF_FONTUNDERL_DOUBLE: mnUnderline = XML_double; break; 649 case BIFF_FONTUNDERL_SINGLE_ACC: mnUnderline = XML_singleAccounting; break; 650 case BIFF_FONTUNDERL_DOUBLE_ACC: mnUnderline = XML_doubleAccounting; break; 651 default: mnUnderline = XML_none; 652 } 653 } 654 655 void FontModel::setBiffEscapement( sal_uInt16 nEscapement ) 656 { 657 static const sal_Int32 spnEscapes[] = { XML_baseline, XML_superscript, XML_subscript }; 658 mnEscapement = STATIC_ARRAY_SELECT( spnEscapes, nEscapement, XML_baseline ); 659 } 660 661 // ---------------------------------------------------------------------------- 662 663 ApiFontUsedFlags::ApiFontUsedFlags( bool bAllUsed ) : 664 mbNameUsed( bAllUsed ), 665 mbColorUsed( bAllUsed ), 666 mbSchemeUsed( bAllUsed ), 667 mbHeightUsed( bAllUsed ), 668 mbUnderlineUsed( bAllUsed ), 669 mbEscapementUsed( bAllUsed ), 670 mbWeightUsed( bAllUsed ), 671 mbPostureUsed( bAllUsed ), 672 mbStrikeoutUsed( bAllUsed ), 673 mbOutlineUsed( bAllUsed ), 674 mbShadowUsed( bAllUsed ) 675 { 676 } 677 678 // ---------------------------------------------------------------------------- 679 680 ApiScriptFontName::ApiScriptFontName() : 681 mnFamily( ::com::sun::star::awt::FontFamily::DONTKNOW ), 682 mnTextEnc( RTL_TEXTENCODING_DONTKNOW ) 683 { 684 } 685 686 // ---------------------------------------------------------------------------- 687 688 ApiFontData::ApiFontData() : 689 maDesc( 690 CREATE_OUSTRING( "Calibri" ), 691 220, // height 11 points 692 0, 693 OUString(), 694 ::com::sun::star::awt::FontFamily::DONTKNOW, 695 RTL_TEXTENCODING_DONTKNOW, 696 ::com::sun::star::awt::FontPitch::DONTKNOW, 697 100.0, 698 ::com::sun::star::awt::FontWeight::NORMAL, 699 ::com::sun::star::awt::FontSlant_NONE, 700 ::com::sun::star::awt::FontUnderline::NONE, 701 ::com::sun::star::awt::FontStrikeout::NONE, 702 0.0, 703 sal_False, 704 sal_False, 705 ::com::sun::star::awt::FontType::DONTKNOW ), 706 mnColor( API_RGB_TRANSPARENT ), 707 mnEscapement( API_ESCAPE_NONE ), 708 mnEscapeHeight( API_ESCAPEHEIGHT_NONE ), 709 mbOutline( false ), 710 mbShadow( false ) 711 { 712 maLatinFont.maName = maDesc.Name; 713 } 714 715 // ============================================================================ 716 717 Font::Font( const WorkbookHelper& rHelper, bool bDxf ) : 718 WorkbookHelper( rHelper ), 719 maModel( rHelper.getTheme().getDefaultFontModel() ), 720 maUsedFlags( !bDxf ), 721 mbDxf( bDxf ) 722 { 723 } 724 725 Font::Font( const WorkbookHelper& rHelper, const FontModel& rModel ) : 726 WorkbookHelper( rHelper ), 727 maModel( rModel ), 728 maUsedFlags( true ), 729 mbDxf( false ) 730 { 731 } 732 733 void Font::importAttribs( sal_Int32 nElement, const AttributeList& rAttribs ) 734 { 735 const FontModel& rDefModel = getTheme().getDefaultFontModel(); 736 switch( nElement ) 737 { 738 case XLS_TOKEN( name ): // when in <font> element 739 case XLS_TOKEN( rFont ): // when in <rPr> element 740 if( rAttribs.hasAttribute( XML_val ) ) 741 { 742 maModel.maName = rAttribs.getXString( XML_val, OUString() ); 743 maUsedFlags.mbNameUsed = true; 744 } 745 break; 746 case XLS_TOKEN( scheme ): 747 maModel.mnScheme = rAttribs.getToken( XML_val, rDefModel.mnScheme ); 748 break; 749 case XLS_TOKEN( family ): 750 maModel.mnFamily = rAttribs.getInteger( XML_val, rDefModel.mnFamily ); 751 break; 752 case XLS_TOKEN( charset ): 753 maModel.mnCharSet = rAttribs.getInteger( XML_val, rDefModel.mnCharSet ); 754 break; 755 case XLS_TOKEN( sz ): 756 maModel.mfHeight = rAttribs.getDouble( XML_val, rDefModel.mfHeight ); 757 maUsedFlags.mbHeightUsed = true; 758 break; 759 case XLS_TOKEN( color ): 760 maModel.maColor.importColor( rAttribs ); 761 maUsedFlags.mbColorUsed = true; 762 break; 763 case XLS_TOKEN( u ): 764 maModel.mnUnderline = rAttribs.getToken( XML_val, XML_single ); 765 maUsedFlags.mbUnderlineUsed = true; 766 break; 767 case XLS_TOKEN( vertAlign ): 768 maModel.mnEscapement = rAttribs.getToken( XML_val, XML_baseline ); 769 maUsedFlags.mbEscapementUsed = true; 770 break; 771 case XLS_TOKEN( b ): 772 maModel.mbBold = rAttribs.getBool( XML_val, true ); 773 maUsedFlags.mbWeightUsed = true; 774 break; 775 case XLS_TOKEN( i ): 776 maModel.mbItalic = rAttribs.getBool( XML_val, true ); 777 maUsedFlags.mbPostureUsed = true; 778 break; 779 case XLS_TOKEN( strike ): 780 maModel.mbStrikeout = rAttribs.getBool( XML_val, true ); 781 maUsedFlags.mbStrikeoutUsed = true; 782 break; 783 case XLS_TOKEN( outline ): 784 maModel.mbOutline = rAttribs.getBool( XML_val, true ); 785 maUsedFlags.mbOutlineUsed = true; 786 break; 787 case XLS_TOKEN( shadow ): 788 maModel.mbShadow = rAttribs.getBool( XML_val, true ); 789 maUsedFlags.mbShadowUsed = true; 790 break; 791 } 792 } 793 794 void Font::importFont( SequenceInputStream& rStrm ) 795 { 796 OSL_ENSURE( !mbDxf, "Font::importFont - unexpected conditional formatting flag" ); 797 798 sal_uInt16 nHeight, nFlags, nWeight, nEscapement; 799 sal_uInt8 nUnderline, nFamily, nCharSet, nScheme; 800 rStrm >> nHeight >> nFlags >> nWeight >> nEscapement >> nUnderline >> nFamily >> nCharSet; 801 rStrm.skip( 1 ); 802 rStrm >> maModel.maColor >> nScheme >> maModel.maName; 803 804 // equal constants in all BIFFs for weight, underline, and escapement 805 maModel.setBiff12Scheme( nScheme ); 806 maModel.setBiffHeight( nHeight ); 807 maModel.setBiffWeight( nWeight ); 808 maModel.setBiffUnderline( nUnderline ); 809 maModel.setBiffEscapement( nEscapement ); 810 maModel.mnFamily = nFamily; 811 maModel.mnCharSet = nCharSet; 812 // equal flags in all BIFFs 813 maModel.mbItalic = getFlag( nFlags, BIFF_FONTFLAG_ITALIC ); 814 maModel.mbStrikeout = getFlag( nFlags, BIFF_FONTFLAG_STRIKEOUT ); 815 maModel.mbOutline = getFlag( nFlags, BIFF_FONTFLAG_OUTLINE ); 816 maModel.mbShadow = getFlag( nFlags, BIFF_FONTFLAG_SHADOW ); 817 } 818 819 void Font::importDxfName( SequenceInputStream& rStrm ) 820 { 821 OSL_ENSURE( mbDxf, "Font::importDxfName - missing conditional formatting flag" ); 822 maModel.maName = BiffHelper::readString( rStrm, false ); 823 maUsedFlags.mbColorUsed = true; 824 } 825 826 void Font::importDxfColor( SequenceInputStream& rStrm ) 827 { 828 OSL_ENSURE( mbDxf, "Font::importDxfColor - missing conditional formatting flag" ); 829 rStrm >> maModel.maColor; 830 maUsedFlags.mbColorUsed = true; 831 } 832 833 void Font::importDxfScheme( SequenceInputStream& rStrm ) 834 { 835 OSL_ENSURE( mbDxf, "Font::importDxfScheme - missing conditional formatting flag" ); 836 maModel.setBiff12Scheme( rStrm.readuInt8() ); 837 maUsedFlags.mbSchemeUsed = true; 838 } 839 840 void Font::importDxfHeight( SequenceInputStream& rStrm ) 841 { 842 OSL_ENSURE( mbDxf, "Font::importDxfHeight - missing conditional formatting flag" ); 843 maModel.setBiffHeight( rStrm.readuInt16() ); 844 maUsedFlags.mbHeightUsed = true; 845 } 846 847 void Font::importDxfWeight( SequenceInputStream& rStrm ) 848 { 849 OSL_ENSURE( mbDxf, "Font::importDxfWeight - missing conditional formatting flag" ); 850 maModel.setBiffWeight( rStrm.readuInt16() ); 851 maUsedFlags.mbWeightUsed = true; 852 } 853 854 void Font::importDxfUnderline( SequenceInputStream& rStrm ) 855 { 856 OSL_ENSURE( mbDxf, "Font::importDxfUnderline - missing conditional formatting flag" ); 857 maModel.setBiffUnderline( rStrm.readuInt16() ); 858 maUsedFlags.mbUnderlineUsed = true; 859 } 860 861 void Font::importDxfEscapement( SequenceInputStream& rStrm ) 862 { 863 OSL_ENSURE( mbDxf, "Font::importDxfEscapement - missing conditional formatting flag" ); 864 maModel.setBiffEscapement( rStrm.readuInt16() ); 865 maUsedFlags.mbEscapementUsed = true; 866 } 867 868 void Font::importDxfFlag( sal_Int32 nElement, SequenceInputStream& rStrm ) 869 { 870 OSL_ENSURE( mbDxf, "Font::importDxfFlag - missing conditional formatting flag" ); 871 bool bFlag = rStrm.readuInt8() != 0; 872 switch( nElement ) 873 { 874 case XML_i: 875 maModel.mbItalic = bFlag; 876 maUsedFlags.mbPostureUsed = true; 877 break; 878 case XML_strike: 879 maModel.mbStrikeout = bFlag; 880 maUsedFlags.mbStrikeoutUsed = true; 881 break; 882 case XML_outline: 883 maModel.mbOutline = bFlag; 884 maUsedFlags.mbOutlineUsed = true; 885 break; 886 case XML_shadow: 887 maModel.mbShadow = bFlag; 888 maUsedFlags.mbShadowUsed = true; 889 break; 890 default: 891 OSL_ENSURE( false, "Font::importDxfFlag - unexpected element identifier" ); 892 } 893 } 894 895 void Font::importFont( BiffInputStream& rStrm ) 896 { 897 OSL_ENSURE( !mbDxf, "Font::importFont - unexpected conditional formatting flag" ); 898 switch( getBiff() ) 899 { 900 case BIFF2: 901 importFontData2( rStrm ); 902 importFontName2( rStrm ); 903 break; 904 case BIFF3: 905 case BIFF4: 906 importFontData2( rStrm ); 907 importFontColor( rStrm ); 908 importFontName2( rStrm ); 909 break; 910 case BIFF5: 911 importFontData2( rStrm ); 912 importFontColor( rStrm ); 913 importFontData5( rStrm ); 914 importFontName2( rStrm ); 915 break; 916 case BIFF8: 917 importFontData2( rStrm ); 918 importFontColor( rStrm ); 919 importFontData5( rStrm ); 920 importFontName8( rStrm ); 921 break; 922 case BIFF_UNKNOWN: break; 923 } 924 } 925 926 void Font::importFontColor( BiffInputStream& rStrm ) 927 { 928 OSL_ENSURE( !mbDxf, "Font::importFontColor - unexpected conditional formatting flag" ); 929 maModel.maColor.importColorId( rStrm ); 930 } 931 932 void Font::importCfRule( BiffInputStream& rStrm ) 933 { 934 OSL_ENSURE( mbDxf, "Font::importCfRule - missing conditional formatting flag" ); 935 936 sal_Int32 nHeight, nColor; 937 sal_uInt32 nStyle, nFontFlags1, nFontFlags2, nFontFlags3; 938 sal_uInt16 nWeight, nEscapement; 939 sal_uInt8 nUnderline; 940 941 OSL_ENSURE( rStrm.getRemaining() >= 118, "Font::importCfRule - missing record data" ); 942 sal_Int64 nRecPos = rStrm.tell(); 943 maModel.maName = rStrm.readUniStringBody( rStrm.readuInt8() ); 944 maUsedFlags.mbNameUsed = maModel.maName.getLength() > 0; 945 OSL_ENSURE( !rStrm.isEof() && (rStrm.tell() <= nRecPos + 64), "Font::importCfRule - font name too long" ); 946 rStrm.seek( nRecPos + 64 ); 947 rStrm >> nHeight >> nStyle >> nWeight >> nEscapement >> nUnderline; 948 rStrm.skip( 3 ); 949 rStrm >> nColor; 950 rStrm.skip( 4 ); 951 rStrm >> nFontFlags1 >> nFontFlags2 >> nFontFlags3; 952 rStrm.skip( 18 ); 953 954 if( (maUsedFlags.mbColorUsed = (0 <= nColor) && (nColor <= 0x7FFF)) == true ) 955 maModel.maColor.setIndexed( nColor ); 956 if( (maUsedFlags.mbHeightUsed = (0 < nHeight) && (nHeight <= 0x7FFF)) == true ) 957 maModel.setBiffHeight( static_cast< sal_uInt16 >( nHeight ) ); 958 if( (maUsedFlags.mbUnderlineUsed = !getFlag( nFontFlags3, BIFF_CFRULE_FONT_UNDERL )) == true ) 959 maModel.setBiffUnderline( nUnderline ); 960 if( (maUsedFlags.mbEscapementUsed = !getFlag( nFontFlags2, BIFF_CFRULE_FONT_ESCAPEM )) == true ) 961 maModel.setBiffEscapement( nEscapement ); 962 if( (maUsedFlags.mbWeightUsed = maUsedFlags.mbPostureUsed = !getFlag( nFontFlags1, BIFF_CFRULE_FONT_STYLE )) == true ) 963 { 964 maModel.setBiffWeight( nWeight ); 965 maModel.mbItalic = getFlag( nStyle, BIFF_CFRULE_FONT_STYLE ); 966 } 967 if( (maUsedFlags.mbStrikeoutUsed = !getFlag( nFontFlags1, BIFF_CFRULE_FONT_STRIKEOUT )) == true ) 968 maModel.mbStrikeout = getFlag( nStyle, BIFF_CFRULE_FONT_STRIKEOUT ); 969 if( (maUsedFlags.mbOutlineUsed = !getFlag( nFontFlags1, BIFF_CFRULE_FONT_OUTLINE )) == true ) 970 maModel.mbOutline = getFlag( nStyle, BIFF_CFRULE_FONT_OUTLINE ); 971 if( (maUsedFlags.mbShadowUsed = !getFlag( nFontFlags1, BIFF_CFRULE_FONT_SHADOW )) == true ) 972 maModel.mbShadow = getFlag( nStyle, BIFF_CFRULE_FONT_SHADOW ); 973 } 974 975 rtl_TextEncoding Font::getFontEncoding() const 976 { 977 // #i63105# cells use text encoding from FONT record character set 978 // #i67768# BIFF2-BIFF4 FONT records do not contain character set 979 // #i71033# do not use maApiData, this function is used before finalizeImport() 980 rtl_TextEncoding eFontEnc = RTL_TEXTENCODING_DONTKNOW; 981 if( (0 <= maModel.mnCharSet) && (maModel.mnCharSet <= SAL_MAX_UINT8) ) 982 eFontEnc = rtl_getTextEncodingFromWindowsCharset( static_cast< sal_uInt8 >( maModel.mnCharSet ) ); 983 return (eFontEnc == RTL_TEXTENCODING_DONTKNOW) ? getTextEncoding() : eFontEnc; 984 } 985 986 void Font::finalizeImport() 987 { 988 namespace cssawt = ::com::sun::star::awt; 989 990 // font name 991 maApiData.maDesc.Name = maModel.maName; 992 993 // font family 994 switch( maModel.mnFamily ) 995 { 996 case OOX_FONTFAMILY_NONE: maApiData.maDesc.Family = cssawt::FontFamily::DONTKNOW; break; 997 case OOX_FONTFAMILY_ROMAN: maApiData.maDesc.Family = cssawt::FontFamily::ROMAN; break; 998 case OOX_FONTFAMILY_SWISS: maApiData.maDesc.Family = cssawt::FontFamily::SWISS; break; 999 case OOX_FONTFAMILY_MODERN: maApiData.maDesc.Family = cssawt::FontFamily::MODERN; break; 1000 case OOX_FONTFAMILY_SCRIPT: maApiData.maDesc.Family = cssawt::FontFamily::SCRIPT; break; 1001 case OOX_FONTFAMILY_DECORATIVE: maApiData.maDesc.Family = cssawt::FontFamily::DECORATIVE; break; 1002 } 1003 1004 // character set (API font descriptor uses rtl_TextEncoding in member CharSet!) 1005 if( (0 <= maModel.mnCharSet) && (maModel.mnCharSet <= SAL_MAX_UINT8) ) 1006 maApiData.maDesc.CharSet = static_cast< sal_Int16 >( 1007 rtl_getTextEncodingFromWindowsCharset( static_cast< sal_uInt8 >( maModel.mnCharSet ) ) ); 1008 1009 // color, height, weight, slant, strikeout, outline, shadow 1010 maApiData.mnColor = maModel.maColor.getColor( getBaseFilter().getGraphicHelper() ); 1011 maApiData.maDesc.Height = static_cast< sal_Int16 >( maModel.mfHeight * 20.0 ); 1012 maApiData.maDesc.Weight = maModel.mbBold ? cssawt::FontWeight::BOLD : cssawt::FontWeight::NORMAL; 1013 maApiData.maDesc.Slant = maModel.mbItalic ? cssawt::FontSlant_ITALIC : cssawt::FontSlant_NONE; 1014 maApiData.maDesc.Strikeout = maModel.mbStrikeout ? cssawt::FontStrikeout::SINGLE : cssawt::FontStrikeout::NONE; 1015 maApiData.mbOutline = maModel.mbOutline; 1016 maApiData.mbShadow = maModel.mbShadow; 1017 1018 // underline 1019 switch( maModel.mnUnderline ) 1020 { 1021 case XML_double: maApiData.maDesc.Underline = cssawt::FontUnderline::DOUBLE; break; 1022 case XML_doubleAccounting: maApiData.maDesc.Underline = cssawt::FontUnderline::DOUBLE; break; 1023 case XML_none: maApiData.maDesc.Underline = cssawt::FontUnderline::NONE; break; 1024 case XML_single: maApiData.maDesc.Underline = cssawt::FontUnderline::SINGLE; break; 1025 case XML_singleAccounting: maApiData.maDesc.Underline = cssawt::FontUnderline::SINGLE; break; 1026 } 1027 1028 // escapement 1029 switch( maModel.mnEscapement ) 1030 { 1031 case XML_baseline: 1032 maApiData.mnEscapement = API_ESCAPE_NONE; 1033 maApiData.mnEscapeHeight = API_ESCAPEHEIGHT_NONE; 1034 break; 1035 case XML_superscript: 1036 maApiData.mnEscapement = API_ESCAPE_SUPERSCRIPT; 1037 maApiData.mnEscapeHeight = API_ESCAPEHEIGHT_DEFAULT; 1038 break; 1039 case XML_subscript: 1040 maApiData.mnEscapement = API_ESCAPE_SUBSCRIPT; 1041 maApiData.mnEscapeHeight = API_ESCAPEHEIGHT_DEFAULT; 1042 break; 1043 } 1044 1045 // supported script types 1046 if( maUsedFlags.mbNameUsed ) 1047 { 1048 PropertySet aDocProps( getDocument() ); 1049 Reference< XDevice > xDevice( aDocProps.getAnyProperty( PROP_ReferenceDevice ), UNO_QUERY ); 1050 if( xDevice.is() ) 1051 { 1052 Reference< XFont2 > xFont( xDevice->getFont( maApiData.maDesc ), UNO_QUERY ); 1053 if( xFont.is() ) 1054 { 1055 // #91658# CJK fonts 1056 bool bHasAsian = 1057 xFont->hasGlyphs( OUString( sal_Unicode( 0x3041 ) ) ) || // 3040-309F: Hiragana 1058 xFont->hasGlyphs( OUString( sal_Unicode( 0x30A1 ) ) ) || // 30A0-30FF: Katakana 1059 xFont->hasGlyphs( OUString( sal_Unicode( 0x3111 ) ) ) || // 3100-312F: Bopomofo 1060 xFont->hasGlyphs( OUString( sal_Unicode( 0x3131 ) ) ) || // 3130-318F: Hangul Compatibility Jamo 1061 xFont->hasGlyphs( OUString( sal_Unicode( 0x3301 ) ) ) || // 3300-33FF: CJK Compatibility 1062 xFont->hasGlyphs( OUString( sal_Unicode( 0x3401 ) ) ) || // 3400-4DBF: CJK Unified Ideographs Extension A 1063 xFont->hasGlyphs( OUString( sal_Unicode( 0x4E01 ) ) ) || // 4E00-9FAF: CJK Unified Ideographs 1064 xFont->hasGlyphs( OUString( sal_Unicode( 0x7E01 ) ) ) || // 4E00-9FAF: CJK unified ideographs 1065 xFont->hasGlyphs( OUString( sal_Unicode( 0xA001 ) ) ) || // A001-A48F: Yi Syllables 1066 xFont->hasGlyphs( OUString( sal_Unicode( 0xAC01 ) ) ) || // AC00-D7AF: Hangul Syllables 1067 xFont->hasGlyphs( OUString( sal_Unicode( 0xCC01 ) ) ) || // AC00-D7AF: Hangul Syllables 1068 xFont->hasGlyphs( OUString( sal_Unicode( 0xF901 ) ) ) || // F900-FAFF: CJK Compatibility Ideographs 1069 xFont->hasGlyphs( OUString( sal_Unicode( 0xFF71 ) ) ); // FF00-FFEF: Halfwidth/Fullwidth Forms 1070 // #113783# CTL fonts 1071 bool bHasCmplx = 1072 xFont->hasGlyphs( OUString( sal_Unicode( 0x05D1 ) ) ) || // 0590-05FF: Hebrew 1073 xFont->hasGlyphs( OUString( sal_Unicode( 0x0631 ) ) ) || // 0600-06FF: Arabic 1074 xFont->hasGlyphs( OUString( sal_Unicode( 0x0721 ) ) ) || // 0700-074F: Syriac 1075 xFont->hasGlyphs( OUString( sal_Unicode( 0x0911 ) ) ) || // 0900-0DFF: Indic scripts 1076 xFont->hasGlyphs( OUString( sal_Unicode( 0x0E01 ) ) ) || // 0E00-0E7F: Thai 1077 xFont->hasGlyphs( OUString( sal_Unicode( 0xFB21 ) ) ) || // FB1D-FB4F: Hebrew Presentation Forms 1078 xFont->hasGlyphs( OUString( sal_Unicode( 0xFB51 ) ) ) || // FB50-FDFF: Arabic Presentation Forms-A 1079 xFont->hasGlyphs( OUString( sal_Unicode( 0xFE71 ) ) ); // FE70-FEFF: Arabic Presentation Forms-B 1080 // Western fonts 1081 bool bHasLatin = 1082 (!bHasAsian && !bHasCmplx) || 1083 xFont->hasGlyphs( OUString( sal_Unicode( 'A' ) ) ); 1084 1085 lclSetFontName( maApiData.maLatinFont, maApiData.maDesc, bHasLatin ); 1086 lclSetFontName( maApiData.maAsianFont, maApiData.maDesc, bHasAsian ); 1087 lclSetFontName( maApiData.maCmplxFont, maApiData.maDesc, bHasCmplx ); 1088 } 1089 } 1090 } 1091 } 1092 1093 const FontDescriptor& Font::getFontDescriptor() const 1094 { 1095 return maApiData.maDesc; 1096 } 1097 1098 bool Font::needsRichTextFormat() const 1099 { 1100 return maApiData.mnEscapement != API_ESCAPE_NONE; 1101 } 1102 1103 void Font::writeToPropertyMap( PropertyMap& rPropMap, FontPropertyType ePropType ) const 1104 { 1105 // font name properties 1106 if( maUsedFlags.mbNameUsed ) 1107 { 1108 if( maApiData.maLatinFont.maName.getLength() > 0 ) 1109 { 1110 rPropMap[ PROP_CharFontName ] <<= maApiData.maLatinFont.maName; 1111 rPropMap[ PROP_CharFontFamily ] <<= maApiData.maLatinFont.mnFamily; 1112 rPropMap[ PROP_CharFontCharSet ] <<= maApiData.maLatinFont.mnTextEnc; 1113 } 1114 if( maApiData.maAsianFont.maName.getLength() > 0 ) 1115 { 1116 rPropMap[ PROP_CharFontNameAsian ] <<= maApiData.maAsianFont.maName; 1117 rPropMap[ PROP_CharFontFamilyAsian ] <<= maApiData.maAsianFont.mnFamily; 1118 rPropMap[ PROP_CharFontCharSetAsian ] <<= maApiData.maAsianFont.mnTextEnc; 1119 } 1120 if( maApiData.maCmplxFont.maName.getLength() > 0 ) 1121 { 1122 rPropMap[ PROP_CharFontNameComplex ] <<= maApiData.maCmplxFont.maName; 1123 rPropMap[ PROP_CharFontFamilyComplex ] <<= maApiData.maCmplxFont.mnFamily; 1124 rPropMap[ PROP_CharFontCharSetComplex ] <<= maApiData.maCmplxFont.mnTextEnc; 1125 } 1126 } 1127 // font height 1128 if( maUsedFlags.mbHeightUsed ) 1129 { 1130 float fHeight = static_cast< float >( maApiData.maDesc.Height / 20.0 ); // twips to points 1131 rPropMap[ PROP_CharHeight ] <<= fHeight; 1132 rPropMap[ PROP_CharHeightAsian ] <<= fHeight; 1133 rPropMap[ PROP_CharHeightComplex ] <<= fHeight; 1134 } 1135 // font weight 1136 if( maUsedFlags.mbWeightUsed ) 1137 { 1138 float fWeight = maApiData.maDesc.Weight; 1139 rPropMap[ PROP_CharWeight ] <<= fWeight; 1140 rPropMap[ PROP_CharWeightAsian ] <<= fWeight; 1141 rPropMap[ PROP_CharWeightComplex ] <<= fWeight; 1142 } 1143 // font posture 1144 if( maUsedFlags.mbPostureUsed ) 1145 { 1146 rPropMap[ PROP_CharPosture ] <<= maApiData.maDesc.Slant; 1147 rPropMap[ PROP_CharPostureAsian ] <<= maApiData.maDesc.Slant; 1148 rPropMap[ PROP_CharPostureComplex ] <<= maApiData.maDesc.Slant; 1149 } 1150 // character color 1151 if( maUsedFlags.mbColorUsed ) 1152 rPropMap[ PROP_CharColor ] <<= maApiData.mnColor; 1153 // underline style 1154 if( maUsedFlags.mbUnderlineUsed ) 1155 rPropMap[ PROP_CharUnderline ] <<= maApiData.maDesc.Underline; 1156 // strike out style 1157 if( maUsedFlags.mbStrikeoutUsed ) 1158 rPropMap[ PROP_CharStrikeout ] <<= maApiData.maDesc.Strikeout; 1159 // outline style 1160 if( maUsedFlags.mbOutlineUsed ) 1161 rPropMap[ PROP_CharContoured ] <<= maApiData.mbOutline; 1162 // shadow style 1163 if( maUsedFlags.mbShadowUsed ) 1164 rPropMap[ PROP_CharShadowed ] <<= maApiData.mbShadow; 1165 // escapement 1166 if( maUsedFlags.mbEscapementUsed && (ePropType == FONT_PROPTYPE_TEXT) ) 1167 { 1168 rPropMap[ PROP_CharEscapement ] <<= maApiData.mnEscapement; 1169 rPropMap[ PROP_CharEscapementHeight ] <<= maApiData.mnEscapeHeight; 1170 } 1171 } 1172 1173 void Font::writeToPropertySet( PropertySet& rPropSet, FontPropertyType ePropType ) const 1174 { 1175 PropertyMap aPropMap; 1176 writeToPropertyMap( aPropMap, ePropType ); 1177 rPropSet.setProperties( aPropMap ); 1178 } 1179 1180 void Font::importFontData2( BiffInputStream& rStrm ) 1181 { 1182 sal_uInt16 nHeight, nFlags; 1183 rStrm >> nHeight >> nFlags; 1184 1185 maModel.setBiffHeight( nHeight ); 1186 maModel.mnFamily = OOX_FONTFAMILY_NONE; 1187 maModel.mnCharSet = -1; // ensure to not use font charset in byte string import 1188 maModel.mnUnderline = getFlagValue( nFlags, BIFF_FONTFLAG_UNDERLINE, XML_single, XML_none ); 1189 maModel.mnEscapement = XML_none; 1190 maModel.mbBold = getFlag( nFlags, BIFF_FONTFLAG_BOLD ); 1191 maModel.mbItalic = getFlag( nFlags, BIFF_FONTFLAG_ITALIC ); 1192 maModel.mbStrikeout = getFlag( nFlags, BIFF_FONTFLAG_STRIKEOUT ); 1193 maModel.mbOutline = getFlag( nFlags, BIFF_FONTFLAG_OUTLINE ); 1194 maModel.mbShadow = getFlag( nFlags, BIFF_FONTFLAG_SHADOW ); 1195 } 1196 1197 void Font::importFontData5( BiffInputStream& rStrm ) 1198 { 1199 sal_uInt16 nWeight, nEscapement; 1200 sal_uInt8 nUnderline, nFamily, nCharSet; 1201 rStrm >> nWeight >> nEscapement >> nUnderline >> nFamily >> nCharSet; 1202 rStrm.skip( 1 ); 1203 1204 maModel.setBiffWeight( nWeight ); 1205 maModel.setBiffUnderline( nUnderline ); 1206 maModel.setBiffEscapement( nEscapement ); 1207 // equal constants in XML and BIFF for family and charset 1208 maModel.mnFamily = nFamily; 1209 maModel.mnCharSet = nCharSet; 1210 } 1211 1212 void Font::importFontName2( BiffInputStream& rStrm ) 1213 { 1214 maModel.maName = rStrm.readByteStringUC( false, getTextEncoding() ); 1215 } 1216 1217 void Font::importFontName8( BiffInputStream& rStrm ) 1218 { 1219 maModel.maName = rStrm.readUniStringBody( rStrm.readuInt8() ); 1220 } 1221 1222 // ============================================================================ 1223 1224 AlignmentModel::AlignmentModel() : 1225 mnHorAlign( XML_general ), 1226 mnVerAlign( XML_bottom ), 1227 mnTextDir( OOX_XF_TEXTDIR_CONTEXT ), 1228 mnRotation( OOX_XF_ROTATION_NONE ), 1229 mnIndent( OOX_XF_INDENT_NONE ), 1230 mbWrapText( false ), 1231 mbShrink( false ), 1232 mbJustLastLine( false ) 1233 { 1234 } 1235 1236 void AlignmentModel::setBiffHorAlign( sal_uInt8 nHorAlign ) 1237 { 1238 static const sal_Int32 spnHorAligns[] = { 1239 XML_general, XML_left, XML_center, XML_right, 1240 XML_fill, XML_justify, XML_centerContinuous, XML_distributed }; 1241 mnHorAlign = STATIC_ARRAY_SELECT( spnHorAligns, nHorAlign, XML_general ); 1242 } 1243 1244 void AlignmentModel::setBiffVerAlign( sal_uInt8 nVerAlign ) 1245 { 1246 static const sal_Int32 spnVerAligns[] = { 1247 XML_top, XML_center, XML_bottom, XML_justify, XML_distributed }; 1248 mnVerAlign = STATIC_ARRAY_SELECT( spnVerAligns, nVerAlign, XML_bottom ); 1249 } 1250 1251 void AlignmentModel::setBiffTextOrient( sal_uInt8 nTextOrient ) 1252 { 1253 static const sal_Int32 spnRotations[] = { 1254 OOX_XF_ROTATION_NONE, OOX_XF_ROTATION_STACKED, 1255 OOX_XF_ROTATION_90CCW, OOX_XF_ROTATION_90CW }; 1256 mnRotation = STATIC_ARRAY_SELECT( spnRotations, nTextOrient, OOX_XF_ROTATION_NONE ); 1257 } 1258 1259 // ---------------------------------------------------------------------------- 1260 1261 ApiAlignmentData::ApiAlignmentData() : 1262 meHorJustify( ::com::sun::star::table::CellHoriJustify_STANDARD ), 1263 meVerJustify( ::com::sun::star::table::CellVertJustify_STANDARD ), 1264 meOrientation( ::com::sun::star::table::CellOrientation_STANDARD ), 1265 mnRotation( 0 ), 1266 mnWritingMode( ::com::sun::star::text::WritingMode2::PAGE ), 1267 mnIndent( 0 ), 1268 mbWrapText( false ), 1269 mbShrink( false ) 1270 { 1271 } 1272 1273 bool operator==( const ApiAlignmentData& rLeft, const ApiAlignmentData& rRight ) 1274 { 1275 return 1276 (rLeft.meHorJustify == rRight.meHorJustify) && 1277 (rLeft.meVerJustify == rRight.meVerJustify) && 1278 (rLeft.meOrientation == rRight.meOrientation) && 1279 (rLeft.mnRotation == rRight.mnRotation) && 1280 (rLeft.mnWritingMode == rRight.mnWritingMode) && 1281 (rLeft.mnIndent == rRight.mnIndent) && 1282 (rLeft.mbWrapText == rRight.mbWrapText) && 1283 (rLeft.mbShrink == rRight.mbShrink); 1284 } 1285 1286 // ============================================================================ 1287 1288 Alignment::Alignment( const WorkbookHelper& rHelper ) : 1289 WorkbookHelper( rHelper ) 1290 { 1291 } 1292 1293 void Alignment::importAlignment( const AttributeList& rAttribs ) 1294 { 1295 maModel.mnHorAlign = rAttribs.getToken( XML_horizontal, XML_general ); 1296 maModel.mnVerAlign = rAttribs.getToken( XML_vertical, XML_bottom ); 1297 maModel.mnTextDir = rAttribs.getInteger( XML_readingOrder, OOX_XF_TEXTDIR_CONTEXT ); 1298 maModel.mnRotation = rAttribs.getInteger( XML_textRotation, OOX_XF_ROTATION_NONE ); 1299 maModel.mnIndent = rAttribs.getInteger( XML_indent, OOX_XF_INDENT_NONE ); 1300 maModel.mbWrapText = rAttribs.getBool( XML_wrapText, false ); 1301 maModel.mbShrink = rAttribs.getBool( XML_shrinkToFit, false ); 1302 maModel.mbJustLastLine = rAttribs.getBool( XML_justifyLastLine, false ); 1303 } 1304 1305 void Alignment::setBiff12Data( sal_uInt32 nFlags ) 1306 { 1307 maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nFlags, 16, 3 ) ); 1308 maModel.setBiffVerAlign( extractValue< sal_uInt8 >( nFlags, 19, 3 ) ); 1309 maModel.mnTextDir = extractValue< sal_Int32 >( nFlags, 26, 2 ); 1310 maModel.mnRotation = extractValue< sal_Int32 >( nFlags, 0, 8 ); 1311 maModel.mnIndent = extractValue< sal_uInt8 >( nFlags, 8, 8 ); 1312 maModel.mbWrapText = getFlag( nFlags, BIFF12_XF_WRAPTEXT ); 1313 maModel.mbShrink = getFlag( nFlags, BIFF12_XF_SHRINK ); 1314 maModel.mbJustLastLine = getFlag( nFlags, BIFF12_XF_JUSTLASTLINE ); 1315 } 1316 1317 void Alignment::setBiff2Data( sal_uInt8 nFlags ) 1318 { 1319 maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nFlags, 0, 3 ) ); 1320 } 1321 1322 void Alignment::setBiff3Data( sal_uInt16 nAlign ) 1323 { 1324 maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nAlign, 0, 3 ) ); 1325 maModel.mbWrapText = getFlag( nAlign, BIFF_XF_WRAPTEXT ); // new in BIFF3 1326 } 1327 1328 void Alignment::setBiff4Data( sal_uInt16 nAlign ) 1329 { 1330 maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nAlign, 0, 3 ) ); 1331 maModel.setBiffVerAlign( extractValue< sal_uInt8 >( nAlign, 4, 2 ) ); // new in BIFF4 1332 maModel.setBiffTextOrient( extractValue< sal_uInt8 >( nAlign, 6, 2 ) ); // new in BIFF4 1333 maModel.mbWrapText = getFlag( nAlign, BIFF_XF_WRAPTEXT ); 1334 } 1335 1336 void Alignment::setBiff5Data( sal_uInt16 nAlign ) 1337 { 1338 maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nAlign, 0, 3 ) ); 1339 maModel.setBiffVerAlign( extractValue< sal_uInt8 >( nAlign, 4, 3 ) ); 1340 maModel.setBiffTextOrient( extractValue< sal_uInt8 >( nAlign, 8, 2 ) ); 1341 maModel.mbWrapText = getFlag( nAlign, BIFF_XF_WRAPTEXT ); 1342 } 1343 1344 void Alignment::setBiff8Data( sal_uInt16 nAlign, sal_uInt16 nMiscAttrib ) 1345 { 1346 maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nAlign, 0, 3 ) ); 1347 maModel.setBiffVerAlign( extractValue< sal_uInt8 >( nAlign, 4, 3 ) ); 1348 maModel.mnTextDir = extractValue< sal_Int32 >( nMiscAttrib, 6, 2 ); // new in BIFF8 1349 maModel.mnRotation = extractValue< sal_Int32 >( nAlign, 8, 8 ); // new in BIFF8 1350 maModel.mnIndent = extractValue< sal_uInt8 >( nMiscAttrib, 0, 4 ); // new in BIFF8 1351 maModel.mbWrapText = getFlag( nAlign, BIFF_XF_WRAPTEXT ); 1352 maModel.mbShrink = getFlag( nMiscAttrib, BIFF_XF_SHRINK ); // new in BIFF8 1353 maModel.mbJustLastLine = getFlag( nAlign, BIFF_XF_JUSTLASTLINE ); // new in BIFF8(?) 1354 } 1355 1356 void Alignment::finalizeImport() 1357 { 1358 namespace csstab = ::com::sun::star::table; 1359 namespace csstxt = ::com::sun::star::text; 1360 1361 // horizontal alignment 1362 switch( maModel.mnHorAlign ) 1363 { 1364 case XML_center: maApiData.meHorJustify = csstab::CellHoriJustify_CENTER; break; 1365 case XML_centerContinuous: maApiData.meHorJustify = csstab::CellHoriJustify_CENTER; break; 1366 case XML_distributed: maApiData.meHorJustify = csstab::CellHoriJustify_BLOCK; break; 1367 case XML_fill: maApiData.meHorJustify = csstab::CellHoriJustify_REPEAT; break; 1368 case XML_general: maApiData.meHorJustify = csstab::CellHoriJustify_STANDARD; break; 1369 case XML_justify: maApiData.meHorJustify = csstab::CellHoriJustify_BLOCK; break; 1370 case XML_left: maApiData.meHorJustify = csstab::CellHoriJustify_LEFT; break; 1371 case XML_right: maApiData.meHorJustify = csstab::CellHoriJustify_RIGHT; break; 1372 } 1373 1374 // vertical alignment 1375 switch( maModel.mnVerAlign ) 1376 { 1377 case XML_bottom: maApiData.meVerJustify = csstab::CellVertJustify_BOTTOM; break; 1378 case XML_center: maApiData.meVerJustify = csstab::CellVertJustify_CENTER; break; 1379 case XML_distributed: maApiData.meVerJustify = csstab::CellVertJustify_TOP; break; 1380 case XML_justify: maApiData.meVerJustify = csstab::CellVertJustify_TOP; break; 1381 case XML_top: maApiData.meVerJustify = csstab::CellVertJustify_TOP; break; 1382 } 1383 1384 /* indentation: expressed as number of blocks of 3 space characters in 1385 OOXML/BIFF12, and as multiple of 10 points in BIFF8. */ 1386 sal_Int32 nIndent = 0; 1387 switch( getFilterType() ) 1388 { 1389 case FILTER_OOXML: nIndent = getUnitConverter().scaleToMm100( 3.0 * maModel.mnIndent, UNIT_SPACE ); break; 1390 case FILTER_BIFF: nIndent = getUnitConverter().scaleToMm100( 10.0 * maModel.mnIndent, UNIT_POINT ); break; 1391 case FILTER_UNKNOWN: break; 1392 } 1393 if( (0 <= nIndent) && (nIndent <= SAL_MAX_INT16) ) 1394 maApiData.mnIndent = static_cast< sal_Int16 >( nIndent ); 1395 1396 // complex text direction 1397 switch( maModel.mnTextDir ) 1398 { 1399 case OOX_XF_TEXTDIR_CONTEXT: maApiData.mnWritingMode = csstxt::WritingMode2::PAGE; break; 1400 case OOX_XF_TEXTDIR_LTR: maApiData.mnWritingMode = csstxt::WritingMode2::LR_TB; break; 1401 case OOX_XF_TEXTDIR_RTL: maApiData.mnWritingMode = csstxt::WritingMode2::RL_TB; break; 1402 } 1403 1404 // rotation: 0-90 means 0 to 90 degrees ccw, 91-180 means 1 to 90 degrees cw, 255 means stacked 1405 sal_Int32 nOoxRot = maModel.mnRotation; 1406 maApiData.mnRotation = ((0 <= nOoxRot) && (nOoxRot <= 90)) ? 1407 (100 * nOoxRot) : 1408 (((91 <= nOoxRot) && (nOoxRot <= 180)) ? (100 * (450 - nOoxRot)) : 0); 1409 1410 // "Orientation" property used for character stacking 1411 maApiData.meOrientation = (nOoxRot == OOX_XF_ROTATION_STACKED) ? 1412 csstab::CellOrientation_STACKED : csstab::CellOrientation_STANDARD; 1413 1414 // alignment flags (#i84960 automatic line break, if vertically justified/distributed) 1415 maApiData.mbWrapText = maModel.mbWrapText || (maModel.mnVerAlign == XML_distributed) || (maModel.mnVerAlign == XML_justify); 1416 maApiData.mbShrink = maModel.mbShrink; 1417 1418 } 1419 1420 void Alignment::writeToPropertyMap( PropertyMap& rPropMap ) const 1421 { 1422 rPropMap[ PROP_HoriJustify ] <<= maApiData.meHorJustify; 1423 rPropMap[ PROP_VertJustify ] <<= maApiData.meVerJustify; 1424 rPropMap[ PROP_WritingMode ] <<= maApiData.mnWritingMode; 1425 rPropMap[ PROP_RotateAngle ] <<= maApiData.mnRotation; 1426 rPropMap[ PROP_Orientation ] <<= maApiData.meOrientation; 1427 rPropMap[ PROP_ParaIndent ] <<= maApiData.mnIndent; 1428 rPropMap[ PROP_IsTextWrapped ] <<= maApiData.mbWrapText; 1429 rPropMap[ PROP_ShrinkToFit ] <<= maApiData.mbShrink; 1430 } 1431 1432 // ============================================================================ 1433 1434 ProtectionModel::ProtectionModel() : 1435 mbLocked( true ), // default in Excel and Calc 1436 mbHidden( false ) 1437 { 1438 } 1439 1440 // ---------------------------------------------------------------------------- 1441 1442 ApiProtectionData::ApiProtectionData() : 1443 maCellProt( sal_True, sal_False, sal_False, sal_False ) 1444 { 1445 } 1446 1447 bool operator==( const ApiProtectionData& rLeft, const ApiProtectionData& rRight ) 1448 { 1449 return 1450 (rLeft.maCellProt.IsLocked == rRight.maCellProt.IsLocked) && 1451 (rLeft.maCellProt.IsFormulaHidden == rRight.maCellProt.IsFormulaHidden) && 1452 (rLeft.maCellProt.IsHidden == rRight.maCellProt.IsHidden) && 1453 (rLeft.maCellProt.IsPrintHidden == rRight.maCellProt.IsPrintHidden); 1454 } 1455 1456 // ============================================================================ 1457 1458 Protection::Protection( const WorkbookHelper& rHelper ) : 1459 WorkbookHelper( rHelper ) 1460 { 1461 } 1462 1463 void Protection::importProtection( const AttributeList& rAttribs ) 1464 { 1465 maModel.mbLocked = rAttribs.getBool( XML_locked, true ); 1466 maModel.mbHidden = rAttribs.getBool( XML_hidden, false ); 1467 } 1468 1469 void Protection::setBiff12Data( sal_uInt32 nFlags ) 1470 { 1471 maModel.mbLocked = getFlag( nFlags, BIFF12_XF_LOCKED ); 1472 maModel.mbHidden = getFlag( nFlags, BIFF12_XF_HIDDEN ); 1473 } 1474 1475 void Protection::setBiff2Data( sal_uInt8 nNumFmt ) 1476 { 1477 maModel.mbLocked = getFlag( nNumFmt, BIFF2_XF_LOCKED ); 1478 maModel.mbHidden = getFlag( nNumFmt, BIFF2_XF_HIDDEN ); 1479 } 1480 1481 void Protection::setBiff3Data( sal_uInt16 nProt ) 1482 { 1483 maModel.mbLocked = getFlag( nProt, BIFF_XF_LOCKED ); 1484 maModel.mbHidden = getFlag( nProt, BIFF_XF_HIDDEN ); 1485 } 1486 1487 void Protection::finalizeImport() 1488 { 1489 maApiData.maCellProt.IsLocked = maModel.mbLocked; 1490 maApiData.maCellProt.IsFormulaHidden = maModel.mbHidden; 1491 } 1492 1493 void Protection::writeToPropertyMap( PropertyMap& rPropMap ) const 1494 { 1495 rPropMap[ PROP_CellProtection ] <<= maApiData.maCellProt; 1496 } 1497 1498 // ============================================================================ 1499 1500 BorderLineModel::BorderLineModel( bool bDxf ) : 1501 mnStyle( XML_none ), 1502 mbUsed( !bDxf ) 1503 { 1504 maColor.setIndexed( OOX_COLOR_WINDOWTEXT ); 1505 } 1506 1507 void BorderLineModel::setBiffStyle( sal_Int32 nLineStyle ) 1508 { 1509 static const sal_Int32 spnStyleIds[] = { 1510 XML_none, XML_thin, XML_medium, XML_dashed, 1511 XML_dotted, XML_thick, XML_double, XML_hair, 1512 XML_mediumDashed, XML_dashDot, XML_mediumDashDot, XML_dashDotDot, 1513 XML_mediumDashDotDot, XML_slantDashDot }; 1514 mnStyle = STATIC_ARRAY_SELECT( spnStyleIds, nLineStyle, XML_none ); 1515 } 1516 1517 void BorderLineModel::setBiffData( sal_uInt8 nLineStyle, sal_uInt16 nLineColor ) 1518 { 1519 maColor.setIndexed( nLineColor ); 1520 setBiffStyle( nLineStyle ); 1521 } 1522 1523 // ---------------------------------------------------------------------------- 1524 1525 BorderModel::BorderModel( bool bDxf ) : 1526 maLeft( bDxf ), 1527 maRight( bDxf ), 1528 maTop( bDxf ), 1529 maBottom( bDxf ), 1530 maDiagonal( bDxf ), 1531 mbDiagTLtoBR( false ), 1532 mbDiagBLtoTR( false ) 1533 { 1534 } 1535 1536 // ---------------------------------------------------------------------------- 1537 1538 ApiBorderData::ApiBorderData() : 1539 mbBorderUsed( false ), 1540 mbDiagUsed( false ) 1541 { 1542 } 1543 1544 bool ApiBorderData::hasAnyOuterBorder() const 1545 { 1546 return 1547 (maBorder.IsTopLineValid && (maBorder.TopLine.OuterLineWidth > 0)) || 1548 (maBorder.IsBottomLineValid && (maBorder.BottomLine.OuterLineWidth > 0)) || 1549 (maBorder.IsLeftLineValid && (maBorder.LeftLine.OuterLineWidth > 0)) || 1550 (maBorder.IsRightLineValid && (maBorder.RightLine.OuterLineWidth > 0)); 1551 } 1552 1553 namespace { 1554 1555 bool operator==( const BorderLine& rLeft, const BorderLine& rRight ) 1556 { 1557 return 1558 (rLeft.Color == rRight.Color) && 1559 (rLeft.InnerLineWidth == rRight.InnerLineWidth) && 1560 (rLeft.OuterLineWidth == rRight.OuterLineWidth) && 1561 (rLeft.LineDistance == rRight.LineDistance); 1562 } 1563 1564 bool operator==( const TableBorder& rLeft, const TableBorder& rRight ) 1565 { 1566 return 1567 (rLeft.TopLine == rRight.TopLine) && 1568 (rLeft.IsTopLineValid == rRight.IsTopLineValid) && 1569 (rLeft.BottomLine == rRight.BottomLine) && 1570 (rLeft.IsBottomLineValid == rRight.IsBottomLineValid) && 1571 (rLeft.LeftLine == rRight.LeftLine) && 1572 (rLeft.IsLeftLineValid == rRight.IsLeftLineValid) && 1573 (rLeft.RightLine == rRight.RightLine) && 1574 (rLeft.IsRightLineValid == rRight.IsRightLineValid) && 1575 (rLeft.HorizontalLine == rRight.HorizontalLine) && 1576 (rLeft.IsHorizontalLineValid == rRight.IsHorizontalLineValid) && 1577 (rLeft.VerticalLine == rRight.VerticalLine) && 1578 (rLeft.IsVerticalLineValid == rRight.IsVerticalLineValid) && 1579 (rLeft.Distance == rRight.Distance) && 1580 (rLeft.IsDistanceValid == rRight.IsDistanceValid); 1581 } 1582 1583 } // namespace 1584 1585 bool operator==( const ApiBorderData& rLeft, const ApiBorderData& rRight ) 1586 { 1587 return 1588 (rLeft.maBorder == rRight.maBorder) && 1589 (rLeft.maTLtoBR == rRight.maTLtoBR) && 1590 (rLeft.maBLtoTR == rRight.maBLtoTR) && 1591 (rLeft.mbBorderUsed == rRight.mbBorderUsed) && 1592 (rLeft.mbDiagUsed == rRight.mbDiagUsed); 1593 } 1594 1595 // ============================================================================ 1596 1597 namespace { 1598 1599 inline void lclSetBorderLineWidth( BorderLine& rBorderLine, 1600 sal_Int16 nOuter, sal_Int16 nDist = API_LINE_NONE, sal_Int16 nInner = API_LINE_NONE ) 1601 { 1602 rBorderLine.OuterLineWidth = nOuter; 1603 rBorderLine.LineDistance = nDist; 1604 rBorderLine.InnerLineWidth = nInner; 1605 } 1606 1607 inline sal_Int32 lclGetBorderLineWidth( const BorderLine& rBorderLine ) 1608 { 1609 return rBorderLine.OuterLineWidth + rBorderLine.LineDistance + rBorderLine.InnerLineWidth; 1610 } 1611 1612 const BorderLine* lclGetThickerLine( const BorderLine& rBorderLine1, sal_Bool bValid1, const BorderLine& rBorderLine2, sal_Bool bValid2 ) 1613 { 1614 if( bValid1 && bValid2 ) 1615 return (lclGetBorderLineWidth( rBorderLine1 ) < lclGetBorderLineWidth( rBorderLine2 )) ? &rBorderLine2 : &rBorderLine1; 1616 if( bValid1 ) 1617 return &rBorderLine1; 1618 if( bValid2 ) 1619 return &rBorderLine2; 1620 return 0; 1621 } 1622 1623 } // namespace 1624 1625 // ---------------------------------------------------------------------------- 1626 1627 Border::Border( const WorkbookHelper& rHelper, bool bDxf ) : 1628 WorkbookHelper( rHelper ), 1629 maModel( bDxf ), 1630 mbDxf( bDxf ) 1631 { 1632 } 1633 1634 void Border::importBorder( const AttributeList& rAttribs ) 1635 { 1636 maModel.mbDiagTLtoBR = rAttribs.getBool( XML_diagonalDown, false ); 1637 maModel.mbDiagBLtoTR = rAttribs.getBool( XML_diagonalUp, false ); 1638 } 1639 1640 void Border::importStyle( sal_Int32 nElement, const AttributeList& rAttribs ) 1641 { 1642 if( BorderLineModel* pBorderLine = getBorderLine( nElement ) ) 1643 { 1644 pBorderLine->mnStyle = rAttribs.getToken( XML_style, XML_none ); 1645 pBorderLine->mbUsed = true; 1646 } 1647 } 1648 1649 void Border::importColor( sal_Int32 nElement, const AttributeList& rAttribs ) 1650 { 1651 if( BorderLineModel* pBorderLine = getBorderLine( nElement ) ) 1652 pBorderLine->maColor.importColor( rAttribs ); 1653 } 1654 1655 void Border::importBorder( SequenceInputStream& rStrm ) 1656 { 1657 sal_uInt8 nFlags = rStrm.readuInt8(); 1658 maModel.mbDiagTLtoBR = getFlag( nFlags, BIFF12_BORDER_DIAG_TLBR ); 1659 maModel.mbDiagBLtoTR = getFlag( nFlags, BIFF12_BORDER_DIAG_BLTR ); 1660 maModel.maTop.setBiffStyle( rStrm.readuInt16() ); 1661 rStrm >> maModel.maTop.maColor; 1662 maModel.maBottom.setBiffStyle( rStrm.readuInt16() ); 1663 rStrm >> maModel.maBottom.maColor; 1664 maModel.maLeft.setBiffStyle( rStrm.readuInt16() ); 1665 rStrm >> maModel.maLeft.maColor; 1666 maModel.maRight.setBiffStyle( rStrm.readuInt16() ); 1667 rStrm >> maModel.maRight.maColor; 1668 maModel.maDiagonal.setBiffStyle( rStrm.readuInt16() ); 1669 rStrm >> maModel.maDiagonal.maColor; 1670 } 1671 1672 void Border::importDxfBorder( sal_Int32 nElement, SequenceInputStream& rStrm ) 1673 { 1674 OSL_ENSURE( mbDxf, "Border::importDxfBorder - missing conditional formatting flag" ); 1675 if( BorderLineModel* pBorderLine = getBorderLine( nElement ) ) 1676 { 1677 sal_uInt16 nStyle; 1678 rStrm >> pBorderLine->maColor >> nStyle; 1679 pBorderLine->setBiffStyle( nStyle ); 1680 pBorderLine->mbUsed = true; 1681 } 1682 } 1683 1684 void Border::setBiff2Data( sal_uInt8 nFlags ) 1685 { 1686 OSL_ENSURE( !mbDxf, "Border::setBiff2Data - unexpected conditional formatting flag" ); 1687 maModel.maLeft.setBiffData( getFlagValue( nFlags, BIFF2_XF_LEFTLINE, BIFF_LINE_THIN, BIFF_LINE_NONE ), BIFF2_COLOR_BLACK ); 1688 maModel.maRight.setBiffData( getFlagValue( nFlags, BIFF2_XF_RIGHTLINE, BIFF_LINE_THIN, BIFF_LINE_NONE ), BIFF2_COLOR_BLACK ); 1689 maModel.maTop.setBiffData( getFlagValue( nFlags, BIFF2_XF_TOPLINE, BIFF_LINE_THIN, BIFF_LINE_NONE ), BIFF2_COLOR_BLACK ); 1690 maModel.maBottom.setBiffData( getFlagValue( nFlags, BIFF2_XF_BOTTOMLINE, BIFF_LINE_THIN, BIFF_LINE_NONE ), BIFF2_COLOR_BLACK ); 1691 maModel.maDiagonal.mbUsed = false; 1692 } 1693 1694 void Border::setBiff3Data( sal_uInt32 nBorder ) 1695 { 1696 OSL_ENSURE( !mbDxf, "Border::setBiff3Data - unexpected conditional formatting flag" ); 1697 maModel.maLeft.setBiffData( extractValue< sal_uInt8 >( nBorder, 8, 3 ), extractValue< sal_uInt16 >( nBorder, 11, 5 ) ); 1698 maModel.maRight.setBiffData( extractValue< sal_uInt8 >( nBorder, 24, 3 ), extractValue< sal_uInt16 >( nBorder, 27, 5 ) ); 1699 maModel.maTop.setBiffData( extractValue< sal_uInt8 >( nBorder, 0, 3 ), extractValue< sal_uInt16 >( nBorder, 3, 5 ) ); 1700 maModel.maBottom.setBiffData( extractValue< sal_uInt8 >( nBorder, 16, 3 ), extractValue< sal_uInt16 >( nBorder, 19, 5 ) ); 1701 maModel.maDiagonal.mbUsed = false; 1702 } 1703 1704 void Border::setBiff5Data( sal_uInt32 nBorder, sal_uInt32 nArea ) 1705 { 1706 OSL_ENSURE( !mbDxf, "Border::setBiff5Data - unexpected conditional formatting flag" ); 1707 maModel.maLeft.setBiffData( extractValue< sal_uInt8 >( nBorder, 3, 3 ), extractValue< sal_uInt16 >( nBorder, 16, 7 ) ); 1708 maModel.maRight.setBiffData( extractValue< sal_uInt8 >( nBorder, 6, 3 ), extractValue< sal_uInt16 >( nBorder, 23, 7 ) ); 1709 maModel.maTop.setBiffData( extractValue< sal_uInt8 >( nBorder, 0, 3 ), extractValue< sal_uInt16 >( nBorder, 9, 7 ) ); 1710 maModel.maBottom.setBiffData( extractValue< sal_uInt8 >( nArea, 22, 3 ), extractValue< sal_uInt16 >( nArea, 25, 7 ) ); 1711 maModel.maDiagonal.mbUsed = false; 1712 } 1713 1714 void Border::setBiff8Data( sal_uInt32 nBorder1, sal_uInt32 nBorder2 ) 1715 { 1716 OSL_ENSURE( !mbDxf, "Border::setBiff8Data - unexpected conditional formatting flag" ); 1717 maModel.maLeft.setBiffData( extractValue< sal_uInt8 >( nBorder1, 0, 4 ), extractValue< sal_uInt16 >( nBorder1, 16, 7 ) ); 1718 maModel.maRight.setBiffData( extractValue< sal_uInt8 >( nBorder1, 4, 4 ), extractValue< sal_uInt16 >( nBorder1, 23, 7 ) ); 1719 maModel.maTop.setBiffData( extractValue< sal_uInt8 >( nBorder1, 8, 4 ), extractValue< sal_uInt16 >( nBorder2, 0, 7 ) ); 1720 maModel.maBottom.setBiffData( extractValue< sal_uInt8 >( nBorder1, 12, 4 ), extractValue< sal_uInt16 >( nBorder2, 7, 7 ) ); 1721 maModel.mbDiagTLtoBR = getFlag( nBorder1, BIFF_XF_DIAG_TLBR ); 1722 maModel.mbDiagBLtoTR = getFlag( nBorder1, BIFF_XF_DIAG_BLTR ); 1723 if( maModel.mbDiagTLtoBR || maModel.mbDiagBLtoTR ) 1724 maModel.maDiagonal.setBiffData( extractValue< sal_uInt8 >( nBorder2, 21, 4 ), extractValue< sal_uInt16 >( nBorder2, 14, 7 ) ); 1725 } 1726 1727 void Border::importCfRule( BiffInputStream& rStrm, sal_uInt32 nFlags ) 1728 { 1729 OSL_ENSURE( mbDxf, "Border::importCfRule - missing conditional formatting flag" ); 1730 OSL_ENSURE( getFlag( nFlags, BIFF_CFRULE_BORDERBLOCK ), "Border::importCfRule - missing border block flag" ); 1731 sal_uInt16 nStyle; 1732 sal_uInt32 nColor; 1733 rStrm >> nStyle >> nColor; 1734 rStrm.skip( 2 ); 1735 maModel.maLeft.setBiffData( extractValue< sal_uInt8 >( nStyle, 0, 4 ), extractValue< sal_uInt16 >( nColor, 0, 7 ) ); 1736 maModel.maRight.setBiffData( extractValue< sal_uInt8 >( nStyle, 4, 4 ), extractValue< sal_uInt16 >( nColor, 7, 7 ) ); 1737 maModel.maTop.setBiffData( extractValue< sal_uInt8 >( nStyle, 8, 4 ), extractValue< sal_uInt16 >( nColor, 16, 7 ) ); 1738 maModel.maBottom.setBiffData( extractValue< sal_uInt8 >( nStyle, 12, 4 ), extractValue< sal_uInt16 >( nColor, 23, 7 ) ); 1739 maModel.maLeft.mbUsed = !getFlag( nFlags, BIFF_CFRULE_BORDER_LEFT ); 1740 maModel.maRight.mbUsed = !getFlag( nFlags, BIFF_CFRULE_BORDER_RIGHT ); 1741 maModel.maTop.mbUsed = !getFlag( nFlags, BIFF_CFRULE_BORDER_TOP ); 1742 maModel.maBottom.mbUsed = !getFlag( nFlags, BIFF_CFRULE_BORDER_BOTTOM ); 1743 } 1744 1745 void Border::finalizeImport() 1746 { 1747 maApiData.mbBorderUsed = maModel.maLeft.mbUsed || maModel.maRight.mbUsed || maModel.maTop.mbUsed || maModel.maBottom.mbUsed; 1748 maApiData.mbDiagUsed = maModel.maDiagonal.mbUsed; 1749 1750 maApiData.maBorder.IsLeftLineValid = convertBorderLine( maApiData.maBorder.LeftLine, maModel.maLeft ); 1751 maApiData.maBorder.IsRightLineValid = convertBorderLine( maApiData.maBorder.RightLine, maModel.maRight ); 1752 maApiData.maBorder.IsTopLineValid = convertBorderLine( maApiData.maBorder.TopLine, maModel.maTop ); 1753 maApiData.maBorder.IsBottomLineValid = convertBorderLine( maApiData.maBorder.BottomLine, maModel.maBottom ); 1754 1755 if( !mbDxf ) 1756 { 1757 maApiData.maBorder.IsVerticalLineValid = maApiData.maBorder.IsLeftLineValid || maApiData.maBorder.IsRightLineValid; 1758 if( const BorderLine* pVertLine = lclGetThickerLine( maApiData.maBorder.LeftLine, maApiData.maBorder.IsLeftLineValid, maApiData.maBorder.RightLine, maApiData.maBorder.IsRightLineValid ) ) 1759 maApiData.maBorder.VerticalLine = *pVertLine; 1760 1761 maApiData.maBorder.IsHorizontalLineValid = maApiData.maBorder.IsTopLineValid || maApiData.maBorder.IsBottomLineValid; 1762 if( const BorderLine* pHorLine = lclGetThickerLine( maApiData.maBorder.TopLine, maApiData.maBorder.IsTopLineValid, maApiData.maBorder.BottomLine, maApiData.maBorder.IsBottomLineValid ) ) 1763 maApiData.maBorder.HorizontalLine = *pHorLine; 1764 } 1765 1766 if( maModel.mbDiagTLtoBR ) 1767 convertBorderLine( maApiData.maTLtoBR, maModel.maDiagonal ); 1768 if( maModel.mbDiagBLtoTR ) 1769 convertBorderLine( maApiData.maBLtoTR, maModel.maDiagonal ); 1770 } 1771 1772 void Border::writeToPropertyMap( PropertyMap& rPropMap ) const 1773 { 1774 if( maApiData.mbBorderUsed ) 1775 rPropMap[ PROP_TableBorder ] <<= maApiData.maBorder; 1776 if( maApiData.mbDiagUsed ) 1777 { 1778 rPropMap[ PROP_DiagonalTLBR ] <<= maApiData.maTLtoBR; 1779 rPropMap[ PROP_DiagonalBLTR ] <<= maApiData.maBLtoTR; 1780 } 1781 } 1782 1783 BorderLineModel* Border::getBorderLine( sal_Int32 nElement ) 1784 { 1785 switch( nElement ) 1786 { 1787 case XLS_TOKEN( left ): return &maModel.maLeft; 1788 case XLS_TOKEN( right ): return &maModel.maRight; 1789 case XLS_TOKEN( top ): return &maModel.maTop; 1790 case XLS_TOKEN( bottom ): return &maModel.maBottom; 1791 case XLS_TOKEN( diagonal ): return &maModel.maDiagonal; 1792 } 1793 return 0; 1794 } 1795 1796 bool Border::convertBorderLine( BorderLine& rBorderLine, const BorderLineModel& rModel ) 1797 { 1798 rBorderLine.Color = rModel.maColor.getColor( getBaseFilter().getGraphicHelper(), API_RGB_BLACK ); 1799 switch( rModel.mnStyle ) 1800 { 1801 case XML_dashDot: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break; 1802 case XML_dashDotDot: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break; 1803 case XML_dashed: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break; 1804 case XML_dotted: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break; 1805 case XML_double: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN, API_LINE_THIN, API_LINE_THIN ); break; 1806 case XML_hair: lclSetBorderLineWidth( rBorderLine, API_LINE_HAIR ); break; 1807 case XML_medium: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break; 1808 case XML_mediumDashDot: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break; 1809 case XML_mediumDashDotDot: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break; 1810 case XML_mediumDashed: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break; 1811 case XML_none: lclSetBorderLineWidth( rBorderLine, API_LINE_NONE ); break; 1812 case XML_slantDashDot: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break; 1813 case XML_thick: lclSetBorderLineWidth( rBorderLine, API_LINE_THICK ); break; 1814 case XML_thin: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break; 1815 default: lclSetBorderLineWidth( rBorderLine, API_LINE_NONE ); break; 1816 } 1817 return rModel.mbUsed; 1818 } 1819 1820 1821 // ============================================================================ 1822 1823 PatternFillModel::PatternFillModel( bool bDxf ) : 1824 mnPattern( XML_none ), 1825 mbPattColorUsed( !bDxf ), 1826 mbFillColorUsed( !bDxf ), 1827 mbPatternUsed( !bDxf ) 1828 { 1829 maPatternColor.setIndexed( OOX_COLOR_WINDOWTEXT ); 1830 maFillColor.setIndexed( OOX_COLOR_WINDOWBACK ); 1831 } 1832 1833 void PatternFillModel::setBiffPattern( sal_Int32 nPattern ) 1834 { 1835 static const sal_Int32 spnPatternIds[] = { 1836 XML_none, XML_solid, XML_mediumGray, XML_darkGray, 1837 XML_lightGray, XML_darkHorizontal, XML_darkVertical, XML_darkDown, 1838 XML_darkUp, XML_darkGrid, XML_darkTrellis, XML_lightHorizontal, 1839 XML_lightVertical, XML_lightDown, XML_lightUp, XML_lightGrid, 1840 XML_lightTrellis, XML_gray125, XML_gray0625 }; 1841 mnPattern = STATIC_ARRAY_SELECT( spnPatternIds, nPattern, XML_none ); 1842 } 1843 1844 void PatternFillModel::setBiffData( sal_uInt16 nPatternColor, sal_uInt16 nFillColor, sal_uInt8 nPattern ) 1845 { 1846 maPatternColor.setIndexed( nPatternColor ); 1847 maFillColor.setIndexed( nFillColor ); 1848 // patterns equal in all BIFFs 1849 setBiffPattern( nPattern ); 1850 } 1851 1852 // ---------------------------------------------------------------------------- 1853 1854 GradientFillModel::GradientFillModel() : 1855 mnType( XML_linear ), 1856 mfAngle( 0.0 ), 1857 mfLeft( 0.0 ), 1858 mfRight( 0.0 ), 1859 mfTop( 0.0 ), 1860 mfBottom( 0.0 ) 1861 { 1862 } 1863 1864 void GradientFillModel::readGradient( SequenceInputStream& rStrm ) 1865 { 1866 sal_Int32 nType; 1867 rStrm >> nType >> mfAngle >> mfLeft >> mfRight >> mfTop >> mfBottom; 1868 static const sal_Int32 spnTypes[] = { XML_linear, XML_path }; 1869 mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_TOKEN_INVALID ); 1870 } 1871 1872 void GradientFillModel::readGradientStop( SequenceInputStream& rStrm, bool bDxf ) 1873 { 1874 Color aColor; 1875 double fPosition; 1876 if( bDxf ) 1877 { 1878 rStrm.skip( 2 ); 1879 rStrm >> fPosition >> aColor; 1880 } 1881 else 1882 { 1883 rStrm >> aColor >> fPosition; 1884 } 1885 if( !rStrm.isEof() && (fPosition >= 0.0) ) 1886 maColors[ fPosition ] = aColor; 1887 } 1888 1889 // ---------------------------------------------------------------------------- 1890 1891 ApiSolidFillData::ApiSolidFillData() : 1892 mnColor( API_RGB_TRANSPARENT ), 1893 mbTransparent( true ), 1894 mbUsed( false ) 1895 { 1896 } 1897 1898 bool operator==( const ApiSolidFillData& rLeft, const ApiSolidFillData& rRight ) 1899 { 1900 return 1901 (rLeft.mnColor == rRight.mnColor) && 1902 (rLeft.mbTransparent == rRight.mbTransparent) && 1903 (rLeft.mbUsed == rRight.mbUsed); 1904 } 1905 1906 // ============================================================================ 1907 1908 namespace { 1909 1910 inline sal_Int32 lclGetMixedColorComp( sal_Int32 nPatt, sal_Int32 nFill, sal_Int32 nAlpha ) 1911 { 1912 return ((nPatt - nFill) * nAlpha) / 0x80 + nFill; 1913 } 1914 1915 sal_Int32 lclGetMixedColor( sal_Int32 nPattColor, sal_Int32 nFillColor, sal_Int32 nAlpha ) 1916 { 1917 return 1918 (lclGetMixedColorComp( nPattColor & 0xFF0000, nFillColor & 0xFF0000, nAlpha ) & 0xFF0000) | 1919 (lclGetMixedColorComp( nPattColor & 0x00FF00, nFillColor & 0x00FF00, nAlpha ) & 0x00FF00) | 1920 (lclGetMixedColorComp( nPattColor & 0x0000FF, nFillColor & 0x0000FF, nAlpha ) & 0x0000FF); 1921 } 1922 1923 } // namespace 1924 1925 // ---------------------------------------------------------------------------- 1926 1927 Fill::Fill( const WorkbookHelper& rHelper, bool bDxf ) : 1928 WorkbookHelper( rHelper ), 1929 mbDxf( bDxf ) 1930 { 1931 } 1932 1933 void Fill::importPatternFill( const AttributeList& rAttribs ) 1934 { 1935 mxPatternModel.reset( new PatternFillModel( mbDxf ) ); 1936 mxPatternModel->mnPattern = rAttribs.getToken( XML_patternType, XML_none ); 1937 if( mbDxf ) 1938 mxPatternModel->mbPatternUsed = rAttribs.hasAttribute( XML_patternType ); 1939 } 1940 1941 void Fill::importFgColor( const AttributeList& rAttribs ) 1942 { 1943 OSL_ENSURE( mxPatternModel.get(), "Fill::importFgColor - missing pattern data" ); 1944 if( mxPatternModel.get() ) 1945 { 1946 mxPatternModel->maPatternColor.importColor( rAttribs ); 1947 mxPatternModel->mbPattColorUsed = true; 1948 } 1949 } 1950 1951 void Fill::importBgColor( const AttributeList& rAttribs ) 1952 { 1953 OSL_ENSURE( mxPatternModel.get(), "Fill::importBgColor - missing pattern data" ); 1954 if( mxPatternModel.get() ) 1955 { 1956 mxPatternModel->maFillColor.importColor( rAttribs ); 1957 mxPatternModel->mbFillColorUsed = true; 1958 } 1959 } 1960 1961 void Fill::importGradientFill( const AttributeList& rAttribs ) 1962 { 1963 mxGradientModel.reset( new GradientFillModel ); 1964 mxGradientModel->mnType = rAttribs.getToken( XML_type, XML_linear ); 1965 mxGradientModel->mfAngle = rAttribs.getDouble( XML_degree, 0.0 ); 1966 mxGradientModel->mfLeft = rAttribs.getDouble( XML_left, 0.0 ); 1967 mxGradientModel->mfRight = rAttribs.getDouble( XML_right, 0.0 ); 1968 mxGradientModel->mfTop = rAttribs.getDouble( XML_top, 0.0 ); 1969 mxGradientModel->mfBottom = rAttribs.getDouble( XML_bottom, 0.0 ); 1970 } 1971 1972 void Fill::importColor( const AttributeList& rAttribs, double fPosition ) 1973 { 1974 OSL_ENSURE( mxGradientModel.get(), "Fill::importColor - missing gradient data" ); 1975 if( mxGradientModel.get() && (fPosition >= 0.0) ) 1976 mxGradientModel->maColors[ fPosition ].importColor( rAttribs ); 1977 } 1978 1979 void Fill::importFill( SequenceInputStream& rStrm ) 1980 { 1981 OSL_ENSURE( !mbDxf, "Fill::importFill - unexpected conditional formatting flag" ); 1982 sal_Int32 nPattern = rStrm.readInt32(); 1983 if( nPattern == BIFF12_FILL_GRADIENT ) 1984 { 1985 mxGradientModel.reset( new GradientFillModel ); 1986 sal_Int32 nStopCount; 1987 rStrm.skip( 16 ); 1988 mxGradientModel->readGradient( rStrm ); 1989 rStrm >> nStopCount; 1990 for( sal_Int32 nStop = 0; (nStop < nStopCount) && !rStrm.isEof(); ++nStop ) 1991 mxGradientModel->readGradientStop( rStrm, false ); 1992 } 1993 else 1994 { 1995 mxPatternModel.reset( new PatternFillModel( mbDxf ) ); 1996 mxPatternModel->setBiffPattern( nPattern ); 1997 rStrm >> mxPatternModel->maPatternColor >> mxPatternModel->maFillColor; 1998 } 1999 } 2000 2001 void Fill::importDxfPattern( SequenceInputStream& rStrm ) 2002 { 2003 OSL_ENSURE( mbDxf, "Fill::importDxfPattern - missing conditional formatting flag" ); 2004 if( !mxPatternModel ) 2005 mxPatternModel.reset( new PatternFillModel( mbDxf ) ); 2006 mxPatternModel->setBiffPattern( rStrm.readuInt8() ); 2007 mxPatternModel->mbPatternUsed = true; 2008 } 2009 2010 void Fill::importDxfFgColor( SequenceInputStream& rStrm ) 2011 { 2012 OSL_ENSURE( mbDxf, "Fill::importDxfFgColor - missing conditional formatting flag" ); 2013 if( !mxPatternModel ) 2014 mxPatternModel.reset( new PatternFillModel( mbDxf ) ); 2015 mxPatternModel->maPatternColor.importColor( rStrm ); 2016 mxPatternModel->mbPattColorUsed = true; 2017 } 2018 2019 void Fill::importDxfBgColor( SequenceInputStream& rStrm ) 2020 { 2021 OSL_ENSURE( mbDxf, "Fill::importDxfBgColor - missing conditional formatting flag" ); 2022 if( !mxPatternModel ) 2023 mxPatternModel.reset( new PatternFillModel( mbDxf ) ); 2024 mxPatternModel->maFillColor.importColor( rStrm ); 2025 mxPatternModel->mbFillColorUsed = true; 2026 } 2027 2028 void Fill::importDxfGradient( SequenceInputStream& rStrm ) 2029 { 2030 OSL_ENSURE( mbDxf, "Fill::importDxfGradient - missing conditional formatting flag" ); 2031 if( !mxGradientModel ) 2032 mxGradientModel.reset( new GradientFillModel ); 2033 mxGradientModel->readGradient( rStrm ); 2034 } 2035 2036 void Fill::importDxfStop( SequenceInputStream& rStrm ) 2037 { 2038 OSL_ENSURE( mbDxf, "Fill::importDxfStop - missing conditional formatting flag" ); 2039 if( !mxGradientModel ) 2040 mxGradientModel.reset( new GradientFillModel ); 2041 mxGradientModel->readGradientStop( rStrm, true ); 2042 } 2043 2044 void Fill::setBiff2Data( sal_uInt8 nFlags ) 2045 { 2046 OSL_ENSURE( !mbDxf, "Fill::setBiff2Data - unexpected conditional formatting flag" ); 2047 mxPatternModel.reset( new PatternFillModel( mbDxf ) ); 2048 mxPatternModel->setBiffData( 2049 BIFF2_COLOR_BLACK, 2050 BIFF2_COLOR_WHITE, 2051 getFlagValue( nFlags, BIFF2_XF_BACKGROUND, BIFF_PATT_125, BIFF_PATT_NONE ) ); 2052 } 2053 2054 void Fill::setBiff3Data( sal_uInt16 nArea ) 2055 { 2056 OSL_ENSURE( !mbDxf, "Fill::setBiff3Data - unexpected conditional formatting flag" ); 2057 mxPatternModel.reset( new PatternFillModel( mbDxf ) ); 2058 mxPatternModel->setBiffData( 2059 extractValue< sal_uInt16 >( nArea, 6, 5 ), 2060 extractValue< sal_uInt16 >( nArea, 11, 5 ), 2061 extractValue< sal_uInt8 >( nArea, 0, 6 ) ); 2062 } 2063 2064 void Fill::setBiff5Data( sal_uInt32 nArea ) 2065 { 2066 OSL_ENSURE( !mbDxf, "Fill::setBiff5Data - unexpected conditional formatting flag" ); 2067 mxPatternModel.reset( new PatternFillModel( mbDxf ) ); 2068 mxPatternModel->setBiffData( 2069 extractValue< sal_uInt16 >( nArea, 0, 7 ), 2070 extractValue< sal_uInt16 >( nArea, 7, 7 ), 2071 extractValue< sal_uInt8 >( nArea, 16, 6 ) ); 2072 } 2073 2074 void Fill::setBiff8Data( sal_uInt32 nBorder2, sal_uInt16 nArea ) 2075 { 2076 OSL_ENSURE( !mbDxf, "Fill::setBiff8Data - unexpected conditional formatting flag" ); 2077 mxPatternModel.reset( new PatternFillModel( mbDxf ) ); 2078 mxPatternModel->setBiffData( 2079 extractValue< sal_uInt16 >( nArea, 0, 7 ), 2080 extractValue< sal_uInt16 >( nArea, 7, 7 ), 2081 extractValue< sal_uInt8 >( nBorder2, 26, 6 ) ); 2082 } 2083 2084 void Fill::importCfRule( BiffInputStream& rStrm, sal_uInt32 nFlags ) 2085 { 2086 OSL_ENSURE( mbDxf, "Fill::importCfRule - missing conditional formatting flag" ); 2087 OSL_ENSURE( getFlag( nFlags, BIFF_CFRULE_FILLBLOCK ), "Fill::importCfRule - missing fill block flag" ); 2088 mxPatternModel.reset( new PatternFillModel( mbDxf ) ); 2089 sal_uInt32 nFillData; 2090 rStrm >> nFillData; 2091 mxPatternModel->setBiffData( 2092 extractValue< sal_uInt16 >( nFillData, 16, 7 ), 2093 extractValue< sal_uInt16 >( nFillData, 23, 7 ), 2094 extractValue< sal_uInt8 >( nFillData, 10, 6 ) ); 2095 mxPatternModel->mbPattColorUsed = !getFlag( nFlags, BIFF_CFRULE_FILL_PATTCOLOR ); 2096 mxPatternModel->mbFillColorUsed = !getFlag( nFlags, BIFF_CFRULE_FILL_FILLCOLOR ); 2097 mxPatternModel->mbPatternUsed = !getFlag( nFlags, BIFF_CFRULE_FILL_PATTERN ); 2098 } 2099 2100 void Fill::finalizeImport() 2101 { 2102 const GraphicHelper& rGraphicHelper = getBaseFilter().getGraphicHelper(); 2103 2104 if( mxPatternModel.get() ) 2105 { 2106 // finalize the OOXML data struct 2107 PatternFillModel& rModel = *mxPatternModel; 2108 if( mbDxf ) 2109 { 2110 if( rModel.mbFillColorUsed && (!rModel.mbPatternUsed || (rModel.mnPattern == XML_solid)) ) 2111 { 2112 rModel.maPatternColor = rModel.maFillColor; 2113 rModel.mnPattern = XML_solid; 2114 rModel.mbPattColorUsed = rModel.mbPatternUsed = true; 2115 } 2116 else if( !rModel.mbFillColorUsed && rModel.mbPatternUsed && (rModel.mnPattern == XML_solid) ) 2117 { 2118 rModel.mbPatternUsed = false; 2119 } 2120 } 2121 2122 // convert to API fill settings 2123 maApiData.mbUsed = rModel.mbPatternUsed; 2124 if( rModel.mnPattern == XML_none ) 2125 { 2126 maApiData.mnColor = API_RGB_TRANSPARENT; 2127 maApiData.mbTransparent = true; 2128 } 2129 else 2130 { 2131 sal_Int32 nAlpha = 0x80; 2132 switch( rModel.mnPattern ) 2133 { 2134 case XML_darkDown: nAlpha = 0x40; break; 2135 case XML_darkGray: nAlpha = 0x60; break; 2136 case XML_darkGrid: nAlpha = 0x40; break; 2137 case XML_darkHorizontal: nAlpha = 0x40; break; 2138 case XML_darkTrellis: nAlpha = 0x60; break; 2139 case XML_darkUp: nAlpha = 0x40; break; 2140 case XML_darkVertical: nAlpha = 0x40; break; 2141 case XML_gray0625: nAlpha = 0x08; break; 2142 case XML_gray125: nAlpha = 0x10; break; 2143 case XML_lightDown: nAlpha = 0x20; break; 2144 case XML_lightGray: nAlpha = 0x20; break; 2145 case XML_lightGrid: nAlpha = 0x38; break; 2146 case XML_lightHorizontal: nAlpha = 0x20; break; 2147 case XML_lightTrellis: nAlpha = 0x30; break; 2148 case XML_lightUp: nAlpha = 0x20; break; 2149 case XML_lightVertical: nAlpha = 0x20; break; 2150 case XML_mediumGray: nAlpha = 0x40; break; 2151 case XML_solid: nAlpha = 0x80; break; 2152 } 2153 2154 sal_Int32 nWinTextColor = rGraphicHelper.getSystemColor( XML_windowText ); 2155 sal_Int32 nWinColor = rGraphicHelper.getSystemColor( XML_window ); 2156 2157 if( !rModel.mbPattColorUsed ) 2158 rModel.maPatternColor.setAuto(); 2159 sal_Int32 nPattColor = rModel.maPatternColor.getColor( rGraphicHelper, nWinTextColor ); 2160 2161 if( !rModel.mbFillColorUsed ) 2162 rModel.maFillColor.setAuto(); 2163 sal_Int32 nFillColor = rModel.maFillColor.getColor( rGraphicHelper, nWinColor ); 2164 2165 maApiData.mnColor = lclGetMixedColor( nPattColor, nFillColor, nAlpha ); 2166 maApiData.mbTransparent = false; 2167 } 2168 } 2169 else if( mxGradientModel.get() && !mxGradientModel->maColors.empty() ) 2170 { 2171 GradientFillModel& rModel = *mxGradientModel; 2172 maApiData.mbUsed = true; // no support for differential attributes 2173 GradientFillModel::ColorMap::const_iterator aIt = rModel.maColors.begin(); 2174 OSL_ENSURE( !aIt->second.isAuto(), "Fill::finalizeImport - automatic gradient color" ); 2175 maApiData.mnColor = aIt->second.getColor( rGraphicHelper, API_RGB_WHITE ); 2176 if( ++aIt != rModel.maColors.end() ) 2177 { 2178 OSL_ENSURE( !aIt->second.isAuto(), "Fill::finalizeImport - automatic gradient color" ); 2179 sal_Int32 nEndColor = aIt->second.getColor( rGraphicHelper, API_RGB_WHITE ); 2180 maApiData.mnColor = lclGetMixedColor( maApiData.mnColor, nEndColor, 0x40 ); 2181 maApiData.mbTransparent = false; 2182 } 2183 } 2184 } 2185 2186 void Fill::writeToPropertyMap( PropertyMap& rPropMap ) const 2187 { 2188 if( maApiData.mbUsed ) 2189 { 2190 rPropMap[ PROP_CellBackColor ] <<= maApiData.mnColor; 2191 rPropMap[ PROP_IsCellBackgroundTransparent ] <<= maApiData.mbTransparent; 2192 } 2193 } 2194 2195 // ============================================================================ 2196 2197 XfModel::XfModel() : 2198 mnStyleXfId( -1 ), 2199 mnFontId( -1 ), 2200 mnNumFmtId( -1 ), 2201 mnBorderId( -1 ), 2202 mnFillId( -1 ), 2203 mbCellXf( true ), 2204 mbFontUsed( false ), 2205 mbNumFmtUsed( false ), 2206 mbAlignUsed( false ), 2207 mbProtUsed( false ), 2208 mbBorderUsed( false ), 2209 mbAreaUsed( false ) 2210 { 2211 } 2212 2213 // ============================================================================ 2214 2215 Xf::Xf( const WorkbookHelper& rHelper ) : 2216 WorkbookHelper( rHelper ), 2217 maAlignment( rHelper ), 2218 maProtection( rHelper ), 2219 meRotationRef( ::com::sun::star::table::CellVertJustify_STANDARD ) 2220 { 2221 } 2222 2223 void Xf::setAllUsedFlags( bool bUsed ) 2224 { 2225 maModel.mbAlignUsed = maModel.mbProtUsed = maModel.mbFontUsed = 2226 maModel.mbNumFmtUsed = maModel.mbBorderUsed = maModel.mbAreaUsed = bUsed; 2227 } 2228 2229 void Xf::importXf( const AttributeList& rAttribs, bool bCellXf ) 2230 { 2231 maModel.mbCellXf = bCellXf; 2232 maModel.mnStyleXfId = rAttribs.getInteger( XML_xfId, -1 ); 2233 maModel.mnFontId = rAttribs.getInteger( XML_fontId, -1 ); 2234 maModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, -1 ); 2235 maModel.mnBorderId = rAttribs.getInteger( XML_borderId, -1 ); 2236 maModel.mnFillId = rAttribs.getInteger( XML_fillId, -1 ); 2237 2238 /* Default value of the apply*** attributes is dependent on context: 2239 true in cellStyleXfs element, false in cellXfs element... */ 2240 maModel.mbAlignUsed = rAttribs.getBool( XML_applyAlignment, !maModel.mbCellXf ); 2241 maModel.mbProtUsed = rAttribs.getBool( XML_applyProtection, !maModel.mbCellXf ); 2242 maModel.mbFontUsed = rAttribs.getBool( XML_applyFont, !maModel.mbCellXf ); 2243 maModel.mbNumFmtUsed = rAttribs.getBool( XML_applyNumberFormat, !maModel.mbCellXf ); 2244 maModel.mbBorderUsed = rAttribs.getBool( XML_applyBorder, !maModel.mbCellXf ); 2245 maModel.mbAreaUsed = rAttribs.getBool( XML_applyFill, !maModel.mbCellXf ); 2246 } 2247 2248 void Xf::importAlignment( const AttributeList& rAttribs ) 2249 { 2250 maAlignment.importAlignment( rAttribs ); 2251 } 2252 2253 void Xf::importProtection( const AttributeList& rAttribs ) 2254 { 2255 maProtection.importProtection( rAttribs ); 2256 } 2257 2258 void Xf::importXf( SequenceInputStream& rStrm, bool bCellXf ) 2259 { 2260 maModel.mbCellXf = bCellXf; 2261 maModel.mnStyleXfId = rStrm.readuInt16(); 2262 maModel.mnNumFmtId = rStrm.readuInt16(); 2263 maModel.mnFontId = rStrm.readuInt16(); 2264 maModel.mnFillId = rStrm.readuInt16(); 2265 maModel.mnBorderId = rStrm.readuInt16(); 2266 sal_uInt32 nFlags = rStrm.readuInt32(); 2267 maAlignment.setBiff12Data( nFlags ); 2268 maProtection.setBiff12Data( nFlags ); 2269 // used flags, see comments in Xf::setBiffUsedFlags() 2270 sal_uInt16 nUsedFlags = rStrm.readuInt16(); 2271 maModel.mbFontUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_FONT_USED ); 2272 maModel.mbNumFmtUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_NUMFMT_USED ); 2273 maModel.mbAlignUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_ALIGN_USED ); 2274 maModel.mbProtUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_PROT_USED ); 2275 maModel.mbBorderUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_BORDER_USED ); 2276 maModel.mbAreaUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_AREA_USED ); 2277 } 2278 2279 void Xf::importXf( BiffInputStream& rStrm ) 2280 { 2281 BorderRef xBorder = getStyles().createBorder( &maModel.mnBorderId ); 2282 FillRef xFill = getStyles().createFill( &maModel.mnFillId ); 2283 2284 switch( getBiff() ) 2285 { 2286 case BIFF2: 2287 { 2288 sal_uInt8 nFontId, nNumFmtId, nFlags; 2289 rStrm >> nFontId; 2290 rStrm.skip( 1 ); 2291 rStrm >> nNumFmtId >> nFlags; 2292 2293 // only cell XFs in BIFF2, no parent style, used flags always true 2294 setAllUsedFlags( true ); 2295 2296 // attributes 2297 maAlignment.setBiff2Data( nFlags ); 2298 maProtection.setBiff2Data( nNumFmtId ); 2299 xBorder->setBiff2Data( nFlags ); 2300 xFill->setBiff2Data( nFlags ); 2301 maModel.mnFontId = static_cast< sal_Int32 >( nFontId ); 2302 maModel.mnNumFmtId = static_cast< sal_Int32 >( nNumFmtId & BIFF2_XF_VALFMT_MASK ); 2303 } 2304 break; 2305 2306 case BIFF3: 2307 { 2308 sal_uInt32 nBorder; 2309 sal_uInt16 nTypeProt, nAlign, nArea; 2310 sal_uInt8 nFontId, nNumFmtId; 2311 rStrm >> nFontId >> nNumFmtId >> nTypeProt >> nAlign >> nArea >> nBorder; 2312 2313 // XF type/parent 2314 maModel.mbCellXf = !getFlag( nTypeProt, BIFF_XF_STYLE ); // new in BIFF3 2315 maModel.mnStyleXfId = extractValue< sal_Int32 >( nAlign, 4, 12 ); // new in BIFF3 2316 // attribute used flags 2317 setBiffUsedFlags( extractValue< sal_uInt8 >( nTypeProt, 10, 6 ) ); // new in BIFF3 2318 2319 // attributes 2320 maAlignment.setBiff3Data( nAlign ); 2321 maProtection.setBiff3Data( nTypeProt ); 2322 xBorder->setBiff3Data( nBorder ); 2323 xFill->setBiff3Data( nArea ); 2324 maModel.mnFontId = static_cast< sal_Int32 >( nFontId ); 2325 maModel.mnNumFmtId = static_cast< sal_Int32 >( nNumFmtId ); 2326 } 2327 break; 2328 2329 case BIFF4: 2330 { 2331 sal_uInt32 nBorder; 2332 sal_uInt16 nTypeProt, nAlign, nArea; 2333 sal_uInt8 nFontId, nNumFmtId; 2334 rStrm >> nFontId >> nNumFmtId >> nTypeProt >> nAlign >> nArea >> nBorder; 2335 2336 // XF type/parent 2337 maModel.mbCellXf = !getFlag( nTypeProt, BIFF_XF_STYLE ); 2338 maModel.mnStyleXfId = extractValue< sal_Int32 >( nTypeProt, 4, 12 ); 2339 // attribute used flags 2340 setBiffUsedFlags( extractValue< sal_uInt8 >( nAlign, 10, 6 ) ); 2341 2342 // attributes 2343 maAlignment.setBiff4Data( nAlign ); 2344 maProtection.setBiff3Data( nTypeProt ); 2345 xBorder->setBiff3Data( nBorder ); 2346 xFill->setBiff3Data( nArea ); 2347 maModel.mnFontId = static_cast< sal_Int32 >( nFontId ); 2348 maModel.mnNumFmtId = static_cast< sal_Int32 >( nNumFmtId ); 2349 } 2350 break; 2351 2352 case BIFF5: 2353 { 2354 sal_uInt32 nArea, nBorder; 2355 sal_uInt16 nFontId, nNumFmtId, nTypeProt, nAlign; 2356 rStrm >> nFontId >> nNumFmtId >> nTypeProt >> nAlign >> nArea >> nBorder; 2357 2358 // XF type/parent 2359 maModel.mbCellXf = !getFlag( nTypeProt, BIFF_XF_STYLE ); 2360 maModel.mnStyleXfId = extractValue< sal_Int32 >( nTypeProt, 4, 12 ); 2361 // attribute used flags 2362 setBiffUsedFlags( extractValue< sal_uInt8 >( nAlign, 10, 6 ) ); 2363 2364 // attributes 2365 maAlignment.setBiff5Data( nAlign ); 2366 maProtection.setBiff3Data( nTypeProt ); 2367 xBorder->setBiff5Data( nBorder, nArea ); 2368 xFill->setBiff5Data( nArea ); 2369 maModel.mnFontId = static_cast< sal_Int32 >( nFontId ); 2370 maModel.mnNumFmtId = static_cast< sal_Int32 >( nNumFmtId ); 2371 } 2372 break; 2373 2374 case BIFF8: 2375 { 2376 sal_uInt32 nBorder1, nBorder2; 2377 sal_uInt16 nFontId, nNumFmtId, nTypeProt, nAlign, nMiscAttrib, nArea; 2378 rStrm >> nFontId >> nNumFmtId >> nTypeProt >> nAlign >> nMiscAttrib >> nBorder1 >> nBorder2 >> nArea; 2379 2380 // XF type/parent 2381 maModel.mbCellXf = !getFlag( nTypeProt, BIFF_XF_STYLE ); 2382 maModel.mnStyleXfId = extractValue< sal_Int32 >( nTypeProt, 4, 12 ); 2383 // attribute used flags 2384 setBiffUsedFlags( extractValue< sal_uInt8 >( nMiscAttrib, 10, 6 ) ); 2385 2386 // attributes 2387 maAlignment.setBiff8Data( nAlign, nMiscAttrib ); 2388 maProtection.setBiff3Data( nTypeProt ); 2389 xBorder->setBiff8Data( nBorder1, nBorder2 ); 2390 xFill->setBiff8Data( nBorder2, nArea ); 2391 maModel.mnFontId = static_cast< sal_Int32 >( nFontId ); 2392 maModel.mnNumFmtId = static_cast< sal_Int32 >( nNumFmtId ); 2393 } 2394 break; 2395 2396 case BIFF_UNKNOWN: break; 2397 } 2398 } 2399 2400 void Xf::finalizeImport() 2401 { 2402 StylesBuffer& rStyles = getStyles(); 2403 2404 // alignment and protection 2405 maAlignment.finalizeImport(); 2406 maProtection.finalizeImport(); 2407 2408 /* Enables the used flags, if the formatting attributes differ from the 2409 style XF. In cell XFs Excel uses the cell attributes, if they differ 2410 from the parent style XF (even if the used flag is switched off). 2411 #109899# ...or if the respective flag is not set in parent style XF. 2412 */ 2413 const Xf* pStyleXf = isCellXf() ? rStyles.getStyleXf( maModel.mnStyleXfId ).get() : 0; 2414 if( pStyleXf ) 2415 { 2416 const XfModel& rStyleData = pStyleXf->maModel; 2417 if( !maModel.mbFontUsed ) 2418 maModel.mbFontUsed = !rStyleData.mbFontUsed || (maModel.mnFontId != rStyleData.mnFontId); 2419 if( !maModel.mbNumFmtUsed ) 2420 maModel.mbNumFmtUsed = !rStyleData.mbNumFmtUsed || (maModel.mnNumFmtId != rStyleData.mnNumFmtId); 2421 if( !maModel.mbAlignUsed ) 2422 maModel.mbAlignUsed = !rStyleData.mbAlignUsed || !(maAlignment.getApiData() == pStyleXf->maAlignment.getApiData()); 2423 if( !maModel.mbProtUsed ) 2424 maModel.mbProtUsed = !rStyleData.mbProtUsed || !(maProtection.getApiData() == pStyleXf->maProtection.getApiData()); 2425 if( !maModel.mbBorderUsed ) 2426 maModel.mbBorderUsed = !rStyleData.mbBorderUsed || !rStyles.equalBorders( maModel.mnBorderId, rStyleData.mnBorderId ); 2427 if( !maModel.mbAreaUsed ) 2428 maModel.mbAreaUsed = !rStyleData.mbAreaUsed || !rStyles.equalFills( maModel.mnFillId, rStyleData.mnFillId ); 2429 } 2430 2431 /* #i38709# Decide which rotation reference mode to use. If any outer 2432 border line of the cell is set (either explicitly or via cell style), 2433 and the cell contents are rotated, set rotation reference to bottom of 2434 cell. This causes the borders to be painted rotated with the text. */ 2435 if( const Alignment* pAlignment = maModel.mbAlignUsed ? &maAlignment : (pStyleXf ? &pStyleXf->maAlignment : 0) ) 2436 { 2437 sal_Int32 nBorderId = maModel.mbBorderUsed ? maModel.mnBorderId : (pStyleXf ? pStyleXf->maModel.mnBorderId : -1); 2438 if( const Border* pBorder = rStyles.getBorder( nBorderId ).get() ) 2439 if( (pAlignment->getApiData().mnRotation != 0) && pBorder->getApiData().hasAnyOuterBorder() ) 2440 meRotationRef = ::com::sun::star::table::CellVertJustify_BOTTOM; 2441 } 2442 } 2443 2444 FontRef Xf::getFont() const 2445 { 2446 return getStyles().getFont( maModel.mnFontId ); 2447 } 2448 2449 bool Xf::hasAnyUsedFlags() const 2450 { 2451 return 2452 maModel.mbAlignUsed || maModel.mbProtUsed || maModel.mbFontUsed || 2453 maModel.mbNumFmtUsed || maModel.mbBorderUsed || maModel.mbAreaUsed; 2454 } 2455 2456 void Xf::writeToPropertyMap( PropertyMap& rPropMap ) const 2457 { 2458 StylesBuffer& rStyles = getStyles(); 2459 2460 // create and set cell style 2461 if( isCellXf() ) 2462 rPropMap[ PROP_CellStyle ] <<= rStyles.createCellStyle( maModel.mnStyleXfId ); 2463 2464 if( maModel.mbFontUsed ) 2465 rStyles.writeFontToPropertyMap( rPropMap, maModel.mnFontId ); 2466 if( maModel.mbNumFmtUsed ) 2467 rStyles.writeNumFmtToPropertyMap( rPropMap, maModel.mnNumFmtId ); 2468 if( maModel.mbAlignUsed ) 2469 maAlignment.writeToPropertyMap( rPropMap ); 2470 if( maModel.mbProtUsed ) 2471 maProtection.writeToPropertyMap( rPropMap ); 2472 if( maModel.mbBorderUsed ) 2473 rStyles.writeBorderToPropertyMap( rPropMap, maModel.mnBorderId ); 2474 if( maModel.mbAreaUsed ) 2475 rStyles.writeFillToPropertyMap( rPropMap, maModel.mnFillId ); 2476 if( maModel.mbAlignUsed || maModel.mbBorderUsed ) 2477 rPropMap[ PROP_RotateReference ] <<= meRotationRef; 2478 } 2479 2480 void Xf::writeToPropertySet( PropertySet& rPropSet ) const 2481 { 2482 PropertyMap aPropMap; 2483 writeToPropertyMap( aPropMap ); 2484 rPropSet.setProperties( aPropMap ); 2485 } 2486 2487 /*static*/ void Xf::writeBiff2CellFormatToPropertySet( const WorkbookHelper& rHelper, 2488 PropertySet& rPropSet, sal_uInt8 nFlags1, sal_uInt8 nFlags2, sal_uInt8 nFlags3 ) 2489 { 2490 /* Create an XF object and let it do the work. We will have access to its 2491 private members here. Also, create temporary border and fill objects, 2492 this prevents polluting the border and fill buffers with new temporary 2493 objects per imported cell. */ 2494 Xf aXf( rHelper ); 2495 Border aBorder( rHelper, false ); 2496 Fill aFill( rHelper, false ); 2497 2498 // no used flags available in BIFF2 (always true) 2499 aXf.setAllUsedFlags( true ); 2500 2501 // set the attributes 2502 aXf.maModel.mnFontId = extractValue< sal_Int32 >( nFlags2, 6, 2 ); 2503 aXf.maModel.mnNumFmtId = extractValue< sal_Int32 >( nFlags2, 0, 6 ); 2504 aXf.maAlignment.setBiff2Data( nFlags3 ); 2505 aXf.maProtection.setBiff2Data( nFlags1 ); 2506 aBorder.setBiff2Data( nFlags3 ); 2507 aFill.setBiff2Data( nFlags3 ); 2508 2509 // finalize the objects (convert model to API attributes) 2510 aXf.finalizeImport(); 2511 aBorder.finalizeImport(); 2512 aFill.finalizeImport(); 2513 2514 // write the properties to the property set 2515 PropertyMap aPropMap; 2516 aXf.writeToPropertyMap( aPropMap ); 2517 aBorder.writeToPropertyMap( aPropMap ); 2518 aFill.writeToPropertyMap( aPropMap ); 2519 rPropSet.setProperties( aPropMap ); 2520 } 2521 2522 void Xf::setBiffUsedFlags( sal_uInt8 nUsedFlags ) 2523 { 2524 /* Notes about finding the used flags: 2525 - In cell XFs a *set* bit means a used attribute. 2526 - In style XFs a *cleared* bit means a used attribute. 2527 The boolean flags always store true, if the attribute is used. 2528 The "isCellXf() == getFlag(...)" construct evaluates to true in both 2529 mentioned cases: cell XF and set bit; or style XF and cleared bit. 2530 */ 2531 maModel.mbFontUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_FONT_USED ); 2532 maModel.mbNumFmtUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_NUMFMT_USED ); 2533 maModel.mbAlignUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_ALIGN_USED ); 2534 maModel.mbProtUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_PROT_USED ); 2535 maModel.mbBorderUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_BORDER_USED ); 2536 maModel.mbAreaUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_AREA_USED ); 2537 } 2538 2539 // ============================================================================ 2540 2541 Dxf::Dxf( const WorkbookHelper& rHelper ) : 2542 WorkbookHelper( rHelper ) 2543 { 2544 } 2545 2546 FontRef Dxf::createFont( bool bAlwaysNew ) 2547 { 2548 if( bAlwaysNew || !mxFont ) 2549 mxFont.reset( new Font( *this, true ) ); 2550 return mxFont; 2551 } 2552 2553 BorderRef Dxf::createBorder( bool bAlwaysNew ) 2554 { 2555 if( bAlwaysNew || !mxBorder ) 2556 mxBorder.reset( new Border( *this, true ) ); 2557 return mxBorder; 2558 } 2559 2560 FillRef Dxf::createFill( bool bAlwaysNew ) 2561 { 2562 if( bAlwaysNew || !mxFill ) 2563 mxFill.reset( new Fill( *this, true ) ); 2564 return mxFill; 2565 } 2566 2567 void Dxf::importNumFmt( const AttributeList& rAttribs ) 2568 { 2569 mxNumFmt = getStyles().importNumFmt( rAttribs ); 2570 } 2571 2572 void Dxf::importAlignment( const AttributeList& rAttribs ) 2573 { 2574 mxAlignment.reset( new Alignment( *this ) ); 2575 mxAlignment->importAlignment( rAttribs ); 2576 } 2577 2578 void Dxf::importProtection( const AttributeList& rAttribs ) 2579 { 2580 mxProtection.reset( new Protection( *this ) ); 2581 mxProtection->importProtection( rAttribs ); 2582 } 2583 2584 void Dxf::importDxf( SequenceInputStream& rStrm ) 2585 { 2586 sal_Int32 nNumFmtId = -1; 2587 OUString aFmtCode; 2588 sal_uInt16 nRecCount; 2589 rStrm.skip( 4 ); // flags 2590 rStrm >> nRecCount; 2591 for( sal_uInt16 nRec = 0; !rStrm.isEof() && (nRec < nRecCount); ++nRec ) 2592 { 2593 sal_uInt16 nSubRecId, nSubRecSize; 2594 sal_Int64 nRecEnd = rStrm.tell(); 2595 rStrm >> nSubRecId >> nSubRecSize; 2596 nRecEnd += nSubRecSize; 2597 switch( nSubRecId ) 2598 { 2599 case BIFF12_DXF_FILL_PATTERN: createFill( false )->importDxfPattern( rStrm ); break; 2600 case BIFF12_DXF_FILL_FGCOLOR: createFill( false )->importDxfFgColor( rStrm ); break; 2601 case BIFF12_DXF_FILL_BGCOLOR: createFill( false )->importDxfBgColor( rStrm ); break; 2602 case BIFF12_DXF_FILL_GRADIENT: createFill( false )->importDxfGradient( rStrm ); break; 2603 case BIFF12_DXF_FILL_STOP: createFill( false )->importDxfStop( rStrm ); break; 2604 case BIFF12_DXF_FONT_COLOR: createFont( false )->importDxfColor( rStrm ); break; 2605 case BIFF12_DXF_BORDER_TOP: createBorder( false )->importDxfBorder( XLS_TOKEN( top ), rStrm ); break; 2606 case BIFF12_DXF_BORDER_BOTTOM: createBorder( false )->importDxfBorder( XLS_TOKEN( bottom ), rStrm ); break; 2607 case BIFF12_DXF_BORDER_LEFT: createBorder( false )->importDxfBorder( XLS_TOKEN( left ), rStrm ); break; 2608 case BIFF12_DXF_BORDER_RIGHT: createBorder( false )->importDxfBorder( XLS_TOKEN( right ), rStrm ); break; 2609 case BIFF12_DXF_FONT_NAME: createFont( false )->importDxfName( rStrm ); break; 2610 case BIFF12_DXF_FONT_WEIGHT: createFont( false )->importDxfWeight( rStrm ); break; 2611 case BIFF12_DXF_FONT_UNDERLINE: createFont( false )->importDxfUnderline( rStrm ); break; 2612 case BIFF12_DXF_FONT_ESCAPEMENT: createFont( false )->importDxfEscapement( rStrm ); break; 2613 case BIFF12_DXF_FONT_ITALIC: createFont( false )->importDxfFlag( XML_i, rStrm ); break; 2614 case BIFF12_DXF_FONT_STRIKE: createFont( false )->importDxfFlag( XML_strike, rStrm ); break; 2615 case BIFF12_DXF_FONT_OUTLINE: createFont( false )->importDxfFlag( XML_outline, rStrm ); break; 2616 case BIFF12_DXF_FONT_SHADOW: createFont( false )->importDxfFlag( XML_shadow, rStrm ); break; 2617 case BIFF12_DXF_FONT_HEIGHT: createFont( false )->importDxfHeight( rStrm ); break; 2618 case BIFF12_DXF_FONT_SCHEME: createFont( false )->importDxfScheme( rStrm ); break; 2619 case BIFF12_DXF_NUMFMT_CODE: aFmtCode = BiffHelper::readString( rStrm, false ); break; 2620 case BIFF12_DXF_NUMFMT_ID: nNumFmtId = rStrm.readuInt16(); break; 2621 } 2622 rStrm.seek( nRecEnd ); 2623 } 2624 OSL_ENSURE( !rStrm.isEof() && (rStrm.getRemaining() == 0), "Dxf::importDxf - unexpected remaining data" ); 2625 mxNumFmt = getStyles().createNumFmt( nNumFmtId, aFmtCode ); 2626 } 2627 2628 void Dxf::importCfRule( BiffInputStream& rStrm, sal_uInt32 nFlags ) 2629 { 2630 if( getFlag( nFlags, BIFF_CFRULE_FONTBLOCK ) ) 2631 createFont()->importCfRule( rStrm ); 2632 if( getFlag( nFlags, BIFF_CFRULE_ALIGNBLOCK ) ) 2633 rStrm.skip( 8 ); 2634 if( getFlag( nFlags, BIFF_CFRULE_BORDERBLOCK ) ) 2635 createBorder()->importCfRule( rStrm, nFlags ); 2636 if( getFlag( nFlags, BIFF_CFRULE_FILLBLOCK ) ) 2637 createFill()->importCfRule( rStrm, nFlags ); 2638 if( getFlag( nFlags, BIFF_CFRULE_PROTBLOCK ) ) 2639 rStrm.skip( 2 ); 2640 } 2641 2642 void Dxf::finalizeImport() 2643 { 2644 if( mxFont.get() ) 2645 mxFont->finalizeImport(); 2646 // number format already finalized by the number formats buffer 2647 if( mxAlignment.get() ) 2648 mxAlignment->finalizeImport(); 2649 if( mxProtection.get() ) 2650 mxProtection->finalizeImport(); 2651 if( mxBorder.get() ) 2652 mxBorder->finalizeImport(); 2653 if( mxFill.get() ) 2654 mxFill->finalizeImport(); 2655 } 2656 2657 void Dxf::writeToPropertyMap( PropertyMap& rPropMap ) const 2658 { 2659 if( mxFont.get() ) 2660 mxFont->writeToPropertyMap( rPropMap, FONT_PROPTYPE_CELL ); 2661 if( mxNumFmt.get() ) 2662 mxNumFmt->writeToPropertyMap( rPropMap ); 2663 if( mxAlignment.get() ) 2664 mxAlignment->writeToPropertyMap( rPropMap ); 2665 if( mxProtection.get() ) 2666 mxProtection->writeToPropertyMap( rPropMap ); 2667 if( mxBorder.get() ) 2668 mxBorder->writeToPropertyMap( rPropMap ); 2669 if( mxFill.get() ) 2670 mxFill->writeToPropertyMap( rPropMap ); 2671 } 2672 2673 void Dxf::writeToPropertySet( PropertySet& rPropSet ) const 2674 { 2675 PropertyMap aPropMap; 2676 writeToPropertyMap( aPropMap ); 2677 rPropSet.setProperties( aPropMap ); 2678 } 2679 2680 // ============================================================================ 2681 2682 namespace { 2683 2684 const sal_Char* const spcLegacyStyleNamePrefix = "Excel_BuiltIn_"; 2685 const sal_Char* const sppcLegacyStyleNames[] = 2686 { 2687 "Normal", 2688 "RowLevel_", // outline level will be appended 2689 "ColumnLevel_", // outline level will be appended 2690 "Comma", 2691 "Currency", 2692 "Percent", 2693 "Comma_0", // new in BIFF4 2694 "Currency_0", 2695 "Hyperlink", // new in BIFF8 2696 "Followed_Hyperlink" 2697 }; 2698 const sal_Int32 snLegacyStyleNamesCount = static_cast< sal_Int32 >( STATIC_ARRAY_SIZE( sppcLegacyStyleNames ) ); 2699 2700 const sal_Char* const spcStyleNamePrefix = "Excel Built-in "; 2701 const sal_Char* const sppcStyleNames[] = 2702 { 2703 "Normal", 2704 "RowLevel_", // outline level will be appended 2705 "ColLevel_", // outline level will be appended 2706 "Comma", 2707 "Currency", 2708 "Percent", 2709 "Comma [0]", // new in BIFF4 2710 "Currency [0]", 2711 "Hyperlink", // new in BIFF8 2712 "Followed Hyperlink", 2713 "Note", // new in OOX 2714 "Warning Text", 2715 0, 2716 0, 2717 0, 2718 "Title", 2719 "Heading 1", 2720 "Heading 2", 2721 "Heading 3", 2722 "Heading 4", 2723 "Input", 2724 "Output", 2725 "Calculation", 2726 "Check Cell", 2727 "Linked Cell", 2728 "Total", 2729 "Good", 2730 "Bad", 2731 "Neutral", 2732 "Accent1", 2733 "20% - Accent1", 2734 "40% - Accent1", 2735 "60% - Accent1", 2736 "Accent2", 2737 "20% - Accent2", 2738 "40% - Accent2", 2739 "60% - Accent2", 2740 "Accent3", 2741 "20% - Accent3", 2742 "40% - Accent3", 2743 "60% - Accent3", 2744 "Accent4", 2745 "20% - Accent4", 2746 "40% - Accent4", 2747 "60% - Accent4", 2748 "Accent5", 2749 "20% - Accent5", 2750 "40% - Accent5", 2751 "60% - Accent5", 2752 "Accent6", 2753 "20% - Accent6", 2754 "40% - Accent6", 2755 "60% - Accent6", 2756 "Explanatory Text" 2757 }; 2758 const sal_Int32 snStyleNamesCount = static_cast< sal_Int32 >( STATIC_ARRAY_SIZE( sppcStyleNames ) ); 2759 2760 OUString lclGetBuiltinStyleName( sal_Int32 nBuiltinId, const OUString& rName, sal_Int32 nLevel = 0 ) 2761 { 2762 OSL_ENSURE( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount), "lclGetBuiltinStyleName - unknown built-in style" ); 2763 OUStringBuffer aStyleName; 2764 aStyleName.appendAscii( spcStyleNamePrefix ); 2765 if( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount) && (sppcStyleNames[ nBuiltinId ] != 0) ) 2766 aStyleName.appendAscii( sppcStyleNames[ nBuiltinId ] ); 2767 else if( rName.getLength() > 0 ) 2768 aStyleName.append( rName ); 2769 else 2770 aStyleName.append( nBuiltinId ); 2771 if( (nBuiltinId == OOX_STYLE_ROWLEVEL) || (nBuiltinId == OOX_STYLE_COLLEVEL) ) 2772 aStyleName.append( nLevel ); 2773 return aStyleName.makeStringAndClear(); 2774 } 2775 2776 OUString lclCreateStyleName( const CellStyleModel& rModel ) 2777 { 2778 return rModel.mbBuiltin ? lclGetBuiltinStyleName( rModel.mnBuiltinId, rModel.maName, rModel.mnLevel ) : rModel.maName; 2779 } 2780 2781 bool lclIsBuiltinStyleName( const OUString& rStyleName, sal_Int32* pnBuiltinId, sal_Int32* pnNextChar ) 2782 { 2783 // try the other built-in styles 2784 OUString aPrefix = OUString::createFromAscii( spcStyleNamePrefix ); 2785 sal_Int32 nPrefixLen = aPrefix.getLength(); 2786 sal_Int32 nFoundId = 0; 2787 sal_Int32 nNextChar = 0; 2788 if( rStyleName.matchIgnoreAsciiCase( aPrefix ) ) 2789 { 2790 OUString aShortName; 2791 for( sal_Int32 nId = 0; nId < snStyleNamesCount; ++nId ) 2792 { 2793 if( sppcStyleNames[ nId ] != 0 ) 2794 { 2795 aShortName = OUString::createFromAscii( sppcStyleNames[ nId ] ); 2796 if( rStyleName.matchIgnoreAsciiCase( aShortName, nPrefixLen ) && 2797 (nNextChar < nPrefixLen + aShortName.getLength()) ) 2798 { 2799 nFoundId = nId; 2800 nNextChar = nPrefixLen + aShortName.getLength(); 2801 } 2802 } 2803 } 2804 } 2805 2806 if( nNextChar > 0 ) 2807 { 2808 if( pnBuiltinId ) *pnBuiltinId = nFoundId; 2809 if( pnNextChar ) *pnNextChar = nNextChar; 2810 return true; 2811 } 2812 2813 if( pnBuiltinId ) *pnBuiltinId = -1; 2814 if( pnNextChar ) *pnNextChar = 0; 2815 return false; 2816 } 2817 2818 bool lclGetBuiltinStyleId( sal_Int32& rnBuiltinId, sal_Int32& rnLevel, const OUString& rStyleName ) 2819 { 2820 sal_Int32 nBuiltinId; 2821 sal_Int32 nNextChar; 2822 if( lclIsBuiltinStyleName( rStyleName, &nBuiltinId, &nNextChar ) ) 2823 { 2824 if( (nBuiltinId == OOX_STYLE_ROWLEVEL) || (nBuiltinId == OOX_STYLE_COLLEVEL) ) 2825 { 2826 OUString aLevel = rStyleName.copy( nNextChar ); 2827 sal_Int32 nLevel = aLevel.toInt32(); 2828 if( (0 < nLevel) && (nLevel <= OOX_STYLE_LEVELCOUNT) ) 2829 { 2830 rnBuiltinId = nBuiltinId; 2831 rnLevel = nLevel; 2832 return true; 2833 } 2834 } 2835 else if( rStyleName.getLength() == nNextChar ) 2836 { 2837 rnBuiltinId = nBuiltinId; 2838 rnLevel = 0; 2839 return true; 2840 } 2841 } 2842 rnBuiltinId = -1; 2843 rnLevel = 0; 2844 return false; 2845 } 2846 2847 } // namespace 2848 2849 // ---------------------------------------------------------------------------- 2850 2851 CellStyleModel::CellStyleModel() : 2852 mnXfId( -1 ), 2853 mnBuiltinId( -1 ), 2854 mnLevel( 0 ), 2855 mbBuiltin( false ), 2856 mbCustom( false ), 2857 mbHidden( false ) 2858 { 2859 } 2860 2861 bool CellStyleModel::isBuiltin() const 2862 { 2863 return mbBuiltin && (mnBuiltinId >= 0); 2864 } 2865 2866 bool CellStyleModel::isDefaultStyle() const 2867 { 2868 return mbBuiltin && (mnBuiltinId == OOX_STYLE_NORMAL); 2869 } 2870 2871 // ============================================================================ 2872 2873 CellStyle::CellStyle( const WorkbookHelper& rHelper ) : 2874 WorkbookHelper( rHelper ), 2875 mbCreated( false ) 2876 { 2877 } 2878 2879 void CellStyle::importCellStyle( const AttributeList& rAttribs ) 2880 { 2881 maModel.maName = rAttribs.getXString( XML_name, OUString() ); 2882 maModel.mnXfId = rAttribs.getInteger( XML_xfId, -1 ); 2883 maModel.mnBuiltinId = rAttribs.getInteger( XML_builtinId, -1 ); 2884 maModel.mnLevel = rAttribs.getInteger( XML_iLevel, 0 ); 2885 maModel.mbBuiltin = rAttribs.hasAttribute( XML_builtinId ); 2886 maModel.mbCustom = rAttribs.getBool( XML_customBuiltin, false ); 2887 maModel.mbHidden = rAttribs.getBool( XML_hidden, false ); 2888 } 2889 2890 void CellStyle::importCellStyle( SequenceInputStream& rStrm ) 2891 { 2892 sal_uInt16 nFlags; 2893 rStrm >> maModel.mnXfId >> nFlags; 2894 maModel.mnBuiltinId = rStrm.readInt8(); 2895 maModel.mnLevel = rStrm.readInt8(); 2896 rStrm >> maModel.maName; 2897 maModel.mbBuiltin = getFlag( nFlags, BIFF12_CELLSTYLE_BUILTIN ); 2898 maModel.mbCustom = getFlag( nFlags, BIFF12_CELLSTYLE_CUSTOM ); 2899 maModel.mbHidden = getFlag( nFlags, BIFF12_CELLSTYLE_HIDDEN ); 2900 } 2901 2902 void CellStyle::importStyle( BiffInputStream& rStrm ) 2903 { 2904 sal_uInt16 nStyleXf; 2905 rStrm >> nStyleXf; 2906 maModel.mnXfId = static_cast< sal_Int32 >( nStyleXf & BIFF_STYLE_XFMASK ); 2907 maModel.mbBuiltin = getFlag( nStyleXf, BIFF_STYLE_BUILTIN ); 2908 if( maModel.mbBuiltin ) 2909 { 2910 maModel.mnBuiltinId = rStrm.readInt8(); 2911 maModel.mnLevel = rStrm.readInt8(); 2912 } 2913 else 2914 { 2915 maModel.maName = (getBiff() == BIFF8) ? 2916 rStrm.readUniString() : rStrm.readByteStringUC( false, getTextEncoding() ); 2917 // #i103281# check if this is a new built-in style introduced in XL2007 2918 if( (getBiff() == BIFF8) && (rStrm.getNextRecId() == BIFF_ID_STYLEEXT) && rStrm.startNextRecord() ) 2919 { 2920 sal_uInt8 nExtFlags; 2921 rStrm.skip( 12 ); 2922 rStrm >> nExtFlags; 2923 maModel.mbBuiltin = getFlag( nExtFlags, BIFF_STYLEEXT_BUILTIN ); 2924 maModel.mbCustom = getFlag( nExtFlags, BIFF_STYLEEXT_CUSTOM ); 2925 maModel.mbHidden = getFlag( nExtFlags, BIFF_STYLEEXT_HIDDEN ); 2926 if( maModel.mbBuiltin ) 2927 { 2928 maModel.mnBuiltinId = rStrm.readInt8(); 2929 maModel.mnLevel = rStrm.readInt8(); 2930 } 2931 } 2932 } 2933 } 2934 2935 void CellStyle::createCellStyle() 2936 { 2937 // #i1624# #i1768# ignore unnamed user styles 2938 if( !mbCreated ) 2939 mbCreated = maFinalName.getLength() == 0; 2940 2941 /* #i103281# do not create another style of the same name, if it exists 2942 already. This is needed to prevent that styles pasted from clipboard 2943 get duplicated over and over. */ 2944 if( !mbCreated ) try 2945 { 2946 Reference< XNameAccess > xCellStylesNA( getStyleFamily( false ), UNO_QUERY_THROW ); 2947 mbCreated = xCellStylesNA->hasByName( maFinalName ); 2948 } 2949 catch( Exception& ) 2950 { 2951 } 2952 2953 // create the style object in the document 2954 if( !mbCreated ) try 2955 { 2956 mbCreated = true; 2957 Reference< XStyle > xStyle( createStyleObject( maFinalName, false ), UNO_SET_THROW ); 2958 // write style formatting properties 2959 PropertySet aPropSet( xStyle ); 2960 getStyles().writeStyleXfToPropertySet( aPropSet, maModel.mnXfId ); 2961 if( !maModel.isDefaultStyle() ) 2962 xStyle->setParentStyle( getStyles().getDefaultStyleName() ); 2963 } 2964 catch( Exception& ) 2965 { 2966 } 2967 } 2968 2969 void CellStyle::finalizeImport( const OUString& rFinalName ) 2970 { 2971 maFinalName = rFinalName; 2972 if( !maModel.isBuiltin() || maModel.mbCustom ) 2973 createCellStyle(); 2974 } 2975 2976 // ============================================================================ 2977 2978 CellStyleBuffer::CellStyleBuffer( const WorkbookHelper& rHelper ) : 2979 WorkbookHelper( rHelper ) 2980 { 2981 } 2982 2983 CellStyleRef CellStyleBuffer::importCellStyle( const AttributeList& rAttribs ) 2984 { 2985 CellStyleRef xCellStyle( new CellStyle( *this ) ); 2986 xCellStyle->importCellStyle( rAttribs ); 2987 insertCellStyle( xCellStyle ); 2988 return xCellStyle; 2989 } 2990 2991 CellStyleRef CellStyleBuffer::importCellStyle( SequenceInputStream& rStrm ) 2992 { 2993 CellStyleRef xCellStyle( new CellStyle( *this ) ); 2994 xCellStyle->importCellStyle( rStrm ); 2995 insertCellStyle( xCellStyle ); 2996 return xCellStyle; 2997 } 2998 2999 CellStyleRef CellStyleBuffer::importStyle( BiffInputStream& rStrm ) 3000 { 3001 CellStyleRef xCellStyle( new CellStyle( *this ) ); 3002 xCellStyle->importStyle( rStrm ); 3003 insertCellStyle( xCellStyle ); 3004 return xCellStyle; 3005 } 3006 3007 void CellStyleBuffer::finalizeImport() 3008 { 3009 // calculate final names of all styles 3010 typedef RefMap< OUString, CellStyle, IgnoreCaseCompare > CellStyleNameMap; 3011 CellStyleNameMap aCellStyles; 3012 CellStyleVector aConflictNameStyles; 3013 3014 /* First, reserve style names that are built-in in Calc. This causes that 3015 imported cell styles get different unused names and thus do not try to 3016 overwrite these built-in styles. For BIFF4 workbooks (which contain a 3017 separate list of cell styles per sheet), reserve all existing styles if 3018 current sheet is not the first sheet (this styles buffer will be 3019 constructed again for every new sheet). This will create unique names 3020 for styles in different sheets with the same name. Assuming that the 3021 BIFF4W import filter is never used to import from clipboard... */ 3022 bool bReserveAll = (getFilterType() == FILTER_BIFF) && (getBiff() == BIFF4) && isWorkbookFile() && (getCurrentSheetIndex() > 0); 3023 try 3024 { 3025 // unfortunately, com.sun.star.style.StyleFamily does not implement XEnumerationAccess... 3026 Reference< XIndexAccess > xStyleFamilyIA( getStyleFamily( false ), UNO_QUERY_THROW ); 3027 for( sal_Int32 nIndex = 0, nCount = xStyleFamilyIA->getCount(); nIndex < nCount; ++nIndex ) 3028 { 3029 Reference< XStyle > xStyle( xStyleFamilyIA->getByIndex( nIndex ), UNO_QUERY_THROW ); 3030 if( bReserveAll || !xStyle->isUserDefined() ) 3031 { 3032 Reference< XNamed > xStyleName( xStyle, UNO_QUERY_THROW ); 3033 // create an empty entry by using ::std::map<>::operator[] 3034 aCellStyles[ xStyleName->getName() ]; 3035 } 3036 } 3037 } 3038 catch( Exception& ) 3039 { 3040 } 3041 3042 /* Calculate names of built-in styles. Store styles with reserved names 3043 in the aConflictNameStyles list. */ 3044 for( CellStyleVector::iterator aIt = maBuiltinStyles.begin(), aEnd = maBuiltinStyles.end(); aIt != aEnd; ++aIt ) 3045 { 3046 const CellStyleModel& rModel = (*aIt)->getModel(); 3047 OUString aStyleName = lclCreateStyleName( rModel ); 3048 /* If a builtin style entry already exists, and we do not reserve all 3049 existing styles, we just stick with the last definition and ignore 3050 the preceding ones. */ 3051 if( bReserveAll && (aCellStyles.count( aStyleName ) > 0) ) 3052 aConflictNameStyles.push_back( *aIt ); 3053 else 3054 aCellStyles[ aStyleName ] = *aIt; 3055 } 3056 3057 /* Calculate names of user defined styles. Store styles with reserved 3058 names in the aConflictNameStyles list. */ 3059 for( CellStyleVector::iterator aIt = maUserStyles.begin(), aEnd = maUserStyles.end(); aIt != aEnd; ++aIt ) 3060 { 3061 const CellStyleModel& rModel = (*aIt)->getModel(); 3062 OUString aStyleName = lclCreateStyleName( rModel ); 3063 // #i1624# #i1768# ignore unnamed user styles 3064 if( aStyleName.getLength() > 0 ) 3065 { 3066 if( aCellStyles.count( aStyleName ) > 0 ) 3067 aConflictNameStyles.push_back( *aIt ); 3068 else 3069 aCellStyles[ aStyleName ] = *aIt; 3070 } 3071 } 3072 3073 // find unused names for all styles with conflicting names 3074 for( CellStyleVector::iterator aIt = aConflictNameStyles.begin(), aEnd = aConflictNameStyles.end(); aIt != aEnd; ++aIt ) 3075 { 3076 const CellStyleModel& rModel = (*aIt)->getModel(); 3077 OUString aStyleName = lclCreateStyleName( rModel ); 3078 OUString aUnusedName; 3079 sal_Int32 nIndex = 0; 3080 do 3081 { 3082 aUnusedName = OUStringBuffer( aStyleName ).append( sal_Unicode( ' ' ) ).append( ++nIndex ).makeStringAndClear(); 3083 } 3084 while( aCellStyles.count( aUnusedName ) > 0 ); 3085 aCellStyles[ aUnusedName ] = *aIt; 3086 } 3087 3088 // set final names and create user-defined and modified built-in cell styles 3089 aCellStyles.forEachMemWithKey( &CellStyle::finalizeImport ); 3090 } 3091 3092 sal_Int32 CellStyleBuffer::getDefaultXfId() const 3093 { 3094 return mxDefStyle.get() ? mxDefStyle->getModel().mnXfId : -1; 3095 } 3096 3097 OUString CellStyleBuffer::getDefaultStyleName() const 3098 { 3099 return createCellStyle( mxDefStyle ); 3100 } 3101 3102 OUString CellStyleBuffer::createCellStyle( sal_Int32 nXfId ) const 3103 { 3104 return createCellStyle( maStylesByXf.get( nXfId ) ); 3105 } 3106 3107 // private -------------------------------------------------------------------- 3108 3109 void CellStyleBuffer::insertCellStyle( CellStyleRef xCellStyle ) 3110 { 3111 const CellStyleModel& rModel = xCellStyle->getModel(); 3112 if( rModel.mnXfId >= 0 ) 3113 { 3114 // insert into the built-in map or user defined map 3115 (rModel.isBuiltin() ? maBuiltinStyles : maUserStyles).push_back( xCellStyle ); 3116 3117 // insert into the XF identifier map 3118 OSL_ENSURE( maStylesByXf.count( rModel.mnXfId ) == 0, "CellStyleBuffer::insertCellStyle - multiple styles with equal XF identifier" ); 3119 maStylesByXf[ rModel.mnXfId ] = xCellStyle; 3120 3121 // remember default cell style 3122 if( rModel.isDefaultStyle() ) 3123 mxDefStyle = xCellStyle; 3124 } 3125 } 3126 3127 OUString CellStyleBuffer::createCellStyle( const CellStyleRef& rxCellStyle ) const 3128 { 3129 if( rxCellStyle.get() ) 3130 { 3131 rxCellStyle->createCellStyle(); 3132 const OUString& rStyleName = rxCellStyle->getFinalStyleName(); 3133 if( rStyleName.getLength() > 0 ) 3134 return rStyleName; 3135 } 3136 // on error: fallback to default style 3137 return lclGetBuiltinStyleName( OOX_STYLE_NORMAL, OUString() ); 3138 } 3139 3140 // ============================================================================ 3141 3142 AutoFormatModel::AutoFormatModel() : 3143 mnAutoFormatId( 0 ), 3144 mbApplyNumFmt( false ), 3145 mbApplyFont( false ), 3146 mbApplyAlignment( false ), 3147 mbApplyBorder( false ), 3148 mbApplyFill( false ), 3149 mbApplyProtection( false ) 3150 { 3151 } 3152 3153 // ============================================================================ 3154 3155 StylesBuffer::StylesBuffer( const WorkbookHelper& rHelper ) : 3156 WorkbookHelper( rHelper ), 3157 maPalette( rHelper ), 3158 maNumFmts( rHelper ), 3159 maCellStyles( rHelper ) 3160 { 3161 } 3162 3163 FontRef StylesBuffer::createFont( sal_Int32* opnFontId ) 3164 { 3165 if( opnFontId ) *opnFontId = static_cast< sal_Int32 >( maFonts.size() ); 3166 FontRef xFont( new Font( *this, false ) ); 3167 maFonts.push_back( xFont ); 3168 return xFont; 3169 } 3170 3171 NumberFormatRef StylesBuffer::createNumFmt( sal_Int32 nNumFmtId, const OUString& rFmtCode ) 3172 { 3173 return maNumFmts.createNumFmt( nNumFmtId, rFmtCode ); 3174 } 3175 3176 BorderRef StylesBuffer::createBorder( sal_Int32* opnBorderId ) 3177 { 3178 if( opnBorderId ) *opnBorderId = static_cast< sal_Int32 >( maBorders.size() ); 3179 BorderRef xBorder( new Border( *this, false ) ); 3180 maBorders.push_back( xBorder ); 3181 return xBorder; 3182 } 3183 3184 FillRef StylesBuffer::createFill( sal_Int32* opnFillId ) 3185 { 3186 if( opnFillId ) *opnFillId = static_cast< sal_Int32 >( maFills.size() ); 3187 FillRef xFill( new Fill( *this, false ) ); 3188 maFills.push_back( xFill ); 3189 return xFill; 3190 } 3191 3192 XfRef StylesBuffer::createCellXf( sal_Int32* opnXfId ) 3193 { 3194 if( opnXfId ) *opnXfId = static_cast< sal_Int32 >( maCellXfs.size() ); 3195 XfRef xXf( new Xf( *this ) ); 3196 maCellXfs.push_back( xXf ); 3197 return xXf; 3198 } 3199 3200 XfRef StylesBuffer::createStyleXf( sal_Int32* opnXfId ) 3201 { 3202 if( opnXfId ) *opnXfId = static_cast< sal_Int32 >( maStyleXfs.size() ); 3203 XfRef xXf( new Xf( *this ) ); 3204 maStyleXfs.push_back( xXf ); 3205 return xXf; 3206 } 3207 3208 DxfRef StylesBuffer::createDxf( sal_Int32* opnDxfId ) 3209 { 3210 if( opnDxfId ) *opnDxfId = static_cast< sal_Int32 >( maDxfs.size() ); 3211 DxfRef xDxf( new Dxf( *this ) ); 3212 maDxfs.push_back( xDxf ); 3213 return xDxf; 3214 } 3215 3216 void StylesBuffer::importPaletteColor( const AttributeList& rAttribs ) 3217 { 3218 maPalette.importPaletteColor( rAttribs ); 3219 } 3220 3221 NumberFormatRef StylesBuffer::importNumFmt( const AttributeList& rAttribs ) 3222 { 3223 return maNumFmts.importNumFmt( rAttribs ); 3224 } 3225 3226 CellStyleRef StylesBuffer::importCellStyle( const AttributeList& rAttribs ) 3227 { 3228 return maCellStyles.importCellStyle( rAttribs ); 3229 } 3230 3231 void StylesBuffer::importPaletteColor( SequenceInputStream& rStrm ) 3232 { 3233 maPalette.importPaletteColor( rStrm ); 3234 } 3235 3236 void StylesBuffer::importNumFmt( SequenceInputStream& rStrm ) 3237 { 3238 maNumFmts.importNumFmt( rStrm ); 3239 } 3240 3241 void StylesBuffer::importCellStyle( SequenceInputStream& rStrm ) 3242 { 3243 maCellStyles.importCellStyle( rStrm ); 3244 } 3245 3246 void StylesBuffer::importPalette( BiffInputStream& rStrm ) 3247 { 3248 maPalette.importPalette( rStrm ); 3249 } 3250 3251 void StylesBuffer::importFont( BiffInputStream& rStrm ) 3252 { 3253 /* Font with index 4 is not stored in BIFF. This means effectively, first 3254 font in the BIFF file has index 0, fourth font has index 3, and fifth 3255 font has index 5. Insert a dummy font to correctly map passed font 3256 identifiers. */ 3257 if( maFonts.size() == 4 ) 3258 maFonts.push_back( maFonts.front() ); 3259 3260 FontRef xFont = createFont(); 3261 xFont->importFont( rStrm ); 3262 3263 /* #i71033# Set stream text encoding from application font, if CODEPAGE 3264 record is missing. Must be done now (not while finalizeImport() runs), 3265 to be able to read all following byte strings correctly (e.g. cell 3266 style names). */ 3267 if( maFonts.size() == 1 ) 3268 setAppFontEncoding( xFont->getFontEncoding() ); 3269 } 3270 3271 void StylesBuffer::importFontColor( BiffInputStream& rStrm ) 3272 { 3273 if( !maFonts.empty() ) 3274 maFonts.back()->importFontColor( rStrm ); 3275 } 3276 3277 void StylesBuffer::importFormat( BiffInputStream& rStrm ) 3278 { 3279 maNumFmts.importFormat( rStrm ); 3280 } 3281 3282 void StylesBuffer::importXf( BiffInputStream& rStrm ) 3283 { 3284 XfRef xXf( new Xf( *this ) ); 3285 xXf->importXf( rStrm ); 3286 3287 XfRef xCellXf, xStyleXf; 3288 (xXf->isCellXf() ? xCellXf : xStyleXf) = xXf; 3289 maCellXfs.push_back( xCellXf ); 3290 maStyleXfs.push_back( xStyleXf ); 3291 } 3292 3293 void StylesBuffer::importStyle( BiffInputStream& rStrm ) 3294 { 3295 maCellStyles.importStyle( rStrm ); 3296 } 3297 3298 void StylesBuffer::importPalette( const Any& rPalette ) 3299 { 3300 maPalette.importPalette( rPalette ); 3301 } 3302 3303 void StylesBuffer::finalizeImport() 3304 { 3305 // fonts first, are needed to finalize unit converter and XFs below 3306 maFonts.forEachMem( &Font::finalizeImport ); 3307 // finalize unit coefficients after default font is known 3308 getUnitConverter().finalizeImport(); 3309 // number formats 3310 maNumFmts.finalizeImport(); 3311 // borders and fills 3312 maBorders.forEachMem( &Border::finalizeImport ); 3313 maFills.forEachMem( &Fill::finalizeImport ); 3314 // style XFs and cell XFs 3315 maStyleXfs.forEachMem( &Xf::finalizeImport ); 3316 maCellXfs.forEachMem( &Xf::finalizeImport ); 3317 // built-in and user defined cell styles 3318 maCellStyles.finalizeImport(); 3319 // differential formatting (for conditional formatting) 3320 maDxfs.forEachMem( &Dxf::finalizeImport ); 3321 } 3322 3323 sal_Int32 StylesBuffer::getPaletteColor( sal_Int32 nPaletteIdx ) const 3324 { 3325 return maPalette.getColor( nPaletteIdx ); 3326 } 3327 3328 FontRef StylesBuffer::getFont( sal_Int32 nFontId ) const 3329 { 3330 return maFonts.get( nFontId ); 3331 } 3332 3333 BorderRef StylesBuffer::getBorder( sal_Int32 nBorderId ) const 3334 { 3335 return maBorders.get( nBorderId ); 3336 } 3337 3338 XfRef StylesBuffer::getCellXf( sal_Int32 nXfId ) const 3339 { 3340 return maCellXfs.get( nXfId ); 3341 } 3342 3343 XfRef StylesBuffer::getStyleXf( sal_Int32 nXfId ) const 3344 { 3345 return maStyleXfs.get( nXfId ); 3346 } 3347 3348 DxfRef StylesBuffer::getDxf( sal_Int32 nDxfId ) const 3349 { 3350 return maDxfs.get( nDxfId ); 3351 } 3352 3353 FontRef StylesBuffer::getFontFromCellXf( sal_Int32 nXfId ) const 3354 { 3355 FontRef xFont; 3356 if( const Xf* pXf = getCellXf( nXfId ).get() ) 3357 xFont = pXf->getFont(); 3358 return xFont; 3359 } 3360 3361 FontRef StylesBuffer::getDefaultFont() const 3362 { 3363 FontRef xDefFont; 3364 if( const Xf* pXf = getStyleXf( maCellStyles.getDefaultXfId() ).get() ) 3365 xDefFont = pXf->getFont(); 3366 // no font from styles - try first loaded font (e.g. BIFF2) 3367 if( !xDefFont ) 3368 xDefFont = maFonts.get( 0 ); 3369 OSL_ENSURE( xDefFont.get(), "StylesBuffer::getDefaultFont - no default font found" ); 3370 return xDefFont; 3371 } 3372 3373 const FontModel& StylesBuffer::getDefaultFontModel() const 3374 { 3375 FontRef xDefFont = getDefaultFont(); 3376 return xDefFont.get() ? xDefFont->getModel() : getTheme().getDefaultFontModel(); 3377 } 3378 3379 bool StylesBuffer::equalBorders( sal_Int32 nBorderId1, sal_Int32 nBorderId2 ) const 3380 { 3381 if( nBorderId1 == nBorderId2 ) 3382 return true; 3383 3384 switch( getFilterType() ) 3385 { 3386 case FILTER_OOXML: 3387 // in OOXML, borders are assumed to be unique 3388 return false; 3389 3390 case FILTER_BIFF: 3391 { 3392 // in BIFF, a new border entry has been created for every XF 3393 const Border* pBorder1 = maBorders.get( nBorderId1 ).get(); 3394 const Border* pBorder2 = maBorders.get( nBorderId2 ).get(); 3395 return pBorder1 && pBorder2 && (pBorder1->getApiData() == pBorder2->getApiData()); 3396 } 3397 3398 case FILTER_UNKNOWN: 3399 break; 3400 } 3401 return false; 3402 } 3403 3404 bool StylesBuffer::equalFills( sal_Int32 nFillId1, sal_Int32 nFillId2 ) const 3405 { 3406 if( nFillId1 == nFillId2 ) 3407 return true; 3408 3409 switch( getFilterType() ) 3410 { 3411 case FILTER_OOXML: 3412 // in OOXML, fills are assumed to be unique 3413 return false; 3414 3415 case FILTER_BIFF: 3416 { 3417 // in BIFF, a new fill entry has been created for every XF 3418 const Fill* pFill1 = maFills.get( nFillId1 ).get(); 3419 const Fill* pFill2 = maFills.get( nFillId2 ).get(); 3420 return pFill1 && pFill2 && (pFill1->getApiData() == pFill2->getApiData()); 3421 } 3422 3423 case FILTER_UNKNOWN: 3424 break; 3425 } 3426 return false; 3427 } 3428 3429 OUString StylesBuffer::getDefaultStyleName() const 3430 { 3431 return maCellStyles.getDefaultStyleName(); 3432 } 3433 3434 OUString StylesBuffer::createCellStyle( sal_Int32 nXfId ) const 3435 { 3436 return maCellStyles.createCellStyle( nXfId ); 3437 } 3438 3439 OUString StylesBuffer::createDxfStyle( sal_Int32 nDxfId ) const 3440 { 3441 OUString& rStyleName = maDxfStyles[ nDxfId ]; 3442 if( rStyleName.getLength() == 0 ) 3443 { 3444 if( Dxf* pDxf = maDxfs.get( nDxfId ).get() ) 3445 { 3446 rStyleName = OUStringBuffer( CREATE_OUSTRING( "ConditionalStyle_" ) ).append( nDxfId + 1 ).makeStringAndClear(); 3447 // create the style sheet (this may change rStyleName if such a style already exists) 3448 Reference< XStyle > xStyle = createStyleObject( rStyleName, false ); 3449 // write style formatting properties 3450 PropertySet aPropSet( xStyle ); 3451 pDxf->writeToPropertySet( aPropSet ); 3452 } 3453 // on error: fallback to default style 3454 if( rStyleName.getLength() == 0 ) 3455 rStyleName = maCellStyles.getDefaultStyleName(); 3456 } 3457 return rStyleName; 3458 } 3459 3460 void StylesBuffer::writeFontToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFontId ) const 3461 { 3462 if( Font* pFont = maFonts.get( nFontId ).get() ) 3463 pFont->writeToPropertyMap( rPropMap, FONT_PROPTYPE_CELL ); 3464 } 3465 3466 void StylesBuffer::writeNumFmtToPropertyMap( PropertyMap& rPropMap, sal_Int32 nNumFmtId ) const 3467 { 3468 maNumFmts.writeToPropertyMap( rPropMap, nNumFmtId ); 3469 } 3470 3471 void StylesBuffer::writeBorderToPropertyMap( PropertyMap& rPropMap, sal_Int32 nBorderId ) const 3472 { 3473 if( Border* pBorder = maBorders.get( nBorderId ).get() ) 3474 pBorder->writeToPropertyMap( rPropMap ); 3475 } 3476 3477 void StylesBuffer::writeFillToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFillId ) const 3478 { 3479 if( Fill* pFill = maFills.get( nFillId ).get() ) 3480 pFill->writeToPropertyMap( rPropMap ); 3481 } 3482 3483 void StylesBuffer::writeCellXfToPropertyMap( PropertyMap& rPropMap, sal_Int32 nXfId ) const 3484 { 3485 if( Xf* pXf = maCellXfs.get( nXfId ).get() ) 3486 pXf->writeToPropertyMap( rPropMap ); 3487 } 3488 3489 void StylesBuffer::writeStyleXfToPropertyMap( PropertyMap& rPropMap, sal_Int32 nXfId ) const 3490 { 3491 if( Xf* pXf = maStyleXfs.get( nXfId ).get() ) 3492 pXf->writeToPropertyMap( rPropMap ); 3493 } 3494 3495 void StylesBuffer::writeCellXfToPropertySet( PropertySet& rPropSet, sal_Int32 nXfId ) const 3496 { 3497 if( Xf* pXf = maCellXfs.get( nXfId ).get() ) 3498 pXf->writeToPropertySet( rPropSet ); 3499 } 3500 3501 void StylesBuffer::writeStyleXfToPropertySet( PropertySet& rPropSet, sal_Int32 nXfId ) const 3502 { 3503 if( Xf* pXf = maStyleXfs.get( nXfId ).get() ) 3504 pXf->writeToPropertySet( rPropSet ); 3505 } 3506 3507 // ============================================================================ 3508 3509 } // namespace xls 3510 } // namespace oox 3511