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 :
22 : #include "layfrm.hxx"
23 : #include "ftnboss.hxx"
24 : #include "ndtxt.hxx"
25 : #include "paratr.hxx"
26 : #include <editeng/orphitem.hxx>
27 : #include <editeng/widwitem.hxx>
28 : #include <editeng/keepitem.hxx>
29 : #include <editeng/spltitem.hxx>
30 : #include <frmatr.hxx>
31 : #include <txtftn.hxx>
32 : #include <fmtftn.hxx>
33 : #include <rowfrm.hxx>
34 :
35 : #include "widorp.hxx"
36 : #include "txtfrm.hxx"
37 : #include "itrtxt.hxx"
38 : #include "sectfrm.hxx"
39 : #include "ftnfrm.hxx"
40 :
41 : #undef WIDOWTWIPS
42 :
43 : namespace
44 : {
45 :
46 : // A Follow on the same page as its master is nasty.
47 0 : inline bool IsNastyFollow( const SwTxtFrm *pFrm )
48 : {
49 : OSL_ENSURE( !pFrm->IsFollow() || !pFrm->GetPrev() ||
50 : ((const SwTxtFrm*)pFrm->GetPrev())->GetFollow() == pFrm,
51 : "IsNastyFollow: Was ist denn hier los?" );
52 0 : return pFrm->IsFollow() && pFrm->GetPrev();
53 : }
54 :
55 : }
56 :
57 : /*************************************************************************
58 : * SwTxtFrmBreak::SwTxtFrmBreak()
59 : *************************************************************************/
60 :
61 0 : SwTxtFrmBreak::SwTxtFrmBreak( SwTxtFrm *pNewFrm, const SwTwips nRst )
62 0 : : nRstHeight(nRst), pFrm(pNewFrm)
63 : {
64 0 : SWAP_IF_SWAPPED( pFrm )
65 0 : SWRECTFN( pFrm )
66 0 : nOrigin = (pFrm->*fnRect->fnGetPrtTop)();
67 : SwSectionFrm* pSct;
68 0 : bKeep = !pFrm->IsMoveable() || IsNastyFollow( pFrm ) ||
69 0 : ( pFrm->IsInSct() && (pSct=pFrm->FindSctFrm())->Lower()->IsColumnFrm()
70 0 : && !pSct->MoveAllowed( pFrm ) ) ||
71 0 : !pFrm->GetTxtNode()->GetSwAttrSet().GetSplit().GetValue() ||
72 0 : pFrm->GetTxtNode()->GetSwAttrSet().GetKeep().GetValue();
73 0 : bBreak = false;
74 :
75 0 : if( !nRstHeight && !pFrm->IsFollow() && pFrm->IsInFtn() && pFrm->HasPara() )
76 : {
77 0 : nRstHeight = pFrm->GetFtnFrmHeight();
78 0 : nRstHeight += (pFrm->Prt().*fnRect->fnGetHeight)() -
79 0 : (pFrm->Frm().*fnRect->fnGetHeight)();
80 0 : if( nRstHeight < 0 )
81 0 : nRstHeight = 0;
82 : }
83 :
84 0 : UNDO_SWAP( pFrm )
85 0 : }
86 :
87 : /* BP 18.6.93: Widows.
88 : * In contrast to the first implementation the Widows are not calculated
89 : * in advance but detected when formatting the split Follow.
90 : * In Master the Widows-calculation is dropped completely
91 : * (nWidows is manipulated). If the Follow detects that the
92 : * Widows rule applies it sends a Prepare to its predecessor.
93 : * A special problem is when the Widow rule applies but in Master
94 : * there are some lines available.
95 : *
96 : */
97 :
98 : /*************************************************************************
99 : * SwTxtFrmBreak::IsInside()
100 : *************************************************************************/
101 :
102 : /* BP(22.07.92): Calculation of Widows and Orphans.
103 : * The method returns true if one of the rules matches.
104 : *
105 : * One difficulty with Widows and different formats between
106 : * Master- and Follow-Frame:
107 : * Example: If the first column is 3cm and the second is 4cm and
108 : * Widows is set to 3, the decision if the Widows rule matches can not
109 : * be done until the Follow is formated. Unfortunately this is crucial
110 : * to decide if the whole paragraph goes to the next page or not.
111 : */
112 :
113 0 : bool SwTxtFrmBreak::IsInside( SwTxtMargin &rLine ) const
114 : {
115 0 : bool bFit = false;
116 :
117 0 : SWAP_IF_SWAPPED( pFrm )
118 0 : SWRECTFN( pFrm )
119 : // nOrigin is an absolut value, rLine referes to the swapped situation.
120 :
121 : SwTwips nTmpY;
122 0 : if ( pFrm->IsVertical() )
123 0 : nTmpY = pFrm->SwitchHorizontalToVertical( rLine.Y() + rLine.GetLineHeight() );
124 : else
125 0 : nTmpY = rLine.Y() + rLine.GetLineHeight();
126 :
127 0 : SwTwips nLineHeight = (*fnRect->fnYDiff)( nTmpY , nOrigin );
128 :
129 : // 7455 und 6114: Calculate extra space for bottom border.
130 0 : nLineHeight += (pFrm->*fnRect->fnGetBottomMargin)();
131 :
132 0 : if( nRstHeight )
133 0 : bFit = nRstHeight >= nLineHeight;
134 : else
135 : {
136 : // The Frm has a height to fit on the page.
137 : SwTwips nHeight =
138 0 : (*fnRect->fnYDiff)( (pFrm->GetUpper()->*fnRect->fnGetPrtBottom)(), nOrigin );
139 : // If everything is inside the existing frame the result is true;
140 0 : bFit = nHeight >= nLineHeight;
141 :
142 : // --> OD #i103292#
143 0 : if ( !bFit )
144 : {
145 0 : if ( rLine.GetNext() &&
146 0 : pFrm->IsInTab() && !pFrm->GetFollow() && !pFrm->GetIndNext() )
147 : {
148 : // add additional space taken as lower space as last content in a table
149 : // for all text lines except the last one.
150 0 : nHeight += pFrm->CalcAddLowerSpaceAsLastInTableCell();
151 0 : bFit = nHeight >= nLineHeight;
152 : }
153 : }
154 : // <--
155 0 : if( !bFit )
156 : {
157 : // The LineHeight exceeds the current Frm height.
158 : // Call a test Grow to detect if the Frame could
159 : // grow the requested area.
160 0 : nHeight += pFrm->GrowTst( LONG_MAX );
161 :
162 : // The Grow() returns the height by which the Upper of the TxtFrm
163 : // would let the TxtFrm grow.
164 : // The TxtFrm itself can grow as much as it wants.
165 0 : bFit = nHeight >= nLineHeight;
166 : }
167 : }
168 :
169 0 : UNDO_SWAP( pFrm );
170 :
171 0 : return bFit;
172 : }
173 :
174 : /*************************************************************************
175 : * SwTxtFrmBreak::IsBreakNow()
176 : *************************************************************************/
177 :
178 0 : bool SwTxtFrmBreak::IsBreakNow( SwTxtMargin &rLine )
179 : {
180 0 : SWAP_IF_SWAPPED( pFrm )
181 :
182 : // bKeep is stronger than IsBreakNow()
183 : // Is there enough space ?
184 0 : if( bKeep || IsInside( rLine ) )
185 0 : bBreak = false;
186 : else
187 : {
188 : /* This class assumes that the SwTxtMargin is processed from Top to
189 : * Bottom. Because of performance reasons we stop splitting in the
190 : * following cases:
191 : * If only one line does not fit.
192 : * Special case: with DummyPortions there is LineNr == 1, though we
193 : * want to split.
194 : */
195 : // 6010: include DropLines
196 :
197 0 : bool bFirstLine = 1 == rLine.GetLineNr() && !rLine.GetPrev();
198 0 : bBreak = true;
199 0 : if( ( bFirstLine && pFrm->GetIndPrev() )
200 0 : || ( rLine.GetLineNr() <= rLine.GetDropLines() ) )
201 : {
202 0 : bKeep = true;
203 0 : bBreak = false;
204 : }
205 0 : else if(bFirstLine && pFrm->IsInFtn() && !pFrm->FindFtnFrm()->GetPrev())
206 : {
207 0 : SwLayoutFrm* pTmp = pFrm->FindFtnBossFrm()->FindBodyCont();
208 0 : if( !pTmp || !pTmp->Lower() )
209 0 : bBreak = false;
210 : }
211 : }
212 :
213 0 : UNDO_SWAP( pFrm )
214 :
215 0 : return bBreak;
216 : }
217 :
218 : // OD 2004-02-27 #106629# - no longer inline
219 0 : void SwTxtFrmBreak::SetRstHeight( const SwTxtMargin &rLine )
220 : {
221 : // OD, FME 2004-02-27 #106629# - consider bottom margin
222 0 : SWRECTFN( pFrm )
223 :
224 0 : nRstHeight = (pFrm->*fnRect->fnGetBottomMargin)();
225 :
226 0 : if ( bVert )
227 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
228 : {
229 0 : if ( pFrm->IsVertLR() )
230 0 : nRstHeight = (*fnRect->fnYDiff)( pFrm->SwitchHorizontalToVertical( rLine.Y() ) , nOrigin );
231 : else
232 0 : nRstHeight += nOrigin - pFrm->SwitchHorizontalToVertical( rLine.Y() );
233 : }
234 : else
235 0 : nRstHeight += rLine.Y() - nOrigin;
236 0 : }
237 :
238 : /*************************************************************************
239 : * WidowsAndOrphans::WidowsAndOrphans()
240 : *************************************************************************/
241 :
242 0 : WidowsAndOrphans::WidowsAndOrphans( SwTxtFrm *pNewFrm, const SwTwips nRst,
243 : bool bChkKeep )
244 0 : : SwTxtFrmBreak( pNewFrm, nRst ), nWidLines( 0 ), nOrphLines( 0 )
245 : {
246 0 : SWAP_IF_SWAPPED( pFrm )
247 :
248 0 : if( bKeep )
249 : {
250 : // 5652: If pararagraph should not be split but is larger than
251 : // the page, then bKeep is overruled.
252 0 : if( bChkKeep && !pFrm->GetPrev() && !pFrm->IsInFtn() &&
253 0 : pFrm->IsMoveable() &&
254 0 : ( !pFrm->IsInSct() || pFrm->FindSctFrm()->MoveAllowed(pFrm) ) )
255 0 : bKeep = false;
256 : // Even if Keep is set, Orphans has to be respected.
257 : // e.g. if there are chained frames where a Follow in the last frame
258 : // receives a Keep, because it is not (forward) movable -
259 : // nevertheless the paragraph can request lines from the Master
260 : // because of the Orphan rule.
261 0 : if( pFrm->IsFollow() )
262 0 : nWidLines = pFrm->GetTxtNode()->GetSwAttrSet().GetWidows().GetValue();
263 : }
264 : else
265 : {
266 0 : const SwAttrSet& rSet = pFrm->GetTxtNode()->GetSwAttrSet();
267 0 : const SvxOrphansItem &rOrph = rSet.GetOrphans();
268 0 : if ( rOrph.GetValue() > 1 )
269 0 : nOrphLines = rOrph.GetValue();
270 0 : if ( pFrm->IsFollow() )
271 0 : nWidLines = rSet.GetWidows().GetValue();
272 :
273 : }
274 :
275 0 : if ( bKeep || nWidLines || nOrphLines )
276 : {
277 0 : bool bResetFlags = false;
278 :
279 0 : if ( pFrm->IsInTab() )
280 : {
281 : // For compatibility reasons, we disable Keep/Widows/Orphans
282 : // inside splittable row frames:
283 0 : if ( pFrm->GetNextCellLeaf( MAKEPAGE_NONE ) || pFrm->IsInFollowFlowRow() )
284 : {
285 0 : const SwFrm* pTmpFrm = pFrm->GetUpper();
286 0 : while ( !pTmpFrm->IsRowFrm() )
287 0 : pTmpFrm = pTmpFrm->GetUpper();
288 0 : if ( static_cast<const SwRowFrm*>(pTmpFrm)->IsRowSplitAllowed() )
289 0 : bResetFlags = true;
290 : }
291 : }
292 :
293 0 : if( pFrm->IsInFtn() && !pFrm->GetIndPrev() )
294 : {
295 : // Inside of footnotes there are good reasons to turn off the Keep attribute
296 : // as well as Widows/Orphans.
297 0 : SwFtnFrm *pFtn = pFrm->FindFtnFrm();
298 0 : const bool bFt = !pFtn->GetAttr()->GetFtn().IsEndNote();
299 0 : if( !pFtn->GetPrev() &&
300 0 : pFtn->FindFtnBossFrm( bFt ) != pFtn->GetRef()->FindFtnBossFrm( bFt )
301 0 : && ( !pFrm->IsInSct() || pFrm->FindSctFrm()->MoveAllowed(pFrm) ) )
302 : {
303 0 : bResetFlags = true;
304 : }
305 : }
306 :
307 0 : if ( bResetFlags )
308 : {
309 0 : bKeep = false;
310 0 : nOrphLines = 0;
311 0 : nWidLines = 0;
312 : }
313 : }
314 :
315 0 : UNDO_SWAP( pFrm )
316 0 : }
317 :
318 : /*************************************************************************
319 : * WidowsAndOrphans::FindBreak()
320 : *************************************************************************/
321 :
322 : /* The Find*-Methodes do not only search, but adjust the SwTxtMargin to the
323 : * line where the paragraph should have a break and truncate the paragraph there.
324 : * FindBreak()
325 : */
326 :
327 0 : bool WidowsAndOrphans::FindBreak( SwTxtFrm *pFrame, SwTxtMargin &rLine,
328 : bool bHasToFit )
329 : {
330 : // OD 2004-02-25 #i16128# - Why member <pFrm> _*and*_ parameter <pFrame>??
331 : // Thus, assertion on situation, that these are different to figure out why.
332 : OSL_ENSURE( pFrm == pFrame, "<WidowsAndOrphans::FindBreak> - pFrm != pFrame" );
333 :
334 0 : SWAP_IF_SWAPPED( pFrm )
335 :
336 0 : bool bRet = true;
337 0 : MSHORT nOldOrphans = nOrphLines;
338 0 : if( bHasToFit )
339 0 : nOrphLines = 0;
340 0 : rLine.Bottom();
341 : // OD 2004-02-25 #i16128# - method renamed
342 0 : if( !IsBreakNowWidAndOrp( rLine ) )
343 0 : bRet = false;
344 0 : if( !FindWidows( pFrame, rLine ) )
345 : {
346 0 : bool bBack = false;
347 : // OD 2004-02-25 #i16128# - method renamed
348 0 : while( IsBreakNowWidAndOrp( rLine ) )
349 : {
350 0 : if( rLine.PrevLine() )
351 0 : bBack = true;
352 : else
353 0 : break;
354 : }
355 : // Usually Orphans are not taken into account for HasToFit.
356 : // But if Dummy-Lines are concerned and the Orphans rule is violated
357 : // we make an exception: We leave behind one Dummyline and take
358 : // the whole text to the next page/column.
359 0 : if( rLine.GetLineNr() <= nOldOrphans &&
360 0 : rLine.GetInfo().GetParaPortion()->IsDummy() &&
361 0 : ( ( bHasToFit && bRet ) || IsBreakNow( rLine ) ) )
362 0 : rLine.Top();
363 :
364 0 : rLine.TruncLines( true );
365 0 : bRet = bBack;
366 : }
367 0 : nOrphLines = nOldOrphans;
368 :
369 0 : UNDO_SWAP( pFrm )
370 :
371 0 : return bRet;
372 : }
373 :
374 : /*************************************************************************
375 : * WidowsAndOrphans::FindWidows()
376 : *************************************************************************/
377 :
378 : /* FindWidows positions the SwTxtMargin of the Master to the line where to
379 : * break by examining and formatting the Follow.
380 : * Returns true if the Widows-rule matches, that means that the
381 : * paragraph should not be split (keep) !
382 : */
383 :
384 0 : bool WidowsAndOrphans::FindWidows( SwTxtFrm *pFrame, SwTxtMargin &rLine )
385 : {
386 : OSL_ENSURE( ! pFrame->IsVertical() || ! pFrame->IsSwapped(),
387 : "WidowsAndOrphans::FindWidows with swapped frame" );
388 :
389 0 : if( !nWidLines || !pFrame->IsFollow() )
390 0 : return false;
391 :
392 0 : rLine.Bottom();
393 :
394 : // Wir koennen noch was abzwacken
395 0 : SwTxtFrm *pMaster = pFrame->FindMaster();
396 : OSL_ENSURE(pMaster, "+WidowsAndOrphans::FindWidows: Widows in a master?");
397 0 : if( !pMaster )
398 0 : return false;
399 :
400 : // 5156: If the first line of the Follow does not fit, the master
401 : // probably is full of Dummies. In this case a PREP_WIDOWS would be fatal.
402 0 : if( pMaster->GetOfst() == pFrame->GetOfst() )
403 0 : return false;
404 :
405 : // Remaining height of the master
406 0 : SWRECTFN( pFrame )
407 :
408 0 : const SwTwips nDocPrtTop = (pFrame->*fnRect->fnGetPrtTop)();
409 : SwTwips nOldHeight;
410 0 : SwTwips nTmpY = rLine.Y() + rLine.GetLineHeight();
411 :
412 0 : if ( bVert )
413 : {
414 0 : nTmpY = pFrame->SwitchHorizontalToVertical( nTmpY );
415 0 : nOldHeight = -(pFrame->Prt().*fnRect->fnGetHeight)();
416 : }
417 : else
418 0 : nOldHeight = (pFrame->Prt().*fnRect->fnGetHeight)();
419 :
420 0 : const SwTwips nChg = (*fnRect->fnYDiff)( nTmpY, nDocPrtTop + nOldHeight );
421 :
422 : // below the Widows-treshold...
423 0 : if( rLine.GetLineNr() >= nWidLines )
424 : {
425 : // 8575: Follow to Master I
426 : // If the Follow *grows*, there is the chance for the Master to
427 : // receive lines, that it was forced to hand over to the Follow lately:
428 : // Prepare(Need); check that below nChg!
429 : // (0W, 2O, 2M, 2F) + 1F = 3M, 2F
430 0 : if( rLine.GetLineNr() > nWidLines && pFrame->IsJustWidow() )
431 : {
432 : // If the Master is locked, it has probably just donated a line
433 : // to us, we don't return that just because we turned it into
434 : // multiple lines (e.g. via frames).
435 0 : if( !pMaster->IsLocked() && pMaster->GetUpper() )
436 : {
437 0 : const SwTwips nTmpRstHeight = (pMaster->Frm().*fnRect->fnBottomDist)
438 0 : ( (pMaster->GetUpper()->*fnRect->fnGetPrtBottom)() );
439 0 : if ( nTmpRstHeight >=
440 0 : SwTwips(rLine.GetInfo().GetParaPortion()->Height() ) )
441 : {
442 0 : pMaster->Prepare( PREP_ADJUST_FRM );
443 0 : pMaster->_InvalidateSize();
444 0 : pMaster->InvalidatePage();
445 : }
446 : }
447 :
448 0 : pFrame->SetJustWidow( false );
449 : }
450 0 : return false;
451 : }
452 :
453 : // 8575: Follow to Master II
454 : // If the Follow *shrinks*, maybe the Master can absorb the whole Orphan.
455 : // (0W, 2O, 2M, 1F) - 1F = 3M, 0F -> PREP_ADJUST_FRM
456 : // (0W, 2O, 3M, 2F) - 1F = 2M, 2F -> PREP_WIDOWS
457 :
458 0 : if( 0 > nChg && !pMaster->IsLocked() && pMaster->GetUpper() )
459 : {
460 0 : SwTwips nTmpRstHeight = (pMaster->Frm().*fnRect->fnBottomDist)
461 0 : ( (pMaster->GetUpper()->*fnRect->fnGetPrtBottom)() );
462 0 : if( nTmpRstHeight >= SwTwips(rLine.GetInfo().GetParaPortion()->Height() ) )
463 : {
464 0 : pMaster->Prepare( PREP_ADJUST_FRM );
465 0 : pMaster->_InvalidateSize();
466 0 : pMaster->InvalidatePage();
467 0 : pFrame->SetJustWidow( false );
468 0 : return false;
469 : }
470 : }
471 :
472 : // Master to Follow
473 : // Wenn der Follow nach seiner Formatierung weniger Zeilen enthaelt
474 : // als Widows, so besteht noch die Chance, einige Zeilen des Masters
475 : // abzuzwacken. Wenn dadurch die Orphans-Regel des Masters in Kraft
476 : // tritt muss im CalcPrep() des Master-Frame der Frame so vergroessert
477 : // werden, dass er nicht mehr auf seine urspruengliche Seite passt.
478 : // Wenn er noch ein paar Zeilen entbehren kann, dann muss im CalcPrep()
479 : // ein Shrink() erfolgen, der Follow mit dem Widows rutscht dann auf
480 : // die Seite des Masters, haelt sich aber zusammen, so dass er (endlich)
481 : // auf die naechste Seite rutscht. - So die Theorie!
482 :
483 : // Wir fordern nur noch ein Zeile zur Zeit an, weil eine Zeile des Masters
484 : // bei uns durchaus mehrere Zeilen ergeben koennten.
485 : // Dafuer behaelt CalcFollow solange die Kontrolle, bis der Follow alle
486 : // notwendigen Zeilen bekommen hat.
487 0 : MSHORT nNeed = 1; // frueher: nWidLines - rLine.GetLineNr();
488 :
489 : // Special case: Master cannot give lines to follow
490 : // #i91421#
491 0 : if ( !pMaster->GetIndPrev() )
492 : {
493 0 : sal_uLong nLines = pMaster->GetThisLines();
494 0 : if(nLines == 0 && pMaster->HasPara())
495 : {
496 0 : const SwParaPortion *pMasterPara = pMaster->GetPara();
497 0 : if(pMasterPara && pMasterPara->GetNext())
498 0 : nLines = 2;
499 : }
500 0 : if( nLines <= nNeed )
501 0 : return false;
502 : }
503 :
504 0 : pMaster->Prepare( PREP_WIDOWS, (void*)&nNeed );
505 0 : return true;
506 : }
507 :
508 : /*************************************************************************
509 : * WidowsAndOrphans::WouldFit()
510 : *************************************************************************/
511 :
512 0 : bool WidowsAndOrphans::WouldFit( SwTxtMargin &rLine, SwTwips &rMaxHeight, bool bTst )
513 : {
514 : // Here it does not matter, if pFrm is swapped or not.
515 : // IsInside() takes care for itself
516 :
517 : // We expect that rLine is set to the last line
518 : OSL_ENSURE( !rLine.GetNext(), "WouldFit: aLine::Bottom missed!" );
519 0 : MSHORT nLineCnt = rLine.GetLineNr();
520 :
521 : // First satisfy the Orphans-rule and the wish for initials ...
522 0 : const MSHORT nMinLines = std::max( GetOrphansLines(), rLine.GetDropLines() );
523 0 : if ( nLineCnt < nMinLines )
524 0 : return false;
525 :
526 0 : rLine.Top();
527 0 : SwTwips nLineSum = rLine.GetLineHeight();
528 :
529 0 : while( nMinLines > rLine.GetLineNr() )
530 : {
531 0 : if( !rLine.NextLine() )
532 0 : return false;
533 0 : nLineSum += rLine.GetLineHeight();
534 : }
535 :
536 : // We do not fit
537 0 : if( !IsInside( rLine ) )
538 0 : return false;
539 :
540 : // Check the Widows-rule
541 0 : if( !nWidLines && !pFrm->IsFollow() )
542 : {
543 : // Usually we only have to check for Widows if we are a Follow.
544 : // On WouldFit the rule has to be checked for the Master too,
545 : // because we are just in the middle of calculating the break.
546 : // In Ctor of WidowsAndOrphans the nWidLines are only calced for
547 : // Follows from the AttrSet - so we catch up now:
548 0 : const SwAttrSet& rSet = pFrm->GetTxtNode()->GetSwAttrSet();
549 0 : nWidLines = rSet.GetWidows().GetValue();
550 : }
551 :
552 : // After Orphans/Initials, do enough lines remain for Widows?
553 : // #111937#: If we are currently doing a test formatting, we may not
554 : // consider the widows rule for two reasons:
555 : // 1. The columns may have different widths.
556 : // Widow lines would have wrong width.
557 : // 2. Test formatting is only done up to the given space.
558 : // we do not have any lines for widows at all.
559 0 : if( bTst || nLineCnt - nMinLines >= GetWidowsLines() )
560 : {
561 0 : if( rMaxHeight >= nLineSum )
562 : {
563 0 : rMaxHeight -= nLineSum;
564 0 : return true;
565 : }
566 : }
567 0 : return false;
568 : }
569 :
570 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|