bump product version to 4.1.6.2
[LibreOffice.git] / filter / source / msfilter / util.cxx
bloba10e4381d510dc00a1fda6770075a0aa402540a2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
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>
17 namespace msfilter {
18 namespace util {
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)
40 sal_uInt8
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;
46 return nColor;
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
58 Monday=1
59 ( wdy can be ignored ) Tuesday=2
60 Wednesday=3
61 Thursday=4
62 Friday=5
63 Saturday=6)
65 DateTime aDateTime(Date( 0 ), Time( 0 ));
66 if( lDTTM )
68 sal_uInt16 lMin = (sal_uInt16)(lDTTM & 0x0000003F);
69 lDTTM >>= 6;
70 sal_uInt16 lHour= (sal_uInt16)(lDTTM & 0x0000001F);
71 lDTTM >>= 5;
72 sal_uInt16 lDay = (sal_uInt16)(lDTTM & 0x0000001F);
73 lDTTM >>= 5;
74 sal_uInt16 lMon = (sal_uInt16)(lDTTM & 0x0000000F);
75 lDTTM >>= 4;
76 sal_uInt16 lYear= (sal_uInt16)(lDTTM & 0x000001FF) + 1900;
77 aDateTime = DateTime(Date(lDay, lMon, lYear), Time(lHour, lMin));
79 return aDateTime;
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" );
88 return;
91 if ( nNum < 10 )
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);
131 delete pConvert;
132 if (!sFont.isEmpty())
134 cChar = static_cast< sal_Unicode >(cChar | 0xF000);
135 rFontName = sFont;
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);
150 else
153 Well we don't have an available substition, and we're
154 in our private area, so give up and show a standard
155 bullet symbol
157 rFontName = "Wingdings";
158 cChar = static_cast< sal_Unicode >(0x6C);
160 return cChar;
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)
212 eRet = latin;
213 else if (0x0080 <= codePoint && codePoint <= 0x00A6)
214 eRet = latin;
215 else if (0x00A9 <= codePoint && codePoint <= 0x00AF)
216 eRet = latin;
217 else if (0x00B2 <= codePoint && codePoint <= 0x00B3)
218 eRet = latin;
219 else if (0x00B5 <= codePoint && codePoint <= 0x00D6)
220 eRet = latin;
221 else if (0x00D8 <= codePoint && codePoint <= 0x00F6)
222 eRet = latin;
223 else if (0x00F8 <= codePoint && codePoint <= 0x058F)
224 eRet = latin;
225 else if (0x0590 <= codePoint && codePoint <= 0x074F)
226 eRet = cs;
227 else if (0x0780 <= codePoint && codePoint <= 0x07BF)
228 eRet = cs;
229 else if (0x0900 <= codePoint && codePoint <= 0x109F)
230 eRet = cs;
231 else if (0x10A0 <= codePoint && codePoint <= 0x10FF)
232 eRet = latin;
233 else if (0x1200 <= codePoint && codePoint <= 0x137F)
234 eRet = latin;
235 else if (0x13A0 <= codePoint && codePoint <= 0x177F)
236 eRet = latin;
237 else if (0x1D00 <= codePoint && codePoint <= 0x1D7F)
238 eRet = latin;
239 else if (0x1E00 <= codePoint && codePoint <= 0x1FFF)
240 eRet = latin;
241 else if (0x1780 <= codePoint && codePoint <= 0x18AF)
242 eRet = cs;
243 else if (0x2000 <= codePoint && codePoint <= 0x200B)
244 eRet = latin;
245 else if (0x200C <= codePoint && codePoint <= 0x200F)
246 eRet = cs;
247 else if (0x2010 <= codePoint && codePoint <= 0x2029)
249 eRet = latin;
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")
261 eRet = ea;
265 else if (0x202A <= codePoint && codePoint <= 0x202F)
266 eRet = cs;
267 else if (0x2030 <= codePoint && codePoint <= 0x2046)
268 eRet = latin;
269 else if (0x204A <= codePoint && codePoint <= 0x245F)
270 eRet = latin;
271 else if (0x2670 <= codePoint && codePoint <= 0x2671)
272 eRet = latin;
273 else if (0x27C0 <= codePoint && codePoint <= 0x2BFF)
274 eRet = latin;
275 else if (0x3099 <= codePoint && codePoint <= 0x309A)
276 eRet = ea;
277 else if (0xD835 == codePoint)
278 eRet = latin;
279 else if (0xF000 <= codePoint && codePoint <= 0xF0FF)
280 eRet = sym;
281 else if (0xFB00 <= codePoint && codePoint <= 0xFB17)
282 eRet = latin;
283 else if (0xFB1D <= codePoint && codePoint <= 0xFB4F)
284 eRet = cs;
285 else if (0xFE50 <= codePoint && codePoint <= 0xFE6F)
286 eRet = latin;
287 return eRet;
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 );
307 return color;
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;
406 else
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;
419 return 0;
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 )
433 OUString sRet;
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);
445 return sRet;
452 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */