xref: /aoo42x/main/sc/source/filter/excel/xlstyle.cxx (revision b77af630)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_scfilt.hxx"
26 
27 #include "xlstyle.hxx"
28 #include <com/sun/star/awt/FontFamily.hpp>
29 #include <com/sun/star/awt/FontSlant.hpp>
30 #include <com/sun/star/awt/FontUnderline.hpp>
31 #include <com/sun/star/i18n/ScriptType.hpp>
32 #include <vcl/svapp.hxx>
33 #include <vcl/font.hxx>
34 #include <rtl/tencinfo.h>
35 #include <toolkit/helper/vclunohelper.hxx>
36 #include <editeng/svxfont.hxx>
37 #include "global.hxx"
38 #include "xlroot.hxx"
39 
40 // Color data =================================================================
41 
42 /** Standard EGA colors, bright. */
43 #define EXC_PALETTE_EGA_COLORS_LIGHT \
44             0x000000, 0xFFFFFF, 0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF
45 /** Standard EGA colors, dark. */
46 #define EXC_PALETTE_EGA_COLORS_DARK \
47             0x800000, 0x008000, 0x000080, 0x808000, 0x800080, 0x008080, 0xC0C0C0, 0x808080
48 
49 /** Default color table for BIFF2. */
50 static const ColorData spnDefColorTable2[] =
51 {
52 /*  0 */    EXC_PALETTE_EGA_COLORS_LIGHT
53 };
54 
55 /** Default color table for BIFF3/BIFF4. */
56 static const ColorData spnDefColorTable3[] =
57 {
58 /*  0 */    EXC_PALETTE_EGA_COLORS_LIGHT,
59 /*  8 */    EXC_PALETTE_EGA_COLORS_LIGHT,
60 /* 16 */    EXC_PALETTE_EGA_COLORS_DARK
61 };
62 
63 /** Default color table for BIFF5/BIFF7. */
64 static const ColorData spnDefColorTable5[] =
65 {
66 /*  0 */    EXC_PALETTE_EGA_COLORS_LIGHT,
67 /*  8 */    EXC_PALETTE_EGA_COLORS_LIGHT,
68 /* 16 */    EXC_PALETTE_EGA_COLORS_DARK,
69 /* 24 */    0x8080FF, 0x802060, 0xFFFFC0, 0xA0E0E0, 0x600080, 0xFF8080, 0x0080C0, 0xC0C0FF,
70 /* 32 */    0x000080, 0xFF00FF, 0xFFFF00, 0x00FFFF, 0x800080, 0x800000, 0x008080, 0x0000FF,
71 /* 40 */    0x00CFFF, 0x69FFFF, 0xE0FFE0, 0xFFFF80, 0xA6CAF0, 0xDD9CB3, 0xB38FEE, 0xE3E3E3,
72 /* 48 */    0x2A6FF9, 0x3FB8CD, 0x488436, 0x958C41, 0x8E5E42, 0xA0627A, 0x624FAC, 0x969696,
73 /* 56 */    0x1D2FBE, 0x286676, 0x004500, 0x453E01, 0x6A2813, 0x85396A, 0x4A3285, 0x424242
74 };
75 
76 /** Default color table for BIFF8. */
77 static const ColorData spnDefColorTable8[] =
78 {
79 /*  0 */    EXC_PALETTE_EGA_COLORS_LIGHT,
80 /*  8 */    EXC_PALETTE_EGA_COLORS_LIGHT,
81 /* 16 */    EXC_PALETTE_EGA_COLORS_DARK,
82 /* 24 */    0x9999FF, 0x993366, 0xFFFFCC, 0xCCFFFF, 0x660066, 0xFF8080, 0x0066CC, 0xCCCCFF,
83 /* 32 */    0x000080, 0xFF00FF, 0xFFFF00, 0x00FFFF, 0x800080, 0x800000, 0x008080, 0x0000FF,
84 /* 40 */    0x00CCFF, 0xCCFFFF, 0xCCFFCC, 0xFFFF99, 0x99CCFF, 0xFF99CC, 0xCC99FF, 0xFFCC99,
85 /* 48 */    0x3366FF, 0x33CCCC, 0x99CC00, 0xFFCC00, 0xFF9900, 0xFF6600, 0x666699, 0x969696,
86 /* 56 */    0x003366, 0x339966, 0x003300, 0x333300, 0x993300, 0x993366, 0x333399, 0x333333
87 };
88 
89 #undef EXC_PALETTE_EGA_COLORS_LIGHT
90 #undef EXC_PALETTE_EGA_COLORS_DARK
91 
92 // ----------------------------------------------------------------------------
93 
XclDefaultPalette(const XclRoot & rRoot)94 XclDefaultPalette::XclDefaultPalette( const XclRoot& rRoot ) :
95     mpnColorTable( 0 ),
96     mnTableSize( 0 )
97 {
98     const StyleSettings& rSett = Application::GetSettings().GetStyleSettings();
99     mnWindowText = rSett.GetWindowTextColor().GetColor();
100     mnWindowBack = rSett.GetWindowColor().GetColor();
101     mnFaceColor = rSett.GetFaceColor().GetColor();
102     mnNoteText = rSett.GetHelpTextColor().GetColor();
103     mnNoteBack = rSett.GetHelpColor().GetColor();
104 
105     // default colors
106     switch( rRoot.GetBiff() )
107     {
108         case EXC_BIFF2:
109             mpnColorTable = spnDefColorTable2;
110             mnTableSize = STATIC_ARRAY_SIZE( spnDefColorTable2 );
111         break;
112         case EXC_BIFF3:
113         case EXC_BIFF4:
114             mpnColorTable = spnDefColorTable3;
115             mnTableSize = STATIC_ARRAY_SIZE( spnDefColorTable3 );
116         break;
117         case EXC_BIFF5:
118             mpnColorTable = spnDefColorTable5;
119             mnTableSize = STATIC_ARRAY_SIZE( spnDefColorTable5 );
120         break;
121         case EXC_BIFF8:
122             mpnColorTable = spnDefColorTable8;
123             mnTableSize = STATIC_ARRAY_SIZE( spnDefColorTable8 );
124         break;
125         default:
126             DBG_ERROR_BIFF();
127     }
128 }
129 
GetDefColorData(sal_uInt16 nXclIndex) const130 ColorData XclDefaultPalette::GetDefColorData( sal_uInt16 nXclIndex ) const
131 {
132     ColorData nColor;
133     if( nXclIndex < mnTableSize )
134         nColor = mpnColorTable[ nXclIndex ];
135     else switch( nXclIndex )
136     {
137         case EXC_COLOR_WINDOWTEXT3:
138         case EXC_COLOR_WINDOWTEXT:
139         case EXC_COLOR_CHWINDOWTEXT:    nColor = mnWindowText;  break;
140         case EXC_COLOR_WINDOWBACK3:
141         case EXC_COLOR_WINDOWBACK:
142         case EXC_COLOR_CHWINDOWBACK:    nColor = mnWindowBack;  break;
143         case EXC_COLOR_BUTTONBACK:      nColor = mnFaceColor;   break;
144         case EXC_COLOR_CHBORDERAUTO:    nColor = COL_BLACK;     break;  // TODO: really always black?
145         case EXC_COLOR_NOTEBACK:        nColor = mnNoteBack;    break;
146         case EXC_COLOR_NOTETEXT:        nColor = mnNoteText;    break;
147         case EXC_COLOR_FONTAUTO:        nColor = COL_AUTO;      break;
148         default:
149             DBG_ERROR1( "XclDefaultPalette::GetDefColorData - unknown default color index: %d", nXclIndex );
150             nColor = COL_AUTO;
151     }
152     return nColor;
153 }
154 
155 // Font Data ==================================================================
156 
157 namespace Awt              = ::com::sun::star::awt;
158 namespace AwtFontFamily    = Awt::FontFamily;
159 namespace AwtFontUnderline = Awt::FontUnderline;
160 namespace AwtFontStrikeout = Awt::FontStrikeout;
161 
162 // ----------------------------------------------------------------------------
163 
XclFontData()164 XclFontData::XclFontData()
165 {
166     Clear();
167 }
168 
XclFontData(const Font & rFont)169 XclFontData::XclFontData( const Font& rFont )
170 {
171     Clear();
172     FillFromVclFont( rFont );
173 }
174 
XclFontData(const SvxFont & rFont)175 XclFontData::XclFontData( const SvxFont& rFont )
176 {
177     FillFromSvxFont( rFont );
178 }
179 
Clear()180 void XclFontData::Clear()
181 {
182     maName.Erase();
183     maStyle.Erase();
184     maColor.SetColor( COL_AUTO );
185     mnHeight = 0;
186     mnWeight = EXC_FONTWGHT_DONTKNOW;
187     mnEscapem = EXC_FONTESC_NONE;
188     mnFamily = EXC_FONTFAM_SYSTEM;
189     mnCharSet = EXC_FONTCSET_ANSI_LATIN;
190     mnUnderline = EXC_FONTUNDERL_NONE;
191     mbItalic = mbStrikeout = mbOutline = mbShadow = false;
192 }
193 
FillFromVclFont(const Font & rFont)194 void XclFontData::FillFromVclFont( const Font& rFont )
195 {
196     maName = XclTools::GetXclFontName( rFont.GetName() );   // #106246# substitute with MS fonts
197     maStyle.Erase();
198     maColor = rFont.GetColor();
199     SetScUnderline( rFont.GetUnderline() );
200     mnEscapem = EXC_FONTESC_NONE;
201     SetScHeight( rFont.GetSize().Height() );
202     SetScWeight( rFont.GetWeight() );
203     SetScFamily( rFont.GetFamily() );
204     SetFontEncoding( rFont.GetCharSet() );
205     SetScPosture( rFont.GetItalic() );
206     SetScStrikeout( rFont.GetStrikeout() );
207     mbOutline = rFont.IsOutline();
208     mbShadow = rFont.IsShadow();
209 }
210 
FillFromSvxFont(const SvxFont & rFont)211 void XclFontData::FillFromSvxFont( const SvxFont& rFont )
212 {
213     FillFromVclFont( rFont );
214     SetScEscapement( rFont.GetEscapement() );
215 }
216 
217 // *** conversion of VCL/SVX constants *** ------------------------------------
218 
GetScFamily(rtl_TextEncoding eDefTextEnc) const219 FontFamily XclFontData::GetScFamily( rtl_TextEncoding eDefTextEnc ) const
220 {
221     FontFamily eScFamily;
222     // ! format differs from Windows documentation: family is in lower nibble, pitch unknown
223     switch( mnFamily & 0x0F )
224     {
225         case EXC_FONTFAM_ROMAN:         eScFamily = FAMILY_ROMAN;       break;
226         case EXC_FONTFAM_SWISS:         eScFamily = FAMILY_SWISS;       break;
227         case EXC_FONTFAM_MODERN:        eScFamily = FAMILY_MODERN;      break;
228         case EXC_FONTFAM_SCRIPT:        eScFamily = FAMILY_SCRIPT;      break;
229         case EXC_FONTFAM_DECORATIVE:    eScFamily = FAMILY_DECORATIVE;  break;
230         default:
231             eScFamily =
232                 ((eDefTextEnc == RTL_TEXTENCODING_APPLE_ROMAN) &&
233                 (maName.EqualsIgnoreCaseAscii( "Geneva" ) || maName.EqualsIgnoreCaseAscii( "Chicago" ))) ?
234                 FAMILY_SWISS : FAMILY_DONTKNOW;
235     }
236     return eScFamily;
237 }
238 
GetFontEncoding() const239 rtl_TextEncoding XclFontData::GetFontEncoding() const
240 {
241     // convert Windows character set to text encoding identifier
242     return rtl_getTextEncodingFromWindowsCharset( mnCharSet );
243 }
244 
GetScPosture() const245 FontItalic XclFontData::GetScPosture() const
246 {
247     return mbItalic ? ITALIC_NORMAL : ITALIC_NONE;
248 }
249 
GetScWeight() const250 FontWeight XclFontData::GetScWeight() const
251 {
252     FontWeight eScWeight;
253 
254     if( !mnWeight )             eScWeight = WEIGHT_DONTKNOW;
255     else if( mnWeight < 150 )   eScWeight = WEIGHT_THIN;
256     else if( mnWeight < 250 )   eScWeight = WEIGHT_ULTRALIGHT;
257     else if( mnWeight < 325 )   eScWeight = WEIGHT_LIGHT;
258     else if( mnWeight < 375 )   eScWeight = WEIGHT_SEMILIGHT;
259     else if( mnWeight < 450 )   eScWeight = WEIGHT_NORMAL;
260     else if( mnWeight < 550 )   eScWeight = WEIGHT_MEDIUM;
261     else if( mnWeight < 650 )   eScWeight = WEIGHT_SEMIBOLD;
262     else if( mnWeight < 750 )   eScWeight = WEIGHT_BOLD;
263     else if( mnWeight < 850 )   eScWeight = WEIGHT_ULTRABOLD;
264     else                        eScWeight = WEIGHT_BLACK;
265 
266     return eScWeight;
267 }
268 
GetScUnderline() const269 FontUnderline XclFontData::GetScUnderline() const
270 {
271     FontUnderline eScUnderl = UNDERLINE_NONE;
272     switch( mnUnderline )
273     {
274         case EXC_FONTUNDERL_SINGLE:
275         case EXC_FONTUNDERL_SINGLE_ACC: eScUnderl = UNDERLINE_SINGLE;  break;
276         case EXC_FONTUNDERL_DOUBLE:
277         case EXC_FONTUNDERL_DOUBLE_ACC: eScUnderl = UNDERLINE_DOUBLE;  break;
278     }
279     return eScUnderl;
280 }
281 
GetScEscapement() const282 SvxEscapement XclFontData::GetScEscapement() const
283 {
284     SvxEscapement eScEscapem = SVX_ESCAPEMENT_OFF;
285     switch( mnEscapem )
286     {
287         case EXC_FONTESC_SUPER: eScEscapem = SVX_ESCAPEMENT_SUPERSCRIPT;    break;
288         case EXC_FONTESC_SUB:   eScEscapem = SVX_ESCAPEMENT_SUBSCRIPT;      break;
289     }
290     return eScEscapem;
291 }
292 
GetScStrikeout() const293 FontStrikeout XclFontData::GetScStrikeout() const
294 {
295     return mbStrikeout ? STRIKEOUT_SINGLE : STRIKEOUT_NONE;
296 }
297 
SetScHeight(sal_Int32 nTwips)298 void XclFontData::SetScHeight( sal_Int32 nTwips )
299 {
300     mnHeight = static_cast< sal_uInt16 >( ::std::min( nTwips, static_cast<sal_Int32>(0x7FFFL) ) );
301 }
302 
SetScFamily(FontFamily eScFamily)303 void XclFontData::SetScFamily( FontFamily eScFamily )
304 {
305     switch( eScFamily )
306     {
307         case FAMILY_DONTKNOW:   mnFamily = EXC_FONTFAM_DONTKNOW;    break;
308         case FAMILY_DECORATIVE: mnFamily = EXC_FONTFAM_DECORATIVE;  break;
309         case FAMILY_MODERN:     mnFamily = EXC_FONTFAM_MODERN;      break;
310         case FAMILY_ROMAN:      mnFamily = EXC_FONTFAM_ROMAN;       break;
311         case FAMILY_SCRIPT:     mnFamily = EXC_FONTFAM_SCRIPT;      break;
312         case FAMILY_SWISS:      mnFamily = EXC_FONTFAM_SWISS;       break;
313         case FAMILY_SYSTEM:     mnFamily = EXC_FONTFAM_SYSTEM;      break;
314         default:
315             DBG_ERRORFILE( "XclFontData::SetScFamily - unknown font family" );
316             mnFamily = EXC_FONTFAM_DONTKNOW;
317     }
318 }
319 
SetFontEncoding(rtl_TextEncoding eFontEnc)320 void XclFontData::SetFontEncoding( rtl_TextEncoding eFontEnc )
321 {
322     // convert text encoding identifier to Windows character set
323     mnCharSet = rtl_getBestWindowsCharsetFromTextEncoding( eFontEnc );
324 }
325 
326 
SetScPosture(FontItalic eScPosture)327 void XclFontData::SetScPosture( FontItalic eScPosture )
328 {
329     mbItalic = (eScPosture == ITALIC_OBLIQUE) || (eScPosture == ITALIC_NORMAL);
330 }
331 
SetScWeight(FontWeight eScWeight)332 void XclFontData::SetScWeight( FontWeight eScWeight )
333 {
334     switch( eScWeight )
335     {
336         case WEIGHT_DONTKNOW:   mnWeight = EXC_FONTWGHT_DONTKNOW;   break;
337         case WEIGHT_THIN:       mnWeight = EXC_FONTWGHT_THIN;       break;
338         case WEIGHT_ULTRALIGHT: mnWeight = EXC_FONTWGHT_ULTRALIGHT; break;
339         case WEIGHT_LIGHT:      mnWeight = EXC_FONTWGHT_LIGHT;      break;
340         case WEIGHT_SEMILIGHT:  mnWeight = EXC_FONTWGHT_SEMILIGHT;  break;
341         case WEIGHT_NORMAL:     mnWeight = EXC_FONTWGHT_NORMAL;     break;
342         case WEIGHT_MEDIUM:     mnWeight = EXC_FONTWGHT_MEDIUM;     break;
343         case WEIGHT_SEMIBOLD:   mnWeight = EXC_FONTWGHT_SEMIBOLD;   break;
344         case WEIGHT_BOLD:       mnWeight = EXC_FONTWGHT_BOLD;       break;
345         case WEIGHT_ULTRABOLD:  mnWeight = EXC_FONTWGHT_ULTRABOLD;  break;
346         case WEIGHT_BLACK:      mnWeight = EXC_FONTWGHT_BLACK;      break;
347         default:                mnWeight = EXC_FONTWGHT_NORMAL;
348     }
349 }
350 
SetScUnderline(FontUnderline eScUnderl)351 void XclFontData::SetScUnderline( FontUnderline eScUnderl )
352 {
353     switch( eScUnderl )
354     {
355         case UNDERLINE_NONE:
356         case UNDERLINE_DONTKNOW:    mnUnderline = EXC_FONTUNDERL_NONE;      break;
357         case UNDERLINE_DOUBLE:
358         case UNDERLINE_DOUBLEWAVE:  mnUnderline = EXC_FONTUNDERL_DOUBLE;    break;
359         default:                    mnUnderline = EXC_FONTUNDERL_SINGLE;
360     }
361 }
362 
SetScEscapement(short nScEscapem)363 void XclFontData::SetScEscapement( short nScEscapem )
364 {
365     if( nScEscapem > 0 )
366         mnEscapem = EXC_FONTESC_SUPER;
367     else if( nScEscapem < 0 )
368         mnEscapem = EXC_FONTESC_SUB;
369     else
370         mnEscapem = EXC_FONTESC_NONE;
371 }
372 
SetScStrikeout(FontStrikeout eScStrikeout)373 void XclFontData::SetScStrikeout( FontStrikeout eScStrikeout )
374 {
375     mbStrikeout =
376         (eScStrikeout == STRIKEOUT_SINGLE) || (eScStrikeout == STRIKEOUT_DOUBLE) ||
377         (eScStrikeout == STRIKEOUT_BOLD)   || (eScStrikeout == STRIKEOUT_SLASH)  ||
378         (eScStrikeout == STRIKEOUT_X);
379 }
380 
381 // *** conversion of API constants *** ----------------------------------------
382 
GetApiHeight() const383 float XclFontData::GetApiHeight() const
384 {
385     return static_cast< float >( mnHeight / TWIPS_PER_POINT );
386 }
387 
GetApiFamily() const388 sal_Int16 XclFontData::GetApiFamily() const
389 {
390     sal_Int16 nApiFamily = AwtFontFamily::DONTKNOW;
391     switch( mnFamily )
392     {
393         case FAMILY_DECORATIVE: nApiFamily = AwtFontFamily::DECORATIVE; break;
394         case FAMILY_MODERN:     nApiFamily = AwtFontFamily::MODERN;     break;
395         case FAMILY_ROMAN:      nApiFamily = AwtFontFamily::ROMAN;      break;
396         case FAMILY_SCRIPT:     nApiFamily = AwtFontFamily::SCRIPT;     break;
397         case FAMILY_SWISS:      nApiFamily = AwtFontFamily::SWISS;      break;
398         case FAMILY_SYSTEM:     nApiFamily = AwtFontFamily::SYSTEM;     break;
399     }
400     return nApiFamily;
401 }
402 
GetApiFontEncoding() const403 sal_Int16 XclFontData::GetApiFontEncoding() const
404 {
405     // API constants are equal to rtl_TextEncoding constants
406     return static_cast< sal_Int16 >( GetFontEncoding() );
407 }
408 
GetApiPosture() const409 Awt::FontSlant XclFontData::GetApiPosture() const
410 {
411     return mbItalic ? Awt::FontSlant_ITALIC : Awt::FontSlant_NONE;
412 }
413 
GetApiWeight() const414 float XclFontData::GetApiWeight() const
415 {
416     return VCLUnoHelper::ConvertFontWeight( GetScWeight() );
417 }
418 
GetApiUnderline() const419 sal_Int16 XclFontData::GetApiUnderline() const
420 {
421     sal_Int16 nApiUnderl = AwtFontUnderline::NONE;
422     switch( mnUnderline )
423     {
424         case EXC_FONTUNDERL_SINGLE:
425         case EXC_FONTUNDERL_SINGLE_ACC: nApiUnderl = AwtFontUnderline::SINGLE;  break;
426         case EXC_FONTUNDERL_DOUBLE:
427         case EXC_FONTUNDERL_DOUBLE_ACC: nApiUnderl = AwtFontUnderline::DOUBLE;  break;
428     }
429     return nApiUnderl;
430 }
431 
GetApiEscapement() const432 sal_Int16 XclFontData::GetApiEscapement() const
433 {
434     sal_Int16 nApiEscapem = 0;
435     switch( mnEscapem )
436     {
437         case EXC_FONTESC_SUPER: nApiEscapem = 33;   break;
438         case EXC_FONTESC_SUB:   nApiEscapem = -33;  break;
439     }
440     return nApiEscapem;
441 }
442 
GetApiStrikeout() const443 sal_Int16 XclFontData::GetApiStrikeout() const
444 {
445     return mbStrikeout ? AwtFontStrikeout::SINGLE : AwtFontStrikeout::NONE;
446 }
447 
SetApiHeight(float fPoint)448 void XclFontData::SetApiHeight( float fPoint )
449 {
450     mnHeight = static_cast< sal_uInt16 >( ::std::min( fPoint * TWIPS_PER_POINT + 0.5, 32767.0 ) );
451 }
452 
SetApiFamily(sal_Int16 nApiFamily)453 void XclFontData::SetApiFamily( sal_Int16 nApiFamily )
454 {
455     switch( nApiFamily )
456     {
457         case AwtFontFamily::DECORATIVE: mnFamily = FAMILY_DECORATIVE;   break;
458         case AwtFontFamily::MODERN:     mnFamily = FAMILY_MODERN;       break;
459         case AwtFontFamily::ROMAN:      mnFamily = FAMILY_ROMAN;        break;
460         case AwtFontFamily::SCRIPT:     mnFamily = FAMILY_SCRIPT;       break;
461         case AwtFontFamily::SWISS:      mnFamily = FAMILY_SWISS;        break;
462         case AwtFontFamily::SYSTEM:     mnFamily = FAMILY_SYSTEM;       break;
463         default:                        mnFamily = FAMILY_DONTKNOW;
464     }
465 }
466 
467 //UNUSED2009-05 void XclFontData::SetApiFontEncoding( sal_Int16 nApiFontEnc )
468 //UNUSED2009-05 {
469 //UNUSED2009-05     // API constants are equal to rtl_TextEncoding constants
470 //UNUSED2009-05     SetFontEncoding( static_cast< rtl_TextEncoding >( nApiFontEnc ) );
471 //UNUSED2009-05 }
472 
SetApiPosture(Awt::FontSlant eApiPosture)473 void XclFontData::SetApiPosture( Awt::FontSlant eApiPosture )
474 {
475     mbItalic =
476         (eApiPosture == Awt::FontSlant_OBLIQUE) ||
477         (eApiPosture == Awt::FontSlant_ITALIC) ||
478         (eApiPosture == Awt::FontSlant_REVERSE_OBLIQUE) ||
479         (eApiPosture == Awt::FontSlant_REVERSE_ITALIC);
480 }
481 
SetApiWeight(float fApiWeight)482 void XclFontData::SetApiWeight( float fApiWeight )
483 {
484     SetScWeight( VCLUnoHelper::ConvertFontWeight( fApiWeight ) );
485 }
486 
SetApiUnderline(sal_Int16 nApiUnderl)487 void XclFontData::SetApiUnderline( sal_Int16 nApiUnderl )
488 {
489     switch( nApiUnderl )
490     {
491         case AwtFontUnderline::NONE:
492         case AwtFontUnderline::DONTKNOW:    mnUnderline = EXC_FONTUNDERL_NONE;      break;
493         case AwtFontUnderline::DOUBLE:
494         case AwtFontUnderline::DOUBLEWAVE:  mnUnderline = EXC_FONTUNDERL_DOUBLE;    break;
495         default:                            mnUnderline = EXC_FONTUNDERL_SINGLE;
496     }
497 }
498 
SetApiEscapement(sal_Int16 nApiEscapem)499 void XclFontData::SetApiEscapement( sal_Int16 nApiEscapem )
500 {
501     if( nApiEscapem > 0 )
502         mnEscapem = EXC_FONTESC_SUPER;
503     else if( nApiEscapem < 0 )
504         mnEscapem = EXC_FONTESC_SUB;
505     else
506         mnEscapem = EXC_FONTESC_NONE;
507 }
508 
SetApiStrikeout(sal_Int16 nApiStrikeout)509 void XclFontData::SetApiStrikeout( sal_Int16 nApiStrikeout )
510 {
511     mbStrikeout =
512         (nApiStrikeout != AwtFontStrikeout::NONE) &&
513         (nApiStrikeout != AwtFontStrikeout::DONTKNOW);
514 }
515 
516 // ----------------------------------------------------------------------------
517 
operator ==(const XclFontData & rLeft,const XclFontData & rRight)518 bool operator==( const XclFontData& rLeft, const XclFontData& rRight )
519 {
520     return
521         (rLeft.mnHeight    == rRight.mnHeight)    &&
522         (rLeft.mnWeight    == rRight.mnWeight)    &&
523         (rLeft.mnUnderline == rRight.mnUnderline) &&
524         (rLeft.maColor     == rRight.maColor)     &&
525         (rLeft.mnEscapem   == rRight.mnEscapem)   &&
526         (rLeft.mnFamily    == rRight.mnFamily)    &&
527         (rLeft.mnCharSet   == rRight.mnCharSet)   &&
528         (rLeft.mbItalic    == rRight.mbItalic)    &&
529         (rLeft.mbStrikeout == rRight.mbStrikeout) &&
530         (rLeft.mbOutline   == rRight.mbOutline)   &&
531         (rLeft.mbShadow    == rRight.mbShadow)    &&
532         (rLeft.maName      == rRight.maName);
533 }
534 
535 // ----------------------------------------------------------------------------
536 
537 namespace {
538 
539 /** Property names for common font settings. */
540 const sal_Char *const sppcPropNamesChCommon[] =
541 {
542     "CharUnderline", "CharStrikeout", "CharColor", "CharContoured", "CharShadowed", 0
543 };
544 /** Property names for Western font settings. */
545 const sal_Char *const sppcPropNamesChWstrn[] =
546 {
547     "CharFontName", "CharHeight", "CharPosture", "CharWeight", 0
548 };
549 /** Property names for Asian font settings. */
550 const sal_Char *const sppcPropNamesChAsian[] =
551 {
552     "CharFontNameAsian", "CharHeightAsian", "CharPostureAsian", "CharWeightAsian", 0
553 };
554 /** Property names for Complex font settings. */
555 const sal_Char *const sppcPropNamesChCmplx[] =
556 {
557     "CharFontNameComplex", "CharHeightComplex", "CharPostureComplex", "CharWeightComplex", 0
558 };
559 /** Property names for escapement. */
560 const sal_Char *const sppcPropNamesChEscapement[] =
561 {
562     "CharEscapement", "CharEscapementHeight", 0
563 };
564 const sal_Int8 EXC_API_ESC_HEIGHT           = 58;   /// Default escapement font height.
565 
566 /** Property names for Western font settings without font name. */
567 const sal_Char *const *const sppcPropNamesChWstrnNoName = sppcPropNamesChWstrn + 1;
568 /** Property names for Asian font settings without font name. */
569 const sal_Char *const *const sppcPropNamesChAsianNoName = sppcPropNamesChAsian + 1;
570 /** Property names for Complex font settings without font name. */
571 const sal_Char *const *const sppcPropNamesChCmplxNoName = sppcPropNamesChCmplx + 1;
572 
573 /** Property names for font settings in form controls. */
574 const sal_Char *const sppcPropNamesControl[] =
575 {
576     "FontName", "FontFamily", "FontCharset", "FontHeight", "FontSlant",
577     "FontWeight", "FontUnderline", "FontStrikeout", "TextColor", 0
578 };
579 
580 /** Inserts all passed API font settings into the font data object. */
lclSetApiFontSettings(XclFontData & rFontData,const String & rApiFontName,float fApiHeight,float fApiWeight,Awt::FontSlant eApiPosture,sal_Int16 nApiUnderl,sal_Int16 nApiStrikeout)581 void lclSetApiFontSettings( XclFontData& rFontData,
582         const String& rApiFontName, float fApiHeight, float fApiWeight,
583         Awt::FontSlant eApiPosture, sal_Int16 nApiUnderl, sal_Int16 nApiStrikeout )
584 {
585     rFontData.maName = XclTools::GetXclFontName( rApiFontName );
586     rFontData.SetApiHeight( fApiHeight );
587     rFontData.SetApiWeight( fApiWeight );
588     rFontData.SetApiPosture( eApiPosture );
589     rFontData.SetApiUnderline( nApiUnderl );
590     rFontData.SetApiStrikeout( nApiStrikeout );
591 }
592 
593 /** Writes script dependent properties to a font property set helper. */
lclWriteChartFont(ScfPropertySet & rPropSet,ScfPropSetHelper & rHlpName,ScfPropSetHelper & rHlpNoName,const XclFontData & rFontData,bool bHasFontName)594 void lclWriteChartFont( ScfPropertySet& rPropSet,
595         ScfPropSetHelper& rHlpName, ScfPropSetHelper& rHlpNoName,
596         const XclFontData& rFontData, bool bHasFontName )
597 {
598     // select the font helper
599     ScfPropSetHelper& rPropSetHlp = bHasFontName ? rHlpName : rHlpNoName;
600     // initialize the font helper (must be called before writing any properties)
601     rPropSetHlp.InitializeWrite();
602     // write font name
603     if( bHasFontName )
604         rPropSetHlp << rFontData.maName;
605     // write remaining properties
606     rPropSetHlp << rFontData.GetApiHeight() << rFontData.GetApiPosture() << rFontData.GetApiWeight();
607     // write properties to property set
608     rPropSetHlp.WriteToPropertySet( rPropSet );
609 }
610 
611 } // namespace
612 
613 // ----------------------------------------------------------------------------
614 
XclFontPropSetHelper()615 XclFontPropSetHelper::XclFontPropSetHelper() :
616     maHlpChCommon( sppcPropNamesChCommon ),
617     maHlpChWstrn( sppcPropNamesChWstrn ),
618     maHlpChAsian( sppcPropNamesChAsian ),
619     maHlpChCmplx( sppcPropNamesChCmplx ),
620     maHlpChWstrnNoName( sppcPropNamesChWstrnNoName ),
621     maHlpChAsianNoName( sppcPropNamesChAsianNoName ),
622     maHlpChCmplxNoName( sppcPropNamesChCmplxNoName ),
623     maHlpChEscapement( sppcPropNamesChEscapement ),
624     maHlpControl( sppcPropNamesControl )
625 {
626 }
627 
ReadFontProperties(XclFontData & rFontData,const ScfPropertySet & rPropSet,XclFontPropSetType eType,sal_Int16 nScript)628 void XclFontPropSetHelper::ReadFontProperties( XclFontData& rFontData,
629         const ScfPropertySet& rPropSet, XclFontPropSetType eType, sal_Int16 nScript )
630 {
631     switch( eType )
632     {
633         case EXC_FONTPROPSET_CHART:
634         {
635             String aApiFontName;
636             float fApiHeight, fApiWeight;
637             sal_Int16 nApiUnderl = 0, nApiStrikeout = 0;
638             Awt::FontSlant eApiPosture;
639 
640             // read script type dependent properties
641             ScfPropSetHelper& rPropSetHlp = GetChartHelper( nScript );
642             rPropSetHlp.ReadFromPropertySet( rPropSet );
643             rPropSetHlp >> aApiFontName >> fApiHeight >> eApiPosture >> fApiWeight;
644             // read common properties
645             maHlpChCommon.ReadFromPropertySet( rPropSet );
646             maHlpChCommon   >> nApiUnderl
647                             >> nApiStrikeout
648                             >> rFontData.maColor
649                             >> rFontData.mbOutline
650                             >> rFontData.mbShadow;
651 
652             // convert API property values to Excel settings
653             lclSetApiFontSettings( rFontData, aApiFontName,
654                 fApiHeight, fApiWeight, eApiPosture, nApiUnderl, nApiStrikeout );
655 
656             // font escapement
657             sal_Int16 nApiEscapement = 0;
658             sal_Int8 nApiEscHeight = 0;
659             maHlpChEscapement.ReadFromPropertySet( rPropSet );
660             maHlpChEscapement.ReadFromPropertySet( rPropSet );
661             maHlpChEscapement.ReadFromPropertySet( rPropSet );
662             maHlpChEscapement >> nApiEscapement >> nApiEscHeight;
663             rFontData.SetApiEscapement( nApiEscapement );
664         }
665         break;
666 
667         case EXC_FONTPROPSET_CONTROL:
668         {
669             String aApiFontName;
670             float fApiHeight, fApiWeight;
671             sal_Int16 nApiFamily, nApiCharSet, nApiPosture, nApiUnderl, nApiStrikeout;
672 
673             // read font properties
674             maHlpControl.ReadFromPropertySet( rPropSet );
675             maHlpControl    >> aApiFontName
676                             >> nApiFamily
677                             >> nApiCharSet
678                             >> fApiHeight
679                             >> nApiPosture
680                             >> fApiWeight
681                             >> nApiUnderl
682                             >> nApiStrikeout
683                             >> rFontData.maColor;
684 
685             // convert API property values to Excel settings
686             Awt::FontSlant eApiPosture = static_cast< Awt::FontSlant >( nApiPosture );
687             lclSetApiFontSettings( rFontData, aApiFontName,
688                 fApiHeight, fApiWeight, eApiPosture, nApiUnderl, nApiStrikeout );
689             rFontData.SetApiFamily( nApiFamily );
690             rFontData.SetFontEncoding( nApiCharSet );
691         }
692         break;
693     }
694 }
695 
WriteFontProperties(ScfPropertySet & rPropSet,XclFontPropSetType eType,const XclFontData & rFontData,bool bHasWstrn,bool bHasAsian,bool bHasCmplx,const Color * pFontColor)696 void XclFontPropSetHelper::WriteFontProperties(
697         ScfPropertySet& rPropSet, XclFontPropSetType eType,
698         const XclFontData& rFontData, bool bHasWstrn, bool bHasAsian, bool bHasCmplx,
699         const Color* pFontColor )
700 {
701     switch( eType )
702     {
703         case EXC_FONTPROPSET_CHART:
704         {
705             // write common properties
706             maHlpChCommon.InitializeWrite();
707             const Color& rColor = pFontColor ? *pFontColor : rFontData.maColor;
708             maHlpChCommon   << rFontData.GetApiUnderline()
709                             << rFontData.GetApiStrikeout()
710                             << rColor
711                             << rFontData.mbOutline
712                             << rFontData.mbShadow;
713             maHlpChCommon.WriteToPropertySet( rPropSet );
714 
715             // write script type dependent properties
716             lclWriteChartFont( rPropSet, maHlpChWstrn, maHlpChWstrnNoName, rFontData, bHasWstrn );
717             lclWriteChartFont( rPropSet, maHlpChAsian, maHlpChAsianNoName, rFontData, bHasAsian );
718             lclWriteChartFont( rPropSet, maHlpChCmplx, maHlpChCmplxNoName, rFontData, bHasCmplx );
719 
720             // font escapement
721             if( rFontData.GetScEscapement() != SVX_ESCAPEMENT_OFF )
722             {
723                 maHlpChEscapement.InitializeWrite();
724                 maHlpChEscapement << rFontData.GetApiEscapement() << EXC_API_ESC_HEIGHT;
725                 maHlpChEscapement.WriteToPropertySet( rPropSet );
726             }
727         }
728         break;
729 
730         case EXC_FONTPROPSET_CONTROL:
731         {
732             maHlpControl.InitializeWrite();
733             maHlpControl    << rFontData.maName
734                             << rFontData.GetApiFamily()
735                             << rFontData.GetApiFontEncoding()
736                             << static_cast< sal_Int16 >( rFontData.GetApiHeight() + 0.5 )
737                             << rFontData.GetApiPosture()
738                             << rFontData.GetApiWeight()
739                             << rFontData.GetApiUnderline()
740                             << rFontData.GetApiStrikeout()
741                             << rFontData.maColor;
742             maHlpControl.WriteToPropertySet( rPropSet );
743         }
744         break;
745     }
746 }
747 
GetChartHelper(sal_Int16 nScript)748 ScfPropSetHelper& XclFontPropSetHelper::GetChartHelper( sal_Int16 nScript )
749 {
750     namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
751     switch( nScript )
752     {
753         case ApiScriptType::LATIN:      return maHlpChWstrn;
754         case ApiScriptType::ASIAN:      return maHlpChAsian;
755         case ApiScriptType::COMPLEX:    return maHlpChCmplx;
756         default:    DBG_ERRORFILE( "XclFontPropSetHelper::GetChartHelper - unknown script type" );
757     }
758     return maHlpChWstrn;
759 }
760 
761 // Number formats =============================================================
762 
763 namespace {
764 
765 // ----------------------------------------------------------------------------
766 
767 /** Special number format index describing a reused format. */
768 const NfIndexTableOffset PRV_NF_INDEX_REUSE = NF_INDEX_TABLE_ENTRIES;
769 
770 /** German primary language not defined, LANGUAGE_GERMAN belongs to Germany. */
771 const LanguageType PRV_LANGUAGE_GERMAN_PRIM = LANGUAGE_GERMAN & LANGUAGE_MASK_PRIMARY;
772 /** French primary language not defined, LANGUAGE_FRENCH belongs to France. */
773 const LanguageType PRV_LANGUAGE_FRENCH_PRIM = LANGUAGE_FRENCH & LANGUAGE_MASK_PRIMARY;
774 /** Parent language identifier for Asian languages (LANGUAGE_CHINESE is a primary only ID). */
775 const LanguageType PRV_LANGUAGE_ASIAN_PRIM = LANGUAGE_CHINESE;
776 
777 // ----------------------------------------------------------------------------
778 
779 /** Stores the number format used in Calc for an Excel built-in number format. */
780 struct XclBuiltInFormat
781 {
782     sal_uInt16          mnXclNumFmt;    /// Excel built-in index.
783     const sal_Char*     mpFormat;       /// Format string, may be 0 (meOffset used then).
784     NfIndexTableOffset  meOffset;       /// SvNumberFormatter format index, if mpFormat==0.
785     sal_uInt16          mnXclReuseFmt;  /// Use this Excel format, if meOffset==PRV_NF_INDEX_REUSE.
786 };
787 
788 // ----------------------------------------------------------------------------
789 
790 /** Defines a literal Excel built-in number format. */
791 #define EXC_NUMFMT_STRING( nXclNumFmt, pcUtf8 ) \
792     { nXclNumFmt, pcUtf8, NF_NUMBER_STANDARD, 0 }
793 
794 /** Defines an Excel built-in number format that maps to an own built-in format. */
795 #define EXC_NUMFMT_OFFSET( nXclNumFmt, eOffset ) \
796     { nXclNumFmt, 0, eOffset, 0 }
797 
798 /** Defines an Excel built-in number format that is the same as the specified. */
799 #define EXC_NUMFMT_REUSE( nXclNumFmt, nXclReuse ) \
800     { nXclNumFmt, 0, PRV_NF_INDEX_REUSE, nXclReuse }
801 
802 /** Terminates an Excel built-in number format table. */
803 #define EXC_NUMFMT_ENDTABLE() \
804     { EXC_FORMAT_NOTFOUND, 0, NF_NUMBER_STANDARD, 0 }
805 
806 // ----------------------------------------------------------------------------
807 
808 // Currency unit characters
809 #define UTF8_BAHT       "\340\270\277"
810 #define UTF8_EURO       "\342\202\254"
811 #define UTF8_POUND_UK   "\302\243"
812 #define UTF8_SHEQEL     "\342\202\252"
813 #define UTF8_WON        "\357\277\246"
814 #define UTF8_YEN_CS     "\357\277\245"
815 #define UTF8_YEN_JP     "\302\245"
816 
817 // Japanese/Chinese date/time characters
818 #define UTF8_CJ_YEAR    "\345\271\264"
819 #define UTF8_CJ_MON     "\346\234\210"
820 #define UTF8_CJ_DAY     "\346\227\245"
821 #define UTF8_CJ_HOUR    "\346\231\202"
822 #define UTF8_CJ_MIN     "\345\210\206"
823 #define UTF8_CJ_SEC     "\347\247\222"
824 
825 // Chinese Simplified date/time characters
826 #define UTF8_CS_HOUR    "\346\227\266"
827 
828 // Korean date/time characters
829 #define UTF8_KO_YEAR    "\353\205\204"
830 #define UTF8_KO_MON     "\354\233\224"
831 #define UTF8_KO_DAY     "\354\235\274"
832 #define UTF8_KO_HOUR    "\354\213\234"
833 #define UTF8_KO_MIN     "\353\266\204"
834 #define UTF8_KO_SEC     "\354\264\210"
835 
836 // ----------------------------------------------------------------------------
837 
838 /** Default number format table. Last parent of all other tables, used for unknown languages. */
839 static const XclBuiltInFormat spBuiltInFormats_DONTKNOW[] =
840 {
841     EXC_NUMFMT_OFFSET(   0, NF_NUMBER_STANDARD ),       // General
842     EXC_NUMFMT_OFFSET(   1, NF_NUMBER_INT ),            // 0
843     EXC_NUMFMT_OFFSET(   2, NF_NUMBER_DEC2 ),           // 0.00
844     EXC_NUMFMT_OFFSET(   3, NF_NUMBER_1000INT ),        // #,##0
845     EXC_NUMFMT_OFFSET(   4, NF_NUMBER_1000DEC2 ),       // #,##0.00
846     // 5...8 contained in file
847     EXC_NUMFMT_OFFSET(   9, NF_PERCENT_INT ),           // 0%
848     EXC_NUMFMT_OFFSET(  10, NF_PERCENT_DEC2 ),          // 0.00%
849     EXC_NUMFMT_OFFSET(  11, NF_SCIENTIFIC_000E00 ),     // 0.00E+00
850     EXC_NUMFMT_OFFSET(  12, NF_FRACTION_1 ),            // # ?/?
851     EXC_NUMFMT_OFFSET(  13, NF_FRACTION_2 ),            // # ??/??
852 
853     // 14...22 date and time formats
854     EXC_NUMFMT_OFFSET(  14, NF_DATE_SYS_DDMMYYYY ),
855     EXC_NUMFMT_OFFSET(  15, NF_DATE_SYS_DMMMYY ),
856     EXC_NUMFMT_OFFSET(  16, NF_DATE_SYS_DDMMM ),
857     EXC_NUMFMT_OFFSET(  17, NF_DATE_SYS_MMYY ),
858     EXC_NUMFMT_OFFSET(  18, NF_TIME_HHMMAMPM ),
859     EXC_NUMFMT_OFFSET(  19, NF_TIME_HHMMSSAMPM ),
860     EXC_NUMFMT_OFFSET(  20, NF_TIME_HHMM ),
861     EXC_NUMFMT_OFFSET(  21, NF_TIME_HHMMSS ),
862     EXC_NUMFMT_OFFSET(  22, NF_DATETIME_SYSTEM_SHORT_HHMM ),
863 
864     // 23...36 international formats
865     EXC_NUMFMT_REUSE(   23, 0 ),
866     EXC_NUMFMT_REUSE(   24, 0 ),
867     EXC_NUMFMT_REUSE(   25, 0 ),
868     EXC_NUMFMT_REUSE(   26, 0 ),
869     EXC_NUMFMT_REUSE(   27, 14 ),
870     EXC_NUMFMT_REUSE(   28, 14 ),
871     EXC_NUMFMT_REUSE(   29, 14 ),
872     EXC_NUMFMT_REUSE(   30, 14 ),
873     EXC_NUMFMT_REUSE(   31, 14 ),
874     EXC_NUMFMT_REUSE(   32, 21 ),
875     EXC_NUMFMT_REUSE(   33, 21 ),
876     EXC_NUMFMT_REUSE(   34, 21 ),
877     EXC_NUMFMT_REUSE(   35, 21 ),
878     EXC_NUMFMT_REUSE(   36, 14 ),
879 
880     // 37...44 accounting formats
881     // 41...44 contained in file
882     EXC_NUMFMT_STRING(  37, "#,##0;-#,##0" ),
883     EXC_NUMFMT_STRING(  38, "#,##0;[RED]-#,##0" ),
884     EXC_NUMFMT_STRING(  39, "#,##0.00;-#,##0.00" ),
885     EXC_NUMFMT_STRING(  40, "#,##0.00;[RED]-#,##0.00" ),
886 
887     // 45...49 more special formats
888     EXC_NUMFMT_STRING(  45, "mm:ss" ),
889     EXC_NUMFMT_STRING(  46, "[h]:mm:ss" ),
890     EXC_NUMFMT_STRING(  47, "mm:ss.0" ),
891     EXC_NUMFMT_STRING(  48, "##0.0E+0" ),
892     EXC_NUMFMT_OFFSET(  49, NF_TEXT ),
893 
894     // 50...81 international formats
895     EXC_NUMFMT_REUSE(   50, 14 ),
896     EXC_NUMFMT_REUSE(   51, 14 ),
897     EXC_NUMFMT_REUSE(   52, 14 ),
898     EXC_NUMFMT_REUSE(   53, 14 ),
899     EXC_NUMFMT_REUSE(   54, 14 ),
900     EXC_NUMFMT_REUSE(   55, 14 ),
901     EXC_NUMFMT_REUSE(   56, 14 ),
902     EXC_NUMFMT_REUSE(   57, 14 ),
903     EXC_NUMFMT_REUSE(   58, 14 ),
904     EXC_NUMFMT_REUSE(   59, 1 ),
905     EXC_NUMFMT_REUSE(   60, 2 ),
906     EXC_NUMFMT_REUSE(   61, 3 ),
907     EXC_NUMFMT_REUSE(   62, 4 ),
908     EXC_NUMFMT_REUSE(   67, 9 ),
909     EXC_NUMFMT_REUSE(   68, 10 ),
910     EXC_NUMFMT_REUSE(   69, 12 ),
911     EXC_NUMFMT_REUSE(   70, 13 ),
912     EXC_NUMFMT_REUSE(   71, 14 ),
913     EXC_NUMFMT_REUSE(   72, 14 ),
914     EXC_NUMFMT_REUSE(   73, 15 ),
915     EXC_NUMFMT_REUSE(   74, 16 ),
916     EXC_NUMFMT_REUSE(   75, 17 ),
917     EXC_NUMFMT_REUSE(   76, 20 ),
918     EXC_NUMFMT_REUSE(   77, 21 ),
919     EXC_NUMFMT_REUSE(   78, 22 ),
920     EXC_NUMFMT_REUSE(   79, 45 ),
921     EXC_NUMFMT_REUSE(   80, 46 ),
922     EXC_NUMFMT_REUSE(   81, 47 ),
923 
924     // 82...163 not used, must not occur in a file (Excel may crash)
925 
926     EXC_NUMFMT_ENDTABLE()
927 };
928 
929 // ENGLISH --------------------------------------------------------------------
930 
931 /** Base table for English locales. */
932 static const XclBuiltInFormat spBuiltInFormats_ENGLISH[] =
933 {
934     EXC_NUMFMT_STRING(  15, "DD-MMM-YY" ),
935     EXC_NUMFMT_STRING(  16, "DD-MMM" ),
936     EXC_NUMFMT_STRING(  17, "MMM-YY" ),
937     EXC_NUMFMT_STRING(  18, "h:mm AM/PM" ),
938     EXC_NUMFMT_STRING(  19, "h:mm:ss AM/PM" ),
939     EXC_NUMFMT_STRING(  22, "DD/MM/YYYY hh:mm" ),
940     EXC_NUMFMT_ENDTABLE()
941 };
942 
943 static const XclBuiltInFormat spBuiltInFormats_ENGLISH_UK[] =
944 {
945     EXC_NUMFMT_STRING(  63, UTF8_POUND_UK "#,##0;-" UTF8_POUND_UK "#,##0" ),
946     EXC_NUMFMT_STRING(  64, UTF8_POUND_UK "#,##0;[RED]-" UTF8_POUND_UK "#,##0" ),
947     EXC_NUMFMT_STRING(  65, UTF8_POUND_UK "#,##0.00;-" UTF8_POUND_UK "#,##0.00" ),
948     EXC_NUMFMT_STRING(  66, UTF8_POUND_UK "#,##0.00;[RED]-" UTF8_POUND_UK "#,##0.00" ),
949     EXC_NUMFMT_ENDTABLE()
950 };
951 
952 static const XclBuiltInFormat spBuiltInFormats_ENGLISH_EIRE[] =
953 {
954     EXC_NUMFMT_STRING(  63, UTF8_EURO "#,##0;-" UTF8_EURO "#,##0" ),
955     EXC_NUMFMT_STRING(  64, UTF8_EURO "#,##0;[RED]-" UTF8_EURO "#,##0" ),
956     EXC_NUMFMT_STRING(  65, UTF8_EURO "#,##0.00;-" UTF8_EURO "#,##0.00" ),
957     EXC_NUMFMT_STRING(  66, UTF8_EURO "#,##0.00;[RED]-" UTF8_EURO "#,##0.00" ),
958     EXC_NUMFMT_ENDTABLE()
959 };
960 
961 static const XclBuiltInFormat spBuiltInFormats_ENGLISH_US[] =
962 {
963     EXC_NUMFMT_STRING(  14, "M/D/YYYY" ),
964     EXC_NUMFMT_STRING(  15, "D-MMM-YY" ),
965     EXC_NUMFMT_STRING(  16, "D-MMM" ),
966     EXC_NUMFMT_STRING(  20, "h:mm" ),
967     EXC_NUMFMT_STRING(  21, "h:mm:ss" ),
968     EXC_NUMFMT_STRING(  22, "M/D/YYYY h:mm" ),
969     EXC_NUMFMT_STRING(  37, "#,##0_);(#,##0)" ),
970     EXC_NUMFMT_STRING(  38, "#,##0_);[RED](#,##0)" ),
971     EXC_NUMFMT_STRING(  39, "#,##0.00_);(#,##0.00)" ),
972     EXC_NUMFMT_STRING(  40, "#,##0.00_);[RED](#,##0.00)" ),
973     EXC_NUMFMT_STRING(  63, "$#,##0_);($#,##0)" ),
974     EXC_NUMFMT_STRING(  64, "$#,##0_);[RED]($#,##0)" ),
975     EXC_NUMFMT_STRING(  65, "$#,##0.00_);($#,##0.00)" ),
976     EXC_NUMFMT_STRING(  66, "$#,##0.00_);[RED]($#,##0.00)" ),
977     EXC_NUMFMT_ENDTABLE()
978 };
979 
980 static const XclBuiltInFormat spBuiltInFormats_ENGLISH_CAN[] =
981 {
982     EXC_NUMFMT_STRING(  20, "h:mm" ),
983     EXC_NUMFMT_STRING(  21, "h:mm:ss" ),
984     EXC_NUMFMT_STRING(  22, "DD/MM/YYYY h:mm" ),
985     EXC_NUMFMT_STRING(  63, "$#,##0;-$#,##0" ),
986     EXC_NUMFMT_STRING(  64, "$#,##0;[RED]-$#,##0" ),
987     EXC_NUMFMT_STRING(  65, "$#,##0.00;-$#,##0.00" ),
988     EXC_NUMFMT_STRING(  66, "$#,##0.00;[RED]-$#,##0.00" ),
989     EXC_NUMFMT_ENDTABLE()
990 };
991 
992 static const XclBuiltInFormat spBuiltInFormats_ENGLISH_AUS[] =
993 {
994     EXC_NUMFMT_STRING(  14, "D/MM/YYYY" ),
995     EXC_NUMFMT_STRING(  15, "D-MMM-YY" ),
996     EXC_NUMFMT_STRING(  16, "D-MMM" ),
997     EXC_NUMFMT_STRING(  20, "h:mm" ),
998     EXC_NUMFMT_STRING(  21, "h:mm:ss" ),
999     EXC_NUMFMT_STRING(  22, "D/MM/YYYY h:mm" ),
1000     EXC_NUMFMT_STRING(  63, "$#,##0;-$#,##0" ),
1001     EXC_NUMFMT_STRING(  64, "$#,##0;[RED]-$#,##0" ),
1002     EXC_NUMFMT_STRING(  65, "$#,##0.00;-$#,##0.00" ),
1003     EXC_NUMFMT_STRING(  66, "$#,##0.00;[RED]-$#,##0.00" ),
1004     EXC_NUMFMT_ENDTABLE()
1005 };
1006 
1007 static const XclBuiltInFormat spBuiltInFormats_ENGLISH_SAFRICA[] =
1008 {
1009     EXC_NUMFMT_STRING(  14, "YYYY/MM/DD" ),
1010     EXC_NUMFMT_OFFSET(  18, NF_TIME_HHMMAMPM ),
1011     EXC_NUMFMT_OFFSET(  19, NF_TIME_HHMMSSAMPM ),
1012     EXC_NUMFMT_STRING(  22, "YYYY/MM/DD hh:mm" ),
1013     EXC_NUMFMT_STRING(  63, "\\R #,##0;\\R -#,##0" ),
1014     EXC_NUMFMT_STRING(  64, "\\R #,##0;[RED]\\R -#,##0" ),
1015     EXC_NUMFMT_STRING(  65, "\\R #,##0.00;\\R -#,##0.00" ),
1016     EXC_NUMFMT_STRING(  66, "\\R #,##0.00;[RED]\\R -#,##0.00" ),
1017     EXC_NUMFMT_ENDTABLE()
1018 };
1019 
1020 // FRENCH ---------------------------------------------------------------------
1021 
1022 /** Base table for French locales. */
1023 static const XclBuiltInFormat spBuiltInFormats_FRENCH[] =
1024 {
1025     EXC_NUMFMT_STRING(  15, "DD-MMM-YY" ),
1026     EXC_NUMFMT_STRING(  16, "DD-MMM" ),
1027     EXC_NUMFMT_STRING(  17, "MMM-YY" ),
1028     EXC_NUMFMT_STRING(  18, "h:mm AM/PM" ),
1029     EXC_NUMFMT_STRING(  19, "h:mm:ss AM/PM" ),
1030     EXC_NUMFMT_ENDTABLE()
1031 };
1032 
1033 static const XclBuiltInFormat spBuiltInFormats_FRENCH_FRANCE[] =
1034 {
1035     EXC_NUMFMT_STRING(  22, "DD/MM/YYYY hh:mm" ),
1036     EXC_NUMFMT_STRING(  37, "#,##0\\ _" UTF8_EURO ";-#,##0\\ _" UTF8_EURO ),
1037     EXC_NUMFMT_STRING(  38, "#,##0\\ _" UTF8_EURO ";[RED]-#,##0\\ _" UTF8_EURO ),
1038     EXC_NUMFMT_STRING(  39, "#,##0.00\\ _" UTF8_EURO ";-#,##0.00\\ _" UTF8_EURO ),
1039     EXC_NUMFMT_STRING(  40, "#,##0.00\\ _" UTF8_EURO ";[RED]-#,##0.00\\ _" UTF8_EURO ),
1040     EXC_NUMFMT_STRING(  63, "#,##0\\ " UTF8_EURO ";-#,##0\\ " UTF8_EURO ),
1041     EXC_NUMFMT_STRING(  64, "#,##0\\ " UTF8_EURO ";[RED]-#,##0\\ " UTF8_EURO ),
1042     EXC_NUMFMT_STRING(  65, "#,##0.00\\ " UTF8_EURO ";-#,##0.00\\ " UTF8_EURO ),
1043     EXC_NUMFMT_STRING(  66, "#,##0.00\\ " UTF8_EURO ";[RED]-#,##0.00\\ " UTF8_EURO ),
1044     EXC_NUMFMT_ENDTABLE()
1045 };
1046 
1047 static const XclBuiltInFormat spBuiltInFormats_FRENCH_CANADIAN[] =
1048 {
1049     EXC_NUMFMT_STRING(  22, "YYYY-MM-DD hh:mm" ),
1050     EXC_NUMFMT_STRING(  37, "#,##0\\ _$_-;#,##0\\ _$-" ),
1051     EXC_NUMFMT_STRING(  38, "#,##0\\ _$_-;[RED]#,##0\\ _$-" ),
1052     EXC_NUMFMT_STRING(  39, "#,##0.00\\ _$_-;#,##0.00\\ _$-" ),
1053     EXC_NUMFMT_STRING(  40, "#,##0.00\\ _$_-;[RED]#,##0.00\\ _$-" ),
1054     EXC_NUMFMT_STRING(  63, "#,##0\\ $_-;#,##0\\ $-" ),
1055     EXC_NUMFMT_STRING(  64, "#,##0\\ $_-;[RED]#,##0\\ $-" ),
1056     EXC_NUMFMT_STRING(  65, "#,##0.00\\ $_-;#,##0.00\\ $-" ),
1057     EXC_NUMFMT_STRING(  66, "#,##0.00\\ $_-;[RED]#,##0.00\\ $-" ),
1058     EXC_NUMFMT_ENDTABLE()
1059 };
1060 
1061 static const XclBuiltInFormat spBuiltInFormats_FRENCH_SWISS[] =
1062 {
1063     EXC_NUMFMT_STRING(  15, "DD.MMM.YY" ),
1064     EXC_NUMFMT_STRING(  16, "DD.MMM" ),
1065     EXC_NUMFMT_STRING(  17, "MMM.YY" ),
1066     EXC_NUMFMT_STRING(  22, "DD.MM.YYYY hh:mm" ),
1067     EXC_NUMFMT_STRING(  63, "\"SFr. \"#,##0;\"SFr. \"-#,##0" ),
1068     EXC_NUMFMT_STRING(  64, "\"SFr. \"#,##0;[RED]\"SFr. \"-#,##0" ),
1069     EXC_NUMFMT_STRING(  65, "\"SFr. \"#,##0.00;\"SFr. \"-#,##0.00" ),
1070     EXC_NUMFMT_STRING(  66, "\"SFr. \"#,##0.00;[RED]\"SFr. \"-#,##0.00" ),
1071     EXC_NUMFMT_ENDTABLE()
1072 };
1073 
1074 static const XclBuiltInFormat spBuiltInFormats_FRENCH_BELGIAN[] =
1075 {
1076     EXC_NUMFMT_STRING(  14, "D/MM/YYYY" ),
1077     EXC_NUMFMT_STRING(  15, "D-MMM-YY" ),
1078     EXC_NUMFMT_STRING(  16, "D-MMM" ),
1079     EXC_NUMFMT_STRING(  20, "h:mm" ),
1080     EXC_NUMFMT_STRING(  21, "h:mm:ss" ),
1081     EXC_NUMFMT_STRING(  22, "D/MM/YYYY h:mm" ),
1082     EXC_NUMFMT_ENDTABLE()
1083 };
1084 
1085 // GERMAN ---------------------------------------------------------------------
1086 
1087 /** Base table for German locales. */
1088 static const XclBuiltInFormat spBuiltInFormats_GERMAN[] =
1089 {
1090     EXC_NUMFMT_STRING(  15, "DD. MMM YY" ),
1091     EXC_NUMFMT_STRING(  16, "DD. MMM" ),
1092     EXC_NUMFMT_STRING(  17, "MMM YY" ),
1093     EXC_NUMFMT_STRING(  18, "h:mm AM/PM" ),
1094     EXC_NUMFMT_STRING(  19, "h:mm:ss AM/PM" ),
1095     EXC_NUMFMT_STRING(  22, "DD.MM.YYYY hh:mm" ),
1096     EXC_NUMFMT_ENDTABLE()
1097 };
1098 
1099 static const XclBuiltInFormat spBuiltInFormats_GERMAN_GERMANY[] =
1100 {
1101     EXC_NUMFMT_STRING(  37, "#,##0 _" UTF8_EURO ";-#,##0 _" UTF8_EURO ),
1102     EXC_NUMFMT_STRING(  38, "#,##0 _" UTF8_EURO ";[RED]-#,##0 _" UTF8_EURO ),
1103     EXC_NUMFMT_STRING(  39, "#,##0.00 _" UTF8_EURO ";-#,##0.00 _" UTF8_EURO ),
1104     EXC_NUMFMT_STRING(  40, "#,##0.00 _" UTF8_EURO ";[RED]-#,##0.00 _" UTF8_EURO ),
1105     EXC_NUMFMT_STRING(  63, "#,##0 " UTF8_EURO ";-#,##0 " UTF8_EURO ),
1106     EXC_NUMFMT_STRING(  64, "#,##0 " UTF8_EURO ";[RED]-#,##0 " UTF8_EURO ),
1107     EXC_NUMFMT_STRING(  65, "#,##0.00 " UTF8_EURO ";-#,##0.00 " UTF8_EURO ),
1108     EXC_NUMFMT_STRING(  66, "#,##0.00 " UTF8_EURO ";[RED]-#,##0.00 " UTF8_EURO ),
1109     EXC_NUMFMT_ENDTABLE()
1110 };
1111 
1112 static const XclBuiltInFormat spBuiltInFormats_GERMAN_AUSTRIAN[] =
1113 {
1114     EXC_NUMFMT_STRING(  15, "DD.MMM.YY" ),
1115     EXC_NUMFMT_STRING(  16, "DD.MMM" ),
1116     EXC_NUMFMT_STRING(  17, "MMM.YY" ),
1117     EXC_NUMFMT_STRING(  63, UTF8_EURO " #,##0;-" UTF8_EURO " #,##0" ),
1118     EXC_NUMFMT_STRING(  64, UTF8_EURO " #,##0;[RED]-" UTF8_EURO " #,##0" ),
1119     EXC_NUMFMT_STRING(  65, UTF8_EURO " #,##0.00;-" UTF8_EURO " #,##0.00" ),
1120     EXC_NUMFMT_STRING(  66, UTF8_EURO " #,##0.00;[RED]-" UTF8_EURO " #,##0.00" ),
1121     EXC_NUMFMT_ENDTABLE()
1122 };
1123 
1124 static const XclBuiltInFormat spBuiltInFormats_GERMAN_SWISS[] =
1125 {
1126     EXC_NUMFMT_STRING(  63, "\"SFr. \"#,##0;\"SFr. \"-#,##0" ),
1127     EXC_NUMFMT_STRING(  64, "\"SFr. \"#,##0;[RED]\"SFr. \"-#,##0" ),
1128     EXC_NUMFMT_STRING(  65, "\"SFr. \"#,##0.00;\"SFr. \"-#,##0.00" ),
1129     EXC_NUMFMT_STRING(  66, "\"SFr. \"#,##0.00;[RED]\"SFr. \"-#,##0.00" ),
1130     EXC_NUMFMT_ENDTABLE()
1131 };
1132 
1133 static const XclBuiltInFormat spBuiltInFormats_GERMAN_LUXEMBOURG[] =
1134 {
1135     EXC_NUMFMT_STRING(  15, "DD.MMM.YY" ),
1136     EXC_NUMFMT_STRING(  16, "DD.MMM" ),
1137     EXC_NUMFMT_STRING(  17, "MMM.YY" ),
1138     EXC_NUMFMT_STRING(  37, "#,##0 _" UTF8_EURO ";-#,##0 _" UTF8_EURO ),
1139     EXC_NUMFMT_STRING(  38, "#,##0 _" UTF8_EURO ";[RED]-#,##0 _" UTF8_EURO ),
1140     EXC_NUMFMT_STRING(  39, "#,##0.00 _" UTF8_EURO ";-#,##0.00 _" UTF8_EURO ),
1141     EXC_NUMFMT_STRING(  40, "#,##0.00 _" UTF8_EURO ";[RED]-#,##0.00 _" UTF8_EURO ),
1142     EXC_NUMFMT_STRING(  63, "#,##0 " UTF8_EURO ";-#,##0 " UTF8_EURO ),
1143     EXC_NUMFMT_STRING(  64, "#,##0 " UTF8_EURO ";[RED]-#,##0 " UTF8_EURO ),
1144     EXC_NUMFMT_STRING(  65, "#,##0.00 " UTF8_EURO ";-#,##0.00 " UTF8_EURO ),
1145     EXC_NUMFMT_STRING(  66, "#,##0.00 " UTF8_EURO ";[RED]-#,##0.00 " UTF8_EURO ),
1146     EXC_NUMFMT_ENDTABLE()
1147 };
1148 
1149 static const XclBuiltInFormat spBuiltInFormats_GERMAN_LIECHTENSTEIN[] =
1150 {
1151     EXC_NUMFMT_STRING(  63, "\"CHF \"#,##0;\"CHF \"-#,##0" ),
1152     EXC_NUMFMT_STRING(  64, "\"CHF \"#,##0;[RED]\"CHF \"-#,##0" ),
1153     EXC_NUMFMT_STRING(  65, "\"CHF \"#,##0.00;\"CHF \"-#,##0.00" ),
1154     EXC_NUMFMT_STRING(  66, "\"CHF \"#,##0.00;[RED]\"CHF \"-#,##0.00" ),
1155     EXC_NUMFMT_ENDTABLE()
1156 };
1157 
1158 // ITALIAN --------------------------------------------------------------------
1159 
1160 static const XclBuiltInFormat spBuiltInFormats_ITALIAN_ITALY[] =
1161 {
1162     EXC_NUMFMT_STRING(  15, "DD-MMM-YY" ),
1163     EXC_NUMFMT_STRING(  16, "DD-MMM" ),
1164     EXC_NUMFMT_STRING(  17, "MMM-YY" ),
1165     EXC_NUMFMT_STRING(  18, "h:mm AM/PM" ),
1166     EXC_NUMFMT_STRING(  19, "h:mm:ss AM/PM" ),
1167     EXC_NUMFMT_STRING(  20, "h:mm" ),
1168     EXC_NUMFMT_STRING(  21, "h:mm:ss" ),
1169     EXC_NUMFMT_STRING(  22, "DD/MM/YYYY h:mm" ),
1170     EXC_NUMFMT_STRING(  63, UTF8_EURO " #,##0;-" UTF8_EURO " #,##0" ),
1171     EXC_NUMFMT_STRING(  64, UTF8_EURO " #,##0;[RED]-" UTF8_EURO " #,##0" ),
1172     EXC_NUMFMT_STRING(  65, UTF8_EURO " #,##0.00;-" UTF8_EURO " #,##0.00" ),
1173     EXC_NUMFMT_STRING(  66, UTF8_EURO " #,##0.00;[RED]-" UTF8_EURO " #,##0.00" ),
1174     EXC_NUMFMT_ENDTABLE()
1175 };
1176 
1177 static const XclBuiltInFormat spBuiltInFormats_ITALIAN_SWISS[] =
1178 {
1179     EXC_NUMFMT_STRING(  15, "DD.MMM.YY" ),
1180     EXC_NUMFMT_STRING(  16, "DD.MMM" ),
1181     EXC_NUMFMT_STRING(  17, "MMM.YY" ),
1182     EXC_NUMFMT_STRING(  18, "h:mm AM/PM" ),
1183     EXC_NUMFMT_STRING(  19, "h:mm:ss AM/PM" ),
1184     EXC_NUMFMT_STRING(  22, "DD.MM.YYYY hh:mm" ),
1185     EXC_NUMFMT_STRING(  63, "\"SFr. \"#,##0;\"SFr. \"-#,##0" ),
1186     EXC_NUMFMT_STRING(  64, "\"SFr. \"#,##0;[RED]\"SFr. \"-#,##0" ),
1187     EXC_NUMFMT_STRING(  65, "\"SFr. \"#,##0.00;\"SFr. \"-#,##0.00" ),
1188     EXC_NUMFMT_STRING(  66, "\"SFr. \"#,##0.00;[RED]\"SFr. \"-#,##0.00" ),
1189     EXC_NUMFMT_ENDTABLE()
1190 };
1191 
1192 // SWEDISH --------------------------------------------------------------------
1193 
1194 static const XclBuiltInFormat spBuiltInFormats_SWEDISH_SWEDEN[] =
1195 {
1196     EXC_NUMFMT_STRING(  15, "DD-MMM-YY" ),
1197     EXC_NUMFMT_STRING(  16, "DD-MMM" ),
1198     EXC_NUMFMT_STRING(  17, "MMM-YY" ),
1199     EXC_NUMFMT_STRING(  18, "h:mm AM/PM" ),
1200     EXC_NUMFMT_STRING(  19, "h:mm:ss AM/PM" ),
1201     EXC_NUMFMT_STRING(  22, "YYYY-MM-DD hh:mm" ),
1202     EXC_NUMFMT_STRING(  37, "#,##0 _k_r;-#,##0 _k_r" ),
1203     EXC_NUMFMT_STRING(  38, "#,##0 _k_r;[RED]-#,##0 _k_r" ),
1204     EXC_NUMFMT_STRING(  39, "#,##0.00 _k_r;-#,##0.00 _k_r" ),
1205     EXC_NUMFMT_STRING(  40, "#,##0.00 _k_r;[RED]-#,##0.00 _k_r" ),
1206     EXC_NUMFMT_STRING(  63, "#,##0 \"kr\";-#,##0 \"kr\"" ),
1207     EXC_NUMFMT_STRING(  64, "#,##0 \"kr\";[RED]-#,##0 \"kr\"" ),
1208     EXC_NUMFMT_STRING(  65, "#,##0.00 \"kr\";-#,##0.00 \"kr\"" ),
1209     EXC_NUMFMT_STRING(  66, "#,##0.00 \"kr\";[RED]-#,##0.00 \"kr\"" ),
1210     EXC_NUMFMT_ENDTABLE()
1211 };
1212 
1213 static const XclBuiltInFormat spBuiltInFormats_SWEDISH_FINLAND[] =
1214 {
1215     EXC_NUMFMT_STRING(   9, "0 %" ),
1216     EXC_NUMFMT_STRING(  10, "0.00 %" ),
1217     EXC_NUMFMT_STRING(  15, "DD.MMM.YY" ),
1218     EXC_NUMFMT_STRING(  16, "DD.MMM" ),
1219     EXC_NUMFMT_STRING(  17, "MMM.YY" ),
1220     EXC_NUMFMT_STRING(  18, "h:mm AM/PM" ),
1221     EXC_NUMFMT_STRING(  19, "h:mm:ss AM/PM" ),
1222     EXC_NUMFMT_STRING(  22, "D.M.YYYY hh:mm" ),
1223     EXC_NUMFMT_STRING(  37, "#,##0 _" UTF8_EURO ";-#,##0 _" UTF8_EURO ),
1224     EXC_NUMFMT_STRING(  38, "#,##0 _" UTF8_EURO ";[RED]-#,##0 _" UTF8_EURO ),
1225     EXC_NUMFMT_STRING(  39, "#,##0.00 _" UTF8_EURO ";-#,##0.00 _" UTF8_EURO ),
1226     EXC_NUMFMT_STRING(  40, "#,##0.00 _" UTF8_EURO ";[RED]-#,##0.00 _" UTF8_EURO ),
1227     EXC_NUMFMT_STRING(  63, "#,##0 " UTF8_EURO ";-#,##0 " UTF8_EURO ),
1228     EXC_NUMFMT_STRING(  64, "#,##0 " UTF8_EURO ";[RED]-#,##0 " UTF8_EURO ),
1229     EXC_NUMFMT_STRING(  65, "#,##0.00 " UTF8_EURO ";-#,##0.00 " UTF8_EURO ),
1230     EXC_NUMFMT_STRING(  66, "#,##0.00 " UTF8_EURO ";[RED]-#,##0.00 " UTF8_EURO ),
1231     EXC_NUMFMT_ENDTABLE()
1232 };
1233 
1234 // ASIAN ----------------------------------------------------------------------
1235 
1236 /** Base table for Asian locales. */
1237 static const XclBuiltInFormat spBuiltInFormats_ASIAN[] =
1238 {
1239     EXC_NUMFMT_STRING(  18, "h:mm AM/PM" ),
1240     EXC_NUMFMT_STRING(  19, "h:mm:ss AM/PM" ),
1241     EXC_NUMFMT_STRING(  20, "h:mm" ),
1242     EXC_NUMFMT_STRING(  21, "h:mm:ss" ),
1243     EXC_NUMFMT_STRING(  23, "$#,##0_);($#,##0)" ),
1244     EXC_NUMFMT_STRING(  24, "$#,##0_);[RED]($#,##0)" ),
1245     EXC_NUMFMT_STRING(  25, "$#,##0.00_);($#,##0.00)" ),
1246     EXC_NUMFMT_STRING(  26, "$#,##0.00_);[RED]($#,##0.00)" ),
1247     EXC_NUMFMT_REUSE(   29, 28 ),
1248     EXC_NUMFMT_REUSE(   36, 27 ),
1249     EXC_NUMFMT_REUSE(   50, 27 ),
1250     EXC_NUMFMT_REUSE(   51, 28 ),
1251     EXC_NUMFMT_REUSE(   52, 34 ),
1252     EXC_NUMFMT_REUSE(   53, 35 ),
1253     EXC_NUMFMT_REUSE(   54, 28 ),
1254     EXC_NUMFMT_REUSE(   55, 34 ),
1255     EXC_NUMFMT_REUSE(   56, 35 ),
1256     EXC_NUMFMT_REUSE(   57, 27 ),
1257     EXC_NUMFMT_REUSE(   58, 28 ),
1258     EXC_NUMFMT_ENDTABLE()
1259 };
1260 
1261 static const XclBuiltInFormat spBuiltInFormats_JAPANESE[] =
1262 {
1263     EXC_NUMFMT_STRING(  14, "YYYY/M/D" ),
1264     EXC_NUMFMT_STRING(  15, "D-MMM-YY" ),
1265     EXC_NUMFMT_STRING(  16, "D-MMM" ),
1266     EXC_NUMFMT_STRING(  17, "MMM-YY" ),
1267     EXC_NUMFMT_STRING(  22, "YYYY/M/D h:mm" ),
1268     EXC_NUMFMT_STRING(  27, "[$-0411]GE.M.D" ),
1269     EXC_NUMFMT_STRING(  28, "[$-0411]GGGE" UTF8_CJ_YEAR "M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
1270     EXC_NUMFMT_STRING(  30, "[$-0411]M/D/YY" ),
1271     EXC_NUMFMT_STRING(  31, "[$-0411]YYYY" UTF8_CJ_YEAR "M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
1272     EXC_NUMFMT_STRING(  32, "[$-0411]h" UTF8_CJ_HOUR "mm" UTF8_CJ_MIN ),
1273     EXC_NUMFMT_STRING(  33, "[$-0411]h" UTF8_CJ_HOUR "mm" UTF8_CJ_MIN "ss" UTF8_CJ_SEC ),
1274     EXC_NUMFMT_STRING(  34, "[$-0411]YYYY" UTF8_CJ_YEAR "M" UTF8_CJ_MON ),
1275     EXC_NUMFMT_STRING(  35, "[$-0411]M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
1276     EXC_NUMFMT_STRING(  63, UTF8_YEN_JP "#,##0;-" UTF8_YEN_JP "#,##0" ),
1277     EXC_NUMFMT_STRING(  64, UTF8_YEN_JP "#,##0;[RED]-" UTF8_YEN_JP "#,##0" ),
1278     EXC_NUMFMT_STRING(  65, UTF8_YEN_JP "#,##0.00;-" UTF8_YEN_JP "#,##0.00" ),
1279     EXC_NUMFMT_STRING(  66, UTF8_YEN_JP "#,##0.00;[RED]-" UTF8_YEN_JP "#,##0.00" ),
1280     EXC_NUMFMT_ENDTABLE()
1281 };
1282 
1283 static const XclBuiltInFormat spBuiltInFormats_KOREAN[] =
1284 {
1285     EXC_NUMFMT_STRING(  14, "YYYY-MM-DD" ),
1286     EXC_NUMFMT_STRING(  15, "DD-MMM-YY" ),
1287     EXC_NUMFMT_STRING(  16, "DD-MMM" ),
1288     EXC_NUMFMT_STRING(  17, "MMM-YY" ),
1289     EXC_NUMFMT_STRING(  22, "YYYY-MM-DD h:mm" ),
1290     EXC_NUMFMT_STRING(  27, "[$-0412]YYYY" UTF8_CJ_YEAR " MM" UTF8_CJ_MON " DD" UTF8_CJ_DAY ),
1291     EXC_NUMFMT_STRING(  28, "[$-0412]MM-DD" ),
1292     EXC_NUMFMT_STRING(  30, "[$-0412]MM-DD-YY" ),
1293     EXC_NUMFMT_STRING(  31, "[$-0412]YYYY" UTF8_KO_YEAR " MM" UTF8_KO_MON " DD" UTF8_KO_DAY ),
1294     EXC_NUMFMT_STRING(  32, "[$-0412]h" UTF8_KO_HOUR " mm" UTF8_KO_MIN ),
1295     EXC_NUMFMT_STRING(  33, "[$-0412]h" UTF8_KO_HOUR " mm" UTF8_KO_MIN " ss" UTF8_KO_SEC ),
1296     EXC_NUMFMT_STRING(  34, "[$-0412]YYYY\"/\"MM\"/\"DD" ),
1297     EXC_NUMFMT_STRING(  35, "[$-0412]YYYY-MM-DD" ),
1298     EXC_NUMFMT_STRING(  63, UTF8_WON "#,##0;-" UTF8_WON "#,##0" ),
1299     EXC_NUMFMT_STRING(  64, UTF8_WON "#,##0;[RED]-" UTF8_WON "#,##0" ),
1300     EXC_NUMFMT_STRING(  65, UTF8_WON "#,##0.00;-" UTF8_WON "#,##0.00" ),
1301     EXC_NUMFMT_STRING(  66, UTF8_WON "#,##0.00;[RED]-" UTF8_WON "#,##0.00" ),
1302     EXC_NUMFMT_ENDTABLE()
1303 };
1304 
1305 static const XclBuiltInFormat spBuiltInFormats_CHINESE_SIMPLIFIED[] =
1306 {
1307     EXC_NUMFMT_STRING(  14, "YYYY-M-D" ),
1308     EXC_NUMFMT_STRING(  15, "D-MMM-YY" ),
1309     EXC_NUMFMT_STRING(  16, "D-MMM" ),
1310     EXC_NUMFMT_STRING(  17, "MMM-YY" ),
1311     EXC_NUMFMT_STRING(  22, "YYYY-M-D h:mm" ),
1312     EXC_NUMFMT_STRING(  27, "[$-0804]YYYY" UTF8_CJ_YEAR "M" UTF8_CJ_MON ),
1313     EXC_NUMFMT_STRING(  28, "[$-0804]M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
1314     EXC_NUMFMT_STRING(  30, "[$-0804]M-D-YY" ),
1315     EXC_NUMFMT_STRING(  31, "[$-0804]YYYY" UTF8_CJ_YEAR "M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
1316     EXC_NUMFMT_STRING(  32, "[$-0804]h" UTF8_CS_HOUR "mm" UTF8_CJ_MIN ),
1317     EXC_NUMFMT_STRING(  33, "[$-0804]h" UTF8_CS_HOUR "mm" UTF8_CJ_MIN "ss" UTF8_CJ_SEC ),
1318     EXC_NUMFMT_STRING(  34, "[$-0804]AM/PMh" UTF8_CS_HOUR "mm" UTF8_CJ_MIN ),
1319     EXC_NUMFMT_STRING(  35, "[$-0804]AM/PMh" UTF8_CS_HOUR "mm" UTF8_CJ_MIN "ss" UTF8_CJ_SEC ),
1320     EXC_NUMFMT_REUSE(   52, 27 ),
1321     EXC_NUMFMT_REUSE(   53, 28 ),
1322     EXC_NUMFMT_STRING(  63, UTF8_YEN_CS "#,##0;-" UTF8_YEN_CS "#,##0" ),
1323     EXC_NUMFMT_STRING(  64, UTF8_YEN_CS "#,##0;[RED]-" UTF8_YEN_CS "#,##0" ),
1324     EXC_NUMFMT_STRING(  65, UTF8_YEN_CS "#,##0.00;-" UTF8_YEN_CS "#,##0.00" ),
1325     EXC_NUMFMT_STRING(  66, UTF8_YEN_CS "#,##0.00;[RED]-" UTF8_YEN_CS "#,##0.00" ),
1326     EXC_NUMFMT_ENDTABLE()
1327 };
1328 
1329 static const XclBuiltInFormat spBuiltInFormats_CHINESE_TRADITIONAL[] =
1330 {
1331     EXC_NUMFMT_STRING(  15, "D-MMM-YY" ),
1332     EXC_NUMFMT_STRING(  16, "D-MMM" ),
1333     EXC_NUMFMT_STRING(  17, "MMM-YY" ),
1334     EXC_NUMFMT_STRING(  18, "hh:mm AM/PM" ),
1335     EXC_NUMFMT_STRING(  19, "hh:mm:ss AM/PM" ),
1336     EXC_NUMFMT_OFFSET(  20, NF_TIME_HHMM ),
1337     EXC_NUMFMT_OFFSET(  21, NF_TIME_HHMMSS ),
1338     EXC_NUMFMT_STRING(  22, "YYYY/M/D hh:mm" ),
1339     EXC_NUMFMT_STRING(  23, "US$#,##0_);(US$#,##0)" ),
1340     EXC_NUMFMT_STRING(  24, "US$#,##0_);[RED](US$#,##0)" ),
1341     EXC_NUMFMT_STRING(  25, "US$#,##0.00_);(US$#,##0.00)" ),
1342     EXC_NUMFMT_STRING(  26, "US$#,##0.00_);[RED](US$#,##0.00)" ),
1343     EXC_NUMFMT_STRING(  27, "[$-0404]E/M/D" ),
1344     EXC_NUMFMT_STRING(  28, "[$-0404]E" UTF8_CJ_YEAR "M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
1345     EXC_NUMFMT_STRING(  30, "[$-0404]M/D/YY" ),
1346     EXC_NUMFMT_STRING(  31, "[$-0404]YYYY" UTF8_CJ_YEAR "M" UTF8_CJ_MON "D" UTF8_CJ_DAY ),
1347     EXC_NUMFMT_STRING(  32, "[$-0404]hh" UTF8_CJ_HOUR "mm" UTF8_CJ_MIN ),
1348     EXC_NUMFMT_STRING(  33, "[$-0404]hh" UTF8_CJ_HOUR "mm" UTF8_CJ_MIN "ss" UTF8_CJ_SEC ),
1349     EXC_NUMFMT_STRING(  34, "[$-0404]AM/PMhh" UTF8_CJ_HOUR "mm" UTF8_CJ_MIN ),
1350     EXC_NUMFMT_STRING(  35, "[$-0404]AM/PMhh" UTF8_CJ_HOUR "mm" UTF8_CJ_MIN "ss" UTF8_CJ_SEC ),
1351     EXC_NUMFMT_STRING(  63, "$#,##0;-$#,##0" ),
1352     EXC_NUMFMT_STRING(  64, "$#,##0;[RED]-$#,##0" ),
1353     EXC_NUMFMT_STRING(  65, "$#,##0.00;-$#,##0.00" ),
1354     EXC_NUMFMT_STRING(  66, "$#,##0.00;[RED]-$#,##0.00" ),
1355     EXC_NUMFMT_ENDTABLE()
1356 };
1357 
1358 // OTHER ----------------------------------------------------------------------
1359 
1360 static const XclBuiltInFormat spBuiltInFormats_HEBREW[] =
1361 {
1362     EXC_NUMFMT_STRING(  15, "DD-MMMM-YY" ),
1363     EXC_NUMFMT_STRING(  16, "DD-MMMM" ),
1364     EXC_NUMFMT_STRING(  17, "MMMM-YY" ),
1365     EXC_NUMFMT_STRING(  18, "h:mm AM/PM" ),
1366     EXC_NUMFMT_STRING(  19, "h:mm:ss AM/PM" ),
1367     EXC_NUMFMT_STRING(  63, UTF8_SHEQEL " #,##0;" UTF8_SHEQEL " -#,##0" ),
1368     EXC_NUMFMT_STRING(  64, UTF8_SHEQEL " #,##0;[RED]" UTF8_SHEQEL " -#,##0" ),
1369     EXC_NUMFMT_STRING(  65, UTF8_SHEQEL " #,##0.00;" UTF8_SHEQEL " -#,##0.00" ),
1370     EXC_NUMFMT_STRING(  66, UTF8_SHEQEL " #,##0.00;[RED]" UTF8_SHEQEL " -#,##0.00" ),
1371     EXC_NUMFMT_ENDTABLE()
1372 };
1373 
1374 static const XclBuiltInFormat spBuiltInFormats_THAI[] =
1375 {
1376     EXC_NUMFMT_STRING(  14, "D/M/YYYY" ),
1377     EXC_NUMFMT_STRING(  15, "D-MMM-YY" ),
1378     EXC_NUMFMT_STRING(  16, "D-MMM" ),
1379     EXC_NUMFMT_STRING(  17, "MMM-YY" ),
1380     EXC_NUMFMT_STRING(  18, "h:mm AM/PM" ),
1381     EXC_NUMFMT_STRING(  19, "h:mm:ss AM/PM" ),
1382     EXC_NUMFMT_STRING(  22, "D/M/YYYY h:mm" ),
1383     EXC_NUMFMT_STRING(  59, "t0" ),
1384     EXC_NUMFMT_STRING(  60, "t0.00" ),
1385     EXC_NUMFMT_STRING(  61, "t#,##0" ),
1386     EXC_NUMFMT_STRING(  62, "t#,##0.00" ),
1387     EXC_NUMFMT_STRING(  63, "t" UTF8_BAHT "#,##0_);t(" UTF8_BAHT "#,##0)" ),
1388     EXC_NUMFMT_STRING(  64, "t" UTF8_BAHT "#,##0_);[RED]t(" UTF8_BAHT "#,##0)" ),
1389     EXC_NUMFMT_STRING(  65, "t" UTF8_BAHT "#,##0.00_);t(" UTF8_BAHT "#,##0.00)" ),
1390     EXC_NUMFMT_STRING(  66, "t" UTF8_BAHT "#,##0.00_);[RED]t(" UTF8_BAHT "#,##0.00)" ),
1391     EXC_NUMFMT_STRING(  67, "t0%" ),
1392     EXC_NUMFMT_STRING(  68, "t0.00%" ),
1393     EXC_NUMFMT_STRING(  69, "t# ?/?" ),
1394     EXC_NUMFMT_STRING(  70, "t# ?\?/?\?" ),
1395     EXC_NUMFMT_STRING(  71, "tD/M/EE" ),
1396     EXC_NUMFMT_STRING(  72, "tD-MMM-E" ),
1397     EXC_NUMFMT_STRING(  73, "tD-MMM" ),
1398     EXC_NUMFMT_STRING(  74, "tMMM-E" ),
1399     EXC_NUMFMT_STRING(  75, "th:mm" ),
1400     EXC_NUMFMT_STRING(  76, "th:mm:ss" ),
1401     EXC_NUMFMT_STRING(  77, "tD/M/EE h:mm" ),
1402     EXC_NUMFMT_STRING(  78, "tmm:ss" ),
1403     EXC_NUMFMT_STRING(  79, "t[h]:mm:ss" ),
1404     EXC_NUMFMT_STRING(  80, "tmm:ss.0" ),
1405     EXC_NUMFMT_STRING(  81, "D/M/E" ),
1406     EXC_NUMFMT_ENDTABLE()
1407 };
1408 
1409 // ----------------------------------------------------------------------------
1410 
1411 #undef EXC_NUMFMT_ENDTABLE
1412 #undef EXC_NUMFMT_REUSE
1413 #undef EXC_NUMFMT_OFFSET
1414 #undef EXC_NUMFMT_STRING
1415 
1416 // ----------------------------------------------------------------------------
1417 
1418 /** Specifies a number format table for a specific langauge. */
1419 struct XclBuiltInFormatTable
1420 {
1421     LanguageType        meLanguage;         /// The language of this table.
1422     LanguageType        meParentLang;       /// The language of the parent table.
1423     const XclBuiltInFormat* mpFormats;      /// The number format table.
1424 };
1425 
1426 static const XclBuiltInFormatTable spBuiltInFormatTables[] =
1427 {   //  language                        parent language             format table
1428     {   LANGUAGE_DONTKNOW,              LANGUAGE_NONE,              spBuiltInFormats_DONTKNOW               },
1429 
1430     {   LANGUAGE_ENGLISH,               LANGUAGE_DONTKNOW,          spBuiltInFormats_ENGLISH                },
1431     {   LANGUAGE_ENGLISH_UK,            LANGUAGE_ENGLISH,           spBuiltInFormats_ENGLISH_UK             },
1432     {   LANGUAGE_ENGLISH_EIRE,          LANGUAGE_ENGLISH,           spBuiltInFormats_ENGLISH_EIRE           },
1433     {   LANGUAGE_ENGLISH_US,            LANGUAGE_ENGLISH,           spBuiltInFormats_ENGLISH_US             },
1434     {   LANGUAGE_ENGLISH_CAN,           LANGUAGE_ENGLISH,           spBuiltInFormats_ENGLISH_CAN            },
1435     {   LANGUAGE_ENGLISH_AUS,           LANGUAGE_ENGLISH,           spBuiltInFormats_ENGLISH_AUS            },
1436     {   LANGUAGE_ENGLISH_SAFRICA,       LANGUAGE_ENGLISH,           spBuiltInFormats_ENGLISH_SAFRICA        },
1437     {   LANGUAGE_ENGLISH_NZ,            LANGUAGE_ENGLISH_AUS,       0                                       },
1438 
1439     {   PRV_LANGUAGE_FRENCH_PRIM,       LANGUAGE_DONTKNOW,          spBuiltInFormats_FRENCH                 },
1440     {   LANGUAGE_FRENCH,                PRV_LANGUAGE_FRENCH_PRIM,   spBuiltInFormats_FRENCH_FRANCE          },
1441     {   LANGUAGE_FRENCH_CANADIAN,       PRV_LANGUAGE_FRENCH_PRIM,   spBuiltInFormats_FRENCH_CANADIAN        },
1442     {   LANGUAGE_FRENCH_SWISS,          PRV_LANGUAGE_FRENCH_PRIM,   spBuiltInFormats_FRENCH_SWISS           },
1443     {   LANGUAGE_FRENCH_BELGIAN,        LANGUAGE_FRENCH,            spBuiltInFormats_FRENCH_BELGIAN         },
1444     {   LANGUAGE_FRENCH_LUXEMBOURG,     LANGUAGE_FRENCH,            0                                       },
1445     {   LANGUAGE_FRENCH_MONACO,         LANGUAGE_FRENCH,            0                                       },
1446 
1447     {   PRV_LANGUAGE_GERMAN_PRIM,       LANGUAGE_DONTKNOW,          spBuiltInFormats_GERMAN                 },
1448     {   LANGUAGE_GERMAN,                PRV_LANGUAGE_GERMAN_PRIM,   spBuiltInFormats_GERMAN_GERMANY         },
1449     {   LANGUAGE_GERMAN_AUSTRIAN,       PRV_LANGUAGE_GERMAN_PRIM,   spBuiltInFormats_GERMAN_AUSTRIAN        },
1450     {   LANGUAGE_GERMAN_SWISS,          PRV_LANGUAGE_GERMAN_PRIM,   spBuiltInFormats_GERMAN_SWISS           },
1451     {   LANGUAGE_GERMAN_LUXEMBOURG,     PRV_LANGUAGE_GERMAN_PRIM,   spBuiltInFormats_GERMAN_LUXEMBOURG      },
1452     {   LANGUAGE_GERMAN_LIECHTENSTEIN,  PRV_LANGUAGE_GERMAN_PRIM,   spBuiltInFormats_GERMAN_LIECHTENSTEIN   },
1453 
1454     {   LANGUAGE_ITALIAN,               LANGUAGE_DONTKNOW,          spBuiltInFormats_ITALIAN_ITALY          },
1455     {   LANGUAGE_ITALIAN_SWISS,         LANGUAGE_DONTKNOW,          spBuiltInFormats_ITALIAN_SWISS          },
1456 
1457     {   LANGUAGE_SWEDISH,               LANGUAGE_DONTKNOW,          spBuiltInFormats_SWEDISH_SWEDEN         },
1458     {   LANGUAGE_SWEDISH_FINLAND,       LANGUAGE_DONTKNOW,          spBuiltInFormats_SWEDISH_FINLAND        },
1459 
1460     {   PRV_LANGUAGE_ASIAN_PRIM,        LANGUAGE_DONTKNOW,          spBuiltInFormats_ASIAN                  },
1461     {   LANGUAGE_JAPANESE,              PRV_LANGUAGE_ASIAN_PRIM,    spBuiltInFormats_JAPANESE               },
1462     {   LANGUAGE_KOREAN,                PRV_LANGUAGE_ASIAN_PRIM,    spBuiltInFormats_KOREAN                 },
1463     {   LANGUAGE_CHINESE_SIMPLIFIED,    PRV_LANGUAGE_ASIAN_PRIM,    spBuiltInFormats_CHINESE_SIMPLIFIED     },
1464     {   LANGUAGE_CHINESE_TRADITIONAL,   PRV_LANGUAGE_ASIAN_PRIM,    spBuiltInFormats_CHINESE_TRADITIONAL    },
1465 
1466     {   LANGUAGE_HEBREW,                LANGUAGE_DONTKNOW,          spBuiltInFormats_HEBREW                 },
1467     {   LANGUAGE_THAI,                  LANGUAGE_DONTKNOW,          spBuiltInFormats_THAI                   }
1468 };
1469 
1470 // ----------------------------------------------------------------------------
1471 
1472 } // namespace
1473 
1474 // ============================================================================
1475 
XclNumFmtBuffer(const XclRoot & rRoot)1476 XclNumFmtBuffer::XclNumFmtBuffer( const XclRoot& rRoot ) :
1477     meSysLang( rRoot.GetSysLanguage() ),
1478     mnStdScNumFmt( rRoot.GetFormatter().GetStandardFormat( ScGlobal::eLnge ) )
1479 {
1480     // *** insert default formats (BIFF5+ only)***
1481 
1482     if( rRoot.GetBiff() >= EXC_BIFF5 )
1483         InsertBuiltinFormats();
1484 }
1485 
InitializeImport()1486 void XclNumFmtBuffer::InitializeImport()
1487 {
1488     maFmtMap.clear();
1489 }
1490 
1491 //UNUSED2008-05  const XclNumFmt* XclNumFmtBuffer::GetFormat( sal_uInt16 nXclNumFmt ) const
1492 //UNUSED2008-05  {
1493 //UNUSED2008-05      XclNumFmtMap::const_iterator aIt = maFmtMap.find( nXclNumFmt );
1494 //UNUSED2008-05      return (aIt != maFmtMap.end()) ? &aIt->second : 0;
1495 //UNUSED2008-05  }
1496 
InsertFormat(sal_uInt16 nXclNumFmt,const String & rFormat)1497 void XclNumFmtBuffer::InsertFormat( sal_uInt16 nXclNumFmt, const String& rFormat )
1498 {
1499     XclNumFmt& rNumFmt = maFmtMap[ nXclNumFmt ];
1500     rNumFmt.maFormat = rFormat;
1501     // #i62053# rFormat may be an empty string, meOffset must be initialized
1502     rNumFmt.meOffset = NF_NUMBER_STANDARD;
1503     rNumFmt.meLanguage = LANGUAGE_SYSTEM;
1504 }
1505 
InsertBuiltinFormats()1506 void XclNumFmtBuffer::InsertBuiltinFormats()
1507 {
1508     // build a map containing tables for all languages
1509     typedef ::std::map< LanguageType, const XclBuiltInFormatTable* > XclBuiltInMap;
1510     XclBuiltInMap aBuiltInMap;
1511     for( const XclBuiltInFormatTable* pTable = spBuiltInFormatTables;
1512             pTable != STATIC_ARRAY_END( spBuiltInFormatTables ); ++pTable )
1513         aBuiltInMap[ pTable->meLanguage ] = pTable;
1514 
1515     // build a list of table pointers for the current language, with all parent tables
1516     typedef ::std::vector< const XclBuiltInFormatTable* > XclBuiltInVec;
1517     XclBuiltInVec aBuiltInVec;
1518     for( XclBuiltInMap::const_iterator aMIt = aBuiltInMap.find( meSysLang ), aMEnd = aBuiltInMap.end();
1519             aMIt != aMEnd; aMIt = aBuiltInMap.find( aMIt->second->meParentLang ) )
1520         aBuiltInVec.push_back( aMIt->second );
1521     // language not supported
1522     if( aBuiltInVec.empty() )
1523     {
1524         DBG_ERROR1( "XclNumFmtBuffer::InsertBuiltinFormats - language 0x%04hX not supported (#i29949#)", meSysLang );
1525         XclBuiltInMap::const_iterator aMIt = aBuiltInMap.find( LANGUAGE_DONTKNOW );
1526         DBG_ASSERT( aMIt != aBuiltInMap.end(), "XclNumFmtBuffer::InsertBuiltinFormats - default map not found" );
1527         if( aMIt != aBuiltInMap.end() )
1528             aBuiltInVec.push_back( aMIt->second );
1529     }
1530 
1531     // insert the default formats in the format map, from root parent to system language
1532     typedef ::std::map< sal_uInt16, sal_uInt16 > XclReuseMap;
1533     XclReuseMap aReuseMap;
1534     for( XclBuiltInVec::reverse_iterator aVIt = aBuiltInVec.rbegin(), aVEnd = aBuiltInVec.rend(); aVIt != aVEnd; ++aVIt )
1535     {
1536         // put LANGUAGE_SYSTEM for all entries in default table
1537         LanguageType eLang = ((*aVIt)->meLanguage == LANGUAGE_DONTKNOW) ? LANGUAGE_SYSTEM : meSysLang;
1538         for( const XclBuiltInFormat* pBuiltIn = (*aVIt)->mpFormats; pBuiltIn && (pBuiltIn->mnXclNumFmt != EXC_FORMAT_NOTFOUND); ++pBuiltIn )
1539         {
1540             XclNumFmt& rNumFmt = maFmtMap[ pBuiltIn->mnXclNumFmt ];
1541 
1542             rNumFmt.meOffset = pBuiltIn->meOffset;
1543             rNumFmt.meLanguage = eLang;
1544 
1545             if( pBuiltIn->mpFormat )
1546                 rNumFmt.maFormat = String( pBuiltIn->mpFormat, RTL_TEXTENCODING_UTF8 );
1547             else
1548                 rNumFmt.maFormat = EMPTY_STRING;
1549 
1550             if( pBuiltIn->meOffset == PRV_NF_INDEX_REUSE )
1551                 aReuseMap[ pBuiltIn->mnXclNumFmt ] = pBuiltIn->mnXclReuseFmt;
1552             else
1553                 aReuseMap.erase( pBuiltIn->mnXclNumFmt );
1554         }
1555     }
1556 
1557     // copy reused number formats
1558     for( XclReuseMap::const_iterator aRIt = aReuseMap.begin(), aREnd = aReuseMap.end(); aRIt != aREnd; ++aRIt )
1559         maFmtMap[ aRIt->first ] = maFmtMap[ aRIt->second ];
1560 }
1561 
1562 // Cell formatting data (XF) ==================================================
1563 
XclCellProt()1564 XclCellProt::XclCellProt() :
1565     mbLocked( true ),       // default in Excel and Calc
1566     mbHidden( false )
1567 {
1568 }
1569 
operator ==(const XclCellProt & rLeft,const XclCellProt & rRight)1570 bool operator==( const XclCellProt& rLeft, const XclCellProt& rRight )
1571 {
1572     return (rLeft.mbLocked == rRight.mbLocked) && (rLeft.mbHidden == rRight.mbHidden);
1573 }
1574 
1575 // ----------------------------------------------------------------------------
1576 
XclCellAlign()1577 XclCellAlign::XclCellAlign() :
1578     mnHorAlign( EXC_XF_HOR_GENERAL ),
1579     mnVerAlign( EXC_XF_VER_BOTTOM ),
1580     mnOrient( EXC_ORIENT_NONE ),
1581     mnTextDir( EXC_XF_TEXTDIR_CONTEXT ),
1582     mnRotation( EXC_ROT_NONE ),
1583     mnIndent( 0 ),
1584     mbLineBreak( false ),
1585     mbShrink( false )
1586 {
1587 }
1588 
GetScHorAlign() const1589 SvxCellHorJustify XclCellAlign::GetScHorAlign() const
1590 {
1591     SvxCellHorJustify eHorJust = SVX_HOR_JUSTIFY_STANDARD;
1592     switch( mnHorAlign )
1593     {
1594         case EXC_XF_HOR_GENERAL:    eHorJust = SVX_HOR_JUSTIFY_STANDARD;    break;
1595         case EXC_XF_HOR_LEFT:       eHorJust = SVX_HOR_JUSTIFY_LEFT;        break;
1596         case EXC_XF_HOR_CENTER_AS:
1597         case EXC_XF_HOR_CENTER:     eHorJust = SVX_HOR_JUSTIFY_CENTER;      break;
1598         case EXC_XF_HOR_RIGHT:      eHorJust = SVX_HOR_JUSTIFY_RIGHT;       break;
1599         case EXC_XF_HOR_FILL:       eHorJust = SVX_HOR_JUSTIFY_REPEAT;      break;
1600         case EXC_XF_HOR_JUSTIFY:
1601         case EXC_XF_HOR_DISTRIB:    eHorJust = SVX_HOR_JUSTIFY_BLOCK;       break;
1602         default:    DBG_ERRORFILE( "XclCellAlign::GetScHorAlign - unknown horizontal alignment" );
1603     }
1604     return eHorJust;
1605 }
1606 
GetScVerAlign() const1607 SvxCellVerJustify XclCellAlign::GetScVerAlign() const
1608 {
1609     SvxCellVerJustify eVerJust = SVX_VER_JUSTIFY_STANDARD;
1610     switch( mnVerAlign )
1611     {
1612         case EXC_XF_VER_TOP:        eVerJust = SVX_VER_JUSTIFY_TOP;         break;
1613         case EXC_XF_VER_CENTER:     eVerJust = SVX_VER_JUSTIFY_CENTER;      break;
1614         case EXC_XF_VER_BOTTOM:     eVerJust = SVX_VER_JUSTIFY_STANDARD;    break;
1615         case EXC_XF_VER_JUSTIFY:
1616         case EXC_XF_VER_DISTRIB:    eVerJust = SVX_VER_JUSTIFY_TOP;         break;
1617         default:    DBG_ERRORFILE( "XclCellAlign::GetScVerAlign - unknown vertical alignment" );
1618     }
1619     return eVerJust;
1620 }
1621 
GetScFrameDir() const1622 SvxFrameDirection XclCellAlign::GetScFrameDir() const
1623 {
1624     SvxFrameDirection eFrameDir = FRMDIR_ENVIRONMENT;
1625     switch( mnTextDir )
1626     {
1627         case EXC_XF_TEXTDIR_CONTEXT:    eFrameDir = FRMDIR_ENVIRONMENT;     break;
1628         case EXC_XF_TEXTDIR_LTR:        eFrameDir = FRMDIR_HORI_LEFT_TOP;   break;
1629         case EXC_XF_TEXTDIR_RTL:        eFrameDir = FRMDIR_HORI_RIGHT_TOP;  break;
1630         default:    DBG_ERRORFILE( "XclCellAlign::GetScFrameDir - unknown CTL text direction" );
1631     }
1632     return eFrameDir;
1633 }
1634 
SetScHorAlign(SvxCellHorJustify eHorJust)1635 void XclCellAlign::SetScHorAlign( SvxCellHorJustify eHorJust )
1636 {
1637     switch( eHorJust )
1638     {
1639         case SVX_HOR_JUSTIFY_STANDARD:  mnHorAlign = EXC_XF_HOR_GENERAL;    break;
1640         case SVX_HOR_JUSTIFY_LEFT:      mnHorAlign = EXC_XF_HOR_LEFT;       break;
1641         case SVX_HOR_JUSTIFY_CENTER:    mnHorAlign = EXC_XF_HOR_CENTER;     break;
1642         case SVX_HOR_JUSTIFY_RIGHT:     mnHorAlign = EXC_XF_HOR_RIGHT;      break;
1643         case SVX_HOR_JUSTIFY_BLOCK:     mnHorAlign = EXC_XF_HOR_JUSTIFY;    break;
1644         case SVX_HOR_JUSTIFY_REPEAT:    mnHorAlign = EXC_XF_HOR_FILL;       break;
1645         default:                        mnHorAlign = EXC_XF_HOR_GENERAL;
1646             DBG_ERROR( "XclCellAlign::SetScHorAlign - unknown horizontal alignment" );
1647     }
1648 }
1649 
SetScVerAlign(SvxCellVerJustify eVerJust)1650 void XclCellAlign::SetScVerAlign( SvxCellVerJustify eVerJust )
1651 {
1652     switch( eVerJust )
1653     {
1654         case SVX_VER_JUSTIFY_STANDARD:  mnVerAlign = EXC_XF_VER_BOTTOM; break;
1655         case SVX_VER_JUSTIFY_TOP:       mnVerAlign = EXC_XF_VER_TOP;    break;
1656         case SVX_VER_JUSTIFY_CENTER:    mnVerAlign = EXC_XF_VER_CENTER; break;
1657         case SVX_VER_JUSTIFY_BOTTOM:    mnVerAlign = EXC_XF_VER_BOTTOM; break;
1658         default:                        mnVerAlign = EXC_XF_VER_BOTTOM;
1659             DBG_ERROR( "XclCellAlign::SetScVerAlign - unknown vertical alignment" );
1660     }
1661 }
1662 
SetScFrameDir(SvxFrameDirection eFrameDir)1663 void XclCellAlign::SetScFrameDir( SvxFrameDirection eFrameDir )
1664 {
1665     switch( eFrameDir )
1666     {
1667         case FRMDIR_ENVIRONMENT:    mnTextDir = EXC_XF_TEXTDIR_CONTEXT; break;
1668         case FRMDIR_HORI_LEFT_TOP:  mnTextDir = EXC_XF_TEXTDIR_LTR;     break;
1669         case FRMDIR_HORI_RIGHT_TOP: mnTextDir = EXC_XF_TEXTDIR_RTL;     break;
1670         default:                    mnTextDir = EXC_XF_TEXTDIR_CONTEXT;
1671             DBG_ERRORFILE( "XclCellAlign::SetScFrameDir - unknown CTL text direction" );
1672     }
1673 }
1674 
operator ==(const XclCellAlign & rLeft,const XclCellAlign & rRight)1675 bool operator==( const XclCellAlign& rLeft, const XclCellAlign& rRight )
1676 {
1677     return
1678         (rLeft.mnHorAlign  == rRight.mnHorAlign)  && (rLeft.mnVerAlign == rRight.mnVerAlign) &&
1679         (rLeft.mnTextDir   == rRight.mnTextDir)   && (rLeft.mnOrient   == rRight.mnOrient)   &&
1680         (rLeft.mnRotation  == rRight.mnRotation)  && (rLeft.mnIndent   == rRight.mnIndent)   &&
1681         (rLeft.mbLineBreak == rRight.mbLineBreak) && (rLeft.mbShrink   == rRight.mbShrink);
1682 }
1683 
1684 // ----------------------------------------------------------------------------
1685 
XclCellBorder()1686 XclCellBorder::XclCellBorder() :
1687     mnLeftColor( 0 ),
1688     mnRightColor( 0 ),
1689     mnTopColor( 0 ),
1690     mnBottomColor( 0 ),
1691     mnDiagColor( 0 ),
1692     mnLeftLine( EXC_LINE_NONE ),
1693     mnRightLine( EXC_LINE_NONE ),
1694     mnTopLine( EXC_LINE_NONE ),
1695     mnBottomLine( EXC_LINE_NONE ),
1696     mnDiagLine( EXC_LINE_NONE ),
1697     mbDiagTLtoBR( false ),
1698     mbDiagBLtoTR( false )
1699 {
1700 }
1701 
operator ==(const XclCellBorder & rLeft,const XclCellBorder & rRight)1702 bool operator==( const XclCellBorder& rLeft, const XclCellBorder& rRight )
1703 {
1704     return
1705         (rLeft.mnLeftColor  == rRight.mnLeftColor)  && (rLeft.mnRightColor  == rRight.mnRightColor)  &&
1706         (rLeft.mnTopColor   == rRight.mnTopColor)   && (rLeft.mnBottomColor == rRight.mnBottomColor) &&
1707         (rLeft.mnLeftLine   == rRight.mnLeftLine)   && (rLeft.mnRightLine   == rRight.mnRightLine)   &&
1708         (rLeft.mnTopLine    == rRight.mnTopLine)    && (rLeft.mnBottomLine  == rRight.mnBottomLine)  &&
1709         (rLeft.mnDiagColor  == rRight.mnDiagColor)  && (rLeft.mnDiagLine    == rRight.mnDiagLine)    &&
1710         (rLeft.mbDiagTLtoBR == rRight.mbDiagTLtoBR) && (rLeft.mbDiagBLtoTR  == rRight.mbDiagBLtoTR);
1711 }
1712 
1713 // ----------------------------------------------------------------------------
1714 
XclCellArea()1715 XclCellArea::XclCellArea() :
1716     mnForeColor( EXC_COLOR_WINDOWTEXT ),
1717     mnBackColor( EXC_COLOR_WINDOWBACK ),
1718     mnPattern( EXC_PATT_NONE )
1719 {
1720 }
1721 
IsTransparent() const1722 bool XclCellArea::IsTransparent() const
1723 {
1724     return (mnPattern == EXC_PATT_NONE) && (mnBackColor == EXC_COLOR_WINDOWBACK);
1725 }
1726 
operator ==(const XclCellArea & rLeft,const XclCellArea & rRight)1727 bool operator==( const XclCellArea& rLeft, const XclCellArea& rRight )
1728 {
1729     return
1730         (rLeft.mnForeColor == rRight.mnForeColor) && (rLeft.mnBackColor == rRight.mnBackColor) &&
1731         (rLeft.mnPattern == rRight.mnPattern);
1732 }
1733 
1734 // ----------------------------------------------------------------------------
1735 
XclXFBase(bool bCellXF)1736 XclXFBase::XclXFBase( bool bCellXF ) :
1737     mnParent( bCellXF ? EXC_XF_DEFAULTSTYLE : EXC_XF_STYLEPARENT ),
1738     mbCellXF( bCellXF )
1739 {
1740     SetAllUsedFlags( false );
1741 }
1742 
~XclXFBase()1743 XclXFBase::~XclXFBase()
1744 {
1745 }
1746 
SetAllUsedFlags(bool bUsed)1747 void XclXFBase::SetAllUsedFlags( bool bUsed )
1748 {
1749     mbProtUsed = mbFontUsed = mbFmtUsed = mbAlignUsed = mbBorderUsed = mbAreaUsed = bUsed;
1750 }
1751 
HasUsedFlags() const1752 bool XclXFBase::HasUsedFlags() const
1753 {
1754     return mbProtUsed || mbFontUsed || mbFmtUsed || mbAlignUsed || mbBorderUsed || mbAreaUsed;
1755 }
1756 
Equals(const XclXFBase & rCmp) const1757 bool XclXFBase::Equals( const XclXFBase& rCmp ) const
1758 {
1759     return
1760         (mbCellXF     == rCmp.mbCellXF)     && (mnParent    == rCmp.mnParent)    &&
1761         (mbProtUsed   == rCmp.mbProtUsed)   && (mbFontUsed  == rCmp.mbFontUsed)  &&
1762         (mbFmtUsed    == rCmp.mbFmtUsed)    && (mbAlignUsed == rCmp.mbAlignUsed) &&
1763         (mbBorderUsed == rCmp.mbBorderUsed) && (mbAreaUsed  == rCmp.mbAreaUsed);
1764 }
1765 
1766 // ============================================================================
1767 
1768