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