示例#1
0
        private PageLayout ApplyPageBreak()
        {
            //	Collapse any space layouts at the top of the page. Space layouts are
            //	intended to provide space _between_ layouts and thus are not appropriate
            //	at the top of a page. We collapse top space after drafting so that we know
            //	where the space layouts fall on this page, but before applying the next
            //	page break because lower layouts might now fit on this page.
            CollapseTopSpace();

            PageDisposition disposition = AssessPageBreak(_bodyBox);

            //	Avoid infinite overflow. If any layout starts at the top of the page and
            //	is longer than the page, then it will return disposition overflow or split
            //	and its page split index will be zero. Splitting at index zero is the same
            //	thing as overflowing. Overflowing a full page will cause this page to move
            //	all of its content onto a new page, leaving itself empty, and this will lead
            //	to infinite overflow. So just stop the overflow right now. This will give us
            //	an oversized page, but that's better than making a report with an infinite
            //	number of empty pages. (In the current implementation, AssessPageBreak here on
            //	a page layout will never return overflow because SetPageSplitIndex always
            //	converts overflow to split, and then because a page can split it doesn't convert
            //	it back to overflow. But for semantic clarity we still check for overflow here.)
            if ((disposition == PageDisposition.Overflow)
                ||
                (disposition == PageDisposition.Split && _pageSplitIndex == 0))
            {
                //	If we can split as requested then do so. Otherwise bump the page split
                //	index from zero to one - this will leave the oversized layout on this
                //	page but overflow subsequent layouts to the next. If it's not possible
                //	to bump the index then return an empty page to stop the overflow.
                Bump bump = BumpPageSplitIndex();
                switch (bump)
                {
                case Bump.Bumped:
                case Bump.Unnecessary:
                    //	The split index has been moved beyond zero (or was already there)
                    //	and so we can now do the normal page break. This may still leave
                    //	the oversized layout on this page, but later layouts are moved
                    //	to the next page.
                    break;

                case Bump.Impossible:
                    //	Couldn't fix the situation by splitting further down, so
                    //	just accept the oversized layout
                    return((PageLayout)ShallowCopy());
                }
            }

            PageLayout overflow = (PageLayout)DoPageBreak();

            //	This page now contains only the content that can fit in it. Content
            //	that must be moved to the next page, or a later page, is now contained
            //	in the overflow page. If the overflow page is empty then this is the last
            //	page.

            //	Redraft this page to set the layouts' bottoms so that they can
            //	draw borders correctly, and redraft the new page so that its contents
            //	start at the top of the page.
            Redraft(_bodyBox.Top);
            overflow?.Redraft(overflow._bodyBox.Top);
            return(overflow);
        }