Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <hintids.hxx>
31 : : #include <editeng/keepitem.hxx>
32 : : #include <editeng/hyznitem.hxx>
33 : : #include <pagefrm.hxx> // ChangeFtnRef
34 : : #include <ndtxt.hxx> // MakeFrm()
35 : : #include <dcontact.hxx> // SwDrawContact
36 : : #include <dflyobj.hxx> // SwVirtFlyDrawObj
37 : : #include <flyfrm.hxx>
38 : : #include <ftnfrm.hxx> // SwFtnFrm
39 : : #include <txtftn.hxx>
40 : : #include <fmtftn.hxx>
41 : : #include <paratr.hxx>
42 : : #include <viewopt.hxx> // SwViewOptions
43 : : #include <viewsh.hxx> // ViewShell
44 : : #include <frmatr.hxx>
45 : : #include <pam.hxx>
46 : : #include <flyfrms.hxx>
47 : : #include <fmtanchr.hxx>
48 : : #include <itrform2.hxx> // SwTxtFormatter
49 : : #include <widorp.hxx> // Widows and Orphans
50 : : #include <txtcache.hxx>
51 : : #include <porrst.hxx> // SwEmptyPortion
52 : : #include <blink.hxx> // pBlink
53 : : #include <porfld.hxx> // SwFldPortion
54 : : #include <sectfrm.hxx> // SwSectionFrm
55 : : #include <pormulti.hxx> // SwMultiPortion
56 : :
57 : : #include <rootfrm.hxx>
58 : : #include <frmfmt.hxx> // SwFrmFmt
59 : : // OD 2004-05-24 #i28701#
60 : : #include <sortedobjs.hxx>
61 : :
62 : : // Tolerance in formatting and text output
63 : : #define SLOPPY_TWIPS 5
64 : :
65 : : class FormatLevel
66 : : {
67 : : static MSHORT nLevel;
68 : : public:
69 : 15607 : inline FormatLevel() { ++nLevel; }
70 : 15607 : inline ~FormatLevel() { --nLevel; }
71 : 15607 : inline MSHORT GetLevel() const { return nLevel; }
72 : 624 : static sal_Bool LastLevel() { return 10 < nLevel; }
73 : : };
74 : : MSHORT FormatLevel::nLevel = 0;
75 : :
76 : 69 : void ValidateTxt( SwFrm *pFrm ) // Friend of frame
77 : : {
78 [ + - - + : 138 : if ( ( ! pFrm->IsVertical() &&
# # # # ]
[ + - ]
79 : 69 : pFrm->Frm().Width() == pFrm->GetUpper()->Prt().Width() ) ||
80 : 0 : ( pFrm->IsVertical() &&
81 : 0 : pFrm->Frm().Height() == pFrm->GetUpper()->Prt().Height() ) )
82 : 69 : pFrm->bValidSize = sal_True;
83 : 69 : }
84 : :
85 : 69 : void SwTxtFrm::ValidateFrm()
86 : : {
87 : : // Validate surroundings to avoid oscillation
88 [ - + ][ # # ]: 69 : SWAP_IF_SWAPPED( this )
[ - + ]
89 : :
90 [ + - ][ + - ]: 69 : if ( !IsInFly() && !IsInTab() )
[ + - ]
91 : : { // Only validate 'this' when inside a fly, the rest should actually only be
92 : : // needed for footnotes, which do not exist in flys.
93 : 69 : SwSectionFrm* pSct = FindSctFrm();
94 [ - + ]: 69 : if( pSct )
95 : : {
96 [ # # ]: 0 : if( !pSct->IsColLocked() )
97 : 0 : pSct->ColLock();
98 : : else
99 : 0 : pSct = NULL;
100 : : }
101 : :
102 : 69 : SwFrm *pUp = GetUpper();
103 : 69 : pUp->Calc();
104 [ - + ]: 69 : if( pSct )
105 : 0 : pSct->ColUnlock();
106 : : }
107 : 69 : ValidateTxt( this );
108 : :
109 : : // We at least have to save the MustFit flag!
110 : : OSL_ENSURE( HasPara(), "ResetPreps(), missing ParaPortion." );
111 : 69 : SwParaPortion *pPara = GetPara();
112 : 69 : const sal_Bool bMustFit = pPara->IsPrepMustFit();
113 : 69 : ResetPreps();
114 : 69 : pPara->SetPrepMustFit( bMustFit );
115 : :
116 [ - + ]: 69 : UNDO_SWAP( this )
117 : 69 : }
118 : :
119 : : /*************************************************************************
120 : : * ValidateBodyFrm()
121 : : * After a RemoveFtn the BodyFrm and all Frms contained within it, need to be
122 : : * recalculated, so that the DeadLine is right.
123 : : * First we search outwards, on the way back we calculate everything.
124 : : *************************************************************************/
125 : :
126 : 69 : void _ValidateBodyFrm( SwFrm *pFrm )
127 : : {
128 [ + - ][ + - ]: 69 : if( pFrm && !pFrm->IsCellFrm() )
[ + - ]
129 : : {
130 [ - + ][ # # ]: 69 : if( !pFrm->IsBodyFrm() && pFrm->GetUpper() )
[ - + ]
131 : 0 : _ValidateBodyFrm( pFrm->GetUpper() );
132 [ + - ]: 69 : if( !pFrm->IsSctFrm() )
133 : 69 : pFrm->Calc();
134 : : else
135 : : {
136 : 0 : sal_Bool bOld = ((SwSectionFrm*)pFrm)->IsCntntLocked();
137 : 0 : ((SwSectionFrm*)pFrm)->SetCntntLock( sal_True );
138 : 0 : pFrm->Calc();
139 [ # # ]: 0 : if( !bOld )
140 : 0 : ((SwSectionFrm*)pFrm)->SetCntntLock( sal_False );
141 : : }
142 : : }
143 : 69 : }
144 : :
145 : 69 : void SwTxtFrm::ValidateBodyFrm()
146 : : {
147 [ - + ][ # # ]: 69 : SWAP_IF_SWAPPED( this )
[ - + ]
148 : :
149 : : // See comment in ValidateFrm()
150 [ + - ]: 138 : if ( !IsInFly() && !IsInTab() &&
[ + - - + ]
[ + - ]
151 [ # # ]: 69 : !( IsInSct() && FindSctFrm()->Lower()->IsColumnFrm() ) )
152 : 69 : _ValidateBodyFrm( GetUpper() );
153 : :
154 [ - + ]: 69 : UNDO_SWAP( this )
155 : 69 : }
156 : :
157 : 459 : sal_Bool SwTxtFrm::_GetDropRect( SwRect &rRect ) const
158 : : {
159 [ + - ][ - + ]: 459 : SWAP_IF_NOT_SWAPPED( this )
[ # # ][ - + ]
[ # # ]
160 : :
161 : : OSL_ENSURE( HasPara(), "SwTxtFrm::_GetDropRect: try again next year." );
162 [ + - ]: 459 : SwTxtSizeInfo aInf( (SwTxtFrm*)this );
163 [ + - ]: 459 : SwTxtMargin aLine( (SwTxtFrm*)this, &aInf );
164 [ - + ]: 459 : if( aLine.GetDropLines() )
165 : : {
166 : 0 : rRect.Top( aLine.Y() );
167 [ # # ]: 0 : rRect.Left( aLine.GetLineStart() );
168 : 0 : rRect.Height( aLine.GetDropHeight() );
169 : 0 : rRect.Width( aLine.GetDropLeft() );
170 : :
171 [ # # ][ # # ]: 0 : if ( IsRightToLeft() )
172 [ # # ]: 0 : SwitchLTRtoRTL( rRect );
173 : :
174 [ # # ][ # # ]: 0 : if ( IsVertical() )
175 [ # # ]: 0 : SwitchHorizontalToVertical( rRect );
176 [ # # ][ # # ]: 0 : UNDO_SWAP( this )
177 : 0 : return sal_True;
178 : : }
179 : :
180 [ - + ][ # # ]: 459 : UNDO_SWAP( this )
181 : :
182 [ + - ]: 459 : return sal_False;
183 : : }
184 : :
185 : 14881 : const SwBodyFrm *SwTxtFrm::FindBodyFrm() const
186 : : {
187 [ + + ]: 14881 : if ( IsInDocBody() )
188 : : {
189 : 14245 : const SwFrm *pFrm = GetUpper();
190 [ + - ][ + + ]: 20547 : while( pFrm && !pFrm->IsBodyFrm() )
[ + + ]
191 : 6302 : pFrm = pFrm->GetUpper();
192 : 14245 : return (const SwBodyFrm*)pFrm;
193 : : }
194 : 14881 : return 0;
195 : : }
196 : :
197 : 692 : sal_Bool SwTxtFrm::CalcFollow( const xub_StrLen nTxtOfst )
198 : : {
199 [ - + ][ # # ]: 692 : SWAP_IF_SWAPPED( this )
[ - + ]
200 : :
201 : : OSL_ENSURE( HasFollow(), "CalcFollow: missing Follow." );
202 : :
203 : 692 : SwTxtFrm* pMyFollow = GetFollow();
204 : :
205 : 692 : SwParaPortion *pPara = GetPara();
206 [ + - ]: 692 : sal_Bool bFollowFld = pPara ? pPara->IsFollowField() : sal_False;
207 : :
208 [ + + ][ + - ]: 964 : if( !pMyFollow->GetOfst() || pMyFollow->GetOfst() != nTxtOfst ||
[ + - + -
- + # # +
- - + ]
[ + + ]
209 : 68 : bFollowFld || pMyFollow->IsFieldFollow() ||
210 : 68 : ( pMyFollow->IsVertical() && !pMyFollow->Prt().Width() ) ||
211 : 136 : ( ! pMyFollow->IsVertical() && !pMyFollow->Prt().Height() ) )
212 : : {
213 : : #if OSL_DEBUG_LEVEL > 0
214 : : const SwFrm *pOldUp = GetUpper();
215 : : #endif
216 : :
217 [ + - ][ - + ]: 624 : SWRECTFN ( this )
[ # # ][ # # ]
[ - + ]
218 [ + - ][ + - ]: 624 : SwTwips nOldBottom = (GetUpper()->Frm().*fnRect->fnGetBottom)();
219 [ + - ][ + - ]: 624 : SwTwips nMyPos = (Frm().*fnRect->fnGetTop)();
220 : :
221 : 624 : const SwPageFrm *pPage = 0;
222 : 624 : sal_Bool bOldInvaCntnt = sal_True;
223 [ + - ][ + - ]: 624 : if ( !IsInFly() && GetNext() )
[ + + ][ + + ]
224 : : {
225 [ + - ]: 63 : pPage = FindPageFrm();
226 : : // Minimize = that is set back if needed - for invalidation see below
227 : 63 : bOldInvaCntnt = pPage->IsInvalidCntnt();
228 : : }
229 : :
230 [ + - ]: 624 : pMyFollow->_SetOfst( nTxtOfst );
231 : 624 : pMyFollow->SetFieldFollow( bFollowFld );
232 [ - + ][ - + ]: 624 : if( HasFtn() || pMyFollow->HasFtn() )
[ + - ]
233 : : {
234 [ # # ]: 0 : ValidateFrm();
235 [ # # ]: 0 : ValidateBodyFrm();
236 [ # # ]: 0 : if( pPara )
237 : : {
238 : 0 : *(pPara->GetReformat()) = SwCharRange();
239 : 0 : *(pPara->GetDelta()) = 0;
240 : : }
241 : : }
242 : :
243 : : // The footnote area must not get larger
244 [ + - ][ + - ]: 624 : SwSaveFtnHeight aSave( FindFtnBossFrm( sal_True ), LONG_MAX );
245 : :
246 [ + - ]: 624 : pMyFollow->CalcFtnFlag();
247 [ + + ][ + - ]: 624 : if ( !pMyFollow->GetNext() && !pMyFollow->HasFtn() )
[ + + ]
248 [ - + ]: 342 : nOldBottom = bVert ? 0 : LONG_MAX;
249 : :
250 : 0 : while( sal_True )
251 : : {
252 [ + - ]: 624 : if( !FormatLevel::LastLevel() )
253 : : {
254 : : // If the follow is contained within a column section or column
255 : : // frame, we need to calculate that first. This is because the
256 : : // FormatWidthCols() does not work if it is called from MakeAll
257 : : // of the _locked_ follow.
258 [ + - ]: 624 : SwSectionFrm* pSct = pMyFollow->FindSctFrm();
259 [ - + ][ # # ]: 624 : if( pSct && !pSct->IsAnLower( this ) )
[ # # ][ - + ]
260 : : {
261 [ # # ]: 0 : if( pSct->GetFollow() )
262 [ # # ]: 0 : pSct->SimpleFormat();
263 [ # # ][ # # ]: 0 : else if( ( pSct->IsVertical() && !pSct->Frm().Width() ) ||
[ # # ]
[ # # # # ]
[ # # ]
264 [ # # ]: 0 : ( ! pSct->IsVertical() && !pSct->Frm().Height() ) )
265 : 0 : break;
266 : : }
267 : : // OD 14.03.2003 #i11760# - intrinsic format of follow is controlled.
268 [ + - ]: 624 : if ( FollowFormatAllowed() )
269 : : {
270 : : // OD 14.03.2003 #i11760# - no nested format of follows, if
271 : : // text frame is contained in a column frame.
272 : : // Thus, forbid intrinsic format of follow.
273 : : {
274 : 624 : bool bIsFollowInColumn = false;
275 : 624 : SwFrm* pFollowUpper = pMyFollow->GetUpper();
276 [ + - ]: 1248 : while ( pFollowUpper )
277 : : {
278 [ - + ]: 1248 : if ( pFollowUpper->IsColumnFrm() )
279 : : {
280 : 0 : bIsFollowInColumn = true;
281 : 0 : break;
282 : : }
283 [ + + - + ]: 1872 : if ( pFollowUpper->IsPageFrm() ||
[ + + ]
284 : 624 : pFollowUpper->IsFlyFrm() )
285 : : {
286 : 624 : break;
287 : : }
288 : 624 : pFollowUpper = pFollowUpper->GetUpper();
289 : : }
290 [ - + ]: 624 : if ( bIsFollowInColumn )
291 : : {
292 : 0 : pMyFollow->ForbidFollowFormat();
293 : : }
294 : : }
295 : :
296 [ + - ]: 624 : pMyFollow->Calc();
297 : : // The Follow can tell from its Frm().Height() that something went wrong
298 : : OSL_ENSURE( !pMyFollow->GetPrev(), "SwTxtFrm::CalcFollow: cheesy follow" );
299 [ - + ]: 624 : if( pMyFollow->GetPrev() )
300 : : {
301 [ # # ]: 0 : pMyFollow->Prepare( PREP_CLEAR );
302 [ # # ]: 0 : pMyFollow->Calc();
303 : : OSL_ENSURE( !pMyFollow->GetPrev(), "SwTxtFrm::CalcFollow: very cheesy follow" );
304 : : }
305 : :
306 : : // OD 14.03.2003 #i11760# - reset control flag for follow format.
307 : 624 : pMyFollow->AllowFollowFormat();
308 : : }
309 : :
310 : : // Make sure that the Follow gets painted
311 : 624 : pMyFollow->SetCompletePaint();
312 : : }
313 : :
314 [ + - ]: 624 : pPara = GetPara();
315 : : // As long as the Follow is requested due to orphan lines, it is passed these
316 : : // and is reformatted if possible
317 [ + - ][ - + ]: 624 : if( pPara && pPara->IsPrepWidows() )
[ - + ]
318 [ # # ]: 0 : CalcPreps();
319 : : else
320 : 624 : break;
321 : : }
322 : :
323 [ + - ][ - + ]: 624 : if( HasFtn() || pMyFollow->HasFtn() )
[ - + ]
324 : : {
325 [ # # ]: 0 : ValidateBodyFrm();
326 [ # # ]: 0 : ValidateFrm();
327 [ # # ]: 0 : if( pPara )
328 : : {
329 : 0 : *(pPara->GetReformat()) = SwCharRange();
330 : 0 : *(pPara->GetDelta()) = 0;
331 : : }
332 : : }
333 : :
334 [ + + ]: 624 : if ( pPage )
335 : : {
336 [ - + ]: 63 : if ( !bOldInvaCntnt )
337 : 0 : pPage->ValidateCntnt();
338 : : }
339 : :
340 : : #if OSL_DEBUG_LEVEL > 0
341 : : OSL_ENSURE( pOldUp == GetUpper(), "SwTxtFrm::CalcFollow: heavy follow" );
342 : : #endif
343 : :
344 : : const long nRemaining =
345 [ + - ][ + - ]: 624 : - (GetUpper()->Frm().*fnRect->fnBottomDist)( nOldBottom );
346 [ - + ][ # # ]: 624 : if ( nRemaining > 0 && !GetUpper()->IsSctFrm() &&
[ # # ][ # # ]
[ - + ]
347 : : nRemaining != ( bVert ?
348 : 0 : nMyPos - Frm().Right() :
349 : 0 : Frm().Top() - nMyPos ) )
350 : : {
351 [ # # ][ # # ]: 0 : UNDO_SWAP( this )
352 : 624 : return sal_True;
353 [ + - ][ + - ]: 624 : }
354 : : }
355 : :
356 [ - + ]: 692 : UNDO_SWAP( this )
357 : :
358 : 692 : return sal_False;
359 : : }
360 : :
361 : 19434 : void SwTxtFrm::AdjustFrm( const SwTwips nChgHght, sal_Bool bHasToFit )
362 : : {
363 [ + + ]: 19434 : if( IsUndersized() )
364 : : {
365 [ + + ][ + - ]: 213 : if( GetOfst() && !IsFollow() ) // A scrolled paragraph (undersized)
[ + + ]
366 : 42 : return;
367 [ + - ][ - + ]: 171 : SetUndersized( nChgHght == 0 || bHasToFit );
368 : : }
369 : :
370 : : // AdjustFrm is called with a swapped frame during
371 : : // formatting but the frame is not swapped during FormatEmpty
372 [ - + ][ # # ]: 19392 : SWAP_IF_SWAPPED( this )
[ - + ]
373 [ - + ][ # # ]: 19392 : SWRECTFN ( this )
[ # # ][ - + ]
374 : :
375 : : // The Frame's size variable is incremented by Grow or decremented by Shrink.
376 : : // If the size cannot change, nothing should happen!
377 [ + + ]: 19392 : if( nChgHght >= 0)
378 : : {
379 : 18908 : SwTwips nChgHeight = nChgHght;
380 [ + + ][ + - ]: 18908 : if( nChgHght && !bHasToFit )
381 : : {
382 [ + + ][ + + ]: 7139 : if( IsInFtn() && !IsInSct() )
[ + + ]
383 : : {
384 : 75 : SwTwips nReal = Grow( nChgHght, sal_True );
385 [ - + ]: 75 : if( nReal < nChgHght )
386 : : {
387 : 0 : SwTwips nBot = (*fnRect->fnYInc)( (Frm().*fnRect->fnGetBottom)(),
388 [ # # ]: 0 : nChgHght - nReal );
389 : 0 : SwFrm* pCont = FindFtnFrm()->GetUpper();
390 : :
391 [ # # ][ # # ]: 0 : if( (pCont->Frm().*fnRect->fnBottomDist)( nBot ) > 0 )
392 : : {
393 [ # # ]: 0 : (Frm().*fnRect->fnAddBottom)( nChgHght );
394 [ # # ]: 0 : if( bVert )
395 : 0 : Prt().SSize().Width() += nChgHght;
396 : : else
397 : 0 : Prt().SSize().Height() += nChgHght;
398 [ # # ]: 0 : UNDO_SWAP( this )
399 : 0 : return;
400 : : }
401 : : }
402 : : }
403 : :
404 : 7139 : Grow( nChgHght );
405 : :
406 [ + + ]: 7139 : if ( IsInFly() )
407 : : {
408 : : // If one of the Upper is a Fly, it's very likely that this fly changes its
409 : : // position by the Grow. Therefore, my position has to be corrected also or
410 : : // the check further down is not meaningful.
411 : : // The predecessors need to be calculated, so that the position can be
412 : : // calculated correctly.
413 [ + + ]: 170 : if ( GetPrev() )
414 : : {
415 : 16 : SwFrm *pPre = GetUpper()->Lower();
416 [ + + ][ + + ]: 27 : do
[ + - ]
417 [ + - ]: 27 : { pPre->Calc();
418 : 27 : pPre = pPre->GetNext();
419 : : } while ( pPre && pPre != this );
420 : : }
421 : 170 : const Point aOldPos( Frm().Pos() );
422 [ + - ]: 170 : MakePos();
423 [ + + ]: 170 : if ( aOldPos != Frm().Pos() )
424 : : {
425 : : // OD 2004-07-01 #i28701# - use new method <SwFrm::InvalidateObjs(..)>
426 : : // No format is performed for the floating screen objects.
427 [ + - ]: 170 : InvalidateObjs( true );
428 : : }
429 : : }
430 : 7139 : nChgHeight = 0;
431 : : }
432 : : // A Grow() is always accepted by the Layout, even if the
433 : : // FixSize of the surrounding layout frame should not allow it.
434 : : // We text for this case and correct the values.
435 : : // The Frm must NOT be shrinked further than its size permits
436 : : // even in the case of an emergency.
437 : : SwTwips nRstHeight;
438 [ - + ]: 18908 : if ( IsVertical() )
439 : : {
440 : : OSL_ENSURE( ! IsSwapped(),"Swapped frame while calculating nRstHeight" );
441 : :
442 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
443 [ # # ]: 0 : if ( IsVertLR() )
444 : 0 : nRstHeight = GetUpper()->Frm().Left()
445 : 0 : + GetUpper()->Prt().Left()
446 : 0 : + GetUpper()->Prt().Width()
447 : 0 : - Frm().Left();
448 : : else
449 : 0 : nRstHeight = Frm().Left() + Frm().Width() -
450 : 0 : ( GetUpper()->Frm().Left() + GetUpper()->Prt().Left() );
451 : : }
452 : : else
453 : 18908 : nRstHeight = GetUpper()->Frm().Top()
454 : 18908 : + GetUpper()->Prt().Top()
455 : 18908 : + GetUpper()->Prt().Height()
456 : 18908 : - Frm().Top();
457 : :
458 : : // We can get a bit of space in table cells, because there could be some
459 : : // left through a vertical alignment to the top.
460 : : // #115759# - assure, that first lower in upper
461 : : // is the current one or is valid.
462 [ + + + + : 23617 : if ( IsInTab() &&
+ - ][ + + ]
463 : 4702 : ( GetUpper()->Lower() == this ||
464 : 7 : GetUpper()->Lower()->IsValid() ) )
465 : : {
466 : 4702 : long nAdd = (*fnRect->fnYDiff)( (GetUpper()->Lower()->Frm().*fnRect->fnGetTop)(),
467 [ + - ][ + - ]: 9404 : (GetUpper()->*fnRect->fnGetPrtTop)() );
468 : : OSL_ENSURE( nAdd >= 0, "Ey" );
469 : 4702 : nRstHeight += nAdd;
470 : : }
471 : :
472 : : /* ------------------------------------
473 : : * nRstHeight < 0 means that the TxtFrm is located completely outside of its Upper.
474 : : * This can happen, if it's located within a FlyAtCntFrm, which changed sides by a
475 : : * Grow(). In such a case, it's wrong to execute the following Grow().
476 : : * In the case of a bug, we end up with an infinite loop.
477 : : * -----------------------------------*/
478 [ + - ]: 18908 : SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)();
479 [ + - ]: 18908 : SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)();
480 : :
481 [ + + ]: 18908 : if( nRstHeight < nFrmHeight )
482 : : {
483 : : // It can be that I have the right size, but the Upper is too small and can get me some room
484 [ + + ][ - + ]: 349 : if( ( nRstHeight >= 0 || ( IsInFtn() && IsInSct() ) ) && !bHasToFit )
[ # # ][ + + ]
[ + + ]
485 : 296 : nRstHeight += GetUpper()->Grow( nFrmHeight - nRstHeight );
486 : : // In column sections we do not want to get too big or else more areas are created by
487 : : // GetNextSctLeaf. Instead, we shrink and remember bUndersized, so that FormatWidthCols
488 : : // can calculate the right column size.
489 [ + + ]: 349 : if ( nRstHeight < nFrmHeight )
490 : : {
491 [ + + ][ + + : 657 : if( bHasToFit || !IsMoveable() ||
+ + - + ]
[ + + ]
492 : 310 : ( IsInSct() && !FindSctFrm()->MoveAllowed(this) ) )
493 : : {
494 : 142 : SetUndersized( sal_True );
495 : 142 : Shrink( Min( ( nFrmHeight - nRstHeight), nPrtHeight ) );
496 : : }
497 : : else
498 : 205 : SetUndersized( sal_False );
499 : : }
500 : : }
501 [ - + ]: 18559 : else if( nChgHeight )
502 : : {
503 [ # # ]: 0 : if( nRstHeight - nFrmHeight < nChgHeight )
504 : 0 : nChgHeight = nRstHeight - nFrmHeight;
505 [ # # ]: 0 : if( nChgHeight )
506 : 0 : Grow( nChgHeight );
507 : : }
508 : : }
509 : : else
510 : 484 : Shrink( -nChgHght );
511 : :
512 [ - + ]: 19434 : UNDO_SWAP( this )
513 : : }
514 : :
515 : : /*************************************************************************
516 : : * SwTxtFrm::AdjustFollow()
517 : : * AdjustFollow expects the following situation:
518 : : * The SwTxtIter points to the lower end of the Master, the Offset is set in
519 : : * the Follow.
520 : : * nOffset holds the Offset in the text string, from which the Master closes
521 : : * and the Follow starts.
522 : : * If it's 0, the FollowFrame is deleted.
523 : : *************************************************************************/
524 : :
525 : 966 : void SwTxtFrm::_AdjustFollow( SwTxtFormatter &rLine,
526 : : const xub_StrLen nOffset, const xub_StrLen nEnd,
527 : : const sal_uInt8 nMode )
528 : : {
529 [ + - ]: 966 : SwFrmSwapper aSwapper( this, sal_False );
530 : :
531 : : // We got the rest of the text mass: Delete all Follows
532 : : // DummyPortions() are a special case.
533 : : // Special cases are controlled by parameter <nMode>.
534 [ + + ][ + + ]: 966 : if( HasFollow() && !(nMode & 1) && nOffset == nEnd )
[ + + ][ + + ]
535 : : {
536 [ + + ]: 88 : while( GetFollow() )
537 : : {
538 [ - + ]: 45 : if( ((SwTxtFrm*)GetFollow())->IsLocked() )
539 : : {
540 : : OSL_FAIL( "+SwTxtFrm::JoinFrm: Follow is locked." );
541 : : return;
542 : : }
543 [ + - ]: 45 : JoinFrm();
544 : : }
545 : :
546 : : return;
547 : : }
548 : :
549 : : // Dancing on the volcano: We'll just format the last line quickly
550 : : // for the QuoVadis stuff.
551 : : // The Offset can move of course:
552 [ + - ][ + - ]: 1182 : const xub_StrLen nNewOfst = ( IsInFtn() && ( !GetIndNext() || HasFollow() ) ) ?
553 [ + + ]: 1182 : rLine.FormatQuoVadis(nOffset) : nOffset;
[ + + - + ]
[ + - ]
554 : :
555 [ + + ]: 923 : if( !(nMode & 1) )
556 : : {
557 : : // We steal text mass from our Follows
558 : : // It can happen that we have to join some of them
559 [ + + ]: 299 : while( GetFollow() && GetFollow()->GetFollow() &&
[ - + # # ]
[ - + ]
560 : 0 : nNewOfst >= GetFollow()->GetFollow()->GetOfst() )
561 : : {
562 [ # # ]: 0 : JoinFrm();
563 : : }
564 : : }
565 : :
566 : : // The Offset moved
567 [ + + ]: 923 : if( GetFollow() )
568 : : {
569 : : #if OSL_DEBUG_LEVEL > 1
570 : : static sal_Bool bTest = sal_False;
571 : : if( !bTest || ( nMode & 1 ) )
572 : : #endif
573 [ + + ]: 692 : if ( nMode )
574 : 624 : GetFollow()->ManipOfst( 0 );
575 : :
576 [ + - ][ - + ]: 692 : if ( CalcFollow( nNewOfst ) ) // CalcFollow only at the end, we do a SetOfst there
577 : 923 : rLine.SetOnceMore( sal_True );
578 [ + - ][ + + ]: 966 : }
579 : : }
580 : :
581 : 45 : SwCntntFrm *SwTxtFrm::JoinFrm()
582 : : {
583 : : OSL_ENSURE( GetFollow(), "+SwTxtFrm::JoinFrm: no follow" );
584 : 45 : SwTxtFrm *pFoll = GetFollow();
585 : :
586 : 45 : SwTxtFrm *pNxt = pFoll->GetFollow();
587 : :
588 : : // All footnotes of the to-be-destroyed Follow are relocated to us
589 : 45 : xub_StrLen nStart = pFoll->GetOfst();
590 [ - + ]: 45 : if ( pFoll->HasFtn() )
591 : : {
592 : 0 : const SwpHints *pHints = pFoll->GetTxtNode()->GetpSwpHints();
593 [ # # ]: 0 : if( pHints )
594 : : {
595 : 0 : SwFtnBossFrm *pFtnBoss = 0;
596 : 0 : SwFtnBossFrm *pEndBoss = 0;
597 [ # # ]: 0 : for ( sal_uInt16 i = 0; i < pHints->Count(); ++i )
598 : : {
599 : 0 : const SwTxtAttr *pHt = (*pHints)[i];
600 [ # # ][ # # ]: 0 : if( RES_TXTATR_FTN==pHt->Which() && *pHt->GetStart()>=nStart )
[ # # ]
601 : : {
602 [ # # ]: 0 : if( pHt->GetFtn().IsEndNote() )
603 : : {
604 [ # # ]: 0 : if( !pEndBoss )
605 : 0 : pEndBoss = pFoll->FindFtnBossFrm();
606 : 0 : pEndBoss->ChangeFtnRef( pFoll, (SwTxtFtn*)pHt, this );
607 : : }
608 : : else
609 : : {
610 [ # # ]: 0 : if( !pFtnBoss )
611 : 0 : pFtnBoss = pFoll->FindFtnBossFrm( sal_True );
612 : 0 : pFtnBoss->ChangeFtnRef( pFoll, (SwTxtFtn*)pHt, this );
613 : : }
614 : 0 : SetFtn( sal_True );
615 : : }
616 : : }
617 : : }
618 : : }
619 : :
620 : : #ifdef DBG_UTIL
621 : : else if ( pFoll->GetValidPrtAreaFlag() ||
622 : : pFoll->GetValidSizeFlag() )
623 : : {
624 : : pFoll->CalcFtnFlag();
625 : : OSL_ENSURE( !pFoll->HasFtn(), "Missing FtnFlag." );
626 : : }
627 : : #endif
628 : :
629 : 45 : pFoll->MoveFlyInCnt( this, nStart, STRING_LEN );
630 : 45 : pFoll->SetFtn( sal_False );
631 : : // #i27138#
632 : : // notify accessibility paragraphs objects about changed CONTENT_FLOWS_FROM/_TO relation.
633 : : // Relation CONTENT_FLOWS_FROM for current next paragraph will change
634 : : // and relation CONTENT_FLOWS_TO for current previous paragraph, which
635 : : // is <this>, will change.
636 : : {
637 : 45 : ViewShell* pViewShell( pFoll->getRootFrm()->GetCurrShell() );
638 [ + - - + ]: 90 : if ( pViewShell && pViewShell->GetLayout() &&
[ - + ][ + - ]
639 : 45 : pViewShell->GetLayout()->IsAnyShellAccessible() )
640 : : {
641 : : pViewShell->InvalidateAccessibleParaFlowRelation(
642 : 0 : dynamic_cast<SwTxtFrm*>(pFoll->FindNextCnt( true )),
643 [ # # ]: 0 : this );
644 : : }
645 : : }
646 : 45 : pFoll->Cut();
647 [ + + ]: 45 : SetFollow(pNxt);
648 [ + - ]: 45 : delete pFoll;
649 : 45 : return pNxt;
650 : : }
651 : :
652 : 63 : SwCntntFrm *SwTxtFrm::SplitFrm( const xub_StrLen nTxtPos )
653 : : {
654 [ + - ][ - + ]: 63 : SWAP_IF_SWAPPED( this )
[ # # ][ - + ]
[ # # ]
655 : :
656 : : // The Paste sends a Modify() to me
657 : : // I lock myself, so that my data does not disappear
658 : 63 : SwTxtFrmLocker aLock( this );
659 [ + - ]: 63 : SwTxtFrm *pNew = (SwTxtFrm *)(GetTxtNode()->MakeFrm( this ));
660 : :
661 [ - + ][ + - ]: 63 : pNew->SetFollow( GetFollow() );
662 [ + - ][ + - ]: 63 : SetFollow( pNew );
663 : :
664 [ + - ]: 63 : pNew->Paste( GetUpper(), GetNext() );
665 : : // #i27138#
666 : : // notify accessibility paragraphs objects about changed CONTENT_FLOWS_FROM/_TO relation.
667 : : // Relation CONTENT_FLOWS_FROM for current next paragraph will change
668 : : // and relation CONTENT_FLOWS_TO for current previous paragraph, which
669 : : // is <this>, will change.
670 : : {
671 : 63 : ViewShell* pViewShell( pNew->getRootFrm()->GetCurrShell() );
672 [ + - ]: 126 : if ( pViewShell && pViewShell->GetLayout() &&
[ + - - + ]
[ - + ][ + - ]
673 [ + - ]: 63 : pViewShell->GetLayout()->IsAnyShellAccessible() )
674 : : {
675 : : pViewShell->InvalidateAccessibleParaFlowRelation(
676 [ # # ]: 0 : dynamic_cast<SwTxtFrm*>(pNew->FindNextCnt( true )),
677 [ # # ][ # # ]: 0 : this );
678 : : }
679 : : }
680 : :
681 : : // If footnotes end up in pNew bz our actions, we need
682 : : // to re-register them
683 [ - + ]: 63 : if ( HasFtn() )
684 : : {
685 : 0 : const SwpHints *pHints = GetTxtNode()->GetpSwpHints();
686 [ # # ]: 0 : if( pHints )
687 : : {
688 : 0 : SwFtnBossFrm *pFtnBoss = 0;
689 : 0 : SwFtnBossFrm *pEndBoss = 0;
690 [ # # ]: 0 : for ( sal_uInt16 i = 0; i < pHints->Count(); ++i )
691 : : {
692 [ # # ]: 0 : const SwTxtAttr *pHt = (*pHints)[i];
693 [ # # ][ # # ]: 0 : if( RES_TXTATR_FTN==pHt->Which() && *pHt->GetStart()>=nTxtPos )
[ # # ][ # # ]
694 : : {
695 [ # # ]: 0 : if( pHt->GetFtn().IsEndNote() )
696 : : {
697 [ # # ]: 0 : if( !pEndBoss )
698 [ # # ]: 0 : pEndBoss = FindFtnBossFrm();
699 [ # # ]: 0 : pEndBoss->ChangeFtnRef( this, (SwTxtFtn*)pHt, pNew );
700 : : }
701 : : else
702 : : {
703 [ # # ]: 0 : if( !pFtnBoss )
704 [ # # ]: 0 : pFtnBoss = FindFtnBossFrm( sal_True );
705 [ # # ]: 0 : pFtnBoss->ChangeFtnRef( this, (SwTxtFtn*)pHt, pNew );
706 : : }
707 : 0 : pNew->SetFtn( sal_True );
708 : : }
709 : : }
710 : : }
711 : : }
712 : :
713 : : #ifdef DBG_UTIL
714 : : else
715 : : {
716 : : CalcFtnFlag( nTxtPos-1 );
717 : : OSL_ENSURE( !HasFtn(), "Missing FtnFlag." );
718 : : }
719 : : #endif
720 : :
721 [ + - ]: 63 : MoveFlyInCnt( pNew, nTxtPos, STRING_LEN );
722 : :
723 : : // No SetOfst or CalcFollow, because an AdjustFollow follows immediately anyways
724 : :
725 : 63 : pNew->ManipOfst( nTxtPos );
726 : :
727 [ # # ][ - + ]: 63 : UNDO_SWAP( this )
728 : 63 : return pNew;
729 : : }
730 : :
731 : 668 : void SwTxtFrm::_SetOfst( const xub_StrLen nNewOfst )
732 : : {
733 : : // We do not need to invalidate out Follow.
734 : : // We are a Follow, get formatted right away and call
735 : : // SetOfst() from there
736 : 668 : nOfst = nNewOfst;
737 : 668 : SwParaPortion *pPara = GetPara();
738 [ + + ]: 668 : if( pPara )
739 : : {
740 : 598 : SwCharRange &rReformat = *(pPara->GetReformat());
741 : 598 : rReformat.Start() = 0;
742 : 598 : rReformat.Len() = GetTxt().Len();
743 : 598 : *(pPara->GetDelta()) = rReformat.Len();
744 : : }
745 : 668 : InvalidateSize();
746 : 668 : }
747 : :
748 : 15169 : sal_Bool SwTxtFrm::CalcPreps()
749 : : {
750 : : OSL_ENSURE( ! IsVertical() || ! IsSwapped(), "SwTxtFrm::CalcPreps with swapped frame" );
751 [ - + ][ # # ]: 15169 : SWRECTFN( this );
[ # # ][ - + ]
752 : :
753 : 15169 : SwParaPortion *pPara = GetPara();
754 [ + + ]: 15169 : if ( !pPara )
755 : 4863 : return sal_False;
756 : 10306 : sal_Bool bPrep = pPara->IsPrep();
757 : 10306 : sal_Bool bPrepWidows = pPara->IsPrepWidows();
758 : 10306 : sal_Bool bPrepAdjust = pPara->IsPrepAdjust();
759 : 10306 : sal_Bool bPrepMustFit = pPara->IsPrepMustFit();
760 : 10306 : ResetPreps();
761 : :
762 : 10306 : sal_Bool bRet = sal_False;
763 [ + + ][ + + ]: 10306 : if( bPrep && !pPara->GetReformat()->Len() )
[ + + ]
764 : : {
765 : : // PREP_WIDOWS means that the orphans rule got activated in the Follow.
766 : : // In unfortunate cases we could also have a PrepAdjust!
767 [ - + ]: 688 : if( bPrepWidows )
768 : : {
769 [ # # ]: 0 : if( !GetFollow() )
770 : : {
771 : : OSL_ENSURE( GetFollow(), "+SwTxtFrm::CalcPreps: no credits" );
772 : 0 : return sal_False;
773 : : }
774 : :
775 : : // We need to prepare for two cases:
776 : : // We were able to hand over a few lines to the Follow
777 : : // -> we need to shrink
778 : : // or we need to go on the next page
779 : : // -> we let our Frame become too big
780 : :
781 : 0 : SwTwips nChgHeight = GetParHeight();
782 [ # # ][ # # ]: 0 : if( nChgHeight >= (Prt().*fnRect->fnGetHeight)() )
783 : : {
784 [ # # ]: 0 : if( bPrepMustFit )
785 : : {
786 : 0 : GetFollow()->SetJustWidow( sal_True );
787 : 0 : GetFollow()->Prepare( PREP_CLEAR );
788 : : }
789 [ # # ]: 0 : else if ( bVert )
790 : : {
791 : 0 : Frm().Width( Frm().Width() + Frm().Left() );
792 : 0 : Prt().Width( Prt().Width() + Frm().Left() );
793 : 0 : Frm().Left( 0 );
794 : 0 : SetWidow( sal_True );
795 : : }
796 : : else
797 : : {
798 : 0 : SwTwips nTmp = LONG_MAX - (Frm().Top()+10000);
799 : 0 : SwTwips nDiff = nTmp - Frm().Height();
800 : 0 : Frm().Height( nTmp );
801 : 0 : Prt().Height( Prt().Height() + nDiff );
802 : 0 : SetWidow( sal_True );
803 : : }
804 : : }
805 : : else
806 : : {
807 : : OSL_ENSURE( nChgHeight < (Prt().*fnRect->fnGetHeight)(),
808 : : "+SwTxtFrm::CalcPrep: wanna shrink" );
809 : :
810 [ # # ]: 0 : nChgHeight = (Prt().*fnRect->fnGetHeight)() - nChgHeight;
811 : :
812 : 0 : GetFollow()->SetJustWidow( sal_True );
813 : 0 : GetFollow()->Prepare( PREP_CLEAR );
814 : 0 : Shrink( nChgHeight );
815 : 0 : SwRect &rRepaint = *(pPara->GetRepaint());
816 : :
817 [ # # ]: 0 : if ( bVert )
818 : : {
819 : 0 : SwRect aRepaint( Frm().Pos() + Prt().Pos(), Prt().SSize() );
820 [ # # ]: 0 : SwitchVerticalToHorizontal( aRepaint );
821 : 0 : rRepaint.Chg( aRepaint.Pos(), aRepaint.SSize() );
822 : : }
823 : : else
824 : 0 : rRepaint.Chg( Frm().Pos() + Prt().Pos(), Prt().SSize() );
825 : :
826 [ # # ]: 0 : if( 0 >= rRepaint.Width() )
827 : 0 : rRepaint.Width(1);
828 : : }
829 : 0 : bRet = sal_True;
830 : : }
831 : :
832 [ + + ]: 688 : else if ( bPrepAdjust )
833 : : {
834 [ + + ]: 666 : if ( HasFtn() )
835 : : {
836 [ + - ][ - + ]: 14 : if( !CalcPrepFtnAdjust() )
837 : : {
838 [ # # ]: 0 : if( bPrepMustFit )
839 : : {
840 [ # # ]: 0 : SwTxtLineAccess aAccess( this );
841 [ # # ][ # # ]: 0 : aAccess.GetPara()->SetPrepMustFit( sal_True );
842 : : }
843 : 0 : return sal_False;
844 : : }
845 : : }
846 : :
847 [ + - ][ - + ]: 666 : SWAP_IF_NOT_SWAPPED( this )
[ # # ][ - + ]
[ # # ]
848 : :
849 [ + - ]: 666 : SwTxtFormatInfo aInf( this );
850 [ + - ]: 666 : SwTxtFormatter aLine( this, &aInf );
851 : :
852 [ + - ]: 666 : WidowsAndOrphans aFrmBreak( this );
853 : : // Whatever the attributes say: we split the paragraph in
854 : : // MustFit in any case
855 [ + + ]: 666 : if( bPrepMustFit )
856 : : {
857 : 50 : aFrmBreak.SetKeep( sal_False );
858 : 50 : aFrmBreak.ClrOrphLines();
859 : : }
860 : : // Before calling FormatAdjust, we need to make sure
861 : : // that the lines protruding at the bottom get indeed
862 : : // truncated
863 [ + - ]: 666 : sal_Bool bBreak = aFrmBreak.IsBreakNowWidAndOrp( aLine );
864 : 666 : bRet = sal_True;
865 [ + + ][ + - ]: 4688 : while( !bBreak && aLine.Next() )
[ + + ][ + + ]
866 : : {
867 [ + - ]: 4022 : bBreak = aFrmBreak.IsBreakNowWidAndOrp( aLine );
868 : : }
869 [ + + ]: 666 : if( bBreak )
870 : : {
871 : : // We run into troubles: when TruncLines get called, the
872 : : // conditions in IsInside change immediately such that
873 : : // IsBreakNow can return different results.
874 : : // For this reason, we make it clear to rFrmBreak, that the
875 : : // end is reached at the location of rLine.
876 : : // Let's see if it works ...
877 [ + - ]: 323 : aLine.TruncLines();
878 [ + - ]: 323 : aFrmBreak.SetRstHeight( aLine );
879 [ + - ]: 323 : FormatAdjust( aLine, aFrmBreak, aInf.GetTxt().Len(), aInf.IsStop() );
880 : : }
881 : : else
882 : : {
883 [ + + ]: 343 : if( !GetFollow() )
884 : : {
885 : : FormatAdjust( aLine, aFrmBreak,
886 [ + - ]: 273 : aInf.GetTxt().Len(), aInf.IsStop() );
887 : : }
888 [ + + ]: 70 : else if ( !aFrmBreak.IsKeepAlways() )
889 : : {
890 : : // We delete a line before the Master, because the Follow
891 : : // could hand over a line
892 : 48 : const SwCharRange aFollowRg( GetFollow()->GetOfst(), 1 );
893 [ + - ]: 48 : *(pPara->GetReformat()) += aFollowRg;
894 : : // We should continue!
895 : 48 : bRet = sal_False;
896 : : }
897 : : }
898 : :
899 [ - + ][ # # ]: 666 : UNDO_SWAP( this )
900 : : // A final check, if FormatAdjust() didn't help we need to
901 : : // truncate
902 [ + + ]: 666 : if( bPrepMustFit )
903 : : {
904 [ + - ][ + - ]: 50 : const SwTwips nMust = (GetUpper()->*fnRect->fnGetPrtBottom)();
905 [ + - ][ + - ]: 50 : const SwTwips nIs = (Frm().*fnRect->fnGetBottom)();
906 : :
907 [ - + ][ # # ]: 50 : if( bVert && nIs < nMust )
908 : : {
909 [ # # ]: 0 : Shrink( nMust - nIs );
910 [ # # ]: 0 : if( Prt().Width() < 0 )
911 : 0 : Prt().Width( 0 );
912 : 0 : SetUndersized( sal_True );
913 : : }
914 [ + - ][ + - ]: 50 : else if ( ! bVert && nIs > nMust )
915 : : {
916 [ + - ]: 50 : Shrink( nIs - nMust );
917 [ - + ]: 50 : if( Prt().Height() < 0 )
918 : 0 : Prt().Height( 0 );
919 : 50 : SetUndersized( sal_True );
920 : : }
921 [ + - ][ + - ]: 666 : }
922 : : }
923 : : }
924 : 10306 : pPara->SetPrepMustFit( bPrepMustFit );
925 : 15169 : return bRet;
926 : : }
927 : :
928 : : /*************************************************************************
929 : : * SwTxtFrm::FormatAdjust()
930 : : * We rewire the footnotes and the character bound objects
931 : : *************************************************************************/
932 : :
933 : : #define CHG_OFFSET( pFrm, nNew )\
934 : : {\
935 : : if( pFrm->GetOfst() < nNew )\
936 : : pFrm->MoveFlyInCnt( this, 0, nNew );\
937 : : else if( pFrm->GetOfst() > nNew )\
938 : : MoveFlyInCnt( pFrm, nNew, STRING_LEN );\
939 : : }
940 : :
941 : 14711 : void SwTxtFrm::FormatAdjust( SwTxtFormatter &rLine,
942 : : WidowsAndOrphans &rFrmBreak,
943 : : const xub_StrLen nStrLen,
944 : : const sal_Bool bDummy )
945 : : {
946 [ - + ][ # # ]: 14711 : SWAP_IF_NOT_SWAPPED( this )
[ - + ]
947 : :
948 : 14711 : SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
949 : :
950 : 14711 : xub_StrLen nEnd = rLine.GetStart();
951 : :
952 : 14711 : sal_Bool bHasToFit = pPara->IsPrepMustFit();
953 : :
954 : : // The StopFlag is set by footnotes which want to go onto the next page
955 : : // Call base class method <SwTxtFrmBreak::IsBreakNow(..)>
956 : : // instead of method <WidowsAndOrphans::IsBreakNow(..)> to get a break,
957 : : // even if due to widow rule no enough lines exists.
958 : 14711 : sal_uInt8 nNew = ( !GetFollow() &&
959 : : nEnd < nStrLen &&
960 : 11960 : ( rLine.IsStop() ||
961 : : ( bHasToFit
962 : 0 : ? ( rLine.GetLineNr() > 1 &&
963 : 0 : !rFrmBreak.IsInside( rLine ) )
964 [ + + ]: 11960 : : rFrmBreak.IsBreakNow( rLine ) ) ) )
965 [ + + + - ]: 38631 : ? 1 : 0;
[ - + # #
# # ][ + + ]
966 : : // --> OD #i84870#
967 : : // no split of text frame, which only contains a as-character anchored object
968 : : const bool bOnlyContainsAsCharAnchoredObj =
969 : 14711 : !IsFollow() && nStrLen == 1 &&
970 : 1648 : GetDrawObjs() && GetDrawObjs()->Count() == 1 &&
971 [ + + + + : 16359 : (*GetDrawObjs())[0]->GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AS_CHAR;
+ + ][ + + ]
[ + + ]
972 [ + + ][ - + ]: 14711 : if ( nNew && bOnlyContainsAsCharAnchoredObj )
973 : : {
974 : 0 : nNew = 0;
975 : : }
976 : : // <--
977 [ + + ]: 14711 : if ( nNew )
978 : : {
979 : 63 : SplitFrm( nEnd );
980 : : }
981 : :
982 : 14711 : const SwFrm *pBodyFrm = (const SwFrm*)(FindBodyFrm());
983 : :
984 : 14075 : const long nBodyHeight = pBodyFrm ? ( IsVertical() ?
985 : 0 : pBodyFrm->Frm().Width() :
986 [ + + - + ]: 28786 : pBodyFrm->Frm().Height() ) : 0;
987 : :
988 : : // If the current values have been calculated, show that they
989 : : // are valid now
990 : 14711 : *(pPara->GetReformat()) = SwCharRange();
991 : 14711 : sal_Bool bDelta = *pPara->GetDelta() != 0;
992 : 14711 : *(pPara->GetDelta()) = 0;
993 : :
994 [ - + ]: 14711 : if( rLine.IsStop() )
995 : : {
996 : 0 : rLine.TruncLines( sal_True );
997 : 0 : nNew = 1;
998 : : }
999 : :
1000 : : // FindBreak truncates the last line
1001 [ + + ]: 14711 : if( !rFrmBreak.FindBreak( this, rLine, bHasToFit ) )
1002 : : {
1003 : : // If we're done formatting, we set nEnd to the end.
1004 : : // AdjustFollow might execute JoinFrm() because of this.
1005 : : // Else, nEnd is the end of the last line in the Master.
1006 : 14017 : xub_StrLen nOld = nEnd;
1007 : 14017 : nEnd = rLine.GetEnd();
1008 [ + + ]: 14017 : if( GetFollow() )
1009 : : {
1010 [ - + ][ # # ]: 43 : if( nNew && nOld < nEnd )
1011 : 0 : RemoveFtn( nOld, nEnd - nOld );
1012 [ + + ][ + - ]: 43 : CHG_OFFSET( GetFollow(), nEnd )
1013 [ - + ]: 43 : if( !bDelta )
1014 : 0 : GetFollow()->ManipOfst( nEnd );
1015 : : }
1016 : : }
1017 : : else
1018 : : { // If we pass over lines, we must not call Join in Follows, instead we even
1019 : : // need to create a Follow.
1020 : : // We also need to do this if the whole mass of text remains in the Master,
1021 : : // because a hard line break could necessitate another line (without text mass)!
1022 : 694 : nEnd = rLine.GetEnd();
1023 [ + + ]: 694 : if( GetFollow() )
1024 : : {
1025 : : // Another case for not joining the follow:
1026 : : // Text frame has no content, but a numbering. Then, do *not* join.
1027 : : // Example of this case: When an empty, but numbered paragraph
1028 : : // at the end of page is completely displaced by a fly frame.
1029 : : // Thus, the text frame introduced a follow by a
1030 : : // <SwTxtFrm::SplitFrm(..)> - see below. The follow then shows
1031 : : // the numbering and must stay.
1032 [ + + + - ]: 823 : if ( GetFollow()->GetOfst() != nEnd ||
[ - + # # ]
[ + + ]
1033 : 131 : GetFollow()->IsFieldFollow() ||
1034 : 0 : ( nStrLen == 0 && GetTxtNode()->GetNumRule() ) )
1035 : : {
1036 : 561 : nNew |= 3;
1037 : : }
1038 [ + + ][ + + ]: 692 : CHG_OFFSET( GetFollow(), nEnd )
1039 : 692 : GetFollow()->ManipOfst( nEnd );
1040 : : }
1041 : : else
1042 : : {
1043 : : // Only split frame, if the frame contains
1044 : : // content or contains no content, but has a numbering.
1045 : : // OD #i84870# - no split, if text frame only contains one
1046 : : // as-character anchored object.
1047 [ + - ][ + - ]: 4 : if ( !bOnlyContainsAsCharAnchoredObj &&
[ + - - + ]
[ - + ]
1048 : : ( nStrLen > 0 ||
1049 : 2 : ( nStrLen == 0 && GetTxtNode()->GetNumRule() ) )
1050 : : )
1051 : : {
1052 : 0 : SplitFrm( nEnd );
1053 : 0 : nNew |= 3;
1054 : : }
1055 : : }
1056 : : // If the remaining height changed e.g by RemoveFtn() we need to
1057 : : // fill up in order to avoid oscillation.
1058 [ - + ]: 694 : if( bDummy && pBodyFrm &&
[ # # # # ]
[ # # ][ - + ]
1059 : 0 : nBodyHeight < ( IsVertical() ?
1060 : 0 : pBodyFrm->Frm().Width() :
1061 : 0 : pBodyFrm->Frm().Height() ) )
1062 : 0 : rLine.MakeDummyLine();
1063 : : }
1064 : :
1065 : : // In AdjustFrm() we set ourselves via Grow/Shrink
1066 : : // In AdjustFollow() we set our FollowFrame
1067 : :
1068 : 14711 : const SwTwips nDocPrtTop = Frm().Top() + Prt().Top();
1069 : 14711 : const SwTwips nOldHeight = Prt().SSize().Height();
1070 : 14711 : SwTwips nChg = rLine.CalcBottomLine() - nDocPrtTop - nOldHeight;
1071 : : // --> OD #i84870# - no shrink of text frame, if it only contains one
1072 : : // as-character anchored object.
1073 [ + + ][ + + ]: 14711 : if ( nChg < 0 &&
1074 : : bOnlyContainsAsCharAnchoredObj )
1075 : : {
1076 : 2 : nChg = 0;
1077 : : }
1078 : : // <--
1079 : :
1080 : : // Vertical Formatting:
1081 : : // The (rotated) repaint rectangle's x coordinate referes to the frame.
1082 : : // If the frame grows (or shirks) the repaint rectangle cannot simply
1083 : : // be rotated back after formatting, because we use the upper left point
1084 : : // of the frame for rotation. This point changes when growing/shrinking.
1085 : :
1086 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
1087 [ - + ][ # # ]: 14711 : if ( IsVertical() && !IsVertLR() && nChg )
[ # # ][ - + ]
1088 : : {
1089 : 0 : SwRect &rRepaint = *(pPara->GetRepaint());
1090 : 0 : rRepaint.Left( rRepaint.Left() - nChg );
1091 : 0 : rRepaint.Width( rRepaint.Width() - nChg );
1092 : : }
1093 : :
1094 : 14711 : AdjustFrm( nChg, bHasToFit );
1095 : :
1096 [ + + ][ + + ]: 14711 : if( HasFollow() || IsInFtn() )
[ + + ]
1097 : 966 : _AdjustFollow( rLine, nEnd, nStrLen, nNew );
1098 : :
1099 : 14711 : pPara->SetPrepMustFit( sal_False );
1100 : :
1101 [ - + ]: 14711 : UNDO_SWAP( this )
1102 : 14711 : }
1103 : :
1104 : : /*************************************************************************
1105 : : * SwTxtFrm::FormatLine()
1106 : : * bPrev is set whether Reformat.Start() was called because of Prev().
1107 : : * Else, wo don't know whether we can limit the repaint or not.
1108 : : *************************************************************************/
1109 : :
1110 : 52762 : sal_Bool SwTxtFrm::FormatLine( SwTxtFormatter &rLine, const sal_Bool bPrev )
1111 : : {
1112 : : OSL_ENSURE( ! IsVertical() || IsSwapped(),
1113 : : "SwTxtFrm::FormatLine( rLine, bPrev) with unswapped frame" );
1114 : 52762 : SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
1115 : 52762 : const SwLineLayout *pOldCur = rLine.GetCurr();
1116 : 52762 : const xub_StrLen nOldLen = pOldCur->GetLen();
1117 : 52762 : const KSHORT nOldAscent = pOldCur->GetAscent();
1118 : 52762 : const KSHORT nOldHeight = pOldCur->Height();
1119 [ + - ]: 52762 : const SwTwips nOldWidth = pOldCur->Width() + pOldCur->GetHangingMargin();
1120 : 52762 : const sal_Bool bOldHyph = pOldCur->IsEndHyph();
1121 : 52762 : SwTwips nOldTop = 0;
1122 : 52762 : SwTwips nOldBottom = 0;
1123 [ - + ]: 52762 : if( rLine.GetCurr()->IsClipping() )
1124 [ # # ]: 0 : rLine.CalcUnclipped( nOldTop, nOldBottom );
1125 : :
1126 [ + - ]: 52762 : const xub_StrLen nNewStart = rLine.FormatLine( rLine.GetStart() );
1127 : :
1128 : : OSL_ENSURE( Frm().Pos().Y() + Prt().Pos().Y() == rLine.GetFirstPos(),
1129 : : "SwTxtFrm::FormatLine: frame leaves orbit." );
1130 : : OSL_ENSURE( rLine.GetCurr()->Height(),
1131 : : "SwTxtFrm::FormatLine: line height is zero" );
1132 : :
1133 : : // The current line break object
1134 : 52762 : const SwLineLayout *pNew = rLine.GetCurr();
1135 : :
1136 : 52762 : sal_Bool bUnChg = nOldLen == pNew->GetLen() &&
1137 [ + - ][ + + ]: 52762 : bOldHyph == pNew->IsEndHyph();
1138 [ + + ][ + + ]: 52762 : if ( bUnChg && !bPrev )
1139 : : {
1140 : 25551 : const long nWidthDiff = nOldWidth > pNew->Width()
1141 : 1735 : ? nOldWidth - pNew->Width()
1142 [ + + ]: 27286 : : pNew->Width() - nOldWidth;
1143 : :
1144 : : // we only declare a line as unchanged, if its main values have not
1145 : : // changed and it is not the last line (!paragraph end symbol!)
1146 : 25551 : bUnChg = nOldHeight == pNew->Height() &&
1147 : 23974 : nOldAscent == pNew->GetAscent() &&
1148 : : nWidthDiff <= SLOPPY_TWIPS &&
1149 [ + + ][ + + ]: 49525 : pOldCur->GetNext();
[ + + + + ]
1150 : : }
1151 : :
1152 : : // Calculate rRepaint
1153 : 52762 : const SwTwips nBottom = rLine.Y() + rLine.GetLineHeight();
1154 : 52762 : SwRepaint &rRepaint = *(pPara->GetRepaint());
1155 [ + + ][ + + : 54559 : if( bUnChg && rRepaint.Top() == rLine.Y()
+ + + + ]
[ + + ][ + + ]
1156 : 583 : && (bPrev || nNewStart <= pPara->GetReformat()->Start())
1157 : 1214 : && ( nNewStart < GetTxtNode()->GetTxt().Len() ) )
1158 : : {
1159 : 1212 : rRepaint.Top( nBottom );
1160 : 1212 : rRepaint.Height( 0 );
1161 : : }
1162 : : else
1163 : : {
1164 [ - + ]: 51550 : if( nOldTop )
1165 : : {
1166 [ # # ]: 0 : if( nOldTop < rRepaint.Top() )
1167 : 0 : rRepaint.Top( nOldTop );
1168 [ # # ][ # # ]: 0 : if( !rLine.IsUnclipped() || nOldBottom > rRepaint.Bottom() )
[ # # ]
1169 : : {
1170 : 0 : rRepaint.Bottom( nOldBottom - 1 );
1171 : 0 : rLine.SetUnclipped( sal_True );
1172 : : }
1173 : : }
1174 [ - + ][ # # ]: 51550 : if( rLine.GetCurr()->IsClipping() && rLine.IsFlyInCntBase() )
[ - + ]
1175 : : {
1176 : : SwTwips nTmpTop, nTmpBottom;
1177 [ # # ]: 0 : rLine.CalcUnclipped( nTmpTop, nTmpBottom );
1178 [ # # ]: 0 : if( nTmpTop < rRepaint.Top() )
1179 : 0 : rRepaint.Top( nTmpTop );
1180 [ # # ][ # # ]: 0 : if( !rLine.IsUnclipped() || nTmpBottom > rRepaint.Bottom() )
[ # # ]
1181 : : {
1182 : 0 : rRepaint.Bottom( nTmpBottom - 1 );
1183 : 0 : rLine.SetUnclipped( sal_True );
1184 : : }
1185 : : }
1186 : : else
1187 : : {
1188 [ - + ][ # # ]: 51550 : if( !rLine.IsUnclipped() || nBottom > rRepaint.Bottom() )
[ + - ]
1189 : : {
1190 : 51550 : rRepaint.Bottom( nBottom - 1 );
1191 : 51550 : rLine.SetUnclipped( sal_False );
1192 : : }
1193 : : }
1194 : 51550 : SwTwips nRght = Max( nOldWidth, pNew->Width() +
1195 [ + - ]: 51550 : pNew->GetHangingMargin() );
1196 : 51550 : ViewShell *pSh = getRootFrm()->GetCurrShell();
1197 [ + - ]: 51550 : const SwViewOption *pOpt = pSh ? pSh->GetViewOptions() : 0;
1198 [ + - ][ + - ]: 51550 : if( pOpt && (pOpt->IsParagraph() || pOpt->IsLineBreak()) )
[ - + ][ - + ]
1199 : 0 : nRght += ( Max( nOldAscent, pNew->GetAscent() ) );
1200 : : else
1201 : 51550 : nRght += ( Max( nOldAscent, pNew->GetAscent() ) / 4);
1202 [ + - ]: 51550 : nRght += rLine.GetLeftMargin();
1203 [ + + ][ + + ]: 51550 : if( rRepaint.GetOfst() || rRepaint.GetRightOfst() < nRght )
[ + + ]
1204 : 17781 : rRepaint.SetRightOfst( nRght );
1205 : :
1206 : : // Finally we enlarge the repaint rectangle if we found an underscore
1207 : : // within our line. 40 Twips should be enough
1208 : : const sal_Bool bHasUnderscore =
1209 : 51550 : ( rLine.GetInfo().GetUnderScorePos() < nNewStart );
1210 [ + + ][ + + ]: 51550 : if ( bHasUnderscore || rLine.GetCurr()->HasUnderscore() )
[ + + ]
1211 : 88 : rRepaint.Bottom( rRepaint.Bottom() + 40 );
1212 : :
1213 : 51550 : ((SwLineLayout*)rLine.GetCurr())->SetUnderscore( bHasUnderscore );
1214 : : }
1215 [ + + ]: 52762 : if( !bUnChg )
1216 : 32091 : rLine.SetChanges();
1217 : :
1218 : : // Calculating the good ol' nDelta
1219 : 52762 : *(pPara->GetDelta()) -= long(pNew->GetLen()) - long(nOldLen);
1220 : :
1221 : : // Stop!
1222 [ - + ][ + - ]: 52762 : if( rLine.IsStop() )
1223 : 0 : return sal_False;
1224 : :
1225 : : // Absolutely another line
1226 [ + - ][ + + ]: 52762 : if( rLine.IsNewLine() )
1227 : 97 : return sal_True;
1228 : :
1229 : : // Until the String's end?
1230 [ + + ]: 52665 : if( nNewStart >= GetTxtNode()->GetTxt().Len() )
1231 : 11785 : return sal_False;
1232 : :
1233 [ + + ]: 40880 : if( rLine.GetInfo().IsShift() )
1234 : 5603 : return sal_True;
1235 : :
1236 : : // Reached the Reformat's end?
1237 : 35277 : const xub_StrLen nEnd = pPara->GetReformat()->Start() +
1238 : 35277 : pPara->GetReformat()->Len();
1239 : :
1240 [ + + ]: 35277 : if( nNewStart <= nEnd )
1241 : 12261 : return sal_True;
1242 : :
1243 : 52762 : return 0 != *(pPara->GetDelta());
1244 : : }
1245 : :
1246 : 14117 : void SwTxtFrm::_Format( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf,
1247 : : const sal_Bool bAdjust )
1248 : : {
1249 : : OSL_ENSURE( ! IsVertical() || IsSwapped(),"SwTxtFrm::_Format with unswapped frame" );
1250 : :
1251 : 14117 : SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
1252 : 14117 : rLine.SetUnclipped( sal_False );
1253 : :
1254 : : // That was too complicated for the C30: aString( GetTxt() );
1255 : 14117 : const XubString &rString = GetTxtNode()->GetTxt();
1256 : 14117 : const xub_StrLen nStrLen = rString.Len();
1257 : :
1258 : 14117 : SwCharRange &rReformat = *(pPara->GetReformat());
1259 : 14117 : SwRepaint &rRepaint = *(pPara->GetRepaint());
1260 : 14117 : SwRepaint *pFreeze = NULL;
1261 : :
1262 : : // Due to performance reasons we set rReformat to STRING_LEN in Init()
1263 : : // In this case we adjust rReformat
1264 [ + + ]: 14117 : if( rReformat.Len() > nStrLen )
1265 : 5268 : rReformat.Len() = nStrLen;
1266 : :
1267 : : // Optimized:
1268 : 14117 : xub_StrLen nEnd = rReformat.Start() + rReformat.Len();
1269 [ + + ]: 14117 : if( nEnd > nStrLen )
1270 : : {
1271 : 45 : rReformat.Len() = nStrLen - rReformat.Start();
1272 : 45 : nEnd = nStrLen;
1273 : : }
1274 : :
1275 : : SwTwips nOldBottom;
1276 [ + + ][ + + ]: 14117 : if( GetOfst() && !IsFollow() )
[ + + ]
1277 : : {
1278 [ + - ]: 42 : rLine.Bottom();
1279 : 42 : nOldBottom = rLine.Y();
1280 [ + - ]: 42 : rLine.Top();
1281 : : }
1282 : : else
1283 : 14075 : nOldBottom = 0;
1284 [ + - ]: 14117 : rLine.CharToLine( rReformat.Start() );
1285 : :
1286 : : // Words can be swapped-out when inserting a space into the
1287 : : // line that comes before the edited one. That's why we also
1288 : : // need to format that.
1289 : : // Optimization: If rReformat starts after the first word of the line
1290 : : // this line cannot possibly influence the previous one.
1291 : : // Unfortunately it can: Text size changes + FlyFrames.
1292 : : // The backlash can affect multiple lines (Frame!)!
1293 : :
1294 : : // #i46560#
1295 : : // FME: Yes, consider this case: (word) has to go to the next line
1296 : : // because) is a forbidden character at the beginning of a line although
1297 : : // (word would still fit on the previous line. Adding text right in front
1298 : : // of) would not trigger a reformatting of the previous line. Adding 1
1299 : : // to the result of FindBrk() does not solve the problem in all cases,
1300 : : // nevertheless it should be sufficient.
1301 [ + - ]: 14117 : sal_Bool bPrev = rLine.GetPrev() &&
1302 [ + - ]: 2868 : ( FindBrk( rString, rLine.GetStart(), rReformat.Start() + 1 )
1303 : : // #i46560#
1304 : : + 1
1305 : 2868 : >= rReformat.Start() ||
1306 [ + + + + ]: 16985 : rLine.GetCurr()->IsRest() );
[ - + ]
1307 [ + + ]: 14117 : if( bPrev )
1308 : : {
1309 [ + - ][ + + ]: 1288 : while( rLine.Prev() )
1310 [ + + ][ + - ]: 1287 : if( rLine.GetCurr()->GetLen() && !rLine.GetCurr()->IsRest() )
[ + + ]
1311 : : {
1312 [ + + ]: 1284 : if( !rLine.GetStart() )
1313 [ + - ]: 72 : rLine.Top(); // So that NumDone doesn't get confused
1314 : 1284 : break;
1315 : : }
1316 : 1285 : xub_StrLen nNew = rLine.GetStart() + rLine.GetLength();
1317 [ + + ]: 1285 : if( nNew )
1318 : : {
1319 : 1284 : --nNew;
1320 [ + + ]: 1284 : if( CH_BREAK == rString.GetChar( nNew ) )
1321 : : {
1322 : 63 : ++nNew;
1323 [ + - ]: 63 : rLine.Next();
1324 : 63 : bPrev = sal_False;
1325 : : }
1326 : : }
1327 : 1285 : rReformat.Len() += rReformat.Start() - nNew;
1328 : 1285 : rReformat.Start() = nNew;
1329 : : }
1330 : :
1331 : 14117 : rRepaint.SetOfst( 0 );
1332 : 14117 : rRepaint.SetRightOfst( 0 );
1333 : 14117 : rRepaint.Chg( Frm().Pos() + Prt().Pos(), Prt().SSize() );
1334 [ - + ]: 14117 : if( pPara->IsMargin() )
1335 [ # # ]: 0 : rRepaint.Width( rRepaint.Width() + pPara->GetHangingMargin() );
1336 : 14117 : rRepaint.Top( rLine.Y() );
1337 [ - + ]: 14117 : if( 0 >= rRepaint.Width() )
1338 : 0 : rRepaint.Width(1);
1339 [ + + ][ + - ]: 14117 : WidowsAndOrphans aFrmBreak( this, rInf.IsTest() ? 1 : 0 );
1340 : :
1341 : : // rLine is now set to the first line which needs formatting.
1342 : : // The bFirst flag makes sure that Next() is not called.
1343 : : // The whole thing looks weird, but we need to make sure that
1344 : : // rLine stops at the last non-fitting line when calling IsBreakNow.
1345 : 14117 : sal_Bool bFirst = sal_True;
1346 : 14117 : sal_Bool bFormat = sal_True;
1347 : :
1348 : : // The CharToLine() can also get us into the danger zone.
1349 : : // In that case we need to walk back until rLine is set
1350 : : // to the non-fitting line. Or else the mass of text is lost,
1351 : : // because the Ofst was set wrongly in the Follow.
1352 : :
1353 : 14143 : sal_Bool bBreak = ( !pPara->IsPrepMustFit() || rLine.GetLineNr() > 1 )
1354 [ + - ][ + + ]: 14143 : && aFrmBreak.IsBreakNowWidAndOrp( rLine );
[ + + - + ]
1355 [ + + ]: 14117 : if( bBreak )
1356 : : {
1357 [ + - ]: 48 : sal_Bool bPrevDone = 0 != rLine.Prev();
1358 [ - + ][ # # ]: 48 : while( bPrevDone && aFrmBreak.IsBreakNowWidAndOrp(rLine) )
[ # # ][ - + ]
1359 [ # # ]: 0 : bPrevDone = 0 != rLine.Prev();
1360 [ - + ]: 48 : if( bPrevDone )
1361 : : {
1362 : 0 : aFrmBreak.SetKeep( sal_False );
1363 [ # # ]: 0 : rLine.Next();
1364 : : }
1365 [ + - ]: 48 : rLine.TruncLines();
1366 : :
1367 : : // Play it safe
1368 [ + - ]: 48 : bBreak = aFrmBreak.IsBreakNowWidAndOrp(rLine) &&
1369 [ + - ][ - + ]: 48 : ( !pPara->IsPrepMustFit() || rLine.GetLineNr() > 1 );
[ # # ]
1370 : : }
1371 : :
1372 : : /* Meaning if the following flags are set:
1373 : :
1374 : : Watch(End/Mid)Hyph: we need to format if we have a break at
1375 : : the line end/Fly, as long as MaxHyph is reached
1376 : :
1377 : : Jump(End/Mid)Flag: the next line which has no break (line end/Fly),
1378 : : needs to be formatted, because we could wrap now. This might have been
1379 : : forbidden earlier by MaxHyph
1380 : :
1381 : : Watch(End/Mid)Hyph: if the last formatted line got a cutoff point, but
1382 : : didn't have one before
1383 : :
1384 : : Jump(End/Mid)Hyph: if a cutoff point disappears
1385 : : */
1386 : 14117 : sal_Bool bJumpEndHyph = sal_False,
1387 : 14117 : bWatchEndHyph = sal_False,
1388 : 14117 : bJumpMidHyph = sal_False,
1389 : 14117 : bWatchMidHyph = sal_False;
1390 : :
1391 [ + - ]: 14117 : const SwAttrSet& rAttrSet = GetTxtNode()->GetSwAttrSet();
1392 : : sal_Bool bMaxHyph = ( 0 !=
1393 [ + - ]: 14117 : ( rInf.MaxHyph() = rAttrSet.GetHyphenZone().GetMaxHyphens() ) );
1394 [ + + ]: 14117 : if ( bMaxHyph )
1395 [ + - ]: 3 : rLine.InitCntHyph();
1396 : :
1397 [ + + ][ - + ]: 14117 : if( IsFollow() && IsFieldFollow() && rLine.GetStart() == GetOfst() )
[ # # ][ - + ]
1398 : : {
1399 [ # # ]: 0 : SwTxtFrm *pMaster = FindMaster();
1400 : : OSL_ENSURE( pMaster, "SwTxtFrm::Format: homeless follow" );
1401 : 0 : const SwLineLayout* pLine=NULL;
1402 [ # # ]: 0 : if (pMaster)
1403 : : {
1404 [ # # ][ # # ]: 0 : if( !pMaster->HasPara() )
1405 [ # # ]: 0 : pMaster->GetFormatted();
1406 [ # # ]: 0 : SwTxtSizeInfo aInf( pMaster );
1407 [ # # ]: 0 : SwTxtIter aMasterLine( pMaster, &aInf );
1408 [ # # ]: 0 : aMasterLine.Bottom();
1409 [ # # ]: 0 : pLine = aMasterLine.GetCurr();
1410 : : }
1411 : : SwLinePortion* pRest = pLine ?
1412 [ # # ][ # # ]: 0 : rLine.MakeRestPortion(pLine, GetOfst()) : NULL;
1413 [ # # ]: 0 : if( pRest )
1414 : 0 : rInf.SetRest( pRest );
1415 : : else
1416 : 0 : SetFieldFollow( sal_False );
1417 : : }
1418 : :
1419 : : /* Ad cancel criterion:
1420 : : * In order to recognize, whether a line does not fit onto the page
1421 : : * anymore, we need to format it. This overflow is removed again in
1422 : : * e.g. AdjustFollow.
1423 : : * Another complication: if we are the Master, we need to traverse
1424 : : * the lines, because it could happen that one line can overflow
1425 : : * from the Follow to the Master.
1426 : : */
1427 [ + + ]: 39011 : do
1428 : : {
1429 [ + + ]: 52762 : if( bFirst )
1430 : 14117 : bFirst = sal_False;
1431 : : else
1432 : : {
1433 [ - + ]: 38645 : if ( bMaxHyph )
1434 : : {
1435 [ # # ]: 0 : if ( rLine.GetCurr()->IsEndHyph() )
1436 : 0 : rLine.CntEndHyph()++;
1437 : : else
1438 : 0 : rLine.CntEndHyph() = 0;
1439 [ # # ]: 0 : if ( rLine.GetCurr()->IsMidHyph() )
1440 : 0 : rLine.CntMidHyph()++;
1441 : : else
1442 : 0 : rLine.CntMidHyph() = 0;
1443 : : }
1444 [ + - ][ + + ]: 38645 : if( !rLine.Next() )
1445 : : {
1446 [ + + ]: 6910 : if( !bFormat )
1447 : : {
1448 : : SwLinePortion* pRest =
1449 [ + - ]: 70 : rLine.MakeRestPortion( rLine.GetCurr(), rLine.GetEnd() );
1450 [ - + ]: 70 : if( pRest )
1451 : 0 : rInf.SetRest( pRest );
1452 : : }
1453 [ + - ][ + - ]: 6910 : rLine.Insert( new SwLineLayout() );
[ + - ]
1454 [ + - ]: 6910 : rLine.Next();
1455 : 6910 : bFormat = sal_True;
1456 : : }
1457 : : }
1458 [ - + ][ # # ]: 52762 : if ( !bFormat && bMaxHyph &&
[ # # ][ # # ]
[ # # ][ # # ]
1459 : : (bWatchEndHyph || bJumpEndHyph || bWatchMidHyph || bJumpMidHyph) )
1460 : : {
1461 [ # # ]: 0 : if ( rLine.GetCurr()->IsEndHyph() )
1462 : : {
1463 [ # # ]: 0 : if ( bWatchEndHyph )
1464 : 0 : bFormat = ( rLine.CntEndHyph() == rInf.MaxHyph() );
1465 : : }
1466 : : else
1467 : : {
1468 : 0 : bFormat = bJumpEndHyph;
1469 : 0 : bWatchEndHyph = sal_False;
1470 : 0 : bJumpEndHyph = sal_False;
1471 : : }
1472 [ # # ]: 0 : if ( rLine.GetCurr()->IsMidHyph() )
1473 : : {
1474 [ # # ][ # # ]: 0 : if ( bWatchMidHyph && !bFormat )
1475 : 0 : bFormat = ( rLine.CntEndHyph() == rInf.MaxHyph() );
1476 : : }
1477 : : else
1478 : : {
1479 [ # # ][ # # ]: 0 : bFormat = bFormat || bJumpMidHyph;
1480 : 0 : bWatchMidHyph = sal_False;
1481 : 0 : bJumpMidHyph = sal_False;
1482 : : }
1483 : : }
1484 [ + - ]: 52762 : if( bFormat )
1485 : : {
1486 : 52762 : sal_Bool bOldEndHyph = rLine.GetCurr()->IsEndHyph();
1487 : 52762 : sal_Bool bOldMidHyph = rLine.GetCurr()->IsMidHyph();
1488 [ + - ]: 52762 : bFormat = FormatLine( rLine, bPrev );
1489 : : // There can only be one bPrev ... (???)
1490 : 52762 : bPrev = sal_False;
1491 [ + + ]: 52762 : if ( bMaxHyph )
1492 : : {
1493 [ - + ]: 3 : if ( rLine.GetCurr()->IsEndHyph() != bOldEndHyph )
1494 : : {
1495 : 0 : bWatchEndHyph = !bOldEndHyph;
1496 : 0 : bJumpEndHyph = bOldEndHyph;
1497 : : }
1498 [ - + ]: 3 : if ( rLine.GetCurr()->IsMidHyph() != bOldMidHyph )
1499 : : {
1500 : 0 : bWatchMidHyph = !bOldMidHyph;
1501 : 0 : bJumpMidHyph = bOldMidHyph;
1502 : : }
1503 : : }
1504 : : }
1505 : :
1506 [ + + ]: 52762 : if( !rInf.IsNewLine() )
1507 : : {
1508 [ + + ]: 52665 : if( !bFormat )
1509 : 13821 : bFormat = 0 != rInf.GetRest();
1510 [ + - ][ + + ]: 52665 : if( rInf.IsStop() || rInf.GetIdx() >= nStrLen )
[ + + ]
1511 : 11785 : break;
1512 [ + + ][ - + ]: 40880 : if( !bFormat && ( !bMaxHyph || ( !bWatchEndHyph &&
[ # # ][ # # ]
[ # # ][ # # ]
1513 : : !bJumpEndHyph && !bWatchMidHyph && !bJumpMidHyph ) ) )
1514 : : {
1515 [ + + ]: 2036 : if( GetFollow() )
1516 : : {
1517 [ + - ][ + + ]: 1860 : while( rLine.Next() )
1518 : : ; //Nothing
1519 [ + - ]: 70 : pFreeze = new SwRepaint( rRepaint ); // to minimize painting
1520 : : }
1521 : : else
1522 : 1966 : break;
1523 : : }
1524 : : }
1525 [ + - ]: 39011 : bBreak = aFrmBreak.IsBreakNowWidAndOrp(rLine);
1526 : 39011 : }while( !bBreak );
1527 : :
1528 [ + + ]: 14117 : if( pFreeze )
1529 : : {
1530 : 70 : rRepaint = *pFreeze;
1531 : 70 : delete pFreeze;
1532 : : }
1533 : :
1534 [ + - ][ + - ]: 14117 : if( !rLine.IsStop() )
1535 : : {
1536 : : // If we're finished formatting the text and we still
1537 : : // have other line objects left, these are superfluous
1538 : : // now because the text has gotten shorter.
1539 [ + + + + ]: 25902 : if( rLine.GetStart() + rLine.GetLength() >= nStrLen &&
[ + + ]
1540 : 11785 : rLine.GetCurr()->GetNext() )
1541 : : {
1542 [ + - ]: 112 : rLine.TruncLines();
1543 : 112 : rLine.SetTruncLines( sal_True );
1544 : : }
1545 : : }
1546 : :
1547 [ + + ]: 14117 : if( !rInf.IsTest() )
1548 : : {
1549 : : // FormatAdjust does not pay off at OnceMore
1550 [ + - ][ - + ]: 14115 : if( bAdjust || !rLine.GetDropFmt() || !rLine.CalcOnceMore() )
[ # # ][ # # ]
[ + - ]
1551 : : {
1552 [ + - ]: 14115 : FormatAdjust( rLine, aFrmBreak, nStrLen, rInf.IsStop() );
1553 : : }
1554 [ + - ][ + - ]: 14115 : if( rRepaint.HasArea() )
1555 : 14115 : SetRepaint();
1556 : 14115 : rLine.SetTruncLines( sal_False );
1557 [ + + ]: 14115 : if( nOldBottom ) // We check whether paragraphs that need scrolling can
1558 : : // be shrunk, so that they don't need scrolling anymore
1559 : : {
1560 [ + - ]: 42 : rLine.Bottom();
1561 : 42 : SwTwips nNewBottom = rLine.Y();
1562 [ - + ]: 42 : if( nNewBottom < nOldBottom )
1563 [ # # ]: 0 : _SetOfst( 0 );
1564 : : }
1565 : : }
1566 : 14117 : }
1567 : :
1568 : 0 : void SwTxtFrm::FormatOnceMore( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf )
1569 : : {
1570 : : OSL_ENSURE( ! IsVertical() || IsSwapped(),
1571 : : "A frame is not swapped in SwTxtFrm::FormatOnceMore" );
1572 : :
1573 : 0 : SwParaPortion *pPara = rLine.GetInfo().GetParaPortion();
1574 [ # # ]: 0 : if( !pPara )
1575 : 0 : return;
1576 : :
1577 : : // If necessary the pPara
1578 : 0 : KSHORT nOld = ((const SwTxtMargin&)rLine).GetDropHeight();
1579 : 0 : sal_Bool bShrink = sal_False,
1580 : 0 : bGrow = sal_False,
1581 : 0 : bGoOn = rLine.IsOnceMore();
1582 : 0 : sal_uInt8 nGo = 0;
1583 [ # # ]: 0 : while( bGoOn )
1584 : : {
1585 : 0 : ++nGo;
1586 [ # # ]: 0 : rInf.Init();
1587 [ # # ]: 0 : rLine.Top();
1588 [ # # ]: 0 : if( !rLine.GetDropFmt() )
1589 : 0 : rLine.SetOnceMore( sal_False );
1590 : 0 : SwCharRange aRange( 0, rInf.GetTxt().Len() );
1591 : 0 : *(pPara->GetReformat()) = aRange;
1592 [ # # ]: 0 : _Format( rLine, rInf );
1593 : :
1594 : 0 : bGoOn = rLine.IsOnceMore();
1595 [ # # ]: 0 : if( bGoOn )
1596 : : {
1597 : 0 : const KSHORT nNew = ((const SwTxtMargin&)rLine).GetDropHeight();
1598 [ # # ]: 0 : if( nOld == nNew )
1599 : 0 : bGoOn = sal_False;
1600 : : else
1601 : : {
1602 [ # # ]: 0 : if( nOld > nNew )
1603 : 0 : bShrink = sal_True;
1604 : : else
1605 : 0 : bGrow = sal_True;
1606 : :
1607 [ # # ][ # # ]: 0 : if( bShrink == bGrow || 5 < nGo )
1608 : 0 : bGoOn = sal_False;
1609 : :
1610 : 0 : nOld = nNew;
1611 : : }
1612 : :
1613 : : // If something went wrong, we need to reformat again
1614 [ # # ]: 0 : if( !bGoOn )
1615 : : {
1616 [ # # ]: 0 : rInf.CtorInitTxtFormatInfo( this );
1617 [ # # ]: 0 : rLine.CtorInitTxtFormatter( this, &rInf );
1618 : 0 : rLine.SetDropLines( 1 );
1619 [ # # ]: 0 : rLine.CalcDropHeight( 1 );
1620 : 0 : SwCharRange aTmpRange( 0, rInf.GetTxt().Len() );
1621 : 0 : *(pPara->GetReformat()) = aTmpRange;
1622 [ # # ]: 0 : _Format( rLine, rInf, sal_True );
1623 : : // We paint everything ...
1624 : 0 : SetCompletePaint();
1625 : : }
1626 : : }
1627 : : }
1628 : : }
1629 : :
1630 : 14115 : void SwTxtFrm::_Format( SwParaPortion *pPara )
1631 : : {
1632 [ + - ]: 14115 : const xub_StrLen nStrLen = GetTxt().Len();
1633 : :
1634 [ + + ]: 14115 : if ( !nStrLen )
1635 : : {
1636 : : // Empty lines do not get tortured for very long:
1637 : : // pPara is cleared, which is the same as:
1638 : : // *pPara = SwParaPortion;
1639 : 1808 : sal_Bool bMustFit = pPara->IsPrepMustFit();
1640 [ + - ]: 1808 : pPara->Truncate();
1641 : 1808 : pPara->FormatReset();
1642 [ - + ][ - + ]: 1808 : if( pBlink && pPara->IsBlinking() )
[ + + ]
1643 [ # # ]: 0 : pBlink->Delete( pPara );
1644 : :
1645 : : // delete pSpaceAdd und pKanaComp
1646 : 1808 : pPara->FinishSpaceAdd();
1647 : 1808 : pPara->FinishKanaComp();
1648 : 1808 : pPara->ResetFlags();
1649 : 1808 : pPara->SetPrepMustFit( bMustFit );
1650 : : }
1651 : :
1652 : : OSL_ENSURE( ! IsSwapped(), "A frame is swapped before _Format" );
1653 : :
1654 [ + - ][ - + ]: 14115 : if ( IsVertical() )
1655 [ # # ]: 0 : SwapWidthAndHeight();
1656 : :
1657 [ + - ]: 14115 : SwTxtFormatInfo aInf( this );
1658 [ + - ]: 14115 : SwTxtFormatter aLine( this, &aInf );
1659 : :
1660 [ + - ]: 14115 : HideAndShowObjects();
1661 : :
1662 [ + - ]: 14115 : _Format( aLine, aInf );
1663 : :
1664 [ - + ]: 14115 : if( aLine.IsOnceMore() )
1665 [ # # ]: 0 : FormatOnceMore( aLine, aInf );
1666 : :
1667 [ + - ][ - + ]: 14115 : if ( IsVertical() )
1668 [ # # ]: 0 : SwapWidthAndHeight();
1669 : :
1670 : : OSL_ENSURE( ! IsSwapped(), "A frame is swapped after _Format" );
1671 : :
1672 [ - + ]: 14115 : if( 1 < aLine.GetDropLines() )
1673 : : {
1674 [ # # # # ]: 0 : if( SVX_ADJUST_LEFT != aLine.GetAdjust() &&
[ # # ]
1675 : 0 : SVX_ADJUST_BLOCK != aLine.GetAdjust() )
1676 : : {
1677 [ # # ]: 0 : aLine.CalcDropAdjust();
1678 : 0 : aLine.SetPaintDrop( sal_True );
1679 : : }
1680 : :
1681 [ # # ]: 0 : if( aLine.IsPaintDrop() )
1682 : : {
1683 [ # # ]: 0 : aLine.CalcDropRepaint();
1684 : 0 : aLine.SetPaintDrop( sal_False );
1685 : : }
1686 [ + - ][ + - ]: 14115 : }
1687 : 14115 : }
1688 : :
1689 : : /*************************************************************************
1690 : : * SwTxtFrm::Format()
1691 : : * We calculate the text frame's size and send a notification.
1692 : : * Shrink() or Grow() to adjust the frame's size to the changed required space.
1693 : : *************************************************************************/
1694 : :
1695 : 20402 : void SwTxtFrm::Format( const SwBorderAttrs * )
1696 : : {
1697 [ + + ][ + - ]: 20402 : SWRECTFN( this )
[ - + ][ - + ]
1698 : :
1699 : 20402 : CalcAdditionalFirstLineOffset();
1700 : :
1701 : : // The range autopilot or the BASIC interface pass us TxtFrms with
1702 : : // a width <= 0 from time to time
1703 [ + + ][ + - ]: 20402 : if( (Prt().*fnRect->fnGetWidth)() <= 0 )
1704 : : {
1705 : : // If MustFit is set, we shrink to the Upper's bottom edge if needed.
1706 : : // Else we just take a standard size of 12 Pt. (240 twip).
1707 [ + - ]: 118 : SwTxtLineAccess aAccess( this );
1708 [ + - ][ + - ]: 118 : long nFrmHeight = (Frm().*fnRect->fnGetHeight)();
1709 [ + - ][ + + ]: 118 : if( aAccess.GetPara()->IsPrepMustFit() )
1710 : : {
1711 [ + - ][ + - ]: 2 : const SwTwips nLimit = (GetUpper()->*fnRect->fnGetPrtBottom)();
1712 [ + - ][ + - ]: 2 : const SwTwips nDiff = - (Frm().*fnRect->fnBottomDist)( nLimit );
1713 [ + - ]: 2 : if( nDiff > 0 )
1714 [ + - ]: 2 : Shrink( nDiff );
1715 : : }
1716 [ + + ]: 116 : else if( 240 < nFrmHeight )
1717 [ + - ]: 14 : Shrink( nFrmHeight - 240 );
1718 [ + + ]: 102 : else if( 240 > nFrmHeight )
1719 [ + - ]: 96 : Grow( 240 - nFrmHeight );
1720 [ + - ][ + - ]: 118 : nFrmHeight = (Frm().*fnRect->fnGetHeight)();
1721 : :
1722 [ + - ][ + - ]: 118 : long nTop = (this->*fnRect->fnGetTopMargin)();
1723 [ - + ]: 118 : if( nTop > nFrmHeight )
1724 [ # # ][ # # ]: 0 : (this->*fnRect->fnSetYMargins)( nFrmHeight, 0 );
1725 [ + - ][ + - ]: 118 : else if( (Prt().*fnRect->fnGetHeight)() < 0 )
[ - + ]
1726 [ # # ][ # # ]: 0 : (Prt().*fnRect->fnSetHeight)( 0 );
1727 [ + - ]: 118 : return;
1728 : : }
1729 : :
1730 : 20284 : const xub_StrLen nStrLen = GetTxtNode()->GetTxt().Len();
1731 [ + + ][ + + ]: 20284 : if ( nStrLen || !FormatEmpty() )
[ + + ]
1732 : : {
1733 : :
1734 : 15607 : SetEmpty( sal_False );
1735 : : // In order to not get confused by nested Formats
1736 : 15607 : FormatLevel aLevel;
1737 [ - + ]: 15607 : if( 12 == aLevel.GetLevel() )
1738 : : return;
1739 : :
1740 : : // We could be possibly not allowed to alter the format information
1741 [ - + ]: 15607 : if( IsLocked() )
1742 : : return;
1743 : :
1744 : : // Attention: Format() could be triggered by GetFormatted()
1745 [ + - ][ + + ]: 15607 : if( IsHiddenNow() )
1746 : : {
1747 [ + - ][ + - ]: 438 : long nPrtHeight = (Prt().*fnRect->fnGetHeight)();
1748 [ + + ]: 438 : if( nPrtHeight )
1749 : : {
1750 [ + - ]: 4 : HideHidden();
1751 [ + - ]: 4 : Shrink( nPrtHeight );
1752 : : }
1753 : : else
1754 : : {
1755 : : // Assure that objects anchored
1756 : : // at paragraph resp. at/as character inside paragraph
1757 : : // are hidden.
1758 [ + - ]: 434 : HideAndShowObjects();
1759 : : }
1760 [ + - ]: 438 : ChgThisLines();
1761 : : return;
1762 : : }
1763 : :
1764 : : // We do not want to be interrupted during formatting
1765 : 15169 : SwTxtFrmLocker aLock(this);
1766 [ + - ]: 15169 : SwTxtLineAccess aAccess( this );
1767 [ + - ]: 15169 : const sal_Bool bNew = !aAccess.SwTxtLineAccess::IsAvailable();
1768 [ + + ][ - + ]: 15169 : const sal_Bool bSetOfst = ( GetOfst() && GetOfst() > GetTxtNode()->GetTxt().Len() );
1769 : :
1770 [ + - ][ + + ]: 15169 : if( CalcPreps() )
1771 : : ; // nothing
1772 : : // We return if already formatted, but if the TxtFrm was just created
1773 : : // and does not have any format information
1774 [ + + ][ + - ]: 14551 : else if( !bNew && !aAccess.GetPara()->GetReformat()->Len() )
[ + + ][ + + ]
1775 : : {
1776 [ + - ][ + - ]: 436 : if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() )
[ - + ]
1777 : : {
1778 [ # # ]: 0 : aAccess.GetPara()->SetPrepAdjust( sal_True );
1779 [ # # ]: 0 : aAccess.GetPara()->SetPrep( sal_True );
1780 [ # # ]: 0 : CalcPreps();
1781 : : }
1782 : 436 : SetWidow( sal_False );
1783 : : }
1784 [ - + ][ # # ]: 14115 : else if( bSetOfst && IsFollow() )
[ - + ]
1785 : : {
1786 [ # # ]: 0 : SwTxtFrm *pMaster = FindMaster();
1787 : : OSL_ENSURE( pMaster, "SwTxtFrm::Format: homeless follow" );
1788 [ # # ]: 0 : if( pMaster )
1789 [ # # ]: 0 : pMaster->Prepare( PREP_FOLLOW_FOLLOWS );
1790 [ # # ][ # # ]: 0 : SwTwips nMaxY = (GetUpper()->*fnRect->fnGetPrtBottom)();
1791 [ # # ][ # # ]: 0 : if( (Frm().*fnRect->fnOverStep)( nMaxY ) )
[ # # ]
1792 [ # # ][ # # ]: 0 : (this->*fnRect->fnSetLimit)( nMaxY );
1793 [ # # ][ # # ]: 0 : else if( (Frm().*fnRect->fnBottomDist)( nMaxY ) < 0 )
[ # # ]
1794 [ # # ][ # # ]: 0 : (Frm().*fnRect->fnAddBottom)( -(Frm().*fnRect->fnGetHeight)() );
[ # # ][ # # ]
1795 : : }
1796 : : else
1797 : : {
1798 : : // bSetOfst here means that we have the "red arrow situation"
1799 [ - + ]: 14115 : if ( bSetOfst )
1800 [ # # ]: 0 : _SetOfst( 0 );
1801 : :
1802 : 14115 : const sal_Bool bOrphan = IsWidow();
1803 [ + - ][ + + ]: 14115 : const SwFtnBossFrm* pFtnBoss = HasFtn() ? FindFtnBossFrm() : 0;
1804 : 14115 : SwTwips nFtnHeight = 0;
1805 [ + + ]: 14115 : if( pFtnBoss )
1806 : : {
1807 [ + - ]: 75 : const SwFtnContFrm* pCont = pFtnBoss->FindFtnCont();
1808 [ + + ][ + - ]: 75 : nFtnHeight = pCont ? (pCont->Frm().*fnRect->fnGetHeight)() : 0;
[ + - ]
1809 : : }
1810 [ # # ]: 0 : do
1811 : : {
1812 [ + - ][ + - ]: 14115 : _Format( aAccess.GetPara() );
1813 [ + + ][ + + ]: 14115 : if( pFtnBoss && nFtnHeight )
1814 : : {
1815 [ + - ]: 48 : const SwFtnContFrm* pCont = pFtnBoss->FindFtnCont();
1816 [ + - ][ + - ]: 48 : SwTwips nNewHeight = pCont ? (pCont->Frm().*fnRect->fnGetHeight)() : 0;
[ + - ]
1817 : : // If we lost some footnotes, we may have more space
1818 : : // for our main text, so we have to format again ...
1819 [ - + ]: 48 : if( nNewHeight < nFtnHeight )
1820 : 0 : nFtnHeight = nNewHeight;
1821 : : else
1822 : 48 : break;
1823 : : }
1824 : : else
1825 : 14067 : break;
1826 : : } while ( pFtnBoss );
1827 [ - + ]: 14115 : if( bOrphan )
1828 : : {
1829 [ # # ]: 0 : ValidateFrm();
1830 : 0 : SetWidow( sal_False );
1831 : : }
1832 : : }
1833 [ + - ][ - + ]: 15169 : if( IsEmptyMaster() )
1834 : : {
1835 : 0 : SwFrm* pPre = GetPrev();
1836 [ # # # # ]: 0 : if( pPre &&
[ # # ][ # # ]
1837 : : // #i10826# It's the first, it cannot keep!
1838 [ # # ]: 0 : pPre->GetIndPrev() &&
1839 [ # # ][ # # ]: 0 : pPre->GetAttrSet()->GetKeep().GetValue() )
1840 : : {
1841 [ # # ]: 0 : pPre->InvalidatePos();
1842 : : }
1843 [ + - ][ + + ]: 15607 : }
1844 : : }
1845 : :
1846 : 19846 : ChgThisLines();
1847 : :
1848 : : // the PrepMustFit should not survive a Format operation
1849 : 19846 : SwParaPortion *pPara = GetPara();
1850 [ + + ]: 19846 : if ( pPara )
1851 : 15169 : pPara->SetPrepMustFit( sal_False );
1852 : :
1853 : 19846 : CalcBaseOfstForFly();
1854 : 20402 : _CalcHeightOfLastLine(); // #i11860#
1855 : : }
1856 : :
1857 : : /*************************************************************************
1858 : : * SwTxtFrm::FormatQuick()
1859 : : *
1860 : : * bForceQuickFormat is set if GetFormatted() has been called during the
1861 : : * painting process. Actually I cannot imagine a situation which requires
1862 : : * a full formatting of the paragraph during painting, on the other hand
1863 : : * a full formatting can cause the invalidation of other layout frames,
1864 : : * e.g., if there are footnotes in this paragraph, and invalid layout
1865 : : * frames will not calculated during the painting. So I actually want to
1866 : : * avoid a formatting during painting, but since I'm a coward, I'll only
1867 : : * force the quick formatting in the situation of issue i29062.
1868 : : *************************************************************************/
1869 : :
1870 : 0 : sal_Bool SwTxtFrm::FormatQuick( bool bForceQuickFormat )
1871 : : {
1872 : : OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
1873 : : "SwTxtFrm::FormatQuick with swapped frame" );
1874 : :
1875 : : #if OSL_DEBUG_LEVEL > 1
1876 : : const XubString aXXX = GetTxtNode()->GetTxt();
1877 : : const SwTwips nDbgY = Frm().Top();
1878 : : (void)nDbgY;
1879 : : // nStopAt allows CV to alter it
1880 : : static MSHORT nStopAt = 0;
1881 : : if( nStopAt == GetFrmId() )
1882 : : {
1883 : : int i = GetFrmId();
1884 : : (void)i;
1885 : : }
1886 : : #endif
1887 : :
1888 [ # # ][ # # ]: 0 : if( IsEmpty() && FormatEmpty() )
[ # # ][ # # ]
1889 : 0 : return sal_True;
1890 : :
1891 : : // We're very picky:
1892 [ # # ][ # # ]: 0 : if( HasPara() || IsWidow() || IsLocked()
[ # # ]
[ # # # # ]
[ # # # # ]
[ # # ][ # # ]
1893 : 0 : || !GetValidSizeFlag() ||
1894 [ # # ][ # # ]: 0 : ( ( IsVertical() ? Prt().Width() : Prt().Height() ) && IsHiddenNow() ) )
[ # # ]
1895 : 0 : return sal_False;
1896 : :
1897 [ # # ]: 0 : SwTxtLineAccess aAccess( this );
1898 [ # # ]: 0 : SwParaPortion *pPara = aAccess.GetPara();
1899 [ # # ]: 0 : if( !pPara )
1900 : 0 : return sal_False;
1901 : :
1902 [ # # ]: 0 : SwFrmSwapper aSwapper( this, sal_True );
1903 : :
1904 : 0 : SwTxtFrmLocker aLock(this);
1905 [ # # ]: 0 : SwTxtFormatInfo aInf( this, sal_False, sal_True );
1906 [ # # ]: 0 : if( 0 != aInf.MaxHyph() ) // Respect MaxHyphen!
1907 : 0 : return sal_False;
1908 : :
1909 [ # # ]: 0 : SwTxtFormatter aLine( this, &aInf );
1910 : :
1911 : : // DropCaps are too complicated ...
1912 [ # # ]: 0 : if( aLine.GetDropFmt() )
1913 : 0 : return sal_False;
1914 : :
1915 : 0 : xub_StrLen nStart = GetOfst();
1916 : 0 : const xub_StrLen nEnd = GetFollow()
1917 [ # # ]: 0 : ? GetFollow()->GetOfst() : aInf.GetTxt().Len();
1918 [ # # ]: 0 : do
1919 : : {
1920 [ # # ]: 0 : nStart = aLine.FormatLine( nStart );
1921 [ # # ][ # # ]: 0 : if( aInf.IsNewLine() || (!aInf.IsStop() && nStart < nEnd) )
[ # # ][ # # ]
1922 [ # # ][ # # ]: 0 : aLine.Insert( new SwLineLayout() );
[ # # ]
1923 [ # # ]: 0 : } while( aLine.Next() );
1924 : :
1925 : : // Last exit: the heights need to match
1926 : 0 : Point aTopLeft( Frm().Pos() );
1927 : 0 : aTopLeft += Prt().Pos();
1928 : 0 : const SwTwips nNewHeight = aLine.Y() + aLine.GetLineHeight();
1929 : 0 : const SwTwips nOldHeight = aTopLeft.Y() + Prt().Height();
1930 : :
1931 [ # # ][ # # ]: 0 : if( !bForceQuickFormat && nNewHeight != nOldHeight && !IsUndersized() )
[ # # ][ # # ]
1932 : : {
1933 : : // Attention: This situation can occur due to FormatLevel==12. Don't panic!
1934 : 0 : const xub_StrLen nStrt = GetOfst();
1935 [ # # ]: 0 : _InvalidateRange( SwCharRange( nStrt, nEnd - nStrt) );
1936 : 0 : return sal_False;
1937 : : }
1938 : :
1939 [ # # ][ # # ]: 0 : if (m_pFollow && nStart != (static_cast<SwTxtFrm*>(m_pFollow))->GetOfst())
[ # # ][ # # ]
1940 : 0 : return sal_False; // can be caused by e.g. Orphans
1941 : :
1942 : : // We made it!
1943 : :
1944 : : // Set repaint
1945 : 0 : pPara->GetRepaint()->Pos( aTopLeft );
1946 : 0 : pPara->GetRepaint()->SSize( Prt().SSize() );
1947 : :
1948 : : // Delete reformat
1949 : 0 : *(pPara->GetReformat()) = SwCharRange();
1950 : 0 : *(pPara->GetDelta()) = 0;
1951 : :
1952 [ # # ][ # # ]: 0 : return sal_True;
[ # # ][ # # ]
1953 : : }
1954 : :
1955 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|