Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / filter / oox / stylesbuffer.cxx
blob6818f03ba454926a9ca54412371fffa91ab05514
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "stylesbuffer.hxx"
22 #include <com/sun/star/awt/FontDescriptor.hpp>
23 #include <com/sun/star/awt/FontFamily.hpp>
24 #include <com/sun/star/awt/FontPitch.hpp>
25 #include <com/sun/star/awt/FontSlant.hpp>
26 #include <com/sun/star/awt/FontStrikeout.hpp>
27 #include <com/sun/star/awt/FontType.hpp>
28 #include <com/sun/star/awt/FontWeight.hpp>
29 #include <com/sun/star/awt/FontUnderline.hpp>
30 #include <com/sun/star/awt/XDevice.hpp>
31 #include <com/sun/star/awt/XFont2.hpp>
32 #include <com/sun/star/container/XIndexAccess.hpp>
33 #include <com/sun/star/container/XNameAccess.hpp>
34 #include <com/sun/star/style/XStyle.hpp>
35 #include <com/sun/star/text/WritingMode2.hpp>
36 #include <com/sun/star/text/XText.hpp>
37 #include <com/sun/star/table/BorderLineStyle.hpp>
38 #include <com/sun/star/table/CellVertJustify2.hpp>
39 #include <com/sun/star/table/CellJustifyMethod.hpp>
40 #include <com/sun/star/table/TableBorder.hpp>
41 #include <editeng/justifyitem.hxx>
42 #include <editeng/frmdiritem.hxx>
43 #include <editeng/fontitem.hxx>
44 #include <editeng/postitem.hxx>
45 #include <editeng/fhgtitem.hxx>
46 #include <editeng/wghtitem.hxx>
47 #include <editeng/udlnitem.hxx>
48 #include <editeng/colritem.hxx>
49 #include <editeng/crossedoutitem.hxx>
50 #include <editeng/contouritem.hxx>
51 #include <editeng/escapementitem.hxx>
52 #include <editeng/shdditem.hxx>
53 #include <editeng/eeitem.hxx>
54 #include <editeng/boxitem.hxx>
55 #include <editeng/lineitem.hxx>
56 #include <editeng/brushitem.hxx>
57 #include <svx/rotmodit.hxx>
58 #include <tools/fontenum.hxx>
59 #include <toolkit/helper/vclunohelper.hxx>
60 #include <rtl/tencinfo.h>
61 #include <rtl/ustrbuf.hxx>
62 #include <oox/core/filterbase.hxx>
63 #include <oox/helper/attributelist.hxx>
64 #include <oox/helper/containerhelper.hxx>
65 #include <oox/helper/propertymap.hxx>
66 #include <oox/helper/propertyset.hxx>
67 #include <oox/token/namespaces.hxx>
68 #include <oox/token/properties.hxx>
69 #include <oox/token/tokens.hxx>
70 #include "biffinputstream.hxx"
71 #include "condformatbuffer.hxx"
72 #include "excelhandlers.hxx"
73 #include "themebuffer.hxx"
74 #include "unitconverter.hxx"
75 #include "document.hxx"
76 #include "stlpool.hxx"
77 #include "docpool.hxx"
78 #include "ftools.hxx"
79 #include "scitems.hxx"
80 #include "attrib.hxx"
81 #include "globstr.hrc"
82 #include "xlconst.hxx"
83 #include <documentimport.hxx>
84 #include <numformat.hxx>
86 using ::com::sun::star::table::BorderLine2;
87 namespace oox {
88 namespace xls {
90 using namespace com::sun::star;
91 using namespace ::com::sun::star::awt;
92 using namespace ::com::sun::star::container;
93 using namespace ::com::sun::star::style;
94 using namespace ::com::sun::star::table;
95 using namespace ::com::sun::star::text;
96 using namespace ::com::sun::star::uno;
99 namespace {
101 // OOXML constants ------------------------------------------------------------
103 // OOXML predefined color indexes (also used in BIFF3-BIFF8)
104 const sal_Int32 OOX_COLOR_USEROFFSET = 0; /// First user defined color in palette (OOXML/BIFF12).
105 const sal_Int32 BIFF_COLOR_USEROFFSET = 8; /// First user defined color in palette (BIFF3-BIFF8).
107 // OOXML font family (also used in BIFF)
108 const sal_Int32 OOX_FONTFAMILY_NONE = 0;
109 const sal_Int32 OOX_FONTFAMILY_ROMAN = 1;
110 const sal_Int32 OOX_FONTFAMILY_SWISS = 2;
111 const sal_Int32 OOX_FONTFAMILY_MODERN = 3;
112 const sal_Int32 OOX_FONTFAMILY_SCRIPT = 4;
113 const sal_Int32 OOX_FONTFAMILY_DECORATIVE = 5;
115 // OOXML cell text direction (also used in BIFF)
116 const sal_Int32 OOX_XF_TEXTDIR_CONTEXT = 0;
117 const sal_Int32 OOX_XF_TEXTDIR_LTR = 1;
118 const sal_Int32 OOX_XF_TEXTDIR_RTL = 2;
120 // OOXML cell rotation (also used in BIFF)
121 const sal_Int32 OOX_XF_ROTATION_NONE = 0;
122 const sal_Int32 OOX_XF_ROTATION_STACKED = 255;
124 // OOXML cell indentation
125 const sal_Int32 OOX_XF_INDENT_NONE = 0;
127 // OOXML built-in cell styles (also used in BIFF)
128 const sal_Int32 OOX_STYLE_NORMAL = 0; /// Default cell style.
129 const sal_Int32 OOX_STYLE_ROWLEVEL = 1; /// RowLevel_x cell style.
130 const sal_Int32 OOX_STYLE_COLLEVEL = 2; /// ColLevel_x cell style.
132 // BIFF12 constants -----------------------------------------------------------
134 // BIFF12 color types
135 const sal_uInt8 BIFF12_COLOR_AUTO = 0;
136 const sal_uInt8 BIFF12_COLOR_INDEXED = 1;
137 const sal_uInt8 BIFF12_COLOR_RGB = 2;
138 const sal_uInt8 BIFF12_COLOR_THEME = 3;
140 // BIFF12 diagonal borders
141 const sal_uInt8 BIFF12_BORDER_DIAG_TLBR = 0x01; /// Top-left to bottom-right.
142 const sal_uInt8 BIFF12_BORDER_DIAG_BLTR = 0x02; /// Bottom-left to top-right.
144 // BIFF12 gradient fill
145 const sal_Int32 BIFF12_FILL_GRADIENT = 40;
147 // BIFF12 XF flags
148 const sal_uInt32 BIFF12_XF_WRAPTEXT = 0x00400000;
149 const sal_uInt32 BIFF12_XF_JUSTLASTLINE = 0x00800000;
150 const sal_uInt32 BIFF12_XF_SHRINK = 0x01000000;
151 const sal_uInt32 BIFF12_XF_LOCKED = 0x10000000;
152 const sal_uInt32 BIFF12_XF_HIDDEN = 0x20000000;
154 // BIFF12 XF attribute used flags
155 const sal_uInt16 BIFF12_XF_NUMFMT_USED = 0x0001;
156 const sal_uInt16 BIFF12_XF_FONT_USED = 0x0002;
157 const sal_uInt16 BIFF12_XF_ALIGN_USED = 0x0004;
158 const sal_uInt16 BIFF12_XF_BORDER_USED = 0x0008;
159 const sal_uInt16 BIFF12_XF_AREA_USED = 0x0010;
160 const sal_uInt16 BIFF12_XF_PROT_USED = 0x0020;
162 // BIFF12 DXF constants
163 const sal_uInt16 BIFF12_DXF_FILL_PATTERN = 0;
164 const sal_uInt16 BIFF12_DXF_FILL_FGCOLOR = 1;
165 const sal_uInt16 BIFF12_DXF_FILL_BGCOLOR = 2;
166 const sal_uInt16 BIFF12_DXF_FILL_GRADIENT = 3;
167 const sal_uInt16 BIFF12_DXF_FILL_STOP = 4;
168 const sal_uInt16 BIFF12_DXF_FONT_COLOR = 5;
169 const sal_uInt16 BIFF12_DXF_BORDER_TOP = 6;
170 const sal_uInt16 BIFF12_DXF_BORDER_BOTTOM = 7;
171 const sal_uInt16 BIFF12_DXF_BORDER_LEFT = 8;
172 const sal_uInt16 BIFF12_DXF_BORDER_RIGHT = 9;
173 const sal_uInt16 BIFF12_DXF_FONT_NAME = 24;
174 const sal_uInt16 BIFF12_DXF_FONT_WEIGHT = 25;
175 const sal_uInt16 BIFF12_DXF_FONT_UNDERLINE = 26;
176 const sal_uInt16 BIFF12_DXF_FONT_ESCAPEMENT = 27;
177 const sal_uInt16 BIFF12_DXF_FONT_ITALIC = 28;
178 const sal_uInt16 BIFF12_DXF_FONT_STRIKE = 29;
179 const sal_uInt16 BIFF12_DXF_FONT_OUTLINE = 30;
180 const sal_uInt16 BIFF12_DXF_FONT_SHADOW = 31;
181 const sal_uInt16 BIFF12_DXF_FONT_HEIGHT = 36;
182 const sal_uInt16 BIFF12_DXF_FONT_SCHEME = 37;
183 const sal_uInt16 BIFF12_DXF_NUMFMT_CODE = 38;
184 const sal_uInt16 BIFF12_DXF_NUMFMT_ID = 41;
186 // BIFF12 CELLSTYLE flags
187 const sal_uInt16 BIFF12_CELLSTYLE_BUILTIN = 0x0001;
188 const sal_uInt16 BIFF12_CELLSTYLE_HIDDEN = 0x0002;
189 const sal_uInt16 BIFF12_CELLSTYLE_CUSTOM = 0x0004;
191 // BIFF constants -------------------------------------------------------------
193 // BIFF font flags, also used in BIFF12
194 const sal_uInt16 BIFF_FONTFLAG_ITALIC = 0x0002;
195 const sal_uInt16 BIFF_FONTFLAG_STRIKEOUT = 0x0008;
196 const sal_uInt16 BIFF_FONTFLAG_OUTLINE = 0x0010;
197 const sal_uInt16 BIFF_FONTFLAG_SHADOW = 0x0020;
199 // BIFF font weight
200 const sal_uInt16 BIFF_FONTWEIGHT_BOLD = 450;
202 // BIFF font underline, also used in BIFF12
203 const sal_uInt8 BIFF_FONTUNDERL_NONE = 0;
204 const sal_uInt8 BIFF_FONTUNDERL_SINGLE = 1;
205 const sal_uInt8 BIFF_FONTUNDERL_DOUBLE = 2;
206 const sal_uInt8 BIFF_FONTUNDERL_SINGLE_ACC = 33;
207 const sal_uInt8 BIFF_FONTUNDERL_DOUBLE_ACC = 34;
209 sal_Int32 lclReadRgbColor( BinaryInputStream& rStrm )
211 sal_uInt8 nR, nG, nB, nA;
212 nR = rStrm.readuChar();
213 nG = rStrm.readuChar();
214 nB = rStrm.readuChar();
215 nA = rStrm.readuChar();
216 sal_Int32 nValue = nA;
217 nValue <<= 8;
218 nValue |= nR;
219 nValue <<= 8;
220 nValue |= nG;
221 nValue <<= 8;
222 nValue |= nB;
223 return nValue;
226 } // namespace
228 ExcelGraphicHelper::ExcelGraphicHelper( const WorkbookHelper& rHelper ) :
229 GraphicHelper( rHelper.getBaseFilter().getComponentContext(), rHelper.getBaseFilter().getTargetFrame(), rHelper.getBaseFilter().getStorage() ),
230 WorkbookHelper( rHelper )
234 sal_Int32 ExcelGraphicHelper::getSchemeColor( sal_Int32 nToken ) const
236 if( getFilterType() == FILTER_OOXML )
237 return getTheme().getColorByToken( nToken );
238 return GraphicHelper::getSchemeColor( nToken );
241 sal_Int32 ExcelGraphicHelper::getPaletteColor( sal_Int32 nPaletteIdx ) const
243 return getStyles().getPaletteColor( nPaletteIdx );
246 void Color::setAuto()
248 clearTransformations();
249 setSchemeClr( XML_phClr );
252 void Color::setRgb( sal_Int32 nRgbValue, double fTint )
254 clearTransformations();
255 setSrgbClr( nRgbValue & 0xFFFFFF );
256 if( fTint != 0.0 ) addExcelTintTransformation( fTint );
259 void Color::setTheme( sal_Int32 nThemeIdx, double fTint )
261 clearTransformations();
262 static const sal_Int32 spnColorTokens[] = {
263 XML_lt1, XML_dk1, XML_lt2, XML_dk2, XML_accent1, XML_accent2,
264 XML_accent3, XML_accent4, XML_accent5, XML_accent6, XML_hlink, XML_folHlink };
265 setSchemeClr( STATIC_ARRAY_SELECT( spnColorTokens, nThemeIdx, XML_TOKEN_INVALID ) );
266 if( fTint != 0.0 ) addExcelTintTransformation( fTint );
269 void Color::setIndexed( sal_Int32 nPaletteIdx, double fTint )
271 clearTransformations();
272 setPaletteClr( nPaletteIdx );
273 if( fTint != 0.0 ) addExcelTintTransformation( fTint );
276 void Color::importColor( const AttributeList& rAttribs )
278 if( rAttribs.getBool( XML_auto, false ) )
279 setAuto();
280 else if( rAttribs.hasAttribute( XML_rgb ) )
281 setRgb( rAttribs.getIntegerHex( XML_rgb, API_RGB_TRANSPARENT ), rAttribs.getDouble( XML_tint, 0.0 ) );
282 else if( rAttribs.hasAttribute( XML_theme ) )
283 setTheme( rAttribs.getInteger( XML_theme, -1 ), rAttribs.getDouble( XML_tint, 0.0 ) );
284 else if( rAttribs.hasAttribute( XML_indexed ) )
285 setIndexed( rAttribs.getInteger( XML_indexed, -1 ), rAttribs.getDouble( XML_tint, 0.0 ) );
286 else
288 OSL_FAIL( "Color::importColor - unknown color type" );
289 setAuto();
293 void Color::importColor( SequenceInputStream& rStrm )
295 sal_uInt8 nFlags, nIndex;
296 sal_Int16 nTint;
297 nFlags = rStrm.readuChar();
298 nIndex = rStrm.readuChar();
299 nTint = rStrm.readInt16();
301 // scale tint from signed 16-bit to double range -1.0 ... 1.0
302 double fTint = nTint;
303 if( nTint < 0 )
304 fTint /= -SAL_MIN_INT16;
305 else if( nTint > 0 )
306 fTint /= SAL_MAX_INT16;
308 switch( extractValue< sal_uInt8 >( nFlags, 1, 7 ) )
310 case BIFF12_COLOR_AUTO:
311 setAuto();
312 rStrm.skip( 4 );
313 break;
314 case BIFF12_COLOR_INDEXED:
315 setIndexed( nIndex, fTint );
316 rStrm.skip( 4 );
317 break;
318 case BIFF12_COLOR_RGB:
319 setRgb( lclReadRgbColor( rStrm ), fTint );
320 break;
321 case BIFF12_COLOR_THEME:
322 setTheme( nIndex, fTint );
323 rStrm.skip( 4 );
324 break;
325 default:
326 OSL_FAIL( "Color::importColor - unknown color type" );
327 setAuto();
328 rStrm.skip( 4 );
332 void Color::importColorId( SequenceInputStream& rStrm )
334 setIndexed( rStrm.readInt32() );
337 SequenceInputStream& operator>>( SequenceInputStream& rStrm, Color& orColor )
339 orColor.importColor( rStrm );
340 return rStrm;
343 namespace {
345 /** Standard EGA colors, bright. */
346 #define PALETTE_EGA_COLORS_LIGHT \
347 0x000000, 0xFFFFFF, 0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF
348 /** Standard EGA colors, dark. */
349 #define PALETTE_EGA_COLORS_DARK \
350 0x800000, 0x008000, 0x000080, 0x808000, 0x800080, 0x008080, 0xC0C0C0, 0x808080
352 /** Default color table for BIFF2. */
353 static const sal_Int32 spnDefColors2[] =
355 /* 0 */ PALETTE_EGA_COLORS_LIGHT
358 /** Default color table for BIFF3/BIFF4. */
359 static const sal_Int32 spnDefColors3[] =
361 /* 0 */ PALETTE_EGA_COLORS_LIGHT,
362 /* 8 */ PALETTE_EGA_COLORS_LIGHT,
363 /* 16 */ PALETTE_EGA_COLORS_DARK
366 /** Default color table for BIFF5. */
367 static const sal_Int32 spnDefColors5[] =
369 /* 0 */ PALETTE_EGA_COLORS_LIGHT,
370 /* 8 */ PALETTE_EGA_COLORS_LIGHT,
371 /* 16 */ PALETTE_EGA_COLORS_DARK,
372 /* 24 */ 0x8080FF, 0x802060, 0xFFFFC0, 0xA0E0E0, 0x600080, 0xFF8080, 0x0080C0, 0xC0C0FF,
373 /* 32 */ 0x000080, 0xFF00FF, 0xFFFF00, 0x00FFFF, 0x800080, 0x800000, 0x008080, 0x0000FF,
374 /* 40 */ 0x00CFFF, 0x69FFFF, 0xE0FFE0, 0xFFFF80, 0xA6CAF0, 0xDD9CB3, 0xB38FEE, 0xE3E3E3,
375 /* 48 */ 0x2A6FF9, 0x3FB8CD, 0x488436, 0x958C41, 0x8E5E42, 0xA0627A, 0x624FAC, 0x969696,
376 /* 56 */ 0x1D2FBE, 0x286676, 0x004500, 0x453E01, 0x6A2813, 0x85396A, 0x4A3285, 0x424242
379 /** Default color table for BIFF8/BIFF12/OOXML. */
380 static const sal_Int32 spnDefColors8[] =
382 /* 0 */ PALETTE_EGA_COLORS_LIGHT,
383 /* 8 */ PALETTE_EGA_COLORS_LIGHT,
384 /* 16 */ PALETTE_EGA_COLORS_DARK,
385 /* 24 */ 0x9999FF, 0x993366, 0xFFFFCC, 0xCCFFFF, 0x660066, 0xFF8080, 0x0066CC, 0xCCCCFF,
386 /* 32 */ 0x000080, 0xFF00FF, 0xFFFF00, 0x00FFFF, 0x800080, 0x800000, 0x008080, 0x0000FF,
387 /* 40 */ 0x00CCFF, 0xCCFFFF, 0xCCFFCC, 0xFFFF99, 0x99CCFF, 0xFF99CC, 0xCC99FF, 0xFFCC99,
388 /* 48 */ 0x3366FF, 0x33CCCC, 0x99CC00, 0xFFCC00, 0xFF9900, 0xFF6600, 0x666699, 0x969696,
389 /* 56 */ 0x003366, 0x339966, 0x003300, 0x333300, 0x993300, 0x993366, 0x333399, 0x333333
392 #undef PALETTE_EGA_COLORS_LIGHT
393 #undef PALETTE_EGA_COLORS_DARK
395 } // namespace
397 ColorPalette::ColorPalette( const WorkbookHelper& rHelper )
398 : WorkbookHelper(rHelper)
399 , mnAppendIndex(0)
401 // default colors
402 switch( getFilterType() )
404 case FILTER_OOXML:
405 maColors.insert( maColors.begin(), spnDefColors8, ::std::end(spnDefColors8) );
406 mnAppendIndex = OOX_COLOR_USEROFFSET;
407 break;
408 case FILTER_BIFF:
409 switch( getBiff() )
411 case BIFF2: maColors.insert( maColors.begin(), spnDefColors2, ::std::end(spnDefColors2) ); break;
412 case BIFF3:
413 case BIFF4: maColors.insert( maColors.begin(), spnDefColors3, ::std::end(spnDefColors3) ); break;
414 case BIFF5: maColors.insert( maColors.begin(), spnDefColors5, ::std::end(spnDefColors5) ); break;
415 case BIFF8: maColors.insert( maColors.begin(), spnDefColors8, ::std::end(spnDefColors8) ); break;
416 case BIFF_UNKNOWN: break;
418 mnAppendIndex = BIFF_COLOR_USEROFFSET;
419 break;
420 case FILTER_UNKNOWN: break;
424 void ColorPalette::importPaletteColor( const AttributeList& rAttribs )
426 appendColor( rAttribs.getIntegerHex( XML_rgb, API_RGB_WHITE ) );
429 void ColorPalette::importPaletteColor( SequenceInputStream& rStrm )
431 sal_Int32 nRgb = lclReadRgbColor( rStrm );
432 appendColor( nRgb & 0xFFFFFF );
435 sal_Int32 ColorPalette::getColor( sal_Int32 nPaletteIdx ) const
437 sal_Int32 nColor = API_RGB_TRANSPARENT;
438 if( const sal_Int32* pnPaletteColor = ContainerHelper::getVectorElement( maColors, nPaletteIdx ) )
440 nColor = *pnPaletteColor;
442 else switch( nPaletteIdx )
444 case OOX_COLOR_WINDOWTEXT3:
445 case OOX_COLOR_WINDOWTEXT:
446 case OOX_COLOR_CHWINDOWTEXT: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_windowText ); break;
447 case OOX_COLOR_WINDOWBACK3:
448 case OOX_COLOR_WINDOWBACK:
449 case OOX_COLOR_CHWINDOWBACK: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_window ); break;
450 case OOX_COLOR_BUTTONBACK: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_btnFace ); break;
451 case OOX_COLOR_CHBORDERAUTO: nColor = API_RGB_BLACK; /* really always black? */ break;
452 case OOX_COLOR_NOTEBACK: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_infoBk ); break;
453 case OOX_COLOR_NOTETEXT: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_infoText ); break;
454 case OOX_COLOR_FONTAUTO: nColor = API_RGB_TRANSPARENT; break;
455 default: OSL_FAIL( "ColorPalette::getColor - unknown color index" );
457 return nColor;
460 void ColorPalette::appendColor( sal_Int32 nRGBValue )
462 if( mnAppendIndex < maColors.size() )
463 maColors[ mnAppendIndex ] = nRGBValue;
464 else
465 maColors.push_back( nRGBValue );
466 ++mnAppendIndex;
469 namespace {
471 void lclSetFontName( ApiScriptFontName& rFontName, const FontDescriptor& rFontDesc, bool bHasGlyphs )
473 if( bHasGlyphs )
475 rFontName.maName = rFontDesc.Name;
476 rFontName.mnFamily = rFontDesc.Family;
477 // API font descriptor contains rtl_TextEncoding constants
478 rFontName.mnTextEnc = rFontDesc.CharSet;
480 else
482 rFontName = ApiScriptFontName();
486 } // namespace
488 FontModel::FontModel() :
489 mnScheme( XML_none ),
490 mnFamily( OOX_FONTFAMILY_NONE ),
491 mnCharSet( WINDOWS_CHARSET_DEFAULT ),
492 mfHeight( 0.0 ),
493 mnUnderline( XML_none ),
494 mnEscapement( XML_baseline ),
495 mbBold( false ),
496 mbItalic( false ),
497 mbStrikeout( false ),
498 mbOutline( false ),
499 mbShadow( false )
503 void FontModel::setBiff12Scheme( sal_uInt8 nScheme )
505 static const sal_Int32 spnSchemes[] = { XML_none, XML_major, XML_minor };
506 mnScheme = STATIC_ARRAY_SELECT( spnSchemes, nScheme, XML_none );
509 void FontModel::setBiffHeight( sal_uInt16 nHeight )
511 mfHeight = nHeight / 20.0; // convert twips to points
514 void FontModel::setBiffWeight( sal_uInt16 nWeight )
516 mbBold = nWeight >= BIFF_FONTWEIGHT_BOLD;
519 void FontModel::setBiffUnderline( sal_uInt16 nUnderline )
521 switch( nUnderline )
523 case BIFF_FONTUNDERL_NONE: mnUnderline = XML_none; break;
524 case BIFF_FONTUNDERL_SINGLE: mnUnderline = XML_single; break;
525 case BIFF_FONTUNDERL_DOUBLE: mnUnderline = XML_double; break;
526 case BIFF_FONTUNDERL_SINGLE_ACC: mnUnderline = XML_singleAccounting; break;
527 case BIFF_FONTUNDERL_DOUBLE_ACC: mnUnderline = XML_doubleAccounting; break;
528 default: mnUnderline = XML_none;
532 void FontModel::setBiffEscapement( sal_uInt16 nEscapement )
534 static const sal_Int32 spnEscapes[] = { XML_baseline, XML_superscript, XML_subscript };
535 mnEscapement = STATIC_ARRAY_SELECT( spnEscapes, nEscapement, XML_baseline );
538 ApiFontUsedFlags::ApiFontUsedFlags( bool bAllUsed ) :
539 mbNameUsed( bAllUsed ),
540 mbColorUsed( bAllUsed ),
541 mbSchemeUsed( bAllUsed ),
542 mbHeightUsed( bAllUsed ),
543 mbUnderlineUsed( bAllUsed ),
544 mbEscapementUsed( bAllUsed ),
545 mbWeightUsed( bAllUsed ),
546 mbPostureUsed( bAllUsed ),
547 mbStrikeoutUsed( bAllUsed ),
548 mbOutlineUsed( bAllUsed ),
549 mbShadowUsed( bAllUsed )
553 ApiScriptFontName::ApiScriptFontName() :
554 mnFamily( css::awt::FontFamily::DONTKNOW ),
555 mnTextEnc( RTL_TEXTENCODING_DONTKNOW )
559 ApiFontData::ApiFontData() :
560 maDesc(
561 "Calibri",
562 220, // height 11 points
564 OUString(),
565 css::awt::FontFamily::DONTKNOW,
566 RTL_TEXTENCODING_DONTKNOW,
567 css::awt::FontPitch::DONTKNOW,
568 100.0,
569 css::awt::FontWeight::NORMAL,
570 css::awt::FontSlant_NONE,
571 css::awt::FontUnderline::NONE,
572 css::awt::FontStrikeout::NONE,
573 0.0,
574 false,
575 false,
576 css::awt::FontType::DONTKNOW ),
577 mnColor( API_RGB_TRANSPARENT ),
578 mnEscapement( API_ESCAPE_NONE ),
579 mnEscapeHeight( API_ESCAPEHEIGHT_NONE ),
580 mbOutline( false ),
581 mbShadow( false )
583 maLatinFont.maName = maDesc.Name;
586 Font::Font( const WorkbookHelper& rHelper, bool bDxf ) :
587 WorkbookHelper( rHelper ),
588 maModel( rHelper.getTheme().getDefaultFontModel() ),
589 maUsedFlags( !bDxf ),
590 mbDxf( bDxf )
594 Font::Font( const WorkbookHelper& rHelper, const FontModel& rModel ) :
595 WorkbookHelper( rHelper ),
596 maModel( rModel ),
597 maUsedFlags( true ),
598 mbDxf( false )
602 void Font::importAttribs( sal_Int32 nElement, const AttributeList& rAttribs )
604 const FontModel& rDefModel = getTheme().getDefaultFontModel();
605 switch( nElement )
607 case XLS_TOKEN( name ): // when in <font> element
608 case XLS_TOKEN( rFont ): // when in <rPr> element
609 if( rAttribs.hasAttribute( XML_val ) )
611 maModel.maName = rAttribs.getXString( XML_val, OUString() );
612 maUsedFlags.mbNameUsed = true;
614 break;
615 case XLS_TOKEN( scheme ):
616 maModel.mnScheme = rAttribs.getToken( XML_val, rDefModel.mnScheme );
617 break;
618 case XLS_TOKEN( family ):
619 maModel.mnFamily = rAttribs.getInteger( XML_val, rDefModel.mnFamily );
620 break;
621 case XLS_TOKEN( charset ):
622 maModel.mnCharSet = rAttribs.getInteger( XML_val, rDefModel.mnCharSet );
623 break;
624 case XLS_TOKEN( sz ):
625 maModel.mfHeight = rAttribs.getDouble( XML_val, rDefModel.mfHeight );
626 maUsedFlags.mbHeightUsed = true;
627 break;
628 case XLS_TOKEN( color ):
629 maModel.maColor.importColor( rAttribs );
630 maUsedFlags.mbColorUsed = true;
631 break;
632 case XLS_TOKEN( u ):
633 maModel.mnUnderline = rAttribs.getToken( XML_val, XML_single );
634 maUsedFlags.mbUnderlineUsed = true;
635 break;
636 case XLS_TOKEN( vertAlign ):
637 maModel.mnEscapement = rAttribs.getToken( XML_val, XML_baseline );
638 maUsedFlags.mbEscapementUsed = true;
639 break;
640 case XLS_TOKEN( b ):
641 maModel.mbBold = rAttribs.getBool( XML_val, true );
642 maUsedFlags.mbWeightUsed = true;
643 break;
644 case XLS_TOKEN( i ):
645 maModel.mbItalic = rAttribs.getBool( XML_val, true );
646 maUsedFlags.mbPostureUsed = true;
647 break;
648 case XLS_TOKEN( strike ):
649 maModel.mbStrikeout = rAttribs.getBool( XML_val, true );
650 maUsedFlags.mbStrikeoutUsed = true;
651 break;
652 case XLS_TOKEN( outline ):
653 maModel.mbOutline = rAttribs.getBool( XML_val, true );
654 maUsedFlags.mbOutlineUsed = true;
655 break;
656 case XLS_TOKEN( shadow ):
657 maModel.mbShadow = rAttribs.getBool( XML_val, true );
658 maUsedFlags.mbShadowUsed = true;
659 break;
663 void Font::importFont( SequenceInputStream& rStrm )
665 SAL_WARN_IF( mbDxf, "sc", "Font::importFont - unexpected conditional formatting flag" );
667 sal_uInt16 nHeight, nFlags, nWeight, nEscapement;
668 sal_uInt8 nUnderline, nFamily, nCharSet, nScheme;
669 nHeight = rStrm.readuInt16();
670 nFlags = rStrm.readuInt16();
671 nWeight = rStrm.readuInt16();
672 nEscapement = rStrm.readuInt16();
673 nUnderline = rStrm.readuChar();
674 nFamily = rStrm.readuChar();
675 nCharSet = rStrm.readuChar();
676 rStrm.skip( 1 );
677 rStrm >> maModel.maColor;
678 nScheme = rStrm.readuChar();
679 rStrm >> maModel.maName;
681 // equal constants in all BIFFs for weight, underline, and escapement
682 maModel.setBiff12Scheme( nScheme );
683 maModel.setBiffHeight( nHeight );
684 maModel.setBiffWeight( nWeight );
685 maModel.setBiffUnderline( nUnderline );
686 maModel.setBiffEscapement( nEscapement );
687 maModel.mnFamily = nFamily;
688 maModel.mnCharSet = nCharSet;
689 // equal flags in all BIFFs
690 maModel.mbItalic = getFlag( nFlags, BIFF_FONTFLAG_ITALIC );
691 maModel.mbStrikeout = getFlag( nFlags, BIFF_FONTFLAG_STRIKEOUT );
692 maModel.mbOutline = getFlag( nFlags, BIFF_FONTFLAG_OUTLINE );
693 maModel.mbShadow = getFlag( nFlags, BIFF_FONTFLAG_SHADOW );
696 void Font::importDxfName( SequenceInputStream& rStrm )
698 SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfName - missing conditional formatting flag" );
699 maModel.maName = BiffHelper::readString( rStrm, false );
700 maUsedFlags.mbColorUsed = true;
703 void Font::importDxfColor( SequenceInputStream& rStrm )
705 SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfColor - missing conditional formatting flag" );
706 rStrm >> maModel.maColor;
707 maUsedFlags.mbColorUsed = true;
710 void Font::importDxfScheme( SequenceInputStream& rStrm )
712 SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfScheme - missing conditional formatting flag" );
713 maModel.setBiff12Scheme( rStrm.readuInt8() );
714 maUsedFlags.mbSchemeUsed = true;
717 void Font::importDxfHeight( SequenceInputStream& rStrm )
719 SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfHeight - missing conditional formatting flag" );
720 maModel.setBiffHeight( rStrm.readuInt16() );
721 maUsedFlags.mbHeightUsed = true;
724 void Font::importDxfWeight( SequenceInputStream& rStrm )
726 SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfWeight - missing conditional formatting flag" );
727 maModel.setBiffWeight( rStrm.readuInt16() );
728 maUsedFlags.mbWeightUsed = true;
731 void Font::importDxfUnderline( SequenceInputStream& rStrm )
733 SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfUnderline - missing conditional formatting flag" );
734 maModel.setBiffUnderline( rStrm.readuInt16() );
735 maUsedFlags.mbUnderlineUsed = true;
738 void Font::importDxfEscapement( SequenceInputStream& rStrm )
740 SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfEscapement - missing conditional formatting flag" );
741 maModel.setBiffEscapement( rStrm.readuInt16() );
742 maUsedFlags.mbEscapementUsed = true;
745 void Font::importDxfFlag( sal_Int32 nElement, SequenceInputStream& rStrm )
747 SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfFlag - missing conditional formatting flag" );
748 bool bFlag = rStrm.readuInt8() != 0;
749 switch( nElement )
751 case XML_i:
752 maModel.mbItalic = bFlag;
753 maUsedFlags.mbPostureUsed = true;
754 break;
755 case XML_strike:
756 maModel.mbStrikeout = bFlag;
757 maUsedFlags.mbStrikeoutUsed = true;
758 break;
759 case XML_outline:
760 maModel.mbOutline = bFlag;
761 maUsedFlags.mbOutlineUsed = true;
762 break;
763 case XML_shadow:
764 maModel.mbShadow = bFlag;
765 maUsedFlags.mbShadowUsed = true;
766 break;
767 default:
768 OSL_FAIL( "Font::importDxfFlag - unexpected element identifier" );
772 void Font::finalizeImport()
774 // font name
775 maApiData.maDesc.Name = maModel.maName;
777 // font family
778 switch( maModel.mnFamily )
780 case OOX_FONTFAMILY_NONE: maApiData.maDesc.Family = css::awt::FontFamily::DONTKNOW; break;
781 case OOX_FONTFAMILY_ROMAN: maApiData.maDesc.Family = css::awt::FontFamily::ROMAN; break;
782 case OOX_FONTFAMILY_SWISS: maApiData.maDesc.Family = css::awt::FontFamily::SWISS; break;
783 case OOX_FONTFAMILY_MODERN: maApiData.maDesc.Family = css::awt::FontFamily::MODERN; break;
784 case OOX_FONTFAMILY_SCRIPT: maApiData.maDesc.Family = css::awt::FontFamily::SCRIPT; break;
785 case OOX_FONTFAMILY_DECORATIVE: maApiData.maDesc.Family = css::awt::FontFamily::DECORATIVE; break;
788 // character set (API font descriptor uses rtl_TextEncoding in member CharSet!)
789 if( (0 <= maModel.mnCharSet) && (maModel.mnCharSet <= SAL_MAX_UINT8) )
790 maApiData.maDesc.CharSet = static_cast< sal_Int16 >(
791 rtl_getTextEncodingFromWindowsCharset( static_cast< sal_uInt8 >( maModel.mnCharSet ) ) );
793 // color, height, weight, slant, strikeout, outline, shadow
794 maApiData.mnColor = maModel.maColor.getColor( getBaseFilter().getGraphicHelper() );
795 maApiData.maDesc.Height = static_cast< sal_Int16 >( maModel.mfHeight * 20.0 );
796 maApiData.maDesc.Weight = maModel.mbBold ? css::awt::FontWeight::BOLD : css::awt::FontWeight::NORMAL;
797 maApiData.maDesc.Slant = maModel.mbItalic ? css::awt::FontSlant_ITALIC : css::awt::FontSlant_NONE;
798 maApiData.maDesc.Strikeout = maModel.mbStrikeout ? css::awt::FontStrikeout::SINGLE : css::awt::FontStrikeout::NONE;
799 maApiData.mbOutline = maModel.mbOutline;
800 maApiData.mbShadow = maModel.mbShadow;
802 // underline
803 switch( maModel.mnUnderline )
805 case XML_double: maApiData.maDesc.Underline = css::awt::FontUnderline::DOUBLE; break;
806 case XML_doubleAccounting: maApiData.maDesc.Underline = css::awt::FontUnderline::DOUBLE; break;
807 case XML_none: maApiData.maDesc.Underline = css::awt::FontUnderline::NONE; break;
808 case XML_single: maApiData.maDesc.Underline = css::awt::FontUnderline::SINGLE; break;
809 case XML_singleAccounting: maApiData.maDesc.Underline = css::awt::FontUnderline::SINGLE; break;
812 // escapement
813 switch( maModel.mnEscapement )
815 case XML_baseline:
816 maApiData.mnEscapement = API_ESCAPE_NONE;
817 maApiData.mnEscapeHeight = API_ESCAPEHEIGHT_NONE;
818 break;
819 case XML_superscript:
820 maApiData.mnEscapement = API_ESCAPE_SUPERSCRIPT;
821 maApiData.mnEscapeHeight = API_ESCAPEHEIGHT_DEFAULT;
822 break;
823 case XML_subscript:
824 maApiData.mnEscapement = API_ESCAPE_SUBSCRIPT;
825 maApiData.mnEscapeHeight = API_ESCAPEHEIGHT_DEFAULT;
826 break;
829 // supported script types
830 if( maUsedFlags.mbNameUsed )
832 PropertySet aDocProps( getDocument() );
833 Reference< XDevice > xDevice( aDocProps.getAnyProperty( PROP_ReferenceDevice ), UNO_QUERY );
834 if( xDevice.is() )
836 Reference< XFont2 > xFont( xDevice->getFont( maApiData.maDesc ), UNO_QUERY );
837 if( xFont.is() )
839 // #91658# CJK fonts
840 bool bHasAsian =
841 xFont->hasGlyphs( OUString( sal_Unicode( 0x3041 ) ) ) || // 3040-309F: Hiragana
842 xFont->hasGlyphs( OUString( sal_Unicode( 0x30A1 ) ) ) || // 30A0-30FF: Katakana
843 xFont->hasGlyphs( OUString( sal_Unicode( 0x3111 ) ) ) || // 3100-312F: Bopomofo
844 xFont->hasGlyphs( OUString( sal_Unicode( 0x3131 ) ) ) || // 3130-318F: Hangul Compatibility Jamo
845 xFont->hasGlyphs( OUString( sal_Unicode( 0x3301 ) ) ) || // 3300-33FF: CJK Compatibility
846 xFont->hasGlyphs( OUString( sal_Unicode( 0x3401 ) ) ) || // 3400-4DBF: CJK Unified Ideographs Extension A
847 xFont->hasGlyphs( OUString( sal_Unicode( 0x4E01 ) ) ) || // 4E00-9FAF: CJK Unified Ideographs
848 xFont->hasGlyphs( OUString( sal_Unicode( 0x7E01 ) ) ) || // 4E00-9FAF: CJK unified ideographs
849 xFont->hasGlyphs( OUString( sal_Unicode( 0xA001 ) ) ) || // A001-A48F: Yi Syllables
850 xFont->hasGlyphs( OUString( sal_Unicode( 0xAC01 ) ) ) || // AC00-D7AF: Hangul Syllables
851 xFont->hasGlyphs( OUString( sal_Unicode( 0xCC01 ) ) ) || // AC00-D7AF: Hangul Syllables
852 xFont->hasGlyphs( OUString( sal_Unicode( 0xF901 ) ) ) || // F900-FAFF: CJK Compatibility Ideographs
853 xFont->hasGlyphs( OUString( sal_Unicode( 0xFF71 ) ) ); // FF00-FFEF: Halfwidth/Fullwidth Forms
854 // #113783# CTL fonts
855 bool bHasCmplx =
856 xFont->hasGlyphs( OUString( sal_Unicode( 0x05D1 ) ) ) || // 0590-05FF: Hebrew
857 xFont->hasGlyphs( OUString( sal_Unicode( 0x0631 ) ) ) || // 0600-06FF: Arabic
858 xFont->hasGlyphs( OUString( sal_Unicode( 0x0721 ) ) ) || // 0700-074F: Syriac
859 xFont->hasGlyphs( OUString( sal_Unicode( 0x0911 ) ) ) || // 0900-0DFF: Indic scripts
860 xFont->hasGlyphs( OUString( sal_Unicode( 0x0E01 ) ) ) || // 0E00-0E7F: Thai
861 xFont->hasGlyphs( OUString( sal_Unicode( 0xFB21 ) ) ) || // FB1D-FB4F: Hebrew Presentation Forms
862 xFont->hasGlyphs( OUString( sal_Unicode( 0xFB51 ) ) ) || // FB50-FDFF: Arabic Presentation Forms-A
863 xFont->hasGlyphs( OUString( sal_Unicode( 0xFE71 ) ) ); // FE70-FEFF: Arabic Presentation Forms-B
864 // Western fonts
865 bool bHasLatin =
866 (!bHasAsian && !bHasCmplx) ||
867 xFont->hasGlyphs( OUString( 'A' ) );
869 lclSetFontName( maApiData.maLatinFont, maApiData.maDesc, bHasLatin );
870 lclSetFontName( maApiData.maAsianFont, maApiData.maDesc, bHasAsian );
871 lclSetFontName( maApiData.maCmplxFont, maApiData.maDesc, bHasCmplx );
877 bool Font::needsRichTextFormat() const
879 return maApiData.mnEscapement != API_ESCAPE_NONE;
882 ::FontFamily lcl_getFontFamily( sal_Int32 nFamily )
884 ::FontFamily eScFamily = FAMILY_DONTKNOW;
885 switch( nFamily )
887 case css::awt::FontFamily::DONTKNOW:
888 eScFamily = FAMILY_DONTKNOW;
889 break;
890 case css::awt::FontFamily::ROMAN:
891 eScFamily = FAMILY_ROMAN;
892 break;
893 case css::awt::FontFamily::SWISS:
894 eScFamily = FAMILY_SWISS;
895 break;
896 case css::awt::FontFamily::MODERN:
897 eScFamily = FAMILY_MODERN;
898 break;
899 case css::awt::FontFamily::SCRIPT:
900 eScFamily = FAMILY_SCRIPT;
901 break;
902 case css::awt::FontFamily::DECORATIVE:
903 eScFamily = FAMILY_DECORATIVE;
904 break;
906 return eScFamily;
909 void Font::fillToItemSet( SfxItemSet& rItemSet, bool bEditEngineText, bool bSkipPoolDefs ) const
911 if ( maUsedFlags.mbNameUsed )
913 if( !maApiData.maLatinFont.maName.isEmpty() )
915 rtl_TextEncoding eFontEnc = maApiData.maLatinFont.mnTextEnc;
916 // taken from binary importer
917 rtl_TextEncoding eTempTextEnc = (bEditEngineText && (eFontEnc == getTextEncoding())) ?
918 ScfTools::GetSystemTextEncoding() : eFontEnc;
920 SvxFontItem aFontItem( lcl_getFontFamily( maApiData.maLatinFont.mnFamily ), maApiData.maLatinFont.maName, OUString(),
921 PITCH_DONTKNOW, eTempTextEnc, ATTR_FONT );
922 ScfTools::PutItem( rItemSet, aFontItem, bEditEngineText ? EE_CHAR_FONTINFO : ATTR_FONT, bSkipPoolDefs );
924 if( !maApiData.maAsianFont.maName.isEmpty() )
926 rtl_TextEncoding eFontEnc = maApiData.maAsianFont.mnTextEnc;
927 // taken from binary importer
928 rtl_TextEncoding eTempTextEnc = (bEditEngineText && (eFontEnc == getTextEncoding())) ?
929 ScfTools::GetSystemTextEncoding() : eFontEnc;
930 SvxFontItem aFontItem( lcl_getFontFamily( maApiData.maAsianFont.mnFamily ), maApiData.maAsianFont.maName, OUString(),
931 PITCH_DONTKNOW, eTempTextEnc, ATTR_FONT );
932 ScfTools::PutItem( rItemSet, aFontItem, bEditEngineText ? EE_CHAR_FONTINFO_CJK : ATTR_CJK_FONT, bSkipPoolDefs );
934 if( !maApiData.maCmplxFont.maName.isEmpty() )
936 rtl_TextEncoding eFontEnc = maApiData.maCmplxFont.mnTextEnc;
937 // taken from binary importer
938 rtl_TextEncoding eTempTextEnc = (bEditEngineText && (eFontEnc == getTextEncoding())) ?
939 ScfTools::GetSystemTextEncoding() : eFontEnc;
940 SvxFontItem aFontItem( lcl_getFontFamily( maApiData.maCmplxFont.mnFamily ), maApiData.maCmplxFont.maName, OUString(),
941 PITCH_DONTKNOW, eTempTextEnc, ATTR_FONT );
942 ScfTools::PutItem( rItemSet, aFontItem, bEditEngineText ? EE_CHAR_FONTINFO_CTL : ATTR_CTL_FONT, bSkipPoolDefs );
945 // font height
946 if( maUsedFlags.mbHeightUsed )
948 sal_Int32 nHeight = maApiData.maDesc.Height;
949 // do we use EXC_FONTITEM_HF ( or is it just relevant for the binary filter )
950 if( bEditEngineText/* && (eType != EXC_FONTITEM_HF) */) // do not convert header/footer height
951 nHeight = (nHeight * 127 + 36) / EXC_POINTS_PER_INCH; // 1 in == 72 pt
952 SvxFontHeightItem aHeightItem( nHeight, 100, ATTR_FONT_HEIGHT );
953 ScfTools::PutItem( rItemSet, aHeightItem, bEditEngineText ? EE_CHAR_FONTHEIGHT : ATTR_FONT_HEIGHT, bSkipPoolDefs );
954 ScfTools::PutItem( rItemSet, aHeightItem, bEditEngineText ? EE_CHAR_FONTHEIGHT_CJK : ATTR_CJK_FONT_HEIGHT, bSkipPoolDefs );
955 ScfTools::PutItem( rItemSet, aHeightItem, bEditEngineText ? EE_CHAR_FONTHEIGHT_CTL : ATTR_CTL_FONT_HEIGHT, bSkipPoolDefs );
957 // font weight
958 if( maUsedFlags.mbWeightUsed )
960 ::FontWeight fWeight = VCLUnoHelper::ConvertFontWeight( maApiData.maDesc.Weight );
961 SvxWeightItem aWeightItem( fWeight, ATTR_FONT_WEIGHT );
962 ScfTools::PutItem( rItemSet, aWeightItem, bEditEngineText ? EE_CHAR_WEIGHT : ATTR_FONT_WEIGHT, bSkipPoolDefs );
963 ScfTools::PutItem( rItemSet, aWeightItem, bEditEngineText ? EE_CHAR_WEIGHT_CTL : ATTR_CTL_FONT_WEIGHT, bSkipPoolDefs );
964 ScfTools::PutItem( rItemSet, aWeightItem, bEditEngineText ? EE_CHAR_WEIGHT_CJK : ATTR_CJK_FONT_WEIGHT, bSkipPoolDefs );
966 // font posture
967 if( maUsedFlags.mbPostureUsed )
969 SvxPostureItem aPostItem( ( maApiData.maDesc.Slant == css::awt::FontSlant_ITALIC ) ? ITALIC_NORMAL : ITALIC_NONE, ATTR_FONT_POSTURE);
970 ScfTools::PutItem( rItemSet, aPostItem, bEditEngineText ? EE_CHAR_ITALIC : ATTR_FONT_POSTURE, bSkipPoolDefs );
971 ScfTools::PutItem( rItemSet, aPostItem, bEditEngineText ? EE_CHAR_ITALIC_CJK : ATTR_CJK_FONT_POSTURE, bSkipPoolDefs );
972 ScfTools::PutItem( rItemSet, aPostItem, bEditEngineText ? EE_CHAR_ITALIC_CTL : ATTR_CTL_FONT_POSTURE, bSkipPoolDefs );
974 // character color
975 if( maUsedFlags.mbColorUsed )
977 ScfTools::PutItem( rItemSet,SvxColorItem( maApiData.mnColor, bEditEngineText ? EE_CHAR_COLOR : ATTR_FONT_COLOR ) , bSkipPoolDefs );
979 // underline style
980 if( maUsedFlags.mbUnderlineUsed )
982 FontLineStyle eScUnderl;
983 if ( maApiData.maDesc.Underline == css::awt::FontUnderline::DOUBLE )
984 eScUnderl = LINESTYLE_DOUBLE;
985 else if ( maApiData.maDesc.Underline == css::awt::FontUnderline::SINGLE )
986 eScUnderl = LINESTYLE_SINGLE;
987 else
988 eScUnderl = LINESTYLE_NONE;
989 SvxUnderlineItem aUnderlItem( eScUnderl, ATTR_FONT_UNDERLINE );
990 ScfTools::PutItem( rItemSet, aUnderlItem, bEditEngineText ? EE_CHAR_UNDERLINE : ATTR_FONT_UNDERLINE, bSkipPoolDefs );
992 // strike out style
993 if( maUsedFlags.mbStrikeoutUsed )
995 ScfTools::PutItem( rItemSet, SvxCrossedOutItem( maModel.mbStrikeout ? STRIKEOUT_SINGLE : STRIKEOUT_NONE, bEditEngineText ? EE_CHAR_STRIKEOUT : ATTR_FONT_CROSSEDOUT ), bEditEngineText ? EE_CHAR_STRIKEOUT : ATTR_FONT_CROSSEDOUT, bSkipPoolDefs );
998 // outline style
999 if( maUsedFlags.mbOutlineUsed )
1001 ScfTools::PutItem( rItemSet, SvxContourItem( maApiData.mbOutline, ATTR_FONT_CONTOUR ), bEditEngineText ? EE_CHAR_OUTLINE : ATTR_FONT_CONTOUR, bSkipPoolDefs );
1004 // shadow style
1005 if( maUsedFlags.mbShadowUsed )
1007 ScfTools::PutItem( rItemSet, SvxShadowedItem( maApiData.mbShadow, ATTR_FONT_SHADOWED ), bEditEngineText ? EE_CHAR_SHADOW : ATTR_FONT_SHADOWED, bSkipPoolDefs );
1009 if( maUsedFlags.mbEscapementUsed )
1011 SvxEscapement eScEscapem = SVX_ESCAPEMENT_OFF;
1012 if ( maApiData.mnEscapement == API_ESCAPE_SUPERSCRIPT )
1013 eScEscapem = SVX_ESCAPEMENT_SUPERSCRIPT;
1014 else if ( maApiData.mnEscapement == API_ESCAPE_SUBSCRIPT )
1015 eScEscapem = SVX_ESCAPEMENT_SUBSCRIPT;
1016 if( bEditEngineText )
1018 // #TODO handle EscapementHeight
1019 rItemSet.Put( SvxEscapementItem( eScEscapem, EE_CHAR_ESCAPEMENT ) );
1024 void Font::writeToPropertyMap( PropertyMap& rPropMap, FontPropertyType ePropType ) const
1026 // font name properties
1027 if( maUsedFlags.mbNameUsed )
1029 if( !maApiData.maLatinFont.maName.isEmpty() )
1031 rPropMap.setProperty( PROP_CharFontName, maApiData.maLatinFont.maName);
1032 rPropMap.setProperty( PROP_CharFontFamily, maApiData.maLatinFont.mnFamily);
1033 rPropMap.setProperty( PROP_CharFontCharSet, maApiData.maLatinFont.mnTextEnc);
1035 if( !maApiData.maAsianFont.maName.isEmpty() )
1037 rPropMap.setProperty( PROP_CharFontNameAsian, maApiData.maAsianFont.maName);
1038 rPropMap.setProperty( PROP_CharFontFamilyAsian, maApiData.maAsianFont.mnFamily);
1039 rPropMap.setProperty( PROP_CharFontCharSetAsian, maApiData.maAsianFont.mnTextEnc);
1041 if( !maApiData.maCmplxFont.maName.isEmpty() )
1043 rPropMap.setProperty( PROP_CharFontNameComplex, maApiData.maCmplxFont.maName);
1044 rPropMap.setProperty( PROP_CharFontFamilyComplex, maApiData.maCmplxFont.mnFamily);
1045 rPropMap.setProperty( PROP_CharFontCharSetComplex, maApiData.maCmplxFont.mnTextEnc);
1048 // font height
1049 if( maUsedFlags.mbHeightUsed )
1051 float fHeight = static_cast< float >( maApiData.maDesc.Height / 20.0 ); // twips to points
1052 rPropMap.setProperty( PROP_CharHeight, fHeight);
1053 rPropMap.setProperty( PROP_CharHeightAsian, fHeight);
1054 rPropMap.setProperty( PROP_CharHeightComplex, fHeight);
1056 // font weight
1057 if( maUsedFlags.mbWeightUsed )
1059 float fWeight = maApiData.maDesc.Weight;
1060 rPropMap.setProperty( PROP_CharWeight, fWeight);
1061 rPropMap.setProperty( PROP_CharWeightAsian, fWeight);
1062 rPropMap.setProperty( PROP_CharWeightComplex, fWeight);
1064 // font posture
1065 if( maUsedFlags.mbPostureUsed )
1067 rPropMap.setProperty( PROP_CharPosture, maApiData.maDesc.Slant);
1068 rPropMap.setProperty( PROP_CharPostureAsian, maApiData.maDesc.Slant);
1069 rPropMap.setProperty( PROP_CharPostureComplex, maApiData.maDesc.Slant);
1071 // character color
1072 if( maUsedFlags.mbColorUsed )
1073 rPropMap.setProperty( PROP_CharColor, maApiData.mnColor);
1074 // underline style
1075 if( maUsedFlags.mbUnderlineUsed )
1076 rPropMap.setProperty( PROP_CharUnderline, maApiData.maDesc.Underline);
1077 // strike out style
1078 if( maUsedFlags.mbStrikeoutUsed )
1079 rPropMap.setProperty( PROP_CharStrikeout, maApiData.maDesc.Strikeout);
1080 // outline style
1081 if( maUsedFlags.mbOutlineUsed )
1082 rPropMap.setProperty( PROP_CharContoured, maApiData.mbOutline);
1083 // shadow style
1084 if( maUsedFlags.mbShadowUsed )
1085 rPropMap.setProperty( PROP_CharShadowed, maApiData.mbShadow);
1086 // escapement
1087 if( maUsedFlags.mbEscapementUsed )
1089 rPropMap.setProperty( PROP_CharEscapement, maApiData.mnEscapement);
1090 if( ePropType == FONT_PROPTYPE_TEXT )
1091 rPropMap.setProperty( PROP_CharEscapementHeight, maApiData.mnEscapeHeight);
1095 void Font::writeToPropertySet( PropertySet& rPropSet, FontPropertyType ePropType ) const
1097 PropertyMap aPropMap;
1098 writeToPropertyMap( aPropMap, ePropType );
1099 rPropSet.setProperties( aPropMap );
1102 AlignmentModel::AlignmentModel() :
1103 mnHorAlign( XML_general ),
1104 mnVerAlign( XML_bottom ),
1105 mnTextDir( OOX_XF_TEXTDIR_CONTEXT ),
1106 mnRotation( OOX_XF_ROTATION_NONE ),
1107 mnIndent( OOX_XF_INDENT_NONE ),
1108 mbWrapText( false ),
1109 mbShrink( false ),
1110 mbJustLastLine( false )
1114 void AlignmentModel::setBiffHorAlign( sal_uInt8 nHorAlign )
1116 static const sal_Int32 spnHorAligns[] = {
1117 XML_general, XML_left, XML_center, XML_right,
1118 XML_fill, XML_justify, XML_centerContinuous, XML_distributed };
1119 mnHorAlign = STATIC_ARRAY_SELECT( spnHorAligns, nHorAlign, XML_general );
1122 void AlignmentModel::setBiffVerAlign( sal_uInt8 nVerAlign )
1124 static const sal_Int32 spnVerAligns[] = {
1125 XML_top, XML_center, XML_bottom, XML_justify, XML_distributed };
1126 mnVerAlign = STATIC_ARRAY_SELECT( spnVerAligns, nVerAlign, XML_bottom );
1129 ApiAlignmentData::ApiAlignmentData() :
1130 meHorJustify( css::table::CellHoriJustify_STANDARD ),
1131 mnHorJustifyMethod( css::table::CellJustifyMethod::AUTO ),
1132 mnVerJustify( css::table::CellVertJustify2::STANDARD ),
1133 mnVerJustifyMethod( css::table::CellJustifyMethod::AUTO ),
1134 meOrientation( css::table::CellOrientation_STANDARD ),
1135 mnRotation( 0 ),
1136 mnWritingMode( css::text::WritingMode2::PAGE ),
1137 mnIndent( 0 ),
1138 mbWrapText( false ),
1139 mbShrink( false )
1143 bool operator==( const ApiAlignmentData& rLeft, const ApiAlignmentData& rRight )
1145 return
1146 (rLeft.meHorJustify == rRight.meHorJustify) &&
1147 (rLeft.mnHorJustifyMethod == rRight.mnHorJustifyMethod) &&
1148 (rLeft.mnVerJustify == rRight.mnVerJustify) &&
1149 (rLeft.mnVerJustifyMethod == rRight.mnVerJustifyMethod) &&
1150 (rLeft.meOrientation == rRight.meOrientation) &&
1151 (rLeft.mnRotation == rRight.mnRotation) &&
1152 (rLeft.mnWritingMode == rRight.mnWritingMode) &&
1153 (rLeft.mnIndent == rRight.mnIndent) &&
1154 (rLeft.mbWrapText == rRight.mbWrapText) &&
1155 (rLeft.mbShrink == rRight.mbShrink);
1158 Alignment::Alignment( const WorkbookHelper& rHelper ) :
1159 WorkbookHelper( rHelper )
1163 void Alignment::importAlignment( const AttributeList& rAttribs )
1165 maModel.mnHorAlign = rAttribs.getToken( XML_horizontal, XML_general );
1166 maModel.mnVerAlign = rAttribs.getToken( XML_vertical, XML_bottom );
1167 maModel.mnTextDir = rAttribs.getInteger( XML_readingOrder, OOX_XF_TEXTDIR_CONTEXT );
1168 maModel.mnRotation = rAttribs.getInteger( XML_textRotation, OOX_XF_ROTATION_NONE );
1169 maModel.mnIndent = rAttribs.getInteger( XML_indent, OOX_XF_INDENT_NONE );
1170 maModel.mbWrapText = rAttribs.getBool( XML_wrapText, false );
1171 maModel.mbShrink = rAttribs.getBool( XML_shrinkToFit, false );
1172 maModel.mbJustLastLine = rAttribs.getBool( XML_justifyLastLine, false );
1175 void Alignment::setBiff12Data( sal_uInt32 nFlags )
1177 maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nFlags, 16, 3 ) );
1178 maModel.setBiffVerAlign( extractValue< sal_uInt8 >( nFlags, 19, 3 ) );
1179 maModel.mnTextDir = extractValue< sal_Int32 >( nFlags, 26, 2 );
1180 maModel.mnRotation = extractValue< sal_Int32 >( nFlags, 0, 8 );
1181 maModel.mnIndent = extractValue< sal_uInt8 >( nFlags, 8, 8 );
1182 maModel.mbWrapText = getFlag( nFlags, BIFF12_XF_WRAPTEXT );
1183 maModel.mbShrink = getFlag( nFlags, BIFF12_XF_SHRINK );
1184 maModel.mbJustLastLine = getFlag( nFlags, BIFF12_XF_JUSTLASTLINE );
1187 void Alignment::finalizeImport()
1189 // horizontal alignment
1190 switch( maModel.mnHorAlign )
1192 case XML_center: maApiData.meHorJustify = css::table::CellHoriJustify_CENTER; break;
1193 case XML_centerContinuous: maApiData.meHorJustify = css::table::CellHoriJustify_CENTER; break;
1194 case XML_distributed: maApiData.meHorJustify = css::table::CellHoriJustify_BLOCK; break;
1195 case XML_fill: maApiData.meHorJustify = css::table::CellHoriJustify_REPEAT; break;
1196 case XML_general: maApiData.meHorJustify = css::table::CellHoriJustify_STANDARD; break;
1197 case XML_justify: maApiData.meHorJustify = css::table::CellHoriJustify_BLOCK; break;
1198 case XML_left: maApiData.meHorJustify = css::table::CellHoriJustify_LEFT; break;
1199 case XML_right: maApiData.meHorJustify = css::table::CellHoriJustify_RIGHT; break;
1202 if (maModel.mnHorAlign == XML_distributed)
1203 maApiData.mnHorJustifyMethod = css::table::CellJustifyMethod::DISTRIBUTE;
1205 // vertical alignment
1206 switch( maModel.mnVerAlign )
1208 case XML_bottom: maApiData.mnVerJustify = css::table::CellVertJustify2::BOTTOM; break;
1209 case XML_center: maApiData.mnVerJustify = css::table::CellVertJustify2::CENTER; break;
1210 case XML_distributed: maApiData.mnVerJustify = css::table::CellVertJustify2::BLOCK; break;
1211 case XML_justify: maApiData.mnVerJustify = css::table::CellVertJustify2::BLOCK; break;
1212 case XML_top: maApiData.mnVerJustify = css::table::CellVertJustify2::TOP; break;
1215 if (maModel.mnVerAlign == XML_distributed)
1216 maApiData.mnVerJustifyMethod = css::table::CellJustifyMethod::DISTRIBUTE;
1218 /* indentation: expressed as number of blocks of 3 space characters in
1219 OOXML/BIFF12, and as multiple of 10 points in BIFF8. */
1220 sal_Int32 nIndent = 0;
1221 switch( getFilterType() )
1223 case FILTER_OOXML: nIndent = getUnitConverter().scaleToMm100( 3.0 * maModel.mnIndent, UNIT_SPACE ); break;
1224 case FILTER_BIFF: nIndent = getUnitConverter().scaleToMm100( 10.0 * maModel.mnIndent, UNIT_POINT ); break;
1225 case FILTER_UNKNOWN: break;
1227 if( (0 <= nIndent) && (nIndent <= SAL_MAX_INT16) )
1228 maApiData.mnIndent = static_cast< sal_Int16 >( nIndent );
1230 // complex text direction
1231 switch( maModel.mnTextDir )
1233 case OOX_XF_TEXTDIR_CONTEXT: maApiData.mnWritingMode = css::text::WritingMode2::PAGE; break;
1234 case OOX_XF_TEXTDIR_LTR: maApiData.mnWritingMode = css::text::WritingMode2::LR_TB; break;
1235 case OOX_XF_TEXTDIR_RTL: maApiData.mnWritingMode = css::text::WritingMode2::RL_TB; break;
1238 // rotation: 0-90 means 0 to 90 degrees ccw, 91-180 means 1 to 90 degrees cw, 255 means stacked
1239 sal_Int32 nOoxRot = maModel.mnRotation;
1240 maApiData.mnRotation = ((0 <= nOoxRot) && (nOoxRot <= 90)) ?
1241 (100 * nOoxRot) :
1242 (((91 <= nOoxRot) && (nOoxRot <= 180)) ? (100 * (450 - nOoxRot)) : 0);
1244 // "Orientation" property used for character stacking
1245 maApiData.meOrientation = (nOoxRot == OOX_XF_ROTATION_STACKED) ?
1246 css::table::CellOrientation_STACKED : css::table::CellOrientation_STANDARD;
1248 // alignment flags (#i84960 automatic line break, if vertically justified/distributed)
1249 maApiData.mbWrapText = maModel.mbWrapText || (maModel.mnVerAlign == XML_distributed) || (maModel.mnVerAlign == XML_justify);
1250 maApiData.mbShrink = maModel.mbShrink;
1254 ::SvxCellVerJustify Alignment::GetScVerAlign() const
1256 ::SvxCellVerJustify nVert = ::SVX_VER_JUSTIFY_STANDARD;
1257 switch ( maApiData.mnVerJustify )
1259 case css::table::CellVertJustify2::BOTTOM:
1260 nVert = ::SVX_VER_JUSTIFY_BOTTOM;
1261 break;
1262 case css::table::CellVertJustify2::CENTER:
1263 nVert = ::SVX_VER_JUSTIFY_CENTER;
1264 break;
1265 case css::table::CellVertJustify2::TOP:
1266 nVert = ::SVX_VER_JUSTIFY_TOP;
1267 break;
1268 case css::table::CellVertJustify2::BLOCK:
1269 nVert = ::SVX_VER_JUSTIFY_BLOCK;
1270 break;
1271 case css::table::CellVertJustify2::STANDARD:
1272 default:
1273 nVert = ::SVX_VER_JUSTIFY_STANDARD;
1274 break;
1276 return nVert;
1279 ::SvxCellHorJustify Alignment::GetScHorAlign() const
1281 ::SvxCellHorJustify nHori = ::SVX_HOR_JUSTIFY_STANDARD;
1282 switch( maApiData.meHorJustify )
1284 case css::table::CellHoriJustify_LEFT:
1285 nHori = ::SVX_HOR_JUSTIFY_LEFT;
1286 break;
1287 case css::table::CellHoriJustify_CENTER:
1288 nHori = ::SVX_HOR_JUSTIFY_CENTER;
1289 break;
1290 case css::table::CellHoriJustify_RIGHT:
1291 nHori = ::SVX_HOR_JUSTIFY_RIGHT;
1292 break;
1293 case css::table::CellHoriJustify_BLOCK:
1294 nHori = ::SVX_HOR_JUSTIFY_BLOCK;
1295 break;
1296 case css::table::CellHoriJustify_REPEAT:
1297 nHori = ::SVX_HOR_JUSTIFY_REPEAT;
1298 break;
1299 case css::table::CellHoriJustify_STANDARD:
1300 default:
1301 nHori = ::SVX_HOR_JUSTIFY_STANDARD;
1302 break;
1304 return nHori;
1307 ::SvxFrameDirection Alignment::GetScFrameDir() const
1309 ::SvxFrameDirection eFrameDir = ::FRMDIR_ENVIRONMENT;
1310 switch( maApiData.mnWritingMode )
1312 case css::text::WritingMode2::PAGE:
1313 eFrameDir = ::FRMDIR_ENVIRONMENT;
1314 break;
1315 case css::text::WritingMode2::LR_TB:
1316 eFrameDir = ::FRMDIR_HORI_LEFT_TOP;
1317 break;
1318 case css::text::WritingMode2::RL_TB:
1319 eFrameDir = ::FRMDIR_HORI_RIGHT_TOP;
1320 break;
1321 default:
1322 OSL_FAIL( "GetScFrameDir - unknown CTL text direction" );
1324 return eFrameDir;
1327 void Alignment::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
1329 // horizontal alignment
1330 ScfTools::PutItem( rItemSet, SvxHorJustifyItem( GetScHorAlign(), ATTR_HOR_JUSTIFY ), bSkipPoolDefs );
1331 ScfTools::PutItem( rItemSet, SvxJustifyMethodItem( ( maApiData.mnHorJustifyMethod == css::table::CellJustifyMethod::DISTRIBUTE ) ? ::SVX_JUSTIFY_METHOD_DISTRIBUTE : ::SVX_JUSTIFY_METHOD_AUTO, ATTR_HOR_JUSTIFY_METHOD ), bSkipPoolDefs );
1332 ScfTools::PutItem( rItemSet, SvxVerJustifyItem( GetScVerAlign(), ATTR_VER_JUSTIFY ), bSkipPoolDefs );
1333 // vertical alignment
1334 ScfTools::PutItem( rItemSet, SvxJustifyMethodItem( ( maApiData.mnVerJustifyMethod == css::table::CellJustifyMethod::DISTRIBUTE ) ? ::SVX_JUSTIFY_METHOD_DISTRIBUTE : ::SVX_JUSTIFY_METHOD_AUTO, ATTR_VER_JUSTIFY_METHOD ), bSkipPoolDefs );
1336 // CTL text direction
1337 ScfTools::PutItem( rItemSet, SvxFrameDirectionItem( GetScFrameDir(), ATTR_WRITINGDIR ), bSkipPoolDefs );
1338 // set an angle in the range from -90 to 90 degrees
1339 ScfTools::PutItem( rItemSet, SfxInt32Item( ATTR_ROTATE_VALUE, maApiData.mnRotation ), bSkipPoolDefs );
1340 // Orientation
1341 ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_STACKED, maApiData.meOrientation == css::table::CellOrientation_STACKED ), bSkipPoolDefs );
1342 // indent
1343 ScfTools::PutItem( rItemSet, SfxUInt16Item( ATTR_INDENT, maApiData.mnIndent ), bSkipPoolDefs );
1344 // line wrap
1345 ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_LINEBREAK, maApiData.mbWrapText ), bSkipPoolDefs );
1346 ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_SHRINKTOFIT, maApiData.mbShrink ), bSkipPoolDefs );
1349 void Alignment::writeToPropertyMap( PropertyMap& rPropMap ) const
1351 rPropMap.setProperty( PROP_HoriJustify, maApiData.meHorJustify);
1352 rPropMap.setProperty( PROP_HoriJustifyMethod, maApiData.mnHorJustifyMethod);
1353 rPropMap.setProperty( PROP_VertJustify, maApiData.mnVerJustify);
1354 rPropMap.setProperty( PROP_VertJustifyMethod, maApiData.mnVerJustifyMethod);
1355 rPropMap.setProperty( PROP_WritingMode, maApiData.mnWritingMode);
1356 rPropMap.setProperty( PROP_RotateAngle, maApiData.mnRotation);
1357 rPropMap.setProperty( PROP_Orientation, maApiData.meOrientation);
1358 rPropMap.setProperty( PROP_ParaIndent, maApiData.mnIndent);
1359 rPropMap.setProperty( PROP_IsTextWrapped, maApiData.mbWrapText);
1360 rPropMap.setProperty( PROP_ShrinkToFit, maApiData.mbShrink);
1363 ProtectionModel::ProtectionModel() :
1364 mbLocked( true ), // default in Excel and Calc
1365 mbHidden( false )
1369 ApiProtectionData::ApiProtectionData() :
1370 maCellProt( true, false, false, false )
1374 bool operator==( const ApiProtectionData& rLeft, const ApiProtectionData& rRight )
1376 return
1377 (rLeft.maCellProt.IsLocked == rRight.maCellProt.IsLocked) &&
1378 (rLeft.maCellProt.IsFormulaHidden == rRight.maCellProt.IsFormulaHidden) &&
1379 (rLeft.maCellProt.IsHidden == rRight.maCellProt.IsHidden) &&
1380 (rLeft.maCellProt.IsPrintHidden == rRight.maCellProt.IsPrintHidden);
1383 Protection::Protection( const WorkbookHelper& rHelper ) :
1384 WorkbookHelper( rHelper )
1388 void Protection::importProtection( const AttributeList& rAttribs )
1390 maModel.mbLocked = rAttribs.getBool( XML_locked, true );
1391 maModel.mbHidden = rAttribs.getBool( XML_hidden, false );
1394 void Protection::setBiff12Data( sal_uInt32 nFlags )
1396 maModel.mbLocked = getFlag( nFlags, BIFF12_XF_LOCKED );
1397 maModel.mbHidden = getFlag( nFlags, BIFF12_XF_HIDDEN );
1400 void Protection::finalizeImport()
1402 maApiData.maCellProt.IsLocked = maModel.mbLocked;
1403 maApiData.maCellProt.IsFormulaHidden = maModel.mbHidden;
1406 void Protection::writeToPropertyMap( PropertyMap& rPropMap ) const
1408 rPropMap.setProperty( PROP_CellProtection, maApiData.maCellProt);
1411 void Protection::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
1413 ScfTools::PutItem( rItemSet, ScProtectionAttr( maApiData.maCellProt.IsLocked, maApiData.maCellProt.IsFormulaHidden ), bSkipPoolDefs );
1416 namespace {
1418 bool lcl_isBorder(const css::table::BorderLine& rBorder)
1420 return (rBorder.InnerLineWidth > 0) || (rBorder.OuterLineWidth > 0);
1425 BorderLineModel::BorderLineModel( bool bDxf ) :
1426 mnStyle( XML_none ),
1427 mbUsed( !bDxf )
1429 maColor.setIndexed( OOX_COLOR_WINDOWTEXT );
1432 void BorderLineModel::setBiffStyle( sal_Int32 nLineStyle )
1434 static const sal_Int32 spnStyleIds[] = {
1435 XML_none, XML_thin, XML_medium, XML_dashed,
1436 XML_dotted, XML_thick, XML_double, XML_hair,
1437 XML_mediumDashed, XML_dashDot, XML_mediumDashDot, XML_dashDotDot,
1438 XML_mediumDashDotDot, XML_slantDashDot };
1439 mnStyle = STATIC_ARRAY_SELECT( spnStyleIds, nLineStyle, XML_none );
1442 BorderModel::BorderModel( bool bDxf ) :
1443 maLeft( bDxf ),
1444 maRight( bDxf ),
1445 maTop( bDxf ),
1446 maBottom( bDxf ),
1447 maDiagonal( bDxf ),
1448 mbDiagTLtoBR( false ),
1449 mbDiagBLtoTR( false )
1453 ApiBorderData::ApiBorderData() :
1454 mbBorderUsed( false ),
1455 mbDiagUsed( false )
1459 bool ApiBorderData::hasAnyOuterBorder() const
1461 return
1462 ( ( lcl_isBorder( maTop ) && maTop.OuterLineWidth > 0 ) ) ||
1463 ( ( lcl_isBorder( maBottom ) && maBottom.OuterLineWidth > 0 ) ) ||
1464 ( ( lcl_isBorder( maLeft ) && maLeft.OuterLineWidth > 0 ) ) ||
1465 ( ( lcl_isBorder( maRight ) && maRight.OuterLineWidth > 0 ) );
1468 bool operator==( const ApiBorderData& rLeft, const ApiBorderData& rRight )
1470 return
1471 (rLeft.maLeft == rRight.maLeft) &&
1472 (rLeft.maRight == rRight.maRight) &&
1473 (rLeft.maTop == rRight.maTop) &&
1474 (rLeft.maBottom == rRight.maBottom) &&
1475 (rLeft.maTLtoBR == rRight.maTLtoBR) &&
1476 (rLeft.maBLtoTR == rRight.maBLtoTR) &&
1477 (rLeft.mbBorderUsed == rRight.mbBorderUsed) &&
1478 (rLeft.mbDiagUsed == rRight.mbDiagUsed);
1481 namespace {
1483 inline void lclSetBorderLineWidth( BorderLine& rBorderLine,
1484 sal_Int16 nOuter, sal_Int16 nDist = API_LINE_NONE, sal_Int16 nInner = API_LINE_NONE )
1486 rBorderLine.OuterLineWidth = nOuter;
1487 rBorderLine.LineDistance = nDist;
1488 rBorderLine.InnerLineWidth = nInner;
1491 } // namespace
1493 Border::Border( const WorkbookHelper& rHelper, bool bDxf ) :
1494 WorkbookHelper( rHelper ),
1495 maModel( bDxf ),
1496 mbDxf( bDxf )
1500 void Border::importBorder( const AttributeList& rAttribs )
1502 maModel.mbDiagTLtoBR = rAttribs.getBool( XML_diagonalDown, false );
1503 maModel.mbDiagBLtoTR = rAttribs.getBool( XML_diagonalUp, false );
1506 void Border::importStyle( sal_Int32 nElement, const AttributeList& rAttribs )
1508 if( BorderLineModel* pBorderLine = getBorderLine( nElement ) )
1510 pBorderLine->mnStyle = rAttribs.getToken( XML_style, XML_none );
1511 pBorderLine->mbUsed = true;
1515 void Border::importColor( sal_Int32 nElement, const AttributeList& rAttribs )
1517 if( BorderLineModel* pBorderLine = getBorderLine( nElement ) )
1518 pBorderLine->maColor.importColor( rAttribs );
1521 void Border::importBorder( SequenceInputStream& rStrm )
1523 sal_uInt8 nFlags = rStrm.readuInt8();
1524 maModel.mbDiagTLtoBR = getFlag( nFlags, BIFF12_BORDER_DIAG_TLBR );
1525 maModel.mbDiagBLtoTR = getFlag( nFlags, BIFF12_BORDER_DIAG_BLTR );
1526 maModel.maTop.setBiffStyle( rStrm.readuInt16() );
1527 rStrm >> maModel.maTop.maColor;
1528 maModel.maBottom.setBiffStyle( rStrm.readuInt16() );
1529 rStrm >> maModel.maBottom.maColor;
1530 maModel.maLeft.setBiffStyle( rStrm.readuInt16() );
1531 rStrm >> maModel.maLeft.maColor;
1532 maModel.maRight.setBiffStyle( rStrm.readuInt16() );
1533 rStrm >> maModel.maRight.maColor;
1534 maModel.maDiagonal.setBiffStyle( rStrm.readuInt16() );
1535 rStrm >> maModel.maDiagonal.maColor;
1538 void Border::importDxfBorder( sal_Int32 nElement, SequenceInputStream& rStrm )
1540 SAL_WARN_IF( !mbDxf, "sc", "Border::importDxfBorder - missing conditional formatting flag" );
1541 if( BorderLineModel* pBorderLine = getBorderLine( nElement ) )
1543 sal_uInt16 nStyle;
1544 rStrm >> pBorderLine->maColor;
1545 nStyle = rStrm.readuInt16();
1546 pBorderLine->setBiffStyle( nStyle );
1547 pBorderLine->mbUsed = true;
1551 void Border::finalizeImport( bool bRTL )
1553 if ( bRTL )
1555 BorderLineModel aTmp = maModel.maLeft;
1556 maModel.maLeft = maModel.maRight;
1557 maModel.maRight = aTmp;
1559 maApiData.mbBorderUsed = maModel.maLeft.mbUsed || maModel.maRight.mbUsed || maModel.maTop.mbUsed || maModel.maBottom.mbUsed;
1560 maApiData.mbDiagUsed = maModel.maDiagonal.mbUsed;
1562 convertBorderLine( maApiData.maLeft, maModel.maLeft );
1563 convertBorderLine( maApiData.maRight, maModel.maRight );
1564 convertBorderLine( maApiData.maTop, maModel.maTop );
1565 convertBorderLine( maApiData.maBottom, maModel.maBottom );
1567 if( maModel.mbDiagTLtoBR )
1568 convertBorderLine( maApiData.maTLtoBR, maModel.maDiagonal );
1569 if( maModel.mbDiagBLtoTR )
1570 convertBorderLine( maApiData.maBLtoTR, maModel.maDiagonal );
1573 void Border::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
1575 if( maApiData.mbBorderUsed )
1577 SvxBoxItem aBoxItem( ATTR_BORDER );
1578 ::editeng::SvxBorderLine aLine;
1580 if (SvxBoxItem::LineToSvxLine(maApiData.maLeft, aLine, false))
1582 aBoxItem.SetLine( &aLine, SvxBoxItemLine::LEFT );
1584 if (SvxBoxItem::LineToSvxLine(maApiData.maRight, aLine, false))
1586 aBoxItem.SetLine( &aLine, SvxBoxItemLine::RIGHT );
1588 if (SvxBoxItem::LineToSvxLine(maApiData.maTop, aLine, false))
1590 aBoxItem.SetLine( &aLine, SvxBoxItemLine::TOP );
1592 if (SvxBoxItem::LineToSvxLine(maApiData.maBottom, aLine, false))
1594 aBoxItem.SetLine( &aLine, SvxBoxItemLine::BOTTOM );
1596 ScfTools::PutItem( rItemSet, aBoxItem, bSkipPoolDefs );
1598 if ( maApiData.mbDiagUsed )
1600 SvxLineItem aTLBRItem( ATTR_BORDER_TLBR );
1601 SvxLineItem aBLTRItem( ATTR_BORDER_BLTR );
1602 ::editeng::SvxBorderLine aLine;
1603 if (SvxBoxItem::LineToSvxLine(maApiData.maTLtoBR, aLine, false))
1605 aTLBRItem.SetLine( &aLine );
1607 if (SvxBoxItem::LineToSvxLine(maApiData.maBLtoTR, aLine, false))
1609 aBLTRItem.SetLine( &aLine );
1611 ScfTools::PutItem( rItemSet, aTLBRItem, bSkipPoolDefs );
1612 ScfTools::PutItem( rItemSet, aBLTRItem, bSkipPoolDefs );
1616 void Border::writeToPropertyMap( PropertyMap& rPropMap ) const
1618 if( maApiData.mbBorderUsed )
1620 rPropMap.setProperty( PROP_LeftBorder, maApiData.maLeft);
1621 rPropMap.setProperty( PROP_RightBorder, maApiData.maRight);
1622 rPropMap.setProperty( PROP_TopBorder, maApiData.maTop);
1623 rPropMap.setProperty( PROP_BottomBorder, maApiData.maBottom);
1625 if( maApiData.mbDiagUsed )
1627 rPropMap.setProperty( PROP_DiagonalTLBR, maApiData.maTLtoBR);
1628 rPropMap.setProperty( PROP_DiagonalBLTR, maApiData.maBLtoTR);
1632 bool Border::hasBorder() const
1634 if (lcl_isBorder(maApiData.maBottom))
1635 return true;
1637 if (lcl_isBorder(maApiData.maTop))
1638 return true;
1640 if (lcl_isBorder(maApiData.maLeft))
1641 return true;
1643 if (lcl_isBorder(maApiData.maRight))
1644 return true;
1646 return false;
1649 BorderLineModel* Border::getBorderLine( sal_Int32 nElement )
1651 switch( nElement )
1653 case XLS_TOKEN( left ): return &maModel.maLeft;
1654 case XLS_TOKEN( start ): return &maModel.maLeft;
1655 case XLS_TOKEN( right ): return &maModel.maRight;
1656 case XLS_TOKEN( end ): return &maModel.maRight;
1657 case XLS_TOKEN( top ): return &maModel.maTop;
1658 case XLS_TOKEN( bottom ): return &maModel.maBottom;
1659 case XLS_TOKEN( diagonal ): return &maModel.maDiagonal;
1661 return nullptr;
1664 bool Border::convertBorderLine( BorderLine2& rBorderLine, const BorderLineModel& rModel )
1666 // Document: sc/qa/unit/data/README.cellborders
1668 rBorderLine.Color = rModel.maColor.getColor( getBaseFilter().getGraphicHelper(), API_RGB_BLACK );
1669 switch( rModel.mnStyle )
1671 case XML_dashDot:
1672 lclSetBorderLineWidth( rBorderLine, API_LINE_THIN );
1673 rBorderLine.LineStyle = table::BorderLineStyle::DASH_DOT;
1674 break;
1675 case XML_dashDotDot:
1676 lclSetBorderLineWidth( rBorderLine, API_LINE_THIN );
1677 rBorderLine.LineStyle = table::BorderLineStyle::DASH_DOT_DOT;
1678 break;
1679 case XML_dashed:
1680 lclSetBorderLineWidth( rBorderLine, API_LINE_THIN );
1681 rBorderLine.LineStyle = table::BorderLineStyle::FINE_DASHED;
1682 break;
1683 case XML_dotted:
1684 lclSetBorderLineWidth( rBorderLine, API_LINE_THIN );
1685 rBorderLine.LineStyle = table::BorderLineStyle::DOTTED;
1686 break;
1687 case XML_double:
1688 lclSetBorderLineWidth( rBorderLine, 10, 15, 10 );
1689 rBorderLine.LineStyle = table::BorderLineStyle::DOUBLE_THIN;
1690 break;
1691 case XML_hair: lclSetBorderLineWidth( rBorderLine, API_LINE_HAIR ); break;
1692 case XML_medium: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break;
1693 case XML_mediumDashDot:
1694 lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM );
1695 rBorderLine.LineStyle = table::BorderLineStyle::DASH_DOT;
1696 break;
1697 case XML_mediumDashDotDot:
1698 lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM );
1699 rBorderLine.LineStyle = table::BorderLineStyle::DASH_DOT_DOT;
1700 break;
1701 case XML_mediumDashed:
1702 lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM );
1703 rBorderLine.LineStyle = table::BorderLineStyle::DASHED;
1704 break;
1705 case XML_none: lclSetBorderLineWidth( rBorderLine, API_LINE_NONE ); break;
1706 case XML_slantDashDot:
1707 lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM );
1708 rBorderLine.LineStyle = table::BorderLineStyle::FINE_DASHED;
1709 break;
1710 case XML_thick: lclSetBorderLineWidth( rBorderLine, API_LINE_THICK ); break;
1711 case XML_thin: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break;
1712 default: lclSetBorderLineWidth( rBorderLine, API_LINE_NONE ); break;
1714 return rModel.mbUsed;
1717 PatternFillModel::PatternFillModel( bool bDxf ) :
1718 mnPattern( XML_none ),
1719 mbPattColorUsed( !bDxf ),
1720 mbFillColorUsed( !bDxf ),
1721 mbPatternUsed( !bDxf )
1723 maPatternColor.setIndexed( OOX_COLOR_WINDOWTEXT );
1724 maFillColor.setIndexed( OOX_COLOR_WINDOWBACK );
1727 void PatternFillModel::setBiffPattern( sal_Int32 nPattern )
1729 static const sal_Int32 spnPatternIds[] = {
1730 XML_none, XML_solid, XML_mediumGray, XML_darkGray,
1731 XML_lightGray, XML_darkHorizontal, XML_darkVertical, XML_darkDown,
1732 XML_darkUp, XML_darkGrid, XML_darkTrellis, XML_lightHorizontal,
1733 XML_lightVertical, XML_lightDown, XML_lightUp, XML_lightGrid,
1734 XML_lightTrellis, XML_gray125, XML_gray0625 };
1735 mnPattern = STATIC_ARRAY_SELECT( spnPatternIds, nPattern, XML_none );
1738 GradientFillModel::GradientFillModel() :
1739 mnType( XML_linear ),
1740 mfAngle( 0.0 ),
1741 mfLeft( 0.0 ),
1742 mfRight( 0.0 ),
1743 mfTop( 0.0 ),
1744 mfBottom( 0.0 )
1748 void GradientFillModel::readGradient( SequenceInputStream& rStrm )
1750 sal_Int32 nType;
1751 nType = rStrm.readInt32();
1752 mfAngle = rStrm.readDouble();
1753 mfLeft = rStrm.readDouble();
1754 mfRight = rStrm.readDouble();
1755 mfTop = rStrm.readDouble();
1756 mfBottom = rStrm.readDouble();
1757 static const sal_Int32 spnTypes[] = { XML_linear, XML_path };
1758 mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_TOKEN_INVALID );
1761 void GradientFillModel::readGradientStop( SequenceInputStream& rStrm, bool bDxf )
1763 Color aColor;
1764 double fPosition;
1765 if( bDxf )
1767 rStrm.skip( 2 );
1768 fPosition = rStrm.readDouble();
1769 rStrm >> aColor;
1771 else
1773 rStrm >> aColor;
1774 fPosition = rStrm.readDouble();
1776 if( !rStrm.isEof() && (fPosition >= 0.0) )
1777 maColors[ fPosition ] = aColor;
1780 ApiSolidFillData::ApiSolidFillData() :
1781 mnColor( API_RGB_TRANSPARENT ),
1782 mbTransparent( true ),
1783 mbUsed( false )
1787 bool operator==( const ApiSolidFillData& rLeft, const ApiSolidFillData& rRight )
1789 return
1790 (rLeft.mnColor == rRight.mnColor) &&
1791 (rLeft.mbTransparent == rRight.mbTransparent) &&
1792 (rLeft.mbUsed == rRight.mbUsed);
1795 namespace {
1797 inline sal_Int32 lclGetMixedColorComp( sal_Int32 nPatt, sal_Int32 nFill, sal_Int32 nAlpha )
1799 return ((nPatt - nFill) * nAlpha) / 0x80 + nFill;
1802 sal_Int32 lclGetMixedColor( sal_Int32 nPattColor, sal_Int32 nFillColor, sal_Int32 nAlpha )
1804 return
1805 (lclGetMixedColorComp( nPattColor & 0xFF0000, nFillColor & 0xFF0000, nAlpha ) & 0xFF0000) |
1806 (lclGetMixedColorComp( nPattColor & 0x00FF00, nFillColor & 0x00FF00, nAlpha ) & 0x00FF00) |
1807 (lclGetMixedColorComp( nPattColor & 0x0000FF, nFillColor & 0x0000FF, nAlpha ) & 0x0000FF);
1810 } // namespace
1812 Fill::Fill( const WorkbookHelper& rHelper, bool bDxf ) :
1813 WorkbookHelper( rHelper ),
1814 mbDxf( bDxf )
1818 void Fill::importPatternFill( const AttributeList& rAttribs )
1820 mxPatternModel.reset( new PatternFillModel( mbDxf ) );
1821 mxPatternModel->mnPattern = rAttribs.getToken( XML_patternType, XML_none );
1822 if( mbDxf )
1823 mxPatternModel->mbPatternUsed = rAttribs.hasAttribute( XML_patternType );
1826 void Fill::importFgColor( const AttributeList& rAttribs )
1828 OSL_ENSURE( mxPatternModel.get(), "Fill::importFgColor - missing pattern data" );
1829 if( mxPatternModel.get() )
1831 mxPatternModel->maPatternColor.importColor( rAttribs );
1832 mxPatternModel->mbPattColorUsed = true;
1836 void Fill::importBgColor( const AttributeList& rAttribs )
1838 OSL_ENSURE( mxPatternModel.get(), "Fill::importBgColor - missing pattern data" );
1839 if( mxPatternModel.get() )
1841 mxPatternModel->maFillColor.importColor( rAttribs );
1842 mxPatternModel->mbFillColorUsed = true;
1846 void Fill::importGradientFill( const AttributeList& rAttribs )
1848 mxGradientModel.reset( new GradientFillModel );
1849 mxGradientModel->mnType = rAttribs.getToken( XML_type, XML_linear );
1850 mxGradientModel->mfAngle = rAttribs.getDouble( XML_degree, 0.0 );
1851 mxGradientModel->mfLeft = rAttribs.getDouble( XML_left, 0.0 );
1852 mxGradientModel->mfRight = rAttribs.getDouble( XML_right, 0.0 );
1853 mxGradientModel->mfTop = rAttribs.getDouble( XML_top, 0.0 );
1854 mxGradientModel->mfBottom = rAttribs.getDouble( XML_bottom, 0.0 );
1857 void Fill::importColor( const AttributeList& rAttribs, double fPosition )
1859 OSL_ENSURE( mxGradientModel.get(), "Fill::importColor - missing gradient data" );
1860 if( mxGradientModel.get() && (fPosition >= 0.0) )
1861 mxGradientModel->maColors[ fPosition ].importColor( rAttribs );
1864 void Fill::importFill( SequenceInputStream& rStrm )
1866 SAL_WARN_IF( mbDxf, "sc", "Fill::importFill - unexpected conditional formatting flag" );
1867 sal_Int32 nPattern = rStrm.readInt32();
1868 if( nPattern == BIFF12_FILL_GRADIENT )
1870 mxGradientModel.reset( new GradientFillModel );
1871 sal_Int32 nStopCount;
1872 rStrm.skip( 16 );
1873 mxGradientModel->readGradient( rStrm );
1874 nStopCount = rStrm.readInt32();
1875 for( sal_Int32 nStop = 0; (nStop < nStopCount) && !rStrm.isEof(); ++nStop )
1876 mxGradientModel->readGradientStop( rStrm, false );
1878 else
1880 mxPatternModel.reset( new PatternFillModel( mbDxf ) );
1881 mxPatternModel->setBiffPattern( nPattern );
1882 rStrm >> mxPatternModel->maPatternColor >> mxPatternModel->maFillColor;
1886 void Fill::importDxfPattern( SequenceInputStream& rStrm )
1888 SAL_WARN_IF( !mbDxf, "sc", "Fill::importDxfPattern - missing conditional formatting flag" );
1889 if( !mxPatternModel )
1890 mxPatternModel.reset( new PatternFillModel( mbDxf ) );
1891 mxPatternModel->setBiffPattern( rStrm.readuInt8() );
1892 mxPatternModel->mbPatternUsed = true;
1895 void Fill::importDxfFgColor( SequenceInputStream& rStrm )
1897 SAL_WARN_IF( !mbDxf, "sc", "Fill::importDxfFgColor - missing conditional formatting flag" );
1898 if( !mxPatternModel )
1899 mxPatternModel.reset( new PatternFillModel( mbDxf ) );
1900 mxPatternModel->maPatternColor.importColor( rStrm );
1901 mxPatternModel->mbPattColorUsed = true;
1904 void Fill::importDxfBgColor( SequenceInputStream& rStrm )
1906 SAL_WARN_IF( !mbDxf, "sc", "Fill::importDxfBgColor - missing conditional formatting flag" );
1907 if( !mxPatternModel )
1908 mxPatternModel.reset( new PatternFillModel( mbDxf ) );
1909 mxPatternModel->maFillColor.importColor( rStrm );
1910 mxPatternModel->mbFillColorUsed = true;
1913 void Fill::importDxfGradient( SequenceInputStream& rStrm )
1915 SAL_WARN_IF( !mbDxf, "sc", "Fill::importDxfGradient - missing conditional formatting flag" );
1916 if( !mxGradientModel )
1917 mxGradientModel.reset( new GradientFillModel );
1918 mxGradientModel->readGradient( rStrm );
1921 void Fill::importDxfStop( SequenceInputStream& rStrm )
1923 SAL_WARN_IF( !mbDxf, "sc", "Fill::importDxfStop - missing conditional formatting flag" );
1924 if( !mxGradientModel )
1925 mxGradientModel.reset( new GradientFillModel );
1926 mxGradientModel->readGradientStop( rStrm, true );
1929 void Fill::finalizeImport()
1931 const GraphicHelper& rGraphicHelper = getBaseFilter().getGraphicHelper();
1933 if( mxPatternModel.get() )
1935 // finalize the OOXML data struct
1936 PatternFillModel& rModel = *mxPatternModel;
1937 if( mbDxf )
1939 if( rModel.mbFillColorUsed && (!rModel.mbPatternUsed || (rModel.mnPattern == XML_solid)) )
1941 rModel.maPatternColor = rModel.maFillColor;
1942 rModel.mnPattern = XML_solid;
1943 rModel.mbPattColorUsed = rModel.mbPatternUsed = true;
1945 else if( !rModel.mbFillColorUsed && rModel.mbPatternUsed && (rModel.mnPattern == XML_solid) )
1947 rModel.mbPatternUsed = false;
1951 // convert to API fill settings
1952 maApiData.mbUsed = rModel.mbPatternUsed;
1953 if( rModel.mnPattern == XML_none )
1955 maApiData.mnColor = API_RGB_TRANSPARENT;
1956 maApiData.mbTransparent = true;
1958 else
1960 sal_Int32 nAlpha = 0x80;
1961 switch( rModel.mnPattern )
1963 case XML_darkDown: nAlpha = 0x40; break;
1964 case XML_darkGray: nAlpha = 0x60; break;
1965 case XML_darkGrid: nAlpha = 0x40; break;
1966 case XML_darkHorizontal: nAlpha = 0x40; break;
1967 case XML_darkTrellis: nAlpha = 0x60; break;
1968 case XML_darkUp: nAlpha = 0x40; break;
1969 case XML_darkVertical: nAlpha = 0x40; break;
1970 case XML_gray0625: nAlpha = 0x08; break;
1971 case XML_gray125: nAlpha = 0x10; break;
1972 case XML_lightDown: nAlpha = 0x20; break;
1973 case XML_lightGray: nAlpha = 0x20; break;
1974 case XML_lightGrid: nAlpha = 0x38; break;
1975 case XML_lightHorizontal: nAlpha = 0x20; break;
1976 case XML_lightTrellis: nAlpha = 0x30; break;
1977 case XML_lightUp: nAlpha = 0x20; break;
1978 case XML_lightVertical: nAlpha = 0x20; break;
1979 case XML_mediumGray: nAlpha = 0x40; break;
1980 case XML_solid: nAlpha = 0x80; break;
1983 sal_Int32 nWinTextColor = rGraphicHelper.getSystemColor( XML_windowText );
1984 sal_Int32 nWinColor = rGraphicHelper.getSystemColor( XML_window );
1986 if( !rModel.mbPattColorUsed )
1987 rModel.maPatternColor.setAuto();
1988 sal_Int32 nPattColor = rModel.maPatternColor.getColor( rGraphicHelper, nWinTextColor );
1990 if( !rModel.mbFillColorUsed )
1991 rModel.maFillColor.setAuto();
1992 sal_Int32 nFillColor = rModel.maFillColor.getColor( rGraphicHelper, nWinColor );
1994 maApiData.mnColor = lclGetMixedColor( nPattColor, nFillColor, nAlpha );
1995 maApiData.mbTransparent = false;
1998 else if( mxGradientModel.get() && !mxGradientModel->maColors.empty() )
2000 GradientFillModel& rModel = *mxGradientModel;
2001 maApiData.mbUsed = true; // no support for differential attributes
2002 GradientFillModel::ColorMap::const_iterator aIt = rModel.maColors.begin();
2003 OSL_ENSURE( !aIt->second.isAuto(), "Fill::finalizeImport - automatic gradient color" );
2004 maApiData.mnColor = aIt->second.getColor( rGraphicHelper, API_RGB_WHITE );
2005 if( ++aIt != rModel.maColors.end() )
2007 OSL_ENSURE( !aIt->second.isAuto(), "Fill::finalizeImport - automatic gradient color" );
2008 sal_Int32 nEndColor = aIt->second.getColor( rGraphicHelper, API_RGB_WHITE );
2009 maApiData.mnColor = lclGetMixedColor( maApiData.mnColor, nEndColor, 0x40 );
2010 maApiData.mbTransparent = false;
2015 void Fill::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
2017 if( maApiData.mbUsed )
2019 SvxBrushItem aBrushItem( ATTR_BACKGROUND );
2020 if ( maApiData.mbTransparent )
2022 aBrushItem.SetColor( ::Color( COL_TRANSPARENT ) );
2024 else
2026 aBrushItem.SetColor( maApiData.mnColor );
2028 ScfTools::PutItem( rItemSet, aBrushItem, bSkipPoolDefs );
2032 void Fill::writeToPropertyMap( PropertyMap& rPropMap ) const
2034 if( maApiData.mbUsed )
2036 rPropMap.setProperty( PROP_CellBackColor, maApiData.mnColor);
2037 rPropMap.setProperty( PROP_IsCellBackgroundTransparent, maApiData.mbTransparent);
2041 XfModel::XfModel() :
2042 mnStyleXfId( -1 ),
2043 mnFontId( -1 ),
2044 mnNumFmtId( -1 ),
2045 mnBorderId( -1 ),
2046 mnFillId( -1 ),
2047 mbCellXf( true ),
2048 mbFontUsed( false ),
2049 mbNumFmtUsed( false ),
2050 mbAlignUsed( false ),
2051 mbProtUsed( false ),
2052 mbBorderUsed( false ),
2053 mbAreaUsed( false )
2057 Xf::AttrList::AttrList(const ScPatternAttr* pDefPattern):
2058 mbLatinNumFmtOnly(true),
2059 mpDefPattern(pDefPattern)
2062 Xf::Xf( const WorkbookHelper& rHelper ) :
2063 WorkbookHelper( rHelper ),
2064 mnScNumFmt(0),
2065 maAlignment( rHelper ),
2066 maProtection( rHelper ),
2067 meRotationRef( css::table::CellVertJustify2::STANDARD ),
2068 mpStyleSheet( nullptr )
2072 void Xf::importXf( const AttributeList& rAttribs, bool bCellXf )
2074 maModel.mbCellXf = bCellXf;
2075 // tdf#70565 Set proper default value to "0" of xfId attribute
2076 // When xfId is not exist during .xlsx import
2077 // it must have values set to "0".
2078 // Is is not impacts spreadsheets created with MS Excel,
2079 // as xfId attribute is always created during export to .xlsx
2080 // Not setting "0" value is causing wrong .xlsx import by LibreOffice,
2081 // for spreadsheets created by external applications (ex. SAP BI).
2082 if ( maModel.mbCellXf )
2084 maModel.mnStyleXfId = rAttribs.getInteger( XML_xfId, 0 );
2086 else
2088 maModel.mnStyleXfId = rAttribs.getInteger( XML_xfId, -1 );
2090 maModel.mnFontId = rAttribs.getInteger( XML_fontId, -1 );
2091 maModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, -1 );
2092 maModel.mnBorderId = rAttribs.getInteger( XML_borderId, -1 );
2093 maModel.mnFillId = rAttribs.getInteger( XML_fillId, -1 );
2096 /* Default value of the apply*** attributes is dependent on context:
2097 true in cellStyleXfs element, false in cellXfs element... */
2098 maModel.mbAlignUsed = rAttribs.getBool( XML_applyAlignment, !maModel.mbCellXf );
2099 maModel.mbProtUsed = rAttribs.getBool( XML_applyProtection, !maModel.mbCellXf );
2100 maModel.mbFontUsed = rAttribs.getBool( XML_applyFont, !maModel.mbCellXf );
2101 maModel.mbNumFmtUsed = rAttribs.getBool( XML_applyNumberFormat, !maModel.mbCellXf );
2102 maModel.mbBorderUsed = rAttribs.getBool( XML_applyBorder, !maModel.mbCellXf );
2103 maModel.mbAreaUsed = rAttribs.getBool( XML_applyFill, !maModel.mbCellXf );
2106 void Xf::importAlignment( const AttributeList& rAttribs )
2108 maAlignment.importAlignment( rAttribs );
2111 void Xf::importProtection( const AttributeList& rAttribs )
2113 maProtection.importProtection( rAttribs );
2116 void Xf::importXf( SequenceInputStream& rStrm, bool bCellXf )
2118 maModel.mbCellXf = bCellXf;
2119 maModel.mnStyleXfId = rStrm.readuInt16();
2120 maModel.mnNumFmtId = rStrm.readuInt16();
2121 maModel.mnFontId = rStrm.readuInt16();
2122 maModel.mnFillId = rStrm.readuInt16();
2123 maModel.mnBorderId = rStrm.readuInt16();
2124 sal_uInt32 nFlags = rStrm.readuInt32();
2125 maAlignment.setBiff12Data( nFlags );
2126 maProtection.setBiff12Data( nFlags );
2127 // used flags, see comments in Xf::setBiffUsedFlags()
2128 sal_uInt16 nUsedFlags = rStrm.readuInt16();
2129 maModel.mbFontUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_FONT_USED );
2130 maModel.mbNumFmtUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_NUMFMT_USED );
2131 maModel.mbAlignUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_ALIGN_USED );
2132 maModel.mbProtUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_PROT_USED );
2133 maModel.mbBorderUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_BORDER_USED );
2134 maModel.mbAreaUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_AREA_USED );
2137 void Xf::finalizeImport()
2139 // alignment and protection
2140 maAlignment.finalizeImport();
2141 maProtection.finalizeImport();
2144 FontRef Xf::getFont() const
2146 return getStyles().getFont( maModel.mnFontId );
2149 void Xf::applyPatternToAttrList( AttrList& rAttrs, SCROW nRow1, SCROW nRow2, sal_Int32 nNumFmtId )
2151 createPattern();
2152 ScPatternAttr& rPat = *mpPattern;
2153 ScDocument& rDoc = getScDocument();
2154 if ( isCellXf() )
2156 StylesBuffer& rStyles = getStyles();
2157 rStyles.createCellStyle( maModel.mnStyleXfId );
2159 mpStyleSheet = rStyles.getCellStyleSheet( maModel.mnStyleXfId );
2160 if ( mpStyleSheet )
2162 //rDoc.ApplySelectionStyle( static_cast<ScStyleSheet&>(*mpStyleSheet), rMarkData );
2163 rPat.SetStyleSheet(mpStyleSheet, false);
2165 else
2167 ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool();
2168 if (pStylePool)
2170 ScStyleSheet* pStyleSheet = static_cast<ScStyleSheet*>(
2171 pStylePool->Find(
2172 ScGlobal::GetRscString(STR_STYLENAME_STANDARD), SfxStyleFamily::Para));
2174 if (pStyleSheet)
2175 rPat.SetStyleSheet( pStyleSheet, false );
2179 if ( nNumFmtId >= 0 )
2181 ScPatternAttr aNumPat(rDoc.GetPool());
2182 mnScNumFmt = getStyles().writeNumFmtToItemSet( aNumPat.GetItemSet(), nNumFmtId );
2183 rPat.GetItemSet().Put(aNumPat.GetItemSet());
2186 if (!sc::NumFmtUtil::isLatinScript(mnScNumFmt, rDoc))
2187 rAttrs.mbLatinNumFmtOnly = false;
2189 if (rPat.GetStyleName())
2191 // Check for a gap between the last entry and this one.
2192 bool bHasGap = false;
2193 if (rAttrs.maAttrs.empty() && nRow1 > 0)
2194 // First attribute range doesn't start at row 0.
2195 bHasGap = true;
2197 if (!rAttrs.maAttrs.empty() && rAttrs.maAttrs.back().nRow + 1 < nRow1)
2198 bHasGap = true;
2200 if (bHasGap)
2202 // Fill this gap with the default pattern.
2203 ScAttrEntry aEntry;
2204 aEntry.nRow = nRow1 - 1;
2205 aEntry.pPattern = static_cast<const ScPatternAttr*>(&rDoc.GetPool()->Put(*rAttrs.mpDefPattern));
2206 rAttrs.maAttrs.push_back(aEntry);
2208 // Check if the default pattern is 'General'.
2209 if (!sc::NumFmtUtil::isLatinScript(*aEntry.pPattern, rDoc))
2210 rAttrs.mbLatinNumFmtOnly = false;
2213 ScAttrEntry aEntry;
2214 aEntry.nRow = nRow2;
2215 aEntry.pPattern = static_cast<const ScPatternAttr*>(&rDoc.GetPool()->Put(rPat));
2216 rAttrs.maAttrs.push_back(aEntry);
2218 if (!sc::NumFmtUtil::isLatinScript(*aEntry.pPattern, rDoc))
2219 rAttrs.mbLatinNumFmtOnly = false;
2223 void Xf::writeToPropertyMap( PropertyMap& rPropMap ) const
2225 StylesBuffer& rStyles = getStyles();
2227 // create and set cell style.
2229 // TODO : We should gradually move things to writeToDoc(), to set cell
2230 // styles to the document directly.
2232 if( maModel.mbFontUsed )
2233 rStyles.writeFontToPropertyMap( rPropMap, maModel.mnFontId );
2234 if( maModel.mbNumFmtUsed )
2235 rStyles.writeNumFmtToPropertyMap( rPropMap, maModel.mnNumFmtId );
2236 if( maModel.mbAlignUsed )
2237 maAlignment.writeToPropertyMap( rPropMap );
2238 if( maModel.mbProtUsed )
2239 maProtection.writeToPropertyMap( rPropMap );
2240 if( maModel.mbBorderUsed )
2241 rStyles.writeBorderToPropertyMap( rPropMap, maModel.mnBorderId );
2242 if( maModel.mbAreaUsed )
2243 rStyles.writeFillToPropertyMap( rPropMap, maModel.mnFillId );
2246 void Xf::writeToPropertySet( PropertySet& rPropSet ) const
2248 PropertyMap aPropMap;
2249 writeToPropertyMap( aPropMap );
2250 rPropSet.setProperties( aPropMap );
2253 void Xf::writeToDoc( ScDocumentImport& rDoc, const table::CellRangeAddress& rRange )
2255 const StylesBuffer& rStyles = getStyles();
2257 if (isCellXf())
2259 // Cell style name.
2260 OUString aStyleName = rStyles.createCellStyle(maModel.mnStyleXfId);
2262 ScStyleSheet* pStyleSheet =
2263 static_cast<ScStyleSheet*>(
2264 rDoc.getDoc().GetStyleSheetPool()->Find(aStyleName, SfxStyleFamily::Para));
2266 if (pStyleSheet)
2268 rDoc.getDoc().ApplyStyleAreaTab(
2269 rRange.StartColumn, rRange.StartRow, rRange.EndColumn, rRange.EndRow, rRange.Sheet,
2270 *pStyleSheet);
2274 const ScPatternAttr& rAttr = createPattern();
2275 rDoc.getDoc().ApplyPatternAreaTab(
2276 rRange.StartColumn, rRange.StartRow, rRange.EndColumn, rRange.EndRow, rRange.Sheet, rAttr);
2279 const ::ScPatternAttr&
2280 Xf::createPattern( bool bSkipPoolDefs )
2282 if( mpPattern.get() )
2283 return *mpPattern;
2284 mpPattern.reset( new ::ScPatternAttr( getScDocument().GetPool() ) );
2285 SfxItemSet& rItemSet = mpPattern->GetItemSet();
2286 /* Enables the used flags, if the formatting attributes differ from the
2287 style XF. In cell XFs Excel uses the cell attributes, if they differ
2288 from the parent style XF (even if the used flag is switched off).
2289 #109899# ...or if the respective flag is not set in parent style XF.
2291 StylesBuffer& rStyles = getStyles();
2293 const Xf* pStyleXf = isCellXf() ? rStyles.getStyleXf( maModel.mnStyleXfId ).get() : nullptr;
2294 if( pStyleXf && !mpStyleSheet )
2296 rStyles.createCellStyle( maModel.mnStyleXfId );
2297 mpStyleSheet = rStyles.getCellStyleSheet( maModel.mnStyleXfId );
2298 OSL_ENSURE( mpStyleSheet, "Xf::createPattern - no parentStyle created" );
2300 const XfModel& rStyleData = pStyleXf->maModel;
2301 if( !maModel.mbFontUsed )
2302 maModel.mbFontUsed = !rStyleData.mbFontUsed || (maModel.mnFontId != rStyleData.mnFontId);
2303 if( !maModel.mbNumFmtUsed )
2304 maModel.mbNumFmtUsed = !rStyleData.mbNumFmtUsed || (maModel.mnNumFmtId != rStyleData.mnNumFmtId);
2305 if( !maModel.mbAlignUsed )
2306 maModel.mbAlignUsed = !rStyleData.mbAlignUsed || !(maAlignment.getApiData() == pStyleXf->maAlignment.getApiData());
2307 if( !maModel.mbProtUsed )
2308 maModel.mbProtUsed = !rStyleData.mbProtUsed || !(maProtection.getApiData() == pStyleXf->maProtection.getApiData());
2309 if( !maModel.mbBorderUsed )
2310 maModel.mbBorderUsed = !rStyleData.mbBorderUsed || !rStyles.equalBorders( maModel.mnBorderId, rStyleData.mnBorderId );
2311 if( !maModel.mbAreaUsed )
2312 maModel.mbAreaUsed = !rStyleData.mbAreaUsed || !rStyles.equalFills( maModel.mnFillId, rStyleData.mnFillId );
2314 // cell protection
2315 if( maModel.mbProtUsed )
2317 maProtection.fillToItemSet( rItemSet, bSkipPoolDefs );
2320 // font
2321 if( maModel.mbFontUsed )
2323 rStyles.writeFontToItemSet( rItemSet, maModel.mnFontId, bSkipPoolDefs );
2326 // value format
2327 if( maModel.mbNumFmtUsed )
2329 mnScNumFmt = rStyles.writeNumFmtToItemSet( rItemSet, maModel.mnNumFmtId, bSkipPoolDefs );
2331 // alignment
2332 if( maModel.mbAlignUsed )
2334 maAlignment.fillToItemSet( rItemSet, bSkipPoolDefs );
2337 // border
2338 if( maModel.mbBorderUsed )
2340 rStyles.writeBorderToItemSet( rItemSet, maModel.mnBorderId, bSkipPoolDefs );
2343 // area
2344 if( maModel.mbAreaUsed )
2346 rStyles.writeFillToItemSet( rItemSet, maModel.mnFillId, bSkipPoolDefs );
2349 /* #i38709# Decide which rotation reference mode to use. If any outer
2350 border line of the cell is set (either explicitly or via cell style),
2351 and the cell contents are rotated, set rotation reference to bottom of
2352 cell. This causes the borders to be painted rotated with the text. */
2353 if( const Alignment* pAlignment = maModel.mbAlignUsed ? &maAlignment : (pStyleXf ? &pStyleXf->maAlignment : nullptr) )
2355 SvxRotateMode eRotateMode = SVX_ROTATE_MODE_STANDARD;
2356 sal_Int32 nBorderId = maModel.mbBorderUsed ? maModel.mnBorderId : (pStyleXf ? pStyleXf->maModel.mnBorderId : -1);
2357 if( const Border* pBorder = rStyles.getBorder( nBorderId ).get() )
2359 if( (pAlignment->getApiData().mnRotation != 0) && pBorder->getApiData().hasAnyOuterBorder() )
2361 meRotationRef = css::table::CellVertJustify2::BOTTOM;
2362 eRotateMode = SVX_ROTATE_MODE_BOTTOM;
2365 ScfTools::PutItem( rItemSet, SvxRotateModeItem( eRotateMode, ATTR_ROTATE_MODE ), bSkipPoolDefs );
2368 return *mpPattern;
2371 Dxf::Dxf( const WorkbookHelper& rHelper ) :
2372 WorkbookHelper( rHelper )
2376 FontRef Dxf::createFont( bool bAlwaysNew )
2378 if( bAlwaysNew || !mxFont )
2379 mxFont.reset( new Font( *this, true ) );
2380 return mxFont;
2383 BorderRef Dxf::createBorder( bool bAlwaysNew )
2385 if( bAlwaysNew || !mxBorder )
2386 mxBorder.reset( new Border( *this, true ) );
2387 return mxBorder;
2390 FillRef Dxf::createFill( bool bAlwaysNew )
2392 if( bAlwaysNew || !mxFill )
2393 mxFill.reset( new Fill( *this, true ) );
2394 return mxFill;
2397 void Dxf::importNumFmt( const AttributeList& rAttribs )
2399 // don't propagate number formats defined in Dxf entries
2400 // they can have the same id ( but different format codes ) as those
2401 // defined globally earlier. We discard the id defined in XML_numFmtId
2402 // and generate one ourselves ( this assumes that the normal numberformat
2403 // import has already taken place )
2404 sal_Int32 nNumFmtId = getStyles().nextFreeNumFmtId();
2405 OUString aFmtCode = rAttribs.getXString( XML_formatCode, OUString() );
2406 mxNumFmt = getStyles().createNumFmt( nNumFmtId, aFmtCode );
2409 void Dxf::importDxf( SequenceInputStream& rStrm )
2411 sal_Int32 nNumFmtId = -1;
2412 OUString aFmtCode;
2413 sal_uInt16 nRecCount;
2414 rStrm.skip( 4 ); // flags
2415 nRecCount = rStrm.readuInt16();
2416 for( sal_uInt16 nRec = 0; !rStrm.isEof() && (nRec < nRecCount); ++nRec )
2418 sal_uInt16 nSubRecId, nSubRecSize;
2419 sal_Int64 nRecEnd = rStrm.tell();
2420 nSubRecId = rStrm.readuInt16();
2421 nSubRecSize = rStrm.readuInt16();
2422 nRecEnd += nSubRecSize;
2423 switch( nSubRecId )
2425 case BIFF12_DXF_FILL_PATTERN: createFill( false )->importDxfPattern( rStrm ); break;
2426 case BIFF12_DXF_FILL_FGCOLOR: createFill( false )->importDxfFgColor( rStrm ); break;
2427 case BIFF12_DXF_FILL_BGCOLOR: createFill( false )->importDxfBgColor( rStrm ); break;
2428 case BIFF12_DXF_FILL_GRADIENT: createFill( false )->importDxfGradient( rStrm ); break;
2429 case BIFF12_DXF_FILL_STOP: createFill( false )->importDxfStop( rStrm ); break;
2430 case BIFF12_DXF_FONT_COLOR: createFont( false )->importDxfColor( rStrm ); break;
2431 case BIFF12_DXF_BORDER_TOP: createBorder( false )->importDxfBorder( XLS_TOKEN( top ), rStrm ); break;
2432 case BIFF12_DXF_BORDER_BOTTOM: createBorder( false )->importDxfBorder( XLS_TOKEN( bottom ), rStrm ); break;
2433 case BIFF12_DXF_BORDER_LEFT: createBorder( false )->importDxfBorder( XLS_TOKEN( left ), rStrm ); break;
2434 case BIFF12_DXF_BORDER_RIGHT: createBorder( false )->importDxfBorder( XLS_TOKEN( right ), rStrm ); break;
2435 case BIFF12_DXF_FONT_NAME: createFont( false )->importDxfName( rStrm ); break;
2436 case BIFF12_DXF_FONT_WEIGHT: createFont( false )->importDxfWeight( rStrm ); break;
2437 case BIFF12_DXF_FONT_UNDERLINE: createFont( false )->importDxfUnderline( rStrm ); break;
2438 case BIFF12_DXF_FONT_ESCAPEMENT: createFont( false )->importDxfEscapement( rStrm ); break;
2439 case BIFF12_DXF_FONT_ITALIC: createFont( false )->importDxfFlag( XML_i, rStrm ); break;
2440 case BIFF12_DXF_FONT_STRIKE: createFont( false )->importDxfFlag( XML_strike, rStrm ); break;
2441 case BIFF12_DXF_FONT_OUTLINE: createFont( false )->importDxfFlag( XML_outline, rStrm ); break;
2442 case BIFF12_DXF_FONT_SHADOW: createFont( false )->importDxfFlag( XML_shadow, rStrm ); break;
2443 case BIFF12_DXF_FONT_HEIGHT: createFont( false )->importDxfHeight( rStrm ); break;
2444 case BIFF12_DXF_FONT_SCHEME: createFont( false )->importDxfScheme( rStrm ); break;
2445 case BIFF12_DXF_NUMFMT_CODE: aFmtCode = BiffHelper::readString( rStrm, false ); break;
2446 case BIFF12_DXF_NUMFMT_ID: nNumFmtId = rStrm.readuInt16(); break;
2448 rStrm.seek( nRecEnd );
2450 OSL_ENSURE( !rStrm.isEof() && (rStrm.getRemaining() == 0), "Dxf::importDxf - unexpected remaining data" );
2451 mxNumFmt = getStyles().createNumFmt( nNumFmtId, aFmtCode );
2454 void Dxf::finalizeImport()
2456 if( mxFont.get() )
2457 mxFont->finalizeImport();
2458 bool bRTL = false;
2459 // number format already finalized by the number formats buffer
2460 if( mxAlignment.get() )
2462 mxAlignment->finalizeImport();
2463 // how do we detect RTL when text dir is OOX_XF_CONTEXT? ( seems you
2464 // would need access to the cell content, which we don't here )
2465 if ( mxAlignment->getModel().mnTextDir == OOX_XF_TEXTDIR_RTL )
2466 bRTL = true;
2468 if( mxProtection.get() )
2469 mxProtection->finalizeImport();
2470 if( mxBorder.get() )
2472 mxBorder->finalizeImport( bRTL );
2474 if( mxFill.get() )
2475 mxFill->finalizeImport();
2478 void Dxf::fillToItemSet( SfxItemSet& rSet ) const
2480 if (mxFont)
2481 mxFont->fillToItemSet(rSet, false);
2482 if (mxNumFmt)
2483 mxNumFmt->fillToItemSet(rSet);
2484 if (mxAlignment)
2485 mxAlignment->fillToItemSet(rSet);
2486 if (mxProtection)
2487 mxProtection->fillToItemSet(rSet);
2488 if (mxBorder)
2489 mxBorder->fillToItemSet(rSet);
2490 if (mxFill)
2491 mxFill->fillToItemSet(rSet);
2494 namespace {
2496 const sal_Char* const spcStyleNamePrefix = "Excel Built-in ";
2497 const sal_Char* const sppcStyleNames[] =
2499 "Normal",
2500 "RowLevel_", // outline level will be appended
2501 "ColLevel_", // outline level will be appended
2502 "Comma",
2503 "Currency",
2504 "Percent",
2505 "Comma [0]", // new in BIFF4
2506 "Currency [0]",
2507 "Hyperlink", // new in BIFF8
2508 "Followed Hyperlink",
2509 "Note", // new in OOX
2510 "Warning Text",
2511 nullptr,
2512 nullptr,
2513 nullptr,
2514 "Title",
2515 "Heading 1",
2516 "Heading 2",
2517 "Heading 3",
2518 "Heading 4",
2519 "Input",
2520 "Output",
2521 "Calculation",
2522 "Check Cell",
2523 "Linked Cell",
2524 "Total",
2525 "Good",
2526 "Bad",
2527 "Neutral",
2528 "Accent1",
2529 "20% - Accent1",
2530 "40% - Accent1",
2531 "60% - Accent1",
2532 "Accent2",
2533 "20% - Accent2",
2534 "40% - Accent2",
2535 "60% - Accent2",
2536 "Accent3",
2537 "20% - Accent3",
2538 "40% - Accent3",
2539 "60% - Accent3",
2540 "Accent4",
2541 "20% - Accent4",
2542 "40% - Accent4",
2543 "60% - Accent4",
2544 "Accent5",
2545 "20% - Accent5",
2546 "40% - Accent5",
2547 "60% - Accent5",
2548 "Accent6",
2549 "20% - Accent6",
2550 "40% - Accent6",
2551 "60% - Accent6",
2552 "Explanatory Text"
2554 const sal_Int32 snStyleNamesCount = static_cast< sal_Int32 >( SAL_N_ELEMENTS( sppcStyleNames ) );
2556 OUString lclGetBuiltinStyleName( sal_Int32 nBuiltinId, const OUString& rName, sal_Int32 nLevel = 0 )
2558 OSL_ENSURE( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount), "lclGetBuiltinStyleName - unknown built-in style" );
2559 OUStringBuffer aStyleName;
2560 aStyleName.appendAscii( spcStyleNamePrefix );
2561 if( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount) && (sppcStyleNames[ nBuiltinId ] != nullptr) )
2562 aStyleName.appendAscii( sppcStyleNames[ nBuiltinId ] );
2563 else if( !rName.isEmpty() )
2564 aStyleName.append( rName );
2565 else
2566 aStyleName.append( nBuiltinId );
2567 if( (nBuiltinId == OOX_STYLE_ROWLEVEL) || (nBuiltinId == OOX_STYLE_COLLEVEL) )
2568 aStyleName.append( nLevel );
2569 return aStyleName.makeStringAndClear();
2572 OUString lclCreateStyleName( const CellStyleModel& rModel )
2574 return rModel.mbBuiltin ? lclGetBuiltinStyleName( rModel.mnBuiltinId, rModel.maName, rModel.mnLevel ) : rModel.maName;
2577 } // namespace
2579 CellStyleModel::CellStyleModel() :
2580 mnXfId( -1 ),
2581 mnBuiltinId( -1 ),
2582 mnLevel( 0 ),
2583 mbBuiltin( false ),
2584 mbCustom( false ),
2585 mbHidden( false )
2589 bool CellStyleModel::isBuiltin() const
2591 return mbBuiltin && (mnBuiltinId >= 0);
2594 bool CellStyleModel::isDefaultStyle() const
2596 return mbBuiltin && (mnBuiltinId == OOX_STYLE_NORMAL);
2599 CellStyle::CellStyle( const WorkbookHelper& rHelper ) :
2600 WorkbookHelper( rHelper ),
2601 mbCreated( false ),
2602 mpStyleSheet( nullptr )
2606 void CellStyle::importCellStyle( const AttributeList& rAttribs )
2608 maModel.maName = rAttribs.getXString( XML_name, OUString() );
2609 maModel.mnXfId = rAttribs.getInteger( XML_xfId, -1 );
2610 maModel.mnBuiltinId = rAttribs.getInteger( XML_builtinId, -1 );
2611 maModel.mnLevel = rAttribs.getInteger( XML_iLevel, 0 );
2612 maModel.mbBuiltin = rAttribs.hasAttribute( XML_builtinId );
2613 maModel.mbCustom = rAttribs.getBool( XML_customBuiltin, false );
2614 maModel.mbHidden = rAttribs.getBool( XML_hidden, false );
2617 void CellStyle::importCellStyle( SequenceInputStream& rStrm )
2619 sal_uInt16 nFlags;
2620 maModel.mnXfId = rStrm.readInt32();
2621 nFlags = rStrm.readuInt16();
2622 maModel.mnBuiltinId = rStrm.readInt8();
2623 maModel.mnLevel = rStrm.readInt8();
2624 rStrm >> maModel.maName;
2625 maModel.mbBuiltin = getFlag( nFlags, BIFF12_CELLSTYLE_BUILTIN );
2626 maModel.mbCustom = getFlag( nFlags, BIFF12_CELLSTYLE_CUSTOM );
2627 maModel.mbHidden = getFlag( nFlags, BIFF12_CELLSTYLE_HIDDEN );
2630 void CellStyle::createCellStyle()
2633 // #i1624# #i1768# ignore unnamed user styles
2634 bool bDefStyle = maModel.isDefaultStyle();
2635 if( !mbCreated )
2637 if ( bDefStyle && maFinalName.isEmpty() )
2638 maFinalName = ScGlobal::GetRscString( STR_STYLENAME_STANDARD );
2639 mbCreated = maFinalName.isEmpty();
2642 if( !mbCreated && !mpStyleSheet )
2644 bool bCreatePattern = false;
2645 Xf* pXF = getStyles().getStyleXf( maModel.mnXfId ).get();
2646 ::ScDocument& rDoc = getScDocument();
2648 if( bDefStyle )
2650 // use existing "Default" style sheet
2651 mpStyleSheet = static_cast< ScStyleSheet* >( static_cast< ScStyleSheetPool* >( rDoc.GetStyleSheetPool() )->Find(
2652 ScGlobal::GetRscString( STR_STYLENAME_STANDARD ), SfxStyleFamily::Para ) );
2653 OSL_ENSURE( mpStyleSheet, "CellStyle::createStyle - Default style not found" );
2654 bCreatePattern = true;
2656 else
2658 mpStyleSheet = static_cast< ScStyleSheet* >( static_cast< ScStyleSheetPool* >( rDoc.GetStyleSheetPool() )->Find( maFinalName, SfxStyleFamily::Para ) );
2659 if( !mpStyleSheet )
2661 mpStyleSheet = &static_cast< ScStyleSheet& >( rDoc.GetStyleSheetPool()->Make( maFinalName, SfxStyleFamily::Para, SFXSTYLEBIT_USERDEF ) );
2662 bCreatePattern = true;
2666 // bDefStyle==true omits default pool items in CreatePattern()
2667 if( bCreatePattern && mpStyleSheet && pXF )
2668 mpStyleSheet->GetItemSet().Put( pXF->createPattern( bDefStyle ).GetItemSet() );
2672 void CellStyle::finalizeImport( const OUString& rFinalName )
2674 maFinalName = rFinalName;
2675 if( !maModel.isBuiltin() || maModel.mbCustom )
2676 createCellStyle();
2679 CellStyleBuffer::CellStyleBuffer( const WorkbookHelper& rHelper ) :
2680 WorkbookHelper( rHelper )
2684 CellStyleRef CellStyleBuffer::importCellStyle( const AttributeList& rAttribs )
2686 CellStyleRef xCellStyle( new CellStyle( *this ) );
2687 xCellStyle->importCellStyle( rAttribs );
2688 insertCellStyle( xCellStyle );
2689 return xCellStyle;
2692 CellStyleRef CellStyleBuffer::importCellStyle( SequenceInputStream& rStrm )
2694 CellStyleRef xCellStyle( new CellStyle( *this ) );
2695 xCellStyle->importCellStyle( rStrm );
2696 insertCellStyle( xCellStyle );
2697 return xCellStyle;
2700 void CellStyleBuffer::finalizeImport()
2702 // calculate final names of all styles
2703 typedef RefMap< OUString, CellStyle, IgnoreCaseCompare > CellStyleNameMap;
2704 CellStyleNameMap aCellStyles;
2705 CellStyleVector aConflictNameStyles;
2707 /* First, reserve style names that are built-in in Calc. This causes that
2708 imported cell styles get different unused names and thus do not try to
2709 overwrite these built-in styles. For BIFF4 workbooks (which contain a
2710 separate list of cell styles per sheet), reserve all existing styles if
2711 current sheet is not the first sheet (this styles buffer will be
2712 constructed again for every new sheet). This will create unique names
2713 for styles in different sheets with the same name. Assuming that the
2714 BIFF4W import filter is never used to import from clipboard... */
2715 bool bReserveAll = (getFilterType() == FILTER_BIFF) && (getBiff() == BIFF4) && isWorkbookFile() && (getCurrentSheetIndex() > 0);
2718 // unfortunately, com.sun.star.style.StyleFamily does not implement XEnumerationAccess...
2719 Reference< XIndexAccess > xStyleFamilyIA( getCellStyleFamily(), UNO_QUERY_THROW );
2720 for( sal_Int32 nIndex = 0, nCount = xStyleFamilyIA->getCount(); nIndex < nCount; ++nIndex )
2722 Reference< XStyle > xStyle( xStyleFamilyIA->getByIndex( nIndex ), UNO_QUERY_THROW );
2723 if( bReserveAll || !xStyle->isUserDefined() )
2725 // create an empty entry by using ::std::map<>::operator[]
2726 aCellStyles[ xStyle->getName() ];
2730 catch( Exception& )
2734 /* Calculate names of built-in styles. Store styles with reserved names
2735 in the aConflictNameStyles list. */
2736 for( CellStyleVector::iterator aIt = maBuiltinStyles.begin(), aEnd = maBuiltinStyles.end(); aIt != aEnd; ++aIt )
2738 const CellStyleModel& rModel = (*aIt)->getModel();
2739 if (rModel.isDefaultStyle())
2740 continue;
2742 OUString aStyleName = lclCreateStyleName( rModel );
2743 /* If a builtin style entry already exists, and we do not reserve all
2744 existing styles, we just stick with the last definition and ignore
2745 the preceding ones. */
2746 if( bReserveAll && (aCellStyles.find( aStyleName ) != aCellStyles.end()) )
2747 aConflictNameStyles.push_back( *aIt );
2748 else
2749 aCellStyles[ aStyleName ] = *aIt;
2752 /* Calculate names of user defined styles. Store styles with reserved
2753 names in the aConflictNameStyles list. */
2754 for( CellStyleVector::iterator aIt = maUserStyles.begin(), aEnd = maUserStyles.end(); aIt != aEnd; ++aIt )
2756 const CellStyleModel& rModel = (*aIt)->getModel();
2757 OUString aStyleName = lclCreateStyleName( rModel );
2758 // #i1624# #i1768# ignore unnamed user styles
2759 if( aStyleName.getLength() > 0 )
2761 if( aCellStyles.find( aStyleName ) != aCellStyles.end() )
2762 aConflictNameStyles.push_back( *aIt );
2763 else
2764 aCellStyles[ aStyleName ] = *aIt;
2768 // find unused names for all styles with conflicting names
2769 // having the index counter outside the loop prevents performance problems with opening some pathological documents (tdf#62095)
2770 sal_Int32 nIndex = 0;
2771 for( CellStyleVector::iterator aIt = aConflictNameStyles.begin(), aEnd = aConflictNameStyles.end(); aIt != aEnd; ++aIt )
2773 const CellStyleModel& rModel = (*aIt)->getModel();
2774 OUString aStyleName = lclCreateStyleName( rModel );
2775 OUString aUnusedName;
2778 aUnusedName = OUStringBuffer( aStyleName ).append( ' ' ).append( ++nIndex ).makeStringAndClear();
2780 while( aCellStyles.find( aUnusedName ) != aCellStyles.end() );
2781 aCellStyles[ aUnusedName ] = *aIt;
2784 // set final names and create user-defined and modified built-in cell styles
2785 aCellStyles.forEachMemWithKey( &CellStyle::finalizeImport );
2788 sal_Int32 CellStyleBuffer::getDefaultXfId() const
2790 return mxDefStyle.get() ? mxDefStyle->getModel().mnXfId : -1;
2793 OUString CellStyleBuffer::getDefaultStyleName() const
2795 return createCellStyle( mxDefStyle );
2798 OUString CellStyleBuffer::createCellStyle( sal_Int32 nXfId ) const
2800 return createCellStyle( maStylesByXf.get( nXfId ) );
2803 ::ScStyleSheet* CellStyleBuffer::getCellStyleSheet( sal_Int32 nXfId ) const
2805 return getCellStyleSheet( maStylesByXf.get( nXfId ) );
2808 // private --------------------------------------------------------------------
2810 void CellStyleBuffer::insertCellStyle( CellStyleRef xCellStyle )
2812 const CellStyleModel& rModel = xCellStyle->getModel();
2813 if( rModel.mnXfId >= 0 )
2815 // insert into the built-in map or user defined map
2816 (rModel.isBuiltin() ? maBuiltinStyles : maUserStyles).push_back( xCellStyle );
2818 // insert into the XF identifier map
2819 OSL_ENSURE( maStylesByXf.count( rModel.mnXfId ) == 0, "CellStyleBuffer::insertCellStyle - multiple styles with equal XF identifier" );
2820 maStylesByXf[ rModel.mnXfId ] = xCellStyle;
2822 // remember default cell style
2823 if( rModel.isDefaultStyle() )
2824 mxDefStyle = xCellStyle;
2828 ::ScStyleSheet* CellStyleBuffer::getCellStyleSheet( const CellStyleRef& rxCellStyle )
2830 ::ScStyleSheet* pStyleSheet = nullptr;
2831 if ( rxCellStyle.get() )
2832 pStyleSheet = rxCellStyle->getStyleSheet();
2833 return pStyleSheet;
2836 OUString CellStyleBuffer::createCellStyle( const CellStyleRef& rxCellStyle )
2838 if( rxCellStyle.get() )
2840 rxCellStyle->createCellStyle();
2841 const OUString& rStyleName = rxCellStyle->getFinalStyleName();
2842 if( !rStyleName.isEmpty() )
2843 return rStyleName;
2845 // on error: fallback to default style
2846 return lclGetBuiltinStyleName( OOX_STYLE_NORMAL, OUString() );
2849 AutoFormatModel::AutoFormatModel() :
2850 mnAutoFormatId( 0 ),
2851 mbApplyNumFmt( false ),
2852 mbApplyFont( false ),
2853 mbApplyAlignment( false ),
2854 mbApplyBorder( false ),
2855 mbApplyFill( false ),
2856 mbApplyProtection( false )
2860 StylesBuffer::StylesBuffer( const WorkbookHelper& rHelper ) :
2861 WorkbookHelper( rHelper ),
2862 maPalette( rHelper ),
2863 maNumFmts( rHelper ),
2864 maCellStyles( rHelper )
2868 FontRef StylesBuffer::createFont()
2870 FontRef xFont( new Font( *this, false ) );
2871 maFonts.push_back( xFont );
2872 return xFont;
2875 NumberFormatRef StylesBuffer::createNumFmt( sal_Int32 nNumFmtId, const OUString& rFmtCode )
2877 return maNumFmts.createNumFmt( nNumFmtId, rFmtCode );
2880 sal_Int32 StylesBuffer::nextFreeNumFmtId()
2882 return maNumFmts.nextFreeId();
2885 BorderRef StylesBuffer::createBorder()
2887 BorderRef xBorder( new Border( *this, false ) );
2888 maBorders.push_back( xBorder );
2889 return xBorder;
2892 FillRef StylesBuffer::createFill()
2894 FillRef xFill( new Fill( *this, false ) );
2895 maFills.push_back( xFill );
2896 return xFill;
2899 XfRef StylesBuffer::createCellXf()
2901 XfRef xXf( new Xf( *this ) );
2902 maCellXfs.push_back( xXf );
2903 return xXf;
2906 XfRef StylesBuffer::createStyleXf()
2908 XfRef xXf( new Xf( *this ) );
2909 maStyleXfs.push_back( xXf );
2910 return xXf;
2913 DxfRef StylesBuffer::createDxf()
2915 DxfRef xDxf( new Dxf( *this ) );
2916 maDxfs.push_back( xDxf );
2917 return xDxf;
2920 void StylesBuffer::importPaletteColor( const AttributeList& rAttribs )
2922 maPalette.importPaletteColor( rAttribs );
2925 NumberFormatRef StylesBuffer::importNumFmt( const AttributeList& rAttribs )
2927 return maNumFmts.importNumFmt( rAttribs );
2930 CellStyleRef StylesBuffer::importCellStyle( const AttributeList& rAttribs )
2932 return maCellStyles.importCellStyle( rAttribs );
2935 void StylesBuffer::importPaletteColor( SequenceInputStream& rStrm )
2937 maPalette.importPaletteColor( rStrm );
2940 void StylesBuffer::importNumFmt( SequenceInputStream& rStrm )
2942 maNumFmts.importNumFmt( rStrm );
2945 void StylesBuffer::importCellStyle( SequenceInputStream& rStrm )
2947 maCellStyles.importCellStyle( rStrm );
2950 void StylesBuffer::finalizeImport()
2952 // fonts first, are needed to finalize unit converter and XFs below
2953 maFonts.forEachMem( &Font::finalizeImport );
2954 // finalize unit coefficients after default font is known
2955 getUnitConverter().finalizeImport();
2956 // number formats
2957 maNumFmts.finalizeImport();
2958 // borders and fills
2959 // is there a document wide RTL setting that we
2960 // would/could need to pass to finalizeImport here ?
2961 maBorders.forEachMem( &Border::finalizeImport, false );
2962 maFills.forEachMem( &Fill::finalizeImport );
2963 // style XFs and cell XFs
2964 maStyleXfs.forEachMem( &Xf::finalizeImport );
2965 maCellXfs.forEachMem( &Xf::finalizeImport );
2966 // built-in and user defined cell styles
2967 maCellStyles.finalizeImport();
2968 // differential formatting (for conditional formatting)
2969 maDxfs.forEachMem( &Dxf::finalizeImport );
2972 sal_Int32 StylesBuffer::getPaletteColor( sal_Int32 nPaletteIdx ) const
2974 return maPalette.getColor( nPaletteIdx );
2977 FontRef StylesBuffer::getFont( sal_Int32 nFontId ) const
2979 return maFonts.get( nFontId );
2982 BorderRef StylesBuffer::getBorder( sal_Int32 nBorderId ) const
2984 return maBorders.get( nBorderId );
2987 XfRef StylesBuffer::getCellXf( sal_Int32 nXfId ) const
2989 return maCellXfs.get( nXfId );
2992 XfRef StylesBuffer::getStyleXf( sal_Int32 nXfId ) const
2994 return maStyleXfs.get( nXfId );
2997 FontRef StylesBuffer::getFontFromCellXf( sal_Int32 nXfId ) const
2999 FontRef xFont;
3000 if( const Xf* pXf = getCellXf( nXfId ).get() )
3001 xFont = pXf->getFont();
3002 return xFont;
3005 FontRef StylesBuffer::getDefaultFont() const
3007 FontRef xDefFont;
3008 if( const Xf* pXf = getStyleXf( maCellStyles.getDefaultXfId() ).get() )
3009 xDefFont = pXf->getFont();
3010 // no font from styles - try first loaded font (e.g. BIFF2)
3011 if( !xDefFont )
3012 xDefFont = maFonts.get( 0 );
3013 OSL_ENSURE( xDefFont.get(), "StylesBuffer::getDefaultFont - no default font found" );
3014 return xDefFont;
3017 const FontModel& StylesBuffer::getDefaultFontModel() const
3019 FontRef xDefFont = getDefaultFont();
3020 return xDefFont.get() ? xDefFont->getModel() : getTheme().getDefaultFontModel();
3023 bool StylesBuffer::equalBorders( sal_Int32 nBorderId1, sal_Int32 nBorderId2 ) const
3025 if( nBorderId1 == nBorderId2 )
3026 return true;
3028 switch( getFilterType() )
3030 case FILTER_OOXML:
3031 // in OOXML, borders are assumed to be unique
3032 return false;
3034 case FILTER_BIFF:
3036 // in BIFF, a new border entry has been created for every XF
3037 const Border* pBorder1 = maBorders.get( nBorderId1 ).get();
3038 const Border* pBorder2 = maBorders.get( nBorderId2 ).get();
3039 return pBorder1 && pBorder2 && (pBorder1->getApiData() == pBorder2->getApiData());
3042 case FILTER_UNKNOWN:
3043 break;
3045 return false;
3048 bool StylesBuffer::equalFills( sal_Int32 nFillId1, sal_Int32 nFillId2 ) const
3050 if( nFillId1 == nFillId2 )
3051 return true;
3053 switch( getFilterType() )
3055 case FILTER_OOXML:
3056 // in OOXML, fills are assumed to be unique
3057 return false;
3059 case FILTER_BIFF:
3061 // in BIFF, a new fill entry has been created for every XF
3062 const Fill* pFill1 = maFills.get( nFillId1 ).get();
3063 const Fill* pFill2 = maFills.get( nFillId2 ).get();
3064 return pFill1 && pFill2 && (pFill1->getApiData() == pFill2->getApiData());
3067 case FILTER_UNKNOWN:
3068 break;
3070 return false;
3073 OUString StylesBuffer::getDefaultStyleName() const
3075 return maCellStyles.getDefaultStyleName();
3078 OUString StylesBuffer::createCellStyle( sal_Int32 nXfId ) const
3080 return maCellStyles.createCellStyle( nXfId );
3083 ::ScStyleSheet* StylesBuffer::getCellStyleSheet( sal_Int32 nXfId ) const
3085 return maCellStyles.getCellStyleSheet( nXfId );
3088 OUString StylesBuffer::createDxfStyle( sal_Int32 nDxfId ) const
3090 OUString& rStyleName = maDxfStyles[ nDxfId ];
3091 if (!rStyleName.isEmpty())
3092 return rStyleName;
3094 if (Dxf* pDxf = maDxfs.get(nDxfId).get())
3096 rStyleName = OUStringBuffer("ConditionalStyle_").append(nDxfId + 1).makeStringAndClear();
3098 // Create a cell style. This may overwrite an existing style if
3099 // one with the same name exists.
3100 ScStyleSheet& rStyleSheet = ScfTools::MakeCellStyleSheet(
3101 *getScDocument().GetStyleSheetPool(), rStyleName, true);
3103 rStyleSheet.ResetParent();
3104 SfxItemSet& rStyleItemSet =
3105 rStyleSheet.GetItemSet();
3107 pDxf->fillToItemSet(rStyleItemSet);
3110 // on error: fallback to default style
3111 if (rStyleName.isEmpty())
3112 rStyleName = maCellStyles.getDefaultStyleName();
3114 return rStyleName;
3117 void StylesBuffer::writeFontToItemSet( SfxItemSet& rItemSet, sal_Int32 nFontId, bool bSkipPoolDefs ) const
3119 if( Font* pFont = maFonts.get( nFontId ).get() )
3120 pFont->fillToItemSet( rItemSet, false, bSkipPoolDefs );
3123 void StylesBuffer::writeFontToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFontId ) const
3125 if( Font* pFont = maFonts.get( nFontId ).get() )
3126 pFont->writeToPropertyMap( rPropMap, FONT_PROPTYPE_CELL );
3129 sal_uLong StylesBuffer::writeNumFmtToItemSet( SfxItemSet& rItemSet, sal_Int32 nNumFmtId, bool bSkipPoolDefs ) const
3131 return maNumFmts.fillToItemSet( rItemSet, nNumFmtId, bSkipPoolDefs );
3134 void StylesBuffer::writeNumFmtToPropertyMap( PropertyMap& rPropMap, sal_Int32 nNumFmtId ) const
3136 maNumFmts.writeToPropertyMap( rPropMap, nNumFmtId );
3139 void StylesBuffer::writeBorderToItemSet( SfxItemSet& rItemSet, sal_Int32 nBorderId, bool bSkipPoolDefs ) const
3141 if( Border* pBorder = maBorders.get( nBorderId ).get() )
3142 pBorder->fillToItemSet( rItemSet, bSkipPoolDefs );
3145 void StylesBuffer::writeBorderToPropertyMap( PropertyMap& rPropMap, sal_Int32 nBorderId ) const
3147 if( Border* pBorder = maBorders.get( nBorderId ).get() )
3148 pBorder->writeToPropertyMap( rPropMap );
3151 void StylesBuffer::writeFillToItemSet( SfxItemSet& rItemSet, sal_Int32 nFillId, bool bSkipPoolDefs ) const
3153 if( Fill* pFill = maFills.get( nFillId ).get() )
3154 pFill->fillToItemSet( rItemSet, bSkipPoolDefs );
3157 void StylesBuffer::writeFillToPropertyMap( PropertyMap& rPropMap, sal_Int32 nFillId ) const
3159 if( Fill* pFill = maFills.get( nFillId ).get() )
3160 pFill->writeToPropertyMap( rPropMap );
3163 bool operator==( const XfModel& rXfModel1, const XfModel& rXfModel2 )
3165 return ( rXfModel1.mbCellXf == rXfModel2.mbCellXf &&
3166 rXfModel1.mnStyleXfId == rXfModel2.mnStyleXfId &&
3167 rXfModel1.mbFontUsed == rXfModel2.mbFontUsed &&
3168 rXfModel1.mnFontId == rXfModel2.mnFontId &&
3169 rXfModel1.mbNumFmtUsed == rXfModel2.mbNumFmtUsed &&
3170 rXfModel1.mnNumFmtId == rXfModel2.mnNumFmtId &&
3171 rXfModel1.mbAlignUsed == rXfModel2.mbAlignUsed &&
3172 rXfModel1.mbBorderUsed == rXfModel2.mbBorderUsed &&
3173 rXfModel1.mnBorderId == rXfModel2.mnBorderId &&
3174 rXfModel1.mbAreaUsed == rXfModel2.mbAreaUsed &&
3175 rXfModel1.mnFillId == rXfModel2.mnFillId &&
3176 rXfModel1.mbProtUsed == rXfModel2.mbProtUsed );
3179 bool operator==( const Xf& rXf1, const Xf& rXf2 )
3181 if ( rXf1.maModel == rXf2.maModel )
3183 if ( rXf1.maModel.mbAlignUsed )
3185 if ( !( rXf1.maAlignment.getApiData() == rXf2.maAlignment.getApiData() ) )
3186 return false;
3188 if ( rXf1.maModel.mbProtUsed )
3190 if ( !( rXf1.maProtection.getApiData() == rXf2.maProtection.getApiData() ) )
3191 return false;
3193 return true;
3195 return false;
3198 void StylesBuffer::writeCellXfToDoc(
3199 ScDocumentImport& rDoc, const table::CellRangeAddress& rRange, sal_Int32 nXfId ) const
3201 Xf* pXf = maCellXfs.get(nXfId).get();
3202 if (!pXf)
3203 return;
3205 pXf->writeToDoc(rDoc, rRange);
3208 } // namespace xls
3209 } // namespace oox
3211 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */