/// <summary>
        /// Renders a MigraDoc document to the specified graphics object.
        /// </summary>
        public void RenderPage(XGraphics gfx, int page, PageRenderOptions options)
        {
            if (_formattedDocument.IsEmptyPage(page))
            {
                return;
            }

            FieldInfos fieldInfos = _formattedDocument.GetFieldInfos(page);

            fieldInfos.Date = _printDate != DateTime.MinValue ? _printDate : DateTime.Now;

            if ((options & PageRenderOptions.RenderHeader) == PageRenderOptions.RenderHeader)
            {
                RenderHeader(gfx, page);
            }
            if ((options & PageRenderOptions.RenderFooter) == PageRenderOptions.RenderFooter)
            {
                RenderFooter(gfx, page);
            }

            if ((options & PageRenderOptions.RenderContent) == PageRenderOptions.RenderContent)
            {
                RenderInfo[] renderInfos = _formattedDocument.GetRenderInfos(page);
                //foreach (RenderInfo renderInfo in renderInfos)
                int count = renderInfos.Length;
                for (int idx = 0; idx < count; idx++)
                {
                    RenderInfo renderInfo = renderInfos[idx];
                    Renderer   renderer   = Renderer.Create(gfx, this, renderInfo, fieldInfos);
                    renderer.Render();
                }
            }
        }
        /// <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();
        }
예제 #3
0
        private void RenderFooter(XGraphics graphics, int page)
        {
            FormattedHeaderFooter formattedFooter = this.formattedDocument.GetFormattedFooter(page);

            if (formattedFooter == null)
            {
                return;
            }

            Rectangle footerArea = this.formattedDocument.GetFooterArea(page);

            RenderInfo[] renderInfos = formattedFooter.GetRenderInfos();
            XUnit        topY        = footerArea.Y + footerArea.Height - RenderInfo.GetTotalHeight(renderInfos);

            FieldInfos fieldInfos = this.formattedDocument.GetFieldInfos(page);

            foreach (RenderInfo renderInfo in renderInfos)
            {
                Renderer renderer = Renderer.Create(graphics, this, renderInfo, fieldInfos);
                XUnit    savedY   = renderer.RenderInfo.LayoutInfo.ContentArea.Y;
                renderer.RenderInfo.LayoutInfo.ContentArea.Y = topY;
                renderer.Render();
                renderer.RenderInfo.LayoutInfo.ContentArea.Y = savedY;
            }
        }
        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);
        }
예제 #5
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);
        }
