This commit is contained in:
2021-05-25 17:00:45 +05:00
parent e2fcfed44c
commit ec2dac13d8
1172 changed files with 5636 additions and 5839 deletions

View File

@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Version>3.0.0.0</Version>
<TargetFramework>netstandard2.0</TargetFramework>
<DefineConstants>$(DefineConstants);CORE;CORE_WITH_GDI</DefineConstants>
<AssemblyName>MigraDoc.Rendering</AssemblyName>
<PackageId>MigraDoc.Rendering</PackageId>
<GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
<GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
<RootNamespace>MigraDoc.Rendering</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="4.5.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MigraDoc.DocumentObjectModel\MigraDoc.DocumentObjectModel.csproj" />
<ProjectReference Include="..\PdfSharp.Charting\PdfSharp.Charting.csproj" />
<ProjectReference Include="..\PdfSharp\PdfSharp.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
<ItemGroup>
<Compile Update="Rendering.Printing\MigraDocPrintDocument.cs">
<SubType>Component</SubType>
</Compile>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,153 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A0B7940A-0BFC-476D-A204-73F7C0F88FDE}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MigraDoc</RootNamespace>
<AssemblyName>MigraDoc.Rendering</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;CORE;CORE_WITH_GDI</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;CORE;CORE_WITH_GDI</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\MigraDoc.Rendering.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>StrongnameKey.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\VersionInfo.cs" />
<Compile Include="Rendering.ChartMapper\AxisMapper.cs" />
<Compile Include="Rendering.ChartMapper\ChartMapper.cs" />
<Compile Include="Rendering.ChartMapper\DataLabelMapper.cs" />
<Compile Include="Rendering.ChartMapper\FillFormatMapper.cs" />
<Compile Include="Rendering.ChartMapper\FontMapper.cs" />
<Compile Include="Rendering.ChartMapper\LegendMapper.cs" />
<Compile Include="Rendering.ChartMapper\LineFormatMapper.cs" />
<Compile Include="Rendering.ChartMapper\PlotAreaMapper.cs" />
<Compile Include="Rendering.ChartMapper\SeriesCollectionMapper.cs" />
<Compile Include="Rendering.ChartMapper\XValuesMapper.cs" />
<Compile Include="Rendering.Resources\Messages2.cs" />
<Compile Include="Rendering.UnitTest\TestLayout.cs" />
<Compile Include="Rendering.UnitTest\TestParagraphIterator.cs" />
<Compile Include="Rendering.UnitTest\TestParagraphRenderer.cs" />
<Compile Include="Rendering.UnitTest\TestTable.cs" />
<Compile Include="Rendering.UnitTest\ValueDumper.cs" />
<Compile Include="Rendering\Area.cs" />
<Compile Include="Rendering\BordersRenderer.cs" />
<Compile Include="Rendering\ChartFormatInfo.cs" />
<Compile Include="Rendering\ChartRenderer.cs" />
<Compile Include="Rendering\ChartRenderInfo.cs" />
<Compile Include="Rendering\ColorHelper.cs" />
<Compile Include="Rendering\DocumentRenderer.cs" />
<Compile Include="Rendering\enums\ElementAlignment.cs" />
<Compile Include="Rendering\enums\Floating.cs" />
<Compile Include="Rendering\enums\HorizontalReference.cs" />
<Compile Include="Rendering\enums\ImageFailure.cs" />
<Compile Include="Rendering\enums\PageRenderOptions.cs" />
<Compile Include="Rendering\enums\VerticalReference.cs" />
<Compile Include="Rendering\FieldInfos.cs" />
<Compile Include="Rendering\FillFormatRenderer.cs" />
<Compile Include="Rendering\FontHandler.cs" />
<Compile Include="Rendering\FormatInfo.cs" />
<Compile Include="Rendering\FormattedCell.cs" />
<Compile Include="Rendering\FormattedDocument.cs" />
<Compile Include="Rendering\FormattedHeaderFooter.cs" />
<Compile Include="Rendering\FormattedTextArea.cs" />
<Compile Include="Rendering\FormattedTextFrame.cs" />
<Compile Include="Rendering\IAreaProvider.cs" />
<Compile Include="Rendering\ImageFormatInfo.cs" />
<Compile Include="Rendering\ImageRenderer.cs" />
<Compile Include="Rendering\ImageRenderInfo.cs" />
<Compile Include="Rendering\LayoutInfo.cs" />
<Compile Include="Rendering\LineFormatRenderer.cs" />
<Compile Include="Rendering\NumberFormatter.cs" />
<Compile Include="Rendering\PageBreakFormatInfo.cs" />
<Compile Include="Rendering\PageBreakRenderer.cs" />
<Compile Include="Rendering\PageBreakRenderInfo.cs" />
<Compile Include="Rendering\PageInfo.cs" />
<Compile Include="Rendering\ParagraphFormatInfo.cs" />
<Compile Include="Rendering\ParagraphIterator.cs" />
<Compile Include="Rendering\ParagraphRenderer.cs" />
<Compile Include="Rendering\ParagraphRenderInfo.cs" />
<Compile Include="Rendering\PdfDocumentRenderer.cs" />
<Compile Include="Rendering\PdfPrinter.cs" />
<Compile Include="Rendering\Renderer.cs" />
<Compile Include="Rendering\RenderInfo.cs" />
<Compile Include="Rendering\ShadingRenderer.cs" />
<Compile Include="Rendering\ShapeFormatInfo.cs" />
<Compile Include="Rendering\ShapeRenderer.cs" />
<Compile Include="Rendering\ShapeRenderInfo.cs" />
<Compile Include="Rendering\TableFormatInfo.cs" />
<Compile Include="Rendering\TableRenderer.cs" />
<Compile Include="Rendering\TableRenderInfo.cs" />
<Compile Include="Rendering\TextFrameFormatInfo.cs" />
<Compile Include="Rendering\TextFrameRenderer.cs" />
<Compile Include="Rendering\TextFrameRenderInfo.cs" />
<Compile Include="Rendering\TopDownFormatter.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\PDFsharp\src\PdfSharp.Charting\PdfSharp.Charting.csproj">
<Project>{6f98a822-41b0-4c7a-85a6-e95c1d3e88ef}</Project>
<Name>PdfSharp.Charting</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\PDFsharp\src\PdfSharp\PDFsharp.csproj">
<Project>{5a6055bc-bf86-4fdd-9f62-0109db7a303b}</Project>
<Name>PDFsharp</Name>
</ProjectReference>
<ProjectReference Include="..\MigraDoc.DocumentObjectModel\MigraDoc.DocumentObjectModel.csproj">
<Project>{6318a852-ef6b-486f-8547-3d7e736d7943}</Project>
<Name>MigraDoc.DocumentObjectModel</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Rendering.Resources\Messages.de.restext" />
<EmbeddedResource Include="Rendering.Resources\Messages.restext" />
<None Include="StrongnameKey.snk" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Rendering.Resources\Messages2.de.resx">
<DependentUpon>Messages2.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Rendering.Resources\Messages2.resx">
<DependentUpon>Messages2.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,100 @@
#region MigraDoc - Creating Documents on the Fly
//
// Authors:
// David Stephensen
//
// 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.ChartMapper
{
/// <summary>
/// The AxisMapper class.
/// </summary>
public class AxisMapper
{
/// <summary>
/// Initializes a new instance of the <see cref="AxisMapper"/> class.
/// </summary>
public AxisMapper()
{ }
static void MapObject(Axis axis, DocumentObjectModel.Shapes.Charts.Axis domAxis)
{
if (!domAxis.IsNull("TickLabels.Format"))
axis.TickLabels.Format = domAxis.TickLabels.Format;
if (!domAxis.IsNull("TickLabels.Style"))
FontMapper.Map(axis.TickLabels.Font, domAxis.TickLabels.Document, domAxis.TickLabels.Style);
if (!domAxis.IsNull("TickLabels.Font"))
FontMapper.Map(axis.TickLabels.Font, domAxis.TickLabels.Font);
if (!domAxis.IsNull("MajorTickMark"))
axis.MajorTickMark = (TickMarkType)domAxis.MajorTickMark;
if (!domAxis.IsNull("MinorTickMark"))
axis.MinorTickMark = (TickMarkType)domAxis.MinorTickMark;
if (!domAxis.IsNull("MajorTick"))
axis.MajorTick = domAxis.MajorTick;
if (!domAxis.IsNull("MinorTick"))
axis.MinorTick = domAxis.MinorTick;
if (!domAxis.IsNull("Title"))
{
axis.Title.Caption = domAxis.Title.Caption;
if (!domAxis.IsNull("Title.Style"))
FontMapper.Map(axis.Title.Font, domAxis.Title.Document, domAxis.Title.Style);
if (!domAxis.IsNull("Title.Font"))
FontMapper.Map(axis.Title.Font, domAxis.Title.Font);
axis.Title.Orientation = domAxis.Title.Orientation.Value;
axis.Title.Alignment = (HorizontalAlignment)domAxis.Title.Alignment;
axis.Title.VerticalAlignment = (VerticalAlignment)domAxis.Title.VerticalAlignment;
}
axis.HasMajorGridlines = domAxis.HasMajorGridlines;
axis.HasMinorGridlines = domAxis.HasMinorGridlines;
if (!domAxis.IsNull("MajorGridlines") && !domAxis.MajorGridlines.IsNull("LineFormat"))
LineFormatMapper.Map(axis.MajorGridlines.LineFormat, domAxis.MajorGridlines.LineFormat);
if (!domAxis.IsNull("MinorGridlines") && !domAxis.MinorGridlines.IsNull("LineFormat"))
LineFormatMapper.Map(axis.MinorGridlines.LineFormat, domAxis.MinorGridlines.LineFormat);
if (!domAxis.IsNull("MaximumScale"))
axis.MaximumScale = domAxis.MaximumScale;
if (!domAxis.IsNull("MinimumScale"))
axis.MinimumScale = domAxis.MinimumScale;
if (!domAxis.IsNull("LineFormat"))
LineFormatMapper.Map(axis.LineFormat, domAxis.LineFormat);
}
public static void Map(Axis axis, DocumentObjectModel.Shapes.Charts.Axis domAxis)
{
AxisMapper mapper = new AxisMapper();
MapObject(axis, domAxis);
}
}
}

View File

@@ -0,0 +1,93 @@
#region MigraDoc - Creating Documents on the Fly
//
// Authors:
// David Stephensen
//
// 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;
using PdfSharp.Drawing;
namespace MigraDoc.Rendering.ChartMapper
{
/// <summary>
/// Maps charts from the MigraDoc.DocumentObjectModel to charts from Pdf.Charting.
/// </summary>
public class ChartMapper
{
/// <summary>
/// Initializes a new instance of the chart mapper object.
/// </summary>
public ChartMapper()
{ }
private ChartFrame MapObject(DocumentObjectModel.Shapes.Charts.Chart domChart)
{
ChartFrame chartFrame = new ChartFrame();
chartFrame.Size = new XSize(domChart.Width.Point, domChart.Height.Point);
chartFrame.Location = new XPoint(domChart.Left.Position.Point, domChart.Top.Position.Point);
Chart chart = new Chart((ChartType)domChart.Type);
if (!domChart.IsNull("XAxis"))
AxisMapper.Map(chart.XAxis, domChart.XAxis);
if (!domChart.IsNull("YAxis"))
AxisMapper.Map(chart.YAxis, domChart.YAxis);
PlotAreaMapper.Map(chart.PlotArea, domChart.PlotArea);
SeriesCollectionMapper.Map(chart.SeriesCollection, domChart.SeriesCollection);
LegendMapper.Map(chart, domChart);
chart.DisplayBlanksAs = (BlankType)domChart.DisplayBlanksAs;
chart.HasDataLabel = domChart.HasDataLabel;
if (!domChart.IsNull("DataLabel"))
DataLabelMapper.Map(chart.DataLabel, domChart.DataLabel);
if (!domChart.IsNull("Style"))
FontMapper.Map(chart.Font, domChart.Document, domChart.Style);
if (!domChart.IsNull("Format.Font"))
FontMapper.Map(chart.Font, domChart.Format.Font);
if (!domChart.IsNull("XValues"))
XValuesMapper.Map(chart.XValues, domChart.XValues);
chartFrame.Add(chart);
return chartFrame;
}
/// <summary>
/// Maps the specified DOM chart.
/// </summary>
/// <param name="domChart">The DOM chart.</param>
/// <returns></returns>
public static ChartFrame Map(DocumentObjectModel.Shapes.Charts.Chart domChart)
{
ChartMapper mapper = new ChartMapper();
return mapper.MapObject(domChart);
}
}
}

View File

@@ -0,0 +1,59 @@
#region MigraDoc - Creating Documents on the Fly
//
// Authors:
// David Stephensen
//
// 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.ChartMapper
{
public class DataLabelMapper
{
private DataLabelMapper()
{ }
void MapObject(DataLabel dataLabel, DocumentObjectModel.Shapes.Charts.DataLabel domDataLabel)
{
if (!domDataLabel.IsNull("Style"))
FontMapper.Map(dataLabel.Font, domDataLabel.Document, domDataLabel.Style);
if (!domDataLabel.IsNull("Font"))
FontMapper.Map(dataLabel.Font, domDataLabel.Font);
dataLabel.Format = domDataLabel.Format;
if (!domDataLabel.IsNull("Position"))
dataLabel.Position = (DataLabelPosition)domDataLabel.Position;
if (!domDataLabel.IsNull("Type"))
dataLabel.Type = (DataLabelType)domDataLabel.Type;
}
public static void Map(DataLabel dataLabel, DocumentObjectModel.Shapes.Charts.DataLabel domDataLabel)
{
DataLabelMapper mapper = new DataLabelMapper();
mapper.MapObject(dataLabel, domDataLabel);
}
}
}

View File

@@ -0,0 +1,62 @@
#region MigraDoc - Creating Documents on the Fly
//
// Authors:
// David Stephensen
//
// 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;
using PdfSharp.Drawing;
namespace MigraDoc.Rendering.ChartMapper
{
public class FillFormatMapper
{
private FillFormatMapper()
{ }
void MapObject(FillFormat fillFormat, DocumentObjectModel.Shapes.FillFormat domFillFormat)
{
if (domFillFormat.Color.IsEmpty)
fillFormat.Color = XColor.Empty;
else
{
#if noCMYK
fillFormat.Color = XColor.FromArgb((int)domFillFormat.Color.Argb);
#else
fillFormat.Color = ColorHelper.ToXColor(domFillFormat.Color, domFillFormat.Document.UseCmykColor);
#endif
}
fillFormat.Visible = domFillFormat.Visible;
}
public static void Map(FillFormat fillFormat, DocumentObjectModel.Shapes.FillFormat domFillFormat)
{
FillFormatMapper mapper = new FillFormatMapper();
mapper.MapObject(fillFormat, domFillFormat);
}
}
}

View File

@@ -0,0 +1,80 @@
#region MigraDoc - Creating Documents on the Fly
//
// Authors:
// David Stephensen
//
// 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;
using PdfSharp.Drawing;
namespace MigraDoc.Rendering.ChartMapper
{
public class FontMapper
{
private FontMapper()
{ }
void MapObject(Font font, DocumentObjectModel.Font domFont)
{
font.Bold = domFont.Bold;
if (domFont.Color.IsEmpty)
font.Color = XColor.Empty;
else
{
#if noCMYK
font.Color = XColor.FromArgb((int)domFont.Color.Argb);
#else
font.Color = ColorHelper.ToXColor(domFont.Color, domFont.Document.UseCmykColor);
#endif
}
font.Italic = domFont.Italic;
if (!domFont.IsNull("Name"))
font.Name = domFont.Name;
if (!domFont.IsNull("Size"))
font.Size = domFont.Size.Point;
font.Subscript = domFont.Subscript;
font.Superscript = domFont.Superscript;
font.Underline = (Underline)domFont.Underline;
}
public static void Map(Font font, DocumentObjectModel.Document domDocument, string domStyleName)
{
DocumentObjectModel.Style domStyle = domDocument.Styles[domStyleName];
if (domStyle != null)
{
FontMapper mapper = new FontMapper();
mapper.MapObject(font, domStyle.Font);
}
}
public static void Map(Font font, DocumentObjectModel.Font domFont)
{
FontMapper mapper = new FontMapper();
mapper.MapObject(font, domFont);
}
}
}

View File

@@ -0,0 +1,122 @@
#region MigraDoc - Creating Documents on the Fly
//
// Authors:
// David Stephensen
//
// 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.ChartMapper
{
public class LegendMapper
{
private LegendMapper()
{ }
void MapObject(Chart chart, DocumentObjectModel.Shapes.Charts.Chart domChart)
{
DocumentObjectModel.Shapes.Charts.Legend domLegend = null;
DocumentObjectModel.Shapes.Charts.TextArea textArea = null;
foreach (DocumentObjectModel.DocumentObject domObj in domChart.BottomArea.Elements)
{
if (domObj is DocumentObjectModel.Shapes.Charts.Legend)
{
chart.Legend.Docking = DockingType.Bottom;
domLegend = domObj as DocumentObjectModel.Shapes.Charts.Legend;
textArea = domChart.BottomArea;
}
}
foreach (DocumentObjectModel.DocumentObject domObj in domChart.RightArea.Elements)
{
if (domObj is DocumentObjectModel.Shapes.Charts.Legend)
{
chart.Legend.Docking = DockingType.Right;
domLegend = domObj as DocumentObjectModel.Shapes.Charts.Legend;
textArea = domChart.RightArea;
}
}
foreach (DocumentObjectModel.DocumentObject domObj in domChart.LeftArea.Elements)
{
if (domObj is DocumentObjectModel.Shapes.Charts.Legend)
{
chart.Legend.Docking = DockingType.Left;
domLegend = domObj as DocumentObjectModel.Shapes.Charts.Legend;
textArea = domChart.LeftArea;
}
}
foreach (DocumentObjectModel.DocumentObject domObj in domChart.TopArea.Elements)
{
if (domObj is DocumentObjectModel.Shapes.Charts.Legend)
{
chart.Legend.Docking = DockingType.Top;
domLegend = domObj as DocumentObjectModel.Shapes.Charts.Legend;
textArea = domChart.TopArea;
}
}
foreach (DocumentObjectModel.DocumentObject domObj in domChart.HeaderArea.Elements)
{
if (domObj is DocumentObjectModel.Shapes.Charts.Legend)
{
chart.Legend.Docking = DockingType.Top;
domLegend = domObj as DocumentObjectModel.Shapes.Charts.Legend;
textArea = domChart.HeaderArea;
}
}
foreach (DocumentObjectModel.DocumentObject domObj in domChart.FooterArea.Elements)
{
if (domObj is DocumentObjectModel.Shapes.Charts.Legend)
{
chart.Legend.Docking = DockingType.Bottom;
domLegend = domObj as DocumentObjectModel.Shapes.Charts.Legend;
textArea = domChart.FooterArea;
}
}
if (domLegend != null)
{
if (!domLegend.IsNull("LineFormat"))
LineFormatMapper.Map(chart.Legend.LineFormat, domLegend.LineFormat);
if (!textArea.IsNull("Style"))
FontMapper.Map(chart.Legend.Font, textArea.Document, textArea.Style);
if (!domLegend.IsNull("Format.Font"))
FontMapper.Map(chart.Legend.Font, domLegend.Format.Font);
}
}
public static void Map(Chart chart, DocumentObjectModel.Shapes.Charts.Chart domChart)
{
LegendMapper mapper = new LegendMapper();
mapper.MapObject(chart, domChart);
}
}
}

View File

@@ -0,0 +1,98 @@
#region MigraDoc - Creating Documents on the Fly
//
// Authors:
// David Stephensen
//
// 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;
using PdfSharp.Drawing;
namespace MigraDoc.Rendering.ChartMapper
{
/// <summary>
/// The LineFormatMapper class.
/// </summary>
public class LineFormatMapper
{
/// <summary>
/// Initializes a new instance of the <see cref="LineFormatMapper"/> class.
/// </summary>
public LineFormatMapper()
{ }
void MapObject(LineFormat lineFormat, DocumentObjectModel.Shapes.LineFormat domLineFormat)
{
if (domLineFormat.Color.IsEmpty)
lineFormat.Color = XColor.Empty;
else
{
#if noCMYK
lineFormat.Color = XColor.FromArgb(domLineFormat.Color.Argb);
#else
lineFormat.Color = ColorHelper.ToXColor(domLineFormat.Color, domLineFormat.Document.UseCmykColor);
#endif
}
switch (domLineFormat.DashStyle)
{
case DocumentObjectModel.Shapes.DashStyle.Dash:
lineFormat.DashStyle = XDashStyle.Dash;
break;
case DocumentObjectModel.Shapes.DashStyle.DashDot:
lineFormat.DashStyle = XDashStyle.DashDot;
break;
case DocumentObjectModel.Shapes.DashStyle.DashDotDot:
lineFormat.DashStyle = XDashStyle.DashDotDot;
break;
case DocumentObjectModel.Shapes.DashStyle.Solid:
lineFormat.DashStyle = XDashStyle.Solid;
break;
case DocumentObjectModel.Shapes.DashStyle.SquareDot:
lineFormat.DashStyle = XDashStyle.Dot;
break;
default:
lineFormat.DashStyle = XDashStyle.Solid;
break;
}
switch (domLineFormat.Style)
{
case DocumentObjectModel.Shapes.LineStyle.Single:
lineFormat.Style = LineStyle.Single;
break;
}
lineFormat.Visible = domLineFormat.Visible;
if (domLineFormat.IsNull("Visible"))
lineFormat.Visible = true;
lineFormat.Width = domLineFormat.Width.Point;
}
public static void Map(LineFormat lineFormat, DocumentObjectModel.Shapes.LineFormat domLineFormat)
{
LineFormatMapper mapper = new LineFormatMapper();
mapper.MapObject(lineFormat, domLineFormat);
}
}
}

View File

@@ -0,0 +1,65 @@
#region MigraDoc - Creating Documents on the Fly
//
// Authors:
// David Stephensen
//
// 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.ChartMapper
{
/// <summary>
/// The PlotAreaMapper class.
/// </summary>
public class PlotAreaMapper
{
/// <summary>
/// Initializes a new instance of the <see cref="PlotAreaMapper"/> class.
/// </summary>
public PlotAreaMapper()
{ }
void MapObject(PlotArea plotArea, DocumentObjectModel.Shapes.Charts.PlotArea domPlotArea)
{
plotArea.BottomPadding = domPlotArea.BottomPadding.Point;
plotArea.RightPadding = domPlotArea.RightPadding.Point;
plotArea.LeftPadding = domPlotArea.LeftPadding.Point;
plotArea.TopPadding = domPlotArea.TopPadding.Point;
if (!domPlotArea.IsNull("LineFormat"))
LineFormatMapper.Map(plotArea.LineFormat, domPlotArea.LineFormat);
if (!domPlotArea.IsNull("FillFormat"))
FillFormatMapper.Map(plotArea.FillFormat, domPlotArea.FillFormat);
}
public static void Map(PlotArea plotArea, DocumentObjectModel.Shapes.Charts.PlotArea domPlotArea)
{
PlotAreaMapper mapper = new PlotAreaMapper();
mapper.MapObject(plotArea, domPlotArea);
}
}
}

View File

@@ -0,0 +1,116 @@
#region MigraDoc - Creating Documents on the Fly
//
// Authors:
// David Stephensen
//
// 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 PdfSharp.Charting;
namespace MigraDoc.Rendering.ChartMapper
{
/// <summary>
/// The SeriesCollectionMapper class.
/// </summary>
public class SeriesCollectionMapper
{
/// <summary>
/// Initializes a new instance of the <see cref="SeriesCollectionMapper"/> class.
/// </summary>
public SeriesCollectionMapper()
{ }
void MapObject(SeriesCollection seriesCollection, DocumentObjectModel.Shapes.Charts.SeriesCollection domSeriesCollection)
{
foreach (DocumentObjectModel.Shapes.Charts.Series domSeries in domSeriesCollection)
{
Series series = seriesCollection.AddSeries();
series.Name = domSeries.Name;
if (domSeries.IsNull("ChartType"))
{
DocumentObjectModel.Shapes.Charts.Chart chart = (DocumentObjectModel.Shapes.Charts.Chart)DocumentObjectModel.DocumentRelations.GetParentOfType(domSeries, typeof(DocumentObjectModel.Shapes.Charts.Chart));
series.ChartType = (ChartType)chart.Type;
}
else
series.ChartType = (ChartType)domSeries.ChartType;
if (!domSeries.IsNull("DataLabel"))
DataLabelMapper.Map(series.DataLabel, domSeries.DataLabel);
if (!domSeries.IsNull("LineFormat"))
LineFormatMapper.Map(series.LineFormat, domSeries.LineFormat);
if (!domSeries.IsNull("FillFormat"))
FillFormatMapper.Map(series.FillFormat, domSeries.FillFormat);
series.HasDataLabel = domSeries.HasDataLabel;
if (domSeries.MarkerBackgroundColor.IsEmpty)
series.MarkerBackgroundColor = XColor.Empty;
else
{
#if noCMYK
series.MarkerBackgroundColor = XColor.FromArgb(domSeries.MarkerBackgroundColor.Argb);
#else
series.MarkerBackgroundColor =
ColorHelper.ToXColor(domSeries.MarkerBackgroundColor, domSeries.Document.UseCmykColor);
#endif
}
if (domSeries.MarkerForegroundColor.IsEmpty)
series.MarkerForegroundColor = XColor.Empty;
else
{
#if noCMYK
series.MarkerForegroundColor = XColor.FromArgb(domSeries.MarkerForegroundColor.Argb);
#else
series.MarkerForegroundColor =
ColorHelper.ToXColor(domSeries.MarkerForegroundColor, domSeries.Document.UseCmykColor);
#endif
}
series.MarkerSize = domSeries.MarkerSize.Point;
if (!domSeries.IsNull("MarkerStyle"))
series.MarkerStyle = (MarkerStyle)domSeries.MarkerStyle;
foreach (DocumentObjectModel.Shapes.Charts.Point domPoint in domSeries.Elements)
{
if (domPoint != null)
{
Point point = series.Add(domPoint.Value);
FillFormatMapper.Map(point.FillFormat, domPoint.FillFormat);
LineFormatMapper.Map(point.LineFormat, domPoint.LineFormat);
}
else
series.Add(double.NaN);
}
}
}
public static void Map(SeriesCollection seriesCollection, DocumentObjectModel.Shapes.Charts.SeriesCollection domSeriesCollection)
{
SeriesCollectionMapper mapper = new SeriesCollectionMapper();
mapper.MapObject(seriesCollection, domSeriesCollection);
}
}
}

View File

@@ -0,0 +1,68 @@
#region MigraDoc - Creating Documents on the Fly
//
// Authors:
// David Stephensen
//
// 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.ChartMapper
{
/// <summary>
/// The XValuesMapper class.
/// </summary>
public class XValuesMapper
{
/// <summary>
/// Initializes a new instance of the <see cref="XValuesMapper"/> class.
/// </summary>
public XValuesMapper()
{ }
void MapObject(XValues xValues, DocumentObjectModel.Shapes.Charts.XValues domXValues)
{
foreach (DocumentObjectModel.Shapes.Charts.XSeries domXSeries in domXValues)
{
XSeries xSeries = xValues.AddXSeries();
DocumentObjectModel.Shapes.Charts.XSeriesElements domXSeriesElements = domXSeries.GetValue("XSeriesElements") as DocumentObjectModel.Shapes.Charts.XSeriesElements;
foreach (DocumentObjectModel.Shapes.Charts.XValue domXValue in domXSeriesElements)
{
if (domXValue == null)
xSeries.AddBlank();
else
xSeries.Add(domXValue.GetValue("Value").ToString());
}
}
}
public static void Map(XValues xValues, DocumentObjectModel.Shapes.Charts.XValues domXValues)
{
XValuesMapper mapper = new XValuesMapper();
mapper.MapObject(xValues, domXValues);
}
}
}

View File

@@ -0,0 +1,197 @@
#region MigraDoc - Creating Documents on the Fly
//
// Authors:
// Stefan Lange (mailto:Stefan.Lange@pdfsharp.com)
//
// Copyright (c) 2001-2013 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.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Printing;
using PdfSharp;
using PdfSharp.Drawing;
using MigraDoc.DocumentObjectModel.publics;
using MigraDoc.DocumentObjectModel.Visitors;
using MigraDoc.DocumentObjectModel.IO;
namespace MigraDoc.Rendering.Printing
{
/// <summary>
/// Represents a specialized System.Drawing.Printing.PrintDocument for MigraDoc documents.
/// This component knows about MigraDoc and simplifies printing of MigraDoc documents.
/// </summary>
public class MigraDocPrintDocument : PrintDocument
{
/// <summary>
/// Initializes a new instance of the <see cref="T:MigraDoc.Rendering.Printing.MigraDocPrintDocument"/> class.
/// </summary>
public MigraDocPrintDocument()
{
DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
OriginAtMargins = false;
}
/// <summary>
/// Initializes a new instance of the <see cref="T:MigraDoc.Rendering.Printing.MigraDocPrintDocument"/> class
/// with the specified <see cref="T:MigraDoc.Rendering.DocumentRenderer"/> object.
/// </summary>
public MigraDocPrintDocument(DocumentRenderer renderer)
{
_renderer = renderer;
DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
OriginAtMargins = false;
}
/// <summary>
/// Gets or sets the DocumentRenderer that prints the pages of the document.
/// </summary>
public DocumentRenderer Renderer
{
get { return _renderer; }
set { _renderer = value; }
}
DocumentRenderer _renderer;
/// <summary>
/// Gets or sets the page number that identifies the selected page. It it used on printing when
/// PrintRange.Selection is set.
/// </summary>
public int SelectedPage
{
get { return _selectedPage; }
set { _selectedPage = value; }
}
int _selectedPage;
/// <summary>
/// Raises the <see cref="E:System.Drawing.Printing.PrintDocument.BeginPrint"/> event. It is called after the <see cref="M:System.Drawing.Printing.PrintDocument.Print"/> method is called and before the first page of the document prints.
/// </summary>
/// <param name="e">A <see cref="T:System.Drawing.Printing.PrintEventArgs"/> that contains the event data.</param>
protected override void OnBeginPrint(PrintEventArgs e)
{
Debug.Assert(_renderer != null, "Cannot print without a MigraDoc.Rendering.DocumentRenderer.");
base.OnBeginPrint(e);
if (!e.Cancel)
{
switch (PrinterSettings.PrintRange)
{
case PrintRange.AllPages:
_pageNumber = 1;
_pageCount = _renderer.FormattedDocument.PageCount;
break;
case PrintRange.SomePages:
_pageNumber = PrinterSettings.FromPage;
_pageCount = PrinterSettings.ToPage - PrinterSettings.FromPage + 1;
break;
case PrintRange.Selection:
_pageNumber = _selectedPage;
_pageCount = 1;
break;
default:
Debug.Assert(false, "Invalid PrinterRange.");
e.Cancel = true;
break;
}
}
}
int _pageNumber = -1;
int _pageCount;
/// <summary>
/// Raises the <see cref="E:System.Drawing.Printing.PrintDocument.QueryPageSettings"/> event. It is called immediately before each <see cref="E:System.Drawing.Printing.PrintDocument.PrintPage"/> event.
/// </summary>
/// <param name="e">A <see cref="T:System.Drawing.Printing.QueryPageSettingsEventArgs"/> that contains the event data.</param>
protected override void OnQueryPageSettings(QueryPageSettingsEventArgs e)
{
base.OnQueryPageSettings(e);
if (!e.Cancel)
{
PageSettings settings = e.PageSettings;
PageInfo pageInfo = _renderer.FormattedDocument.GetPageInfo(_pageNumber);
// set portrait/landscape
settings.Landscape = pageInfo.Orientation == PageOrientation.Landscape;
}
}
/// <summary>
/// Raises the <see cref="E:System.Drawing.Printing.PrintDocument.PrintPage"/> event. It is called before a page prints.
/// </summary>
/// <param name="e">A <see cref="T:System.Drawing.Printing.PrintPageEventArgs"/> that contains the event data.</param>
protected override void OnPrintPage(PrintPageEventArgs e)
{
base.OnPrintPage(e);
if (!e.Cancel)
{
PageSettings settings = e.PageSettings;
try
{
Graphics graphics = e.Graphics;
IntPtr hdc = graphics.GetHdc();
int xOffset = GetDeviceCaps(hdc, PHYSICALOFFSETX);
int yOffset = GetDeviceCaps(hdc, PHYSICALOFFSETY);
graphics.ReleaseHdc(hdc);
graphics.TranslateTransform(-xOffset * 100 / graphics.DpiX, -yOffset * 100 / graphics.DpiY);
// Recall: Width and Height are exchanged when settings.Landscape is true.
XSize size = new XSize(e.PageSettings.Bounds.Width / 100.0 * 72, e.PageSettings.Bounds.Height / 100.0 * 72);
const float scale = 100f / 72f;
graphics.ScaleTransform(scale, scale);
// draw line A4 portrait
//graphics.DrawLine(Pens.Red, 0, 0, 21f / 2.54f * 72, 29.7f / 2.54f * 72);
}
catch
{
e.Cancel = true;
}
_pageNumber++;
_pageCount--;
e.HasMorePages = _pageCount > 0;
}
}
/// <summary>
/// Raises the <see cref="E:System.Drawing.Printing.PrintDocument.EndPrint"/> event. It is called when the last page of the document has printed.
/// </summary>
/// <param name="e">A <see cref="T:System.Drawing.Printing.PrintEventArgs"/> that contains the event data.</param>
protected override void OnEndPrint(PrintEventArgs e)
{
base.OnEndPrint(e);
_pageNumber = -1;
}
[DllImport("gdi32.dll")]
static extern int GetDeviceCaps(IntPtr hdc, int capability);
const int PHYSICALOFFSETX = 112; // Physical Printable Area x margin
const int PHYSICALOFFSETY = 113; // Physical Printable Area y margin
}
}

View File

@@ -0,0 +1,47 @@
; MigraDoc - Creating Documents on the Fly
;
; Authors:
; Klaus Potzesny (mailto:Klaus.Potzesny@pdfsharp.com)
;
; Copyright (c) 2001-2014 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.
; ----- German (de) Messages ---------------------------------------------------
; Messages for German language
; that differ from the default messages.
; ------------------------------------------------------------------------------
PropertyNotSetBefore = '{0}' muss vor dem Aufruf von '{1}' gesetzt werden.
BookmarkNotDefined = Lesezeichen '{0}' ist innerhalb des Dokuments nicht definiert.
ImageNotFound = Bild '{0}' nicht gefunden.
InvalidImageType = Ungültiger Bildtyp: '{0}'.
ImageNotReadable = Bild '{0}' konnte nicht eingelesen werden. Es trat eine Ausnahme mit der folgenden Meldung auf:\n{1}
EmptyImageSize = Ihre Benutzereingaben führten zu einem leeren Bildbereich.
ObjectNotRenderable = Nur Bilder, Textrahmen, Diagramme und Absätze können frei gerendert werden.
NumberTooLargeForRoman = Die Zahl {0} ist zu groß für eine Darstellung in römischen Ziffern.
NumberTooLargeForLetters = Die Zahl {0} ist zu groß für eine Darstellung in Buchstaben.
DisplayEmptyImageSize = Leerer Bildbereich.
DisplayImageFileNotFound = Bild nicht gefunden.
DisplayInvalidImageType = Ungültiger Bildtyp.
DisplayImageNotRead = Bild nicht eingelesen.

View File

@@ -0,0 +1,46 @@
; MigraDoc - Creating Documents on the Fly
;
; Authors:
; Klaus Potzesny (mailto:Klaus.Potzesny@pdfsharp.com)
;
; Copyright (c) 2001-2014 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.
; ----- Default Messages -------------------------------------------------------
; Default Messages for any system culture.
; ------------------------------------------------------------------------------
PropertyNotSetBefore = '{0}' must be set before calling '{1}'.
BookmarkNotDefined = Bookmark '{0}' is not defined within the document.
ImageNotFound = Image '{0}' not found.
InvalidImageType = Invalid image type: '{0}'.
ImageNotReadable = Image {0} could not be read.\n Inner exception: {1}
EmptyImageSize = The specified image size is empty.
ObjectNotRenderable = Only images, textframes, charts and paragraphs can be rendered freely.
NumberTooLargeForRoman = The number {0} is to large to be displayed as roman.
NumberTooLargeForLetters = The number {0} is to large to be displayed as letters.
DisplayEmptyImageSize = Image has empty size.
DisplayImageFileNotFound = Image not found.
DisplayInvalidImageType = Image has no valid type.
DisplayImageNotRead = Image could not be read.

View File

@@ -0,0 +1,177 @@
#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.Resources;
using System.Reflection;
#if DEBUG
using System.Text.RegularExpressions;
#endif
namespace MigraDoc.Rendering.Resources
{
/// <summary>
/// Provides diagnostic messages taken from the resources.
/// </summary>
public static class Messages2
{
public static string NumberTooLargeForRoman(int number)
{
return FormatMessage(IDs.NumberTooLargeForRoman, number);
}
public static string NumberTooLargeForLetters(int number)
{
return FormatMessage(IDs.NumberTooLargeForLetters, number);
}
public static string DisplayEmptyImageSize
{
get { return FormatMessage(IDs.DisplayEmptyImageSize); }
}
public static string DisplayImageFileNotFound
{
get { return FormatMessage(IDs.DisplayImageFileNotFound); }
}
public static string DisplayInvalidImageType
{
get { return FormatMessage(IDs.DisplayInvalidImageType); }
}
public static string DisplayImageNotRead
{
get { return FormatMessage(IDs.DisplayImageNotRead); }
}
public static string PropertyNotSetBefore(string propertyName, string functionName)
{
return FormatMessage(IDs.PropertyNotSetBefore, propertyName, functionName);
}
public static string BookmarkNotDefined(string bookmarkName)
{
return FormatMessage(IDs.BookmarkNotDefined, bookmarkName);
}
public static string ImageNotFound(string imageName)
{
return FormatMessage(IDs.ImageNotFound, imageName);
}
public static string InvalidImageType(string type)
{
return FormatMessage(IDs.InvalidImageType, type);
}
public static string ImageNotReadable(string imageName, string innerException)
{
return FormatMessage(IDs.ImageNotReadable, imageName, innerException);
}
public static string EmptyImageSize
{
get { return FormatMessage(IDs.EmptyImageSize); }
}
public static string ObjectNotRenderable
{
get { return FormatMessage(IDs.ObjectNotRenderable); }
}
// ReSharper disable InconsistentNaming
private enum IDs
{
PropertyNotSetBefore,
BookmarkNotDefined,
ImageNotFound,
InvalidImageType,
ImageNotReadable,
EmptyImageSize,
ObjectNotRenderable,
NumberTooLargeForRoman,
NumberTooLargeForLetters,
DisplayEmptyImageSize,
DisplayImageFileNotFound,
DisplayInvalidImageType,
DisplayImageNotRead
}
// ReSharper restore InconsistentNaming
private static ResourceManager ResourceManager
{
// ReSharper disable ConvertIfStatementToNullCoalescingExpression
get
{
if (_resourceManager == null)
{
#if !NETFX_CORE
_resourceManager = new ResourceManager("MigraDoc.Rendering.Resources.Messages", Assembly.GetExecutingAssembly());
#else
_resourceManager = new ResourceManager("MigraDoc.Rendering.Resources.Messages", typeof(Messages2).GetTypeInfo().Assembly);
#endif
}
return _resourceManager;
}
// ReSharper restore ConvertIfStatementToNullCoalescingExpression
}
private static ResourceManager _resourceManager;
private static string FormatMessage(IDs id, params object[] args)
{
string message;
try
{
message = ResourceManager.GetString(id.ToString());
if (message != null)
{
#if DEBUG
if (Regex.Matches(message, @"\{[0-9]\}").Count > args.Length)
{
//TODO too many placeholders or too few args...
}
#endif
message = String.Format(message, args);
}
else
message = "<<<error: message not found>>>";
return message;
}
catch (Exception ex)
{
message = "public ERROR while formatting error message: " + ex;
}
return message;
}
}
}

View File

@@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="EmptyImageSize" xml:space="preserve">
<value>Ihre Benutzereingaben führten zu einem leeren Bildbereich.</value>
</data>
<data name="DisplayImageFileNotFound" xml:space="preserve">
<value>Bild nicht gefunden.</value>
</data>
<data name="DisplayImageNotRead" xml:space="preserve">
<value>Bild nicht eingelesen.</value>
</data>
<data name="NumberTooLargeForLetters" xml:space="preserve">
<value>Die Zahl {0} ist zu groß für eine Darstellung in Buchstaben.</value>
</data>
<data name="BookmarkNotDefined" xml:space="preserve">
<value>Lesezeichen '{0}' ist innerhalb des Dokuments nicht definiert.</value>
</data>
<data name="InvalidImageType" xml:space="preserve">
<value>Ungültiger Bildtyp: '{0}'.</value>
</data>
<data name="NumberTooLargeForRoman" xml:space="preserve">
<value>Die Zahl {0} ist zu groß für eine Darstellung in römischen Ziffern.</value>
</data>
<data name="ImageNotFound" xml:space="preserve">
<value>Bild '{0}' nicht gefunden.</value>
</data>
<data name="PropertyNotSetBefore" xml:space="preserve">
<value>'{0}' muss vor dem Aufruf von '{1}' gesetzt werden.</value>
</data>
<data name="DisplayEmptyImageSize" xml:space="preserve">
<value>Leerer Bildbereich.</value>
</data>
<data name="DisplayInvalidImageType" xml:space="preserve">
<value>Ungültiger Bildtyp.</value>
</data>
<data name="ObjectNotRenderable" xml:space="preserve">
<value>Nur Bilder, Textrahmen, Diagramme und Absätze können frei gerendert werden.</value>
</data>
<data name="ImageNotReadable" xml:space="preserve">
<value>Bild '{0}' konnte nicht eingelesen werden. Es trat eine Ausnahme mit der folgenden Meldung auf:
{1}</value>
</data>
</root>

View File

@@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="EmptyImageSize" xml:space="preserve">
<value>The specified image size is empty.</value>
</data>
<data name="DisplayImageFileNotFound" xml:space="preserve">
<value>Image not found.</value>
</data>
<data name="DisplayImageNotRead" xml:space="preserve">
<value>Image could not be read.</value>
</data>
<data name="NumberTooLargeForLetters" xml:space="preserve">
<value>The number {0} is to large to be displayed as letters.</value>
</data>
<data name="BookmarkNotDefined" xml:space="preserve">
<value>Bookmark '{0}' is not defined within the document.</value>
</data>
<data name="InvalidImageType" xml:space="preserve">
<value>Invalid image type: '{0}'.</value>
</data>
<data name="NumberTooLargeForRoman" xml:space="preserve">
<value>The number {0} is to large to be displayed as roman.</value>
</data>
<data name="ImageNotFound" xml:space="preserve">
<value>Image '{0}' not found.</value>
</data>
<data name="PropertyNotSetBefore" xml:space="preserve">
<value>'{0}' must be set before calling '{1}'.</value>
</data>
<data name="DisplayEmptyImageSize" xml:space="preserve">
<value>Image has empty size.</value>
</data>
<data name="DisplayInvalidImageType" xml:space="preserve">
<value>Image has no valid type.</value>
</data>
<data name="ObjectNotRenderable" xml:space="preserve">
<value>Only images, textframes, charts and paragraphs can be rendered freely.</value>
</data>
<data name="ImageNotReadable" xml:space="preserve">
<value>Image {0} could not be read.
Inner exception: {1}</value>
</data>
</root>

View File

@@ -0,0 +1,78 @@
using MigraDoc.DocumentObjectModel;
#pragma warning disable 1591
namespace MigraDoc.Rendering.UnitTest
{
/// <summary>
/// Summary description for TestLayout.
/// </summary>
public class TestLayout
{
public static void TwoParagraphs(string outputFile)
{
Document doc = new Document();
Section sec = doc.Sections.AddSection();
sec.PageSetup.TopMargin = 0;
sec.PageSetup.BottomMargin = 0;
Paragraph par1 = sec.AddParagraph();
TestParagraphRenderer.FillFormattedParagraph(par1);
TestParagraphRenderer.GiveBorders(par1);
par1.Format.SpaceAfter = "2cm";
par1.Format.SpaceBefore = "3cm";
Paragraph par2 = sec.AddParagraph();
TestParagraphRenderer.FillFormattedParagraph(par2);
TestParagraphRenderer.GiveBorders(par2);
par2.Format.SpaceBefore = "3cm";
PdfDocumentRenderer renderer = new PdfDocumentRenderer();
renderer.Document = doc;
renderer.RenderDocument();
renderer.PdfDocument.Save(outputFile);
}
public static void A1000Paragraphs(string outputFile)
{
Document doc = new Document();
Section sec = doc.Sections.AddSection();
sec.PageSetup.TopMargin = 0;
sec.PageSetup.BottomMargin = 0;
for (int idx = 1; idx <= 1000; ++idx)
{
Paragraph par = sec.AddParagraph();
par.AddText("Paragraph " + idx + ": ");
TestParagraphRenderer.FillFormattedParagraph(par);
TestParagraphRenderer.GiveBorders(par);
}
PdfDocumentRenderer renderer = new PdfDocumentRenderer();
renderer.Document = doc;
renderer.RenderDocument();
renderer.PdfDocument.Save(outputFile);
}
public static string DumpParagraph()
{
return "";
// Document doc = new Document();
// Paragraph par = doc.Sections.AddSection().AddParagraph();
// par.Format.SpaceAfter = "3cm";
// par.Format.SpaceBefore = "2cm";
// TestParagraphRenderer.FillFormattedParagraph(par);
// PdfFlattenVisitor visitor = new PdfFlattenVisitor(doc);
// visitor.Visit();
//
// XGraphics gfx = XGraphics.FromGraphics(Graphics.FromHwnd(IntPtr.Zero), new XSize(2000, 2000));
// //Renderer rndrr = Renderer.Create(gfx, par, new FieldInfos(new Hashtable()));
// rndrr.Format(new Rectangle(0, 0, XUnit.FromCentimeter(21), XUnit.FromCentimeter(29)), null);
// string retVal = ValueDumper.DumpValues(rndrr.RenderInfo.LayoutInfo);
// retVal += "\r\n";
//
// retVal += ValueDumper.DumpValues(rndrr.RenderInfo.LayoutInfo.ContentArea);
// return retVal;
}
}
}

View File

@@ -0,0 +1,47 @@
using MigraDoc.DocumentObjectModel;
#pragma warning disable 1591
namespace MigraDoc.Rendering.UnitTest
{
/// <summary>
/// Summary description for TestParagraphIterator.
/// </summary>
public class TestParagraphIterator
{
public TestParagraphIterator()
{ }
public static string GetIterators(Paragraph paragraph)
{
ParagraphIterator iter = new ParagraphIterator(paragraph.Elements);
iter = iter.GetFirstLeaf();
string retString = "";
while (iter != null)
{
retString += "[" + iter.Current.GetType().Name + ":]";
if (iter.Current is Text)
retString += ((Text)iter.Current).Content;
iter = iter.GetNextLeaf();
}
return retString;
}
public static string GetBackIterators(Paragraph paragraph)
{
ParagraphIterator iter = new ParagraphIterator(paragraph.Elements);
iter = iter.GetLastLeaf();
string retString = "";
while (iter != null)
{
retString += "[" + iter.Current.GetType().Name + ":]";
if (iter.Current is Text)
retString += ((Text)iter.Current).Content;
iter = iter.GetPreviousLeaf();
}
return retString;
}
}
}

View File

@@ -0,0 +1,211 @@
using MigraDoc.DocumentObjectModel;
namespace MigraDoc.Rendering.UnitTest
{
/// <summary>
/// Summary description for ParagraphRenderer.
/// </summary>
public class TestParagraphRenderer
{
/// <summary>
/// Tests texts and blanks.
/// </summary>
public static void TextAndBlanks(string pdfOutputFile)
{
Document document = new Document();
Section section = document.AddSection();
Paragraph par = section.AddParagraph("Dies");
for (int idx = 0; idx <= 40; ++idx)
{
par.AddCharacter(SymbolName.Blank);
par.AddText(idx.ToString());
par.AddCharacter(SymbolName.Blank);
par.AddText((idx + 1).ToString());
par.AddCharacter(SymbolName.Blank);
par.AddText((idx + 2).ToString());
}
PdfDocumentRenderer renderer = new PdfDocumentRenderer();
renderer.Document = document;
renderer.RenderDocument();
renderer.PdfDocument.Save(pdfOutputFile);
}
/// <summary>
/// Tests AddFormattedText.
/// </summary>
public static void Formatted(string pdfOutputFile)
{
Document document = new Document();
Section section = document.AddSection();
Paragraph par = section.AddParagraph();
FillFormattedParagraph(par);
PdfDocumentRenderer printer = new PdfDocumentRenderer();
printer.Document = document;
printer.RenderDocument();
printer.PdfDocument.Save(pdfOutputFile);
}
public static void FillFormattedParagraph(Paragraph par)
{
for (int idx = 0; idx <= 140; ++idx)
{
if (idx < 60)
{
FormattedText formText = par.AddFormattedText((idx).ToString(), TextFormat.Bold);
formText.Font.Size = 16;
formText.AddText(" ");
}
else if (idx < 100)
{
par.AddText((idx).ToString());
par.AddText(" ");
}
else
{
FormattedText formText = par.AddFormattedText((idx).ToString(), TextFormat.Italic);
formText.Font.Size = 6;
formText.AddText(" ");
}
if (idx % 50 == 0)
par.AddLineBreak();
}
par.AddText(" ...ready.");
}
/// <summary>
/// Tests alignments.
/// </summary>
public static void Alignment(string pdfOutputFile)
{
Document document = new Document();
Section section = document.AddSection();
section.PageSetup.LeftMargin = 0;
section.PageSetup.RightMargin = 0;
Paragraph par = section.AddParagraph();
// FillFormattedParagraph(par);
// par.Format.Alignment = ParagraphAlignment.Left;
// par = section.AddParagraph();
// FillFormattedParagraph(par);
// par.Format.Alignment = ParagraphAlignment.Right;
// par = section.AddParagraph();
FillFormattedParagraph(par);
par.Format.Alignment = ParagraphAlignment.Center;
//
// par = section.AddParagraph();
// FillFormattedParagraph(par);
// par.Format.Alignment = ParagraphAlignment.Justify;
par.Format.FirstLineIndent = "-2cm";
par.Format.LeftIndent = "2cm";
par.Format.RightIndent = "3cm";
PdfDocumentRenderer renderer = new PdfDocumentRenderer();
renderer.Document = document;
renderer.RenderDocument();
renderer.PdfDocument.Save(pdfOutputFile);
}
/// <summary>
/// Tests tab stops.
/// </summary>
public static void Tabs(string pdfOutputFile)
{
Document document = new Document();
Section section = document.AddSection();
section.PageSetup.LeftMargin = 0;
section.PageSetup.RightMargin = 0;
Paragraph par = section.AddParagraph();
par.Format.TabStops.AddTabStop("20cm", TabAlignment.Right);
par.AddText(" text before tab bla bla bla. text before tab bla bla bla. text before tab bla bla bla. text before tab bla bla bla.");
//par.AddTab();
par.AddText(" ............ after tab bla bla bla.");
PdfDocumentRenderer renderer = new PdfDocumentRenderer();
renderer.Document = document;
renderer.RenderDocument();
renderer.PdfDocument.Save(pdfOutputFile);
}
public static void GiveBorders(Paragraph par)
{
Borders borders = par.Format.Borders;
borders.Top.Color = Colors.Gray;
borders.Top.Width = 4;
borders.Top.Style = BorderStyle.DashDot;
borders.Left.Color = Colors.Red;
borders.Left.Style = BorderStyle.Dot;
borders.Left.Width = 7;
borders.Bottom.Color = Colors.Red;
borders.Bottom.Width = 3;
borders.Bottom.Style = BorderStyle.DashLargeGap;
borders.Right.Style = BorderStyle.DashSmallGap;
borders.Right.Width = 3;
borders.DistanceFromBottom = "1cm";
borders.DistanceFromTop = "1.5cm";
borders.DistanceFromLeft = "0.5cm";
borders.DistanceFromRight = "2cm";
par.Format.Shading.Color = Colors.LightBlue;
}
/// <summary>
/// Tests borders.
/// </summary>
public static void Borders(string outputFile)
{
Document document = new Document();
Section section = document.AddSection();
Paragraph par = section.AddParagraph();
FillFormattedParagraph(par);
GiveBorders(par);
PdfDocumentRenderer renderer = new PdfDocumentRenderer();
renderer.Document = document;
renderer.RenderDocument();
renderer.PdfDocument.Save(outputFile);
}
/// <summary>
/// Tests document fields.
/// </summary>
public static void Fields(string outputFile)
{
Document document = new Document();
Section section = document.AddSection();
Paragraph par = section.AddParagraph();
par.AddText("Section: ");
par.AddSectionField().Format = "ALPHABETIC";
par.AddLineBreak();
par.AddText("SectionPages: ");
par.AddSectionField().Format = "alphabetic";
par.AddLineBreak();
par.AddText("Page: ");
par.AddPageField().Format = "ROMAN";
par.AddLineBreak();
par.AddText("NumPages: ");
par.AddNumPagesField();
par.AddLineBreak();
par.AddText("Date: ");
par.AddDateField();
par.AddLineBreak();
par.AddText("Bookmark: ");
par.AddBookmark("Egal");
par.AddLineBreak();
par.AddText("PageRef: ");
par.AddPageRefField("Egal");
PdfDocumentRenderer renderer = new PdfDocumentRenderer();
renderer.Document = document;
renderer.RenderDocument();
renderer.PdfDocument.Save(outputFile);
}
}
}

View File

@@ -0,0 +1,99 @@
using MigraDoc.DocumentObjectModel;
using MigraDoc.DocumentObjectModel.Tables;
#pragma warning disable 1591
namespace MigraDoc.Rendering.UnitTest
{
/// <summary>
/// Summary description for TestTable.
/// </summary>
public class TestTable
{
public static void Borders(string outputFile)
{
Document document = new Document();
Section sec = document.Sections.AddSection();
sec.AddParagraph("A paragraph before.");
Table table = sec.AddTable();
table.Borders.Visible = true;
table.AddColumn();
table.AddColumn();
table.Rows.HeightRule = RowHeightRule.Exactly;
table.Rows.Height = 14;
Row row = table.AddRow();
Cell cell = row.Cells[0];
cell.Borders.Visible = true;
cell.Borders.Left.Width = 8;
cell.Borders.Right.Width = 2;
cell.AddParagraph("First Cell");
row = table.AddRow();
cell = row.Cells[1];
cell.AddParagraph("Last Cell within this table");
cell.Borders.Bottom.Width = 15;
cell.Shading.Color = Colors.LightBlue;
sec.AddParagraph("A Paragraph afterwards");
PdfDocumentRenderer renderer = new PdfDocumentRenderer();
renderer.Document = document;
renderer.RenderDocument();
renderer.PdfDocument.Save(outputFile);
}
public static void CellMerge(string outputFile)
{
Document document = new Document();
Section sec = document.Sections.AddSection();
sec.AddParagraph("A paragraph before.");
Table table = sec.AddTable();
table.Borders.Visible = true;
table.AddColumn();
table.AddColumn();
Row row = table.AddRow();
Cell cell = row.Cells[0];
cell.MergeRight = 1;
cell.Borders.Visible = true;
cell.Borders.Left.Width = 8;
cell.Borders.Right.Width = 2;
cell.AddParagraph("First Cell");
row = table.AddRow();
cell = row.Cells[1];
cell.AddParagraph("Last Cell within this row");
cell.MergeDown = 1;
cell.Borders.Bottom.Width = 15;
cell.Borders.Right.Width = 30;
cell.Shading.Color = Colors.LightBlue;
row = table.AddRow();
sec.AddParagraph("A Paragraph afterwards");
PdfDocumentRenderer renderer = new PdfDocumentRenderer();
renderer.Document = document;
renderer.RenderDocument();
renderer.PdfDocument.Save(outputFile);
}
public static void VerticalAlign(string outputFile)
{
Document document = new Document();
Section sec = document.Sections.AddSection();
sec.AddParagraph("A paragraph before.");
Table table = sec.AddTable();
table.Borders.Visible = true;
table.AddColumn();
table.AddColumn();
Row row = table.AddRow();
row.HeightRule = RowHeightRule.Exactly;
row.Height = 70;
row.VerticalAlignment = VerticalAlignment.Center;
row[0].AddParagraph("First Cell");
row[1].AddParagraph("Second Cell");
sec.AddParagraph("A Paragraph afterwards.");
PdfDocumentRenderer renderer = new PdfDocumentRenderer();
renderer.Document = document;
renderer.RenderDocument();
renderer.PdfDocument.Save(outputFile);
}
}
}

View File

@@ -0,0 +1,26 @@
using System.Reflection;
namespace MigraDoc.Rendering.UnitTest
{
/// <summary>
/// Summary description for ValueDumper.
/// </summary>
public class ValueDumper
{
public ValueDumper()
{ }
public static string DumpValues(object obj)
{
string dumpString = "[" + obj.GetType() + "]\r\n";
foreach (FieldInfo fieldInfo in obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
{
if (fieldInfo.FieldType.IsValueType)
{
dumpString += " " + fieldInfo.Name + " = " + fieldInfo.GetValue(obj) + "\r\n";
}
}
return dumpString;
}
}
}

View 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);
}
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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);
}
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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
}
}

View 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;
}
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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);
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}
}

View 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; }
}
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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>();
}
}

View 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;
}
}

View 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;
}
}
}

File diff suppressed because it is too large Load Diff

View 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;
}
}
}

View 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

View 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;
}
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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
}
}

View 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,
}
}

View 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
}
}

View 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
}
}

View 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
}
}

View 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
}
}

View File

@@ -0,0 +1,111 @@
{
"runtimeTarget": {
"name": ".NETStandard,Version=v2.0/",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETStandard,Version=v2.0": {},
".NETStandard,Version=v2.0/": {
"MigraDoc.Rendering/3.0.0.0": {
"dependencies": {
"MigraDoc.DocumentObjectModel": "3.0.0",
"NETStandard.Library": "2.0.3",
"PdfSharp": "3.0.0",
"PdfSharp.Charting": "3.0.0",
"System.Drawing.Common": "4.5.0"
},
"runtime": {
"MigraDoc.Rendering.dll": {}
},
"resources": {
"de/MigraDoc.Rendering.resources.dll": {
"locale": "de"
}
}
},
"Microsoft.NETCore.Platforms/1.1.0": {},
"NETStandard.Library/2.0.3": {
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0"
}
},
"System.Drawing.Common/4.5.0": {
"runtime": {
"lib/netstandard2.0/System.Drawing.Common.dll": {
"assemblyVersion": "4.0.0.0",
"fileVersion": "4.6.26515.6"
}
}
},
"MigraDoc.DocumentObjectModel/3.0.0": {
"dependencies": {
"System.Drawing.Common": "4.5.0"
},
"runtime": {
"MigraDoc.DocumentObjectModel.dll": {}
}
},
"PdfSharp/3.0.0": {
"dependencies": {
"System.Drawing.Common": "4.5.0"
},
"runtime": {
"PdfSharp.dll": {}
}
},
"PdfSharp.Charting/3.0.0": {
"dependencies": {
"PdfSharp": "3.0.0",
"System.Drawing.Common": "4.5.0"
},
"runtime": {
"PdfSharp.Charting.dll": {}
}
}
}
},
"libraries": {
"MigraDoc.Rendering/3.0.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Microsoft.NETCore.Platforms/1.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==",
"path": "microsoft.netcore.platforms/1.1.0",
"hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512"
},
"NETStandard.Library/2.0.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
"path": "netstandard.library/2.0.3",
"hashPath": "netstandard.library.2.0.3.nupkg.sha512"
},
"System.Drawing.Common/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-AiJFxxVPdeITstiRS5aAu8+8Dpf5NawTMoapZ53Gfirml24p7HIfhjmCRxdXnmmf3IUA3AX3CcW7G73CjWxW/Q==",
"path": "system.drawing.common/4.5.0",
"hashPath": "system.drawing.common.4.5.0.nupkg.sha512"
},
"MigraDoc.DocumentObjectModel/3.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"PdfSharp/3.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"PdfSharp.Charting/3.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

View File

@@ -0,0 +1,111 @@
{
"runtimeTarget": {
"name": ".NETStandard,Version=v2.0/",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETStandard,Version=v2.0": {},
".NETStandard,Version=v2.0/": {
"MigraDoc.Rendering/3.0.0.0": {
"dependencies": {
"MigraDoc.DocumentObjectModel": "3.0.0",
"NETStandard.Library": "2.0.3",
"PdfSharp": "3.0.0",
"PdfSharp.Charting": "3.0.0",
"System.Drawing.Common": "4.5.0"
},
"runtime": {
"MigraDoc.Rendering.dll": {}
},
"resources": {
"de/MigraDoc.Rendering.resources.dll": {
"locale": "de"
}
}
},
"Microsoft.NETCore.Platforms/1.1.0": {},
"NETStandard.Library/2.0.3": {
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0"
}
},
"System.Drawing.Common/4.5.0": {
"runtime": {
"lib/netstandard2.0/System.Drawing.Common.dll": {
"assemblyVersion": "4.0.0.0",
"fileVersion": "4.6.26515.6"
}
}
},
"MigraDoc.DocumentObjectModel/3.0.0": {
"dependencies": {
"System.Drawing.Common": "4.5.0"
},
"runtime": {
"MigraDoc.DocumentObjectModel.dll": {}
}
},
"PdfSharp/3.0.0": {
"dependencies": {
"System.Drawing.Common": "4.5.0"
},
"runtime": {
"PdfSharp.dll": {}
}
},
"PdfSharp.Charting/3.0.0": {
"dependencies": {
"PdfSharp": "3.0.0",
"System.Drawing.Common": "4.5.0"
},
"runtime": {
"PdfSharp.Charting.dll": {}
}
}
}
},
"libraries": {
"MigraDoc.Rendering/3.0.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Microsoft.NETCore.Platforms/1.1.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==",
"path": "microsoft.netcore.platforms/1.1.0",
"hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512"
},
"NETStandard.Library/2.0.3": {
"type": "package",
"serviceable": true,
"sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
"path": "netstandard.library/2.0.3",
"hashPath": "netstandard.library.2.0.3.nupkg.sha512"
},
"System.Drawing.Common/4.5.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-AiJFxxVPdeITstiRS5aAu8+8Dpf5NawTMoapZ53Gfirml24p7HIfhjmCRxdXnmmf3IUA3AX3CcW7G73CjWxW/Q==",
"path": "system.drawing.common/4.5.0",
"hashPath": "system.drawing.common.4.5.0.nupkg.sha512"
},
"MigraDoc.DocumentObjectModel/3.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"PdfSharp/3.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"PdfSharp.Charting/3.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
}
}
}

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETStandard,Version=v2.0", FrameworkDisplayName = "")]

View File

@@ -0,0 +1,18 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Этот код создан программой.
// Исполняемая версия:4.0.30319.42000
//
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
// повторной генерации кода.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyFileVersionAttribute("3.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("3.0.0.0")]
// Создано классом WriteCodeFragment MSBuild.

View File

@@ -0,0 +1 @@
c9bbb4259b11bff14843734a92523ce79fd4d971

Some files were not shown because too many files have changed in this diff Show More