LCOV - code coverage report
Current view: top level - sw/source/core/text - txtdrop.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 5 487 1.0 %
Date: 2012-08-25 Functions: 2 25 8.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1 595 0.2 %

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

Generated by: LCOV version 1.10