// // 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 } }
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); } }