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

Generated by: LCOV version 1.10