Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <msfilter.hxx>
30 : : #include "writerwordglue.hxx"
31 : : #include <doc.hxx>
32 : : #include "writerhelper.hxx"
33 : :
34 : : #include <algorithm> //std::find_if
35 : : #include <functional> //std::unary_function
36 : :
37 : : #include <unicode/ubidi.h> //ubidi_getLogicalRun
38 : : #include <tools/tenccvt.hxx> //GetExtendedTextEncoding
39 : : #include <com/sun/star/i18n/ScriptType.hpp> //ScriptType
40 : :
41 : : #include <unotools/fontcvt.hxx> //GetSubsFontName
42 : : #include <editeng/paperinf.hxx> //lA0Width...
43 : : #include <editeng/lrspitem.hxx> //SvxLRSpaceItem
44 : : #include <editeng/ulspitem.hxx> //SvxULSpaceItem
45 : : #include <editeng/boxitem.hxx> //SvxBoxItem
46 : : #include <editeng/fontitem.hxx> //SvxFontItem
47 : : #include <frmfmt.hxx> //SwFrmFmt
48 : : #include <fmtclds.hxx> //SwFmtCol
49 : : #include <hfspacingitem.hxx> //SwHeaderAndFooterEatSpacingItem
50 : : #include <fmtfsize.hxx> //SwFmtFrmSize
51 : : #include <swrect.hxx> //SwRect
52 : : #include <fmthdft.hxx> //SwFmtHeader/SwFmtFooter
53 : : #include <frmatr.hxx> //GetLRSpace...
54 : : #include <ndtxt.hxx> //SwTxtNode
55 : : #include <breakit.hxx> //pBreakIt
56 : : #include <i18npool/mslangid.hxx>
57 : :
58 : : #define ASSIGN_CONST_ASC(s) AssignAscii(RTL_CONSTASCII_STRINGPARAM(s))
59 : :
60 : : namespace myImplHelpers
61 : : {
62 : 6 : SwTwips CalcHdFtDist(const SwFrmFmt& rFmt, sal_uInt16 nSpacing)
63 : : {
64 : : /*
65 : : The normal case for reexporting word docs is to have dynamic spacing,
66 : : as this is word's only setting, and the reason for the existance of the
67 : : dynamic spacing features. If we have dynamic spacing active then we can
68 : : add its spacing to the value height of the h/f and get the wanted total
69 : : size for word.
70 : :
71 : : Otherwise we have to get the real layout rendered
72 : : height, which is totally nonoptimum, but the best we can do.
73 : : */
74 : 6 : long nDist=0;
75 : 6 : const SwFmtFrmSize& rSz = rFmt.GetFrmSize();
76 : :
77 : : const SwHeaderAndFooterEatSpacingItem &rSpacingCtrl =
78 : : sw::util::ItemGet<SwHeaderAndFooterEatSpacingItem>
79 : 6 : (rFmt, RES_HEADER_FOOTER_EAT_SPACING);
80 [ + - ]: 6 : if (rSpacingCtrl.GetValue())
81 : 6 : nDist += rSz.GetHeight();
82 : : else
83 : : {
84 [ # # ]: 0 : SwRect aRect(rFmt.FindLayoutRect(false));
85 [ # # ]: 0 : if (aRect.Height())
86 : 0 : nDist += aRect.Height();
87 : : else
88 : : {
89 [ # # ]: 0 : const SwFmtFrmSize& rSize = rFmt.GetFrmSize();
90 [ # # ]: 0 : if (ATT_VAR_SIZE != rSize.GetHeightSizeType())
91 : 0 : nDist += rSize.GetHeight();
92 : : else
93 : : {
94 : 0 : nDist += 274; // default for 12pt text
95 : 0 : nDist += nSpacing;
96 : : }
97 : : }
98 : : }
99 : 6 : return nDist;
100 : : }
101 : :
102 : 3 : SwTwips CalcHdDist(const SwFrmFmt& rFmt)
103 : : {
104 : 3 : return CalcHdFtDist(rFmt, rFmt.GetULSpace().GetUpper());
105 : : }
106 : :
107 : 3 : SwTwips CalcFtDist(const SwFrmFmt& rFmt)
108 : : {
109 : 3 : return CalcHdFtDist(rFmt, rFmt.GetULSpace().GetLower());
110 : : }
111 : :
112 : : /*
113 : : SwTxtFmtColl and SwCharFmt are quite distinct types and how they are
114 : : gotten is also distinct, but the algorithm to match word's eqivalents into
115 : : them is the same, so we put the different stuff into two seperate helper
116 : : implementations and a core template that uses the helpers that uses the
117 : : same algorithm to do the work. We'll make the helpers specializations of a
118 : : non existing template so I can let the compiler figure out the right one
119 : : to use from a simple argument to the algorithm class
120 : : */
121 : : template <class C> class MapperImpl;
122 : : template<> class MapperImpl<SwTxtFmtColl>
123 : : {
124 : : private:
125 : : SwDoc &mrDoc;
126 : : public:
127 : 108 : MapperImpl(SwDoc &rDoc) : mrDoc(rDoc) {}
128 : : SwTxtFmtColl* GetBuiltInStyle(ww::sti eSti);
129 : : SwTxtFmtColl* GetStyle(const String &rName);
130 : : SwTxtFmtColl* MakeStyle(const String &rName);
131 : : };
132 : :
133 : 744 : SwTxtFmtColl* MapperImpl<SwTxtFmtColl>::GetBuiltInStyle(ww::sti eSti)
134 : : {
135 : 744 : const RES_POOL_COLLFMT_TYPE RES_NONE = RES_POOLCOLL_DOC_END;
136 : : static const RES_POOL_COLLFMT_TYPE aArr[]=
137 : : {
138 : : RES_POOLCOLL_STANDARD, RES_POOLCOLL_HEADLINE1,
139 : : RES_POOLCOLL_HEADLINE2, RES_POOLCOLL_HEADLINE3,
140 : : RES_POOLCOLL_HEADLINE4, RES_POOLCOLL_HEADLINE5,
141 : : RES_POOLCOLL_HEADLINE6, RES_POOLCOLL_HEADLINE7,
142 : : RES_POOLCOLL_HEADLINE8, RES_POOLCOLL_HEADLINE9,
143 : : RES_POOLCOLL_TOX_IDX1, RES_POOLCOLL_TOX_IDX2,
144 : : RES_POOLCOLL_TOX_IDX3, RES_NONE, RES_NONE, RES_NONE, RES_NONE,
145 : : RES_NONE, RES_NONE, RES_POOLCOLL_TOX_CNTNT1,
146 : : RES_POOLCOLL_TOX_CNTNT2, RES_POOLCOLL_TOX_CNTNT3,
147 : : RES_POOLCOLL_TOX_CNTNT4, RES_POOLCOLL_TOX_CNTNT5,
148 : : RES_POOLCOLL_TOX_CNTNT6, RES_POOLCOLL_TOX_CNTNT7,
149 : : RES_POOLCOLL_TOX_CNTNT8, RES_POOLCOLL_TOX_CNTNT9, RES_NONE,
150 : : RES_POOLCOLL_FOOTNOTE, RES_NONE, RES_POOLCOLL_HEADER,
151 : : RES_POOLCOLL_FOOTER, RES_POOLCOLL_TOX_IDXH, RES_NONE, RES_NONE,
152 : : RES_POOLCOLL_JAKETADRESS, RES_POOLCOLL_SENDADRESS, RES_NONE,
153 : : RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_POOLCOLL_ENDNOTE,
154 : : RES_NONE, RES_NONE, RES_NONE, RES_POOLCOLL_LISTS_BEGIN,
155 : : RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE,
156 : : RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE,
157 : : RES_NONE, RES_NONE, RES_POOLCOLL_HEADLINE_BASE, RES_NONE,
158 : : RES_POOLCOLL_SIGNATURE, RES_NONE, RES_POOLCOLL_TEXT,
159 : : RES_POOLCOLL_TEXT_MOVE, RES_NONE, RES_NONE, RES_NONE, RES_NONE,
160 : : RES_NONE, RES_NONE, RES_POOLCOLL_DOC_SUBTITEL
161 : : };
162 : :
163 : : OSL_ENSURE(SAL_N_ELEMENTS(aArr) == 75, "Style Array has false size");
164 : :
165 : 744 : SwTxtFmtColl* pRet = 0;
166 : : //If this is a built-in word style that has a built-in writer
167 : : //equivalent, then map it to one of our built in styles regardless
168 : : //of its name
169 [ + + ][ + + ]: 744 : if (sal::static_int_cast< size_t >(eSti) < SAL_N_ELEMENTS(aArr) && aArr[eSti] != RES_NONE)
[ + + ]
170 : 483 : pRet = mrDoc.GetTxtCollFromPool( static_cast< sal_uInt16 >(aArr[eSti]), false);
171 : 744 : return pRet;
172 : : }
173 : :
174 : 447 : SwTxtFmtColl* MapperImpl<SwTxtFmtColl>::GetStyle(const String &rName)
175 : : {
176 [ + - ]: 447 : return sw::util::GetParaStyle(mrDoc, rName);
177 : : }
178 : :
179 : 183 : SwTxtFmtColl* MapperImpl<SwTxtFmtColl>::MakeStyle(const String &rName)
180 : : {
181 : : return mrDoc.MakeTxtFmtColl(rName,
182 : 183 : const_cast<SwTxtFmtColl *>(mrDoc.GetDfltTxtFmtColl()));
183 : : }
184 : :
185 : : template<> class MapperImpl<SwCharFmt>
186 : : {
187 : : private:
188 : : SwDoc &mrDoc;
189 : : public:
190 : 108 : MapperImpl(SwDoc &rDoc) : mrDoc(rDoc) {}
191 : : SwCharFmt* GetBuiltInStyle(ww::sti eSti);
192 : : SwCharFmt* GetStyle(const String &rName);
193 : : SwCharFmt* MakeStyle(const String &rName);
194 : : };
195 : :
196 : 252 : SwCharFmt* MapperImpl<SwCharFmt>::GetBuiltInStyle(ww::sti eSti)
197 : : {
198 : 252 : RES_POOL_CHRFMT_TYPE eLookup = RES_POOLCHR_NORMAL_END;
199 [ + - + + : 252 : switch (eSti)
+ + + +
+ ]
200 : : {
201 : : case ww::stiFtnRef:
202 : 3 : eLookup = RES_POOLCHR_FOOTNOTE;
203 : 3 : break;
204 : : case ww::stiLnn:
205 : 0 : eLookup = RES_POOLCHR_LINENUM;
206 : 0 : break;
207 : : case ww::stiPgn:
208 : 24 : eLookup = RES_POOLCHR_PAGENO;
209 : 24 : break;
210 : : case ww::stiEdnRef:
211 : 3 : eLookup = RES_POOLCHR_ENDNOTE;
212 : 3 : break;
213 : : case ww::stiHyperlink:
214 : 24 : eLookup = RES_POOLCHR_INET_NORMAL;
215 : 24 : break;
216 : : case ww::stiHyperlinkFollowed:
217 : 3 : eLookup = RES_POOLCHR_INET_VISIT;
218 : 3 : break;
219 : : case ww::stiStrong:
220 : 3 : eLookup = RES_POOLCHR_HTML_STRONG;
221 : 3 : break;
222 : : case ww::stiEmphasis:
223 : 3 : eLookup = RES_POOLCHR_HTML_EMPHASIS;
224 : 3 : break;
225 : : default:
226 : 189 : eLookup = RES_POOLCHR_NORMAL_END;
227 : 189 : break;
228 : : }
229 : 252 : SwCharFmt *pRet = 0;
230 [ + + ]: 252 : if (eLookup != RES_POOLCHR_NORMAL_END)
231 : 63 : pRet = mrDoc.GetCharFmtFromPool( static_cast< sal_uInt16 >(eLookup) );
232 : 252 : return pRet;
233 : : }
234 : :
235 : 444 : SwCharFmt* MapperImpl<SwCharFmt>::GetStyle(const String &rName)
236 : : {
237 [ + - ]: 444 : return sw::util::GetCharStyle(mrDoc, rName);
238 : : }
239 : :
240 : 168 : SwCharFmt* MapperImpl<SwCharFmt>::MakeStyle(const String &rName)
241 : : {
242 : 168 : return mrDoc.MakeCharFmt(rName, mrDoc.GetDfltCharFmt());
243 : : }
244 : :
245 : 216 : template<class C> class StyleMapperImpl
246 : : {
247 : : private:
248 : : MapperImpl<C> maHelper;
249 : : std::set<const C*> maUsedStyles;
250 : : C* MakeNonCollidingStyle(const String& rName);
251 : : public:
252 : : typedef std::pair<C*, bool> StyleResult;
253 : 216 : StyleMapperImpl(SwDoc &rDoc) : maHelper(rDoc) {}
254 : : StyleResult GetStyle(const String& rName, ww::sti eSti);
255 : : };
256 : :
257 : : template<class C>
258 : : typename StyleMapperImpl<C>::StyleResult
259 : 996 : StyleMapperImpl<C>::GetStyle(const String& rName, ww::sti eSti)
260 : : {
261 [ + - ][ + - ]: 996 : C *pRet = maHelper.GetBuiltInStyle(eSti);
262 : :
263 : : //If we've used it once, don't reuse it
264 [ + + ][ + - ]: 996 : if (pRet && (maUsedStyles.end() != maUsedStyles.find(pRet)))
[ + + ][ + + ]
[ + + ][ + + ]
[ + + # #
# # # # ]
[ + + ][ + - ]
[ + - ][ - + ]
[ + + ][ + + ]
[ + + ][ - +
# # # # #
# ]
265 : 6 : pRet = 0;
266 : :
267 [ + + ][ + + ]: 996 : if (!pRet)
268 : : {
269 [ + - ][ + - ]: 456 : pRet = maHelper.GetStyle(rName);
270 : : //If we've used it once, don't reuse it
271 [ + + ][ + - ]: 456 : if (pRet && (maUsedStyles.end() != maUsedStyles.find(pRet)))
[ + + ][ + + ]
[ + + ][ + + ]
[ + + # #
# # # # ]
[ + + ][ + - ]
[ + - ][ + + ]
[ + + ][ + + ]
[ + + ][ + +
# # # # #
# ]
272 : 45 : pRet = 0;
273 : : }
274 : :
275 : 996 : bool bStyExist = pRet ? true : false;
276 : :
277 [ + + ][ + + ]: 996 : if (!pRet)
278 : : {
279 [ + - ][ + - ]: 351 : String aName(rName);
280 [ + - ][ + - ]: 351 : xub_StrLen nPos = aName.Search(',');
281 : : // No commas allow in SW style names
282 [ - + ][ - + ]: 351 : if (STRING_NOTFOUND != nPos)
283 [ # # ][ # # ]: 0 : aName.Erase(nPos);
284 [ + - ][ + - ]: 351 : pRet = MakeNonCollidingStyle(aName);
[ + - ][ + - ]
285 : : }
286 : :
287 [ + - ][ + - ]: 996 : if (pRet)
288 [ + - ][ + - ]: 996 : maUsedStyles.insert(pRet);
289 : :
290 [ + - ]: 996 : return StyleResult(pRet, bStyExist);
291 : : }
292 : :
293 : : template<class C>
294 : 351 : C* StyleMapperImpl<C>::MakeNonCollidingStyle(const String& rName)
295 : : {
296 [ + - ][ + - ]: 351 : String aName(rName);
297 : 351 : C* pColl = 0;
298 : :
299 [ + - ][ + + ]: 351 : if (0 != (pColl = maHelper.GetStyle(aName)))
[ + - ][ + + ]
300 : : {
301 : : //If the style collides first stick WW- in front of it, unless
302 : : //it already has it and then successively add a larger and
303 : : //larger number after it, its got to work at some stage!
304 [ + - ][ + + ]: 45 : if (!aName.EqualsIgnoreCaseAscii("WW-", 0, 3))
[ + - ][ + - ]
305 [ + - ][ + - ]: 6 : aName.InsertAscii("WW-" , 0);
306 : :
307 : 45 : sal_Int32 nI = 1;
308 [ + - ][ + + ]: 84 : while (
[ + - ][ + + ]
[ + - ][ - + ]
[ # # ][ - + ]
309 : : 0 != (pColl = maHelper.GetStyle(aName)) &&
310 : : (nI < SAL_MAX_INT32)
311 : : )
312 : : {
313 [ + - ][ + - ]: 39 : aName += String::CreateFromInt32(nI++);
[ + - ][ # # ]
[ # # ][ # # ]
314 : : }
315 : : }
316 : :
317 [ + - ][ + - ]: 351 : return pColl ? 0 : maHelper.MakeStyle(aName);
[ + - ][ + - ]
[ + - ][ + - ]
318 : : }
319 : :
320 : 2460 : String FindBestMSSubstituteFont(const String &rFont)
321 : : {
322 : 2460 : String sRet;
323 [ + - ][ + + ]: 2460 : if (sw::util::IsStarSymbol(rFont))
[ + - ]
324 [ + - ]: 9 : sRet.ASSIGN_CONST_ASC("Arial Unicode MS");
325 : : else
326 [ + - ][ + - ]: 2451 : sRet = GetSubsFontName(rFont, SUBSFONT_ONLYONE | SUBSFONT_MS);
[ + - ]
327 : 2460 : return sRet;
328 : : }
329 : :
330 : : //Utility to remove entries before a given starting position
331 : : class IfBeforeStart
332 : : : public std::unary_function<const sw::util::CharRunEntry&, bool>
333 : : {
334 : : private:
335 : : xub_StrLen mnStart;
336 : : public:
337 : 258 : IfBeforeStart(xub_StrLen nStart) : mnStart(nStart) {}
338 : 258 : bool operator()(const sw::util::CharRunEntry &rEntry) const
339 : : {
340 : 258 : return rEntry.mnEndPos < mnStart;
341 : : }
342 : : };
343 : : }
344 : :
345 : : namespace sw
346 : : {
347 : : namespace util
348 : : {
349 : :
350 : 0 : bool IsPlausableSingleWordSection(const SwFrmFmt &rTitleFmt,
351 : : const SwFrmFmt &rFollowFmt)
352 : : {
353 : 0 : bool bPlausableTitlePage = true;
354 : :
355 : 0 : const SwFmtCol& rFirstCols = rTitleFmt.GetCol();
356 : 0 : const SwFmtCol& rFollowCols = rFollowFmt.GetCol();
357 : 0 : const SwColumns& rFirstColumns = rFirstCols.GetColumns();
358 : 0 : const SwColumns& rFollowColumns = rFollowCols.GetColumns();
359 : 0 : const SvxLRSpaceItem &rOneLR = rTitleFmt.GetLRSpace();
360 : 0 : const SvxLRSpaceItem &rTwoLR= rFollowFmt.GetLRSpace();
361 : :
362 [ # # ]: 0 : if (rFirstColumns.size() != rFollowColumns.size())
363 : : {
364 : : //e.g. #i4320#
365 : 0 : bPlausableTitlePage = false;
366 : : }
367 [ # # ]: 0 : else if (rOneLR != rTwoLR)
368 : 0 : bPlausableTitlePage = false;
369 : : else
370 : : {
371 [ # # ]: 0 : HdFtDistanceGlue aOne(rTitleFmt.GetAttrSet());
372 [ # # ]: 0 : HdFtDistanceGlue aTwo(rFollowFmt.GetAttrSet());
373 : : //e.g. #i14509#
374 [ # # ]: 0 : if (!aOne.EqualTopBottom(aTwo))
375 : 0 : bPlausableTitlePage = false;
376 : : }
377 : 0 : return bPlausableTitlePage;
378 : : }
379 : :
380 : 240 : HdFtDistanceGlue::HdFtDistanceGlue(const SfxItemSet &rPage)
381 : : {
382 [ + - ]: 240 : if (const SvxBoxItem *pBox = HasItem<SvxBoxItem>(rPage, RES_BOX))
383 : : {
384 : 240 : dyaHdrTop = pBox->CalcLineSpace(BOX_LINE_TOP);
385 : 240 : dyaHdrBottom = pBox->CalcLineSpace(BOX_LINE_BOTTOM);
386 : : }
387 : : else
388 : : {
389 : 0 : dyaHdrTop = dyaHdrBottom = 0;
390 : 0 : dyaHdrBottom = 0;
391 : : }
392 : : const SvxULSpaceItem &rUL =
393 : 240 : ItemGet<SvxULSpaceItem>(rPage, RES_UL_SPACE);
394 : 240 : dyaHdrTop = dyaHdrTop + rUL.GetUpper();
395 : 240 : dyaHdrBottom = dyaHdrBottom + rUL.GetLower();
396 : :
397 : 240 : dyaTop = dyaHdrTop;
398 : 240 : dyaBottom = dyaHdrBottom;
399 : :
400 : : using sw::types::msword_cast;
401 : :
402 : 240 : const SwFmtHeader *pHd = HasItem<SwFmtHeader>(rPage, RES_HEADER);
403 [ + + ][ + - ]: 240 : if (pHd && pHd->IsActive() && pHd->GetHeaderFmt())
[ + + ][ + - ]
404 : : {
405 : 3 : mbHasHeader = true;
406 : 3 : dyaTop = dyaTop + static_cast< sal_uInt16 >( (myImplHelpers::CalcHdDist(*(pHd->GetHeaderFmt()))) );
407 : : }
408 : : else
409 : 237 : mbHasHeader = false;
410 : :
411 : 240 : const SwFmtFooter *pFt = HasItem<SwFmtFooter>(rPage, RES_FOOTER);
412 [ + + ][ + - ]: 240 : if (pFt && pFt->IsActive() && pFt->GetFooterFmt())
[ + + ][ + - ]
413 : : {
414 : 3 : mbHasFooter = true;
415 : 3 : dyaBottom = dyaBottom + static_cast< sal_uInt16 >( (myImplHelpers::CalcFtDist(*(pFt->GetFooterFmt()))) );
416 : : }
417 : : else
418 : 237 : mbHasFooter = false;
419 : 240 : }
420 : :
421 : 0 : bool HdFtDistanceGlue::EqualTopBottom(const HdFtDistanceGlue &rOther)
422 : : const
423 : : {
424 [ # # ][ # # ]: 0 : return (dyaTop == rOther.dyaTop && dyaBottom == rOther.dyaBottom);
425 : : }
426 : :
427 : 108 : ParaStyleMapper::ParaStyleMapper(SwDoc &rDoc)
428 [ + - ]: 108 : : mpImpl(new myImplHelpers::StyleMapperImpl<SwTxtFmtColl>(rDoc))
429 : : {
430 : 108 : }
431 : :
432 : 108 : ParaStyleMapper::~ParaStyleMapper()
433 : : {
434 [ + - ]: 108 : delete mpImpl;
435 : 108 : }
436 : :
437 : 744 : ParaStyleMapper::StyleResult ParaStyleMapper::GetStyle(
438 : : const String& rName, ww::sti eSti)
439 : : {
440 : 744 : return mpImpl->GetStyle(rName, eSti);
441 : : }
442 : :
443 : 108 : CharStyleMapper::CharStyleMapper(SwDoc &rDoc)
444 [ + - ]: 108 : : mpImpl(new myImplHelpers::StyleMapperImpl<SwCharFmt>(rDoc))
445 : : {
446 : 108 : }
447 : :
448 : 108 : CharStyleMapper::~CharStyleMapper()
449 : : {
450 [ + - ]: 108 : delete mpImpl;
451 : 108 : }
452 : :
453 : 252 : CharStyleMapper::StyleResult CharStyleMapper::GetStyle(
454 : : const String& rName, ww::sti eSti)
455 : : {
456 : 252 : return mpImpl->GetStyle(rName, eSti);
457 : : }
458 : :
459 [ + - ]: 2460 : FontMapExport::FontMapExport(const String &rFamilyName)
460 : : {
461 : 2460 : xub_StrLen nIndex = 0;
462 [ + - ][ + - ]: 2460 : msPrimary = GetNextFontToken(rFamilyName, nIndex);
[ + - ]
463 [ + - ][ + - ]: 2460 : msSecondary = myImplHelpers::FindBestMSSubstituteFont(msPrimary);
[ + - ]
464 [ + + ][ - + ]: 2460 : if (!msSecondary.Len() && nIndex != STRING_NOTFOUND)
[ - + ]
465 [ # # ][ # # ]: 0 : msSecondary = GetNextFontToken(rFamilyName, nIndex);
[ # # ]
466 : 2460 : }
467 : :
468 : 66504 : bool ItemSort::operator()(sal_uInt16 nA, sal_uInt16 nB) const
469 : : {
470 : : /*
471 : : #i24291#
472 : : All we want to do is ensure for now is that if a charfmt exist
473 : : in the character properties that it rises to the top and is
474 : : exported first. In the future we might find more ordering
475 : : depandancies for export, in which case this is the place to do
476 : : it
477 : : */
478 [ - + ]: 66504 : if (nA == nB)
479 : 0 : return false;
480 [ + + ]: 66504 : if (nA == RES_TXTATR_CHARFMT)
481 : 231 : return true;
482 [ + + ]: 66273 : if (nB == RES_TXTATR_CHARFMT)
483 : 234 : return false;
484 : 66504 : return nA < nB;
485 : : }
486 : :
487 : 300 : CharRuns GetPseudoCharRuns(const SwTxtNode& rTxtNd,
488 : : xub_StrLen nTxtStart, bool bSplitOnCharSet)
489 : : {
490 : 300 : const String &rTxt = rTxtNd.GetTxt();
491 : :
492 : 300 : bool bParaIsRTL = false;
493 : : OSL_ENSURE(rTxtNd.GetDoc(), "No document for node?, suspicious");
494 [ + - ]: 300 : if (rTxtNd.GetDoc())
495 : : {
496 [ - + ]: 300 : if (FRMDIR_HORI_RIGHT_TOP ==
497 [ + - ][ + - ]: 300 : rTxtNd.GetDoc()->GetTextDirection(SwPosition(rTxtNd)))
[ + - ]
498 : : {
499 : 0 : bParaIsRTL = true;
500 : : }
501 : : }
502 : :
503 : : using namespace ::com::sun::star::i18n;
504 : :
505 : 300 : sal_uInt16 nScript = i18n::ScriptType::LATIN;
506 [ + + ][ + - ]: 300 : if (rTxt.Len() && pBreakIt && pBreakIt->GetBreakIter().is())
[ + - ][ + - ]
[ + + ]
[ + + # # ]
507 [ + - ][ + - ]: 258 : nScript = pBreakIt->GetBreakIter()->getScriptType(rTxt, 0);
[ + - ][ + - ]
508 : :
509 : : rtl_TextEncoding eChrSet = ItemGet<SvxFontItem>(rTxtNd,
510 [ + - ][ + - ]: 300 : GetWhichOfScript(RES_CHRATR_FONT, nScript)).GetCharSet();
511 [ + - ]: 300 : eChrSet = GetExtendedTextEncoding(eChrSet);
512 : :
513 [ + - ]: 300 : CharRuns aRunChanges;
514 : :
515 [ + + ]: 300 : if (!rTxt.Len())
516 : : {
517 : : aRunChanges.push_back(CharRunEntry(0, nScript, eChrSet,
518 [ + - ]: 42 : bParaIsRTL));
519 : : return aRunChanges;
520 : : }
521 : :
522 : : typedef std::pair<int32_t, bool> DirEntry;
523 : : typedef std::vector<DirEntry> DirChanges;
524 : : typedef DirChanges::const_iterator cDirIter;
525 : :
526 : : typedef std::pair<xub_StrLen, sal_Int16> CharSetEntry;
527 : : typedef std::vector<CharSetEntry> CharSetChanges;
528 : : typedef CharSetChanges::const_iterator cCharSetIter;
529 : :
530 : : typedef std::pair<xub_StrLen, sal_uInt16> ScriptEntry;
531 : : typedef std::vector<ScriptEntry> ScriptChanges;
532 : : typedef ScriptChanges::const_iterator cScriptIter;
533 : :
534 [ + - ]: 258 : DirChanges aDirChanges;
535 [ + - ]: 258 : CharSetChanges aCharSets;
536 [ + - ]: 258 : ScriptChanges aScripts;
537 : :
538 [ - + ]: 258 : UBiDiDirection eDefaultDir = bParaIsRTL ? UBIDI_RTL : UBIDI_LTR;
539 : 258 : UErrorCode nError = U_ZERO_ERROR;
540 [ + - ]: 258 : UBiDi* pBidi = ubidi_openSized(rTxt.Len(), 0, &nError);
541 : 258 : ubidi_setPara(pBidi, reinterpret_cast<const UChar *>(rTxt.GetBuffer()), rTxt.Len(),
542 [ + - ]: 258 : static_cast< UBiDiLevel >(eDefaultDir), 0, &nError);
543 : :
544 [ + - ]: 258 : sal_Int32 nCount = ubidi_countRuns(pBidi, &nError);
545 [ + - ]: 258 : aDirChanges.reserve(nCount);
546 : :
547 : 258 : int32_t nStart = 0;
548 : : int32_t nEnd;
549 : : UBiDiLevel nCurrDir;
550 : :
551 [ + + ]: 516 : for (sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx)
552 : : {
553 [ + - ]: 258 : ubidi_getLogicalRun(pBidi, nStart, &nEnd, &nCurrDir);
554 : : /*
555 : : UBiDiLevel is the type of the level values in this BiDi
556 : : implementation.
557 : :
558 : : It holds an embedding level and indicates the visual direction
559 : : by its bit 0 (even/odd value).
560 : :
561 : : The value for UBIDI_DEFAULT_LTR is even and the one for
562 : : UBIDI_DEFAULT_RTL is odd
563 : : */
564 [ + - ][ + - ]: 258 : aDirChanges.push_back(DirEntry(nEnd, nCurrDir & 0x1));
565 : 258 : nStart = nEnd;
566 : : }
567 [ + - ]: 258 : ubidi_close(pBidi);
568 : :
569 [ - + ]: 258 : if (bSplitOnCharSet)
570 : : {
571 : : //Split unicode text into plausable 8bit ranges for export to
572 : : //older non unicode aware format
573 : 0 : xub_StrLen nLen = rTxt.Len();
574 : 0 : xub_StrLen nPos = 0;
575 [ # # ]: 0 : while (nPos != nLen)
576 : : {
577 : : rtl_TextEncoding ScriptType =
578 [ # # ]: 0 : getBestMSEncodingByChar(rTxt.GetChar(nPos++));
579 [ # # ][ # # ]: 0 : while (
[ # # ]
580 : : (nPos != nLen) &&
581 [ # # ]: 0 : (ScriptType == getBestMSEncodingByChar(rTxt.GetChar(nPos)))
582 : : )
583 : : {
584 : 0 : ++nPos;
585 : : }
586 : :
587 [ # # ][ # # ]: 0 : aCharSets.push_back(CharSetEntry(nPos, ScriptType));
588 : : }
589 : : }
590 : :
591 : : using sw::types::writer_cast;
592 : :
593 [ + - ][ + - ]: 258 : if (pBreakIt && pBreakIt->GetBreakIter().is())
[ + - ][ + - ]
[ + - # # ]
594 : : {
595 : 258 : xub_StrLen nLen = rTxt.Len();
596 : 258 : xub_StrLen nPos = 0;
597 [ + + ]: 516 : while (nPos < nLen)
598 : : {
599 [ + - ][ + - ]: 516 : sal_Int32 nEnd2 = pBreakIt->GetBreakIter()->endOfScript(rTxt, nPos,
600 [ + - ][ + - ]: 258 : nScript);
601 [ - + ]: 258 : if (nEnd2 < 0)
602 : 0 : break;
603 : 258 : nPos = static_cast< xub_StrLen >(nEnd2);
604 [ + - ][ + - ]: 258 : aScripts.push_back(ScriptEntry(nPos, nScript));
605 [ + - ][ + - ]: 258 : nScript = pBreakIt->GetBreakIter()->getScriptType(rTxt, nPos);
[ + - ][ + - ]
606 : : }
607 : : }
608 : :
609 [ + - ]: 258 : cDirIter aBiDiEnd = aDirChanges.end();
610 [ + - ]: 258 : cCharSetIter aCharSetEnd = aCharSets.end();
611 [ + - ]: 258 : cScriptIter aScriptEnd = aScripts.end();
612 : :
613 [ + - ]: 258 : cDirIter aBiDiIter = aDirChanges.begin();
614 [ + - ]: 258 : cCharSetIter aCharSetIter = aCharSets.begin();
615 [ + - ]: 258 : cScriptIter aScriptIter = aScripts.begin();
616 : :
617 : 258 : bool bCharIsRTL = bParaIsRTL;
618 : :
619 [ + + ][ + - ]: 1290 : while (
[ - + ][ + + ]
620 [ + - ]: 516 : aBiDiIter != aBiDiEnd ||
621 [ + - ]: 258 : aCharSetIter != aCharSetEnd ||
622 [ + - ]: 258 : aScriptIter != aScriptEnd
623 : : )
624 : : {
625 : 258 : xub_StrLen nMinPos = rTxt.Len();
626 : :
627 [ + - ][ + - ]: 258 : if (aBiDiIter != aBiDiEnd)
628 : : {
629 [ + - ][ - + ]: 258 : if (aBiDiIter->first < nMinPos)
630 [ # # ]: 0 : nMinPos = static_cast< xub_StrLen >(aBiDiIter->first);
631 [ + - ]: 258 : bCharIsRTL = aBiDiIter->second;
632 : : }
633 : :
634 [ + - ][ - + ]: 258 : if (aCharSetIter != aCharSetEnd)
635 : : {
636 [ # # ][ # # ]: 0 : if (aCharSetIter->first < nMinPos)
637 [ # # ]: 0 : nMinPos = aCharSetIter->first;
638 [ # # ]: 0 : eChrSet = aCharSetIter->second;
639 : : }
640 : :
641 [ + - ][ + - ]: 258 : if (aScriptIter != aScriptEnd)
642 : : {
643 [ + - ][ - + ]: 258 : if (aScriptIter->first < nMinPos)
644 [ # # ]: 0 : nMinPos = aScriptIter->first;
645 [ + - ]: 258 : nScript = aScriptIter->second;
646 : : }
647 : :
648 : : aRunChanges.push_back(
649 [ + - ]: 258 : CharRunEntry(nMinPos, nScript, eChrSet, bCharIsRTL));
650 : :
651 [ + - ][ + - ]: 258 : if (aBiDiIter != aBiDiEnd)
652 : : {
653 [ + - ][ + - ]: 258 : if (aBiDiIter->first == nMinPos)
654 [ + - ]: 258 : ++aBiDiIter;
655 : : }
656 : :
657 [ + - ][ - + ]: 258 : if (aCharSetIter != aCharSetEnd)
658 : : {
659 [ # # ][ # # ]: 0 : if (aCharSetIter->first == nMinPos)
660 [ # # ]: 0 : ++aCharSetIter;
661 : : }
662 : :
663 [ + - ][ + - ]: 258 : if (aScriptIter != aScriptEnd)
664 : : {
665 [ + - ][ + - ]: 258 : if (aScriptIter->first == nMinPos)
666 [ + - ]: 258 : ++aScriptIter;
667 : : }
668 : : }
669 : :
670 : : aRunChanges.erase(std::remove_if(aRunChanges.begin(),
671 [ + - ][ + - ]: 258 : aRunChanges.end(), myImplHelpers::IfBeforeStart(nTxtStart)), aRunChanges.end());
672 : :
673 : 300 : return aRunChanges;
674 : : }
675 : : }
676 : :
677 : : namespace ms
678 : : {
679 : 2823 : sal_uInt8 rtl_TextEncodingToWinCharset(rtl_TextEncoding eTextEncoding)
680 : : {
681 : : sal_uInt8 nRet =
682 : 2823 : rtl_getBestWindowsCharsetFromTextEncoding(eTextEncoding);
683 [ + + ]: 2823 : switch (eTextEncoding)
684 : : {
685 : : case RTL_TEXTENCODING_DONTKNOW:
686 : : case RTL_TEXTENCODING_UCS2:
687 : : case RTL_TEXTENCODING_UTF7:
688 : : case RTL_TEXTENCODING_UTF8:
689 : : case RTL_TEXTENCODING_JAVA_UTF8:
690 : : OSL_ENSURE(nRet != 0x80, "This method may be redundant");
691 : 2133 : nRet = 0x80;
692 : 2133 : break;
693 : : default:
694 : 690 : break;
695 : : }
696 : 2823 : return nRet;
697 : : }
698 : :
699 : 30 : long DateTime2DTTM( const DateTime& rDT )
700 : : {
701 : : /*
702 : : mint short :6 0000003F minutes (0-59)
703 : : hr short :5 000007C0 hours (0-23)
704 : : dom short :5 0000F800 days of month (1-31)
705 : : mon short :4 000F0000 months (1-12)
706 : : yr short :9 1FF00000 years (1900-2411)-1900
707 : : wdy short :3 E0000000 weekday(Sunday=0
708 : : Monday=1
709 : : ( wdy can be ignored ) Tuesday=2
710 : : Wednesday=3
711 : : Thursday=4
712 : : Friday=5
713 : : Saturday=6)
714 : : */
715 : :
716 [ + + ]: 30 : if ( rDT.GetDate() == 0L )
717 : 9 : return 0L;
718 : 21 : long nDT = ( rDT.GetDayOfWeek() + 1 ) % 7;
719 : 21 : nDT <<= 9;
720 : 21 : nDT += ( rDT.GetYear() - 1900 ) & 0x1ff;
721 : 21 : nDT <<= 4;
722 : 21 : nDT += rDT.GetMonth() & 0xf;
723 : 21 : nDT <<= 5;
724 : 21 : nDT += rDT.GetDay() & 0x1f;
725 : 21 : nDT <<= 5;
726 : 21 : nDT += rDT.GetHour() & 0x1f;
727 : 21 : nDT <<= 6;
728 : 21 : nDT += rDT.GetMin() & 0x3f;
729 : 30 : return nDT;
730 : : }
731 : :
732 : 0 : sal_uLong MSDateTimeFormatToSwFormat(String& rParams,
733 : : SvNumberFormatter *pFormatter, sal_uInt16 &rLang, bool bHijri,
734 : : sal_uInt16 nDocLang)
735 : : {
736 : : // tell the Formatter about the new entry
737 : 0 : sal_uInt16 nCheckPos = 0;
738 : 0 : short nType = NUMBERFORMAT_DEFINED;
739 : 0 : sal_uInt32 nKey = 0;
740 : :
741 [ # # ]: 0 : SwapQuotesInField(rParams);
742 : :
743 : : // Force to Japanese when finding one of 'geaE'
744 : 0 : rtl::OUString sJChars( "geE" );
745 [ # # ]: 0 : bool bForceJapanese = ( STRING_NOTFOUND != rParams.SearchChar( sJChars.getStr() ) );
746 [ # # ]: 0 : if ( bForceJapanese )
747 : : {
748 : : rParams.SearchAndReplaceAll( rtl::OUString( "ee" ),
749 [ # # ][ # # ]: 0 : rtl::OUString( "yyyy" ) );
[ # # ][ # # ]
[ # # ]
750 : : rParams.SearchAndReplaceAll( rtl::OUString( "EE" ),
751 [ # # ][ # # ]: 0 : rtl::OUString( "YYYY" ) );
[ # # ][ # # ]
[ # # ]
752 : : }
753 [ # # ]: 0 : if (LANGUAGE_FRENCH != nDocLang)
754 : : {
755 : : // Handle the 'a' case here
756 : 0 : xub_StrLen nLastPos = 0;
757 [ # # ]: 0 : do
758 : : {
759 [ # # ]: 0 : xub_StrLen nPos = rParams.Search( 'a', nLastPos + 1 );
760 [ # # ][ # # ]: 0 : bForceJapanese |= ( nPos != STRING_NOTFOUND && IsNotAM( rParams, nPos ) );
761 : 0 : nLastPos = nPos;
762 : : } while ( STRING_NOTFOUND != nLastPos );
763 : : }
764 : :
765 : : // Force to NatNum when finding one of 'oOA'
766 [ # # ]: 0 : String sOldParams( rParams );
767 : : rParams.SearchAndReplaceAll( rtl::OUString( "o" ),
768 [ # # ][ # # ]: 0 : rtl::OUString( "m" ) );
[ # # ][ # # ]
[ # # ]
769 : : rParams.SearchAndReplaceAll( rtl::OUString( "O" ),
770 [ # # ][ # # ]: 0 : rtl::OUString( "M" ) );
[ # # ][ # # ]
[ # # ]
771 [ # # ]: 0 : bool bForceNatNum = !sOldParams.Equals( rParams );
772 [ # # ]: 0 : if (LANGUAGE_FRENCH != nDocLang)
773 : : {
774 : : // Handle the 'A' case here
775 : 0 : xub_StrLen nLastPos = 0;
776 [ # # ]: 0 : do
777 : : {
778 [ # # ]: 0 : xub_StrLen nPos = rParams.Search( 'A', nLastPos + 1 );
779 [ # # ][ # # ]: 0 : bool bIsCharA = ( nPos != STRING_NOTFOUND && IsNotAM( rParams, nPos ) );
780 : 0 : bForceNatNum |= bIsCharA;
781 [ # # ]: 0 : if ( bIsCharA )
782 [ # # ]: 0 : rParams.SetChar( nPos, 'D' );
783 : 0 : nLastPos = nPos;
784 : : } while ( STRING_NOTFOUND != nLastPos );
785 : : }
786 : :
787 : 0 : xub_StrLen nLen = rParams.Len();
788 : 0 : xub_StrLen nI = 0;
789 [ # # ]: 0 : while (nI < nLen)
790 : : {
791 [ # # ]: 0 : if (rParams.GetChar(nI) == '\\')
792 : 0 : nI++;
793 [ # # ]: 0 : else if (rParams.GetChar(nI) == '\"')
794 : : {
795 : 0 : ++nI;
796 : : //While not at the end and not at an unescaped end quote
797 [ # # ][ # # ]: 0 : while ((nI < nLen) && (!(rParams.GetChar(nI) == '\"') && (rParams.GetChar(nI-1) != '\\')))
[ # # ][ # # ]
798 : 0 : ++nI;
799 : : }
800 : : else //normal unquoted section
801 : : {
802 : 0 : sal_Unicode nChar = rParams.GetChar(nI);
803 : :
804 : : // Change the localized word string to english
805 [ # # ]: 0 : switch ( nDocLang )
806 : : {
807 : : case LANGUAGE_FRENCH:
808 [ # # ][ # # ]: 0 : if ( ( nChar == 'a' || nChar == 'A' ) && IsNotAM(rParams, nI) )
[ # # ][ # # ]
809 [ # # ]: 0 : rParams.SetChar(nI, 'Y');
810 : 0 : break;
811 : : default:
812 : : ;
813 : : }
814 [ # # ]: 0 : if (nChar == '/')
815 : : {
816 : : // MM We have to escape '/' in case it's used as a char
817 [ # # ][ # # ]: 0 : rParams.Replace(nI, 1, rtl::OUString("\\/"));
[ # # ]
818 : 0 : nI++;
819 : 0 : nLen++;
820 : : }
821 : :
822 : : // Deal with language differences in date format expression.
823 : : // Should be made with i18n framework.
824 : : // The list of the mappings and of those "special" locales is to be found at:
825 : : // http://l10n.openoffice.org/i18n_framework/LocaleData.html
826 [ # # ][ # # ]: 0 : if ( !bForceJapanese && !bForceNatNum )
827 : : {
828 : : // Convert to the localized equivalent for OOo
829 [ # # # # : 0 : switch ( rLang )
# # # # ]
830 : : {
831 : : case LANGUAGE_FINNISH:
832 : : {
833 [ # # ][ # # ]: 0 : if (nChar == 'y' || nChar == 'Y')
834 [ # # ]: 0 : rParams.SetChar (nI, 'V');
835 [ # # ][ # # ]: 0 : else if (nChar == 'm' || nChar == 'M')
836 [ # # ]: 0 : rParams.SetChar (nI, 'K');
837 [ # # ][ # # ]: 0 : else if (nChar == 'd' || nChar == 'D')
838 [ # # ]: 0 : rParams.SetChar (nI, 'P');
839 [ # # ][ # # ]: 0 : else if (nChar == 'h' || nChar == 'H')
840 [ # # ]: 0 : rParams.SetChar (nI, 'T');
841 : : }
842 : 0 : break;
843 : : case LANGUAGE_DANISH:
844 : : case LANGUAGE_NORWEGIAN:
845 : : case LANGUAGE_NORWEGIAN_BOKMAL:
846 : : case LANGUAGE_NORWEGIAN_NYNORSK:
847 : : case LANGUAGE_SWEDISH:
848 : : case LANGUAGE_SWEDISH_FINLAND:
849 : : {
850 [ # # ][ # # ]: 0 : if (nChar == 'h' || nChar == 'H')
851 [ # # ]: 0 : rParams.SetChar (nI, 'T');
852 : : }
853 : 0 : break;
854 : : case LANGUAGE_PORTUGUESE:
855 : : case LANGUAGE_PORTUGUESE_BRAZILIAN:
856 : : case LANGUAGE_SPANISH_MODERN:
857 : : case LANGUAGE_SPANISH_DATED:
858 : : case LANGUAGE_SPANISH_MEXICAN:
859 : : case LANGUAGE_SPANISH_GUATEMALA:
860 : : case LANGUAGE_SPANISH_COSTARICA:
861 : : case LANGUAGE_SPANISH_PANAMA:
862 : : case LANGUAGE_SPANISH_DOMINICAN_REPUBLIC:
863 : : case LANGUAGE_SPANISH_VENEZUELA:
864 : : case LANGUAGE_SPANISH_COLOMBIA:
865 : : case LANGUAGE_SPANISH_PERU:
866 : : case LANGUAGE_SPANISH_ARGENTINA:
867 : : case LANGUAGE_SPANISH_ECUADOR:
868 : : case LANGUAGE_SPANISH_CHILE:
869 : : case LANGUAGE_SPANISH_URUGUAY:
870 : : case LANGUAGE_SPANISH_PARAGUAY:
871 : : case LANGUAGE_SPANISH_BOLIVIA:
872 : : case LANGUAGE_SPANISH_EL_SALVADOR:
873 : : case LANGUAGE_SPANISH_HONDURAS:
874 : : case LANGUAGE_SPANISH_NICARAGUA:
875 : : case LANGUAGE_SPANISH_PUERTO_RICO:
876 : : {
877 [ # # ][ # # ]: 0 : if (nChar == 'a' || nChar == 'A')
878 [ # # ]: 0 : rParams.SetChar (nI, 'O');
879 [ # # ][ # # ]: 0 : else if (nChar == 'y' || nChar == 'Y')
880 [ # # ]: 0 : rParams.SetChar (nI, 'A');
881 : : }
882 : 0 : break;
883 : : case LANGUAGE_DUTCH:
884 : : case LANGUAGE_DUTCH_BELGIAN:
885 : : {
886 [ # # ][ # # ]: 0 : if (nChar == 'y' || nChar == 'Y')
887 [ # # ]: 0 : rParams.SetChar (nI, 'J');
888 [ # # ][ # # ]: 0 : else if (nChar == 'u' || nChar == 'U')
889 [ # # ]: 0 : rParams.SetChar (nI, 'H');
890 : : }
891 : 0 : break;
892 : : case LANGUAGE_ITALIAN:
893 : : case LANGUAGE_ITALIAN_SWISS:
894 : : {
895 [ # # ][ # # ]: 0 : if (nChar == 'a' || nChar == 'A')
896 [ # # ]: 0 : rParams.SetChar (nI, 'O');
897 [ # # ][ # # ]: 0 : else if (nChar == 'g' || nChar == 'G')
898 [ # # ]: 0 : rParams.SetChar (nI, 'X');
899 [ # # ][ # # ]: 0 : else if (nChar == 'y' || nChar == 'Y')
900 [ # # ]: 0 : rParams.SetChar(nI, 'A');
901 [ # # ][ # # ]: 0 : else if (nChar == 'd' || nChar == 'D')
902 [ # # ]: 0 : rParams.SetChar (nI, 'G');
903 : : }
904 : 0 : break;
905 : : case LANGUAGE_GERMAN:
906 : : case LANGUAGE_GERMAN_SWISS:
907 : : case LANGUAGE_GERMAN_AUSTRIAN:
908 : : case LANGUAGE_GERMAN_LUXEMBOURG:
909 : : case LANGUAGE_GERMAN_LIECHTENSTEIN:
910 : : {
911 [ # # ][ # # ]: 0 : if (nChar == 'y' || nChar == 'Y')
912 [ # # ]: 0 : rParams.SetChar (nI, 'J');
913 [ # # ][ # # ]: 0 : else if (nChar == 'd' || nChar == 'D')
914 [ # # ]: 0 : rParams.SetChar (nI, 'T');
915 : : }
916 : 0 : break;
917 : : case LANGUAGE_FRENCH:
918 : : case LANGUAGE_FRENCH_BELGIAN:
919 : : case LANGUAGE_FRENCH_CANADIAN:
920 : : case LANGUAGE_FRENCH_SWISS:
921 : : case LANGUAGE_FRENCH_LUXEMBOURG:
922 : : case LANGUAGE_FRENCH_MONACO:
923 : : {
924 [ # # ][ # # ]: 0 : if (nChar == 'y' || nChar == 'Y' || nChar == 'a')
[ # # ]
925 [ # # ]: 0 : rParams.SetChar (nI, 'A');
926 [ # # ][ # # ]: 0 : else if (nChar == 'd' || nChar == 'D' || nChar == 'j')
[ # # ]
927 [ # # ]: 0 : rParams.SetChar (nI, 'J');
928 : : }
929 : 0 : break;
930 : : default:
931 : : {
932 : : ; // Nothing
933 : : }
934 : : }
935 : : }
936 : : }
937 : 0 : ++nI;
938 : : }
939 : :
940 [ # # ]: 0 : if (bForceNatNum)
941 : 0 : bForceJapanese = true;
942 : :
943 [ # # ]: 0 : if (bForceJapanese)
944 : 0 : rLang = LANGUAGE_JAPANESE;
945 : :
946 [ # # ]: 0 : if (bForceNatNum)
947 [ # # ][ # # ]: 0 : rParams.Insert(rtl::OUString("[NatNum1][$-411]"),0);
[ # # ]
948 : :
949 [ # # ]: 0 : if (bHijri)
950 [ # # ][ # # ]: 0 : rParams.Insert(rtl::OUString("[~hijri]"), 0);
[ # # ]
951 : :
952 [ # # ]: 0 : pFormatter->PutEntry(rParams, nCheckPos, nType, nKey, rLang);
953 : :
954 [ # # ]: 0 : return nKey;
955 : : }
956 : :
957 : 0 : bool IsNotAM(String& rParams, xub_StrLen nPos)
958 : : {
959 : : return (
960 : 0 : (nPos == rParams.Len() - 1) ||
961 : : (
962 : 0 : (rParams.GetChar(nPos+1) != 'M') &&
963 : 0 : (rParams.GetChar(nPos+1) != 'm')
964 : : )
965 [ # # # # : 0 : );
# # ]
966 : : }
967 : :
968 : 0 : void SwapQuotesInField(String &rFmt)
969 : : {
970 : : //Swap unescaped " and ' with ' and "
971 : 0 : xub_StrLen nLen = rFmt.Len();
972 [ # # ]: 0 : for (xub_StrLen nI = 0; nI < nLen; ++nI)
973 : : {
974 [ # # ][ # # ]: 0 : if ((rFmt.GetChar(nI) == '\"') && (!nI || rFmt.GetChar(nI-1) != '\\'))
[ # # ][ # # ]
975 : 0 : rFmt.SetChar(nI, '\'');
976 [ # # ][ # # ]: 0 : else if ((rFmt.GetChar(nI) == '\'') && (!nI || rFmt.GetChar(nI-1) != '\\'))
[ # # ][ # # ]
977 : 0 : rFmt.SetChar(nI, '\"');
978 : : }
979 : 0 : }
980 : :
981 : : }
982 : : }
983 : :
984 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|