//
        // overflow methods
        //

        #region protected virtual bool StartListInAnotherRegion(PDFUnit itemHeight, PDFLayoutBlock item, int itemindex)

        /// <summary>
        /// Closes down the current list and attempts to open a new region to start laying out any further items.
        /// Returns true if a new region was created, otherwise false.
        /// </summary>
        /// <param name="itemHeight"></param>
        /// <param name="item"></param>
        /// <param name="itemindex"></param>
        /// <returns></returns>
        protected virtual bool StartListInAnotherRegion(PDFUnit itemHeight, PDFLayoutBlock item, int itemindex)
        {
            PDFLayoutRegion itemRegion     = item.CurrentRegion;
            PDFLayoutBlock  origListBlock  = item.Parent as PDFLayoutBlock;
            PDFLayoutRegion origListRegion = origListBlock.CurrentRegion;

            if (origListBlock.IsClosed == false)
            {
                origListBlock.Close();
            }
            //(origListBlock.Parent as PDFLayoutBlock).CurrentRegion.AddToSize(origListBlock);

            bool newPage;
            bool started = this.MoveToNextRegion(itemHeight, ref itemRegion, ref item, out newPage);

            if (started)
            {
                if (this.Context.ShouldLogVerbose)
                {
                    this.Context.TraceLog.Add(TraceLevel.Verbose, ListEngineLogCategory, "Started list '" + this.List.ID + "' in a new " + (newPage ? "Page" : "Region") + " and list item block is now '" + item.ToString() + "'");
                }
            }

            return(started);
        }
        //
        // main override
        //

        #region protected override void DoLayoutComponent()

        /// <summary>
        /// Performs the actual layout of the list and items in it.
        /// </summary>
        protected override void DoLayoutComponent()
        {
            if (this.Context.ShouldLogDebug)
            {
                this.Context.TraceLog.Begin(TraceLevel.Debug, ListEngineLogCategory, string.Format("Starting the layout of the list {0}", this.List.ID));
            }

            this.ContinueLayout = true;

            this.CurrentBlock = this.Context.DocumentLayout.CurrentPage.LastOpenBlock();
            if (this.CurrentBlock.CurrentRegion != null && this.CurrentBlock.CurrentRegion.HasOpenItem)
            {
                this.CurrentBlock.CurrentRegion.CloseCurrentItem();
            }

            PDFPositionOptions pos = this.FullStyle.CreatePostionOptions();


            //Set up the outer container block that will hold the list and all it's items
            _listBlock = this.CurrentBlock.BeginNewContainerBlock(this.List, this, this.FullStyle, pos.PositionMode);
            PDFRect bounds = this.CurrentBlock.CurrentRegion.UnusedBounds;

            if (bounds.X > 0)
            {
                bounds.X = PDFUnit.Zero;
            }

            if (pos.Width.HasValue)
            {
                bounds.Width = pos.Width.Value;
            }
            else if (pos.Margins.IsEmpty == false)
            {
                bounds.Width -= pos.Margins.Left + pos.Margins.Right;
            }


            if (pos.Height.HasValue)
            {
                bounds.Height = pos.Height.Value;
            }
            else if (pos.Margins.IsEmpty == false)
            {
                bounds.Height -= pos.Margins.Top + pos.Margins.Bottom;
            }

            PDFColumnOptions columnOptions = new PDFColumnOptions()
            {
                AlleyWidth = PDFUnit.Zero, AutoFlow = false, ColumnCount = 1
            };

            _listBlock.InitRegions(bounds, pos, columnOptions, this.Context);

            this.OpenListNumbering();

            this.BuildListEntries(out _itemNumberWidth);
            this.LayoutListItems(pos);

            _listBlock.CurrentRegion.CloseCurrentItem();
            _listBlock.CurrentRegion.Close();
            _listBlock.Close();

            this.CurrentBlock.CurrentRegion.AddToSize(_listBlock);

            if (this.Context.ShouldLogDebug)
            {
                this.Context.TraceLog.End(TraceLevel.Debug, ListEngineLogCategory, string.Format("Completed the layout of the list {0}", this.List.ID));
            }

            this.CloseListNumbering();
        }
        /// <summary>
        /// Checks the overflow style and if new pages are supported closes the current page layout and
        /// creates a new page layout (becomming the current page) and returns true.
        /// If overflow is not supported - returns false
        /// </summary>
        /// <param name="region">If there is a change in current page, this is set to the new region</param>
        /// <param name="block">If there is a change in current page, this is set to the new block</param>
        /// <returns></returns>
        public override bool MoveToNextPage(IPDFComponent initiator, Style initiatorStyle, Stack <PDFLayoutBlock> depth, ref PDFLayoutRegion region, ref PDFLayoutBlock block)
        {
            StyleValue <OverflowAction> action;

            if (this.FullStyle.TryGetValue(StyleKeys.OverflowActionKey, out action) && action.Value == OverflowAction.NewPage)
            {
                PDFLayoutPage  lastpage = this.DocumentLayout.CurrentPage;
                PDFLayoutBlock open     = lastpage.ContentBlock;
                if (open.IsClosed)
                {
                    open = null;
                }
                else
                {
                    open = open.LastOpenBlock();
                }

                List <PDFLayoutBlock> toclose = new List <PDFLayoutBlock>(depth);

                for (int i = toclose.Count - 1; i >= 0; i--)
                {
                    open = toclose[i];
                    if (open.CurrentRegion != null && open.CurrentRegion.IsClosed == false)
                    {
                        PDFLayoutRegion openRegion = open.CurrentRegion;
                        openRegion.Close();
                    }

                    PDFLayoutBlock parent = open.Parent as PDFLayoutBlock;
                    if (null != parent)
                    {
                        PDFLayoutRegion parentRegion = parent.CurrentRegion;
                        if (null != parentRegion)
                        {
                            open.Close();
                            parentRegion.AddToSize(open);
                        }
                    }

                    //open = parent;
                }
                lastpage.Close();
                var           pgSize = this.GetNextPageSize(initiator, initiatorStyle, lastpage.Size);
                PDFLayoutPage page   = BuildContinuationPage(lastpage, pgSize);

                block  = page.CurrentBlock;
                region = block.CurrentRegion;

                if (this.Context.ShouldLogVerbose)
                {
                    this.Context.TraceLog.Add(TraceLevel.Verbose, LOG_CATEGORY, "Built a new continuation page for " + this.Component + " and recreated the " + toclose.Count + " blocks and regions on the new page");
                }
                return(true);
            }
            else
            {
                if (this.Context.ShouldLogVerbose)
                {
                    this.Context.TraceLog.Add(TraceLevel.Verbose, LOG_CATEGORY, "Cannot overflow content for page " + this.Component + " halting the continued layout by returning false");
                }

                return(false); //Cannot overflow
            }
        }
