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