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: */
|