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