LCOV - code coverage report
Current view: top level - libreoffice/sw/source/core/text - inftxt.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 577 936 61.6 %
Date: 2012-12-27 Functions: 38 51 74.5 %
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 <com/sun/star/uno/Sequence.h>
      21             : #include <unotools/linguprops.hxx>
      22             : #include <unotools/lingucfg.hxx>
      23             : #include <hintids.hxx>
      24             : #include <sfx2/printer.hxx>
      25             : #include <editeng/hyznitem.hxx>
      26             : #include <editeng/escpitem.hxx>
      27             : #include <editeng/hngpnctitem.hxx>
      28             : #include <editeng/scriptspaceitem.hxx>
      29             : #include <editeng/brshitem.hxx>
      30             : #include <editeng/splwrap.hxx>
      31             : #include <editeng/pgrditem.hxx>
      32             : #include <editeng/tstpitem.hxx>
      33             : #include <xmloff/odffields.hxx>
      34             : 
      35             : #include <SwSmartTagMgr.hxx>
      36             : #include <linguistic/lngprops.hxx>
      37             : #include <editeng/unolingu.hxx>
      38             : #include <breakit.hxx>
      39             : #include <editeng/forbiddenruleitem.hxx>
      40             : #include <txatbase.hxx>
      41             : #include <fmtinfmt.hxx>
      42             : #include <fmtfld.hxx>
      43             : #include <fldbas.hxx>
      44             : #include <PostItMgr.hxx>
      45             : #include <swmodule.hxx>
      46             : #include <vcl/svapp.hxx>
      47             : #include <vcl/wrkwin.hxx>
      48             : #include <viewsh.hxx>   // ViewShell
      49             : #include <viewopt.hxx>  // SwViewOptions
      50             : #include <frmtool.hxx>  // DrawGraphic
      51             : #include <IDocumentSettingAccess.hxx>
      52             : #include <IDocumentDeviceAccess.hxx>
      53             : #include <paratr.hxx>   // SwFmtDrop
      54             : #include <rootfrm.hxx>  // SwRootFrm
      55             : #include <inftxt.hxx>   // SwTxtInfo
      56             : #include <blink.hxx>    // SwBlink
      57             : #include <noteurl.hxx>  // SwNoteURL
      58             : #include <porftn.hxx>   // SwFtnPortion
      59             : #include <porrst.hxx>   // SwHangingPortion
      60             : #include <itratr.hxx>
      61             : #include <accessibilityoptions.hxx>
      62             : #include <wrong.hxx>
      63             : #include <doc.hxx>
      64             : #include <pam.hxx>
      65             : #include <SwGrammarMarkUp.hxx>
      66             : #include <cstdio>
      67             : // #i12836# enhanced pdf export
      68             : #include <EnhancedPDFExportHelper.hxx>
      69             : 
      70             : #include <unomid.h>
      71             : 
      72             : #if OSL_DEBUG_LEVEL > 1
      73             : #include <stdio.h>
      74             : #endif
      75             : 
      76             : using namespace ::com::sun::star;
      77             : using namespace ::com::sun::star::linguistic2;
      78             : using namespace ::com::sun::star::uno;
      79             : using namespace ::com::sun::star::beans;
      80             : 
      81             : 
      82             : #define CHAR_UNDERSCORE ((sal_Unicode)0x005F)
      83             : #define CHAR_LEFT_ARROW ((sal_Unicode)0x25C0)
      84             : #define CHAR_RIGHT_ARROW ((sal_Unicode)0x25B6)
      85             : #define CHAR_TAB ((sal_Unicode)0x2192)
      86             : #define CHAR_TAB_RTL ((sal_Unicode)0x2190)
      87             : #define CHAR_LINEBREAK ((sal_Unicode)0x21B5)
      88             : #define CHAR_LINEBREAK_RTL ((sal_Unicode)0x21B3)
      89             : 
      90             : #define DRAW_SPECIAL_OPTIONS_CENTER 1
      91             : #define DRAW_SPECIAL_OPTIONS_ROTATE 2
      92             : 
      93             : // variable moved to class <numfunc:GetDefBulletConfig>
      94             : //extern const sal_Char sBulletFntName[];
      95             : namespace numfunc
      96             : {
      97             :     extern const String& GetDefBulletFontname();
      98             :     extern bool IsDefBulletFontUserDefined();
      99             : }
     100             : 
     101             : #ifdef DBG_UTIL
     102             : sal_Bool SwTxtSizeInfo::IsOptDbg() const { return GetOpt().IsTest4(); }
     103             : #endif
     104             : 
     105        4152 : SwLineInfo::SwLineInfo()
     106             :     : pRuler( 0 ),
     107             :       pSpace( 0 ),
     108             :       nVertAlign( 0 ),
     109             :       nDefTabStop( 0 ),
     110             :       bListTabStopIncluded( false ),
     111        4152 :       nListTabStopPosition( 0 )
     112             : {
     113        4152 : }
     114             : 
     115        4152 : SwLineInfo::~SwLineInfo()
     116             : {
     117        4152 :     delete pRuler;
     118        4152 : }
     119        4152 : void SwLineInfo::CtorInitLineInfo( const SwAttrSet& rAttrSet,
     120             :                                    const SwTxtNode& rTxtNode )
     121             : {
     122        4152 :     delete pRuler;
     123        4152 :     pRuler = new SvxTabStopItem( rAttrSet.GetTabStops() );
     124        4152 :     if ( rTxtNode.GetListTabStopPosition( nListTabStopPosition ) )
     125             :     {
     126         167 :         bListTabStopIncluded = true;
     127             : 
     128             :         // insert the list tab stop into SvxTabItem instance <pRuler>
     129             :         const SvxTabStop aListTabStop( nListTabStopPosition,
     130         167 :                                        SVX_TAB_ADJUST_LEFT );
     131         167 :         pRuler->Insert( aListTabStop );
     132             : 
     133             :         // remove default tab stops, which are before the inserted list tab stop
     134         419 :         for ( sal_uInt16 i = 0; i < pRuler->Count(); i++ )
     135             :         {
     136         252 :             if ( (*pRuler)[i].GetTabPos() < nListTabStopPosition &&
     137           0 :                  (*pRuler)[i].GetAdjustment() == SVX_TAB_ADJUST_DEFAULT )
     138             :             {
     139           0 :                 pRuler->Remove(i);
     140           0 :                 continue;
     141             :             }
     142             :         }
     143             :     }
     144             : 
     145        4152 :     if ( !rTxtNode.getIDocumentSettingAccess()->get(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT) )
     146             :     {
     147             :         // remove default tab stop at position 0
     148        8639 :         for ( sal_uInt16 i = 0; i < pRuler->Count(); i++ )
     149             :         {
     150        4951 :             if ( (*pRuler)[i].GetTabPos() == 0 &&
     151         161 :                  (*pRuler)[i].GetAdjustment() == SVX_TAB_ADJUST_DEFAULT )
     152             :             {
     153           0 :                 pRuler->Remove(i);
     154           0 :                 break;
     155             :             }
     156             :         }
     157             :     }
     158             : 
     159        4152 :     pSpace = &rAttrSet.GetLineSpacing();
     160        4152 :     nVertAlign = rAttrSet.GetParaVertAlign().GetValue();
     161        4152 :     nDefTabStop = MSHRT_MAX;
     162        4152 : }
     163             : 
     164        4152 : void SwTxtInfo::CtorInitTxtInfo( SwTxtFrm *pFrm )
     165             : {
     166        4152 :     pPara = pFrm->GetPara();
     167        4152 :     nTxtStart = pFrm->GetOfst();
     168        4152 :     if( !pPara )
     169             :     {
     170             :         OSL_ENSURE( pPara, "+SwTxtInfo::CTOR: missing paragraph information" );
     171           0 :         pFrm->Format();
     172           0 :         pPara = pFrm->GetPara();
     173             :     }
     174        4152 : }
     175             : 
     176        2985 : SwTxtInfo::SwTxtInfo( const SwTxtInfo &rInf )
     177        2985 :     : pPara( ((SwTxtInfo&)rInf).GetParaPortion() ),
     178        2985 :       nTxtStart( rInf.GetTxtStart() )
     179        2985 : { }
     180             : 
     181             : 
     182             : #if OSL_DEBUG_LEVEL > 0
     183             : 
     184             : void ChkOutDev( const SwTxtSizeInfo &rInf )
     185             : {
     186             :     if ( !rInf.GetVsh() )
     187             :         return;
     188             : 
     189             :     const OutputDevice* pOut = rInf.GetOut();
     190             :     const OutputDevice* pRef = rInf.GetRefDev();
     191             :     OSL_ENSURE( pOut && pRef, "ChkOutDev: invalid output devices" );
     192             : }
     193             : #endif
     194             : 
     195             : 
     196        6416 : inline xub_StrLen GetMinLen( const SwTxtSizeInfo &rInf )
     197             : {
     198        6416 :     const xub_StrLen nInfLen = rInf.GetIdx() + rInf.GetLen();
     199        6416 :     return Min( rInf.GetTxt().Len(), nInfLen );
     200             : }
     201             : 
     202             : 
     203         721 : SwTxtSizeInfo::SwTxtSizeInfo( const SwTxtSizeInfo &rNew )
     204             :     : SwTxtInfo( rNew ),
     205         721 :       pKanaComp(((SwTxtSizeInfo&)rNew).GetpKanaComp()),
     206         721 :       pVsh(((SwTxtSizeInfo&)rNew).GetVsh()),
     207         721 :       pOut(((SwTxtSizeInfo&)rNew).GetOut()),
     208         721 :       pRef(((SwTxtSizeInfo&)rNew).GetRefDev()),
     209         721 :       pFnt(((SwTxtSizeInfo&)rNew).GetFont()),
     210         721 :       pUnderFnt(((SwTxtSizeInfo&)rNew).GetUnderFnt()),
     211             :       pFrm(rNew.pFrm),
     212         721 :       pOpt(&rNew.GetOpt()),
     213         721 :       pTxt(&rNew.GetTxt()),
     214         721 :       nIdx(rNew.GetIdx()),
     215         721 :       nLen(rNew.GetLen()),
     216         721 :       nKanaIdx( rNew.GetKanaIdx() ),
     217         721 :       bOnWin( rNew.OnWin() ),
     218         721 :       bNotEOL( rNew.NotEOL() ),
     219         721 :       bURLNotify( rNew.URLNotify() ),
     220         721 :       bStopUnderFlow( rNew.StopUnderFlow() ),
     221         721 :       bFtnInside( rNew.IsFtnInside() ),
     222         721 :       bOtherThanFtnInside( rNew.IsOtherThanFtnInside() ),
     223         721 :       bMulti( rNew.IsMulti() ),
     224         721 :       bFirstMulti( rNew.IsFirstMulti() ),
     225         721 :       bRuby( rNew.IsRuby() ),
     226         721 :       bHanging( rNew.IsHanging() ),
     227         721 :       bScriptSpace( rNew.HasScriptSpace() ),
     228         721 :       bForbiddenChars( rNew.HasForbiddenChars() ),
     229         721 :       bSnapToGrid( rNew.SnapToGrid() ),
     230       18025 :       nDirection( rNew.GetDirection() )
     231             : {
     232             : #if OSL_DEBUG_LEVEL > 0
     233             :     ChkOutDev( *this );
     234             : #endif
     235         721 : }
     236             : 
     237        4152 : void SwTxtSizeInfo::CtorInitTxtSizeInfo( SwTxtFrm *pFrame, SwFont *pNewFnt,
     238             :                    const xub_StrLen nNewIdx, const xub_StrLen nNewLen )
     239             : {
     240        4152 :     pKanaComp = NULL;
     241        4152 :     nKanaIdx = 0;
     242        4152 :     pFrm = pFrame;
     243        4152 :     CtorInitTxtInfo( pFrm );
     244        4152 :     const SwTxtNode *pNd = pFrm->GetTxtNode();
     245        4152 :     pVsh = pFrm->getRootFrm()->GetCurrShell();
     246             : 
     247             :     // Get the output and reference device
     248        4152 :     if ( pVsh )
     249             :     {
     250        4152 :         pOut = pVsh->GetOut();
     251        4152 :         pRef = &pVsh->GetRefDev();
     252        4152 :         bOnWin = pVsh->GetWin() || OUTDEV_WINDOW == pOut->GetOutDevType();
     253             :     }
     254             :     else
     255             :     {
     256             :         // Access via StarONE. We do not need a Shell or an active one.
     257           0 :         if ( pNd->getIDocumentSettingAccess()->get(IDocumentSettingAccess::HTML_MODE) )
     258             :         {
     259             :             // We can only pick the AppWin here? (there's nothing better to pick?)
     260           0 :             pOut = GetpApp()->GetDefaultDevice();
     261             :         }
     262             :         else
     263           0 :             pOut = pNd->getIDocumentDeviceAccess()->getPrinter( false );
     264             : 
     265           0 :         pRef = pOut;
     266             :     }
     267             : 
     268             : #if OSL_DEBUG_LEVEL > 0
     269             :     ChkOutDev( *this );
     270             : #endif
     271             : 
     272             :     // Set default layout mode ( LTR or RTL ).
     273        4152 :     if ( pFrm->IsRightToLeft() )
     274             :     {
     275           0 :         pOut->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG | TEXT_LAYOUT_BIDI_RTL );
     276           0 :         pRef->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG | TEXT_LAYOUT_BIDI_RTL );
     277           0 :         nDirection = DIR_RIGHT2LEFT;
     278             :     }
     279             :     else
     280             :     {
     281        4152 :         pOut->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG );
     282        4152 :         pRef->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG );
     283        4152 :         nDirection = DIR_LEFT2RIGHT;
     284             :     }
     285             : 
     286             :     //
     287             :     // The Options
     288             :     //
     289             :     pOpt = pVsh ?
     290        4152 :            pVsh->GetViewOptions() :
     291        8304 :            SW_MOD()->GetViewOption( pNd->getIDocumentSettingAccess()->get(IDocumentSettingAccess::HTML_MODE) ); // Options from Module, due to StarONE
     292             : 
     293             :     // bURLNotify is set if MakeGraphic prepares it
     294             :     // TODO: Unwind
     295        4152 :     bURLNotify = pNoteURL && !bOnWin;
     296             : 
     297        4152 :     SetSnapToGrid( pNd->GetSwAttrSet().GetParaGrid().GetValue() &&
     298        4152 :                    pFrm->IsInDocBody() );
     299             : 
     300        4152 :     pFnt = pNewFnt;
     301        4152 :     pUnderFnt = 0;
     302        4152 :     pTxt = &pNd->GetTxt();
     303             : 
     304        4152 :     nIdx = nNewIdx;
     305        4152 :     nLen = nNewLen;
     306        4152 :     bNotEOL = false;
     307        4152 :     bStopUnderFlow = bFtnInside = bOtherThanFtnInside = false;
     308             :     bMulti = bFirstMulti = bRuby = bHanging = bScriptSpace =
     309        4152 :         bForbiddenChars = false;
     310             : 
     311        4152 :     SetLen( GetMinLen( *this ) );
     312        4152 : }
     313             : 
     314        2264 : SwTxtSizeInfo::SwTxtSizeInfo( const SwTxtSizeInfo &rNew, const XubString &rTxt,
     315             :                               const xub_StrLen nIndex, const xub_StrLen nLength )
     316             :     : SwTxtInfo( rNew ),
     317        2264 :       pKanaComp(((SwTxtSizeInfo&)rNew).GetpKanaComp()),
     318        2264 :       pVsh(((SwTxtSizeInfo&)rNew).GetVsh()),
     319        2264 :       pOut(((SwTxtSizeInfo&)rNew).GetOut()),
     320        2264 :       pRef(((SwTxtSizeInfo&)rNew).GetRefDev()),
     321        2264 :       pFnt(((SwTxtSizeInfo&)rNew).GetFont()),
     322        2264 :       pUnderFnt(((SwTxtSizeInfo&)rNew).GetUnderFnt()),
     323             :       pFrm( rNew.pFrm ),
     324        2264 :       pOpt(&rNew.GetOpt()),
     325             :       pTxt(&rTxt),
     326             :       nIdx(nIndex),
     327             :       nLen(nLength),
     328        2264 :       nKanaIdx( rNew.GetKanaIdx() ),
     329        2264 :       bOnWin( rNew.OnWin() ),
     330        2264 :       bNotEOL( rNew.NotEOL() ),
     331        2264 :       bURLNotify( rNew.URLNotify() ),
     332        2264 :       bStopUnderFlow( rNew.StopUnderFlow() ),
     333        2264 :       bFtnInside( rNew.IsFtnInside() ),
     334        2264 :       bOtherThanFtnInside( rNew.IsOtherThanFtnInside() ),
     335        2264 :       bMulti( rNew.IsMulti() ),
     336        2264 :       bFirstMulti( rNew.IsFirstMulti() ),
     337        2264 :       bRuby( rNew.IsRuby() ),
     338        2264 :       bHanging( rNew.IsHanging() ),
     339        2264 :       bScriptSpace( rNew.HasScriptSpace() ),
     340        2264 :       bForbiddenChars( rNew.HasForbiddenChars() ),
     341        2264 :       bSnapToGrid( rNew.SnapToGrid() ),
     342       49808 :       nDirection( rNew.GetDirection() )
     343             : {
     344             : #if OSL_DEBUG_LEVEL > 0
     345             :     ChkOutDev( *this );
     346             : #endif
     347        2264 :     SetLen( GetMinLen( *this ) );
     348        2264 : }
     349             : 
     350         307 : void SwTxtSizeInfo::SelectFont()
     351             : {
     352             :      // The path needs to go via ChgPhysFnt or the FontMetricCache gets confused.
     353             :      // In this case pLastMet has it's old value.
     354             :      // Wrong: GetOut()->SetFont( GetFont()->GetFnt() );
     355         307 :     GetFont()->Invalidate();
     356         307 :     GetFont()->ChgPhysFnt( pVsh, *GetOut() );
     357         307 : }
     358             : 
     359           0 : void SwTxtSizeInfo::NoteAnimation() const
     360             : {
     361           0 :     if( OnWin() )
     362           0 :         SwRootFrm::FlushVout();
     363             : 
     364             :     OSL_ENSURE( pOut == pVsh->GetOut(),
     365             :             "SwTxtSizeInfo::NoteAnimation() changed pOut" );
     366           0 : }
     367             : 
     368           3 : SwPosSize SwTxtSizeInfo::GetTxtSize( OutputDevice* pOutDev,
     369             :                                      const SwScriptInfo* pSI,
     370             :                                      const XubString& rTxt,
     371             :                                      const xub_StrLen nIndex,
     372             :                                      const xub_StrLen nLength,
     373             :                                      const sal_uInt16 nComp ) const
     374             : {
     375           3 :     SwDrawTextInfo aDrawInf( pVsh, *pOutDev, pSI, rTxt, nIndex, nLength );
     376           3 :     aDrawInf.SetFrm( pFrm );
     377           3 :     aDrawInf.SetFont( pFnt );
     378           3 :     aDrawInf.SetSnapToGrid( SnapToGrid() );
     379           3 :     aDrawInf.SetKanaComp( nComp );
     380           3 :     SwPosSize aSize = pFnt->_GetTxtSize( aDrawInf );
     381           3 :     return aSize;
     382             : }
     383             : 
     384           6 : SwPosSize SwTxtSizeInfo::GetTxtSize() const
     385             : {
     386             :     const SwScriptInfo& rSI =
     387           6 :                      ( (SwParaPortion*)GetParaPortion() )->GetScriptInfo();
     388             : 
     389             :     // in some cases, compression is not allowed or suppressed for
     390             :     // performance reasons
     391           6 :     sal_uInt16 nComp =( SW_CJK == GetFont()->GetActual() &&
     392           0 :                     rSI.CountCompChg() &&
     393           0 :                     ! IsMulti() ) ?
     394             :                     GetKanaComp() :
     395           6 :                                 0 ;
     396             : 
     397           6 :     SwDrawTextInfo aDrawInf( pVsh, *pOut, &rSI, *pTxt, nIdx, nLen );
     398           6 :     aDrawInf.SetFrm( pFrm );
     399           6 :     aDrawInf.SetFont( pFnt );
     400           6 :     aDrawInf.SetSnapToGrid( SnapToGrid() );
     401           6 :     aDrawInf.SetKanaComp( nComp );
     402           6 :     return pFnt->_GetTxtSize( aDrawInf );
     403             : }
     404             : 
     405         673 : void SwTxtSizeInfo::GetTxtSize( const SwScriptInfo* pSI, const xub_StrLen nIndex,
     406             :                                 const xub_StrLen nLength, const sal_uInt16 nComp,
     407             :                                 sal_uInt16& nMinSize, sal_uInt16& nMaxSizeDiff ) const
     408             : {
     409         673 :     SwDrawTextInfo aDrawInf( pVsh, *pOut, pSI, *pTxt, nIndex, nLength );
     410         673 :     aDrawInf.SetFrm( pFrm );
     411         673 :     aDrawInf.SetFont( pFnt );
     412         673 :     aDrawInf.SetSnapToGrid( SnapToGrid() );
     413         673 :     aDrawInf.SetKanaComp( nComp );
     414         673 :     SwPosSize aSize = pFnt->_GetTxtSize( aDrawInf );
     415         673 :     nMaxSizeDiff = (sal_uInt16)aDrawInf.GetKanaDiff();
     416         673 :     nMinSize = aSize.Width();
     417         673 : }
     418             : 
     419         101 : xub_StrLen SwTxtSizeInfo::GetTxtBreak( const long nLineWidth,
     420             :                                        const xub_StrLen nMaxLen,
     421             :                                        const sal_uInt16 nComp ) const
     422             : {
     423             :     const SwScriptInfo& rScriptInfo =
     424         101 :                      ( (SwParaPortion*)GetParaPortion() )->GetScriptInfo();
     425             : 
     426             :     OSL_ENSURE( pRef == pOut, "GetTxtBreak is supposed to use the RefDev" );
     427             :     SwDrawTextInfo aDrawInf( pVsh, *pOut, &rScriptInfo,
     428         101 :                              *pTxt, GetIdx(), nMaxLen );
     429         101 :     aDrawInf.SetFrm( pFrm );
     430         101 :     aDrawInf.SetFont( pFnt );
     431         101 :     aDrawInf.SetSnapToGrid( SnapToGrid() );
     432         101 :     aDrawInf.SetKanaComp( nComp );
     433         101 :     aDrawInf.SetHyphPos( 0 );
     434             : 
     435         101 :     return pFnt->GetTxtBreak( aDrawInf, nLineWidth );
     436             : }
     437             : 
     438           0 : xub_StrLen SwTxtSizeInfo::GetTxtBreak( const long nLineWidth,
     439             :                                        const xub_StrLen nMaxLen,
     440             :                                        const sal_uInt16 nComp,
     441             :                                        xub_StrLen& rExtraCharPos ) const
     442             : {
     443             :     const SwScriptInfo& rScriptInfo =
     444           0 :                      ( (SwParaPortion*)GetParaPortion() )->GetScriptInfo();
     445             : 
     446             :     OSL_ENSURE( pRef == pOut, "GetTxtBreak is supposed to use the RefDev" );
     447             :     SwDrawTextInfo aDrawInf( pVsh, *pOut, &rScriptInfo,
     448           0 :                              *pTxt, GetIdx(), nMaxLen );
     449           0 :     aDrawInf.SetFrm( pFrm );
     450           0 :     aDrawInf.SetFont( pFnt );
     451           0 :     aDrawInf.SetSnapToGrid( SnapToGrid() );
     452           0 :     aDrawInf.SetKanaComp( nComp );
     453           0 :     aDrawInf.SetHyphPos( &rExtraCharPos );
     454             : 
     455           0 :     return pFnt->GetTxtBreak( aDrawInf, nLineWidth );
     456             : }
     457             : 
     458        1169 : void SwTxtPaintInfo::CtorInitTxtPaintInfo( SwTxtFrm *pFrame, const SwRect &rPaint )
     459             : {
     460        1169 :     CtorInitTxtSizeInfo( pFrame );
     461        1169 :     aTxtFly.CtorInitTxtFly( pFrame ),
     462        1169 :     aPaintRect = rPaint;
     463        1169 :     nSpaceIdx = 0;
     464        1169 :     pSpaceAdd = NULL;
     465        1169 :     pWrongList = NULL;
     466        1169 :     pGrammarCheckList = NULL;
     467        1169 :     pSmartTags = NULL;  // SMARTTAGS
     468             : 
     469             : #if OSL_DEBUG_LEVEL > 1
     470             :     pBrushItem = ((SvxBrushItem*)-1);
     471             : #else
     472        1169 :     pBrushItem = 0;
     473             : #endif
     474        1169 : }
     475             : 
     476           0 : SwTxtPaintInfo::SwTxtPaintInfo( const SwTxtPaintInfo &rInf, const XubString &rTxt )
     477             :     : SwTxtSizeInfo( rInf, rTxt ),
     478           0 :       pWrongList( rInf.GetpWrongList() ),
     479           0 :       pGrammarCheckList( rInf.GetGrammarCheckList() ),
     480           0 :       pSmartTags( rInf.GetSmartTags() ),    // SMARTTAGS
     481           0 :       pSpaceAdd( rInf.GetpSpaceAdd() ),
     482           0 :       pBrushItem( rInf.GetBrushItem() ),
     483           0 :       aTxtFly( *rInf.GetTxtFly() ),
     484           0 :       aPos( rInf.GetPos() ),
     485           0 :       aPaintRect( rInf.GetPaintRect() ),
     486           0 :       nSpaceIdx( rInf.GetSpaceIdx() )
     487           0 : { }
     488             : 
     489         721 : SwTxtPaintInfo::SwTxtPaintInfo( const SwTxtPaintInfo &rInf )
     490             :     : SwTxtSizeInfo( rInf ),
     491         721 :       pWrongList( rInf.GetpWrongList() ),
     492         721 :       pGrammarCheckList( rInf.GetGrammarCheckList() ),
     493         721 :       pSmartTags( rInf.GetSmartTags() ),    // SMARTTAGS
     494         721 :       pSpaceAdd( rInf.GetpSpaceAdd() ),
     495         721 :       pBrushItem( rInf.GetBrushItem() ),
     496         721 :       aTxtFly( *rInf.GetTxtFly() ),
     497         721 :       aPos( rInf.GetPos() ),
     498         721 :       aPaintRect( rInf.GetPaintRect() ),
     499        6489 :       nSpaceIdx( rInf.GetSpaceIdx() )
     500         721 : { }
     501             : 
     502             : extern Color aGlobalRetoucheColor;
     503             : 
     504             : /*************************************************************************
     505             :  * lcl_IsDarkBackground
     506             :  *
     507             :  * Returns if the current background color is dark.
     508             :  *************************************************************************/
     509             : 
     510          22 : static sal_Bool lcl_IsDarkBackground( const SwTxtPaintInfo& rInf )
     511             : {
     512          22 :     const Color* pCol = rInf.GetFont()->GetBackColor();
     513          22 :     if( ! pCol || COL_TRANSPARENT == pCol->GetColor() )
     514             :     {
     515             :         const SvxBrushItem* pItem;
     516          22 :         SwRect aOrigBackRect;
     517             : 
     518             :         // Consider, that [GetBackgroundBrush(...)] can set <pCol>
     519             :         // See implementation in /core/layout/paintfrm.cxx
     520             :         // There is a background color, if there is a background brush and
     521             :         // its color is *not* "no fill"/"auto fill".
     522          22 :         if( rInf.GetTxtFrm()->GetBackgroundBrush( pItem, pCol, aOrigBackRect, sal_False ) )
     523             :         {
     524           0 :             if ( !pCol )
     525           0 :                 pCol = &pItem->GetColor();
     526             : 
     527             :             // Determined color <pCol> can be <COL_TRANSPARENT>. Thus, check it.
     528           0 :             if ( pCol->GetColor() == COL_TRANSPARENT)
     529           0 :                 pCol = NULL;
     530             :         }
     531             :         else
     532          22 :             pCol = NULL;
     533             :     }
     534             : 
     535             : 
     536          22 :     if( !pCol )
     537          22 :         pCol = &aGlobalRetoucheColor;
     538             : 
     539          22 :     return pCol->IsDark();
     540             : }
     541             : 
     542             : /*************************************************************************
     543             :  * SwTxtPaintInfo::_DrawText()
     544             :  *************************************************************************/
     545             : 
     546         449 : void SwTxtPaintInfo::_DrawText( const XubString &rText, const SwLinePortion &rPor,
     547             :                                 const xub_StrLen nStart, const xub_StrLen nLength,
     548             :                                 const sal_Bool bKern, const sal_Bool bWrong,
     549             :                                 const sal_Bool bSmartTag,
     550             :                                 const sal_Bool bGrammarCheck )  // SMARTTAGS
     551             : {
     552         449 :     if( !nLength )
     553             :         return;
     554             : 
     555         449 :     if( GetFont()->IsBlink() && OnWin() && rPor.Width() )
     556             :     {
     557             :         // check if accessibility options allow blinking portions:
     558           0 :         const ViewShell* pSh = GetTxtFrm()->getRootFrm()->GetCurrShell();
     559           0 :         if ( pSh && ! pSh->GetAccessibilityOptions()->IsStopAnimatedText() &&
     560           0 :              ! pSh->IsPreView() )
     561             :         {
     562           0 :             if( !pBlink )
     563           0 :                 pBlink = new SwBlink();
     564             : 
     565           0 :             Point aPoint( aPos );
     566             : 
     567           0 :             if ( GetTxtFrm()->IsRightToLeft() )
     568           0 :                 GetTxtFrm()->SwitchLTRtoRTL( aPoint );
     569             : 
     570           0 :             if ( TEXT_LAYOUT_BIDI_STRONG != GetOut()->GetLayoutMode() )
     571           0 :                 aPoint.X() -= rPor.Width();
     572             : 
     573           0 :             if ( GetTxtFrm()->IsVertical() )
     574           0 :                 GetTxtFrm()->SwitchHorizontalToVertical( aPoint );
     575             : 
     576           0 :             pBlink->Insert( aPoint, &rPor, GetTxtFrm(), pFnt->GetOrientation() );
     577             : 
     578           0 :             if( !pBlink->IsVisible() )
     579             :                 return;
     580             :         }
     581             :         else
     582             :         {
     583           0 :             delete pBlink;
     584           0 :             pBlink = NULL;
     585             :         }
     586             :     }
     587             : 
     588             :     // The SwScriptInfo is useless if we are inside a field portion
     589         449 :     SwScriptInfo* pSI = 0;
     590         449 :     if ( ! rPor.InFldGrp() )
     591         405 :         pSI = &GetParaPortion()->GetScriptInfo();
     592             : 
     593             :     // in some cases, kana compression is not allowed or suppressed for
     594             :     // performance reasons
     595         449 :     sal_uInt16 nComp = 0;
     596         449 :     if ( ! IsMulti() )
     597         449 :         nComp = GetKanaComp();
     598             : 
     599         449 :     sal_Bool bCfgIsAutoGrammar = sal_False;
     600         449 :     SvtLinguConfig().GetProperty( UPN_IS_GRAMMAR_AUTO ) >>= bCfgIsAutoGrammar;
     601         449 :     const sal_Bool bBullet = OnWin() && GetOpt().IsBlank() && IsNoSymbol();
     602         449 :     const sal_Bool bTmpWrong = bWrong && OnWin() && GetOpt().IsOnlineSpell();
     603         449 :     const sal_Bool bTmpGrammarCheck = bGrammarCheck && OnWin() && bCfgIsAutoGrammar && GetOpt().IsOnlineSpell();
     604         449 :     const sal_Bool bTmpSmart = bSmartTag && OnWin() && !GetOpt().IsPagePreview() && SwSmartTagMgr::Get().IsSmartTagsEnabled(); // SMARTTAGS
     605             : 
     606             :     OSL_ENSURE( GetParaPortion(), "No paragraph!");
     607             :     SwDrawTextInfo aDrawInf( pFrm->getRootFrm()->GetCurrShell(), *pOut, pSI, rText, nStart, nLength,
     608         449 :                              rPor.Width(), bBullet );
     609             : 
     610         449 :     aDrawInf.SetLeft( GetPaintRect().Left() );
     611         449 :     aDrawInf.SetRight( GetPaintRect().Right() );
     612         449 :     aDrawInf.SetUnderFnt( pUnderFnt );
     613             : 
     614         890 :     const long nSpaceAdd = ( rPor.IsBlankPortion() || rPor.IsDropPortion() ||
     615         890 :                              rPor.InNumberGrp() ) ? 0 : GetSpaceAdd();
     616         449 :     if ( nSpaceAdd )
     617             :     {
     618             :         xub_StrLen nCharCnt;
     619             :         // #i41860# Thai justified alignment needs some
     620             :         // additional information:
     621           4 :         aDrawInf.SetNumberOfBlanks( rPor.InTxtGrp() ?
     622           4 :                                     static_cast<const SwTxtPortion&>(rPor).GetSpaceCnt( *this, nCharCnt ) :
     623           8 :                                     0 );
     624             :     }
     625             : 
     626         449 :     aDrawInf.SetSpace( nSpaceAdd );
     627         449 :     aDrawInf.SetKanaComp( nComp );
     628             : 
     629             :     // the font is used to identify the current script via nActual
     630         449 :     aDrawInf.SetFont( pFnt );
     631             :     // the frame is used to identify the orientation
     632         449 :     aDrawInf.SetFrm( GetTxtFrm() );
     633             :     // we have to know if the paragraph should snap to grid
     634         449 :     aDrawInf.SetSnapToGrid( SnapToGrid() );
     635             :     // for underlining we must know when not to add extra space behind
     636             :     // a character in justified mode
     637         449 :     aDrawInf.SetSpaceStop( ! rPor.GetPortion() ||
     638         135 :                              rPor.GetPortion()->InFixMargGrp() ||
     639         584 :                              rPor.GetPortion()->IsHolePortion() );
     640             : 
     641         449 :     if( GetTxtFly()->IsOn() )
     642             :     {
     643             :         // aPos needs to be the TopLeft, because we cannot calculate the
     644             :         // ClipRects otherwise
     645           0 :         const Point aPoint( aPos.X(), aPos.Y() - rPor.GetAscent() );
     646           0 :         const Size aSize( rPor.Width(), rPor.Height() );
     647           0 :         aDrawInf.SetPos( aPoint );
     648           0 :         aDrawInf.SetSize( aSize );
     649           0 :         aDrawInf.SetAscent( rPor.GetAscent() );
     650           0 :         aDrawInf.SetKern( bKern ? rPor.Width() : 0 );
     651           0 :         aDrawInf.SetWrong( bTmpWrong ? pWrongList : NULL );
     652           0 :         aDrawInf.SetGrammarCheck( bTmpGrammarCheck ? pGrammarCheckList : NULL );
     653           0 :         aDrawInf.SetSmartTags( bTmpSmart ? pSmartTags : NULL );     // SMARTTAGS
     654           0 :         GetTxtFly()->DrawTextOpaque( aDrawInf );
     655             :     }
     656             :     else
     657             :     {
     658         449 :         aDrawInf.SetPos( aPos );
     659         449 :         if( bKern )
     660           0 :             pFnt->_DrawStretchText( aDrawInf );
     661             :         else
     662             :         {
     663         449 :             aDrawInf.SetWrong( bTmpWrong ? pWrongList : NULL );
     664         449 :             aDrawInf.SetGrammarCheck( bTmpGrammarCheck ? pGrammarCheckList : NULL );
     665         449 :             aDrawInf.SetSmartTags( bTmpSmart ? pSmartTags : NULL );  // SMARTTAGS
     666         449 :             pFnt->_DrawText( aDrawInf );
     667             :         }
     668             :     }
     669             : }
     670             : 
     671         527 : void SwTxtPaintInfo::CalcRect( const SwLinePortion& rPor,
     672             :                                SwRect* pRect, SwRect* pIntersect ) const
     673             : {
     674         527 :     Size aSize( rPor.Width(), rPor.Height() );
     675         527 :     if( rPor.IsHangingPortion() )
     676           0 :         aSize.Width() = ((SwHangingPortion&)rPor).GetInnerWidth();
     677         527 :     if( rPor.InSpaceGrp() && GetSpaceAdd() )
     678             :     {
     679           4 :         SwTwips nAdd = rPor.CalcSpacing( GetSpaceAdd(), *this );
     680           4 :         if( rPor.InFldGrp() && GetSpaceAdd() < 0 && nAdd )
     681           0 :             nAdd += GetSpaceAdd() / SPACING_PRECISION_FACTOR;
     682           4 :         aSize.Width() += nAdd;
     683             :     }
     684             : 
     685         527 :     Point aPoint;
     686             : 
     687         527 :     if( IsRotated() )
     688             :     {
     689           0 :         long nTmp = aSize.Width();
     690           0 :         aSize.Width() = aSize.Height();
     691           0 :         aSize.Height() = nTmp;
     692           0 :         if ( 1 == GetDirection() )
     693             :         {
     694           0 :             aPoint.A() = X() - rPor.GetAscent();
     695           0 :             aPoint.B() = Y() - aSize.Height();
     696             :         }
     697             :         else
     698             :         {
     699           0 :             aPoint.A() = X() - rPor.Height() + rPor.GetAscent();
     700           0 :             aPoint.B() = Y();
     701             :         }
     702             :     }
     703             :     else
     704             :     {
     705         527 :         aPoint.A() = X();
     706             :         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     707         527 :         if ( GetTxtFrm()->IsVertLR() )
     708           0 :             aPoint.B() = Y() - rPor.Height() + rPor.GetAscent();
     709             :         else
     710         527 :             aPoint.B() = Y() - rPor.GetAscent();
     711             :     }
     712             : 
     713             :     // Adjust x coordinate if we are inside a bidi portion
     714         527 :     const sal_Bool bFrmDir = GetTxtFrm()->IsRightToLeft();
     715         527 :     bool bCounterDir = ( ! bFrmDir && DIR_RIGHT2LEFT == GetDirection() ) ||
     716        1054 :                        (   bFrmDir && DIR_LEFT2RIGHT == GetDirection() );
     717             : 
     718         527 :     if ( bCounterDir )
     719           2 :         aPoint.A() -= aSize.Width();
     720             : 
     721         527 :     SwRect aRect( aPoint, aSize );
     722             : 
     723         527 :     if ( GetTxtFrm()->IsRightToLeft() )
     724           0 :         GetTxtFrm()->SwitchLTRtoRTL( aRect );
     725             : 
     726         527 :     if ( GetTxtFrm()->IsVertical() )
     727           0 :         GetTxtFrm()->SwitchHorizontalToVertical( aRect );
     728             : 
     729         527 :     if ( pRect )
     730         497 :         *pRect = aRect;
     731             : 
     732         527 :     if( aRect.HasArea() && pIntersect )
     733             :     {
     734          30 :         ::SwAlignRect( aRect, (ViewShell*)GetVsh() );
     735             : 
     736          30 :         if ( GetOut()->IsClipRegion() )
     737             :         {
     738           2 :             SwRect aClip( GetOut()->GetClipRegion().GetBoundRect() );
     739           2 :             aRect.Intersection( aClip );
     740             :         }
     741             : 
     742          30 :         *pIntersect = aRect;
     743             :     }
     744         527 : }
     745             : 
     746             : /*************************************************************************
     747             :  * lcl_DrawSpecial
     748             :  *
     749             :  * Draws a special portion, e.g., line break portion, tab portion.
     750             :  * rPor     - The portion
     751             :  * rRect    - The rectangle surrounding the character
     752             :  * pCol     - Specify a color for the character
     753             :  * bCenter  - Draw the character centered, otherwise left aligned
     754             :  * bRotate  - Rotate the character if character rotation is set
     755             :  *************************************************************************/
     756             : 
     757           0 : static void lcl_DrawSpecial( const SwTxtPaintInfo& rInf, const SwLinePortion& rPor,
     758             :                       SwRect& rRect, const Color* pCol, sal_Unicode cChar,
     759             :                       sal_uInt8 nOptions )
     760             : {
     761           0 :     bool bCenter = 0 != ( nOptions & DRAW_SPECIAL_OPTIONS_CENTER );
     762           0 :     bool bRotate = 0 != ( nOptions & DRAW_SPECIAL_OPTIONS_ROTATE );
     763             : 
     764             :     // rRect is given in absolute coordinates
     765           0 :     if ( rInf.GetTxtFrm()->IsRightToLeft() )
     766           0 :         rInf.GetTxtFrm()->SwitchRTLtoLTR( rRect );
     767           0 :     if ( rInf.GetTxtFrm()->IsVertical() )
     768           0 :         rInf.GetTxtFrm()->SwitchVerticalToHorizontal( rRect );
     769             : 
     770           0 :     const SwFont* pOldFnt = rInf.GetFont();
     771             : 
     772             :     // Font is generated only once:
     773             :     static SwFont* pFnt = 0;
     774           0 :     if ( ! pFnt )
     775             :     {
     776           0 :         pFnt = new SwFont( *pOldFnt );
     777           0 :         pFnt->SetFamily( FAMILY_DONTKNOW, pFnt->GetActual() );
     778           0 :         pFnt->SetName( numfunc::GetDefBulletFontname(), pFnt->GetActual() );
     779           0 :         pFnt->SetStyleName( aEmptyStr, pFnt->GetActual() );
     780           0 :         pFnt->SetCharSet( RTL_TEXTENCODING_SYMBOL, pFnt->GetActual() );
     781             :     }
     782             : 
     783             :     // Some of the current values are set at the font:
     784           0 :     if ( ! bRotate )
     785           0 :         pFnt->SetVertical( 0, rInf.GetTxtFrm()->IsVertical() );
     786             :     else
     787           0 :         pFnt->SetVertical( pOldFnt->GetOrientation() );
     788             : 
     789           0 :     if ( pCol )
     790           0 :         pFnt->SetColor( *pCol );
     791             :     else
     792           0 :         pFnt->SetColor( pOldFnt->GetColor() );
     793             : 
     794           0 :     Size aFontSize( 0, SPECIAL_FONT_HEIGHT );
     795           0 :     pFnt->SetSize( aFontSize, pFnt->GetActual() );
     796             : 
     797           0 :     ((SwTxtPaintInfo&)rInf).SetFont( pFnt );
     798             : 
     799             :     // The maximum width depends on the current orientation
     800           0 :     const sal_uInt16 nDir = pFnt->GetOrientation( rInf.GetTxtFrm()->IsVertical() );
     801           0 :     SwTwips nMaxWidth = 0;
     802           0 :     switch ( nDir )
     803             :     {
     804             :     case 0 :
     805           0 :         nMaxWidth = rRect.Width();
     806           0 :         break;
     807             :     case 900 :
     808             :     case 2700 :
     809           0 :         nMaxWidth = rRect.Height();
     810           0 :         break;
     811             :     default:
     812             :         OSL_FAIL( "Unknown direction set at font" );
     813           0 :         break;
     814             :     }
     815             : 
     816             :     // check if char fits into rectangle
     817           0 :     const OUString aTmp( cChar );
     818           0 :     aFontSize = rInf.GetTxtSize( aTmp ).SvLSize();
     819           0 :     while ( aFontSize.Width() > nMaxWidth )
     820             :     {
     821           0 :         SwTwips nFactor = ( 100 * aFontSize.Width() ) / nMaxWidth;
     822           0 :         const SwTwips nOldWidth = aFontSize.Width();
     823             : 
     824             :         // new height for font
     825           0 :         const sal_uInt8 nAct = pFnt->GetActual();
     826           0 :         aFontSize.Height() = ( 100 * pFnt->GetSize( nAct ).Height() ) / nFactor;
     827           0 :         aFontSize.Width() = ( 100 * pFnt->GetSize( nAct).Width() ) / nFactor;
     828             : 
     829           0 :         if ( !aFontSize.Width() && !aFontSize.Height() )
     830           0 :             break;
     831             : 
     832           0 :         pFnt->SetSize( aFontSize, nAct );
     833             : 
     834           0 :         aFontSize = rInf.GetTxtSize( aTmp ).SvLSize();
     835             : 
     836           0 :         if ( aFontSize.Width() >= nOldWidth )
     837           0 :             break;
     838             :     }
     839             : 
     840           0 :     const Point aOldPos( rInf.GetPos() );
     841             : 
     842             :     // adjust values so that tab is vertically and horizontally centered
     843           0 :     SwTwips nX = rRect.Left();
     844           0 :     SwTwips nY = rRect.Top();
     845           0 :     switch ( nDir )
     846             :     {
     847             :     case 0 :
     848           0 :         if ( bCenter )
     849           0 :             nX += ( rRect.Width() - aFontSize.Width() ) / 2;
     850           0 :         nY += ( rRect.Height() - aFontSize.Height() ) / 2 + rInf.GetAscent();
     851           0 :         break;
     852             :     case 900 :
     853           0 :         if ( bCenter )
     854           0 :             nX += ( rRect.Width() - aFontSize.Height() ) / 2 + rInf.GetAscent();
     855           0 :         nY += ( rRect.Height() + aFontSize.Width() ) / 2;
     856           0 :         break;
     857             :     case 2700 :
     858           0 :         if ( bCenter )
     859           0 :             nX += ( rRect.Width() + aFontSize.Height() ) / 2 - rInf.GetAscent();
     860           0 :         nY += ( rRect.Height() - aFontSize.Width() ) / 2;
     861           0 :         break;
     862             :     }
     863             : 
     864           0 :     Point aTmpPos( nX, nY );
     865           0 :     ((SwTxtPaintInfo&)rInf).SetPos( aTmpPos );
     866           0 :     sal_uInt16 nOldWidth = rPor.Width();
     867           0 :     ((SwLinePortion&)rPor).Width( (sal_uInt16)aFontSize.Width() );
     868           0 :     rInf.DrawText( aTmp, rPor );
     869           0 :     ((SwLinePortion&)rPor).Width( nOldWidth );
     870           0 :     ((SwTxtPaintInfo&)rInf).SetFont( (SwFont*)pOldFnt );
     871           0 :     ((SwTxtPaintInfo&)rInf).SetPos( aOldPos );
     872           0 : }
     873             : 
     874          28 : void SwTxtPaintInfo::DrawRect( const SwRect &rRect, sal_Bool bNoGraphic,
     875             :                                sal_Bool bRetouche ) const
     876             : {
     877          28 :     if ( OnWin() || !bRetouche )
     878             :     {
     879          28 :         if( aTxtFly.IsOn() )
     880             :             ((SwTxtPaintInfo*)this)->GetTxtFly()->
     881           0 :                 DrawFlyRect( pOut, rRect, *this, bNoGraphic );
     882          28 :         else if ( bNoGraphic )
     883          28 :             pOut->DrawRect( rRect.SVRect() );
     884             :         else
     885             :         {
     886             :             OSL_ENSURE( ((SvxBrushItem*)-1) != pBrushItem, "DrawRect: Uninitialized BrushItem!" );
     887           0 :             ::DrawGraphic( pBrushItem, pOut, aItemRect, rRect );
     888             :         }
     889             :     }
     890          28 : }
     891             : 
     892           0 : void SwTxtPaintInfo::DrawTab( const SwLinePortion &rPor ) const
     893             : {
     894           0 :     if( OnWin() )
     895             :     {
     896           0 :         SwRect aRect;
     897           0 :         CalcRect( rPor, &aRect );
     898             : 
     899           0 :         if ( ! aRect.HasArea() )
     900           0 :             return;
     901             : 
     902           0 :         const sal_Unicode cChar = GetTxtFrm()->IsRightToLeft() ?
     903           0 :                                   CHAR_TAB_RTL : CHAR_TAB;
     904             :         const sal_uInt8 nOptions = DRAW_SPECIAL_OPTIONS_CENTER |
     905           0 :                               DRAW_SPECIAL_OPTIONS_ROTATE;
     906           0 :         lcl_DrawSpecial( *this, rPor, aRect, 0, cChar, nOptions );
     907             :     }
     908             : }
     909             : 
     910           0 : void SwTxtPaintInfo::DrawLineBreak( const SwLinePortion &rPor ) const
     911             : {
     912           0 :     if( OnWin() )
     913             :     {
     914           0 :         KSHORT nOldWidth = rPor.Width();
     915           0 :         ((SwLinePortion&)rPor).Width( LINE_BREAK_WIDTH );
     916             : 
     917           0 :         SwRect aRect;
     918           0 :         CalcRect( rPor, &aRect );
     919             : 
     920           0 :         if( aRect.HasArea() )
     921             :         {
     922           0 :             const sal_Unicode cChar = GetTxtFrm()->IsRightToLeft() ?
     923           0 :                                       CHAR_LINEBREAK_RTL : CHAR_LINEBREAK;
     924           0 :             const sal_uInt8 nOptions = 0;
     925           0 :             lcl_DrawSpecial( *this, rPor, aRect, 0, cChar, nOptions );
     926             :         }
     927             : 
     928           0 :         ((SwLinePortion&)rPor).Width( nOldWidth );
     929             :     }
     930           0 : }
     931             : 
     932           0 : void SwTxtPaintInfo::DrawRedArrow( const SwLinePortion &rPor ) const
     933             : {
     934           0 :     Size aSize( SPECIAL_FONT_HEIGHT, SPECIAL_FONT_HEIGHT );
     935           0 :     SwRect aRect( ((SwArrowPortion&)rPor).GetPos(), aSize );
     936             :     sal_Unicode cChar;
     937           0 :     if( ((SwArrowPortion&)rPor).IsLeft() )
     938             :     {
     939           0 :         aRect.Pos().Y() += 20 - GetAscent();
     940           0 :         aRect.Pos().X() += 20;
     941           0 :         if( aSize.Height() > rPor.Height() )
     942           0 :             aRect.Height( rPor.Height() );
     943           0 :         cChar = CHAR_LEFT_ARROW;
     944             :     }
     945             :     else
     946             :     {
     947           0 :         if( aSize.Height() > rPor.Height() )
     948           0 :             aRect.Height( rPor.Height() );
     949           0 :         aRect.Pos().Y() -= aRect.Height() + 20;
     950           0 :         aRect.Pos().X() -= aRect.Width() + 20;
     951           0 :         cChar = CHAR_RIGHT_ARROW;
     952             :     }
     953             : 
     954           0 :     if ( GetTxtFrm()->IsVertical() )
     955           0 :         GetTxtFrm()->SwitchHorizontalToVertical( aRect );
     956             : 
     957           0 :     Color aCol( COL_LIGHTRED );
     958             : 
     959           0 :     if( aRect.HasArea() )
     960             :     {
     961           0 :         const sal_uInt8 nOptions = 0;
     962           0 :         lcl_DrawSpecial( *this, rPor, aRect, &aCol, cChar, nOptions );
     963             :     }
     964           0 : }
     965             : 
     966           3 : void SwTxtPaintInfo::DrawPostIts( const SwLinePortion&, sal_Bool bScript ) const
     967             : {
     968           3 :     if( OnWin() && pOpt->IsPostIts() )
     969             :     {
     970           3 :         Size aSize;
     971           3 :         Point aTmp;
     972             : 
     973           3 :         const sal_uInt16 nPostItsWidth = pOpt->GetPostItsWidth( GetOut() );
     974           3 :         const sal_uInt16 nFontHeight = pFnt->GetHeight( pVsh, *GetOut() );
     975           3 :         const sal_uInt16 nFontAscent = pFnt->GetAscent( pVsh, *GetOut() );
     976             : 
     977           3 :         switch ( pFnt->GetOrientation( GetTxtFrm()->IsVertical() ) )
     978             :         {
     979             :         case 0 :
     980           3 :             aSize.Width() = nPostItsWidth;
     981           3 :             aSize.Height() = nFontHeight;
     982           3 :             aTmp.X() = aPos.X();
     983           3 :             aTmp.Y() = aPos.Y() - nFontAscent;
     984           3 :             break;
     985             :         case 900 :
     986           0 :             aSize.Height() = nPostItsWidth;
     987           0 :             aSize.Width() = nFontHeight;
     988           0 :             aTmp.X() = aPos.X() - nFontAscent;
     989           0 :             aTmp.Y() = aPos.Y();
     990           0 :             break;
     991             :         case 2700 :
     992           0 :             aSize.Height() = nPostItsWidth;
     993           0 :             aSize.Width() = nFontHeight;
     994           0 :             aTmp.X() = aPos.X() - nFontHeight +
     995           0 :                                   nFontAscent;
     996           0 :             aTmp.Y() = aPos.Y();
     997           0 :             break;
     998             :         }
     999             : 
    1000           3 :         SwRect aTmpRect( aTmp, aSize );
    1001             : 
    1002           3 :         if ( GetTxtFrm()->IsRightToLeft() )
    1003           0 :             GetTxtFrm()->SwitchLTRtoRTL( aTmpRect );
    1004             : 
    1005           3 :         if ( GetTxtFrm()->IsVertical() )
    1006           0 :             GetTxtFrm()->SwitchHorizontalToVertical( aTmpRect );
    1007             : 
    1008           3 :         const Rectangle aRect( aTmpRect.SVRect() );
    1009           3 :         pOpt->PaintPostIts( (OutputDevice*)GetOut(), aRect, bScript );
    1010             :     }
    1011           3 : }
    1012             : 
    1013           0 : void SwTxtPaintInfo::DrawCheckBox( const SwFieldFormPortion &rPor, bool checked) const
    1014             : {
    1015           0 :     SwRect aIntersect;
    1016           0 :     CalcRect( rPor, &aIntersect, 0 );
    1017           0 :     if ( aIntersect.HasArea() )
    1018             :     {
    1019           0 :         if (OnWin() && SwViewOption::IsFieldShadings() &&
    1020           0 :                 !GetOpt().IsPagePreview())
    1021             :         {
    1022           0 :             OutputDevice* pOut_ = (OutputDevice*)GetOut();
    1023           0 :             pOut_->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
    1024           0 :             pOut_->SetFillColor( SwViewOption::GetFieldShadingsColor() );
    1025           0 :             pOut_->SetLineColor();
    1026           0 :             pOut_->DrawRect( aIntersect.SVRect() );
    1027           0 :             pOut_->Pop();
    1028             :         }
    1029           0 :         const int delta=10;
    1030           0 :         Rectangle r(aIntersect.Left()+delta, aIntersect.Top()+delta, aIntersect.Right()-delta, aIntersect.Bottom()-delta);
    1031           0 :         pOut->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
    1032           0 :         pOut->SetLineColor( Color(0, 0, 0));
    1033           0 :         pOut->SetFillColor();
    1034           0 :         pOut->DrawRect( r );
    1035           0 :         if (checked) {
    1036           0 :             pOut->DrawLine(r.TopLeft(), r.BottomRight());
    1037           0 :             pOut->DrawLine(r.TopRight(), r.BottomLeft());
    1038             :         }
    1039           0 :         pOut->Pop();
    1040             :     }
    1041           0 : }
    1042             : 
    1043          24 : void SwTxtPaintInfo::DrawBackground( const SwLinePortion &rPor ) const
    1044             : {
    1045             :     OSL_ENSURE( OnWin(), "SwTxtPaintInfo::DrawBackground: printer pollution ?" );
    1046             : 
    1047          24 :     SwRect aIntersect;
    1048          24 :     CalcRect( rPor, 0, &aIntersect );
    1049             : 
    1050          24 :     if ( aIntersect.HasArea() )
    1051             :     {
    1052          22 :         OutputDevice* pTmpOut = (OutputDevice*)GetOut();
    1053          22 :         pTmpOut->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
    1054             : 
    1055             :         // For dark background we do not want to have a filled rectangle
    1056          22 :         if ( GetVsh() && GetVsh()->GetWin() && lcl_IsDarkBackground( *this ) )
    1057             :         {
    1058           0 :             pTmpOut->SetLineColor( SwViewOption::GetFontColor().GetColor() );
    1059             :         }
    1060             :         else
    1061             :         {
    1062          22 :             pTmpOut->SetFillColor( SwViewOption::GetFieldShadingsColor() );
    1063          22 :             pTmpOut->SetLineColor();
    1064             :         }
    1065             : 
    1066          22 :         DrawRect( aIntersect, sal_True );
    1067          22 :         pTmpOut->Pop();
    1068             :     }
    1069          24 : }
    1070             : 
    1071         497 : void SwTxtPaintInfo::_DrawBackBrush( const SwLinePortion &rPor ) const
    1072             : {
    1073             :     {
    1074         497 :         SwRect aIntersect;
    1075         497 :         CalcRect( rPor, &aIntersect, 0 );
    1076         497 :         if(aIntersect.HasArea())
    1077             :         {
    1078         497 :             SwTxtNode *pNd = pFrm->GetTxtNode();
    1079         497 :             const ::sw::mark::IFieldmark* pFieldmark = NULL;
    1080         497 :             if(pNd)
    1081             :             {
    1082         497 :                 const SwDoc *doc=pNd->GetDoc();
    1083         497 :                 if(doc)
    1084             :                 {
    1085         497 :                     SwIndex aIndex(pNd, GetIdx());
    1086         497 :                     SwPosition aPosition(*pNd, aIndex);
    1087         497 :                     pFieldmark=doc->getIDocumentMarkAccess()->getFieldmarkFor(aPosition);
    1088             :                 }
    1089             :             }
    1090         497 :             bool bIsStartMark=(1==GetLen() && CH_TXT_ATR_FIELDSTART==GetTxt().GetChar(GetIdx()));
    1091             :             if(pFieldmark) {
    1092             :                 OSL_TRACE("Found Fieldmark");
    1093             : #if OSL_DEBUG_LEVEL > 1
    1094             :                 OUString str = pFieldmark->ToString( );
    1095             :                 fprintf( stderr, "%s\n", rtl::OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr( ) );
    1096             : #endif
    1097             :             }
    1098             :             if(bIsStartMark) OSL_TRACE("Found StartMark");
    1099         503 :             if (OnWin() && (pFieldmark!=NULL || bIsStartMark) &&
    1100           3 :                     SwViewOption::IsFieldShadings() &&
    1101           3 :                     !GetOpt().IsPagePreview())
    1102             :             {
    1103           3 :                 OutputDevice* pOutDev = (OutputDevice*)GetOut();
    1104           3 :                 pOutDev->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
    1105           3 :                 bool bFilled = false;
    1106             :                 // If this is a comment range, need to look up the color of the comment author.
    1107           3 :                 if (pFieldmark->GetFieldname() == ODF_COMMENTRANGE)
    1108             :                 {
    1109             :                     // Search for the position of the postit field
    1110           3 :                     const sal_Unicode fld[] = { CH_TXTATR_INWORD, 0 };
    1111           3 :                     xub_StrLen nEndIdx = GetTxt().SearchChar(fld, GetIdx());
    1112           3 :                     if (nEndIdx != STRING_NOTFOUND)
    1113             :                     {
    1114           3 :                         SwTxtAttr* pTxtAttr = pNd->GetTxtAttrForCharAt(nEndIdx, RES_TXTATR_FIELD);
    1115           3 :                         const SwFmtFld& rPostItField = pTxtAttr->GetFld();
    1116             :                         // Look up the author name
    1117           3 :                         const OUString& rAuthor = rPostItField.GetFld()->GetPar1();
    1118           3 :                         sal_uInt16 nIndex = pNd->GetDoc()->InsertRedlineAuthor(rAuthor);
    1119           3 :                         pOutDev->SetFillColor( SwPostItMgr::GetColorLight(nIndex) );
    1120           3 :                         pOutDev->SetLineColor( SwPostItMgr::GetColorAnchor(nIndex) );
    1121           3 :                         bFilled = true;
    1122             :                     }
    1123             :                 }
    1124           3 :                 if (!bFilled)
    1125             :                 {
    1126           0 :                     pOutDev->SetFillColor( SwViewOption::GetFieldShadingsColor() );
    1127           0 :                     pOutDev->SetLineColor( );
    1128             :                 }
    1129           3 :                 pOutDev->DrawRect( aIntersect.SVRect() );
    1130           3 :                 pOutDev->Pop();
    1131             :             }
    1132             :         }
    1133             :     }
    1134         994 :     if( !pFnt->GetBackColor() ) return;
    1135             : 
    1136             :     OSL_ENSURE( pFnt->GetBackColor(), "DrawBackBrush: Lost Color" );
    1137             : 
    1138           6 :     SwRect aIntersect;
    1139           6 :     CalcRect( rPor, 0, &aIntersect );
    1140             : 
    1141           6 :     if ( aIntersect.HasArea() )
    1142             :     {
    1143           6 :         OutputDevice* pTmpOut = (OutputDevice*)GetOut();
    1144             : 
    1145             :         // #i16816# tagged pdf support
    1146           6 :         SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pTmpOut );
    1147             : 
    1148           6 :         pTmpOut->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
    1149             : 
    1150           6 :         pTmpOut->SetFillColor( *pFnt->GetBackColor() );
    1151           6 :         pTmpOut->SetLineColor();
    1152             : 
    1153           6 :         DrawRect( aIntersect, sal_True, sal_False );
    1154             : 
    1155           6 :         pTmpOut->Pop();
    1156             :     }
    1157             : }
    1158             : 
    1159          56 : void SwTxtPaintInfo::DrawViewOpt( const SwLinePortion &rPor,
    1160             :                                   const MSHORT nWhich ) const
    1161             : {
    1162          56 :     if( OnWin() && !IsMulti() )
    1163             :     {
    1164          56 :         bool bDraw = false;
    1165          56 :         switch( nWhich )
    1166             :         {
    1167             :             case POR_FTN:
    1168             :             case POR_QUOVADIS:
    1169             :             case POR_NUMBER:
    1170             :             case POR_FLD:
    1171             :             case POR_URL:
    1172             :             case POR_HIDDEN:
    1173             :             case POR_TOX:
    1174             :             case POR_REF:
    1175             :             case POR_META:
    1176             :             case POR_CONTROLCHAR:
    1177         164 :                 if ( !GetOpt().IsPagePreview() &&
    1178          44 :                      !GetOpt().IsReadonly() &&
    1179          44 :                      SwViewOption::IsFieldShadings() &&
    1180             :                      (POR_NUMBER != nWhich ||
    1181          32 :                       pFrm->GetTxtNode()->HasMarkedLabel())) // #i27615#
    1182          12 :                     bDraw = true;
    1183          44 :             break;
    1184           0 :             case POR_TAB:       if ( GetOpt().IsTab() )     bDraw = true; break;
    1185           4 :             case POR_SOFTHYPH:  if ( GetOpt().IsSoftHyph() )bDraw = true; break;
    1186           8 :             case POR_BLANK:     if ( GetOpt().IsHardBlank())bDraw = true; break;
    1187             :             default:
    1188             :             {
    1189             :                 OSL_ENSURE( !this, "SwTxtPaintInfo::DrawViewOpt: don't know how to draw this" );
    1190           0 :                 break;
    1191             :             }
    1192             :         }
    1193          56 :         if ( bDraw )
    1194          24 :             DrawBackground( rPor );
    1195             :     }
    1196          56 : }
    1197             : 
    1198           0 : void SwTxtPaintInfo::_NotifyURL( const SwLinePortion &rPor ) const
    1199             : {
    1200             :     OSL_ENSURE( pNoteURL, "NotifyURL: pNoteURL gone with the wind!" );
    1201             : 
    1202           0 :     SwRect aIntersect;
    1203           0 :     CalcRect( rPor, 0, &aIntersect );
    1204             : 
    1205           0 :     if( aIntersect.HasArea() )
    1206             :     {
    1207           0 :         SwTxtNode *pNd = (SwTxtNode*)GetTxtFrm()->GetTxtNode();
    1208             :         SwTxtAttr *const pAttr =
    1209           0 :             pNd->GetTxtAttrAt(GetIdx(), RES_TXTATR_INETFMT);
    1210           0 :         if( pAttr )
    1211             :         {
    1212           0 :             const SwFmtINetFmt& rFmt = pAttr->GetINetFmt();
    1213           0 :             pNoteURL->InsertURLNote( rFmt.GetValue(), rFmt.GetTargetFrame(),
    1214           0 :                 aIntersect );
    1215             :         }
    1216             :     }
    1217           0 : }
    1218             : 
    1219           2 : static void lcl_InitHyphValues( PropertyValues &rVals,
    1220             :             sal_Int16 nMinLeading, sal_Int16 nMinTrailing )
    1221             : {
    1222           2 :     sal_Int32 nLen = rVals.getLength();
    1223             : 
    1224           2 :     if (0 == nLen)  // yet to be initialized?
    1225             :     {
    1226           2 :         rVals.realloc( 2 );
    1227           2 :         PropertyValue *pVal = rVals.getArray();
    1228             : 
    1229           2 :         pVal[0].Name    = UPN_HYPH_MIN_LEADING;
    1230           2 :         pVal[0].Handle  = UPH_HYPH_MIN_LEADING;
    1231           2 :         pVal[0].Value   <<= nMinLeading;
    1232             : 
    1233           2 :         pVal[1].Name    = UPN_HYPH_MIN_TRAILING;
    1234           2 :         pVal[1].Handle  = UPH_HYPH_MIN_TRAILING;
    1235           2 :         pVal[1].Value   <<= nMinTrailing;
    1236             :     }
    1237           0 :     else if (2 == nLen) // already initialized once?
    1238             :     {
    1239           0 :         PropertyValue *pVal = rVals.getArray();
    1240           0 :         pVal[0].Value <<= nMinLeading;
    1241           0 :         pVal[1].Value <<= nMinTrailing;
    1242             :     }
    1243             :     else {
    1244             :         OSL_FAIL( "unexpected size of sequence" );
    1245             :     }
    1246           2 : }
    1247             : 
    1248           0 : const PropertyValues & SwTxtFormatInfo::GetHyphValues() const
    1249             : {
    1250             :     OSL_ENSURE( 2 == aHyphVals.getLength(),
    1251             :             "hyphenation values not yet initialized" );
    1252           0 :     return aHyphVals;
    1253             : }
    1254             : 
    1255         692 : sal_Bool SwTxtFormatInfo::InitHyph( const sal_Bool bAutoHyphen )
    1256             : {
    1257         692 :     const SwAttrSet& rAttrSet = GetTxtFrm()->GetTxtNode()->GetSwAttrSet();
    1258         692 :     SetHanging( rAttrSet.GetHangingPunctuation().GetValue() );
    1259         692 :     SetScriptSpace( rAttrSet.GetScriptSpace().GetValue() );
    1260         692 :     SetForbiddenChars( rAttrSet.GetForbiddenRule().GetValue() );
    1261         692 :     const SvxHyphenZoneItem &rAttr = rAttrSet.GetHyphenZone();
    1262         692 :     MaxHyph() = rAttr.GetMaxHyphens();
    1263         692 :     sal_Bool bAuto = bAutoHyphen || rAttr.IsHyphen();
    1264         692 :     if( bAuto || bInterHyph )
    1265             :     {
    1266           2 :         nHyphStart = nHyphWrdStart = STRING_LEN;
    1267           2 :         nHyphWrdLen = 0;
    1268             : 
    1269           2 :         const sal_Int16 nMinimalLeading  = Max(rAttr.GetMinLead(), sal_uInt8(2));
    1270           2 :         const sal_Int16 nMinimalTrailing = rAttr.GetMinTrail();
    1271           2 :         lcl_InitHyphValues( aHyphVals, nMinimalLeading, nMinimalTrailing);
    1272             :     }
    1273         692 :     return bAuto;
    1274             : }
    1275             : 
    1276         692 : void SwTxtFormatInfo::CtorInitTxtFormatInfo( SwTxtFrm *pNewFrm, const sal_Bool bNewInterHyph,
    1277             :                                 const sal_Bool bNewQuick, const sal_Bool bTst )
    1278             : {
    1279         692 :     CtorInitTxtPaintInfo( pNewFrm, SwRect() );
    1280             : 
    1281         692 :     bQuick = bNewQuick;
    1282         692 :     bInterHyph = bNewInterHyph;
    1283             : 
    1284             :     //! needs to be done in this order
    1285         692 :     nMinLeading     = 2;
    1286         692 :     nMinTrailing    = 2;
    1287         692 :     nMinWordLength  = 0;
    1288         692 :     bAutoHyph = InitHyph();
    1289             : 
    1290         692 :     bIgnoreFly = sal_False;
    1291         692 :     bFakeLineStart = sal_False;
    1292         692 :     bShift = sal_False;
    1293         692 :     bDropInit = sal_False;
    1294         692 :     bTestFormat = bTst;
    1295         692 :     nLeft = 0;
    1296         692 :     nRight = 0;
    1297         692 :     nFirst = 0;
    1298         692 :     nRealWidth = 0;
    1299         692 :     nForcedLeftMargin = 0;
    1300         692 :     pRest = 0;
    1301         692 :     nLineHeight = 0;
    1302         692 :     nLineNettoHeight = 0;
    1303         692 :     SetLineStart(0);
    1304         692 :     Init();
    1305         692 : }
    1306             : 
    1307             : /*************************************************************************
    1308             :  * SwTxtFormatInfo::IsHyphenate()
    1309             :  * If the Hyphenator returns ERROR or the language is set to NOLANGUAGE
    1310             :  * we do not hyphenate.
    1311             :  * Else, we always hyphenate if we do interactive hyphenation.
    1312             :  * If we do not do interactive hyphenation, we only hyphenate if ParaFmt is
    1313             :  * set to automatic hyphenation.
    1314             :  *************************************************************************/
    1315         101 : sal_Bool SwTxtFormatInfo::IsHyphenate() const
    1316             : {
    1317         101 :     if( !bInterHyph && !bAutoHyph )
    1318         101 :         return sal_False;
    1319             : 
    1320           0 :     LanguageType eTmp = GetFont()->GetLanguage();
    1321           0 :     if( LANGUAGE_DONTKNOW == eTmp || LANGUAGE_NONE == eTmp )
    1322           0 :         return sal_False;
    1323             : 
    1324           0 :     uno::Reference< XHyphenator > xHyph = ::GetHyphenator();
    1325           0 :     if (bInterHyph && xHyph.is())
    1326           0 :         SvxSpellWrapper::CheckHyphLang( xHyph, eTmp );
    1327             : 
    1328           0 :     if( !xHyph.is() || !xHyph->hasLocale( pBreakIt->GetLocale(eTmp) ) )
    1329           0 :         return sal_False;
    1330           0 :     return sal_True;
    1331             : }
    1332             : 
    1333             : /*************************************************************************
    1334             :  * SwTxtFormatInfo::GetDropFmt()
    1335             :  * Dropcaps called by the SwTxtFormatter::CTOR
    1336             : *************************************************************************/
    1337             : 
    1338         692 : const SwFmtDrop *SwTxtFormatInfo::GetDropFmt() const
    1339             : {
    1340         692 :     const SwFmtDrop *pDrop = &GetTxtFrm()->GetTxtNode()->GetSwAttrSet().GetDrop();
    1341         692 :     if( 1 >= pDrop->GetLines() ||
    1342           0 :         ( !pDrop->GetChars() && !pDrop->GetWholeWord() ) )
    1343         692 :         pDrop = 0;
    1344         692 :     return pDrop;
    1345             : }
    1346             : 
    1347        1447 : void SwTxtFormatInfo::Init()
    1348             : {
    1349             :     // Not initialized: pRest, nLeft, nRight, nFirst, nRealWidth
    1350        1447 :     X(0);
    1351             :     bArrowDone = bFull = bFtnDone = bErgoDone = bNumDone = bNoEndHyph =
    1352        1447 :         bNoMidHyph = bStop = bNewLine = bUnderFlow = bTabOverflow = sal_False;
    1353             : 
    1354             :     // generally we do not allow number portions in follows, except...
    1355        1447 :     if ( GetTxtFrm()->IsFollow() )
    1356             :     {
    1357           0 :         const SwTxtFrm* pMaster = GetTxtFrm()->FindMaster();
    1358             :         OSL_ENSURE(pMaster, "pTxtFrm without Master");
    1359           0 :         const SwLinePortion* pTmpPara = pMaster ? pMaster->GetPara() : NULL;
    1360             : 
    1361             :         // there is a master for this follow and the master does not have
    1362             :         // any contents (especially it does not have a number portion)
    1363             :         bNumDone = ! pTmpPara ||
    1364           0 :                    ! ((SwParaPortion*)pTmpPara)->GetFirstPortion()->IsFlyPortion();
    1365             :     }
    1366             : 
    1367        1447 :     pRoot = 0;
    1368        1447 :     pLast = 0;
    1369        1447 :     pFly = 0;
    1370        1447 :     pLastFld = 0;
    1371        1447 :     pLastTab = 0;
    1372        1447 :     pUnderFlow = 0;
    1373        1447 :     cTabDecimal = 0;
    1374        1447 :     nWidth = nRealWidth;
    1375        1447 :     nForcedLeftMargin = 0;
    1376        1447 :     nSoftHyphPos = 0;
    1377        1447 :     nUnderScorePos = STRING_LEN;
    1378        1447 :     cHookChar = 0;
    1379        1447 :     SetIdx(0);
    1380        1447 :     SetLen( GetTxt().Len() );
    1381        1447 :     SetPaintOfst(0);
    1382        1447 : }
    1383             : 
    1384             : /*--------------------------------------------------
    1385             :  * There are a few differences between a copy constructor
    1386             :  * and the following constructor for multi-line formatting.
    1387             :  * The root is the first line inside the multi-portion,
    1388             :  * the line start is the actual position in the text,
    1389             :  * the line width is the rest width from the surrounding line
    1390             :  * and the bMulti and bFirstMulti-flag has to be set correctly.
    1391             :  * --------------------------------------------------*/
    1392             : 
    1393           1 : SwTxtFormatInfo::SwTxtFormatInfo( const SwTxtFormatInfo& rInf,
    1394             :     SwLineLayout& rLay, SwTwips nActWidth ) : SwTxtPaintInfo( rInf ),
    1395           1 :     bTabOverflow( sal_False )
    1396             : {
    1397           1 :     pRoot = &rLay;
    1398           1 :     pLast = &rLay;
    1399           1 :     pFly = NULL;
    1400           1 :     pLastFld = NULL;
    1401           1 :     pUnderFlow = NULL;
    1402           1 :     pRest = NULL;
    1403           1 :     pLastTab = NULL;
    1404             : 
    1405           1 :     nSoftHyphPos = 0;
    1406           1 :     nUnderScorePos = STRING_LEN;
    1407           1 :     nHyphStart = 0;
    1408           1 :     nHyphWrdStart = 0;
    1409           1 :     nHyphWrdLen = 0;
    1410           1 :     nLineStart = rInf.GetIdx();
    1411           1 :     nLeft = rInf.nLeft;
    1412           1 :     nRight = rInf.nRight;
    1413           1 :     nFirst = rInf.nLeft;
    1414           1 :     nRealWidth = KSHORT(nActWidth);
    1415           1 :     nWidth = nRealWidth;
    1416           1 :     nLineHeight = 0;
    1417           1 :     nLineNettoHeight = 0;
    1418           1 :     nForcedLeftMargin = 0;
    1419             : 
    1420           1 :     nMinLeading = 0;
    1421           1 :     nMinTrailing = 0;
    1422           1 :     nMinWordLength = 0;
    1423           1 :     bFull = sal_False;
    1424           1 :     bFtnDone = sal_True;
    1425           1 :     bErgoDone = sal_True;
    1426           1 :     bNumDone = sal_True;
    1427           1 :     bArrowDone = sal_True;
    1428           1 :     bStop = sal_False;
    1429           1 :     bNewLine = sal_True;
    1430           1 :     bShift  = sal_False;
    1431           1 :     bUnderFlow = sal_False;
    1432           1 :     bInterHyph = sal_False;
    1433           1 :     bAutoHyph = sal_False;
    1434           1 :     bDropInit = sal_False;
    1435           1 :     bQuick  = rInf.bQuick;
    1436           1 :     bNoEndHyph  = sal_False;
    1437           1 :     bNoMidHyph  = sal_False;
    1438           1 :     bIgnoreFly = sal_False;
    1439           1 :     bFakeLineStart = sal_False;
    1440             : 
    1441           1 :     cTabDecimal = 0;
    1442           1 :     cHookChar = 0;
    1443           1 :     nMaxHyph = 0;
    1444           1 :     bTestFormat = rInf.bTestFormat;
    1445           1 :     SetMulti( sal_True );
    1446           1 :     SetFirstMulti( rInf.IsFirstMulti() );
    1447           1 : }
    1448           5 : sal_Bool SwTxtFormatInfo::_CheckFtnPortion( SwLineLayout* pCurr )
    1449             : {
    1450           5 :     KSHORT nHeight = pCurr->GetRealHeight();
    1451           5 :     SwLinePortion *pPor = pCurr->GetPortion();
    1452           5 :     sal_Bool bRet = sal_False;
    1453          22 :     while( pPor )
    1454             :     {
    1455          12 :         if( pPor->IsFtnPortion() && nHeight > ((SwFtnPortion*)pPor)->Orig() )
    1456             :         {
    1457           0 :             bRet = sal_True;
    1458           0 :             SetLineHeight( nHeight );
    1459           0 :             SetLineNettoHeight( pCurr->Height() );
    1460           0 :             break;
    1461             :         }
    1462          12 :         pPor = pPor->GetPortion();
    1463             :     }
    1464           5 :     return bRet;
    1465             : }
    1466             : 
    1467         682 : xub_StrLen SwTxtFormatInfo::ScanPortionEnd( const xub_StrLen nStart,
    1468             :                                             const xub_StrLen nEnd )
    1469             : {
    1470         682 :     cHookChar = 0;
    1471         682 :     xub_StrLen i = nStart;
    1472             : 
    1473             :     //
    1474             :     // Used for decimal tab handling:
    1475             :     //
    1476         682 :     const sal_Unicode cTabDec = GetLastTab() ? (sal_Unicode)GetTabDecimal() : 0;
    1477         682 :     const sal_Unicode cThousandSep  = ',' == cTabDec ? '.' : ',';
    1478             :     // #i45951# German (Switzerland) uses ' as thousand separator
    1479         682 :     const sal_Unicode cThousandSep2 = ',' == cTabDec ? '.' : '\'';
    1480             : 
    1481         682 :     bool bNumFound = false;
    1482         682 :     const bool bTabCompat = GetTxtFrm()->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::TAB_COMPAT);
    1483             : 
    1484       12016 :     for( ; i < nEnd; ++i )
    1485             :     {
    1486       11401 :         const sal_Unicode cPos = GetChar( i );
    1487       11401 :         switch( cPos )
    1488             :         {
    1489             :         case CH_TXTATR_BREAKWORD:
    1490             :         case CH_TXTATR_INWORD:
    1491           0 :             if( !HasHint( i ))
    1492           0 :                 break;
    1493             :             // no break;
    1494             : 
    1495             :         case CHAR_SOFTHYPHEN:
    1496             :         case CHAR_HARDHYPHEN:
    1497             :         case CHAR_HARDBLANK:
    1498             :         case CH_TAB:
    1499             :         case CH_BREAK:
    1500             :         case CHAR_ZWSP :
    1501             :         case CHAR_ZWNBSP :
    1502          67 :             cHookChar = cPos;
    1503          67 :             return i;
    1504             : 
    1505             :         case CHAR_UNDERSCORE:
    1506        1872 :             if ( STRING_LEN == nUnderScorePos )
    1507           6 :                 nUnderScorePos = i;
    1508        1872 :             break;
    1509             : 
    1510             :         default:
    1511        9462 :             if ( cTabDec )
    1512             :             {
    1513           0 :                 if( cTabDec == cPos )
    1514             :                 {
    1515             :                     OSL_ENSURE( cPos, "Unexpected end of string" );
    1516           0 :                     if( cPos ) // robust
    1517             :                     {
    1518           0 :                         cHookChar = cPos;
    1519           0 :                         return i;
    1520             :                     }
    1521             :                 }
    1522             : 
    1523             :                 //
    1524             :                 // Compatibility: First non-digit character behind a
    1525             :                 // a digit character becomes the hook character
    1526             :                 //
    1527           0 :                 if ( bTabCompat )
    1528             :                 {
    1529           0 :                     if ( ( 0x2F < cPos && cPos < 0x3A ) ||
    1530             :                          ( bNumFound && ( cPos == cThousandSep || cPos == cThousandSep2 ) ) )
    1531             :                     {
    1532           0 :                         bNumFound = true;
    1533             :                     }
    1534             :                     else
    1535             :                     {
    1536           0 :                         if ( bNumFound )
    1537             :                         {
    1538           0 :                             cHookChar = cPos;
    1539           0 :                             SetTabDecimal( cPos );
    1540           0 :                             return i;
    1541             :                         }
    1542             :                     }
    1543             :                 }
    1544             :             }
    1545             :         }
    1546             :     }
    1547             : 
    1548             :     // Check if character *behind* the portion has
    1549             :     // to become the hook:
    1550         615 :     if ( i == nEnd && i < GetTxt().Len() && bNumFound )
    1551             :     {
    1552           0 :         const sal_Unicode cPos = GetChar( i );
    1553           0 :         if ( cPos != cTabDec && cPos != cThousandSep && cPos !=cThousandSep2 && ( 0x2F >= cPos || cPos >= 0x3A ) )
    1554             :         {
    1555           0 :             cHookChar = GetChar( i );
    1556           0 :             SetTabDecimal( cHookChar );
    1557             :         }
    1558             :     }
    1559             : 
    1560         615 :     return i;
    1561             : }
    1562             : 
    1563         755 : sal_Bool SwTxtFormatInfo::LastKernPortion()
    1564             : {
    1565         755 :     if( GetLast() )
    1566             :     {
    1567         755 :          if( GetLast()->IsKernPortion() )
    1568           1 :             return sal_True;
    1569         763 :         if( GetLast()->Width() || ( GetLast()->GetLen() &&
    1570           9 :             !GetLast()->IsHolePortion() ) )
    1571         677 :             return sal_False;
    1572             :     }
    1573          77 :     SwLinePortion* pPor = GetRoot();
    1574          77 :     SwLinePortion *pKern = NULL;
    1575         251 :     while( pPor )
    1576             :     {
    1577          97 :         if( pPor->IsKernPortion() )
    1578           0 :             pKern = pPor;
    1579          97 :         else if( pPor->Width() || ( pPor->GetLen() && !pPor->IsHolePortion() ) )
    1580          20 :             pKern = NULL;
    1581          97 :         pPor = pPor->GetPortion();
    1582             :     }
    1583          77 :     if( pKern )
    1584             :     {
    1585           0 :         SetLast( pKern );
    1586           0 :         return sal_True;
    1587             :     }
    1588          77 :     return sal_False;
    1589             : }
    1590             : 
    1591          64 : SwTxtSlot::SwTxtSlot( const SwTxtSizeInfo *pNew, const SwLinePortion *pPor,
    1592             :                       bool bTxtLen, bool bExgLists, const sal_Char *pCh )
    1593             :     : pOldTxt( 0 ),
    1594             :       pOldSmartTagList( 0 ),
    1595             :       pOldGrammarCheckList( 0 ),
    1596          64 :       pTempList( 0 )
    1597             : {
    1598          64 :     if( pCh )
    1599             :     {
    1600           0 :         aTxt = XubString( pCh, RTL_TEXTENCODING_MS_1252 );
    1601           0 :         bOn = sal_True;
    1602             :     }
    1603             :     else
    1604          64 :         bOn = pPor->GetExpTxt( *pNew, aTxt );
    1605             : 
    1606             :     // Teh text is replaced ...
    1607          64 :     if( bOn )
    1608             :     {
    1609          64 :         pInf = (SwTxtSizeInfo*)pNew;
    1610          64 :         nIdx = pInf->GetIdx();
    1611          64 :         nLen = pInf->GetLen();
    1612          64 :         pOldTxt = &(pInf->GetTxt());
    1613          64 :         pInf->SetTxt( aTxt );
    1614          64 :         pInf->SetIdx( 0 );
    1615          64 :         pInf->SetLen( bTxtLen ? pInf->GetTxt().Len() : pPor->GetLen() );
    1616             : 
    1617             :         // ST2
    1618          64 :         if ( bExgLists )
    1619             :         {
    1620          56 :             pOldSmartTagList = static_cast<SwTxtPaintInfo*>(pInf)->GetSmartTags();
    1621          56 :             if ( pOldSmartTagList )
    1622             :             {
    1623           0 :                 const sal_uInt16 nPos = pOldSmartTagList->GetWrongPos(nIdx);
    1624           0 :                 const xub_StrLen nListPos = pOldSmartTagList->Pos(nPos);
    1625           0 :                 if( nListPos == nIdx )
    1626           0 :                     ((SwTxtPaintInfo*)pInf)->SetSmartTags( pOldSmartTagList->SubList( nPos ) );
    1627           0 :                 else if( !pTempList && nPos < pOldSmartTagList->Count() && nListPos < nIdx && aTxt.Len() )
    1628             :                 {
    1629           0 :                     pTempList = new SwWrongList( WRONGLIST_SMARTTAG );
    1630           0 :                     pTempList->Insert( OUString(), 0, 0, aTxt.Len(), 0 );
    1631           0 :                     ((SwTxtPaintInfo*)pInf)->SetSmartTags( pTempList );
    1632             :                 }
    1633             :                 else
    1634           0 :                     ((SwTxtPaintInfo*)pInf)->SetSmartTags( 0);
    1635             :             }
    1636          56 :             pOldGrammarCheckList = static_cast<SwTxtPaintInfo*>(pInf)->GetGrammarCheckList();
    1637          56 :             if ( pOldGrammarCheckList )
    1638             :             {
    1639           0 :                 const sal_uInt16 nPos = pOldGrammarCheckList->GetWrongPos(nIdx);
    1640           0 :                 const xub_StrLen nListPos = pOldGrammarCheckList->Pos(nPos);
    1641           0 :                 if( nListPos == nIdx )
    1642           0 :                     ((SwTxtPaintInfo*)pInf)->SetGrammarCheckList( pOldGrammarCheckList->SubList( nPos ) );
    1643           0 :                 else if( !pTempList && nPos < pOldGrammarCheckList->Count() && nListPos < nIdx && aTxt.Len() )
    1644             :                 {
    1645           0 :                     pTempList = new SwWrongList( WRONGLIST_GRAMMAR );
    1646           0 :                     pTempList->Insert( OUString(), 0, 0, aTxt.Len(), 0 );
    1647           0 :                     ((SwTxtPaintInfo*)pInf)->SetGrammarCheckList( pTempList );
    1648             :                 }
    1649             :                 else
    1650           0 :                     ((SwTxtPaintInfo*)pInf)->SetGrammarCheckList( 0);
    1651             :             }
    1652             :         }
    1653             :     }
    1654          64 : }
    1655             : 
    1656         128 : SwTxtSlot::~SwTxtSlot()
    1657             : {
    1658          64 :     if( bOn )
    1659             :     {
    1660          64 :         pInf->SetTxt( *pOldTxt );
    1661          64 :         pInf->SetIdx( nIdx );
    1662          64 :         pInf->SetLen( nLen );
    1663             : 
    1664             :         // ST2
    1665             :         // Restore old smart tag list
    1666          64 :         if ( pOldSmartTagList )
    1667           0 :             ((SwTxtPaintInfo*)pInf)->SetSmartTags( pOldSmartTagList );
    1668          64 :         if ( pOldGrammarCheckList )
    1669           0 :             ((SwTxtPaintInfo*)pInf)->SetGrammarCheckList( pOldGrammarCheckList );
    1670          64 :         delete pTempList;
    1671             :     }
    1672          64 : }
    1673             : 
    1674         326 : SwFontSave::SwFontSave( const SwTxtSizeInfo &rInf, SwFont *pNew,
    1675             :         SwAttrIter* pItr )
    1676         326 :         : pFnt( pNew ? ((SwTxtSizeInfo&)rInf).GetFont() : 0 )
    1677             : {
    1678         326 :     if( pFnt )
    1679             :     {
    1680         306 :         pInf = &((SwTxtSizeInfo&)rInf);
    1681             :         // In these cases we temporarily switch to the new font:
    1682             :         // 1. the fonts have a different magic number
    1683             :         // 2. they have different script types
    1684             :         // 3. their background colors differ (this is not covered by 1.)
    1685        1306 :         if( pFnt->DifferentMagic( pNew, pFnt->GetActual() ) ||
    1686         200 :             pNew->GetActual() != pFnt->GetActual() ||
    1687         400 :             ( ! pNew->GetBackColor() && pFnt->GetBackColor() ) ||
    1688         200 :             ( pNew->GetBackColor() && ! pFnt->GetBackColor() ) ||
    1689         200 :             ( pNew->GetBackColor() && pFnt->GetBackColor() &&
    1690           0 :               ( *pNew->GetBackColor() != *pFnt->GetBackColor() ) ) )
    1691             :         {
    1692         106 :             pNew->SetTransparent( sal_True );
    1693         106 :             pNew->SetAlign( ALIGN_BASELINE );
    1694         106 :             pInf->SetFont( pNew );
    1695             :         }
    1696             :         else
    1697         200 :             pFnt = 0;
    1698         306 :         pNew->Invalidate();
    1699         306 :         pNew->ChgPhysFnt( pInf->GetVsh(), *pInf->GetOut() );
    1700         306 :         if( pItr && pItr->GetFnt() == pFnt )
    1701             :         {
    1702           0 :             pIter = pItr;
    1703           0 :             pIter->SetFnt( pNew );
    1704             :         }
    1705             :         else
    1706         306 :             pIter = NULL;
    1707             :     }
    1708         326 : }
    1709             : 
    1710         326 : SwFontSave::~SwFontSave()
    1711             : {
    1712         326 :     if( pFnt )
    1713             :     {
    1714             :         // Reset SwFont
    1715         106 :         pFnt->Invalidate();
    1716         106 :         pInf->SetFont( pFnt );
    1717         106 :         if( pIter )
    1718             :         {
    1719           0 :             pIter->SetFnt( pFnt );
    1720           0 :             pIter->nPos = STRING_LEN;
    1721             :         }
    1722             :     }
    1723         326 : }
    1724             : 
    1725           0 : SwDefFontSave::SwDefFontSave( const SwTxtSizeInfo &rInf )
    1726           0 :         : pFnt( ((SwTxtSizeInfo&)rInf).GetFont()  )
    1727             : {
    1728           0 :     const bool bTmpAlter = pFnt->GetFixKerning() ||
    1729           0 :          ( RTL_TEXTENCODING_SYMBOL == pFnt->GetCharSet(pFnt->GetActual()) )
    1730             :         ;
    1731             : 
    1732             :     const bool bFamily = bTmpAlter &&
    1733           0 :           pFnt->GetName( pFnt->GetActual() ) != numfunc::GetDefBulletFontname();
    1734           0 :     const bool bRotation = pFnt->GetOrientation() &&
    1735           0 :                                 ! rInf.GetTxtFrm()->IsVertical();
    1736             : 
    1737           0 :     if( bFamily || bRotation )
    1738             :     {
    1739           0 :         pNewFnt = new SwFont( *pFnt );
    1740             : 
    1741           0 :         if ( bFamily )
    1742             :         {
    1743           0 :             pNewFnt->SetFamily( FAMILY_DONTKNOW, pFnt->GetActual() );
    1744           0 :             pNewFnt->SetName( numfunc::GetDefBulletFontname(), pFnt->GetActual() );
    1745           0 :             pNewFnt->SetStyleName( aEmptyStr, pFnt->GetActual() );
    1746           0 :             pNewFnt->SetCharSet( RTL_TEXTENCODING_SYMBOL, pFnt->GetActual() );
    1747           0 :             pNewFnt->SetFixKerning( 0 );
    1748             :         }
    1749             : 
    1750           0 :         if ( bRotation )
    1751           0 :             pNewFnt->SetVertical( 0, rInf.GetTxtFrm()->IsVertical() );
    1752             : 
    1753           0 :         pInf = &((SwTxtSizeInfo&)rInf);
    1754           0 :         pNewFnt->Invalidate();
    1755           0 :         pInf->SetFont( pNewFnt );
    1756             :     }
    1757             :     else
    1758             :     {
    1759           0 :         pFnt = 0;
    1760           0 :         pNewFnt = 0;
    1761             :     }
    1762           0 : }
    1763             : 
    1764           0 : SwDefFontSave::~SwDefFontSave()
    1765             : {
    1766           0 :     if( pFnt )
    1767             :     {
    1768           0 :         delete pNewFnt;
    1769             :         // Reset SwFont
    1770           0 :         pFnt->Invalidate();
    1771           0 :         pInf->SetFont( pFnt );
    1772             :     }
    1773           0 : }
    1774             : 
    1775           0 : sal_Bool SwTxtFormatInfo::ChgHyph( const sal_Bool bNew )
    1776             : {
    1777           0 :     const sal_Bool bOld = bAutoHyph;
    1778           0 :     if( bAutoHyph != bNew )
    1779             :     {
    1780           0 :         bAutoHyph = bNew;
    1781           0 :         InitHyph( bNew );
    1782             :         // Set language in the Hyphenator
    1783           0 :         if( pFnt )
    1784           0 :             pFnt->ChgPhysFnt( pVsh, *pOut );
    1785             :     }
    1786           0 :     return bOld;
    1787             : }
    1788             : 
    1789             : 
    1790             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10