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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include <ConversionHelper.hxx>
20 #include <com/sun/star/table/BorderLine2.hpp>
21 #include <com/sun/star/table/BorderLineStyle.hpp>
22 #include <com/sun/star/lang/Locale.hpp>
23 #include <com/sun/star/text/HoriOrientation.hpp>
24 #include <com/sun/star/style/NumberingType.hpp>
25 #include <editeng/borderline.hxx>
26 #include <ooxml/resourceids.hxx>
27 #include <rtl/ustrbuf.hxx>
28 #include <tools/color.hxx>
32 using namespace com::sun::star
;
33 using namespace com::sun::star::table::BorderLineStyle
;
35 namespace writerfilter
{
37 namespace ConversionHelper
{
39 const sal_Int16 API_LINE_SOLID
= 0;
40 const sal_Int16 API_LINE_DOTTED
= 1;
41 const sal_Int16 API_LINE_DASHED
= 2;
43 #define TWIP_TO_MM100(TWIP) ((TWIP) >= 0 ? (((TWIP)*127L+36L)/72L) : (((TWIP)*127L-36L)/72L))
45 sal_Int32
MakeBorderLine( sal_Int32 nSprmValue
, table::BorderLine2
& rToFill
)
47 //TODO: Lines are always solid
49 //borders are defined as:
52 // || || || ---- Line width in 1/8 pt
54 // || || ------- Line type: 0 - none 1 - single ... 25 - engrave 3D and 64 - 230 page borders
56 // || ---------- Line color
58 // ------------- seven bits line space
59 // -------------- first bit: with shading
60 sal_Int16 nLineThicknessTwip
= (sal_Int16
)((nSprmValue
& 0xff) * 20)/8L ;
61 sal_Int32 nLineType
= ((nSprmValue
& 0xff00) >> 8);
62 sal_Int32 nLineColor
= (nSprmValue
& 0xff0000)>>16;
63 sal_Int32 nLineDistance
= (((nSprmValue
& 0x3f000000)>>24) * 2540 + 36)/72L;
64 MakeBorderLine( nLineThicknessTwip
, nLineType
, nLineColor
, rToFill
, false);
67 void MakeBorderLine( sal_Int32 nLineThickness
, sal_Int32 nLineType
,
69 table::BorderLine2
& rToFill
, bool bIsOOXML
)
71 static const sal_Int32 aBorderDefColor
[] =
73 // The first item means automatic color (COL_AUTO), but we
74 // do not use it anyway (see the next statement) .-)
75 0, COL_BLACK
, COL_LIGHTBLUE
, COL_LIGHTCYAN
, COL_LIGHTGREEN
,
76 COL_LIGHTMAGENTA
, COL_LIGHTRED
, COL_YELLOW
, COL_WHITE
, COL_BLUE
,
77 COL_CYAN
, COL_GREEN
, COL_MAGENTA
, COL_RED
, COL_BROWN
, COL_GRAY
,
80 //no auto color for borders
83 if(!bIsOOXML
&& sal::static_int_cast
<sal_uInt32
>(nLineColor
) < SAL_N_ELEMENTS(aBorderDefColor
))
84 nLineColor
= aBorderDefColor
[nLineColor
];
86 // Map to our border types, we should use of one equal line
87 // thickness, or one of smaller thickness. If too small we
88 // can make the defecit up in additional white space or
90 ::editeng::SvxBorderStyle
const nLineStyle(
91 ::editeng::ConvertBorderStyleFromWord(nLineType
));
92 rToFill
.LineStyle
= nLineStyle
;
93 double const fConverted( (NONE
== nLineStyle
) ? 0.0 :
94 ::editeng::ConvertBorderWidthFromWord(nLineStyle
, nLineThickness
,
96 rToFill
.LineWidth
= convertTwipToMM100(fConverted
);
97 rToFill
.Color
= nLineColor
;
101 void lcl_SwapQuotesInField(OUString
&rFmt
)
103 //Swap unescaped " and ' with ' and "
104 sal_Int32 nLen
= rFmt
.getLength();
105 OUStringBuffer
aBuffer( rFmt
.getStr() );
106 const sal_Unicode
* pFmt
= rFmt
.getStr();
107 for (sal_Int32 nI
= 0; nI
< nLen
; ++nI
)
109 if ((pFmt
[nI
] == '\"') && (!nI
|| pFmt
[nI
-1] != '\\'))
111 else if ((pFmt
[nI
] == '\'') && (!nI
|| pFmt
[nI
-1] != '\\'))
114 rFmt
= aBuffer
.makeStringAndClear();
116 bool lcl_IsNotAM(OUString
& rFmt
, sal_Int32 nPos
)
119 (nPos
== rFmt
.getLength() - 1) ||
121 (rFmt
[nPos
+1] != 'M') &&
122 (rFmt
[nPos
+1] != 'm')
128 OUString
ConvertMSFormatStringToSO(
129 const OUString
& rFormat
, lang::Locale
& rLocale
, bool bHijri
)
131 OUString
sFormat(rFormat
);
132 lcl_SwapQuotesInField(sFormat
);
134 //#102782#, #102815#, #108341# & #111944# have to work at the same time :-)
135 bool bForceJapanese(false);
136 bool bForceNatNum(false);
137 sal_Int32 nLen
= sFormat
.getLength();
139 // const sal_Unicode* pFormat = sFormat.getStr();
140 OUStringBuffer
aNewFormat( sFormat
);
143 if (aNewFormat
[nI
] == '\\')
145 else if (aNewFormat
[nI
] == '\"')
148 //While not at the end and not at an unescaped end quote
149 while ((nI
< nLen
) && (!(aNewFormat
[nI
] == '\"') && (aNewFormat
[nI
-1] != '\\')))
152 else //normal unquoted section
154 sal_Unicode nChar
= aNewFormat
[nI
];
157 aNewFormat
[nI
] = 'M';
160 else if (nChar
== 'o')
162 aNewFormat
[nI
] = 'm';
165 else if ((nChar
== 'A') && lcl_IsNotAM(sFormat
, nI
))
167 aNewFormat
[nI
] = 'D';
170 else if ((nChar
== 'g') || (nChar
== 'G'))
171 bForceJapanese
= true;
172 else if ((nChar
== 'a') && lcl_IsNotAM(sFormat
, nI
))
173 bForceJapanese
= true;
174 else if (nChar
== 'E')
176 if ((nI
!= nLen
-1) && (aNewFormat
[nI
+1] == 'E'))
178 //todo: this cannot be the right way to replace a part of the string!
179 aNewFormat
[nI
] = 'Y';
180 aNewFormat
[nI
+ 1] = 'Y';
181 aNewFormat
.insert(nI
+ 2, "YY");
185 bForceJapanese
= true;
187 else if (nChar
== 'e')
189 if ((nI
!= nLen
-1) && (aNewFormat
[nI
+1] == 'e'))
191 //todo: this cannot be the right way to replace a part of the string!
192 aNewFormat
[nI
] = 'y';
193 aNewFormat
[nI
+ 1] = 'y';
194 aNewFormat
.insert(nI
+ 2, "yy");
198 bForceJapanese
= true;
200 else if (nChar
== '/')
202 // MM We have to escape '/' in case it's used as a char
203 //todo: this cannot be the right way to replace a part of the string!
204 aNewFormat
[nI
] = '\\';
205 aNewFormat
.insert(nI
+ 1, "/");
214 bForceJapanese
= true;
218 rLocale
.Language
= "ja";
219 rLocale
.Country
= "JP";
224 aNewFormat
.insert( 0, "[NatNum1][$-411]");
229 aNewFormat
.insert( 0, "[~hijri]");
231 return aNewFormat
.makeStringAndClear();
236 sal_Int32
convertTwipToMM100(sal_Int32 _t
)
238 return TWIP_TO_MM100( _t
);
242 sal_Int32
convertEMUToMM100(sal_Int32 _t
)
247 /*-------------------------------------------------------------------------
248 contains a color from 0xTTRRGGBB to 0xTTRRGGBB
249 -----------------------------------------------------------------------*/
250 sal_Int32
ConvertColor(sal_Int32 nWordColor
)
253 r(static_cast<sal_uInt8
>(nWordColor
&0xFF)),
254 g(static_cast<sal_uInt8
>(((nWordColor
)>>8)&0xFF)),
255 b(static_cast<sal_uInt8
>((nWordColor
>>16)&0xFF)),
256 t(static_cast<sal_uInt8
>((nWordColor
>>24)&0xFF));
257 sal_Int32 nRet
= (t
<<24) + (r
<<16) + (g
<<8) + b
;
262 sal_Int16
convertTableJustification( sal_Int32 nIntValue
)
264 sal_Int16 nOrient
= text::HoriOrientation::LEFT_AND_WIDTH
;
267 case 1 : nOrient
= text::HoriOrientation::CENTER
; break;
268 case 2 : nOrient
= text::HoriOrientation::RIGHT
; break;
277 sal_Int16
ConvertNumberingType(sal_Int32 nNFC
)
282 case NS_ooxml::LN_Value_ST_NumberFormat_decimal
:
284 nRet
= style::NumberingType::ARABIC
;
286 case NS_ooxml::LN_Value_ST_NumberFormat_upperRoman
:
288 nRet
= style::NumberingType::ROMAN_UPPER
;
290 case NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman
:
292 nRet
= style::NumberingType::ROMAN_LOWER
;
295 nRet
= style::NumberingType::CHARS_UPPER_LETTER_N
;
298 nRet
= style::NumberingType::CHARS_LOWER_LETTER_N
;
301 nRet
= style::NumberingType::ARABIC
;
303 case NS_ooxml::LN_Value_ST_NumberFormat_bullet
:
306 nRet
= style::NumberingType::CHAR_SPECIAL
;
308 case NS_ooxml::LN_Value_ST_NumberFormat_none
:
310 nRet
= style::NumberingType::NUMBER_NONE
;
312 case NS_ooxml::LN_Value_ST_NumberFormat_upperLetter
:
313 nRet
= style::NumberingType::CHARS_UPPER_LETTER
;
315 case NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter
:
316 nRet
= style::NumberingType::CHARS_LOWER_LETTER
;
318 case NS_ooxml::LN_Value_ST_NumberFormat_iroha
:
319 nRet
= style::NumberingType::IROHA_HALFWIDTH_JA
;
321 case NS_ooxml::LN_Value_ST_NumberFormat_irohaFullWidth
:
322 nRet
= style::NumberingType::IROHA_FULLWIDTH_JA
;
324 case NS_ooxml::LN_Value_ST_NumberFormat_aiueo
:
325 nRet
= style::NumberingType::AIU_HALFWIDTH_JA
;
327 case NS_ooxml::LN_Value_ST_NumberFormat_aiueoFullWidth
:
328 nRet
= style::NumberingType::AIU_FULLWIDTH_JA
;
330 case NS_ooxml::LN_Value_ST_NumberFormat_hebrew2
:
331 nRet
= style::NumberingType::CHARS_HEBREW
;
333 case NS_ooxml::LN_Value_ST_NumberFormat_thaiLetters
:
334 nRet
= style::NumberingType::CHARS_THAI
;
336 case NS_ooxml::LN_Value_ST_NumberFormat_russianLower
:
337 nRet
= style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_RU
;
339 case NS_ooxml::LN_Value_ST_NumberFormat_russianUpper
:
340 nRet
= style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_RU
;
342 case NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedCircleChinese
:
343 case NS_ooxml::LN_Value_ST_NumberFormat_ideographEnclosedCircle
:
344 nRet
= style::NumberingType::CIRCLE_NUMBER
;
346 case NS_ooxml::LN_Value_ST_NumberFormat_ideographTraditional
:
347 nRet
= style::NumberingType::TIAN_GAN_ZH
;
349 case NS_ooxml::LN_Value_ST_NumberFormat_ideographZodiac
:
350 nRet
= style::NumberingType::DI_ZI_ZH
;
352 case NS_ooxml::LN_Value_ST_NumberFormat_ganada
:
353 nRet
= style::NumberingType::HANGUL_SYLLABLE_KO
;
355 case NS_ooxml::LN_Value_ST_NumberFormat_chosung
:
356 nRet
= style::NumberingType::HANGUL_JAMO_KO
;
358 case NS_ooxml::LN_Value_ST_NumberFormat_koreanDigital
:
359 case NS_ooxml::LN_Value_ST_NumberFormat_koreanCounting
:
360 case NS_ooxml::LN_Value_ST_NumberFormat_koreanDigital2
:
361 nRet
= style::NumberingType::NUMBER_HANGUL_KO
;
363 case NS_ooxml::LN_Value_ST_NumberFormat_ideographLegalTraditional
:
364 nRet
= style::NumberingType::NUMBER_UPPER_ZH_TW
;
366 case NS_ooxml::LN_Value_ST_NumberFormat_arabicAlpha
:
367 nRet
= style::NumberingType::CHARS_ARABIC
;
369 case NS_ooxml::LN_Value_ST_NumberFormat_hindiVowels
:
370 nRet
= style::NumberingType::CHARS_NEPALI
;
372 case NS_ooxml::LN_Value_ST_NumberFormat_japaneseLegal
:
373 nRet
= style::NumberingType::NUMBER_TRADITIONAL_JA
;
375 case NS_ooxml::LN_Value_ST_NumberFormat_chineseCounting
:
376 case NS_ooxml::LN_Value_ST_NumberFormat_japaneseCounting
:
377 case NS_ooxml::LN_Value_ST_NumberFormat_taiwaneseCounting
:
378 case NS_ooxml::LN_Value_ST_NumberFormat_ideographDigital
:
379 case NS_ooxml::LN_Value_ST_NumberFormat_chineseCountingThousand
:
380 nRet
= style::NumberingType::NUMBER_LOWER_ZH
;
382 case NS_ooxml::LN_Value_ST_NumberFormat_chineseLegalSimplified
:
383 nRet
= style::NumberingType::NUMBER_UPPER_ZH
;
385 default: nRet
= style::NumberingType::ARABIC
;
387 /* TODO: Lots of additional values are available - some are supported in the I18 framework
388 NS_ooxml::LN_Value_ST_NumberFormat_ordinal = 91682;
389 NS_ooxml::LN_Value_ST_NumberFormat_cardinalText = 91683;
390 NS_ooxml::LN_Value_ST_NumberFormat_ordinalText = 91684;
391 NS_ooxml::LN_Value_ST_NumberFormat_hex = 91685;
392 NS_ooxml::LN_Value_ST_NumberFormat_chicago = 91686;
393 NS_ooxml::LN_Value_ST_NumberFormat_decimalFullWidth = 91691;
394 NS_ooxml::LN_Value_ST_NumberFormat_decimalHalfWidth = 91692;
395 NS_ooxml::LN_Value_ST_NumberFormat_japaneseDigitalTenThousand = 91694;
396 NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedCircle = 91695;
397 NS_ooxml::LN_Value_ST_NumberFormat_decimalFullWidth2 = 91696;
398 NS_ooxml::LN_Value_ST_NumberFormat_decimalZero = 91699;
399 NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedFullstop = 91703;
400 NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedParen = 91704;
401 NS_ooxml::LN_Value_ST_NumberFormat_ideographZodiacTraditional = 91709;
402 NS_ooxml::LN_Value_ST_NumberFormat_taiwaneseCountingThousand = 91712;
403 NS_ooxml::LN_Value_ST_NumberFormat_taiwaneseDigital = 91713;
404 NS_ooxml::LN_Value_ST_NumberFormat_chineseLegalSimplified = 91715;
405 NS_ooxml::LN_Value_ST_NumberFormat_chineseCountingThousand = 91716;
406 NS_ooxml::LN_Value_ST_NumberFormat_koreanLegal = 91719;
407 NS_ooxml::LN_Value_ST_NumberFormat_vietnameseCounting = 91721;
408 NS_ooxml::LN_Value_ST_NumberFormat_numberInDash = 91725;
409 NS_ooxml::LN_Value_ST_NumberFormat_arabicAbjad:
410 NS_ooxml::LN_Value_ST_NumberFormat_hebrew1 = 91726;
411 NS_ooxml::LN_Value_ST_NumberFormat_hindiConsonants = 91731;
412 NS_ooxml::LN_Value_ST_NumberFormat_hindiNumbers = 91732;
413 NS_ooxml::LN_Value_ST_NumberFormat_hindiCounting = 91733;
414 NS_ooxml::LN_Value_ST_NumberFormat_thaiNumbers = 91735;
415 NS_ooxml::LN_Value_ST_NumberFormat_thaiCounting = 91736;*/
420 } // namespace ConversionHelper
421 } //namespace dmapper
422 } //namespace writerfilter
424 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */