LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/core/text - txthyph.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 37 269 13.8 %
Date: 2013-07-09 Functions: 8 22 36.4 %
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 <editeng/unolingu.hxx>
      22             : #include <com/sun/star/i18n/WordType.hpp>
      23             : #include <EnhancedPDFExportHelper.hxx>
      24             : #include <viewopt.hxx>  // SwViewOptions
      25             : #include <viewsh.hxx>
      26             : #include <SwPortionHandler.hxx>
      27             : #include <porhyph.hxx>  //
      28             : #include <inftxt.hxx>
      29             : #include <itrform2.hxx> //
      30             : #include <guess.hxx>    //
      31             : #include <splargs.hxx>  // SwInterHyphInfo
      32             : 
      33             : using namespace ::com::sun::star;
      34             : using namespace ::com::sun::star::uno;
      35             : using namespace ::com::sun::star::beans;
      36             : using namespace ::com::sun::star::linguistic2;
      37             : using namespace ::com::sun::star::i18n;
      38             : 
      39             : /*************************************************************************
      40             :  *                      SwTxtFormatInfo::HyphWord()
      41             :  *************************************************************************/
      42             : 
      43           0 : Reference< XHyphenatedWord >  SwTxtFormatInfo::HyphWord(
      44             :                                 const XubString &rTxt, const MSHORT nMinTrail )
      45             : {
      46           0 :     if( rTxt.Len() < 4 || m_pFnt->IsSymbol(m_pVsh) )
      47           0 :         return 0;
      48           0 :     Reference< XHyphenator >  xHyph = ::GetHyphenator();
      49           0 :     Reference< XHyphenatedWord > xHyphWord;
      50             : 
      51           0 :     if( xHyph.is() )
      52           0 :         xHyphWord = xHyph->hyphenate( OUString(rTxt),
      53           0 :                             g_pBreakIt->GetLocale( m_pFnt->GetLanguage() ),
      54           0 :                             rTxt.Len() - nMinTrail, GetHyphValues() );
      55           0 :     return xHyphWord;
      56             : 
      57             : }
      58             : 
      59             : /*************************************************************************
      60             :  *                      SwTxtFrm::Hyphenate
      61             :  *
      62             :  * Wir formatieren eine Zeile fuer die interaktive Trennung
      63             :  *************************************************************************/
      64             : 
      65           0 : sal_Bool SwTxtFrm::Hyphenate( SwInterHyphInfo &rHyphInf )
      66             : {
      67             :     OSL_ENSURE( ! IsVertical() || ! IsSwapped(),"swapped frame at SwTxtFrm::Hyphenate" );
      68             : 
      69           0 :     if( !g_pBreakIt->GetBreakIter().is() )
      70           0 :         return sal_False;
      71             :     // Wir machen den Laden erstmal dicht:
      72             :     OSL_ENSURE( !IsLocked(), "SwTxtFrm::Hyphenate: this is locked" );
      73             :     // 4935: Der frame::Frame muss eine gueltige SSize haben!
      74           0 :     Calc();
      75           0 :     GetFormatted();
      76             : 
      77           0 :     sal_Bool bRet = sal_False;
      78           0 :     if( !IsEmpty() )
      79             :     {
      80             :         // Wir muessen die Trennung immer einschalten.
      81             :         // Keine Angst, der SwTxtIter sichert im Hyphenate die alte Zeile.
      82           0 :         SwTxtFrmLocker aLock( this );
      83             : 
      84           0 :         if ( IsVertical() )
      85           0 :             SwapWidthAndHeight();
      86             : 
      87           0 :         SwTxtFormatInfo aInf( this, sal_True );     // sal_True fuer interactive hyph!
      88           0 :         SwTxtFormatter aLine( this, &aInf );
      89           0 :         aLine.CharToLine( rHyphInf.nStart );
      90             :         // Wenn wir innerhalb des ersten Wortes einer Zeile stehen, so koennte
      91             :         // dieses in der vorherigen getrennt werden, deshalb gehen wir ein Zeile
      92             :         // zurueck.
      93           0 :         if( aLine.Prev() )
      94             :         {
      95           0 :             SwLinePortion *pPor = aLine.GetCurr()->GetFirstPortion();
      96           0 :             while( pPor->GetPortion() )
      97           0 :                 pPor = pPor->GetPortion();
      98           0 :             if( pPor->GetWhichPor() == POR_SOFTHYPH ||
      99           0 :                 pPor->GetWhichPor() == POR_SOFTHYPHSTR )
     100           0 :                 aLine.Next();
     101             :         }
     102             : 
     103           0 :         const xub_StrLen nEnd = rHyphInf.GetEnd();
     104           0 :         while( !bRet && aLine.GetStart() < nEnd )
     105             :         {
     106           0 :             bRet = aLine.Hyphenate( rHyphInf );
     107           0 :             if( !aLine.Next() )
     108           0 :                 break;
     109             :         }
     110             : 
     111           0 :         if ( IsVertical() )
     112           0 :             SwapWidthAndHeight();
     113             :     }
     114           0 :     return bRet;
     115             : }
     116             : 
     117             : /*************************************************************************
     118             :  *                      SwTxtFormatter::Hyphenate
     119             :  *
     120             :  * Wir formatieren eine Zeile fuer die interaktive Trennung
     121             :  *************************************************************************/
     122             : // Wir koennen davon ausgehen, dass bereits formatiert wurde.
     123             : // Fuer die CeBIT'93 gehen wir den einfachen, sicheren Weg:
     124             : // Die Zeile wird einfach neu formatiert, der Hyphenator wird dann
     125             : // so vorbereitet, wie ihn die UI erwartet.
     126             : // Hier stehen natuerlich enorme Optimierungsmoeglichkeiten offen.
     127             : 
     128           0 : void SetParaPortion( SwTxtInfo *pInf, SwParaPortion *pRoot )
     129             : {
     130             :     OSL_ENSURE( pRoot, "SetParaPortion: no root anymore" );
     131           0 :     pInf->pPara = pRoot;
     132           0 : }
     133             : 
     134           0 : sal_Bool SwTxtFormatter::Hyphenate( SwInterHyphInfo &rHyphInf )
     135             : {
     136           0 :     SwTxtFormatInfo &rInf = GetInfo();
     137           0 :     sal_Bool bRet = sal_False;
     138             : 
     139             :     // In der letzten Zeile gibt es nie etwas zu trennen.
     140             :     // Es sei denn, es befindet sich eine FlyPortion darin,
     141             :     // oder es ist die letzte Zeile des Masters
     142           0 :     if( !GetNext() && !rInf.GetTxtFly()->IsOn() && !pFrm->GetFollow() )
     143           0 :         return bRet;
     144             : 
     145           0 :     xub_StrLen nWrdStart = nStart;
     146             : 
     147             :     // Wir muessen die alte Zeile erhalten. Ein Beispiel:
     148             :     // Das Attribut fuer Trennung wurde nicht gesetzt,
     149             :     // in SwTxtFrm::Hyphenate wird es jedoch immer gesetzt,
     150             :     // weil wir Trennpositionen im Hyphenator einstellen wollen.
     151           0 :     SwLineLayout *pOldCurr = pCurr;
     152             : 
     153           0 :     InitCntHyph();
     154             : 
     155             :     // 5298: IsParaLine() (ex.IsFirstLine) fragt auf GetParaPortion() ab.
     156             :     // wir muessen gleiche Bedingungen schaffen: in der ersten
     157             :     // Zeile formatieren wir SwParaPortions...
     158           0 :     if( pOldCurr->IsParaPortion() )
     159             :     {
     160           0 :         SwParaPortion *pPara = new SwParaPortion();
     161           0 :         SetParaPortion( &rInf, pPara );
     162           0 :         pCurr = pPara;
     163             :         OSL_ENSURE( IsParaLine(), "SwTxtFormatter::Hyphenate: not the first" );
     164             :     }
     165             :     else
     166           0 :         pCurr = new SwLineLayout();
     167             : 
     168           0 :     nWrdStart = FormatLine( nWrdStart );
     169             : 
     170             :     // Man muss immer im Hinterkopf behalten, dass es z.B.
     171             :     // Felder gibt, die aufgetrennt werden koennen ...
     172           0 :     if( pCurr->PrtWidth() && pCurr->GetLen() )
     173             :     {
     174             :         // Wir muessen uns darauf einstellen, dass in der Zeile
     175             :         // FlyFrms haengen, an denen auch umgebrochen werden darf.
     176             :         // Wir suchen also die erste HyphPortion in dem angegebenen
     177             :         // Bereich.
     178             : 
     179           0 :         SwLinePortion *pPos = pCurr->GetPortion();
     180           0 :         const xub_StrLen nPamStart = rHyphInf.nStart;
     181           0 :         nWrdStart = nStart;
     182           0 :         const xub_StrLen nEnd = rHyphInf.GetEnd();
     183           0 :         while( pPos )
     184             :         {
     185             :             // Entweder wir liegen drueber oder wir laufen gerade auf eine
     186             :             // Hyphportion die am Ende der Zeile oder vor einem Flys steht.
     187           0 :             if( nWrdStart >= nEnd )
     188             :             {
     189           0 :                 nWrdStart = 0;
     190           0 :                 break;
     191             :             }
     192             : 
     193           0 :             if( nWrdStart >= nPamStart && pPos->InHyphGrp()
     194           0 :                 && ( !pPos->IsSoftHyphPortion()
     195           0 :                      || ((SwSoftHyphPortion*)pPos)->IsExpand() ) )
     196             :             {
     197           0 :                 nWrdStart = nWrdStart + pPos->GetLen();
     198           0 :                 break;
     199             :             }
     200             : 
     201           0 :             nWrdStart = nWrdStart + pPos->GetLen();
     202           0 :             pPos = pPos->GetPortion();
     203             :         }
     204             :         // Wenn pPos 0 ist, wurde keine Trennstelle ermittelt.
     205           0 :         if( !pPos )
     206           0 :             nWrdStart = 0;
     207             :     }
     208             : 
     209             :     // Das alte LineLayout wird wieder eingestellt ...
     210           0 :     delete pCurr;
     211           0 :     pCurr = pOldCurr;
     212             : 
     213           0 :     if( pOldCurr->IsParaPortion() )
     214             :     {
     215           0 :         SetParaPortion( &rInf, (SwParaPortion*)pOldCurr );
     216             :         OSL_ENSURE( IsParaLine(), "SwTxtFormatter::Hyphenate: even not the first" );
     217             :     }
     218             : 
     219           0 :     if( nWrdStart )
     220             :     {
     221             :         // nWrdStart bezeichnet nun die Position im String, der
     222             :         // fuer eine Trennung zur Debatte steht.
     223             :         // Start() hangelt sich zum End()
     224           0 :         rHyphInf.nWordStart = nWrdStart;
     225             : 
     226           0 :         xub_StrLen nLen = 0;
     227           0 :         const xub_StrLen nEnd = nWrdStart;
     228             : 
     229             :         // Wir suchen vorwaerts
     230           0 :         Reference< XHyphenatedWord > xHyphWord;
     231             : 
     232             :         Boundary aBound =
     233           0 :             g_pBreakIt->GetBreakIter()->getWordBoundary( rInf.GetTxt(), nWrdStart,
     234           0 :             g_pBreakIt->GetLocale( rInf.GetFont()->GetLanguage() ), WordType::DICTIONARY_WORD, sal_True );
     235           0 :         nWrdStart = static_cast<xub_StrLen>(aBound.startPos);
     236           0 :         nLen = static_cast<xub_StrLen>(aBound.endPos - nWrdStart);
     237           0 :         bRet = 0 != nLen;
     238           0 :         if( bRet )
     239             :         {
     240           0 :             XubString aSelTxt( rInf.GetTxt().copy(nWrdStart, nLen) );
     241             : 
     242             :             {
     243           0 :                 MSHORT nMinTrail = 0;
     244           0 :                 if( nWrdStart + nLen > nEnd )
     245           0 :                     nMinTrail = nWrdStart + nLen - nEnd - 1;
     246             : 
     247             :                 //!! rHyphInf.SetHyphWord( ... ) mu??? hier geschehen
     248           0 :                 xHyphWord = rInf.HyphWord( aSelTxt, nMinTrail );
     249           0 :                 bRet = xHyphWord.is();
     250           0 :                 if ( !rHyphInf.IsCheck() && sal_False == bRet )
     251           0 :                     rHyphInf.SetNoLang( sal_True );
     252             :             }
     253             : 
     254           0 :             if( bRet )
     255             :             {
     256           0 :                 rHyphInf.SetHyphWord( xHyphWord );
     257           0 :                 rHyphInf.nWordStart = nWrdStart;
     258           0 :                 rHyphInf.nWordLen = nLen;
     259           0 :                 rHyphInf.SetNoLang( sal_False );
     260           0 :                 rHyphInf.SetCheck( sal_True );
     261           0 :             }
     262           0 :         }
     263             :     }
     264           0 :     return bRet;
     265             : }
     266             : 
     267             : /*************************************************************************
     268             :  *                      SwTxtPortion::CreateHyphen()
     269             :  *************************************************************************/
     270             : 
     271           0 : sal_Bool SwTxtPortion::CreateHyphen( SwTxtFormatInfo &rInf, SwTxtGuess &rGuess )
     272             : {
     273           0 :     Reference< XHyphenatedWord >  xHyphWord = rGuess.HyphWord();
     274             : 
     275             :     OSL_ENSURE( !pPortion, "SwTxtPortion::CreateHyphen(): another portion, another planet..." );
     276             :     OSL_ENSURE( xHyphWord.is(), "SwTxtPortion::CreateHyphen(): You are lucky! The code is robust here." );
     277             : 
     278           0 :     if( rInf.IsHyphForbud() ||
     279           0 :         pPortion || // robust
     280           0 :         !xHyphWord.is() || // more robust
     281             :         // Mehrzeilige Felder duerfen nicht interaktiv getrennt werden.
     282           0 :         ( rInf.IsInterHyph() && InFldGrp() ) )
     283           0 :         return sal_False;
     284             : 
     285             :     SwHyphPortion *pHyphPor;
     286             :     xub_StrLen nPorEnd;
     287           0 :     SwTxtSizeInfo aInf( rInf );
     288             : 
     289             :     // first case: hyphenated word has alternative spelling
     290           0 :     if ( xHyphWord->isAlternativeSpelling() )
     291             :     {
     292           0 :         SvxAlternativeSpelling aAltSpell;
     293           0 :         aAltSpell = SvxGetAltSpelling( xHyphWord );
     294             :         OSL_ENSURE( aAltSpell.bIsAltSpelling, "no alternatve spelling" );
     295             : 
     296           0 :         XubString  aAltTxt   = aAltSpell.aReplacement;
     297           0 :         nPorEnd = aAltSpell.nChangedPos + rGuess.BreakStart() - rGuess.FieldDiff();
     298           0 :         xub_StrLen nTmpLen = 0;
     299             : 
     300             :         // soft hyphen at alternative spelling position?
     301           0 :         if( rInf.GetTxt()[ rInf.GetSoftHyphPos() ] == CHAR_SOFTHYPHEN )
     302             :         {
     303           0 :             pHyphPor = new SwSoftHyphStrPortion( aAltTxt );
     304           0 :             nTmpLen = 1;
     305             :         }
     306             :         else {
     307           0 :             pHyphPor = new SwHyphStrPortion( aAltTxt );
     308             :         }
     309             : 
     310             :         // length of pHyphPor is adjusted
     311           0 :         pHyphPor->SetLen( aAltTxt.Len() + 1 );
     312           0 :         (SwPosSize&)(*pHyphPor) = pHyphPor->GetTxtSize( rInf );
     313           0 :         pHyphPor->SetLen( aAltSpell.nChangedLength + nTmpLen );
     314             :     }
     315             :     else
     316             :     {
     317             :         // second case: no alternative spelling
     318           0 :         SwHyphPortion aHyphPor;
     319           0 :         aHyphPor.SetLen( 1 );
     320             : 
     321             :         static const void* pLastMagicNo = 0;
     322             :         static KSHORT aMiniCacheH = 0, aMiniCacheW = 0;
     323             :         const void* pTmpMagic;
     324             :         MSHORT nFntIdx;
     325           0 :         rInf.GetFont()->GetMagic( pTmpMagic, nFntIdx, rInf.GetFont()->GetActual() );
     326           0 :         if( !pLastMagicNo || pLastMagicNo != pTmpMagic ) {
     327           0 :             pLastMagicNo = pTmpMagic;
     328           0 :             (SwPosSize&)aHyphPor = aHyphPor.GetTxtSize( rInf );
     329           0 :             aMiniCacheH = aHyphPor.Height(), aMiniCacheW = aHyphPor.Width();
     330             :         } else {
     331           0 :             aHyphPor.Height( aMiniCacheH ), aHyphPor.Width( aMiniCacheW );
     332             :         }
     333           0 :         aHyphPor.SetLen( 0 );
     334           0 :         pHyphPor = new SwHyphPortion( aHyphPor );
     335             : 
     336           0 :         pHyphPor->SetWhichPor( POR_HYPH );
     337             : 
     338             :         // values required for this
     339           0 :         nPorEnd = xHyphWord->getHyphenPos() + 1 + rGuess.BreakStart()
     340           0 :                 - rGuess.FieldDiff();
     341             :     }
     342             : 
     343             :     // portion end must be in front of us
     344             :     // we do not put hyphens at start of line
     345           0 :     if ( nPorEnd > rInf.GetIdx() ||
     346           0 :          ( nPorEnd == rInf.GetIdx() && rInf.GetLineStart() != rInf.GetIdx() ) )
     347             :     {
     348           0 :         aInf.SetLen( nPorEnd - rInf.GetIdx() );
     349           0 :         pHyphPor->SetAscent( GetAscent() );
     350           0 :         SetLen( aInf.GetLen() );
     351           0 :         CalcTxtSize( aInf );
     352             : 
     353           0 :         Insert( pHyphPor );
     354             : 
     355           0 :         short nKern = rInf.GetFont()->CheckKerning();
     356           0 :         if( nKern )
     357           0 :             new SwKernPortion( *this, nKern );
     358             : 
     359           0 :         return sal_True;
     360             :     }
     361             : 
     362             :     // last exit for the lost
     363           0 :     delete pHyphPor;
     364           0 :     BreakCut( rInf, rGuess );
     365           0 :     return sal_False;
     366             : }
     367             : 
     368             : 
     369             : /*************************************************************************
     370             :  *              virtual SwHyphPortion::GetExpTxt()
     371             :  *************************************************************************/
     372             : 
     373           2 : sal_Bool SwHyphPortion::GetExpTxt( const SwTxtSizeInfo &rInf, OUString &rTxt ) const
     374             : {
     375             :     // #i16816# tagged pdf support
     376           4 :     const sal_Unicode cChar = rInf.GetVsh() &&
     377           2 :                               rInf.GetVsh()->GetViewOptions()->IsPDFExport() &&
     378           0 :                               SwTaggedPDFHelper::IsExportTaggedPDF( *rInf.GetOut() ) ?
     379             :                               0xad :
     380           2 :                               '-';
     381             : 
     382           2 :     rTxt = OUString(cChar);
     383           2 :     return sal_True;
     384             : }
     385             : 
     386             : /*************************************************************************
     387             :  *              virtual SwHyphPortion::HandlePortion()
     388             :  *************************************************************************/
     389             : 
     390           0 : void SwHyphPortion::HandlePortion( SwPortionHandler& rPH ) const
     391             : {
     392           0 :     OUString aString( '-' );
     393           0 :     rPH.Special( GetLen(), aString, GetWhichPor() );
     394           0 : }
     395             : 
     396             : /*************************************************************************
     397             :  *                 virtual SwHyphPortion::Format()
     398             :  *************************************************************************/
     399             : 
     400           2 : sal_Bool SwHyphPortion::Format( SwTxtFormatInfo &rInf )
     401             : {
     402           2 :     const SwLinePortion *pLast = rInf.GetLast();
     403           2 :     Height( pLast->Height() );
     404           2 :     SetAscent( pLast->GetAscent() );
     405           2 :     OUString aTxt;
     406             : 
     407           2 :     if( !GetExpTxt( rInf, aTxt ) )
     408           0 :         return sal_False;
     409             : 
     410           2 :     PrtWidth( rInf.GetTxtSize( aTxt ).Width() );
     411           2 :     const sal_Bool bFull = rInf.Width() <= rInf.X() + PrtWidth();
     412           2 :     if( bFull && !rInf.IsUnderFlow() ) {
     413           0 :         Truncate();
     414           0 :         rInf.SetUnderFlow( this );
     415             :     }
     416             : 
     417           2 :     return bFull;
     418             : }
     419             : 
     420             : /*************************************************************************
     421             :  *              virtual SwHyphStrPortion::GetExpTxt()
     422             :  *************************************************************************/
     423             : 
     424           0 : sal_Bool SwHyphStrPortion::GetExpTxt( const SwTxtSizeInfo &, OUString &rTxt ) const
     425             : {
     426           0 :     rTxt = aExpand;
     427           0 :     return sal_True;
     428             : }
     429             : 
     430             : /*************************************************************************
     431             :  *              virtual SwHyphStrPortion::HandlePortion()
     432             :  *************************************************************************/
     433             : 
     434           0 : void SwHyphStrPortion::HandlePortion( SwPortionHandler& rPH ) const
     435             : {
     436           0 :     rPH.Special( GetLen(), aExpand, GetWhichPor() );
     437           0 : }
     438             : 
     439             : /*************************************************************************
     440             :  *                      class SwSoftHyphPortion
     441             :  *************************************************************************/
     442             : 
     443           2 : SwLinePortion *SwSoftHyphPortion::Compress() { return this; }
     444             : 
     445           2 : SwSoftHyphPortion::SwSoftHyphPortion() :
     446           2 :     bExpand(sal_False), nViewWidth(0), nHyphWidth(0)
     447             : {
     448           2 :     SetLen(1);
     449           2 :     SetWhichPor( POR_SOFTHYPH );
     450           2 : }
     451             : 
     452           0 : KSHORT SwSoftHyphPortion::GetViewWidth( const SwTxtSizeInfo &rInf ) const
     453             : {
     454             :     // Wir stehen zwar im const, aber nViewWidth sollte erst im letzten
     455             :     // Moment errechnet werden:
     456           0 :     if( !Width() && rInf.OnWin() && rInf.GetOpt().IsSoftHyph() && !IsExpand() )
     457             :     {
     458           0 :         if( !nViewWidth )
     459             :             ((SwSoftHyphPortion*)this)->nViewWidth
     460           0 :                 = rInf.GetTxtSize(OUString('-')).Width();
     461             :     }
     462             :     else
     463           0 :         ((SwSoftHyphPortion*)this)->nViewWidth = 0;
     464           0 :     return nViewWidth;
     465             : }
     466             : 
     467             : /*  Faelle:
     468             :  *  1) SoftHyph steht in der Zeile, ViewOpt aus.
     469             :  *     -> unsichtbar, Nachbarn unveraendert
     470             :  *  2) SoftHyph steht in der Zeile, ViewOpt an.
     471             :  *     -> sichtbar, Nachbarn veraendert
     472             :  *  3) SoftHyph steht am Zeilenende, ViewOpt aus/an.
     473             :  *     -> immer sichtbar, Nachbarn unveraendert
     474             :  */
     475             : 
     476           0 : void SwSoftHyphPortion::Paint( const SwTxtPaintInfo &rInf ) const
     477             : {
     478           0 :     if( Width() )
     479             :     {
     480           0 :         rInf.DrawViewOpt( *this, POR_SOFTHYPH );
     481           0 :         SwExpandPortion::Paint( rInf );
     482             :     }
     483           0 : }
     484             : 
     485             : /*************************************************************************
     486             :  *                 virtual SwSoftHyphPortion::Format()
     487             :  *************************************************************************/
     488             : 
     489             : /* Die endgueltige Breite erhalten wir im FormatEOL().
     490             :  * In der Underflow-Phase stellen wir fest, ob ueberhaupt ein
     491             :  * alternatives Spelling vorliegt. Wenn ja ...
     492             :  *
     493             :  * Fall 1: "Au-to"
     494             :  * 1) {Au}{-}{to}, {to} passt nicht mehr => Underflow
     495             :  * 2) {-} ruft Hyphenate => keine Alternative
     496             :  * 3) FormatEOL() und bFull = sal_True
     497             :  *
     498             :  * Fall 2: "Zuc-ker"
     499             :  * 1) {Zuc}{-}{ker}, {ker} passt nicht mehr => Underflow
     500             :  * 2) {-} ruft Hyphenate => Alternative!
     501             :  * 3) Underflow() und bFull = sal_True
     502             :  * 4) {Zuc} ruft Hyphenate => {Zuk}{-}{ker}
     503             :  */
     504             : 
     505           2 : sal_Bool SwSoftHyphPortion::Format( SwTxtFormatInfo &rInf )
     506             : {
     507           2 :     sal_Bool bFull = sal_True;
     508             : 
     509             :     // special case for old german spelling
     510           2 :     if( rInf.IsUnderFlow()  )
     511             :     {
     512           0 :         if( rInf.GetSoftHyphPos() )
     513           0 :             return sal_True;
     514             : 
     515           0 :         const sal_Bool bHyph = rInf.ChgHyph( sal_True );
     516           0 :         if( rInf.IsHyphenate() )
     517             :         {
     518           0 :             rInf.SetSoftHyphPos( rInf.GetIdx() );
     519           0 :             Width(0);
     520             :             // if the soft hyphend word has an alternative spelling
     521             :             // when hyphenated (old german spelling), the soft hyphen
     522             :             // portion has to trigger an underflow
     523           0 :             SwTxtGuess aGuess;
     524           0 :             bFull = rInf.IsInterHyph() ||
     525           0 :                     !aGuess.AlternativeSpelling( rInf, rInf.GetIdx() - 1 );
     526             :         }
     527           0 :         rInf.ChgHyph( bHyph );
     528             : 
     529           0 :         if( bFull && !rInf.IsHyphForbud() )
     530             :         {
     531           0 :             rInf.SetSoftHyphPos(0);
     532           0 :             FormatEOL( rInf );
     533           0 :             if ( rInf.GetFly() )
     534           0 :                 rInf.GetRoot()->SetMidHyph( sal_True );
     535             :             else
     536           0 :                 rInf.GetRoot()->SetEndHyph( sal_True );
     537             :         }
     538             :         else
     539             :         {
     540           0 :             rInf.SetSoftHyphPos( rInf.GetIdx() );
     541           0 :             Truncate();
     542           0 :             rInf.SetUnderFlow( this );
     543             :         }
     544           0 :         return sal_True;
     545             :     }
     546             : 
     547           2 :     rInf.SetSoftHyphPos(0);
     548           2 :     SetExpand( sal_True );
     549           2 :     bFull = SwHyphPortion::Format( rInf );
     550           2 :     SetExpand( sal_False );
     551           2 :     if( !bFull )
     552             :     {
     553             :         // default-maessig besitzen wir keine Breite, aber eine Hoehe
     554           2 :         nHyphWidth = Width();
     555           2 :         Width(0);
     556             :     }
     557           2 :     return bFull;
     558             : }
     559             : 
     560             : /*************************************************************************
     561             :  *                 virtual SwSoftHyphPortion::FormatEOL()
     562             :  *************************************************************************/
     563             : // Format end of Line
     564             : 
     565           0 : void SwSoftHyphPortion::FormatEOL( SwTxtFormatInfo &rInf )
     566             : {
     567           0 :     if( !IsExpand() )
     568             :     {
     569           0 :         SetExpand( sal_True );
     570           0 :         if( rInf.GetLast() == this )
     571           0 :             rInf.SetLast( FindPrevPortion( rInf.GetRoot() ) );
     572             : 
     573             :         // 5964: alte Werte muessen wieder zurueckgesetzt werden.
     574           0 :         const SwTwips nOldX  = rInf.X();
     575           0 :         const xub_StrLen nOldIdx = rInf.GetIdx();
     576           0 :         rInf.X( rInf.X() - PrtWidth() );
     577           0 :         rInf.SetIdx( rInf.GetIdx() - GetLen() );
     578           0 :         const sal_Bool bFull = SwHyphPortion::Format( rInf );
     579           0 :         nHyphWidth = Width();
     580             : 
     581             :         // 6976: Eine truebe Sache: Wir werden erlaubterweise breiter,
     582             :         // aber gleich wird noch ein Fly verarbeitet, der eine korrekte
     583             :         // X-Position braucht.
     584           0 :         if( bFull || !rInf.GetFly() )
     585           0 :             rInf.X( nOldX );
     586             :         else
     587           0 :             rInf.X( nOldX + Width() );
     588           0 :         rInf.SetIdx( nOldIdx );
     589             :     }
     590           0 : }
     591             : 
     592             : /*************************************************************************
     593             :  *              virtual SwSoftHyphPortion::GetExpTxt()
     594             :  *
     595             :  * Wir expandieren:
     596             :  * - wenn die Sonderzeichen sichtbar sein sollen
     597             :  * - wenn wir am Ende der Zeile stehen.
     598             :  * - wenn wir vor einem (echten/emuliertem) Zeilenumbruch stehen
     599             :  *************************************************************************/
     600             : 
     601           2 : sal_Bool SwSoftHyphPortion::GetExpTxt( const SwTxtSizeInfo &rInf, OUString &rTxt ) const
     602             : {
     603           4 :     if( IsExpand() || ( rInf.OnWin() && rInf.GetOpt().IsSoftHyph() ) ||
     604           0 :         ( GetPortion() && ( GetPortion()->InFixGrp() ||
     605           0 :           GetPortion()->IsDropPortion() || GetPortion()->IsLayPortion() ||
     606           0 :           GetPortion()->IsParaPortion() || GetPortion()->IsBreakPortion() ) ) )
     607             :     {
     608           2 :         return SwHyphPortion::GetExpTxt( rInf, rTxt );
     609             :     }
     610           0 :     return sal_False;
     611             : }
     612             : 
     613             : /*************************************************************************
     614             :  *              virtual SwSoftHyphPortion::HandlePortion()
     615             :  *************************************************************************/
     616             : 
     617           0 : void SwSoftHyphPortion::HandlePortion( SwPortionHandler& rPH ) const
     618             : {
     619           0 :     const OUString aString( '-' );
     620           0 :     const sal_uInt16 nWhich = ! Width() ?
     621             :                           POR_SOFTHYPH_COMP :
     622           0 :                           GetWhichPor();
     623           0 :     rPH.Special( GetLen(), aString, nWhich );
     624           0 : }
     625             : 
     626             : /*************************************************************************
     627             :  *                      SwSoftHyphStrPortion::Paint
     628             :  *************************************************************************/
     629             : 
     630           0 : void SwSoftHyphStrPortion::Paint( const SwTxtPaintInfo &rInf ) const
     631             : {
     632             :     // Bug oder feature?:
     633             :     // {Zu}{k-}{ker}, {k-} wird grau statt {-}
     634           0 :     rInf.DrawViewOpt( *this, POR_SOFTHYPH );
     635           0 :     SwHyphStrPortion::Paint( rInf );
     636           0 : }
     637             : 
     638           0 : SwSoftHyphStrPortion::SwSoftHyphStrPortion( const XubString &rStr )
     639           0 :     : SwHyphStrPortion( rStr )
     640             : {
     641           0 :     SetLen( 1 );
     642           0 :     SetWhichPor( POR_SOFTHYPHSTR );
     643          99 : }
     644             : 
     645             : 
     646             : 
     647             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10