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