LCOV - code coverage report
Current view: top level - sw/source/core/text - txtdrop.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 517 0.0 %
Date: 2014-04-14 Functions: 0 24 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <hintids.hxx>
      21             : #include <vcl/metric.hxx>
      22             : #include <vcl/window.hxx>
      23             : #include <vcl/svapp.hxx>
      24             : #include <paratr.hxx>
      25             : #include <txtfrm.hxx>
      26             : #include <charfmt.hxx>
      27             : #include <viewopt.hxx>
      28             : #include <viewsh.hxx>
      29             : #include <pordrop.hxx>
      30             : #include <itrform2.hxx>
      31             : #include <txtpaint.hxx>
      32             : #include <blink.hxx>
      33             : #include <breakit.hxx>
      34             : #include <com/sun/star/i18n/ScriptType.hpp>
      35             : #include <com/sun/star/i18n/WordType.hpp>
      36             : #include <editeng/langitem.hxx>
      37             : #include <charatr.hxx>
      38             : #include <editeng/fhgtitem.hxx>
      39             : #include <switerator.hxx>
      40             : 
      41             : using namespace ::com::sun::star::i18n;
      42             : using namespace ::com::sun::star;
      43             : 
      44             : /*************************************************************************
      45             :  *                lcl_IsDropFlyInter
      46             :  *
      47             :  *  Calculates if a drop caps portion intersects with a fly
      48             :  *  The width and height of the drop caps portion are passed as arguments,
      49             :  *  the position is calculated from the values in rInf
      50             :  *************************************************************************/
      51             : 
      52           0 : static bool lcl_IsDropFlyInter( const SwTxtFormatInfo &rInf,
      53             :                              sal_uInt16 nWidth, sal_uInt16 nHeight )
      54             : {
      55           0 :     const SwTxtFly *pTxtFly = rInf.GetTxtFly();
      56           0 :     if( pTxtFly && pTxtFly->IsOn() )
      57             :     {
      58           0 :         SwRect aRect( rInf.GetTxtFrm()->Frm().Pos(), Size( nWidth, nHeight) );
      59           0 :         aRect.Pos() += rInf.GetTxtFrm()->Prt().Pos();
      60           0 :         aRect.Pos().X() += rInf.X();
      61           0 :         aRect.Pos().Y() = rInf.Y();
      62           0 :         aRect = pTxtFly->GetFrm( aRect );
      63           0 :         return aRect.HasArea();
      64             :     }
      65             : 
      66           0 :     return false;
      67             : }
      68             : 
      69             : class SwDropSave
      70             : {
      71             :     SwTxtPaintInfo* pInf;
      72             :     sal_Int32 nIdx;
      73             :     sal_Int32 nLen;
      74             :     long nX;
      75             :     long nY;
      76             : 
      77             : public:
      78             :     SwDropSave( const SwTxtPaintInfo &rInf );
      79             :     ~SwDropSave();
      80             : };
      81             : 
      82           0 : SwDropSave::SwDropSave( const SwTxtPaintInfo &rInf ) :
      83           0 :         pInf( ((SwTxtPaintInfo*)&rInf) ), nIdx( rInf.GetIdx() ),
      84           0 :         nLen( rInf.GetLen() ), nX( rInf.X() ), nY( rInf.Y() )
      85             : {
      86           0 : }
      87             : 
      88           0 : SwDropSave::~SwDropSave()
      89             : {
      90           0 :     pInf->SetIdx( nIdx );
      91           0 :     pInf->SetLen( nLen );
      92           0 :     pInf->X( nX );
      93           0 :     pInf->Y( nY );
      94           0 : }
      95             : 
      96             : // SwDropPortionPart DTor
      97           0 : SwDropPortionPart::~SwDropPortionPart()
      98             : {
      99           0 :     delete pFollow;
     100           0 :     delete pFnt;
     101           0 : }
     102             : 
     103             : // SwDropPortion CTor, DTor
     104           0 : SwDropPortion::SwDropPortion( const MSHORT nLineCnt,
     105             :                               const KSHORT nDrpHeight,
     106             :                               const KSHORT nDrpDescent,
     107             :                               const KSHORT nDist )
     108             :   : pPart( 0 ),
     109             :     nLines( nLineCnt ),
     110             :     nDropHeight(nDrpHeight),
     111             :     nDropDescent(nDrpDescent),
     112             :     nDistance(nDist),
     113             :     nFix(0),
     114             :     nX(0),
     115           0 :     nY(0)
     116             : {
     117           0 :     SetWhichPor( POR_DROP );
     118           0 : }
     119             : 
     120           0 : SwDropPortion::~SwDropPortion()
     121             : {
     122           0 :     delete pPart;
     123           0 :     if( pBlink )
     124           0 :         pBlink->Delete( this );
     125           0 : }
     126             : 
     127             : // nWishLen = 0 indicates that we want a whole word
     128           0 : MSHORT SwTxtNode::GetDropLen( MSHORT nWishLen ) const
     129             : {
     130           0 :     sal_Int32 nEnd = GetTxt().getLength();
     131           0 :     if( nWishLen && nWishLen < nEnd )
     132           0 :         nEnd = nWishLen;
     133             : 
     134           0 :     if ( ! nWishLen && g_pBreakIt->GetBreakIter().is() )
     135             :     {
     136             :         // find first word
     137           0 :         const SwAttrSet& rAttrSet = GetSwAttrSet();
     138           0 :         const sal_uInt16 nTxtScript = g_pBreakIt->GetRealScriptOfText( GetTxt(), 0 );
     139             : 
     140             :         LanguageType eLanguage;
     141             : 
     142           0 :         switch ( nTxtScript )
     143             :         {
     144             :         case i18n::ScriptType::ASIAN :
     145           0 :             eLanguage = rAttrSet.GetCJKLanguage().GetLanguage();
     146           0 :             break;
     147             :         case i18n::ScriptType::COMPLEX :
     148           0 :             eLanguage = rAttrSet.GetCTLLanguage().GetLanguage();
     149           0 :             break;
     150             :         default :
     151           0 :             eLanguage = rAttrSet.GetLanguage().GetLanguage();
     152           0 :             break;
     153             :         }
     154             : 
     155             :         Boundary aBound =
     156           0 :             g_pBreakIt->GetBreakIter()->getWordBoundary( GetTxt(), 0,
     157           0 :             g_pBreakIt->GetLocale( eLanguage ), WordType::DICTIONARY_WORD, true );
     158             : 
     159           0 :         nEnd = aBound.endPos;
     160             :     }
     161             : 
     162           0 :     sal_Int32 i = 0;
     163           0 :     for( ; i < nEnd; ++i )
     164             :     {
     165           0 :         sal_Unicode const cChar = GetTxt()[i];
     166           0 :         if( CH_TAB == cChar || CH_BREAK == cChar ||
     167           0 :             (( CH_TXTATR_BREAKWORD == cChar || CH_TXTATR_INWORD == cChar )
     168           0 :                 && SwTxtSizeInfo::_HasHint( this, i ) ) )
     169           0 :             break;
     170             :     }
     171           0 :     return i;
     172             : }
     173             : 
     174             : /*************************************************************************
     175             :  *                    SwTxtNode::GetDropSize()
     176             :  *
     177             :  *  If a dropcap is found the return value is true otherwise false. The
     178             :  *  drop cap sizes passed back by reference are font height, drop height
     179             :  *  and drop descent.
     180             :  *************************************************************************/
     181           0 : bool SwTxtNode::GetDropSize(int& rFontHeight, int& rDropHeight, int& rDropDescent) const
     182             : {
     183           0 :     rFontHeight = 0;
     184           0 :     rDropHeight = 0;
     185           0 :     rDropDescent =0;
     186             : 
     187           0 :     const SwAttrSet& rSet = GetSwAttrSet();
     188           0 :     const SwFmtDrop& rDrop = rSet.GetDrop();
     189             : 
     190             :     // Return (0,0) if there is no drop cap at this paragraph
     191           0 :     if( 1 >= rDrop.GetLines() ||
     192           0 :         ( !rDrop.GetChars() && !rDrop.GetWholeWord() ) )
     193             :     {
     194           0 :         return false;
     195             :     }
     196             : 
     197             :     // get text frame
     198           0 :     SwIterator<SwTxtFrm,SwTxtNode> aIter( *this );
     199           0 :     for( SwTxtFrm* pLastFrm = aIter.First(); pLastFrm; pLastFrm = aIter.Next() )
     200             :     {
     201             :         // Only (master-) text frames can have a drop cap.
     202           0 :         if ( !pLastFrm->IsFollow() )
     203             :         {
     204             : 
     205           0 :             if( !pLastFrm->HasPara() )
     206           0 :                 pLastFrm->GetFormatted();
     207             : 
     208           0 :             if ( !pLastFrm->IsEmpty() )
     209             :             {
     210           0 :                 const SwParaPortion* pPara = pLastFrm->GetPara();
     211             :                 OSL_ENSURE( pPara, "GetDropSize could not find the ParaPortion, I'll guess the drop cap size" );
     212             : 
     213           0 :                 if ( pPara )
     214             :                 {
     215           0 :                     const SwLinePortion* pFirstPor = pPara->GetFirstPortion();
     216           0 :                     if (pFirstPor && pFirstPor->IsDropPortion())
     217             :                     {
     218           0 :                         const SwDropPortion* pDrop = (const SwDropPortion*)pFirstPor;
     219           0 :                         rDropHeight = pDrop->GetDropHeight();
     220           0 :                         rDropDescent = pDrop->GetDropDescent();
     221           0 :                         if (const SwFont *pFont = pDrop->GetFnt())
     222           0 :                             rFontHeight = pFont->GetSize(pFont->GetActual()).Height();
     223             :                         else
     224             :                         {
     225           0 :                             const SvxFontHeightItem& rItem = (SvxFontHeightItem&)rSet.Get(RES_CHRATR_FONTSIZE);
     226           0 :                             rFontHeight = rItem.GetHeight();
     227             :                         }
     228             :                     }
     229             :                 }
     230             :             }
     231           0 :             break;
     232             :         }
     233             :     }
     234             : 
     235           0 :     if (rFontHeight==0 && rDropHeight==0 && rDropDescent==0)
     236             :     {
     237           0 :         const sal_uInt16 nLines = rDrop.GetLines();
     238             : 
     239           0 :         const SvxFontHeightItem& rItem = (SvxFontHeightItem&)rSet.Get( RES_CHRATR_FONTSIZE );
     240           0 :         rFontHeight = rItem.GetHeight();
     241           0 :         rDropHeight = nLines * rFontHeight;
     242           0 :         rDropDescent = rFontHeight / 5;
     243           0 :         return false;
     244             :     }
     245             : 
     246           0 :     return true;
     247             : }
     248             : 
     249             : // Manipulate the width, otherwise the chars are being stretched
     250           0 : void SwDropPortion::PaintTxt( const SwTxtPaintInfo &rInf ) const
     251             : {
     252             :     OSL_ENSURE( nDropHeight && pPart && nLines != 1, "Drop Portion painted twice" );
     253             : 
     254           0 :     const SwDropPortionPart* pCurrPart = GetPart();
     255           0 :     const sal_Int32 nOldLen = GetLen();
     256           0 :     const KSHORT nOldWidth = Width();
     257           0 :     const KSHORT nOldAscent = GetAscent();
     258             : 
     259           0 :     const SwTwips nBasePosY  = rInf.Y();
     260           0 :     ((SwTxtPaintInfo&)rInf).Y( nBasePosY + nY );
     261           0 :     ((SwDropPortion*)this)->SetAscent( nOldAscent + nY );
     262           0 :     SwDropSave aSave( rInf );
     263             :     // for text inside drop portions we let vcl handle the text directions
     264           0 :     SwLayoutModeModifier aLayoutModeModifier( *rInf.GetOut() );
     265           0 :     aLayoutModeModifier.SetAuto();
     266             : 
     267           0 :     while ( pCurrPart )
     268             :     {
     269           0 :         ((SwDropPortion*)this)->SetLen( pCurrPart->GetLen() );
     270           0 :         ((SwDropPortion*)this)->Width( pCurrPart->GetWidth() );
     271           0 :         ((SwTxtPaintInfo&)rInf).SetLen( pCurrPart->GetLen() );
     272           0 :         SwFontSave aFontSave( rInf, &pCurrPart->GetFont() );
     273           0 :         const_cast<SwDropPortion*>(this)->SetJoinBorderWithNext(pCurrPart->GetJoinBorderWithNext());
     274           0 :         const_cast<SwDropPortion*>(this)->SetJoinBorderWithPrev(pCurrPart->GetJoinBorderWithPrev());
     275             : 
     276           0 :         if ( rInf.OnWin() &&
     277           0 :             !rInf.GetOpt().IsPagePreview() && !rInf.GetOpt().IsReadonly() && SwViewOption::IsFieldShadings() &&
     278           0 :             (!pCurrPart->GetFont().GetBackColor() || *pCurrPart->GetFont().GetBackColor() == Color(COL_TRANSPARENT)) )
     279             :         {
     280           0 :             rInf.DrawBackground( *this );
     281             :         }
     282             : 
     283           0 :         SwTxtPortion::Paint( rInf );
     284             : 
     285           0 :         ((SwTxtPaintInfo&)rInf).SetIdx( rInf.GetIdx() + pCurrPart->GetLen() );
     286           0 :         ((SwTxtPaintInfo&)rInf).X( rInf.X() + pCurrPart->GetWidth() );
     287           0 :         pCurrPart = pCurrPart->GetFollow();
     288           0 :     }
     289             : 
     290           0 :     ((SwTxtPaintInfo&)rInf).Y( nBasePosY );
     291           0 :     ((SwDropPortion*)this)->Width( nOldWidth );
     292           0 :     ((SwDropPortion*)this)->SetLen( nOldLen );
     293           0 :     ((SwDropPortion*)this)->SetAscent( nOldAscent );
     294           0 :     const_cast<SwDropPortion*>(this)->SetJoinBorderWithNext(false);
     295           0 :     const_cast<SwDropPortion*>(this)->SetJoinBorderWithPrev(false);
     296           0 : }
     297             : 
     298           0 : void SwDropPortion::PaintDrop( const SwTxtPaintInfo &rInf ) const
     299             : {
     300             :     // normal output is being done during the normal painting
     301           0 :     if( ! nDropHeight || ! pPart || nLines == 1 )
     302           0 :         return;
     303             : 
     304             :     // set the lying values
     305           0 :     const KSHORT nOldHeight = Height();
     306           0 :     const KSHORT nOldWidth  = Width();
     307           0 :     const KSHORT nOldAscent = GetAscent();
     308           0 :     const SwTwips nOldPosY  = rInf.Y();
     309           0 :     const KSHORT nOldPosX   = (KSHORT)rInf.X();
     310           0 :     const SwParaPortion *pPara = rInf.GetParaPortion();
     311           0 :     const Point aOutPos( nOldPosX + nX, nOldPosY - pPara->GetAscent()
     312           0 :                          - pPara->GetRealHeight() + pPara->Height() );
     313             :     // make good for retouching
     314             : 
     315             :     // Set baseline
     316           0 :     ((SwTxtPaintInfo&)rInf).Y( aOutPos.Y() + nDropHeight );
     317             : 
     318             :     // for background
     319           0 :     ((SwDropPortion*)this)->Height( nDropHeight + nDropDescent );
     320           0 :     ((SwDropPortion*)this)->Width( Width() - nX );
     321           0 :     ((SwDropPortion*)this)->SetAscent( nDropHeight );
     322             : 
     323             :     // adapt Clipregion to us
     324             :     // Und zwar immer, und nie mit dem bestehenden ClipRect
     325             :     // verrechnen, weil dies auf die Zeile eingestellt sein koennte.
     326             : 
     327           0 :     SwRect aClipRect;
     328           0 :     if ( rInf.OnWin() )
     329             :     {
     330           0 :         aClipRect = SwRect( aOutPos, SvLSize() );
     331           0 :         aClipRect.Intersection( rInf.GetPaintRect() );
     332             :     }
     333           0 :     SwSaveClip aClip( (OutputDevice*)rInf.GetOut() );
     334           0 :     aClip.ChgClip( aClipRect, rInf.GetTxtFrm() );
     335             :     // Das machen, was man sonst nur macht ...
     336           0 :     PaintTxt( rInf );
     337             : 
     338             :     // save old values
     339           0 :     ((SwDropPortion*)this)->Height( nOldHeight );
     340           0 :     ((SwDropPortion*)this)->Width( nOldWidth );
     341           0 :     ((SwDropPortion*)this)->SetAscent( nOldAscent );
     342           0 :     ((SwTxtPaintInfo&)rInf).Y( nOldPosY );
     343             : }
     344             : 
     345           0 : void SwDropPortion::Paint( const SwTxtPaintInfo &rInf ) const
     346             : {
     347             :     // normal output is being done here
     348           0 :     if( ! nDropHeight || ! pPart || 1 == nLines )
     349             :     {
     350           0 :         if ( rInf.OnWin() &&
     351           0 :             !rInf.GetOpt().IsPagePreview() && !rInf.GetOpt().IsReadonly() && SwViewOption::IsFieldShadings()       )
     352           0 :             rInf.DrawBackground( *this );
     353             : 
     354             :         // make sure that font is not rotated
     355           0 :         SwFont* pTmpFont = 0;
     356           0 :         if ( rInf.GetFont()->GetOrientation( rInf.GetTxtFrm()->IsVertical() ) )
     357             :         {
     358           0 :             pTmpFont = new SwFont( *rInf.GetFont() );
     359           0 :             pTmpFont->SetVertical( 0, rInf.GetTxtFrm()->IsVertical() );
     360             :         }
     361             : 
     362           0 :         SwFontSave aFontSave( rInf, pTmpFont );
     363             :         // for text inside drop portions we let vcl handle the text directions
     364           0 :         SwLayoutModeModifier aLayoutModeModifier( *rInf.GetOut() );
     365           0 :         aLayoutModeModifier.SetAuto();
     366             : 
     367           0 :         SwTxtPortion::Paint( rInf );
     368           0 :         delete pTmpFont;
     369             :     }
     370           0 : }
     371             : 
     372           0 : bool SwDropPortion::FormatTxt( SwTxtFormatInfo &rInf )
     373             : {
     374           0 :     const sal_Int32 nOldLen = GetLen();
     375           0 :     const sal_Int32 nOldInfLen = rInf.GetLen();
     376           0 :     if (!SwTxtPortion::Format( rInf ))
     377           0 :         return false;
     378             : 
     379             :     // looks like shit, but what can we do?
     380           0 :     rInf.SetUnderflow( 0 );
     381           0 :     Truncate();
     382           0 :     SetLen( nOldLen );
     383           0 :     rInf.SetLen( nOldInfLen );
     384           0 :     return true;
     385             : }
     386             : 
     387           0 : SwPosSize SwDropPortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const
     388             : {
     389           0 :     sal_uInt16 nMyX = 0;
     390           0 :     sal_Int32 nIdx = 0;
     391             : 
     392           0 :     const SwDropPortionPart* pCurrPart = GetPart();
     393             : 
     394             :     // skip parts
     395           0 :     while ( pCurrPart && nIdx + pCurrPart->GetLen() < rInf.GetLen() )
     396             :     {
     397           0 :         nMyX = nMyX + pCurrPart->GetWidth();
     398           0 :         nIdx = nIdx + pCurrPart->GetLen();
     399           0 :         pCurrPart = pCurrPart->GetFollow();
     400             :     }
     401             : 
     402           0 :     sal_Int32 nOldIdx = rInf.GetIdx();
     403           0 :     sal_Int32 nOldLen = rInf.GetLen();
     404             : 
     405           0 :     ((SwTxtSizeInfo&)rInf).SetIdx( nIdx );
     406           0 :     ((SwTxtSizeInfo&)rInf).SetLen( rInf.GetLen() - nIdx );
     407             : 
     408           0 :     if( pCurrPart )
     409             :     {
     410           0 :         const_cast<SwDropPortion*>(this)->SetJoinBorderWithNext(pCurrPart->GetJoinBorderWithNext());
     411           0 :         const_cast<SwDropPortion*>(this)->SetJoinBorderWithPrev(pCurrPart->GetJoinBorderWithPrev());
     412             :     }
     413             : 
     414             :     // robust
     415           0 :     SwFontSave aFontSave( rInf, pCurrPart ? &pCurrPart->GetFont() : 0 );
     416           0 :     SwPosSize aPosSize( SwTxtPortion::GetTxtSize( rInf ) );
     417           0 :     aPosSize.Width( aPosSize.Width() + nMyX );
     418             : 
     419           0 :     ((SwTxtSizeInfo&)rInf).SetIdx( nOldIdx );
     420           0 :     ((SwTxtSizeInfo&)rInf).SetLen( nOldLen );
     421           0 :     if( pCurrPart )
     422             :     {
     423           0 :         const_cast<SwDropPortion*>(this)->SetJoinBorderWithNext(false);
     424           0 :         const_cast<SwDropPortion*>(this)->SetJoinBorderWithPrev(false);
     425             :     }
     426             : 
     427           0 :     return aPosSize;
     428             : }
     429             : 
     430           0 : sal_Int32 SwDropPortion::GetCrsrOfst( const KSHORT ) const
     431             : {
     432           0 :     return 0;
     433             : }
     434             : 
     435           0 : void SwTxtFormatter::CalcDropHeight( const MSHORT nLines )
     436             : {
     437           0 :     const SwLinePortion *const pOldCurr = GetCurr();
     438           0 :     KSHORT nDropHght = 0;
     439           0 :     KSHORT nAscent = 0;
     440           0 :     KSHORT nHeight = 0;
     441           0 :     KSHORT nDropLns = 0;
     442           0 :     const bool bRegisterOld = IsRegisterOn();
     443           0 :     bRegisterOn = false;
     444             : 
     445           0 :     Top();
     446             : 
     447           0 :     while( GetCurr()->IsDummy() )
     448             :     {
     449           0 :         if ( !Next() )
     450           0 :             break;
     451             :     }
     452             : 
     453             :     // If we have only one line we return 0
     454           0 :     if( GetNext() || GetDropLines() == 1 )
     455             :     {
     456           0 :         for( ; nDropLns < nLines; nDropLns++ )
     457             :         {
     458           0 :             if ( GetCurr()->IsDummy() )
     459           0 :                 break;
     460             :             else
     461             :             {
     462           0 :                 CalcAscentAndHeight( nAscent, nHeight );
     463           0 :                 nDropHght = nDropHght + nHeight;
     464           0 :                 bRegisterOn = bRegisterOld;
     465             :             }
     466           0 :             if ( !Next() )
     467             :             {
     468           0 :                 nDropLns++; // Fix: 11356
     469           0 :                 break;
     470             :             }
     471             :         }
     472             : 
     473             :         // In der letzten Zeile plumpsen wir auf den Zeilenascent!
     474           0 :         nDropHght = nDropHght - nHeight;
     475           0 :         nDropHght = nDropHght + nAscent;
     476           0 :         Top();
     477             :     }
     478           0 :     bRegisterOn = bRegisterOld;
     479           0 :     SetDropDescent( nHeight - nAscent );
     480           0 :     SetDropHeight( nDropHght );
     481           0 :     SetDropLines( nDropLns );
     482             :     // Alte Stelle wiederfinden!
     483           0 :     while( pOldCurr != GetCurr() )
     484             :     {
     485           0 :         if( !Next() )
     486             :         {
     487             :             OSL_ENSURE( !this, "SwTxtFormatter::_CalcDropHeight: left Toulouse" );
     488           0 :             break;
     489             :         }
     490             :     }
     491           0 : }
     492             : 
     493             : /*************************************************************************
     494             :  *                SwTxtFormatter::GuessDropHeight()
     495             :  *
     496             :  *  We assume hat the font height doesn't change and that at first there
     497             :  *  are at least as many lines, as the DropCap-setting claims
     498             :  *
     499             :  *************************************************************************/
     500           0 : void SwTxtFormatter::GuessDropHeight( const MSHORT nLines )
     501             : {
     502             :     OSL_ENSURE( nLines, "GuessDropHeight: Give me more Lines!" );
     503           0 :     KSHORT nAscent = 0;
     504           0 :     KSHORT nHeight = 0;
     505           0 :     SetDropLines( nLines );
     506           0 :     if ( GetDropLines() > 1 )
     507             :     {
     508           0 :         CalcRealHeight();
     509           0 :         CalcAscentAndHeight( nAscent, nHeight );
     510             :     }
     511           0 :     SetDropDescent( nHeight - nAscent );
     512           0 :     SetDropHeight( nHeight * nLines - GetDropDescent() );
     513           0 : }
     514             : 
     515           0 : SwDropPortion *SwTxtFormatter::NewDropPortion( SwTxtFormatInfo &rInf )
     516             : {
     517           0 :     if( !pDropFmt )
     518           0 :         return 0;
     519             : 
     520           0 :     sal_Int32 nPorLen = pDropFmt->GetWholeWord() ? 0 : pDropFmt->GetChars();
     521           0 :     nPorLen = pFrm->GetTxtNode()->GetDropLen( nPorLen );
     522           0 :     if( !nPorLen )
     523             :     {
     524           0 :         ((SwTxtFormatter*)this)->ClearDropFmt();
     525           0 :         return 0;
     526             :     }
     527             : 
     528           0 :     SwDropPortion *pDropPor = 0;
     529             : 
     530             :     // first or second round?
     531           0 :     if ( !( GetDropHeight() || IsOnceMore() ) )
     532             :     {
     533           0 :         if ( GetNext() )
     534           0 :             CalcDropHeight( pDropFmt->GetLines() );
     535             :         else
     536           0 :             GuessDropHeight( pDropFmt->GetLines() );
     537             :     }
     538             : 
     539             :     // the DropPortion
     540           0 :     if( GetDropHeight() )
     541           0 :         pDropPor = new SwDropPortion( GetDropLines(), GetDropHeight(),
     542           0 :                                       GetDropDescent(), pDropFmt->GetDistance() );
     543             :     else
     544           0 :         pDropPor = new SwDropPortion( 0,0,0,pDropFmt->GetDistance() );
     545             : 
     546           0 :     pDropPor->SetLen( nPorLen );
     547             : 
     548             :     // If it was not possible to create a proper drop cap portion
     549             :     // due to avoiding endless loops. We return a drop cap portion
     550             :     // with an empty SwDropCapPart. For these portions the current
     551             :     // font is used.
     552           0 :     if ( GetDropLines() < 2 )
     553             :     {
     554           0 :         ((SwTxtFormatter*)this)->SetPaintDrop( true );
     555           0 :         return pDropPor;
     556             :     }
     557             : 
     558             :     // build DropPortionParts:
     559             :     OSL_ENSURE( ! rInf.GetIdx(), "Drop Portion not at 0 position!" );
     560           0 :     sal_Int32 nNextChg = 0;
     561           0 :     const SwCharFmt* pFmt = pDropFmt->GetCharFmt();
     562           0 :     SwDropPortionPart* pCurrPart = 0;
     563             : 
     564           0 :     while ( nNextChg  < nPorLen )
     565             :     {
     566             :         // check for attribute changes and if the portion has to split:
     567           0 :         Seek( nNextChg );
     568             : 
     569             :         // the font is deleted in the destructor of the drop portion part
     570           0 :         SwFont* pTmpFnt = new SwFont( *rInf.GetFont() );
     571           0 :         if ( pFmt )
     572             :         {
     573           0 :             const SwAttrSet& rSet = pFmt->GetAttrSet();
     574           0 :             pTmpFnt->SetDiffFnt( &rSet, pFrm->GetTxtNode()->getIDocumentSettingAccess() );
     575             :         }
     576             : 
     577             :         // we do not allow a vertical font for the drop portion
     578           0 :         pTmpFnt->SetVertical( 0, rInf.GetTxtFrm()->IsVertical() );
     579             : 
     580             :         // find next attribute change / script change
     581           0 :         const sal_Int32 nTmpIdx = nNextChg;
     582           0 :         sal_Int32 nNextAttr = std::min( static_cast<sal_Int32>(GetNextAttr()), rInf.GetTxt().getLength() );
     583           0 :         nNextChg = pScriptInfo->NextScriptChg( nTmpIdx );
     584           0 :         if( nNextChg > nNextAttr )
     585           0 :             nNextChg = nNextAttr;
     586           0 :         if ( nNextChg > nPorLen )
     587           0 :             nNextChg = nPorLen;
     588             : 
     589             :         SwDropPortionPart* pPart =
     590           0 :                 new SwDropPortionPart( *pTmpFnt, nNextChg - nTmpIdx );
     591             : 
     592           0 :         if ( ! pCurrPart )
     593           0 :             pDropPor->SetPart( pPart );
     594             :         else
     595           0 :             pCurrPart->SetFollow( pPart );
     596             : 
     597           0 :         pCurrPart = pPart;
     598             :     }
     599             : 
     600           0 :     ((SwTxtFormatter*)this)->SetPaintDrop( true );
     601           0 :     return pDropPor;
     602             : }
     603             : 
     604           0 : void SwTxtPainter::PaintDropPortion()
     605             : {
     606           0 :     const SwDropPortion *pDrop = GetInfo().GetParaPortion()->FindDropPortion();
     607             :     OSL_ENSURE( pDrop, "DrapCop-Portion not available." );
     608           0 :     if( !pDrop )
     609           0 :         return;
     610             : 
     611           0 :     const SwTwips nOldY = GetInfo().Y();
     612             : 
     613           0 :     Top();
     614             : 
     615           0 :     GetInfo().SetpSpaceAdd( pCurr->GetpLLSpaceAdd() );
     616           0 :     GetInfo().ResetSpaceIdx();
     617           0 :     GetInfo().SetKanaComp( pCurr->GetpKanaComp() );
     618           0 :     GetInfo().ResetKanaIdx();
     619             : 
     620             :     // 8047: Drops and Dummies
     621           0 :     while( !pCurr->GetLen() && Next() )
     622             :         ;
     623             : 
     624             :     // MarginPortion und Adjustment!
     625           0 :     const SwLinePortion *pPor = pCurr->GetFirstPortion();
     626           0 :     KSHORT nX = 0;
     627           0 :     while( pPor && !pPor->IsDropPortion() )
     628             :     {
     629           0 :         nX = nX + pPor->Width();
     630           0 :         pPor = pPor->GetPortion();
     631             :     }
     632           0 :     Point aLineOrigin( GetTopLeft() );
     633             : 
     634           0 :     aLineOrigin.X() += nX;
     635             :     KSHORT nTmpAscent, nTmpHeight;
     636           0 :     CalcAscentAndHeight( nTmpAscent, nTmpHeight );
     637           0 :     aLineOrigin.Y() += nTmpAscent;
     638           0 :     GetInfo().SetIdx( GetStart() );
     639           0 :     GetInfo().SetPos( aLineOrigin );
     640           0 :     GetInfo().SetLen( pDrop->GetLen() );
     641             : 
     642           0 :     pDrop->PaintDrop( GetInfo() );
     643             : 
     644           0 :     GetInfo().Y( nOldY );
     645             : }
     646             : 
     647             : /*************************************************************************
     648             :  *                      class SwDropCapCache
     649             :  *
     650             :  * Since the calculation of the font size is expensive, this is being
     651             :  * channeled through a DropCapCache
     652             :  *************************************************************************/
     653             : 
     654             : #define DROP_CACHE_SIZE 10
     655             : 
     656             : class SwDropCapCache
     657             : {
     658             :     long aMagicNo[ DROP_CACHE_SIZE ];
     659             :     OUString aTxt[ DROP_CACHE_SIZE ];
     660             :     sal_uInt16 aFactor[ DROP_CACHE_SIZE ];
     661             :     KSHORT aWishedHeight[ DROP_CACHE_SIZE ];
     662             :     short aDescent[ DROP_CACHE_SIZE ];
     663             :     MSHORT nIndex;
     664             : public:
     665             :     SwDropCapCache();
     666           0 :     ~SwDropCapCache(){}
     667             :     void CalcFontSize( SwDropPortion* pDrop, SwTxtFormatInfo &rInf );
     668             : };
     669             : 
     670             : // SwDropCapCache Ctor / Dtor
     671           0 : SwDropCapCache::SwDropCapCache() : nIndex( 0 )
     672             : {
     673           0 :     memset( &aMagicNo, 0, sizeof(aMagicNo) );
     674           0 :     memset( &aWishedHeight, 0, sizeof(aWishedHeight) );
     675           0 : }
     676             : 
     677           0 : void SwDropPortion::DeleteDropCapCache()
     678             : {
     679           0 :     delete pDropCapCache;
     680           0 : }
     681             : 
     682           0 : void SwDropCapCache::CalcFontSize( SwDropPortion* pDrop, SwTxtFormatInfo &rInf )
     683             : {
     684           0 :     const void* pFntNo = 0;
     685           0 :     MSHORT nTmpIdx = 0;
     686             : 
     687             :     OSL_ENSURE( pDrop->GetPart(),"DropPortion without part during font calculation");
     688             : 
     689           0 :     SwDropPortionPart* pCurrPart = pDrop->GetPart();
     690           0 :     const bool bUseCache = ! pCurrPart->GetFollow() && !pCurrPart->GetFont().HasBorder();
     691           0 :     sal_Int32 nIdx = rInf.GetIdx();
     692           0 :     OUString aStr(rInf.GetTxt().copy(nIdx, pCurrPart->GetLen()));
     693             : 
     694           0 :     long nAscent = 0;
     695           0 :     long nDescent = 0;
     696           0 :     long nFactor = -1;
     697             : 
     698           0 :     if ( bUseCache )
     699             :     {
     700           0 :         SwFont& rFnt = pCurrPart->GetFont();
     701           0 :         rFnt.ChkMagic( rInf.GetVsh(), rFnt.GetActual() );
     702           0 :         rFnt.GetMagic( pFntNo, nTmpIdx, rFnt.GetActual() );
     703             : 
     704           0 :         nTmpIdx = 0;
     705             : 
     706           0 :         while( nTmpIdx < DROP_CACHE_SIZE &&
     707           0 :             ( aTxt[ nTmpIdx ] != aStr || aMagicNo[ nTmpIdx ] != sal_IntPtr(pFntNo) ||
     708           0 :             aWishedHeight[ nTmpIdx ] != pDrop->GetDropHeight() ) )
     709           0 :             ++nTmpIdx;
     710             :     }
     711             : 
     712             :     // we have to calculate a new font scaling factor if
     713             :     // 1. we did not find a scaling factor in the cache or
     714             :     // 2. we are not allowed to use the cache because the drop portion
     715             :     //    consists of more than one part
     716           0 :     if( nTmpIdx >= DROP_CACHE_SIZE || ! bUseCache )
     717             :     {
     718           0 :         ++nIndex;
     719           0 :         nIndex %= DROP_CACHE_SIZE;
     720           0 :         nTmpIdx = nIndex;
     721             : 
     722           0 :         long nWishedHeight = pDrop->GetDropHeight();
     723             : 
     724             :         // find out biggest font size for initial scaling factor
     725           0 :         long nMaxFontHeight = 0;
     726           0 :         while ( pCurrPart )
     727             :         {
     728           0 :             const SwFont& rFnt = pCurrPart->GetFont();
     729           0 :             const long nCurrHeight = rFnt.GetHeight( rFnt.GetActual() );
     730           0 :             if ( nCurrHeight > nMaxFontHeight )
     731           0 :                 nMaxFontHeight = nCurrHeight;
     732             : 
     733           0 :             pCurrPart = pCurrPart->GetFollow();
     734             :         }
     735             : 
     736           0 :         nFactor = ( 1000 * nWishedHeight ) / nMaxFontHeight;
     737             : 
     738           0 :         if ( bUseCache )
     739             :         {
     740             :             // save keys for cache
     741           0 :             aMagicNo[ nTmpIdx ] = sal_IntPtr(pFntNo);
     742           0 :             aTxt[ nTmpIdx ] = aStr;
     743           0 :             aWishedHeight[ nTmpIdx ] = KSHORT(nWishedHeight);
     744             :             // save initial scaling factor
     745           0 :             aFactor[ nTmpIdx ] = (sal_uInt16)nFactor;
     746             :         }
     747             : 
     748           0 :         bool bGrow = ( pDrop->GetLen() != 0 );
     749             : 
     750             :         // for growing controll
     751           0 :         long nMax = KSHRT_MAX;
     752           0 :         long nMin = 0;
     753             : #if OSL_DEBUG_LEVEL > 1
     754             :         long nGrow = 0;
     755             : #endif
     756             : 
     757           0 :         bool bWinUsed = false;
     758           0 :         Font aOldFnt;
     759           0 :         MapMode aOldMap( MAP_TWIP );
     760           0 :         OutputDevice* pOut = rInf.GetOut();
     761             :         OutputDevice* pWin;
     762           0 :         if( rInf.GetVsh() && rInf.GetVsh()->GetWin() )
     763           0 :             pWin = rInf.GetVsh()->GetWin();
     764             :         else
     765           0 :             pWin = GetpApp()->GetDefaultDevice();
     766             : 
     767           0 :         while( bGrow )
     768             :         {
     769             :             // reset pCurrPart to first part
     770           0 :             pCurrPart = pDrop->GetPart();
     771           0 :             bool bFirstGlyphRect = true;
     772           0 :             bool bHaveGlyphRect = false;
     773           0 :             Rectangle aCommonRect, aRect;
     774             : 
     775           0 :             while ( pCurrPart )
     776             :             {
     777             :                 // current font
     778           0 :                 SwFont& rFnt = pCurrPart->GetFont();
     779             : 
     780             :                 // Get height including proportion
     781             :                 const sal_uInt16 nCurrHeight =
     782           0 :                          (sal_uInt16)rFnt.GetHeight( rFnt.GetActual() );
     783             : 
     784             :                 // Get without proportion
     785           0 :                 const sal_uInt8 nOldProp = rFnt.GetPropr();
     786           0 :                 rFnt.SetProportion( 100 );
     787           0 :                 Size aOldSize = Size( 0, rFnt.GetHeight( rFnt.GetActual() ) );
     788             : 
     789           0 :                 Size aNewSize( 0, ( nFactor * nCurrHeight ) / 1000 );
     790           0 :                 rFnt.SetSize( aNewSize, rFnt.GetActual() );
     791           0 :                 rFnt.ChgPhysFnt( rInf.GetVsh(), *pOut );
     792             : 
     793           0 :                 nAscent = rFnt.GetAscent( rInf.GetVsh(), *pOut );
     794             : 
     795             :                 // we get the rectangle that covers all chars
     796           0 :                 bHaveGlyphRect = pOut->GetTextBoundRect( aRect, rInf.GetTxt(), 0,
     797           0 :                                      nIdx, pCurrPart->GetLen() ) &&
     798           0 :                                  ! aRect.IsEmpty();
     799             : 
     800           0 :                 if ( ! bHaveGlyphRect )
     801             :                 {
     802             :                     // getting glyph boundaries failed for some reason,
     803             :                     // we take the window for calculating sizes
     804           0 :                     if ( pWin )
     805             :                     {
     806           0 :                         if ( ! bWinUsed )
     807             :                         {
     808           0 :                             bWinUsed = true;
     809           0 :                             aOldMap = pWin->GetMapMode( );
     810           0 :                             pWin->SetMapMode( MapMode( MAP_TWIP ) );
     811           0 :                             aOldFnt = pWin->GetFont();
     812             :                         }
     813           0 :                         pWin->SetFont( rFnt.GetActualFont() );
     814             : 
     815           0 :                         bHaveGlyphRect = pWin->GetTextBoundRect( aRect, rInf.GetTxt(), 0,
     816           0 :                                             nIdx, pCurrPart->GetLen() ) &&
     817           0 :                                         ! aRect.IsEmpty();
     818             :                     }
     819           0 :                     if ( bHaveGlyphRect )
     820             :                     {
     821           0 :                         FontMetric aWinMet( pWin->GetFontMetric() );
     822           0 :                         nAscent = (KSHORT) aWinMet.GetAscent();
     823             :                     }
     824             :                     else
     825             :                     // We do not have a window or our window could not
     826             :                     // give us glyph boundaries.
     827           0 :                         aRect = Rectangle( Point( 0, 0 ), Size( 0, nAscent ) );
     828             :                 }
     829             : 
     830             :                 // Now we (hopefully) have a bounding rectangle for the
     831             :                 // glyphs of the current portion and the ascent of the current
     832             :                 // font
     833             : 
     834             :                 // reset font size and proportion
     835           0 :                 rFnt.SetSize( aOldSize, rFnt.GetActual() );
     836           0 :                 rFnt.SetProportion( nOldProp );
     837             : 
     838             :                 // Modify the bounding rectangle with the borders
     839             :                 // Robust: If the padding is so big as drop cap letter has no enough space than
     840             :                 // remove all padding.
     841           0 :                 if( rFnt.GetTopBorderSpace() + rFnt.GetBottomBorderSpace() >= nWishedHeight )
     842             :                 {
     843           0 :                     rFnt.SetTopBorderDist(0);
     844           0 :                     rFnt.SetBottomBorderDist(0);
     845           0 :                     rFnt.SetRightBorderDist(0);
     846           0 :                     rFnt.SetLeftBorderDist(0);
     847             :                 }
     848             : 
     849           0 :                 if( rFnt.GetTopBorder() )
     850             :                 {
     851           0 :                     aRect.setHeight(aRect.GetHeight() + rFnt.GetTopBorderSpace());
     852           0 :                     aRect.setY(aRect.getY() - rFnt.GetTopBorderSpace());
     853             :                 }
     854             : 
     855           0 :                 if( rFnt.GetBottomBorder() )
     856             :                 {
     857           0 :                     aRect.setHeight(aRect.GetHeight() + rFnt.GetBottomBorderSpace());
     858             :                 }
     859             : 
     860           0 :                 if ( bFirstGlyphRect )
     861             :                 {
     862           0 :                     aCommonRect = aRect;
     863           0 :                     bFirstGlyphRect = false;
     864             :                 }
     865             :                 else
     866           0 :                     aCommonRect.Union( aRect );
     867             : 
     868           0 :                 nIdx = nIdx + pCurrPart->GetLen();
     869           0 :                 pCurrPart = pCurrPart->GetFollow();
     870             :             }
     871             : 
     872             :             // now we have a union ( aCommonRect ) of all glyphs with
     873             :             // respect to a common baseline : 0
     874             : 
     875             :             // get descent and ascent from union
     876           0 :             if ( rInf.GetTxtFrm()->IsVertical() )
     877             :             {
     878           0 :                 nDescent = aCommonRect.Left();
     879           0 :                 nAscent = aCommonRect.Right();
     880             : 
     881           0 :                 if ( nDescent < 0 )
     882           0 :                     nDescent = -nDescent;
     883             :             }
     884             :             else
     885             :             {
     886           0 :                 nDescent = aCommonRect.Bottom();
     887           0 :                 nAscent = aCommonRect.Top();
     888             :             }
     889           0 :             if ( nAscent < 0 )
     890           0 :                 nAscent = -nAscent;
     891             : 
     892           0 :             const long nHght = nAscent + nDescent;
     893           0 :             if ( nHght )
     894             :             {
     895           0 :                 if ( nHght > nWishedHeight )
     896           0 :                     nMax = nFactor;
     897             :                 else
     898             :                 {
     899           0 :                     if ( bUseCache )
     900           0 :                         aFactor[ nTmpIdx ] = (sal_uInt16)nFactor;
     901           0 :                     nMin = nFactor;
     902             :                 }
     903             : 
     904           0 :                 nFactor = ( nFactor * nWishedHeight ) / nHght;
     905           0 :                 bGrow = ( nFactor > nMin ) && ( nFactor < nMax );
     906             : #if OSL_DEBUG_LEVEL > 1
     907             :                 if ( bGrow )
     908             :                     nGrow++;
     909             : #endif
     910           0 :                 nIdx = rInf.GetIdx();
     911             :             }
     912             :             else
     913           0 :                 bGrow = false;
     914             :         }
     915             : 
     916           0 :         if ( bWinUsed )
     917             :         {
     918             :             // reset window if it has been used
     919           0 :             pWin->SetMapMode( aOldMap );
     920           0 :             pWin->SetFont( aOldFnt );
     921             :         }
     922             : 
     923           0 :         if ( bUseCache )
     924           0 :             aDescent[ nTmpIdx ] = -short( nDescent );
     925             :     }
     926             : 
     927           0 :     pCurrPart = pDrop->GetPart();
     928             : 
     929             :     // did made any new calculations or did we use the cache?
     930           0 :     if ( -1 == nFactor )
     931             :     {
     932           0 :         nFactor = aFactor[ nTmpIdx ];
     933           0 :         nDescent = aDescent[ nTmpIdx ];
     934             :     }
     935             :     else
     936           0 :         nDescent = -nDescent;
     937             : 
     938           0 :     while ( pCurrPart )
     939             :     {
     940             :         // scale current font
     941           0 :         SwFont& rFnt = pCurrPart->GetFont();
     942           0 :         Size aNewSize( 0, ( nFactor * rFnt.GetHeight( rFnt.GetActual() ) ) / 1000 );
     943             : 
     944           0 :         const sal_uInt8 nOldProp = rFnt.GetPropr();
     945           0 :         rFnt.SetProportion( 100 );
     946           0 :         rFnt.SetSize( aNewSize, rFnt.GetActual() );
     947           0 :         rFnt.SetProportion( nOldProp );
     948             : 
     949           0 :         pCurrPart = pCurrPart->GetFollow();
     950             :     }
     951           0 :     pDrop->SetY( (short)nDescent );
     952           0 : }
     953             : 
     954           0 : bool SwDropPortion::Format( SwTxtFormatInfo &rInf )
     955             : {
     956           0 :     bool bFull = false;
     957           0 :     Fix( (sal_uInt16)rInf.X() );
     958             : 
     959           0 :     SwLayoutModeModifier aLayoutModeModifier( *rInf.GetOut() );
     960           0 :     aLayoutModeModifier.SetAuto();
     961             : 
     962           0 :     if( nDropHeight && pPart && nLines!=1 )
     963             :     {
     964           0 :         if( !pDropCapCache )
     965           0 :             pDropCapCache = new SwDropCapCache();
     966             : 
     967             :         // adjust font sizes to fit into the rectangle
     968           0 :         pDropCapCache->CalcFontSize( this, rInf );
     969             : 
     970           0 :         const long nOldX = rInf.X();
     971             :         {
     972           0 :             SwDropSave aSave( rInf );
     973           0 :             SwDropPortionPart* pCurrPart = pPart;
     974             : 
     975           0 :             while ( pCurrPart )
     976             :             {
     977           0 :                 rInf.SetLen( pCurrPart->GetLen() );
     978           0 :                 SwFont& rFnt = pCurrPart->GetFont();
     979             :                 {
     980           0 :                     SwFontSave aFontSave( rInf, &rFnt );
     981           0 :                     SetJoinBorderWithNext(pCurrPart->GetJoinBorderWithNext());
     982           0 :                     SetJoinBorderWithPrev(pCurrPart->GetJoinBorderWithPrev());
     983           0 :                     bFull = FormatTxt( rInf );
     984             : 
     985           0 :                     if ( bFull )
     986           0 :                         break;
     987             :                 }
     988             : 
     989             :                 const SwTwips nTmpWidth =
     990           0 :                         ( InSpaceGrp() && rInf.GetSpaceAdd() ) ?
     991           0 :                         Width() + CalcSpacing( rInf.GetSpaceAdd(), rInf ) :
     992           0 :                         Width();
     993             : 
     994             :                 // set values
     995           0 :                 pCurrPart->SetWidth( (sal_uInt16)nTmpWidth );
     996             : 
     997             :                 // Move
     998           0 :                 rInf.SetIdx( rInf.GetIdx() + pCurrPart->GetLen() );
     999           0 :                 rInf.X( rInf.X() + nTmpWidth );
    1000           0 :                 pCurrPart = pCurrPart->GetFollow();
    1001             :             }
    1002           0 :             SetJoinBorderWithNext(false);
    1003           0 :             SetJoinBorderWithPrev(false);
    1004           0 :             Width( (sal_uInt16)(rInf.X() - nOldX) );
    1005             :         }
    1006             : 
    1007             :         // reset my length
    1008           0 :         SetLen( rInf.GetLen() );
    1009             : 
    1010             :         // 7631, 7633: bei Ueberlappungen mit Flys ist Schluss.
    1011           0 :         if( ! bFull )
    1012           0 :             bFull = lcl_IsDropFlyInter( rInf, Width(), nDropHeight );
    1013             : 
    1014           0 :         if( bFull )
    1015             :         {
    1016             :             // Durch FormatTxt kann nHeight auf 0 gesetzt worden sein
    1017           0 :             if ( !Height() )
    1018           0 :                 Height( rInf.GetTxtHeight() );
    1019             : 
    1020             :             // Jetzt noch einmal der ganze Spass
    1021           0 :             nDropHeight = nLines = 0;
    1022           0 :             delete pPart;
    1023           0 :             pPart = NULL;
    1024             : 
    1025             :             // meanwhile use normal formatting
    1026           0 :             bFull = SwTxtPortion::Format( rInf );
    1027             :         }
    1028             :         else
    1029           0 :             rInf.SetDropInit( true );
    1030             : 
    1031           0 :         Height( rInf.GetTxtHeight() );
    1032           0 :         SetAscent( rInf.GetAscent() );
    1033             :     }
    1034             :     else
    1035           0 :         bFull = SwTxtPortion::Format( rInf );
    1036             : 
    1037           0 :     if( bFull )
    1038           0 :         nDistance = 0;
    1039             :     else
    1040             :     {
    1041           0 :         const KSHORT nWant = Width() + GetDistance();
    1042           0 :         const KSHORT nRest = (sal_uInt16)(rInf.Width() - rInf.X());
    1043           0 :         if( ( nWant > nRest ) ||
    1044           0 :             lcl_IsDropFlyInter( rInf, Width() + GetDistance(), nDropHeight ) )
    1045           0 :             nDistance = 0;
    1046             : 
    1047           0 :         Width( Width() + nDistance );
    1048             :     }
    1049           0 :     return bFull;
    1050             : }
    1051             : 
    1052             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10