LCOV - code coverage report
Current view: top level - sw/source/filter/ww8 - writerwordglue.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 332 416 79.8 %
Date: 2014-04-11 Functions: 41 41 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10