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