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

Generated by: LCOV version 1.11