/// <summary> /// Formats the elements on the areas provided by the area provider. /// </summary> /// <param name="gfx">The graphics object to render on.</param> /// <param name="topLevel">if set to <c>true</c> formats the object is on top level.</param> public void FormatOnAreas(XGraphics gfx, bool topLevel) { this.gfx = gfx; XUnit prevBottomMargin = 0; XUnit yPos = prevBottomMargin; RenderInfo prevRenderInfo = null; FormatInfo prevFormatInfo = null; ArrayList renderInfos = new ArrayList(); bool ready = this.elements.Count == 0; bool isFirstOnPage = true; Area area = this.areaProvider.GetNextArea(); XUnit maxHeight = area.Height; if (ready) { this.areaProvider.StoreRenderInfos(renderInfos); return; } int idx = 0; while (!ready && area != null) { DocumentObject docObj = this.elements[idx]; Renderer renderer = Renderer.Create(gfx, this.documentRenderer, docObj, this.areaProvider.AreaFieldInfos); if (renderer != null) // "Slightly hacked" for legends: see below { renderer.MaxElementHeight = maxHeight; } if (topLevel && this.documentRenderer.HasPrepareDocumentProgress) { this.documentRenderer.OnPrepareDocumentProgress(this.documentRenderer.ProgressCompleted + idx + 1, this.documentRenderer.ProgressMaximum); } // "Slightly hacked" for legends: they are rendered as part of the chart. // So they are skipped here. if (renderer == null) { ready = idx == this.elements.Count - 1; if (ready) { this.areaProvider.StoreRenderInfos(renderInfos); } ++idx; continue; } /////////////////////////////////////////// if (prevFormatInfo == null) { LayoutInfo initialLayoutInfo = renderer.InitialLayoutInfo; XUnit distance = prevBottomMargin; if (initialLayoutInfo.VerticalReference == VerticalReference.PreviousElement && initialLayoutInfo.Floating != Floating.None) //Added KlPo 12.07.07 { distance = MarginMax(initialLayoutInfo.MarginTop, distance); } area = area.Lower(distance); } renderer.Format(area, prevFormatInfo); this.areaProvider.PositionHorizontally(renderer.RenderInfo.LayoutInfo); bool pagebreakBefore = this.areaProvider.IsAreaBreakBefore(renderer.RenderInfo.LayoutInfo) && !isFirstOnPage; pagebreakBefore = pagebreakBefore || !isFirstOnPage && IsForcedAreaBreak(idx, renderer, area); if (!pagebreakBefore && renderer.RenderInfo.FormatInfo.IsEnding) { if (PreviousRendererNeedsRemoveEnding(prevRenderInfo, renderer.RenderInfo, area)) { prevRenderInfo.RemoveEnding(); renderer = Renderer.Create(gfx, this.documentRenderer, docObj, this.areaProvider.AreaFieldInfos); renderer.MaxElementHeight = maxHeight; renderer.Format(area, prevRenderInfo.FormatInfo); } else if (NeedsEndingOnNextArea(idx, renderer, area, isFirstOnPage)) { renderer.RenderInfo.RemoveEnding(); prevRenderInfo = FinishPage(renderer.RenderInfo, pagebreakBefore, ref renderInfos); if (prevRenderInfo != null) { prevFormatInfo = prevRenderInfo.FormatInfo; } else { prevFormatInfo = null; isFirstOnPage = true; } prevBottomMargin = 0; area = this.areaProvider.GetNextArea(); maxHeight = area.Height; } else { renderInfos.Add(renderer.RenderInfo); isFirstOnPage = false; areaProvider.PositionVertically(renderer.RenderInfo.LayoutInfo); if (renderer.RenderInfo.LayoutInfo.VerticalReference == VerticalReference.PreviousElement && renderer.RenderInfo.LayoutInfo.Floating != Floating.None)//Added KlPo 12.07.07 { prevBottomMargin = renderer.RenderInfo.LayoutInfo.MarginBottom; if (renderer.RenderInfo.LayoutInfo.Floating != Floating.None) { area = area.Lower(renderer.RenderInfo.LayoutInfo.ContentArea.Height); } } else { prevBottomMargin = 0; } prevFormatInfo = null; prevRenderInfo = null; ++idx; } } else { if (renderer.RenderInfo.FormatInfo.IsEmpty && isFirstOnPage) { area = area.Unite(new Rectangle(area.X, area.Y, area.Width, double.MaxValue)); renderer = Renderer.Create(gfx, this.documentRenderer, docObj, this.areaProvider.AreaFieldInfos); renderer.MaxElementHeight = maxHeight; renderer.Format(area, prevFormatInfo); prevFormatInfo = null; //Added KlPo 12.07.07 this.areaProvider.PositionHorizontally(renderer.RenderInfo.LayoutInfo); this.areaProvider.PositionVertically(renderer.RenderInfo.LayoutInfo); //Added End ready = idx == this.elements.Count - 1; ++idx; } prevRenderInfo = FinishPage(renderer.RenderInfo, pagebreakBefore, ref renderInfos); if (prevRenderInfo != null) { prevFormatInfo = prevRenderInfo.FormatInfo; } else { prevFormatInfo = null; } isFirstOnPage = true; prevBottomMargin = 0; #if false area = this.areaProvider.GetNextArea(); #else if (!ready) //!!!newTHHO 19.01.2007: korrekt? oder GetNextArea immer ausführen??? { area = this.areaProvider.GetNextArea(); maxHeight = area.Height; } #endif } if (idx == this.elements.Count && !ready) { this.areaProvider.StoreRenderInfos(renderInfos); ready = true; } } }
/// <summary> /// Formats the object by calculating distances and linebreaks and stopping when the area is filled. /// </summary> /// <param name="area">The area to render into.</param> /// <param name="previousFormatInfo">An information object received from a previous call of Format(). /// Null for the first call.</param> internal abstract void Format(Area area, FormatInfo previousFormatInfo);
/// <summary> /// Formats (measures) the table. /// </summary> /// <param name="area">The area on which to fit the table.</param> /// <param name="previousFormatInfo"></param> internal override void Format(Area area, FormatInfo previousFormatInfo) { DocumentElements elements = DocumentRelations.GetParent(this.table) as DocumentElements; if (elements != null) { Section section = DocumentRelations.GetParent(elements) as Section; if (section != null) { this.doHorizontalBreak = section.PageSetup.HorizontalPageBreak; } } this.renderInfo = new TableRenderInfo(); InitFormat(area, previousFormatInfo); // Don't take any Rows higher then MaxElementHeight XUnit topHeight = this.CalcStartingHeight(); XUnit probeHeight = topHeight; XUnit offset = 0; if (this.startRow > this.lastHeaderRow + 1 && this.startRow < this.table.Rows.Count) { offset = (XUnit)this.bottomBorderMap[this.startRow] - topHeight; } else { offset = -CalcMaxTopBorderWidth(0); } int probeRow = this.startRow; XUnit currentHeight = 0; XUnit startingHeight = 0; bool isEmpty = false; while (probeRow < this.table.Rows.Count) { bool firstProbe = probeRow == this.startRow; probeRow = (int)this.connectedRowsMap[probeRow]; // Don't take any Rows higher then MaxElementHeight probeHeight = (XUnit)this.bottomBorderMap[probeRow + 1] - offset; if (firstProbe && probeHeight > MaxElementHeight - Tolerance) { probeHeight = MaxElementHeight - Tolerance; } //The height for the first new row(s) + headerrows: if (startingHeight == 0) { if (probeHeight > area.Height) { isEmpty = true; break; } startingHeight = probeHeight; } if (probeHeight > area.Height) { break; } else { this.currRow = probeRow; currentHeight = probeHeight; ++probeRow; } } if (!isEmpty) { TableFormatInfo formatInfo = (TableFormatInfo)this.renderInfo.FormatInfo; formatInfo.startRow = this.startRow; formatInfo.isEnding = currRow >= this.table.Rows.Count - 1; formatInfo.endRow = this.currRow; } FinishLayoutInfo(area, currentHeight, startingHeight); }