@@ -382,81 +382,86 @@ public boolean doLayout(int flowBPD, boolean autoHeight) {
382382 while (hasMoreContent ()) {
383383 blockLists .clear ();
384384
385- //*** Phase 1: Get Knuth elements ***
386- nextSequenceStartsOn = getNextBlockList (childLC , nextSequenceStartsOn );
387- empty = empty && blockLists .size () == 0 ;
388-
389- //*** Phases 2 and 3 ***
390- log .debug ("PLM> blockLists.size() = " + blockLists .size ());
391- for (blockListIndex = 0 ; blockListIndex < blockLists .size (); blockListIndex ++) {
392- blockList = blockLists .get (blockListIndex );
393-
394- //debug code start
395- if (log .isDebugEnabled ()) {
396- log .debug (" blockListIndex = " + blockListIndex );
397- log .debug (" sequence starts on " + getBreakClassName (blockList .startOn ));
398- }
399- observeElementList (blockList );
400- //debug code end
401-
402- //*** Phase 2: Alignment and breaking ***
403- log .debug ("PLM> start of algorithm (" + this .getClass ().getName ()
404- + "), flow BPD =" + flowBPD );
405- PageBreakingAlgorithm alg = new PageBreakingAlgorithm (getTopLevelLM (),
406- getPageProvider (), createLayoutListener (),
407- alignment , alignmentLast , footnoteSeparatorLength ,
408- isPartOverflowRecoveryActivated (), autoHeight , isSinglePartFavored ());
409-
410- alg .setConstantLineWidth (flowBPD );
411- int optimalPageCount = alg .findBreakingPoints (blockList , 1 , true ,
412- BreakingAlgorithm .ALL_BREAKS );
413- boolean ipdChangesOnNextPage = (alg .getIPDdifference () != 0 );
414- boolean onLastPageAndIPDChanges = false ;
415- if (!ipdChangesOnNextPage ) {
416- onLastPageAndIPDChanges = (lastPageHasIPDChange (optimalPageCount ) && !thereIsANonRestartableLM (alg )
417- && (shouldRedoLayout () || (wasLayoutRedone () && optimalPageCount > 1 )));
418- }
419- if (shouldRedoLayoutWithoutPagePositionOnly (ipdChangesOnNextPage , optimalPageCount )) {
420- return false ;
421- }
422- if (alg .handlingFloat ()) {
423- nextSequenceStartsOn = handleFloatLayout (alg , optimalPageCount , blockList , childLC );
424- } else if (ipdChangesOnNextPage || onLastPageAndIPDChanges ) {
425- boolean visitedBefore = false ;
426- if (onLastPageAndIPDChanges ) {
427- visitedBefore = wasLayoutRedone ();
428- prepareToRedoLayout (alg , optimalPageCount , blockList , blockList );
385+ try {
386+ //*** Phase 1: Get Knuth elements ***
387+ nextSequenceStartsOn = getNextBlockList (childLC , nextSequenceStartsOn );
388+ empty = empty && blockLists .size () == 0 ;
389+
390+ //*** Phases 2 and 3 ***
391+ log .debug ("PLM> blockLists.size() = " + blockLists .size ());
392+ for (blockListIndex = 0 ; blockListIndex < blockLists .size (); blockListIndex ++) {
393+ blockList = blockLists .get (blockListIndex );
394+
395+ //debug code start
396+ if (log .isDebugEnabled ()) {
397+ log .debug (" blockListIndex = " + blockListIndex );
398+ log .debug (" sequence starts on " + getBreakClassName (blockList .startOn ));
429399 }
430-
431- firstElementsForRestart = null ;
432- RestartAtLM restartAtLMClass = new RestartAtLM ();
433- LayoutManager restartAtLM = restartAtLMClass .getRestartAtLM (this , alg , ipdChangesOnNextPage ,
434- onLastPageAndIPDChanges , visitedBefore , blockList , 1 );
435- if (restartAtLMClass .invalidPosition ) {
400+ observeElementList (blockList );
401+ //debug code end
402+
403+ //*** Phase 2: Alignment and breaking ***
404+ log .debug ("PLM> start of algorithm (" + this .getClass ().getName ()
405+ + "), flow BPD =" + flowBPD );
406+ PageBreakingAlgorithm alg = new PageBreakingAlgorithm (getTopLevelLM (),
407+ getPageProvider (), createLayoutListener (),
408+ alignment , alignmentLast , footnoteSeparatorLength ,
409+ isPartOverflowRecoveryActivated (), autoHeight , isSinglePartFavored ());
410+
411+ alg .setConstantLineWidth (flowBPD );
412+ int optimalPageCount = alg .findBreakingPoints (blockList , 1 , true ,
413+ BreakingAlgorithm .ALL_BREAKS );
414+ boolean ipdChangesOnNextPage = (alg .getIPDdifference () != 0 );
415+ boolean onLastPageAndIPDChanges = false ;
416+ if (!ipdChangesOnNextPage ) {
417+ onLastPageAndIPDChanges = (lastPageHasIPDChange (optimalPageCount )
418+ && !thereIsANonRestartableLM (alg )
419+ && (shouldRedoLayout () || (wasLayoutRedone () && optimalPageCount > 1 )));
420+ }
421+ if (shouldRedoLayoutWithoutPagePositionOnly (ipdChangesOnNextPage , optimalPageCount , alg )) {
436422 return false ;
437423 }
438- if (restartAtLM == null || restartAtLM .getChildLMs ().isEmpty ()) {
424+ if (alg .handlingFloat ()) {
425+ nextSequenceStartsOn = handleFloatLayout (alg , optimalPageCount , blockList , childLC );
426+ } else if (ipdChangesOnNextPage || onLastPageAndIPDChanges ) {
427+ boolean visitedBefore = false ;
428+ if (onLastPageAndIPDChanges ) {
429+ visitedBefore = wasLayoutRedone ();
430+ prepareToRedoLayout (alg , optimalPageCount , blockList , blockList );
431+ }
432+
439433 firstElementsForRestart = null ;
440- LayoutManager restartAtLM2 = new RestartAtLM ().getRestartAtLM (this , alg , ipdChangesOnNextPage ,
441- onLastPageAndIPDChanges , visitedBefore , blockList , 0 );
442- if (restartAtLM2 != null ) {
443- restartAtLM = restartAtLM2 ;
434+ RestartAtLM restartAtLMClass = new RestartAtLM ();
435+ LayoutManager restartAtLM = restartAtLMClass .getRestartAtLM (this , alg , ipdChangesOnNextPage ,
436+ onLastPageAndIPDChanges , visitedBefore , blockList , 1 );
437+ if (restartAtLMClass .invalidPosition ) {
438+ return false ;
444439 }
445- }
446- if (ipdChangesOnNextPage ) {
447- addAreas (alg , optimalPageCount , blockList , blockList );
448- }
449- blockLists .clear ();
450- blockListIndex = -1 ;
451- nextSequenceStartsOn = getNextBlockList (childLC , Constants .EN_COLUMN , positionAtBreak ,
452- restartAtLM , firstElementsForRestart );
453- } else {
454- log .debug ("PLM> optimalPageCount= " + optimalPageCount
455- + " pageBreaks.size()= " + alg .getPageBreaks ().size ());
440+ if (restartAtLM == null || restartAtLM .getChildLMs ().isEmpty ()) {
441+ firstElementsForRestart = null ;
442+ LayoutManager restartAtLM2 = new RestartAtLM ().getRestartAtLM (this , alg ,
443+ ipdChangesOnNextPage , onLastPageAndIPDChanges , visitedBefore , blockList , 0 );
444+ if (restartAtLM2 != null ) {
445+ restartAtLM = restartAtLM2 ;
446+ }
447+ }
448+ if (ipdChangesOnNextPage ) {
449+ addAreas (alg , optimalPageCount , blockList , blockList );
450+ }
451+ blockLists .clear ();
452+ blockListIndex = -1 ;
453+ nextSequenceStartsOn = getNextBlockList (childLC , Constants .EN_COLUMN , positionAtBreak ,
454+ restartAtLM , firstElementsForRestart );
455+ } else {
456+ log .debug ("PLM> optimalPageCount= " + optimalPageCount
457+ + " pageBreaks.size()= " + alg .getPageBreaks ().size ());
456458
457- //*** Phase 3: Add areas ***
458- doPhase3 (alg , optimalPageCount , blockList , blockList );
459+ //*** Phase 3: Add areas ***
460+ doPhase3 (alg , optimalPageCount , blockList , blockList );
461+ }
459462 }
463+ } catch (PagePositionOnlyException e ) {
464+ return false ;
460465 }
461466 }
462467
@@ -465,11 +470,26 @@ public boolean doLayout(int flowBPD, boolean autoHeight) {
465470 return true ;
466471 }
467472
468- private boolean shouldRedoLayoutWithoutPagePositionOnly (boolean ipdChangesOnNextPage , int optimalPageCount ) {
473+ static class PagePositionOnlyException extends RuntimeException {
474+ }
475+
476+ private boolean shouldRedoLayoutWithoutPagePositionOnly (boolean ipdChangesOnNextPage , int optimalPageCount ,
477+ PageBreakingAlgorithm alg ) {
469478 if ((ipdChangesOnNextPage || hasMoreContent () || optimalPageCount > 1 )
470479 && pslm != null && pslm .getCurrentPage ().isPagePositionOnly ) {
480+ if (getPageProvider ().foUserAgent .isLegacySkipPagePositionOnly ()) {
481+ return true ;
482+ }
471483 RegionBody rb = (RegionBody )pslm .getCurrentPage ().getSimplePageMaster ().getRegion (Constants .FO_REGION_BODY );
472- return rb .getColumnCount () == 1 ;
484+ if (rb .getColumnCount () == 1 ) {
485+ return true ;
486+ }
487+ int restartPoint = getPageProvider ().getStartingPartIndexForLastPage (optimalPageCount );
488+ if (restartPoint > 0 ) {
489+ PageBreakPosition pbp = (PageBreakPosition ) alg .getPageBreaks ().get (restartPoint - 1 );
490+ int newStartPos = alg .par .getFirstBoxIndex (pbp .getLeafPos () + 1 );
491+ return newStartPos > 0 ;
492+ }
473493 }
474494 return false ;
475495 }
0 commit comments