protected override void DoLayoutComponent() { if (this.Context.ShouldLogVerbose) { this.Context.TraceLog.Begin(TraceLevel.Verbose, "Panel Layout Engine", "Beginning layout of component '" + this.Component + "' as a viewport component"); } PDFPositionOptions pos = this.FullStyle.CreatePostionOptions(); PDFColumnOptions columns = this.FullStyle.CreateColumnOptions(); if (pos.PositionMode != Drawing.PositionMode.Inline) { this.DoLayoutBlockComponent(pos, columns); } else { PDFLayoutInlineBegin begin = CreateAndAddInlineBegin(pos); this.DoLayoutChildren(); this.CreateAndAddInlineEnd(pos, begin); } if (this.Context.ShouldLogVerbose) { this.Context.TraceLog.End(TraceLevel.Verbose, "Panel Layout Engine", "Completed layout of component '" + this.Component + "' as a viewport component"); } }
/// <summary> /// Lays out all the content of this panel /// </summary> /// <param name="position"></param> protected virtual void DoLayoutBlockComponent(PDFPositionOptions position, PDFColumnOptions columnOptions) { PDFLayoutBlock containerBlock = CreateContinerBlock(position); if (null == containerBlock) { return; } CreateBlockRegions(containerBlock, position, columnOptions); this.DoLayoutChildren(); EnsureContentsFit(); }
// // methods // #region public void InitPage(int index, PDFSize size, PDFThickness margthick ...) /// <summary> /// Initializes this page with the required top block size and other measurements /// </summary> /// <param name="size"></param> /// <param name="margthick"></param> /// <param name="padthick"></param> /// <param name="available"></param> /// <param name="mode"></param> /// <param name="cansplit"></param> /// <param name="colcount"></param> /// <param name="alley"></param> public virtual void InitPage(PDFSize size, PDFPositionOptions options, PDFColumnOptions columns, PDFLayoutContext context) { this.Size = size; this.PositionOptions = options; OverflowSplit split = options.OverflowSplit; PDFLayoutBlock block = new PDFLayoutBlock(this, this.Owner, this.Engine, this.FullStyle, split); PDFRect totalbounds = new PDFRect(PDFPoint.Empty, this.Size); block.InitRegions(totalbounds, options, columns, context); //We need to set the bounds of the page block to the total for a page //(as margins are taken off from the size of the page // - this is different to a block where margins increase any explicit sizes). block.TotalBounds = totalbounds; this.ContentBlock = block; this.CurrentBlock = block; }
// // 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> /// Lays out a single list item based on the entry, and the list position options /// </summary> /// <param name="index"></param> /// <param name="entry"></param> /// <param name="listPosOpts"></param> /// <returns></returns> private PDFUnit LayoutAnItem(int index, ListNumberEntry entry, PDFPositionOptions listPosOpts) { //restore the items applied style onto the stack this.StyleStack.Push(entry.AppliedStyle); Style full = entry.FullStyle; PDFUnit numberWidth = entry.NumberWidth; PDFArtefactRegistrationSet artefacts = entry.ListItem.RegisterLayoutArtefacts(this.Context, full); PDFPositionOptions itemopts = full.CreatePostionOptions(); PDFUnit pageHeight = this.Context.DocumentLayout.CurrentPage.Height; PDFUnit h = pageHeight; PDFUnit w = _listBlock.AvailableBounds.Width; PDFUnit y = _itemoffset; PDFUnit alley = DefaultListItemAlley; if (itemopts.HasAlleyWidth) { alley = itemopts.AlleyWidth; } else if (listPosOpts.HasAlleyWidth) { alley = listPosOpts.AlleyWidth; } if (itemopts.Height.HasValue) { h = itemopts.Height.Value; } else if (itemopts.Margins.IsEmpty == false) { h -= itemopts.Margins.Top + itemopts.Margins.Bottom; } h -= itemopts.Padding.Top + itemopts.Padding.Bottom; if (itemopts.Width.HasValue) { w = itemopts.Width.Value; } else if (itemopts.Margins.IsEmpty == false) { w -= itemopts.Margins.Left + itemopts.Margins.Right; } w -= itemopts.Padding.Left + itemopts.Padding.Right; PDFRect totalBounds = new PDFRect(PDFUnit.Zero, y, w, h); this._itemblock = _listBlock.BeginNewContainerBlock(entry.ListItem, this, full, itemopts.PositionMode); PDFColumnOptions colOpts = new PDFColumnOptions() { AlleyWidth = alley, AutoFlow = false, ColumnCount = 2 }; this._itemblock.InitRegions(totalBounds, itemopts, colOpts, this.Context); //Alter the widths of the regions to allow for only the number width PDFRect region1bounds = this._itemblock.Columns[0].TotalBounds; PDFUnit difference = region1bounds.Width - numberWidth; region1bounds.Width = numberWidth; this._itemblock.Columns[0].TotalBounds = region1bounds; this._itemblock.Columns[0].HAlignment = entry.NumberAlignment; PDFRect region2Bounds = this._itemblock.Columns[1].TotalBounds; if (region2Bounds.X > 0) { region2Bounds.X -= difference; } region2Bounds.Width += difference; this._itemblock.Columns[1].TotalBounds = region2Bounds; PDFUnit numberHeight = this.LayoutItemNumber(entry, full); this._itemblock.CurrentRegion.Close(); bool success = this._itemblock.MoveToNextRegion(true, PDFUnit.Zero, this.Context); //Pass Zero as we are not interested in overflowing yet PDFUnit contentHeight = this.LayoutItemContent(entry); //check that we can fit - addind the margins and padding back in. PDFUnit itemHeight = PDFUnit.Max(numberHeight, contentHeight); if (itemopts.Height.HasValue) { itemHeight = itemopts.Height.Value; } else if (itemopts.Margins.IsEmpty == false) { itemHeight += itemopts.Margins.Top + itemopts.Margins.Bottom; } itemHeight += itemopts.Padding.Top + itemopts.Padding.Bottom; if (itemHeight > this._listBlock.AvailableBounds.Height - _itemoffset) { PDFLayoutBlock origparent = this.CurrentBlock; PDFLayoutRegion origregion = this.CurrentBlock.CurrentRegion; PDFLayoutBlock origlist = this._listBlock; PDFLayoutBlock origItem = this._itemblock; if (this._listBlock.Position.OverflowSplit == OverflowSplit.Never) { if (this.MoveFullListToNextRegion(_itemoffset + itemHeight)) { //_itemoffset += itemHeight; //PDFRect avail = _listBlock.AvailableBounds; //avail.Height = avail.Height - _itemoffset; } else { this.Context.TraceLog.Add(TraceLevel.Warning, LOG_CATEGORY, "List '" + this.List.UniqueID + "' has filled the available space, and cannot overflow onto a new region. Layout has stopped at item index " + index); this.ContinueLayout = false; return(0); } } else if (this.StartListInAnotherRegion(itemHeight, origItem, index)) { //origregion.AddToSize(origlist); _itemoffset = 0; origItem.Offset(0, 0); } else { (origItem.Parent as PDFLayoutBlock).CurrentRegion.RemoveItem(origItem); this.Context.TraceLog.Add(TraceLevel.Warning, LOG_CATEGORY, "List '" + this.List.UniqueID + "' has filled the available space, and cannot overflow onto a new region. Layout has stopped at item index " + index); this.ContinueLayout = false; } } else if (this._itemblock.CurrentRegion.IsClosed) { this._itemblock = this.CurrentBlock.LastOpenBlock(); this._listBlock = this._itemblock.Parent as PDFLayoutBlock; } if (null != this._itemblock) { if (this._itemblock.CurrentRegion.IsClosed == false) { this._itemblock.CurrentRegion.Close(); } if (this._itemblock.IsClosed == false) { this._itemblock.Close(); this._listBlock.CurrentRegion.AddToSize(this._itemblock); } } if (this.ContinueLayout) { RegisterChildLayout(entry.ListItem); } if (null != artefacts) { entry.ListItem.CloseLayoutArtefacts(this.Context, artefacts, full); } this.StyleStack.Pop(); return(itemHeight); }
// // overrides // /// <summary> /// Main overridden method /// </summary> protected override void DoLayoutComponent() { IDisposable record = this.Context.PerformanceMonitor.Record(PerformanceMonitorType.Layout_Pages, "Page " + this.Component.ID); //Take a copy of the style stack for the header and footer this.PageStyleStack = this.Context.StyleStack.Clone(); //Get the page size and position options PageSize pgsize = this.FullStyle.CreatePageSize(); pgsize.Size = this.GetNextPageSize(this.Component, this.FullStyle, pgsize.Size); PDFPositionOptions options = this.FullStyle.CreatePostionOptions(); //Graphics PDFGraphics g = this.Page.CreateGraphics(this.StyleStack, this.Context); this.Context.Graphics = g; //Size, border, margins PDFRect bounds = new PDFRect(PDFPoint.Empty, pgsize.Size); PDFRect contentrect = GetContentRectFromBounds(bounds, options.Margins, options.Padding); //Columns PDFColumnOptions colOpts = this.FullStyle.CreateColumnOptions(); //Overflow OverflowAction action = options.OverflowAction; PDFLayoutPage pg = BuildNewPage(pgsize.Size, options, colOpts, action); //Register page numbering PDFPageNumberOptions numbers = this.GetPageNumbering(this.FullStyle); this.RegisterPageNumbering(pg, numbers); this.LayoutPageContent(); //close the last page PDFLayoutPage last = this.DocumentLayout.CurrentPage; if (last.IsClosed == false) { last.Close(); } //Unregister the page numbers. this.UnRegisterPageNumbering(last, numbers); //release graphics this.Context.Graphics = null; g.Dispose(); record.Dispose(); }
// // support methods // #region protected virtual void BuildNewPage(PDFPageSize pgsize, PDFPositionOptions options ...) /// <summary> /// Creates a new page with the specified options and adds it to the current layout /// </summary> /// <param name="pgsize"></param> /// <param name="options"></param> /// <param name="alley"></param> /// <param name="colcount"></param> /// <param name="action"></param> protected virtual PDFLayoutPage BuildNewPage(PDFSize pgsize, PDFPositionOptions options, PDFColumnOptions colOpts, OverflowAction action) { PDFLayoutDocument doclayout = this.DocumentLayout; PDFLayoutPage pg = doclayout.BeginNewPage(this.Page, this, this.FullStyle, action); pg.InitPage(pgsize, options, colOpts, this.Context); return(pg); }
protected virtual void CreateBlockRegions(PDFLayoutBlock containerBlock, PDFPositionOptions position, PDFColumnOptions columnOptions) { PDFRect unused = containerBlock.CurrentRegion.UnusedBounds; PDFUnit yoffset = containerBlock.CurrentRegion.Height; PDFRect total = new PDFRect(PDFUnit.Zero, yoffset, unused.Width, unused.Height); if (position.Width.HasValue) { total.Width = position.Width.Value; } //ADDED for min/max sizes. Include the margins as we are making this the available width. else if (position.MaximumWidth.HasValue) { total.Width = position.MaximumWidth.Value + position.Margins.Left + position.Margins.Right; } if (position.Height.HasValue) { total.Height = position.Height.Value; } //ADDED for min/max sizes. Include the margins as we are making this the available height. else if (position.MaximumHeight.HasValue) { total.Height = position.MaximumHeight.Value + position.Margins.Top + position.Margins.Bottom; } CurrentBlock.InitRegions(total, position, columnOptions, this.Context); }