1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #include <stylesbuffer.hxx>
21
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/style/XStyle.hpp>
34 #include <com/sun/star/text/WritingMode2.hpp>
35 #include <com/sun/star/table/BorderLineStyle.hpp>
36 #include <com/sun/star/table/CellVertJustify2.hpp>
37 #include <com/sun/star/table/CellJustifyMethod.hpp>
38 #include <editeng/justifyitem.hxx>
39 #include <editeng/frmdiritem.hxx>
40 #include <editeng/fontitem.hxx>
41 #include <editeng/postitem.hxx>
42 #include <editeng/fhgtitem.hxx>
43 #include <editeng/wghtitem.hxx>
44 #include <editeng/udlnitem.hxx>
45 #include <editeng/colritem.hxx>
46 #include <editeng/crossedoutitem.hxx>
47 #include <editeng/contouritem.hxx>
48 #include <editeng/escapementitem.hxx>
49 #include <editeng/shdditem.hxx>
50 #include <editeng/eeitem.hxx>
51 #include <editeng/borderline.hxx>
52 #include <editeng/boxitem.hxx>
53 #include <editeng/lineitem.hxx>
54 #include <editeng/brushitem.hxx>
55 #include <svx/rotmodit.hxx>
56 #include <tools/fontenum.hxx>
57 #include <vcl/unohelp.hxx>
58 #include <rtl/tencinfo.h>
59 #include <rtl/ustrbuf.hxx>
60 #include <sal/log.hxx>
61 #include <osl/diagnose.h>
62 #include <oox/core/filterbase.hxx>
63 #include <oox/helper/attributelist.hxx>
64 #include <oox/helper/binaryinputstream.hxx>
65 #include <oox/helper/containerhelper.hxx>
66 #include <oox/helper/propertymap.hxx>
67 #include <oox/helper/propertyset.hxx>
68 #include <oox/token/namespaces.hxx>
69 #include <oox/token/properties.hxx>
70 #include <oox/token/tokens.hxx>
71 #include <themebuffer.hxx>
72 #include <unitconverter.hxx>
73 #include <document.hxx>
74 #include <stlpool.hxx>
75 #include <docpool.hxx>
76 #include <ftools.hxx>
77 #include <scitems.hxx>
78 #include <attrib.hxx>
79 #include <globstr.hrc>
80 #include <scresid.hxx>
81 #include <xlconst.hxx>
82 #include <documentimport.hxx>
83 #include <numformat.hxx>
84 #include <patattr.hxx>
85 #include <stlsheet.hxx>
86 #include <biffhelper.hxx>
87
88 namespace oox {
89 namespace xls {
90
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;
97
98
99 namespace {
100
101 // OOXML constants ------------------------------------------------------------
102
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
106 // OOXML font family (also used in BIFF)
107 const sal_Int32 OOX_FONTFAMILY_NONE = 0;
108 const sal_Int32 OOX_FONTFAMILY_ROMAN = 1;
109 const sal_Int32 OOX_FONTFAMILY_SWISS = 2;
110 const sal_Int32 OOX_FONTFAMILY_MODERN = 3;
111 const sal_Int32 OOX_FONTFAMILY_SCRIPT = 4;
112 const sal_Int32 OOX_FONTFAMILY_DECORATIVE = 5;
113
114 // OOXML cell text direction (also used in BIFF)
115 const sal_Int32 OOX_XF_TEXTDIR_CONTEXT = 0;
116 const sal_Int32 OOX_XF_TEXTDIR_LTR = 1;
117 const sal_Int32 OOX_XF_TEXTDIR_RTL = 2;
118
119 // OOXML cell rotation (also used in BIFF)
120 const sal_Int32 OOX_XF_ROTATION_NONE = 0;
121 const sal_Int32 OOX_XF_ROTATION_STACKED = 255;
122
123 // OOXML cell indentation
124 const sal_Int32 OOX_XF_INDENT_NONE = 0;
125
126 // OOXML built-in cell styles (also used in BIFF)
127 const sal_Int32 OOX_STYLE_NORMAL = 0; /// Default cell style.
128 const sal_Int32 OOX_STYLE_ROWLEVEL = 1; /// RowLevel_x cell style.
129 const sal_Int32 OOX_STYLE_COLLEVEL = 2; /// ColLevel_x cell style.
130
131 // BIFF12 constants -----------------------------------------------------------
132
133 // BIFF12 color types
134 const sal_uInt8 BIFF12_COLOR_AUTO = 0;
135 const sal_uInt8 BIFF12_COLOR_INDEXED = 1;
136 const sal_uInt8 BIFF12_COLOR_RGB = 2;
137 const sal_uInt8 BIFF12_COLOR_THEME = 3;
138
139 // BIFF12 diagonal borders
140 const sal_uInt8 BIFF12_BORDER_DIAG_TLBR = 0x01; /// Top-left to bottom-right.
141 const sal_uInt8 BIFF12_BORDER_DIAG_BLTR = 0x02; /// Bottom-left to top-right.
142
143 // BIFF12 gradient fill
144 const sal_Int32 BIFF12_FILL_GRADIENT = 40;
145
146 // BIFF12 XF flags
147 const sal_uInt32 BIFF12_XF_WRAPTEXT = 0x00400000;
148 const sal_uInt32 BIFF12_XF_JUSTLASTLINE = 0x00800000;
149 const sal_uInt32 BIFF12_XF_SHRINK = 0x01000000;
150 const sal_uInt32 BIFF12_XF_LOCKED = 0x10000000;
151 const sal_uInt32 BIFF12_XF_HIDDEN = 0x20000000;
152
153 // BIFF12 XF attribute used flags
154 const sal_uInt16 BIFF12_XF_NUMFMT_USED = 0x0001;
155 const sal_uInt16 BIFF12_XF_FONT_USED = 0x0002;
156 const sal_uInt16 BIFF12_XF_ALIGN_USED = 0x0004;
157 const sal_uInt16 BIFF12_XF_BORDER_USED = 0x0008;
158 const sal_uInt16 BIFF12_XF_AREA_USED = 0x0010;
159 const sal_uInt16 BIFF12_XF_PROT_USED = 0x0020;
160
161 // BIFF12 DXF constants
162 const sal_uInt16 BIFF12_DXF_FILL_PATTERN = 0;
163 const sal_uInt16 BIFF12_DXF_FILL_FGCOLOR = 1;
164 const sal_uInt16 BIFF12_DXF_FILL_BGCOLOR = 2;
165 const sal_uInt16 BIFF12_DXF_FILL_GRADIENT = 3;
166 const sal_uInt16 BIFF12_DXF_FILL_STOP = 4;
167 const sal_uInt16 BIFF12_DXF_FONT_COLOR = 5;
168 const sal_uInt16 BIFF12_DXF_BORDER_TOP = 6;
169 const sal_uInt16 BIFF12_DXF_BORDER_BOTTOM = 7;
170 const sal_uInt16 BIFF12_DXF_BORDER_LEFT = 8;
171 const sal_uInt16 BIFF12_DXF_BORDER_RIGHT = 9;
172 const sal_uInt16 BIFF12_DXF_FONT_NAME = 24;
173 const sal_uInt16 BIFF12_DXF_FONT_WEIGHT = 25;
174 const sal_uInt16 BIFF12_DXF_FONT_UNDERLINE = 26;
175 const sal_uInt16 BIFF12_DXF_FONT_ESCAPEMENT = 27;
176 const sal_uInt16 BIFF12_DXF_FONT_ITALIC = 28;
177 const sal_uInt16 BIFF12_DXF_FONT_STRIKE = 29;
178 const sal_uInt16 BIFF12_DXF_FONT_OUTLINE = 30;
179 const sal_uInt16 BIFF12_DXF_FONT_SHADOW = 31;
180 const sal_uInt16 BIFF12_DXF_FONT_HEIGHT = 36;
181 const sal_uInt16 BIFF12_DXF_FONT_SCHEME = 37;
182 const sal_uInt16 BIFF12_DXF_NUMFMT_CODE = 38;
183 const sal_uInt16 BIFF12_DXF_NUMFMT_ID = 41;
184
185 // BIFF12 CELLSTYLE flags
186 const sal_uInt16 BIFF12_CELLSTYLE_BUILTIN = 0x0001;
187 const sal_uInt16 BIFF12_CELLSTYLE_HIDDEN = 0x0002;
188 const sal_uInt16 BIFF12_CELLSTYLE_CUSTOM = 0x0004;
189
190 // BIFF constants -------------------------------------------------------------
191
192 // BIFF font flags, also used in BIFF12
193 const sal_uInt16 BIFF_FONTFLAG_ITALIC = 0x0002;
194 const sal_uInt16 BIFF_FONTFLAG_STRIKEOUT = 0x0008;
195 const sal_uInt16 BIFF_FONTFLAG_OUTLINE = 0x0010;
196 const sal_uInt16 BIFF_FONTFLAG_SHADOW = 0x0020;
197
198 // BIFF font weight
199 const sal_uInt16 BIFF_FONTWEIGHT_BOLD = 450;
200
201 // BIFF font underline, also used in BIFF12
202 const sal_uInt8 BIFF_FONTUNDERL_NONE = 0;
203 const sal_uInt8 BIFF_FONTUNDERL_SINGLE = 1;
204 const sal_uInt8 BIFF_FONTUNDERL_DOUBLE = 2;
205 const sal_uInt8 BIFF_FONTUNDERL_SINGLE_ACC = 33;
206 const sal_uInt8 BIFF_FONTUNDERL_DOUBLE_ACC = 34;
207
lclReadRgbColor(BinaryInputStream & rStrm)208 ::Color lclReadRgbColor( BinaryInputStream& rStrm )
209 {
210 sal_uInt8 nR, nG, nB, nA;
211 nR = rStrm.readuChar();
212 nG = rStrm.readuChar();
213 nB = rStrm.readuChar();
214 nA = rStrm.readuChar();
215 sal_Int32 nValue = nA;
216 nValue <<= 8;
217 nValue |= nR;
218 nValue <<= 8;
219 nValue |= nG;
220 nValue <<= 8;
221 nValue |= nB;
222 return ::Color(nValue);
223 }
224
225 } // namespace
226
ExcelGraphicHelper(const WorkbookHelper & rHelper)227 ExcelGraphicHelper::ExcelGraphicHelper( const WorkbookHelper& rHelper ) :
228 GraphicHelper( rHelper.getBaseFilter().getComponentContext(), rHelper.getBaseFilter().getTargetFrame(), rHelper.getBaseFilter().getStorage() ),
229 WorkbookHelper( rHelper )
230 {
231 }
232
getSchemeColor(sal_Int32 nToken) const233 ::Color ExcelGraphicHelper::getSchemeColor( sal_Int32 nToken ) const
234 {
235 return getTheme().getColorByToken( nToken );
236 }
237
getPaletteColor(sal_Int32 nPaletteIdx) const238 ::Color ExcelGraphicHelper::getPaletteColor( sal_Int32 nPaletteIdx ) const
239 {
240 return getStyles().getPaletteColor( nPaletteIdx );
241 }
242
setAuto()243 void Color::setAuto()
244 {
245 clearTransformations();
246 setSchemeClr( XML_phClr );
247 }
248
setRgb(::Color nRgbValue,double fTint)249 void Color::setRgb( ::Color nRgbValue, double fTint )
250 {
251 clearTransformations();
252 setSrgbClr( sal_uInt32(nRgbValue) & 0xFFFFFF );
253 if( fTint != 0.0 ) addExcelTintTransformation( fTint );
254 }
255
setTheme(sal_Int32 nThemeIdx,double fTint)256 void Color::setTheme( sal_Int32 nThemeIdx, double fTint )
257 {
258 clearTransformations();
259 static const sal_Int32 spnColorTokens[] = {
260 XML_lt1, XML_dk1, XML_lt2, XML_dk2, XML_accent1, XML_accent2,
261 XML_accent3, XML_accent4, XML_accent5, XML_accent6, XML_hlink, XML_folHlink };
262 setSchemeClr( STATIC_ARRAY_SELECT( spnColorTokens, nThemeIdx, XML_TOKEN_INVALID ) );
263 if( fTint != 0.0 ) addExcelTintTransformation( fTint );
264 }
265
setIndexed(sal_Int32 nPaletteIdx,double fTint)266 void Color::setIndexed( sal_Int32 nPaletteIdx, double fTint )
267 {
268 clearTransformations();
269 setPaletteClr( nPaletteIdx );
270 if( fTint != 0.0 ) addExcelTintTransformation( fTint );
271 }
272
importColor(const AttributeList & rAttribs)273 void Color::importColor( const AttributeList& rAttribs )
274 {
275 // tdf#113271 The order of import color is very important in case of more than one color attributes was provided.
276 // This order (theme -> rgb -> indexed -> auto) is not documented and was gathered experimentally based on MS Excel 2013.
277 if( rAttribs.hasAttribute( XML_theme ) )
278 setTheme( rAttribs.getInteger( XML_theme, -1 ), rAttribs.getDouble( XML_tint, 0.0 ) );
279 else if( rAttribs.hasAttribute( XML_rgb ) )
280 setRgb( rAttribs.getIntegerHex( XML_rgb, sal_Int32(API_RGB_TRANSPARENT) ), rAttribs.getDouble( XML_tint, 0.0 ) );
281 else if( rAttribs.hasAttribute( XML_indexed ) )
282 setIndexed( rAttribs.getInteger( XML_indexed, -1 ), rAttribs.getDouble( XML_tint, 0.0 ) );
283 else if( rAttribs.getBool( XML_auto, false ) )
284 setAuto();
285 else
286 {
287 OSL_FAIL( "Color::importColor - unknown color type" );
288 setAuto();
289 }
290 }
291
importColor(SequenceInputStream & rStrm)292 void Color::importColor( SequenceInputStream& rStrm )
293 {
294 sal_uInt8 nFlags, nIndex;
295 sal_Int16 nTint;
296 nFlags = rStrm.readuChar();
297 nIndex = rStrm.readuChar();
298 nTint = rStrm.readInt16();
299
300 // scale tint from signed 16-bit to double range -1.0 ... 1.0
301 double fTint = nTint;
302 if( nTint < 0 )
303 fTint /= -SAL_MIN_INT16;
304 else if( nTint > 0 )
305 fTint /= SAL_MAX_INT16;
306
307 switch( extractValue< sal_uInt8 >( nFlags, 1, 7 ) )
308 {
309 case BIFF12_COLOR_AUTO:
310 setAuto();
311 rStrm.skip( 4 );
312 break;
313 case BIFF12_COLOR_INDEXED:
314 setIndexed( nIndex, fTint );
315 rStrm.skip( 4 );
316 break;
317 case BIFF12_COLOR_RGB:
318 setRgb( lclReadRgbColor( rStrm ), fTint );
319 break;
320 case BIFF12_COLOR_THEME:
321 setTheme( nIndex, fTint );
322 rStrm.skip( 4 );
323 break;
324 default:
325 OSL_FAIL( "Color::importColor - unknown color type" );
326 setAuto();
327 rStrm.skip( 4 );
328 }
329 }
330
importColorId(SequenceInputStream & rStrm)331 void Color::importColorId( SequenceInputStream& rStrm )
332 {
333 setIndexed( rStrm.readInt32() );
334 }
335
operator >>(SequenceInputStream & rStrm,Color & orColor)336 SequenceInputStream& operator>>( SequenceInputStream& rStrm, Color& orColor )
337 {
338 orColor.importColor( rStrm );
339 return rStrm;
340 }
341
342 namespace {
343
344 /** Standard EGA colors, bright. */
345 #define PALETTE_EGA_COLORS_LIGHT \
346 ::Color(0x000000), ::Color(0xFFFFFF), ::Color(0xFF0000), ::Color(0x00FF00), ::Color(0x0000FF), ::Color(0xFFFF00), ::Color(0xFF00FF), ::Color(0x00FFFF)
347 /** Standard EGA colors), dark. */
348 #define PALETTE_EGA_COLORS_DARK \
349 ::Color(0x800000), ::Color(0x008000), ::Color(0x000080), ::Color(0x808000), ::Color(0x800080), ::Color(0x008080), ::Color(0xC0C0C0), ::Color(0x808080)
350
351 /** Default color table for BIFF8/BIFF12/OOXML. */
352 static const ::Color spnDefColors8[] =
353 {
354 /* 0 */ PALETTE_EGA_COLORS_LIGHT,
355 /* 8 */ PALETTE_EGA_COLORS_LIGHT,
356 /* 16 */ PALETTE_EGA_COLORS_DARK,
357 /* 24 */ ::Color(0x9999FF), ::Color(0x993366), ::Color(0xFFFFCC), ::Color(0xCCFFFF), ::Color(0x660066), ::Color(0xFF8080), ::Color(0x0066CC), ::Color(0xCCCCFF),
358 /* 32 */ ::Color(0x000080), ::Color(0xFF00FF), ::Color(0xFFFF00), ::Color(0x00FFFF), ::Color(0x800080), ::Color(0x800000), ::Color(0x008080), ::Color(0x0000FF),
359 /* 40 */ ::Color(0x00CCFF), ::Color(0xCCFFFF), ::Color(0xCCFFCC), ::Color(0xFFFF99), ::Color(0x99CCFF), ::Color(0xFF99CC), ::Color(0xCC99FF), ::Color(0xFFCC99),
360 /* 48 */ ::Color(0x3366FF), ::Color(0x33CCCC), ::Color(0x99CC00), ::Color(0xFFCC00), ::Color(0xFF9900), ::Color(0xFF6600), ::Color(0x666699), ::Color(0x969696),
361 /* 56 */ ::Color(0x003366), ::Color(0x339966), ::Color(0x003300), ::Color(0x333300), ::Color(0x993300), ::Color(0x993366), ::Color(0x333399), ::Color(0x333333)
362 };
363
364 #undef PALETTE_EGA_COLORS_LIGHT
365 #undef PALETTE_EGA_COLORS_DARK
366
367 } // namespace
368
ColorPalette(const WorkbookHelper & rHelper)369 ColorPalette::ColorPalette( const WorkbookHelper& rHelper )
370 : WorkbookHelper(rHelper)
371 , mnAppendIndex(0)
372 {
373 // default colors
374 maColors.insert( maColors.begin(), spnDefColors8, spnDefColors8 + SAL_N_ELEMENTS(spnDefColors8) );
375 mnAppendIndex = OOX_COLOR_USEROFFSET;
376 }
377
importPaletteColor(const AttributeList & rAttribs)378 void ColorPalette::importPaletteColor( const AttributeList& rAttribs )
379 {
380 appendColor( rAttribs.getIntegerHex( XML_rgb, sal_Int32(API_RGB_WHITE) ) );
381 }
382
importPaletteColor(SequenceInputStream & rStrm)383 void ColorPalette::importPaletteColor( SequenceInputStream& rStrm )
384 {
385 ::Color nRgb = lclReadRgbColor( rStrm );
386 appendColor( nRgb );
387 }
388
getColor(sal_Int32 nPaletteIdx) const389 ::Color ColorPalette::getColor( sal_Int32 nPaletteIdx ) const
390 {
391 ::Color nColor = API_RGB_TRANSPARENT;
392 if( const ::Color* pnPaletteColor = ContainerHelper::getVectorElement( maColors, nPaletteIdx ) )
393 {
394 nColor = *pnPaletteColor;
395 }
396 else switch( nPaletteIdx )
397 {
398 case OOX_COLOR_WINDOWTEXT3:
399 case OOX_COLOR_WINDOWTEXT:
400 case OOX_COLOR_CHWINDOWTEXT: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_windowText ); break;
401 case OOX_COLOR_WINDOWBACK3:
402 case OOX_COLOR_WINDOWBACK:
403 case OOX_COLOR_CHWINDOWBACK: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_window ); break;
404 case OOX_COLOR_BUTTONBACK: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_btnFace ); break;
405 case OOX_COLOR_CHBORDERAUTO: nColor = API_RGB_BLACK; /* really always black? */ break;
406 case OOX_COLOR_NOTEBACK: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_infoBk ); break;
407 case OOX_COLOR_NOTETEXT: nColor = getBaseFilter().getGraphicHelper().getSystemColor( XML_infoText ); break;
408 case OOX_COLOR_FONTAUTO: nColor = API_RGB_TRANSPARENT; break;
409 default: OSL_FAIL( "ColorPalette::getColor - unknown color index" );
410 }
411 return nColor;
412 }
413
appendColor(::Color nRGBValue)414 void ColorPalette::appendColor( ::Color nRGBValue )
415 {
416 if( mnAppendIndex < maColors.size() )
417 maColors[ mnAppendIndex ] = nRGBValue;
418 else
419 maColors.push_back( nRGBValue );
420 ++mnAppendIndex;
421 }
422
423 namespace {
424
lclSetFontName(ApiScriptFontName & rFontName,const FontDescriptor & rFontDesc,bool bHasGlyphs)425 void lclSetFontName( ApiScriptFontName& rFontName, const FontDescriptor& rFontDesc, bool bHasGlyphs )
426 {
427 if( bHasGlyphs )
428 {
429 rFontName.maName = rFontDesc.Name;
430 rFontName.mnFamily = rFontDesc.Family;
431 // API font descriptor contains rtl_TextEncoding constants
432 rFontName.mnTextEnc = rFontDesc.CharSet;
433 }
434 else
435 {
436 rFontName = ApiScriptFontName();
437 }
438 }
439
440 } // namespace
441
FontModel()442 FontModel::FontModel() :
443 mnScheme( XML_none ),
444 mnFamily( OOX_FONTFAMILY_NONE ),
445 mnCharSet( WINDOWS_CHARSET_DEFAULT ),
446 mfHeight( 0.0 ),
447 mnUnderline( XML_none ),
448 mnEscapement( XML_baseline ),
449 mbBold( false ),
450 mbItalic( false ),
451 mbStrikeout( false ),
452 mbOutline( false ),
453 mbShadow( false )
454 {
455 }
456
setBiff12Scheme(sal_uInt8 nScheme)457 void FontModel::setBiff12Scheme( sal_uInt8 nScheme )
458 {
459 static const sal_Int32 spnSchemes[] = { XML_none, XML_major, XML_minor };
460 mnScheme = STATIC_ARRAY_SELECT( spnSchemes, nScheme, XML_none );
461 }
462
setBiffHeight(sal_uInt16 nHeight)463 void FontModel::setBiffHeight( sal_uInt16 nHeight )
464 {
465 mfHeight = nHeight / 20.0; // convert twips to points
466 }
467
setBiffWeight(sal_uInt16 nWeight)468 void FontModel::setBiffWeight( sal_uInt16 nWeight )
469 {
470 mbBold = nWeight >= BIFF_FONTWEIGHT_BOLD;
471 }
472
setBiffUnderline(sal_uInt16 nUnderline)473 void FontModel::setBiffUnderline( sal_uInt16 nUnderline )
474 {
475 switch( nUnderline )
476 {
477 case BIFF_FONTUNDERL_NONE: mnUnderline = XML_none; break;
478 case BIFF_FONTUNDERL_SINGLE: mnUnderline = XML_single; break;
479 case BIFF_FONTUNDERL_DOUBLE: mnUnderline = XML_double; break;
480 case BIFF_FONTUNDERL_SINGLE_ACC: mnUnderline = XML_singleAccounting; break;
481 case BIFF_FONTUNDERL_DOUBLE_ACC: mnUnderline = XML_doubleAccounting; break;
482 default: mnUnderline = XML_none;
483 }
484 }
485
setBiffEscapement(sal_uInt16 nEscapement)486 void FontModel::setBiffEscapement( sal_uInt16 nEscapement )
487 {
488 static const sal_Int32 spnEscapes[] = { XML_baseline, XML_superscript, XML_subscript };
489 mnEscapement = STATIC_ARRAY_SELECT( spnEscapes, nEscapement, XML_baseline );
490 }
491
ApiFontUsedFlags(bool bAllUsed)492 ApiFontUsedFlags::ApiFontUsedFlags( bool bAllUsed ) :
493 mbNameUsed( bAllUsed ),
494 mbColorUsed( bAllUsed ),
495 mbSchemeUsed( bAllUsed ),
496 mbHeightUsed( bAllUsed ),
497 mbUnderlineUsed( bAllUsed ),
498 mbEscapementUsed( bAllUsed ),
499 mbWeightUsed( bAllUsed ),
500 mbPostureUsed( bAllUsed ),
501 mbStrikeoutUsed( bAllUsed ),
502 mbOutlineUsed( bAllUsed ),
503 mbShadowUsed( bAllUsed )
504 {
505 }
506
ApiScriptFontName()507 ApiScriptFontName::ApiScriptFontName() :
508 mnFamily( css::awt::FontFamily::DONTKNOW ),
509 mnTextEnc( RTL_TEXTENCODING_DONTKNOW )
510 {
511 }
512
ApiFontData()513 ApiFontData::ApiFontData() :
514 maDesc(
515 "Calibri",
516 220, // height 11 points
517 0,
518 OUString(),
519 css::awt::FontFamily::DONTKNOW,
520 RTL_TEXTENCODING_DONTKNOW,
521 css::awt::FontPitch::DONTKNOW,
522 100.0,
523 css::awt::FontWeight::NORMAL,
524 css::awt::FontSlant_NONE,
525 css::awt::FontUnderline::NONE,
526 css::awt::FontStrikeout::NONE,
527 0.0,
528 false,
529 false,
530 css::awt::FontType::DONTKNOW ),
531 mnColor( API_RGB_TRANSPARENT ),
532 mnEscapement( API_ESCAPE_NONE ),
533 mnEscapeHeight( API_ESCAPEHEIGHT_NONE ),
534 mbOutline( false ),
535 mbShadow( false )
536 {
537 maLatinFont.maName = maDesc.Name;
538 }
539
Font(const WorkbookHelper & rHelper,bool bDxf)540 Font::Font( const WorkbookHelper& rHelper, bool bDxf ) :
541 WorkbookHelper( rHelper ),
542 maModel( rHelper.getTheme().getDefaultFontModel() ),
543 maUsedFlags( !bDxf ),
544 mbDxf( bDxf )
545 {
546 }
547
Font(const WorkbookHelper & rHelper,const FontModel & rModel)548 Font::Font( const WorkbookHelper& rHelper, const FontModel& rModel ) :
549 WorkbookHelper( rHelper ),
550 maModel( rModel ),
551 maUsedFlags( true ),
552 mbDxf( false )
553 {
554 }
555
importAttribs(sal_Int32 nElement,const AttributeList & rAttribs)556 void Font::importAttribs( sal_Int32 nElement, const AttributeList& rAttribs )
557 {
558 const FontModel& rDefModel = getTheme().getDefaultFontModel();
559 switch( nElement )
560 {
561 case XLS_TOKEN( name ): // when in <font> element
562 case XLS_TOKEN( rFont ): // when in <rPr> element
563 if( rAttribs.hasAttribute( XML_val ) )
564 {
565 maModel.maName = rAttribs.getXString( XML_val, OUString() );
566 maUsedFlags.mbNameUsed = true;
567 }
568 break;
569 case XLS_TOKEN( scheme ):
570 maModel.mnScheme = rAttribs.getToken( XML_val, rDefModel.mnScheme );
571 break;
572 case XLS_TOKEN( family ):
573 maModel.mnFamily = rAttribs.getInteger( XML_val, rDefModel.mnFamily );
574 break;
575 case XLS_TOKEN( charset ):
576 maModel.mnCharSet = rAttribs.getInteger( XML_val, rDefModel.mnCharSet );
577 break;
578 case XLS_TOKEN( sz ):
579 maModel.mfHeight = rAttribs.getDouble( XML_val, rDefModel.mfHeight );
580 maUsedFlags.mbHeightUsed = true;
581 break;
582 case XLS_TOKEN( color ):
583 maModel.maColor.importColor( rAttribs );
584 maUsedFlags.mbColorUsed = true;
585 break;
586 case XLS_TOKEN( u ):
587 maModel.mnUnderline = rAttribs.getToken( XML_val, XML_single );
588 maUsedFlags.mbUnderlineUsed = true;
589 break;
590 case XLS_TOKEN( vertAlign ):
591 maModel.mnEscapement = rAttribs.getToken( XML_val, XML_baseline );
592 maUsedFlags.mbEscapementUsed = true;
593 break;
594 case XLS_TOKEN( b ):
595 maModel.mbBold = rAttribs.getBool( XML_val, true );
596 maUsedFlags.mbWeightUsed = true;
597 break;
598 case XLS_TOKEN( i ):
599 maModel.mbItalic = rAttribs.getBool( XML_val, true );
600 maUsedFlags.mbPostureUsed = true;
601 break;
602 case XLS_TOKEN( strike ):
603 maModel.mbStrikeout = rAttribs.getBool( XML_val, true );
604 maUsedFlags.mbStrikeoutUsed = true;
605 break;
606 case XLS_TOKEN( outline ):
607 maModel.mbOutline = rAttribs.getBool( XML_val, true );
608 maUsedFlags.mbOutlineUsed = true;
609 break;
610 case XLS_TOKEN( shadow ):
611 maModel.mbShadow = rAttribs.getBool( XML_val, true );
612 maUsedFlags.mbShadowUsed = true;
613 break;
614 }
615 }
616
importFont(SequenceInputStream & rStrm)617 void Font::importFont( SequenceInputStream& rStrm )
618 {
619 SAL_WARN_IF( mbDxf, "sc", "Font::importFont - unexpected conditional formatting flag" );
620
621 sal_uInt16 nHeight, nFlags, nWeight, nEscapement;
622 sal_uInt8 nUnderline, nFamily, nCharSet, nScheme;
623 nHeight = rStrm.readuInt16();
624 nFlags = rStrm.readuInt16();
625 nWeight = rStrm.readuInt16();
626 nEscapement = rStrm.readuInt16();
627 nUnderline = rStrm.readuChar();
628 nFamily = rStrm.readuChar();
629 nCharSet = rStrm.readuChar();
630 rStrm.skip( 1 );
631 rStrm >> maModel.maColor;
632 nScheme = rStrm.readuChar();
633 rStrm >> maModel.maName;
634
635 // equal constants in all BIFFs for weight, underline, and escapement
636 maModel.setBiff12Scheme( nScheme );
637 maModel.setBiffHeight( nHeight );
638 maModel.setBiffWeight( nWeight );
639 maModel.setBiffUnderline( nUnderline );
640 maModel.setBiffEscapement( nEscapement );
641 maModel.mnFamily = nFamily;
642 maModel.mnCharSet = nCharSet;
643 // equal flags in all BIFFs
644 maModel.mbItalic = getFlag( nFlags, BIFF_FONTFLAG_ITALIC );
645 maModel.mbStrikeout = getFlag( nFlags, BIFF_FONTFLAG_STRIKEOUT );
646 maModel.mbOutline = getFlag( nFlags, BIFF_FONTFLAG_OUTLINE );
647 maModel.mbShadow = getFlag( nFlags, BIFF_FONTFLAG_SHADOW );
648 }
649
importDxfName(SequenceInputStream & rStrm)650 void Font::importDxfName( SequenceInputStream& rStrm )
651 {
652 SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfName - missing conditional formatting flag" );
653 maModel.maName = BiffHelper::readString( rStrm, false );
654 maUsedFlags.mbColorUsed = true;
655 }
656
importDxfColor(SequenceInputStream & rStrm)657 void Font::importDxfColor( SequenceInputStream& rStrm )
658 {
659 SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfColor - missing conditional formatting flag" );
660 rStrm >> maModel.maColor;
661 maUsedFlags.mbColorUsed = true;
662 }
663
importDxfScheme(SequenceInputStream & rStrm)664 void Font::importDxfScheme( SequenceInputStream& rStrm )
665 {
666 SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfScheme - missing conditional formatting flag" );
667 maModel.setBiff12Scheme( rStrm.readuInt8() );
668 maUsedFlags.mbSchemeUsed = true;
669 }
670
importDxfHeight(SequenceInputStream & rStrm)671 void Font::importDxfHeight( SequenceInputStream& rStrm )
672 {
673 SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfHeight - missing conditional formatting flag" );
674 maModel.setBiffHeight( rStrm.readuInt16() );
675 maUsedFlags.mbHeightUsed = true;
676 }
677
importDxfWeight(SequenceInputStream & rStrm)678 void Font::importDxfWeight( SequenceInputStream& rStrm )
679 {
680 SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfWeight - missing conditional formatting flag" );
681 maModel.setBiffWeight( rStrm.readuInt16() );
682 maUsedFlags.mbWeightUsed = true;
683 }
684
importDxfUnderline(SequenceInputStream & rStrm)685 void Font::importDxfUnderline( SequenceInputStream& rStrm )
686 {
687 SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfUnderline - missing conditional formatting flag" );
688 maModel.setBiffUnderline( rStrm.readuInt16() );
689 maUsedFlags.mbUnderlineUsed = true;
690 }
691
importDxfEscapement(SequenceInputStream & rStrm)692 void Font::importDxfEscapement( SequenceInputStream& rStrm )
693 {
694 SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfEscapement - missing conditional formatting flag" );
695 maModel.setBiffEscapement( rStrm.readuInt16() );
696 maUsedFlags.mbEscapementUsed = true;
697 }
698
importDxfFlag(sal_Int32 nElement,SequenceInputStream & rStrm)699 void Font::importDxfFlag( sal_Int32 nElement, SequenceInputStream& rStrm )
700 {
701 SAL_WARN_IF( !mbDxf, "sc", "Font::importDxfFlag - missing conditional formatting flag" );
702 bool bFlag = rStrm.readuInt8() != 0;
703 switch( nElement )
704 {
705 case XML_i:
706 maModel.mbItalic = bFlag;
707 maUsedFlags.mbPostureUsed = true;
708 break;
709 case XML_strike:
710 maModel.mbStrikeout = bFlag;
711 maUsedFlags.mbStrikeoutUsed = true;
712 break;
713 case XML_outline:
714 maModel.mbOutline = bFlag;
715 maUsedFlags.mbOutlineUsed = true;
716 break;
717 case XML_shadow:
718 maModel.mbShadow = bFlag;
719 maUsedFlags.mbShadowUsed = true;
720 break;
721 default:
722 OSL_FAIL( "Font::importDxfFlag - unexpected element identifier" );
723 }
724 }
725
finalizeImport()726 void Font::finalizeImport()
727 {
728 // font name
729 maApiData.maDesc.Name = maModel.maName;
730
731 // font family
732 switch( maModel.mnFamily )
733 {
734 case OOX_FONTFAMILY_NONE: maApiData.maDesc.Family = css::awt::FontFamily::DONTKNOW; break;
735 case OOX_FONTFAMILY_ROMAN: maApiData.maDesc.Family = css::awt::FontFamily::ROMAN; break;
736 case OOX_FONTFAMILY_SWISS: maApiData.maDesc.Family = css::awt::FontFamily::SWISS; break;
737 case OOX_FONTFAMILY_MODERN: maApiData.maDesc.Family = css::awt::FontFamily::MODERN; break;
738 case OOX_FONTFAMILY_SCRIPT: maApiData.maDesc.Family = css::awt::FontFamily::SCRIPT; break;
739 case OOX_FONTFAMILY_DECORATIVE: maApiData.maDesc.Family = css::awt::FontFamily::DECORATIVE; break;
740 }
741
742 // character set (API font descriptor uses rtl_TextEncoding in member CharSet!)
743 if( (0 <= maModel.mnCharSet) && (maModel.mnCharSet <= SAL_MAX_UINT8) )
744 maApiData.maDesc.CharSet = static_cast< sal_Int16 >(
745 rtl_getTextEncodingFromWindowsCharset( static_cast< sal_uInt8 >( maModel.mnCharSet ) ) );
746
747 // color, height, weight, slant, strikeout, outline, shadow
748 maApiData.mnColor = maModel.maColor.getColor( getBaseFilter().getGraphicHelper() );
749 maApiData.maDesc.Height = static_cast< sal_Int16 >( maModel.mfHeight * 20.0 );
750 maApiData.maDesc.Weight = maModel.mbBold ? css::awt::FontWeight::BOLD : css::awt::FontWeight::NORMAL;
751 maApiData.maDesc.Slant = maModel.mbItalic ? css::awt::FontSlant_ITALIC : css::awt::FontSlant_NONE;
752 maApiData.maDesc.Strikeout = maModel.mbStrikeout ? css::awt::FontStrikeout::SINGLE : css::awt::FontStrikeout::NONE;
753 maApiData.mbOutline = maModel.mbOutline;
754 maApiData.mbShadow = maModel.mbShadow;
755
756 // underline
757 switch( maModel.mnUnderline )
758 {
759 case XML_double: maApiData.maDesc.Underline = css::awt::FontUnderline::DOUBLE; break;
760 case XML_doubleAccounting: maApiData.maDesc.Underline = css::awt::FontUnderline::DOUBLE; break;
761 case XML_none: maApiData.maDesc.Underline = css::awt::FontUnderline::NONE; break;
762 case XML_single: maApiData.maDesc.Underline = css::awt::FontUnderline::SINGLE; break;
763 case XML_singleAccounting: maApiData.maDesc.Underline = css::awt::FontUnderline::SINGLE; break;
764 }
765
766 // escapement
767 switch( maModel.mnEscapement )
768 {
769 case XML_baseline:
770 maApiData.mnEscapement = API_ESCAPE_NONE;
771 maApiData.mnEscapeHeight = API_ESCAPEHEIGHT_NONE;
772 break;
773 case XML_superscript:
774 maApiData.mnEscapement = API_ESCAPE_SUPERSCRIPT;
775 maApiData.mnEscapeHeight = API_ESCAPEHEIGHT_DEFAULT;
776 break;
777 case XML_subscript:
778 maApiData.mnEscapement = API_ESCAPE_SUBSCRIPT;
779 maApiData.mnEscapeHeight = API_ESCAPEHEIGHT_DEFAULT;
780 break;
781 }
782
783 // supported script types
784 if( maUsedFlags.mbNameUsed )
785 {
786 PropertySet aDocProps( getDocument() );
787 Reference< XDevice > xDevice( aDocProps.getAnyProperty( PROP_ReferenceDevice ), UNO_QUERY );
788 if( xDevice.is() )
789 {
790 Reference< XFont2 > xFont( xDevice->getFont( maApiData.maDesc ), UNO_QUERY );
791 if( xFont.is() )
792 {
793 // #91658# CJK fonts
794 bool bHasAsian =
795 xFont->hasGlyphs( OUString( u'\x3041' ) ) || // 3040-309F: Hiragana
796 xFont->hasGlyphs( OUString( u'\x30A1' ) ) || // 30A0-30FF: Katakana
797 xFont->hasGlyphs( OUString( u'\x3111' ) ) || // 3100-312F: Bopomofo
798 xFont->hasGlyphs( OUString( u'\x3131' ) ) || // 3130-318F: Hangul Compatibility Jamo
799 xFont->hasGlyphs( OUString( u'\x3301' ) ) || // 3300-33FF: CJK Compatibility
800 xFont->hasGlyphs( OUString( u'\x3401' ) ) || // 3400-4DBF: CJK Unified Ideographs Extension A
801 xFont->hasGlyphs( OUString( u'\x4E01' ) ) || // 4E00-9FFF: CJK Unified Ideographs
802 xFont->hasGlyphs( OUString( u'\x7E01' ) ) || // 4E00-9FFF: CJK Unified Ideographs
803 xFont->hasGlyphs( OUString( u'\xA001' ) ) || // A001-A48F: Yi Syllables
804 xFont->hasGlyphs( OUString( u'\xAC01' ) ) || // AC00-D7AF: Hangul Syllables
805 xFont->hasGlyphs( OUString( u'\xCC01' ) ) || // AC00-D7AF: Hangul Syllables
806 xFont->hasGlyphs( OUString( u'\xF901' ) ) || // F900-FAFF: CJK Compatibility Ideographs
807 xFont->hasGlyphs( OUString( u'\xFF71' ) ); // FF00-FFEF: Halfwidth/Fullwidth Forms
808 // #113783# CTL fonts
809 bool bHasCmplx =
810 xFont->hasGlyphs( OUString( u'\x05D1' ) ) || // 0590-05FF: Hebrew
811 xFont->hasGlyphs( OUString( u'\x0631' ) ) || // 0600-06FF: Arabic
812 xFont->hasGlyphs( OUString( u'\x0721' ) ) || // 0700-074F: Syriac
813 xFont->hasGlyphs( OUString( u'\x0911' ) ) || // 0900-0DFF: Indic scripts
814 xFont->hasGlyphs( OUString( u'\x0E01' ) ) || // 0E00-0E7F: Thai
815 xFont->hasGlyphs( OUString( u'\xFB21' ) ) || // FB1D-FB4F: Hebrew Presentation Forms
816 xFont->hasGlyphs( OUString( u'\xFB51' ) ) || // FB50-FDFF: Arabic Presentation Forms-A
817 xFont->hasGlyphs( OUString( u'\xFE71' ) ); // FE70-FEFF: Arabic Presentation Forms-B
818 // Western fonts
819 bool bHasLatin =
820 (!bHasAsian && !bHasCmplx) ||
821 xFont->hasGlyphs( OUString( 'A' ) );
822
823 lclSetFontName( maApiData.maLatinFont, maApiData.maDesc, bHasLatin );
824 lclSetFontName( maApiData.maAsianFont, maApiData.maDesc, bHasAsian );
825 lclSetFontName( maApiData.maCmplxFont, maApiData.maDesc, bHasCmplx );
826 }
827 }
828 }
829 }
830
needsRichTextFormat() const831 bool Font::needsRichTextFormat() const
832 {
833 return maApiData.mnEscapement != API_ESCAPE_NONE;
834 }
835
lcl_getFontFamily(sal_Int32 nFamily)836 static ::FontFamily lcl_getFontFamily( sal_Int32 nFamily )
837 {
838 ::FontFamily eScFamily = FAMILY_DONTKNOW;
839 switch( nFamily )
840 {
841 case css::awt::FontFamily::DONTKNOW:
842 eScFamily = FAMILY_DONTKNOW;
843 break;
844 case css::awt::FontFamily::ROMAN:
845 eScFamily = FAMILY_ROMAN;
846 break;
847 case css::awt::FontFamily::SWISS:
848 eScFamily = FAMILY_SWISS;
849 break;
850 case css::awt::FontFamily::MODERN:
851 eScFamily = FAMILY_MODERN;
852 break;
853 case css::awt::FontFamily::SCRIPT:
854 eScFamily = FAMILY_SCRIPT;
855 break;
856 case css::awt::FontFamily::DECORATIVE:
857 eScFamily = FAMILY_DECORATIVE;
858 break;
859 }
860 return eScFamily;
861 }
862
fillToItemSet(SfxItemSet & rItemSet,bool bEditEngineText,bool bSkipPoolDefs) const863 void Font::fillToItemSet( SfxItemSet& rItemSet, bool bEditEngineText, bool bSkipPoolDefs ) const
864 {
865 if ( maUsedFlags.mbNameUsed )
866 {
867 if( !maApiData.maLatinFont.maName.isEmpty() )
868 {
869 rtl_TextEncoding eFontEnc = maApiData.maLatinFont.mnTextEnc;
870 // taken from binary importer
871 rtl_TextEncoding eTempTextEnc = (bEditEngineText && (eFontEnc == getTextEncoding())) ?
872 ScfTools::GetSystemTextEncoding() : eFontEnc;
873
874 SvxFontItem aFontItem( lcl_getFontFamily( maApiData.maLatinFont.mnFamily ), maApiData.maLatinFont.maName, OUString(),
875 PITCH_DONTKNOW, eTempTextEnc, ATTR_FONT );
876 ScfTools::PutItem( rItemSet, aFontItem, bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_FONTINFO) : ATTR_FONT, bSkipPoolDefs );
877 }
878 if( !maApiData.maAsianFont.maName.isEmpty() )
879 {
880 rtl_TextEncoding eFontEnc = maApiData.maAsianFont.mnTextEnc;
881 // taken from binary importer
882 rtl_TextEncoding eTempTextEnc = (bEditEngineText && (eFontEnc == getTextEncoding())) ?
883 ScfTools::GetSystemTextEncoding() : eFontEnc;
884 SvxFontItem aFontItem( lcl_getFontFamily( maApiData.maAsianFont.mnFamily ), maApiData.maAsianFont.maName, OUString(),
885 PITCH_DONTKNOW, eTempTextEnc, ATTR_FONT );
886 ScfTools::PutItem( rItemSet, aFontItem, bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_FONTINFO_CJK) : ATTR_CJK_FONT, bSkipPoolDefs );
887 }
888 if( !maApiData.maCmplxFont.maName.isEmpty() )
889 {
890 rtl_TextEncoding eFontEnc = maApiData.maCmplxFont.mnTextEnc;
891 // taken from binary importer
892 rtl_TextEncoding eTempTextEnc = (bEditEngineText && (eFontEnc == getTextEncoding())) ?
893 ScfTools::GetSystemTextEncoding() : eFontEnc;
894 SvxFontItem aFontItem( lcl_getFontFamily( maApiData.maCmplxFont.mnFamily ), maApiData.maCmplxFont.maName, OUString(),
895 PITCH_DONTKNOW, eTempTextEnc, ATTR_FONT );
896 ScfTools::PutItem( rItemSet, aFontItem, bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_FONTINFO_CTL) : ATTR_CTL_FONT, bSkipPoolDefs );
897 }
898 }
899 // font height
900 if( maUsedFlags.mbHeightUsed )
901 {
902 sal_Int32 nHeight = maApiData.maDesc.Height;
903 // do we use XclFontItemType::HeaderFooter ( or is it just relevant for the binary filter )
904 if( bEditEngineText/* && (eType != XclFontItemType::HeaderFooter) */) // do not convert header/footer height
905 nHeight = (nHeight * 127 + 36) / EXC_POINTS_PER_INCH; // 1 in == 72 pt
906 SvxFontHeightItem aHeightItem( nHeight, 100, ATTR_FONT_HEIGHT );
907 ScfTools::PutItem( rItemSet, aHeightItem, bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_FONTHEIGHT) : ATTR_FONT_HEIGHT, bSkipPoolDefs );
908 ScfTools::PutItem( rItemSet, aHeightItem, bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_FONTHEIGHT_CJK) : ATTR_CJK_FONT_HEIGHT, bSkipPoolDefs );
909 ScfTools::PutItem( rItemSet, aHeightItem, bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_FONTHEIGHT_CTL) : ATTR_CTL_FONT_HEIGHT, bSkipPoolDefs );
910 }
911 // font weight
912 if( maUsedFlags.mbWeightUsed )
913 {
914 ::FontWeight fWeight = vcl::unohelper::ConvertFontWeight( maApiData.maDesc.Weight );
915 SvxWeightItem aWeightItem( fWeight, ATTR_FONT_WEIGHT );
916 ScfTools::PutItem( rItemSet, aWeightItem, bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_WEIGHT) : ATTR_FONT_WEIGHT, bSkipPoolDefs );
917 ScfTools::PutItem( rItemSet, aWeightItem, bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_WEIGHT_CTL) : ATTR_CTL_FONT_WEIGHT, bSkipPoolDefs );
918 ScfTools::PutItem( rItemSet, aWeightItem, bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_WEIGHT_CJK) : ATTR_CJK_FONT_WEIGHT, bSkipPoolDefs );
919 }
920 // font posture
921 if( maUsedFlags.mbPostureUsed )
922 {
923 SvxPostureItem aPostItem( ( maApiData.maDesc.Slant == css::awt::FontSlant_ITALIC ) ? ITALIC_NORMAL : ITALIC_NONE, ATTR_FONT_POSTURE);
924 ScfTools::PutItem( rItemSet, aPostItem, bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_ITALIC) : ATTR_FONT_POSTURE, bSkipPoolDefs );
925 ScfTools::PutItem( rItemSet, aPostItem, bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_ITALIC_CJK) : ATTR_CJK_FONT_POSTURE, bSkipPoolDefs );
926 ScfTools::PutItem( rItemSet, aPostItem, bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_ITALIC_CTL) : ATTR_CTL_FONT_POSTURE, bSkipPoolDefs );
927 }
928 // character color
929 if( maUsedFlags.mbColorUsed )
930 {
931 ScfTools::PutItem( rItemSet,SvxColorItem( maApiData.mnColor, bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_COLOR) : ATTR_FONT_COLOR), bSkipPoolDefs );
932 }
933 // underline style
934 if( maUsedFlags.mbUnderlineUsed )
935 {
936 FontLineStyle eScUnderl;
937 if ( maApiData.maDesc.Underline == css::awt::FontUnderline::DOUBLE )
938 eScUnderl = LINESTYLE_DOUBLE;
939 else if ( maApiData.maDesc.Underline == css::awt::FontUnderline::SINGLE )
940 eScUnderl = LINESTYLE_SINGLE;
941 else
942 eScUnderl = LINESTYLE_NONE;
943 SvxUnderlineItem aUnderlItem( eScUnderl, ATTR_FONT_UNDERLINE );
944 ScfTools::PutItem( rItemSet, aUnderlItem, bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_UNDERLINE) : ATTR_FONT_UNDERLINE, bSkipPoolDefs );
945 }
946 // strike out style
947 if( maUsedFlags.mbStrikeoutUsed )
948 {
949 ScfTools::PutItem( rItemSet, SvxCrossedOutItem( maModel.mbStrikeout ? STRIKEOUT_SINGLE : STRIKEOUT_NONE, bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_STRIKEOUT) : ATTR_FONT_CROSSEDOUT ), bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_STRIKEOUT) : ATTR_FONT_CROSSEDOUT, bSkipPoolDefs );
950 }
951
952 // outline style
953 if( maUsedFlags.mbOutlineUsed )
954 {
955 ScfTools::PutItem( rItemSet, SvxContourItem( maApiData.mbOutline, ATTR_FONT_CONTOUR ), bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_OUTLINE) : ATTR_FONT_CONTOUR, bSkipPoolDefs );
956 }
957
958 // shadow style
959 if( maUsedFlags.mbShadowUsed )
960 {
961 ScfTools::PutItem( rItemSet, SvxShadowedItem( maApiData.mbShadow, ATTR_FONT_SHADOWED ), bEditEngineText ? static_cast<sal_uInt16>(EE_CHAR_SHADOW) : ATTR_FONT_SHADOWED, bSkipPoolDefs );
962 }
963 if( maUsedFlags.mbEscapementUsed )
964 {
965 SvxEscapement eScEscapem = SvxEscapement::Off;
966 if ( maApiData.mnEscapement == API_ESCAPE_SUPERSCRIPT )
967 eScEscapem = SvxEscapement::Superscript;
968 else if ( maApiData.mnEscapement == API_ESCAPE_SUBSCRIPT )
969 eScEscapem = SvxEscapement::Subscript;
970 if( bEditEngineText )
971 {
972 // #TODO handle EscapementHeight
973 rItemSet.Put( SvxEscapementItem( eScEscapem, EE_CHAR_ESCAPEMENT ) );
974 }
975 }
976 }
977
writeToPropertyMap(PropertyMap & rPropMap) const978 void Font::writeToPropertyMap( PropertyMap& rPropMap ) const
979 {
980 // font name properties
981 if( maUsedFlags.mbNameUsed )
982 {
983 if( !maApiData.maLatinFont.maName.isEmpty() )
984 {
985 rPropMap.setProperty( PROP_CharFontName, maApiData.maLatinFont.maName);
986 rPropMap.setProperty( PROP_CharFontFamily, maApiData.maLatinFont.mnFamily);
987 rPropMap.setProperty( PROP_CharFontCharSet, maApiData.maLatinFont.mnTextEnc);
988 }
989 if( !maApiData.maAsianFont.maName.isEmpty() )
990 {
991 rPropMap.setProperty( PROP_CharFontNameAsian, maApiData.maAsianFont.maName);
992 rPropMap.setProperty( PROP_CharFontFamilyAsian, maApiData.maAsianFont.mnFamily);
993 rPropMap.setProperty( PROP_CharFontCharSetAsian, maApiData.maAsianFont.mnTextEnc);
994 }
995 if( !maApiData.maCmplxFont.maName.isEmpty() )
996 {
997 rPropMap.setProperty( PROP_CharFontNameComplex, maApiData.maCmplxFont.maName);
998 rPropMap.setProperty( PROP_CharFontFamilyComplex, maApiData.maCmplxFont.mnFamily);
999 rPropMap.setProperty( PROP_CharFontCharSetComplex, maApiData.maCmplxFont.mnTextEnc);
1000 }
1001 }
1002 // font height
1003 if( maUsedFlags.mbHeightUsed )
1004 {
1005 float fHeight = static_cast< float >( maApiData.maDesc.Height / 20.0 ); // twips to points
1006 rPropMap.setProperty( PROP_CharHeight, fHeight);
1007 rPropMap.setProperty( PROP_CharHeightAsian, fHeight);
1008 rPropMap.setProperty( PROP_CharHeightComplex, fHeight);
1009 }
1010 // font weight
1011 if( maUsedFlags.mbWeightUsed )
1012 {
1013 float fWeight = maApiData.maDesc.Weight;
1014 rPropMap.setProperty( PROP_CharWeight, fWeight);
1015 rPropMap.setProperty( PROP_CharWeightAsian, fWeight);
1016 rPropMap.setProperty( PROP_CharWeightComplex, fWeight);
1017 }
1018 // font posture
1019 if( maUsedFlags.mbPostureUsed )
1020 {
1021 rPropMap.setProperty( PROP_CharPosture, maApiData.maDesc.Slant);
1022 rPropMap.setProperty( PROP_CharPostureAsian, maApiData.maDesc.Slant);
1023 rPropMap.setProperty( PROP_CharPostureComplex, maApiData.maDesc.Slant);
1024 }
1025 // character color
1026 if( maUsedFlags.mbColorUsed )
1027 rPropMap.setProperty( PROP_CharColor, maApiData.mnColor);
1028 // underline style
1029 if( maUsedFlags.mbUnderlineUsed )
1030 rPropMap.setProperty( PROP_CharUnderline, maApiData.maDesc.Underline);
1031 // strike out style
1032 if( maUsedFlags.mbStrikeoutUsed )
1033 rPropMap.setProperty( PROP_CharStrikeout, maApiData.maDesc.Strikeout);
1034 // outline style
1035 if( maUsedFlags.mbOutlineUsed )
1036 rPropMap.setProperty( PROP_CharContoured, maApiData.mbOutline);
1037 // shadow style
1038 if( maUsedFlags.mbShadowUsed )
1039 rPropMap.setProperty( PROP_CharShadowed, maApiData.mbShadow);
1040 // escapement
1041 if( maUsedFlags.mbEscapementUsed )
1042 {
1043 rPropMap.setProperty( PROP_CharEscapement, maApiData.mnEscapement);
1044 rPropMap.setProperty( PROP_CharEscapementHeight, maApiData.mnEscapeHeight);
1045 }
1046 }
1047
writeToPropertySet(PropertySet & rPropSet) const1048 void Font::writeToPropertySet( PropertySet& rPropSet ) const
1049 {
1050 PropertyMap aPropMap;
1051 writeToPropertyMap( aPropMap );
1052 rPropSet.setProperties( aPropMap );
1053 }
1054
AlignmentModel()1055 AlignmentModel::AlignmentModel() :
1056 mnHorAlign( XML_general ),
1057 mnVerAlign( XML_bottom ),
1058 mnTextDir( OOX_XF_TEXTDIR_CONTEXT ),
1059 mnRotation( OOX_XF_ROTATION_NONE ),
1060 mnIndent( OOX_XF_INDENT_NONE ),
1061 mbWrapText( false ),
1062 mbShrink( false ),
1063 mbJustLastLine( false )
1064 {
1065 }
1066
setBiffHorAlign(sal_uInt8 nHorAlign)1067 void AlignmentModel::setBiffHorAlign( sal_uInt8 nHorAlign )
1068 {
1069 static const sal_Int32 spnHorAligns[] = {
1070 XML_general, XML_left, XML_center, XML_right,
1071 XML_fill, XML_justify, XML_centerContinuous, XML_distributed };
1072 mnHorAlign = STATIC_ARRAY_SELECT( spnHorAligns, nHorAlign, XML_general );
1073 }
1074
setBiffVerAlign(sal_uInt8 nVerAlign)1075 void AlignmentModel::setBiffVerAlign( sal_uInt8 nVerAlign )
1076 {
1077 static const sal_Int32 spnVerAligns[] = {
1078 XML_top, XML_center, XML_bottom, XML_justify, XML_distributed };
1079 mnVerAlign = STATIC_ARRAY_SELECT( spnVerAligns, nVerAlign, XML_bottom );
1080 }
1081
ApiAlignmentData()1082 ApiAlignmentData::ApiAlignmentData() :
1083 meHorJustify( css::table::CellHoriJustify_STANDARD ),
1084 mnHorJustifyMethod( css::table::CellJustifyMethod::AUTO ),
1085 mnVerJustify( css::table::CellVertJustify2::STANDARD ),
1086 mnVerJustifyMethod( css::table::CellJustifyMethod::AUTO ),
1087 meOrientation( css::table::CellOrientation_STANDARD ),
1088 mnRotation( 0 ),
1089 mnWritingMode( css::text::WritingMode2::PAGE ),
1090 mnIndent( 0 ),
1091 mbWrapText( false ),
1092 mbShrink( false )
1093 {
1094 }
1095
operator ==(const ApiAlignmentData & rLeft,const ApiAlignmentData & rRight)1096 bool operator==( const ApiAlignmentData& rLeft, const ApiAlignmentData& rRight )
1097 {
1098 return
1099 (rLeft.meHorJustify == rRight.meHorJustify) &&
1100 (rLeft.mnHorJustifyMethod == rRight.mnHorJustifyMethod) &&
1101 (rLeft.mnVerJustify == rRight.mnVerJustify) &&
1102 (rLeft.mnVerJustifyMethod == rRight.mnVerJustifyMethod) &&
1103 (rLeft.meOrientation == rRight.meOrientation) &&
1104 (rLeft.mnRotation == rRight.mnRotation) &&
1105 (rLeft.mnWritingMode == rRight.mnWritingMode) &&
1106 (rLeft.mnIndent == rRight.mnIndent) &&
1107 (rLeft.mbWrapText == rRight.mbWrapText) &&
1108 (rLeft.mbShrink == rRight.mbShrink);
1109 }
1110
Alignment(const WorkbookHelper & rHelper)1111 Alignment::Alignment( const WorkbookHelper& rHelper ) :
1112 WorkbookHelper( rHelper )
1113 {
1114 }
1115
importAlignment(const AttributeList & rAttribs)1116 void Alignment::importAlignment( const AttributeList& rAttribs )
1117 {
1118 maModel.mnVerAlign = rAttribs.getToken( XML_vertical, XML_bottom );
1119 maModel.mnTextDir = rAttribs.getInteger( XML_readingOrder, OOX_XF_TEXTDIR_CONTEXT );
1120 maModel.mnRotation = rAttribs.getInteger( XML_textRotation, OOX_XF_ROTATION_NONE );
1121 sal_Int32 nDefaultHorAlign = XML_general;
1122 if (maModel.mnRotation != OOX_XF_ROTATION_NONE)
1123 {
1124 if (maModel.mnRotation < 90 || maModel.mnRotation == 180)
1125 {
1126 nDefaultHorAlign = XML_left;
1127 }
1128 else
1129 {
1130 nDefaultHorAlign = XML_right;
1131 }
1132 }
1133 maModel.mnHorAlign = rAttribs.getToken( XML_horizontal, nDefaultHorAlign );
1134 maModel.mnIndent = rAttribs.getInteger( XML_indent, OOX_XF_INDENT_NONE );
1135 maModel.mbWrapText = rAttribs.getBool( XML_wrapText, false );
1136 maModel.mbShrink = rAttribs.getBool( XML_shrinkToFit, false );
1137 maModel.mbJustLastLine = rAttribs.getBool( XML_justifyLastLine, false );
1138 }
1139
setBiff12Data(sal_uInt32 nFlags)1140 void Alignment::setBiff12Data( sal_uInt32 nFlags )
1141 {
1142 maModel.setBiffHorAlign( extractValue< sal_uInt8 >( nFlags, 16, 3 ) );
1143 maModel.setBiffVerAlign( extractValue< sal_uInt8 >( nFlags, 19, 3 ) );
1144 maModel.mnTextDir = extractValue< sal_Int32 >( nFlags, 26, 2 );
1145 maModel.mnRotation = extractValue< sal_Int32 >( nFlags, 0, 8 );
1146 maModel.mnIndent = extractValue< sal_uInt8 >( nFlags, 8, 8 );
1147 maModel.mbWrapText = getFlag( nFlags, BIFF12_XF_WRAPTEXT );
1148 maModel.mbShrink = getFlag( nFlags, BIFF12_XF_SHRINK );
1149 maModel.mbJustLastLine = getFlag( nFlags, BIFF12_XF_JUSTLASTLINE );
1150 }
1151
finalizeImport()1152 void Alignment::finalizeImport()
1153 {
1154 // horizontal alignment
1155 switch( maModel.mnHorAlign )
1156 {
1157 case XML_center: maApiData.meHorJustify = css::table::CellHoriJustify_CENTER; break;
1158 case XML_centerContinuous: maApiData.meHorJustify = css::table::CellHoriJustify_CENTER; break;
1159 case XML_distributed: maApiData.meHorJustify = css::table::CellHoriJustify_BLOCK; break;
1160 case XML_fill: maApiData.meHorJustify = css::table::CellHoriJustify_REPEAT; break;
1161 case XML_general: maApiData.meHorJustify = css::table::CellHoriJustify_STANDARD; break;
1162 case XML_justify: maApiData.meHorJustify = css::table::CellHoriJustify_BLOCK; break;
1163 case XML_left: maApiData.meHorJustify = css::table::CellHoriJustify_LEFT; break;
1164 case XML_right: maApiData.meHorJustify = css::table::CellHoriJustify_RIGHT; break;
1165 }
1166
1167 if (maModel.mnHorAlign == XML_distributed)
1168 maApiData.mnHorJustifyMethod = css::table::CellJustifyMethod::DISTRIBUTE;
1169
1170 // vertical alignment
1171 switch( maModel.mnVerAlign )
1172 {
1173 case XML_bottom: maApiData.mnVerJustify = css::table::CellVertJustify2::BOTTOM; break;
1174 case XML_center: maApiData.mnVerJustify = css::table::CellVertJustify2::CENTER; break;
1175 case XML_distributed: maApiData.mnVerJustify = css::table::CellVertJustify2::BLOCK; break;
1176 case XML_justify: maApiData.mnVerJustify = css::table::CellVertJustify2::BLOCK; break;
1177 case XML_top: maApiData.mnVerJustify = css::table::CellVertJustify2::TOP; break;
1178 }
1179
1180 if (maModel.mnVerAlign == XML_distributed)
1181 maApiData.mnVerJustifyMethod = css::table::CellJustifyMethod::DISTRIBUTE;
1182
1183 /* indentation: expressed as number of blocks of 3 space characters in
1184 OOXML. */
1185 sal_Int32 nIndent = getUnitConverter().scaleToMm100( 3.0 * maModel.mnIndent, Unit::Space );
1186 if( (0 <= nIndent) && (nIndent <= SAL_MAX_INT16) )
1187 maApiData.mnIndent = static_cast< sal_Int16 >( nIndent );
1188
1189 // complex text direction
1190 switch( maModel.mnTextDir )
1191 {
1192 case OOX_XF_TEXTDIR_CONTEXT: maApiData.mnWritingMode = css::text::WritingMode2::PAGE; break;
1193 case OOX_XF_TEXTDIR_LTR: maApiData.mnWritingMode = css::text::WritingMode2::LR_TB; break;
1194 case OOX_XF_TEXTDIR_RTL: maApiData.mnWritingMode = css::text::WritingMode2::RL_TB; break;
1195 }
1196
1197 // rotation: 0-90 means 0 to 90 degrees ccw, 91-180 means 1 to 90 degrees cw, 255 means stacked
1198 sal_Int32 nOoxRot = maModel.mnRotation;
1199 maApiData.mnRotation = ((0 <= nOoxRot) && (nOoxRot <= 90)) ?
1200 (100 * nOoxRot) :
1201 (((91 <= nOoxRot) && (nOoxRot <= 180)) ? (100 * (450 - nOoxRot)) : 0);
1202
1203 // "Orientation" property used for character stacking
1204 maApiData.meOrientation = (nOoxRot == OOX_XF_ROTATION_STACKED) ?
1205 css::table::CellOrientation_STACKED : css::table::CellOrientation_STANDARD;
1206
1207 // alignment flags (#i84960 automatic line break, if vertically justified/distributed)
1208 maApiData.mbWrapText = maModel.mbWrapText || (maModel.mnVerAlign == XML_distributed) || (maModel.mnVerAlign == XML_justify);
1209 maApiData.mbShrink = maModel.mbShrink;
1210
1211 }
1212
GetScVerAlign() const1213 ::SvxCellVerJustify Alignment::GetScVerAlign() const
1214 {
1215 ::SvxCellVerJustify nVert = ::SvxCellVerJustify::Standard;
1216 switch ( maApiData.mnVerJustify )
1217 {
1218 case css::table::CellVertJustify2::BOTTOM:
1219 nVert = ::SvxCellVerJustify::Bottom;
1220 break;
1221 case css::table::CellVertJustify2::CENTER:
1222 nVert = ::SvxCellVerJustify::Center;
1223 break;
1224 case css::table::CellVertJustify2::TOP:
1225 nVert = ::SvxCellVerJustify::Top;
1226 break;
1227 case css::table::CellVertJustify2::BLOCK:
1228 nVert = ::SvxCellVerJustify::Block;
1229 break;
1230 case css::table::CellVertJustify2::STANDARD:
1231 default:
1232 nVert = ::SvxCellVerJustify::Standard;
1233 break;
1234 }
1235 return nVert;
1236 }
1237
GetScHorAlign() const1238 ::SvxCellHorJustify Alignment::GetScHorAlign() const
1239 {
1240 ::SvxCellHorJustify nHori = ::SvxCellHorJustify::Standard;
1241 switch( maApiData.meHorJustify )
1242 {
1243 case css::table::CellHoriJustify_LEFT:
1244 nHori = ::SvxCellHorJustify::Left;
1245 break;
1246 case css::table::CellHoriJustify_CENTER:
1247 nHori = ::SvxCellHorJustify::Center;
1248 break;
1249 case css::table::CellHoriJustify_RIGHT:
1250 nHori = ::SvxCellHorJustify::Right;
1251 break;
1252 case css::table::CellHoriJustify_BLOCK:
1253 nHori = ::SvxCellHorJustify::Block;
1254 break;
1255 case css::table::CellHoriJustify_REPEAT:
1256 nHori = ::SvxCellHorJustify::Repeat;
1257 break;
1258 case css::table::CellHoriJustify_STANDARD:
1259 default:
1260 nHori = ::SvxCellHorJustify::Standard;
1261 break;
1262 }
1263 return nHori;
1264 }
1265
GetScFrameDir() const1266 SvxFrameDirection Alignment::GetScFrameDir() const
1267 {
1268 SvxFrameDirection eFrameDir = SvxFrameDirection::Environment;
1269 switch( maApiData.mnWritingMode )
1270 {
1271 case css::text::WritingMode2::PAGE:
1272 eFrameDir = SvxFrameDirection::Environment;
1273 break;
1274 case css::text::WritingMode2::LR_TB:
1275 eFrameDir = SvxFrameDirection::Horizontal_LR_TB;
1276 break;
1277 case css::text::WritingMode2::RL_TB:
1278 eFrameDir = SvxFrameDirection::Horizontal_RL_TB;
1279 break;
1280 default:
1281 OSL_FAIL( "GetScFrameDir - unknown CTL text direction" );
1282 }
1283 return eFrameDir;
1284 }
1285
fillToItemSet(SfxItemSet & rItemSet,bool bSkipPoolDefs) const1286 void Alignment::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
1287 {
1288 // horizontal alignment
1289 ScfTools::PutItem( rItemSet, SvxHorJustifyItem( GetScHorAlign(), ATTR_HOR_JUSTIFY ), bSkipPoolDefs );
1290 ScfTools::PutItem( rItemSet, SvxJustifyMethodItem( ( maApiData.mnHorJustifyMethod == css::table::CellJustifyMethod::DISTRIBUTE ) ? ::SvxCellJustifyMethod::Distribute : ::SvxCellJustifyMethod::Auto, ATTR_HOR_JUSTIFY_METHOD ), bSkipPoolDefs );
1291 ScfTools::PutItem( rItemSet, SvxVerJustifyItem( GetScVerAlign(), ATTR_VER_JUSTIFY ), bSkipPoolDefs );
1292 // vertical alignment
1293 ScfTools::PutItem( rItemSet, SvxJustifyMethodItem( ( maApiData.mnVerJustifyMethod == css::table::CellJustifyMethod::DISTRIBUTE ) ? ::SvxCellJustifyMethod::Distribute : ::SvxCellJustifyMethod::Auto, ATTR_VER_JUSTIFY_METHOD ), bSkipPoolDefs );
1294
1295 // CTL text direction
1296 ScfTools::PutItem( rItemSet, SvxFrameDirectionItem( GetScFrameDir(), ATTR_WRITINGDIR ), bSkipPoolDefs );
1297 // set an angle in the range from -90 to 90 degrees
1298 ScfTools::PutItem( rItemSet, SfxInt32Item( ATTR_ROTATE_VALUE, maApiData.mnRotation ), bSkipPoolDefs );
1299 // Orientation
1300 ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_STACKED, maApiData.meOrientation == css::table::CellOrientation_STACKED ), bSkipPoolDefs );
1301 // indent
1302 ScfTools::PutItem( rItemSet, SfxUInt16Item( ATTR_INDENT, maApiData.mnIndent ), bSkipPoolDefs );
1303 // line wrap
1304 ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_LINEBREAK, maApiData.mbWrapText ), bSkipPoolDefs );
1305 ScfTools::PutItem( rItemSet, SfxBoolItem( ATTR_SHRINKTOFIT, maApiData.mbShrink ), bSkipPoolDefs );
1306 }
1307
ProtectionModel()1308 ProtectionModel::ProtectionModel() :
1309 mbLocked( true ), // default in Excel and Calc
1310 mbHidden( false )
1311 {
1312 }
1313
ApiProtectionData()1314 ApiProtectionData::ApiProtectionData() :
1315 maCellProt( true, false, false, false )
1316 {
1317 }
1318
operator ==(const ApiProtectionData & rLeft,const ApiProtectionData & rRight)1319 bool operator==( const ApiProtectionData& rLeft, const ApiProtectionData& rRight )
1320 {
1321 return
1322 (rLeft.maCellProt.IsLocked == rRight.maCellProt.IsLocked) &&
1323 (rLeft.maCellProt.IsFormulaHidden == rRight.maCellProt.IsFormulaHidden) &&
1324 (rLeft.maCellProt.IsHidden == rRight.maCellProt.IsHidden) &&
1325 (rLeft.maCellProt.IsPrintHidden == rRight.maCellProt.IsPrintHidden);
1326 }
1327
Protection(const WorkbookHelper & rHelper)1328 Protection::Protection( const WorkbookHelper& rHelper ) :
1329 WorkbookHelper( rHelper )
1330 {
1331 }
1332
importProtection(const AttributeList & rAttribs)1333 void Protection::importProtection( const AttributeList& rAttribs )
1334 {
1335 maModel.mbLocked = rAttribs.getBool( XML_locked, true );
1336 maModel.mbHidden = rAttribs.getBool( XML_hidden, false );
1337 }
1338
setBiff12Data(sal_uInt32 nFlags)1339 void Protection::setBiff12Data( sal_uInt32 nFlags )
1340 {
1341 maModel.mbLocked = getFlag( nFlags, BIFF12_XF_LOCKED );
1342 maModel.mbHidden = getFlag( nFlags, BIFF12_XF_HIDDEN );
1343 }
1344
finalizeImport()1345 void Protection::finalizeImport()
1346 {
1347 maApiData.maCellProt.IsLocked = maModel.mbLocked;
1348 maApiData.maCellProt.IsFormulaHidden = maModel.mbHidden;
1349 }
1350
fillToItemSet(SfxItemSet & rItemSet,bool bSkipPoolDefs) const1351 void Protection::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
1352 {
1353 ScfTools::PutItem( rItemSet, ScProtectionAttr( maApiData.maCellProt.IsLocked, maApiData.maCellProt.IsFormulaHidden ), bSkipPoolDefs );
1354 }
1355
1356 namespace {
1357
lcl_isBorder(const css::table::BorderLine & rBorder)1358 bool lcl_isBorder(const css::table::BorderLine& rBorder)
1359 {
1360 return (rBorder.InnerLineWidth > 0) || (rBorder.OuterLineWidth > 0);
1361 }
1362
1363 }
1364
BorderLineModel(bool bDxf)1365 BorderLineModel::BorderLineModel( bool bDxf ) :
1366 mnStyle( XML_none ),
1367 mbUsed( !bDxf )
1368 {
1369 maColor.setIndexed( OOX_COLOR_WINDOWTEXT );
1370 }
1371
setBiffStyle(sal_Int32 nLineStyle)1372 void BorderLineModel::setBiffStyle( sal_Int32 nLineStyle )
1373 {
1374 static const sal_Int32 spnStyleIds[] = {
1375 XML_none, XML_thin, XML_medium, XML_dashed,
1376 XML_dotted, XML_thick, XML_double, XML_hair,
1377 XML_mediumDashed, XML_dashDot, XML_mediumDashDot, XML_dashDotDot,
1378 XML_mediumDashDotDot, XML_slantDashDot };
1379 mnStyle = STATIC_ARRAY_SELECT( spnStyleIds, nLineStyle, XML_none );
1380 }
1381
BorderModel(bool bDxf)1382 BorderModel::BorderModel( bool bDxf ) :
1383 maLeft( bDxf ),
1384 maRight( bDxf ),
1385 maTop( bDxf ),
1386 maBottom( bDxf ),
1387 maDiagonal( bDxf ),
1388 mbDiagTLtoBR( false ),
1389 mbDiagBLtoTR( false )
1390 {
1391 }
1392
ApiBorderData()1393 ApiBorderData::ApiBorderData() :
1394 mbBorderUsed( false ),
1395 mbDiagUsed( false )
1396 {
1397 }
1398
hasAnyOuterBorder() const1399 bool ApiBorderData::hasAnyOuterBorder() const
1400 {
1401 return
1402 ( lcl_isBorder( maTop ) && maTop.OuterLineWidth > 0 ) ||
1403 ( lcl_isBorder( maBottom ) && maBottom.OuterLineWidth > 0 ) ||
1404 ( lcl_isBorder( maLeft ) && maLeft.OuterLineWidth > 0 ) ||
1405 ( lcl_isBorder( maRight ) && maRight.OuterLineWidth > 0 );
1406 }
1407
1408 namespace {
1409
lclSetBorderLineWidth(BorderLine & rBorderLine,sal_Int16 nOuter,sal_Int16 nDist=API_LINE_NONE,sal_Int16 nInner=API_LINE_NONE)1410 void lclSetBorderLineWidth( BorderLine& rBorderLine,
1411 sal_Int16 nOuter, sal_Int16 nDist = API_LINE_NONE, sal_Int16 nInner = API_LINE_NONE )
1412 {
1413 rBorderLine.OuterLineWidth = nOuter;
1414 rBorderLine.LineDistance = nDist;
1415 rBorderLine.InnerLineWidth = nInner;
1416 }
1417
1418 } // namespace
1419
Border(const WorkbookHelper & rHelper,bool bDxf)1420 Border::Border( const WorkbookHelper& rHelper, bool bDxf ) :
1421 WorkbookHelper( rHelper ),
1422 maModel( bDxf ),
1423 mbDxf( bDxf )
1424 {
1425 }
1426
importBorder(const AttributeList & rAttribs)1427 void Border::importBorder( const AttributeList& rAttribs )
1428 {
1429 maModel.mbDiagTLtoBR = rAttribs.getBool( XML_diagonalDown, false );
1430 maModel.mbDiagBLtoTR = rAttribs.getBool( XML_diagonalUp, false );
1431 }
1432
importStyle(sal_Int32 nElement,const AttributeList & rAttribs)1433 void Border::importStyle( sal_Int32 nElement, const AttributeList& rAttribs )
1434 {
1435 if( BorderLineModel* pBorderLine = getBorderLine( nElement ) )
1436 {
1437 pBorderLine->mnStyle = rAttribs.getToken( XML_style, XML_none );
1438 pBorderLine->mbUsed = true;
1439 }
1440 }
1441
importColor(sal_Int32 nElement,const AttributeList & rAttribs)1442 void Border::importColor( sal_Int32 nElement, const AttributeList& rAttribs )
1443 {
1444 if( BorderLineModel* pBorderLine = getBorderLine( nElement ) )
1445 pBorderLine->maColor.importColor( rAttribs );
1446 }
1447
importBorder(SequenceInputStream & rStrm)1448 void Border::importBorder( SequenceInputStream& rStrm )
1449 {
1450 sal_uInt8 nFlags = rStrm.readuInt8();
1451 maModel.mbDiagTLtoBR = getFlag( nFlags, BIFF12_BORDER_DIAG_TLBR );
1452 maModel.mbDiagBLtoTR = getFlag( nFlags, BIFF12_BORDER_DIAG_BLTR );
1453 maModel.maTop.setBiffStyle( rStrm.readuInt16() );
1454 rStrm >> maModel.maTop.maColor;
1455 maModel.maBottom.setBiffStyle( rStrm.readuInt16() );
1456 rStrm >> maModel.maBottom.maColor;
1457 maModel.maLeft.setBiffStyle( rStrm.readuInt16() );
1458 rStrm >> maModel.maLeft.maColor;
1459 maModel.maRight.setBiffStyle( rStrm.readuInt16() );
1460 rStrm >> maModel.maRight.maColor;
1461 maModel.maDiagonal.setBiffStyle( rStrm.readuInt16() );
1462 rStrm >> maModel.maDiagonal.maColor;
1463 }
1464
importDxfBorder(sal_Int32 nElement,SequenceInputStream & rStrm)1465 void Border::importDxfBorder( sal_Int32 nElement, SequenceInputStream& rStrm )
1466 {
1467 SAL_WARN_IF( !mbDxf, "sc", "Border::importDxfBorder - missing conditional formatting flag" );
1468 if( BorderLineModel* pBorderLine = getBorderLine( nElement ) )
1469 {
1470 sal_uInt16 nStyle;
1471 rStrm >> pBorderLine->maColor;
1472 nStyle = rStrm.readuInt16();
1473 pBorderLine->setBiffStyle( nStyle );
1474 pBorderLine->mbUsed = true;
1475 }
1476 }
1477
finalizeImport(bool bRTL)1478 void Border::finalizeImport( bool bRTL )
1479 {
1480 if ( bRTL )
1481 {
1482 BorderLineModel aTmp = maModel.maLeft;
1483 maModel.maLeft = maModel.maRight;
1484 maModel.maRight = aTmp;
1485 }
1486 maApiData.mbBorderUsed = maModel.maLeft.mbUsed || maModel.maRight.mbUsed || maModel.maTop.mbUsed || maModel.maBottom.mbUsed;
1487 maApiData.mbDiagUsed = maModel.maDiagonal.mbUsed;
1488
1489 convertBorderLine( maApiData.maLeft, maModel.maLeft );
1490 convertBorderLine( maApiData.maRight, maModel.maRight );
1491 convertBorderLine( maApiData.maTop, maModel.maTop );
1492 convertBorderLine( maApiData.maBottom, maModel.maBottom );
1493
1494 if( maModel.mbDiagTLtoBR )
1495 convertBorderLine( maApiData.maTLtoBR, maModel.maDiagonal );
1496 if( maModel.mbDiagBLtoTR )
1497 convertBorderLine( maApiData.maBLtoTR, maModel.maDiagonal );
1498 }
1499
fillToItemSet(SfxItemSet & rItemSet,bool bSkipPoolDefs) const1500 void Border::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
1501 {
1502 if( maApiData.mbBorderUsed )
1503 {
1504 SvxBoxItem aBoxItem( ATTR_BORDER );
1505 ::editeng::SvxBorderLine aLine;
1506
1507 if (SvxBoxItem::LineToSvxLine(maApiData.maLeft, aLine, false))
1508 {
1509 aBoxItem.SetLine( &aLine, SvxBoxItemLine::LEFT );
1510 }
1511 if (SvxBoxItem::LineToSvxLine(maApiData.maRight, aLine, false))
1512 {
1513 aBoxItem.SetLine( &aLine, SvxBoxItemLine::RIGHT );
1514 }
1515 if (SvxBoxItem::LineToSvxLine(maApiData.maTop, aLine, false))
1516 {
1517 aBoxItem.SetLine( &aLine, SvxBoxItemLine::TOP );
1518 }
1519 if (SvxBoxItem::LineToSvxLine(maApiData.maBottom, aLine, false))
1520 {
1521 aBoxItem.SetLine( &aLine, SvxBoxItemLine::BOTTOM );
1522 }
1523 ScfTools::PutItem( rItemSet, aBoxItem, bSkipPoolDefs );
1524 }
1525 if ( maApiData.mbDiagUsed )
1526 {
1527 SvxLineItem aTLBRItem( ATTR_BORDER_TLBR );
1528 SvxLineItem aBLTRItem( ATTR_BORDER_BLTR );
1529 ::editeng::SvxBorderLine aLine;
1530 if (SvxBoxItem::LineToSvxLine(maApiData.maTLtoBR, aLine, false))
1531 {
1532 aTLBRItem.SetLine( &aLine );
1533 }
1534 if (SvxBoxItem::LineToSvxLine(maApiData.maBLtoTR, aLine, false))
1535 {
1536 aBLTRItem.SetLine( &aLine );
1537 }
1538 ScfTools::PutItem( rItemSet, aTLBRItem, bSkipPoolDefs );
1539 ScfTools::PutItem( rItemSet, aBLTRItem, bSkipPoolDefs );
1540 }
1541 }
1542
getBorderLine(sal_Int32 nElement)1543 BorderLineModel* Border::getBorderLine( sal_Int32 nElement )
1544 {
1545 switch( nElement )
1546 {
1547 case XLS_TOKEN( left ): return &maModel.maLeft;
1548 case XLS_TOKEN( start ): return &maModel.maLeft;
1549 case XLS_TOKEN( right ): return &maModel.maRight;
1550 case XLS_TOKEN( end ): return &maModel.maRight;
1551 case XLS_TOKEN( top ): return &maModel.maTop;
1552 case XLS_TOKEN( bottom ): return &maModel.maBottom;
1553 case XLS_TOKEN( diagonal ): return &maModel.maDiagonal;
1554 }
1555 return nullptr;
1556 }
1557
convertBorderLine(BorderLine2 & rBorderLine,const BorderLineModel & rModel)1558 bool Border::convertBorderLine( BorderLine2& rBorderLine, const BorderLineModel& rModel )
1559 {
1560 // Document: sc/qa/unit/data/README.cellborders
1561
1562 rBorderLine.Color = sal_Int32(rModel.maColor.getColor( getBaseFilter().getGraphicHelper(), API_RGB_BLACK ));
1563 switch( rModel.mnStyle )
1564 {
1565 case XML_dashDot:
1566 lclSetBorderLineWidth( rBorderLine, API_LINE_THIN );
1567 rBorderLine.LineStyle = BorderLineStyle::DASH_DOT;
1568 break;
1569 case XML_dashDotDot:
1570 lclSetBorderLineWidth( rBorderLine, API_LINE_THIN );
1571 rBorderLine.LineStyle = BorderLineStyle::DASH_DOT_DOT;
1572 break;
1573 case XML_dashed:
1574 lclSetBorderLineWidth( rBorderLine, API_LINE_THIN );
1575 rBorderLine.LineStyle = BorderLineStyle::FINE_DASHED;
1576 break;
1577 case XML_dotted:
1578 lclSetBorderLineWidth( rBorderLine, API_LINE_THIN );
1579 rBorderLine.LineStyle = BorderLineStyle::DOTTED;
1580 break;
1581 case XML_double:
1582 lclSetBorderLineWidth( rBorderLine, 10, 15, 10 );
1583 rBorderLine.LineStyle = BorderLineStyle::DOUBLE_THIN;
1584 break;
1585 case XML_hair: lclSetBorderLineWidth( rBorderLine, API_LINE_HAIR ); break;
1586 case XML_medium: lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM ); break;
1587 case XML_mediumDashDot:
1588 lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM );
1589 rBorderLine.LineStyle = BorderLineStyle::DASH_DOT;
1590 break;
1591 case XML_mediumDashDotDot:
1592 lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM );
1593 rBorderLine.LineStyle = BorderLineStyle::DASH_DOT_DOT;
1594 break;
1595 case XML_mediumDashed:
1596 lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM );
1597 rBorderLine.LineStyle = BorderLineStyle::DASHED;
1598 break;
1599 case XML_none: lclSetBorderLineWidth( rBorderLine, API_LINE_NONE ); break;
1600 case XML_slantDashDot:
1601 lclSetBorderLineWidth( rBorderLine, API_LINE_MEDIUM );
1602 rBorderLine.LineStyle = BorderLineStyle::FINE_DASHED;
1603 break;
1604 case XML_thick: lclSetBorderLineWidth( rBorderLine, API_LINE_THICK ); break;
1605 case XML_thin: lclSetBorderLineWidth( rBorderLine, API_LINE_THIN ); break;
1606 default: lclSetBorderLineWidth( rBorderLine, API_LINE_NONE ); break;
1607 }
1608 return rModel.mbUsed;
1609 }
1610
PatternFillModel(bool bDxf)1611 PatternFillModel::PatternFillModel( bool bDxf ) :
1612 mnPattern( XML_none ),
1613 mbPattColorUsed( !bDxf ),
1614 mbFillColorUsed( !bDxf ),
1615 mbPatternUsed( !bDxf )
1616 {
1617 maPatternColor.setIndexed( OOX_COLOR_WINDOWTEXT );
1618 maFillColor.setIndexed( OOX_COLOR_WINDOWBACK );
1619 }
1620
setBiffPattern(sal_Int32 nPattern)1621 void PatternFillModel::setBiffPattern( sal_Int32 nPattern )
1622 {
1623 static const sal_Int32 spnPatternIds[] = {
1624 XML_none, XML_solid, XML_mediumGray, XML_darkGray,
1625 XML_lightGray, XML_darkHorizontal, XML_darkVertical, XML_darkDown,
1626 XML_darkUp, XML_darkGrid, XML_darkTrellis, XML_lightHorizontal,
1627 XML_lightVertical, XML_lightDown, XML_lightUp, XML_lightGrid,
1628 XML_lightTrellis, XML_gray125, XML_gray0625 };
1629 mnPattern = STATIC_ARRAY_SELECT( spnPatternIds, nPattern, XML_none );
1630 }
1631
GradientFillModel()1632 GradientFillModel::GradientFillModel() :
1633 mnType( XML_linear ),
1634 mfAngle( 0.0 ),
1635 mfLeft( 0.0 ),
1636 mfRight( 0.0 ),
1637 mfTop( 0.0 ),
1638 mfBottom( 0.0 )
1639 {
1640 }
1641
readGradient(SequenceInputStream & rStrm)1642 void GradientFillModel::readGradient( SequenceInputStream& rStrm )
1643 {
1644 sal_Int32 nType;
1645 nType = rStrm.readInt32();
1646 mfAngle = rStrm.readDouble();
1647 mfLeft = rStrm.readDouble();
1648 mfRight = rStrm.readDouble();
1649 mfTop = rStrm.readDouble();
1650 mfBottom = rStrm.readDouble();
1651 static const sal_Int32 spnTypes[] = { XML_linear, XML_path };
1652 mnType = STATIC_ARRAY_SELECT( spnTypes, nType, XML_TOKEN_INVALID );
1653 }
1654
readGradientStop(SequenceInputStream & rStrm,bool bDxf)1655 void GradientFillModel::readGradientStop( SequenceInputStream& rStrm, bool bDxf )
1656 {
1657 Color aColor;
1658 double fPosition;
1659 if( bDxf )
1660 {
1661 rStrm.skip( 2 );
1662 fPosition = rStrm.readDouble();
1663 rStrm >> aColor;
1664 }
1665 else
1666 {
1667 rStrm >> aColor;
1668 fPosition = rStrm.readDouble();
1669 }
1670 if( !rStrm.isEof() && (fPosition >= 0.0) )
1671 maColors[ fPosition ] = aColor;
1672 }
1673
ApiSolidFillData()1674 ApiSolidFillData::ApiSolidFillData() :
1675 mnColor( API_RGB_TRANSPARENT ),
1676 mbTransparent( true ),
1677 mbUsed( false )
1678 {
1679 }
1680
1681 namespace {
1682
lclGetMixedColorComp(sal_Int32 nPatt,sal_Int32 nFill,sal_Int32 nAlpha)1683 sal_Int32 lclGetMixedColorComp( sal_Int32 nPatt, sal_Int32 nFill, sal_Int32 nAlpha )
1684 {
1685 return ((nPatt - nFill) * nAlpha) / 0x80 + nFill;
1686 }
1687
lclGetMixedColor(::Color nPattColor,::Color nFillColor,sal_Int32 nAlpha)1688 ::Color lclGetMixedColor( ::Color nPattColor, ::Color nFillColor, sal_Int32 nAlpha )
1689 {
1690 return ::Color(
1691 lclGetMixedColorComp( nPattColor.GetRed(), nFillColor.GetRed(), nAlpha ),
1692 lclGetMixedColorComp( nPattColor.GetGreen(), nFillColor.GetGreen(), nAlpha ),
1693 lclGetMixedColorComp( nPattColor.GetBlue(), nFillColor.GetBlue(), nAlpha ) );
1694 }
1695
1696 } // namespace
1697
Fill(const WorkbookHelper & rHelper,bool bDxf)1698 Fill::Fill( const WorkbookHelper& rHelper, bool bDxf ) :
1699 WorkbookHelper( rHelper ),
1700 mbDxf( bDxf )
1701 {
1702 }
1703
importPatternFill(const AttributeList & rAttribs)1704 void Fill::importPatternFill( const AttributeList& rAttribs )
1705 {
1706 mxPatternModel.reset( new PatternFillModel( mbDxf ) );
1707 mxPatternModel->mnPattern = rAttribs.getToken( XML_patternType, XML_none );
1708 if( mbDxf )
1709 mxPatternModel->mbPatternUsed = rAttribs.hasAttribute( XML_patternType );
1710 }
1711
importFgColor(const AttributeList & rAttribs)1712 void Fill::importFgColor( const AttributeList& rAttribs )
1713 {
1714 OSL_ENSURE( mxPatternModel.get(), "Fill::importFgColor - missing pattern data" );
1715 if( mxPatternModel.get() )
1716 {
1717 mxPatternModel->maPatternColor.importColor( rAttribs );
1718 mxPatternModel->mbPattColorUsed = true;
1719 }
1720 }
1721
importBgColor(const AttributeList & rAttribs)1722 void Fill::importBgColor( const AttributeList& rAttribs )
1723 {
1724 OSL_ENSURE( mxPatternModel.get(), "Fill::importBgColor - missing pattern data" );
1725 if( mxPatternModel.get() )
1726 {
1727 mxPatternModel->maFillColor.importColor( rAttribs );
1728 mxPatternModel->mbFillColorUsed = true;
1729 }
1730 }
1731
importGradientFill(const AttributeList & rAttribs)1732 void Fill::importGradientFill( const AttributeList& rAttribs )
1733 {
1734 mxGradientModel.reset( new GradientFillModel );
1735 mxGradientModel->mnType = rAttribs.getToken( XML_type, XML_linear );
1736 mxGradientModel->mfAngle = rAttribs.getDouble( XML_degree, 0.0 );
1737 mxGradientModel->mfLeft = rAttribs.getDouble( XML_left, 0.0 );
1738 mxGradientModel->mfRight = rAttribs.getDouble( XML_right, 0.0 );
1739 mxGradientModel->mfTop = rAttribs.getDouble( XML_top, 0.0 );
1740 mxGradientModel->mfBottom = rAttribs.getDouble( XML_bottom, 0.0 );
1741 }
1742
importColor(const AttributeList & rAttribs,double fPosition)1743 void Fill::importColor( const AttributeList& rAttribs, double fPosition )
1744 {
1745 OSL_ENSURE( mxGradientModel.get(), "Fill::importColor - missing gradient data" );
1746 if( mxGradientModel.get() && (fPosition >= 0.0) )
1747 mxGradientModel->maColors[ fPosition ].importColor( rAttribs );
1748 }
1749
importFill(SequenceInputStream & rStrm)1750 void Fill::importFill( SequenceInputStream& rStrm )
1751 {
1752 SAL_WARN_IF( mbDxf, "sc", "Fill::importFill - unexpected conditional formatting flag" );
1753 sal_Int32 nPattern = rStrm.readInt32();
1754 if( nPattern == BIFF12_FILL_GRADIENT )
1755 {
1756 mxGradientModel.reset( new GradientFillModel );
1757 sal_Int32 nStopCount;
1758 rStrm.skip( 16 );
1759 mxGradientModel->readGradient( rStrm );
1760 nStopCount = rStrm.readInt32();
1761 for( sal_Int32 nStop = 0; (nStop < nStopCount) && !rStrm.isEof(); ++nStop )
1762 mxGradientModel->readGradientStop( rStrm, false );
1763 }
1764 else
1765 {
1766 mxPatternModel.reset( new PatternFillModel( mbDxf ) );
1767 mxPatternModel->setBiffPattern( nPattern );
1768 rStrm >> mxPatternModel->maPatternColor >> mxPatternModel->maFillColor;
1769 }
1770 }
1771
importDxfPattern(SequenceInputStream & rStrm)1772 void Fill::importDxfPattern( SequenceInputStream& rStrm )
1773 {
1774 SAL_WARN_IF( !mbDxf, "sc", "Fill::importDxfPattern - missing conditional formatting flag" );
1775 if( !mxPatternModel )
1776 mxPatternModel.reset( new PatternFillModel( mbDxf ) );
1777 mxPatternModel->setBiffPattern( rStrm.readuInt8() );
1778 mxPatternModel->mbPatternUsed = true;
1779 }
1780
importDxfFgColor(SequenceInputStream & rStrm)1781 void Fill::importDxfFgColor( SequenceInputStream& rStrm )
1782 {
1783 SAL_WARN_IF( !mbDxf, "sc", "Fill::importDxfFgColor - missing conditional formatting flag" );
1784 if( !mxPatternModel )
1785 mxPatternModel.reset( new PatternFillModel( mbDxf ) );
1786 mxPatternModel->maPatternColor.importColor( rStrm );
1787 mxPatternModel->mbPattColorUsed = true;
1788 }
1789
importDxfBgColor(SequenceInputStream & rStrm)1790 void Fill::importDxfBgColor( SequenceInputStream& rStrm )
1791 {
1792 SAL_WARN_IF( !mbDxf, "sc", "Fill::importDxfBgColor - missing conditional formatting flag" );
1793 if( !mxPatternModel )
1794 mxPatternModel.reset( new PatternFillModel( mbDxf ) );
1795 mxPatternModel->maFillColor.importColor( rStrm );
1796 mxPatternModel->mbFillColorUsed = true;
1797 }
1798
importDxfGradient(SequenceInputStream & rStrm)1799 void Fill::importDxfGradient( SequenceInputStream& rStrm )
1800 {
1801 SAL_WARN_IF( !mbDxf, "sc", "Fill::importDxfGradient - missing conditional formatting flag" );
1802 if( !mxGradientModel )
1803 mxGradientModel.reset( new GradientFillModel );
1804 mxGradientModel->readGradient( rStrm );
1805 }
1806
importDxfStop(SequenceInputStream & rStrm)1807 void Fill::importDxfStop( SequenceInputStream& rStrm )
1808 {
1809 SAL_WARN_IF( !mbDxf, "sc", "Fill::importDxfStop - missing conditional formatting flag" );
1810 if( !mxGradientModel )
1811 mxGradientModel.reset( new GradientFillModel );
1812 mxGradientModel->readGradientStop( rStrm, true );
1813 }
1814
finalizeImport()1815 void Fill::finalizeImport()
1816 {
1817 const GraphicHelper& rGraphicHelper = getBaseFilter().getGraphicHelper();
1818
1819 if( mxPatternModel.get() )
1820 {
1821 // finalize the OOXML data struct
1822 PatternFillModel& rModel = *mxPatternModel;
1823 if( mbDxf )
1824 {
1825 if( rModel.mbFillColorUsed && (!rModel.mbPatternUsed || (rModel.mnPattern == XML_solid)) )
1826 {
1827 rModel.maPatternColor = rModel.maFillColor;
1828 rModel.mnPattern = XML_solid;
1829 rModel.mbPattColorUsed = rModel.mbPatternUsed = true;
1830 }
1831 else if( !rModel.mbFillColorUsed && rModel.mbPatternUsed && (rModel.mnPattern == XML_solid) )
1832 {
1833 rModel.mbPatternUsed = false;
1834 }
1835 }
1836
1837 // convert to API fill settings
1838 maApiData.mbUsed = rModel.mbPatternUsed;
1839 if( rModel.mnPattern == XML_none )
1840 {
1841 maApiData.mnColor = API_RGB_TRANSPARENT;
1842 maApiData.mbTransparent = true;
1843 }
1844 else
1845 {
1846 sal_Int32 nAlpha = 0x80;
1847 switch( rModel.mnPattern )
1848 {
1849 case XML_darkDown: nAlpha = 0x40; break;
1850 case XML_darkGray: nAlpha = 0x60; break;
1851 case XML_darkGrid: nAlpha = 0x40; break;
1852 case XML_darkHorizontal: nAlpha = 0x40; break;
1853 case XML_darkTrellis: nAlpha = 0x60; break;
1854 case XML_darkUp: nAlpha = 0x40; break;
1855 case XML_darkVertical: nAlpha = 0x40; break;
1856 case XML_gray0625: nAlpha = 0x08; break;
1857 case XML_gray125: nAlpha = 0x10; break;
1858 case XML_lightDown: nAlpha = 0x20; break;
1859 case XML_lightGray: nAlpha = 0x20; break;
1860 case XML_lightGrid: nAlpha = 0x38; break;
1861 case XML_lightHorizontal: nAlpha = 0x20; break;
1862 case XML_lightTrellis: nAlpha = 0x30; break;
1863 case XML_lightUp: nAlpha = 0x20; break;
1864 case XML_lightVertical: nAlpha = 0x20; break;
1865 case XML_mediumGray: nAlpha = 0x40; break;
1866 case XML_solid: nAlpha = 0x80; break;
1867 }
1868
1869 ::Color nWinTextColor = rGraphicHelper.getSystemColor( XML_windowText );
1870 ::Color nWinColor = rGraphicHelper.getSystemColor( XML_window );
1871
1872 if( !rModel.mbPattColorUsed )
1873 rModel.maPatternColor.setAuto();
1874 ::Color nPattColor = rModel.maPatternColor.getColor( rGraphicHelper, nWinTextColor );
1875
1876 if( !rModel.mbFillColorUsed )
1877 rModel.maFillColor.setAuto();
1878 ::Color nFillColor = rModel.maFillColor.getColor( rGraphicHelper, nWinColor );
1879
1880 maApiData.mnColor = lclGetMixedColor( nPattColor, nFillColor, nAlpha );
1881 maApiData.mbTransparent = false;
1882 }
1883 }
1884 else if( mxGradientModel.get() && !mxGradientModel->maColors.empty() )
1885 {
1886 GradientFillModel& rModel = *mxGradientModel;
1887 maApiData.mbUsed = true; // no support for differential attributes
1888 GradientFillModel::ColorMap::const_iterator aIt = rModel.maColors.begin();
1889 OSL_ENSURE( !aIt->second.isAuto(), "Fill::finalizeImport - automatic gradient color" );
1890 maApiData.mnColor = aIt->second.getColor( rGraphicHelper, API_RGB_WHITE );
1891 if( ++aIt != rModel.maColors.end() )
1892 {
1893 OSL_ENSURE( !aIt->second.isAuto(), "Fill::finalizeImport - automatic gradient color" );
1894 ::Color nEndColor = aIt->second.getColor( rGraphicHelper, API_RGB_WHITE );
1895 maApiData.mnColor = lclGetMixedColor( maApiData.mnColor, nEndColor, 0x40 );
1896 maApiData.mbTransparent = false;
1897 }
1898 }
1899 }
1900
fillToItemSet(SfxItemSet & rItemSet,bool bSkipPoolDefs) const1901 void Fill::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
1902 {
1903 if( maApiData.mbUsed )
1904 {
1905 SvxBrushItem aBrushItem( ATTR_BACKGROUND );
1906 if ( maApiData.mbTransparent )
1907 {
1908 aBrushItem.SetColor( COL_TRANSPARENT );
1909 }
1910 else
1911 {
1912 aBrushItem.SetColor( maApiData.mnColor );
1913 }
1914 ScfTools::PutItem( rItemSet, aBrushItem, bSkipPoolDefs );
1915 }
1916 }
1917
XfModel()1918 XfModel::XfModel() :
1919 mnStyleXfId( -1 ),
1920 mnFontId( -1 ),
1921 mnNumFmtId( -1 ),
1922 mnBorderId( -1 ),
1923 mnFillId( -1 ),
1924 mbCellXf( true ),
1925 mbFontUsed( false ),
1926 mbNumFmtUsed( false ),
1927 mbAlignUsed( false ),
1928 mbProtUsed( false ),
1929 mbBorderUsed( false ),
1930 mbAreaUsed( false )
1931 {
1932 }
1933
AttrList(const ScPatternAttr * pDefPattern)1934 Xf::AttrList::AttrList(const ScPatternAttr* pDefPattern):
1935 mbLatinNumFmtOnly(true),
1936 mpDefPattern(pDefPattern)
1937 {}
1938
Xf(const WorkbookHelper & rHelper)1939 Xf::Xf( const WorkbookHelper& rHelper ) :
1940 WorkbookHelper( rHelper ),
1941 mnScNumFmt(0),
1942 maAlignment( rHelper ),
1943 maProtection( rHelper ),
1944 meRotationRef( css::table::CellVertJustify2::STANDARD ),
1945 mpStyleSheet( nullptr )
1946 {
1947 }
1948
importXf(const AttributeList & rAttribs,bool bCellXf)1949 void Xf::importXf( const AttributeList& rAttribs, bool bCellXf )
1950 {
1951 maModel.mbCellXf = bCellXf;
1952 // tdf#70565 Set proper default value to "0" of xfId attribute
1953 // When xfId is not exist during .xlsx import
1954 // it must have values set to "0".
1955 // This doesn't impact spreadsheets created with MS Excel,
1956 // as xfId attribute is always created during export to .xlsx
1957 // Not setting "0" value is causing wrong .xlsx import by LibreOffice,
1958 // for spreadsheets created by external applications (ex. SAP BI).
1959 if ( maModel.mbCellXf )
1960 {
1961 maModel.mnStyleXfId = rAttribs.getInteger( XML_xfId, 0 );
1962 }
1963 else
1964 {
1965 maModel.mnStyleXfId = rAttribs.getInteger( XML_xfId, -1 );
1966 }
1967 maModel.mnFontId = rAttribs.getInteger( XML_fontId, -1 );
1968 maModel.mnNumFmtId = rAttribs.getInteger( XML_numFmtId, -1 );
1969 maModel.mnBorderId = rAttribs.getInteger( XML_borderId, -1 );
1970 maModel.mnFillId = rAttribs.getInteger( XML_fillId, -1 );
1971
1972
1973 /* Default value of the apply*** attributes is dependent on context:
1974 true in cellStyleXfs element, false in cellXfs element... */
1975 maModel.mbAlignUsed = rAttribs.getBool( XML_applyAlignment, !maModel.mbCellXf );
1976 maModel.mbProtUsed = rAttribs.getBool( XML_applyProtection, !maModel.mbCellXf );
1977 maModel.mbFontUsed = rAttribs.getBool( XML_applyFont, !maModel.mbCellXf );
1978 maModel.mbNumFmtUsed = rAttribs.getBool( XML_applyNumberFormat, !maModel.mbCellXf );
1979 maModel.mbBorderUsed = rAttribs.getBool( XML_applyBorder, !maModel.mbCellXf );
1980 maModel.mbAreaUsed = rAttribs.getBool( XML_applyFill, !maModel.mbCellXf );
1981 }
1982
importAlignment(const AttributeList & rAttribs)1983 void Xf::importAlignment( const AttributeList& rAttribs )
1984 {
1985 maAlignment.importAlignment( rAttribs );
1986 }
1987
importProtection(const AttributeList & rAttribs)1988 void Xf::importProtection( const AttributeList& rAttribs )
1989 {
1990 maProtection.importProtection( rAttribs );
1991 }
1992
importXf(SequenceInputStream & rStrm,bool bCellXf)1993 void Xf::importXf( SequenceInputStream& rStrm, bool bCellXf )
1994 {
1995 maModel.mbCellXf = bCellXf;
1996 maModel.mnStyleXfId = rStrm.readuInt16();
1997 maModel.mnNumFmtId = rStrm.readuInt16();
1998 maModel.mnFontId = rStrm.readuInt16();
1999 maModel.mnFillId = rStrm.readuInt16();
2000 maModel.mnBorderId = rStrm.readuInt16();
2001 sal_uInt32 nFlags = rStrm.readuInt32();
2002 maAlignment.setBiff12Data( nFlags );
2003 maProtection.setBiff12Data( nFlags );
2004 // used flags, see comments in Xf::setBiffUsedFlags()
2005 sal_uInt16 nUsedFlags = rStrm.readuInt16();
2006 maModel.mbFontUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_FONT_USED );
2007 maModel.mbNumFmtUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_NUMFMT_USED );
2008 maModel.mbAlignUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_ALIGN_USED );
2009 maModel.mbProtUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_PROT_USED );
2010 maModel.mbBorderUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_BORDER_USED );
2011 maModel.mbAreaUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF12_XF_AREA_USED );
2012 }
2013
finalizeImport()2014 void Xf::finalizeImport()
2015 {
2016 // alignment and protection
2017 maAlignment.finalizeImport();
2018 maProtection.finalizeImport();
2019 }
2020
getFont() const2021 FontRef Xf::getFont() const
2022 {
2023 return getStyles().getFont( maModel.mnFontId );
2024 }
2025
applyPatternToAttrList(AttrList & rAttrs,SCROW nRow1,SCROW nRow2,sal_Int32 nNumFmtId)2026 void Xf::applyPatternToAttrList( AttrList& rAttrs, SCROW nRow1, SCROW nRow2, sal_Int32 nNumFmtId )
2027 {
2028 createPattern();
2029 ScPatternAttr& rPat = *mpPattern;
2030 ScDocument& rDoc = getScDocument();
2031 if ( isCellXf() )
2032 {
2033 StylesBuffer& rStyles = getStyles();
2034 rStyles.createCellStyle( maModel.mnStyleXfId );
2035
2036 mpStyleSheet = rStyles.getCellStyleSheet( maModel.mnStyleXfId );
2037 if ( mpStyleSheet )
2038 {
2039 //rDoc.ApplySelectionStyle( static_cast<ScStyleSheet&>(*mpStyleSheet), rMarkData );
2040 rPat.SetStyleSheet(mpStyleSheet, false);
2041 }
2042 else
2043 {
2044 ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool();
2045 if (pStylePool)
2046 {
2047 ScStyleSheet* pStyleSheet = static_cast<ScStyleSheet*>(
2048 pStylePool->Find(
2049 ScResId(STR_STYLENAME_STANDARD), SfxStyleFamily::Para));
2050
2051 if (pStyleSheet)
2052 rPat.SetStyleSheet( pStyleSheet, false );
2053 }
2054 }
2055 }
2056 if ( nNumFmtId >= 0 )
2057 {
2058 ScPatternAttr aNumPat(rDoc.GetPool());
2059 mnScNumFmt = getStyles().writeNumFmtToItemSet( aNumPat.GetItemSet(), nNumFmtId, false );
2060 rPat.GetItemSet().Put(aNumPat.GetItemSet());
2061 }
2062
2063 if (!sc::NumFmtUtil::isLatinScript(mnScNumFmt, rDoc))
2064 rAttrs.mbLatinNumFmtOnly = false;
2065
2066 if (rPat.GetStyleName())
2067 {
2068 // Check for a gap between the last entry and this one.
2069 bool bHasGap = false;
2070 if (rAttrs.maAttrs.empty() && nRow1 > 0)
2071 // First attribute range doesn't start at row 0.
2072 bHasGap = true;
2073
2074 if (!rAttrs.maAttrs.empty() && rAttrs.maAttrs.back().nEndRow + 1 < nRow1)
2075 bHasGap = true;
2076
2077 if (bHasGap)
2078 {
2079 // Fill this gap with the default pattern.
2080 ScAttrEntry aEntry;
2081 aEntry.nEndRow = nRow1 - 1;
2082 aEntry.pPattern = &rDoc.GetPool()->Put(*rAttrs.mpDefPattern);
2083 rAttrs.maAttrs.push_back(aEntry);
2084
2085 // Check if the default pattern is 'General'.
2086 if (!sc::NumFmtUtil::isLatinScript(*aEntry.pPattern, rDoc))
2087 rAttrs.mbLatinNumFmtOnly = false;
2088 }
2089
2090 ScAttrEntry aEntry;
2091 aEntry.nEndRow = nRow2;
2092 aEntry.pPattern = &rDoc.GetPool()->Put(rPat);
2093 rAttrs.maAttrs.push_back(aEntry);
2094
2095 if (!sc::NumFmtUtil::isLatinScript(*aEntry.pPattern, rDoc))
2096 rAttrs.mbLatinNumFmtOnly = false;
2097 }
2098 }
2099
writeToDoc(ScDocumentImport & rDoc,const ScRange & rRange)2100 void Xf::writeToDoc( ScDocumentImport& rDoc, const ScRange& rRange )
2101 {
2102 const StylesBuffer& rStyles = getStyles();
2103
2104 if (isCellXf())
2105 {
2106 // Cell style name.
2107 OUString aStyleName = rStyles.createCellStyle(maModel.mnStyleXfId);
2108
2109 ScStyleSheet* pStyleSheet =
2110 static_cast<ScStyleSheet*>(
2111 rDoc.getDoc().GetStyleSheetPool()->Find(aStyleName, SfxStyleFamily::Para));
2112
2113 if (pStyleSheet)
2114 {
2115 rDoc.getDoc().ApplyStyleAreaTab(
2116 rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aStart.Tab(),
2117 *pStyleSheet);
2118 }
2119 }
2120
2121 const ScPatternAttr& rAttr = createPattern();
2122 rDoc.getDoc().ApplyPatternAreaTab(
2123 rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aStart.Tab(), rAttr);
2124 }
2125
2126 const ::ScPatternAttr&
createPattern(bool bSkipPoolDefs)2127 Xf::createPattern( bool bSkipPoolDefs )
2128 {
2129 if( mpPattern.get() )
2130 return *mpPattern;
2131 mpPattern.reset( new ::ScPatternAttr( getScDocument().GetPool() ) );
2132 SfxItemSet& rItemSet = mpPattern->GetItemSet();
2133 /* Enables the used flags, if the formatting attributes differ from the
2134 style XF. In cell XFs Excel uses the cell attributes, if they differ
2135 from the parent style XF (even if the used flag is switched off).
2136 #109899# ...or if the respective flag is not set in parent style XF.
2137 */
2138 StylesBuffer& rStyles = getStyles();
2139
2140 const Xf* pStyleXf = isCellXf() ? rStyles.getStyleXf( maModel.mnStyleXfId ).get() : nullptr;
2141 if( pStyleXf && !mpStyleSheet )
2142 {
2143 rStyles.createCellStyle( maModel.mnStyleXfId );
2144 mpStyleSheet = rStyles.getCellStyleSheet( maModel.mnStyleXfId );
2145 OSL_ENSURE( mpStyleSheet, "Xf::createPattern - no parentStyle created" );
2146
2147 const XfModel& rStyleData = pStyleXf->maModel;
2148 if( !maModel.mbFontUsed )
2149 maModel.mbFontUsed = !rStyleData.mbFontUsed || (maModel.mnFontId != rStyleData.mnFontId);
2150 if( !maModel.mbNumFmtUsed )
2151 maModel.mbNumFmtUsed = !rStyleData.mbNumFmtUsed || (maModel.mnNumFmtId != rStyleData.mnNumFmtId);
2152 if( !maModel.mbAlignUsed )
2153 maModel.mbAlignUsed = !rStyleData.mbAlignUsed || !(maAlignment.getApiData() == pStyleXf->maAlignment.getApiData());
2154 if( !maModel.mbProtUsed )
2155 maModel.mbProtUsed = !rStyleData.mbProtUsed || !(maProtection.getApiData() == pStyleXf->maProtection.getApiData());
2156 if( !maModel.mbBorderUsed )
2157 maModel.mbBorderUsed = !rStyleData.mbBorderUsed || !StylesBuffer::equalBorders( maModel.mnBorderId, rStyleData.mnBorderId );
2158 if( !maModel.mbAreaUsed )
2159 maModel.mbAreaUsed = !rStyleData.mbAreaUsed || !StylesBuffer::equalFills( maModel.mnFillId, rStyleData.mnFillId );
2160 }
2161 // cell protection
2162 if( maModel.mbProtUsed )
2163 {
2164 maProtection.fillToItemSet( rItemSet, bSkipPoolDefs );
2165 }
2166
2167 // font
2168 if( maModel.mbFontUsed )
2169 {
2170 rStyles.writeFontToItemSet( rItemSet, maModel.mnFontId, bSkipPoolDefs );
2171 }
2172
2173 // value format
2174 if( maModel.mbNumFmtUsed )
2175 {
2176 mnScNumFmt = rStyles.writeNumFmtToItemSet( rItemSet, maModel.mnNumFmtId, bSkipPoolDefs );
2177 }
2178 // alignment
2179 if( maModel.mbAlignUsed )
2180 {
2181 maAlignment.fillToItemSet( rItemSet, bSkipPoolDefs );
2182 }
2183
2184 // border
2185 if( maModel.mbBorderUsed )
2186 {
2187 rStyles.writeBorderToItemSet( rItemSet, maModel.mnBorderId, bSkipPoolDefs );
2188 }
2189
2190 // area
2191 if( maModel.mbAreaUsed )
2192 {
2193 rStyles.writeFillToItemSet( rItemSet, maModel.mnFillId, bSkipPoolDefs );
2194 }
2195
2196 /* #i38709# Decide which rotation reference mode to use. If any outer
2197 border line of the cell is set (either explicitly or via cell style),
2198 and the cell contents are rotated, set rotation reference to bottom of
2199 cell. This causes the borders to be painted rotated with the text. */
2200 if( const Alignment* pAlignment = maModel.mbAlignUsed ? &maAlignment : (pStyleXf ? &pStyleXf->maAlignment : nullptr) )
2201 {
2202 SvxRotateMode eRotateMode = SVX_ROTATE_MODE_STANDARD;
2203 sal_Int32 nBorderId = maModel.mbBorderUsed ? maModel.mnBorderId : (pStyleXf ? pStyleXf->maModel.mnBorderId : -1);
2204 if( const Border* pBorder = rStyles.getBorder( nBorderId ).get() )
2205 {
2206 if( (pAlignment->getApiData().mnRotation != 0) && pBorder->getApiData().hasAnyOuterBorder() )
2207 {
2208 meRotationRef = css::table::CellVertJustify2::BOTTOM;
2209 eRotateMode = SVX_ROTATE_MODE_BOTTOM;
2210 }
2211 }
2212 ScfTools::PutItem( rItemSet, SvxRotateModeItem( eRotateMode, ATTR_ROTATE_MODE ), bSkipPoolDefs );
2213 }
2214
2215 return *mpPattern;
2216 }
2217
Dxf(const WorkbookHelper & rHelper)2218 Dxf::Dxf( const WorkbookHelper& rHelper ) :
2219 WorkbookHelper( rHelper )
2220 {
2221 }
2222
createFont(bool bAlwaysNew)2223 FontRef const & Dxf::createFont( bool bAlwaysNew )
2224 {
2225 if( bAlwaysNew || !mxFont )
2226 mxFont.reset( new Font( *this, true ) );
2227 return mxFont;
2228 }
2229
createBorder(bool bAlwaysNew)2230 BorderRef const & Dxf::createBorder( bool bAlwaysNew )
2231 {
2232 if( bAlwaysNew || !mxBorder )
2233 mxBorder.reset( new Border( *this, true ) );
2234 return mxBorder;
2235 }
2236
createFill(bool bAlwaysNew)2237 FillRef const & Dxf::createFill( bool bAlwaysNew )
2238 {
2239 if( bAlwaysNew || !mxFill )
2240 mxFill.reset( new Fill( *this, true ) );
2241 return mxFill;
2242 }
2243
importNumFmt(const AttributeList & rAttribs)2244 void Dxf::importNumFmt( const AttributeList& rAttribs )
2245 {
2246 // don't propagate number formats defined in Dxf entries
2247 // they can have the same id ( but different format codes ) as those
2248 // defined globally earlier. We discard the id defined in XML_numFmtId
2249 // and generate one ourselves ( this assumes that the normal numberformat
2250 // import has already taken place )
2251 sal_Int32 nNumFmtId = getStyles().nextFreeNumFmtId();
2252 OUString aFmtCode = rAttribs.getXString( XML_formatCode, OUString() );
2253 mxNumFmt = getStyles().createNumFmt( nNumFmtId, aFmtCode );
2254 }
2255
importDxf(SequenceInputStream & rStrm)2256 void Dxf::importDxf( SequenceInputStream& rStrm )
2257 {
2258 sal_Int32 nNumFmtId = -1;
2259 OUString aFmtCode;
2260 sal_uInt16 nRecCount;
2261 rStrm.skip( 4 ); // flags
2262 nRecCount = rStrm.readuInt16();
2263 for( sal_uInt16 nRec = 0; !rStrm.isEof() && (nRec < nRecCount); ++nRec )
2264 {
2265 sal_uInt16 nSubRecId, nSubRecSize;
2266 sal_Int64 nRecEnd = rStrm.tell();
2267 nSubRecId = rStrm.readuInt16();
2268 nSubRecSize = rStrm.readuInt16();
2269 nRecEnd += nSubRecSize;
2270 switch( nSubRecId )
2271 {
2272 case BIFF12_DXF_FILL_PATTERN: createFill( false )->importDxfPattern( rStrm ); break;
2273 case BIFF12_DXF_FILL_FGCOLOR: createFill( false )->importDxfFgColor( rStrm ); break;
2274 case BIFF12_DXF_FILL_BGCOLOR: createFill( false )->importDxfBgColor( rStrm ); break;
2275 case BIFF12_DXF_FILL_GRADIENT: createFill( false )->importDxfGradient( rStrm ); break;
2276 case BIFF12_DXF_FILL_STOP: createFill( false )->importDxfStop( rStrm ); break;
2277 case BIFF12_DXF_FONT_COLOR: createFont( false )->importDxfColor( rStrm ); break;
2278 case BIFF12_DXF_BORDER_TOP: createBorder( false )->importDxfBorder( XLS_TOKEN( top ), rStrm ); break;
2279 case BIFF12_DXF_BORDER_BOTTOM: createBorder( false )->importDxfBorder( XLS_TOKEN( bottom ), rStrm ); break;
2280 case BIFF12_DXF_BORDER_LEFT: createBorder( false )->importDxfBorder( XLS_TOKEN( left ), rStrm ); break;
2281 case BIFF12_DXF_BORDER_RIGHT: createBorder( false )->importDxfBorder( XLS_TOKEN( right ), rStrm ); break;
2282 case BIFF12_DXF_FONT_NAME: createFont( false )->importDxfName( rStrm ); break;
2283 case BIFF12_DXF_FONT_WEIGHT: createFont( false )->importDxfWeight( rStrm ); break;
2284 case BIFF12_DXF_FONT_UNDERLINE: createFont( false )->importDxfUnderline( rStrm ); break;
2285 case BIFF12_DXF_FONT_ESCAPEMENT: createFont( false )->importDxfEscapement( rStrm ); break;
2286 case BIFF12_DXF_FONT_ITALIC: createFont( false )->importDxfFlag( XML_i, rStrm ); break;
2287 case BIFF12_DXF_FONT_STRIKE: createFont( false )->importDxfFlag( XML_strike, rStrm ); break;
2288 case BIFF12_DXF_FONT_OUTLINE: createFont( false )->importDxfFlag( XML_outline, rStrm ); break;
2289 case BIFF12_DXF_FONT_SHADOW: createFont( false )->importDxfFlag( XML_shadow, rStrm ); break;
2290 case BIFF12_DXF_FONT_HEIGHT: createFont( false )->importDxfHeight( rStrm ); break;
2291 case BIFF12_DXF_FONT_SCHEME: createFont( false )->importDxfScheme( rStrm ); break;
2292 case BIFF12_DXF_NUMFMT_CODE: aFmtCode = BiffHelper::readString( rStrm, false ); break;
2293 case BIFF12_DXF_NUMFMT_ID: nNumFmtId = rStrm.readuInt16(); break;
2294 }
2295 rStrm.seek( nRecEnd );
2296 }
2297 OSL_ENSURE( !rStrm.isEof() && (rStrm.getRemaining() == 0), "Dxf::importDxf - unexpected remaining data" );
2298 mxNumFmt = getStyles().createNumFmt( nNumFmtId, aFmtCode );
2299 }
2300
finalizeImport()2301 void Dxf::finalizeImport()
2302 {
2303 if( mxFont.get() )
2304 mxFont->finalizeImport();
2305 bool bRTL = false;
2306 // number format already finalized by the number formats buffer
2307 if( mxAlignment.get() )
2308 {
2309 mxAlignment->finalizeImport();
2310 // how do we detect RTL when text dir is OOX_XF_CONTEXT? ( seems you
2311 // would need access to the cell content, which we don't here )
2312 if ( mxAlignment->getModel().mnTextDir == OOX_XF_TEXTDIR_RTL )
2313 bRTL = true;
2314 }
2315 if( mxProtection.get() )
2316 mxProtection->finalizeImport();
2317 if( mxBorder.get() )
2318 {
2319 mxBorder->finalizeImport( bRTL );
2320 }
2321 if( mxFill.get() )
2322 mxFill->finalizeImport();
2323 }
2324
fillToItemSet(SfxItemSet & rSet) const2325 void Dxf::fillToItemSet( SfxItemSet& rSet ) const
2326 {
2327 if (mxFont)
2328 mxFont->fillToItemSet(rSet, false);
2329 if (mxNumFmt)
2330 mxNumFmt->fillToItemSet(rSet);
2331 if (mxAlignment)
2332 mxAlignment->fillToItemSet(rSet);
2333 if (mxProtection)
2334 mxProtection->fillToItemSet(rSet);
2335 if (mxBorder)
2336 mxBorder->fillToItemSet(rSet);
2337 if (mxFill)
2338 mxFill->fillToItemSet(rSet);
2339 }
2340
2341 namespace {
2342
2343 const sal_Char* const sppcStyleNames[] =
2344 {
2345 "Normal",
2346 "RowLevel_", // outline level will be appended
2347 "ColLevel_", // outline level will be appended
2348 "Comma",
2349 "Currency",
2350 "Percent",
2351 "Comma [0]", // new in BIFF4
2352 "Currency [0]",
2353 "Hyperlink", // new in BIFF8
2354 "Followed Hyperlink",
2355 "Note", // new in OOX
2356 "Warning Text",
2357 nullptr,
2358 nullptr,
2359 nullptr,
2360 "Title",
2361 "Heading 1",
2362 "Heading 2",
2363 "Heading 3",
2364 "Heading 4",
2365 "Input",
2366 "Output",
2367 "Calculation",
2368 "Check Cell",
2369 "Linked Cell",
2370 "Total",
2371 "Good",
2372 "Bad",
2373 "Neutral",
2374 "Accent1",
2375 "20% - Accent1",
2376 "40% - Accent1",
2377 "60% - Accent1",
2378 "Accent2",
2379 "20% - Accent2",
2380 "40% - Accent2",
2381 "60% - Accent2",
2382 "Accent3",
2383 "20% - Accent3",
2384 "40% - Accent3",
2385 "60% - Accent3",
2386 "Accent4",
2387 "20% - Accent4",
2388 "40% - Accent4",
2389 "60% - Accent4",
2390 "Accent5",
2391 "20% - Accent5",
2392 "40% - Accent5",
2393 "60% - Accent5",
2394 "Accent6",
2395 "20% - Accent6",
2396 "40% - Accent6",
2397 "60% - Accent6",
2398 "Explanatory Text"
2399 };
2400 const sal_Int32 snStyleNamesCount = static_cast< sal_Int32 >( SAL_N_ELEMENTS( sppcStyleNames ) );
2401
lclGetBuiltinStyleName(sal_Int32 nBuiltinId,const OUString & rName,sal_Int32 nLevel=0)2402 OUString lclGetBuiltinStyleName( sal_Int32 nBuiltinId, const OUString& rName, sal_Int32 nLevel = 0 )
2403 {
2404 OSL_ENSURE( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount), "lclGetBuiltinStyleName - unknown built-in style" );
2405 OUStringBuffer aStyleName("Excel Built-in ");
2406 if( (0 <= nBuiltinId) && (nBuiltinId < snStyleNamesCount) && (sppcStyleNames[ nBuiltinId ] != nullptr) )
2407 aStyleName.appendAscii( sppcStyleNames[ nBuiltinId ] );
2408 else if( !rName.isEmpty() )
2409 aStyleName.append( rName );
2410 else
2411 aStyleName.append( nBuiltinId );
2412 if( (nBuiltinId == OOX_STYLE_ROWLEVEL) || (nBuiltinId == OOX_STYLE_COLLEVEL) )
2413 aStyleName.append( nLevel );
2414 return aStyleName.makeStringAndClear();
2415 }
2416
lclCreateStyleName(const CellStyleModel & rModel)2417 OUString lclCreateStyleName( const CellStyleModel& rModel )
2418 {
2419 return rModel.mbBuiltin ? lclGetBuiltinStyleName( rModel.mnBuiltinId, rModel.maName, rModel.mnLevel ) : rModel.maName;
2420 }
2421
2422 } // namespace
2423
CellStyleModel()2424 CellStyleModel::CellStyleModel() :
2425 mnXfId( -1 ),
2426 mnBuiltinId( -1 ),
2427 mnLevel( 0 ),
2428 mbBuiltin( false ),
2429 mbCustom( false ),
2430 mbHidden( false )
2431 {
2432 }
2433
isBuiltin() const2434 bool CellStyleModel::isBuiltin() const
2435 {
2436 return mbBuiltin && (mnBuiltinId >= 0);
2437 }
2438
isDefaultStyle() const2439 bool CellStyleModel::isDefaultStyle() const
2440 {
2441 return mbBuiltin && (mnBuiltinId == OOX_STYLE_NORMAL);
2442 }
2443
CellStyle(const WorkbookHelper & rHelper)2444 CellStyle::CellStyle( const WorkbookHelper& rHelper ) :
2445 WorkbookHelper( rHelper ),
2446 mbCreated( false ),
2447 mpStyleSheet( nullptr )
2448 {
2449 }
2450
importCellStyle(const AttributeList & rAttribs)2451 void CellStyle::importCellStyle( const AttributeList& rAttribs )
2452 {
2453 maModel.maName = rAttribs.getXString( XML_name, OUString() );
2454 maModel.mnXfId = rAttribs.getInteger( XML_xfId, -1 );
2455 maModel.mnBuiltinId = rAttribs.getInteger( XML_builtinId, -1 );
2456 maModel.mnLevel = rAttribs.getInteger( XML_iLevel, 0 );
2457 maModel.mbBuiltin = rAttribs.hasAttribute( XML_builtinId );
2458 maModel.mbCustom = rAttribs.getBool( XML_customBuiltin, false );
2459 maModel.mbHidden = rAttribs.getBool( XML_hidden, false );
2460 }
2461
importCellStyle(SequenceInputStream & rStrm)2462 void CellStyle::importCellStyle( SequenceInputStream& rStrm )
2463 {
2464 sal_uInt16 nFlags;
2465 maModel.mnXfId = rStrm.readInt32();
2466 nFlags = rStrm.readuInt16();
2467 maModel.mnBuiltinId = rStrm.readInt8();
2468 maModel.mnLevel = rStrm.readInt8();
2469 rStrm >> maModel.maName;
2470 maModel.mbBuiltin = getFlag( nFlags, BIFF12_CELLSTYLE_BUILTIN );
2471 maModel.mbCustom = getFlag( nFlags, BIFF12_CELLSTYLE_CUSTOM );
2472 maModel.mbHidden = getFlag( nFlags, BIFF12_CELLSTYLE_HIDDEN );
2473 }
2474
createCellStyle()2475 void CellStyle::createCellStyle()
2476 {
2477
2478 // #i1624# #i1768# ignore unnamed user styles
2479 bool bDefStyle = maModel.isDefaultStyle();
2480 if( !mbCreated )
2481 {
2482 if ( bDefStyle && maFinalName.isEmpty() )
2483 maFinalName = ScResId( STR_STYLENAME_STANDARD );
2484 mbCreated = maFinalName.isEmpty();
2485 }
2486
2487 if( !mbCreated && !mpStyleSheet )
2488 {
2489 bool bCreatePattern = false;
2490 Xf* pXF = getStyles().getStyleXf( maModel.mnXfId ).get();
2491 ::ScDocument& rDoc = getScDocument();
2492
2493 if( bDefStyle )
2494 {
2495 // use existing "Default" style sheet
2496 mpStyleSheet = static_cast< ScStyleSheet* >( rDoc.GetStyleSheetPool()->Find(
2497 ScResId( STR_STYLENAME_STANDARD ), SfxStyleFamily::Para ) );
2498 OSL_ENSURE( mpStyleSheet, "CellStyle::createStyle - Default style not found" );
2499 bCreatePattern = true;
2500 }
2501 else
2502 {
2503 mpStyleSheet = static_cast< ScStyleSheet* >( rDoc.GetStyleSheetPool()->Find( maFinalName, SfxStyleFamily::Para ) );
2504 if( !mpStyleSheet )
2505 {
2506 mpStyleSheet = &static_cast< ScStyleSheet& >( rDoc.GetStyleSheetPool()->Make( maFinalName, SfxStyleFamily::Para, SfxStyleSearchBits::UserDefined ) );
2507 bCreatePattern = true;
2508 }
2509 }
2510
2511 // bDefStyle==true omits default pool items in CreatePattern()
2512 if( bCreatePattern && mpStyleSheet && pXF )
2513 mpStyleSheet->GetItemSet().Put( pXF->createPattern( bDefStyle ).GetItemSet() );
2514 }
2515 }
2516
finalizeImport(const OUString & rFinalName)2517 void CellStyle::finalizeImport( const OUString& rFinalName )
2518 {
2519 maFinalName = rFinalName;
2520 if( !maModel.isBuiltin() || maModel.mbCustom )
2521 createCellStyle();
2522 }
2523
CellStyleBuffer(const WorkbookHelper & rHelper)2524 CellStyleBuffer::CellStyleBuffer( const WorkbookHelper& rHelper ) :
2525 WorkbookHelper( rHelper )
2526 {
2527 }
2528
importCellStyle(const AttributeList & rAttribs)2529 CellStyleRef CellStyleBuffer::importCellStyle( const AttributeList& rAttribs )
2530 {
2531 CellStyleRef xCellStyle( new CellStyle( *this ) );
2532 xCellStyle->importCellStyle( rAttribs );
2533 insertCellStyle( xCellStyle );
2534 return xCellStyle;
2535 }
2536
importCellStyle(SequenceInputStream & rStrm)2537 CellStyleRef CellStyleBuffer::importCellStyle( SequenceInputStream& rStrm )
2538 {
2539 CellStyleRef xCellStyle( new CellStyle( *this ) );
2540 xCellStyle->importCellStyle( rStrm );
2541 insertCellStyle( xCellStyle );
2542 return xCellStyle;
2543 }
2544
finalizeImport()2545 void CellStyleBuffer::finalizeImport()
2546 {
2547 // calculate final names of all styles
2548 typedef RefMap< OUString, CellStyle, IgnoreCaseCompare > CellStyleNameMap;
2549 CellStyleNameMap aCellStyles;
2550 CellStyleVector aConflictNameStyles;
2551
2552 /* First, reserve style names that are built-in in Calc. This causes that
2553 imported cell styles get different unused names and thus do not try to
2554 overwrite these built-in styles. */
2555 try
2556 {
2557 // unfortunately, com.sun.star.style.StyleFamily does not implement XEnumerationAccess...
2558 Reference< XIndexAccess > xStyleFamilyIA( getCellStyleFamily(), UNO_QUERY_THROW );
2559 for( sal_Int32 nIndex = 0, nCount = xStyleFamilyIA->getCount(); nIndex < nCount; ++nIndex )
2560 {
2561 Reference< XStyle > xStyle( xStyleFamilyIA->getByIndex( nIndex ), UNO_QUERY_THROW );
2562 if( !xStyle->isUserDefined() )
2563 {
2564 // create an empty entry by using ::std::map<>::operator[]
2565 aCellStyles[ xStyle->getName() ];
2566 }
2567 }
2568 }
2569 catch( Exception& )
2570 {
2571 }
2572
2573 /* Calculate names of built-in styles. Store styles with reserved names
2574 in the aConflictNameStyles list. */
2575 for( const auto& rxStyle : maBuiltinStyles )
2576 {
2577 const CellStyleModel& rModel = rxStyle->getModel();
2578 if (rModel.isDefaultStyle())
2579 continue;
2580
2581 OUString aStyleName = lclCreateStyleName( rModel );
2582 /* If a builtin style entry already exists,
2583 we just stick with the last definition and ignore
2584 the preceding ones. */
2585 aCellStyles[ aStyleName ] = rxStyle;
2586 }
2587
2588 /* Calculate names of user defined styles. Store styles with reserved
2589 names in the aConflictNameStyles list. */
2590 for( const auto& rxStyle : maUserStyles )
2591 {
2592 const CellStyleModel& rModel = rxStyle->getModel();
2593 OUString aStyleName = lclCreateStyleName( rModel );
2594 // #i1624# #i1768# ignore unnamed user styles
2595 if( aStyleName.getLength() > 0 )
2596 {
2597 if( aCellStyles.find( aStyleName ) != aCellStyles.end() )
2598 aConflictNameStyles.push_back( rxStyle );
2599 else
2600 aCellStyles[ aStyleName ] = rxStyle;
2601 }
2602 }
2603
2604 // find unused names for all styles with conflicting names
2605 // having the index counter outside the loop prevents performance problems with opening some pathological documents (tdf#62095)
2606 sal_Int32 nIndex = 0;
2607 for( const auto& rxStyle : aConflictNameStyles )
2608 {
2609 const CellStyleModel& rModel = rxStyle->getModel();
2610 OUString aStyleName = lclCreateStyleName( rModel );
2611 OUString aUnusedName;
2612 do
2613 {
2614 aUnusedName = aStyleName + OUStringChar(' ') + OUString::number( ++nIndex );
2615 }
2616 while( aCellStyles.find( aUnusedName ) != aCellStyles.end() );
2617 aCellStyles[ aUnusedName ] = rxStyle;
2618 }
2619
2620 // set final names and create user-defined and modified built-in cell styles
2621 aCellStyles.forEachMemWithKey( &CellStyle::finalizeImport );
2622 }
2623
getDefaultXfId() const2624 sal_Int32 CellStyleBuffer::getDefaultXfId() const
2625 {
2626 return mxDefStyle.get() ? mxDefStyle->getModel().mnXfId : -1;
2627 }
2628
getDefaultStyleName() const2629 OUString CellStyleBuffer::getDefaultStyleName() const
2630 {
2631 return createCellStyle( mxDefStyle );
2632 }
2633
createCellStyle(sal_Int32 nXfId) const2634 OUString CellStyleBuffer::createCellStyle( sal_Int32 nXfId ) const
2635 {
2636 return createCellStyle( maStylesByXf.get( nXfId ) );
2637 }
2638
getCellStyleSheet(sal_Int32 nXfId) const2639 ::ScStyleSheet* CellStyleBuffer::getCellStyleSheet( sal_Int32 nXfId ) const
2640 {
2641 return getCellStyleSheet( maStylesByXf.get( nXfId ) );
2642 }
2643
2644 // private --------------------------------------------------------------------
2645
insertCellStyle(CellStyleRef const & xCellStyle)2646 void CellStyleBuffer::insertCellStyle( CellStyleRef const & xCellStyle )
2647 {
2648 const CellStyleModel& rModel = xCellStyle->getModel();
2649 if( rModel.mnXfId >= 0 )
2650 {
2651 // insert into the built-in map or user defined map
2652 (rModel.isBuiltin() ? maBuiltinStyles : maUserStyles).push_back( xCellStyle );
2653
2654 // insert into the XF identifier map
2655 OSL_ENSURE( maStylesByXf.count( rModel.mnXfId ) == 0, "CellStyleBuffer::insertCellStyle - multiple styles with equal XF identifier" );
2656 maStylesByXf[ rModel.mnXfId ] = xCellStyle;
2657
2658 // remember default cell style
2659 if( rModel.isDefaultStyle() )
2660 mxDefStyle = xCellStyle;
2661 }
2662 }
2663
getCellStyleSheet(const CellStyleRef & rxCellStyle)2664 ::ScStyleSheet* CellStyleBuffer::getCellStyleSheet( const CellStyleRef& rxCellStyle )
2665 {
2666 ::ScStyleSheet* pStyleSheet = nullptr;
2667 if ( rxCellStyle.get() )
2668 pStyleSheet = rxCellStyle->getStyleSheet();
2669 return pStyleSheet;
2670 }
2671
createCellStyle(const CellStyleRef & rxCellStyle)2672 OUString CellStyleBuffer::createCellStyle( const CellStyleRef& rxCellStyle )
2673 {
2674 if( rxCellStyle.get() )
2675 {
2676 rxCellStyle->createCellStyle();
2677 const OUString& rStyleName = rxCellStyle->getFinalStyleName();
2678 if( !rStyleName.isEmpty() )
2679 return rStyleName;
2680 }
2681 // on error: fallback to default style
2682 return lclGetBuiltinStyleName( OOX_STYLE_NORMAL, OUString() );
2683 }
2684
AutoFormatModel()2685 AutoFormatModel::AutoFormatModel() :
2686 mnAutoFormatId( 0 ),
2687 mbApplyNumFmt( false ),
2688 mbApplyFont( false ),
2689 mbApplyAlignment( false ),
2690 mbApplyBorder( false ),
2691 mbApplyFill( false ),
2692 mbApplyProtection( false )
2693 {
2694 }
2695
StylesBuffer(const WorkbookHelper & rHelper)2696 StylesBuffer::StylesBuffer( const WorkbookHelper& rHelper ) :
2697 WorkbookHelper( rHelper ),
2698 maPalette( rHelper ),
2699 maNumFmts( rHelper ),
2700 maCellStyles( rHelper )
2701 {
2702 }
2703
createFont()2704 FontRef StylesBuffer::createFont()
2705 {
2706 FontRef xFont( new Font( *this, false ) );
2707 maFonts.push_back( xFont );
2708 return xFont;
2709 }
2710
createNumFmt(sal_Int32 nNumFmtId,const OUString & rFmtCode)2711 NumberFormatRef StylesBuffer::createNumFmt( sal_Int32 nNumFmtId, const OUString& rFmtCode )
2712 {
2713 return maNumFmts.createNumFmt( nNumFmtId, rFmtCode );
2714 }
2715
nextFreeNumFmtId()2716 sal_Int32 StylesBuffer::nextFreeNumFmtId()
2717 {
2718 return maNumFmts.nextFreeId();
2719 }
2720
createBorder()2721 BorderRef StylesBuffer::createBorder()
2722 {
2723 BorderRef xBorder( new Border( *this, false ) );
2724 maBorders.push_back( xBorder );
2725 return xBorder;
2726 }
2727
createFill()2728 FillRef StylesBuffer::createFill()
2729 {
2730 FillRef xFill( new Fill( *this, false ) );
2731 maFills.push_back( xFill );
2732 return xFill;
2733 }
2734
createCellXf()2735 XfRef StylesBuffer::createCellXf()
2736 {
2737 XfRef xXf( new Xf( *this ) );
2738 maCellXfs.push_back( xXf );
2739 return xXf;
2740 }
2741
createStyleXf()2742 XfRef StylesBuffer::createStyleXf()
2743 {
2744 XfRef xXf( new Xf( *this ) );
2745 maStyleXfs.push_back( xXf );
2746 return xXf;
2747 }
2748
createDxf()2749 DxfRef StylesBuffer::createDxf()
2750 {
2751 DxfRef xDxf( new Dxf( *this ) );
2752 maDxfs.push_back( xDxf );
2753 return xDxf;
2754 }
2755
createExtDxf()2756 DxfRef StylesBuffer::createExtDxf()
2757 {
2758 DxfRef xDxf( new Dxf( *this ) );
2759 maExtDxfs.push_back( xDxf );
2760 return xDxf;
2761 }
2762
importPaletteColor(const AttributeList & rAttribs)2763 void StylesBuffer::importPaletteColor( const AttributeList& rAttribs )
2764 {
2765 maPalette.importPaletteColor( rAttribs );
2766 }
2767
importNumFmt(const AttributeList & rAttribs)2768 NumberFormatRef StylesBuffer::importNumFmt( const AttributeList& rAttribs )
2769 {
2770 return maNumFmts.importNumFmt( rAttribs );
2771 }
2772
importCellStyle(const AttributeList & rAttribs)2773 CellStyleRef StylesBuffer::importCellStyle( const AttributeList& rAttribs )
2774 {
2775 return maCellStyles.importCellStyle( rAttribs );
2776 }
2777
importPaletteColor(SequenceInputStream & rStrm)2778 void StylesBuffer::importPaletteColor( SequenceInputStream& rStrm )
2779 {
2780 maPalette.importPaletteColor( rStrm );
2781 }
2782
importNumFmt(SequenceInputStream & rStrm)2783 void StylesBuffer::importNumFmt( SequenceInputStream& rStrm )
2784 {
2785 maNumFmts.importNumFmt( rStrm );
2786 }
2787
importCellStyle(SequenceInputStream & rStrm)2788 void StylesBuffer::importCellStyle( SequenceInputStream& rStrm )
2789 {
2790 maCellStyles.importCellStyle( rStrm );
2791 }
2792
finalizeImport()2793 void StylesBuffer::finalizeImport()
2794 {
2795 // fonts first, are needed to finalize unit converter and XFs below
2796 maFonts.forEachMem( &Font::finalizeImport );
2797 // finalize unit coefficients after default font is known
2798 getUnitConverter().finalizeImport();
2799 // number formats
2800 maNumFmts.finalizeImport();
2801 // borders and fills
2802 // is there a document wide RTL setting that we
2803 // would/could need to pass to finalizeImport here ?
2804 maBorders.forEachMem( &Border::finalizeImport, false );
2805 maFills.forEachMem( &Fill::finalizeImport );
2806 // style XFs and cell XFs
2807 maStyleXfs.forEachMem( &Xf::finalizeImport );
2808 maCellXfs.forEachMem( &Xf::finalizeImport );
2809 // built-in and user defined cell styles
2810 maCellStyles.finalizeImport();
2811 // differential formatting (for conditional formatting)
2812 maDxfs.forEachMem( &Dxf::finalizeImport );
2813 }
2814
getPaletteColor(sal_Int32 nPaletteIdx) const2815 ::Color StylesBuffer::getPaletteColor( sal_Int32 nPaletteIdx ) const
2816 {
2817 return maPalette.getColor( nPaletteIdx );
2818 }
2819
getFont(sal_Int32 nFontId) const2820 FontRef StylesBuffer::getFont( sal_Int32 nFontId ) const
2821 {
2822 return maFonts.get( nFontId );
2823 }
2824
getBorder(sal_Int32 nBorderId) const2825 BorderRef StylesBuffer::getBorder( sal_Int32 nBorderId ) const
2826 {
2827 return maBorders.get( nBorderId );
2828 }
2829
getCellXf(sal_Int32 nXfId) const2830 XfRef StylesBuffer::getCellXf( sal_Int32 nXfId ) const
2831 {
2832 return maCellXfs.get( nXfId );
2833 }
2834
getStyleXf(sal_Int32 nXfId) const2835 XfRef StylesBuffer::getStyleXf( sal_Int32 nXfId ) const
2836 {
2837 return maStyleXfs.get( nXfId );
2838 }
2839
getFontFromCellXf(sal_Int32 nXfId) const2840 FontRef StylesBuffer::getFontFromCellXf( sal_Int32 nXfId ) const
2841 {
2842 FontRef xFont;
2843 if( const Xf* pXf = getCellXf( nXfId ).get() )
2844 xFont = pXf->getFont();
2845 return xFont;
2846 }
2847
getDefaultFont() const2848 FontRef StylesBuffer::getDefaultFont() const
2849 {
2850 FontRef xDefFont;
2851 if( const Xf* pXf = getStyleXf( maCellStyles.getDefaultXfId() ).get() )
2852 xDefFont = pXf->getFont();
2853 // no font from styles - try first loaded font (e.g. BIFF2)
2854 if( !xDefFont )
2855 xDefFont = maFonts.get( 0 );
2856 OSL_ENSURE( xDefFont.get(), "StylesBuffer::getDefaultFont - no default font found" );
2857 return xDefFont;
2858 }
2859
getDefaultFontModel() const2860 const FontModel& StylesBuffer::getDefaultFontModel() const
2861 {
2862 FontRef xDefFont = getDefaultFont();
2863 return xDefFont.get() ? xDefFont->getModel() : getTheme().getDefaultFontModel();
2864 }
2865
equalBorders(sal_Int32 nBorderId1,sal_Int32 nBorderId2)2866 bool StylesBuffer::equalBorders( sal_Int32 nBorderId1, sal_Int32 nBorderId2 )
2867 {
2868 // in OOXML, borders are assumed to be unique
2869 return nBorderId1 == nBorderId2;
2870 }
2871
equalFills(sal_Int32 nFillId1,sal_Int32 nFillId2)2872 bool StylesBuffer::equalFills( sal_Int32 nFillId1, sal_Int32 nFillId2 )
2873 {
2874 // in OOXML, fills are assumed to be unique
2875 return nFillId1 == nFillId2;
2876 }
2877
getDefaultStyleName() const2878 OUString StylesBuffer::getDefaultStyleName() const
2879 {
2880 return maCellStyles.getDefaultStyleName();
2881 }
2882
createCellStyle(sal_Int32 nXfId) const2883 OUString StylesBuffer::createCellStyle( sal_Int32 nXfId ) const
2884 {
2885 return maCellStyles.createCellStyle( nXfId );
2886 }
2887
getCellStyleSheet(sal_Int32 nXfId) const2888 ::ScStyleSheet* StylesBuffer::getCellStyleSheet( sal_Int32 nXfId ) const
2889 {
2890 return maCellStyles.getCellStyleSheet( nXfId );
2891 }
2892
createDxfStyle(sal_Int32 nDxfId) const2893 OUString StylesBuffer::createDxfStyle( sal_Int32 nDxfId ) const
2894 {
2895 OUString& rStyleName = maDxfStyles[ nDxfId ];
2896 if (!rStyleName.isEmpty())
2897 return rStyleName;
2898
2899 if (Dxf* pDxf = maDxfs.get(nDxfId).get())
2900 {
2901 rStyleName = "ConditionalStyle_" + OUString::number(nDxfId + 1);
2902
2903 // Create a cell style. This may overwrite an existing style if
2904 // one with the same name exists.
2905 ScStyleSheet& rStyleSheet = ScfTools::MakeCellStyleSheet(
2906 *getScDocument().GetStyleSheetPool(), rStyleName, true);
2907
2908 rStyleSheet.ResetParent();
2909 SfxItemSet& rStyleItemSet =
2910 rStyleSheet.GetItemSet();
2911
2912 pDxf->fillToItemSet(rStyleItemSet);
2913
2914 }
2915
2916 // on error: fallback to default style
2917 if (rStyleName.isEmpty())
2918 rStyleName = maCellStyles.getDefaultStyleName();
2919
2920 return rStyleName;
2921 }
2922
createExtDxfStyle(sal_Int32 nDxfId) const2923 OUString StylesBuffer::createExtDxfStyle( sal_Int32 nDxfId ) const
2924 {
2925 OUString rStyleName;
2926
2927 if (Dxf* pDxf = maExtDxfs.get(nDxfId).get())
2928 {
2929 rStyleName = "ExtConditionalStyle_" + OUString::number(nDxfId + 1);
2930
2931 // Create a cell style. This may overwrite an existing style if
2932 // one with the same name exists.
2933 ScStyleSheet& rStyleSheet = ScfTools::MakeCellStyleSheet(
2934 *getScDocument().GetStyleSheetPool(), rStyleName, true);
2935
2936 rStyleSheet.ResetParent();
2937 SfxItemSet& rStyleItemSet =
2938 rStyleSheet.GetItemSet();
2939
2940 pDxf->fillToItemSet(rStyleItemSet);
2941 }
2942
2943 // on error: fallback to default style
2944 if (rStyleName.isEmpty())
2945 rStyleName = maCellStyles.getDefaultStyleName();
2946
2947 return rStyleName;
2948 }
2949
writeFontToItemSet(SfxItemSet & rItemSet,sal_Int32 nFontId,bool bSkipPoolDefs) const2950 void StylesBuffer::writeFontToItemSet( SfxItemSet& rItemSet, sal_Int32 nFontId, bool bSkipPoolDefs ) const
2951 {
2952 if( Font* pFont = maFonts.get( nFontId ).get() )
2953 pFont->fillToItemSet( rItemSet, false, bSkipPoolDefs );
2954 }
2955
writeNumFmtToItemSet(SfxItemSet & rItemSet,sal_uInt32 nNumFmtId,bool bSkipPoolDefs) const2956 sal_uInt32 StylesBuffer::writeNumFmtToItemSet( SfxItemSet& rItemSet, sal_uInt32 nNumFmtId, bool bSkipPoolDefs ) const
2957 {
2958 return maNumFmts.fillToItemSet( rItemSet, nNumFmtId, bSkipPoolDefs );
2959 }
2960
writeBorderToItemSet(SfxItemSet & rItemSet,sal_Int32 nBorderId,bool bSkipPoolDefs) const2961 void StylesBuffer::writeBorderToItemSet( SfxItemSet& rItemSet, sal_Int32 nBorderId, bool bSkipPoolDefs ) const
2962 {
2963 if( Border* pBorder = maBorders.get( nBorderId ).get() )
2964 pBorder->fillToItemSet( rItemSet, bSkipPoolDefs );
2965 }
2966
writeFillToItemSet(SfxItemSet & rItemSet,sal_Int32 nFillId,bool bSkipPoolDefs) const2967 void StylesBuffer::writeFillToItemSet( SfxItemSet& rItemSet, sal_Int32 nFillId, bool bSkipPoolDefs ) const
2968 {
2969 if( Fill* pFill = maFills.get( nFillId ).get() )
2970 pFill->fillToItemSet( rItemSet, bSkipPoolDefs );
2971 }
2972
operator ==(const XfModel & rXfModel1,const XfModel & rXfModel2)2973 bool operator==( const XfModel& rXfModel1, const XfModel& rXfModel2 )
2974 {
2975 return ( rXfModel1.mbCellXf == rXfModel2.mbCellXf &&
2976 rXfModel1.mnStyleXfId == rXfModel2.mnStyleXfId &&
2977 rXfModel1.mbFontUsed == rXfModel2.mbFontUsed &&
2978 rXfModel1.mnFontId == rXfModel2.mnFontId &&
2979 rXfModel1.mbNumFmtUsed == rXfModel2.mbNumFmtUsed &&
2980 rXfModel1.mnNumFmtId == rXfModel2.mnNumFmtId &&
2981 rXfModel1.mbAlignUsed == rXfModel2.mbAlignUsed &&
2982 rXfModel1.mbBorderUsed == rXfModel2.mbBorderUsed &&
2983 rXfModel1.mnBorderId == rXfModel2.mnBorderId &&
2984 rXfModel1.mbAreaUsed == rXfModel2.mbAreaUsed &&
2985 rXfModel1.mnFillId == rXfModel2.mnFillId &&
2986 rXfModel1.mbProtUsed == rXfModel2.mbProtUsed );
2987 }
2988
operator ==(const Xf & rXf1,const Xf & rXf2)2989 bool operator==( const Xf& rXf1, const Xf& rXf2 )
2990 {
2991 if ( rXf1.maModel == rXf2.maModel )
2992 {
2993 if ( rXf1.maModel.mbAlignUsed )
2994 {
2995 if ( !( rXf1.maAlignment.getApiData() == rXf2.maAlignment.getApiData() ) )
2996 return false;
2997 }
2998 if ( rXf1.maModel.mbProtUsed )
2999 {
3000 if ( !( rXf1.maProtection.getApiData() == rXf2.maProtection.getApiData() ) )
3001 return false;
3002 }
3003 return true;
3004 }
3005 return false;
3006 }
3007
writeCellXfToDoc(ScDocumentImport & rDoc,const ScRange & rRange,sal_Int32 nXfId) const3008 void StylesBuffer::writeCellXfToDoc(
3009 ScDocumentImport& rDoc, const ScRange& rRange, sal_Int32 nXfId ) const
3010 {
3011 Xf* pXf = maCellXfs.get(nXfId).get();
3012 if (!pXf)
3013 return;
3014
3015 pXf->writeToDoc(rDoc, rRange);
3016 }
3017
3018 } // namespace xls
3019 } // namespace oox
3020
3021 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
3022