/// <summary>
        /// Renders a single object to the specified graphics object at the given point.
        /// </summary>
        /// <param name="graphics">The graphics object to render on.</param>
        /// <param name="xPosition">The left position of the rendered object.</param>
        /// <param name="yPosition">The top position of the rendered object.</param>
        /// <param name="width">The width.</param>
        /// <param name="documentObject">The document object to render. Can be paragraph, table, or shape.</param>
        /// <remarks>This function is still in an experimental state.</remarks>
        public void RenderObject(XGraphics graphics, XUnit xPosition, XUnit yPosition, XUnit width, DocumentObject documentObject)
        {
            if (graphics == null)
            {
                throw new ArgumentNullException("graphics");
            }

            if (documentObject == null)
            {
                throw new ArgumentNullException("documentObject");
            }

            if (!(documentObject is Shape) && !(documentObject is Table) &&
                !(documentObject is Paragraph))
            {
                throw new ArgumentException(Messages2.ObjectNotRenderable, "documentObject");
            }

            Renderer renderer = Renderer.Create(graphics, this, documentObject, null);

            renderer.Format(new Rectangle(xPosition, yPosition, width, double.MaxValue), null);

            RenderInfo renderInfo = renderer.RenderInfo;

            renderInfo.LayoutInfo.ContentArea.X = xPosition;
            renderInfo.LayoutInfo.ContentArea.Y = yPosition;

            renderer = Renderer.Create(graphics, this, renderer.RenderInfo, null);
            renderer.Render();
        }
        bool NextElementsDontFit(int idx, Area remainingArea, XUnit previousMarginBottom)
        {
            XUnit elementDistance = previousMarginBottom;
            Area  area            = remainingArea;

            for (int index = idx + 1; index < _elements.Count; ++index)
            {
                // Never combine more than MaxCombineElements elements
                if (index - idx > MaxCombineElements)
                {
                    return(false);
                }

                DocumentObject obj          = _elements[index];
                Renderer       currRenderer = Renderer.Create(_gfx, _documentRenderer, obj, _areaProvider.AreaFieldInfos);
                elementDistance = MarginMax(elementDistance, currRenderer.InitialLayoutInfo.MarginTop);
                area            = area.Lower(elementDistance);

                if (area.Height <= 0)
                {
                    return(true);
                }

                currRenderer.Format(area, null);
                FormatInfo currFormatInfo = currRenderer.RenderInfo.FormatInfo;
                LayoutInfo currLayoutInfo = currRenderer.RenderInfo.LayoutInfo;

                if (currLayoutInfo.VerticalReference != VerticalReference.PreviousElement)
                {
                    return(false);
                }

                if (!currFormatInfo.StartingIsComplete)
                {
                    return(true);
                }

                if (currLayoutInfo.KeepTogether && !currFormatInfo.IsComplete)
                {
                    return(true);
                }

                if (!(currLayoutInfo.KeepTogether && currLayoutInfo.KeepWithNext))
                {
                    return(false);
                }

                area = area.Lower(currLayoutInfo.ContentArea.Height);
                if (area.Height <= 0)
                {
                    return(true);
                }

                elementDistance = currLayoutInfo.MarginBottom;
            }
            return(false);
        }
Example #3
0
        XUnit CalcInherentWidth()
        {
            XUnit inherentWidth = 0;

            foreach (DocumentObject obj in this.textArea.Elements)
            {
                Renderer renderer = Renderer.Create(this.gfx, this.documentRenderer, obj, this.fieldInfos);
                if (renderer != null)
                {
                    renderer.Format(new Rectangle(0, 0, double.MaxValue, double.MaxValue), null);
                    inherentWidth = Math.Max(renderer.RenderInfo.LayoutInfo.MinWidth, inherentWidth);
                }
            }
            inherentWidth += this.textArea.LeftPadding;
            inherentWidth += this.textArea.RightPadding;
            return(inherentWidth);
        }
        /// <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)
        {
            _gfx = gfx;
            XUnit             prevBottomMargin = 0;
            XUnit             yPos             = prevBottomMargin;
            RenderInfo        prevRenderInfo   = null;
            FormatInfo        prevFormatInfo   = null;
            List <RenderInfo> renderInfos      = new List <RenderInfo>();
            bool  ready         = _elements.Count == 0;
            bool  isFirstOnPage = true;
            Area  area          = _areaProvider.GetNextArea();
            XUnit maxHeight     = area.Height;

            if (ready)
            {
                _areaProvider.StoreRenderInfos(renderInfos);
                return;
            }
            int idx = 0;

            while (!ready && area != null)
            {
                DocumentObject docObj   = _elements[idx];
                Renderer       renderer = Renderer.Create(gfx, _documentRenderer, docObj, _areaProvider.AreaFieldInfos);
                if (renderer != null) // "Slightly hacked" for legends: see below
                {
                    renderer.MaxElementHeight = maxHeight;
                }

                if (topLevel && _documentRenderer.HasPrepareDocumentProgress)
                {
                    _documentRenderer.OnPrepareDocumentProgress(_documentRenderer.ProgressCompleted + idx + 1,
                                                                _documentRenderer.ProgressMaximum);
                }

                // "Slightly hacked" for legends: they are rendered as part of the chart.
                // So they are skipped here.
                if (renderer == null)
                {
                    ready = idx == _elements.Count - 1;
                    if (ready)
                    {
                        _areaProvider.StoreRenderInfos(renderInfos);
                    }
                    ++idx;
                    continue;
                }
                ///////////////////////////////////////////
                if (prevFormatInfo == null)
                {
                    LayoutInfo initialLayoutInfo = renderer.InitialLayoutInfo;
                    XUnit      distance          = prevBottomMargin;
                    if (initialLayoutInfo.VerticalReference == VerticalReference.PreviousElement &&
                        initialLayoutInfo.Floating != Floating.None)
                    {
                        distance = MarginMax(initialLayoutInfo.MarginTop, distance);
                    }

                    area = area.Lower(distance);
                }
                renderer.Format(area, prevFormatInfo);
                _areaProvider.PositionHorizontally(renderer.RenderInfo.LayoutInfo);
                bool pagebreakBefore = _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, _documentRenderer, docObj, _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             = _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)
                        {
                            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, _documentRenderer, docObj, _areaProvider.AreaFieldInfos);
                        renderer.MaxElementHeight = maxHeight;
                        renderer.Format(area, prevFormatInfo);
                        prevFormatInfo = null;

                        _areaProvider.PositionHorizontally(renderer.RenderInfo.LayoutInfo);
                        _areaProvider.PositionVertically(renderer.RenderInfo.LayoutInfo);

                        ready = idx == _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 (!ready)
                    {
                        area      = _areaProvider.GetNextArea();
                        maxHeight = area.Height;
                    }
                }
                if (idx == _elements.Count && !ready)
                {
                    _areaProvider.StoreRenderInfos(renderInfos);
                    ready = true;
                }
            }
        }