Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "xestyle.hxx"
21 :
22 : #include <iostream>
23 : #include <algorithm>
24 : #include <iterator>
25 : #include <set>
26 : #include <com/sun/star/i18n/ScriptType.hpp>
27 : #include <vcl/font.hxx>
28 : #include <svl/zformat.hxx>
29 : #include <svl/itempool.hxx>
30 : #include <svl/languageoptions.hxx>
31 : #include <sfx2/printer.hxx>
32 : #include "scitems.hxx"
33 : #include <svx/algitem.hxx>
34 : #include <editeng/boxitem.hxx>
35 : #include <editeng/lineitem.hxx>
36 : #include <svx/rotmodit.hxx>
37 : #include <editeng/colritem.hxx>
38 : #include <editeng/brushitem.hxx>
39 : #include <editeng/frmdiritem.hxx>
40 : #include <editeng/fontitem.hxx>
41 : #include <editeng/eeitem.hxx>
42 : #include <editeng/escapementitem.hxx>
43 : #include <editeng/justifyitem.hxx>
44 : #include "document.hxx"
45 : #include "stlpool.hxx"
46 : #include "stlsheet.hxx"
47 : #include "patattr.hxx"
48 : #include "attrib.hxx"
49 : #include "globstr.hrc"
50 : #include "xestring.hxx"
51 : #include "conditio.hxx"
52 :
53 : #include <oox/token/tokens.hxx>
54 : #include <boost/ptr_container/ptr_vector.hpp>
55 :
56 : using namespace ::com::sun::star;
57 : using namespace oox;
58 :
59 : // PALETTE record - color information =========================================
60 :
61 : namespace {
62 :
63 483 : sal_uInt32 lclGetWeighting( XclExpColorType eType )
64 : {
65 483 : switch( eType )
66 : {
67 124 : case EXC_COLOR_CHARTLINE: return 1;
68 : case EXC_COLOR_CELLBORDER:
69 177 : case EXC_COLOR_CHARTAREA: return 2;
70 : case EXC_COLOR_CELLTEXT:
71 : case EXC_COLOR_CHARTTEXT:
72 173 : case EXC_COLOR_CTRLTEXT: return 10;
73 : case EXC_COLOR_TABBG:
74 9 : case EXC_COLOR_CELLAREA: return 20;
75 0 : case EXC_COLOR_GRID: return 50;
76 : default: OSL_FAIL( "lclGetWeighting - unknown color type" );
77 : }
78 0 : return 1;
79 : }
80 :
81 23357 : sal_Int32 lclGetColorDistance( const Color& rColor1, const Color& rColor2 )
82 : {
83 23357 : sal_Int32 nDist = rColor1.GetRed() - rColor2.GetRed();
84 23357 : nDist *= nDist * 77;
85 23357 : sal_Int32 nDummy = rColor1.GetGreen() - rColor2.GetGreen();
86 23357 : nDist += nDummy * nDummy * 151;
87 23357 : nDummy = rColor1.GetBlue() - rColor2.GetBlue();
88 23357 : nDist += nDummy * nDummy * 28;
89 23357 : return nDist;
90 : }
91 :
92 0 : sal_uInt8 lclGetMergedColorComp( sal_uInt8 nComp1, sal_uInt32 nWeight1, sal_uInt8 nComp2, sal_uInt32 nWeight2 )
93 : {
94 0 : sal_uInt8 nComp1Dist = ::std::min< sal_uInt8 >( nComp1, 0xFF - nComp1 );
95 0 : sal_uInt8 nComp2Dist = ::std::min< sal_uInt8 >( nComp2, 0xFF - nComp2 );
96 0 : if( nComp1Dist != nComp2Dist )
97 : {
98 : /* #i36945# One of the passed RGB components is nearer at the limits (0x00 or 0xFF).
99 : Increase its weighting to prevent fading of the colors during reduction. */
100 0 : const sal_uInt8& rnCompNearer = (nComp1Dist < nComp2Dist) ? nComp1 : nComp2;
101 0 : sal_uInt32& rnWeight = (nComp1Dist < nComp2Dist) ? nWeight1 : nWeight2;
102 0 : rnWeight *= ((rnCompNearer - 0x80L) * (rnCompNearer - 0x7FL) / 0x1000L + 1);
103 : }
104 0 : sal_uInt32 nWSum = nWeight1 + nWeight2;
105 0 : return static_cast< sal_uInt8 >( (nComp1 * nWeight1 + nComp2 * nWeight2 + nWSum / 2) / nWSum );
106 : }
107 :
108 0 : void lclSetMixedColor( Color& rDest, const Color& rSrc1, const Color& rSrc2 )
109 : {
110 0 : rDest.SetRed( static_cast< sal_uInt8 >( (static_cast< sal_uInt16 >( rSrc1.GetRed() ) + rSrc2.GetRed()) / 2 ) );
111 0 : rDest.SetGreen( static_cast< sal_uInt8 >( (static_cast< sal_uInt16 >( rSrc1.GetGreen() ) + rSrc2.GetGreen()) / 2 ) );
112 0 : rDest.SetBlue( static_cast< sal_uInt8 >( (static_cast< sal_uInt16 >( rSrc1.GetBlue() ) + rSrc2.GetBlue()) / 2 ) );
113 0 : }
114 :
115 : } // namespace
116 :
117 : // additional classes for color reduction -------------------------------------
118 :
119 : namespace {
120 :
121 : /** Represents an entry in a color list.
122 :
123 : The color stores a weighting value, which increases the more the color is
124 : used in the document. Heavy-weighted colors will change less than others on
125 : color reduction.
126 : */
127 : class XclListColor
128 : {
129 356 : DECL_FIXEDMEMPOOL_NEWDEL( XclListColor )
130 :
131 : private:
132 : Color maColor; /// The color value of this palette entry.
133 : sal_uInt32 mnColorId; /// Unique color ID for color reduction.
134 : sal_uInt32 mnWeight; /// Weighting for color reduction.
135 : bool mbBaseColor; /// true = Handle as base color, (don't remove/merge).
136 :
137 : public:
138 : explicit XclListColor( const Color& rColor, sal_uInt32 nColorId );
139 :
140 : /** Returns the RGB color value of the color. */
141 2168 : inline const Color& GetColor() const { return maColor; }
142 : /** Returns the unique ID of the color. */
143 661 : inline sal_uInt32 GetColorId() const { return mnColorId; }
144 : /** Returns the current weighting of the color. */
145 0 : inline sal_uInt32 GetWeighting() const { return mnWeight; }
146 : /** Returns true, if this color is a base color, i.e. it will not be removed or merged. */
147 0 : inline bool IsBaseColor() const { return mbBaseColor; }
148 :
149 : /** Adds the passed weighting to this color. */
150 483 : inline void AddWeighting( sal_uInt32 nWeight ) { mnWeight += nWeight; }
151 : /** Merges this color with rColor, regarding weighting settings. */
152 : void Merge( const XclListColor& rColor );
153 : };
154 :
155 10 : IMPL_FIXEDMEMPOOL_NEWDEL( XclListColor )
156 :
157 178 : XclListColor::XclListColor( const Color& rColor, sal_uInt32 nColorId ) :
158 : maColor( rColor ),
159 : mnColorId( nColorId ),
160 178 : mnWeight( 0 )
161 : {
162 : mbBaseColor =
163 372 : ((rColor.GetRed() == 0x00) || (rColor.GetRed() == 0xFF)) &&
164 464 : ((rColor.GetGreen() == 0x00) || (rColor.GetGreen() == 0xFF)) &&
165 265 : ((rColor.GetBlue() == 0x00) || (rColor.GetBlue() == 0xFF));
166 178 : }
167 :
168 0 : void XclListColor::Merge( const XclListColor& rColor )
169 : {
170 0 : sal_uInt32 nWeight2 = rColor.GetWeighting();
171 : // do not change RGB value of base colors
172 0 : if( !mbBaseColor )
173 : {
174 0 : maColor.SetRed( lclGetMergedColorComp( maColor.GetRed(), mnWeight, rColor.maColor.GetRed(), nWeight2 ) );
175 0 : maColor.SetGreen( lclGetMergedColorComp( maColor.GetGreen(), mnWeight, rColor.maColor.GetGreen(), nWeight2 ) );
176 0 : maColor.SetBlue( lclGetMergedColorComp( maColor.GetBlue(), mnWeight, rColor.maColor.GetBlue(), nWeight2 ) );
177 : }
178 0 : AddWeighting( nWeight2 );
179 0 : }
180 :
181 : /** Data for each inserted original color, represented by a color ID. */
182 178 : struct XclColorIdData
183 : {
184 : Color maColor; /// The original inserted color.
185 : sal_uInt32 mnIndex; /// Maps current color ID to color list or export color vector.
186 : /** Sets the contents of this struct. */
187 178 : inline void Set( const Color& rColor, sal_uInt32 nIndex ) { maColor = rColor; mnIndex = nIndex; }
188 : };
189 :
190 : /** A color that will be written to the Excel file. */
191 : struct XclPaletteColor
192 : {
193 : Color maColor; /// Resulting color to export.
194 : bool mbUsed; /// true = Entry is used in the document.
195 :
196 4032 : inline explicit XclPaletteColor( const Color& rColor ) : maColor( rColor ), mbUsed( false ) {}
197 178 : inline void SetColor( const Color& rColor ) { maColor = rColor; mbUsed = true; }
198 : };
199 :
200 : /** Maps a color list index to a palette index.
201 : @descr Used to remap the color ID data vector from list indexes to palette indexes. */
202 : struct XclRemap
203 : {
204 : sal_uInt32 mnPalIndex; /// Index to palette.
205 : bool mbProcessed; /// true = List color already processed.
206 :
207 178 : inline explicit XclRemap() : mnPalIndex( 0 ), mbProcessed( false ) {}
208 178 : inline void SetIndex( sal_uInt32 nPalIndex )
209 178 : { mnPalIndex = nPalIndex; mbProcessed = true; }
210 : };
211 :
212 : /** Stores the nearest palette color index of a list color. */
213 : struct XclNearest
214 : {
215 : sal_uInt32 mnPalIndex; /// Index to nearest palette color.
216 : sal_Int32 mnDist; /// Distance to palette color.
217 :
218 178 : inline explicit XclNearest() : mnPalIndex( 0 ), mnDist( 0 ) {}
219 : };
220 :
221 : typedef ::std::vector< XclRemap > XclRemapVec;
222 : typedef ::std::vector< XclNearest > XclNearestVec;
223 :
224 : } // namespace
225 :
226 72 : class XclExpPaletteImpl
227 : {
228 : public:
229 : explicit XclExpPaletteImpl( const XclDefaultPalette& rDefPal );
230 :
231 : /** Inserts the color into the list and updates weighting.
232 : @param nAutoDefault The Excel palette index for automatic color.
233 : @return A unique ID for this color. */
234 : sal_uInt32 InsertColor( const Color& rColor, XclExpColorType eType, sal_uInt16 nAutoDefault = 0 );
235 : /** Returns the color ID representing a fixed Excel palette index (i.e. for auto colors). */
236 : static sal_uInt32 GetColorIdFromIndex( sal_uInt16 nIndex );
237 :
238 : /** Reduces the color list to the maximum count of the current BIFF version. */
239 : void Finalize();
240 :
241 : /** Returns the Excel palette index of the color with passed color ID. */
242 : sal_uInt16 GetColorIndex( sal_uInt32 nColorId ) const;
243 :
244 : /** Returns a foreground and background color for the two passed color IDs.
245 : @descr If rnXclPattern contains a solid pattern, this function tries to find
246 : the two best fitting colors and a mix pattern (25%, 50% or 75%) for nForeColorId.
247 : This will result in a better approximation to the passed foreground color. */
248 : void GetMixedColors(
249 : sal_uInt16& rnXclForeIx, sal_uInt16& rnXclBackIx, sal_uInt8& rnXclPattern,
250 : sal_uInt32 nForeColorId, sal_uInt32 nBackColorId ) const;
251 :
252 : /** Returns the RGB color data for a (non-zero-based) Excel palette entry.
253 : @return The color from current or default palette or COL_AUTO, if nothing else found. */
254 : ColorData GetColorData( sal_uInt16 nXclIndex ) const;
255 :
256 : /** Returns true, if all colors of the palette are equal to default palette colors. */
257 : bool IsDefaultPalette() const;
258 : /** Writes the color list (contents of the palette record) to the passed stream. */
259 : void WriteBody( XclExpStream& rStrm );
260 : void SaveXml( XclExpXmlStream& rStrm );
261 :
262 : private:
263 : /** Returns the Excel index of a 0-based color index. */
264 7211 : static inline sal_uInt16 GetXclIndex( sal_uInt32 nIndex )
265 7211 : { return static_cast< sal_uInt16 >( nIndex + EXC_COLOR_USEROFFSET ); }
266 :
267 : /** Returns the original inserted color represented by the color ID nColorId. */
268 : const Color& GetOriginalColor( sal_uInt32 nColorId ) const;
269 :
270 : /** Searches for rColor, returns the ordered insertion index for rColor in rnIndex. */
271 : XclListColor* SearchListEntry( const Color& rColor, sal_uInt32& rnIndex );
272 : /** Creates and inserts a new color list entry at the specified list position. */
273 : XclListColor* CreateListEntry( const Color& rColor, sal_uInt32 nIndex );
274 :
275 : /** Raw and fast reduction of the palette. */
276 : void RawReducePalette( sal_uInt32 nPass );
277 : /** Reduction of one color using advanced color merging based on color weighting. */
278 : void ReduceLeastUsedColor();
279 :
280 : /** Finds the least used color and returns its current list index. */
281 : sal_uInt32 GetLeastUsedListColor() const;
282 : /** Returns the list index of the color nearest to rColor.
283 : @param nIgnore List index of a color which will be ignored.
284 : @return The list index of the found color. */
285 : sal_uInt32 GetNearestListColor( const Color& rColor, sal_uInt32 nIgnore ) const;
286 : /** Returns the list index of the color nearest to the color with list index nIndex. */
287 : sal_uInt32 GetNearestListColor( sal_uInt32 nIndex ) const;
288 :
289 : /** Returns in rnIndex the palette index of the color nearest to rColor.
290 : @param bDefaultOnly true = Searches for default colors only (colors never replaced).
291 : @return The distance from passed color to found color. */
292 : sal_Int32 GetNearestPaletteColor(
293 : sal_uInt32& rnIndex,
294 : const Color& rColor, bool bDefaultOnly ) const;
295 : /** Returns in rnFirst and rnSecond the palette indexes of the two colors nearest to rColor.
296 : @return The minimum distance from passed color to found colors. */
297 : sal_Int32 GetNearPaletteColors(
298 : sal_uInt32& rnFirst, sal_uInt32& rnSecond,
299 : const Color& rColor ) const;
300 :
301 : private:
302 : typedef boost::ptr_vector< XclListColor > XclListColorList;
303 : typedef boost::shared_ptr< XclListColorList > XclListColorListRef;
304 : typedef ::std::vector< XclColorIdData > XclColorIdDataVec;
305 : typedef ::std::vector< XclPaletteColor > XclPaletteColorVec;
306 :
307 : const XclDefaultPalette& mrDefPal; /// The default palette for the current BIFF version.
308 : XclListColorListRef mxColorList; /// Working color list.
309 : XclColorIdDataVec maColorIdDataVec; /// Data of all CIDs.
310 : XclPaletteColorVec maPalette; /// Contains resulting colors to export.
311 : sal_uInt32 mnLastIdx; /// Last insertion index for search opt.
312 : };
313 :
314 : const sal_uInt32 EXC_PAL_INDEXBASE = 0xFFFF0000;
315 : const sal_uInt32 EXC_PAL_MAXRAWSIZE = 1024;
316 :
317 72 : XclExpPaletteImpl::XclExpPaletteImpl( const XclDefaultPalette& rDefPal ) :
318 : mrDefPal( rDefPal ),
319 72 : mxColorList( new XclListColorList ),
320 144 : mnLastIdx( 0 )
321 : {
322 : // initialize maPalette with default colors
323 72 : sal_uInt16 nCount = static_cast< sal_uInt16 >( mrDefPal.GetColorCount() );
324 72 : maPalette.reserve( nCount );
325 4104 : for( sal_uInt16 nIdx = 0; nIdx < nCount; ++nIdx )
326 4032 : maPalette.push_back( XclPaletteColor( mrDefPal.GetDefColor( GetXclIndex( nIdx ) ) ) );
327 :
328 72 : InsertColor( Color( COL_BLACK ), EXC_COLOR_CELLTEXT );
329 72 : }
330 :
331 607 : sal_uInt32 XclExpPaletteImpl::InsertColor( const Color& rColor, XclExpColorType eType, sal_uInt16 nAutoDefault )
332 : {
333 607 : if( rColor.GetColor() == COL_AUTO )
334 124 : return GetColorIdFromIndex( nAutoDefault );
335 :
336 483 : sal_uInt32 nFoundIdx = 0;
337 483 : XclListColor* pEntry = SearchListEntry( rColor, nFoundIdx );
338 483 : if( !pEntry || (pEntry->GetColor() != rColor) )
339 178 : pEntry = CreateListEntry( rColor, nFoundIdx );
340 483 : pEntry->AddWeighting( lclGetWeighting( eType ) );
341 :
342 483 : return pEntry->GetColorId();
343 : }
344 :
345 7746 : sal_uInt32 XclExpPaletteImpl::GetColorIdFromIndex( sal_uInt16 nIndex )
346 : {
347 7746 : return EXC_PAL_INDEXBASE | nIndex;
348 : }
349 :
350 72 : void XclExpPaletteImpl::Finalize()
351 : {
352 : // --- build initial color ID data vector (maColorIdDataVec) ---
353 :
354 72 : sal_uInt32 nCount = mxColorList->size();
355 72 : maColorIdDataVec.resize( nCount );
356 250 : for( sal_uInt32 nIdx = 0; nIdx < nCount; ++nIdx )
357 : {
358 178 : const XclListColor& listColor = mxColorList->at( nIdx );
359 178 : maColorIdDataVec[ listColor.GetColorId() ].Set( listColor.GetColor(), nIdx );
360 : }
361 :
362 : // --- loop as long as current color count does not fit into palette of current BIFF ---
363 :
364 : // phase 1: raw reduction (performance reasons, #i36945#)
365 72 : sal_uInt32 nPass = 0;
366 144 : while( mxColorList->size() > EXC_PAL_MAXRAWSIZE )
367 0 : RawReducePalette( nPass++ );
368 :
369 : // phase 2: precise reduction using advanced color merging based on color weighting
370 144 : while( mxColorList->size() > mrDefPal.GetColorCount() )
371 0 : ReduceLeastUsedColor();
372 :
373 : // --- use default palette and replace colors with nearest used colors ---
374 :
375 72 : nCount = mxColorList->size();
376 72 : XclRemapVec aRemapVec( nCount );
377 144 : XclNearestVec aNearestVec( nCount );
378 :
379 : // in each run: search the best fitting color and replace a default color with it
380 250 : for( sal_uInt32 nRun = 0; nRun < nCount; ++nRun )
381 : {
382 : sal_uInt32 nIndex;
383 : // find nearest unused default color for each unprocessed list color
384 852 : for( nIndex = 0; nIndex < nCount; ++nIndex )
385 674 : aNearestVec[ nIndex ].mnDist = aRemapVec[ nIndex ].mbProcessed ? SAL_MAX_INT32 :
386 674 : GetNearestPaletteColor( aNearestVec[ nIndex ].mnPalIndex, mxColorList->at( nIndex ).GetColor(), true );
387 : // find the list color which is nearest to a default color
388 178 : sal_uInt32 nFound = 0;
389 674 : for( nIndex = 1; nIndex < nCount; ++nIndex )
390 496 : if( aNearestVec[ nIndex ].mnDist < aNearestVec[ nFound ].mnDist )
391 156 : nFound = nIndex;
392 : // replace default color with list color
393 178 : sal_uInt32 nNearest = aNearestVec[ nFound ].mnPalIndex;
394 : OSL_ENSURE( nNearest < maPalette.size(), "XclExpPaletteImpl::Finalize - algorithm error" );
395 178 : maPalette[ nNearest ].SetColor( mxColorList->at( nFound ).GetColor() );
396 178 : aRemapVec[ nFound ].SetIndex( nNearest );
397 : }
398 :
399 : // remap color ID data map (maColorIdDataVec) from list indexes to palette indexes
400 250 : for( XclColorIdDataVec::iterator aIt = maColorIdDataVec.begin(), aEnd = maColorIdDataVec.end(); aIt != aEnd; ++aIt )
401 250 : aIt->mnIndex = aRemapVec[ aIt->mnIndex ].mnPalIndex;
402 72 : }
403 :
404 11936 : sal_uInt16 XclExpPaletteImpl::GetColorIndex( sal_uInt32 nColorId ) const
405 : {
406 11936 : sal_uInt16 nRet = 0;
407 11936 : if( nColorId >= EXC_PAL_INDEXBASE )
408 11776 : nRet = static_cast< sal_uInt16 >( nColorId & ~EXC_PAL_INDEXBASE );
409 160 : else if( nColorId < maColorIdDataVec.size() )
410 160 : nRet = GetXclIndex( maColorIdDataVec[ nColorId ].mnIndex );
411 11936 : return nRet;
412 : }
413 :
414 1670 : void XclExpPaletteImpl::GetMixedColors(
415 : sal_uInt16& rnXclForeIx, sal_uInt16& rnXclBackIx, sal_uInt8& rnXclPattern,
416 : sal_uInt32 nForeColorId, sal_uInt32 nBackColorId ) const
417 : {
418 1670 : rnXclForeIx = GetColorIndex( nForeColorId );
419 1670 : rnXclBackIx = GetColorIndex( nBackColorId );
420 1670 : if( (rnXclPattern != EXC_PATT_SOLID) || (nForeColorId >= maColorIdDataVec.size()) )
421 3340 : return;
422 :
423 : // now we have solid pattern, and a defined foreground (background doesn't care for solid pattern)
424 :
425 : sal_uInt32 nIndex1, nIndex2;
426 0 : Color aForeColor( GetOriginalColor( nForeColorId ) );
427 0 : sal_Int32 nFirstDist = GetNearPaletteColors( nIndex1, nIndex2, aForeColor );
428 0 : if( (nIndex1 >= maPalette.size()) || (nIndex2 >= maPalette.size()) )
429 0 : return;
430 :
431 0 : Color aColorArr[ 5 ];
432 0 : aColorArr[ 0 ] = maPalette[ nIndex1 ].maColor;
433 0 : aColorArr[ 4 ] = maPalette[ nIndex2 ].maColor;
434 0 : lclSetMixedColor( aColorArr[ 2 ], aColorArr[ 0 ], aColorArr[ 4 ] );
435 0 : lclSetMixedColor( aColorArr[ 1 ], aColorArr[ 0 ], aColorArr[ 2 ] );
436 0 : lclSetMixedColor( aColorArr[ 3 ], aColorArr[ 2 ], aColorArr[ 4 ] );
437 :
438 0 : sal_Int32 nMinDist = nFirstDist;
439 0 : sal_uInt32 nMinIndex = 0;
440 0 : for( sal_uInt32 nCnt = 1; nCnt < 4; ++nCnt )
441 : {
442 0 : sal_Int32 nDist = lclGetColorDistance( aForeColor, aColorArr[ nCnt ] );
443 0 : if( nDist < nMinDist )
444 : {
445 0 : nMinDist = nDist;
446 0 : nMinIndex = nCnt;
447 : }
448 : }
449 0 : rnXclForeIx = GetXclIndex( nIndex1 );
450 0 : rnXclBackIx = GetXclIndex( nIndex2 );
451 0 : if( nMinDist < nFirstDist )
452 : {
453 0 : switch( nMinIndex )
454 : {
455 0 : case 1: rnXclPattern = EXC_PATT_75_PERC; break;
456 0 : case 2: rnXclPattern = EXC_PATT_50_PERC; break;
457 0 : case 3: rnXclPattern = EXC_PATT_25_PERC; break;
458 : }
459 : }
460 : }
461 :
462 510 : ColorData XclExpPaletteImpl::GetColorData( sal_uInt16 nXclIndex ) const
463 : {
464 510 : if( nXclIndex >= EXC_COLOR_USEROFFSET )
465 : {
466 109 : sal_uInt32 nIdx = nXclIndex - EXC_COLOR_USEROFFSET;
467 109 : if( nIdx < maPalette.size() )
468 109 : return maPalette[ nIdx ].maColor.GetColor();
469 : }
470 401 : return mrDefPal.GetDefColorData( nXclIndex );
471 : }
472 :
473 72 : bool XclExpPaletteImpl::IsDefaultPalette() const
474 : {
475 72 : bool bDefault = true;
476 3091 : for( sal_uInt32 nIdx = 0, nSize = static_cast< sal_uInt32 >( maPalette.size() ); bDefault && (nIdx < nSize); ++nIdx )
477 3019 : bDefault = maPalette[ nIdx ].maColor == mrDefPal.GetDefColor( GetXclIndex( nIdx ) );
478 72 : return bDefault;
479 : }
480 :
481 1 : void XclExpPaletteImpl::WriteBody( XclExpStream& rStrm )
482 : {
483 1 : rStrm << static_cast< sal_uInt16 >( maPalette.size() );
484 57 : for( XclPaletteColorVec::const_iterator aIt = maPalette.begin(), aEnd = maPalette.end(); aIt != aEnd; ++aIt )
485 56 : rStrm << aIt->maColor;
486 1 : }
487 :
488 27 : void XclExpPaletteImpl::SaveXml( XclExpXmlStream& rStrm )
489 : {
490 27 : if( !maPalette.size() )
491 27 : return;
492 :
493 27 : sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
494 27 : rStyleSheet->startElement( XML_colors, FSEND );
495 27 : rStyleSheet->startElement( XML_indexedColors, FSEND );
496 1539 : for( XclPaletteColorVec::const_iterator aIt = maPalette.begin(), aEnd = maPalette.end(); aIt != aEnd; ++aIt )
497 : rStyleSheet->singleElement( XML_rgbColor,
498 1512 : XML_rgb, XclXmlUtils::ToOString( aIt->maColor ).getStr(),
499 1512 : FSEND );
500 27 : rStyleSheet->endElement( XML_indexedColors );
501 27 : rStyleSheet->endElement( XML_colors );
502 : }
503 :
504 0 : const Color& XclExpPaletteImpl::GetOriginalColor( sal_uInt32 nColorId ) const
505 : {
506 0 : if( nColorId < maColorIdDataVec.size() )
507 0 : return maColorIdDataVec[ nColorId ].maColor;
508 0 : return maPalette[ 0 ].maColor;
509 : }
510 :
511 483 : XclListColor* XclExpPaletteImpl::SearchListEntry( const Color& rColor, sal_uInt32& rnIndex )
512 : {
513 483 : rnIndex = 0;
514 :
515 483 : if (mxColorList->empty())
516 72 : return NULL;
517 :
518 411 : XclListColor* pEntry = NULL;
519 :
520 : // search optimization for equal-colored objects occurring repeatedly
521 411 : if (mnLastIdx < mxColorList->size())
522 : {
523 411 : pEntry = &(*mxColorList)[mnLastIdx];
524 411 : if( pEntry->GetColor() == rColor )
525 : {
526 239 : rnIndex = mnLastIdx;
527 239 : return pEntry;
528 : }
529 : }
530 :
531 : // binary search for color
532 172 : sal_uInt32 nBegIdx = 0;
533 172 : sal_uInt32 nEndIdx = mxColorList->size();
534 172 : bool bFound = false;
535 659 : while( !bFound && (nBegIdx < nEndIdx) )
536 : {
537 315 : rnIndex = (nBegIdx + nEndIdx) / 2;
538 315 : pEntry = &(*mxColorList)[rnIndex];
539 315 : bFound = pEntry->GetColor() == rColor;
540 315 : if( !bFound )
541 : {
542 249 : if( pEntry->GetColor().GetColor() < rColor.GetColor() )
543 150 : nBegIdx = rnIndex + 1;
544 : else
545 99 : nEndIdx = rnIndex;
546 : }
547 : }
548 :
549 : // not found - use end of range as new insertion position
550 172 : if( !bFound )
551 106 : rnIndex = nEndIdx;
552 :
553 172 : mnLastIdx = rnIndex;
554 172 : return pEntry;
555 : }
556 :
557 178 : XclListColor* XclExpPaletteImpl::CreateListEntry( const Color& rColor, sal_uInt32 nIndex )
558 : {
559 178 : XclListColor* pEntry = new XclListColor( rColor, mxColorList->size() );
560 178 : XclListColorList::iterator itr = mxColorList->begin();
561 178 : ::std::advance(itr, nIndex);
562 178 : mxColorList->insert(itr, pEntry);
563 178 : return pEntry;
564 : }
565 :
566 0 : void XclExpPaletteImpl::RawReducePalette( sal_uInt32 nPass )
567 : {
568 : /* Fast palette reduction - in each call of this function one RGB component
569 : of each color is reduced to a lower number of distinct values.
570 : Pass 0: Blue is reduced to 128 distinct values.
571 : Pass 1: Red is reduced to 128 distinct values.
572 : Pass 2: Green is reduced to 128 distinct values.
573 : Pass 3: Blue is reduced to 64 distinct values.
574 : Pass 4: Red is reduced to 64 distinct values.
575 : Pass 5: Green is reduced to 64 distinct values.
576 : And so on...
577 : */
578 :
579 0 : XclListColorListRef xOldList = mxColorList;
580 0 : mxColorList.reset( new XclListColorList );
581 :
582 : // maps old list indexes to new list indexes, used to update maColorIdDataVec
583 0 : ScfUInt32Vec aListIndexMap;
584 0 : aListIndexMap.reserve( xOldList->size() );
585 :
586 : // preparations
587 : sal_uInt8 nR, nG, nB;
588 0 : sal_uInt8& rnComp = ((nPass % 3 == 0) ? nB : ((nPass % 3 == 1) ? nR : nG));
589 0 : nPass /= 3;
590 : OSL_ENSURE( nPass < 7, "XclExpPaletteImpl::RawReducePalette - reduction not terminated" );
591 :
592 : static const sal_uInt8 spnFactor2[] = { 0x81, 0x82, 0x84, 0x88, 0x92, 0xAA, 0xFF };
593 0 : sal_uInt8 nFactor1 = static_cast< sal_uInt8 >( 0x02 << nPass );
594 0 : sal_uInt8 nFactor2 = spnFactor2[ nPass ];
595 0 : sal_uInt8 nFactor3 = static_cast< sal_uInt8 >( 0x40 >> nPass );
596 :
597 : // process each color in the old color list
598 0 : for( sal_uInt32 nIdx = 0, nCount = xOldList->size(); nIdx < nCount; ++nIdx )
599 : {
600 : // get the old list entry
601 0 : const XclListColor* pOldEntry = &(xOldList->at( nIdx ));
602 0 : nR = pOldEntry->GetColor().GetRed();
603 0 : nG = pOldEntry->GetColor().GetGreen();
604 0 : nB = pOldEntry->GetColor().GetBlue();
605 :
606 : /* Calculate the new RGB component (rnComp points to one of nR, nG, nB).
607 : Using integer arithmetic with its rounding errors, the results of
608 : this calculation are always exactly in the range 0x00 to 0xFF
609 : (simply cutting the lower bits would darken the colors slightly). */
610 0 : sal_uInt32 nNewComp = rnComp;
611 0 : nNewComp /= nFactor1;
612 0 : nNewComp *= nFactor2;
613 0 : nNewComp /= nFactor3;
614 0 : rnComp = static_cast< sal_uInt8 >( nNewComp );
615 0 : Color aNewColor( nR, nG, nB );
616 :
617 : // find or insert the new color
618 0 : sal_uInt32 nFoundIdx = 0;
619 0 : XclListColor* pNewEntry = SearchListEntry( aNewColor, nFoundIdx );
620 0 : if( !pNewEntry || (pNewEntry->GetColor() != aNewColor) )
621 0 : pNewEntry = CreateListEntry( aNewColor, nFoundIdx );
622 0 : pNewEntry->AddWeighting( pOldEntry->GetWeighting() );
623 0 : aListIndexMap.push_back( nFoundIdx );
624 : }
625 :
626 : // update color ID data map (maps color IDs to color list indexes), replace old by new list indexes
627 0 : for( XclColorIdDataVec::iterator aIt = maColorIdDataVec.begin(), aEnd = maColorIdDataVec.end(); aIt != aEnd; ++aIt )
628 0 : aIt->mnIndex = aListIndexMap[ aIt->mnIndex ];
629 0 : }
630 :
631 0 : void XclExpPaletteImpl::ReduceLeastUsedColor()
632 : {
633 : // find a list color to remove
634 0 : sal_uInt32 nRemove = GetLeastUsedListColor();
635 : // find its nearest neighbor
636 0 : sal_uInt32 nKeep = GetNearestListColor( nRemove );
637 :
638 : // merge both colors to one color, remove one color from list
639 0 : XclListColor* pKeepEntry = &mxColorList->at(nKeep);
640 0 : XclListColor* pRemoveEntry = &mxColorList->at(nRemove);
641 0 : if( pKeepEntry && pRemoveEntry )
642 : {
643 : // merge both colors (if pKeepEntry is a base color, it will not change)
644 0 : pKeepEntry->Merge( *pRemoveEntry );
645 : // remove the less used color, adjust nKeep index if kept color follows removed color
646 0 : XclListColorList::iterator itr = mxColorList->begin();
647 0 : ::std::advance(itr, nRemove);
648 0 : mxColorList->erase(itr);
649 0 : if( nKeep > nRemove ) --nKeep;
650 :
651 : // recalculate color ID data map (maps color IDs to color list indexes)
652 0 : for( XclColorIdDataVec::iterator aIt = maColorIdDataVec.begin(), aEnd = maColorIdDataVec.end(); aIt != aEnd; ++aIt )
653 : {
654 0 : if( aIt->mnIndex > nRemove )
655 0 : --aIt->mnIndex;
656 0 : else if( aIt->mnIndex == nRemove )
657 0 : aIt->mnIndex = nKeep;
658 : }
659 : }
660 0 : }
661 :
662 0 : sal_uInt32 XclExpPaletteImpl::GetLeastUsedListColor() const
663 : {
664 0 : sal_uInt32 nFound = 0;
665 0 : sal_uInt32 nMinW = SAL_MAX_UINT32;
666 :
667 0 : for( sal_uInt32 nIdx = 0, nCount = mxColorList->size(); nIdx < nCount; ++nIdx )
668 : {
669 0 : XclListColor& pEntry = mxColorList->at( nIdx );
670 : // ignore the base colors
671 0 : if( !pEntry.IsBaseColor() && (pEntry.GetWeighting() < nMinW) )
672 : {
673 0 : nFound = nIdx;
674 0 : nMinW = pEntry.GetWeighting();
675 : }
676 : }
677 0 : return nFound;
678 : }
679 :
680 0 : sal_uInt32 XclExpPaletteImpl::GetNearestListColor( const Color& rColor, sal_uInt32 nIgnore ) const
681 : {
682 0 : sal_uInt32 nFound = 0;
683 0 : sal_Int32 nMinD = SAL_MAX_INT32;
684 :
685 0 : for( sal_uInt32 nIdx = 0, nCount = mxColorList->size(); nIdx < nCount; ++nIdx )
686 : {
687 0 : if( nIdx != nIgnore )
688 : {
689 0 : if( XclListColor* pEntry = &mxColorList->at(nIdx) )
690 : {
691 0 : sal_Int32 nDist = lclGetColorDistance( rColor, pEntry->GetColor() );
692 0 : if( nDist < nMinD )
693 : {
694 0 : nFound = nIdx;
695 0 : nMinD = nDist;
696 : }
697 : }
698 : }
699 : }
700 0 : return nFound;
701 : }
702 :
703 0 : sal_uInt32 XclExpPaletteImpl::GetNearestListColor( sal_uInt32 nIndex ) const
704 : {
705 0 : if (nIndex >= mxColorList->size())
706 0 : return 0;
707 0 : XclListColor* pEntry = &mxColorList->at(nIndex);
708 0 : return GetNearestListColor( pEntry->GetColor(), nIndex );
709 : }
710 :
711 426 : sal_Int32 XclExpPaletteImpl::GetNearestPaletteColor(
712 : sal_uInt32& rnIndex, const Color& rColor, bool bDefaultOnly ) const
713 : {
714 426 : rnIndex = 0;
715 426 : sal_Int32 nDist = SAL_MAX_INT32;
716 :
717 24282 : for( XclPaletteColorVec::const_iterator aIt = maPalette.begin(), aEnd = maPalette.end();
718 : aIt != aEnd; ++aIt )
719 : {
720 23856 : if( !bDefaultOnly || !aIt->mbUsed )
721 : {
722 23357 : sal_Int32 nCurrDist = lclGetColorDistance( rColor, aIt->maColor );
723 23357 : if( nCurrDist < nDist )
724 : {
725 2089 : rnIndex = aIt - maPalette.begin();
726 2089 : nDist = nCurrDist;
727 : }
728 : }
729 : }
730 426 : return nDist;
731 : }
732 :
733 0 : sal_Int32 XclExpPaletteImpl::GetNearPaletteColors(
734 : sal_uInt32& rnFirst, sal_uInt32& rnSecond, const Color& rColor ) const
735 : {
736 0 : rnFirst = rnSecond = 0;
737 0 : sal_Int32 nDist1 = SAL_MAX_INT32;
738 0 : sal_Int32 nDist2 = SAL_MAX_INT32;
739 :
740 0 : for( XclPaletteColorVec::const_iterator aIt = maPalette.begin(), aEnd = maPalette.end();
741 : aIt != aEnd; ++aIt )
742 : {
743 0 : sal_Int32 nCurrDist = lclGetColorDistance( rColor, aIt->maColor );
744 0 : if( nCurrDist < nDist1 )
745 : {
746 0 : rnSecond = rnFirst;
747 0 : nDist2 = nDist1;
748 0 : rnFirst = aIt - maPalette.begin();
749 0 : nDist1 = nCurrDist;
750 : }
751 0 : else if( nCurrDist < nDist2 )
752 : {
753 0 : rnSecond = aIt - maPalette.begin();
754 0 : nDist2 = nCurrDist;
755 : }
756 : }
757 0 : return nDist1;
758 : }
759 :
760 72 : XclExpPalette::XclExpPalette( const XclExpRoot& rRoot ) :
761 : XclDefaultPalette( rRoot ),
762 72 : XclExpRecord( EXC_ID_PALETTE )
763 : {
764 72 : mxImpl.reset( new XclExpPaletteImpl( *this ) );
765 72 : SetRecSize( GetColorCount() * 4 + 2 );
766 72 : }
767 :
768 144 : XclExpPalette::~XclExpPalette()
769 : {
770 144 : }
771 :
772 535 : sal_uInt32 XclExpPalette::InsertColor( const Color& rColor, XclExpColorType eType, sal_uInt16 nAutoDefault )
773 : {
774 535 : return mxImpl->InsertColor( rColor, eType, nAutoDefault );
775 : }
776 :
777 7622 : sal_uInt32 XclExpPalette::GetColorIdFromIndex( sal_uInt16 nIndex )
778 : {
779 7622 : return XclExpPaletteImpl::GetColorIdFromIndex( nIndex );
780 : }
781 :
782 72 : void XclExpPalette::Finalize()
783 : {
784 72 : mxImpl->Finalize();
785 72 : }
786 :
787 8596 : sal_uInt16 XclExpPalette::GetColorIndex( sal_uInt32 nColorId ) const
788 : {
789 8596 : return mxImpl->GetColorIndex( nColorId );
790 : }
791 :
792 1670 : void XclExpPalette::GetMixedColors(
793 : sal_uInt16& rnXclForeIx, sal_uInt16& rnXclBackIx, sal_uInt8& rnXclPattern,
794 : sal_uInt32 nForeColorId, sal_uInt32 nBackColorId ) const
795 : {
796 1670 : return mxImpl->GetMixedColors( rnXclForeIx, rnXclBackIx, rnXclPattern, nForeColorId, nBackColorId );
797 : }
798 :
799 510 : ColorData XclExpPalette::GetColorData( sal_uInt16 nXclIndex ) const
800 : {
801 510 : return mxImpl->GetColorData( nXclIndex );
802 : }
803 :
804 17 : void XclExpPalette::Save( XclExpStream& rStrm )
805 : {
806 17 : if( !mxImpl->IsDefaultPalette() )
807 1 : XclExpRecord::Save( rStrm );
808 17 : }
809 :
810 55 : void XclExpPalette::SaveXml( XclExpXmlStream& rStrm )
811 : {
812 55 : if( !mxImpl->IsDefaultPalette() )
813 27 : mxImpl->SaveXml( rStrm );
814 55 : }
815 :
816 1 : void XclExpPalette::WriteBody( XclExpStream& rStrm )
817 : {
818 1 : mxImpl->WriteBody( rStrm );
819 1 : }
820 :
821 : // FONT record - font information =============================================
822 :
823 : namespace {
824 :
825 : typedef ::std::pair< sal_uInt16, sal_Int16 > WhichAndScript;
826 :
827 34 : sal_Int16 lclCheckFontItems( const SfxItemSet& rItemSet,
828 : const WhichAndScript& rWAS1, const WhichAndScript& rWAS2, const WhichAndScript& rWAS3 )
829 : {
830 34 : if( ScfTools::CheckItem( rItemSet, rWAS1.first, false ) ) return rWAS1.second;
831 22 : if( ScfTools::CheckItem( rItemSet, rWAS2.first, false ) ) return rWAS2.second;
832 22 : if( ScfTools::CheckItem( rItemSet, rWAS3.first, false ) ) return rWAS3.second;
833 22 : return 0;
834 : };
835 :
836 : } // namespace
837 :
838 22 : sal_Int16 XclExpFontHelper::GetFirstUsedScript( const XclExpRoot& rRoot, const SfxItemSet& rItemSet )
839 : {
840 : namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
841 :
842 : /* #i17050# #i107170# We need to determine which font items are set in the
843 : item set, and which script type we should prefer according to the
844 : current language settings. */
845 :
846 : static const WhichAndScript WAS_LATIN( ATTR_FONT, ::com::sun::star::i18n::ScriptType::LATIN );
847 : static const WhichAndScript WAS_ASIAN( ATTR_CJK_FONT, ::com::sun::star::i18n::ScriptType::ASIAN );
848 : static const WhichAndScript WAS_CMPLX( ATTR_CTL_FONT, ::com::sun::star::i18n::ScriptType::COMPLEX );
849 :
850 : /* do not let a font from a parent style override an explicit
851 : cell font. */
852 :
853 22 : sal_Int16 nDefScript = rRoot.GetDefApiScript();
854 22 : sal_Int16 nScript = 0;
855 22 : const SfxItemSet* pCurrSet = &rItemSet;
856 :
857 78 : while( (nScript == 0) && pCurrSet )
858 : {
859 34 : switch( nDefScript )
860 : {
861 : case ApiScriptType::LATIN:
862 34 : nScript = lclCheckFontItems( *pCurrSet, WAS_LATIN, WAS_CMPLX, WAS_ASIAN );
863 34 : break;
864 : case ApiScriptType::ASIAN:
865 0 : nScript = lclCheckFontItems( *pCurrSet, WAS_ASIAN, WAS_CMPLX, WAS_LATIN );
866 0 : break;
867 : case ApiScriptType::COMPLEX:
868 0 : nScript = lclCheckFontItems( *pCurrSet, WAS_CMPLX, WAS_ASIAN, WAS_LATIN );
869 0 : break;
870 : default:
871 : OSL_FAIL( "XclExpFontHelper::GetFirstUsedScript - unknown script type" );
872 0 : nScript = ApiScriptType::LATIN;
873 : };
874 34 : pCurrSet = pCurrSet->GetParent();
875 : }
876 :
877 22 : if (nScript == 0)
878 10 : nScript = nDefScript;
879 :
880 22 : if (nScript == 0)
881 : {
882 : OSL_FAIL( "XclExpFontHelper::GetFirstUsedScript - unknown script type" );
883 0 : nScript = ApiScriptType::LATIN;
884 : }
885 :
886 22 : return nScript;
887 : }
888 :
889 737 : vcl::Font XclExpFontHelper::GetFontFromItemSet( const XclExpRoot& rRoot, const SfxItemSet& rItemSet, sal_Int16 nScript )
890 : {
891 : // if WEAK is passed, guess script type from existing items in the item set
892 737 : if( nScript == css::i18n::ScriptType::WEAK )
893 12 : nScript = GetFirstUsedScript( rRoot, rItemSet );
894 :
895 : // convert to core script type constants
896 737 : SvtScriptType nScScript = SvtLanguageOptions::FromI18NToSvtScriptType(nScript);
897 :
898 : // fill the font object
899 737 : vcl::Font aFont;
900 737 : ScPatternAttr::GetFont( aFont, rItemSet, SC_AUTOCOL_RAW, 0, 0, 0, nScScript );
901 737 : return aFont;
902 : }
903 :
904 10 : ScDxfFont XclExpFontHelper::GetDxfFontFromItemSet(const XclExpRoot& rRoot, const SfxItemSet& rItemSet)
905 : {
906 10 : sal_Int16 nScript = GetFirstUsedScript(rRoot, rItemSet);
907 :
908 : // convert to core script type constants
909 10 : SvtScriptType nScScript = SvtLanguageOptions::FromI18NToSvtScriptType(nScript);
910 10 : return ScPatternAttr::GetDxfFont(rItemSet, nScScript);
911 : }
912 :
913 268 : bool XclExpFontHelper::CheckItems( const XclExpRoot& rRoot, const SfxItemSet& rItemSet, sal_Int16 nScript, bool bDeep )
914 : {
915 : static const sal_uInt16 pnCommonIds[] = {
916 : ATTR_FONT_UNDERLINE, ATTR_FONT_CROSSEDOUT, ATTR_FONT_CONTOUR,
917 : ATTR_FONT_SHADOWED, ATTR_FONT_COLOR, ATTR_FONT_LANGUAGE, 0 };
918 : static const sal_uInt16 pnLatinIds[] = {
919 : ATTR_FONT, ATTR_FONT_HEIGHT, ATTR_FONT_WEIGHT, ATTR_FONT_POSTURE, 0 };
920 : static const sal_uInt16 pnAsianIds[] = {
921 : ATTR_CJK_FONT, ATTR_CJK_FONT_HEIGHT, ATTR_CJK_FONT_WEIGHT, ATTR_CJK_FONT_POSTURE, 0 };
922 : static const sal_uInt16 pnComplexIds[] = {
923 : ATTR_CTL_FONT, ATTR_CTL_FONT_HEIGHT, ATTR_CTL_FONT_WEIGHT, ATTR_CTL_FONT_POSTURE, 0 };
924 :
925 268 : bool bUsed = ScfTools::CheckItems( rItemSet, pnCommonIds, bDeep );
926 268 : if( !bUsed )
927 : {
928 : namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
929 : // if WEAK is passed, guess script type from existing items in the item set
930 200 : if( nScript == ApiScriptType::WEAK )
931 0 : nScript = GetFirstUsedScript( rRoot, rItemSet );
932 : // check the correct items
933 200 : switch( nScript )
934 : {
935 200 : case ApiScriptType::LATIN: bUsed = ScfTools::CheckItems( rItemSet, pnLatinIds, bDeep ); break;
936 0 : case ApiScriptType::ASIAN: bUsed = ScfTools::CheckItems( rItemSet, pnAsianIds, bDeep ); break;
937 0 : case ApiScriptType::COMPLEX: bUsed = ScfTools::CheckItems( rItemSet, pnComplexIds, bDeep ); break;
938 : default: OSL_FAIL( "XclExpFontHelper::CheckItems - unknown script type" );
939 : }
940 : }
941 268 : return bUsed;
942 : }
943 :
944 : namespace {
945 :
946 985 : sal_uInt32 lclCalcHash( const XclFontData& rFontData )
947 : {
948 985 : sal_uInt32 nHash = rFontData.maName.getLength();
949 985 : nHash += rFontData.maColor.GetColor() * 2;
950 985 : nHash += rFontData.mnWeight * 3;
951 985 : nHash += rFontData.mnCharSet * 5;
952 985 : nHash += rFontData.mnFamily * 7;
953 985 : nHash += rFontData.mnHeight * 11;
954 985 : nHash += rFontData.mnUnderline * 13;
955 985 : nHash += rFontData.mnEscapem * 17;
956 985 : if( rFontData.mbItalic ) nHash += 19;
957 985 : if( rFontData.mbStrikeout ) nHash += 23;
958 985 : if( rFontData.mbOutline ) nHash += 29;
959 985 : if( rFontData.mbShadow ) nHash += 31;
960 985 : return nHash;
961 : }
962 :
963 : } // namespace
964 :
965 225 : XclExpFont::XclExpFont( const XclExpRoot& rRoot,
966 : const XclFontData& rFontData, XclExpColorType eColorType ) :
967 : XclExpRecord( EXC_ID2_FONT, 14 ),
968 : XclExpRoot( rRoot ),
969 225 : maData( rFontData )
970 : {
971 : // insert font color into palette
972 225 : mnColorId = rRoot.GetPalette().InsertColor( rFontData.maColor, eColorType, EXC_COLOR_FONTAUTO );
973 : // hash value for faster comparison
974 225 : mnHash = lclCalcHash( maData );
975 : // record size
976 225 : sal_Int32 nStrLen = maData.maName.getLength();
977 225 : SetRecSize( ((GetBiff() == EXC_BIFF8) ? (nStrLen * 2 + 1) : nStrLen) + 15 );
978 225 : }
979 :
980 2119 : bool XclExpFont::Equals( const XclFontData& rFontData, sal_uInt32 nHash ) const
981 : {
982 2119 : return (mnHash == nHash) && (maData == rFontData);
983 : }
984 :
985 276 : void XclExpFont::SaveXml( XclExpXmlStream& rStrm )
986 : {
987 276 : sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
988 276 : rStyleSheet->startElement( XML_font, FSEND );
989 276 : XclXmlUtils::WriteFontData( rStyleSheet, maData, XML_name );
990 : // OOXTODO: XML_scheme; //scheme/@val values: "major", "minor", "none"
991 276 : rStyleSheet->endElement( XML_font );
992 276 : }
993 :
994 : // private --------------------------------------------------------------------
995 :
996 76 : void XclExpFont::WriteBody( XclExpStream& rStrm )
997 : {
998 76 : sal_uInt16 nAttr = EXC_FONTATTR_NONE;
999 76 : ::set_flag( nAttr, EXC_FONTATTR_ITALIC, maData.mbItalic );
1000 76 : ::set_flag( nAttr, EXC_FONTATTR_STRIKEOUT, maData.mbStrikeout );
1001 76 : ::set_flag( nAttr, EXC_FONTATTR_OUTLINE, maData.mbOutline );
1002 76 : ::set_flag( nAttr, EXC_FONTATTR_SHADOW, maData.mbShadow );
1003 :
1004 : OSL_ENSURE( maData.maName.getLength() < 256, "XclExpFont::WriteBody - font name too long" );
1005 76 : XclExpString aFontName;
1006 76 : if( GetBiff() <= EXC_BIFF5 )
1007 0 : aFontName.AssignByte( maData.maName, GetTextEncoding(), EXC_STR_8BITLENGTH );
1008 : else
1009 76 : aFontName.Assign( maData.maName, EXC_STR_FORCEUNICODE | EXC_STR_8BITLENGTH );
1010 :
1011 76 : rStrm << maData.mnHeight
1012 152 : << nAttr
1013 152 : << GetPalette().GetColorIndex( mnColorId )
1014 152 : << maData.mnWeight
1015 152 : << maData.mnEscapem
1016 152 : << maData.mnUnderline
1017 152 : << maData.mnFamily
1018 152 : << maData.mnCharSet
1019 76 : << sal_uInt8( 0 )
1020 76 : << aFontName;
1021 76 : }
1022 :
1023 10 : XclExpDxfFont::XclExpDxfFont(const XclExpRoot& rRoot,
1024 : const SfxItemSet& rItemSet):
1025 10 : XclExpRoot(rRoot)
1026 : {
1027 10 : maDxfData = XclExpFontHelper::GetDxfFontFromItemSet(rRoot, rItemSet);
1028 10 : }
1029 :
1030 : namespace {
1031 :
1032 0 : const char* getUnderlineOOXValue(FontUnderline eUnderline)
1033 : {
1034 0 : switch (eUnderline)
1035 : {
1036 : case UNDERLINE_NONE:
1037 : case UNDERLINE_DONTKNOW:
1038 0 : return "none";
1039 : case UNDERLINE_DOUBLE:
1040 : case UNDERLINE_DOUBLEWAVE:
1041 0 : return "double";
1042 : default:
1043 0 : return "single";
1044 : }
1045 : }
1046 :
1047 0 : const char* getFontFamilyOOXValue(FontFamily eValue)
1048 : {
1049 0 : switch (eValue)
1050 : {
1051 : case FAMILY_DONTKNOW:
1052 0 : return "0";
1053 : break;
1054 : case FAMILY_SWISS:
1055 : case FAMILY_SYSTEM:
1056 0 : return "2";
1057 : case FAMILY_ROMAN:
1058 0 : return "1";
1059 : case FAMILY_SCRIPT:
1060 0 : return "4";
1061 : case FAMILY_MODERN:
1062 0 : return "3";
1063 : case FAMILY_DECORATIVE:
1064 0 : return "5";
1065 : default:
1066 0 : return "0";
1067 : }
1068 : }
1069 :
1070 : }
1071 :
1072 10 : void XclExpDxfFont::SaveXml(XclExpXmlStream& rStrm)
1073 : {
1074 10 : if (maDxfData.isEmpty())
1075 20 : return;
1076 :
1077 0 : sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
1078 0 : rStyleSheet->startElement(XML_font, FSEND);
1079 :
1080 0 : if (maDxfData.pFontAttr)
1081 : {
1082 0 : OUString aFontName = (*maDxfData.pFontAttr)->GetFamilyName();
1083 :
1084 0 : aFontName = XclTools::GetXclFontName(aFontName);
1085 0 : if (!aFontName.isEmpty())
1086 : {
1087 : rStyleSheet->singleElement(XML_name,
1088 : XML_val, XclXmlUtils::ToOString(aFontName).getStr(),
1089 0 : FSEND);
1090 : }
1091 :
1092 0 : rtl_TextEncoding eTextEnc = (*maDxfData.pFontAttr)->GetCharSet();
1093 0 : sal_uInt8 nExcelCharSet = rtl_getBestWindowsCharsetFromTextEncoding(eTextEnc);
1094 0 : if (nExcelCharSet)
1095 : {
1096 : rStyleSheet->singleElement(XML_charset,
1097 : XML_val, OString::number(nExcelCharSet).getStr(),
1098 0 : FSEND);
1099 : }
1100 :
1101 0 : FontFamily eFamily = (*maDxfData.pFontAttr)->GetFamily();
1102 0 : const char* pVal = getFontFamilyOOXValue(eFamily);
1103 0 : if (pVal)
1104 : {
1105 : rStyleSheet->singleElement(XML_family,
1106 : XML_val, pVal,
1107 0 : FSEND);
1108 0 : }
1109 : }
1110 :
1111 0 : if (maDxfData.eWeight)
1112 : {
1113 : rStyleSheet->singleElement(XML_b,
1114 0 : XML_val, XclXmlUtils::ToPsz10(maDxfData.eWeight.get() != WEIGHT_NORMAL),
1115 0 : FSEND);
1116 : }
1117 :
1118 0 : if (maDxfData.eItalic)
1119 : {
1120 0 : bool bItalic = (maDxfData.eItalic.get() == ITALIC_OBLIQUE) || (maDxfData.eItalic.get() == ITALIC_NORMAL);
1121 : rStyleSheet->singleElement(XML_i,
1122 : XML_val, XclXmlUtils::ToPsz10(bItalic),
1123 0 : FSEND);
1124 : }
1125 :
1126 0 : if (maDxfData.eStrike)
1127 : {
1128 : bool bStrikeout =
1129 0 : (maDxfData.eStrike.get() == STRIKEOUT_SINGLE) || (maDxfData.eStrike.get() == STRIKEOUT_DOUBLE) ||
1130 0 : (maDxfData.eStrike.get() == STRIKEOUT_BOLD) || (maDxfData.eStrike.get() == STRIKEOUT_SLASH) ||
1131 0 : (maDxfData.eStrike.get() == STRIKEOUT_X);
1132 :
1133 : rStyleSheet->singleElement(XML_strike,
1134 : XML_val, XclXmlUtils::ToPsz10(bStrikeout),
1135 0 : FSEND);
1136 : }
1137 :
1138 0 : if (maDxfData.bOutline)
1139 : {
1140 : rStyleSheet->singleElement(XML_outline,
1141 0 : XML_val, XclXmlUtils::ToPsz10(maDxfData.bOutline.get()),
1142 0 : FSEND);
1143 : }
1144 :
1145 0 : if (maDxfData.bShadow)
1146 : {
1147 : rStyleSheet->singleElement(XML_shadow,
1148 0 : XML_val, XclXmlUtils::ToPsz10(maDxfData.bShadow.get()),
1149 0 : FSEND);
1150 : }
1151 :
1152 0 : if (maDxfData.aColor)
1153 : {
1154 : rStyleSheet->singleElement(XML_color,
1155 0 : XML_rgb, XclXmlUtils::ToOString(maDxfData.aColor.get()).getStr(),
1156 0 : FSEND);
1157 : }
1158 :
1159 0 : if (maDxfData.eUnder)
1160 : {
1161 0 : const char* pVal = getUnderlineOOXValue(maDxfData.eUnder.get());
1162 : rStyleSheet->singleElement(XML_u,
1163 : XML_val, pVal,
1164 0 : FSEND);
1165 : }
1166 :
1167 0 : rStyleSheet->endElement(XML_font);
1168 : }
1169 :
1170 17 : XclExpBlindFont::XclExpBlindFont( const XclExpRoot& rRoot ) :
1171 17 : XclExpFont( rRoot, XclFontData(), EXC_COLOR_CELLTEXT )
1172 : {
1173 17 : }
1174 :
1175 102 : bool XclExpBlindFont::Equals( const XclFontData& /*rFontData*/, sal_uInt32 /*nHash*/ ) const
1176 : {
1177 102 : return false;
1178 : }
1179 :
1180 17 : void XclExpBlindFont::Save( XclExpStream& /*rStrm*/ )
1181 : {
1182 : // do nothing
1183 17 : }
1184 :
1185 72 : XclExpFontBuffer::XclExpFontBuffer( const XclExpRoot& rRoot ) :
1186 : XclExpRoot( rRoot ),
1187 72 : mnXclMaxSize( 0 )
1188 : {
1189 72 : switch( GetBiff() )
1190 : {
1191 0 : case EXC_BIFF4: mnXclMaxSize = EXC_FONT_MAXCOUNT4; break;
1192 0 : case EXC_BIFF5: mnXclMaxSize = EXC_FONT_MAXCOUNT5; break;
1193 72 : case EXC_BIFF8: mnXclMaxSize = EXC_FONT_MAXCOUNT8; break;
1194 : default: DBG_ERROR_BIFF();
1195 : }
1196 72 : InitDefaultFonts();
1197 72 : }
1198 :
1199 250 : const XclExpFont* XclExpFontBuffer::GetFont( sal_uInt16 nXclFont ) const
1200 : {
1201 250 : return maFontList.GetRecord( nXclFont ).get();
1202 : }
1203 :
1204 316 : const XclFontData& XclExpFontBuffer::GetAppFontData() const
1205 : {
1206 316 : return maFontList.GetRecord( EXC_FONT_APP )->GetFontData(); // exists always
1207 : }
1208 :
1209 832 : sal_uInt16 XclExpFontBuffer::Insert(
1210 : const XclFontData& rFontData, XclExpColorType eColorType, bool bAppFont )
1211 : {
1212 832 : if( bAppFont )
1213 : {
1214 72 : XclExpFontRef xFont( new XclExpFont( GetRoot(), rFontData, eColorType ) );
1215 72 : maFontList.ReplaceRecord( xFont, EXC_FONT_APP );
1216 : // set width of '0' character for column width export
1217 72 : SetCharWidth( xFont->GetFontData() );
1218 72 : return EXC_FONT_APP;
1219 : }
1220 :
1221 760 : size_t nPos = Find( rFontData );
1222 760 : if( nPos == EXC_FONTLIST_NOTFOUND )
1223 : {
1224 : // not found in buffer - create new font
1225 64 : size_t nSize = maFontList.GetSize();
1226 64 : if( nSize < mnXclMaxSize )
1227 : {
1228 : // possible to insert
1229 64 : maFontList.AppendNewRecord( new XclExpFont( GetRoot(), rFontData, eColorType ) );
1230 64 : nPos = nSize; // old size is last position now
1231 : }
1232 : else
1233 : {
1234 : // buffer is full - ignore new font, use default font
1235 0 : nPos = EXC_FONT_APP;
1236 : }
1237 : }
1238 760 : return static_cast< sal_uInt16 >( nPos );
1239 : }
1240 :
1241 268 : sal_uInt16 XclExpFontBuffer::Insert(
1242 : const vcl::Font& rFont, XclExpColorType eColorType, bool bAppFont )
1243 : {
1244 268 : return Insert( XclFontData( rFont ), eColorType, bAppFont );
1245 : }
1246 :
1247 469 : sal_uInt16 XclExpFontBuffer::Insert(
1248 : const SvxFont& rFont, XclExpColorType eColorType, bool bAppFont )
1249 : {
1250 469 : return Insert( XclFontData( rFont ), eColorType, bAppFont );
1251 : }
1252 :
1253 268 : sal_uInt16 XclExpFontBuffer::Insert( const SfxItemSet& rItemSet,
1254 : sal_Int16 nScript, XclExpColorType eColorType, bool bAppFont )
1255 : {
1256 : // #i17050# script type now provided by caller
1257 268 : vcl::Font aFont = XclExpFontHelper::GetFontFromItemSet( GetRoot(), rItemSet, nScript );
1258 268 : return Insert( aFont, eColorType, bAppFont );
1259 : }
1260 :
1261 17 : void XclExpFontBuffer::Save( XclExpStream& rStrm )
1262 : {
1263 17 : maFontList.Save( rStrm );
1264 17 : }
1265 :
1266 55 : void XclExpFontBuffer::SaveXml( XclExpXmlStream& rStrm )
1267 : {
1268 55 : if( maFontList.IsEmpty() )
1269 55 : return;
1270 :
1271 55 : sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
1272 : rStyleSheet->startElement( XML_fonts,
1273 : XML_count, OString::number( maFontList.GetSize() ).getStr(),
1274 55 : FSEND );
1275 :
1276 55 : maFontList.SaveXml( rStrm );
1277 :
1278 55 : rStyleSheet->endElement( XML_fonts );
1279 : }
1280 :
1281 : // private --------------------------------------------------------------------
1282 :
1283 72 : void XclExpFontBuffer::InitDefaultFonts()
1284 : {
1285 72 : XclFontData aFontData;
1286 72 : aFontData.maName = "Arial";
1287 72 : aFontData.SetScFamily( FAMILY_DONTKNOW );
1288 72 : aFontData.SetFontEncoding( ScfTools::GetSystemTextEncoding() );
1289 72 : aFontData.SetScHeight( 200 ); // 200 twips = 10 pt
1290 72 : aFontData.SetScWeight( WEIGHT_NORMAL );
1291 :
1292 72 : switch( GetBiff() )
1293 : {
1294 : case EXC_BIFF5:
1295 : {
1296 0 : maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
1297 0 : aFontData.SetScWeight( WEIGHT_BOLD );
1298 0 : maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
1299 0 : aFontData.SetScWeight( WEIGHT_NORMAL );
1300 0 : aFontData.SetScPosture( ITALIC_NORMAL );
1301 0 : maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
1302 0 : aFontData.SetScWeight( WEIGHT_BOLD );
1303 0 : maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
1304 : // the blind font with index 4
1305 0 : maFontList.AppendNewRecord( new XclExpBlindFont( GetRoot() ) );
1306 : // already add the first user defined font (Excel does it too)
1307 0 : aFontData.SetScWeight( WEIGHT_NORMAL );
1308 0 : aFontData.SetScPosture( ITALIC_NONE );
1309 0 : maFontList.AppendNewRecord( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
1310 : }
1311 0 : break;
1312 : case EXC_BIFF8:
1313 : {
1314 72 : XclExpFontRef xFont( new XclExpFont( GetRoot(), aFontData, EXC_COLOR_CELLTEXT ) );
1315 72 : maFontList.AppendRecord( xFont );
1316 72 : maFontList.AppendRecord( xFont );
1317 72 : maFontList.AppendRecord( xFont );
1318 72 : maFontList.AppendRecord( xFont );
1319 72 : if( GetOutput() == EXC_OUTPUT_BINARY )
1320 : // the blind font with index 4
1321 17 : maFontList.AppendNewRecord( new XclExpBlindFont( GetRoot() ) );
1322 : }
1323 72 : break;
1324 : default:
1325 : DBG_ERROR_BIFF();
1326 72 : }
1327 72 : }
1328 :
1329 760 : size_t XclExpFontBuffer::Find( const XclFontData& rFontData )
1330 : {
1331 760 : sal_uInt32 nHash = lclCalcHash( rFontData );
1332 2285 : for( size_t nPos = 0, nSize = maFontList.GetSize(); nPos < nSize; ++nPos )
1333 2221 : if( maFontList.GetRecord( nPos )->Equals( rFontData, nHash ) )
1334 696 : return nPos;
1335 64 : return EXC_FONTLIST_NOTFOUND;
1336 : }
1337 :
1338 : // FORMAT record - number formats =============================================
1339 :
1340 : /** Predicate for search algorithm. */
1341 : struct XclExpNumFmtPred
1342 : {
1343 : sal_uLong mnScNumFmt;
1344 348 : inline explicit XclExpNumFmtPred( sal_uLong nScNumFmt ) : mnScNumFmt( nScNumFmt ) {}
1345 315 : inline bool operator()( const XclExpNumFmt& rFormat ) const
1346 315 : { return rFormat.mnScNumFmt == mnScNumFmt; }
1347 : };
1348 :
1349 74 : void XclExpNumFmt::SaveXml( XclExpXmlStream& rStrm )
1350 : {
1351 74 : sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
1352 : rStyleSheet->singleElement( XML_numFmt,
1353 : XML_numFmtId, OString::number( mnXclNumFmt ).getStr(),
1354 : XML_formatCode, OUStringToOString(maNumFmtString, RTL_TEXTENCODING_UTF8).getStr(),
1355 74 : FSEND );
1356 74 : }
1357 :
1358 72 : XclExpNumFmtBuffer::XclExpNumFmtBuffer( const XclExpRoot& rRoot ) :
1359 : XclExpRoot( rRoot ),
1360 : /* Compiler needs a hint, this doesn't work: new NfKeywordTable;
1361 : cannot convert from 'class String *' to 'class String (*)[54]'
1362 : The effective result here is class String (*)[54*1] */
1363 72 : mxFormatter( new SvNumberFormatter( comphelper::getProcessComponentContext(), LANGUAGE_ENGLISH_US ) ),
1364 72 : mpKeywordTable( new NfKeywordTable ),
1365 216 : mnStdFmt( GetFormatter().GetStandardFormat( ScGlobal::eLnge ) )
1366 : {
1367 72 : switch( GetBiff() )
1368 : {
1369 0 : case EXC_BIFF5: mnXclOffset = EXC_FORMAT_OFFSET5; break;
1370 72 : case EXC_BIFF8: mnXclOffset = EXC_FORMAT_OFFSET8; break;
1371 0 : default: mnXclOffset = 0; DBG_ERROR_BIFF();
1372 : }
1373 :
1374 72 : mxFormatter->FillKeywordTable( *mpKeywordTable, LANGUAGE_ENGLISH_US );
1375 : // remap codes unknown to Excel
1376 72 : (*mpKeywordTable)[ NF_KEY_NN ] = "DDD";
1377 72 : (*mpKeywordTable)[ NF_KEY_NNN ] = "DDDD";
1378 : // NNNN gets a separator appended in SvNumberformat::GetMappedFormatString()
1379 72 : (*mpKeywordTable)[ NF_KEY_NNNN ] = "DDDD";
1380 : // Export the Thai T NatNum modifier.
1381 72 : (*mpKeywordTable)[ NF_KEY_THAI_T ] = "T";
1382 72 : }
1383 :
1384 144 : XclExpNumFmtBuffer::~XclExpNumFmtBuffer()
1385 : {
1386 144 : }
1387 :
1388 348 : sal_uInt16 XclExpNumFmtBuffer::Insert( sal_uLong nScNumFmt )
1389 : {
1390 : XclExpNumFmtVec::const_iterator aIt =
1391 348 : ::std::find_if( maFormatMap.begin(), maFormatMap.end(), XclExpNumFmtPred( nScNumFmt ) );
1392 348 : if( aIt != maFormatMap.end() )
1393 262 : return aIt->mnXclNumFmt;
1394 :
1395 86 : size_t nSize = maFormatMap.size();
1396 86 : if( nSize < static_cast< size_t >( 0xFFFF - mnXclOffset ) )
1397 : {
1398 86 : sal_uInt16 nXclNumFmt = static_cast< sal_uInt16 >( nSize + mnXclOffset );
1399 86 : maFormatMap.push_back( XclExpNumFmt( nScNumFmt, nXclNumFmt, GetFormatCode( nScNumFmt ) ) );
1400 86 : return nXclNumFmt;
1401 : }
1402 :
1403 0 : return 0;
1404 : }
1405 :
1406 17 : void XclExpNumFmtBuffer::Save( XclExpStream& rStrm )
1407 : {
1408 39 : for( XclExpNumFmtVec::const_iterator aIt = maFormatMap.begin(), aEnd = maFormatMap.end(); aIt != aEnd; ++aIt )
1409 22 : WriteFormatRecord( rStrm, *aIt );
1410 17 : }
1411 :
1412 55 : void XclExpNumFmtBuffer::SaveXml( XclExpXmlStream& rStrm )
1413 : {
1414 55 : if( !maFormatMap.size() )
1415 55 : return;
1416 :
1417 55 : sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
1418 : rStyleSheet->startElement( XML_numFmts,
1419 : XML_count, OString::number( maFormatMap.size() ).getStr(),
1420 55 : FSEND );
1421 119 : for( XclExpNumFmtVec::iterator aIt = maFormatMap.begin(), aEnd = maFormatMap.end(); aIt != aEnd; ++aIt )
1422 : {
1423 64 : aIt->SaveXml( rStrm );
1424 : }
1425 55 : rStyleSheet->endElement( XML_numFmts );
1426 : }
1427 :
1428 22 : void XclExpNumFmtBuffer::WriteFormatRecord( XclExpStream& rStrm, sal_uInt16 nXclNumFmt, const OUString& rFormatStr )
1429 : {
1430 22 : XclExpString aExpStr;
1431 22 : if( GetBiff() <= EXC_BIFF5 )
1432 0 : aExpStr.AssignByte( rFormatStr, GetTextEncoding(), EXC_STR_8BITLENGTH );
1433 : else
1434 22 : aExpStr.Assign( rFormatStr );
1435 :
1436 22 : rStrm.StartRecord( EXC_ID4_FORMAT, 2 + aExpStr.GetSize() );
1437 22 : rStrm << nXclNumFmt << aExpStr;
1438 22 : rStrm.EndRecord();
1439 22 : }
1440 :
1441 22 : void XclExpNumFmtBuffer::WriteFormatRecord( XclExpStream& rStrm, const XclExpNumFmt& rFormat )
1442 : {
1443 22 : WriteFormatRecord( rStrm, rFormat.mnXclNumFmt, GetFormatCode( rFormat.mnScNumFmt ) );
1444 22 : }
1445 :
1446 : namespace {
1447 :
1448 118 : OUString GetNumberFormatCode(XclRoot& rRoot, const sal_uInt16 nScNumFmt, SvNumberFormatter* xFormatter, NfKeywordTable* pKeywordTable)
1449 : {
1450 118 : OUString aFormatStr;
1451 :
1452 118 : if( const SvNumberformat* pEntry = rRoot.GetFormatter().GetEntry( nScNumFmt ) )
1453 : {
1454 118 : if( pEntry->GetType() == css::util::NumberFormat::LOGICAL )
1455 : {
1456 : // build Boolean number format
1457 0 : Color* pColor = 0;
1458 0 : OUString aTemp;
1459 0 : const_cast< SvNumberformat* >( pEntry )->GetOutputString( 1.0, aTemp, &pColor );
1460 0 : aFormatStr += "\"" + aTemp + "\";\"" + aTemp + "\";\"";
1461 0 : const_cast< SvNumberformat* >( pEntry )->GetOutputString( 0.0, aTemp, &pColor );
1462 0 : aFormatStr += aTemp + "\"";
1463 : }
1464 : else
1465 : {
1466 118 : LanguageType eLang = pEntry->GetLanguage();
1467 118 : if( eLang != LANGUAGE_ENGLISH_US )
1468 : {
1469 : sal_Int32 nCheckPos;
1470 118 : short nType = css::util::NumberFormat::DEFINED;
1471 : sal_uInt32 nKey;
1472 118 : OUString aTemp( pEntry->GetFormatstring() );
1473 118 : xFormatter->PutandConvertEntry( aTemp, nCheckPos, nType, nKey, eLang, LANGUAGE_ENGLISH_US );
1474 : OSL_ENSURE( nCheckPos == 0, "XclExpNumFmtBuffer::WriteFormatRecord - format code not convertible" );
1475 118 : pEntry = xFormatter->GetEntry( nKey );
1476 : }
1477 :
1478 118 : aFormatStr = pEntry->GetMappedFormatstring( *pKeywordTable, *xFormatter->GetLocaleData() );
1479 118 : if( aFormatStr == "Standard" )
1480 0 : aFormatStr = "General";
1481 : }
1482 : }
1483 : else
1484 : {
1485 : OSL_FAIL( "XclExpNumFmtBuffer::WriteFormatRecord - format not found" );
1486 0 : aFormatStr = "General";
1487 : }
1488 :
1489 118 : return aFormatStr;
1490 : }
1491 :
1492 : }
1493 :
1494 108 : OUString XclExpNumFmtBuffer::GetFormatCode( sal_uInt16 nScNumFmt )
1495 : {
1496 108 : return GetNumberFormatCode( *this, nScNumFmt, mxFormatter.get(), mpKeywordTable.get() );
1497 : }
1498 :
1499 : // XF, STYLE record - Cell formatting =========================================
1500 :
1501 312 : bool XclExpCellProt::FillFromItemSet( const SfxItemSet& rItemSet, bool bStyle )
1502 : {
1503 312 : const ScProtectionAttr& rProtItem = GETITEM( rItemSet, ScProtectionAttr, ATTR_PROTECTION );
1504 312 : mbLocked = rProtItem.GetProtection();
1505 312 : mbHidden = rProtItem.GetHideFormula() || rProtItem.GetHideCell();
1506 312 : return ScfTools::CheckItem( rItemSet, ATTR_PROTECTION, bStyle );
1507 : }
1508 :
1509 402 : void XclExpCellProt::FillToXF3( sal_uInt16& rnProt ) const
1510 : {
1511 402 : ::set_flag( rnProt, EXC_XF_LOCKED, mbLocked );
1512 402 : ::set_flag( rnProt, EXC_XF_HIDDEN, mbHidden );
1513 402 : }
1514 :
1515 181 : void XclExpCellProt::SaveXml( XclExpXmlStream& rStrm ) const
1516 : {
1517 181 : rStrm.GetCurrentStream()->singleElement( XML_protection,
1518 : XML_locked, XclXmlUtils::ToPsz( mbLocked ),
1519 : XML_hidden, XclXmlUtils::ToPsz( mbHidden ),
1520 362 : FSEND );
1521 181 : }
1522 :
1523 312 : bool XclExpCellAlign::FillFromItemSet(
1524 : const SfxItemSet& rItemSet, bool bForceLineBreak, XclBiff eBiff, bool bStyle )
1525 : {
1526 312 : bool bUsed = false;
1527 312 : SvxCellHorJustify eHorAlign = GETITEMVALUE( rItemSet, SvxHorJustifyItem, ATTR_HOR_JUSTIFY, SvxCellHorJustify );
1528 312 : SvxCellVerJustify eVerAlign = GETITEMVALUE( rItemSet, SvxVerJustifyItem, ATTR_VER_JUSTIFY, SvxCellVerJustify );
1529 :
1530 312 : switch( eBiff )
1531 : {
1532 : // ALL 'case's - run through!
1533 :
1534 : case EXC_BIFF8: // attributes new in BIFF8
1535 : {
1536 : // text indent
1537 312 : long nTmpIndent = GETITEMVALUE( rItemSet, SfxUInt16Item, ATTR_INDENT, sal_Int32 );
1538 312 : (nTmpIndent += 100) /= 200; // 1 Excel unit == 10 pt == 200 twips
1539 312 : mnIndent = limit_cast< sal_uInt8 >( nTmpIndent, 0, 15 );
1540 312 : bUsed |= ScfTools::CheckItem( rItemSet, ATTR_INDENT, bStyle );
1541 :
1542 : // shrink to fit
1543 312 : mbShrink = GETITEM( rItemSet, SfxBoolItem, ATTR_SHRINKTOFIT ).GetValue();
1544 312 : bUsed |= ScfTools::CheckItem( rItemSet, ATTR_SHRINKTOFIT, bStyle );
1545 :
1546 : // CTL text direction
1547 312 : SetScFrameDir( GETITEMVALUE( rItemSet, SvxFrameDirectionItem, ATTR_WRITINGDIR, SvxFrameDirection ) );
1548 312 : bUsed |= ScfTools::CheckItem( rItemSet, ATTR_WRITINGDIR, bStyle );
1549 : }
1550 :
1551 : case EXC_BIFF5: // attributes new in BIFF5
1552 : case EXC_BIFF4: // attributes new in BIFF4
1553 : {
1554 : // vertical alignment
1555 312 : SetScVerAlign( eVerAlign );
1556 312 : bUsed |= ScfTools::CheckItem( rItemSet, ATTR_VER_JUSTIFY, bStyle );
1557 :
1558 : // stacked/rotation
1559 312 : bool bStacked = GETITEM( rItemSet, SfxBoolItem, ATTR_STACKED ).GetValue();
1560 312 : bUsed |= ScfTools::CheckItem( rItemSet, ATTR_STACKED, bStyle );
1561 312 : if( bStacked )
1562 : {
1563 0 : mnRotation = EXC_ROT_STACKED;
1564 : }
1565 : else
1566 : {
1567 : // rotation
1568 312 : sal_Int32 nScRot = GETITEMVALUE( rItemSet, SfxInt32Item, ATTR_ROTATE_VALUE, sal_Int32 );
1569 312 : mnRotation = XclTools::GetXclRotation( nScRot );
1570 312 : bUsed |= ScfTools::CheckItem( rItemSet, ATTR_ROTATE_VALUE, bStyle );
1571 : }
1572 312 : mnOrient = XclTools::GetXclOrientFromRot( mnRotation );
1573 : }
1574 :
1575 : case EXC_BIFF3: // attributes new in BIFF3
1576 : {
1577 : // text wrap
1578 312 : mbLineBreak = bForceLineBreak || GETITEMBOOL( rItemSet, ATTR_LINEBREAK );
1579 312 : bUsed |= bForceLineBreak || ScfTools::CheckItem( rItemSet, ATTR_LINEBREAK, bStyle );
1580 : }
1581 :
1582 : case EXC_BIFF2: // attributes new in BIFF2
1583 : {
1584 : // horizontal alignment
1585 312 : SetScHorAlign( eHorAlign );
1586 312 : bUsed |= ScfTools::CheckItem( rItemSet, ATTR_HOR_JUSTIFY, bStyle );
1587 : }
1588 :
1589 312 : break;
1590 : default: DBG_ERROR_BIFF();
1591 : }
1592 :
1593 312 : if (eBiff == EXC_BIFF8)
1594 : {
1595 : // Adjust for distributed alignments.
1596 312 : if (eHorAlign == SVX_HOR_JUSTIFY_BLOCK)
1597 : {
1598 0 : SvxCellJustifyMethod eHorJustMethod = GETITEMVALUE(
1599 : rItemSet, SvxJustifyMethodItem, ATTR_HOR_JUSTIFY_METHOD, SvxCellJustifyMethod);
1600 0 : if (eHorJustMethod == SVX_JUSTIFY_METHOD_DISTRIBUTE)
1601 0 : mnHorAlign = EXC_XF_HOR_DISTRIB;
1602 : }
1603 :
1604 312 : if (eVerAlign == SVX_VER_JUSTIFY_BLOCK)
1605 : {
1606 0 : SvxCellJustifyMethod eVerJustMethod = GETITEMVALUE(
1607 : rItemSet, SvxJustifyMethodItem, ATTR_VER_JUSTIFY_METHOD, SvxCellJustifyMethod);
1608 0 : if (eVerJustMethod == SVX_JUSTIFY_METHOD_DISTRIBUTE)
1609 0 : mnVerAlign = EXC_XF_VER_DISTRIB;
1610 : }
1611 : }
1612 :
1613 312 : return bUsed;
1614 : }
1615 :
1616 0 : void XclExpCellAlign::FillToXF5( sal_uInt16& rnAlign ) const
1617 : {
1618 0 : ::insert_value( rnAlign, mnHorAlign, 0, 3 );
1619 0 : ::set_flag( rnAlign, EXC_XF_LINEBREAK, mbLineBreak );
1620 0 : ::insert_value( rnAlign, mnVerAlign, 4, 3 );
1621 0 : ::insert_value( rnAlign, mnOrient, 8, 2 );
1622 0 : }
1623 :
1624 402 : void XclExpCellAlign::FillToXF8( sal_uInt16& rnAlign, sal_uInt16& rnMiscAttrib ) const
1625 : {
1626 402 : ::insert_value( rnAlign, mnHorAlign, 0, 3 );
1627 402 : ::set_flag( rnAlign, EXC_XF_LINEBREAK, mbLineBreak );
1628 402 : ::insert_value( rnAlign, mnVerAlign, 4, 3 );
1629 402 : ::insert_value( rnAlign, mnRotation, 8, 8 );
1630 402 : ::insert_value( rnMiscAttrib, mnIndent, 0, 4 );
1631 402 : ::set_flag( rnMiscAttrib, EXC_XF8_SHRINK, mbShrink );
1632 402 : ::insert_value( rnMiscAttrib, mnTextDir, 6, 2 );
1633 402 : }
1634 :
1635 193 : static const char* ToHorizontalAlignment( sal_uInt8 nHorAlign )
1636 : {
1637 193 : switch( nHorAlign )
1638 : {
1639 175 : case EXC_XF_HOR_GENERAL: return "general";
1640 15 : case EXC_XF_HOR_LEFT: return "left";
1641 2 : case EXC_XF_HOR_CENTER: return "center";
1642 1 : case EXC_XF_HOR_RIGHT: return "right";
1643 0 : case EXC_XF_HOR_FILL: return "fill";
1644 0 : case EXC_XF_HOR_JUSTIFY: return "justify";
1645 0 : case EXC_XF_HOR_CENTER_AS: return "centerContinuous";
1646 0 : case EXC_XF_HOR_DISTRIB: return "distributed";
1647 : }
1648 0 : return "*unknown*";
1649 : }
1650 :
1651 193 : static const char* ToVerticalAlignment( sal_uInt8 nVerAlign )
1652 : {
1653 193 : switch( nVerAlign )
1654 : {
1655 0 : case EXC_XF_VER_TOP: return "top";
1656 3 : case EXC_XF_VER_CENTER: return "center";
1657 190 : case EXC_XF_VER_BOTTOM: return "bottom";
1658 0 : case EXC_XF_VER_JUSTIFY: return "justify";
1659 0 : case EXC_XF_VER_DISTRIB: return "distributed";
1660 : }
1661 0 : return "*unknown*";
1662 : }
1663 :
1664 193 : void XclExpCellAlign::SaveXml( XclExpXmlStream& rStrm ) const
1665 : {
1666 193 : rStrm.GetCurrentStream()->singleElement( XML_alignment,
1667 : XML_horizontal, ToHorizontalAlignment( mnHorAlign ),
1668 : XML_vertical, ToVerticalAlignment( mnVerAlign ),
1669 : XML_textRotation, OString::number( mnRotation ).getStr(),
1670 : XML_wrapText, XclXmlUtils::ToPsz( mbLineBreak ),
1671 : XML_indent, OString::number( mnIndent ).getStr(),
1672 : // OOXTODO: XML_relativeIndent, mnIndent?
1673 : // OOXTODO: XML_justifyLastLine,
1674 : XML_shrinkToFit, XclXmlUtils::ToPsz( mbShrink ),
1675 : // OOXTODO: XML_readingOrder,
1676 386 : FSEND );
1677 193 : }
1678 :
1679 : namespace {
1680 :
1681 1872 : void lclGetBorderLine(
1682 : sal_uInt8& rnXclLine, sal_uInt32& rnColorId,
1683 : const ::editeng::SvxBorderLine* pLine, XclExpPalette& rPalette, XclBiff eBiff )
1684 : {
1685 1872 : rnXclLine = EXC_LINE_NONE;
1686 1872 : if( pLine )
1687 : {
1688 138 : sal_uInt16 nOuterWidth = pLine->GetOutWidth();
1689 138 : sal_uInt16 nDistance = pLine->GetDistance();
1690 138 : if( nDistance > 0 )
1691 3 : rnXclLine = EXC_LINE_DOUBLE;
1692 135 : else if( nOuterWidth >= EXC_BORDER_THICK )
1693 3 : rnXclLine = EXC_LINE_THICK;
1694 132 : else if( nOuterWidth >= EXC_BORDER_MEDIUM )
1695 : {
1696 47 : rnXclLine = EXC_LINE_MEDIUM;
1697 47 : switch (pLine->GetBorderLineStyle())
1698 : {
1699 : case table::BorderLineStyle::DASHED:
1700 3 : rnXclLine = EXC_LINE_MEDIUM_DASHED;
1701 3 : break;
1702 : case table::BorderLineStyle::DASH_DOT:
1703 3 : rnXclLine = EXC_LINE_MEDIUM_DASHDOT;
1704 3 : break;
1705 : case table::BorderLineStyle::DASH_DOT_DOT:
1706 3 : rnXclLine = EXC_LINE_MEDIUM_DASHDOTDOT;
1707 3 : break;
1708 : default:
1709 : ;
1710 : }
1711 : }
1712 85 : else if( nOuterWidth >= EXC_BORDER_THIN )
1713 : {
1714 83 : rnXclLine = EXC_LINE_THIN;
1715 83 : switch (pLine->GetBorderLineStyle())
1716 : {
1717 : case table::BorderLineStyle::DASHED:
1718 : case table::BorderLineStyle::FINE_DASHED:
1719 3 : rnXclLine = EXC_LINE_DASHED;
1720 3 : break;
1721 : case table::BorderLineStyle::DASH_DOT:
1722 3 : rnXclLine = EXC_LINE_THIN_DASHDOT;
1723 3 : break;
1724 : case table::BorderLineStyle::DASH_DOT_DOT:
1725 3 : rnXclLine = EXC_LINE_THIN_DASHDOTDOT;
1726 3 : break;
1727 : case table::BorderLineStyle::DOTTED:
1728 3 : rnXclLine = EXC_LINE_DOTTED;
1729 3 : break;
1730 : default:
1731 71 : break;
1732 : }
1733 : }
1734 2 : else if (nOuterWidth >= EXC_BORDER_HAIR)
1735 2 : rnXclLine = EXC_LINE_HAIR;
1736 : else
1737 0 : rnXclLine = EXC_LINE_NONE;
1738 : }
1739 1872 : if( (eBiff == EXC_BIFF2) && (rnXclLine != EXC_LINE_NONE) )
1740 0 : rnXclLine = EXC_LINE_THIN;
1741 :
1742 138 : rnColorId = (pLine && (rnXclLine != EXC_LINE_NONE)) ?
1743 138 : rPalette.InsertColor( pLine->GetColor(), EXC_COLOR_CELLBORDER ) :
1744 2010 : XclExpPalette::GetColorIdFromIndex( 0 );
1745 1872 : }
1746 :
1747 : } // namespace
1748 :
1749 538 : XclExpCellBorder::XclExpCellBorder() :
1750 538 : mnLeftColorId( XclExpPalette::GetColorIdFromIndex( mnLeftColor ) ),
1751 538 : mnRightColorId( XclExpPalette::GetColorIdFromIndex( mnRightColor ) ),
1752 538 : mnTopColorId( XclExpPalette::GetColorIdFromIndex( mnTopColor ) ),
1753 538 : mnBottomColorId( XclExpPalette::GetColorIdFromIndex( mnBottomColor ) ),
1754 2690 : mnDiagColorId( XclExpPalette::GetColorIdFromIndex( mnDiagColor ) )
1755 : {
1756 538 : }
1757 :
1758 312 : bool XclExpCellBorder::FillFromItemSet(
1759 : const SfxItemSet& rItemSet, XclExpPalette& rPalette, XclBiff eBiff, bool bStyle )
1760 : {
1761 312 : bool bUsed = false;
1762 :
1763 312 : switch( eBiff )
1764 : {
1765 : // ALL 'case's - run through!
1766 :
1767 : case EXC_BIFF8: // attributes new in BIFF8
1768 : {
1769 312 : const SvxLineItem& rTLBRItem = GETITEM( rItemSet, SvxLineItem, ATTR_BORDER_TLBR );
1770 : sal_uInt8 nTLBRLine;
1771 : sal_uInt32 nTLBRColorId;
1772 312 : lclGetBorderLine( nTLBRLine, nTLBRColorId, rTLBRItem.GetLine(), rPalette, eBiff );
1773 312 : mbDiagTLtoBR = (nTLBRLine != EXC_LINE_NONE);
1774 :
1775 312 : const SvxLineItem& rBLTRItem = GETITEM( rItemSet, SvxLineItem, ATTR_BORDER_BLTR );
1776 : sal_uInt8 nBLTRLine;
1777 : sal_uInt32 nBLTRColorId;
1778 312 : lclGetBorderLine( nBLTRLine, nBLTRColorId, rBLTRItem.GetLine(), rPalette, eBiff );
1779 312 : mbDiagBLtoTR = (nBLTRLine != EXC_LINE_NONE);
1780 :
1781 312 : if( ::ScHasPriority( rTLBRItem.GetLine(), rBLTRItem.GetLine() ) )
1782 : {
1783 0 : mnDiagLine = nTLBRLine;
1784 0 : mnDiagColorId = nTLBRColorId;
1785 : }
1786 : else
1787 : {
1788 312 : mnDiagLine = nBLTRLine;
1789 312 : mnDiagColorId = nBLTRColorId;
1790 : }
1791 :
1792 574 : bUsed |= ScfTools::CheckItem( rItemSet, ATTR_BORDER_TLBR, bStyle ) ||
1793 574 : ScfTools::CheckItem( rItemSet, ATTR_BORDER_BLTR, bStyle );
1794 : }
1795 :
1796 : case EXC_BIFF5:
1797 : case EXC_BIFF4:
1798 : case EXC_BIFF3:
1799 : case EXC_BIFF2:
1800 : {
1801 312 : const SvxBoxItem& rBoxItem = GETITEM( rItemSet, SvxBoxItem, ATTR_BORDER );
1802 312 : lclGetBorderLine( mnLeftLine, mnLeftColorId, rBoxItem.GetLeft(), rPalette, eBiff );
1803 312 : lclGetBorderLine( mnRightLine, mnRightColorId, rBoxItem.GetRight(), rPalette, eBiff );
1804 312 : lclGetBorderLine( mnTopLine, mnTopColorId, rBoxItem.GetTop(), rPalette, eBiff );
1805 312 : lclGetBorderLine( mnBottomLine, mnBottomColorId, rBoxItem.GetBottom(), rPalette, eBiff );
1806 312 : bUsed |= ScfTools::CheckItem( rItemSet, ATTR_BORDER, bStyle );
1807 : }
1808 :
1809 312 : break;
1810 : default: DBG_ERROR_BIFF();
1811 : }
1812 :
1813 312 : return bUsed;
1814 : }
1815 :
1816 1670 : void XclExpCellBorder::SetFinalColors( const XclExpPalette& rPalette )
1817 : {
1818 1670 : mnLeftColor = rPalette.GetColorIndex( mnLeftColorId );
1819 1670 : mnRightColor = rPalette.GetColorIndex( mnRightColorId );
1820 1670 : mnTopColor = rPalette.GetColorIndex( mnTopColorId );
1821 1670 : mnBottomColor = rPalette.GetColorIndex( mnBottomColorId );
1822 1670 : mnDiagColor = rPalette.GetColorIndex( mnDiagColorId );
1823 1670 : }
1824 :
1825 0 : void XclExpCellBorder::FillToXF5( sal_uInt32& rnBorder, sal_uInt32& rnArea ) const
1826 : {
1827 0 : ::insert_value( rnBorder, mnTopLine, 0, 3 );
1828 0 : ::insert_value( rnBorder, mnLeftLine, 3, 3 );
1829 0 : ::insert_value( rnArea, mnBottomLine, 22, 3 );
1830 0 : ::insert_value( rnBorder, mnRightLine, 6, 3 );
1831 0 : ::insert_value( rnBorder, mnTopColor, 9, 7 );
1832 0 : ::insert_value( rnBorder, mnLeftColor, 16, 7 );
1833 0 : ::insert_value( rnArea, mnBottomColor, 25, 7 );
1834 0 : ::insert_value( rnBorder, mnRightColor, 23, 7 );
1835 0 : }
1836 :
1837 402 : void XclExpCellBorder::FillToXF8( sal_uInt32& rnBorder1, sal_uInt32& rnBorder2 ) const
1838 : {
1839 402 : ::insert_value( rnBorder1, mnLeftLine, 0, 4 );
1840 402 : ::insert_value( rnBorder1, mnRightLine, 4, 4 );
1841 402 : ::insert_value( rnBorder1, mnTopLine, 8, 4 );
1842 402 : ::insert_value( rnBorder1, mnBottomLine, 12, 4 );
1843 402 : ::insert_value( rnBorder1, mnLeftColor, 16, 7 );
1844 402 : ::insert_value( rnBorder1, mnRightColor, 23, 7 );
1845 402 : ::insert_value( rnBorder2, mnTopColor, 0, 7 );
1846 402 : ::insert_value( rnBorder2, mnBottomColor, 7, 7 );
1847 402 : ::insert_value( rnBorder2, mnDiagColor, 14, 7 );
1848 402 : ::insert_value( rnBorder2, mnDiagLine, 21, 4 );
1849 402 : ::set_flag( rnBorder1, EXC_XF_DIAGONAL_TL_TO_BR, mbDiagTLtoBR );
1850 402 : ::set_flag( rnBorder1, EXC_XF_DIAGONAL_BL_TO_TR, mbDiagBLtoTR );
1851 402 : }
1852 :
1853 0 : void XclExpCellBorder::FillToCF8( sal_uInt16& rnLine, sal_uInt32& rnColor ) const
1854 : {
1855 0 : ::insert_value( rnLine, mnLeftLine, 0, 4 );
1856 0 : ::insert_value( rnLine, mnRightLine, 4, 4 );
1857 0 : ::insert_value( rnLine, mnTopLine, 8, 4 );
1858 0 : ::insert_value( rnLine, mnBottomLine, 12, 4 );
1859 0 : ::insert_value( rnColor, mnLeftColor, 0, 7 );
1860 0 : ::insert_value( rnColor, mnRightColor, 7, 7 );
1861 0 : ::insert_value( rnColor, mnTopColor, 16, 7 );
1862 0 : ::insert_value( rnColor, mnBottomColor, 23, 7 );
1863 0 : }
1864 :
1865 109 : static const char* ToLineStyle( sal_uInt8 nLineStyle )
1866 : {
1867 109 : switch( nLineStyle )
1868 : {
1869 0 : case EXC_LINE_NONE: return "none";
1870 64 : case EXC_LINE_THIN: return "thin";
1871 35 : case EXC_LINE_MEDIUM: return "medium";
1872 1 : case EXC_LINE_THICK: return "thick";
1873 1 : case EXC_LINE_DOUBLE: return "double";
1874 1 : case EXC_LINE_HAIR: return "hair";
1875 1 : case EXC_LINE_DOTTED: return "dotted";
1876 1 : case EXC_LINE_DASHED: return "dashed";
1877 1 : case EXC_LINE_MEDIUM_DASHED: return "mediumDashed";
1878 1 : case EXC_LINE_THIN_DASHDOT: return "dashDot";
1879 1 : case EXC_LINE_THIN_DASHDOTDOT: return "dashDotDot";
1880 1 : case EXC_LINE_MEDIUM_DASHDOT: return "mediumDashDot";
1881 1 : case EXC_LINE_MEDIUM_DASHDOTDOT: return "mediumDashDotDot";
1882 : }
1883 0 : return "*unknown*";
1884 : }
1885 :
1886 510 : static void lcl_WriteBorder( XclExpXmlStream& rStrm, sal_Int32 nElement, sal_uInt8 nLineStyle, const Color& rColor )
1887 : {
1888 510 : sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
1889 510 : if( nLineStyle == EXC_LINE_NONE )
1890 401 : rStyleSheet->singleElement( nElement, FSEND );
1891 109 : else if( rColor == Color( 0, 0, 0, 0 ) )
1892 : rStyleSheet->singleElement( nElement,
1893 : XML_style, ToLineStyle( nLineStyle ),
1894 109 : FSEND );
1895 : else
1896 : {
1897 : rStyleSheet->startElement( nElement,
1898 : XML_style, ToLineStyle( nLineStyle ),
1899 0 : FSEND );
1900 : rStyleSheet->singleElement( XML_color,
1901 : XML_rgb, XclXmlUtils::ToOString( rColor ).getStr(),
1902 0 : FSEND );
1903 0 : rStyleSheet->endElement( nElement );
1904 : }
1905 510 : }
1906 :
1907 102 : void XclExpCellBorder::SaveXml( XclExpXmlStream& rStrm ) const
1908 : {
1909 102 : sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
1910 :
1911 102 : XclExpPalette& rPalette = rStrm.GetRoot().GetPalette();
1912 :
1913 : rStyleSheet->startElement( XML_border,
1914 : XML_diagonalUp, XclXmlUtils::ToPsz( mbDiagBLtoTR ),
1915 : XML_diagonalDown, XclXmlUtils::ToPsz( mbDiagTLtoBR ),
1916 : // OOXTODO: XML_outline,
1917 102 : FSEND );
1918 102 : lcl_WriteBorder( rStrm, XML_left, mnLeftLine, rPalette.GetColor( mnLeftColor ) );
1919 102 : lcl_WriteBorder( rStrm, XML_right, mnRightLine, rPalette.GetColor( mnRightColor ) );
1920 102 : lcl_WriteBorder( rStrm, XML_top, mnTopLine, rPalette.GetColor( mnTopColor ) );
1921 102 : lcl_WriteBorder( rStrm, XML_bottom, mnBottomLine, rPalette.GetColor( mnBottomColor ) );
1922 102 : lcl_WriteBorder( rStrm, XML_diagonal, mnDiagLine, rPalette.GetColor( mnDiagColor ) );
1923 : // OOXTODO: XML_vertical, XML_horizontal
1924 102 : rStyleSheet->endElement( XML_border );
1925 102 : }
1926 :
1927 672 : XclExpCellArea::XclExpCellArea() :
1928 672 : mnForeColorId( XclExpPalette::GetColorIdFromIndex( mnForeColor ) ),
1929 1344 : mnBackColorId( XclExpPalette::GetColorIdFromIndex( mnBackColor ) )
1930 : {
1931 672 : }
1932 :
1933 302 : bool XclExpCellArea::FillFromItemSet( const SfxItemSet& rItemSet, XclExpPalette& rPalette, bool bStyle )
1934 : {
1935 302 : const SvxBrushItem& rBrushItem = GETITEM( rItemSet, SvxBrushItem, ATTR_BACKGROUND );
1936 302 : if( rBrushItem.GetColor().GetTransparency() )
1937 : {
1938 302 : mnPattern = EXC_PATT_NONE;
1939 302 : mnForeColorId = XclExpPalette::GetColorIdFromIndex( EXC_COLOR_WINDOWTEXT );
1940 302 : mnBackColorId = XclExpPalette::GetColorIdFromIndex( EXC_COLOR_WINDOWBACK );
1941 : }
1942 : else
1943 : {
1944 0 : mnPattern = EXC_PATT_SOLID;
1945 0 : mnForeColorId = rPalette.InsertColor( rBrushItem.GetColor(), EXC_COLOR_CELLAREA );
1946 0 : mnBackColorId = XclExpPalette::GetColorIdFromIndex( EXC_COLOR_WINDOWTEXT );
1947 : }
1948 302 : return ScfTools::CheckItem( rItemSet, ATTR_BACKGROUND, bStyle );
1949 : }
1950 :
1951 1670 : void XclExpCellArea::SetFinalColors( const XclExpPalette& rPalette )
1952 : {
1953 1670 : rPalette.GetMixedColors( mnForeColor, mnBackColor, mnPattern, mnForeColorId, mnBackColorId );
1954 1670 : }
1955 :
1956 0 : void XclExpCellArea::FillToXF5( sal_uInt32& rnArea ) const
1957 : {
1958 0 : ::insert_value( rnArea, mnPattern, 16, 6 );
1959 0 : ::insert_value( rnArea, mnForeColor, 0, 7 );
1960 0 : ::insert_value( rnArea, mnBackColor, 7, 7 );
1961 0 : }
1962 :
1963 402 : void XclExpCellArea::FillToXF8( sal_uInt32& rnBorder2, sal_uInt16& rnArea ) const
1964 : {
1965 402 : ::insert_value( rnBorder2, mnPattern, 26, 6 );
1966 402 : ::insert_value( rnArea, mnForeColor, 0, 7 );
1967 402 : ::insert_value( rnArea, mnBackColor, 7, 7 );
1968 402 : }
1969 :
1970 0 : void XclExpCellArea::FillToCF8( sal_uInt16& rnPattern, sal_uInt16& rnColor ) const
1971 : {
1972 0 : XclCellArea aTmp( *this );
1973 0 : if( !aTmp.IsTransparent() && (aTmp.mnBackColor == EXC_COLOR_WINDOWTEXT) )
1974 0 : aTmp.mnBackColor = 0;
1975 0 : if( aTmp.mnPattern == EXC_PATT_SOLID )
1976 0 : ::std::swap( aTmp.mnForeColor, aTmp.mnBackColor );
1977 0 : ::insert_value( rnColor, aTmp.mnForeColor, 0, 7 );
1978 0 : ::insert_value( rnColor, aTmp.mnBackColor, 7, 7 );
1979 0 : ::insert_value( rnPattern, aTmp.mnPattern, 10, 6 );
1980 0 : }
1981 :
1982 110 : static const char* ToPatternType( sal_uInt8 nPattern )
1983 : {
1984 110 : switch( nPattern )
1985 : {
1986 55 : case EXC_PATT_NONE: return "none";
1987 0 : case EXC_PATT_SOLID: return "solid";
1988 0 : case EXC_PATT_50_PERC: return "mediumGray";
1989 0 : case EXC_PATT_75_PERC: return "darkGray";
1990 0 : case EXC_PATT_25_PERC: return "lightGray";
1991 55 : case EXC_PATT_12_5_PERC: return "gray125";
1992 0 : case EXC_PATT_6_25_PERC: return "gray0625";
1993 : }
1994 0 : return "*unknown*";
1995 : }
1996 :
1997 110 : void XclExpCellArea::SaveXml( XclExpXmlStream& rStrm ) const
1998 : {
1999 110 : sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
2000 : rStyleSheet->startElement( XML_fill,
2001 110 : FSEND );
2002 :
2003 : // OOXTODO: XML_gradientFill
2004 :
2005 110 : XclExpPalette& rPalette = rStrm.GetRoot().GetPalette();
2006 :
2007 110 : if( mnPattern == EXC_PATT_NONE || ( mnForeColor == 0 && mnBackColor == 0 ) )
2008 : rStyleSheet->singleElement( XML_patternFill,
2009 : XML_patternType, ToPatternType( mnPattern ),
2010 110 : FSEND );
2011 : else
2012 : {
2013 : rStyleSheet->startElement( XML_patternFill,
2014 : XML_patternType, ToPatternType( mnPattern ),
2015 0 : FSEND );
2016 : rStyleSheet->singleElement( XML_fgColor,
2017 0 : XML_rgb, XclXmlUtils::ToOString( rPalette.GetColor( mnForeColor ) ).getStr(),
2018 0 : FSEND );
2019 : rStyleSheet->singleElement( XML_bgColor,
2020 0 : XML_rgb, XclXmlUtils::ToOString( rPalette.GetColor( mnBackColor ) ).getStr(),
2021 0 : FSEND );
2022 0 : rStyleSheet->endElement( XML_patternFill );
2023 : }
2024 :
2025 110 : rStyleSheet->endElement( XML_fill );
2026 110 : }
2027 :
2028 10 : bool XclExpColor::FillFromItemSet( const SfxItemSet& rItemSet )
2029 : {
2030 10 : if( !ScfTools::CheckItem( rItemSet, ATTR_BACKGROUND, true ) )
2031 10 : return false;
2032 :
2033 0 : const SvxBrushItem& rBrushItem = GETITEM( rItemSet, SvxBrushItem, ATTR_BACKGROUND );
2034 0 : maColor = rBrushItem.GetColor();
2035 :
2036 0 : return true;
2037 : }
2038 :
2039 0 : void XclExpColor::SaveXml( XclExpXmlStream& rStrm ) const
2040 : {
2041 0 : sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
2042 : rStyleSheet->startElement( XML_fill,
2043 0 : FSEND );
2044 : rStyleSheet->startElement( XML_patternFill,
2045 0 : FSEND );
2046 : rStyleSheet->singleElement( XML_bgColor,
2047 : XML_rgb, XclXmlUtils::ToOString(maColor).getStr(),
2048 0 : FSEND );
2049 :
2050 0 : rStyleSheet->endElement( XML_patternFill );
2051 0 : rStyleSheet->endElement( XML_fill );
2052 0 : }
2053 :
2054 109824 : XclExpXFId::XclExpXFId() :
2055 109824 : mnXFId( XclExpXFBuffer::GetDefCellXFId() ),
2056 109824 : mnXFIndex( EXC_XF_DEFAULTCELL )
2057 : {
2058 109824 : }
2059 :
2060 6108 : XclExpXFId::XclExpXFId( sal_uInt32 nXFId ) :
2061 : mnXFId( nXFId ),
2062 6108 : mnXFIndex( EXC_XF_DEFAULTCELL )
2063 : {
2064 6108 : }
2065 :
2066 114360 : void XclExpXFId::ConvertXFIndex( const XclExpRoot& rRoot )
2067 : {
2068 114360 : mnXFIndex = rRoot.GetXFBuffer().GetXFIndex( mnXFId );
2069 114360 : }
2070 :
2071 218 : XclExpXF::XclExpXF(
2072 : const XclExpRoot& rRoot, const ScPatternAttr& rPattern, sal_Int16 nScript,
2073 : sal_uLong nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak ) :
2074 : XclXFBase( true ),
2075 218 : XclExpRoot( rRoot )
2076 : {
2077 218 : mnParentXFId = GetXFBuffer().InsertStyle( rPattern.GetStyleSheet() );
2078 218 : Init( rPattern.GetItemSet(), nScript, nForceScNumFmt, nForceXclFont, bForceLineBreak, false );
2079 218 : }
2080 :
2081 84 : XclExpXF::XclExpXF( const XclExpRoot& rRoot, const SfxStyleSheetBase& rStyleSheet ) :
2082 : XclXFBase( false ),
2083 : XclExpRoot( rRoot ),
2084 84 : mnParentXFId( XclExpXFBuffer::GetXFIdFromIndex( EXC_XF_STYLEPARENT ) )
2085 : {
2086 84 : bool bDefStyle = (rStyleSheet.GetName() == ScGlobal::GetRscString( STR_STYLENAME_STANDARD ));
2087 84 : sal_Int16 nScript = bDefStyle ? GetDefApiScript() : ::com::sun::star::i18n::ScriptType::WEAK;
2088 84 : Init( const_cast< SfxStyleSheetBase& >( rStyleSheet ).GetItemSet(), nScript,
2089 168 : NUMBERFORMAT_ENTRY_NOT_FOUND, EXC_FONT_NOTFOUND, false, bDefStyle );
2090 84 : }
2091 :
2092 216 : XclExpXF::XclExpXF( const XclExpRoot& rRoot, bool bCellXF ) :
2093 : XclXFBase( bCellXF ),
2094 : XclExpRoot( rRoot ),
2095 216 : mnParentXFId( XclExpXFBuffer::GetXFIdFromIndex( EXC_XF_STYLEPARENT ) )
2096 : {
2097 216 : InitDefault();
2098 216 : }
2099 :
2100 413193 : bool XclExpXF::Equals( const ScPatternAttr& rPattern,
2101 : sal_uLong nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak ) const
2102 : {
2103 474476 : return IsCellXF() && (mpItemSet == &rPattern.GetItemSet()) &&
2104 18597 : (!bForceLineBreak || maAlignment.mbLineBreak) &&
2105 432738 : ((nForceScNumFmt == NUMBERFORMAT_ENTRY_NOT_FOUND) || (mnScNumFmt == nForceScNumFmt)) &&
2106 413609 : ((nForceXclFont == EXC_FONT_NOTFOUND) || (mnXclFont == nForceXclFont));
2107 : }
2108 :
2109 1210 : bool XclExpXF::Equals( const SfxStyleSheetBase& rStyleSheet ) const
2110 : {
2111 1210 : return IsStyleXF() && (mpItemSet == &const_cast< SfxStyleSheetBase& >( rStyleSheet ).GetItemSet());
2112 : }
2113 :
2114 1670 : void XclExpXF::SetFinalColors()
2115 : {
2116 1670 : maBorder.SetFinalColors( GetPalette() );
2117 1670 : maArea.SetFinalColors( GetPalette() );
2118 1670 : }
2119 :
2120 1076 : bool XclExpXF::Equals( const XclExpXF& rCmpXF ) const
2121 : {
2122 1605 : return XclXFBase::Equals( rCmpXF ) &&
2123 1584 : (maProtection == rCmpXF.maProtection) && (maAlignment == rCmpXF.maAlignment) &&
2124 638 : (maBorder == rCmpXF.maBorder) && (maArea == rCmpXF.maArea) &&
2125 1194 : (mnXclFont == rCmpXF.mnXclFont) && (mnXclNumFmt == rCmpXF.mnXclNumFmt) &&
2126 1106 : (mnParentXFId == rCmpXF.mnParentXFId);
2127 : }
2128 :
2129 518 : void XclExpXF::InitDefault()
2130 : {
2131 518 : SetRecHeader( EXC_ID5_XF, (GetBiff() == EXC_BIFF8) ? 20 : 16 );
2132 518 : mpItemSet = 0;
2133 518 : mnScNumFmt = NUMBERFORMAT_ENTRY_NOT_FOUND;
2134 518 : mnXclFont = mnXclNumFmt = 0;
2135 518 : SetXmlIds(0, 0);
2136 518 : }
2137 :
2138 302 : void XclExpXF::Init( const SfxItemSet& rItemSet, sal_Int16 nScript,
2139 : sal_uLong nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak, bool bDefStyle )
2140 : {
2141 302 : InitDefault();
2142 302 : mpItemSet = &rItemSet;
2143 :
2144 : // cell protection
2145 302 : mbProtUsed = maProtection.FillFromItemSet( rItemSet, IsStyleXF() );
2146 :
2147 : // font
2148 302 : if( nForceXclFont == EXC_FONT_NOTFOUND )
2149 : {
2150 268 : mnXclFont = GetFontBuffer().Insert( rItemSet, nScript, EXC_COLOR_CELLTEXT, bDefStyle );
2151 268 : mbFontUsed = XclExpFontHelper::CheckItems( GetRoot(), rItemSet, nScript, IsStyleXF() );
2152 : }
2153 : else
2154 : {
2155 34 : mnXclFont = nForceXclFont;
2156 34 : mbFontUsed = true;
2157 : }
2158 :
2159 : // number format
2160 : mnScNumFmt = (nForceScNumFmt == NUMBERFORMAT_ENTRY_NOT_FOUND) ?
2161 302 : GETITEMVALUE( rItemSet, SfxUInt32Item, ATTR_VALUE_FORMAT, sal_uLong ) : nForceScNumFmt;
2162 302 : mnXclNumFmt = GetNumFmtBuffer().Insert( mnScNumFmt );
2163 302 : mbFmtUsed = ScfTools::CheckItem( rItemSet, ATTR_VALUE_FORMAT, IsStyleXF() );
2164 : // alignment
2165 302 : mbAlignUsed = maAlignment.FillFromItemSet( rItemSet, bForceLineBreak, GetBiff(), IsStyleXF() );
2166 :
2167 : // cell border
2168 302 : mbBorderUsed = maBorder.FillFromItemSet( rItemSet, GetPalette(), GetBiff(), IsStyleXF() );
2169 :
2170 : // background area
2171 302 : mbAreaUsed = maArea.FillFromItemSet( rItemSet, GetPalette(), IsStyleXF() );
2172 :
2173 : // set all b***Used flags to true in "Default"/"Normal" style
2174 302 : if( bDefStyle )
2175 72 : SetAllUsedFlags( true );
2176 302 : }
2177 :
2178 402 : sal_uInt8 XclExpXF::GetUsedFlags() const
2179 : {
2180 402 : sal_uInt8 nUsedFlags = 0;
2181 : /* In cell XFs a set bit means a used attribute, in style XFs a cleared bit.
2182 : "mbCellXF == mb***Used" evaluates to correct value in cell and style XFs. */
2183 402 : ::set_flag( nUsedFlags, EXC_XF_DIFF_PROT, mbCellXF == mbProtUsed );
2184 402 : ::set_flag( nUsedFlags, EXC_XF_DIFF_FONT, mbCellXF == mbFontUsed );
2185 402 : ::set_flag( nUsedFlags, EXC_XF_DIFF_VALFMT, mbCellXF == mbFmtUsed );
2186 402 : ::set_flag( nUsedFlags, EXC_XF_DIFF_ALIGN, mbCellXF == mbAlignUsed );
2187 402 : ::set_flag( nUsedFlags, EXC_XF_DIFF_BORDER, mbCellXF == mbBorderUsed );
2188 402 : ::set_flag( nUsedFlags, EXC_XF_DIFF_AREA, mbCellXF == mbAreaUsed );
2189 402 : return nUsedFlags;
2190 : }
2191 :
2192 0 : void XclExpXF::WriteBody5( XclExpStream& rStrm )
2193 : {
2194 0 : sal_uInt16 nTypeProt = 0, nAlign = 0;
2195 0 : sal_uInt32 nArea = 0, nBorder = 0;
2196 :
2197 0 : ::set_flag( nTypeProt, EXC_XF_STYLE, IsStyleXF() );
2198 0 : ::insert_value( nTypeProt, mnParent, 4, 12 );
2199 0 : ::insert_value( nAlign, GetUsedFlags(), 10, 6 );
2200 :
2201 0 : maProtection.FillToXF3( nTypeProt );
2202 0 : maAlignment.FillToXF5( nAlign );
2203 0 : maBorder.FillToXF5( nBorder, nArea );
2204 0 : maArea.FillToXF5( nArea );
2205 :
2206 0 : rStrm << mnXclFont << mnXclNumFmt << nTypeProt << nAlign << nArea << nBorder;
2207 0 : }
2208 :
2209 402 : void XclExpXF::WriteBody8( XclExpStream& rStrm )
2210 : {
2211 402 : sal_uInt16 nTypeProt = 0, nAlign = 0, nMiscAttrib = 0, nArea = 0;
2212 402 : sal_uInt32 nBorder1 = 0, nBorder2 = 0;
2213 :
2214 402 : ::set_flag( nTypeProt, EXC_XF_STYLE, IsStyleXF() );
2215 402 : ::insert_value( nTypeProt, mnParent, 4, 12 );
2216 402 : ::insert_value( nMiscAttrib, GetUsedFlags(), 10, 6 );
2217 :
2218 402 : maProtection.FillToXF3( nTypeProt );
2219 402 : maAlignment.FillToXF8( nAlign, nMiscAttrib );
2220 402 : maBorder.FillToXF8( nBorder1, nBorder2 );
2221 402 : maArea.FillToXF8( nBorder2, nArea );
2222 :
2223 402 : rStrm << mnXclFont << mnXclNumFmt << nTypeProt << nAlign << nMiscAttrib << nBorder1 << nBorder2 << nArea;
2224 402 : }
2225 :
2226 402 : void XclExpXF::WriteBody( XclExpStream& rStrm )
2227 : {
2228 402 : XclExpXFId aParentId( mnParentXFId );
2229 402 : aParentId.ConvertXFIndex( GetRoot() );
2230 402 : mnParent = aParentId.mnXFIndex;
2231 402 : switch( GetBiff() )
2232 : {
2233 0 : case EXC_BIFF5: WriteBody5( rStrm ); break;
2234 402 : case EXC_BIFF8: WriteBody8( rStrm ); break;
2235 : default: DBG_ERROR_BIFF();
2236 : }
2237 402 : }
2238 :
2239 1756 : void XclExpXF::SetXmlIds( sal_uInt32 nBorderId, sal_uInt32 nFillId )
2240 : {
2241 1756 : mnBorderId = nBorderId;
2242 1756 : mnFillId = nFillId;
2243 1756 : }
2244 :
2245 1238 : void XclExpXF::SaveXml( XclExpXmlStream& rStrm )
2246 : {
2247 1238 : sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
2248 :
2249 1238 : sal_Int32 nXfId = 0;
2250 1238 : const XclExpXF* pStyleXF = NULL;
2251 1238 : if( IsCellXF() )
2252 : {
2253 126 : sal_uInt16 nXFIndex = rStrm.GetRoot().GetXFBuffer().GetXFIndex( mnParentXFId );
2254 126 : nXfId = rStrm.GetRoot().GetXFBuffer().GetXmlStyleIndex( nXFIndex );
2255 126 : pStyleXF = rStrm.GetRoot().GetXFBuffer().GetXFById( mnParentXFId );
2256 : }
2257 :
2258 : rStyleSheet->startElement( XML_xf,
2259 : XML_numFmtId, OString::number( mnXclNumFmt ).getStr(),
2260 : XML_fontId, OString::number( mnXclFont ).getStr(),
2261 : XML_fillId, OString::number( mnFillId ).getStr(),
2262 : XML_borderId, OString::number( mnBorderId ).getStr(),
2263 2728 : XML_xfId, IsStyleXF() ? NULL : OString::number( nXfId ).getStr(),
2264 : // OOXTODO: XML_quotePrefix,
2265 : // OOXTODO: XML_pivotButton,
2266 : // OOXTODO: XML_applyNumberFormat, ;
2267 : XML_applyFont, XclXmlUtils::ToPsz( mbFontUsed ),
2268 : // OOXTODO: XML_applyFill,
2269 : XML_applyBorder, XclXmlUtils::ToPsz( mbBorderUsed ),
2270 : XML_applyAlignment, XclXmlUtils::ToPsz( mbAlignUsed ),
2271 : XML_applyProtection, XclXmlUtils::ToPsz( mbProtUsed ),
2272 3714 : FSEND );
2273 1238 : if( mbAlignUsed )
2274 70 : maAlignment.SaveXml( rStrm );
2275 1168 : else if ( pStyleXF )
2276 123 : pStyleXF->GetAlignmentData().SaveXml( rStrm );
2277 1238 : if( mbProtUsed )
2278 55 : maProtection.SaveXml( rStrm );
2279 1183 : else if ( pStyleXF )
2280 126 : pStyleXF->GetProtectionData().SaveXml( rStrm );
2281 :
2282 : // OOXTODO: XML_extLst
2283 1238 : rStyleSheet->endElement( XML_xf );
2284 1238 : }
2285 :
2286 216 : XclExpDefaultXF::XclExpDefaultXF( const XclExpRoot& rRoot, bool bCellXF ) :
2287 216 : XclExpXF( rRoot, bCellXF )
2288 : {
2289 216 : }
2290 :
2291 288 : void XclExpDefaultXF::SetFont( sal_uInt16 nXclFont )
2292 : {
2293 288 : mnXclFont = nXclFont;
2294 288 : mbFontUsed = true;
2295 288 : }
2296 :
2297 360 : void XclExpDefaultXF::SetNumFmt( sal_uInt16 nXclNumFmt )
2298 : {
2299 360 : mnXclNumFmt = nXclNumFmt;
2300 360 : mbFmtUsed = true;
2301 360 : }
2302 :
2303 12 : XclExpStyle::XclExpStyle( sal_uInt32 nXFId, const OUString& rStyleName ) :
2304 : XclExpRecord( EXC_ID_STYLE, 4 ),
2305 : maName( rStyleName ),
2306 : maXFId( nXFId ),
2307 : mnStyleId( EXC_STYLE_USERDEF ),
2308 12 : mnLevel( EXC_STYLE_NOLEVEL )
2309 : {
2310 : OSL_ENSURE( !maName.isEmpty(), "XclExpStyle::XclExpStyle - empty style name" );
2311 : #if OSL_DEBUG_LEVEL > 0
2312 : sal_uInt8 nStyleId, nLevel; // do not use members for debug tests
2313 : OSL_ENSURE( !XclTools::GetBuiltInStyleId( nStyleId, nLevel, maName ),
2314 : "XclExpStyle::XclExpStyle - this is a built-in style" );
2315 : #endif
2316 12 : }
2317 :
2318 432 : XclExpStyle::XclExpStyle( sal_uInt32 nXFId, sal_uInt8 nStyleId, sal_uInt8 nLevel ) :
2319 : XclExpRecord( EXC_ID_STYLE, 4 ),
2320 : maXFId( nXFId ),
2321 : mnStyleId( nStyleId ),
2322 432 : mnLevel( nLevel )
2323 : {
2324 432 : }
2325 :
2326 102 : void XclExpStyle::WriteBody( XclExpStream& rStrm )
2327 : {
2328 102 : maXFId.ConvertXFIndex( rStrm.GetRoot() );
2329 102 : ::set_flag( maXFId.mnXFIndex, EXC_STYLE_BUILTIN, IsBuiltIn() );
2330 102 : rStrm << maXFId.mnXFIndex;
2331 :
2332 102 : if( IsBuiltIn() )
2333 : {
2334 102 : rStrm << mnStyleId << mnLevel;
2335 : }
2336 : else
2337 : {
2338 0 : XclExpString aNameEx;
2339 0 : if( rStrm.GetRoot().GetBiff() == EXC_BIFF8 )
2340 0 : aNameEx.Assign( maName );
2341 : else
2342 0 : aNameEx.AssignByte( maName, rStrm.GetRoot().GetTextEncoding(), EXC_STR_8BITLENGTH );
2343 0 : rStrm << aNameEx;
2344 : }
2345 102 : }
2346 :
2347 330 : static const char* lcl_StyleNameFromId( sal_Int32 nStyleId )
2348 : {
2349 330 : switch( nStyleId )
2350 : {
2351 55 : case 0: return "Normal";
2352 55 : case 3: return "Comma";
2353 55 : case 4: return "Currency";
2354 55 : case 5: return "Percent";
2355 55 : case 6: return "Comma [0]";
2356 55 : case 7: return "Currency [0]";
2357 : }
2358 0 : return "*unknown*";
2359 : }
2360 :
2361 342 : void XclExpStyle::SaveXml( XclExpXmlStream& rStrm )
2362 : {
2363 342 : OString sName;
2364 342 : if( IsBuiltIn() )
2365 : {
2366 330 : sName = OString( lcl_StyleNameFromId( mnStyleId ) );
2367 : }
2368 : else
2369 12 : sName = XclXmlUtils::ToOString( maName );
2370 : // get the index in sortedlist associated with the mnXId
2371 342 : sal_Int32 nXFId = rStrm.GetRoot().GetXFBuffer().GetXFIndex( maXFId.mnXFId );
2372 : // get the style index associated with index into sortedlist
2373 342 : nXFId = rStrm.GetRoot().GetXFBuffer().GetXmlStyleIndex( nXFId );
2374 342 : rStrm.GetCurrentStream()->singleElement( XML_cellStyle,
2375 : XML_name, sName.getStr(),
2376 : XML_xfId, OString::number( nXFId ).getStr(),
2377 : // builtinId of 54 or above is invalid according to OpenXML SDK validator.
2378 : #define CELL_STYLE_MAX_BUILTIN_ID 54
2379 684 : XML_builtinId, OString::number( std::min( static_cast<sal_Int32>( CELL_STYLE_MAX_BUILTIN_ID - 1 ), static_cast <sal_Int32>( mnStyleId ) ) ).getStr(),
2380 : // OOXTODO: XML_iLevel,
2381 : // OOXTODO: XML_hidden,
2382 342 : XML_customBuiltin, XclXmlUtils::ToPsz( ! IsBuiltIn() ),
2383 1368 : FSEND );
2384 : // OOXTODO: XML_extLst
2385 342 : }
2386 :
2387 : namespace {
2388 :
2389 : const sal_uInt32 EXC_XFLIST_INDEXBASE = 0xFFFE0000;
2390 : /** Maximum count of XF records to store in the XF list (performance). */
2391 : const sal_uInt32 EXC_XFLIST_HARDLIMIT = 256 * 1024;
2392 :
2393 22 : bool lclIsBuiltInStyle( const OUString& rStyleName )
2394 : {
2395 : return
2396 44 : XclTools::IsBuiltInStyleName( rStyleName ) ||
2397 44 : XclTools::IsCondFormatStyleName( rStyleName );
2398 : }
2399 :
2400 : } // namespace
2401 :
2402 1512 : XclExpXFBuffer::XclExpBuiltInInfo::XclExpBuiltInInfo() :
2403 : mnStyleId( EXC_STYLE_USERDEF ),
2404 : mnLevel( EXC_STYLE_NOLEVEL ),
2405 : mbPredefined( true ),
2406 1512 : mbHasStyleRec( false )
2407 : {
2408 1512 : }
2409 :
2410 : /** Predicate for search algorithm. */
2411 : struct XclExpBorderPred
2412 : {
2413 : const XclExpCellBorder&
2414 : mrBorder;
2415 2878 : inline explicit XclExpBorderPred( const XclExpCellBorder& rBorder ) : mrBorder( rBorder ) {}
2416 : bool operator()( const XclExpCellBorder& rBorder ) const;
2417 : };
2418 :
2419 3864 : bool XclExpBorderPred::operator()( const XclExpCellBorder& rBorder ) const
2420 : {
2421 : return
2422 7251 : mrBorder.mnLeftColor == rBorder.mnLeftColor &&
2423 6610 : mrBorder.mnRightColor == rBorder.mnRightColor &&
2424 6328 : mrBorder.mnTopColor == rBorder.mnTopColor &&
2425 6142 : mrBorder.mnBottomColor == rBorder.mnBottomColor &&
2426 6074 : mrBorder.mnDiagColor == rBorder.mnDiagColor &&
2427 5995 : mrBorder.mnLeftLine == rBorder.mnLeftLine &&
2428 5906 : mrBorder.mnRightLine == rBorder.mnRightLine &&
2429 5690 : mrBorder.mnTopLine == rBorder.mnTopLine &&
2430 5478 : mrBorder.mnBottomLine == rBorder.mnBottomLine &&
2431 5472 : mrBorder.mnDiagLine == rBorder.mnDiagLine &&
2432 5472 : mrBorder.mbDiagTLtoBR == rBorder.mbDiagTLtoBR &&
2433 5472 : mrBorder.mbDiagBLtoTR == rBorder.mbDiagBLtoTR &&
2434 5472 : mrBorder.mnLeftColorId == rBorder.mnLeftColorId &&
2435 5472 : mrBorder.mnRightColorId == rBorder.mnRightColorId &&
2436 5472 : mrBorder.mnTopColorId == rBorder.mnTopColorId &&
2437 9336 : mrBorder.mnBottomColorId == rBorder.mnBottomColorId &&
2438 6600 : mrBorder.mnDiagColorId == rBorder.mnDiagColorId;
2439 : }
2440 :
2441 : struct XclExpFillPred
2442 : {
2443 : const XclExpCellArea&
2444 : mrFill;
2445 2878 : inline explicit XclExpFillPred( const XclExpCellArea& rFill ) : mrFill( rFill ) {}
2446 : bool operator()( const XclExpCellArea& rFill ) const;
2447 : };
2448 :
2449 2878 : bool XclExpFillPred::operator()( const XclExpCellArea& rFill ) const
2450 : {
2451 : return
2452 5756 : mrFill.mnForeColor == rFill.mnForeColor &&
2453 5756 : mrFill.mnBackColor == rFill.mnBackColor &&
2454 5756 : mrFill.mnPattern == rFill.mnPattern &&
2455 8634 : mrFill.mnForeColorId == rFill.mnForeColorId &&
2456 5756 : mrFill.mnBackColorId == rFill.mnBackColorId;
2457 : }
2458 :
2459 72 : XclExpXFBuffer::XclExpXFBuffer( const XclExpRoot& rRoot ) :
2460 72 : XclExpRoot( rRoot )
2461 : {
2462 72 : }
2463 :
2464 72 : void XclExpXFBuffer::Initialize()
2465 : {
2466 72 : InsertDefaultRecords();
2467 72 : InsertUserStyles();
2468 72 : }
2469 :
2470 111646 : sal_uInt32 XclExpXFBuffer::Insert( const ScPatternAttr* pPattern, sal_Int16 nScript )
2471 : {
2472 111646 : return InsertCellXF( pPattern, nScript, NUMBERFORMAT_ENTRY_NOT_FOUND, EXC_FONT_NOTFOUND, false );
2473 : }
2474 :
2475 449 : sal_uInt32 XclExpXFBuffer::InsertWithFont( const ScPatternAttr* pPattern, sal_Int16 nScript,
2476 : sal_uInt16 nForceXclFont, bool bForceLineBreak )
2477 : {
2478 449 : return InsertCellXF( pPattern, nScript, NUMBERFORMAT_ENTRY_NOT_FOUND, nForceXclFont, bForceLineBreak );
2479 : }
2480 :
2481 1111 : sal_uInt32 XclExpXFBuffer::InsertWithNumFmt( const ScPatternAttr* pPattern, sal_Int16 nScript, sal_uLong nForceScNumFmt, bool bForceLineBreak )
2482 : {
2483 1111 : return InsertCellXF( pPattern, nScript, nForceScNumFmt, EXC_FONT_NOTFOUND, bForceLineBreak );
2484 : }
2485 :
2486 218 : sal_uInt32 XclExpXFBuffer::InsertStyle( const SfxStyleSheetBase* pStyleSheet )
2487 : {
2488 218 : return pStyleSheet ? InsertStyleXF( *pStyleSheet ) : GetXFIdFromIndex( EXC_XF_DEFAULTSTYLE );
2489 : }
2490 :
2491 205276 : sal_uInt32 XclExpXFBuffer::GetXFIdFromIndex( sal_uInt16 nXFIndex )
2492 : {
2493 205276 : return EXC_XFLIST_INDEXBASE | nXFIndex;
2494 : }
2495 :
2496 204976 : sal_uInt32 XclExpXFBuffer::GetDefCellXFId()
2497 : {
2498 204976 : return GetXFIdFromIndex( EXC_XF_DEFAULTCELL );
2499 : }
2500 :
2501 575 : const XclExpXF* XclExpXFBuffer::GetXFById( sal_uInt32 nXFId ) const
2502 : {
2503 575 : return maXFList.GetRecord( nXFId ).get();
2504 : }
2505 :
2506 72 : void XclExpXFBuffer::Finalize()
2507 : {
2508 1742 : for( size_t nPos = 0, nSize = maXFList.GetSize(); nPos < nSize; ++nPos )
2509 1670 : maXFList.GetRecord( nPos )->SetFinalColors();
2510 :
2511 72 : sal_uInt32 nTotalCount = static_cast< sal_uInt32 >( maXFList.GetSize() );
2512 : sal_uInt32 nId;
2513 72 : maXFIndexVec.resize( nTotalCount, EXC_XF_DEFAULTCELL );
2514 72 : maStyleIndexes.resize( nTotalCount, EXC_XF_DEFAULTCELL );
2515 72 : maCellIndexes.resize( nTotalCount, EXC_XF_DEFAULTCELL );
2516 :
2517 72 : XclExpBuiltInMap::const_iterator aBuiltInEnd = maBuiltInMap.end();
2518 : /* nMaxBuiltInXFId used to decide faster whether an XF record is
2519 : user-defined. If the current XF ID is greater than this value,
2520 : maBuiltInMap doesn't need to be searched. */
2521 72 : sal_uInt32 nMaxBuiltInXFId = maBuiltInMap.empty() ? 0 : maBuiltInMap.rbegin()->first;
2522 :
2523 : // *** map all built-in XF records (cell and style) *** -------------------
2524 :
2525 : // do not change XF order -> std::map<> iterates elements in ascending order
2526 1584 : for( XclExpBuiltInMap::const_iterator aIt = maBuiltInMap.begin(); aIt != aBuiltInEnd; ++aIt )
2527 1512 : AppendXFIndex( aIt->first );
2528 :
2529 : // *** insert all user-defined style XF records, without reduce *** -------
2530 :
2531 72 : sal_uInt32 nStyleXFCount = 0; // counts up to EXC_XF_MAXSTYLECOUNT limit
2532 :
2533 1742 : for( nId = 0; nId < nTotalCount; ++nId )
2534 : {
2535 1670 : XclExpXFRef xXF = maXFList.GetRecord( nId );
2536 1670 : if( xXF->IsStyleXF() && ((nId > nMaxBuiltInXFId) || (maBuiltInMap.find( nId ) == aBuiltInEnd)) )
2537 : {
2538 12 : if( nStyleXFCount < EXC_XF_MAXSTYLECOUNT )
2539 : {
2540 : // maximum count of styles not reached
2541 12 : AppendXFIndex( nId );
2542 12 : ++nStyleXFCount;
2543 : }
2544 : else
2545 : {
2546 : /* Maximum count of styles reached - do not append more
2547 : pointers to XFs; use default style XF instead; do not break
2548 : the loop to initialize all maXFIndexVec elements. */
2549 0 : maXFIndexVec[ nId ] = EXC_XF_DEFAULTSTYLE;
2550 : }
2551 : }
2552 1670 : }
2553 :
2554 : // *** insert all cell XF records *** -------------------------------------
2555 :
2556 : // start position to search for equal inserted XF records
2557 72 : size_t nSearchStart = maSortedXFList.GetSize();
2558 :
2559 : // break the loop if XF limit reached - maXFIndexVec is already initialized with default index
2560 72 : XclExpXFRef xDefCellXF = maXFList.GetRecord( EXC_XF_DEFAULTCELL );
2561 1742 : for( nId = 0; (nId < nTotalCount) && (maSortedXFList.GetSize() < EXC_XF_MAXCOUNT); ++nId )
2562 : {
2563 1670 : XclExpXFRef xXF = maXFList.GetRecord( nId );
2564 1670 : if( xXF->IsCellXF() && ((nId > nMaxBuiltInXFId) || (maBuiltInMap.find( nId ) == aBuiltInEnd)) )
2565 : {
2566 : // try to find an XF record equal to *xXF, which is already inserted
2567 146 : sal_uInt16 nFoundIndex = EXC_XF_NOTFOUND;
2568 :
2569 : // first try if it is equal to the default cell XF
2570 146 : if( xDefCellXF->Equals( *xXF ) )
2571 : {
2572 30 : nFoundIndex = EXC_XF_DEFAULTCELL;
2573 : }
2574 1046 : else for( size_t nSearchPos = nSearchStart, nSearchEnd = maSortedXFList.GetSize();
2575 930 : (nSearchPos < nSearchEnd) && (nFoundIndex == EXC_XF_NOTFOUND); ++nSearchPos )
2576 : {
2577 930 : if( maSortedXFList.GetRecord( nSearchPos )->Equals( *xXF ) )
2578 0 : nFoundIndex = static_cast< sal_uInt16 >( nSearchPos );
2579 : }
2580 :
2581 146 : if( nFoundIndex != EXC_XF_NOTFOUND )
2582 : // equal XF already in the list, use its resulting XF index
2583 30 : maXFIndexVec[ nId ] = nFoundIndex;
2584 : else
2585 116 : AppendXFIndex( nId );
2586 : }
2587 1670 : }
2588 :
2589 72 : sal_uInt16 nXmlStyleIndex = 0;
2590 72 : sal_uInt16 nXmlCellIndex = 0;
2591 :
2592 72 : size_t nXFCount = maSortedXFList.GetSize();
2593 1712 : for( size_t i = 0; i < nXFCount; ++i )
2594 : {
2595 1640 : XclExpXFList::RecordRefType xXF = maSortedXFList.GetRecord( i );
2596 1640 : if( xXF->IsStyleXF() )
2597 1452 : maStyleIndexes[ i ] = nXmlStyleIndex++;
2598 : else
2599 188 : maCellIndexes[ i ] = nXmlCellIndex++;
2600 1712 : }
2601 72 : }
2602 :
2603 115776 : sal_uInt16 XclExpXFBuffer::GetXFIndex( sal_uInt32 nXFId ) const
2604 : {
2605 115776 : sal_uInt16 nXFIndex = EXC_XF_DEFAULTSTYLE;
2606 115776 : if( nXFId >= EXC_XFLIST_INDEXBASE )
2607 95479 : nXFIndex = static_cast< sal_uInt16 >( nXFId & ~EXC_XFLIST_INDEXBASE );
2608 20297 : else if( nXFId < maXFIndexVec.size() )
2609 20297 : nXFIndex = maXFIndexVec[ nXFId ];
2610 115776 : return nXFIndex;
2611 : }
2612 :
2613 468 : sal_Int32 XclExpXFBuffer::GetXmlStyleIndex( sal_uInt32 nXFIndex ) const
2614 : {
2615 : OSL_ENSURE( nXFIndex < maStyleIndexes.size(), "XclExpXFBuffer::GetXmlStyleIndex - invalid index!" );
2616 468 : if( nXFIndex > maStyleIndexes.size() )
2617 0 : return 0; // should be caught/debugged via above assert; return "valid" index.
2618 468 : return maStyleIndexes[ nXFIndex ];
2619 : }
2620 :
2621 2030 : sal_Int32 XclExpXFBuffer::GetXmlCellIndex( sal_uInt32 nXFIndex ) const
2622 : {
2623 : OSL_ENSURE( nXFIndex < maCellIndexes.size(), "XclExpXFBuffer::GetXmlStyleIndex - invalid index!" );
2624 2030 : if( nXFIndex > maCellIndexes.size() )
2625 0 : return 0; // should be caught/debugged via above assert; return "valid" index.
2626 2030 : return maCellIndexes[ nXFIndex ];
2627 : }
2628 :
2629 17 : void XclExpXFBuffer::Save( XclExpStream& rStrm )
2630 : {
2631 : // save all XF records contained in the maSortedXFList vector (sorted by XF index)
2632 17 : maSortedXFList.Save( rStrm );
2633 : // save all STYLE records
2634 17 : maStyleList.Save( rStrm );
2635 17 : }
2636 :
2637 55 : static void lcl_GetCellCounts( const XclExpRecordList< XclExpXF >& rXFList, sal_Int32& rCells, sal_Int32& rStyles )
2638 : {
2639 55 : rCells = 0;
2640 55 : rStyles = 0;
2641 55 : size_t nXFCount = rXFList.GetSize();
2642 1293 : for( size_t i = 0; i < nXFCount; ++i )
2643 : {
2644 1238 : XclExpRecordList< XclExpXF >::RecordRefType xXF = rXFList.GetRecord( i );
2645 1238 : if( xXF->IsCellXF() )
2646 126 : ++rCells;
2647 1112 : else if( xXF->IsStyleXF() )
2648 1112 : ++rStyles;
2649 1238 : }
2650 55 : }
2651 :
2652 55 : void XclExpXFBuffer::SaveXml( XclExpXmlStream& rStrm )
2653 : {
2654 55 : sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
2655 :
2656 : rStyleSheet->startElement( XML_fills,
2657 : XML_count, OString::number( maFills.size() ).getStr(),
2658 55 : FSEND );
2659 165 : for( XclExpFillList::iterator aIt = maFills.begin(), aEnd = maFills.end();
2660 : aIt != aEnd; ++aIt )
2661 : {
2662 110 : aIt->SaveXml( rStrm );
2663 : }
2664 55 : rStyleSheet->endElement( XML_fills );
2665 :
2666 : rStyleSheet->startElement( XML_borders,
2667 : XML_count, OString::number( maBorders.size() ).getStr(),
2668 55 : FSEND );
2669 157 : for( XclExpBorderList::iterator aIt = maBorders.begin(), aEnd = maBorders.end();
2670 : aIt != aEnd; ++aIt )
2671 : {
2672 102 : aIt->SaveXml( rStrm );
2673 : }
2674 55 : rStyleSheet->endElement( XML_borders );
2675 :
2676 : // save all XF records contained in the maSortedXFList vector (sorted by XF index)
2677 : sal_Int32 nCells, nStyles;
2678 55 : lcl_GetCellCounts( maSortedXFList, nCells, nStyles );
2679 :
2680 55 : if( nStyles > 0 )
2681 : {
2682 : rStyleSheet->startElement( XML_cellStyleXfs,
2683 : XML_count, OString::number( nStyles ).getStr(),
2684 55 : FSEND );
2685 55 : size_t nXFCount = maSortedXFList.GetSize();
2686 1293 : for( size_t i = 0; i < nXFCount; ++i )
2687 : {
2688 1238 : XclExpXFList::RecordRefType xXF = maSortedXFList.GetRecord( i );
2689 1238 : if( ! xXF->IsStyleXF() )
2690 126 : continue;
2691 1112 : SaveXFXml( rStrm, *xXF );
2692 1112 : }
2693 55 : rStyleSheet->endElement( XML_cellStyleXfs );
2694 : }
2695 :
2696 55 : if( nCells > 0 )
2697 : {
2698 : rStyleSheet->startElement( XML_cellXfs,
2699 : XML_count, OString::number( nCells ).getStr(),
2700 55 : FSEND );
2701 55 : size_t nXFCount = maSortedXFList.GetSize();
2702 1293 : for( size_t i = 0; i < nXFCount; ++i )
2703 : {
2704 1238 : XclExpXFList::RecordRefType xXF = maSortedXFList.GetRecord( i );
2705 1238 : if( ! xXF->IsCellXF() )
2706 1112 : continue;
2707 126 : SaveXFXml( rStrm, *xXF );
2708 126 : }
2709 55 : rStyleSheet->endElement( XML_cellXfs );
2710 : }
2711 :
2712 : // save all STYLE records
2713 : rStyleSheet->startElement( XML_cellStyles,
2714 : XML_count, OString::number( maStyleList.GetSize() ).getStr(),
2715 55 : FSEND );
2716 55 : maStyleList.SaveXml( rStrm );
2717 55 : rStyleSheet->endElement( XML_cellStyles );
2718 55 : }
2719 :
2720 1238 : void XclExpXFBuffer::SaveXFXml( XclExpXmlStream& rStrm, XclExpXF& rXF )
2721 : {
2722 : XclExpBorderList::iterator aBorderPos =
2723 1238 : std::find_if( maBorders.begin(), maBorders.end(), XclExpBorderPred( rXF.GetBorderData() ) );
2724 : OSL_ENSURE( aBorderPos != maBorders.end(), "XclExpXFBuffer::SaveXml - Invalid @borderId!" );
2725 : XclExpFillList::iterator aFillPos =
2726 1238 : std::find_if( maFills.begin(), maFills.end(), XclExpFillPred( rXF.GetAreaData() ) );
2727 : OSL_ENSURE( aFillPos != maFills.end(), "XclExpXFBuffer::SaveXml - Invalid @fillId!" );
2728 :
2729 1238 : sal_Int32 nBorderId = 0, nFillId = 0;
2730 1238 : if( aBorderPos != maBorders.end() )
2731 1238 : nBorderId = std::distance( maBorders.begin(), aBorderPos );
2732 1238 : if( aFillPos != maFills.end() )
2733 1238 : nFillId = std::distance( maFills.begin(), aFillPos );
2734 :
2735 1238 : rXF.SetXmlIds( nBorderId, nFillId );
2736 1238 : rXF.SaveXml( rStrm );
2737 1238 : }
2738 :
2739 18742 : sal_uInt32 XclExpXFBuffer::FindXF( const ScPatternAttr& rPattern,
2740 : sal_uLong nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak ) const
2741 : {
2742 413339 : for( size_t nPos = 0, nSize = maXFList.GetSize(); nPos < nSize; ++nPos )
2743 413193 : if( maXFList.GetRecord( nPos )->Equals( rPattern, nForceScNumFmt, nForceXclFont, bForceLineBreak ) )
2744 18596 : return static_cast< sal_uInt32 >( nPos );
2745 146 : return EXC_XFID_NOTFOUND;
2746 : }
2747 :
2748 50 : sal_uInt32 XclExpXFBuffer::FindXF( const SfxStyleSheetBase& rStyleSheet ) const
2749 : {
2750 1222 : for( size_t nPos = 0, nSize = maXFList.GetSize(); nPos < nSize; ++nPos )
2751 1210 : if( maXFList.GetRecord( nPos )->Equals( rStyleSheet ) )
2752 38 : return static_cast< sal_uInt32 >( nPos );
2753 12 : return EXC_XFID_NOTFOUND;
2754 : }
2755 :
2756 180 : sal_uInt32 XclExpXFBuffer::FindBuiltInXF( sal_uInt8 nStyleId, sal_uInt8 nLevel ) const
2757 : {
2758 180 : for( XclExpBuiltInMap::const_iterator aIt = maBuiltInMap.begin(), aEnd = maBuiltInMap.end(); aIt != aEnd; ++aIt )
2759 180 : if( (aIt->second.mnStyleId == nStyleId) && (aIt->second.mnLevel == nLevel) )
2760 180 : return aIt->first;
2761 0 : return EXC_XFID_NOTFOUND;
2762 : }
2763 :
2764 113206 : sal_uInt32 XclExpXFBuffer::InsertCellXF( const ScPatternAttr* pPattern, sal_Int16 nScript,
2765 : sal_uLong nForceScNumFmt, sal_uInt16 nForceXclFont, bool bForceLineBreak )
2766 : {
2767 113206 : const ScPatternAttr* pDefPattern = GetDoc().GetDefPattern();
2768 113206 : if( !pPattern )
2769 1722 : pPattern = pDefPattern;
2770 :
2771 : // special handling for default cell formatting
2772 113206 : if( (pPattern == pDefPattern) && !bForceLineBreak &&
2773 94652 : (nForceScNumFmt == NUMBERFORMAT_ENTRY_NOT_FOUND) &&
2774 : (nForceXclFont == EXC_FONT_NOTFOUND) )
2775 : {
2776 : // Is it the first try to insert the default cell format?
2777 94464 : bool& rbPredefined = maBuiltInMap[ EXC_XF_DEFAULTCELL ].mbPredefined;
2778 94464 : if( rbPredefined )
2779 : {
2780 : // replace default cell pattern
2781 72 : XclExpXFRef xNewXF( new XclExpXF( GetRoot(), *pPattern, nScript ) );
2782 72 : maXFList.ReplaceRecord( xNewXF, EXC_XF_DEFAULTCELL );
2783 72 : rbPredefined = false;
2784 : }
2785 94464 : return GetDefCellXFId();
2786 : }
2787 :
2788 18742 : sal_uInt32 nXFId = FindXF( *pPattern, nForceScNumFmt, nForceXclFont, bForceLineBreak );
2789 18742 : if( nXFId == EXC_XFID_NOTFOUND )
2790 : {
2791 : // not found - insert new cell XF
2792 146 : if( maXFList.GetSize() < EXC_XFLIST_HARDLIMIT )
2793 : {
2794 : maXFList.AppendNewRecord( new XclExpXF(
2795 146 : GetRoot(), *pPattern, nScript, nForceScNumFmt, nForceXclFont, bForceLineBreak ) );
2796 : // do not set nXFId before the AppendNewRecord() call - it may insert 2 XFs (style+cell)
2797 146 : nXFId = static_cast< sal_uInt32 >( maXFList.GetSize() - 1 );
2798 : }
2799 : else
2800 : {
2801 : // list full - fall back to default cell XF
2802 0 : nXFId = GetDefCellXFId();
2803 : }
2804 : }
2805 18742 : return nXFId;
2806 : }
2807 :
2808 230 : sal_uInt32 XclExpXFBuffer::InsertStyleXF( const SfxStyleSheetBase& rStyleSheet )
2809 : {
2810 : // *** try, if it is a built-in style - create new XF or replace existing predefined XF ***
2811 :
2812 : sal_uInt8 nStyleId, nLevel;
2813 230 : if( XclTools::GetBuiltInStyleId( nStyleId, nLevel, rStyleSheet.GetName() ) )
2814 : {
2815 : // try to find the built-in XF record (if already created in InsertDefaultRecords())
2816 180 : sal_uInt32 nXFId = FindBuiltInXF( nStyleId, nLevel );
2817 180 : if( nXFId == EXC_XFID_NOTFOUND )
2818 : {
2819 : // built-in style XF not yet created - do it now
2820 0 : XclExpXFRef xXF( new XclExpXF( GetRoot(), rStyleSheet ) );
2821 0 : nXFId = AppendBuiltInXFWithStyle( xXF, nStyleId, nLevel );
2822 : // this new XF record is not predefined
2823 0 : maBuiltInMap[ nXFId ].mbPredefined = false;
2824 : }
2825 : else
2826 : {
2827 : OSL_ENSURE( maXFList.HasRecord( nXFId ), "XclExpXFBuffer::InsertStyleXF - built-in XF not found" );
2828 : // XF record still predefined? -> Replace with real XF
2829 180 : bool& rbPredefined = maBuiltInMap[ nXFId ].mbPredefined;
2830 180 : if( rbPredefined )
2831 : {
2832 : // replace predefined built-in style (ReplaceRecord() deletes old record)
2833 0 : maXFList.ReplaceRecord( XclExpXFRef( new XclExpXF( GetRoot(), rStyleSheet ) ), nXFId );
2834 0 : rbPredefined = false;
2835 : }
2836 : }
2837 :
2838 : // STYLE already inserted? (may be not, i.e. for RowLevel/ColLevel or Hyperlink styles)
2839 180 : bool& rbHasStyleRec = maBuiltInMap[ nXFId ].mbHasStyleRec;
2840 180 : if( !rbHasStyleRec )
2841 : {
2842 0 : maStyleList.AppendNewRecord( new XclExpStyle( nXFId, nStyleId, nLevel ) );
2843 0 : rbHasStyleRec = true;
2844 : }
2845 :
2846 180 : return nXFId;
2847 : }
2848 :
2849 : // *** try to find the XF record of a user-defined style ***
2850 :
2851 50 : sal_uInt32 nXFId = FindXF( rStyleSheet );
2852 50 : if( nXFId == EXC_XFID_NOTFOUND )
2853 : {
2854 : // not found - insert new style XF and STYLE
2855 12 : nXFId = static_cast< sal_uInt32 >( maXFList.GetSize() );
2856 12 : if( nXFId < EXC_XFLIST_HARDLIMIT )
2857 : {
2858 12 : maXFList.AppendNewRecord( new XclExpXF( GetRoot(), rStyleSheet ) );
2859 : // create the STYLE record
2860 12 : if( !rStyleSheet.GetName().isEmpty() )
2861 12 : maStyleList.AppendNewRecord( new XclExpStyle( nXFId, rStyleSheet.GetName() ) );
2862 : }
2863 : else
2864 : // list full - fall back to default style XF
2865 0 : nXFId = GetXFIdFromIndex( EXC_XF_DEFAULTSTYLE );
2866 : }
2867 50 : return nXFId;
2868 : }
2869 :
2870 72 : void XclExpXFBuffer::InsertUserStyles()
2871 : {
2872 72 : SfxStyleSheetIterator aStyleIter( GetDoc().GetStyleSheetPool(), SFX_STYLE_FAMILY_PARA );
2873 454 : for( SfxStyleSheetBase* pStyleSheet = aStyleIter.First(); pStyleSheet; pStyleSheet = aStyleIter.Next() )
2874 382 : if( pStyleSheet->IsUserDefined() && !lclIsBuiltInStyle( pStyleSheet->GetName() ) )
2875 84 : InsertStyleXF( *pStyleSheet );
2876 72 : }
2877 :
2878 1440 : sal_uInt32 XclExpXFBuffer::AppendBuiltInXF( XclExpXFRef xXF, sal_uInt8 nStyleId, sal_uInt8 nLevel )
2879 : {
2880 1440 : sal_uInt32 nXFId = static_cast< sal_uInt32 >( maXFList.GetSize() );
2881 1440 : maXFList.AppendRecord( xXF );
2882 1440 : XclExpBuiltInInfo& rInfo = maBuiltInMap[ nXFId ];
2883 1440 : rInfo.mnStyleId = nStyleId;
2884 1440 : rInfo.mnLevel = nLevel;
2885 1440 : rInfo.mbPredefined = true;
2886 1440 : return nXFId;
2887 : }
2888 :
2889 432 : sal_uInt32 XclExpXFBuffer::AppendBuiltInXFWithStyle( XclExpXFRef xXF, sal_uInt8 nStyleId, sal_uInt8 nLevel )
2890 : {
2891 432 : sal_uInt32 nXFId = AppendBuiltInXF( xXF, nStyleId, nLevel );
2892 432 : maStyleList.AppendNewRecord( new XclExpStyle( nXFId, nStyleId, nLevel ) );
2893 432 : maBuiltInMap[ nXFId ].mbHasStyleRec = true; // mark existing STYLE record
2894 432 : return nXFId;
2895 : }
2896 :
2897 72 : static XclExpCellArea lcl_GetPatternFill_None()
2898 : {
2899 72 : XclExpCellArea aFill;
2900 72 : aFill.mnPattern = EXC_PATT_NONE;
2901 72 : return aFill;
2902 : }
2903 :
2904 72 : static XclExpCellArea lcl_GetPatternFill_Gray125()
2905 : {
2906 72 : XclExpCellArea aFill;
2907 72 : aFill.mnPattern = EXC_PATT_12_5_PERC;
2908 72 : aFill.mnForeColor = 0;
2909 72 : aFill.mnBackColor = 0;
2910 72 : return aFill;
2911 : }
2912 :
2913 72 : void XclExpXFBuffer::InsertDefaultRecords()
2914 : {
2915 72 : maFills.push_back( lcl_GetPatternFill_None() );
2916 72 : maFills.push_back( lcl_GetPatternFill_Gray125() );
2917 :
2918 : // index 0: default style
2919 72 : if( SfxStyleSheetBase* pDefStyleSheet = GetStyleSheetPool().Find( ScGlobal::GetRscString( STR_STYLENAME_STANDARD ), SFX_STYLE_FAMILY_PARA ) )
2920 : {
2921 72 : XclExpXFRef xDefStyle( new XclExpXF( GetRoot(), *pDefStyleSheet ) );
2922 72 : sal_uInt32 nXFId = AppendBuiltInXFWithStyle( xDefStyle, EXC_STYLE_NORMAL );
2923 : // mark this XF as not predefined, prevents overwriting
2924 72 : maBuiltInMap[ nXFId ].mbPredefined = false;
2925 : }
2926 : else
2927 : {
2928 : OSL_FAIL( "XclExpXFBuffer::InsertDefaultRecords - default style not found" );
2929 0 : XclExpXFRef xDefStyle( new XclExpDefaultXF( GetRoot(), false ) );
2930 0 : xDefStyle->SetAllUsedFlags( true );
2931 0 : AppendBuiltInXFWithStyle( xDefStyle, EXC_STYLE_NORMAL );
2932 : }
2933 :
2934 : // index 1-14: RowLevel and ColLevel styles (without STYLE records)
2935 72 : XclExpDefaultXF aLevelStyle( GetRoot(), false );
2936 : // RowLevel_1, ColLevel_1
2937 72 : aLevelStyle.SetFont( 1 );
2938 72 : AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_ROWLEVEL, 0 );
2939 72 : AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_COLLEVEL, 0 );
2940 : // RowLevel_2, ColLevel_2
2941 72 : aLevelStyle.SetFont( 2 );
2942 72 : AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_ROWLEVEL, 1 );
2943 72 : AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_COLLEVEL, 1 );
2944 : // RowLevel_3, ColLevel_3 ... RowLevel_7, ColLevel_7
2945 72 : aLevelStyle.SetFont( 0 );
2946 432 : for( sal_uInt8 nLevel = 2; nLevel < EXC_STYLE_LEVELCOUNT; ++nLevel )
2947 : {
2948 360 : AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_ROWLEVEL, nLevel );
2949 360 : AppendBuiltInXF( XclExpXFRef( new XclExpDefaultXF( aLevelStyle ) ), EXC_STYLE_COLLEVEL, nLevel );
2950 : }
2951 :
2952 : // index 15: default hard cell format, placeholder to be able to add more built-in styles
2953 72 : maXFList.AppendNewRecord( new XclExpDefaultXF( GetRoot(), true ) );
2954 72 : maBuiltInMap[ EXC_XF_DEFAULTCELL ].mbPredefined = true;
2955 :
2956 : // index 16-20: other built-in styles
2957 144 : XclExpDefaultXF aFormatStyle( GetRoot(), false );
2958 72 : aFormatStyle.SetFont( 1 );
2959 72 : aFormatStyle.SetNumFmt( 43 );
2960 72 : AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_COMMA );
2961 72 : aFormatStyle.SetNumFmt( 41 );
2962 72 : AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_COMMA_0 );
2963 72 : aFormatStyle.SetNumFmt( 44 );
2964 72 : AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_CURRENCY );
2965 72 : aFormatStyle.SetNumFmt( 42 );
2966 72 : AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_CURRENCY_0 );
2967 72 : aFormatStyle.SetNumFmt( 9 );
2968 72 : AppendBuiltInXFWithStyle( XclExpXFRef( new XclExpDefaultXF( aFormatStyle ) ), EXC_STYLE_PERCENT );
2969 :
2970 : // other built-in style XF records (i.e. Hyperlink styles) are created on demand
2971 :
2972 : /* Insert the real default hard cell format -> 0 is document default pattern.
2973 : Do it here (and not already above) to really have all built-in styles. */
2974 144 : Insert( 0, GetDefApiScript() );
2975 72 : }
2976 :
2977 1640 : void XclExpXFBuffer::AppendXFIndex( sal_uInt32 nXFId )
2978 : {
2979 : OSL_ENSURE( nXFId < maXFIndexVec.size(), "XclExpXFBuffer::AppendXFIndex - XF ID out of range" );
2980 1640 : maXFIndexVec[ nXFId ] = static_cast< sal_uInt16 >( maSortedXFList.GetSize() );
2981 1640 : XclExpXFRef xXF = maXFList.GetRecord( nXFId );
2982 1640 : AddBorderAndFill( *xXF );
2983 1640 : maSortedXFList.AppendRecord( xXF );
2984 1640 : OSL_ENSURE( maXFList.HasRecord( nXFId ), "XclExpXFBuffer::AppendXFIndex - XF not found" );
2985 1640 : }
2986 :
2987 1640 : void XclExpXFBuffer::AddBorderAndFill( const XclExpXF& rXF )
2988 : {
2989 1640 : if( std::none_of( maBorders.begin(), maBorders.end(), XclExpBorderPred( rXF.GetBorderData() ) ) )
2990 : {
2991 142 : maBorders.push_back( rXF.GetBorderData() );
2992 : }
2993 :
2994 1640 : if( std::none_of( maFills.begin(), maFills.end(), XclExpFillPred( rXF.GetAreaData() ) ) )
2995 : {
2996 0 : maFills.push_back( rXF.GetAreaData() );
2997 : }
2998 1640 : }
2999 :
3000 72 : XclExpDxfs::XclExpDxfs( const XclExpRoot& rRoot )
3001 : : XclExpRoot( rRoot ),
3002 72 : mxFormatter( new SvNumberFormatter( comphelper::getProcessComponentContext(), LANGUAGE_ENGLISH_US ) ),
3003 144 : mpKeywordTable( new NfKeywordTable )
3004 : {
3005 72 : mxFormatter->FillKeywordTable( *mpKeywordTable, LANGUAGE_ENGLISH_US );
3006 : // remap codes unknown to Excel
3007 72 : (*mpKeywordTable)[ NF_KEY_NN ] = "DDD";
3008 72 : (*mpKeywordTable)[ NF_KEY_NNN ] = "DDDD";
3009 : // NNNN gets a separator appended in SvNumberformat::GetMappedFormatString()
3010 72 : (*mpKeywordTable)[ NF_KEY_NNNN ] = "DDDD";
3011 : // Export the Thai T NatNum modifier.
3012 72 : (*mpKeywordTable)[ NF_KEY_THAI_T ] = "T";
3013 :
3014 72 : SCTAB nTables = rRoot.GetDoc().GetTableCount();
3015 201 : for(SCTAB nTab = 0; nTab < nTables; ++nTab)
3016 : {
3017 129 : ScConditionalFormatList* pList = rRoot.GetDoc().GetCondFormList(nTab);
3018 129 : if (pList)
3019 : {
3020 129 : sal_Int32 nIndex = 0;
3021 450 : for (ScConditionalFormatList::const_iterator itr = pList->begin();
3022 300 : itr != pList->end(); ++itr)
3023 : {
3024 21 : size_t nEntryCount = itr->size();
3025 42 : for (size_t nFormatEntry = 0; nFormatEntry < nEntryCount; ++nFormatEntry)
3026 : {
3027 21 : const ScFormatEntry* pFormatEntry = itr->GetEntry(nFormatEntry);
3028 32 : if (!pFormatEntry || (pFormatEntry->GetType() != condformat::CONDITION &&
3029 11 : pFormatEntry->GetType() != condformat::DATE))
3030 22 : continue;
3031 :
3032 10 : OUString aStyleName;
3033 10 : if(pFormatEntry->GetType() == condformat::CONDITION)
3034 : {
3035 10 : const ScCondFormatEntry* pEntry = static_cast<const ScCondFormatEntry*>(pFormatEntry);
3036 10 : aStyleName= pEntry->GetStyle();
3037 : }
3038 : else
3039 : {
3040 0 : const ScCondDateFormatEntry* pEntry = static_cast<const ScCondDateFormatEntry*>(pFormatEntry);
3041 0 : aStyleName = pEntry->GetStyleName();
3042 : }
3043 :
3044 10 : if (maStyleNameToDxfId.find(aStyleName) == maStyleNameToDxfId.end())
3045 : {
3046 10 : maStyleNameToDxfId.insert(std::pair<OUString, sal_Int32>(aStyleName, nIndex));
3047 :
3048 10 : SfxStyleSheetBase* pStyle = rRoot.GetDoc().GetStyleSheetPool()->Find(aStyleName);
3049 10 : if(!pStyle)
3050 0 : continue;
3051 :
3052 10 : SfxItemSet& rSet = pStyle->GetItemSet();
3053 :
3054 10 : XclExpCellBorder* pBorder = new XclExpCellBorder;
3055 10 : if (!pBorder->FillFromItemSet( rSet, GetPalette(), GetBiff()) )
3056 : {
3057 10 : delete pBorder;
3058 10 : pBorder = NULL;
3059 : }
3060 :
3061 10 : XclExpCellAlign* pAlign = new XclExpCellAlign;
3062 10 : if (!pAlign->FillFromItemSet( rSet, false, GetBiff()))
3063 : {
3064 10 : delete pAlign;
3065 10 : pAlign = NULL;
3066 : }
3067 :
3068 10 : XclExpCellProt* pCellProt = new XclExpCellProt;
3069 10 : if (!pCellProt->FillFromItemSet( rSet ))
3070 : {
3071 10 : delete pCellProt;
3072 10 : pCellProt = NULL;
3073 : }
3074 :
3075 10 : XclExpColor* pColor = new XclExpColor();
3076 10 : if(!pColor->FillFromItemSet( rSet ))
3077 : {
3078 10 : delete pColor;
3079 10 : pColor = NULL;
3080 : }
3081 :
3082 10 : XclExpDxfFont* pFont = new XclExpDxfFont(rRoot, rSet);
3083 :
3084 10 : XclExpNumFmt* pNumFormat = NULL;
3085 10 : const SfxPoolItem *pPoolItem = NULL;
3086 10 : if( rSet.GetItemState( ATTR_VALUE_FORMAT, true, &pPoolItem ) == SfxItemState::SET )
3087 : {
3088 10 : sal_uLong nScNumFmt = static_cast< const SfxUInt32Item* >(pPoolItem)->GetValue();
3089 10 : sal_Int32 nXclNumFmt = GetRoot().GetNumFmtBuffer().Insert(nScNumFmt);
3090 10 : pNumFormat = new XclExpNumFmt( nScNumFmt, nXclNumFmt, GetNumberFormatCode( *this, nScNumFmt, mxFormatter.get(), mpKeywordTable.get() ));
3091 : }
3092 :
3093 10 : maDxf.push_back(new XclExpDxf( rRoot, pAlign, pBorder, pFont, pNumFormat, pCellProt, pColor ));
3094 10 : ++nIndex;
3095 : }
3096 :
3097 10 : }
3098 : }
3099 : }
3100 : }
3101 72 : }
3102 :
3103 10 : sal_Int32 XclExpDxfs::GetDxfId( const OUString& rStyleName )
3104 : {
3105 10 : std::map<OUString, sal_Int32>::iterator itr = maStyleNameToDxfId.find(rStyleName);
3106 10 : if(itr!= maStyleNameToDxfId.end())
3107 10 : return itr->second;
3108 0 : return -1;
3109 : }
3110 :
3111 55 : void XclExpDxfs::SaveXml( XclExpXmlStream& rStrm )
3112 : {
3113 55 : if(maDxf.empty())
3114 109 : return;
3115 :
3116 1 : sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
3117 : rStyleSheet->startElement( XML_dxfs,
3118 : XML_count, OString::number(maDxf.size()).getStr(),
3119 1 : FSEND );
3120 :
3121 11 : for ( DxfContainer::iterator itr = maDxf.begin(); itr != maDxf.end(); ++itr )
3122 : {
3123 10 : itr->SaveXml( rStrm );
3124 : }
3125 :
3126 1 : rStyleSheet->endElement( XML_dxfs );
3127 : }
3128 :
3129 10 : XclExpDxf::XclExpDxf( const XclExpRoot& rRoot, XclExpCellAlign* pAlign, XclExpCellBorder* pBorder,
3130 : XclExpDxfFont* pFont, XclExpNumFmt* pNumberFmt, XclExpCellProt* pProt, XclExpColor* pColor)
3131 : : XclExpRoot( rRoot ),
3132 : mpAlign(pAlign),
3133 : mpBorder(pBorder),
3134 : mpFont(pFont),
3135 : mpNumberFmt(pNumberFmt),
3136 : mpProt(pProt),
3137 10 : mpColor(pColor)
3138 : {
3139 10 : }
3140 :
3141 20 : XclExpDxf::~XclExpDxf()
3142 : {
3143 20 : }
3144 :
3145 10 : void XclExpDxf::SaveXml( XclExpXmlStream& rStrm )
3146 : {
3147 10 : sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream();
3148 10 : rStyleSheet->startElement( XML_dxf, FSEND );
3149 :
3150 10 : if (mpFont)
3151 10 : mpFont->SaveXml(rStrm);
3152 10 : if (mpNumberFmt)
3153 10 : mpNumberFmt->SaveXml(rStrm);
3154 10 : if (mpColor)
3155 0 : mpColor->SaveXml(rStrm);
3156 10 : if (mpAlign)
3157 0 : mpAlign->SaveXml(rStrm);
3158 10 : if (mpBorder)
3159 0 : mpBorder->SaveXml(rStrm);
3160 10 : if (mpProt)
3161 0 : mpProt->SaveXml(rStrm);
3162 10 : rStyleSheet->endElement( XML_dxf );
3163 10 : }
3164 :
3165 55 : XclExpXmlStyleSheet::XclExpXmlStyleSheet( const XclExpRoot& rRoot )
3166 55 : : XclExpRoot( rRoot )
3167 : {
3168 55 : }
3169 :
3170 55 : void XclExpXmlStyleSheet::SaveXml( XclExpXmlStream& rStrm )
3171 : {
3172 : sax_fastparser::FSHelperPtr aStyleSheet = rStrm.CreateOutputStream(
3173 : OUString( "xl/styles.xml"),
3174 : OUString( "styles.xml" ),
3175 55 : rStrm.GetCurrentStream()->getOutputStream(),
3176 : "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
3177 55 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" );
3178 55 : rStrm.PushStream( aStyleSheet );
3179 :
3180 : aStyleSheet->startElement( XML_styleSheet,
3181 : XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
3182 55 : FSEND );
3183 :
3184 55 : CreateRecord( EXC_ID_FORMATLIST )->SaveXml( rStrm );
3185 55 : CreateRecord( EXC_ID_FONTLIST )->SaveXml( rStrm );
3186 55 : CreateRecord( EXC_ID_XFLIST )->SaveXml( rStrm );
3187 55 : CreateRecord( EXC_ID_DXFS )->SaveXml( rStrm );
3188 55 : CreateRecord( EXC_ID_PALETTE )->SaveXml( rStrm );
3189 :
3190 55 : aStyleSheet->endElement( XML_styleSheet );
3191 :
3192 55 : rStrm.PopStream();
3193 85 : }
3194 :
3195 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|