First commit
Send all results
This commit is contained in:
		
							
								
								
									
										192
									
								
								MigraDoc.Rendering/Rendering/Area.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								MigraDoc.Rendering/Rendering/Area.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,192 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Abstract base class for all areas to render in.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public abstract class Area
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the left boundary of the area.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public abstract XUnit X { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the top boundary of the area.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public abstract XUnit Y { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the largest fitting rect with the given y position and height.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="yPosition">Top bound of the searched rectangle.</param>
 | 
			
		||||
        /// <param name="height">Height of the searched rectangle.</param>
 | 
			
		||||
        /// <returns>
 | 
			
		||||
        /// The largest fitting rect with the given y position and height.
 | 
			
		||||
        /// Null if yPosition exceeds the area.
 | 
			
		||||
        /// </returns>
 | 
			
		||||
        public abstract Rectangle GetFittingRect(XUnit yPosition, XUnit height);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the height of the smallest rectangle containing the area. 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public abstract XUnit Height { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the width of the smallest rectangle containing the area. 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public abstract XUnit Width { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Returns the union of this area snd the given one.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="area">The area to unite with.</param>
 | 
			
		||||
        /// <returns>The union of the two areas.</returns>
 | 
			
		||||
        public abstract Area Unite(Area area);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Lowers the area and makes it smaller.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="verticalOffset">The measure of lowering.</param>
 | 
			
		||||
        /// <returns>The lowered Area.</returns>
 | 
			
		||||
        public abstract Area Lower(XUnit verticalOffset);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class Rectangle : Area
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new rectangle object.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="x">Left bound of the rectangle.</param>
 | 
			
		||||
        /// <param name="y">Upper bound of the rectangle.</param>
 | 
			
		||||
        /// <param name="width">Width of the rectangle.</param>
 | 
			
		||||
        /// <param name="height">Height of the rectangle.</param>
 | 
			
		||||
        public Rectangle(XUnit x, XUnit y, XUnit width, XUnit height)
 | 
			
		||||
        {
 | 
			
		||||
            _x = x;
 | 
			
		||||
            _y = y;
 | 
			
		||||
            _width = width;
 | 
			
		||||
            _height = height;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new Rectangle by copying its values.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="rect">The rectangle to copy.</param>
 | 
			
		||||
        public Rectangle(Rectangle rect)
 | 
			
		||||
        {
 | 
			
		||||
            _x = rect._x;
 | 
			
		||||
            _y = rect._y;
 | 
			
		||||
            _width = rect._width;
 | 
			
		||||
            _height = rect._height;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the largest fitting rect with the given y position and height.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="yPosition">Top boundary of the requested rectangle.</param>
 | 
			
		||||
        /// <param name="height">Height of the requested rectangle.</param>
 | 
			
		||||
        /// <returns>The largest fitting rect with the given y position and height or NULL if the requested height does not fit.</returns>
 | 
			
		||||
        public override Rectangle GetFittingRect(XUnit yPosition, XUnit height)
 | 
			
		||||
        {
 | 
			
		||||
            if (yPosition + height > _y + _height + Renderer.Tolerance)
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            return new Rectangle(_x, yPosition, _width, height);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the left boundary of the rectangle. 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public override XUnit X
 | 
			
		||||
        {
 | 
			
		||||
            get { return _x; }
 | 
			
		||||
            set { _x = value; }
 | 
			
		||||
        }
 | 
			
		||||
        XUnit _x;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the top boundary of the rectangle. 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public override XUnit Y
 | 
			
		||||
        {
 | 
			
		||||
            get { return _y; }
 | 
			
		||||
            set { _y = value; }
 | 
			
		||||
        }
 | 
			
		||||
        XUnit _y;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the width of the rectangle. 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public override XUnit Width
 | 
			
		||||
        {
 | 
			
		||||
            get { return _width; }
 | 
			
		||||
            set { _width = value; }
 | 
			
		||||
        }
 | 
			
		||||
        XUnit _width;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the height of the rectangle. 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public override XUnit Height
 | 
			
		||||
        {
 | 
			
		||||
            get { return _height; }
 | 
			
		||||
            set { _height = value; }
 | 
			
		||||
        }
 | 
			
		||||
        XUnit _height;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Returns the union of the rectangle and the given area.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="area">The area to unite with.</param>
 | 
			
		||||
        /// <returns>The union of the two areas.</returns>
 | 
			
		||||
        public override Area Unite(Area area)
 | 
			
		||||
        {
 | 
			
		||||
            if (area == null)
 | 
			
		||||
                return this;
 | 
			
		||||
            // This implementation is of course not correct, but it works for our purposes.
 | 
			
		||||
            XUnit minTop = Math.Min(_y, area.Y);
 | 
			
		||||
            XUnit minLeft = Math.Min(_x, area.X);
 | 
			
		||||
            XUnit maxRight = Math.Max(_x + _width, area.X + area.Width);
 | 
			
		||||
            XUnit maxBottom = Math.Max(_y + _height, area.Y + area.Height);
 | 
			
		||||
            return new Rectangle(minLeft, minTop, maxRight - minLeft, maxBottom - minTop);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override Area Lower(XUnit verticalOffset)
 | 
			
		||||
        {
 | 
			
		||||
            return new Rectangle(_x, _y + verticalOffset, _width, _height - verticalOffset);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										305
									
								
								MigraDoc.Rendering/Rendering/BordersRenderer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										305
									
								
								MigraDoc.Rendering/Rendering/BordersRenderer.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,305 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Tables;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Renders a single Border.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class BordersRenderer
 | 
			
		||||
    {
 | 
			
		||||
        public BordersRenderer(Borders borders, XGraphics gfx)
 | 
			
		||||
        {
 | 
			
		||||
            Debug.Assert(borders.Document != null);
 | 
			
		||||
            _gfx = gfx;
 | 
			
		||||
            _borders = borders;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private Border GetBorder(BorderType type)
 | 
			
		||||
        {
 | 
			
		||||
            return _borders.GetBorderReadOnly(type);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private XColor GetColor(BorderType type)
 | 
			
		||||
        {
 | 
			
		||||
            Color clr = Colors.Black;
 | 
			
		||||
 | 
			
		||||
            Border border = GetBorder(type);
 | 
			
		||||
            if (border != null && !border.Color.IsEmpty)
 | 
			
		||||
                clr = border.Color;
 | 
			
		||||
            else if (!_borders.Color.IsEmpty)
 | 
			
		||||
                clr = _borders.Color;
 | 
			
		||||
 | 
			
		||||
#if noCMYK
 | 
			
		||||
      return XColor.FromArgb((int)clr.Argb);
 | 
			
		||||
#else
 | 
			
		||||
            //      bool cmyk = false; // BUG CMYK
 | 
			
		||||
            //      if (_borders.Document != null)
 | 
			
		||||
            //        cmyk = _borders.Document.UseCmykColor;
 | 
			
		||||
            //#if DEBUG
 | 
			
		||||
            //      else
 | 
			
		||||
            //        GetT ype();
 | 
			
		||||
            //#endif
 | 
			
		||||
            return ColorHelper.ToXColor(clr, _borders.Document.UseCmykColor);
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private BorderStyle GetStyle(BorderType type)
 | 
			
		||||
        {
 | 
			
		||||
            BorderStyle style = BorderStyle.Single;
 | 
			
		||||
 | 
			
		||||
            Border border = GetBorder(type);
 | 
			
		||||
            if (border != null && !border._style.IsNull)
 | 
			
		||||
                style = border.Style;
 | 
			
		||||
            else if (!_borders._style.IsNull)
 | 
			
		||||
                style = _borders.Style;
 | 
			
		||||
            return style;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public XUnit GetWidth(BorderType type)
 | 
			
		||||
        {
 | 
			
		||||
            if (_borders == null)
 | 
			
		||||
                return 0;
 | 
			
		||||
 | 
			
		||||
            Border border = GetBorder(type);
 | 
			
		||||
 | 
			
		||||
            if (border != null)
 | 
			
		||||
            {
 | 
			
		||||
                if (!border._visible.IsNull && !border.Visible)
 | 
			
		||||
                    return 0;
 | 
			
		||||
 | 
			
		||||
                if (!border._width.IsNull)
 | 
			
		||||
                    return border.Width.Point;
 | 
			
		||||
 | 
			
		||||
                if (!border._color.IsNull || !border._style.IsNull || border.Visible)
 | 
			
		||||
                {
 | 
			
		||||
                    if (!_borders._width.IsNull)
 | 
			
		||||
                        return _borders.Width.Point;
 | 
			
		||||
 | 
			
		||||
                    return 0.5;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else if (!(type == BorderType.DiagonalDown || type == BorderType.DiagonalUp))
 | 
			
		||||
            {
 | 
			
		||||
                if (!_borders._visible.IsNull && !_borders.Visible)
 | 
			
		||||
                    return 0;
 | 
			
		||||
 | 
			
		||||
                if (!_borders._width.IsNull)
 | 
			
		||||
                    return _borders.Width.Point;
 | 
			
		||||
 | 
			
		||||
                if (!_borders._color.IsNull || !_borders._style.IsNull || _borders.Visible)
 | 
			
		||||
                    return 0.5;
 | 
			
		||||
            }
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Renders the border top down.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="type">The type of the border.</param>
 | 
			
		||||
        /// <param name="left">The left position of the border.</param>
 | 
			
		||||
        /// <param name="top">The top position of the border.</param>
 | 
			
		||||
        /// <param name="height">The height on which to render the border.</param>
 | 
			
		||||
        public void RenderVertically(BorderType type, XUnit left, XUnit top, XUnit height)
 | 
			
		||||
        {
 | 
			
		||||
            XUnit borderWidth = GetWidth(type);
 | 
			
		||||
            if (borderWidth == 0)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            left += borderWidth / 2;
 | 
			
		||||
            _gfx.DrawLine(GetPen(type), left, top + height, left, top);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Renders the border top down.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="type">The type of the border.</param>
 | 
			
		||||
        /// <param name="left">The left position of the border.</param>
 | 
			
		||||
        /// <param name="top">The top position of the border.</param>
 | 
			
		||||
        /// <param name="width">The width on which to render the border.</param>
 | 
			
		||||
        public void RenderHorizontally(BorderType type, XUnit left, XUnit top, XUnit width)
 | 
			
		||||
        {
 | 
			
		||||
            XUnit borderWidth = GetWidth(type);
 | 
			
		||||
            if (borderWidth == 0)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            top += borderWidth / 2;
 | 
			
		||||
            _gfx.DrawLine(GetPen(type), left + width, top, left, top);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public void RenderDiagonally(BorderType type, XUnit left, XUnit top, XUnit width, XUnit height)
 | 
			
		||||
        {
 | 
			
		||||
            XUnit borderWidth = GetWidth(type);
 | 
			
		||||
            if (borderWidth == 0)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            XGraphicsState state = _gfx.Save();
 | 
			
		||||
            _gfx.IntersectClip(new XRect(left, top, width, height));
 | 
			
		||||
 | 
			
		||||
            if (type == BorderType.DiagonalDown)
 | 
			
		||||
                _gfx.DrawLine(GetPen(type), left, top, left + width, top + height);
 | 
			
		||||
            else if (type == BorderType.DiagonalUp)
 | 
			
		||||
                _gfx.DrawLine(GetPen(type), left, top + height, left + width, top);
 | 
			
		||||
 | 
			
		||||
            _gfx.Restore(state);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void RenderRounded(RoundedCorner roundedCorner, XUnit x, XUnit y, XUnit width, XUnit height)
 | 
			
		||||
        {
 | 
			
		||||
            if (roundedCorner == RoundedCorner.None)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            // As source we use the vertical borders.
 | 
			
		||||
            // If not set originally, they have been set to the horizontal border values in TableRenderer.EqualizeRoundedCornerBorders().
 | 
			
		||||
            BorderType borderType = BorderType.Top;
 | 
			
		||||
            if (roundedCorner == RoundedCorner.TopLeft || roundedCorner == RoundedCorner.BottomLeft)
 | 
			
		||||
                borderType = BorderType.Left;
 | 
			
		||||
            if (roundedCorner == RoundedCorner.TopRight || roundedCorner == RoundedCorner.BottomRight)
 | 
			
		||||
                borderType = BorderType.Right;
 | 
			
		||||
 | 
			
		||||
            XUnit borderWidth = GetWidth(borderType);
 | 
			
		||||
            XPen borderPen = GetPen(borderType);
 | 
			
		||||
 | 
			
		||||
            if (borderWidth == 0)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            x -= borderWidth / 2;
 | 
			
		||||
            y -= borderWidth / 2;
 | 
			
		||||
            XUnit ellipseWidth = width * 2 + borderWidth;
 | 
			
		||||
            XUnit ellipseHeight = height * 2 + borderWidth;
 | 
			
		||||
 | 
			
		||||
            switch (roundedCorner)
 | 
			
		||||
            {
 | 
			
		||||
                case RoundedCorner.TopLeft:
 | 
			
		||||
                    _gfx.DrawArc(borderPen, new XRect(x, y, ellipseWidth, ellipseHeight), 180, 90);
 | 
			
		||||
                    break;
 | 
			
		||||
                case RoundedCorner.TopRight:
 | 
			
		||||
                    _gfx.DrawArc(borderPen, new XRect(x - width, y, ellipseWidth, ellipseHeight), 270, 90);
 | 
			
		||||
                    break;
 | 
			
		||||
                case RoundedCorner.BottomRight:
 | 
			
		||||
                    _gfx.DrawArc(borderPen, new XRect(x - width, y - height, ellipseWidth, ellipseHeight), 0, 90);
 | 
			
		||||
                    break;
 | 
			
		||||
                case RoundedCorner.BottomLeft:
 | 
			
		||||
                    _gfx.DrawArc(borderPen, new XRect(x, y - height, ellipseWidth, ellipseHeight), 90, 90);
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private XPen GetPen(BorderType type)
 | 
			
		||||
        {
 | 
			
		||||
            XUnit borderWidth = GetWidth(type);
 | 
			
		||||
            if (borderWidth == 0)
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            XPen pen = new XPen(GetColor(type), borderWidth);
 | 
			
		||||
            BorderStyle style = GetStyle(type);
 | 
			
		||||
            switch (style)
 | 
			
		||||
            {
 | 
			
		||||
                case BorderStyle.DashDot:
 | 
			
		||||
                    pen.DashStyle = XDashStyle.DashDot;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case BorderStyle.DashDotDot:
 | 
			
		||||
                    pen.DashStyle = XDashStyle.DashDotDot;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case BorderStyle.DashLargeGap:
 | 
			
		||||
                    pen.DashPattern = new double[] { 3, 3 };
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case BorderStyle.DashSmallGap:
 | 
			
		||||
                    pen.DashPattern = new double[] { 5, 1 };
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case BorderStyle.Dot:
 | 
			
		||||
                    pen.DashStyle = XDashStyle.Dot;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case BorderStyle.Single:
 | 
			
		||||
                default:
 | 
			
		||||
                    pen.DashStyle = XDashStyle.Solid;
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            return pen;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool IsRendered(BorderType borderType)
 | 
			
		||||
        {
 | 
			
		||||
            if (_borders == null)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            switch (borderType)
 | 
			
		||||
            {
 | 
			
		||||
                case BorderType.Left:
 | 
			
		||||
                    if (_borders._left == null || _borders._left.IsNull())
 | 
			
		||||
                        return false;
 | 
			
		||||
                    return GetWidth(borderType) > 0;
 | 
			
		||||
 | 
			
		||||
                case BorderType.Right:
 | 
			
		||||
                    if (_borders._right == null || _borders._right.IsNull())
 | 
			
		||||
                        return false;
 | 
			
		||||
                    return GetWidth(borderType) > 0;
 | 
			
		||||
 | 
			
		||||
                case BorderType.Top:
 | 
			
		||||
                    if (_borders._top == null || _borders._top.IsNull())
 | 
			
		||||
                        return false;
 | 
			
		||||
                    return GetWidth(borderType) > 0;
 | 
			
		||||
 | 
			
		||||
                case BorderType.Bottom:
 | 
			
		||||
                    if (_borders._bottom == null || _borders._bottom.IsNull())
 | 
			
		||||
                        return false;
 | 
			
		||||
 | 
			
		||||
                    return GetWidth(borderType) > 0;
 | 
			
		||||
 | 
			
		||||
                case BorderType.DiagonalDown:
 | 
			
		||||
                    if (_borders._diagonalDown == null || _borders._diagonalDown.IsNull())
 | 
			
		||||
                        return false;
 | 
			
		||||
                    return GetWidth(borderType) > 0;
 | 
			
		||||
 | 
			
		||||
                case BorderType.DiagonalUp:
 | 
			
		||||
                    if (_borders._diagonalUp == null || _borders._diagonalUp.IsNull())
 | 
			
		||||
                        return false;
 | 
			
		||||
 | 
			
		||||
                    return GetWidth(borderType) > 0;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        readonly XGraphics _gfx;
 | 
			
		||||
        readonly Borders _borders;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										48
									
								
								MigraDoc.Rendering/Rendering/ChartFormatInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								MigraDoc.Rendering/Rendering/ChartFormatInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using PdfSharp.Charting;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Formatting information for a chart.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public sealed class ChartFormatInfo : ShapeFormatInfo
 | 
			
		||||
    {
 | 
			
		||||
        public ChartFrame ChartFrame;
 | 
			
		||||
        public FormattedTextArea FormattedHeader;
 | 
			
		||||
        public FormattedTextArea FormattedLeft;
 | 
			
		||||
        public FormattedTextArea FormattedTop;
 | 
			
		||||
        public FormattedTextArea FormattedBottom;
 | 
			
		||||
        public FormattedTextArea FormattedRight;
 | 
			
		||||
        public FormattedTextArea FormattedFooter;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										48
									
								
								MigraDoc.Rendering/Rendering/ChartRenderInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								MigraDoc.Rendering/Rendering/ChartRenderInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Rendering information for charts.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public sealed class ChartRenderInfo : ShapeRenderInfo
 | 
			
		||||
    {
 | 
			
		||||
        public ChartRenderInfo()
 | 
			
		||||
        { }
 | 
			
		||||
 | 
			
		||||
        public override FormatInfo FormatInfo
 | 
			
		||||
        {
 | 
			
		||||
            get { return _formatInfo ?? (_formatInfo = new ChartFormatInfo()); }
 | 
			
		||||
            set { _formatInfo = (ChartFormatInfo)value; }
 | 
			
		||||
        }
 | 
			
		||||
        ChartFormatInfo _formatInfo;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										368
									
								
								MigraDoc.Rendering/Rendering/ChartRenderer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										368
									
								
								MigraDoc.Rendering/Rendering/ChartRenderer.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,368 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using MigraDoc.DocumentObjectModel.publics;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Tables;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Shapes;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Shapes.Charts;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Renders a chart to an XGraphics object.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class ChartRenderer : ShapeRenderer
 | 
			
		||||
    {
 | 
			
		||||
        public ChartRenderer(XGraphics gfx, Chart chart, FieldInfos fieldInfos)
 | 
			
		||||
            : base(gfx, chart, fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _chart = chart;
 | 
			
		||||
            ChartRenderInfo renderInfo = new ChartRenderInfo();
 | 
			
		||||
            renderInfo.DocumentObject = _shape;
 | 
			
		||||
            _renderInfo = renderInfo;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ChartRenderer(XGraphics gfx, RenderInfo renderInfo, FieldInfos fieldInfos)
 | 
			
		||||
            : base(gfx, renderInfo, fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _chart = (Chart)renderInfo.DocumentObject;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        FormattedTextArea GetFormattedTextArea(TextArea area, XUnit width)
 | 
			
		||||
        {
 | 
			
		||||
            if (area == null)
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            FormattedTextArea formattedTextArea = new FormattedTextArea(_documentRenderer, area, _fieldInfos);
 | 
			
		||||
 | 
			
		||||
            if (!double.IsNaN(width))
 | 
			
		||||
                formattedTextArea.InnerWidth = width;
 | 
			
		||||
 | 
			
		||||
            formattedTextArea.Format(_gfx);
 | 
			
		||||
            return formattedTextArea;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        FormattedTextArea GetFormattedTextArea(TextArea area)
 | 
			
		||||
        {
 | 
			
		||||
            return GetFormattedTextArea(area, double.NaN);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void GetLeftRightVerticalPosition(out XUnit top, out XUnit bottom)
 | 
			
		||||
        {
 | 
			
		||||
            //REM: Line width is still ignored while layouting charts.
 | 
			
		||||
            Area contentArea = _renderInfo.LayoutInfo.ContentArea;
 | 
			
		||||
            ChartFormatInfo formatInfo = (ChartFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
            top = contentArea.Y;
 | 
			
		||||
 | 
			
		||||
            if (formatInfo.FormattedHeader != null)
 | 
			
		||||
                top += formatInfo.FormattedHeader.InnerHeight;
 | 
			
		||||
 | 
			
		||||
            bottom = contentArea.Y + contentArea.Height;
 | 
			
		||||
            if (formatInfo.FormattedFooter != null)
 | 
			
		||||
                bottom -= formatInfo.FormattedFooter.InnerHeight;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Rectangle GetLeftRect()
 | 
			
		||||
        {
 | 
			
		||||
            Area contentArea = _renderInfo.LayoutInfo.ContentArea;
 | 
			
		||||
            ChartFormatInfo formatInfo = (ChartFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
            XUnit top;
 | 
			
		||||
            XUnit bottom;
 | 
			
		||||
            GetLeftRightVerticalPosition(out top, out bottom);
 | 
			
		||||
 | 
			
		||||
            XUnit left = contentArea.X;
 | 
			
		||||
            XUnit width = formatInfo.FormattedLeft.InnerWidth;
 | 
			
		||||
 | 
			
		||||
            return new Rectangle(left, top, width, bottom - top);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Rectangle GetRightRect()
 | 
			
		||||
        {
 | 
			
		||||
            Area contentArea = _renderInfo.LayoutInfo.ContentArea;
 | 
			
		||||
            ChartFormatInfo formatInfo = (ChartFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
            XUnit top;
 | 
			
		||||
            XUnit bottom;
 | 
			
		||||
            GetLeftRightVerticalPosition(out top, out bottom);
 | 
			
		||||
 | 
			
		||||
            XUnit left = contentArea.X + contentArea.Width - formatInfo.FormattedRight.InnerWidth;
 | 
			
		||||
            XUnit width = formatInfo.FormattedRight.InnerWidth;
 | 
			
		||||
 | 
			
		||||
            return new Rectangle(left, top, width, bottom - top);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Rectangle GetHeaderRect()
 | 
			
		||||
        {
 | 
			
		||||
            Area contentArea = _renderInfo.LayoutInfo.ContentArea;
 | 
			
		||||
            ChartFormatInfo formatInfo = (ChartFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
 | 
			
		||||
            XUnit left = contentArea.X;
 | 
			
		||||
            XUnit top = contentArea.Y;
 | 
			
		||||
            XUnit width = contentArea.Width;
 | 
			
		||||
            XUnit height = formatInfo.FormattedHeader.InnerHeight;
 | 
			
		||||
 | 
			
		||||
            return new Rectangle(left, top, width, height);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Rectangle GetFooterRect()
 | 
			
		||||
        {
 | 
			
		||||
            Area contentArea = _renderInfo.LayoutInfo.ContentArea;
 | 
			
		||||
            ChartFormatInfo formatInfo = (ChartFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
 | 
			
		||||
            XUnit left = contentArea.X;
 | 
			
		||||
            XUnit top = contentArea.Y + contentArea.Height - formatInfo.FormattedFooter.InnerHeight;
 | 
			
		||||
            XUnit width = contentArea.Width;
 | 
			
		||||
            XUnit height = formatInfo.FormattedFooter.InnerHeight;
 | 
			
		||||
 | 
			
		||||
            return new Rectangle(left, top, width, height);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Rectangle GetTopRect()
 | 
			
		||||
        {
 | 
			
		||||
            Area contentArea = _renderInfo.LayoutInfo.ContentArea;
 | 
			
		||||
            ChartFormatInfo formatInfo = (ChartFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
 | 
			
		||||
            XUnit left;
 | 
			
		||||
            XUnit right;
 | 
			
		||||
            GetTopBottomHorizontalPosition(out left, out right);
 | 
			
		||||
 | 
			
		||||
            XUnit top = contentArea.Y;
 | 
			
		||||
            if (formatInfo.FormattedHeader != null)
 | 
			
		||||
                top += formatInfo.FormattedHeader.InnerHeight;
 | 
			
		||||
 | 
			
		||||
            XUnit height = formatInfo.FormattedTop.InnerHeight;
 | 
			
		||||
 | 
			
		||||
            return new Rectangle(left, top, right - left, height);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Rectangle GetBottomRect()
 | 
			
		||||
        {
 | 
			
		||||
            Area contentArea = _renderInfo.LayoutInfo.ContentArea;
 | 
			
		||||
            ChartFormatInfo formatInfo = (ChartFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
 | 
			
		||||
            XUnit left;
 | 
			
		||||
            XUnit right;
 | 
			
		||||
            GetTopBottomHorizontalPosition(out left, out right);
 | 
			
		||||
 | 
			
		||||
            XUnit top = contentArea.Y + contentArea.Height - formatInfo.FormattedBottom.InnerHeight;
 | 
			
		||||
            if (formatInfo.FormattedFooter != null)
 | 
			
		||||
                top -= formatInfo.FormattedFooter.InnerHeight;
 | 
			
		||||
 | 
			
		||||
            XUnit height = formatInfo.FormattedBottom.InnerHeight;
 | 
			
		||||
            return new Rectangle(left, top, right - left, height);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Rectangle GetPlotRect()
 | 
			
		||||
        {
 | 
			
		||||
            Area contentArea = _renderInfo.LayoutInfo.ContentArea;
 | 
			
		||||
            ChartFormatInfo formatInfo = (ChartFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
            XUnit top = contentArea.Y;
 | 
			
		||||
            if (formatInfo.FormattedHeader != null)
 | 
			
		||||
                top += formatInfo.FormattedHeader.InnerHeight;
 | 
			
		||||
 | 
			
		||||
            if (formatInfo.FormattedTop != null)
 | 
			
		||||
                top += formatInfo.FormattedTop.InnerHeight;
 | 
			
		||||
 | 
			
		||||
            XUnit bottom = contentArea.Y + contentArea.Height;
 | 
			
		||||
            if (formatInfo.FormattedFooter != null)
 | 
			
		||||
                bottom -= formatInfo.FormattedFooter.InnerHeight;
 | 
			
		||||
 | 
			
		||||
            if (formatInfo.FormattedBottom != null)
 | 
			
		||||
                bottom -= formatInfo.FormattedBottom.InnerHeight;
 | 
			
		||||
 | 
			
		||||
            XUnit left = contentArea.X;
 | 
			
		||||
            if (formatInfo.FormattedLeft != null)
 | 
			
		||||
                left += formatInfo.FormattedLeft.InnerWidth;
 | 
			
		||||
 | 
			
		||||
            XUnit right = contentArea.X + contentArea.Width;
 | 
			
		||||
            if (formatInfo.FormattedRight != null)
 | 
			
		||||
                right -= formatInfo.FormattedRight.InnerWidth;
 | 
			
		||||
 | 
			
		||||
            return new Rectangle(left, top, right - left, bottom - top);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void Format(Area area, FormatInfo previousFormatInfo)
 | 
			
		||||
        {
 | 
			
		||||
            ChartFormatInfo formatInfo = (ChartFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
 | 
			
		||||
            TextArea textArea = (TextArea)_chart.GetValue("HeaderArea", GV.ReadOnly);
 | 
			
		||||
            formatInfo.FormattedHeader = GetFormattedTextArea(textArea, _chart.Width.Point);
 | 
			
		||||
 | 
			
		||||
            textArea = (TextArea)_chart.GetValue("FooterArea", GV.ReadOnly);
 | 
			
		||||
            formatInfo.FormattedFooter = GetFormattedTextArea(textArea, _chart.Width.Point);
 | 
			
		||||
 | 
			
		||||
            textArea = (TextArea)_chart.GetValue("LeftArea", GV.ReadOnly);
 | 
			
		||||
            formatInfo.FormattedLeft = GetFormattedTextArea(textArea);
 | 
			
		||||
 | 
			
		||||
            textArea = (TextArea)_chart.GetValue("RightArea", GV.ReadOnly);
 | 
			
		||||
            formatInfo.FormattedRight = GetFormattedTextArea(textArea);
 | 
			
		||||
 | 
			
		||||
            textArea = (TextArea)_chart.GetValue("TopArea", GV.ReadOnly);
 | 
			
		||||
            formatInfo.FormattedTop = GetFormattedTextArea(textArea, GetTopBottomWidth());
 | 
			
		||||
 | 
			
		||||
            textArea = (TextArea)_chart.GetValue("BottomArea", GV.ReadOnly);
 | 
			
		||||
            formatInfo.FormattedBottom = GetFormattedTextArea(textArea, GetTopBottomWidth());
 | 
			
		||||
 | 
			
		||||
            base.Format(area, previousFormatInfo);
 | 
			
		||||
            formatInfo.ChartFrame = ChartMapper.ChartMapper.Map(_chart);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        XUnit AlignVertically(VerticalAlignment vAlign, XUnit top, XUnit bottom, XUnit height)
 | 
			
		||||
        {
 | 
			
		||||
            switch (vAlign)
 | 
			
		||||
            {
 | 
			
		||||
                case VerticalAlignment.Bottom:
 | 
			
		||||
                    return bottom - height;
 | 
			
		||||
 | 
			
		||||
                case VerticalAlignment.Center:
 | 
			
		||||
                    return (top + bottom - height) / 2;
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    return top;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the width of the top and bottom area.
 | 
			
		||||
        /// Used while formatting.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>The width of the top and bottom area</returns>
 | 
			
		||||
        private XUnit GetTopBottomWidth()
 | 
			
		||||
        {
 | 
			
		||||
            ChartFormatInfo formatInfo = (ChartFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
            XUnit width = _chart.Width.Point;
 | 
			
		||||
            if (formatInfo.FormattedRight != null)
 | 
			
		||||
                width -= formatInfo.FormattedRight.InnerWidth;
 | 
			
		||||
            if (formatInfo.FormattedLeft != null)
 | 
			
		||||
                width -= formatInfo.FormattedLeft.InnerWidth;
 | 
			
		||||
            return width;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the horizontal boundaries of the top and bottom area.
 | 
			
		||||
        /// Used while rendering.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="left">The left boundary of the top and bottom area</param>
 | 
			
		||||
        /// <param name="right">The right boundary of the top and bottom area</param>
 | 
			
		||||
        private void GetTopBottomHorizontalPosition(out XUnit left, out XUnit right)
 | 
			
		||||
        {
 | 
			
		||||
            Area contentArea = _renderInfo.LayoutInfo.ContentArea;
 | 
			
		||||
            ChartFormatInfo formatInfo = (ChartFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
            left = contentArea.X;
 | 
			
		||||
            right = contentArea.X + contentArea.Width;
 | 
			
		||||
 | 
			
		||||
            if (formatInfo.FormattedRight != null)
 | 
			
		||||
                right -= formatInfo.FormattedRight.InnerWidth;
 | 
			
		||||
            if (formatInfo.FormattedLeft != null)
 | 
			
		||||
                left += formatInfo.FormattedLeft.InnerWidth;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void RenderArea(FormattedTextArea area, Rectangle rect)
 | 
			
		||||
        {
 | 
			
		||||
            if (area == null)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            TextArea textArea = area.TextArea;
 | 
			
		||||
 | 
			
		||||
            FillFormatRenderer fillFormatRenderer = new FillFormatRenderer((FillFormat)textArea.GetValue("FillFormat", GV.ReadOnly), _gfx);
 | 
			
		||||
            fillFormatRenderer.Render(rect.X, rect.Y, rect.Width, rect.Height);
 | 
			
		||||
 | 
			
		||||
            XUnit top = rect.Y;
 | 
			
		||||
            top += textArea.TopPadding;
 | 
			
		||||
            XUnit bottom = rect.Y + rect.Height;
 | 
			
		||||
            bottom -= textArea.BottomPadding;
 | 
			
		||||
            top = AlignVertically(textArea.VerticalAlignment, top, bottom, area.ContentHeight);
 | 
			
		||||
 | 
			
		||||
            XUnit left = rect.X;
 | 
			
		||||
            left += textArea.LeftPadding;
 | 
			
		||||
 | 
			
		||||
            RenderInfo[] renderInfos = area.GetRenderInfos();
 | 
			
		||||
            RenderByInfos(left, top, renderInfos);
 | 
			
		||||
 | 
			
		||||
            LineFormatRenderer lineFormatRenderer = new LineFormatRenderer((LineFormat)textArea.GetValue("LineFormat", GV.ReadOnly), _gfx);
 | 
			
		||||
            lineFormatRenderer.Render(rect.X, rect.Y, rect.Width, rect.Height);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void Render()
 | 
			
		||||
        {
 | 
			
		||||
            RenderFilling();
 | 
			
		||||
            Area contentArea = _renderInfo.LayoutInfo.ContentArea;
 | 
			
		||||
 | 
			
		||||
            ChartFormatInfo formatInfo = (ChartFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
            if (formatInfo.FormattedHeader != null)
 | 
			
		||||
                RenderArea(formatInfo.FormattedHeader, GetHeaderRect());
 | 
			
		||||
 | 
			
		||||
            if (formatInfo.FormattedFooter != null)
 | 
			
		||||
                RenderArea(formatInfo.FormattedFooter, GetFooterRect());
 | 
			
		||||
 | 
			
		||||
            if (formatInfo.FormattedTop != null)
 | 
			
		||||
                RenderArea(formatInfo.FormattedTop, GetTopRect());
 | 
			
		||||
 | 
			
		||||
            if (formatInfo.FormattedBottom != null)
 | 
			
		||||
                RenderArea(formatInfo.FormattedBottom, GetBottomRect());
 | 
			
		||||
 | 
			
		||||
            if (formatInfo.FormattedLeft != null)
 | 
			
		||||
                RenderArea(formatInfo.FormattedLeft, GetLeftRect());
 | 
			
		||||
 | 
			
		||||
            if (formatInfo.FormattedRight != null)
 | 
			
		||||
                RenderArea(formatInfo.FormattedRight, GetRightRect());
 | 
			
		||||
 | 
			
		||||
            PlotArea plotArea = (PlotArea)_chart.GetValue("PlotArea", GV.ReadOnly);
 | 
			
		||||
            if (plotArea != null)
 | 
			
		||||
                RenderPlotArea(plotArea, GetPlotRect());
 | 
			
		||||
 | 
			
		||||
            RenderLine();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void RenderPlotArea(PlotArea area, Rectangle rect)
 | 
			
		||||
        {
 | 
			
		||||
            PdfSharp.Charting.ChartFrame chartFrame = ((ChartFormatInfo)_renderInfo.FormatInfo).ChartFrame;
 | 
			
		||||
 | 
			
		||||
            XUnit top = rect.Y;
 | 
			
		||||
            top += area.TopPadding;
 | 
			
		||||
 | 
			
		||||
            XUnit bottom = rect.Y + rect.Height;
 | 
			
		||||
            bottom -= area.BottomPadding;
 | 
			
		||||
 | 
			
		||||
            XUnit left = rect.X;
 | 
			
		||||
            left += area.LeftPadding;
 | 
			
		||||
 | 
			
		||||
            XUnit right = rect.X + rect.Width;
 | 
			
		||||
            right -= area.RightPadding;
 | 
			
		||||
 | 
			
		||||
            chartFrame.Location = new XPoint(left, top);
 | 
			
		||||
            chartFrame.Size = new XSize(right - left, bottom - top);
 | 
			
		||||
            chartFrame.DrawChart(_gfx);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        readonly Chart _chart;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										51
									
								
								MigraDoc.Rendering/Rendering/ColorHelper.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								MigraDoc.Rendering/Rendering/ColorHelper.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    static class ColorHelper
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Converts Color to XColor.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static XColor ToXColor(Color color, bool cmyk)
 | 
			
		||||
        {
 | 
			
		||||
            if (color.IsEmpty)
 | 
			
		||||
                return XColor.Empty;
 | 
			
		||||
 | 
			
		||||
            if (cmyk)
 | 
			
		||||
                return XColor.FromCmyk(color.Alpha / 100.0, color.C / 100.0, color.M / 100.0, color.Y / 100.0, color.K / 100.0);
 | 
			
		||||
            return XColor.FromArgb((int)color.Argb);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										405
									
								
								MigraDoc.Rendering/Rendering/DocumentRenderer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										405
									
								
								MigraDoc.Rendering/Rendering/DocumentRenderer.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,405 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
using PdfSharp.Pdf;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Visitors;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Shapes;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Tables;
 | 
			
		||||
using MigraDoc.Rendering.Resources;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Provides methods to render the document or single parts of it to a XGraphics object.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <remarks>
 | 
			
		||||
    /// One prepared instance of this class can serve to render several output formats.
 | 
			
		||||
    /// </remarks>
 | 
			
		||||
    public class DocumentRenderer
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the DocumentRenderer class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="document">The migradoc document to render.</param>
 | 
			
		||||
        public DocumentRenderer(Document document)
 | 
			
		||||
        {
 | 
			
		||||
            _document = document;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Prepares this instance for rendering.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void PrepareDocument()
 | 
			
		||||
        {
 | 
			
		||||
            PdfFlattenVisitor visitor = new PdfFlattenVisitor();
 | 
			
		||||
            visitor.Visit(_document);
 | 
			
		||||
            _previousListNumbers = new Dictionary<ListType, int>(3);
 | 
			
		||||
            _previousListNumbers[ListType.NumberList1] = 0;
 | 
			
		||||
            _previousListNumbers[ListType.NumberList2] = 0;
 | 
			
		||||
            _previousListNumbers[ListType.NumberList3] = 0;
 | 
			
		||||
            _formattedDocument = new FormattedDocument(_document, this);
 | 
			
		||||
            //REM: Size should not be necessary in this case.
 | 
			
		||||
#if true
 | 
			
		||||
            XGraphics gfx = XGraphics.CreateMeasureContext(new XSize(2000, 2000), XGraphicsUnit.Point, XPageDirection.Downwards);
 | 
			
		||||
#else
 | 
			
		||||
#if GDI
 | 
			
		||||
      XGraphics gfx = XGraphics.FromGraphics(Graphics.FromHwnd(IntPtr.Zero), new XSize(2000, 2000));
 | 
			
		||||
#endif
 | 
			
		||||
#if WPF
 | 
			
		||||
      XGraphics gfx = XGraphics.FromDrawingContext(null, new XSize(2000, 2000), XGraphicsUnit.Point);
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
            //      _previousListNumber = int.MinValue;
 | 
			
		||||
            //gfx.MUH = _unicode;
 | 
			
		||||
            //gfx.MFEH = _fontEmbedding;
 | 
			
		||||
 | 
			
		||||
            _previousListInfo = null;
 | 
			
		||||
            _formattedDocument.Format(gfx);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Occurs while the document is being prepared (can be used to show a progress bar).
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public event PrepareDocumentProgressEventHandler PrepareDocumentProgress;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Allows applications to display a progress indicator while PrepareDocument() is being executed.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="value"></param>
 | 
			
		||||
        /// <param name="maximum"></param>
 | 
			
		||||
        public virtual void OnPrepareDocumentProgress(int value, int maximum)
 | 
			
		||||
        {
 | 
			
		||||
            if (PrepareDocumentProgress != null)
 | 
			
		||||
            {
 | 
			
		||||
                // Invokes the delegates. 
 | 
			
		||||
                PrepareDocumentProgressEventArgs e = new PrepareDocumentProgressEventArgs(value, maximum);
 | 
			
		||||
                PrepareDocumentProgress(this, e);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets a value indicating whether this instance supports PrepareDocumentProgress.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool HasPrepareDocumentProgress
 | 
			
		||||
        {
 | 
			
		||||
            get { return PrepareDocumentProgress != null; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the formatted document of this instance.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public FormattedDocument FormattedDocument
 | 
			
		||||
        {
 | 
			
		||||
            get { return _formattedDocument; }
 | 
			
		||||
        }
 | 
			
		||||
        FormattedDocument _formattedDocument;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Renders a MigraDoc document to the specified graphics object.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void RenderPage(XGraphics gfx, int page)
 | 
			
		||||
        {
 | 
			
		||||
            RenderPage(gfx, page, PageRenderOptions.All);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <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>
 | 
			
		||||
        /// Gets the document objects that get rendered on the specified page.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public DocumentObject[] GetDocumentObjectsFromPage(int page)
 | 
			
		||||
        {
 | 
			
		||||
            RenderInfo[] renderInfos = _formattedDocument.GetRenderInfos(page);
 | 
			
		||||
            int count = renderInfos != null ? renderInfos.Length : 0;
 | 
			
		||||
            DocumentObject[] documentObjects = new DocumentObject[count];
 | 
			
		||||
            for (int idx = 0; idx < count; idx++)
 | 
			
		||||
                documentObjects[idx] = renderInfos[idx].DocumentObject;
 | 
			
		||||
            return documentObjects;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the render information for document objects that get rendered on the specified page.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public RenderInfo[] GetRenderInfoFromPage(int page)
 | 
			
		||||
        {
 | 
			
		||||
            return _formattedDocument.GetRenderInfos(page);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <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();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the working directory for rendering.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public string WorkingDirectory
 | 
			
		||||
        {
 | 
			
		||||
            get { return _workingDirectory; }
 | 
			
		||||
            set { _workingDirectory = value; }
 | 
			
		||||
        }
 | 
			
		||||
        string _workingDirectory;
 | 
			
		||||
 | 
			
		||||
        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
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void AddOutline(int level, string title, PdfPage destinationPage)
 | 
			
		||||
        {
 | 
			
		||||
            if (level < 1 || destinationPage == null)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            PdfDocument document = destinationPage.Owner;
 | 
			
		||||
 | 
			
		||||
            if (document == null)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            PdfOutlineCollection outlines = document.Outlines;
 | 
			
		||||
            while (--level > 0)
 | 
			
		||||
            {
 | 
			
		||||
                int count = outlines.Count;
 | 
			
		||||
                if (count == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    // You cannot add empty bookmarks to PDF. So we use blank here.
 | 
			
		||||
                    PdfOutline outline = outlines.Add(" ", destinationPage, true);
 | 
			
		||||
                    outlines = outline.Outlines;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    outlines = outlines[count - 1].Outlines;
 | 
			
		||||
            }
 | 
			
		||||
            outlines.Add(title, destinationPage, true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int NextListNumber(ListInfo listInfo)
 | 
			
		||||
        {
 | 
			
		||||
            ListType listType = listInfo.ListType;
 | 
			
		||||
            bool isNumberList = listType == ListType.NumberList1 ||
 | 
			
		||||
              listType == ListType.NumberList2 ||
 | 
			
		||||
              listType == ListType.NumberList3;
 | 
			
		||||
 | 
			
		||||
            int listNumber = int.MinValue;
 | 
			
		||||
            if (listInfo == _previousListInfo)
 | 
			
		||||
            {
 | 
			
		||||
                if (isNumberList)
 | 
			
		||||
                    return _previousListNumbers[listType];
 | 
			
		||||
                return listNumber;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //bool listTypeChanged = _previousListInfo == null || _previousListInfo.ListType != listType;
 | 
			
		||||
 | 
			
		||||
            if (isNumberList)
 | 
			
		||||
            {
 | 
			
		||||
                listNumber = 1;
 | 
			
		||||
                if (/*!listTypeChanged &&*/ (listInfo._continuePreviousList.IsNull || listInfo.ContinuePreviousList))
 | 
			
		||||
                    listNumber = _previousListNumbers[listType] + 1;
 | 
			
		||||
 | 
			
		||||
                _previousListNumbers[listType] = listNumber;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _previousListInfo = listInfo;
 | 
			
		||||
            return listNumber;
 | 
			
		||||
        }
 | 
			
		||||
        ListInfo _previousListInfo;
 | 
			
		||||
        Dictionary<ListType, int> _previousListNumbers;
 | 
			
		||||
        private readonly Document _document;
 | 
			
		||||
        public DateTime _printDate = DateTime.MinValue;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Arguments for the PrepareDocumentProgressEvent which is called while a document is being prepared (you can use this to display a progress bar).
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public class PrepareDocumentProgressEventArgs : EventArgs
 | 
			
		||||
        {
 | 
			
		||||
            /// <summary>
 | 
			
		||||
            /// Indicates the current step reached in document preparation.
 | 
			
		||||
            /// </summary>
 | 
			
		||||
            public int Value;
 | 
			
		||||
            /// <summary>
 | 
			
		||||
            /// Indicates the final step in document preparation. The quitient of Value and Maximum can be used to calculate a percentage (e. g. for use in a progress bar).
 | 
			
		||||
            /// </summary>
 | 
			
		||||
            public int Maximum;
 | 
			
		||||
 | 
			
		||||
            /// <summary>
 | 
			
		||||
            /// Initializes a new instance of the <see cref="PrepareDocumentProgressEventArgs"/> class.
 | 
			
		||||
            /// </summary>
 | 
			
		||||
            /// <param name="value">The current step in document preparation.</param>
 | 
			
		||||
            /// <param name="maximum">The latest step in document preparation.</param>
 | 
			
		||||
            public PrepareDocumentProgressEventArgs(int value, int maximum)
 | 
			
		||||
            {
 | 
			
		||||
                Value = value;
 | 
			
		||||
                Maximum = maximum;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The event handler that is being called for the PrepareDocumentProgressEvent event.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public delegate void PrepareDocumentProgressEventHandler(object sender, PrepareDocumentProgressEventArgs e);
 | 
			
		||||
 | 
			
		||||
        public int ProgressMaximum;
 | 
			
		||||
        public int ProgressCompleted;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										98
									
								
								MigraDoc.Rendering/Rendering/FieldInfos.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								MigraDoc.Rendering/Rendering/FieldInfos.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Field information used to fill fields when rendering or formatting.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class FieldInfos
 | 
			
		||||
    {
 | 
			
		||||
        public FieldInfos(Dictionary<string, BookmarkInfo> bookmarks)
 | 
			
		||||
        {
 | 
			
		||||
            _bookmarks = bookmarks;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void AddBookmark(string name)
 | 
			
		||||
        {
 | 
			
		||||
            if (PhysicalPageNr <= 0)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            if (_bookmarks.ContainsKey(name))
 | 
			
		||||
                _bookmarks.Remove(name);
 | 
			
		||||
 | 
			
		||||
            if (PhysicalPageNr > 0)
 | 
			
		||||
                _bookmarks.Add(name, new BookmarkInfo(PhysicalPageNr, DisplayPageNr));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int GetShownPageNumber(string bookmarkName)
 | 
			
		||||
        {
 | 
			
		||||
            if (_bookmarks.ContainsKey(bookmarkName))
 | 
			
		||||
            {
 | 
			
		||||
                BookmarkInfo bi = _bookmarks[bookmarkName];
 | 
			
		||||
                return bi.ShownPageNumber;
 | 
			
		||||
            }
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int GetPhysicalPageNumber(string bookmarkName)
 | 
			
		||||
        {
 | 
			
		||||
            if (_bookmarks.ContainsKey(bookmarkName))
 | 
			
		||||
            {
 | 
			
		||||
                BookmarkInfo bi = _bookmarks[bookmarkName];
 | 
			
		||||
                return bi.DisplayPageNumber;
 | 
			
		||||
            }
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public struct BookmarkInfo
 | 
			
		||||
        {
 | 
			
		||||
            public BookmarkInfo(int physicalPageNumber, int displayPageNumber)
 | 
			
		||||
            {
 | 
			
		||||
                DisplayPageNumber = physicalPageNumber;
 | 
			
		||||
                ShownPageNumber = displayPageNumber;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public readonly int DisplayPageNumber;
 | 
			
		||||
            public readonly int ShownPageNumber;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        readonly Dictionary<string, BookmarkInfo> _bookmarks;
 | 
			
		||||
        public int DisplayPageNr;
 | 
			
		||||
        public int PhysicalPageNr;
 | 
			
		||||
        public int Section;
 | 
			
		||||
        public int SectionPages;
 | 
			
		||||
        public int NumPages;
 | 
			
		||||
        public DateTime Date;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										79
									
								
								MigraDoc.Rendering/Rendering/FillFormatRenderer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								MigraDoc.Rendering/Rendering/FillFormatRenderer.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Shapes;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Renders fill formats.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class FillFormatRenderer
 | 
			
		||||
    {
 | 
			
		||||
        public FillFormatRenderer(FillFormat fillFormat, XGraphics gfx)
 | 
			
		||||
        {
 | 
			
		||||
            _gfx = gfx;
 | 
			
		||||
            _fillFormat = fillFormat;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Render(XUnit x, XUnit y, XUnit width, XUnit height)
 | 
			
		||||
        {
 | 
			
		||||
            XBrush brush = GetBrush();
 | 
			
		||||
 | 
			
		||||
            if (brush == null)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            _gfx.DrawRectangle(brush, x.Point, y.Point, width.Point, height.Point);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private bool IsVisible()
 | 
			
		||||
        {
 | 
			
		||||
            if (!_fillFormat._visible.IsNull)
 | 
			
		||||
                return _fillFormat.Visible;
 | 
			
		||||
            return !_fillFormat._color.IsNull;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private XBrush GetBrush()
 | 
			
		||||
        {
 | 
			
		||||
            if (_fillFormat == null || !IsVisible())
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
#if noCMYK
 | 
			
		||||
      return new XSolidBrush(XColor.FromArgb(_fillFormat.Color.Argb));
 | 
			
		||||
#else
 | 
			
		||||
            return new XSolidBrush(ColorHelper.ToXColor(_fillFormat.Color, _fillFormat.Document.UseCmykColor));
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        readonly XGraphics _gfx;
 | 
			
		||||
        readonly FillFormat _fillFormat;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										141
									
								
								MigraDoc.Rendering/Rendering/FontHandler.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								MigraDoc.Rendering/Rendering/FontHandler.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,141 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
#define CACHE_FONTS_
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using PdfSharp.Pdf;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Helps measuring and handling fonts.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class FontHandler
 | 
			
		||||
    {
 | 
			
		||||
#if DEBUG
 | 
			
		||||
        public static int CreateFontCounter;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Converts a DOM Font to an XFont.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static XFont FontToXFont(Font font, PdfFontEncoding encoding)
 | 
			
		||||
        {
 | 
			
		||||
            XPdfFontOptions options = new XPdfFontOptions(encoding);
 | 
			
		||||
            XFontStyle style = GetXStyle(font);
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
            if (StringComparer.OrdinalIgnoreCase.Compare(font.Name, "Segoe UI Semilight") == 0
 | 
			
		||||
                && (style & XFontStyle.BoldItalic) == XFontStyle.Italic)
 | 
			
		||||
                font.GetType();
 | 
			
		||||
#endif
 | 
			
		||||
            XFont xFont = new XFont(font.Name, font.Size, style, options);
 | 
			
		||||
#if DEBUG
 | 
			
		||||
            CreateFontCounter++;
 | 
			
		||||
#endif
 | 
			
		||||
            return xFont;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static XFontStyle GetXStyle(Font font)
 | 
			
		||||
        {
 | 
			
		||||
            XFontStyle style = XFontStyle.Regular;
 | 
			
		||||
            if (font.Bold)
 | 
			
		||||
                style = font.Italic ? XFontStyle.BoldItalic : XFontStyle.Bold;
 | 
			
		||||
            else if (font.Italic)
 | 
			
		||||
                style = XFontStyle.Italic;
 | 
			
		||||
 | 
			
		||||
            return style;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static XUnit GetDescent(XFont font)
 | 
			
		||||
        {
 | 
			
		||||
            XUnit descent = font.Metrics.Descent;
 | 
			
		||||
            descent *= font.Size;
 | 
			
		||||
            descent /= font.FontFamily.GetEmHeight(font.Style);
 | 
			
		||||
            return descent;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static XUnit GetAscent(XFont font)
 | 
			
		||||
        {
 | 
			
		||||
            XUnit ascent = font.Metrics.Ascent;
 | 
			
		||||
            ascent *= font.Size;
 | 
			
		||||
            ascent /= font.FontFamily.GetEmHeight(font.Style);
 | 
			
		||||
            return ascent;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static double GetSubSuperScaling(XFont font)
 | 
			
		||||
        {
 | 
			
		||||
            return 0.8 * GetAscent(font) / font.GetHeight();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static XFont ToSubSuperFont(XFont font)
 | 
			
		||||
        {
 | 
			
		||||
            double size = font.Size * GetSubSuperScaling(font);
 | 
			
		||||
 | 
			
		||||
            return new XFont(font.Name, size, font.Style, font.PdfOptions);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static XBrush FontColorToXBrush(Font font)
 | 
			
		||||
        {
 | 
			
		||||
#if noCMYK
 | 
			
		||||
            return new XSolidBrush(XColor.FromArgb((int)font.Color.A, (int)font.Color.R, (int)font.Color.G, (int)font.Color.B));
 | 
			
		||||
#else
 | 
			
		||||
            return new XSolidBrush(ColorHelper.ToXColor(font.Color, font.Document.UseCmykColor));
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#if CACHE_FONTS
 | 
			
		||||
    static XFont XFontFromCache(Font font, bool unicode, PdfFontEmbedding fontEmbedding)
 | 
			
		||||
    {
 | 
			
		||||
      XFont xFont = null;
 | 
			
		||||
 | 
			
		||||
      XPdfFontOptions options = null;
 | 
			
		||||
      options = new XPdfFontOptions(fontEmbedding, unicode);
 | 
			
		||||
      XFontStyle style = GetXStyle(font);
 | 
			
		||||
      xFont = new XFont(font.Name, font.Size, style, options);
 | 
			
		||||
 | 
			
		||||
      return xFont;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static string BuildSignature(Font font, bool unicode, PdfFontEmbedding fontEmbedding)
 | 
			
		||||
    {
 | 
			
		||||
      StringBuilder signature = new StringBuilder(128);
 | 
			
		||||
      signature.Append(font.Name.ToLower());
 | 
			
		||||
      signature.Append(font.Size.Point.ToString("##0.0"));
 | 
			
		||||
      return signature.ToString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static Hash_table fontCache = new Hash_table();
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										83
									
								
								MigraDoc.Rendering/Rendering/FormatInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								MigraDoc.Rendering/Rendering/FormatInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Abstract base class for formatting information received by calling Format() on a renderer.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public abstract class FormatInfo
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Indicates that the formatted object is starting.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public abstract bool IsStarting
 | 
			
		||||
        {
 | 
			
		||||
            get;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Indicates that the formatted object is ending.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public abstract bool IsEnding
 | 
			
		||||
        {
 | 
			
		||||
            get;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Indicates that the formatted object is complete.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public abstract bool IsComplete
 | 
			
		||||
        {
 | 
			
		||||
            get;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Indicates that the starting of the element is completed
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public abstract bool StartingIsComplete
 | 
			
		||||
        {
 | 
			
		||||
            get;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Indicates that the ending of the element is completed
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public abstract bool EndingIsComplete
 | 
			
		||||
        {
 | 
			
		||||
            get;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public abstract bool IsEmpty
 | 
			
		||||
        {
 | 
			
		||||
            get;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										201
									
								
								MigraDoc.Rendering/Rendering/FormattedCell.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								MigraDoc.Rendering/Rendering/FormattedCell.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Tables;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Represents a formatted cell.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class FormattedCell : IAreaProvider
 | 
			
		||||
    {
 | 
			
		||||
        public FormattedCell(Cell cell, DocumentRenderer documentRenderer, Borders cellBorders, FieldInfos fieldInfos, XUnit xOffset, XUnit yOffset)
 | 
			
		||||
        {
 | 
			
		||||
            _cell = cell;
 | 
			
		||||
            _fieldInfos = fieldInfos;
 | 
			
		||||
            _yOffset = yOffset;
 | 
			
		||||
            _xOffset = xOffset;
 | 
			
		||||
            _bordersRenderer = new BordersRenderer(cellBorders, null);
 | 
			
		||||
            _documentRenderer = documentRenderer;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Area IAreaProvider.GetNextArea()
 | 
			
		||||
        {
 | 
			
		||||
            if (_isFirstArea)
 | 
			
		||||
            {
 | 
			
		||||
                Rectangle rect = CalcContentRect();
 | 
			
		||||
                _isFirstArea = false;
 | 
			
		||||
                return rect;
 | 
			
		||||
            }
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        bool _isFirstArea = true;
 | 
			
		||||
 | 
			
		||||
        Area IAreaProvider.ProbeNextArea()
 | 
			
		||||
        {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Format(XGraphics gfx)
 | 
			
		||||
        {
 | 
			
		||||
            _gfx = gfx;
 | 
			
		||||
            _formatter = new TopDownFormatter(this, _documentRenderer, _cell.Elements);
 | 
			
		||||
            _formatter.FormatOnAreas(gfx, false);
 | 
			
		||||
            _contentHeight = CalcContentHeight(_documentRenderer);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private Rectangle CalcContentRect()
 | 
			
		||||
        {
 | 
			
		||||
            Column column = _cell.Column;
 | 
			
		||||
            XUnit width = InnerWidth;
 | 
			
		||||
            width -= column.LeftPadding.Point;
 | 
			
		||||
            Column rightColumn = _cell.Table.Columns[column.Index + _cell.MergeRight];
 | 
			
		||||
            width -= rightColumn.RightPadding.Point;
 | 
			
		||||
 | 
			
		||||
            XUnit height = double.MaxValue;
 | 
			
		||||
            return new Rectangle(_xOffset, _yOffset, width, height);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public XUnit ContentHeight
 | 
			
		||||
        {
 | 
			
		||||
            get { return _contentHeight; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public XUnit InnerHeight
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                Row row = _cell.Row;
 | 
			
		||||
                XUnit verticalPadding = row.TopPadding.Point;
 | 
			
		||||
                verticalPadding += row.BottomPadding.Point;
 | 
			
		||||
 | 
			
		||||
                switch (row.HeightRule)
 | 
			
		||||
                {
 | 
			
		||||
                    case RowHeightRule.Exactly:
 | 
			
		||||
                        return row.Height.Point;
 | 
			
		||||
 | 
			
		||||
                    case RowHeightRule.Auto:
 | 
			
		||||
                        return verticalPadding + _contentHeight;
 | 
			
		||||
 | 
			
		||||
                    case RowHeightRule.AtLeast:
 | 
			
		||||
                    default:
 | 
			
		||||
                        return Math.Max(row.Height, verticalPadding + _contentHeight);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public XUnit InnerWidth
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                XUnit width = 0;
 | 
			
		||||
                int cellColumnIdx = _cell.Column.Index;
 | 
			
		||||
                for (int toRight = 0; toRight <= _cell.MergeRight; ++toRight)
 | 
			
		||||
                {
 | 
			
		||||
                    int columnIdx = cellColumnIdx + toRight;
 | 
			
		||||
                    width += _cell.Table.Columns[columnIdx].Width;
 | 
			
		||||
                }
 | 
			
		||||
                width -= _bordersRenderer.GetWidth(BorderType.Right);
 | 
			
		||||
 | 
			
		||||
                return width;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        FieldInfos IAreaProvider.AreaFieldInfos
 | 
			
		||||
        {
 | 
			
		||||
            get { return _fieldInfos; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void IAreaProvider.StoreRenderInfos(List<RenderInfo> renderInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _renderInfos = renderInfos;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool IAreaProvider.IsAreaBreakBefore(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool IAreaProvider.PositionVertically(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool IAreaProvider.PositionHorizontally(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private XUnit CalcContentHeight(DocumentRenderer documentRenderer)
 | 
			
		||||
        {
 | 
			
		||||
            XUnit height = RenderInfo.GetTotalHeight(GetRenderInfos());
 | 
			
		||||
            if (height == 0)
 | 
			
		||||
            {
 | 
			
		||||
                height = ParagraphRenderer.GetLineHeight(_cell.Format, _gfx, documentRenderer);
 | 
			
		||||
                height += _cell.Format.SpaceBefore;
 | 
			
		||||
                height += _cell.Format.SpaceAfter;
 | 
			
		||||
            }
 | 
			
		||||
            return height;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        XUnit _contentHeight = 0;
 | 
			
		||||
 | 
			
		||||
        public RenderInfo[] GetRenderInfos()
 | 
			
		||||
        {
 | 
			
		||||
            if (_renderInfos != null)
 | 
			
		||||
                return _renderInfos.ToArray();
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        readonly FieldInfos _fieldInfos;
 | 
			
		||||
        List<RenderInfo> _renderInfos;
 | 
			
		||||
        readonly XUnit _xOffset;
 | 
			
		||||
        readonly XUnit _yOffset;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the cell the formatting information refers to.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public Cell Cell
 | 
			
		||||
        {
 | 
			
		||||
            get { return _cell;}
 | 
			
		||||
        }
 | 
			
		||||
        readonly Cell _cell;
 | 
			
		||||
        TopDownFormatter _formatter;
 | 
			
		||||
        readonly BordersRenderer _bordersRenderer;
 | 
			
		||||
        XGraphics _gfx;
 | 
			
		||||
        readonly DocumentRenderer _documentRenderer;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										725
									
								
								MigraDoc.Rendering/Rendering/FormattedDocument.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										725
									
								
								MigraDoc.Rendering/Rendering/FormattedDocument.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,725 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Globalization;
 | 
			
		||||
using PdfSharp;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.publics;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Represents a formatted document.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class FormattedDocument : IAreaProvider
 | 
			
		||||
    {
 | 
			
		||||
        enum PagePosition
 | 
			
		||||
        {
 | 
			
		||||
            First,
 | 
			
		||||
            Odd,
 | 
			
		||||
            Even
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private struct HeaderFooterPosition
 | 
			
		||||
        {
 | 
			
		||||
            public HeaderFooterPosition(int sectionNr, PagePosition pagePosition)
 | 
			
		||||
            {
 | 
			
		||||
                _sectionNr = sectionNr;
 | 
			
		||||
                _pagePosition = pagePosition;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public override bool Equals(object obj)
 | 
			
		||||
            {
 | 
			
		||||
                if (obj is HeaderFooterPosition)
 | 
			
		||||
                {
 | 
			
		||||
                    HeaderFooterPosition hfp = (HeaderFooterPosition)obj;
 | 
			
		||||
                    return _sectionNr == hfp._sectionNr && _pagePosition == hfp._pagePosition;
 | 
			
		||||
                }
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public override int GetHashCode()
 | 
			
		||||
            {
 | 
			
		||||
                return _sectionNr.GetHashCode() ^ _pagePosition.GetHashCode();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            readonly int _sectionNr;
 | 
			
		||||
            readonly PagePosition _pagePosition;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public FormattedDocument(Document document, DocumentRenderer documentRenderer)
 | 
			
		||||
        {
 | 
			
		||||
            _document = document;
 | 
			
		||||
            _documentRenderer = documentRenderer;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Formats the document by performing line breaks and page breaks.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void Format(XGraphics gfx)
 | 
			
		||||
        {
 | 
			
		||||
            _bookmarks = new Dictionary<string, FieldInfos.BookmarkInfo>();
 | 
			
		||||
            _pageRenderInfos = new Dictionary<int, List<RenderInfo>>();
 | 
			
		||||
            _pageInfos = new Dictionary<int, PageInfo>();
 | 
			
		||||
            _pageFieldInfos = new Dictionary<int, FieldInfos>();
 | 
			
		||||
            _formattedHeaders = new Dictionary<HeaderFooterPosition, FormattedHeaderFooter>();
 | 
			
		||||
            _formattedFooters = new Dictionary<HeaderFooterPosition, FormattedHeaderFooter>();
 | 
			
		||||
            _gfx = gfx;
 | 
			
		||||
            _currentPage = 0;
 | 
			
		||||
            _sectionNumber = 0;
 | 
			
		||||
            _pageCount = 0;
 | 
			
		||||
            _shownPageNumber = 0;
 | 
			
		||||
            _documentRenderer.ProgressCompleted = 0;
 | 
			
		||||
            _documentRenderer.ProgressMaximum = 0;
 | 
			
		||||
            if (_documentRenderer.HasPrepareDocumentProgress)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (Section section in _document.Sections)
 | 
			
		||||
                    _documentRenderer.ProgressMaximum += section.Elements.Count;
 | 
			
		||||
            }
 | 
			
		||||
            foreach (Section section in _document.Sections)
 | 
			
		||||
            {
 | 
			
		||||
                _isNewSection = true;
 | 
			
		||||
                _currentSection = section;
 | 
			
		||||
                ++_sectionNumber;
 | 
			
		||||
                if (NeedsEmptyPage())
 | 
			
		||||
                    InsertEmptyPage();
 | 
			
		||||
 | 
			
		||||
                TopDownFormatter formatter = new TopDownFormatter(this, _documentRenderer, section.Elements);
 | 
			
		||||
                formatter.FormatOnAreas(gfx, true);
 | 
			
		||||
                FillSectionPagesInfo();
 | 
			
		||||
                _documentRenderer.ProgressCompleted += section.Elements.Count;
 | 
			
		||||
            }
 | 
			
		||||
            _pageCount = _currentPage;
 | 
			
		||||
            FillNumPagesInfo();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        PagePosition CurrentPagePosition
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                if (_isNewSection)
 | 
			
		||||
                    return PagePosition.First;
 | 
			
		||||
                // Choose header and footer based on the shown page number, not the physical page number.
 | 
			
		||||
                if (_shownPageNumber % 2 == 0)
 | 
			
		||||
                    return PagePosition.Even;
 | 
			
		||||
                return PagePosition.Odd;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void FormatHeadersFooters()
 | 
			
		||||
        {
 | 
			
		||||
            HeadersFooters headers = (HeadersFooters)_currentSection.GetValue("Headers", GV.ReadOnly);
 | 
			
		||||
            if (headers != null)
 | 
			
		||||
            {
 | 
			
		||||
                PagePosition pagePos = CurrentPagePosition;
 | 
			
		||||
                HeaderFooterPosition hfp = new HeaderFooterPosition(_sectionNumber, pagePos);
 | 
			
		||||
                if (!_formattedHeaders.ContainsKey(hfp))
 | 
			
		||||
                    FormatHeader(hfp, ChooseHeaderFooter(headers, pagePos));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            HeadersFooters footers = (HeadersFooters)_currentSection.GetValue("Footers", GV.ReadOnly);
 | 
			
		||||
            if (footers != null)
 | 
			
		||||
            {
 | 
			
		||||
                PagePosition pagePos = CurrentPagePosition;
 | 
			
		||||
                HeaderFooterPosition hfp = new HeaderFooterPosition(_sectionNumber, pagePos);
 | 
			
		||||
                if (!_formattedFooters.ContainsKey(hfp))
 | 
			
		||||
                    FormatFooter(hfp, ChooseHeaderFooter(footers, pagePos));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        void FormatHeader(HeaderFooterPosition hfp, HeaderFooter header)
 | 
			
		||||
        {
 | 
			
		||||
            if (header != null && !_formattedHeaders.ContainsKey(hfp))
 | 
			
		||||
            {
 | 
			
		||||
                FormattedHeaderFooter formattedHeaderFooter = new FormattedHeaderFooter(header, _documentRenderer, _currentFieldInfos);
 | 
			
		||||
                formattedHeaderFooter.ContentRect = GetHeaderArea(_currentSection, _currentPage);
 | 
			
		||||
                formattedHeaderFooter.Format(_gfx);
 | 
			
		||||
                _formattedHeaders.Add(hfp, formattedHeaderFooter);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        void FormatFooter(HeaderFooterPosition hfp, HeaderFooter footer)
 | 
			
		||||
        {
 | 
			
		||||
            if (footer != null && !_formattedFooters.ContainsKey(hfp))
 | 
			
		||||
            {
 | 
			
		||||
                FormattedHeaderFooter formattedHeaderFooter = new FormattedHeaderFooter(footer, _documentRenderer, _currentFieldInfos);
 | 
			
		||||
                formattedHeaderFooter.ContentRect = GetFooterArea(_currentSection, _currentPage);
 | 
			
		||||
                formattedHeaderFooter.Format(_gfx);
 | 
			
		||||
                _formattedFooters.Add(hfp, formattedHeaderFooter);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Fills the number pages information after formatting the document.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        void FillNumPagesInfo()
 | 
			
		||||
        {
 | 
			
		||||
            for (int page = 1; page <= _pageCount; ++page)
 | 
			
		||||
            {
 | 
			
		||||
                if (IsEmptyPage(page))
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                FieldInfos fieldInfos = _pageFieldInfos[page];
 | 
			
		||||
                fieldInfos.NumPages = _pageCount;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Fills the section pages information after formatting a section.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        void FillSectionPagesInfo()
 | 
			
		||||
        {
 | 
			
		||||
            for (int page = _currentPage; page > 0; --page)
 | 
			
		||||
            {
 | 
			
		||||
                if (IsEmptyPage(page))
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                FieldInfos fieldInfos = _pageFieldInfos[page];
 | 
			
		||||
                if (fieldInfos.Section != _sectionNumber)
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                fieldInfos.SectionPages = _sectionPages;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Rectangle CalcContentRect(int page)
 | 
			
		||||
        {
 | 
			
		||||
            PageSetup pageSetup = _currentSection.PageSetup;
 | 
			
		||||
            XUnit width = pageSetup.EffectivePageWidth.Point;
 | 
			
		||||
 | 
			
		||||
            width -= pageSetup.RightMargin.Point;
 | 
			
		||||
            width -= pageSetup.LeftMargin.Point;
 | 
			
		||||
 | 
			
		||||
            XUnit height = pageSetup.EffectivePageHeight.Point;
 | 
			
		||||
 | 
			
		||||
            height -= pageSetup.TopMargin.Point;
 | 
			
		||||
            height -= pageSetup.BottomMargin.Point;
 | 
			
		||||
            XUnit x;
 | 
			
		||||
            XUnit y = pageSetup.TopMargin.Point;
 | 
			
		||||
            if (pageSetup.MirrorMargins)
 | 
			
		||||
                x = page % 2 == 0 ? pageSetup.RightMargin.Point : pageSetup.LeftMargin.Point;
 | 
			
		||||
            else
 | 
			
		||||
                x = pageSetup.LeftMargin.Point;
 | 
			
		||||
            return new Rectangle(x, y, width, height);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the rendering informations for the page content.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="page">The page to render.</param>
 | 
			
		||||
        /// <returns>Rendering information for the page content.</returns>
 | 
			
		||||
        public RenderInfo[] GetRenderInfos(int page)
 | 
			
		||||
        {
 | 
			
		||||
            if (_pageRenderInfos.ContainsKey(page))
 | 
			
		||||
                return (_pageRenderInfos[page]).ToArray();
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        private Dictionary<int, List<RenderInfo>> _pageRenderInfos;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets a formatted headerfooter object for header of the given page.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="page">The physical page the header shall appear on.</param>
 | 
			
		||||
        /// <returns>The required header, null if none exists to render.</returns>
 | 
			
		||||
        public FormattedHeaderFooter GetFormattedHeader(int page)
 | 
			
		||||
        {
 | 
			
		||||
            FieldInfos fieldInfos = _pageFieldInfos[page];
 | 
			
		||||
            int logicalPage = fieldInfos.DisplayPageNr;
 | 
			
		||||
 | 
			
		||||
            PagePosition pagePos = logicalPage % 2 == 0 ? PagePosition.Even : PagePosition.Odd;
 | 
			
		||||
 | 
			
		||||
            if (page == 1)
 | 
			
		||||
                pagePos = PagePosition.First;
 | 
			
		||||
            else //page > 1
 | 
			
		||||
            {
 | 
			
		||||
                if (IsEmptyPage(page - 1)) // these empty pages only occur between sections.
 | 
			
		||||
                    pagePos = PagePosition.First;
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    FieldInfos prevFieldInfos = _pageFieldInfos[page - 1];
 | 
			
		||||
                    if (fieldInfos.Section != prevFieldInfos.Section)
 | 
			
		||||
                        pagePos = PagePosition.First;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            HeaderFooterPosition hfp = new HeaderFooterPosition(fieldInfos.Section, pagePos);
 | 
			
		||||
            if (_formattedHeaders.ContainsKey(hfp))
 | 
			
		||||
                return _formattedHeaders[hfp];
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets a formatted headerfooter object for footer of the given page.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="page">The physical page the footer shall appear on.</param>
 | 
			
		||||
        /// <returns>The required footer, null if none exists to render.</returns>
 | 
			
		||||
        public FormattedHeaderFooter GetFormattedFooter(int page)
 | 
			
		||||
        {
 | 
			
		||||
            FieldInfos fieldInfos = _pageFieldInfos[page];
 | 
			
		||||
            int logicalPage = fieldInfos.DisplayPageNr;
 | 
			
		||||
 | 
			
		||||
            PagePosition pagePos = logicalPage % 2 == 0 ? PagePosition.Even : PagePosition.Odd;
 | 
			
		||||
 | 
			
		||||
            if (page == 1)
 | 
			
		||||
                pagePos = PagePosition.First;
 | 
			
		||||
            else //page > 1
 | 
			
		||||
            {
 | 
			
		||||
                if (IsEmptyPage(page - 1)) // these empty pages only occur between sections.
 | 
			
		||||
                    pagePos = PagePosition.First;
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    FieldInfos prevFieldInfos = _pageFieldInfos[page - 1];
 | 
			
		||||
                    if (fieldInfos.Section != prevFieldInfos.Section)
 | 
			
		||||
                        pagePos = PagePosition.First;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            HeaderFooterPosition hfp = new HeaderFooterPosition(fieldInfos.Section, pagePos);
 | 
			
		||||
            if (_formattedFooters.ContainsKey(hfp))
 | 
			
		||||
                return _formattedFooters[hfp];
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private Rectangle GetHeaderArea(Section section, int page)
 | 
			
		||||
        {
 | 
			
		||||
            PageSetup pageSetup = section.PageSetup;
 | 
			
		||||
            XUnit xPos;
 | 
			
		||||
            if (pageSetup.MirrorMargins && page % 2 == 0)
 | 
			
		||||
                xPos = pageSetup.RightMargin.Point;
 | 
			
		||||
            else
 | 
			
		||||
                xPos = pageSetup.LeftMargin.Point;
 | 
			
		||||
 | 
			
		||||
            XUnit width = pageSetup.EffectivePageWidth.Point;
 | 
			
		||||
            width -= pageSetup.LeftMargin + pageSetup.RightMargin;
 | 
			
		||||
 | 
			
		||||
            XUnit yPos = pageSetup.HeaderDistance.Point;
 | 
			
		||||
            XUnit height = pageSetup.TopMargin - pageSetup.HeaderDistance;
 | 
			
		||||
            return new Rectangle(xPos, yPos, width, height);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Rectangle GetHeaderArea(int page)
 | 
			
		||||
        {
 | 
			
		||||
            FieldInfos fieldInfos = _pageFieldInfos[page];
 | 
			
		||||
            Section section = _document.Sections[fieldInfos.Section - 1];
 | 
			
		||||
            return GetHeaderArea(section, page);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Rectangle GetFooterArea(int page)
 | 
			
		||||
        {
 | 
			
		||||
            FieldInfos fieldInfos = _pageFieldInfos[page];
 | 
			
		||||
            Section section = _document.Sections[fieldInfos.Section - 1];
 | 
			
		||||
            return GetFooterArea(section, page);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private Rectangle GetFooterArea(Section section, int page)
 | 
			
		||||
        {
 | 
			
		||||
            PageSetup pageSetup = section.PageSetup;
 | 
			
		||||
            XUnit xPos;
 | 
			
		||||
            if (pageSetup.MirrorMargins && page % 2 == 0)
 | 
			
		||||
                xPos = pageSetup.RightMargin.Point;
 | 
			
		||||
            else
 | 
			
		||||
                xPos = pageSetup.LeftMargin.Point;
 | 
			
		||||
 | 
			
		||||
            XUnit width = pageSetup.EffectivePageWidth.Point;
 | 
			
		||||
            width -= pageSetup.LeftMargin + pageSetup.RightMargin;
 | 
			
		||||
            XUnit yPos = pageSetup.EffectivePageHeight.Point;
 | 
			
		||||
 | 
			
		||||
            yPos -= pageSetup.BottomMargin.Point;
 | 
			
		||||
            XUnit height = pageSetup.BottomMargin - pageSetup.FooterDistance;
 | 
			
		||||
            return new Rectangle(xPos, yPos, width, height);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private HeaderFooter ChooseHeaderFooter(HeadersFooters hfs, PagePosition pagePos)
 | 
			
		||||
        {
 | 
			
		||||
            if (hfs == null)
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            PageSetup pageSetup = _currentSection.PageSetup;
 | 
			
		||||
 | 
			
		||||
            if (pagePos == PagePosition.First)
 | 
			
		||||
            {
 | 
			
		||||
                if (pageSetup.DifferentFirstPageHeaderFooter)
 | 
			
		||||
                    return (HeaderFooter)hfs.GetValue("FirstPage", GV.ReadOnly);
 | 
			
		||||
            }
 | 
			
		||||
            if (pagePos == PagePosition.Even || _shownPageNumber/*_currentPage*/ % 2 == 0)
 | 
			
		||||
            {
 | 
			
		||||
                if (pageSetup.OddAndEvenPagesHeaderFooter)
 | 
			
		||||
                    return (HeaderFooter)hfs.GetValue("EvenPage", GV.ReadOnly);
 | 
			
		||||
            }
 | 
			
		||||
            return (HeaderFooter)hfs.GetValue("Primary", GV.ReadOnly);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the number of pages of the document.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public int PageCount
 | 
			
		||||
        {
 | 
			
		||||
            get { return _pageCount; }
 | 
			
		||||
        }
 | 
			
		||||
        int _pageCount;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets information about the specified page.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="page">The page the information is asked for.</param>
 | 
			
		||||
        /// <returns>The page information.</returns>
 | 
			
		||||
        public PageInfo GetPageInfo(int page)
 | 
			
		||||
        {
 | 
			
		||||
            if (page < 1 || page > _pageCount)
 | 
			
		||||
#if !SILVERLIGHT
 | 
			
		||||
                throw new ArgumentOutOfRangeException("page", page, page.ToString(CultureInfo.InvariantCulture));
 | 
			
		||||
#else
 | 
			
		||||
                throw new PdfSharp.ArgumentOutOfRangeException("page", page, page.ToString(CultureInfo.InvariantCulture));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
            return _pageInfos[page];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #region IAreaProvider Members
 | 
			
		||||
 | 
			
		||||
        Area IAreaProvider.GetNextArea()
 | 
			
		||||
        {
 | 
			
		||||
            if (_isNewSection)
 | 
			
		||||
                _sectionPages = 0;
 | 
			
		||||
 | 
			
		||||
            ++_currentPage;
 | 
			
		||||
            ++_shownPageNumber;
 | 
			
		||||
            ++_sectionPages;
 | 
			
		||||
            InitFieldInfos();
 | 
			
		||||
            FormatHeadersFooters();
 | 
			
		||||
            _isNewSection = false;
 | 
			
		||||
            return CalcContentRect(_currentPage);
 | 
			
		||||
        }
 | 
			
		||||
        int _currentPage;
 | 
			
		||||
 | 
			
		||||
        Area IAreaProvider.ProbeNextArea()
 | 
			
		||||
        {
 | 
			
		||||
            return CalcContentRect(_currentPage + 1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void InitFieldInfos()
 | 
			
		||||
        {
 | 
			
		||||
            _currentFieldInfos = new FieldInfos(_bookmarks);
 | 
			
		||||
            _currentFieldInfos.PhysicalPageNr = _currentPage;
 | 
			
		||||
            _currentFieldInfos.Section = _sectionNumber;
 | 
			
		||||
 | 
			
		||||
            if (_isNewSection && !_currentSection.PageSetup._startingNumber.IsNull)
 | 
			
		||||
                _shownPageNumber = _currentSection.PageSetup.StartingNumber;
 | 
			
		||||
 | 
			
		||||
            _currentFieldInfos.DisplayPageNr = _shownPageNumber;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void IAreaProvider.StoreRenderInfos(List<RenderInfo> renderInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _pageRenderInfos.Add(_currentPage, renderInfos);
 | 
			
		||||
            XSize pageSize = CalcPageSize(_currentSection.PageSetup);
 | 
			
		||||
            PageOrientation pageOrientation = CalcPageOrientation(_currentSection.PageSetup);
 | 
			
		||||
            PageInfo pageInfo = new PageInfo(pageSize.Width, pageSize.Height, pageOrientation);
 | 
			
		||||
            _pageInfos.Add(_currentPage, pageInfo);
 | 
			
		||||
            _pageFieldInfos.Add(_currentPage, _currentFieldInfos);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        PageOrientation CalcPageOrientation(PageSetup pageSetup)
 | 
			
		||||
        {
 | 
			
		||||
            PageOrientation pageOrientation = PageOrientation.Portrait;
 | 
			
		||||
            if (_currentSection.PageSetup.Orientation == Orientation.Landscape)
 | 
			
		||||
                pageOrientation = PageOrientation.Landscape;
 | 
			
		||||
 | 
			
		||||
            return pageOrientation;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        XSize CalcPageSize(PageSetup pageSetup)
 | 
			
		||||
        {
 | 
			
		||||
            return new XSize(pageSetup.PageWidth.Point, pageSetup.PageHeight.Point);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool IAreaProvider.PositionHorizontally(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            switch (layoutInfo.HorizontalReference)
 | 
			
		||||
            {
 | 
			
		||||
                case HorizontalReference.PageMargin:
 | 
			
		||||
                case HorizontalReference.AreaBoundary:
 | 
			
		||||
                    return PositionHorizontallyToMargin(layoutInfo);
 | 
			
		||||
 | 
			
		||||
                case HorizontalReference.Page:
 | 
			
		||||
                    return PositionHorizontallyToPage(layoutInfo);
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the alignment depending on the currentPage for the alignments "Outside" and "Inside".
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="alignment">The original alignment</param>
 | 
			
		||||
        /// <returns>the alignment depending on the currentPage for the alignments "Outside" and "Inside"</returns>
 | 
			
		||||
        private ElementAlignment GetCurrentAlignment(ElementAlignment alignment)
 | 
			
		||||
        {
 | 
			
		||||
            ElementAlignment align = alignment;
 | 
			
		||||
 | 
			
		||||
            if (align == ElementAlignment.Inside)
 | 
			
		||||
            {
 | 
			
		||||
                align = _currentPage % 2 == 0 ? ElementAlignment.Far : ElementAlignment.Near;
 | 
			
		||||
            }
 | 
			
		||||
            else if (align == ElementAlignment.Outside)
 | 
			
		||||
            {
 | 
			
		||||
                align = _currentPage % 2 == 0 ? ElementAlignment.Near : ElementAlignment.Far;
 | 
			
		||||
            }
 | 
			
		||||
            return align;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool PositionHorizontallyToMargin(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            Rectangle rect = CalcContentRect(_currentPage);
 | 
			
		||||
            ElementAlignment align = GetCurrentAlignment(layoutInfo.HorizontalAlignment);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            switch (align)
 | 
			
		||||
            {
 | 
			
		||||
                case ElementAlignment.Near:
 | 
			
		||||
                    if (layoutInfo.Left != 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        layoutInfo.ContentArea.X += layoutInfo.Left;
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (layoutInfo.MarginLeft != 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        layoutInfo.ContentArea.X += layoutInfo.MarginLeft;
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                    return false;
 | 
			
		||||
 | 
			
		||||
                case ElementAlignment.Far:
 | 
			
		||||
                    XUnit xPos = rect.X + rect.Width;
 | 
			
		||||
                    xPos -= layoutInfo.ContentArea.Width;
 | 
			
		||||
                    xPos -= layoutInfo.MarginRight;
 | 
			
		||||
                    layoutInfo.ContentArea.X = xPos;
 | 
			
		||||
                    return true;
 | 
			
		||||
 | 
			
		||||
                case ElementAlignment.Center:
 | 
			
		||||
                    xPos = rect.Width;
 | 
			
		||||
                    xPos -= layoutInfo.ContentArea.Width;
 | 
			
		||||
                    xPos = rect.X + xPos / 2;
 | 
			
		||||
                    layoutInfo.ContentArea.X = xPos;
 | 
			
		||||
                    return true;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool PositionHorizontallyToPage(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            XUnit xPos;
 | 
			
		||||
            ElementAlignment align = GetCurrentAlignment(layoutInfo.HorizontalAlignment);
 | 
			
		||||
            switch (align)
 | 
			
		||||
            {
 | 
			
		||||
                case ElementAlignment.Near:
 | 
			
		||||
#if true
 | 
			
		||||
                    // Attempt to make it compatible with MigraDoc CPP.
 | 
			
		||||
                    // Ignore layoutInfo.Left if absolute position is specified in layoutInfo.MarginLeft.
 | 
			
		||||
                    // Use layoutInfo.Left if layoutInfo.MarginLeft is 0.
 | 
			
		||||
                    // TODO We would need HasValue for XUnit to determine whether a value was assigned.
 | 
			
		||||
                    if (layoutInfo.HorizontalReference == HorizontalReference.Page ||
 | 
			
		||||
                      layoutInfo.HorizontalReference == HorizontalReference.PageMargin)
 | 
			
		||||
                        xPos = layoutInfo.MarginLeft != 0 ? layoutInfo.MarginLeft : layoutInfo.Left;
 | 
			
		||||
                    else
 | 
			
		||||
                        xPos = Math.Max(layoutInfo.MarginLeft, layoutInfo.Left);
 | 
			
		||||
#else
 | 
			
		||||
                    if (layoutInfo.HorizontalReference == HorizontalReference.Page ||
 | 
			
		||||
                      layoutInfo.HorizontalReference == HorizontalReference.PageMargin)
 | 
			
		||||
                        xPos = layoutInfo.MarginLeft; // ignore layoutInfo.Left if absolute position is specified
 | 
			
		||||
                    else
 | 
			
		||||
                        xPos = Math.Max(layoutInfo.MarginLeft, layoutInfo.Left);
 | 
			
		||||
#endif
 | 
			
		||||
                    layoutInfo.ContentArea.X = xPos;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case ElementAlignment.Far:
 | 
			
		||||
                    xPos = _currentSection.PageSetup.EffectivePageWidth.Point;
 | 
			
		||||
                    xPos -= layoutInfo.ContentArea.Width;
 | 
			
		||||
                    xPos -= layoutInfo.MarginRight;
 | 
			
		||||
                    layoutInfo.ContentArea.X = xPos;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case ElementAlignment.Center:
 | 
			
		||||
                    xPos = _currentSection.PageSetup.EffectivePageWidth.Point;
 | 
			
		||||
                    xPos -= layoutInfo.ContentArea.Width;
 | 
			
		||||
                    xPos /= 2;
 | 
			
		||||
                    layoutInfo.ContentArea.X = xPos;
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool PositionVerticallyToMargin(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            Rectangle rect = CalcContentRect(_currentPage);
 | 
			
		||||
            XUnit yPos;
 | 
			
		||||
            switch (layoutInfo.VerticalAlignment)
 | 
			
		||||
            {
 | 
			
		||||
                case ElementAlignment.Near:
 | 
			
		||||
                    yPos = rect.Y;
 | 
			
		||||
                    if (layoutInfo.Top == 0)
 | 
			
		||||
                        yPos += layoutInfo.MarginTop;
 | 
			
		||||
                    else
 | 
			
		||||
                        yPos += layoutInfo.Top;
 | 
			
		||||
                    layoutInfo.ContentArea.Y = yPos;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case ElementAlignment.Far:
 | 
			
		||||
                    yPos = rect.Y + rect.Height;
 | 
			
		||||
                    yPos -= layoutInfo.ContentArea.Height;
 | 
			
		||||
                    yPos -= layoutInfo.MarginBottom;
 | 
			
		||||
                    layoutInfo.ContentArea.Y = yPos;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case ElementAlignment.Center:
 | 
			
		||||
                    yPos = rect.Height;
 | 
			
		||||
                    yPos -= layoutInfo.ContentArea.Height;
 | 
			
		||||
                    yPos = rect.Y + yPos / 2;
 | 
			
		||||
                    layoutInfo.ContentArea.Y = yPos;
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool NeedsEmptyPage()
 | 
			
		||||
        {
 | 
			
		||||
            int nextPage = _currentPage + 1;
 | 
			
		||||
            PageSetup pageSetup = _currentSection.PageSetup;
 | 
			
		||||
            bool startOnEvenPage = pageSetup.SectionStart == BreakType.BreakEvenPage;
 | 
			
		||||
            bool startOnOddPage = pageSetup.SectionStart == BreakType.BreakOddPage;
 | 
			
		||||
 | 
			
		||||
            if (startOnOddPage)
 | 
			
		||||
                return nextPage % 2 == 0;
 | 
			
		||||
            if (startOnEvenPage)
 | 
			
		||||
                return nextPage % 2 == 1;
 | 
			
		||||
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void InsertEmptyPage()
 | 
			
		||||
        {
 | 
			
		||||
            ++_currentPage;
 | 
			
		||||
            ++_shownPageNumber;
 | 
			
		||||
            _emptyPages.Add(_currentPage, null);
 | 
			
		||||
 | 
			
		||||
            XSize pageSize = CalcPageSize(_currentSection.PageSetup);
 | 
			
		||||
            PageOrientation pageOrientation = CalcPageOrientation(_currentSection.PageSetup);
 | 
			
		||||
            PageInfo pageInfo = new PageInfo(pageSize.Width, pageSize.Height, pageOrientation);
 | 
			
		||||
            _pageInfos.Add(_currentPage, pageInfo);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool PositionVerticallyToPage(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            XUnit yPos;
 | 
			
		||||
            switch (layoutInfo.VerticalAlignment)
 | 
			
		||||
            {
 | 
			
		||||
                case ElementAlignment.Near:
 | 
			
		||||
                    yPos = Math.Max(layoutInfo.MarginTop, layoutInfo.Top);
 | 
			
		||||
                    layoutInfo.ContentArea.Y = yPos;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case ElementAlignment.Far:
 | 
			
		||||
                    yPos = _currentSection.PageSetup.EffectivePageHeight.Point;
 | 
			
		||||
                    yPos -= layoutInfo.ContentArea.Height;
 | 
			
		||||
                    yPos -= layoutInfo.MarginBottom;
 | 
			
		||||
                    layoutInfo.ContentArea.Y = yPos;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case ElementAlignment.Center:
 | 
			
		||||
                    yPos = _currentSection.PageSetup.EffectivePageHeight.Point;
 | 
			
		||||
                    yPos -= layoutInfo.ContentArea.Height;
 | 
			
		||||
                    yPos /= 2;
 | 
			
		||||
                    layoutInfo.ContentArea.Y = yPos;
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool IAreaProvider.PositionVertically(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            switch (layoutInfo.VerticalReference)
 | 
			
		||||
            {
 | 
			
		||||
                case VerticalReference.PreviousElement:
 | 
			
		||||
                    return false;
 | 
			
		||||
 | 
			
		||||
                case VerticalReference.AreaBoundary:
 | 
			
		||||
                case VerticalReference.PageMargin:
 | 
			
		||||
                    return PositionVerticallyToMargin(layoutInfo);
 | 
			
		||||
 | 
			
		||||
                case VerticalReference.Page:
 | 
			
		||||
                    return PositionVerticallyToPage(layoutInfo);
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public FieldInfos GetFieldInfos(int page)
 | 
			
		||||
        {
 | 
			
		||||
            return _pageFieldInfos[page];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        FieldInfos IAreaProvider.AreaFieldInfos
 | 
			
		||||
        {
 | 
			
		||||
            get { return _currentFieldInfos; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool IAreaProvider.IsAreaBreakBefore(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            return layoutInfo.PageBreakBefore;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool IsEmptyPage(int page)
 | 
			
		||||
        {
 | 
			
		||||
            return _emptyPages.ContainsKey(page);
 | 
			
		||||
        }
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        Dictionary<string, FieldInfos.BookmarkInfo> _bookmarks;
 | 
			
		||||
        int _sectionPages;
 | 
			
		||||
        int _shownPageNumber;
 | 
			
		||||
        int _sectionNumber;
 | 
			
		||||
        Section _currentSection;
 | 
			
		||||
        bool _isNewSection;
 | 
			
		||||
        FieldInfos _currentFieldInfos;
 | 
			
		||||
        Dictionary<int, FieldInfos> _pageFieldInfos;
 | 
			
		||||
        Dictionary<HeaderFooterPosition, FormattedHeaderFooter> _formattedHeaders;
 | 
			
		||||
        Dictionary<HeaderFooterPosition, FormattedHeaderFooter> _formattedFooters;
 | 
			
		||||
        readonly DocumentRenderer _documentRenderer;
 | 
			
		||||
        XGraphics _gfx;
 | 
			
		||||
        Dictionary<int, PageInfo> _pageInfos;
 | 
			
		||||
        readonly Dictionary<int, object> _emptyPages = new Dictionary<int, object>();
 | 
			
		||||
        readonly Document _document;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										128
									
								
								MigraDoc.Rendering/Rendering/FormattedHeaderFooter.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								MigraDoc.Rendering/Rendering/FormattedHeaderFooter.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,128 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Represents a formatted header or footer.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class FormattedHeaderFooter : IAreaProvider
 | 
			
		||||
    {
 | 
			
		||||
        public FormattedHeaderFooter(HeaderFooter headerFooter, DocumentRenderer documentRenderer, FieldInfos fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _headerFooter = headerFooter;
 | 
			
		||||
            _fieldInfos = fieldInfos;
 | 
			
		||||
            _documentRenderer = documentRenderer;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Format(XGraphics gfx)
 | 
			
		||||
        {
 | 
			
		||||
            _gfx = gfx;
 | 
			
		||||
            _isFirstArea = true;
 | 
			
		||||
            _formatter = new TopDownFormatter(this, _documentRenderer, _headerFooter.Elements);
 | 
			
		||||
            _formatter.FormatOnAreas(gfx, false);
 | 
			
		||||
            _contentHeight = RenderInfo.GetTotalHeight(GetRenderInfos());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Area IAreaProvider.GetNextArea()
 | 
			
		||||
        {
 | 
			
		||||
            if (_isFirstArea)
 | 
			
		||||
                return new Rectangle(ContentRect.X, ContentRect.Y, ContentRect.Width, double.MaxValue);
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Area IAreaProvider.ProbeNextArea()
 | 
			
		||||
        {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        FieldInfos IAreaProvider.AreaFieldInfos
 | 
			
		||||
        {
 | 
			
		||||
            get { return _fieldInfos; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void IAreaProvider.StoreRenderInfos(List<RenderInfo> renderInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _renderInfos = renderInfos;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool IAreaProvider.IsAreaBreakBefore(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public RenderInfo[] GetRenderInfos()
 | 
			
		||||
        {
 | 
			
		||||
            if (_renderInfos != null)
 | 
			
		||||
                return _renderInfos.ToArray();
 | 
			
		||||
 | 
			
		||||
            return new RenderInfo[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Rectangle ContentRect
 | 
			
		||||
        {
 | 
			
		||||
            get { return _contentRect; }
 | 
			
		||||
            set { _contentRect = value; }
 | 
			
		||||
        }
 | 
			
		||||
        private Rectangle _contentRect;
 | 
			
		||||
 | 
			
		||||
        XUnit ContentHeight
 | 
			
		||||
        {
 | 
			
		||||
            get { return _contentHeight; }
 | 
			
		||||
        }
 | 
			
		||||
        private XUnit _contentHeight;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        bool IAreaProvider.PositionVertically(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            IAreaProvider formattedDoc = _documentRenderer.FormattedDocument;
 | 
			
		||||
            return formattedDoc.PositionVertically(layoutInfo);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool IAreaProvider.PositionHorizontally(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            IAreaProvider formattedDoc = _documentRenderer.FormattedDocument;
 | 
			
		||||
            return formattedDoc.PositionHorizontally(layoutInfo);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        HeaderFooter _headerFooter;
 | 
			
		||||
        FieldInfos _fieldInfos;
 | 
			
		||||
        TopDownFormatter _formatter;
 | 
			
		||||
        List<RenderInfo> _renderInfos;
 | 
			
		||||
        XGraphics _gfx;
 | 
			
		||||
        bool _isFirstArea;
 | 
			
		||||
        readonly DocumentRenderer _documentRenderer;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										171
									
								
								MigraDoc.Rendering/Rendering/FormattedTextArea.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								MigraDoc.Rendering/Rendering/FormattedTextArea.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,171 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Shapes.Charts;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Represents a formatted text area.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class FormattedTextArea : IAreaProvider
 | 
			
		||||
    {
 | 
			
		||||
        public FormattedTextArea(DocumentRenderer documentRenderer, TextArea textArea, FieldInfos fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            TextArea = textArea;
 | 
			
		||||
            _fieldInfos = fieldInfos;
 | 
			
		||||
            _documentRenderer = documentRenderer;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Format(XGraphics gfx)
 | 
			
		||||
        {
 | 
			
		||||
            _gfx = gfx;
 | 
			
		||||
            _isFirstArea = true;
 | 
			
		||||
            _formatter = new TopDownFormatter(this, _documentRenderer, TextArea.Elements);
 | 
			
		||||
            _formatter.FormatOnAreas(gfx, false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public XUnit InnerWidth
 | 
			
		||||
        {
 | 
			
		||||
            set { _innerWidth = value; }
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                if (double.IsNaN(_innerWidth))
 | 
			
		||||
                {
 | 
			
		||||
                    if (!TextArea._width.IsNull)
 | 
			
		||||
                        _innerWidth = TextArea.Width.Point;
 | 
			
		||||
                    else
 | 
			
		||||
                        _innerWidth = CalcInherentWidth();
 | 
			
		||||
                }
 | 
			
		||||
                return _innerWidth;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        XUnit _innerWidth = double.NaN;
 | 
			
		||||
 | 
			
		||||
        public XUnit InnerHeight
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                if (TextArea._height.IsNull)
 | 
			
		||||
                    return ContentHeight + TextArea.TopPadding + TextArea.BottomPadding;
 | 
			
		||||
                return TextArea.Height.Point;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        XUnit CalcInherentWidth()
 | 
			
		||||
        {
 | 
			
		||||
            XUnit inherentWidth = 0;
 | 
			
		||||
            foreach (DocumentObject obj in TextArea.Elements)
 | 
			
		||||
            {
 | 
			
		||||
                Renderer renderer = Renderer.Create(_gfx, _documentRenderer, obj, _fieldInfos);
 | 
			
		||||
                if (renderer != null)
 | 
			
		||||
                {
 | 
			
		||||
                    renderer.Format(new Rectangle(0, 0, double.MaxValue, double.MaxValue), null);
 | 
			
		||||
                    inherentWidth = Math.Max(renderer.RenderInfo.LayoutInfo.MinWidth, inherentWidth);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            inherentWidth += TextArea.LeftPadding;
 | 
			
		||||
            inherentWidth += TextArea.RightPadding;
 | 
			
		||||
            return inherentWidth;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Area IAreaProvider.GetNextArea()
 | 
			
		||||
        {
 | 
			
		||||
            if (_isFirstArea)
 | 
			
		||||
                return CalcContentRect();
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Area IAreaProvider.ProbeNextArea()
 | 
			
		||||
        {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        FieldInfos IAreaProvider.AreaFieldInfos
 | 
			
		||||
        {
 | 
			
		||||
            get { return _fieldInfos; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void IAreaProvider.StoreRenderInfos(List<RenderInfo> renderInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _renderInfos = renderInfos;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool IAreaProvider.IsAreaBreakBefore(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public RenderInfo[] GetRenderInfos()
 | 
			
		||||
        {
 | 
			
		||||
            if (_renderInfos != null)
 | 
			
		||||
                return _renderInfos.ToArray();
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public XUnit ContentHeight
 | 
			
		||||
        {
 | 
			
		||||
            get { return RenderInfo.GetTotalHeight(GetRenderInfos()); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Rectangle CalcContentRect()
 | 
			
		||||
        {
 | 
			
		||||
            XUnit width = InnerWidth - TextArea.LeftPadding - TextArea.RightPadding;
 | 
			
		||||
            XUnit height = double.MaxValue;
 | 
			
		||||
            return new Rectangle(0, 0, width, height);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool IAreaProvider.PositionVertically(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool IAreaProvider.PositionHorizontally(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public readonly TextArea TextArea;
 | 
			
		||||
 | 
			
		||||
        readonly FieldInfos _fieldInfos;
 | 
			
		||||
        TopDownFormatter _formatter;
 | 
			
		||||
        List<RenderInfo> _renderInfos;
 | 
			
		||||
        XGraphics _gfx;
 | 
			
		||||
        bool _isFirstArea;
 | 
			
		||||
        readonly DocumentRenderer _documentRenderer;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										180
									
								
								MigraDoc.Rendering/Rendering/FormattedTextFrame.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								MigraDoc.Rendering/Rendering/FormattedTextFrame.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,180 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Shapes;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Represents a formatted text frame.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class FormattedTextFrame : IAreaProvider
 | 
			
		||||
    {
 | 
			
		||||
        public FormattedTextFrame(TextFrame textframe, DocumentRenderer documentRenderer, FieldInfos fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _textframe = textframe;
 | 
			
		||||
            _fieldInfos = fieldInfos;
 | 
			
		||||
            _documentRenderer = documentRenderer;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Format(XGraphics gfx)
 | 
			
		||||
        {
 | 
			
		||||
            _gfx = gfx;
 | 
			
		||||
            _isFirstArea = true;
 | 
			
		||||
            _formatter = new TopDownFormatter(this, _documentRenderer, _textframe.Elements);
 | 
			
		||||
            _formatter.FormatOnAreas(gfx, false);
 | 
			
		||||
            _contentHeight = RenderInfo.GetTotalHeight(GetRenderInfos());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Area IAreaProvider.GetNextArea()
 | 
			
		||||
        {
 | 
			
		||||
            if (_isFirstArea)
 | 
			
		||||
                return CalcContentRect();
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Area IAreaProvider.ProbeNextArea()
 | 
			
		||||
        {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        FieldInfos IAreaProvider.AreaFieldInfos
 | 
			
		||||
        {
 | 
			
		||||
            get { return _fieldInfos; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void IAreaProvider.StoreRenderInfos(List<RenderInfo> renderInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _renderInfos = renderInfos;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool IAreaProvider.IsAreaBreakBefore(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public RenderInfo[] GetRenderInfos()
 | 
			
		||||
        {
 | 
			
		||||
            if (_renderInfos != null)
 | 
			
		||||
                return _renderInfos.ToArray();
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Rectangle CalcContentRect()
 | 
			
		||||
        {
 | 
			
		||||
            LineFormatRenderer lfr = new LineFormatRenderer(_textframe.LineFormat, _gfx);
 | 
			
		||||
            XUnit lineWidth = lfr.GetWidth();
 | 
			
		||||
            XUnit width;
 | 
			
		||||
            XUnit xOffset = lineWidth / 2;
 | 
			
		||||
            XUnit yOffset = lineWidth / 2;
 | 
			
		||||
 | 
			
		||||
            if (_textframe.Orientation == TextOrientation.Horizontal ||
 | 
			
		||||
              _textframe.Orientation == TextOrientation.HorizontalRotatedFarEast)
 | 
			
		||||
            {
 | 
			
		||||
                width = _textframe.Width.Point;
 | 
			
		||||
                xOffset += _textframe.MarginLeft;
 | 
			
		||||
                yOffset += _textframe.MarginTop;
 | 
			
		||||
                width -= xOffset;
 | 
			
		||||
                width -= _textframe.MarginRight + lineWidth / 2;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                width = _textframe.Height.Point;
 | 
			
		||||
                if (_textframe.Orientation == TextOrientation.Upward)
 | 
			
		||||
                {
 | 
			
		||||
                    xOffset += _textframe.MarginBottom;
 | 
			
		||||
                    yOffset += _textframe.MarginLeft;
 | 
			
		||||
                    width -= xOffset;
 | 
			
		||||
                    width -= _textframe.MarginTop + lineWidth / 2;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    xOffset += _textframe.MarginTop;
 | 
			
		||||
                    yOffset += _textframe.MarginRight;
 | 
			
		||||
                    width -= xOffset;
 | 
			
		||||
                    width -= _textframe.MarginBottom + lineWidth / 2;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            XUnit height = double.MaxValue;
 | 
			
		||||
            return new Rectangle(xOffset, yOffset, width, height);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        XUnit ContentHeight
 | 
			
		||||
        {
 | 
			
		||||
            get { return _contentHeight; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool IAreaProvider.PositionVertically(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool IAreaProvider.PositionHorizontally(LayoutInfo layoutInfo)
 | 
			
		||||
        {
 | 
			
		||||
            Rectangle rect = CalcContentRect();
 | 
			
		||||
            switch (layoutInfo.HorizontalAlignment)
 | 
			
		||||
            {
 | 
			
		||||
                case ElementAlignment.Near:
 | 
			
		||||
                    if (layoutInfo.Left != 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        layoutInfo.ContentArea.X += layoutInfo.Left;
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                    return false;
 | 
			
		||||
 | 
			
		||||
                case ElementAlignment.Far:
 | 
			
		||||
                    XUnit xPos = rect.X + rect.Width;
 | 
			
		||||
                    xPos -= layoutInfo.ContentArea.Width;
 | 
			
		||||
                    xPos -= layoutInfo.MarginRight;
 | 
			
		||||
                    layoutInfo.ContentArea.X = xPos;
 | 
			
		||||
                    return true;
 | 
			
		||||
 | 
			
		||||
                case ElementAlignment.Center:
 | 
			
		||||
                    xPos = rect.Width;
 | 
			
		||||
                    xPos -= layoutInfo.ContentArea.Width;
 | 
			
		||||
                    xPos = rect.X + xPos / 2;
 | 
			
		||||
                    layoutInfo.ContentArea.X = xPos;
 | 
			
		||||
                    return true;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        readonly TextFrame _textframe;
 | 
			
		||||
        readonly FieldInfos _fieldInfos;
 | 
			
		||||
        TopDownFormatter _formatter;
 | 
			
		||||
        List<RenderInfo> _renderInfos;
 | 
			
		||||
        XGraphics _gfx;
 | 
			
		||||
        bool _isFirstArea;
 | 
			
		||||
        XUnit _contentHeight;
 | 
			
		||||
        readonly DocumentRenderer _documentRenderer;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										78
									
								
								MigraDoc.Rendering/Rendering/IAreaProvider.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								MigraDoc.Rendering/Rendering/IAreaProvider.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Represents a class that provides a series of Areas to render into.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public interface IAreaProvider
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the next area to render into.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        Area GetNextArea();
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Probes the next area to render into like GetNextArea, but doesn't change the provider state. 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>The area for the next rendering act.</returns>
 | 
			
		||||
        Area ProbeNextArea();
 | 
			
		||||
 | 
			
		||||
        FieldInfos AreaFieldInfos { get; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Determines whether the element requires an area break before.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        bool IsAreaBreakBefore(LayoutInfo layoutInfo);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Positions the element vertically relatively to the current area.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="layoutInfo">The layout info of the element.</param>
 | 
			
		||||
        /// <returns>True, if the element was moved by the function.</returns>
 | 
			
		||||
        bool PositionVertically(LayoutInfo layoutInfo);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Positions the element horizontally relatively to the current area.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="layoutInfo">The layout info of the element.</param>
 | 
			
		||||
        /// <returns>True, if the element was moved by the function.</returns>
 | 
			
		||||
        bool PositionHorizontally(LayoutInfo layoutInfo);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Stores the RenderInfos of elements on the current area.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="renderInfos"></param>
 | 
			
		||||
        void StoreRenderInfos(List<RenderInfo> renderInfos);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										50
									
								
								MigraDoc.Rendering/Rendering/ImageFormatInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								MigraDoc.Rendering/Rendering/ImageFormatInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Formatting information for an image.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public sealed class ImageFormatInfo : ShapeFormatInfo
 | 
			
		||||
    {
 | 
			
		||||
        public int CropX;
 | 
			
		||||
        public int CropY;
 | 
			
		||||
        public int CropWidth;
 | 
			
		||||
        public int CropHeight;
 | 
			
		||||
        public XUnit Width;
 | 
			
		||||
        public XUnit Height;
 | 
			
		||||
 | 
			
		||||
        public ImageFailure Failure;
 | 
			
		||||
        public string ImagePath;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										48
									
								
								MigraDoc.Rendering/Rendering/ImageRenderInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								MigraDoc.Rendering/Rendering/ImageRenderInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Represents rendering information for images.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public sealed class ImageRenderInfo : ShapeRenderInfo
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the format information in a specific derived type. For a table, for example, this will be a TableFormatInfo with information about the first and last row showing on a page.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public override FormatInfo FormatInfo
 | 
			
		||||
        {
 | 
			
		||||
            get { return _formatInfo ?? (_formatInfo = new ImageFormatInfo()); }
 | 
			
		||||
            set { _formatInfo = (ImageFormatInfo)value; }
 | 
			
		||||
        }
 | 
			
		||||
        ImageFormatInfo _formatInfo;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										367
									
								
								MigraDoc.Rendering/Rendering/ImageRenderer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								MigraDoc.Rendering/Rendering/ImageRenderer.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,367 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Shapes;
 | 
			
		||||
using MigraDoc.Rendering.Resources;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Renders images.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class ImageRenderer : ShapeRenderer
 | 
			
		||||
    {
 | 
			
		||||
        public ImageRenderer(XGraphics gfx, Image image, FieldInfos fieldInfos)
 | 
			
		||||
            : base(gfx, image, fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _image = image;
 | 
			
		||||
            ImageRenderInfo renderInfo = new ImageRenderInfo();
 | 
			
		||||
            renderInfo.DocumentObject = _shape;
 | 
			
		||||
            _renderInfo = renderInfo;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ImageRenderer(XGraphics gfx, RenderInfo renderInfo, FieldInfos fieldInfos)
 | 
			
		||||
            : base(gfx, renderInfo, fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _image = (Image)renderInfo.DocumentObject;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void Format(Area area, FormatInfo previousFormatInfo)
 | 
			
		||||
        {
 | 
			
		||||
            _imageFilePath = _image.GetFilePath(_documentRenderer.WorkingDirectory);
 | 
			
		||||
            // The Image is stored in the string if path starts with "base64:", otherwise we check whether the file exists.
 | 
			
		||||
            if (!_imageFilePath.StartsWith("base64:") &&
 | 
			
		||||
                !XImage.ExistsFile(_imageFilePath))
 | 
			
		||||
            {
 | 
			
		||||
                _failure = ImageFailure.FileNotFound;
 | 
			
		||||
                Debug.WriteLine(Messages2.ImageNotFound(_image.Name), "warning");
 | 
			
		||||
            }
 | 
			
		||||
            ImageFormatInfo formatInfo = (ImageFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
            formatInfo.Failure = _failure;
 | 
			
		||||
            formatInfo.ImagePath = _imageFilePath;
 | 
			
		||||
            CalculateImageDimensions();
 | 
			
		||||
            base.Format(area, previousFormatInfo);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override XUnit ShapeHeight
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                ImageFormatInfo formatInfo = (ImageFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
                return formatInfo.Height + _lineFormatRenderer.GetWidth();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override XUnit ShapeWidth
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                ImageFormatInfo formatInfo = (ImageFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
                return formatInfo.Width + _lineFormatRenderer.GetWidth();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void Render()
 | 
			
		||||
        {
 | 
			
		||||
            RenderFilling();
 | 
			
		||||
 | 
			
		||||
            ImageFormatInfo formatInfo = (ImageFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
            Area contentArea = _renderInfo.LayoutInfo.ContentArea;
 | 
			
		||||
            XRect destRect = new XRect(contentArea.X, contentArea.Y, formatInfo.Width, formatInfo.Height);
 | 
			
		||||
 | 
			
		||||
            if (formatInfo.Failure == ImageFailure.None)
 | 
			
		||||
            {
 | 
			
		||||
                XImage xImage = null;
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    XRect srcRect = new XRect(formatInfo.CropX, formatInfo.CropY, formatInfo.CropWidth, formatInfo.CropHeight);
 | 
			
		||||
                    //xImage = XImage.FromFile(formatInfo.ImagePath);
 | 
			
		||||
                    xImage = CreateXImage(formatInfo.ImagePath);
 | 
			
		||||
                    _gfx.DrawImage(xImage, destRect, srcRect, XGraphicsUnit.Point); //Pixel.
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception)
 | 
			
		||||
                {
 | 
			
		||||
                    RenderFailureImage(destRect);
 | 
			
		||||
                }
 | 
			
		||||
                finally
 | 
			
		||||
                {
 | 
			
		||||
                    if (xImage != null)
 | 
			
		||||
                        xImage.Dispose();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
                RenderFailureImage(destRect);
 | 
			
		||||
 | 
			
		||||
            RenderLine();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void RenderFailureImage(XRect destRect)
 | 
			
		||||
        {
 | 
			
		||||
            _gfx.DrawRectangle(XBrushes.LightGray, destRect);
 | 
			
		||||
            string failureString;
 | 
			
		||||
            ImageFormatInfo formatInfo = (ImageFormatInfo)RenderInfo.FormatInfo;
 | 
			
		||||
 | 
			
		||||
            switch (formatInfo.Failure)
 | 
			
		||||
            {
 | 
			
		||||
                case ImageFailure.EmptySize:
 | 
			
		||||
                    failureString = Messages2.DisplayEmptyImageSize;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case ImageFailure.FileNotFound:
 | 
			
		||||
                    failureString = Messages2.DisplayImageFileNotFound;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case ImageFailure.InvalidType:
 | 
			
		||||
                    failureString = Messages2.DisplayInvalidImageType;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case ImageFailure.NotRead:
 | 
			
		||||
                default:
 | 
			
		||||
                    failureString = Messages2.DisplayImageNotRead;
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Create stub font
 | 
			
		||||
            XFont font = new XFont("Courier New", 8);
 | 
			
		||||
            _gfx.DrawString(failureString, font, XBrushes.Red, destRect, XStringFormats.Center);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void CalculateImageDimensions()
 | 
			
		||||
        {
 | 
			
		||||
            ImageFormatInfo formatInfo = (ImageFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
 | 
			
		||||
            if (formatInfo.Failure == ImageFailure.None)
 | 
			
		||||
            {
 | 
			
		||||
                XImage xImage = null;
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    //xImage = XImage.FromFile(_imageFilePath);
 | 
			
		||||
                    xImage = CreateXImage(_imageFilePath);
 | 
			
		||||
                }
 | 
			
		||||
                catch (InvalidOperationException ex)
 | 
			
		||||
                {
 | 
			
		||||
                    Debug.WriteLine(Messages2.InvalidImageType(ex.Message));
 | 
			
		||||
                    formatInfo.Failure = ImageFailure.InvalidType;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (formatInfo.Failure == ImageFailure.None)
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        XUnit usrWidth = _image.Width.Point;
 | 
			
		||||
                        XUnit usrHeight = _image.Height.Point;
 | 
			
		||||
                        bool usrWidthSet = !_image._width.IsNull;
 | 
			
		||||
                        bool usrHeightSet = !_image._height.IsNull;
 | 
			
		||||
 | 
			
		||||
                        XUnit resultWidth = usrWidth;
 | 
			
		||||
                        XUnit resultHeight = usrHeight;
 | 
			
		||||
 | 
			
		||||
                        Debug.Assert(xImage != null);
 | 
			
		||||
                        double xPixels = xImage.PixelWidth;
 | 
			
		||||
                        bool usrResolutionSet = !_image._resolution.IsNull;
 | 
			
		||||
 | 
			
		||||
                        double horzRes = usrResolutionSet ? _image.Resolution : xImage.HorizontalResolution;
 | 
			
		||||
                        double vertRes = usrResolutionSet ? _image.Resolution : xImage.VerticalResolution;
 | 
			
		||||
 | 
			
		||||
// ReSharper disable CompareOfFloatsByEqualityOperator
 | 
			
		||||
                        if (horzRes == 0 && vertRes == 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            horzRes = 72;
 | 
			
		||||
                            vertRes = 72;
 | 
			
		||||
                        }
 | 
			
		||||
                        else if (horzRes == 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            Debug.Assert(false, "How can this be?");
 | 
			
		||||
                            horzRes = 72;
 | 
			
		||||
                        }
 | 
			
		||||
                        else if (vertRes == 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            Debug.Assert(false, "How can this be?");
 | 
			
		||||
                            vertRes = 72;
 | 
			
		||||
                        }
 | 
			
		||||
                        // ReSharper restore CompareOfFloatsByEqualityOperator
 | 
			
		||||
 | 
			
		||||
                        XUnit inherentWidth = XUnit.FromInch(xPixels / horzRes);
 | 
			
		||||
                        double yPixels = xImage.PixelHeight;
 | 
			
		||||
                        XUnit inherentHeight = XUnit.FromInch(yPixels / vertRes);
 | 
			
		||||
 | 
			
		||||
                        //bool lockRatio = _image.IsNull("LockAspectRatio") ? true : _image.LockAspectRatio;
 | 
			
		||||
                        bool lockRatio = _image._lockAspectRatio.IsNull || _image.LockAspectRatio;
 | 
			
		||||
 | 
			
		||||
                        double scaleHeight = _image.ScaleHeight;
 | 
			
		||||
                        double scaleWidth = _image.ScaleWidth;
 | 
			
		||||
                        //bool scaleHeightSet = !_image.IsNull("ScaleHeight");
 | 
			
		||||
                        //bool scaleWidthSet = !_image.IsNull("ScaleWidth");
 | 
			
		||||
                        bool scaleHeightSet = !_image._scaleHeight.IsNull;
 | 
			
		||||
                        bool scaleWidthSet = !_image._scaleWidth.IsNull;
 | 
			
		||||
 | 
			
		||||
                        if (lockRatio && !(scaleHeightSet && scaleWidthSet))
 | 
			
		||||
                        {
 | 
			
		||||
                            if (usrWidthSet && !usrHeightSet)
 | 
			
		||||
                            {
 | 
			
		||||
                                resultHeight = inherentHeight / inherentWidth * usrWidth;
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (usrHeightSet && !usrWidthSet)
 | 
			
		||||
                            {
 | 
			
		||||
                                resultWidth = inherentWidth / inherentHeight * usrHeight;
 | 
			
		||||
                            }
 | 
			
		||||
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
 | 
			
		||||
                            else if (!usrHeightSet && !usrWidthSet)
 | 
			
		||||
                            {
 | 
			
		||||
                                resultHeight = inherentHeight;
 | 
			
		||||
                                resultWidth = inherentWidth;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            if (scaleHeightSet)
 | 
			
		||||
                            {
 | 
			
		||||
                                resultHeight = resultHeight * scaleHeight;
 | 
			
		||||
                                resultWidth = resultWidth * scaleHeight;
 | 
			
		||||
                            }
 | 
			
		||||
                            if (scaleWidthSet)
 | 
			
		||||
                            {
 | 
			
		||||
                                resultHeight = resultHeight * scaleWidth;
 | 
			
		||||
                                resultWidth = resultWidth * scaleWidth;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            if (!usrHeightSet)
 | 
			
		||||
                                resultHeight = inherentHeight;
 | 
			
		||||
 | 
			
		||||
                            if (!usrWidthSet)
 | 
			
		||||
                                resultWidth = inherentWidth;
 | 
			
		||||
 | 
			
		||||
                            if (scaleHeightSet)
 | 
			
		||||
                                resultHeight = resultHeight * scaleHeight;
 | 
			
		||||
                            if (scaleWidthSet)
 | 
			
		||||
                                resultWidth = resultWidth * scaleWidth;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        formatInfo.CropWidth = (int)xPixels;
 | 
			
		||||
                        formatInfo.CropHeight = (int)yPixels;
 | 
			
		||||
                        if (_image._pictureFormat != null && !_image._pictureFormat.IsNull())
 | 
			
		||||
                        {
 | 
			
		||||
                            PictureFormat picFormat = _image.PictureFormat;
 | 
			
		||||
                            //Cropping in pixels.
 | 
			
		||||
                            XUnit cropLeft = picFormat.CropLeft.Point;
 | 
			
		||||
                            XUnit cropRight = picFormat.CropRight.Point;
 | 
			
		||||
                            XUnit cropTop = picFormat.CropTop.Point;
 | 
			
		||||
                            XUnit cropBottom = picFormat.CropBottom.Point;
 | 
			
		||||
                            formatInfo.CropX = (int)(horzRes * cropLeft.Inch);
 | 
			
		||||
                            formatInfo.CropY = (int)(vertRes * cropTop.Inch);
 | 
			
		||||
                            formatInfo.CropWidth -= (int)(horzRes * ((XUnit)(cropLeft + cropRight)).Inch);
 | 
			
		||||
                            formatInfo.CropHeight -= (int)(vertRes * ((XUnit)(cropTop + cropBottom)).Inch);
 | 
			
		||||
 | 
			
		||||
                            //Scaled cropping of the height and width.
 | 
			
		||||
                            double xScale = resultWidth / inherentWidth;
 | 
			
		||||
                            double yScale = resultHeight / inherentHeight;
 | 
			
		||||
 | 
			
		||||
                            cropLeft = xScale * cropLeft;
 | 
			
		||||
                            cropRight = xScale * cropRight;
 | 
			
		||||
                            cropTop = yScale * cropTop;
 | 
			
		||||
                            cropBottom = yScale * cropBottom;
 | 
			
		||||
 | 
			
		||||
                            resultHeight = resultHeight - cropTop - cropBottom;
 | 
			
		||||
                            resultWidth = resultWidth - cropLeft - cropRight;
 | 
			
		||||
                        }
 | 
			
		||||
                        if (resultHeight <= 0 || resultWidth <= 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            formatInfo.Width = XUnit.FromCentimeter(2.5);
 | 
			
		||||
                            formatInfo.Height = XUnit.FromCentimeter(2.5);
 | 
			
		||||
                            Debug.WriteLine(Messages2.EmptyImageSize);
 | 
			
		||||
                            _failure = ImageFailure.EmptySize;
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            formatInfo.Width = resultWidth;
 | 
			
		||||
                            formatInfo.Height = resultHeight;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception ex)
 | 
			
		||||
                    {
 | 
			
		||||
                        Debug.WriteLine(Messages2.ImageNotReadable(_image.Name, ex.Message));
 | 
			
		||||
                        formatInfo.Failure = ImageFailure.NotRead;
 | 
			
		||||
                    }
 | 
			
		||||
                    finally
 | 
			
		||||
                    {
 | 
			
		||||
                        if (xImage != null)
 | 
			
		||||
                            xImage.Dispose();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (formatInfo.Failure != ImageFailure.None)
 | 
			
		||||
            {
 | 
			
		||||
                if (!_image._width.IsNull)
 | 
			
		||||
                    formatInfo.Width = _image.Width.Point;
 | 
			
		||||
                else
 | 
			
		||||
                    formatInfo.Width = XUnit.FromCentimeter(2.5);
 | 
			
		||||
 | 
			
		||||
                if (!_image._height.IsNull)
 | 
			
		||||
                    formatInfo.Height = _image.Height.Point;
 | 
			
		||||
                else
 | 
			
		||||
                    formatInfo.Height = XUnit.FromCentimeter(2.5);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        XImage CreateXImage(string uri)
 | 
			
		||||
        {
 | 
			
		||||
            if (uri.StartsWith("base64:"))
 | 
			
		||||
            {
 | 
			
		||||
                string base64 = uri.Substring("base64:".Length);
 | 
			
		||||
                byte[] bytes = Convert.FromBase64String(base64);
 | 
			
		||||
#if WPF || CORE_WITH_GDI || GDI
 | 
			
		||||
                // WPF stores a reference to the stream publicly. We must not destroy the stream here, otherwise rendering the PDF will fail.
 | 
			
		||||
                // Same for GDI. CORE currently uses the GDI implementation.
 | 
			
		||||
                // We have to rely on the garbage collector to properly dispose the MemoryStream.
 | 
			
		||||
                {
 | 
			
		||||
                    Stream stream = new MemoryStream(bytes);
 | 
			
		||||
                    XImage image = XImage.FromStream(stream);
 | 
			
		||||
                    return image;
 | 
			
		||||
                }
 | 
			
		||||
#else
 | 
			
		||||
                using (Stream stream = new MemoryStream(bytes))
 | 
			
		||||
                {
 | 
			
		||||
                    XImage image = XImage.FromStream(stream);
 | 
			
		||||
                    return image;
 | 
			
		||||
                }
 | 
			
		||||
#endif
 | 
			
		||||
            }
 | 
			
		||||
            return XImage.FromFile(uri);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        readonly Image _image;
 | 
			
		||||
        string _imageFilePath;
 | 
			
		||||
        ImageFailure _failure;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										229
									
								
								MigraDoc.Rendering/Rendering/LayoutInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										229
									
								
								MigraDoc.Rendering/Rendering/LayoutInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,229 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Abstract base class to serve as a layoutable unit.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class LayoutInfo
 | 
			
		||||
    {
 | 
			
		||||
        public LayoutInfo()
 | 
			
		||||
        { }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the height necessary to start the document object.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public XUnit StartingHeight
 | 
			
		||||
        {
 | 
			
		||||
            get { return _startingHeight; }
 | 
			
		||||
            set { _startingHeight = value; }
 | 
			
		||||
        }
 | 
			
		||||
        XUnit _startingHeight;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the height necessary to end the document object.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public XUnit TrailingHeight
 | 
			
		||||
        {
 | 
			
		||||
            get { return _trailingHeight; }
 | 
			
		||||
            set { _trailingHeight = value; }
 | 
			
		||||
        }
 | 
			
		||||
        XUnit _trailingHeight;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Indicates whether the document object shall be kept on one page
 | 
			
		||||
        /// with its successor.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool KeepWithNext
 | 
			
		||||
        {
 | 
			
		||||
            get { return _keepWithNext; }
 | 
			
		||||
            set { _keepWithNext = value; }
 | 
			
		||||
        }
 | 
			
		||||
        bool _keepWithNext;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Indicates whether the document object shall be kept together on one page.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool KeepTogether
 | 
			
		||||
        {
 | 
			
		||||
            get { return _keepTogether; }
 | 
			
		||||
            set { _keepTogether = value; }
 | 
			
		||||
        }
 | 
			
		||||
        bool _keepTogether;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The space that shall be kept free above the element's content.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public virtual XUnit MarginTop
 | 
			
		||||
        {
 | 
			
		||||
            get { return _marginTop; }
 | 
			
		||||
            set { _marginTop = value; }
 | 
			
		||||
        }
 | 
			
		||||
        XUnit _marginTop;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The space that shall be kept free right to the element's content.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public XUnit MarginRight
 | 
			
		||||
        {
 | 
			
		||||
            get { return _marginRight; }
 | 
			
		||||
            set { _marginRight = value; }
 | 
			
		||||
        }
 | 
			
		||||
        XUnit _marginRight;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The space that shall be kept free below the element's content.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public XUnit MarginBottom
 | 
			
		||||
        {
 | 
			
		||||
            get { return _marginBottom; }
 | 
			
		||||
            set { _marginBottom = value; }
 | 
			
		||||
        }
 | 
			
		||||
        XUnit _marginBottom;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The space that shall be kept free left to the element's content.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public XUnit MarginLeft
 | 
			
		||||
        {
 | 
			
		||||
            get { return _marginLeft; }
 | 
			
		||||
            set { _marginLeft = value; }
 | 
			
		||||
        }
 | 
			
		||||
        XUnit _marginLeft;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the Area needed by the content (including padding and borders for e.g. paragraphs).
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public Area ContentArea
 | 
			
		||||
        {
 | 
			
		||||
            get { return _contentArea; }
 | 
			
		||||
            set { _contentArea = value; }
 | 
			
		||||
        }
 | 
			
		||||
        Area _contentArea;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the a value indicating whether the element shall appear on a new page.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool PageBreakBefore
 | 
			
		||||
        {
 | 
			
		||||
            get { return _pageBreakBefore; }
 | 
			
		||||
            set { _pageBreakBefore = value; }
 | 
			
		||||
        }
 | 
			
		||||
        bool _pageBreakBefore;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the reference point for horizontal positioning.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <remarks>Default value is AreaBoundary.</remarks>
 | 
			
		||||
        public HorizontalReference HorizontalReference
 | 
			
		||||
        {
 | 
			
		||||
            get { return _horizontalReference; }
 | 
			
		||||
            set { _horizontalReference = value; }
 | 
			
		||||
        }
 | 
			
		||||
        HorizontalReference _horizontalReference;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the reference point for vertical positioning.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <remarks>Default value is PreviousElement.</remarks>
 | 
			
		||||
        public VerticalReference VerticalReference
 | 
			
		||||
        {
 | 
			
		||||
            get { return _verticalReference; }
 | 
			
		||||
            set { _verticalReference = value; }
 | 
			
		||||
        }
 | 
			
		||||
        VerticalReference _verticalReference;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the horizontal alignment of the element.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <remarks>Default value is Near.</remarks>
 | 
			
		||||
        public ElementAlignment HorizontalAlignment
 | 
			
		||||
        {
 | 
			
		||||
            get { return _horizontalAlignment; }
 | 
			
		||||
            set { _horizontalAlignment = value; }
 | 
			
		||||
        }
 | 
			
		||||
        ElementAlignment _horizontalAlignment;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the vertical alignment of the element.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <remarks>Default value is Near.</remarks>
 | 
			
		||||
        public ElementAlignment VerticalAlignment
 | 
			
		||||
        {
 | 
			
		||||
            get { return _verticalAlignment; }
 | 
			
		||||
            set { _verticalAlignment = value; }
 | 
			
		||||
        }
 | 
			
		||||
        ElementAlignment _verticalAlignment;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the floating behavior of surrounding elements.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <remarks>Default value is TopBottom.</remarks>
 | 
			
		||||
        public Floating Floating
 | 
			
		||||
        {
 | 
			
		||||
            get { return _floating; }
 | 
			
		||||
            set { _floating = value; }
 | 
			
		||||
        }
 | 
			
		||||
        Floating _floating;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the top position of the element.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public XUnit Top
 | 
			
		||||
        {
 | 
			
		||||
            get { return _top; }
 | 
			
		||||
            set { _top = value; }
 | 
			
		||||
        }
 | 
			
		||||
        XUnit _top;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the left position of the element.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public XUnit Left
 | 
			
		||||
        {
 | 
			
		||||
            get { return _left; }
 | 
			
		||||
            set { _left = value; }
 | 
			
		||||
        }
 | 
			
		||||
        XUnit _left;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the minimum width of the element.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public XUnit MinWidth
 | 
			
		||||
        {
 | 
			
		||||
            get { return _minWidth; }
 | 
			
		||||
            set { _minWidth = value; }
 | 
			
		||||
        }
 | 
			
		||||
        XUnit _minWidth;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										122
									
								
								MigraDoc.Rendering/Rendering/LineFormatRenderer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								MigraDoc.Rendering/Rendering/LineFormatRenderer.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,122 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Shapes;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Renders a line format to an XGraphics object.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class LineFormatRenderer
 | 
			
		||||
    {
 | 
			
		||||
        public LineFormatRenderer(LineFormat lineFormat, XGraphics gfx)
 | 
			
		||||
        {
 | 
			
		||||
            _lineFormat = lineFormat;
 | 
			
		||||
            _gfx = gfx;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private XColor GetColor()
 | 
			
		||||
        {
 | 
			
		||||
            Color clr = Colors.Black;
 | 
			
		||||
 | 
			
		||||
            if (_lineFormat != null && !_lineFormat.Color.IsEmpty)
 | 
			
		||||
                clr = _lineFormat.Color;
 | 
			
		||||
 | 
			
		||||
#if noCMYK
 | 
			
		||||
      return XColor.FromArgb((int)clr.Argb);
 | 
			
		||||
#else
 | 
			
		||||
            return ColorHelper.ToXColor(clr, _lineFormat.Document.UseCmykColor);
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public XUnit GetWidth()
 | 
			
		||||
        {
 | 
			
		||||
            if (_lineFormat == null)
 | 
			
		||||
                return 0;
 | 
			
		||||
            if (!_lineFormat._visible.IsNull && !_lineFormat.Visible)
 | 
			
		||||
                return 0;
 | 
			
		||||
 | 
			
		||||
            if (!_lineFormat._width.IsNull)
 | 
			
		||||
                return _lineFormat.Width.Point;
 | 
			
		||||
 | 
			
		||||
            if (!_lineFormat._color.IsNull || !_lineFormat._style.IsNull || _lineFormat.Visible)
 | 
			
		||||
                return 1;
 | 
			
		||||
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Render(XUnit xPosition, XUnit yPosition, XUnit width, XUnit height)
 | 
			
		||||
        {
 | 
			
		||||
            XUnit lineWidth = GetWidth();
 | 
			
		||||
            if (lineWidth > 0)
 | 
			
		||||
            {
 | 
			
		||||
                XPen pen = GetPen(lineWidth);
 | 
			
		||||
                _gfx.DrawRectangle(pen, xPosition, yPosition, width, height);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        XPen GetPen(XUnit width)
 | 
			
		||||
        {
 | 
			
		||||
            if (width == 0)
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            XPen pen = new XPen(GetColor(), width);
 | 
			
		||||
            switch (_lineFormat.DashStyle)
 | 
			
		||||
            {
 | 
			
		||||
                case DashStyle.Dash:
 | 
			
		||||
                    pen.DashStyle = XDashStyle.Dash;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case DashStyle.DashDot:
 | 
			
		||||
                    pen.DashStyle = XDashStyle.DashDot;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case DashStyle.DashDotDot:
 | 
			
		||||
                    pen.DashStyle = XDashStyle.DashDotDot;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case DashStyle.Solid:
 | 
			
		||||
                    pen.DashStyle = XDashStyle.Solid;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case DashStyle.SquareDot:
 | 
			
		||||
                    pen.DashStyle = XDashStyle.Dot;
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            return pen;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        readonly LineFormat _lineFormat;
 | 
			
		||||
        readonly XGraphics _gfx;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										125
									
								
								MigraDoc.Rendering/Rendering/NumberFormatter.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								MigraDoc.Rendering/Rendering/NumberFormatter.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,125 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Globalization;
 | 
			
		||||
using MigraDoc.Rendering.Resources;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Formats numbers roman or with letters.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class NumberFormatter
 | 
			
		||||
    {
 | 
			
		||||
        public static string Format(int number, string format)
 | 
			
		||||
        {
 | 
			
		||||
            switch (format)
 | 
			
		||||
            {
 | 
			
		||||
                case "ROMAN":
 | 
			
		||||
                    return AsRoman(number, false);
 | 
			
		||||
 | 
			
		||||
                case "roman":
 | 
			
		||||
                    return AsRoman(number, true);
 | 
			
		||||
 | 
			
		||||
                case "ALPHABETIC":
 | 
			
		||||
                    return AsLetters(number, false);
 | 
			
		||||
 | 
			
		||||
                case "alphabetic":
 | 
			
		||||
                    return AsLetters(number, true);
 | 
			
		||||
            }
 | 
			
		||||
            return number.ToString(CultureInfo.InvariantCulture);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        static string AsRoman(int number, bool lowercase)
 | 
			
		||||
        {
 | 
			
		||||
            if (Math.Abs(number) > 32768)
 | 
			
		||||
            {
 | 
			
		||||
                Debug.WriteLine(Messages2.NumberTooLargeForRoman(number), "warning");
 | 
			
		||||
                return number.ToString(CultureInfo.InvariantCulture);
 | 
			
		||||
            }
 | 
			
		||||
            if (number == 0)
 | 
			
		||||
                return "0";
 | 
			
		||||
 | 
			
		||||
            string res = "";
 | 
			
		||||
            if (number < 0)
 | 
			
		||||
                res += "-";
 | 
			
		||||
 | 
			
		||||
            number = Math.Abs(number);
 | 
			
		||||
 | 
			
		||||
            string[] roman;
 | 
			
		||||
            if (lowercase)
 | 
			
		||||
                roman = new string[] { "m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv", "i" };
 | 
			
		||||
            else
 | 
			
		||||
                roman = new string[] { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
 | 
			
		||||
 | 
			
		||||
            int[] numberValues = new int[] { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < numberValues.Length; ++i)
 | 
			
		||||
            {
 | 
			
		||||
                while (number >= numberValues[i])
 | 
			
		||||
                {
 | 
			
		||||
                    res += roman[i];
 | 
			
		||||
                    number -= numberValues[i];
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return res;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        static string AsLetters(int number, bool lowercase)
 | 
			
		||||
        {
 | 
			
		||||
            if (Math.Abs(number) > 32768)
 | 
			
		||||
            {
 | 
			
		||||
                Debug.WriteLine(Messages2.NumberTooLargeForLetters(number));
 | 
			
		||||
                return number.ToString();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (number == 0)
 | 
			
		||||
                return "0";
 | 
			
		||||
 | 
			
		||||
            string str = "";
 | 
			
		||||
            if (number < 0)
 | 
			
		||||
                str += "-";
 | 
			
		||||
 | 
			
		||||
            number = Math.Abs(number);
 | 
			
		||||
            char cr;
 | 
			
		||||
            if (lowercase)
 | 
			
		||||
                cr = (char)('a' + (number - 1) % 26);
 | 
			
		||||
            else
 | 
			
		||||
                cr = (char)('A' + (number - 1) % 26);
 | 
			
		||||
 | 
			
		||||
            for (int n = 0; n <= (number - 1) / 26; ++n)
 | 
			
		||||
                str += cr;
 | 
			
		||||
 | 
			
		||||
            return str;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										68
									
								
								MigraDoc.Rendering/Rendering/PageBreakFormatInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								MigraDoc.Rendering/Rendering/PageBreakFormatInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Formatting information for a page break.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public sealed class PageBreakFormatInfo : FormatInfo
 | 
			
		||||
    {
 | 
			
		||||
        public override bool EndingIsComplete
 | 
			
		||||
        {
 | 
			
		||||
            get { return true; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool IsComplete
 | 
			
		||||
        {
 | 
			
		||||
            get { return true; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool IsEmpty
 | 
			
		||||
        {
 | 
			
		||||
            get { return false; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool IsEnding
 | 
			
		||||
        {
 | 
			
		||||
            get { return true; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool IsStarting
 | 
			
		||||
        {
 | 
			
		||||
            get { return true; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool StartingIsComplete
 | 
			
		||||
        {
 | 
			
		||||
            get { return true; }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										63
									
								
								MigraDoc.Rendering/Rendering/PageBreakRenderInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								MigraDoc.Rendering/Rendering/PageBreakRenderInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Rendering information for page breaks.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public sealed class PageBreakRenderInfo : RenderInfo
 | 
			
		||||
    {
 | 
			
		||||
        public PageBreakRenderInfo()
 | 
			
		||||
        { }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the format information in a specific derived type. For a table, for example, this will be a TableFormatInfo with information about the first and last row showing on a page.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public override FormatInfo FormatInfo
 | 
			
		||||
        {
 | 
			
		||||
            get { return _pageBreakFormatInfo; }
 | 
			
		||||
            set { _pageBreakFormatInfo = (PageBreakFormatInfo)value; }
 | 
			
		||||
        }
 | 
			
		||||
        PageBreakFormatInfo _pageBreakFormatInfo;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the document object to which the layout information applies. Use the Tag property of DocumentObject to identify an object.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public override DocumentObject DocumentObject
 | 
			
		||||
        {
 | 
			
		||||
            get { return _pageBreak; }
 | 
			
		||||
            set { _pageBreak = (PageBreak)value; }
 | 
			
		||||
        }
 | 
			
		||||
        PageBreak _pageBreak;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										92
									
								
								MigraDoc.Rendering/Rendering/PageBreakRenderer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								MigraDoc.Rendering/Rendering/PageBreakRenderer.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Renders a page break to an XGraphics object.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class PageBreakRenderer : Renderer
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a ParagraphRenderer object for formatting.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="gfx">The XGraphics object to do measurements on.</param>
 | 
			
		||||
        /// <param name="pageBreak">The page break.</param>
 | 
			
		||||
        /// <param name="fieldInfos">The field infos.</param>
 | 
			
		||||
        public PageBreakRenderer(XGraphics gfx, PageBreak pageBreak, FieldInfos fieldInfos)
 | 
			
		||||
            : base(gfx, pageBreak, fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _pageBreak = pageBreak;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a ParagraphRenderer object for rendering.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="gfx">The XGraphics object to render on.</param>
 | 
			
		||||
        /// <param name="renderInfo">The render info object containing information necessary for rendering.</param>
 | 
			
		||||
        /// <param name="fieldInfos">The field infos.</param>
 | 
			
		||||
        public PageBreakRenderer(XGraphics gfx, RenderInfo renderInfo, FieldInfos fieldInfos)
 | 
			
		||||
            : base(gfx, renderInfo, fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _renderInfo = renderInfo;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void Format(Area area, FormatInfo previousFormatInfo)
 | 
			
		||||
        {
 | 
			
		||||
            PageBreakRenderInfo pbRenderInfo = new PageBreakRenderInfo();
 | 
			
		||||
            pbRenderInfo.FormatInfo = new PageBreakFormatInfo();
 | 
			
		||||
            _renderInfo = pbRenderInfo;
 | 
			
		||||
 | 
			
		||||
            pbRenderInfo.LayoutInfo.PageBreakBefore = true;
 | 
			
		||||
            pbRenderInfo.LayoutInfo.ContentArea = new Rectangle(area.Y, area.Y, 0, 0);
 | 
			
		||||
            pbRenderInfo.DocumentObject = _pageBreak;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void Render()
 | 
			
		||||
        {
 | 
			
		||||
            // Nothing to do here.
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override LayoutInfo InitialLayoutInfo
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                LayoutInfo layoutInfo = new LayoutInfo();
 | 
			
		||||
                layoutInfo.PageBreakBefore = true;
 | 
			
		||||
                return layoutInfo;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        readonly PageBreak _pageBreak;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										79
									
								
								MigraDoc.Rendering/Rendering/PageInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								MigraDoc.Rendering/Rendering/PageInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using PdfSharp;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Provides information necessary to render the page.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class PageInfo
 | 
			
		||||
    {
 | 
			
		||||
        public PageInfo(XUnit width, XUnit height, PageOrientation orientation)
 | 
			
		||||
        {
 | 
			
		||||
            _width = width;
 | 
			
		||||
            _height = height;
 | 
			
		||||
            _orientation = orientation;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the with of the described page as specified in Document.PageSetup, i.e. the orientation
 | 
			
		||||
        /// is not taken into account.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public XUnit Width
 | 
			
		||||
        {
 | 
			
		||||
            get { return _width; }
 | 
			
		||||
        }
 | 
			
		||||
        private readonly XUnit _width;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the height of the described page as specified in Document.PageSetup, i.e. the orientation
 | 
			
		||||
        /// is not taken into account.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public XUnit Height
 | 
			
		||||
        {
 | 
			
		||||
            get { return _height; }
 | 
			
		||||
        }
 | 
			
		||||
        private readonly XUnit _height;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the orientation of the described page as specified in Document.PageSetup.
 | 
			
		||||
        /// The value has no influence on the properties Width or Height, i.e. if the result is PageOrientation.Landscape
 | 
			
		||||
        /// you must exchange the values of Width or Height to get the real page size.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public PageOrientation Orientation
 | 
			
		||||
        {
 | 
			
		||||
            get { return _orientation; }
 | 
			
		||||
        }
 | 
			
		||||
        private readonly PageOrientation _orientation;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										187
									
								
								MigraDoc.Rendering/Rendering/ParagraphFormatInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								MigraDoc.Rendering/Rendering/ParagraphFormatInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,187 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Shapes;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Vertical measurements of a paragraph line.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public struct VerticalLineInfo
 | 
			
		||||
    {
 | 
			
		||||
        public VerticalLineInfo(XUnit height, XUnit descent, XUnit inherentlineSpace)
 | 
			
		||||
        {
 | 
			
		||||
            Height = height;
 | 
			
		||||
            Descent = descent;
 | 
			
		||||
            InherentlineSpace = inherentlineSpace;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public XUnit Height;
 | 
			
		||||
 | 
			
		||||
        public XUnit Descent;
 | 
			
		||||
 | 
			
		||||
        public XUnit InherentlineSpace;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Line info object used by the paragraph format info.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public struct LineInfo
 | 
			
		||||
    {
 | 
			
		||||
        public ParagraphIterator StartIter;
 | 
			
		||||
        public ParagraphIterator EndIter;
 | 
			
		||||
        public XUnit WordsWidth;
 | 
			
		||||
        public XUnit LineWidth;
 | 
			
		||||
        public int BlankCount;
 | 
			
		||||
        public VerticalLineInfo Vertical;
 | 
			
		||||
        public List<TabOffset> TabOffsets;
 | 
			
		||||
        public bool ReMeasureLine;
 | 
			
		||||
        public DocumentObject LastTab;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Formatting information for a paragraph.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public sealed class ParagraphFormatInfo : FormatInfo
 | 
			
		||||
    {
 | 
			
		||||
        public ParagraphFormatInfo()
 | 
			
		||||
        { }
 | 
			
		||||
 | 
			
		||||
        public LineInfo GetLineInfo(int lineIdx)
 | 
			
		||||
        {
 | 
			
		||||
            return _lineInfos[lineIdx];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public LineInfo GetLastLineInfo()
 | 
			
		||||
        {
 | 
			
		||||
            return _lineInfos[LineCount - 1];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public LineInfo GetFirstLineInfo()
 | 
			
		||||
        {
 | 
			
		||||
            return _lineInfos[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void AddLineInfo(LineInfo lineInfo)
 | 
			
		||||
        {
 | 
			
		||||
            _lineInfos.Add(lineInfo);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int LineCount
 | 
			
		||||
        {
 | 
			
		||||
            get { return _lineInfos.Count; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="mergeInfo"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public void Append(FormatInfo mergeInfo)
 | 
			
		||||
        {
 | 
			
		||||
            ParagraphFormatInfo formatInfo = (ParagraphFormatInfo)mergeInfo;
 | 
			
		||||
            _lineInfos.AddRange(formatInfo._lineInfos);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Indicates whether the paragraph is ending.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>True if the paragraph is ending.</returns>
 | 
			
		||||
        public override bool IsEnding
 | 
			
		||||
        {
 | 
			
		||||
            get { return _isEnding; }
 | 
			
		||||
        }
 | 
			
		||||
        public bool _isEnding;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Indicates whether the paragraph is starting.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>True if the paragraph is starting.</returns>
 | 
			
		||||
        public override bool IsStarting
 | 
			
		||||
        {
 | 
			
		||||
            get { return _isStarting; }
 | 
			
		||||
        }
 | 
			
		||||
        public bool _isStarting;
 | 
			
		||||
 | 
			
		||||
        public override bool IsComplete
 | 
			
		||||
        {
 | 
			
		||||
            get { return _isStarting && _isEnding; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool IsEmpty
 | 
			
		||||
        {
 | 
			
		||||
            get { return _lineInfos.Count == 0; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool StartingIsComplete
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                if (_widowControl)
 | 
			
		||||
                    return (IsComplete || (_isStarting && _lineInfos.Count >= 2));
 | 
			
		||||
                return _isStarting;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool _widowControl;
 | 
			
		||||
 | 
			
		||||
        public override bool EndingIsComplete
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                if (_widowControl)
 | 
			
		||||
                    return (IsComplete || (_isEnding && _lineInfos.Count >= 2));
 | 
			
		||||
                return _isEnding;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void RemoveEnding()
 | 
			
		||||
        {
 | 
			
		||||
            if (!IsEmpty)
 | 
			
		||||
            {
 | 
			
		||||
                if (_widowControl && _isEnding && LineCount >= 2)
 | 
			
		||||
                    _lineInfos.RemoveAt(LineCount - 2);
 | 
			
		||||
                if (LineCount > 0)
 | 
			
		||||
                    _lineInfos.RemoveAt(LineCount - 1);
 | 
			
		||||
 | 
			
		||||
                _isEnding = false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string ListSymbol;
 | 
			
		||||
        public XFont ListFont;
 | 
			
		||||
        public Dictionary<Image, RenderInfo> ImageRenderInfos;
 | 
			
		||||
        readonly List<LineInfo> _lineInfos = new List<LineInfo>();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										286
									
								
								MigraDoc.Rendering/Rendering/ParagraphIterator.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										286
									
								
								MigraDoc.Rendering/Rendering/ParagraphIterator.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,286 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Iterates sequentially through the elements of a paragraph.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class ParagraphIterator
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a paragraph iterator pointing on the given paragraph elements object.
 | 
			
		||||
        /// Paragraph iterators received from this paragraph iterator relate to this root node.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="rootNode">The root node for the paragraph iterator.</param>
 | 
			
		||||
        public ParagraphIterator(ParagraphElements rootNode)
 | 
			
		||||
        {
 | 
			
		||||
            _rootNode = rootNode;
 | 
			
		||||
            _current = rootNode;
 | 
			
		||||
            _positionIndices = new List<int>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a paragraph iterator given the root node, its position in the object tree and the current object
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="rootNode">The node the position indices relate to.</param>
 | 
			
		||||
        /// <param name="current">The element the iterator shall point to.</param>
 | 
			
		||||
        /// <param name="indices">The position of the paragraph iterator in terms of element indices.</param>
 | 
			
		||||
        private ParagraphIterator(ParagraphElements rootNode, DocumentObject current, List<int> indices)
 | 
			
		||||
        {
 | 
			
		||||
            _rootNode = rootNode;
 | 
			
		||||
            _positionIndices = indices;
 | 
			
		||||
            _current = current;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Determines whether this iterator is the first leaf of the root node.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool IsFirstLeaf
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                if (!(_current is DocumentElements))
 | 
			
		||||
                {
 | 
			
		||||
                    ParagraphIterator prevIter = GetPreviousLeaf();
 | 
			
		||||
                    return prevIter == null;
 | 
			
		||||
                }
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Determines whether this iterator is the last leaf of the document object tree.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool IsLastLeaf
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                if (!(_current is DocumentElements))
 | 
			
		||||
                {
 | 
			
		||||
                    ParagraphIterator nextIter = GetNextLeaf();
 | 
			
		||||
                    return nextIter == null;
 | 
			
		||||
                }
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the document object this instance ponits to.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public DocumentObject Current
 | 
			
		||||
        {
 | 
			
		||||
            get { return _current; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the last leaf of the document object tree.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>The paragraph iterator pointing to the last leaf in the document object tree.</returns>
 | 
			
		||||
        public ParagraphIterator GetLastLeaf()
 | 
			
		||||
        {
 | 
			
		||||
            if (_rootNode.Count == 0)
 | 
			
		||||
                return null;
 | 
			
		||||
            return SeekLastLeaf();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the first leaf of the element tree.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>The paragraph iterator pointing to the first leaf in the element tree.</returns>
 | 
			
		||||
        public ParagraphIterator GetFirstLeaf()
 | 
			
		||||
        {
 | 
			
		||||
            if (_rootNode.Count == 0)
 | 
			
		||||
                return null;
 | 
			
		||||
            return SeekFirstLeaf();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Returns the next iterator in the tree pointing to a leaf.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <remarks>This function is intended to receive the renderable objects of a paragraph.
 | 
			
		||||
        /// Thus, empty ParagraphElement objects (which are collections) don't count as leafs.</remarks>
 | 
			
		||||
        public ParagraphIterator GetNextLeaf()
 | 
			
		||||
        {
 | 
			
		||||
            //Move up to appropriate parent element
 | 
			
		||||
            ParagraphIterator parIterator = GetParentIterator();
 | 
			
		||||
            if (parIterator == null)
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            int elementIndex = LastIndex;
 | 
			
		||||
            ParagraphElements parEls = (ParagraphElements)parIterator._current;
 | 
			
		||||
            while (elementIndex == parEls.Count - 1)
 | 
			
		||||
            {
 | 
			
		||||
                elementIndex = parIterator.LastIndex;
 | 
			
		||||
                parIterator = parIterator.GetParentIterator();
 | 
			
		||||
                if (parIterator == null)
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                parEls = (ParagraphElements)parIterator._current;
 | 
			
		||||
            }
 | 
			
		||||
            if (parIterator == null)
 | 
			
		||||
                return null;
 | 
			
		||||
            int newIndex = elementIndex + 1;
 | 
			
		||||
            if (newIndex >= parEls.Count)
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            List<int> indices = new List<int>(parIterator._positionIndices); //(Array_List)parIterator.positionIndices.Clone();
 | 
			
		||||
            indices.Add(newIndex);
 | 
			
		||||
            DocumentObject obj = GetNodeObject(parEls[newIndex]);
 | 
			
		||||
            ParagraphIterator iterator = new ParagraphIterator(_rootNode, obj, indices);
 | 
			
		||||
            return iterator.SeekFirstLeaf();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the object a paragraph iterator shall point to.
 | 
			
		||||
        /// Only ParagraphElements and renderable objects are allowed.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="obj">The object to select the node object for.</param>
 | 
			
		||||
        /// <returns>The object a paragraph iterator shall point to.</returns>
 | 
			
		||||
        private DocumentObject GetNodeObject(DocumentObject obj)
 | 
			
		||||
        {
 | 
			
		||||
            if (obj is FormattedText)
 | 
			
		||||
                return ((FormattedText)obj).Elements;
 | 
			
		||||
            if (obj is Hyperlink)
 | 
			
		||||
                return ((Hyperlink)obj).Elements;
 | 
			
		||||
            return obj;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Returns the previous iterator to a leaf in the document object tree pointing.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>The previous leaf, null if none exists.</returns>
 | 
			
		||||
        public ParagraphIterator GetPreviousLeaf()
 | 
			
		||||
        {
 | 
			
		||||
            //Move up to appropriate parent element
 | 
			
		||||
            ParagraphIterator parIterator = GetParentIterator();
 | 
			
		||||
            if (parIterator == null)
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            int elementIndex = LastIndex;
 | 
			
		||||
            ParagraphElements parEls = (ParagraphElements)parIterator._current;
 | 
			
		||||
            while (elementIndex == 0)
 | 
			
		||||
            {
 | 
			
		||||
                elementIndex = parIterator.LastIndex;
 | 
			
		||||
                parIterator = parIterator.GetParentIterator();
 | 
			
		||||
                if (parIterator == null)
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                parEls = (ParagraphElements)parIterator._current;
 | 
			
		||||
            }
 | 
			
		||||
            if (parIterator == null)
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            int newIndex = elementIndex - 1;
 | 
			
		||||
            if (newIndex < 0)
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            List<int> indices = new List<int>(parIterator._positionIndices);//(Array_List)parIterator.positionIndices.Clone();
 | 
			
		||||
            indices.Add(newIndex);
 | 
			
		||||
 | 
			
		||||
            DocumentObject obj = GetNodeObject(parEls[newIndex]);
 | 
			
		||||
            ParagraphIterator iterator = new ParagraphIterator(_rootNode, obj, indices);
 | 
			
		||||
            return iterator.SeekLastLeaf();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private ParagraphIterator SeekLastLeaf()
 | 
			
		||||
        {
 | 
			
		||||
            DocumentObject obj = Current;
 | 
			
		||||
            if (!(obj is ParagraphElements))
 | 
			
		||||
                return this;
 | 
			
		||||
 | 
			
		||||
            List<int> indices = new List<int>(_positionIndices);
 | 
			
		||||
 | 
			
		||||
            while (obj is ParagraphElements)
 | 
			
		||||
            {
 | 
			
		||||
                ParagraphElements parEls = (ParagraphElements)obj;
 | 
			
		||||
                if (((ParagraphElements)obj).Count == 0)
 | 
			
		||||
                    return new ParagraphIterator(_rootNode, obj, indices);
 | 
			
		||||
 | 
			
		||||
                int idx = ((ParagraphElements)obj).Count - 1;
 | 
			
		||||
                indices.Add(idx);
 | 
			
		||||
                obj = GetNodeObject(parEls[idx]);
 | 
			
		||||
            }
 | 
			
		||||
            return new ParagraphIterator(_rootNode, obj, indices);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the leftmost leaf within the hierarchy.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>The searched leaf.</returns>
 | 
			
		||||
        ParagraphIterator SeekFirstLeaf()
 | 
			
		||||
        {
 | 
			
		||||
            DocumentObject obj = Current;
 | 
			
		||||
            if (!(obj is ParagraphElements))
 | 
			
		||||
                return this;
 | 
			
		||||
            List<int> indices = new List<int>(_positionIndices);
 | 
			
		||||
 | 
			
		||||
            while (obj is ParagraphElements)
 | 
			
		||||
            {
 | 
			
		||||
                ParagraphElements parEls = (ParagraphElements)obj;
 | 
			
		||||
                if (parEls.Count == 0)
 | 
			
		||||
                    return new ParagraphIterator(_rootNode, obj, indices);
 | 
			
		||||
 | 
			
		||||
                indices.Add(0);
 | 
			
		||||
                obj = GetNodeObject(parEls[0]);
 | 
			
		||||
            }
 | 
			
		||||
            return new ParagraphIterator(_rootNode, obj, indices);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private ParagraphIterator GetParentIterator()
 | 
			
		||||
        {
 | 
			
		||||
            if (_positionIndices.Count == 0)
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            List<int> indices = new List<int>(_positionIndices);
 | 
			
		||||
            indices.RemoveAt(indices.Count - 1);
 | 
			
		||||
            DocumentObject parent = DocumentRelations.GetParentOfType(_current, typeof(ParagraphElements));
 | 
			
		||||
            return new ParagraphIterator(_rootNode, parent, indices);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private int LastIndex
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                if (_positionIndices.Count == 0)
 | 
			
		||||
                    return -1;
 | 
			
		||||
                return _positionIndices[_positionIndices.Count - 1];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        readonly ParagraphElements _rootNode;
 | 
			
		||||
        readonly List<int> _positionIndices;
 | 
			
		||||
        readonly DocumentObject _current;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										71
									
								
								MigraDoc.Rendering/Rendering/ParagraphRenderInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								MigraDoc.Rendering/Rendering/ParagraphRenderInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Represents rendering information for a paragraph.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public sealed class ParagraphRenderInfo : RenderInfo
 | 
			
		||||
    {
 | 
			
		||||
        public ParagraphRenderInfo()
 | 
			
		||||
        { }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the format information in a specific derived type. For a table, for example, this will be a TableFormatInfo with information about the first and last row showing on a page.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public override FormatInfo FormatInfo
 | 
			
		||||
        {
 | 
			
		||||
            get { return _formatInfo; }
 | 
			
		||||
            set { _formatInfo = (ParagraphFormatInfo)value; }
 | 
			
		||||
        }
 | 
			
		||||
        ParagraphFormatInfo _formatInfo = new ParagraphFormatInfo();
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the document object to which the layout information applies. Use the Tag property of DocumentObject to identify an object.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public override DocumentObject DocumentObject
 | 
			
		||||
        {
 | 
			
		||||
            get { return _paragraph; }
 | 
			
		||||
            set { _paragraph = (Paragraph)value; }
 | 
			
		||||
        }
 | 
			
		||||
        Paragraph _paragraph;
 | 
			
		||||
 | 
			
		||||
        public override void RemoveEnding()
 | 
			
		||||
        {
 | 
			
		||||
            ParagraphFormatInfo pfInfo = (ParagraphFormatInfo)FormatInfo;
 | 
			
		||||
            pfInfo.RemoveEnding();
 | 
			
		||||
            Area contentArea = LayoutInfo.ContentArea;
 | 
			
		||||
            contentArea.Height -= LayoutInfo.TrailingHeight;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2545
									
								
								MigraDoc.Rendering/Rendering/ParagraphRenderer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2545
									
								
								MigraDoc.Rendering/Rendering/ParagraphRenderer.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										319
									
								
								MigraDoc.Rendering/Rendering/PdfDocumentRenderer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										319
									
								
								MigraDoc.Rendering/Rendering/PdfDocumentRenderer.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,319 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
using MigraDoc.Rendering.Resources;
 | 
			
		||||
using PdfSharp.Pdf;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Provides the functionality to convert a MigraDoc document into PDF.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class PdfDocumentRenderer
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the PdfDocumentRenderer class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public PdfDocumentRenderer()
 | 
			
		||||
        {
 | 
			
		||||
            //_unicode = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="PdfDocumentRenderer"/> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="unicode">If true Unicode encoding is used for all text. If false, WinAnsi encoding is used.</param>
 | 
			
		||||
        public PdfDocumentRenderer(bool unicode)
 | 
			
		||||
        {
 | 
			
		||||
            _unicode = unicode;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="PdfDocumentRenderer" /> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="unicode">If true Unicode encoding is used for all text. If false, WinAnsi encoding is used.</param>
 | 
			
		||||
        /// <param name="fontEmbedding">Obsolete parameter.</param>
 | 
			
		||||
        [Obsolete("Must not specify an embedding option anymore.")]
 | 
			
		||||
        public PdfDocumentRenderer(bool unicode, PdfFontEmbedding fontEmbedding)
 | 
			
		||||
        {
 | 
			
		||||
            _unicode = unicode;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets a value indicating whether the text is rendered as Unicode.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public bool Unicode
 | 
			
		||||
        {
 | 
			
		||||
            get { return _unicode; }
 | 
			
		||||
        }
 | 
			
		||||
        readonly bool _unicode;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the language.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <value>The language.</value>
 | 
			
		||||
        public string Language
 | 
			
		||||
        {
 | 
			
		||||
            get { return _language; }
 | 
			
		||||
            set { _language = value; }
 | 
			
		||||
        }
 | 
			
		||||
        string _language = String.Empty;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Set the MigraDoc document to be rendered by this printer.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public Document Document
 | 
			
		||||
        {
 | 
			
		||||
            set
 | 
			
		||||
            {
 | 
			
		||||
                _document = null;
 | 
			
		||||
                value.BindToRenderer(this);
 | 
			
		||||
                _document = value;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Document _document;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets a document renderer.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <remarks>
 | 
			
		||||
        /// A document renderer is automatically created and prepared
 | 
			
		||||
        /// when printing before this property was set.
 | 
			
		||||
        /// </remarks>
 | 
			
		||||
        public DocumentRenderer DocumentRenderer
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                if (_documentRenderer == null)
 | 
			
		||||
                    PrepareDocumentRenderer();
 | 
			
		||||
                return _documentRenderer;
 | 
			
		||||
            }
 | 
			
		||||
            set { _documentRenderer = value; }
 | 
			
		||||
        }
 | 
			
		||||
        DocumentRenderer _documentRenderer;
 | 
			
		||||
 | 
			
		||||
        void PrepareDocumentRenderer()
 | 
			
		||||
        {
 | 
			
		||||
            PrepareDocumentRenderer(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void PrepareDocumentRenderer(bool prepareCompletely)
 | 
			
		||||
        {
 | 
			
		||||
            if (_document == null)
 | 
			
		||||
#if !NETFX_CORE
 | 
			
		||||
                throw new InvalidOperationException(Messages2.PropertyNotSetBefore("DocumentRenderer", MethodBase.GetCurrentMethod().Name));
 | 
			
		||||
#else
 | 
			
		||||
                throw new InvalidOperationException(Messages2.PropertyNotSetBefore("DocumentRenderer", "PrepareDocumentRenderer"));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
            if (_documentRenderer == null)
 | 
			
		||||
            {
 | 
			
		||||
                _documentRenderer = new DocumentRenderer(_document);
 | 
			
		||||
                _documentRenderer.WorkingDirectory = _workingDirectory;
 | 
			
		||||
            }
 | 
			
		||||
            if (prepareCompletely && _documentRenderer.FormattedDocument == null)
 | 
			
		||||
            {
 | 
			
		||||
                _documentRenderer.PrepareDocument();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Renders the document into a PdfDocument containing all pages of the document.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void RenderDocument()
 | 
			
		||||
        {
 | 
			
		||||
#if true
 | 
			
		||||
            PrepareRenderPages();
 | 
			
		||||
#else
 | 
			
		||||
            if (this.documentRenderer == null)
 | 
			
		||||
                PrepareDocumentRenderer();
 | 
			
		||||
 | 
			
		||||
            if (this.pdfDocument == null)
 | 
			
		||||
            {
 | 
			
		||||
                this.pdfDocument = new PdfDocument();
 | 
			
		||||
                this.pdfDocument.Info.Creator = VersionInfo.Creator;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            WriteDocumentInformation();
 | 
			
		||||
#endif
 | 
			
		||||
            RenderPages(1, _documentRenderer.FormattedDocument.PageCount);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Renders the document into a PdfDocument containing all pages of the document.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void PrepareRenderPages()
 | 
			
		||||
        {
 | 
			
		||||
            //if (this.documentRenderer == null)
 | 
			
		||||
            PrepareDocumentRenderer(true);
 | 
			
		||||
 | 
			
		||||
            if (_pdfDocument == null)
 | 
			
		||||
            {
 | 
			
		||||
                _pdfDocument = CreatePdfDocument();
 | 
			
		||||
                if (_document.UseCmykColor)
 | 
			
		||||
                    _pdfDocument.Options.ColorMode = PdfColorMode.Cmyk;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            WriteDocumentInformation();
 | 
			
		||||
            //RenderPages(1, this.documentRenderer.FormattedDocument.PageCount);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the count of pages.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public int PageCount
 | 
			
		||||
        {
 | 
			
		||||
            get { return _documentRenderer.FormattedDocument.PageCount; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Saves the PdfDocument to the specified path. If a file already exists, it will be overwritten.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void Save(string path)
 | 
			
		||||
        {
 | 
			
		||||
            if (path == null)
 | 
			
		||||
                throw new ArgumentNullException("path");
 | 
			
		||||
 | 
			
		||||
            if (path == "")
 | 
			
		||||
                throw new ArgumentException("PDF file Path must not be empty");
 | 
			
		||||
 | 
			
		||||
            if (_workingDirectory != null)
 | 
			
		||||
                path = Path.Combine(_workingDirectory, path);
 | 
			
		||||
 | 
			
		||||
            _pdfDocument.Save(path);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Saves the PDF document to the specified stream.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void Save(Stream stream, bool closeStream)
 | 
			
		||||
        {
 | 
			
		||||
            _pdfDocument.Save(stream, closeStream);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Renders the specified page range.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="startPage">The first page to print.</param>
 | 
			
		||||
        /// <param name="endPage">The last page to print</param>
 | 
			
		||||
        public void RenderPages(int startPage, int endPage)
 | 
			
		||||
        {
 | 
			
		||||
            if (startPage < 1)
 | 
			
		||||
                throw new ArgumentOutOfRangeException("startPage");
 | 
			
		||||
 | 
			
		||||
            if (endPage > _documentRenderer.FormattedDocument.PageCount)
 | 
			
		||||
                throw new ArgumentOutOfRangeException("endPage");
 | 
			
		||||
 | 
			
		||||
            if (_documentRenderer == null)
 | 
			
		||||
                PrepareDocumentRenderer();
 | 
			
		||||
 | 
			
		||||
            if (_pdfDocument == null)
 | 
			
		||||
                _pdfDocument = CreatePdfDocument();
 | 
			
		||||
 | 
			
		||||
            _documentRenderer._printDate = DateTime.Now;
 | 
			
		||||
            for (int pageNr = startPage; pageNr <= endPage; ++pageNr)
 | 
			
		||||
            {
 | 
			
		||||
                PdfPage pdfPage = _pdfDocument.AddPage();
 | 
			
		||||
                PageInfo pageInfo = _documentRenderer.FormattedDocument.GetPageInfo(pageNr);
 | 
			
		||||
                pdfPage.Width = pageInfo.Width;
 | 
			
		||||
                pdfPage.Height = pageInfo.Height;
 | 
			
		||||
                pdfPage.Orientation = pageInfo.Orientation;
 | 
			
		||||
 | 
			
		||||
                using (XGraphics gfx = XGraphics.FromPdfPage(pdfPage))
 | 
			
		||||
                {
 | 
			
		||||
                    gfx.MUH = _unicode ? PdfFontEncoding.Unicode : PdfFontEncoding.WinAnsi;
 | 
			
		||||
                    _documentRenderer.RenderPage(gfx, pageNr);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets a working directory for the printing process.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public string WorkingDirectory
 | 
			
		||||
        {
 | 
			
		||||
            get { return _workingDirectory; }
 | 
			
		||||
            set { _workingDirectory = value; }
 | 
			
		||||
        }
 | 
			
		||||
        string _workingDirectory;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the PDF document to render on.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <remarks>A PDF document in memory is automatically created when printing before this property was set.</remarks>
 | 
			
		||||
        public PdfDocument PdfDocument
 | 
			
		||||
        {
 | 
			
		||||
            get { return _pdfDocument; }
 | 
			
		||||
            set { _pdfDocument = value; }
 | 
			
		||||
        }
 | 
			
		||||
        PdfDocument _pdfDocument;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Writes document information like author and subject to the PDF document.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void WriteDocumentInformation()
 | 
			
		||||
        {
 | 
			
		||||
            if (!_document.IsNull("Info"))
 | 
			
		||||
            {
 | 
			
		||||
                DocumentInfo docInfo = _document.Info;
 | 
			
		||||
                PdfDocumentInformation pdfInfo = _pdfDocument.Info;
 | 
			
		||||
 | 
			
		||||
                if (!docInfo.IsNull("Author"))
 | 
			
		||||
                    pdfInfo.Author = docInfo.Author;
 | 
			
		||||
 | 
			
		||||
                if (!docInfo.IsNull("Keywords"))
 | 
			
		||||
                    pdfInfo.Keywords = docInfo.Keywords;
 | 
			
		||||
 | 
			
		||||
                if (!docInfo.IsNull("Subject"))
 | 
			
		||||
                    pdfInfo.Subject = docInfo.Subject;
 | 
			
		||||
 | 
			
		||||
                if (!docInfo.IsNull("Title"))
 | 
			
		||||
                    pdfInfo.Title = docInfo.Title;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Creates a new PDF document.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        PdfDocument CreatePdfDocument()
 | 
			
		||||
        {
 | 
			
		||||
            PdfDocument document = new PdfDocument();
 | 
			
		||||
            document.Info.Creator = "damienbod";
 | 
			
		||||
            if (!String.IsNullOrEmpty(_language))
 | 
			
		||||
                document.Language = _language;
 | 
			
		||||
            return document;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										207
									
								
								MigraDoc.Rendering/Rendering/PdfPrinter.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								MigraDoc.Rendering/Rendering/PdfPrinter.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,207 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
#if DELETED
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Provides the functionality to convert MigraDoc documents into PDF.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [Obsolete("Use class PdfDocumentRenderer.")]  // DELETE: 8/06
 | 
			
		||||
    public class PdfPrinter
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the PdfPrinter class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public PdfPrinter()
 | 
			
		||||
        { }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Set the MigraDoc document to be rendered by this printer.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public Document Document
 | 
			
		||||
        {
 | 
			
		||||
            set
 | 
			
		||||
            {
 | 
			
		||||
                _document = null;
 | 
			
		||||
                value.BindToRenderer(this);
 | 
			
		||||
                _document = value;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Document _document;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets a document renderer.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <remarks>
 | 
			
		||||
        /// A document renderer is automatically created and prepared
 | 
			
		||||
        /// when printing before this property was set.
 | 
			
		||||
        /// </remarks>
 | 
			
		||||
        public DocumentRenderer DocumentRenderer
 | 
			
		||||
        {
 | 
			
		||||
            get { return _documentRenderer; }
 | 
			
		||||
            set { _documentRenderer = value; }
 | 
			
		||||
        }
 | 
			
		||||
        DocumentRenderer _documentRenderer;
 | 
			
		||||
 | 
			
		||||
        void PrepareDocumentRenderer()
 | 
			
		||||
        {
 | 
			
		||||
            if (_document == null)
 | 
			
		||||
                throw new InvalidOperationException(Messages2.PropertyNotSetBefore("DocumentRenderer", MethodInfo.GetCurrentMethod().Name));
 | 
			
		||||
 | 
			
		||||
            _documentRenderer = new DocumentRenderer(_document);
 | 
			
		||||
            _documentRenderer.WorkingDirectory = this.workingDirectory;
 | 
			
		||||
            _documentRenderer.PrepareDocument();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Prints a PDF document containing all pages of the document.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void PrintDocument()
 | 
			
		||||
        {
 | 
			
		||||
            if (_documentRenderer == null)
 | 
			
		||||
                PrepareDocumentRenderer();
 | 
			
		||||
 | 
			
		||||
            if (_pdfDocument == null)
 | 
			
		||||
            {
 | 
			
		||||
                _pdfDocument = new PdfDocument();
 | 
			
		||||
                _pdfDocument.Info.Creator = VersionInfo.Creator;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            WriteDocumentInformation();
 | 
			
		||||
            PrintPages(1, _documentRenderer.FormattedDocument.PageCount);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Saves the PDF document to the specified path. If a file already exists, it will be overwritten.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void Save(string path)
 | 
			
		||||
        {
 | 
			
		||||
            if (path == null)
 | 
			
		||||
                throw new ArgumentNullException("path");
 | 
			
		||||
 | 
			
		||||
            if (path == "")
 | 
			
		||||
                throw new ArgumentException("PDF file Path must not be empty");
 | 
			
		||||
 | 
			
		||||
            if (this.workingDirectory != null)
 | 
			
		||||
                Path.Combine(this.workingDirectory, path);
 | 
			
		||||
 | 
			
		||||
            _pdfDocument.Save(path);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Saves the PDF document to the specified stream.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void Save(Stream stream, bool closeStream)
 | 
			
		||||
        {
 | 
			
		||||
            _pdfDocument.Save(stream, closeStream);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Prints the specified page range.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="startPage">The first page to print.</param>
 | 
			
		||||
        /// <param name="endPage">The last page to print</param>
 | 
			
		||||
        public void PrintPages(int startPage, int endPage)
 | 
			
		||||
        {
 | 
			
		||||
            if (startPage < 1)
 | 
			
		||||
                throw new ArgumentOutOfRangeException("startPage");
 | 
			
		||||
 | 
			
		||||
            if (endPage > _documentRenderer.FormattedDocument.PageCount)
 | 
			
		||||
                throw new ArgumentOutOfRangeException("endPage");
 | 
			
		||||
 | 
			
		||||
            if (_documentRenderer == null)
 | 
			
		||||
                PrepareDocumentRenderer();
 | 
			
		||||
 | 
			
		||||
            if (_pdfDocument == null)
 | 
			
		||||
            {
 | 
			
		||||
                _pdfDocument = new PdfDocument();
 | 
			
		||||
                _pdfDocument.Info.Creator = VersionInfo.Creator;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _documentRenderer._printDate = DateTime.Now;
 | 
			
		||||
            for (int pageNr = startPage; pageNr <= endPage; ++pageNr)
 | 
			
		||||
            {
 | 
			
		||||
                PdfPage pdfPage = _pdfDocument.AddPage();
 | 
			
		||||
                PageInfo pageInfo = _documentRenderer.FormattedDocument.GetPageInfo(pageNr);
 | 
			
		||||
                pdfPage.Width = pageInfo.Width;
 | 
			
		||||
                pdfPage.Height = pageInfo.Height;
 | 
			
		||||
                pdfPage.Orientation = pageInfo.Orientation;
 | 
			
		||||
                _documentRenderer.RenderPage(XGraphics.FromPdfPage(pdfPage), pageNr);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets a working directory for the printing process.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public string WorkingDirectory
 | 
			
		||||
        {
 | 
			
		||||
            get { return this.workingDirectory; }
 | 
			
		||||
            set { this.workingDirectory = value; }
 | 
			
		||||
        }
 | 
			
		||||
        string workingDirectory;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the PDF document to render on.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <remarks>A PDF document in memory is automatically created when printing before this property was set.</remarks>
 | 
			
		||||
        public PdfDocument PdfDocument
 | 
			
		||||
        {
 | 
			
		||||
            get { return _pdfDocument; }
 | 
			
		||||
            set { _pdfDocument = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Writes document information like author and subject to the PDF document.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        private void WriteDocumentInformation()
 | 
			
		||||
        {
 | 
			
		||||
            if (!_document.IsNull("Info"))
 | 
			
		||||
            {
 | 
			
		||||
                DocumentInfo docInfo = _document.Info;
 | 
			
		||||
                PdfDocumentInformation pdfInfo = _pdfDocument.Info;
 | 
			
		||||
 | 
			
		||||
                if (!docInfo.IsNull("Author"))
 | 
			
		||||
                    pdfInfo.Author = docInfo.Author;
 | 
			
		||||
 | 
			
		||||
                if (!docInfo.IsNull("Keywords"))
 | 
			
		||||
                    pdfInfo.Keywords = docInfo.Keywords;
 | 
			
		||||
 | 
			
		||||
                if (!docInfo.IsNull("Subject"))
 | 
			
		||||
                    pdfInfo.Subject = docInfo.Subject;
 | 
			
		||||
 | 
			
		||||
                if (!docInfo.IsNull("Title"))
 | 
			
		||||
                    pdfInfo.Title = docInfo.Title;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        PdfDocument _pdfDocument;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										81
									
								
								MigraDoc.Rendering/Rendering/RenderInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								MigraDoc.Rendering/Rendering/RenderInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Abstract base class for all classes that store rendering information.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public abstract class RenderInfo
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the format information in a specific derived type. For a table, for example, this will be a TableFormatInfo with information about the first and last row showing on a page.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public abstract FormatInfo FormatInfo { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the layout information.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public LayoutInfo LayoutInfo
 | 
			
		||||
        {
 | 
			
		||||
            get { return _layoutInfo; }
 | 
			
		||||
        }
 | 
			
		||||
        readonly LayoutInfo _layoutInfo = new LayoutInfo();
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the document object to which the layout information applies. Use the Tag property of DocumentObject to identify an object.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public abstract DocumentObject DocumentObject { get; set; }
 | 
			
		||||
 | 
			
		||||
        public virtual void RemoveEnding()
 | 
			
		||||
        {
 | 
			
		||||
            System.Diagnostics.Debug.Assert(false, "Unexpected call of RemoveEnding");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static XUnit GetTotalHeight(RenderInfo[] renderInfos)
 | 
			
		||||
        {
 | 
			
		||||
            if (renderInfos == null || renderInfos.Length == 0)
 | 
			
		||||
                return 0;
 | 
			
		||||
 | 
			
		||||
            int lastIdx = renderInfos.Length - 1;
 | 
			
		||||
            RenderInfo firstRenderInfo = renderInfos[0];
 | 
			
		||||
            RenderInfo lastRenderInfo = renderInfos[lastIdx];
 | 
			
		||||
            LayoutInfo firstLayoutInfo = firstRenderInfo.LayoutInfo;
 | 
			
		||||
            LayoutInfo lastLayoutInfo = lastRenderInfo.LayoutInfo;
 | 
			
		||||
            XUnit top = firstLayoutInfo.ContentArea.Y - firstLayoutInfo.MarginTop;
 | 
			
		||||
            XUnit bottom = lastLayoutInfo.ContentArea.Y + lastLayoutInfo.ContentArea.Height;
 | 
			
		||||
            bottom += lastLayoutInfo.MarginBottom;
 | 
			
		||||
            return bottom - top;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										211
									
								
								MigraDoc.Rendering/Rendering/Renderer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								MigraDoc.Rendering/Rendering/Renderer.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,211 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Tables;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Shapes;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Shapes.Charts;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Abstract base class for all renderers.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public abstract class Renderer
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Determines the maximum height a single element may have.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public XUnit MaxElementHeight
 | 
			
		||||
        {
 | 
			
		||||
            get { return _maxElementHeight; }
 | 
			
		||||
            set { _maxElementHeight = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Renderer(XGraphics gfx, DocumentObject documentObject, FieldInfos fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _documentObject = documentObject;
 | 
			
		||||
            _gfx = gfx;
 | 
			
		||||
            _fieldInfos = fieldInfos;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Renderer(XGraphics gfx, RenderInfo renderInfo, FieldInfos fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _documentObject = renderInfo.DocumentObject;
 | 
			
		||||
            _gfx = gfx;
 | 
			
		||||
            _renderInfo = renderInfo;
 | 
			
		||||
            _fieldInfos = fieldInfos;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// In inherited classes, gets a layout info with only margin and break information set.
 | 
			
		||||
        /// It can be taken before the documen object is formatted.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <remarks>
 | 
			
		||||
        /// In inherited classes, the following parts are set properly:
 | 
			
		||||
        /// MarginTop, MarginLeft, MarginRight, MarginBottom, 
 | 
			
		||||
        /// KeepTogether, KeepWithNext, PagebreakBefore, Floating,
 | 
			
		||||
        /// VerticalReference, HorizontalReference.
 | 
			
		||||
        /// </remarks>
 | 
			
		||||
        public abstract LayoutInfo InitialLayoutInfo { get; }
 | 
			
		||||
 | 
			
		||||
        /// <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 = Create(_gfx, _documentRenderer, renderInfo, _fieldInfos);
 | 
			
		||||
                renderer.Render();
 | 
			
		||||
                renderInfo.LayoutInfo.ContentArea.X = savedX;
 | 
			
		||||
                renderInfo.LayoutInfo.ContentArea.Y = savedY;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected void RenderByInfos(RenderInfo[] renderInfos)
 | 
			
		||||
        {
 | 
			
		||||
            RenderByInfos(0, 0, renderInfos);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the render information necessary to render and position the object.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public RenderInfo RenderInfo
 | 
			
		||||
        {
 | 
			
		||||
            get { return _renderInfo; }
 | 
			
		||||
        }
 | 
			
		||||
        protected RenderInfo _renderInfo;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Sets the field infos object.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <remarks>This property is set by the AreaProvider.</remarks>
 | 
			
		||||
        public FieldInfos FieldInfos
 | 
			
		||||
        {
 | 
			
		||||
            set { _fieldInfos = value; }
 | 
			
		||||
        }
 | 
			
		||||
        protected FieldInfos _fieldInfos;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Renders (draws) the object to the Graphics object.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public abstract void Render();
 | 
			
		||||
 | 
			
		||||
        /// <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>
 | 
			
		||||
        public abstract void Format(Area area, FormatInfo previousFormatInfo);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Creates a fitting renderer for the given document object for formatting.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="gfx">The XGraphics object to do measurements on.</param>
 | 
			
		||||
        /// <param name="documentRenderer">The document renderer.</param>
 | 
			
		||||
        /// <param name="documentObject">the document object to format.</param>
 | 
			
		||||
        /// <param name="fieldInfos">The field infos.</param>
 | 
			
		||||
        /// <returns>The fitting Renderer.</returns>
 | 
			
		||||
        public static Renderer Create(XGraphics gfx, DocumentRenderer documentRenderer, DocumentObject documentObject, FieldInfos fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            Renderer renderer = null;
 | 
			
		||||
            if (documentObject is Paragraph)
 | 
			
		||||
                renderer = new ParagraphRenderer(gfx, (Paragraph)documentObject, fieldInfos);
 | 
			
		||||
            else if (documentObject is Table)
 | 
			
		||||
                renderer = new TableRenderer(gfx, (Table)documentObject, fieldInfos);
 | 
			
		||||
            else if (documentObject is PageBreak)
 | 
			
		||||
                renderer = new PageBreakRenderer(gfx, (PageBreak)documentObject, fieldInfos);
 | 
			
		||||
            else if (documentObject is TextFrame)
 | 
			
		||||
                renderer = new TextFrameRenderer(gfx, (TextFrame)documentObject, fieldInfos);
 | 
			
		||||
            else if (documentObject is Chart)
 | 
			
		||||
                renderer = new ChartRenderer(gfx, (Chart)documentObject, fieldInfos);
 | 
			
		||||
            else if (documentObject is Image)
 | 
			
		||||
                renderer = new ImageRenderer(gfx, (Image)documentObject, fieldInfos);
 | 
			
		||||
 | 
			
		||||
            if (renderer != null)
 | 
			
		||||
                renderer._documentRenderer = documentRenderer;
 | 
			
		||||
 | 
			
		||||
            return renderer;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Creates a fitting renderer for the render info to render and layout with.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="gfx">The XGraphics object to render on.</param>
 | 
			
		||||
        /// <param name="documentRenderer">The document renderer.</param>
 | 
			
		||||
        /// <param name="renderInfo">The RenderInfo object stored after a previous call of Format().</param>
 | 
			
		||||
        /// <param name="fieldInfos">The field infos.</param>
 | 
			
		||||
        /// <returns>The fitting Renderer.</returns>
 | 
			
		||||
        public static Renderer Create(XGraphics gfx, DocumentRenderer documentRenderer, RenderInfo renderInfo, FieldInfos fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            Renderer renderer = null;
 | 
			
		||||
 | 
			
		||||
            if (renderInfo.DocumentObject is Paragraph)
 | 
			
		||||
                renderer = new ParagraphRenderer(gfx, renderInfo, fieldInfos);
 | 
			
		||||
            else if (renderInfo.DocumentObject is Table)
 | 
			
		||||
                renderer = new TableRenderer(gfx, renderInfo, fieldInfos);
 | 
			
		||||
            else if (renderInfo.DocumentObject is PageBreak)
 | 
			
		||||
                renderer = new PageBreakRenderer(gfx, renderInfo, fieldInfos);
 | 
			
		||||
            else if (renderInfo.DocumentObject is TextFrame)
 | 
			
		||||
                renderer = new TextFrameRenderer(gfx, renderInfo, fieldInfos);
 | 
			
		||||
            else if (renderInfo.DocumentObject is Chart)
 | 
			
		||||
                renderer = new ChartRenderer(gfx, renderInfo, fieldInfos);
 | 
			
		||||
            //else if (renderInfo.DocumentObject is Chart)
 | 
			
		||||
            //  renderer = new ChartRenderer(gfx, renderInfo, fieldInfos);
 | 
			
		||||
            else if (renderInfo.DocumentObject is Image)
 | 
			
		||||
                renderer = new ImageRenderer(gfx, renderInfo, fieldInfos);
 | 
			
		||||
 | 
			
		||||
            if (renderer != null)
 | 
			
		||||
                renderer._documentRenderer = documentRenderer;
 | 
			
		||||
 | 
			
		||||
            return renderer;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public readonly static XUnit Tolerance = XUnit.FromPoint(0.001);
 | 
			
		||||
        private XUnit _maxElementHeight = -1;
 | 
			
		||||
 | 
			
		||||
        protected DocumentObject _documentObject;
 | 
			
		||||
        protected DocumentRenderer _documentRenderer;
 | 
			
		||||
        protected XGraphics _gfx;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										120
									
								
								MigraDoc.Rendering/Rendering/ShadingRenderer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								MigraDoc.Rendering/Rendering/ShadingRenderer.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,120 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Tables;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Renders a Shading to an XGraphics object.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class ShadingRenderer
 | 
			
		||||
    {
 | 
			
		||||
        public ShadingRenderer(XGraphics gfx, Shading shading)
 | 
			
		||||
        {
 | 
			
		||||
            _gfx = gfx;
 | 
			
		||||
            _shading = shading;
 | 
			
		||||
            RealizeBrush();
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        public void Render(XUnit x, XUnit y, XUnit width, XUnit height)
 | 
			
		||||
        {
 | 
			
		||||
            if (_shading == null || _brush == null)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            _gfx.DrawRectangle(_brush, x.Point, y.Point, width.Point, height.Point);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Render(XUnit x, XUnit y, XUnit width, XUnit height, RoundedCorner roundedCorner)
 | 
			
		||||
        {
 | 
			
		||||
            // If there is no rounded corner, we can use the usual Render method.
 | 
			
		||||
            if (roundedCorner == RoundedCorner.None)
 | 
			
		||||
            {
 | 
			
		||||
                Render(x, y, width, height);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (_shading == null || _brush == null)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            XGraphicsPath path = new XGraphicsPath();
 | 
			
		||||
 | 
			
		||||
            switch (roundedCorner)
 | 
			
		||||
            {
 | 
			
		||||
                case RoundedCorner.TopLeft:
 | 
			
		||||
                    path.AddArc(new XRect(x, y, width * 2, height * 2), 180, 90); // Error in CORE: _corePath.AddArc().
 | 
			
		||||
                    path.AddLine(new XPoint(x + width, y), new XPoint(x + width, y + height));
 | 
			
		||||
                    break;
 | 
			
		||||
                case RoundedCorner.TopRight:
 | 
			
		||||
                    path.AddArc(new XRect(x - width, y, width * 2, height * 2), 270, 90); // Error in CORE: _corePath.AddArc().
 | 
			
		||||
                    path.AddLine(new XPoint(x + width, y + height), new XPoint(x, y + height));
 | 
			
		||||
                    break;
 | 
			
		||||
                case RoundedCorner.BottomRight:
 | 
			
		||||
                    path.AddArc(new XRect(x - width, y - height, width * 2, height * 2), 0, 90); // Error in CORE: _corePath.AddArc().
 | 
			
		||||
                    path.AddLine(new XPoint(x, y + height), new XPoint(x, y));
 | 
			
		||||
                    break;
 | 
			
		||||
                case RoundedCorner.BottomLeft:
 | 
			
		||||
                    path.AddArc(new XRect(x, y - height, width * 2, height * 2), 90, 90); // Error in CORE: _corePath.AddArc().
 | 
			
		||||
                    path.AddLine(new XPoint(x, y), new XPoint(x + width, y));
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            path.CloseFigure();
 | 
			
		||||
            _gfx.DrawPath(_brush, path);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private bool IsVisible()
 | 
			
		||||
        {
 | 
			
		||||
            if (!_shading._visible.IsNull)
 | 
			
		||||
                return _shading.Visible;
 | 
			
		||||
            else
 | 
			
		||||
                return !_shading._color.IsNull;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void RealizeBrush()
 | 
			
		||||
        {
 | 
			
		||||
            if (_shading == null)
 | 
			
		||||
                return;
 | 
			
		||||
            if (IsVisible())
 | 
			
		||||
            {
 | 
			
		||||
#if noCMYK
 | 
			
		||||
                this.brush = new XSolidBrush(XColor.FromArgb((int)this.shading.Color.Argb));
 | 
			
		||||
#else
 | 
			
		||||
                _brush = new XSolidBrush(ColorHelper.ToXColor(_shading.Color, _shading.Document.UseCmykColor));
 | 
			
		||||
#endif
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        readonly Shading _shading;
 | 
			
		||||
        XBrush _brush;
 | 
			
		||||
        readonly XGraphics _gfx;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										77
									
								
								MigraDoc.Rendering/Rendering/ShapeFormatInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								MigraDoc.Rendering/Rendering/ShapeFormatInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Format information for all shapes.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public
 | 
			
		||||
   class ShapeFormatInfo : FormatInfo
 | 
			
		||||
    {
 | 
			
		||||
        public override bool IsStarting
 | 
			
		||||
        {
 | 
			
		||||
            get { return Fits; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool IsEnding
 | 
			
		||||
        {
 | 
			
		||||
            get { return Fits; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool IsComplete
 | 
			
		||||
        {
 | 
			
		||||
            get { return Fits; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Indicates that the starting of the element is completed
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public override bool StartingIsComplete
 | 
			
		||||
        {
 | 
			
		||||
            get { return Fits; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Indicates that the ending of the element is completed
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public override bool EndingIsComplete
 | 
			
		||||
        {
 | 
			
		||||
            get { return Fits; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool IsEmpty
 | 
			
		||||
        {
 | 
			
		||||
            get { return !Fits; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool Fits;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										54
									
								
								MigraDoc.Rendering/Rendering/ShapeRenderInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								MigraDoc.Rendering/Rendering/ShapeRenderInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Shapes;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Rendering information for shapes.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public abstract class ShapeRenderInfo : RenderInfo
 | 
			
		||||
    {
 | 
			
		||||
        public ShapeRenderInfo()
 | 
			
		||||
        { }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the document object to which the layout information applies. Use the Tag property of DocumentObject to identify an object.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public override DocumentObject DocumentObject
 | 
			
		||||
        {
 | 
			
		||||
            get { return _shape; }
 | 
			
		||||
            set { _shape = (Shape)value; }
 | 
			
		||||
        }
 | 
			
		||||
        Shape _shape;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										234
									
								
								MigraDoc.Rendering/Rendering/ShapeRenderer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										234
									
								
								MigraDoc.Rendering/Rendering/ShapeRenderer.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,234 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Shapes;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.publics;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Renders a shape to an XGraphics object.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public abstract class ShapeRenderer : Renderer
 | 
			
		||||
    {
 | 
			
		||||
        public ShapeRenderer(XGraphics gfx, Shape shape, FieldInfos fieldInfos)
 | 
			
		||||
            : base(gfx, shape, fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _shape = shape;
 | 
			
		||||
            LineFormat lf = (LineFormat)_shape.GetValue("LineFormat", GV.ReadOnly);
 | 
			
		||||
            _lineFormatRenderer = new LineFormatRenderer(lf, gfx);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ShapeRenderer(XGraphics gfx, RenderInfo renderInfo, FieldInfos fieldInfos)
 | 
			
		||||
            : base(gfx, renderInfo, fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _shape = (Shape)renderInfo.DocumentObject;
 | 
			
		||||
            LineFormat lf = (LineFormat)_shape.GetValue("LineFormat", GV.ReadOnly);
 | 
			
		||||
            _lineFormatRenderer = new LineFormatRenderer(lf, gfx);
 | 
			
		||||
            FillFormat ff = (FillFormat)_shape.GetValue("FillFormat", GV.ReadOnly);
 | 
			
		||||
            _fillFormatRenderer = new FillFormatRenderer(ff, gfx);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override LayoutInfo InitialLayoutInfo
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                LayoutInfo layoutInfo = new LayoutInfo();
 | 
			
		||||
 | 
			
		||||
                layoutInfo.MarginTop = _shape.WrapFormat.DistanceTop.Point;
 | 
			
		||||
                layoutInfo.MarginLeft = _shape.WrapFormat.DistanceLeft.Point;
 | 
			
		||||
                layoutInfo.MarginBottom = _shape.WrapFormat.DistanceBottom.Point;
 | 
			
		||||
                layoutInfo.MarginRight = _shape.WrapFormat.DistanceRight.Point;
 | 
			
		||||
                layoutInfo.KeepTogether = true;
 | 
			
		||||
                layoutInfo.KeepWithNext = false;
 | 
			
		||||
                layoutInfo.PageBreakBefore = false;
 | 
			
		||||
                layoutInfo.VerticalReference = GetVerticalReference();
 | 
			
		||||
                layoutInfo.HorizontalReference = GetHorizontalReference();
 | 
			
		||||
                layoutInfo.Floating = GetFloating();
 | 
			
		||||
                if (layoutInfo.Floating == Floating.TopBottom && !_shape.Top.Position.IsEmpty)
 | 
			
		||||
                    layoutInfo.MarginTop = Math.Max(layoutInfo.MarginTop, _shape.Top.Position);
 | 
			
		||||
                return layoutInfo;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Floating GetFloating()
 | 
			
		||||
        {
 | 
			
		||||
            if (_shape.RelativeVertical != RelativeVertical.Line && _shape.RelativeVertical != RelativeVertical.Paragraph)
 | 
			
		||||
                return Floating.None;
 | 
			
		||||
 | 
			
		||||
            switch (_shape.WrapFormat.Style)
 | 
			
		||||
            {
 | 
			
		||||
                case WrapStyle.None:
 | 
			
		||||
                case WrapStyle.Through:
 | 
			
		||||
                    return Floating.None;
 | 
			
		||||
            }
 | 
			
		||||
            return Floating.TopBottom;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the shape width including line width.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected virtual XUnit ShapeWidth
 | 
			
		||||
        {
 | 
			
		||||
            get { return _shape.Width + _lineFormatRenderer.GetWidth(); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the shape height including line width.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected virtual XUnit ShapeHeight
 | 
			
		||||
        {
 | 
			
		||||
            get { return _shape.Height + _lineFormatRenderer.GetWidth(); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Formats the shape.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="area">The area to fit in the shape.</param>
 | 
			
		||||
        /// <param name="previousFormatInfo"></param>
 | 
			
		||||
        public override void Format(Area area, FormatInfo previousFormatInfo)
 | 
			
		||||
        {
 | 
			
		||||
            Floating floating = GetFloating();
 | 
			
		||||
            bool fits = floating == Floating.None || ShapeHeight <= area.Height;
 | 
			
		||||
            ((ShapeFormatInfo)_renderInfo.FormatInfo).Fits = fits;
 | 
			
		||||
            FinishLayoutInfo(area);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        void FinishLayoutInfo(Area area)
 | 
			
		||||
        {
 | 
			
		||||
            LayoutInfo layoutInfo = _renderInfo.LayoutInfo;
 | 
			
		||||
            Area contentArea = new Rectangle(area.X, area.Y, ShapeWidth, ShapeHeight);
 | 
			
		||||
            layoutInfo.ContentArea = contentArea;
 | 
			
		||||
            layoutInfo.MarginTop = _shape.WrapFormat.DistanceTop.Point;
 | 
			
		||||
            layoutInfo.MarginLeft = _shape.WrapFormat.DistanceLeft.Point;
 | 
			
		||||
            layoutInfo.MarginBottom = _shape.WrapFormat.DistanceBottom.Point;
 | 
			
		||||
            layoutInfo.MarginRight = _shape.WrapFormat.DistanceRight.Point;
 | 
			
		||||
            layoutInfo.KeepTogether = true;
 | 
			
		||||
            layoutInfo.KeepWithNext = false;
 | 
			
		||||
            layoutInfo.PageBreakBefore = false;
 | 
			
		||||
            layoutInfo.MinWidth = ShapeWidth;
 | 
			
		||||
 | 
			
		||||
            if (_shape.Top.ShapePosition == ShapePosition.Undefined)
 | 
			
		||||
                layoutInfo.Top = _shape.Top.Position.Point;
 | 
			
		||||
 | 
			
		||||
            layoutInfo.VerticalAlignment = GetVerticalAlignment();
 | 
			
		||||
            layoutInfo.HorizontalAlignment = GetHorizontalAlignment();
 | 
			
		||||
 | 
			
		||||
            if (_shape.Left.ShapePosition == ShapePosition.Undefined)
 | 
			
		||||
                layoutInfo.Left = _shape.Left.Position.Point;
 | 
			
		||||
 | 
			
		||||
            layoutInfo.HorizontalReference = GetHorizontalReference();
 | 
			
		||||
            layoutInfo.VerticalReference = GetVerticalReference();
 | 
			
		||||
            layoutInfo.Floating = GetFloating();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        HorizontalReference GetHorizontalReference()
 | 
			
		||||
        {
 | 
			
		||||
            switch (_shape.RelativeHorizontal)
 | 
			
		||||
            {
 | 
			
		||||
                case RelativeHorizontal.Margin:
 | 
			
		||||
                    return HorizontalReference.PageMargin;
 | 
			
		||||
                case RelativeHorizontal.Page:
 | 
			
		||||
                    return HorizontalReference.Page;
 | 
			
		||||
            }
 | 
			
		||||
            return HorizontalReference.AreaBoundary;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        VerticalReference GetVerticalReference()
 | 
			
		||||
        {
 | 
			
		||||
            switch (_shape.RelativeVertical)
 | 
			
		||||
            {
 | 
			
		||||
                case RelativeVertical.Margin:
 | 
			
		||||
                    return VerticalReference.PageMargin;
 | 
			
		||||
 | 
			
		||||
                case RelativeVertical.Page:
 | 
			
		||||
                    return VerticalReference.Page;
 | 
			
		||||
            }
 | 
			
		||||
            return VerticalReference.PreviousElement;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ElementAlignment GetVerticalAlignment()
 | 
			
		||||
        {
 | 
			
		||||
            switch (_shape.Top.ShapePosition)
 | 
			
		||||
            {
 | 
			
		||||
                case ShapePosition.Center:
 | 
			
		||||
                    return ElementAlignment.Center;
 | 
			
		||||
 | 
			
		||||
                case ShapePosition.Bottom:
 | 
			
		||||
                    return ElementAlignment.Far;
 | 
			
		||||
            }
 | 
			
		||||
            return ElementAlignment.Near;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected void RenderFilling()
 | 
			
		||||
        {
 | 
			
		||||
            Area contentArea = _renderInfo.LayoutInfo.ContentArea;
 | 
			
		||||
            XUnit lineWidth = _lineFormatRenderer.GetWidth();
 | 
			
		||||
            // Half of the line is drawn outside the shape, the other half inside the shape.
 | 
			
		||||
            // Therefore we have to reduce the position of the filling by 0.5 lineWidth and width and height by 2 lineWidth.
 | 
			
		||||
            _fillFormatRenderer.Render(contentArea.X + lineWidth / 2, contentArea.Y + lineWidth / 2,
 | 
			
		||||
                contentArea.Width - 2 * lineWidth, contentArea.Height - 2 * lineWidth);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected void RenderLine()
 | 
			
		||||
        {
 | 
			
		||||
            Area contentArea = _renderInfo.LayoutInfo.ContentArea;
 | 
			
		||||
            XUnit lineWidth = _lineFormatRenderer.GetWidth();
 | 
			
		||||
            XUnit width = contentArea.Width - lineWidth;
 | 
			
		||||
            XUnit height = contentArea.Height - lineWidth;
 | 
			
		||||
            _lineFormatRenderer.Render(contentArea.X, contentArea.Y, width, height);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ElementAlignment GetHorizontalAlignment()
 | 
			
		||||
        {
 | 
			
		||||
            switch (_shape.Left.ShapePosition)
 | 
			
		||||
            {
 | 
			
		||||
                case ShapePosition.Center:
 | 
			
		||||
                    return ElementAlignment.Center;
 | 
			
		||||
 | 
			
		||||
                case ShapePosition.Right:
 | 
			
		||||
                    return ElementAlignment.Far;
 | 
			
		||||
 | 
			
		||||
                case ShapePosition.Outside:
 | 
			
		||||
                    return ElementAlignment.Outside;
 | 
			
		||||
 | 
			
		||||
                case ShapePosition.Inside:
 | 
			
		||||
                    return ElementAlignment.Inside;
 | 
			
		||||
            }
 | 
			
		||||
            return ElementAlignment.Near;
 | 
			
		||||
        }
 | 
			
		||||
        protected LineFormatRenderer _lineFormatRenderer;
 | 
			
		||||
        protected FillFormatRenderer _fillFormatRenderer;
 | 
			
		||||
        protected Shape _shape;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										98
									
								
								MigraDoc.Rendering/Rendering/TableFormatInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								MigraDoc.Rendering/Rendering/TableFormatInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Tables;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Visitors;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Formatting information for tables.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class TableFormatInfo : FormatInfo
 | 
			
		||||
    {
 | 
			
		||||
        public TableFormatInfo()
 | 
			
		||||
        { }
 | 
			
		||||
 | 
			
		||||
        public override bool EndingIsComplete
 | 
			
		||||
        {
 | 
			
		||||
            get { return _isEnding; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool StartingIsComplete
 | 
			
		||||
        {
 | 
			
		||||
            get { return !IsEmpty && StartRow > LastHeaderRow; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool IsComplete
 | 
			
		||||
        {
 | 
			
		||||
            get { return false; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool IsEmpty
 | 
			
		||||
        {
 | 
			
		||||
            get { return StartRow < 0; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool IsEnding
 | 
			
		||||
        {
 | 
			
		||||
            get { return _isEnding; }
 | 
			
		||||
        }
 | 
			
		||||
        public bool _isEnding;
 | 
			
		||||
 | 
			
		||||
        public override bool IsStarting
 | 
			
		||||
        {
 | 
			
		||||
            get { return StartRow == LastHeaderRow + 1; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int StartColumn = -1;
 | 
			
		||||
        public int EndColumn = -1;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The first row of the table that is showing on a page.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public int StartRow = -1;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The last row of the table that is showing on a page.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public int EndRow = -1;
 | 
			
		||||
 | 
			
		||||
        public int LastHeaderRow = -1;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The formatted cells.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public Dictionary<Cell, FormattedCell> FormattedCells; //Sorted_List formattedCells;
 | 
			
		||||
        public MergedCellList MergedCells;
 | 
			
		||||
        public Dictionary<int, XUnit> BottomBorderMap; //Sorted_List bottomBorderMap;
 | 
			
		||||
        public Dictionary<int, int> ConnectedRowsMap; //Sorted_List connectedRowsMap;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										64
									
								
								MigraDoc.Rendering/Rendering/TableRenderInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								MigraDoc.Rendering/Rendering/TableRenderInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Tables;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Rendering information for tables.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class TableRenderInfo : RenderInfo
 | 
			
		||||
    {
 | 
			
		||||
        public TableRenderInfo()
 | 
			
		||||
        { }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the format information in a specific derived type. For a table, for example, this will be a TableFormatInfo with information about the first and last row showing on a page.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public override FormatInfo FormatInfo
 | 
			
		||||
        {
 | 
			
		||||
            get { return _formatInfo; }
 | 
			
		||||
            set { _formatInfo = (TableFormatInfo)value; }
 | 
			
		||||
        }
 | 
			
		||||
        TableFormatInfo _formatInfo = new TableFormatInfo();
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the document object to which the layout information applies. Use the Tag property of DocumentObject to identify an object.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public override DocumentObject DocumentObject
 | 
			
		||||
        {
 | 
			
		||||
            get { return _table; }
 | 
			
		||||
            set { _table = (Table)value; }
 | 
			
		||||
        }
 | 
			
		||||
        Table _table;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										821
									
								
								MigraDoc.Rendering/Rendering/TableRenderer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										821
									
								
								MigraDoc.Rendering/Rendering/TableRenderer.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,821 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.publics;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Visitors;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Tables;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///   Renders a table to an XGraphics object.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class TableRenderer : Renderer
 | 
			
		||||
    {
 | 
			
		||||
        public TableRenderer(XGraphics gfx, Table documentObject, FieldInfos fieldInfos)
 | 
			
		||||
            : base(gfx, documentObject, fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _table = documentObject;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public TableRenderer(XGraphics gfx, RenderInfo renderInfo, FieldInfos fieldInfos)
 | 
			
		||||
            : base(gfx, renderInfo, fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _table = (Table)_renderInfo.DocumentObject;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override LayoutInfo InitialLayoutInfo
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                LayoutInfo layoutInfo = new LayoutInfo();
 | 
			
		||||
                layoutInfo.KeepTogether = _table.KeepTogether;
 | 
			
		||||
                layoutInfo.KeepWithNext = false;
 | 
			
		||||
                layoutInfo.MarginBottom = 0;
 | 
			
		||||
                layoutInfo.MarginLeft = 0;
 | 
			
		||||
                layoutInfo.MarginTop = 0;
 | 
			
		||||
                layoutInfo.MarginRight = 0;
 | 
			
		||||
                return layoutInfo;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void InitRendering()
 | 
			
		||||
        {
 | 
			
		||||
            TableFormatInfo formatInfo = (TableFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
            _bottomBorderMap = formatInfo.BottomBorderMap;
 | 
			
		||||
            _connectedRowsMap = formatInfo.ConnectedRowsMap;
 | 
			
		||||
            _formattedCells = formatInfo.FormattedCells;
 | 
			
		||||
 | 
			
		||||
            _currRow = formatInfo.StartRow;
 | 
			
		||||
            _startRow = formatInfo.StartRow;
 | 
			
		||||
            _endRow = formatInfo.EndRow;
 | 
			
		||||
 | 
			
		||||
            _mergedCells = formatInfo.MergedCells;
 | 
			
		||||
            _lastHeaderRow = formatInfo.LastHeaderRow;
 | 
			
		||||
            _startX = _renderInfo.LayoutInfo.ContentArea.X;
 | 
			
		||||
            _startY = _renderInfo.LayoutInfo.ContentArea.Y;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void RenderHeaderRows()
 | 
			
		||||
        {
 | 
			
		||||
            if (_lastHeaderRow < 0)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            foreach (Cell cell in _mergedCells)
 | 
			
		||||
            {
 | 
			
		||||
                if (cell.Row.Index <= _lastHeaderRow)
 | 
			
		||||
                    RenderCell(cell);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void RenderCell(Cell cell)
 | 
			
		||||
        {
 | 
			
		||||
            Rectangle innerRect = GetInnerRect(CalcStartingHeight(), cell);
 | 
			
		||||
            RenderShading(cell, innerRect);
 | 
			
		||||
            RenderContent(cell, innerRect);
 | 
			
		||||
            RenderBorders(cell, innerRect);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void EqualizeRoundedCornerBorders(Cell cell)
 | 
			
		||||
        {
 | 
			
		||||
            // If any of a corner relevant border is set, we want to copy its values to the second corner relevant border, 
 | 
			
		||||
            // to ensure the innerWidth of the cell is the same, regardless of which border is used.
 | 
			
		||||
            // If set, we use the vertical borders as source for the values, otherwise we use the horizontal borders.
 | 
			
		||||
            RoundedCorner roundedCorner = cell.RoundedCorner;
 | 
			
		||||
 | 
			
		||||
            if (roundedCorner == RoundedCorner.None)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            BorderType primaryBorderType = BorderType.Top, secondaryBorderType = BorderType.Top;
 | 
			
		||||
 | 
			
		||||
            if (roundedCorner == RoundedCorner.TopLeft || roundedCorner == RoundedCorner.BottomLeft)
 | 
			
		||||
                primaryBorderType = BorderType.Left;
 | 
			
		||||
            if (roundedCorner == RoundedCorner.TopRight || roundedCorner == RoundedCorner.BottomRight)
 | 
			
		||||
                primaryBorderType = BorderType.Right;
 | 
			
		||||
 | 
			
		||||
            if (roundedCorner == RoundedCorner.TopLeft || roundedCorner == RoundedCorner.TopRight)
 | 
			
		||||
                secondaryBorderType = BorderType.Top;
 | 
			
		||||
            if (roundedCorner == RoundedCorner.BottomLeft || roundedCorner == RoundedCorner.BottomRight)
 | 
			
		||||
                secondaryBorderType = BorderType.Bottom;
 | 
			
		||||
 | 
			
		||||
            // If both borders don't exist, there's nothing to do and we should not create one by accessing it.
 | 
			
		||||
            if (!cell.Borders.HasBorder(primaryBorderType) && !cell.Borders.HasBorder(secondaryBorderType))
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            // Get the borders. By using GV.ReadWrite we create the border, if not existing.
 | 
			
		||||
            Border primaryBorder = (Border)cell.Borders.GetValue(primaryBorderType.ToString(), GV.ReadWrite);
 | 
			
		||||
            Border secondaryBorder = (Border)cell.Borders.GetValue(secondaryBorderType.ToString(), GV.ReadWrite);
 | 
			
		||||
 | 
			
		||||
            Border source = primaryBorder.Visible ? primaryBorder
 | 
			
		||||
                : secondaryBorder.Visible ? secondaryBorder : null;
 | 
			
		||||
            Border target = primaryBorder.Visible ? secondaryBorder
 | 
			
		||||
                : secondaryBorder.Visible ? primaryBorder : null;
 | 
			
		||||
 | 
			
		||||
            if (source == null || target == null)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            target.Visible = source.Visible;
 | 
			
		||||
            target.Width = source.Width;
 | 
			
		||||
            target.Style = source.Style;
 | 
			
		||||
            target.Color = source.Color;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void RenderShading(Cell cell, Rectangle innerRect)
 | 
			
		||||
        {
 | 
			
		||||
            ShadingRenderer shadeRenderer = new ShadingRenderer(_gfx, cell.Shading);
 | 
			
		||||
            shadeRenderer.Render(innerRect.X, innerRect.Y, innerRect.Width, innerRect.Height, cell.RoundedCorner);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void RenderBorders(Cell cell, Rectangle innerRect)
 | 
			
		||||
        {
 | 
			
		||||
            XUnit leftPos = innerRect.X;
 | 
			
		||||
            XUnit rightPos = leftPos + innerRect.Width;
 | 
			
		||||
            XUnit topPos = innerRect.Y;
 | 
			
		||||
            XUnit bottomPos = innerRect.Y + innerRect.Height;
 | 
			
		||||
            Borders mergedBorders = _mergedCells.GetEffectiveBorders(cell);
 | 
			
		||||
 | 
			
		||||
            BordersRenderer bordersRenderer = new BordersRenderer(mergedBorders, _gfx);
 | 
			
		||||
            XUnit bottomWidth = bordersRenderer.GetWidth(BorderType.Bottom);
 | 
			
		||||
            XUnit leftWidth = bordersRenderer.GetWidth(BorderType.Left);
 | 
			
		||||
            XUnit topWidth = bordersRenderer.GetWidth(BorderType.Top);
 | 
			
		||||
            XUnit rightWidth = bordersRenderer.GetWidth(BorderType.Right);
 | 
			
		||||
 | 
			
		||||
            if (cell.RoundedCorner == RoundedCorner.TopLeft)
 | 
			
		||||
                bordersRenderer.RenderRounded(cell.RoundedCorner, innerRect.X, innerRect.Y, innerRect.Width + rightWidth, innerRect.Height + bottomWidth);
 | 
			
		||||
            else if (cell.RoundedCorner == RoundedCorner.TopRight)
 | 
			
		||||
                bordersRenderer.RenderRounded(cell.RoundedCorner, innerRect.X - leftWidth, innerRect.Y, innerRect.Width + leftWidth, innerRect.Height + bottomWidth);
 | 
			
		||||
            else if (cell.RoundedCorner == RoundedCorner.BottomLeft)
 | 
			
		||||
                bordersRenderer.RenderRounded(cell.RoundedCorner, innerRect.X, innerRect.Y - topWidth, innerRect.Width + rightWidth, innerRect.Height + topWidth);
 | 
			
		||||
            else if (cell.RoundedCorner == RoundedCorner.BottomRight)
 | 
			
		||||
                bordersRenderer.RenderRounded(cell.RoundedCorner, innerRect.X - leftWidth, innerRect.Y - topWidth, innerRect.Width + leftWidth, innerRect.Height + topWidth);
 | 
			
		||||
 | 
			
		||||
            // Render horizontal and vertical borders only if touching no rounded corner.
 | 
			
		||||
            if (cell.RoundedCorner != RoundedCorner.TopRight && cell.RoundedCorner != RoundedCorner.BottomRight)
 | 
			
		||||
                bordersRenderer.RenderVertically(BorderType.Right, rightPos, topPos, bottomPos + bottomWidth - topPos);
 | 
			
		||||
 | 
			
		||||
            if (cell.RoundedCorner != RoundedCorner.TopLeft && cell.RoundedCorner != RoundedCorner.BottomLeft)
 | 
			
		||||
                bordersRenderer.RenderVertically(BorderType.Left, leftPos - leftWidth, topPos, bottomPos + bottomWidth - topPos);
 | 
			
		||||
 | 
			
		||||
            if (cell.RoundedCorner != RoundedCorner.BottomLeft && cell.RoundedCorner != RoundedCorner.BottomRight)
 | 
			
		||||
                bordersRenderer.RenderHorizontally(BorderType.Bottom, leftPos - leftWidth, bottomPos, rightPos + rightWidth + leftWidth - leftPos);
 | 
			
		||||
 | 
			
		||||
            if (cell.RoundedCorner != RoundedCorner.TopLeft && cell.RoundedCorner != RoundedCorner.TopRight)
 | 
			
		||||
                bordersRenderer.RenderHorizontally(BorderType.Top, leftPos - leftWidth, topPos - topWidth, rightPos + rightWidth + leftWidth - leftPos);
 | 
			
		||||
 | 
			
		||||
            RenderDiagonalBorders(mergedBorders, innerRect);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void RenderDiagonalBorders(Borders mergedBorders, Rectangle innerRect)
 | 
			
		||||
        {
 | 
			
		||||
            BordersRenderer bordersRenderer = new BordersRenderer(mergedBorders, _gfx);
 | 
			
		||||
            bordersRenderer.RenderDiagonally(BorderType.DiagonalDown, innerRect.X, innerRect.Y, innerRect.Width, innerRect.Height);
 | 
			
		||||
            bordersRenderer.RenderDiagonally(BorderType.DiagonalUp, innerRect.X, innerRect.Y, innerRect.Width, innerRect.Height);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void RenderContent(Cell cell, Rectangle innerRect)
 | 
			
		||||
        {
 | 
			
		||||
            FormattedCell formattedCell = _formattedCells[cell];
 | 
			
		||||
            RenderInfo[] renderInfos = formattedCell.GetRenderInfos();
 | 
			
		||||
 | 
			
		||||
            if (renderInfos == null)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            VerticalAlignment verticalAlignment = cell.VerticalAlignment;
 | 
			
		||||
            XUnit contentHeight = formattedCell.ContentHeight;
 | 
			
		||||
            XUnit innerHeight = innerRect.Height;
 | 
			
		||||
            XUnit targetX = innerRect.X + cell.Column.LeftPadding;
 | 
			
		||||
 | 
			
		||||
            XUnit targetY;
 | 
			
		||||
            if (verticalAlignment == VerticalAlignment.Bottom)
 | 
			
		||||
            {
 | 
			
		||||
                targetY = innerRect.Y + innerRect.Height;
 | 
			
		||||
                targetY -= cell.Row.BottomPadding;
 | 
			
		||||
                targetY -= contentHeight;
 | 
			
		||||
            }
 | 
			
		||||
            else if (verticalAlignment == VerticalAlignment.Center)
 | 
			
		||||
            {
 | 
			
		||||
                targetY = innerRect.Y + cell.Row.TopPadding;
 | 
			
		||||
                targetY += innerRect.Y + innerRect.Height - cell.Row.BottomPadding;
 | 
			
		||||
                targetY -= contentHeight;
 | 
			
		||||
                targetY /= 2;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
                targetY = innerRect.Y + cell.Row.TopPadding;
 | 
			
		||||
 | 
			
		||||
            RenderByInfos(targetX, targetY, renderInfos);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private Rectangle GetInnerRect(XUnit startingHeight, Cell cell)
 | 
			
		||||
        {
 | 
			
		||||
            BordersRenderer bordersRenderer = new BordersRenderer(_mergedCells.GetEffectiveBorders(cell), _gfx);
 | 
			
		||||
            FormattedCell formattedCell = _formattedCells[cell];
 | 
			
		||||
            XUnit width = formattedCell.InnerWidth;
 | 
			
		||||
 | 
			
		||||
            XUnit y = _startY;
 | 
			
		||||
            if (cell.Row.Index > _lastHeaderRow)
 | 
			
		||||
                y += startingHeight;
 | 
			
		||||
            else
 | 
			
		||||
                y += CalcMaxTopBorderWidth(0);
 | 
			
		||||
 | 
			
		||||
#if true
 | 
			
		||||
            // !!!new 18-03-09 Attempt to fix an exception. begin
 | 
			
		||||
            XUnit upperBorderPos;
 | 
			
		||||
            if (!_bottomBorderMap.TryGetValue(cell.Row.Index, out upperBorderPos))
 | 
			
		||||
            {
 | 
			
		||||
                //GetType();
 | 
			
		||||
            }
 | 
			
		||||
            // !!!new 18-03-09 Attempt to fix an exception. end
 | 
			
		||||
#else
 | 
			
		||||
            XUnit upperBorderPos = _bottomBorderMap[cell.Row.Index];
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
            y += upperBorderPos;
 | 
			
		||||
            if (cell.Row.Index > _lastHeaderRow)
 | 
			
		||||
                y -= _bottomBorderMap[_startRow];
 | 
			
		||||
 | 
			
		||||
#if true
 | 
			
		||||
            // !!!new 18-03-09 Attempt to fix an exception. begin
 | 
			
		||||
            XUnit lowerBorderPos;
 | 
			
		||||
            if (!_bottomBorderMap.TryGetValue(cell.Row.Index + cell.MergeDown + 1, out lowerBorderPos))
 | 
			
		||||
            {
 | 
			
		||||
                //GetType();
 | 
			
		||||
            }
 | 
			
		||||
            // !!!new 18-03-09 Attempt to fix an exception. end
 | 
			
		||||
#else
 | 
			
		||||
            XUnit lowerBorderPos = _bottomBorderMap[cell.Row.Index + cell.MergeDown + 1];
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
            XUnit height = lowerBorderPos - upperBorderPos;
 | 
			
		||||
            height -= bordersRenderer.GetWidth(BorderType.Bottom);
 | 
			
		||||
 | 
			
		||||
            XUnit x = _startX;
 | 
			
		||||
            for (int clmIdx = 0; clmIdx < cell.Column.Index; ++clmIdx)
 | 
			
		||||
            {
 | 
			
		||||
                x += _table.Columns[clmIdx].Width;
 | 
			
		||||
            }
 | 
			
		||||
            x += LeftBorderOffset;
 | 
			
		||||
 | 
			
		||||
            return new Rectangle(x, y, width, height);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void Render()
 | 
			
		||||
        {
 | 
			
		||||
            InitRendering();
 | 
			
		||||
            RenderHeaderRows();
 | 
			
		||||
            if (_startRow < _table.Rows.Count)
 | 
			
		||||
            {
 | 
			
		||||
                Cell cell = _table[_startRow, 0];
 | 
			
		||||
 | 
			
		||||
                int cellIdx = _mergedCells.BinarySearch(_table[_startRow, 0], new CellComparer());
 | 
			
		||||
                while (cellIdx < _mergedCells.Count)
 | 
			
		||||
                {
 | 
			
		||||
                    cell = _mergedCells[cellIdx];
 | 
			
		||||
                    if (cell.Row.Index > _endRow)
 | 
			
		||||
                        break;
 | 
			
		||||
 | 
			
		||||
                    RenderCell(cell);
 | 
			
		||||
                    ++cellIdx;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void InitFormat(Area area, FormatInfo previousFormatInfo)
 | 
			
		||||
        {
 | 
			
		||||
            TableFormatInfo prevTableFormatInfo = (TableFormatInfo)previousFormatInfo;
 | 
			
		||||
            TableRenderInfo tblRenderInfo = new TableRenderInfo();
 | 
			
		||||
            tblRenderInfo.DocumentObject = _table;
 | 
			
		||||
 | 
			
		||||
            // Equalize the two borders, that are used to determine a rounded corner's border.
 | 
			
		||||
            // This way the innerWidth of the cell, which is got by the saved _formattedCells, is the same regardless of which corner relevant border is set.
 | 
			
		||||
            foreach (Row row in _table.Rows)
 | 
			
		||||
                foreach (Cell cell in row.Cells)
 | 
			
		||||
                    EqualizeRoundedCornerBorders(cell);
 | 
			
		||||
 | 
			
		||||
            _renderInfo = tblRenderInfo;
 | 
			
		||||
 | 
			
		||||
            if (prevTableFormatInfo != null)
 | 
			
		||||
            {
 | 
			
		||||
                _mergedCells = prevTableFormatInfo.MergedCells;
 | 
			
		||||
                _formattedCells = prevTableFormatInfo.FormattedCells;
 | 
			
		||||
                _bottomBorderMap = prevTableFormatInfo.BottomBorderMap;
 | 
			
		||||
                _lastHeaderRow = prevTableFormatInfo.LastHeaderRow;
 | 
			
		||||
                _connectedRowsMap = prevTableFormatInfo.ConnectedRowsMap;
 | 
			
		||||
                _startRow = prevTableFormatInfo.EndRow + 1;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                _mergedCells = new MergedCellList(_table);
 | 
			
		||||
                FormatCells();
 | 
			
		||||
                CalcLastHeaderRow();
 | 
			
		||||
                CreateConnectedRows();
 | 
			
		||||
                CreateBottomBorderMap();
 | 
			
		||||
                if (_doHorizontalBreak)
 | 
			
		||||
                {
 | 
			
		||||
                    CalcLastHeaderColumn();
 | 
			
		||||
                    CreateConnectedColumns();
 | 
			
		||||
                }
 | 
			
		||||
                _startRow = _lastHeaderRow + 1;
 | 
			
		||||
            }
 | 
			
		||||
            ((TableFormatInfo)tblRenderInfo.FormatInfo).MergedCells = _mergedCells;
 | 
			
		||||
            ((TableFormatInfo)tblRenderInfo.FormatInfo).FormattedCells = _formattedCells;
 | 
			
		||||
            ((TableFormatInfo)tblRenderInfo.FormatInfo).BottomBorderMap = _bottomBorderMap;
 | 
			
		||||
            ((TableFormatInfo)tblRenderInfo.FormatInfo).ConnectedRowsMap = _connectedRowsMap;
 | 
			
		||||
            ((TableFormatInfo)tblRenderInfo.FormatInfo).LastHeaderRow = _lastHeaderRow;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void FormatCells()
 | 
			
		||||
        {
 | 
			
		||||
            _formattedCells = new Dictionary<Cell, FormattedCell>(); //new Sorted_List(new CellComparer());
 | 
			
		||||
            foreach (Cell cell in _mergedCells)
 | 
			
		||||
            {
 | 
			
		||||
                FormattedCell formattedCell = new FormattedCell(cell, _documentRenderer, _mergedCells.GetEffectiveBorders(cell),
 | 
			
		||||
                                                                _fieldInfos, 0, 0);
 | 
			
		||||
                formattedCell.Format(_gfx);
 | 
			
		||||
                _formattedCells.Add(cell, formattedCell);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///   Formats (measures) the table.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="area"> The area on which to fit the table. </param>
 | 
			
		||||
        /// <param name="previousFormatInfo"> </param>
 | 
			
		||||
        public override void Format(Area area, FormatInfo previousFormatInfo)
 | 
			
		||||
        {
 | 
			
		||||
            DocumentElements elements = DocumentRelations.GetParent(_table) as DocumentElements;
 | 
			
		||||
            if (elements != null)
 | 
			
		||||
            {
 | 
			
		||||
                Section section = DocumentRelations.GetParent(elements) as Section;
 | 
			
		||||
                if (section != null)
 | 
			
		||||
                    _doHorizontalBreak = section.PageSetup.HorizontalPageBreak;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _renderInfo = new TableRenderInfo();
 | 
			
		||||
            InitFormat(area, previousFormatInfo);
 | 
			
		||||
 | 
			
		||||
            // Don't take any Rows higher then MaxElementHeight
 | 
			
		||||
            XUnit topHeight = CalcStartingHeight();
 | 
			
		||||
            XUnit probeHeight = topHeight;
 | 
			
		||||
            XUnit offset;
 | 
			
		||||
            if (_startRow > _lastHeaderRow + 1 &&
 | 
			
		||||
                _startRow < _table.Rows.Count)
 | 
			
		||||
                offset = _bottomBorderMap[_startRow] - topHeight;
 | 
			
		||||
            else
 | 
			
		||||
                offset = -CalcMaxTopBorderWidth(0);
 | 
			
		||||
 | 
			
		||||
            int probeRow = _startRow;
 | 
			
		||||
            XUnit currentHeight = 0;
 | 
			
		||||
            XUnit startingHeight = 0;
 | 
			
		||||
            bool isEmpty = false;
 | 
			
		||||
 | 
			
		||||
            while (probeRow < _table.Rows.Count)
 | 
			
		||||
            {
 | 
			
		||||
                bool firstProbe = probeRow == _startRow;
 | 
			
		||||
                probeRow = _connectedRowsMap[probeRow];
 | 
			
		||||
                // Don't take any Rows higher then MaxElementHeight
 | 
			
		||||
                probeHeight = _bottomBorderMap[probeRow + 1] - offset;
 | 
			
		||||
                // First test whether MaxElementHeight has been set.
 | 
			
		||||
                if (MaxElementHeight > 0 && firstProbe && probeHeight > MaxElementHeight - Tolerance)
 | 
			
		||||
                    probeHeight = MaxElementHeight - Tolerance;
 | 
			
		||||
                //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
 | 
			
		||||
                {
 | 
			
		||||
                    _currRow = probeRow;
 | 
			
		||||
                    currentHeight = probeHeight;
 | 
			
		||||
                    ++probeRow;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (!isEmpty)
 | 
			
		||||
            {
 | 
			
		||||
                TableFormatInfo formatInfo = (TableFormatInfo)_renderInfo.FormatInfo;
 | 
			
		||||
                formatInfo.StartRow = _startRow;
 | 
			
		||||
                formatInfo._isEnding = _currRow >= _table.Rows.Count - 1;
 | 
			
		||||
                formatInfo.EndRow = _currRow;
 | 
			
		||||
            }
 | 
			
		||||
            FinishLayoutInfo(area, currentHeight, startingHeight);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void FinishLayoutInfo(Area area, XUnit currentHeight, XUnit startingHeight)
 | 
			
		||||
        {
 | 
			
		||||
            LayoutInfo layoutInfo = _renderInfo.LayoutInfo;
 | 
			
		||||
            layoutInfo.StartingHeight = startingHeight;
 | 
			
		||||
            //REM: Trailing height would have to be calculated in case tables had a keep with next property.
 | 
			
		||||
            layoutInfo.TrailingHeight = 0;
 | 
			
		||||
            if (_currRow >= 0)
 | 
			
		||||
            {
 | 
			
		||||
                layoutInfo.ContentArea = new Rectangle(area.X, area.Y, 0, currentHeight);
 | 
			
		||||
                XUnit width = LeftBorderOffset;
 | 
			
		||||
                foreach (Column clm in _table.Columns)
 | 
			
		||||
                {
 | 
			
		||||
                    width += clm.Width;
 | 
			
		||||
                }
 | 
			
		||||
                layoutInfo.ContentArea.Width = width;
 | 
			
		||||
            }
 | 
			
		||||
            layoutInfo.MinWidth = layoutInfo.ContentArea.Width;
 | 
			
		||||
 | 
			
		||||
            if (!_table.Rows._leftIndent.IsNull)
 | 
			
		||||
                layoutInfo.Left = _table.Rows.LeftIndent.Point;
 | 
			
		||||
 | 
			
		||||
            else if (_table.Rows.Alignment == RowAlignment.Left)
 | 
			
		||||
            {
 | 
			
		||||
                XUnit leftOffset = LeftBorderOffset;
 | 
			
		||||
                leftOffset += _table.Columns[0].LeftPadding;
 | 
			
		||||
                layoutInfo.Left = -leftOffset;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            switch (_table.Rows.Alignment)
 | 
			
		||||
            {
 | 
			
		||||
                case RowAlignment.Left:
 | 
			
		||||
                    layoutInfo.HorizontalAlignment = ElementAlignment.Near;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case RowAlignment.Right:
 | 
			
		||||
                    layoutInfo.HorizontalAlignment = ElementAlignment.Far;
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case RowAlignment.Center:
 | 
			
		||||
                    layoutInfo.HorizontalAlignment = ElementAlignment.Center;
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private XUnit LeftBorderOffset
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                if (_leftBorderOffset < 0)
 | 
			
		||||
                {
 | 
			
		||||
                    if (_table.Rows.Count > 0 && _table.Columns.Count > 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        Borders borders = _mergedCells.GetEffectiveBorders(_table[0, 0]);
 | 
			
		||||
                        BordersRenderer bordersRenderer = new BordersRenderer(borders, _gfx);
 | 
			
		||||
                        _leftBorderOffset = bordersRenderer.GetWidth(BorderType.Left);
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                        _leftBorderOffset = 0;
 | 
			
		||||
                }
 | 
			
		||||
                return _leftBorderOffset;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private XUnit _leftBorderOffset = -1;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///   Calcs either the height of the header rows or the height of the uppermost top border.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns> </returns>
 | 
			
		||||
        private XUnit CalcStartingHeight()
 | 
			
		||||
        {
 | 
			
		||||
            XUnit height = 0;
 | 
			
		||||
            if (_lastHeaderRow >= 0)
 | 
			
		||||
            {
 | 
			
		||||
                height = _bottomBorderMap[_lastHeaderRow + 1];
 | 
			
		||||
                height += CalcMaxTopBorderWidth(0);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if (_table.Rows.Count > _startRow)
 | 
			
		||||
                    height = CalcMaxTopBorderWidth(_startRow);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return height;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        private void CalcLastHeaderColumn()
 | 
			
		||||
        {
 | 
			
		||||
            _lastHeaderColumn = -1;
 | 
			
		||||
            foreach (Column clm in _table.Columns)
 | 
			
		||||
            {
 | 
			
		||||
                if (clm.HeadingFormat)
 | 
			
		||||
                    _lastHeaderColumn = clm.Index;
 | 
			
		||||
                else break;
 | 
			
		||||
            }
 | 
			
		||||
            if (_lastHeaderColumn >= 0)
 | 
			
		||||
                _lastHeaderRow = CalcLastConnectedColumn(_lastHeaderColumn);
 | 
			
		||||
 | 
			
		||||
            // Ignore heading format if all the table is heading:
 | 
			
		||||
            if (_lastHeaderRow == _table.Rows.Count - 1)
 | 
			
		||||
                _lastHeaderRow = -1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void CalcLastHeaderRow()
 | 
			
		||||
        {
 | 
			
		||||
            _lastHeaderRow = -1;
 | 
			
		||||
            foreach (Row row in _table.Rows)
 | 
			
		||||
            {
 | 
			
		||||
                if (row.HeadingFormat)
 | 
			
		||||
                    _lastHeaderRow = row.Index;
 | 
			
		||||
                else break;
 | 
			
		||||
            }
 | 
			
		||||
            if (_lastHeaderRow >= 0)
 | 
			
		||||
                _lastHeaderRow = CalcLastConnectedRow(_lastHeaderRow);
 | 
			
		||||
 | 
			
		||||
            // Ignore heading format if all the table is heading:
 | 
			
		||||
            if (_lastHeaderRow == _table.Rows.Count - 1)
 | 
			
		||||
                _lastHeaderRow = -1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void CreateConnectedRows()
 | 
			
		||||
        {
 | 
			
		||||
            _connectedRowsMap = new Dictionary<int, int>(); //new Sorted_List();
 | 
			
		||||
            foreach (Cell cell in _mergedCells)
 | 
			
		||||
            {
 | 
			
		||||
                if (!_connectedRowsMap.ContainsKey(cell.Row.Index))
 | 
			
		||||
                {
 | 
			
		||||
                    int lastConnectedRow = CalcLastConnectedRow(cell.Row.Index);
 | 
			
		||||
                    _connectedRowsMap[cell.Row.Index] = lastConnectedRow;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void CreateConnectedColumns()
 | 
			
		||||
        {
 | 
			
		||||
            _connectedColumnsMap = new Dictionary<int, int>(); //new SortedList();
 | 
			
		||||
            foreach (Cell cell in _mergedCells)
 | 
			
		||||
            {
 | 
			
		||||
                if (!_connectedColumnsMap.ContainsKey(cell.Column.Index))
 | 
			
		||||
                {
 | 
			
		||||
                    int lastConnectedColumn = CalcLastConnectedColumn(cell.Column.Index);
 | 
			
		||||
                    _connectedColumnsMap[cell.Column.Index] = lastConnectedColumn;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void CreateBottomBorderMap()
 | 
			
		||||
        {
 | 
			
		||||
            _bottomBorderMap = new Dictionary<int, XUnit>(); //new SortedList();
 | 
			
		||||
            _bottomBorderMap.Add(0, XUnit.FromPoint(0));
 | 
			
		||||
            while (!_bottomBorderMap.ContainsKey(_table.Rows.Count))
 | 
			
		||||
            {
 | 
			
		||||
                CreateNextBottomBorderPosition();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///   Calculates the top border width for the first row that is rendered or formatted.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="row"> The row index. </param>
 | 
			
		||||
        private XUnit CalcMaxTopBorderWidth(int row)
 | 
			
		||||
        {
 | 
			
		||||
            XUnit maxWidth = 0;
 | 
			
		||||
            if (_table.Rows.Count > row)
 | 
			
		||||
            {
 | 
			
		||||
                int cellIdx = _mergedCells.BinarySearch(_table[row, 0], new CellComparer());
 | 
			
		||||
                Cell rowCell = _mergedCells[cellIdx];
 | 
			
		||||
                while (cellIdx < _mergedCells.Count)
 | 
			
		||||
                {
 | 
			
		||||
                    rowCell = _mergedCells[cellIdx];
 | 
			
		||||
                    if (rowCell.Row.Index > row)
 | 
			
		||||
                        break;
 | 
			
		||||
 | 
			
		||||
                    if (rowCell._borders != null && !rowCell._borders.IsNull())
 | 
			
		||||
                    {
 | 
			
		||||
                        BordersRenderer bordersRenderer = new BordersRenderer(rowCell.Borders, _gfx);
 | 
			
		||||
                        XUnit width = bordersRenderer.GetWidth(BorderType.Top);
 | 
			
		||||
                        if (width > maxWidth)
 | 
			
		||||
                            maxWidth = width;
 | 
			
		||||
                    }
 | 
			
		||||
                    ++cellIdx;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return maxWidth;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///   Creates the next bottom border position.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        private void CreateNextBottomBorderPosition()
 | 
			
		||||
        {
 | 
			
		||||
            //int lastIdx = _bottomBorderMap.Count - 1;
 | 
			
		||||
            // SortedList version:
 | 
			
		||||
            //int lastBorderRow = (int)bottomBorderMap.GetKey(lastIdx);
 | 
			
		||||
            //XUnit lastPos = (XUnit)bottomBorderMap.GetByIndex(lastIdx);
 | 
			
		||||
            int lastBorderRow = 0;
 | 
			
		||||
            foreach (int key in _bottomBorderMap.Keys)
 | 
			
		||||
            {
 | 
			
		||||
                if (key > lastBorderRow)
 | 
			
		||||
                    lastBorderRow = key;
 | 
			
		||||
            }
 | 
			
		||||
            XUnit lastPos = _bottomBorderMap[lastBorderRow];
 | 
			
		||||
 | 
			
		||||
            Cell minMergedCell = GetMinMergedCell(lastBorderRow);
 | 
			
		||||
            FormattedCell minMergedFormattedCell = _formattedCells[minMergedCell];
 | 
			
		||||
            XUnit maxBottomBorderPosition = lastPos + minMergedFormattedCell.InnerHeight;
 | 
			
		||||
            maxBottomBorderPosition += CalcBottomBorderWidth(minMergedCell);
 | 
			
		||||
 | 
			
		||||
            foreach (Cell cell in _mergedCells)
 | 
			
		||||
            {
 | 
			
		||||
                if (cell.Row.Index > minMergedCell.Row.Index + minMergedCell.MergeDown)
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                if (cell.Row.Index + cell.MergeDown == minMergedCell.Row.Index + minMergedCell.MergeDown)
 | 
			
		||||
                {
 | 
			
		||||
                    FormattedCell formattedCell = _formattedCells[cell];
 | 
			
		||||
                    // !!!new 18-03-09 Attempt to fix an exception. begin
 | 
			
		||||
                    // if (cell.Row.Index < _bottomBorderMap.Count)
 | 
			
		||||
                    {
 | 
			
		||||
                        // !!!new 18-03-09 Attempt to fix an exception. end
 | 
			
		||||
#if true
 | 
			
		||||
                        // !!!new 18-03-09 Attempt to fix an exception. begin
 | 
			
		||||
                        XUnit topBorderPos = maxBottomBorderPosition;
 | 
			
		||||
                        if (!_bottomBorderMap.TryGetValue(cell.Row.Index, out topBorderPos))
 | 
			
		||||
                        {
 | 
			
		||||
                            //GetType();
 | 
			
		||||
                        }
 | 
			
		||||
                        // !!!new 18-03-09 Attempt to fix an exception. end
 | 
			
		||||
#else
 | 
			
		||||
                        XUnit topBorderPos = _bottomBorderMap[cell.Row.Index];
 | 
			
		||||
#endif
 | 
			
		||||
                        XUnit bottomBorderPos = topBorderPos + formattedCell.InnerHeight;
 | 
			
		||||
                        bottomBorderPos += CalcBottomBorderWidth(cell);
 | 
			
		||||
                        if (bottomBorderPos > maxBottomBorderPosition)
 | 
			
		||||
                            maxBottomBorderPosition = bottomBorderPos;
 | 
			
		||||
                        // !!!new 18-03-09 Attempt to fix an exception. begin
 | 
			
		||||
                    }
 | 
			
		||||
                    // !!!new 18-03-09 Attempt to fix an exception. end
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            _bottomBorderMap.Add(minMergedCell.Row.Index + minMergedCell.MergeDown + 1, maxBottomBorderPosition);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///   Calculates bottom border width of a cell.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="cell"> The cell the bottom border of the row that is probed. </param>
 | 
			
		||||
        /// <returns> The calculated border width. </returns>
 | 
			
		||||
        private XUnit CalcBottomBorderWidth(Cell cell)
 | 
			
		||||
        {
 | 
			
		||||
            Borders borders = _mergedCells.GetEffectiveBorders(cell);
 | 
			
		||||
            if (borders != null)
 | 
			
		||||
            {
 | 
			
		||||
                BordersRenderer bordersRenderer = new BordersRenderer(borders, _gfx);
 | 
			
		||||
                return bordersRenderer.GetWidth(BorderType.Bottom);
 | 
			
		||||
            }
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the first cell that ends in the given row or as close as possible.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="row">The row to probe.</param>
 | 
			
		||||
        /// <returns>The first cell with minimal vertical merge.</returns>
 | 
			
		||||
        private Cell GetMinMergedCell(int row)
 | 
			
		||||
        {
 | 
			
		||||
#if true
 | 
			
		||||
            //!!!new 18-03-10 begin
 | 
			
		||||
            // Also look at rows above "row", but only consider cells that end at "row" or as close as possible.
 | 
			
		||||
            int minMerge = _table.Rows.Count;
 | 
			
		||||
            Cell minCell = null;
 | 
			
		||||
            foreach (Cell cell in _mergedCells)
 | 
			
		||||
            {
 | 
			
		||||
                if (cell.Row.Index <= row && cell.Row.Index + cell.MergeDown >= row)
 | 
			
		||||
                {
 | 
			
		||||
                    if (cell.Row.Index == row && cell.MergeDown == 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        // Perfect match: non-merged cell in the desired row.
 | 
			
		||||
                        minCell = cell;
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (cell.Row.Index + cell.MergeDown - row < minMerge)
 | 
			
		||||
                    {
 | 
			
		||||
                        minMerge = cell.Row.Index + cell.MergeDown - row;
 | 
			
		||||
                        minCell = cell;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if (cell.Row.Index > row)
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            //!!!new 18-03-10 end
 | 
			
		||||
#else
 | 
			
		||||
            int minMerge = _table.Rows.Count;
 | 
			
		||||
            Cell minCell = null;
 | 
			
		||||
            foreach (Cell cell in _mergedCells)
 | 
			
		||||
            {
 | 
			
		||||
                if (cell.Row.Index == row)
 | 
			
		||||
                {
 | 
			
		||||
                    if (cell.MergeDown == 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        minCell = cell;
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (cell.MergeDown < minMerge)
 | 
			
		||||
                    {
 | 
			
		||||
                        minMerge = cell.MergeDown;
 | 
			
		||||
                        minCell = cell;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if (cell.Row.Index > row)
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
#endif
 | 
			
		||||
            return minCell;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///   Calculates the last row that is connected with the given row.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="row"> The row that is probed for downward connection. </param>
 | 
			
		||||
        /// <returns> The last row that is connected with the given row. </returns>
 | 
			
		||||
        private int CalcLastConnectedRow(int row)
 | 
			
		||||
        {
 | 
			
		||||
            int lastConnectedRow = row;
 | 
			
		||||
            foreach (Cell cell in _mergedCells)
 | 
			
		||||
            {
 | 
			
		||||
                if (cell.Row.Index <= lastConnectedRow)
 | 
			
		||||
                {
 | 
			
		||||
                    int downConnection = Math.Max(cell.Row.KeepWith, cell.MergeDown);
 | 
			
		||||
                    if (lastConnectedRow < cell.Row.Index + downConnection)
 | 
			
		||||
                        lastConnectedRow = cell.Row.Index + downConnection;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return lastConnectedRow;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///   Calculates the last column that is connected with the specified column.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="column"> The column that is probed for downward connection. </param>
 | 
			
		||||
        /// <returns> The last column that is connected with the given column. </returns>
 | 
			
		||||
        private int CalcLastConnectedColumn(int column)
 | 
			
		||||
        {
 | 
			
		||||
            int lastConnectedColumn = column;
 | 
			
		||||
            foreach (Cell cell in _mergedCells)
 | 
			
		||||
            {
 | 
			
		||||
                if (cell.Column.Index <= lastConnectedColumn)
 | 
			
		||||
                {
 | 
			
		||||
                    int rightConnection = Math.Max(cell.Column.KeepWith, cell.MergeRight);
 | 
			
		||||
                    if (lastConnectedColumn < cell.Column.Index + rightConnection)
 | 
			
		||||
                        lastConnectedColumn = cell.Column.Index + rightConnection;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return lastConnectedColumn;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private readonly Table _table;
 | 
			
		||||
        private MergedCellList _mergedCells;
 | 
			
		||||
        private Dictionary<Cell, FormattedCell> _formattedCells; //SortedList formattedCells;
 | 
			
		||||
        private Dictionary<int, XUnit> _bottomBorderMap; //SortedList bottomBorderMap;
 | 
			
		||||
        private Dictionary<int, int> _connectedRowsMap; //SortedList connectedRowsMap;
 | 
			
		||||
        private Dictionary<int, int> _connectedColumnsMap; //SortedList connectedColumnsMap;
 | 
			
		||||
 | 
			
		||||
        private int _lastHeaderRow;
 | 
			
		||||
        private int _lastHeaderColumn;
 | 
			
		||||
        private int _startRow;
 | 
			
		||||
        private int _currRow;
 | 
			
		||||
        private int _endRow = -1;
 | 
			
		||||
 | 
			
		||||
        private bool _doHorizontalBreak;
 | 
			
		||||
        private XUnit _startX;
 | 
			
		||||
        private XUnit _startY;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								MigraDoc.Rendering/Rendering/TextFrameFormatInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								MigraDoc.Rendering/Rendering/TextFrameFormatInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Formatting information for textframes.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public sealed class TextFrameFormatInfo : ShapeFormatInfo
 | 
			
		||||
    {
 | 
			
		||||
        public FormattedTextFrame FormattedTextFrame;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										48
									
								
								MigraDoc.Rendering/Rendering/TextFrameRenderInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								MigraDoc.Rendering/Rendering/TextFrameRenderInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Summary description for TextFrameRenderInfo.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public sealed class TextFrameRenderInfo : ShapeRenderInfo
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the format information in a specific derived type. For a table, for example, this will be a TableFormatInfo with information about the first and last row showing on a page.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public override FormatInfo FormatInfo
 | 
			
		||||
        {
 | 
			
		||||
            get { return _formatInfo ?? (_formatInfo = new TextFrameFormatInfo()); }
 | 
			
		||||
            set { _formatInfo = (TextFrameFormatInfo)value; }
 | 
			
		||||
        }
 | 
			
		||||
        TextFrameFormatInfo _formatInfo;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										130
									
								
								MigraDoc.Rendering/Rendering/TextFrameRenderer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								MigraDoc.Rendering/Rendering/TextFrameRenderer.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
using MigraDoc.DocumentObjectModel.Shapes;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Renders textframes.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class TextFrameRenderer : ShapeRenderer
 | 
			
		||||
    {
 | 
			
		||||
        public TextFrameRenderer(XGraphics gfx, TextFrame textframe, FieldInfos fieldInfos)
 | 
			
		||||
            : base(gfx, textframe, fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _textframe = textframe;
 | 
			
		||||
            TextFrameRenderInfo renderInfo = new TextFrameRenderInfo();
 | 
			
		||||
            renderInfo.DocumentObject = _shape;
 | 
			
		||||
            _renderInfo = renderInfo;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public TextFrameRenderer(XGraphics gfx, RenderInfo renderInfo, FieldInfos fieldInfos)
 | 
			
		||||
            : base(gfx, renderInfo, fieldInfos)
 | 
			
		||||
        {
 | 
			
		||||
            _textframe = (TextFrame)renderInfo.DocumentObject;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void Format(Area area, FormatInfo previousFormatInfo)
 | 
			
		||||
        {
 | 
			
		||||
            FormattedTextFrame formattedTextFrame = new FormattedTextFrame(_textframe, _documentRenderer, _fieldInfos);
 | 
			
		||||
            formattedTextFrame.Format(_gfx);
 | 
			
		||||
            ((TextFrameFormatInfo)_renderInfo.FormatInfo).FormattedTextFrame = formattedTextFrame;
 | 
			
		||||
            base.Format(area, previousFormatInfo);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override LayoutInfo InitialLayoutInfo
 | 
			
		||||
        {
 | 
			
		||||
            get { return base.InitialLayoutInfo; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void Render()
 | 
			
		||||
        {
 | 
			
		||||
            RenderFilling();
 | 
			
		||||
            RenderContent();
 | 
			
		||||
            RenderLine();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void RenderContent()
 | 
			
		||||
        {
 | 
			
		||||
            FormattedTextFrame formattedTextFrame = ((TextFrameFormatInfo)_renderInfo.FormatInfo).FormattedTextFrame;
 | 
			
		||||
            RenderInfo[] renderInfos = formattedTextFrame.GetRenderInfos();
 | 
			
		||||
            if (renderInfos == null)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            XGraphicsState state = Transform();
 | 
			
		||||
            RenderByInfos(renderInfos);
 | 
			
		||||
            ResetTransform(state);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        XGraphicsState Transform()
 | 
			
		||||
        {
 | 
			
		||||
            Area frameContentArea = _renderInfo.LayoutInfo.ContentArea;
 | 
			
		||||
            XGraphicsState state = _gfx.Save();
 | 
			
		||||
            XUnit xPosition;
 | 
			
		||||
            XUnit yPosition;
 | 
			
		||||
            switch (_textframe.Orientation)
 | 
			
		||||
            {
 | 
			
		||||
                case TextOrientation.Downward:
 | 
			
		||||
                case TextOrientation.Vertical:
 | 
			
		||||
                case TextOrientation.VerticalFarEast:
 | 
			
		||||
                    xPosition = frameContentArea.X + frameContentArea.Width;
 | 
			
		||||
                    yPosition = frameContentArea.Y;
 | 
			
		||||
                    _gfx.TranslateTransform(xPosition, yPosition);
 | 
			
		||||
                    _gfx.RotateTransform(90);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case TextOrientation.Upward:
 | 
			
		||||
                    state = _gfx.Save();
 | 
			
		||||
                    xPosition = frameContentArea.X;
 | 
			
		||||
                    yPosition = frameContentArea.Y + frameContentArea.Height;
 | 
			
		||||
                    _gfx.TranslateTransform(xPosition, yPosition);
 | 
			
		||||
                    _gfx.RotateTransform(-90);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    xPosition = frameContentArea.X;
 | 
			
		||||
                    yPosition = frameContentArea.Y;
 | 
			
		||||
                    _gfx.TranslateTransform(xPosition, yPosition);
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            return state;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void ResetTransform(XGraphicsState state)
 | 
			
		||||
        {
 | 
			
		||||
            if (state != null)
 | 
			
		||||
                _gfx.Restore(state);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        readonly TextFrame _textframe;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										362
									
								
								MigraDoc.Rendering/Rendering/TopDownFormatter.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										362
									
								
								MigraDoc.Rendering/Rendering/TopDownFormatter.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,362 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using MigraDoc.DocumentObjectModel;
 | 
			
		||||
using PdfSharp.Drawing;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Formats a series of document elements from top to bottom.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class TopDownFormatter
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Returns the max of the given Margins, if both are positive or 0, the sum otherwise.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="prevBottomMargin">The bottom margin of the previous element.</param>
 | 
			
		||||
        /// <param name="nextTopMargin">The top margin of the next element.</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        private XUnit MarginMax(XUnit prevBottomMargin, XUnit nextTopMargin)
 | 
			
		||||
        {
 | 
			
		||||
            if (prevBottomMargin >= 0 && nextTopMargin >= 0)
 | 
			
		||||
                return Math.Max(prevBottomMargin, nextTopMargin);
 | 
			
		||||
            return prevBottomMargin + nextTopMargin;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public TopDownFormatter(IAreaProvider areaProvider, DocumentRenderer documentRenderer, DocumentElements elements)
 | 
			
		||||
        {
 | 
			
		||||
            _documentRenderer = documentRenderer;
 | 
			
		||||
            _areaProvider = areaProvider;
 | 
			
		||||
            _elements = elements;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        readonly IAreaProvider _areaProvider;
 | 
			
		||||
 | 
			
		||||
        readonly DocumentElements _elements;
 | 
			
		||||
 | 
			
		||||
        /// <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;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Finishes rendering for the page.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="lastRenderInfo">The last render info.</param>
 | 
			
		||||
        /// <param name="pagebreakBefore">set to <c>true</c> if there is a pagebreak before this page.</param>
 | 
			
		||||
        /// <param name="renderInfos">The render infos.</param>
 | 
			
		||||
        /// <returns>
 | 
			
		||||
        /// The RenderInfo to set as previous RenderInfo.
 | 
			
		||||
        /// </returns>
 | 
			
		||||
        RenderInfo FinishPage(RenderInfo lastRenderInfo, bool pagebreakBefore, ref List<RenderInfo> renderInfos)
 | 
			
		||||
        {
 | 
			
		||||
            RenderInfo prevRenderInfo;
 | 
			
		||||
            if (lastRenderInfo.FormatInfo.IsEmpty || pagebreakBefore)
 | 
			
		||||
            {
 | 
			
		||||
                prevRenderInfo = null;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                prevRenderInfo = lastRenderInfo;
 | 
			
		||||
                renderInfos.Add(lastRenderInfo);
 | 
			
		||||
                if (lastRenderInfo.FormatInfo.IsEnding)
 | 
			
		||||
                    prevRenderInfo = null;
 | 
			
		||||
            }
 | 
			
		||||
            _areaProvider.StoreRenderInfos(renderInfos);
 | 
			
		||||
            renderInfos = new List<RenderInfo>();
 | 
			
		||||
            return prevRenderInfo;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Indicates that a break between areas has to be performed before the element with the given idx.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="idx">Index of the document element.</param>
 | 
			
		||||
        /// <param name="renderer">A formatted renderer for the document element.</param>
 | 
			
		||||
        /// <param name="remainingArea">The remaining area.</param>
 | 
			
		||||
        bool IsForcedAreaBreak(int idx, Renderer renderer, Area remainingArea)
 | 
			
		||||
        {
 | 
			
		||||
            FormatInfo formatInfo = renderer.RenderInfo.FormatInfo;
 | 
			
		||||
            LayoutInfo layoutInfo = renderer.RenderInfo.LayoutInfo;
 | 
			
		||||
 | 
			
		||||
            if (formatInfo.IsStarting && !formatInfo.StartingIsComplete)
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
            if (layoutInfo.KeepTogether && !formatInfo.IsComplete)
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
            if (layoutInfo.KeepTogether && layoutInfo.KeepWithNext)
 | 
			
		||||
            {
 | 
			
		||||
                Area area = remainingArea.Lower(layoutInfo.ContentArea.Height);
 | 
			
		||||
                return NextElementsDontFit(idx, area, layoutInfo.MarginBottom);
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Indicates that the Ending of the element has to be removed.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="prevRenderInfo">The prev render info.</param>
 | 
			
		||||
        /// <param name="succedingRenderInfo">The succeding render info.</param>
 | 
			
		||||
        /// <param name="remainingArea">The remaining area.</param>
 | 
			
		||||
        bool PreviousRendererNeedsRemoveEnding(RenderInfo prevRenderInfo, RenderInfo succedingRenderInfo, Area remainingArea)
 | 
			
		||||
        {
 | 
			
		||||
            if (prevRenderInfo == null)
 | 
			
		||||
                return false;
 | 
			
		||||
            LayoutInfo layoutInfo = succedingRenderInfo.LayoutInfo;
 | 
			
		||||
            FormatInfo formatInfo = succedingRenderInfo.FormatInfo;
 | 
			
		||||
            LayoutInfo prevLayoutInfo = prevRenderInfo.LayoutInfo;
 | 
			
		||||
            if (formatInfo.IsEnding && !formatInfo.EndingIsComplete)
 | 
			
		||||
            {
 | 
			
		||||
                Area area = _areaProvider.ProbeNextArea();
 | 
			
		||||
                if (area.Height > prevLayoutInfo.TrailingHeight + layoutInfo.TrailingHeight + Renderer.Tolerance)
 | 
			
		||||
                    return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The maximum number of elements that can be combined via keepwithnext and keeptogether
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static readonly int MaxCombineElements = 10;
 | 
			
		||||
        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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool NeedsEndingOnNextArea(int idx, Renderer renderer, Area remainingArea, bool isFirstOnPage)
 | 
			
		||||
        {
 | 
			
		||||
            LayoutInfo layoutInfo = renderer.RenderInfo.LayoutInfo;
 | 
			
		||||
            if (isFirstOnPage && layoutInfo.KeepTogether)
 | 
			
		||||
                return false;
 | 
			
		||||
            FormatInfo formatInfo = renderer.RenderInfo.FormatInfo;
 | 
			
		||||
 | 
			
		||||
            if (!formatInfo.EndingIsComplete)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            if (layoutInfo.KeepWithNext)
 | 
			
		||||
            {
 | 
			
		||||
                remainingArea = remainingArea.Lower(layoutInfo.ContentArea.Height);
 | 
			
		||||
                return NextElementsDontFit(idx, remainingArea, layoutInfo.MarginBottom);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        readonly DocumentRenderer _documentRenderer;
 | 
			
		||||
        XGraphics _gfx;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								MigraDoc.Rendering/Rendering/enums/ElementAlignment.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								MigraDoc.Rendering/Rendering/enums/ElementAlignment.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Alignment of layout elements.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public enum ElementAlignment
 | 
			
		||||
    {
 | 
			
		||||
        Near = 0, // Default
 | 
			
		||||
        Center,
 | 
			
		||||
        Far,
 | 
			
		||||
        Inside,
 | 
			
		||||
        Outside
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								MigraDoc.Rendering/Rendering/enums/Floating.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								MigraDoc.Rendering/Rendering/enums/Floating.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Floating behavior of layout elements.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public enum Floating
 | 
			
		||||
    {
 | 
			
		||||
        TopBottom = 0, // Default
 | 
			
		||||
        None, // The element is ignored.
 | 
			
		||||
 | 
			
		||||
        // Served for future extensions:
 | 
			
		||||
        Left,
 | 
			
		||||
        Right,
 | 
			
		||||
        BothSides,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								MigraDoc.Rendering/Rendering/enums/HorizontalReference.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								MigraDoc.Rendering/Rendering/enums/HorizontalReference.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Horizontal reference point of alignment.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public enum HorizontalReference
 | 
			
		||||
    {
 | 
			
		||||
        AreaBoundary = 0, // Default
 | 
			
		||||
        PageMargin,
 | 
			
		||||
        Page
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								MigraDoc.Rendering/Rendering/enums/ImageFailure.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								MigraDoc.Rendering/Rendering/enums/ImageFailure.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    public enum ImageFailure
 | 
			
		||||
    {
 | 
			
		||||
        None = 0,
 | 
			
		||||
        FileNotFound,
 | 
			
		||||
        InvalidType,
 | 
			
		||||
        NotRead,
 | 
			
		||||
        EmptySize
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										81
									
								
								MigraDoc.Rendering/Rendering/enums/PageRenderOptions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								MigraDoc.Rendering/Rendering/enums/PageRenderOptions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Determines the parts of a page to be rendered.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [Flags]
 | 
			
		||||
    public enum PageRenderOptions
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Renders nothing (creates an empty page).
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        None = 0,
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Renders Headers.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        RenderHeader = 1,
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Renders Footers.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        RenderFooter = 2,
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Renders Content.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        RenderContent = 4,
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Renders PDF background pages.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        RenderPdfBackground = 8,
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Renders PDF content pages.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        RenderPdfContent = 16,
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Renders all.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        All = RenderHeader | RenderFooter | RenderContent | RenderPdfBackground | RenderPdfContent,
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Creates not even an empty page.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        RemovePage = 32
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								MigraDoc.Rendering/Rendering/enums/VerticalReference.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								MigraDoc.Rendering/Rendering/enums/VerticalReference.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
#region MigraDoc - Creating Documents on the Fly
 | 
			
		||||
//
 | 
			
		||||
// Authors:
 | 
			
		||||
//   Klaus Potzesny
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2001-2017 empira Software GmbH, Cologne Area (Germany)
 | 
			
		||||
//
 | 
			
		||||
// http://www.pdfsharp.com
 | 
			
		||||
// http://www.migradoc.com
 | 
			
		||||
// http://sourceforge.net/projects/pdfsharp
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a
 | 
			
		||||
// copy of this software and associated documentation files (the "Software"),
 | 
			
		||||
// to deal in the Software without restriction, including without limitation
 | 
			
		||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
			
		||||
// and/or sell copies of the Software, and to permit persons to whom the
 | 
			
		||||
// Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included
 | 
			
		||||
// in all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | 
			
		||||
// DEALINGS IN THE SOFTWARE.
 | 
			
		||||
#endregion
 | 
			
		||||
 | 
			
		||||
namespace MigraDoc.Rendering
 | 
			
		||||
{
 | 
			
		||||
    public enum VerticalReference
 | 
			
		||||
    {
 | 
			
		||||
        PreviousElement = 0, // Default
 | 
			
		||||
        AreaBoundary,
 | 
			
		||||
        PageMargin,
 | 
			
		||||
        Page
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user