예제 #6
0
        /// <summary>
        /// Renders the contents shifted to the given Coordinates.
        /// </summary>
        /// <param name="xShift">The x shift.</param>
        /// <param name="yShift">The y shift.</param>
        /// <param name="renderInfos">The render infos.</param>
        protected void RenderByInfos(XUnit xShift, XUnit yShift, RenderInfo[] renderInfos)
        {
            if (renderInfos == null)
            {
                return;
            }

            foreach (RenderInfo renderInfo in renderInfos)
            {
                XUnit savedX = renderInfo.LayoutInfo.ContentArea.X;
                XUnit savedY = renderInfo.LayoutInfo.ContentArea.Y;
                renderInfo.LayoutInfo.ContentArea.X += xShift;
                renderInfo.LayoutInfo.ContentArea.Y += yShift;
                Renderer renderer = Renderer.Create(this.gfx, this.documentRenderer, renderInfo, this.fieldInfos);
                renderer.Render();
                renderInfo.LayoutInfo.ContentArea.X = savedX;
                renderInfo.LayoutInfo.ContentArea.Y = savedY;
            }
        }
        private void RenderHeader(XGraphics graphics, int page)
        {
            FormattedHeaderFooter formattedHeader = _formattedDocument.GetFormattedHeader(page);

            if (formattedHeader == null)
            {
                return;
            }

            Rectangle headerArea = _formattedDocument.GetHeaderArea(page);

            RenderInfo[] renderInfos = formattedHeader.GetRenderInfos();
            FieldInfos   fieldInfos  = _formattedDocument.GetFieldInfos(page);

            foreach (RenderInfo renderInfo in renderInfos)
            {
                Renderer renderer = Renderer.Create(graphics, this, renderInfo, fieldInfos);
                renderer.Render();
            }
        }
        private void RenderFooter(XGraphics graphics, int page)
        {
            FormattedHeaderFooter formattedFooter = _formattedDocument.GetFormattedFooter(page);

            if (formattedFooter == null)
            {
                return;
            }

            Rectangle footerArea = _formattedDocument.GetFooterArea(page);

            RenderInfo[] renderInfos = formattedFooter.GetRenderInfos();
#if true
#if true
            // The footer is bottom-aligned and grows with its contents. topY specifies the Y position where the footer begins.
            XUnit topY = footerArea.Y + footerArea.Height - RenderInfo.GetTotalHeight(renderInfos);
            // Hack: The purpose of "topY" is unclear, but two paragraphs in the footer will use the same topY and will be rendered at the same position.
            // offsetY specifies the offset (amount of movement) for all footer items. It's the difference between topY and the position calculated for the first item.
            XUnit offsetY  = 0;
            bool  notFirst = false;

            FieldInfos fieldInfos = _formattedDocument.GetFieldInfos(page);
            foreach (RenderInfo renderInfo in renderInfos)
            {
                Renderer renderer = Renderer.Create(graphics, this, renderInfo, fieldInfos);
                if (!notFirst)
                {
                    offsetY  = renderer.RenderInfo.LayoutInfo.ContentArea.Y - topY;
                    notFirst = true;
                }
                XUnit savedY = renderer.RenderInfo.LayoutInfo.ContentArea.Y;
                // Apply offsetY only to items that do not have an absolute position.
                if (renderer.RenderInfo.LayoutInfo.Floating != Floating.None)
                {
                    renderer.RenderInfo.LayoutInfo.ContentArea.Y -= offsetY;
                }
                renderer.Render();
                renderer.RenderInfo.LayoutInfo.ContentArea.Y = savedY;
            }
#else
            // TODO Document the purpose of "topY".
            XUnit topY = footerArea.Y + footerArea.Height - RenderInfo.GetTotalHeight(renderInfos);
            // Hack: The purpose of "topY" is unclear, but two paragraphs in the footer will use the same topY and will be rendered at the same position.
            XUnit offsetY = 0;

            FieldInfos fieldInfos = _formattedDocument.GetFieldInfos(page);
            foreach (RenderInfo renderInfo in renderInfos)
            {
                Renderer renderer = Renderer.Create(graphics, this, renderInfo, fieldInfos);
                XUnit    savedY   = renderer.RenderInfo.LayoutInfo.ContentArea.Y;
                renderer.RenderInfo.LayoutInfo.ContentArea.Y = topY + offsetY;
                renderer.Render();
                renderer.RenderInfo.LayoutInfo.ContentArea.Y = savedY;
                offsetY += renderer.RenderInfo.LayoutInfo.ContentArea.Height;
            }
#endif
#else
            XUnit topY = footerArea.Y + footerArea.Height - RenderInfo.GetTotalHeight(renderInfos);

            FieldInfos fieldInfos = _formattedDocument.GetFieldInfos(page);
            foreach (RenderInfo renderInfo in renderInfos)
            {
                Renderer renderer = Renderer.Create(graphics, this, renderInfo, fieldInfos);
                XUnit    savedY   = renderer.RenderInfo.LayoutInfo.ContentArea.Y;
                renderer.RenderInfo.LayoutInfo.ContentArea.Y = topY;
                renderer.Render();
                renderer.RenderInfo.LayoutInfo.ContentArea.Y = savedY;
            }
#endif
        }
        /// <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;
                }
            }
        }