示例#4
0
        protected void EnsureContentsFit()
        {
            bool           newPage;
            PDFLayoutBlock block = this.CurrentBlock;
            //re-retrieve our container block and region
            //it could have changed whilst laying out other regions / pages.
            PDFLayoutBlock containerBlock = block.Parent as PDFLayoutBlock;

            if (block.IsClosed == false)
            {
                block.Close();
            }

            bool    updateSize = false;
            PDFSize updated    = block.Size;



            if (block.Position.MinimumHeight.HasValue && block.Height < block.Position.MinimumHeight.Value)
            {
                updated.Height = block.Position.MinimumHeight.Value - (block.Position.Padding.Top + block.Position.Padding.Bottom);
                updateSize     = true;
            }

            if (block.Position.MinimumWidth.HasValue && block.Width < block.Position.MinimumWidth.Value)
            {
                updated.Width = block.Position.MinimumWidth.Value - (block.Position.Padding.Left + block.Position.Padding.Right);
                updateSize    = true;
            }



            if (updateSize)
            {
                block.SetContentSize(updated.Width, updated.Height);
            }



            PDFLayoutRegion containerRegion = containerBlock.CurrentRegion;

            //ADDED to support blocks flowing to the next region or page
            PDFUnit vspace = containerRegion.TotalBounds.Height - containerRegion.UsedSize.Height;
            PDFUnit req    = block.Height;



            bool canfitvertical = req <= vspace;


            if (!canfitvertical && containerRegion.Contents.Count > 1)
            {
                PDFLayoutRegion prev = containerRegion;
                if (this.MoveToNextRegion(req, ref containerRegion, ref containerBlock, out newPage))
                {
                    prev.Contents.Remove(block);
                    containerRegion.AddExistingItem(block);
                }
                else
                {
                    this.Context.TraceLog.Add(TraceLevel.Warning, LOG_CATEGORY, "Cannot fit the block for component " + this.Component.UniqueID + " in the avilable height (required = '" + req + "', available = '" + vspace + "'), and we cannot overflow to a new region. Layout of component stopped and returning.");

                    this.ContinueLayout = false;
                }
            }
            else
            {
                //Region has not updated its size as the block was directly closed.
                containerRegion.AddToSize(block);
            }
        }