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