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

Generated by: LCOV version 1.10