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

Generated by: LCOV version 1.10