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

Generated by: LCOV version 1.11