LCOV - code coverage report
Current view: top level - sw/source/filter/ascii - parasc.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 150 230 65.2 %
Date: 2014-11-03 Functions: 8 8 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 <boost/scoped_array.hpp>
      21             : #include <tools/stream.hxx>
      22             : #include <hintids.hxx>
      23             : #include <rtl/tencinfo.h>
      24             : #include <sfx2/printer.hxx>
      25             : #include <editeng/fontitem.hxx>
      26             : #include <editeng/langitem.hxx>
      27             : #include <editeng/formatbreakitem.hxx>
      28             : #include <editeng/scripttypeitem.hxx>
      29             : #include <shellio.hxx>
      30             : #include <doc.hxx>
      31             : #include <IDocumentDeviceAccess.hxx>
      32             : #include <IDocumentStylePoolAccess.hxx>
      33             : #include <swtypes.hxx>
      34             : #include <ndtxt.hxx>
      35             : #include <pam.hxx>
      36             : #include <frmatr.hxx>
      37             : #include <fltini.hxx>
      38             : #include <pagedesc.hxx>
      39             : #include <breakit.hxx>
      40             : #include <swerror.h>
      41             : #include <statstr.hrc>
      42             : #include <mdiexp.hxx>
      43             : #include <poolfmt.hxx>
      44             : 
      45             : #include <vcl/metric.hxx>
      46             : 
      47             : #define ASC_BUFFLEN 4096
      48             : 
      49             : class SwASCIIParser
      50             : {
      51             :     SwDoc* pDoc;
      52             :     SwPaM* pPam;
      53             :     SvStream& rInput;
      54             :     sal_Char* pArr;
      55             :     const SwAsciiOptions& rOpt;
      56             :     SfxItemSet* pItemSet;
      57             :     long nFileSize;
      58             :     sal_uInt16 nScript;
      59             :     bool bNewDoc;
      60             : 
      61             :     sal_uLong ReadChars();
      62             :     void InsertText( const OUString& rStr );
      63             : 
      64             : public:
      65             :     SwASCIIParser( SwDoc* pD, const SwPaM& rCrsr, SvStream& rIn,
      66             :                             bool bReadNewDoc, const SwAsciiOptions& rOpts );
      67             :     ~SwASCIIParser();
      68             : 
      69             :     sal_uLong CallParser();
      70             : };
      71             : 
      72             : // Call for the general reader interface
      73           6 : sal_uLong AsciiReader::Read( SwDoc &rDoc, const OUString&, SwPaM &rPam, const OUString & )
      74             : {
      75           6 :     if( !pStrm )
      76             :     {
      77             :         OSL_ENSURE( false, "ASCII read without a stream" );
      78           0 :         return ERR_SWG_READ_ERROR;
      79             :     }
      80             : 
      81             :     SwASCIIParser* pParser = new SwASCIIParser( &rDoc, rPam, *pStrm,
      82           6 :                                         !bInsertMode, aOpt.GetASCIIOpts() );
      83           6 :     sal_uLong nRet = pParser->CallParser();
      84             : 
      85           6 :     delete pParser;
      86             :     // after Read reset the options
      87           6 :     aOpt.ResetASCIIOpts();
      88           6 :     return nRet;
      89             : }
      90             : 
      91           6 : SwASCIIParser::SwASCIIParser(SwDoc* pD, const SwPaM& rCrsr, SvStream& rIn,
      92             :     bool bReadNewDoc, const SwAsciiOptions& rOpts)
      93             :     : pDoc(pD), rInput(rIn), rOpt(rOpts), nFileSize(0), nScript(0)
      94           6 :     , bNewDoc(bReadNewDoc)
      95             : {
      96           6 :     pPam = new SwPaM( *rCrsr.GetPoint() );
      97           6 :     pArr = new sal_Char [ ASC_BUFFLEN + 2 ];
      98             : 
      99           6 :     pItemSet = new SfxItemSet( pDoc->GetAttrPool(),
     100             :                 RES_CHRATR_FONT,        RES_CHRATR_LANGUAGE,
     101             :                 RES_CHRATR_CJK_FONT,    RES_CHRATR_CJK_LANGUAGE,
     102             :                 RES_CHRATR_CTL_FONT,    RES_CHRATR_CTL_LANGUAGE,
     103           6 :                 0 );
     104             : 
     105             :     // set defaults from the options
     106           6 :     if( rOpt.GetLanguage() )
     107             :     {
     108           6 :         SvxLanguageItem aLang( (LanguageType)rOpt.GetLanguage(),
     109           6 :                                  RES_CHRATR_LANGUAGE );
     110           6 :         pItemSet->Put( aLang );
     111           6 :         pItemSet->Put( aLang, RES_CHRATR_CJK_LANGUAGE );
     112           6 :         pItemSet->Put( aLang, RES_CHRATR_CTL_LANGUAGE );
     113             :     }
     114           6 :     if( !rOpt.GetFontName().isEmpty() )
     115             :     {
     116           6 :         vcl::Font aTextFont( rOpt.GetFontName(), Size( 0, 10 ) );
     117           6 :         if( pDoc->getIDocumentDeviceAccess().getPrinter( false ) )
     118           0 :             aTextFont = pDoc->getIDocumentDeviceAccess().getPrinter( false )->GetFontMetric( aTextFont );
     119           6 :         SvxFontItem aFont( aTextFont.GetFamily(), aTextFont.GetName(),
     120          18 :                            OUString(), aTextFont.GetPitch(), aTextFont.GetCharSet(), RES_CHRATR_FONT );
     121           6 :         pItemSet->Put( aFont );
     122           6 :         pItemSet->Put( aFont, RES_CHRATR_CJK_FONT );
     123          12 :         pItemSet->Put( aFont, RES_CHRATR_CTL_FONT );
     124             :     }
     125           6 : }
     126             : 
     127           6 : SwASCIIParser::~SwASCIIParser()
     128             : {
     129           6 :     delete pPam;
     130           6 :     delete [] pArr;
     131           6 :     delete pItemSet;
     132           6 : }
     133             : 
     134             : // Calling the parser
     135           6 : sal_uLong SwASCIIParser::CallParser()
     136             : {
     137           6 :     rInput.Seek(STREAM_SEEK_TO_END);
     138           6 :     rInput.ResetError();
     139             : 
     140           6 :     nFileSize = rInput.Tell();
     141           6 :     rInput.Seek(STREAM_SEEK_TO_BEGIN);
     142           6 :     rInput.ResetError();
     143             : 
     144           6 :     ::StartProgress( STR_STATSTR_W4WREAD, 0, nFileSize, pDoc->GetDocShell() );
     145             : 
     146           6 :     SwPaM* pInsPam = 0;
     147           6 :     sal_Int32 nSttCntnt = 0;
     148           6 :     if (!bNewDoc)
     149             :     {
     150           0 :         const SwNodeIndex& rTmp = pPam->GetPoint()->nNode;
     151           0 :         pInsPam = new SwPaM( rTmp, rTmp, 0, -1 );
     152           0 :         nSttCntnt = pPam->GetPoint()->nContent.GetIndex();
     153             :     }
     154             : 
     155           6 :     SwTxtFmtColl *pColl = 0;
     156             : 
     157           6 :     if (bNewDoc)
     158             :     {
     159           6 :         pColl = pDoc->getIDocumentStylePoolAccess().GetTxtCollFromPool(RES_POOLCOLL_HTML_PRE, false);
     160           6 :         if (!pColl)
     161           0 :             pColl = pDoc->getIDocumentStylePoolAccess().GetTxtCollFromPool(RES_POOLCOLL_STANDARD,false);
     162           6 :         if (pColl)
     163           6 :             pDoc->SetTxtFmtColl(*pPam, pColl);
     164             :     }
     165             : 
     166           6 :     sal_uLong nError = ReadChars();
     167             : 
     168           6 :     if( pItemSet )
     169             :     {
     170             :         // set only the attribute, for scanned scripts.
     171           6 :         if( !( SCRIPTTYPE_LATIN & nScript ))
     172             :         {
     173           0 :             pItemSet->ClearItem( RES_CHRATR_FONT );
     174           0 :             pItemSet->ClearItem( RES_CHRATR_LANGUAGE );
     175             :         }
     176           6 :         if( !( SCRIPTTYPE_ASIAN & nScript ))
     177             :         {
     178           4 :             pItemSet->ClearItem( RES_CHRATR_CJK_FONT );
     179           4 :             pItemSet->ClearItem( RES_CHRATR_CJK_LANGUAGE );
     180             :         }
     181           6 :         if( !( SCRIPTTYPE_COMPLEX & nScript ))
     182             :         {
     183           4 :             pItemSet->ClearItem( RES_CHRATR_CTL_FONT );
     184           4 :             pItemSet->ClearItem( RES_CHRATR_CTL_LANGUAGE );
     185             :         }
     186           6 :         if( pItemSet->Count() )
     187             :         {
     188           6 :             if( bNewDoc )
     189             :             {
     190           6 :                 if (pColl)
     191             :                 {
     192             :                     // Using the pool defaults for the font causes significant
     193             :                     // trouble for the HTML filter, because it is not able
     194             :                     // to export the pool defaults (or to be more precise:
     195             :                     // the HTML filter is not able to detect whether a pool
     196             :                     // default has changed or not. Even a comparison with the
     197             :                     // HTMLi template does not work, because the defaults are
     198             :                     // not copied when a new doc is created. The result of
     199             :                     // comparing pool defaults therefore would be that the
     200             :                     // defaults are exported always if the have changed for
     201             :                     // text documents in general. That's not sensible, as well
     202             :                     // as it is not sensible to export them always.
     203             :                     sal_uInt16 aWhichIds[4] =
     204             :                     {
     205             :                         RES_CHRATR_FONT, RES_CHRATR_CJK_FONT,
     206             :                         RES_CHRATR_CTL_FONT, 0
     207           6 :                     };
     208           6 :                     sal_uInt16 *pWhichIds = aWhichIds;
     209          30 :                     while (*pWhichIds)
     210             :                     {
     211             :                         const SfxPoolItem *pItem;
     212          18 :                         if (SfxItemState::SET == pItemSet->GetItemState(*pWhichIds,
     213          18 :                             false, &pItem))
     214             :                         {
     215          10 :                             pColl->SetFmtAttr( *pItem );
     216          10 :                             pItemSet->ClearItem( *pWhichIds );
     217             :                         }
     218          18 :                         ++pWhichIds;
     219             :                     }
     220             :                 }
     221           6 :                 if (pItemSet->Count())
     222           6 :                     pDoc->SetDefault(*pItemSet);
     223             :             }
     224           0 :             else if( pInsPam )
     225             :             {
     226             :                 // then set over the insert range the defined attributes
     227           0 :                 *pInsPam->GetMark() = *pPam->GetPoint();
     228           0 :                 pInsPam->GetPoint()->nNode++;
     229           0 :                 pInsPam->GetPoint()->nContent.Assign(
     230           0 :                                     pInsPam->GetCntntNode(), nSttCntnt );
     231             : 
     232             :                 // !!!!!
     233             :                 OSL_ENSURE( false, "Have to change - hard attr. to para. style" );
     234           0 :                 pDoc->getIDocumentContentOperations().InsertItemSet( *pInsPam, *pItemSet, 0 );
     235             :             }
     236             :         }
     237           6 :         delete pItemSet, pItemSet = 0;
     238             :     }
     239             : 
     240           6 :     delete pInsPam;
     241             : 
     242           6 :     ::EndProgress( pDoc->GetDocShell() );
     243           6 :     return nError;
     244             : }
     245             : 
     246           6 : sal_uLong SwASCIIParser::ReadChars()
     247             : {
     248           6 :     sal_Unicode *pStt = 0, *pEnd = 0, *pLastStt = 0;
     249           6 :     long nReadCnt = 0, nLineLen = 0;
     250           6 :     sal_Unicode cLastCR = 0;
     251           6 :     bool bSwapUnicode = false;
     252             : 
     253           6 :     const SwAsciiOptions *pUseMe=&rOpt;
     254           6 :     SwAsciiOptions aEmpty;
     255          36 :     if (nFileSize >= 2 &&
     256          30 :         aEmpty.GetFontName() == rOpt.GetFontName() &&
     257           0 :         aEmpty.GetCharSet() == rOpt.GetCharSet() &&
     258          12 :         aEmpty.GetLanguage() == rOpt.GetLanguage() &&
     259           0 :         aEmpty.GetParaFlags() == rOpt.GetParaFlags())
     260             :     {
     261             :         sal_uLong nLen, nOrig;
     262           0 :         nOrig = nLen = rInput.Read(pArr, ASC_BUFFLEN);
     263             :         rtl_TextEncoding eCharSet;
     264           0 :         bool bRet = SwIoSystem::IsDetectableText(pArr, nLen, &eCharSet, &bSwapUnicode);
     265             :         OSL_ENSURE(bRet, "Autodetect of text import without nag dialog must have failed");
     266           0 :         if (bRet && eCharSet != RTL_TEXTENCODING_DONTKNOW)
     267             :         {
     268           0 :             aEmpty.SetCharSet(eCharSet);
     269           0 :             rInput.SeekRel(-(long(nLen)));
     270             :         }
     271             :         else
     272           0 :             rInput.SeekRel(-(long(nOrig)));
     273           0 :         pUseMe=&aEmpty;
     274             :     }
     275             : 
     276           6 :     rtl_TextToUnicodeConverter hConverter=0;
     277           6 :     rtl_TextToUnicodeContext hContext=0;
     278           6 :     rtl_TextEncoding currentCharSet = pUseMe->GetCharSet();
     279           6 :     if (RTL_TEXTENCODING_UCS2 != currentCharSet)
     280             :     {
     281           6 :         if( currentCharSet == RTL_TEXTENCODING_DONTKNOW )
     282           0 :                 currentCharSet = RTL_TEXTENCODING_ASCII_US;
     283           6 :         hConverter = rtl_createTextToUnicodeConverter( currentCharSet );
     284             :         OSL_ENSURE( hConverter, "no string convert available" );
     285           6 :         if (!hConverter)
     286           0 :             return ERROR_SW_READ_BASE;
     287           6 :         bSwapUnicode = false;
     288           6 :         hContext = rtl_createTextToUnicodeContext( hConverter );
     289             :     }
     290           0 :     else if (pUseMe != &aEmpty)  //Already successfully figured out type
     291             :     {
     292           0 :         rInput.StartReadingUnicodeText( currentCharSet );
     293           0 :         bSwapUnicode = rInput.IsEndianSwap();
     294             :     }
     295             : 
     296          12 :     boost::scoped_array<sal_Unicode> aWork;
     297           6 :     sal_uLong nArrOffset = 0;
     298             : 
     299             :     do {
     300       40366 :         if( pStt >= pEnd )
     301             :         {
     302          20 :             if( pLastStt != pStt )
     303          14 :                 InsertText( OUString( pLastStt ));
     304             : 
     305             :             // Read a new block
     306             :             sal_uLong lGCount;
     307          40 :             if( SVSTREAM_OK != rInput.GetError() || 0 == (lGCount =
     308          20 :                         rInput.Read( pArr + nArrOffset,
     309          40 :                                      ASC_BUFFLEN - nArrOffset )))
     310           6 :                 break;      // break from the while loop
     311             : 
     312             :             /*
     313             :             If there was some unconverted bytes on the last cycle then they
     314             :             were put at the beginning of the array, so total bytes available
     315             :             to convert this cycle includes them. If we found 0 following bytes
     316             :             then we ignore the previous partial character.
     317             :             */
     318          14 :             lGCount+=nArrOffset;
     319             : 
     320          14 :             if( hConverter )
     321             :             {
     322             :                 sal_uInt32 nInfo;
     323          14 :                 sal_Size nNewLen = lGCount, nCntBytes;
     324          14 :                 aWork.reset(new sal_Unicode[nNewLen + 1]); // add 1 for '\0'
     325          14 :                 sal_Unicode* pBuf = aWork.get();
     326             : 
     327             :                 nNewLen = rtl_convertTextToUnicode( hConverter, hContext,
     328             :                                 pArr, lGCount, pBuf, nNewLen,
     329             :                                 (
     330             :                                 RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT |
     331             :                                 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
     332             :                                 RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT |
     333             :                                 RTL_TEXTTOUNICODE_FLAGS_GLOBAL_SIGNATURE
     334             :                                 ),
     335             :                                 &nInfo,
     336          14 :                                 &nCntBytes );
     337          14 :                 if( 0 != ( nArrOffset = lGCount - nCntBytes ) )
     338           0 :                     memmove( pArr, pArr + nCntBytes, nArrOffset );
     339             : 
     340          14 :                 pStt = pLastStt = aWork.get();
     341          14 :                 pEnd = pStt + nNewLen;
     342             :             }
     343             :             else
     344             :             {
     345           0 :                 pStt = pLastStt = (sal_Unicode*)pArr;
     346           0 :                 pEnd = (sal_Unicode*)(pArr + lGCount);
     347             : 
     348           0 :                 if( bSwapUnicode )
     349             :                 {
     350           0 :                     sal_Char* pF = pArr, *pN = pArr + 1;
     351           0 :                     for( sal_uLong n = 0; n < lGCount; n += 2, pF += 2, pN += 2 )
     352             :                     {
     353           0 :                         sal_Char c = *pF;
     354           0 :                         *pF = *pN;
     355           0 :                         *pN = c;
     356             :                     }
     357             :                 }
     358             :             }
     359             : 
     360          14 :             *pEnd = 0;
     361          14 :             nReadCnt += lGCount;
     362             : 
     363          14 :             ::SetProgressState( nReadCnt, pDoc->GetDocShell() );
     364             : 
     365          14 :             if( cLastCR )
     366             :             {
     367           0 :                 if( 0x0a == *pStt && 0x0d == cLastCR )
     368           0 :                     pLastStt = ++pStt;
     369           0 :                 cLastCR = 0;
     370           0 :                 nLineLen = 0;
     371             :                 // We skip the last one at the end
     372           0 :                 if( !rInput.IsEof() || !(pEnd == pStt ||
     373           0 :                     ( !*pEnd && pEnd == pStt+1 ) ) )
     374           0 :                     pDoc->getIDocumentContentOperations().SplitNode( *pPam->GetPoint(), false );
     375             :             }
     376             :         }
     377             : 
     378       40360 :         bool bIns = true, bSplitNode = false;
     379       40360 :         switch( *pStt )
     380             :         {
     381             : 
     382         546 :         case 0x0a:  if( LINEEND_LF == pUseMe->GetParaFlags() )
     383             :                     {
     384         546 :                         bIns = false;
     385         546 :                         *pStt = 0;
     386         546 :                         ++pStt;
     387             : 
     388             :                         // We skip the last one at the end
     389         546 :                         if( !rInput.IsEof() || pEnd != pStt )
     390         540 :                             bSplitNode = true;
     391             :                     }
     392         546 :                     break;
     393             : 
     394           4 :         case 0x0d:  if( LINEEND_LF != pUseMe->GetParaFlags() )
     395             :                     {
     396           0 :                         bIns = false;
     397           0 :                         *pStt = 0;
     398           0 :                         ++pStt;
     399             : 
     400           0 :                         bool bChkSplit = false;
     401           0 :                         if( LINEEND_CRLF == pUseMe->GetParaFlags() )
     402             :                         {
     403           0 :                             if( pStt == pEnd )
     404           0 :                                 cLastCR = 0x0d;
     405           0 :                             else if( 0x0a == *pStt )
     406             :                             {
     407           0 :                                 ++pStt;
     408           0 :                                 bChkSplit = true;
     409             :                             }
     410             :                         }
     411             :                         else
     412           0 :                             bChkSplit = true;
     413             : 
     414             :                         // We skip the last one at the end
     415           0 :                         if( bChkSplit && ( !rInput.IsEof() || pEnd != pStt ))
     416           0 :                             bSplitNode = true;
     417             :                     }
     418           4 :                     break;
     419             : 
     420             :         case 0x0c:
     421             :                     {
     422             :                         // Insert a hard page break
     423           0 :                         *pStt++ = 0;
     424           0 :                         if( nLineLen )
     425             :                         {
     426           0 :                             InsertText( OUString( pLastStt ));
     427             :                         }
     428           0 :                         pDoc->getIDocumentContentOperations().SplitNode( *pPam->GetPoint(), false );
     429           0 :                         pDoc->getIDocumentContentOperations().InsertPoolItem(
     430           0 :                             *pPam, SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE, RES_BREAK ), 0);
     431           0 :                         pLastStt = pStt;
     432           0 :                         nLineLen = 0;
     433           0 :                         bIns = false;
     434             :                     }
     435           0 :                     break;
     436             : 
     437             :         case 0x1a:
     438           0 :                     if( nReadCnt == nFileSize && pStt+1 == pEnd )
     439           0 :                         *pStt = 0;
     440             :                     else
     441           0 :                         *pStt = '#';        // Replacement visualisation
     442           0 :                     break;
     443             : 
     444           0 :         case '\t':  break;
     445             : 
     446             :         default:
     447       39810 :             if( ' ' > *pStt )
     448             :             // Found control char, replace with '#'
     449          14 :                 *pStt = '#';
     450       39810 :             break;
     451             :         }
     452             : 
     453       40360 :         if( bIns )
     454             :         {
     455       39814 :             if( ( nLineLen >= MAX_ASCII_PARA - 100 ) &&
     456           0 :                 ( ( *pStt == ' ' ) || ( nLineLen >= MAX_ASCII_PARA - 1 ) ) )
     457             :             {
     458           0 :                 sal_Unicode c = *pStt;
     459           0 :                 *pStt = 0;
     460           0 :                 InsertText( OUString( pLastStt ));
     461           0 :                 pDoc->getIDocumentContentOperations().SplitNode( *pPam->GetPoint(), false );
     462           0 :                 pLastStt = pStt;
     463           0 :                 nLineLen = 0;
     464           0 :                 *pStt = c;
     465             :             }
     466       39814 :             ++pStt;
     467       39814 :             ++nLineLen;
     468             :         }
     469         546 :         else if( bSplitNode )
     470             :         {
     471             :             // We found a CR/LF, thus save the text
     472         540 :             InsertText( OUString( pLastStt ));
     473         540 :             pDoc->getIDocumentContentOperations().SplitNode( *pPam->GetPoint(), false );
     474         540 :             pLastStt = pStt;
     475         540 :             nLineLen = 0;
     476             :         }
     477             :     } while(true);
     478             : 
     479           6 :     if( hConverter )
     480             :     {
     481           6 :         rtl_destroyTextToUnicodeContext( hConverter, hContext );
     482           6 :         rtl_destroyTextToUnicodeConverter( hConverter );
     483             :     }
     484          12 :     return 0;
     485             : }
     486             : 
     487         554 : void SwASCIIParser::InsertText( const OUString& rStr )
     488             : {
     489         554 :     pDoc->getIDocumentContentOperations().InsertString( *pPam, rStr );
     490         554 :     pDoc->UpdateRsid( *pPam, rStr.getLength() );
     491         554 :     pDoc->UpdateParRsid( pPam->GetPoint()->nNode.GetNode().GetTxtNode() );
     492             : 
     493         554 :     if( pItemSet && g_pBreakIt && nScript != ( SCRIPTTYPE_LATIN |
     494             :                                              SCRIPTTYPE_ASIAN |
     495             :                                              SCRIPTTYPE_COMPLEX ) )
     496         128 :         nScript |= g_pBreakIt->GetAllScriptsOfText( rStr );
     497         824 : }
     498             : 
     499             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10