1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <rtl/ustring.hxx>
11 #include <rtl/strbuf.hxx>
12 #include <unotools/fontcvt.hxx>
13 #include <unotools/fontdefs.hxx>
14 #include <vcl/svapp.hxx>
15 #include <filter/msfilter/util.hxx>
20 rtl_TextEncoding
getBestTextEncodingFromLocale(const ::com::sun::star::lang::Locale
&rLocale
)
22 //Obviously not comprehensive, feel free to expand these, they're for ultimate fallbacks
23 //in last-ditch broken-file-format cases to guess the right 8bit encodings
24 const OUString
&rLanguage
= rLocale
.Language
;
25 if (rLanguage
== "cs" || rLanguage
== "hu" || rLanguage
== "pl")
26 return RTL_TEXTENCODING_MS_1250
;
27 if (rLanguage
== "ru" || rLanguage
== "uk")
28 return RTL_TEXTENCODING_MS_1251
;
29 if (rLanguage
== "el")
30 return RTL_TEXTENCODING_MS_1253
;
31 if (rLanguage
== "tr")
32 return RTL_TEXTENCODING_MS_1254
;
33 if (rLanguage
== "lt")
34 return RTL_TEXTENCODING_MS_1257
;
35 return RTL_TEXTENCODING_MS_1252
;
38 sal_uInt32
BGRToRGB(sal_uInt32 nColor
)
41 r(static_cast<sal_uInt8
>(nColor
&0xFF)),
42 g(static_cast<sal_uInt8
>(((nColor
)>>8)&0xFF)),
43 b(static_cast<sal_uInt8
>((nColor
>>16)&0xFF)),
44 t(static_cast<sal_uInt8
>((nColor
>>24)&0xFF));
45 nColor
= (t
<<24) + (r
<<16) + (g
<<8) + b
;
49 DateTime
DTTM2DateTime( long lDTTM
)
52 mint short :6 0000003F minutes (0-59)
53 hr short :5 000007C0 hours (0-23)
54 dom short :5 0000F800 days of month (1-31)
55 mon short :4 000F0000 months (1-12)
56 yr short :9 1FF00000 years (1900-2411)-1900
57 wdy short :3 E0000000 weekday(Sunday=0
59 ( wdy can be ignored ) Tuesday=2
65 DateTime
aDateTime(Date( 0 ), Time( 0 ));
68 sal_uInt16 lMin
= (sal_uInt16
)(lDTTM
& 0x0000003F);
70 sal_uInt16 lHour
= (sal_uInt16
)(lDTTM
& 0x0000001F);
72 sal_uInt16 lDay
= (sal_uInt16
)(lDTTM
& 0x0000001F);
74 sal_uInt16 lMon
= (sal_uInt16
)(lDTTM
& 0x0000000F);
76 sal_uInt16 lYear
= (sal_uInt16
)(lDTTM
& 0x000001FF) + 1900;
77 aDateTime
= DateTime(Date(lDay
, lMon
, lYear
), Time(lHour
, lMin
));
82 /// Append the number as 2-digit when less than 10.
83 static void lcl_AppendTwoDigits( OStringBuffer
&rBuffer
, sal_Int32 nNum
)
85 if ( nNum
< 0 || nNum
> 99 )
87 rBuffer
.append( "00" );
92 rBuffer
.append( '0' );
94 rBuffer
.append( nNum
);
97 OString
DateTimeToOString( const DateTime
& rDateTime
)
99 DateTime
aInUTC( rDateTime
);
100 // HACK: this is correct according to the spec, but MSOffice believes everybody lives
101 // in UTC+0 when reading it back
102 // aInUTC.ConvertToUTC();
104 OStringBuffer
aBuffer( 25 );
105 aBuffer
.append( sal_Int32( aInUTC
.GetYear() ) );
106 aBuffer
.append( '-' );
108 lcl_AppendTwoDigits( aBuffer
, aInUTC
.GetMonth() );
109 aBuffer
.append( '-' );
111 lcl_AppendTwoDigits( aBuffer
, aInUTC
.GetDay() );
112 aBuffer
.append( 'T' );
114 lcl_AppendTwoDigits( aBuffer
, aInUTC
.GetHour() );
115 aBuffer
.append( ':' );
117 lcl_AppendTwoDigits( aBuffer
, aInUTC
.GetMin() );
118 aBuffer
.append( ':' );
120 lcl_AppendTwoDigits( aBuffer
, aInUTC
.GetSec() );
121 aBuffer
.append( 'Z' ); // we are in UTC
123 return aBuffer
.makeStringAndClear();
126 sal_Unicode
bestFitOpenSymbolToMSFont(sal_Unicode cChar
,
127 rtl_TextEncoding
& rChrSet
, OUString
& rFontName
, bool bDisableUnicodeSupport
)
129 StarSymbolToMSMultiFont
*pConvert
= CreateStarSymbolToMSMultiFont();
130 OUString sFont
= pConvert
->ConvertChar(cChar
);
132 if (!sFont
.isEmpty())
134 cChar
= static_cast< sal_Unicode
>(cChar
| 0xF000);
136 rChrSet
= RTL_TEXTENCODING_SYMBOL
;
138 else if (!bDisableUnicodeSupport
&& (cChar
< 0xE000 || cChar
> 0xF8FF))
141 Ok we can't fit into a known windows unicode font, but
142 we are not in the private area, so we are a
143 standardized symbol, so turn off the symbol bit and
144 let words own font substitution kick in
146 rChrSet
= RTL_TEXTENCODING_UNICODE
;
147 sal_Int32 nIndex
= 0;
148 rFontName
= ::GetNextFontToken(rFontName
, nIndex
);
153 Well we don't have an available substition, and we're
154 in our private area, so give up and show a standard
157 rFontName
= "Wingdings";
158 cChar
= static_cast< sal_Unicode
>(0x6C);
164 http://social.msdn.microsoft.com/Forums/hu-HU/os_openXML-ecma/thread/1bf1f185-ee49-4314-94e7-f4e1563b5c00
166 The following information is being submitted to the standards working group as
167 a proposed resolution to a defect report and is not yet part of ISO 29500-1.
169 For each Unicode character in DrawingML text, the font face can be any of four
170 font “slots”: latin (§21.1.2.3.7), cs (§21.1.2.3.1), ea (§21.1.2.3.3), or sym
171 (§21.1.2.3.10), as specified in the following table. For all ranges not
172 explicitly called out below, the ea font shall be used.
174 U+0000–U+007F Use latin font
175 U+0080–U+00A6 Use latin font
176 U+00A9–U+00AF Use latin font
177 U+00B2–U+00B3 Use latin font
178 U+00B5–U+00D6 Use latin font
179 U+00D8–U+00F6 Use latin font
180 U+00F8–U+058F Use latin font
181 U+0590–U+074F Use cs font
182 U+0780–U+07BF Use cs font
183 U+0900–U+109F Use cs font
184 U+10A0–U+10FF Use latin font
185 U+1200–U+137F Use latin font
186 U+13A0–U+177F Use latin font
187 U+1D00–U+1D7F Use latin font
188 U+1E00–U+1FFF Use latin font
189 U+1780–U+18AF Use cs font
190 U+2000–U+200B Use latin font
191 U+200C–U+200F Use cs font
192 U+2010–U+2029 Use latin font Except, for the quote characters in the range
193 2018 – 201E, use ea font if the text has one of the following language
194 identifiers: ii-CN, ja-JP, ko-KR, zh-CN, zh-HK, zh-MO, zh-SG, zh-TW.
195 U+202A–U+202F Use cs font
196 U+2030–U+2046 Use latin font
197 U+204A–U+245F Use latin font
198 U+2670–U+2671 Use cs font
199 U+27C0–U+2BFF Use latin font
200 U+3099–U+309A Use ea font
201 U+D835 Use latin font
202 U+F000–U+F0FF Symbol, use sym font
203 U+FB00–U+FB17 Use latin font
204 U+FB1D–U+FB4F Use cs font
205 U+FE50–U+FE6F Use latin font
206 Otherwise Use ea font
208 TextCategory
categorizeCodePoint(sal_uInt32 codePoint
, const OUString
&rBcp47LanguageTag
)
210 TextCategory eRet
= ea
;
211 if (codePoint
<= 0x007F)
213 else if (0x0080 <= codePoint
&& codePoint
<= 0x00A6)
215 else if (0x00A9 <= codePoint
&& codePoint
<= 0x00AF)
217 else if (0x00B2 <= codePoint
&& codePoint
<= 0x00B3)
219 else if (0x00B5 <= codePoint
&& codePoint
<= 0x00D6)
221 else if (0x00D8 <= codePoint
&& codePoint
<= 0x00F6)
223 else if (0x00F8 <= codePoint
&& codePoint
<= 0x058F)
225 else if (0x0590 <= codePoint
&& codePoint
<= 0x074F)
227 else if (0x0780 <= codePoint
&& codePoint
<= 0x07BF)
229 else if (0x0900 <= codePoint
&& codePoint
<= 0x109F)
231 else if (0x10A0 <= codePoint
&& codePoint
<= 0x10FF)
233 else if (0x1200 <= codePoint
&& codePoint
<= 0x137F)
235 else if (0x13A0 <= codePoint
&& codePoint
<= 0x177F)
237 else if (0x1D00 <= codePoint
&& codePoint
<= 0x1D7F)
239 else if (0x1E00 <= codePoint
&& codePoint
<= 0x1FFF)
241 else if (0x1780 <= codePoint
&& codePoint
<= 0x18AF)
243 else if (0x2000 <= codePoint
&& codePoint
<= 0x200B)
245 else if (0x200C <= codePoint
&& codePoint
<= 0x200F)
247 else if (0x2010 <= codePoint
&& codePoint
<= 0x2029)
250 if (0x2018 <= codePoint
&& codePoint
<= 0x201E)
252 if (rBcp47LanguageTag
== "ii-CN" ||
253 rBcp47LanguageTag
== "ja-JP" ||
254 rBcp47LanguageTag
== "ko-KR" ||
255 rBcp47LanguageTag
== "zh-CN" ||
256 rBcp47LanguageTag
== "zh-HK" ||
257 rBcp47LanguageTag
== "zh-MO" ||
258 rBcp47LanguageTag
== "zh-SG" ||
259 rBcp47LanguageTag
== "zh-TW")
265 else if (0x202A <= codePoint
&& codePoint
<= 0x202F)
267 else if (0x2030 <= codePoint
&& codePoint
<= 0x2046)
269 else if (0x204A <= codePoint
&& codePoint
<= 0x245F)
271 else if (0x2670 <= codePoint
&& codePoint
<= 0x2671)
273 else if (0x27C0 <= codePoint
&& codePoint
<= 0x2BFF)
275 else if (0x3099 <= codePoint
&& codePoint
<= 0x309A)
277 else if (0xD835 == codePoint
)
279 else if (0xF000 <= codePoint
&& codePoint
<= 0xF0FF)
281 else if (0xFB00 <= codePoint
&& codePoint
<= 0xFB17)
283 else if (0xFB1D <= codePoint
&& codePoint
<= 0xFB4F)
285 else if (0xFE50 <= codePoint
&& codePoint
<= 0xFE6F)
290 OString
ConvertColor( const Color
&rColor
)
292 OString
color( "auto" );
293 if ( rColor
.GetColor() != COL_AUTO
)
295 const char pHexDigits
[] = "0123456789ABCDEF";
296 char pBuffer
[] = "000000";
298 pBuffer
[0] = pHexDigits
[ ( rColor
.GetRed() >> 4 ) & 0x0F ];
299 pBuffer
[1] = pHexDigits
[ rColor
.GetRed() & 0x0F ];
300 pBuffer
[2] = pHexDigits
[ ( rColor
.GetGreen() >> 4 ) & 0x0F ];
301 pBuffer
[3] = pHexDigits
[ rColor
.GetGreen() & 0x0F ];
302 pBuffer
[4] = pHexDigits
[ ( rColor
.GetBlue() >> 4 ) & 0x0F ];
303 pBuffer
[5] = pHexDigits
[ rColor
.GetBlue() & 0x0F ];
305 color
= OString( pBuffer
);
311 #define IN2MM100( v ) static_cast< sal_Int32 >( (v) * 2540.0 + 0.5 )
312 #define MM2MM100( v ) static_cast< sal_Int32 >( (v) * 100.0 + 0.5 )
314 static const ApiPaperSize spPaperSizeTable
[] =
316 { 0, 0 }, // 0 - (undefined)
317 { IN2MM100( 8.5 ), IN2MM100( 11 ) }, // 1 - Letter paper
318 { IN2MM100( 8.5 ), IN2MM100( 11 ) }, // 2 - Letter small paper
319 { IN2MM100( 11 ), IN2MM100( 17 ) }, // 3 - Tabloid paper
320 { IN2MM100( 17 ), IN2MM100( 11 ) }, // 4 - Ledger paper
321 { IN2MM100( 8.5 ), IN2MM100( 14 ) }, // 5 - Legal paper
322 { IN2MM100( 5.5 ), IN2MM100( 8.5 ) }, // 6 - Statement paper
323 { IN2MM100( 7.25 ), IN2MM100( 10.5 ) }, // 7 - Executive paper
324 { MM2MM100( 297 ), MM2MM100( 420 ) }, // 8 - A3 paper
325 { MM2MM100( 210 ), MM2MM100( 297 ) }, // 9 - A4 paper
326 { MM2MM100( 210 ), MM2MM100( 297 ) }, // 10 - A4 small paper
327 { MM2MM100( 148 ), MM2MM100( 210 ) }, // 11 - A5 paper
328 { MM2MM100( 250 ), MM2MM100( 353 ) }, // 12 - B4 paper
329 { MM2MM100( 176 ), MM2MM100( 250 ) }, // 13 - B5 paper
330 { IN2MM100( 8.5 ), IN2MM100( 13 ) }, // 14 - Folio paper
331 { MM2MM100( 215 ), MM2MM100( 275 ) }, // 15 - Quarto paper
332 { IN2MM100( 10 ), IN2MM100( 14 ) }, // 16 - Standard paper
333 { IN2MM100( 11 ), IN2MM100( 17 ) }, // 17 - Standard paper
334 { IN2MM100( 8.5 ), IN2MM100( 11 ) }, // 18 - Note paper
335 { IN2MM100( 3.875 ), IN2MM100( 8.875 ) }, // 19 - #9 envelope
336 { IN2MM100( 4.125 ), IN2MM100( 9.5 ) }, // 20 - #10 envelope
337 { IN2MM100( 4.5 ), IN2MM100( 10.375 ) }, // 21 - #11 envelope
338 { IN2MM100( 4.75 ), IN2MM100( 11 ) }, // 22 - #12 envelope
339 { IN2MM100( 5 ), IN2MM100( 11.5 ) }, // 23 - #14 envelope
340 { IN2MM100( 17 ), IN2MM100( 22 ) }, // 24 - C paper
341 { IN2MM100( 22 ), IN2MM100( 34 ) }, // 25 - D paper
342 { IN2MM100( 34 ), IN2MM100( 44 ) }, // 26 - E paper
343 { MM2MM100( 110 ), MM2MM100( 220 ) }, // 27 - DL envelope
344 { MM2MM100( 162 ), MM2MM100( 229 ) }, // 28 - C5 envelope
345 { MM2MM100( 324 ), MM2MM100( 458 ) }, // 29 - C3 envelope
346 { MM2MM100( 229 ), MM2MM100( 324 ) }, // 30 - C4 envelope
347 { MM2MM100( 114 ), MM2MM100( 162 ) }, // 31 - C6 envelope
348 { MM2MM100( 114 ), MM2MM100( 229 ) }, // 32 - C65 envelope
349 { MM2MM100( 250 ), MM2MM100( 353 ) }, // 33 - B4 envelope
350 { MM2MM100( 176 ), MM2MM100( 250 ) }, // 34 - B5 envelope
351 { MM2MM100( 176 ), MM2MM100( 125 ) }, // 35 - B6 envelope
352 { MM2MM100( 110 ), MM2MM100( 230 ) }, // 36 - Italy envelope
353 { IN2MM100( 3.875 ), IN2MM100( 7.5 ) }, // 37 - Monarch envelope
354 { IN2MM100( 3.625 ), IN2MM100( 6.5 ) }, // 38 - 6 3/4 envelope
355 { IN2MM100( 14.875 ), IN2MM100( 11 ) }, // 39 - US standard fanfold
356 { IN2MM100( 8.5 ), IN2MM100( 12 ) }, // 40 - German standard fanfold
357 { IN2MM100( 8.5 ), IN2MM100( 13 ) }, // 41 - German legal fanfold
358 { MM2MM100( 250 ), MM2MM100( 353 ) }, // 42 - ISO B4
359 { MM2MM100( 200 ), MM2MM100( 148 ) }, // 43 - Japanese double postcard
360 { IN2MM100( 9 ), IN2MM100( 11 ) }, // 44 - Standard paper
361 { IN2MM100( 10 ), IN2MM100( 11 ) }, // 45 - Standard paper
362 { IN2MM100( 15 ), IN2MM100( 11 ) }, // 46 - Standard paper
363 { MM2MM100( 220 ), MM2MM100( 220 ) }, // 47 - Invite envelope
364 { 0, 0 }, // 48 - (undefined)
365 { 0, 0 }, // 49 - (undefined)
366 { IN2MM100( 9.275 ), IN2MM100( 12 ) }, // 50 - Letter extra paper
367 { IN2MM100( 9.275 ), IN2MM100( 15 ) }, // 51 - Legal extra paper
368 { IN2MM100( 11.69 ), IN2MM100( 18 ) }, // 52 - Tabloid extra paper
369 { MM2MM100( 236 ), MM2MM100( 322 ) }, // 53 - A4 extra paper
370 { IN2MM100( 8.275 ), IN2MM100( 11 ) }, // 54 - Letter transverse paper
371 { MM2MM100( 210 ), MM2MM100( 297 ) }, // 55 - A4 transverse paper
372 { IN2MM100( 9.275 ), IN2MM100( 12 ) }, // 56 - Letter extra transverse paper
373 { MM2MM100( 227 ), MM2MM100( 356 ) }, // 57 - SuperA/SuperA/A4 paper
374 { MM2MM100( 305 ), MM2MM100( 487 ) }, // 58 - SuperB/SuperB/A3 paper
375 { IN2MM100( 8.5 ), IN2MM100( 12.69 ) }, // 59 - Letter plus paper
376 { MM2MM100( 210 ), MM2MM100( 330 ) }, // 60 - A4 plus paper
377 { MM2MM100( 148 ), MM2MM100( 210 ) }, // 61 - A5 transverse paper
378 { MM2MM100( 182 ), MM2MM100( 257 ) }, // 62 - JIS B5 transverse paper
379 { MM2MM100( 322 ), MM2MM100( 445 ) }, // 63 - A3 extra paper
380 { MM2MM100( 174 ), MM2MM100( 235 ) }, // 64 - A5 extra paper
381 { MM2MM100( 201 ), MM2MM100( 276 ) }, // 65 - ISO B5 extra paper
382 { MM2MM100( 420 ), MM2MM100( 594 ) }, // 66 - A2 paper
383 { MM2MM100( 297 ), MM2MM100( 420 ) }, // 67 - A3 transverse paper
384 { MM2MM100( 322 ), MM2MM100( 445 ) } // 68 - A3 extra transverse paper
387 sal_Int32
PaperSizeConv::getMSPaperSizeIndex( const com::sun::star::awt::Size
& rSize
)
389 sal_Int32 nElems
= SAL_N_ELEMENTS( spPaperSizeTable
);
390 // Need to find the best match for current size
391 sal_Int32 nDeltaWidth
= 0;
392 sal_Int32 nDeltaHeight
= 0;
394 sal_Int32 nPaperSizeIndex
= 0; // Undefined
395 const ApiPaperSize
* pItem
= spPaperSizeTable
;
396 const ApiPaperSize
* pEnd
= spPaperSizeTable
+ nElems
;
397 for ( ; pItem
!= pEnd
; ++pItem
)
399 sal_Int32 nCurDeltaHeight
= std::abs( pItem
->mnHeight
- rSize
.Height
);
400 sal_Int32 nCurDeltaWidth
= std::abs( pItem
->mnWidth
- rSize
.Width
);
401 if ( pItem
== spPaperSizeTable
) // initialise delta with first item
403 nDeltaWidth
= nCurDeltaWidth
;
404 nDeltaHeight
= nCurDeltaHeight
;
408 if ( nCurDeltaWidth
< nDeltaWidth
&& nCurDeltaHeight
< nDeltaHeight
)
410 nDeltaWidth
= nCurDeltaWidth
;
411 nDeltaHeight
= nCurDeltaHeight
;
412 nPaperSizeIndex
= (pItem
- spPaperSizeTable
);
416 sal_Int32 nTol
= 10; // hmm not sure is this the best way
417 if ( nDeltaWidth
<= nTol
&& nDeltaHeight
<= nTol
)
418 return nPaperSizeIndex
;
422 const ApiPaperSize
& PaperSizeConv::getApiSizeForMSPaperSizeIndex( sal_Int32 nMSOPaperIndex
)
424 sal_Int32 nElems
= SAL_N_ELEMENTS( spPaperSizeTable
);
425 if ( nMSOPaperIndex
< 0 || nMSOPaperIndex
> nElems
- 1 )
426 return spPaperSizeTable
[ 0 ];
427 return spPaperSizeTable
[ nMSOPaperIndex
];
430 OUString
findQuotedText( const OUString
& rCommand
,
431 const sal_Char
* cStartQuote
, const sal_Unicode uEndQuote
)
434 OUString
sStartQuote( OUString::createFromAscii(cStartQuote
) );
435 sal_Int32 nStartIndex
= rCommand
.indexOf( sStartQuote
);
436 if( nStartIndex
>= 0 )
438 sal_Int32 nStartLength
= sStartQuote
.getLength();
439 sal_Int32 nEndIndex
= rCommand
.indexOf( uEndQuote
, nStartIndex
+ nStartLength
);
440 if( nEndIndex
> nStartIndex
)
442 sRet
= rCommand
.copy( nStartIndex
+ nStartLength
, nEndIndex
- nStartIndex
- nStartLength
);
452 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */