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

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

Generated by: LCOV version 1.10