diff --git a/docs/MigraDocCore/faq.md b/docs/MigraDocCore/faq.md
new file mode 100644
index 00000000..9d837e0f
--- /dev/null
+++ b/docs/MigraDocCore/faq.md
@@ -0,0 +1,8 @@
+# MigraDocCore > FAQ
+
+FAQ for [MigraDocCore](index.md):
+
+
+## What is MigraDocCore?
+
+MigraDocCore is the .NET library for modeling and rendering documents.
diff --git a/docs/MigraDocCore/index.md b/docs/MigraDocCore/index.md
new file mode 100644
index 00000000..b8da6332
--- /dev/null
+++ b/docs/MigraDocCore/index.md
@@ -0,0 +1,71 @@
+# MigraDocCore
+
+MigraDocCore is a document generator.
+It supports almost anything you find in any good word processor.
+You just add paragraphs, tables, charts, arrange all this in sections, use bookmarks to create links, tables of contents, indexes, etc.
+MigraDocCore will do the layout creating page breaks as needed.
+MigraDocCore will create PDF documents.
+
+* [Features](#features)
+* [First steps](#first-steps)
+* [Samples](samples/index.md)
+* [FAQ](faq.md)
+
+
+## Features
+
+* Create perfect documents “on the fly”
+* Import data from various sources via XML files or direct interfaces (any data source that can be used with .NET)
+* Integrates easily with existing applications and systems
+* Various options for page layout, text formatting, and document design
+* Dynamic tables and business charts
+* Re-usable building blocks consisting of text and / or code
+* Documents with navigation (hyperlinks and / or bookmarks)
+
+
+## First steps
+
+Both PDFsharpCore and MigraDocCore provide a lot of `AddXxx` functions.
+Typically these functions return the newly created objects. Once you’ve learned the basic principles it’s quite easy to work with.
+Intellisense helps a lot then.
+
+We’ll discuss a few lines of the [Hello World](samples/HelloWorld.md) sample here.
+
+```cs
+// We start with a new document:
+Document document = new Document();
+
+// With MigraDocCore, we don’t add pages, we add sections (at least one):
+Section section = document.AddSection();
+
+// Adding text is simple:
+section.AddParagraph("Hello, World!");
+
+// Adding empty paragraphs is even simpler:
+section.AddParagraph();
+
+// Store the newly created object for modification:
+Paragraph paragraph = section.AddParagraph();
+paragraph.Format.Font.Color = Color.FromCmyk(100, 30, 20, 50);
+paragraph.AddFormattedText("Hello, World!", TextFormat.Underline);
+
+// AddFormattedText also returns an object:
+FormattedText ft = paragraph.AddFormattedText("Small text", TextFormat.Bold);
+ft.Font.Size = 6;
+
+// And there’s much more that can be added: AddTable, AddImage, AddHyperlink, AddBookmark, AddPageField, AddPageBreak, ...
+
+// With MigraDocCore you can create PDF or RTF. Just select the appropriate renderer:
+PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer(false,
+PdfFontEmbedding.Always);
+
+// Pass the document to the renderer:
+pdfRenderer.Document = document;
+
+// Let the renderer do its job:
+pdfRenderer.RenderDocument();
+
+// Save the PDF to a file:
+string filename = "HelloWorld.pdf";
+pdfRenderer.PdfDocument.Save(filename);
+```
diff --git a/docs/MigraDocCore/samples/HelloMigraDocCore.md b/docs/MigraDocCore/samples/HelloMigraDocCore.md
new file mode 100644
index 00000000..eea9eebe
--- /dev/null
+++ b/docs/MigraDocCore/samples/HelloMigraDocCore.md
@@ -0,0 +1,512 @@
+# Hello MigraDocCore
+
+Shows various features of MigraDocCore including table of contents, tables, bookmarks, text formatting and font styles, charts, ...
+
+* [Styles](#define-styles)
+* [Cover](#define-cover)
+* [Table of Contents](#define-table-of-contents)
+* [Content Section](#define-content-section)
+* [Paragraphs](#define-paragraphs)
+* [Tables](#define-tables)
+* [Charts](#define-charts)
+
+
+## The Main method:
+
+```cs
+static void Main()
+{
+ // Create a MigraDocCore document
+ Document document = Documents.CreateDocument();
+
+ //string ddl = MigraDocCore.DocumentObjectModel.IO.DdlWriter.WriteToString(document);
+ MigraDocCore.DocumentObjectModel.IO.DdlWriter.WriteToFile(document, "MigraDocCore.mdddl");
+
+ PdfDocumentRenderer renderer = new PdfDocumentRenderer(true, PdfSharp.Pdf.PdfFontEmbedding.Always);
+ renderer.Document = document;
+
+ renderer.RenderDocument();
+
+ // Save the document...
+ string filename = "HelloMigraDoc.pdf";
+ renderer.PdfDocument.Save(filename);
+}
+```
+
+
+## CreateDocument is the method that creates the content:
+
+```cs
+public static Document CreateDocument()
+{
+ // Create a new MigraDocCore document
+ Document document = new Document();
+ document.Info.Title = "Hello, MigraDocCore";
+ document.Info.Subject = "Demonstrates an excerpt of the capabilities of MigraDocCore.";
+ document.Info.Author = "Stefan Lange";
+
+ Styles.DefineStyles(document);
+ Cover.DefineCover(document);
+ TableOfContents.DefineTableOfContents(document);
+ DefineContentSection(document);
+ Paragraphs.DefineParagraphs(document);
+ Tables.DefineTables(document);
+ Charts.DefineCharts(document);
+
+ return document;
+}
+```
+
+### Define Styles
+
+```cs
+ ///
+ /// Defines the styles used in the document.
+ ///
+ public static void DefineStyles(Document document)
+ {
+ // Get the predefined style Normal.
+ Style style = document.Styles["Normal"];
+ // Because all styles are derived from Normal, the next line changes the
+ // font of the whole document. Or, more exactly, it changes the font of
+ // all styles and paragraphs that do not redefine the font.
+ style.Font.Name = "Times New Roman";
+
+ // Heading1 to Heading9 are predefined styles with an outline level. An outline level
+ // other than OutlineLevel.BodyText automatically creates the outline (or bookmarks)
+ // in PDF.
+
+ style = document.Styles["Heading1"];
+ style.Font.Name = "Tahoma";
+ style.Font.Size = 14;
+ style.Font.Bold = true;
+ style.Font.Color = Colors.DarkBlue;
+ style.ParagraphFormat.PageBreakBefore = true;
+ style.ParagraphFormat.SpaceAfter = 6;
+
+ style = document.Styles["Heading2"];
+ style.Font.Size = 12;
+ style.Font.Bold = true;
+ style.ParagraphFormat.PageBreakBefore = false;
+ style.ParagraphFormat.SpaceBefore = 6;
+ style.ParagraphFormat.SpaceAfter = 6;
+
+ style = document.Styles["Heading3"];
+ style.Font.Size = 10;
+ style.Font.Bold = true;
+ style.Font.Italic = true;
+ style.ParagraphFormat.SpaceBefore = 6;
+ style.ParagraphFormat.SpaceAfter = 3;
+
+ style = document.Styles[StyleNames.Header];
+ style.ParagraphFormat.AddTabStop("16cm", TabAlignment.Right);
+
+ style = document.Styles[StyleNames.Footer];
+ style.ParagraphFormat.AddTabStop("8cm", TabAlignment.Center);
+
+ // Create a new style called TextBox based on style Normal
+ style = document.Styles.AddStyle("TextBox", "Normal");
+ style.ParagraphFormat.Alignment = ParagraphAlignment.Justify;
+ style.ParagraphFormat.Borders.Width = 2.5;
+ style.ParagraphFormat.Borders.Distance = "3pt";
+ style.ParagraphFormat.Shading.Color = Colors.SkyBlue;
+
+ // Create a new style called TOC based on style Normal
+ style = document.Styles.AddStyle("TOC", "Normal");
+ style.ParagraphFormat.AddTabStop("16cm", TabAlignment.Right, TabLeader.Dots);
+ style.ParagraphFormat.Font.Color = Colors.Blue;
+}
+```
+
+### Define Cover
+
+```cs
+///
+/// Defines the cover page.
+///
+public static void DefineCover(Document document)
+{
+ Section section = document.AddSection();
+
+ Paragraph paragraph = section.AddParagraph();
+ paragraph.Format.SpaceAfter = "3cm";
+
+ Image image = section.AddImage("../../images/Logo landscape.png");
+ image.Width = "10cm";
+
+ paragraph = section.AddParagraph("A sample document that demonstrates the\ncapabilities of MigraDocCore");
+ paragraph.Format.Font.Size = 16;
+ paragraph.Format.Font.Color = Colors.DarkRed;
+ paragraph.Format.SpaceBefore = "8cm";
+ paragraph.Format.SpaceAfter = "3cm";
+
+ paragraph = section.AddParagraph("Rendering date: ");
+ paragraph.AddDateField();
+}
+```
+
+### Define Table of Contents
+
+```cs
+///
+/// Defines the table of contents page.
+///
+public static void DefineTableOfContents(Document document)
+{
+ Section section = document.LastSection;
+
+ section.AddPageBreak();
+ Paragraph paragraph = section.AddParagraph("Table of Contents");
+ paragraph.Format.Font.Size = 14;
+ paragraph.Format.Font.Bold = true;
+ paragraph.Format.SpaceAfter = 24;
+ paragraph.Format.OutlineLevel = OutlineLevel.Level1;
+
+ paragraph = section.AddParagraph();
+ paragraph.Style = "TOC";
+ Hyperlink hyperlink = paragraph.AddHyperlink("Paragraphs");
+ hyperlink.AddText("Paragraphs\t");
+ hyperlink.AddPageRefField("Paragraphs");
+
+ paragraph = section.AddParagraph();
+ paragraph.Style = "TOC";
+ hyperlink = paragraph.AddHyperlink("Tables");
+ hyperlink.AddText("Tables\t");
+ hyperlink.AddPageRefField("Tables");
+
+ paragraph = section.AddParagraph();
+ paragraph.Style = "TOC";
+ hyperlink = paragraph.AddHyperlink("Charts");
+ hyperlink.AddText("Charts\t");
+ hyperlink.AddPageRefField("Charts");
+}
+```
+
+### Define Content Section
+
+```cs
+///
+/// Defines page setup, headers, and footers.
+///
+static void DefineContentSection(Document document)
+{
+ Section section = document.AddSection();
+ section.PageSetup.OddAndEvenPagesHeaderFooter = true;
+ section.PageSetup.StartingNumber = 1;
+
+ HeaderFooter header = section.Headers.Primary;
+ header.AddParagraph("\tOdd Page Header");
+
+ header = section.Headers.EvenPage;
+ header.AddParagraph("Even Page Header");
+
+ // Create a paragraph with centered page number. See definition of style "Footer".
+ Paragraph paragraph = new Paragraph();
+ paragraph.AddTab();
+ paragraph.AddPageField();
+
+ // Add paragraph to footer for odd pages.
+ section.Footers.Primary.Add(paragraph);
+ // Add clone of paragraph to footer for odd pages. Cloning is necessary because an object must
+ // not belong to more than one other object. If you forget cloning an exception is thrown.
+ section.Footers.EvenPage.Add(paragraph.Clone());
+}
+```
+
+### Define Paragraphs
+
+```cs
+public static void DefineParagraphs(Document document)
+{
+ Paragraph paragraph = document.LastSection.AddParagraph("Paragraph Layout Overview", "Heading1");
+ paragraph.AddBookmark("Paragraphs");
+
+ DemonstrateAlignment(document);
+ DemonstrateIndent(document);
+ DemonstrateFormattedText(document);
+ DemonstrateBordersAndShading(document);
+}
+
+static void DemonstrateAlignment(Document document)
+{
+ document.LastSection.AddParagraph("Alignment", "Heading2");
+
+ document.LastSection.AddParagraph("Left Aligned", "Heading3");
+
+ Paragraph paragraph = document.LastSection.AddParagraph();
+ paragraph.Format.Alignment = ParagraphAlignment.Left;
+ paragraph.AddText(FillerText.Text);
+
+ document.LastSection.AddParagraph("Right Aligned", "Heading3");
+
+ paragraph = document.LastSection.AddParagraph();
+ paragraph.Format.Alignment = ParagraphAlignment.Right;
+ paragraph.AddText(FillerText.Text);
+
+ document.LastSection.AddParagraph("Centered", "Heading3");
+
+ paragraph = document.LastSection.AddParagraph();
+ paragraph.Format.Alignment = ParagraphAlignment.Center;
+ paragraph.AddText(FillerText.Text);
+
+ document.LastSection.AddParagraph("Justified", "Heading3");
+
+ paragraph = document.LastSection.AddParagraph();
+ paragraph.Format.Alignment = ParagraphAlignment.Justify;
+ paragraph.AddText(FillerText.MediumText);
+}
+
+static void DemonstrateIndent(Document document)
+{
+ document.LastSection.AddParagraph("Indent", "Heading2");
+
+ document.LastSection.AddParagraph("Left Indent", "Heading3");
+
+ Paragraph paragraph = document.LastSection.AddParagraph();
+ paragraph.Format.LeftIndent = "2cm";
+ paragraph.AddText(FillerText.Text);
+
+ document.LastSection.AddParagraph("Right Indent", "Heading3");
+
+ paragraph = document.LastSection.AddParagraph();
+ paragraph.Format.RightIndent = "1in";
+ paragraph.AddText(FillerText.Text);
+
+ document.LastSection.AddParagraph("First Line Indent", "Heading3");
+
+ paragraph = document.LastSection.AddParagraph();
+ paragraph.Format.FirstLineIndent = "12mm";
+ paragraph.AddText(FillerText.Text);
+
+ document.LastSection.AddParagraph("First Line Negative Indent", "Heading3");
+
+ paragraph = document.LastSection.AddParagraph();
+ paragraph.Format.LeftIndent = "1.5cm";
+ paragraph.Format.FirstLineIndent = "-1.5cm";
+ paragraph.AddText(FillerText.Text);
+}
+
+static void DemonstrateFormattedText(Document document)
+{
+ document.LastSection.AddParagraph("Formatted Text", "Heading2");
+
+ //document.LastSection.AddParagraph("Left Aligned", "Heading3");
+
+ Paragraph paragraph = document.LastSection.AddParagraph();
+ paragraph.AddText("Text can be formatted ");
+ paragraph.AddFormattedText("bold", TextFormat.Bold);
+ paragraph.AddText(", ");
+ paragraph.AddFormattedText("italic", TextFormat.Italic);
+ paragraph.AddText(", or ");
+ paragraph.AddFormattedText("bold & italic", TextFormat.Bold | TextFormat.Italic);
+ paragraph.AddText(".");
+ paragraph.AddLineBreak();
+ paragraph.AddText("You can set the ");
+ FormattedText formattedText = paragraph.AddFormattedText("size ");
+ formattedText.Size = 15;
+ paragraph.AddText("the ");
+ formattedText = paragraph.AddFormattedText("color ");
+ formattedText.Color = Colors.Firebrick;
+ paragraph.AddText("the ");
+ formattedText = paragraph.AddFormattedText("font", new Font("Verdana"));
+ paragraph.AddText(".");
+ paragraph.AddLineBreak();
+ paragraph.AddText("You can set the ");
+ formattedText = paragraph.AddFormattedText("subscript");
+ formattedText.Subscript = true;
+ paragraph.AddText(" or ");
+ formattedText = paragraph.AddFormattedText("superscript");
+ formattedText.Superscript = true;
+ paragraph.AddText(".");
+}
+
+static void DemonstrateBordersAndShading(Document document)
+{
+ document.LastSection.AddPageBreak();
+ document.LastSection.AddParagraph("Borders and Shading", "Heading2");
+
+ document.LastSection.AddParagraph("Border around Paragraph", "Heading3");
+
+ Paragraph paragraph = document.LastSection.AddParagraph();
+ paragraph.Format.Borders.Width = 2.5;
+ paragraph.Format.Borders.Color = Colors.Navy;
+ paragraph.Format.Borders.Distance = 3;
+ paragraph.AddText(FillerText.MediumText);
+
+ document.LastSection.AddParagraph("Shading", "Heading3");
+
+ paragraph = document.LastSection.AddParagraph();
+ paragraph.Format.Shading.Color = Colors.LightCoral;
+ paragraph.AddText(FillerText.Text);
+
+ document.LastSection.AddParagraph("Borders & Shading", "Heading3");
+
+ paragraph = document.LastSection.AddParagraph();
+ paragraph.Style = "TextBox";
+ paragraph.AddText(FillerText.MediumText);
+}
+```
+
+### Define Tables
+
+```cs
+public static void DefineTables(Document document)
+{
+ Paragraph paragraph = document.LastSection.AddParagraph("Table Overview", "Heading1");
+ paragraph.AddBookmark("Tables");
+
+ DemonstrateSimpleTable(document);
+ DemonstrateAlignment(document);
+ DemonstrateCellMerge(document);
+}
+
+public static void DemonstrateSimpleTable(Document document)
+{
+ document.LastSection.AddParagraph("Simple Tables", "Heading2");
+
+ Table table = new Table();
+ table.Borders.Width = 0.75;
+
+ Column column = table.AddColumn(Unit.FromCentimeter(2));
+ column.Format.Alignment = ParagraphAlignment.Center;
+
+ table.AddColumn(Unit.FromCentimeter(5));
+
+ Row row = table.AddRow();
+ row.Shading.Color = Colors.PaleGoldenrod;
+ Cell cell = row.Cells[0];
+ cell.AddParagraph("Itemus");
+ cell = row.Cells[1];
+ cell.AddParagraph("Descriptum");
+
+ row = table.AddRow();
+ cell = row.Cells[0];
+ cell.AddParagraph("1");
+ cell = row.Cells[1];
+ cell.AddParagraph(FillerText.ShortText);
+
+ row = table.AddRow();
+ cell = row.Cells[0];
+ cell.AddParagraph("2");
+ cell = row.Cells[1];
+ cell.AddParagraph(FillerText.Text);
+
+ table.SetEdge(0, 0, 2, 3, Edge.Box, BorderStyle.Single, 1.5, Colors.Black);
+
+ document.LastSection.Add(table);
+}
+
+public static void DemonstrateAlignment(Document document)
+{
+ document.LastSection.AddParagraph("Cell Alignment", "Heading2");
+
+ Table table = document.LastSection.AddTable();
+ table.Borders.Visible = true;
+ table.Format.Shading.Color = Colors.LavenderBlush;
+ table.Shading.Color = Colors.Salmon;
+ table.TopPadding = 5;
+ table.BottomPadding = 5;
+
+ Column column = table.AddColumn();
+ column.Format.Alignment = ParagraphAlignment.Left;
+
+ column = table.AddColumn();
+ column.Format.Alignment = ParagraphAlignment.Center;
+
+ column = table.AddColumn();
+ column.Format.Alignment = ParagraphAlignment.Right;
+
+ table.Rows.Height = 35;
+
+ Row row = table.AddRow();
+ row.VerticalAlignment = VerticalAlignment.Top;
+ row.Cells[0].AddParagraph("Text");
+ row.Cells[1].AddParagraph("Text");
+ row.Cells[2].AddParagraph("Text");
+
+ row = table.AddRow();
+ row.VerticalAlignment = VerticalAlignment.Center;
+ row.Cells[0].AddParagraph("Text");
+ row.Cells[1].AddParagraph("Text");
+ row.Cells[2].AddParagraph("Text");
+
+ row = table.AddRow();
+ row.VerticalAlignment = VerticalAlignment.Bottom;
+ row.Cells[0].AddParagraph("Text");
+ row.Cells[1].AddParagraph("Text");
+ row.Cells[2].AddParagraph("Text");
+}
+
+public static void DemonstrateCellMerge(Document document)
+{
+ document.LastSection.AddParagraph("Cell Merge", "Heading2");
+
+ Table table = document.LastSection.AddTable();
+ table.Borders.Visible = true;
+ table.TopPadding = 5;
+ table.BottomPadding = 5;
+
+ Column column = table.AddColumn();
+ column.Format.Alignment = ParagraphAlignment.Left;
+
+ column = table.AddColumn();
+ column.Format.Alignment = ParagraphAlignment.Center;
+
+ column = table.AddColumn();
+ column.Format.Alignment = ParagraphAlignment.Right;
+
+ table.Rows.Height = 35;
+
+ Row row = table.AddRow();
+ row.Cells[0].AddParagraph("Merge Right");
+ row.Cells[0].MergeRight = 1;
+
+ row = table.AddRow();
+ row.VerticalAlignment = VerticalAlignment.Bottom;
+ row.Cells[0].MergeDown = 1;
+ row.Cells[0].VerticalAlignment = VerticalAlignment.Bottom;
+ row.Cells[0].AddParagraph("Merge Down");
+
+ table.AddRow();
+}
+```
+
+### Define Charts
+
+```cs
+public static void DefineCharts(Document document)
+{
+ Paragraph paragraph = document.LastSection.AddParagraph("Chart Overview", "Heading1");
+ paragraph.AddBookmark("Charts");
+
+ document.LastSection.AddParagraph("Sample Chart", "Heading2");
+
+ Chart chart = new Chart();
+ chart.Left = 0;
+
+ chart.Width = Unit.FromCentimeter(16);
+ chart.Height = Unit.FromCentimeter(12);
+ Series series = chart.SeriesCollection.AddSeries();
+ series.ChartType = ChartType.Column2D;
+ series.Add(new double[]{1, 17, 45, 5, 3, 20, 11, 23, 8, 19});
+ series.HasDataLabel = true;
+
+ series = chart.SeriesCollection.AddSeries();
+ series.ChartType = ChartType.Line;
+ series.Add(new double[]{41, 7, 5, 45, 13, 10, 21, 13, 18, 9});
+
+ XSeries xseries = chart.XValues.AddXSeries();
+ xseries.Add("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N");
+
+ chart.XAxis.MajorTickMark = TickMarkType.Outside;
+ chart.XAxis.Title.Caption = "X-Axis";
+
+ chart.YAxis.MajorTickMark = TickMarkType.Outside;
+ chart.YAxis.HasMajorGridlines = true;
+
+ chart.PlotArea.LineFormat.Color = Colors.DarkGray;
+ chart.PlotArea.LineFormat.Width = 1;
+
+ document.LastSection.Add(chart);
+}
+```
diff --git a/docs/MigraDocCore/samples/HelloWorld.md b/docs/MigraDocCore/samples/HelloWorld.md
new file mode 100644
index 00000000..621c2286
--- /dev/null
+++ b/docs/MigraDocCore/samples/HelloWorld.md
@@ -0,0 +1,71 @@
+# Hello World
+
+Is the obligatory "Hello World" program for MigraDocCore documents.
+
+
+## The Main method:
+
+```cs
+static void Main(string[] args)
+{
+ // Create a MigraDocCore document
+ Document document = CreateDocument();
+ document.UseCmykColor = true;
+
+ // ===== Unicode encoding and font program embedding in MigraDocCore is demonstrated here =====
+
+ // A flag indicating whether to create a Unicode PDF or a WinAnsi PDF file.
+ // This setting applies to all fonts used in the PDF document.
+ // This setting has no effect on the RTF renderer.
+ const bool unicode = false;
+
+ // An enum indicating whether to embed fonts or not.
+ // This setting applies to all font programs used in the document.
+ // This setting has no effect on the RTF renderer.
+ // (The term 'font program' is used by Adobe for a file containing a font. Technically a 'font file'
+ // is a collection of small programs and each program renders the glyph of a character when executed.
+ // Using a font in PDFsharpCore may lead to the embedding of one or more font programs, because each outline
+ // (regular, bold, italic, bold+italic, ...) has its own font program)
+ const PdfFontEmbedding embedding = PdfFontEmbedding.Always;
+
+ // ========================================================================================
+
+ // Create a renderer for the MigraDocCore document.
+ PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer(unicode, embedding);
+
+ // Associate the MigraDocCore document with a renderer
+ pdfRenderer.Document = document;
+
+ // Layout and render document to PDF
+ pdfRenderer.RenderDocument();
+
+ // Save the document...
+ const string filename = "HelloWorld.pdf";
+ pdfRenderer.PdfDocument.Save(filename);
+}
+```
+
+The CreateDocument method:
+
+```cs
+///
+/// Creates an absolutely minimalistic document.
+///
+static Document CreateDocument()
+{
+ // Create a new MigraDocCore document
+ Document document = new Document();
+
+ // Add a section to the document
+ Section section = document.AddSection();
+
+ // Add a paragraph to the section
+ Paragraph paragraph = section.AddParagraph();
+ paragraph.Format.Font.Color = Color.FromCmyk(100, 30, 20, 50);
+
+ // Add some text to the paragraph
+ paragraph.AddFormattedText("Hello, World!", TextFormat.Bold);
+
+ return document;
+}
+```
diff --git a/docs/MigraDocCore/samples/Images.md b/docs/MigraDocCore/samples/Images.md
new file mode 100644
index 00000000..d95b63b6
--- /dev/null
+++ b/docs/MigraDocCore/samples/Images.md
@@ -0,0 +1,29 @@
+# Images
+
+Shows how to use images in MigraDocCore documents.
+
+
+## Code
+
+```cs
+///
+/// Creates an absolutely minimalistic document.
+///
+static Document CreateDocument()
+{
+ // Create a new MigraDocCore document
+ Document document = new Document();
+
+ // Add a section to the document
+ Section section = document.AddSection();
+
+ // Add a paragraph to the section
+ Paragraph paragraph = section.AddParagraph();
+
+ // Add some text to the paragraph
+ paragraph.AddFormattedText("Hello, World!", TextFormat.Italic);
+ section.AddImage("../../SomeImage.png");
+
+ return document;
+}
+```
diff --git a/docs/MigraDocCore/samples/Invoice.md b/docs/MigraDocCore/samples/Invoice.md
new file mode 100644
index 00000000..5667c24c
--- /dev/null
+++ b/docs/MigraDocCore/samples/Invoice.md
@@ -0,0 +1,289 @@
+# Invoice
+
+Shows how to create a simple invoice of a fictional book store.
+The invoice document is created with the MigraDocCore document object model and then rendered to PDF with PDFsharpCore.
+
+
+## Creating the Document
+
+```cs
+public Document CreateDocument()
+{
+ // Create a new MigraDocCore document
+ this.document = new Document();
+ this.document.Info.Title = "A sample invoice";
+ this.document.Info.Subject = "Demonstrates how to create an invoice.";
+ this.document.Info.Author = "Stefan Lange";
+
+ DefineStyles();
+ CreatePage();
+ FillContent();
+
+ return this.document;
+}
+```
+
+
+## Defining the Styles
+
+Styles define how the text will look:
+
+```cs
+void DefineStyles()
+{
+ // Get the predefined style Normal.
+ Style style = this.document.Styles["Normal"];
+ // Because all styles are derived from Normal, the next line changes the
+ // font of the whole document. Or, more exactly, it changes the font of
+ // all styles and paragraphs that do not redefine the font.
+ style.Font.Name = "Verdana";
+
+ style = this.document.Styles[StyleNames.Header];
+ style.ParagraphFormat.AddTabStop("16cm", TabAlignment.Right);
+
+ style = this.document.Styles[StyleNames.Footer];
+ style.ParagraphFormat.AddTabStop("8cm", TabAlignment.Center);
+
+ // Create a new style called Table based on style Normal
+ style = this.document.Styles.AddStyle("Table", "Normal");
+ style.Font.Name = "Verdana";
+ style.Font.Name = "Times New Roman";
+ style.Font.Size = 9;
+
+ // Create a new style called Reference based on style Normal
+ style = this.document.Styles.AddStyle("Reference", "Normal");
+ style.ParagraphFormat.SpaceBefore = "5mm";
+ style.ParagraphFormat.SpaceAfter = "5mm";
+ style.ParagraphFormat.TabStops.AddTabStop("16cm", TabAlignment.Right);
+}
+```
+
+
+## Create Page
+
+Create the page with invoice table, header, footer:
+
+```cs
+void CreatePage()
+{
+ // Each MigraDocCore document needs at least one section.
+ Section section = this.document.AddSection();
+
+ // Put a logo in the header
+ Image image = section.Headers.Primary.AddImage("../../PowerBooks.png");
+ image.Height = "2.5cm";
+ image.LockAspectRatio = true;
+ image.RelativeVertical = RelativeVertical.Line;
+ image.RelativeHorizontal = RelativeHorizontal.Margin;
+ image.Top = ShapePosition.Top;
+ image.Left = ShapePosition.Right;
+ image.WrapFormat.Style = WrapStyle.Through;
+
+ // Create footer
+ Paragraph paragraph = section.Footers.Primary.AddParagraph();
+ paragraph.AddText("PowerBooks Inc · Sample Street 42 · 56789 Cologne · Germany");
+ paragraph.Format.Font.Size = 9;
+ paragraph.Format.Alignment = ParagraphAlignment.Center;
+
+ // Create the text frame for the address
+ this.addressFrame = section.AddTextFrame();
+ this.addressFrame.Height = "3.0cm";
+ this.addressFrame.Width = "7.0cm";
+ this.addressFrame.Left = ShapePosition.Left;
+ this.addressFrame.RelativeHorizontal = RelativeHorizontal.Margin;
+ this.addressFrame.Top = "5.0cm";
+ this.addressFrame.RelativeVertical = RelativeVertical.Page;
+
+ // Put sender in address frame
+ paragraph = this.addressFrame.AddParagraph("PowerBooks Inc · Sample Street 42 · 56789 Cologne");
+ paragraph.Format.Font.Name = "Times New Roman";
+ paragraph.Format.Font.Size = 7;
+ paragraph.Format.SpaceAfter = 3;
+
+ // Add the print date field
+ paragraph = section.AddParagraph();
+ paragraph.Format.SpaceBefore = "8cm";
+ paragraph.Style = "Reference";
+ paragraph.AddFormattedText("INVOICE", TextFormat.Bold);
+ paragraph.AddTab();
+ paragraph.AddText("Cologne, ");
+ paragraph.AddDateField("dd.MM.yyyy");
+
+ // Create the item table
+ this.table = section.AddTable();
+ this.table.Style = "Table";
+ this.table.Borders.Color = TableBorder;
+ this.table.Borders.Width = 0.25;
+ this.table.Borders.Left.Width = 0.5;
+ this.table.Borders.Right.Width = 0.5;
+ this.table.Rows.LeftIndent = 0;
+
+ // Before you can add a row, you must define the columns
+ Column column = this.table.AddColumn("1cm");
+ column.Format.Alignment = ParagraphAlignment.Center;
+
+ column = this.table.AddColumn("2.5cm");
+ column.Format.Alignment = ParagraphAlignment.Right;
+
+ column = this.table.AddColumn("3cm");
+ column.Format.Alignment = ParagraphAlignment.Right;
+
+ column = this.table.AddColumn("3.5cm");
+ column.Format.Alignment = ParagraphAlignment.Right;
+
+ column = this.table.AddColumn("2cm");
+ column.Format.Alignment = ParagraphAlignment.Center;
+
+ column = this.table.AddColumn("4cm");
+ column.Format.Alignment = ParagraphAlignment.Right;
+
+ // Create the header of the table
+ Row row = table.AddRow();
+ row.HeadingFormat = true;
+ row.Format.Alignment = ParagraphAlignment.Center;
+ row.Format.Font.Bold = true;
+ row.Shading.Color = TableBlue;
+ row.Cells[0].AddParagraph("Item");
+ row.Cells[0].Format.Font.Bold = false;
+ row.Cells[0].Format.Alignment = ParagraphAlignment.Left;
+ row.Cells[0].VerticalAlignment = VerticalAlignment.Bottom;
+ row.Cells[0].MergeDown = 1;
+ row.Cells[1].AddParagraph("Title and Author");
+ row.Cells[1].Format.Alignment = ParagraphAlignment.Left;
+ row.Cells[1].MergeRight = 3;
+ row.Cells[5].AddParagraph("Extended Price");
+ row.Cells[5].Format.Alignment = ParagraphAlignment.Left;
+ row.Cells[5].VerticalAlignment = VerticalAlignment.Bottom;
+ row.Cells[5].MergeDown = 1;
+
+ row = table.AddRow();
+ row.HeadingFormat = true;
+ row.Format.Alignment = ParagraphAlignment.Center;
+ row.Format.Font.Bold = true;
+ row.Shading.Color = TableBlue;
+ row.Cells[1].AddParagraph("Quantity");
+ row.Cells[1].Format.Alignment = ParagraphAlignment.Left;
+ row.Cells[2].AddParagraph("Unit Price");
+ row.Cells[2].Format.Alignment = ParagraphAlignment.Left;
+ row.Cells[3].AddParagraph("Discount (%)");
+ row.Cells[3].Format.Alignment = ParagraphAlignment.Left;
+ row.Cells[4].AddParagraph("Taxable");
+ row.Cells[4].Format.Alignment = ParagraphAlignment.Left;
+
+ this.table.SetEdge(0, 0, 6, 2, Edge.Box, BorderStyle.Single, 0.75, Color.Empty);
+}
+```
+
+
+## Fill in the Content
+
+This routine adds the dynamic data to the invoice:
+
+```cs
+void FillContent()
+{
+ // Fill address in address text frame
+ XPathNavigator item = SelectItem("/invoice/to");
+ Paragraph paragraph = this.addressFrame.AddParagraph();
+ paragraph.AddText(GetValue(item, "name/singleName"));
+ paragraph.AddLineBreak();
+ paragraph.AddText(GetValue(item, "address/line1"));
+ paragraph.AddLineBreak();
+ paragraph.AddText(GetValue(item, "address/postalCode") + " " + GetValue(item, "address/city"));
+
+ // Iterate the invoice items
+ double totalExtendedPrice = 0;
+ XPathNodeIterator iter = this.navigator.Select("/invoice/items/*");
+ while (iter.MoveNext())
+ {
+ item = iter.Current;
+ double quantity = GetValueAsDouble(item, "quantity");
+ double price = GetValueAsDouble(item, "price");
+ double discount = GetValueAsDouble(item, "discount");
+
+ // Each item fills two rows
+ Row row1 = this.table.AddRow();
+ Row row2 = this.table.AddRow();
+ row1.TopPadding = 1.5;
+ row1.Cells[0].Shading.Color = TableGray;
+ row1.Cells[0].VerticalAlignment = VerticalAlignment.Center;
+ row1.Cells[0].MergeDown = 1;
+ row1.Cells[1].Format.Alignment = ParagraphAlignment.Left;
+ row1.Cells[1].MergeRight = 3;
+ row1.Cells[5].Shading.Color = TableGray;
+ row1.Cells[5].MergeDown = 1;
+
+ row1.Cells[0].AddParagraph(GetValue(item, "itemNumber"));
+ paragraph = row1.Cells[1].AddParagraph();
+ paragraph.AddFormattedText(GetValue(item, "title"), TextFormat.Bold);
+ paragraph.AddFormattedText(" by ", TextFormat.Italic);
+ paragraph.AddText(GetValue(item, "author"));
+ row2.Cells[1].AddParagraph(GetValue(item, "quantity"));
+ row2.Cells[2].AddParagraph(price.ToString("0.00") + " €");
+ row2.Cells[3].AddParagraph(discount.ToString("0.0"));
+ row2.Cells[4].AddParagraph();
+ row2.Cells[5].AddParagraph(price.ToString("0.00"));
+ double extendedPrice = quantity * price;
+ extendedPrice = extendedPrice * (100 - discount) / 100;
+ row1.Cells[5].AddParagraph(extendedPrice.ToString("0.00") + " €");
+ row1.Cells[5].VerticalAlignment = VerticalAlignment.Bottom;
+ totalExtendedPrice += extendedPrice;
+
+ this.table.SetEdge(0, this.table.Rows.Count - 2, 6, 2, Edge.Box, BorderStyle.Single, 0.75);
+ }
+
+ // Add an invisible row as a space line to the table
+ Row row = this.table.AddRow();
+ row.Borders.Visible = false;
+
+ // Add the total price row
+ row = this.table.AddRow();
+ row.Cells[0].Borders.Visible = false;
+ row.Cells[0].AddParagraph("Total Price");
+ row.Cells[0].Format.Font.Bold = true;
+ row.Cells[0].Format.Alignment = ParagraphAlignment.Right;
+ row.Cells[0].MergeRight = 4;
+ row.Cells[5].AddParagraph(totalExtendedPrice.ToString("0.00") + " €");
+
+ // Add the VAT row
+ row = this.table.AddRow();
+ row.Cells[0].Borders.Visible = false;
+ row.Cells[0].AddParagraph("VAT (19%)");
+ row.Cells[0].Format.Font.Bold = true;
+ row.Cells[0].Format.Alignment = ParagraphAlignment.Right;
+ row.Cells[0].MergeRight = 4;
+ row.Cells[5].AddParagraph((0.19 * totalExtendedPrice).ToString("0.00") + " €");
+
+ // Add the additional fee row
+ row = this.table.AddRow();
+ row.Cells[0].Borders.Visible = false;
+ row.Cells[0].AddParagraph("Shipping and Handling");
+ row.Cells[5].AddParagraph(0.ToString("0.00") + " €");
+ row.Cells[0].Format.Font.Bold = true;
+ row.Cells[0].Format.Alignment = ParagraphAlignment.Right;
+ row.Cells[0].MergeRight = 4;
+
+ // Add the total due row
+ row = this.table.AddRow();
+ row.Cells[0].AddParagraph("Total Due");
+ row.Cells[0].Borders.Visible = false;
+ row.Cells[0].Format.Font.Bold = true;
+ row.Cells[0].Format.Alignment = ParagraphAlignment.Right;
+ row.Cells[0].MergeRight = 4;
+ totalExtendedPrice += 0.19 * totalExtendedPrice;
+ row.Cells[5].AddParagraph(totalExtendedPrice.ToString("0.00") + " €");
+
+ // Set the borders of the specified cell range
+ this.table.SetEdge(5, this.table.Rows.Count - 4, 1, 4, Edge.Box, BorderStyle.Single, 0.75);
+
+ // Add the notes paragraph
+ paragraph = this.document.LastSection.AddParagraph();
+ paragraph.Format.SpaceBefore = "1cm";
+ paragraph.Format.Borders.Width = 0.75;
+ paragraph.Format.Borders.Distance = 3;
+ paragraph.Format.Borders.Color = TableBorder;
+ paragraph.Format.Shading.Color = TableGray;
+ item = SelectItem("/invoice");
+ paragraph.AddText(GetValue(item, "notes"));
+}
+```
diff --git a/docs/MigraDocCore/samples/MixMigraDocCoreAndPDFsharpCore.md b/docs/MigraDocCore/samples/MixMigraDocCoreAndPDFsharpCore.md
new file mode 100644
index 00000000..1636be2b
--- /dev/null
+++ b/docs/MigraDocCore/samples/MixMigraDocCoreAndPDFsharpCore.md
@@ -0,0 +1,143 @@
+# Mix MigraDocCore and PDFsharpCore
+
+Demonstrates how to mix MigraDocCore and PDFsharpCore.
+
+
+## Creating the Document
+
+We create a PdfDocument, not a (MigraDocCore) Document:
+
+```cs
+static void Main()
+{
+ DateTime now = DateTime.Now;
+ string filename = "MixMigraDocCoreAndPdfSharpCore.pdf";
+ filename = Guid.NewGuid().ToString("D").ToUpper() + ".pdf";
+ PdfDocument document = new PdfDocument();
+ document.Info.Title = "PDFsharpCore XGraphic Sample";
+ document.Info.Author = "Stefan Lange";
+ document.Info.Subject = "Created with code snippets that show the use of graphical functions";
+ document.Info.Keywords = "PDFsharpCore, XGraphics";
+
+ SamplePage1(document);
+ SamplePage2(document);
+
+ Debug.WriteLine("seconds=" + (DateTime.Now - now).TotalSeconds.ToString());
+
+ // Save the document...
+ document.Save(filename);
+}
+```
+
+
+## The First Page
+
+Here we create a MigraDocCore Document object to draw the content of this page:
+
+```cs
+static void SamplePage1(PdfDocument document)
+{
+ PdfPage page = document.AddPage();
+ XGraphics gfx = XGraphics.FromPdfPage(page);
+ // HACK
+ gfx.MUH = PdfFontEncoding.Unicode;
+ gfx.MFEH = PdfFontEmbedding.Default;
+
+ XFont font = new XFont("Verdana", 13, XFontStyle.Bold);
+
+ gfx.DrawString("The following paragraph was rendered using MigraDocCore:", font, XBrushes.Black,
+ new XRect(100, 100, page.Width - 200, 300), XStringFormats.Center);
+
+ // You always need a MigraDocCore document for rendering.
+ Document doc = new Document();
+ Section sec = doc.AddSection();
+ // Add a single paragraph with some text and format information.
+ Paragraph para = sec.AddParagraph();
+ para.Format.Alignment = ParagraphAlignment.Justify;
+ para.Format.Font.Name = "Times New Roman";
+ para.Format.Font.Size = 12;
+ para.Format.Font.Color = MigraDocCore.DocumentObjectModel.Colors.DarkGray;
+ para.Format.Font.Color = MigraDocCore.DocumentObjectModel.Colors.DarkGray;
+ para.AddText("Duisism odigna acipsum delesenisl ");
+ para.AddFormattedText("ullum in velenit", TextFormat.Bold);
+ para.AddText(" ipit iurero dolum zzriliquisis nit wis dolore vel et nonsequipit, velendigna "+
+ "auguercilit lor se dipisl duismod tatem zzrit at laore magna feummod oloborting ea con vel "+
+ "essit augiati onsequat luptat nos diatum vel ullum illummy nonsent nit ipis et nonsequis "+
+ "niation utpat. Odolobor augait et non etueril landre min ut ulla feugiam commodo lortie ex "+
+ "essent augait el ing eumsan hendre feugait prat augiatem amconul laoreet. ≤≥≈≠");
+ para.Format.Borders.Distance = "5pt";
+ para.Format.Borders.Color = Colors.Gold;
+
+ // Create a renderer and prepare (=layout) the document
+ MigraDocCore.Rendering.DocumentRenderer docRenderer = new DocumentRenderer(doc);
+ docRenderer.PrepareDocument();
+
+ // Render the paragraph. You can render tables or shapes the same way.
+ docRenderer.RenderObject(gfx, XUnit.FromCentimeter(5), XUnit.FromCentimeter(10), "12cm", para);
+}
+```
+
+
+## Creating Page Two
+
+This page contains six pages, created with MigraDocCore and scaled down to fit on one page:
+
+```cs
+static void SamplePage2(PdfDocument document)
+{
+ PdfPage page = document.AddPage();
+ XGraphics gfx = XGraphics.FromPdfPage(page);
+ // HACK
+ gfx.MUH = PdfFontEncoding.Unicode;
+ gfx.MFEH = PdfFontEmbedding.Default;
+
+ // Create document from HalloMigraDoc sample
+ Document doc = HelloMigraDoc.Documents.CreateDocument();
+
+ // Create a renderer and prepare (=layout) the document
+ MigraDocCore.Rendering.DocumentRenderer docRenderer = new DocumentRenderer(doc);
+ docRenderer.PrepareDocument();
+
+ // For clarity we use point as unit of measure in this sample.
+ // A4 is the standard letter size in Germany (21cm x 29.7cm).
+ XRect A4Rect = new XRect(0, 0, A4Width, A4Height);
+
+ int pageCount = docRenderer.FormattedDocument.PageCount;
+ for (int idx = 0; idx < pageCount; idx++)
+ {
+ XRect rect = GetRect(idx);
+
+ // Use BeginContainer / EndContainer for simplicity only. You can naturally use you own transformations.
+ XGraphicsContainer container = gfx.BeginContainer(rect, A4Rect, XGraphicsUnit.Point);
+
+ // Draw page border for better visual representation
+ gfx.DrawRectangle(XPens.LightGray, A4Rect);
+
+ // Render the page. Note that page numbers start with 1.
+ docRenderer.RenderPage(gfx, idx + 1);
+
+ // Note: The outline and the hyperlinks (table of content) does not work in the produced PDF document.
+
+ // Pop the previous graphical state
+ gfx.EndContainer(container);
+ }
+}
+```
+
+
+## Helper Routine GetRect
+
+Calculates the area of a scaled down page:
+
+```cs
+static XRect GetRect(int index)
+{
+ XRect rect = new XRect(0, 0, A4Width / 3 * 0.9, A4Height / 3 * 0.9);
+ rect.X = (index % 3) * A4Width / 3 + A4Width * 0.05 / 3;
+ rect.Y = (index / 3) * A4Height / 3 + A4Height * 0.05 / 3;
+ return rect;
+}
+
+static double A4Width = XUnit.FromCentimeter(21).Point;
+static double A4Height = XUnit.FromCentimeter(29.7).Point;
+```
diff --git a/docs/MigraDocCore/samples/index.md b/docs/MigraDocCore/samples/index.md
new file mode 100644
index 00000000..54d25b94
--- /dev/null
+++ b/docs/MigraDocCore/samples/index.md
@@ -0,0 +1,9 @@
+# MigraDocCore > Samples
+
+Samples for [MigraDocCore](../index.md):
+
+* [Hello World](HelloWorld.md)
+* [Hello MigraDocCore](HelloMigraDocCore.md)
+* [Images](Images.md)
+* [Invoice](Invoice.md)
+* [Mix MigraDocCore and PDFsharpCore](MixMigraDocCoreAndPDFsharpCore.md)
diff --git a/docs/PdfSharpCore/faq.md b/docs/PdfSharpCore/faq.md
new file mode 100644
index 00000000..cf278c88
--- /dev/null
+++ b/docs/PdfSharpCore/faq.md
@@ -0,0 +1,107 @@
+# PDFsharpCore > FAQ
+
+FAQ for [PDFsharpCore](index.md):
+
+
+## What is PDFsharpCore
+
+PDFsharpCore is a .NET library for creating and modifying Adobe PDF documents programmatically. It is written in C# and can be used from any .NET language.
+
+
+## Is PDFsharpCore based on or does it require other libraries or tools?
+
+PDFsharpCore is newly designed and built from scratch in C#. Neither Adobe's PDF Library nor Acrobat are required.
+
+
+## What is the license of PDFsharpCore?
+
+PDFsharpCore is Open Source. You can copy, modify and integrate the source code of PDFsharpCore in your application without restrictions at all.
+
+See also: PDFsharpCore [license](../../LICENCE.md)
+
+
+## Can PDFsharpCore show PDF files? Print PDF files? Create images from PDF files?
+
+PDFsharpCore comes with a preview control designed to visualize drawing operations of the XGraphics object, but it cannot render PDF files.
+
+Further the DrawImage function can be used to draw so called form XObjects in PDF pages. If you try to render such an object in the preview, only the bounding box is drawn to show that it cannot be rendered.
+
+The PDFsharpCore [samples](samples/index.md) show how to invoke Adobe Reader or Acrobat to view or print PDF files and how to invoke GhostScript to create images from PDF pages.
+
+
+## Can I use PostScript fonts with PDFsharpCore?
+
+PDFsharpCore cannot work with PostScript fonts. Only TrueType fonts and OpenType fonts with TrueType outlines can be used with PDFsharpCore. Read more...
+
+
+## Can PDFsharpCore run on Web Servers under Medium Trust?
+
+You can run applications on web servers without full trust provided you only use fonts that are serviced by your own FontResolver. See the PDFsharpCore sample: [Font Resolver](samples/FontResolver.md) for further information.
+
+
+## Does PDFsharpCore support for Arabic, Hebrew, CJK (Chinese, Japanese, Korean)?
+
+Not yet. Right-to-left languages are not yet supported. Only simple languages like English or German are supported, with an easy one-to-one relationship between characters and glyphs.
+
+"Not supported" needs some explanation.
+
+It seems that Hebrew works if you reverse the strings and set all paragraphs to left-aligned.
+
+Japanese characters will be displayed, but left to right and not top to bottom. We cannot read Japanese and cannot verify they are shown correctly. Make sure you select a font that contains Japanese characters.
+
+Arabic characters have different shapes (glyphs), depending on their position (beginning, end, middle, isolated). PDFsharpCore does not support the selection of the correct glyphs. Arabic text may work if you reverse the string and if you make sure to select the correct Unicode characters for beginning, end, middle, or isolated display. Make sure you select a font that contains Arabic characters.
+
+
+## Which PDF versions are supported by PDFsharpCore?
+
+With PDFsharpCore you can create files with PDF versions from 1.2 (Adobe Acrobat Reader 3.0) through 1.7 (Adobe Reader 8.0).
+PDFsharpCore fully supports PDF 1.4 (Adobe Reader 5.0) including the transparency features introduced with this version.
+Some features of PDF 1.5 (Adobe Reader 6.0) are not yet implemented. Therefore PDFsharpCore cannot yet open all files marked for PDF 1.5 or higher. Since not all compression features of PDF 1.5 are implemented, with some files the file size may increase when they are processed with PDFsharpCore.
+
+
+## Does PDFsharpCore support PDF/A?
+
+Not yet.
+
+
+## Does PDFsharpCore support AcroForms?
+
+There is limited support for AcroForms included.
+
+
+## Can I use PDFsharpCore to convert HTML or RTF to PDF?
+
+No, not "out of the box", and we do not plan to write such a converter in the near future.
+
+Yes, PDFsharpCore with some extra code can do it. But we do not supply that extra code.
+On NuGet and other sources you can find a third party library "HTML Renderer for PDF using PdfSharpCore" that converts HTML to PDF. And there may be other libraries for the same or similar purposes, too. Maybe they work for you, maybe they get you started.
+
+
+## Can I use PDFsharpCore to convert PDF to Word, RTF, HTML?
+
+No, and we do not plan to write such a converter in the near future.
+
+
+## Can I use PDF files created with SQL Server 2008 Reporting Services?
+
+There is an issue with the PDFs created by SQL Server 2008 Reporting Services. We are working on it.
+As a workaround, create reports with SQL Server 2005 Reporting Services. Workaround for SQL Server 2008 Reporting Services: For the DeviceSettings parameter for the Render method on the ReportExecutionService object, pass this value:
+`theDeviceSettings = "True";`.
+This disables PDF file compression for SSRS 2008. Then, PDFSharpCore is able to handle the resulting uncompressed PDF file. (Note: SSRS 2005 ignores this setting so it can be passed to both SSRS versions.)
+
+
+## Can I use PDFsharpCore to extract text from PDF?
+
+This can be done at a low level. You can get at the characters in the order they are drawn - and most applications draw them from top-left to bottom-right. There are no high-level functions that return words, paragraphs, or whole pages.
+
+
+## Can PDFsharpCore simulate Bold or Italics?
+
+Not yet.
+
+
+## How many DPI are there in a PDF file? How can I set the DPI?
+
+PDF is a vector format, so there are no DPI. Raster images used in a PDF file do have DPI, but DPI is determined by the usage.
+Consider an image with 300 DPI. This image can be embedded once in the PDF file, but can be drawn several times. There could be a thumbnail on page 1, a full size reproduction on page 2, and a double size reproduction on page 3. Thus the image is drawn with 600 DPI on page 1, 300 DPI on page 2, and 150 DPI on page 3. But when you watch the PDF file in Adobe Reader with a Zoom factor of 1000%, the DPI value will be much lower than that.
+PDF is vector. There is no DPI. PDFsharpCore uses Points as the unit for coordinates. There are 72 Points per Inch. For ease of use, units can be converted from Inch, Centimeter, Millimeter and other units.
diff --git a/docs/PdfSharpCore/index.md b/docs/PdfSharpCore/index.md
new file mode 100644
index 00000000..bdf45ced
--- /dev/null
+++ b/docs/PdfSharpCore/index.md
@@ -0,0 +1,57 @@
+# PDFsharpCore
+
+PDFsharpCore is a .NET library for processing PDF file.
+You create PDF pages using drawing routines known from GDI+.
+Almost anything that can be done with GDI+ will also work with PDFsharpCore.
+Keep in mind it does no longer depend on GDI+, as it was ported to make use of [ImageSharp](https://github.com/SixLabors/ImageSharp).
+Only basic text layout is supported by PDFsharpCore, and page breaks are not created automatically.
+The same drawing routines can be used for screen, PDF, or meta files.
+
+* [Features](#features)
+* [First steps](#first-steps)
+* [Samples](samples/index.md)
+* [FAQ](faq.md)
+
+
+## Features
+
+* Creates PDF documents on the fly from any .NET language
+* Easy to understand object model to compose documents
+* One source code for drawing on a PDF page as well as in a window or on the printer
+* Modify, merge, and split existing PDF files
+* Images with transparency (color mask, monochrome mask, alpha mask)
+* Newly designed from scratch and written entirely in C#
+* The graphical classes go well with .NET
+
+
+## First steps
+
+Both PDFsharpCore and MigraDocCore provide a lot of `AddXxx` functions.
+Typically these functions return the newly created objects. Once you’ve learned the basic principles it’s quite easy to work with.
+Intellisense helps a lot then.
+
+We’ll discuss a few lines of the [Hello World](samples/HelloWorld.md) sample here.
+
+```cs
+// You’ll first need a PDF document:
+PdfDocument document = new PdfDocument();
+
+// And you need a page:
+PdfPage page = document.AddPage();
+
+// Drawing is done with an XGraphics object:
+XGraphics gfx = XGraphics.FromPdfPage(page);
+
+// Then you'll create a font:
+XFont font = new XFont("Verdana", 20, XFontStyle.Bold);
+
+// And you use that font to draw a string:
+gfx.DrawString(
+ "Hello, World!", font, XBrushes.Black,
+ new XRect(0, 0, page.Width, page.Height),
+ XStringFormat.Center);
+
+// When drawing is done, write the file:
+string filename = "HelloWorld.pdf";
+document.Save(filename);
+```
diff --git a/docs/PdfSharpCore/samples/Annotations.md b/docs/PdfSharpCore/samples/Annotations.md
new file mode 100644
index 00000000..6018b158
--- /dev/null
+++ b/docs/PdfSharpCore/samples/Annotations.md
@@ -0,0 +1,72 @@
+# Annotations
+
+This sample shows how to create PDF annotations.
+
+PDFsharpCore supports the creation of the following annotations:
+* [Text annotations](#text-annotations)
+* [Text annotations opened](#text-annotations-opened)
+* [Rubber stamp annotations](#rubber-stamp-annotations)
+
+
+## Text annotations
+
+```cs
+// Create a PDF text annotation
+PdfTextAnnotation textAnnot = new PdfTextAnnotation();
+textAnnot.Title = "This is the title";
+textAnnot.Subject = "This is the subject";
+textAnnot.Contents = "This is the contents of the annotation.\rThis is the 2nd line.";
+textAnnot.Icon = PdfTextAnnotationIcon.Note;
+
+gfx.DrawString("The first text annotation", font, XBrushes.Black, 30, 50, XStringFormats.Default);
+
+// Convert rectangle from world space to page space. This is necessary because the annotation is
+// placed relative to the bottom left corner of the page with units measured in point.
+XRect rect = gfx.Transformer.WorldToDefaultPage(new XRect(new XPoint(30, 60), new XSize(30, 30)));
+textAnnot.Rectangle = new PdfRectangle(rect);
+
+// Add the annotation to the page
+page.Annotations.Add(textAnnot);
+```
+
+
+## Text annotations opened
+```cs
+// Create another PDF text annotation which is open and transparent
+textAnnot = new PdfTextAnnotation();
+textAnnot.Title = "Annotation 2 (title)";
+textAnnot.Subject = "Annotation 2 (subject)";
+textAnnot.Contents = "This is the contents of the 2nd annotation.";
+textAnnot.Icon = PdfTextAnnotationIcon.Help;
+textAnnot.Color = XColors.LimeGreen;
+textAnnot.Opacity = 0.5;
+textAnnot.Open = true;
+
+gfx.DrawString("The second text annotation (opened)", font, XBrushes.Black, 30, 140, XStringFormats.Default);
+
+rect = gfx.Transformer.WorldToDefaultPage(new XRect(new XPoint(30, 150), new XSize(30, 30)));
+textAnnot.Rectangle = new PdfRectangle(rect);
+
+// Add the 2nd annotation to the page
+page.Annotations.Add(textAnnot);
+```
+
+
+## Rubber stamp annotations
+
+```cs
+// Create a so called rubber stamp annotation. I'm not sure if it is useful, but at least
+// it looks impressive...
+PdfRubberStampAnnotation rsAnnot = new PdfRubberStampAnnotation();
+rsAnnot.Icon = PdfRubberStampAnnotationIcon.TopSecret;
+rsAnnot.Flags = PdfAnnotationFlags.ReadOnly;
+
+rect = gfx.Transformer.WorldToDefaultPage(new XRect(new XPoint(100, 400), new XSize(350, 150)));
+rsAnnot.Rectangle = new PdfRectangle(rect);
+
+// Add the rubber stamp annotation to the page
+page.Annotations.Add(rsAnnot);
+```
+
+PDF supports some more pretty types of annotations like PdfLineAnnotation, PdfSquareAnnotation, PdfCircleAnnotation, PdfMarkupAnnotation (with the subtypes PdfHighlightAnnotation, PdfUnderlineAnnotation, PdfStrikeOutAnnotation, and PdfSquigglyAnnotation), PdfSoundAnnotation, or PdfMovieAnnotation.
+If you need one of them, feel encouraged to implement it. It is quite easy.
diff --git a/docs/PdfSharpCore/samples/Booklet.md b/docs/PdfSharpCore/samples/Booklet.md
new file mode 100644
index 00000000..9625544a
--- /dev/null
+++ b/docs/PdfSharpCore/samples/Booklet.md
@@ -0,0 +1,98 @@
+# Booklet
+
+Shows how to produce a booklet by placing two pages of an existing document on one landscape orientated page of a new document (for duplex printing).
+
+
+## Code
+
+Here is the code that does the work:
+
+```cs
+// Create the output document
+PdfDocument outputDocument = new PdfDocument();
+
+// Show single pages
+// (Note: one page contains two pages from the source document.
+// If the number of pages of the source document can not be
+// divided by 4, the first pages of the output document will
+// each contain only one page from the source document.)
+outputDocument.PageLayout = PdfPageLayout.SinglePage;
+
+XGraphics gfx;
+
+// Open the external document as XPdfForm object
+XPdfForm form = XPdfForm.FromFile(filename);
+// Determine width and height
+double extWidth = form.PixelWidth;
+double extHeight = form.PixelHeight;
+
+int inputPages = form.PageCount;
+int sheets = inputPages / 4;
+if (sheets * 4 < inputPages)
+sheets += 1;
+int allpages = 4 * sheets;
+int vacats = allpages - inputPages;
+
+for (int idx = 1; idx <= sheets; idx += 1)
+{
+ // Front page of a sheet:
+ // Add a new page to the output document
+ PdfPage page = outputDocument.AddPage();
+ page.Orientation = PageOrientation.Landscape;
+ page.Width = 2 * extWidth;
+ page.Height = extHeight;
+ double width = page.Width;
+ double height = page.Height;
+
+ gfx = XGraphics.FromPdfPage(page);
+
+ // Skip if left side has to remain blank
+ XRect box;
+ if (vacats > 0)
+ vacats -= 1;
+ else
+ {
+ // Set page number (which is one-based) for left side
+ form.PageNumber = allpages + 2 * (1 - idx);
+ box = new XRect(0, 0, width / 2, height);
+ // Draw the page identified by the page number like an image
+ gfx.DrawImage(form, box);
+ }
+
+ // Set page number (which is one-based) for right side
+ form.PageNumber = 2 * idx - 1;
+ box = new XRect(width / 2, 0, width / 2, height);
+ // Draw the page identified by the page number like an image
+ gfx.DrawImage(form, box);
+
+ // Back page of a sheet
+ page = outputDocument.AddPage();
+ page.Orientation = PageOrientation.Landscape;
+ page.Width = 2 * extWidth;
+ page.Height = extHeight;
+
+ gfx = XGraphics.FromPdfPage(page);
+
+ // Set page number (which is one-based) for left side
+ form.PageNumber = 2 * idx;
+ box = new XRect(0, 0, width / 2, height);
+ // Draw the page identified by the page number like an image
+ gfx.DrawImage(form, box);
+
+ // Skip if right side has to remain blank
+ if (vacats > 0)
+ vacats -= 1;
+ else
+ {
+ // Set page number (which is one-based) for right side
+ form.PageNumber = allpages + 1 - 2 * idx;
+ box = new XRect(width / 2, 0, width / 2, height);
+ // Draw the page identified by the page number like an image
+ gfx.DrawImage(form, box);
+ }
+}
+
+// Save the document...
+filename = "Booklet.pdf";
+outputDocument.Save(filename);
+```
diff --git a/docs/PdfSharpCore/samples/Bookmarks.md b/docs/PdfSharpCore/samples/Bookmarks.md
new file mode 100644
index 00000000..8a60cb99
--- /dev/null
+++ b/docs/PdfSharpCore/samples/Bookmarks.md
@@ -0,0 +1,43 @@
+# Bookmarks
+
+This sample shows how to create bookmarks. Bookmarks are called outlines in the PDF reference manual, that's why you deal with the class PdfOutline.
+
+Acrobat uses the term "bookmark" in its English version and "Lesezeichen" in the German version.
+
+
+## Code
+
+This is the source code that demonstrates the creation of bookmarks:
+
+```cs
+// Create a new PDF document
+PdfDocument document = new PdfDocument();
+
+// Create a font
+XFont font = new XFont("Verdana", 16);
+
+// Create first page
+PdfPage page = document.AddPage();
+XGraphics gfx = XGraphics.FromPdfPage(page);
+gfx.DrawString("Page 1", font, XBrushes.Black, 20, 50, XStringFormats.Default);
+
+// Create the root bookmark. You can set the style and the color.
+PdfOutline outline = document.Outlines.Add("Root", page, true, PdfOutlineStyle.Bold, XColors.Red);
+
+// Create some more pages
+for (int idx = 2; idx <= 5; idx++)
+{
+ page = document.AddPage();
+ gfx = XGraphics.FromPdfPage(page);
+
+ string text = "Page " + idx;
+ gfx.DrawString(text, font, XBrushes.Black, 20, 50, XStringFormats.Default);
+
+ // Create a sub bookmark
+ outline.Outlines.Add(text, page, true);
+}
+
+// Save the document...
+const string filename = "Bookmarks_tempfile.pdf";
+document.Save(filename);
+```
diff --git a/docs/PdfSharpCore/samples/Clock.md b/docs/PdfSharpCore/samples/Clock.md
new file mode 100644
index 00000000..bd0d8b1a
--- /dev/null
+++ b/docs/PdfSharpCore/samples/Clock.md
@@ -0,0 +1,141 @@
+# Clock
+
+This sample shows how to create a PDF document on the fly in an ASP.NET application. For illustration the sample draws an analog clock that displays the current server time.
+
+
+## Code
+Here is the framework for an .aspx page that returns a PDF file:
+
+```cs
+void Page_Load(object sender, EventArgs e)
+{
+ // Create new PDF document
+ PdfDocument document = new PdfDocument();
+ this.time = document.Info.CreationDate;
+ document.Info.Title = "PDFsharpCore Clock Demo";
+ document.Info.Author = "Stefan Lange";
+ document.Info.Subject = "Server time: " +
+ this.time.ToString("F", CultureInfo.InvariantCulture);
+
+ // Create new page
+ PdfPage page = document.AddPage();
+ page.Width = XUnit.FromMillimeter(200);
+ page.Height = XUnit.FromMillimeter(200);
+
+ // Create graphics object and draw clock
+ XGraphics gfx = XGraphics.FromPdfPage(page);
+ RenderClock(gfx);
+
+ // Send PDF to browser
+ MemoryStream stream = new MemoryStream();
+ document.Save(stream, false);
+ Response.Clear();
+ Response.ContentType = "application/pdf";
+ Response.AddHeader("content-length", stream.Length.ToString());
+ Response.BinaryWrite(stream.ToArray());
+ Response.Flush();
+ stream.Close();
+ Response.End();
+}
+```
+
+Here's the routine that draws a clock on a square page (Inspired by Charles Petzold's AnalogClock sample in 'Programming Microsoft Windows with C#'):
+
+```cs
+void RenderClock(XGraphics gfx)
+{
+ // Clocks should always look happy on hardcopies...
+ //this.time = new DateTime(2005, 1, 1, 11, 6, 22, 500);
+
+ XColor strokeColor = XColors.DarkBlue;
+ XColor fillColor = XColors.DarkOrange;
+
+ XPen pen = new XPen(strokeColor, 5);
+ XBrush brush = new XSolidBrush(fillColor);
+
+ strokeColor.A = 0.8;
+ fillColor.A = 0.8;
+ XPen handPen = new XPen(strokeColor, 5);
+ XBrush handBrush = new XSolidBrush(fillColor);
+
+ DrawText(gfx, pen, brush);
+
+ double width = gfx.PageSize.Width;
+ double height = gfx.PageSize.Height;
+ gfx.TranslateTransform(width / 2, height / 2);
+ double scale = Math.Min(width, height);
+ gfx.ScaleTransform(scale / 2000);
+
+ DrawFace(gfx, pen, brush);
+ DrawHourHand(gfx, handPen, handBrush);
+ DrawMinuteHand(gfx, handPen, handBrush);
+ DrawSecondHand(gfx, new XPen(XColors.Red, 7));
+}
+```
+
+The helper that draws the text:
+
+```cs
+static void DrawText(XGraphics gfx, XPen pen, XBrush brush)
+{
+ XSize size = gfx.PageSize;
+ XGraphicsPath path = new XGraphicsPath();
+ path.AddString("PDFsharpCore",
+ new XFontFamily("Verdana"), XFontStyle.BoldItalic, 60,
+ new XRect(0, size.Height / 3.5, size.Width, 0), XStringFormats.Center);
+ gfx.DrawPath(new XPen(pen.Color, 3), brush, path);
+}
+```
+
+The helper that draws the face:
+
+```cs
+static void DrawFace(XGraphics gfx, XPen pen, XBrush brush)
+{
+ for (int i = 0; i < 60; i++)
+ {
+ int size = i % 5 == 0 ? 100 : 30;
+ gfx.DrawEllipse(pen, brush, 0 - size / 2, -900 - size / 2, size, size);
+ gfx.RotateTransform(6);
+ }
+}
+```
+
+Three helpers draw the hands:
+
+```cs
+void DrawHourHand(XGraphics gfx, XPen pen, XBrush brush)
+{
+ XGraphicsState gs = gfx.Save();
+ gfx.RotateTransform(360 * Time.Hour / 12 + 30 * Time.Minute / 60);
+ gfx.DrawPolygon(
+ pen, brush,
+ new XPoint[]{new XPoint(0, 150), new XPoint(100, 0),
+ new XPoint(0, -600), new XPoint(-100, 0)},
+ XFillMode.Winding);
+ gfx.Restore(gs);
+}
+
+void DrawMinuteHand(XGraphics gfx, XPen pen, XBrush brush)
+{
+ XGraphicsState gs = gfx.Save();
+ gfx.RotateTransform(360 * Time.Minute / 60 + 6 * Time.Second / 60);
+
+ gfx.DrawPolygon(pen, brush,
+ new XPoint[]{new XPoint(0, 200), new XPoint(50, 0),
+ new XPoint(0, -800), new XPoint(-50, 0)},
+ XFillMode.Winding);
+ gfx.Restore(gs);
+}
+
+void DrawSecondHand(XGraphics gfx, XPen pen)
+{
+ XGraphicsState gs = gfx.Save();
+
+ gfx.RotateTransform(360 * Time.Second / 60 + 6 * Time.Millisecond / 1000);
+
+ gfx.DrawEllipse(new XSolidBrush(pen.Color), -15, -15, 30, 30);
+ gfx.DrawLine(pen, 0, 40, 0, -800);
+ gfx.Restore(gs);
+}
+```
diff --git a/docs/PdfSharpCore/samples/ColorsCMYK.md b/docs/PdfSharpCore/samples/ColorsCMYK.md
new file mode 100644
index 00000000..b694662b
--- /dev/null
+++ b/docs/PdfSharpCore/samples/ColorsCMYK.md
@@ -0,0 +1,36 @@
+# Colors CMYK
+
+This sample shows how to use CMYK colors.
+
+
+## Code
+
+This is the source code the shows how to set the color mode to CMYK:
+
+```cs
+PdfDocument document = PdfReader.Open(filename);
+document.Options.ColorMode = PdfColorMode.Cmyk;
+
+// Set version to PDF 1.4 (Acrobat 5) because we use transparency.
+if (document.Version < 14)
+ document.Version = 14;
+
+PdfPage page = document.Pages[0];
+
+// Get an XGraphics object for drawing beneath the existing content
+
+XGraphics gfx = XGraphics.FromPdfPage(page, XGraphicsPdfPageOptions.Append);
+
+gfx.DrawRectangle(new XSolidBrush(XColor.FromCmyk(1, 0.68, 0, 0.12)), new XRect(30, 60, 50, 50));
+gfx.DrawRectangle(new XSolidBrush(XColor.FromCmyk(0, 0.70, 1, 0)), new XRect(550, 60, 50, 50));
+
+gfx.DrawRectangle(new XSolidBrush(XColor.FromCmyk(0, 0, 0, 0)), new XRect(90, 100, 50, 50));
+gfx.DrawRectangle(new XSolidBrush(XColor.FromCmyk(0, 0, 0, 0)), new XRect(150, 100, 50, 50));
+
+gfx.DrawRectangle(new XSolidBrush(XColor.FromCmyk(0.7, 0, 0.70, 1, 0)), new XRect(90, 100, 50, 50));
+gfx.DrawRectangle(new XSolidBrush(XColor.FromCmyk(0.5, 0, 0.70, 1, 0)), new XRect(150, 100, 50, 50));
+
+gfx.DrawRectangle(new XSolidBrush(XColor.FromCmyk(0.35, 0.15, 0, 0.08)), new XRect(50, 360, 50, 50));
+gfx.DrawRectangle(new XSolidBrush(XColor.FromCmyk(0.25, 0.10, 0, 0.05)), new XRect(150, 360, 50, 50));
+gfx.DrawRectangle(new XSolidBrush(XColor.FromCmyk(0.15, 0.05, 0, 0)), new XRect(250, 360, 50, 50));
+```
diff --git a/docs/PdfSharpCore/samples/CombineDocuments.md b/docs/PdfSharpCore/samples/CombineDocuments.md
new file mode 100644
index 00000000..f4a14e07
--- /dev/null
+++ b/docs/PdfSharpCore/samples/CombineDocuments.md
@@ -0,0 +1,132 @@
+# Combine Documents
+
+This sample shows how to create a new document from two existing PDF files. The pages are inserted alternately from two external documents. This may be useful for visual comparison.
+
+Two different techniques are demonstrated:
+* How to import a page from an external document. This technique includes all annotations of the imported page.
+* How to import a page as a PDF form object. This technique treats the pages of external documents like images that can be transformed and placed everywhere.
+
+## Variant 1
+
+Imports pages from an external document. Note that this technique imports the whole page including the hyperlinks.
+
+```cs
+// Open the input files
+PdfDocument inputDocument1 = PdfReader.Open(filename1, PdfDocumentOpenMode.Import);
+PdfDocument inputDocument2 = PdfReader.Open(filename2, PdfDocumentOpenMode.Import);
+
+// Create the output document
+PdfDocument outputDocument = new PdfDocument();
+
+// Show consecutive pages facing. Requires Acrobat 5 or higher.
+outputDocument.PageLayout = PdfPageLayout.TwoColumnLeft;
+
+XFont font = new XFont("Verdana", 10, XFontStyle.Bold);
+XStringFormat format = new XStringFormat();
+format.Alignment = XStringAlignment.Center;
+format.LineAlignment = XLineAlignment.Far;
+XGraphics gfx;
+XRect box;
+int count = Math.Max(inputDocument1.PageCount, inputDocument2.PageCount);
+for (int idx = 0; idx < count; idx++)
+{
+ // Get page from 1st document
+ PdfPage page1 = inputDocument1.PageCount > idx ?
+ inputDocument1.Pages[idx] : new PdfPage();
+
+ // Get page from 2nd document
+ PdfPage page2 = inputDocument2.PageCount > idx ?
+ inputDocument2.Pages[idx] : new PdfPage();
+
+ // Add both pages to the output document
+ page1 = outputDocument.AddPage(page1);
+ page2 = outputDocument.AddPage(page2);
+
+ // Write document file name and page number on each page
+ gfx = XGraphics.FromPdfPage(page1);
+ box = page1.MediaBox.ToXRect();
+ box.Inflate(0, -10);
+ gfx.DrawString(String.Format("{0} • {1}", filename1, idx + 1),
+ font, XBrushes.Red, box, format);
+
+ gfx = XGraphics.FromPdfPage(page2);
+ box = page2.MediaBox.ToXRect();
+ box.Inflate(0, -10);
+ gfx.DrawString(String.Format("{0} • {1}", filename2, idx + 1),
+ font, XBrushes.Red, box, format);
+}
+
+// Save the document...
+const string filename = "CompareDocument1_tempfile.pdf";
+outputDocument.Save(filename);
+```
+
+
+## Variant 2
+
+Imports the pages as form X objects. Note that this technique copies only the visual content and the hyperlinks do not work.
+
+```cs
+// Create the output document
+PdfDocument outputDocument = new PdfDocument();
+
+// Show consecutive pages facing
+outputDocument.PageLayout = PdfPageLayout.TwoPageLeft;
+
+XFont font = new XFont("Verdana", 10, XFontStyle.Bold);
+XStringFormat format = new XStringFormat();
+format.Alignment = XStringAlignment.Center;
+format.LineAlignment = XLineAlignment.Far;
+XGraphics gfx;
+XRect box;
+
+// Open the external documents as XPdfForm objects. Such objects are
+// treated like images. By default the first page of the document is
+// referenced by a new XPdfForm.
+XPdfForm form1 = XPdfForm.FromFile(filename1);
+XPdfForm form2 = XPdfForm.FromFile(filename2);
+
+int count = Math.Max(form1.PageCount, form2.PageCount);
+for (int idx = 0; idx < count; idx++)
+{
+ // Add two new pages to the output document
+ PdfPage page1 = outputDocument.AddPage();
+ PdfPage page2 = outputDocument.AddPage();
+
+ if (form1.PageCount > idx)
+ {
+ // Get a graphics object for page1
+ gfx = XGraphics.FromPdfPage(page1);
+
+ // Set page number (which is one-based)
+ form1.PageNumber = idx + 1;
+
+ // Draw the page identified by the page number like an image
+ gfx.DrawImage(form1, new XRect(0, 0, form1.PointWidth, form1.PointHeight));
+
+ // Write document file name and page number on each page
+ box = page1.MediaBox.ToXRect();
+ box.Inflate(0, -10);
+ gfx.DrawString(String.Format("{0} • {1}", filename1, idx + 1),
+ font, XBrushes.Red, box, format);
+ }
+
+ // Same as above for second page
+ if (form2.PageCount > idx)
+ {
+ gfx = XGraphics.FromPdfPage(page2);
+
+ form2.PageNumber = idx + 1;
+ gfx.DrawImage(form2, new XRect(0, 0, form2.PointWidth, form2.PointHeight));
+
+ box = page2.MediaBox.ToXRect();
+ box.Inflate(0, -10);
+ gfx.DrawString(String.Format("{0} • {1}", filename2, idx + 1),
+ font, XBrushes.Red, box, format);
+ }
+}
+
+// Save the document...
+const string filename = "CompareDocument2_tempfile.pdf";
+outputDocument.Save(filename);
+```
diff --git a/docs/PdfSharpCore/samples/ConcatenateDocuments.md b/docs/PdfSharpCore/samples/ConcatenateDocuments.md
new file mode 100644
index 00000000..26242d6e
--- /dev/null
+++ b/docs/PdfSharpCore/samples/ConcatenateDocuments.md
@@ -0,0 +1,196 @@
+# Concatenate Documents
+
+This sample shows how to concatenate the pages of several PDF documents to one single file.
+
+* When you add the same external page twice or more, the content of the pages is shared.
+* Each imported page can be individually extended with graphics and text.
+
+
+## Code
+
+Here are code snippets for the 4 variations implemented in Concatenate Documents:
+
+```cs
+///
+/// Imports all pages from a list of documents.
+///
+static void Variant1()
+{
+ // Get some file names
+ string[] files = GetFiles();
+
+ // Open the output document
+ PdfDocument outputDocument = new PdfDocument();
+
+ // Iterate files
+ foreach (string file in files)
+ {
+ // Open the document to import pages from it.
+ PdfDocument inputDocument = PdfReader.Open(file, PdfDocumentOpenMode.Import);
+
+ // Iterate pages
+ int count = inputDocument.PageCount;
+ for (int idx = 0; idx < count; idx++)
+ {
+ // Get the page from the external document...
+ PdfPage page = inputDocument.Pages[idx];
+ // ...and add it to the output document.
+ outputDocument.AddPage(page);
+ }
+ }
+
+ // Save the document...
+ const string filename = "ConcatenatedDocument1_tempfile.pdf";
+ outputDocument.Save(filename);
+}
+```
+
+```cs
+///
+/// This sample adds each page twice to the output document. The output document
+/// becomes only a little bit larger because the content of the pages is reused
+/// and not duplicated.
+///
+static void Variant2()
+{
+ // Get some file names
+ string[] files = GetFiles();
+
+ // Open the output document
+ PdfDocument outputDocument = new PdfDocument();
+
+ // Show consecutive pages facing. Requires Acrobat 5 or higher.
+ outputDocument.PageLayout = PdfPageLayout.TwoColumnLeft;
+
+ // Iterate files
+ foreach (string file in files)
+ {
+ // Open the document to import pages from it.
+ PdfDocument inputDocument = PdfReader.Open(file, PdfDocumentOpenMode.Import);
+
+ // Iterate pages
+ int count = inputDocument.PageCount;
+ for (int idx = 0; idx < count; idx++)
+ {
+ // Get the page from the external document...
+ PdfPage page = inputDocument.Pages[idx];
+ // ...and add them twice to the output document.
+ outputDocument.AddPage(page);
+ outputDocument.AddPage(page);
+ }
+ }
+
+ // Save the document...
+ const string filename = "ConcatenatedDocument2_tempfile.pdf";
+ outputDocument.Save(filename);
+}
+```
+
+```cs
+///
+/// This sample adds a consecutive number in the middle of each page.
+/// It shows how you can add graphics to an imported page.
+///
+static void Variant3()
+{
+ // Get some file names
+ string[] files = GetFiles();
+
+ // Open the output document
+ PdfDocument outputDocument = new PdfDocument();
+
+ // Note that the output document may look significant larger than in Variant1.
+ // This is because adding graphics to an imported page causes the
+ // uncompression of its content if it was compressed in the external document.
+ // To compare file sizes you should either run the sample as Release build
+ // or uncomment the following line.
+ //outputDocument.Options.CompressContentStreams = true;
+
+ XFont font = new XFont("Verdana", 40, XFontStyle.Bold);
+ int number = 0;
+
+ // Iterate files
+ foreach (string file in files)
+ {
+ // Open the document to import pages from it.
+ PdfDocument inputDocument = PdfReader.Open(file, PdfDocumentOpenMode.Import);
+
+ // Iterate pages
+ int count = inputDocument.PageCount;
+ for (int idx = 0; idx < count; idx++)
+ {
+ // Get the page from the external document...
+ PdfPage page = inputDocument.Pages[idx];
+ // ...and add it to the output document.
+ // Note that the PdfPage instance returned by AddPage is a
+ // different object.
+ page = outputDocument.AddPage(page);
+
+ // Create a graphics object for this page. To draw beneath the existing
+ // content set 'Append' to 'Prepend'.
+ XGraphics gfx = XGraphics.FromPdfPage(page, XGraphicsPdfPageOptions.Append);
+ DrawNumber(gfx, font, ++number);
+ }
+ }
+
+ // Save the document...
+ const string filename = "ConcatenatedDocument3_tempfile.pdf";
+ outputDocument.Save(filename);
+}
+```
+
+```cs
+///
+/// This sample is the combination of Variant2 and Variant3. It shows that you
+/// can add external pages more than once and still add individual graphics on
+/// each page. The external content is shared among the pages, the new graphics
+/// are unique to each page. You can check this by comparing the file size
+/// of Variant3 and Variant4.
+///
+static void Variant4()
+{
+ // Get some file names
+ string[] files = GetFiles();
+
+ // Open the output document
+ PdfDocument outputDocument = new PdfDocument();
+
+ // For checking the file size uncomment next line.
+ //outputDocument.Options.CompressContentStreams = true;
+
+ XFont font = new XFont("Verdana", 40, XFontStyle.Bold);
+ int number = 0;
+
+ // Iterate files
+ foreach (string file in files)
+ {
+ // Open the document to import pages from it.
+ PdfDocument inputDocument = PdfReader.Open(file, PdfDocumentOpenMode.Import);
+
+ // Show consecutive pages facing. Requires Acrobat 5 or higher.
+ outputDocument.PageLayout = PdfPageLayout.TwoColumnLeft;
+
+ // Iterate pages
+ int count = inputDocument.PageCount;
+ for (int idx = 0; idx < count; idx++)
+ {
+ // Get the page from the external document...
+ PdfPage page = inputDocument.Pages[idx];
+ // ...and add it twice to the output document.
+ PdfPage page1 = outputDocument.AddPage(page);
+ PdfPage page2 = outputDocument.AddPage(page);
+
+ XGraphics gfx =
+ XGraphics.FromPdfPage(page1, XGraphicsPdfPageOptions.Append);
+ DrawNumber(gfx, font, ++number);
+
+ gfx = XGraphics.FromPdfPage(page2, XGraphicsPdfPageOptions.Append);
+ DrawNumber(gfx, font, ++number);
+ }
+ }
+
+ // Save the document...
+ const string filename = "ConcatenatedDocument4_tempfile.pdf";
+ outputDocument.Save(filename);
+}
+```
diff --git a/docs/PdfSharpCore/samples/ExportImages.md b/docs/PdfSharpCore/samples/ExportImages.md
new file mode 100644
index 00000000..213aa307
--- /dev/null
+++ b/docs/PdfSharpCore/samples/ExportImages.md
@@ -0,0 +1,102 @@
+# Export Images
+
+This sample shows how to export JPEG images from a PDF file.
+
+Note: This snippet shows how to export JPEG images from a PDF file. PDFsharpCore cannot convert PDF pages to JPEG files. This sample does not handle non-JPEG images. It does not (yet) handle JPEG images that have been flate-encoded.
+
+There are several different formats for non-JPEG images in PDF. Those are not supported by this simple sample and require several hours of coding, but this is left as an exercise to the reader.
+
+PDFsharpCore cannot render PDF pages - not to printers, not to bitmaps, not to JPEG files.
+
+
+## Code
+
+Here is the source code that does the work:
+
+```cs
+const string filename = "../../../../../PDFs/SomeLayout.pdf";
+PdfDocument document = PdfReader.Open(filename);
+
+int imageCount = 0;
+// Iterate pages
+foreach (PdfPage page in document.Pages)
+{
+ // Get resources dictionary
+ PdfDictionary resources = page.Elements.GetDictionary("/Resources");
+ if (resources != null)
+ {
+ // Get external objects dictionary
+ PdfDictionary xObjects = resources.Elements.GetDictionary("/XObject");
+ if (xObjects != null)
+ {
+ ICollection items = xObjects.Elements.Values;
+ // Iterate references to external objects
+ foreach (PdfItem item in items)
+ {
+ PdfReference reference = item as PdfReference;
+ if (reference != null)
+ {
+ PdfDictionary xObject = reference.Value as PdfDictionary;
+ // Is external object an image?
+ if (xObject != null && xObject.Elements.GetString("/Subtype") == "/Image")
+ {
+ ExportImage(xObject, ref imageCount);
+ }
+ }
+ }
+ }
+ }
+}
+```
+
+The image exporter:
+
+```cs
+static void ExportImage(PdfDictionary image, ref int count)
+{
+ string filter = image.Elements.GetName("/Filter");
+ switch (filter)
+ {
+ case "/DCTDecode":
+ ExportJpegImage(image, ref count);
+ break;
+
+ case "/FlateDecode":
+ ExportAsPngImage(image, ref count);
+ break;
+ }
+}
+```
+
+Here's the routine that exports JPEG images:
+
+```cs
+static void ExportJpegImage(PdfDictionary image, ref int count)
+{
+ // Fortunately JPEG has native support in PDF and exporting an image is just writing the stream to a file.
+ byte[] stream = image.Stream.Value;
+ FileStream fs = new FileStream(String.Format("Image{0}.jpeg", count++), FileMode.Create, FileAccess.Write);
+ BinaryWriter bw = new BinaryWriter(fs);
+ bw.Write(stream);
+ bw.Close();
+}
+```
+
+Other image formats are not yet implemented, here is the stub:
+
+```cs
+static void ExportAsPngImage(PdfDictionary image, ref int count)
+{
+ int width = image.Elements.GetInteger(PdfImage.Keys.Width);
+ int height = image.Elements.GetInteger(PdfImage.Keys.Height);
+ int bitsPerComponent = image.Elements.GetInteger(PdfImage.Keys.BitsPerComponent);
+
+ // TODO: You can put the code here that converts vom PDF internal image format to a Windows bitmap
+ // and use GDI+ to save it in PNG format.
+ // It is the work of a day or two for the most important formats. Take a look at the file
+ // PdfSharpCore.Pdf.Advanced/PdfImage.cs to see how we create the PDF image formats.
+ // We don't need that feature at the moment and therefore will not implement it.
+ // If you write the code for exporting images I would be pleased to publish it in a future release
+ // of PDFsharpCore.
+}
+```
diff --git a/docs/PdfSharpCore/samples/FontResolver.md b/docs/PdfSharpCore/samples/FontResolver.md
new file mode 100644
index 00000000..145dadc0
--- /dev/null
+++ b/docs/PdfSharpCore/samples/FontResolver.md
@@ -0,0 +1,35 @@
+# Font Resolver
+
+This sample shows how to use fonts that are included with your application. This allows you to use fonts that are not installed on the computer.
+
+For tasks running on web servers, private fonts may be the only available fonts.
+
+Note: The FontResolver is a global object and applies to all consumers of the PDFsharpCore library. It is also used when the MigraDocCore library creates PDF files.
+
+
+## The IFontResolver Interface
+
+In your application you create a class that implements the IFontResolver interface (it is in the PdfSharpCore.Fonts namespace).
+
+There are only two methods you have to implement. The first method returns a FontResolverInfo for every supported font.
+
+```cs
+public FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic)
+```
+
+The other method is called using the FaceName from the FontResolverInfo you previously returned. At this stage, return the font data as a byte array.
+
+```cs
+public byte[] GetFont(string faceName)
+```
+
+Now you only need one more step: register your font resolver using the global font resolver property. Here SegoeWpFontResolver is the class that implements IFontResolver.
+
+```cs
+// Register font resolver before start using PDFsharpCore.
+GlobalFontSettings.FontResolver = new SegoeWpFontResolver();
+```
+
+## Additional Information
+
+The font resolver set using GlobalFontSettings.FontResolver will be used by PDFsharpCore. Since MigraDocCore uses PDFsharpCore to create PDF files, the font resolver will also be used when generating PDF files from MigraDocCore.
diff --git a/docs/PdfSharpCore/samples/Graphics.md b/docs/PdfSharpCore/samples/Graphics.md
new file mode 100644
index 00000000..a969a64c
--- /dev/null
+++ b/docs/PdfSharpCore/samples/Graphics.md
@@ -0,0 +1,877 @@
+# Graphics
+
+Shows some of the capabilities of the XGraphics class.
+You'll find code snippets for the following graphical primitives:
+
+* [Lines and curves](#lines-and-curves)
+* [Shapes](#shapes)
+* [Graphical paths](#paths-class)
+* [Text and fonts](#text-class)
+* [Images and external PDF forms](#images)
+
+
+## Main program
+
+This is the main function. It creates a PDF document and adds some sample pages listed below.
+
+```cs
+static void Main()
+{
+ // Create a temporary file
+ string filename = String.Format("{0}_tempfile.pdf", Guid.NewGuid().ToString("D").ToUpper());
+ s_document = new PdfDocument();
+ s_document.Info.Title = "PDFsharpCore XGraphic Sample";
+ s_document.Info.Author = "Stefan Lange";
+ s_document.Info.Subject = "Created with code snippets that show the use of graphical functions";
+ s_document.Info.Keywords = "PDFsharpCore, XGraphics";
+
+ // Create demonstration pages
+ new LinesAndCurves().DrawPage(s_document.AddPage());
+ new Shapes().DrawPage(s_document.AddPage());
+ new Paths().DrawPage(s_document.AddPage());
+ new Text().DrawPage(s_document.AddPage());
+ new Images().DrawPage(s_document.AddPage());
+
+ // Save the s_document...
+ s_document.Save(filename);
+}
+```
+
+
+## Lines and Curves
+
+Shows how to draw lines and curves.
+
+```cs
+public void DrawPage(PdfPage page)
+{
+ XGraphics gfx = XGraphics.FromPdfPage(page);
+ DrawTitle(page, gfx, "Lines & Curves");
+
+ DrawLine(gfx, 1);
+ DrawLines(gfx, 2);
+ DrawBezier(gfx, 3);
+ DrawBeziers(gfx, 4);
+ DrawCurve(gfx, 5);
+ DrawArc(gfx, 6);
+}
+```
+
+### Draw simple lines
+
+```cs
+void DrawLine(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawLine");
+
+ gfx.DrawLine(XPens.DarkGreen, 0, 0, 250, 0);
+ gfx.DrawLine(XPens.Gold, 15, 7, 230, 15);
+
+ XPen pen = new XPen(XColors.Navy, 4);
+ gfx.DrawLine(pen, 0, 20, 250, 20);
+
+ pen = new XPen(XColors.Firebrick, 6);
+ pen.DashStyle = XDashStyle.Dash;
+ gfx.DrawLine(pen, 0, 40, 250, 40);
+
+ pen.Width = 7.3;
+ pen.DashStyle = XDashStyle.DashDotDot;
+ gfx.DrawLine(pen, 0, 60, 250, 60);
+
+ pen = new XPen(XColors.Goldenrod, 10);
+ pen.LineCap = XLineCap.Flat;
+ gfx.DrawLine(pen, 10, 90, 240, 90);
+ gfx.DrawLine(XPens.Black, 10, 90, 240, 90);
+
+ pen = new XPen(XColors.Goldenrod, 10);
+ pen.LineCap = XLineCap.Square;
+ gfx.DrawLine(pen, 10, 110, 240, 110);
+ gfx.DrawLine(XPens.Black, 10, 110, 240, 110);
+
+ pen = new XPen(XColors.Goldenrod, 10);
+ pen.LineCap = XLineCap.Round;
+ gfx.DrawLine(pen, 10, 130, 240, 130);
+ gfx.DrawLine(XPens.Black, 10, 130, 240, 130);
+
+ EndBox(gfx);
+}
+```
+
+### Draw a polyline
+
+```cs
+void DrawLines(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawLines");
+
+ XPen pen = new XPen(XColors.DarkSeaGreen, 6);
+ pen.LineCap = XLineCap.Round;
+ pen.LineJoin = XLineJoin.Bevel;
+ XPoint[] points = new XPoint[]
+ {
+ new XPoint(20, 30), new XPoint(60, 120),
+ new XPoint(90, 20), new XPoint(170, 90),
+ new XPoint(230, 40)
+ };
+ gfx.DrawLines(pen, points);
+
+ EndBox(gfx);
+}
+```
+
+### Draw a single Bézier curve
+
+```cs
+void DrawBezier(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawBezier");
+
+ gfx.DrawBezier(new XPen(XColors.DarkRed, 5), 20, 110, 40, 10, 170, 90, 230, 20);
+
+ EndBox(gfx);
+}
+```
+
+### Draw two Bézier curves
+
+```cs
+void DrawBeziers(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawBeziers");
+
+ XPoint[] points = new XPoint[]
+ {
+ new XPoint(20, 30), new XPoint(40, 120),
+ new XPoint(80, 20), new XPoint(110, 90),
+ new XPoint(180, 40), new XPoint(210, 40),
+ new XPoint(220, 80)
+ };
+ XPen pen = new XPen(XColors.Firebrick, 4);
+ gfx.DrawBeziers(pen, points);
+
+ EndBox(gfx);
+}
+```
+
+### Draw a cardinal spline
+
+```cs
+void DrawCurve(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawCurve");
+
+ XPoint[] points = new XPoint[]
+ {
+ new XPoint(20, 30), new XPoint(60, 120),
+ new XPoint(90, 20), new XPoint(170, 90),
+ new XPoint(230, 40)
+ };
+ XPen pen = new XPen(XColors.RoyalBlue, 3.5);
+ gfx.DrawCurve(pen, points, 1);
+
+ EndBox(gfx);
+}
+```
+
+### Draw an arc
+
+```cs
+void DrawArc(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawArc");
+
+ XPen pen = new XPen(XColors.Plum, 4.7);
+ gfx.DrawArc(pen, 0, 0, 250, 140, 190, 200);
+
+ EndBox(gfx);
+}
+```
+
+
+## Shapes
+
+Shows how to draw graphical shapes.
+
+```cs
+public void DrawPage(PdfPage page)
+{
+ XGraphics gfx = XGraphics.FromPdfPage(page);
+ DrawTitle(page, gfx, "Shapes");
+
+ DrawRectangle(gfx, 1);
+ DrawRoundedRectangle(gfx, 2);
+ DrawEllipse(gfx, 3);
+ DrawPolygon(gfx, 4);
+ DrawPie(gfx, 5);
+ DrawClosedCurve(gfx, 6);
+}
+```
+
+### Draw rectangles
+
+```cs
+void DrawRectangle(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawRectangle");
+
+ XPen pen = new XPen(XColors.Navy, Math.PI);
+
+ gfx.DrawRectangle(pen, 10, 0, 100, 60);
+ gfx.DrawRectangle(XBrushes.DarkOrange, 130, 0, 100, 60);
+ gfx.DrawRectangle(pen, XBrushes.DarkOrange, 10, 80, 100, 60);
+ gfx.DrawRectangle(pen, XBrushes.DarkOrange, 150, 80, 60, 60);
+
+ EndBox(gfx);
+}
+```
+
+### Draw rounded rectangles
+
+```cs
+void DrawRoundedRectangle(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawRoundedRectangle");
+
+ XPen pen = new XPen(XColors.RoyalBlue, Math.PI);
+
+ gfx.DrawRoundedRectangle(pen, 10, 0, 100, 60, 30, 20);
+ gfx.DrawRoundedRectangle(XBrushes.Orange, 130, 0, 100, 60, 30, 20);
+ gfx.DrawRoundedRectangle(pen, XBrushes.Orange, 10, 80, 100, 60, 30, 20);
+ gfx.DrawRoundedRectangle(pen, XBrushes.Orange, 150, 80, 60, 60, 20, 20);
+
+ EndBox(gfx);
+}
+```
+
+### Draw ellipses
+
+```cs
+void DrawEllipse(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawEllipse");
+
+ XPen pen = new XPen(XColors.DarkBlue, 2.5);
+
+ gfx.DrawEllipse(pen, 10, 0, 100, 60);
+ gfx.DrawEllipse(XBrushes.Goldenrod, 130, 0, 100, 60);
+ gfx.DrawEllipse(pen, XBrushes.Goldenrod, 10, 80, 100, 60);
+ gfx.DrawEllipse(pen, XBrushes.Goldenrod, 150, 80, 60, 60);
+
+ EndBox(gfx);
+}
+```
+
+### Draw polygons
+
+```cs
+void DrawPolygon(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawPolygon");
+
+ XPen pen = new XPen(XColors.DarkBlue, 2.5);
+
+ gfx.DrawPolygon(pen, XBrushes.LightCoral, GetPentagram(50, new XPoint(60, 70)), XFillMode.Winding);
+ gfx.DrawPolygon(pen, XBrushes.LightCoral, GetPentagram(50, new XPoint(180, 70)), XFillMode.Alternate);
+
+ EndBox(gfx);
+}
+```
+
+### Draw pies
+
+```cs
+void DrawPie(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawPie");
+
+ XPen pen = new XPen(XColors.DarkBlue, 2.5);
+
+ gfx.DrawPie(pen, 10, 0, 100, 90, -120, 75);
+ gfx.DrawPie(XBrushes.Gold, 130, 0, 100, 90, -160, 150);
+ gfx.DrawPie(pen, XBrushes.Gold, 10, 50, 100, 90, 80, 70);
+ gfx.DrawPie(pen, XBrushes.Gold, 150, 80, 60, 60, 35, 290);
+
+ EndBox(gfx);
+}
+```
+
+### Draw a closed cardinal spline
+
+```cs
+void DrawClosedCurve(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawClosedCurve");
+
+ XPen pen = new XPen(XColors.DarkBlue, 2.5);
+ gfx.DrawClosedCurve(
+ pen, XBrushes.SkyBlue,
+ new XPoint[]
+ {
+ new XPoint(10, 120), new XPoint(80, 30),
+ new XPoint(220, 20), new XPoint(170, 110),
+ new XPoint(100, 90)
+ },
+ XFillMode.Winding, 0.7);
+
+ EndBox(gfx);
+}
+```
+
+### Paths class
+
+Shows how to draw graphical paths.
+
+```cs
+public void DrawPage(PdfPage page)
+{
+ XGraphics gfx = XGraphics.FromPdfPage(page);
+
+ DrawTitle(page, gfx, "Paths");
+
+ DrawPathOpen(gfx, 1);
+ DrawPathClosed(gfx, 2);
+ DrawPathAlternateAndWinding(gfx, 3);
+ DrawGlyphs(gfx, 5);
+ DrawClipPath(gfx, 6);
+}
+```
+
+### Stroke an open path
+
+```cs
+void DrawPathOpen(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawPath (open)");
+
+ XPen pen = new XPen(XColors.Navy, Math.PI);
+ pen.DashStyle = XDashStyle.Dash;
+
+ XGraphicsPath path = new XGraphicsPath();
+ path.AddLine(10, 120, 50, 60);
+ path.AddArc(50, 20, 110, 80, 180, 180);
+ path.AddLine(160, 60, 220, 100);
+ gfx.DrawPath(pen, path);
+
+ EndBox(gfx);
+}
+```
+
+### Stroke a closed path
+
+```cs
+void DrawPathClosed(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawPath (closed)");
+
+ XPen pen = new XPen(XColors.Navy, Math.PI);
+ pen.DashStyle = XDashStyle.Dash;
+
+ XGraphicsPath path = new XGraphicsPath();
+ path.AddLine(10, 120, 50, 60);
+ path.AddArc(50, 20, 110, 80, 180, 180);
+ path.AddLine(160, 60, 220, 100);
+ path.CloseFigure();
+ gfx.DrawPath(pen, path);
+
+ EndBox(gfx);
+}
+```
+
+### Draw an alternating and a winding path
+
+```cs
+void DrawPathAlternateAndWinding(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawPath (alternate / winding)");
+
+ XPen pen = new XPen(XColors.Navy, 2.5);
+
+ // Alternate fill mode
+ XGraphicsPath path = new XGraphicsPath();
+ path.FillMode = XFillMode.Alternate;
+ path.AddLine(10, 130, 10, 40);
+ path.AddBeziers(
+ new XPoint[]
+ {
+ new XPoint(10, 40), new XPoint(30, 0),
+ new XPoint(40, 20), new XPoint(60, 40),
+ new XPoint(80, 60), new XPoint(100, 60),
+ new XPoint(120, 40)
+ }
+ );
+ path.AddLine(120, 40, 120, 130);
+ path.CloseFigure();
+ path.AddEllipse(40, 80, 50, 40);
+ gfx.DrawPath(pen, XBrushes.DarkOrange, path);
+
+ // Winding fill mode
+ path = new XGraphicsPath();
+ path.FillMode = XFillMode.Winding;
+ path.AddLine(130, 130, 130, 40);
+ path.AddBeziers(
+ new XPoint[]
+ {
+ new XPoint(130, 40), new XPoint(150, 0),
+ new XPoint(160, 20), new XPoint(180, 40),
+ new XPoint(200, 60), new XPoint(220, 60),
+ new XPoint(240, 40)
+ }
+ );
+ path.AddLine(240, 40, 240, 130);
+ path.CloseFigure();
+ path.AddEllipse(160, 80, 50, 40);
+ gfx.DrawPath(pen, XBrushes.DarkOrange, path);
+
+ EndBox(gfx);
+}
+```
+
+### Convert text to path
+
+```cs
+void DrawGlyphs(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "Draw Glyphs");
+
+ XGraphicsPath path = new XGraphicsPath();
+ path.AddString(
+ "Hello!", new XFontFamily("Times New Roman"),
+ XFontStyle.BoldItalic, 100,
+ new XRect(0, 0, 250, 140),
+ XStringFormats.Center
+ );
+
+ gfx.DrawPath(new XPen(XColors.Purple, 2.3), XBrushes.DarkOrchid, path);
+
+ EndBox(gfx);
+}
+```
+
+### Clip through path
+
+```cs
+void DrawClipPath(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "Clip through Path");
+
+ XGraphicsPath path = new XGraphicsPath();
+ path.AddString(
+ "Clip!", new XFontFamily("Verdana"),
+ XFontStyle.Bold, 90,
+ new XRect(0, 0, 250, 140),
+ XStringFormats.Center
+ );
+
+ gfx.IntersectClip(path);
+
+ // Draw a beam of dotted lines
+ XPen pen = XPens.DarkRed.Clone();
+ pen.DashStyle = XDashStyle.Dot;
+ for (double r = 0; r <= 90; r += 0.5)
+ {
+ gfx.DrawLine(
+ pen, 0, 0,
+ 250 * Math.Cos(r / 90 * Math.PI),
+ 250 * Math.Sin(r / 90 * Math.PI)
+ );
+ }
+
+ EndBox(gfx);
+}
+```
+
+## Text class
+
+Shows how to handle text.
+
+```cs
+public void DrawPage(PdfPage page)
+{
+ XGraphics gfx = XGraphics.FromPdfPage(page);
+ DrawTitle(page, gfx, "Text");
+
+ DrawText(gfx, 1);
+ DrawTextAlignment(gfx, 2);
+ MeasureText(gfx, 3);
+}
+```
+
+### Draw text in different styles
+
+```cs
+ void DrawText(XGraphics gfx, int number)
+ {
+ BeginBox(gfx, number, "Text Styles");
+
+ const string facename = "Times New Roman";
+
+ //XPdfFontOptions options = new XPdfFontOptions(PdfFontEncoding.Unicode, PdfFontEmbedding.Always);
+ XPdfFontOptions options = new XPdfFontOptions(PdfFontEncoding.WinAnsi, PdfFontEmbedding.Default);
+
+ XFont fontRegular = new XFont(facename, 20, XFontStyle.Regular, options);
+ XFont fontBold = new XFont(facename, 20, XFontStyle.Bold, options);
+ XFont fontItalic = new XFont(facename, 20, XFontStyle.Italic, options);
+ XFont fontBoldItalic = new XFont(facename, 20, XFontStyle.BoldItalic, options);
+
+ // The default alignment is baseline left (that differs from GDI+)
+ gfx.DrawString("Times (regular)", fontRegular, XBrushes.DarkSlateGray, 0, 30);
+ gfx.DrawString("Times (bold)", fontBold, XBrushes.DarkSlateGray, 0, 65);
+ gfx.DrawString("Times (italic)", fontItalic, XBrushes.DarkSlateGray, 0, 100);
+ gfx.DrawString("Times (bold italic)", fontBoldItalic, XBrushes.DarkSlateGray, 0, 135);
+
+ EndBox(gfx);
+ }
+```
+
+### Show how to align text in the layout rectangle
+
+```cs
+void DrawTextAlignment(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "Text Alignment");
+ XRect rect = new XRect(0, 0, 250, 140);
+
+ XFont font = new XFont("Verdana", 10);
+ XBrush brush = XBrushes.Purple;
+ XStringFormat format = new XStringFormat();
+
+ gfx.DrawRectangle(XPens.YellowGreen, rect);
+ gfx.DrawLine(XPens.YellowGreen, rect.Width / 2, 0, rect.Width / 2, rect.Height);
+ gfx.DrawLine(XPens.YellowGreen, 0, rect.Height / 2, rect.Width, rect.Height / 2);
+
+ gfx.DrawString("TopLeft", font, brush, rect, format);
+
+ format.Alignment = XStringAlignment.Center;
+ gfx.DrawString("TopCenter", font, brush, rect, format);
+
+ format.Alignment = XStringAlignment.Far;
+ gfx.DrawString("TopRight", font, brush, rect, format);
+
+ format.LineAlignment = XLineAlignment.Center;
+ format.Alignment = XStringAlignment.Near;
+ gfx.DrawString("CenterLeft", font, brush, rect, format);
+
+ format.Alignment = XStringAlignment.Center;
+ gfx.DrawString("Center", font, brush, rect, format);
+
+ format.Alignment = XStringAlignment.Far;
+ gfx.DrawString("CenterRight", font, brush, rect, format);
+
+ format.LineAlignment = XLineAlignment.Far;
+ format.Alignment = XStringAlignment.Near;
+ gfx.DrawString("BottomLeft", font, brush, rect, format);
+
+ format.Alignment = XStringAlignment.Center;
+ gfx.DrawString("BottomCenter", font, brush, rect, format);
+
+ format.Alignment = XStringAlignment.Far;
+ gfx.DrawString("BottomRight", font, brush, rect, format);
+
+ EndBox(gfx);
+}
+```
+
+### Show how to get text metric information
+
+```cs
+void MeasureText(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "Measure Text");
+
+ const XFontStyle style = XFontStyle.Regular;
+ XFont font = new XFont("Times New Roman", 95, style);
+
+ const string text = "Hallo";
+ const double x = 20, y = 100;
+ XSize size = gfx.MeasureString(text, font);
+
+ double lineSpace = font.GetHeight(gfx);
+ int cellSpace = font.FontFamily.GetLineSpacing(style);
+ int cellAscent = font.FontFamily.GetCellAscent(style);
+ int cellDescent = font.FontFamily.GetCellDescent(style);
+ int cellLeading = cellSpace - cellAscent - cellDescent;
+
+ // Get effective ascent
+ double ascent = lineSpace * cellAscent / cellSpace;
+ gfx.DrawRectangle(XBrushes.Bisque, x, y - ascent, size.Width, ascent);
+
+ // Get effective descent
+ double descent = lineSpace * cellDescent / cellSpace;
+ gfx.DrawRectangle(XBrushes.LightGreen, x, y, size.Width, descent);
+
+ // Get effective leading
+ double leading = lineSpace * cellLeading / cellSpace;
+ gfx.DrawRectangle(XBrushes.Yellow, x, y + descent, size.Width, leading);
+
+ // Draw text half transparent
+ XColor color = XColors.DarkSlateBlue;
+ color.A = 0.6;
+ gfx.DrawString(text, font, new XSolidBrush(color), x, y);
+
+ EndBox(gfx);
+}
+```
+
+
+## Images
+
+Shows how to draw images.
+
+```cs
+public void DrawPage(PdfPage page)
+{
+ XGraphics gfx = XGraphics.FromPdfPage(page);
+ DrawTitle(page, gfx, "Images");
+
+ DrawImage(gfx, 1);
+ DrawImageScaled(gfx, 2);
+ DrawImageRotated(gfx, 3);
+ DrawImageSheared(gfx, 4);
+ DrawGif(gfx, 5);
+ DrawPng(gfx, 6);
+ DrawTiff(gfx, 7);
+ DrawFormXObject(gfx, 8);
+}
+```
+
+### Draw an image in original size
+
+```cs
+void DrawImage(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawImage (original)");
+
+ XImage image = XImage.FromFile(jpegSamplePath);
+
+ // Left position in point
+ double x = (250 - image.PixelWidth * 72 / image.HorizontalResolution) / 2;
+ gfx.DrawImage(image, x, 0);
+
+ EndBox(gfx);
+}
+```
+
+### Draw an image scaled
+
+```cs
+void DrawImageScaled(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawImage (scaled)");
+
+ XImage image = XImage.FromFile(jpegSamplePath);
+ gfx.DrawImage(image, 0, 0, 250, 140);
+
+ EndBox(gfx);
+}
+```
+
+### Draw an image transformed
+
+```cs
+void DrawImageRotated(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawImage (rotated)");
+
+ XImage image = XImage.FromFile(jpegSamplePath);
+
+ const double dx = 250, dy = 140;
+
+ gfx.TranslateTransform(dx / 2, dy / 2);
+ gfx.ScaleTransform(0.7);
+ gfx.RotateTransform(-25);
+ gfx.TranslateTransform(-dx / 2, -dy / 2);
+
+ //XMatrix matrix = new XMatrix(); //XMatrix.Identity;
+
+ double width = image.PixelWidth * 72 / image.HorizontalResolution;
+ double height = image.PixelHeight * 72 / image.HorizontalResolution;
+
+ gfx.DrawImage(image, (dx - width) / 2, 0, width, height);
+
+ EndBox(gfx);
+}
+```
+
+### Draw an image transformed
+
+```cs
+void DrawImageSheared(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawImage (sheared)");
+
+ XImage image = XImage.FromFile(jpegSamplePath);
+
+ const double dx = 250, dy = 140;
+
+ gfx.TranslateTransform(dx / 2, dy / 2);
+ gfx.ScaleTransform(-0.7, 0.7);
+ gfx.ShearTransform(-0.4, -0.3);
+ gfx.TranslateTransform(-dx / 2, -dy / 2);
+
+ double width = image.PixelWidth * 72 / image.HorizontalResolution;
+ double height = image.PixelHeight * 72 / image.HorizontalResolution;
+
+ gfx.DrawImage(image, (dx - width) / 2, 0, width, height);
+
+ EndBox(gfx);
+}
+```
+
+### Draw a GIF image with transparency
+
+```cs
+void DrawGif(XGraphics gfx, int number)
+{
+ this.backColor = XColors.LightGoldenrodYellow;
+ this.borderPen = new XPen(XColor.FromArgb(202, 121, 74), this.borderWidth);
+ BeginBox(gfx, number, "DrawImage (GIF)");
+
+ XImage image = XImage.FromFile(gifSamplePath);
+
+ const double dx = 250, dy = 140;
+
+ double width = image.PixelWidth * 72 / image.HorizontalResolution;
+ double height = image.PixelHeight * 72 / image.HorizontalResolution;
+
+ gfx.DrawImage(image, (dx - width) / 2, (dy - height) / 2, width, height);
+
+ EndBox(gfx);
+}
+```
+
+### Draw a PNG image with transparency
+
+```cs
+void DrawPng(XGraphics gfx, int number)
+{
+ BeginBox(gfx, number, "DrawImage (PNG)");
+
+ XImage image = XImage.FromFile(pngSamplePath);
+
+ const double dx = 250, dy = 140;
+
+ double width = image.PixelWidth * 72 / image.HorizontalResolution;
+ double height = image.PixelHeight * 72 / image.HorizontalResolution;
+
+ gfx.DrawImage(image, (dx - width) / 2, (dy - height) / 2, width, height);
+
+ EndBox(gfx);
+}
+```
+
+### Draw a TIFF image with transparency
+
+```cs
+void DrawTiff(XGraphics gfx, int number)
+{
+ XColor oldBackColor = this.backColor;
+ this.backColor = XColors.LightGoldenrodYellow;
+ BeginBox(gfx, number, "DrawImage (TIFF)");
+
+ XImage image = XImage.FromFile(tiffSamplePath);
+
+ const double dx = 250, dy = 140;
+
+ double width = image.PixelWidth * 72 / image.HorizontalResolution;
+ double height = image.PixelHeight * 72 / image.HorizontalResolution;
+
+ gfx.DrawImage(image, (dx - width) / 2, (dy - height) / 2, width, height);
+
+ EndBox(gfx);
+ this.backColor = oldBackColor;
+}
+```
+
+### Draw a form XObject (a page from an external PDF file)
+
+```cs
+void DrawFormXObject(XGraphics gfx, int number)
+{
+ //this.backColor = XColors.LightSalmon;
+ BeginBox(gfx, number, "DrawImage (Form XObject)");
+
+ XImage image = XImage.FromFile(pdfSamplePath);
+
+ const double dx = 250, dy = 140;
+
+ gfx.TranslateTransform(dx / 2, dy / 2);
+ gfx.ScaleTransform(0.35);
+ gfx.TranslateTransform(-dx / 2, -dy / 2);
+
+ double width = image.PixelWidth * 72 / image.HorizontalResolution;
+ double height = image.PixelHeight * 72 / image.HorizontalResolution;
+
+ gfx.DrawImage(image, (dx - width) / 2, (dy - height) / 2, width, height);
+
+ EndBox(gfx);
+}
+```
+
+## Helper Functions
+
+Shows how to draw the page title and the rounded boxes.
+
+### Draw the page title and footer
+
+```cs
+public void DrawTitle(PdfPage page, XGraphics gfx, string title)
+{
+ XRect rect = new XRect(new XPoint(), gfx.PageSize);
+ rect.Inflate(-10, -15);
+ XFont font = new XFont("Verdana", 14, XFontStyle.Bold);
+ gfx.DrawString(title, font, XBrushes.MidnightBlue, rect, XStringFormats.TopCenter);
+
+ rect.Offset(0, 5);
+ font = new XFont("Verdana", 8, XFontStyle.Italic);
+ XStringFormat format = new XStringFormat();
+ format.Alignment = XStringAlignment.Near;
+ format.LineAlignment = XLineAlignment.Far;
+ gfx.DrawString("Created with " + PdfSharp.ProductVersionInfo.Producer, font, XBrushes.DarkOrchid, rect, format);
+
+ font = new XFont("Verdana", 8);
+ format.Alignment = XStringAlignment.Center;
+ gfx.DrawString(Program.s_document.PageCount.ToString(), font, XBrushes.DarkOrchid, rect, format);
+
+ Program.s_document.Outlines.Add(title, page, true);
+}
+```
+
+### Draw the box around the samples
+
+```cs
+public void BeginBox(XGraphics gfx, int number, string title)
+{
+ const int dEllipse = 15;
+ XRect rect = new XRect(0, 20, 300, 200);
+ if (number % 2 == 0)
+ rect.X = 300 - 5;
+ rect.Y = 40 + ((number - 1) / 2) * (200 - 5);
+ rect.Inflate(-10, -10);
+ XRect rect2 = rect;
+ rect2.Offset(this.borderWidth, this.borderWidth);
+ gfx.DrawRoundedRectangle(
+ new XSolidBrush(this.shadowColor),
+ rect2,
+ new XSize(dEllipse + 8, dEllipse + 8)
+ );
+ XLinearGradientBrush brush = new XLinearGradientBrush(
+ rect, this.backColor, this.backColor2, XLinearGradientMode.Vertical);
+ gfx.DrawRoundedRectangle(this.borderPen, brush, rect, new XSize(dEllipse, dEllipse));
+ rect.Inflate(-5, -5);
+
+ XFont font = new XFont("Verdana", 12, XFontStyle.Regular);
+ gfx.DrawString(title, font, XBrushes.Navy, rect, XStringFormats.TopCenter);
+
+ rect.Inflate(-10, -5);
+ rect.Y += 20;
+ rect.Height -= 20;
+
+ this.state = gfx.Save();
+ gfx.TranslateTransform(rect.X, rect.Y);
+}
+
+public void EndBox(XGraphics gfx)
+{
+ gfx.Restore(this.state);
+}
+```
diff --git a/docs/PdfSharpCore/samples/HelloWorld.md b/docs/PdfSharpCore/samples/HelloWorld.md
new file mode 100644
index 00000000..25edfa59
--- /dev/null
+++ b/docs/PdfSharpCore/samples/HelloWorld.md
@@ -0,0 +1,51 @@
+# Hello World
+
+Is the obligatory "Hello World" program.
+
+
+## Code
+
+```cs
+using System;
+using System.Diagnostics;
+using System.IO;
+using PdfSharp;
+using PdfSharp.Drawing;
+using PdfSharp.Pdf;
+using PdfSharp.Pdf.IO;
+
+namespace HelloWorld
+{
+ ///
+ /// This sample is the obligatory Hello World program.
+ ///
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ // Create a new PDF document
+ PdfDocument document = new PdfDocument();
+ document.Info.Title = "Created with PDFsharpCore";
+
+ // Create an empty page
+ PdfPage page = document.AddPage();
+
+ // Get an XGraphics object for drawing
+ XGraphics gfx = XGraphics.FromPdfPage(page);
+
+ // Create a font
+ XFont font = new XFont("Verdana", 20, XFontStyle.BoldItalic);
+
+ // Draw the text
+ gfx.DrawString(
+ "Hello, World!", font, XBrushes.Black,
+ new XRect(0, 0, page.Width, page.Height),
+ XStringFormats.Center);
+
+ // Save the document...
+ const string filename = "HelloWorld.pdf";
+ document.Save(filename);
+ }
+ }
+}
+```
diff --git a/docs/PdfSharpCore/samples/MultiplePages.md b/docs/PdfSharpCore/samples/MultiplePages.md
new file mode 100644
index 00000000..6da16912
--- /dev/null
+++ b/docs/PdfSharpCore/samples/MultiplePages.md
@@ -0,0 +1,100 @@
+# Multiple Pages
+
+This sample shows one way to create a PDF document with multiple pages.
+
+When you program reaches the end of a page, you just have to create a new page by calling the `AddPage()` method of the PdfDocument class. Then you create a new XGraphics object for the new page and use it to draw on the second page, beginning at the top.
+
+Experience shows that users sometimes have difficulties to modify there code with support for a second page. They call `AddPage()`, but do not store the return value. They do not create a new XGraphics object and continue to draw on the first page. Or they try to create a new XGraphics object, but pass the first page as a parameter and receive an error message.
+
+If you know right from the start that you will or may need more than one page, then take this into account right from the start and your program will be readable and easy to maintain.
+
+Note: Consider using MigraDocCore instead of PDFsharpCore for large documents. You can use many attributes to format text and you get the line breaks and page breaks for free.
+
+
+# Code
+
+The class LayoutHelper takes care of the line position and creates pages as needed:
+
+```cs
+public class LayoutHelper
+{
+ private readonly PdfDocument _document;
+ private readonly XUnit _topPosition;
+ private readonly XUnit _bottomMargin;
+ private XUnit _currentPosition;
+
+ public LayoutHelper(PdfDocument document, XUnit topPosition, XUnit bottomMargin)
+ {
+ _document = document;
+ _topPosition = topPosition;
+ _bottomMargin = bottomMargin;
+ // Set a value outside the page - a new page will be created on the first request.
+ _currentPosition = bottomMargin + 10000;
+ }
+
+ public XUnit GetLinePosition(XUnit requestedHeight)
+ {
+ return GetLinePosition(requestedHeight, -1f);
+ }
+
+ public XUnit GetLinePosition(XUnit requestedHeight, XUnit requiredHeight)
+ {
+ XUnit required = requiredHeight == -1f ? requestedHeight : requiredHeight;
+ if (_currentPosition + required > _bottomMargin)
+ CreatePage();
+ XUnit result = _currentPosition;
+ _currentPosition += requestedHeight;
+ return result;
+ }
+
+ public XGraphics Gfx { get; private set; }
+ public PdfPage Page { get; private set; }
+
+ void CreatePage()
+ {
+ Page = _document.AddPage();
+ Page.Size = PageSize.A4;
+ Gfx = XGraphics.FromPdfPage(Page);
+ _currentPosition = _topPosition;
+ }
+}
+```
+
+And sample code that shows the LayoutHelper class at work. The sample uses short texts that will always fit into a single line. Adding line breaks to texts that do not fit into a single line is beyond the scope of this sample.
+
+I wrote it before: Consider using MigraDocCore instead of PDFsharpCore for large documents. You can use many attributes to format text and you get the line breaks and page breaks for free.
+
+```cs
+PdfDocument document = new PdfDocument();
+
+// Sample uses DIN A4, page height is 29.7 cm. We use margins of 2.5 cm.
+LayoutHelper helper = new LayoutHelper(document, XUnit.FromCentimeter(2.5), XUnit.FromCentimeter(29.7 - 2.5));
+XUnit left = XUnit.FromCentimeter(2.5);
+
+// Random generator with seed value, so created document will always be the same.
+Random rand = new Random(42);
+
+const int headerFontSize = 20;
+const int normalFontSize = 10;
+
+XFont fontHeader = new XFont("Verdana", headerFontSize, XFontStyle.BoldItalic);
+XFont fontNormal = new XFont("Verdana", normalFontSize, XFontStyle.Regular);
+
+const int totalLines = 666;
+bool washeader = false;
+for (int line = 0; line < totalLines; ++line)
+{
+ bool isHeader = line == 0 || !washeader && line < totalLines - 1 && rand.Next(15) == 0;
+ washeader = isHeader;
+ // We do not want a single header at the bottom of the page,
+ // so if we have a header we require space for header and a normal text line.
+ XUnit top = helper.GetLinePosition(isHeader ? headerFontSize + 5: normalFontSize + 2, isHeader ? headerFontSize + 5 + normalFontSize : normalFontSize);
+
+ helper.Gfx.DrawString(isHeader ? "Sed massa libero, semper a nisi nec" : "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
+ isHeader ? fontHeader : fontNormal, XBrushes.Black, left, top, XStringFormats.TopLeft);
+}
+
+// Save the document...
+const string filename = "MultiplePages.pdf";
+document.Save(filename);
+```
diff --git a/docs/PdfSharpCore/samples/PageSizes.md b/docs/PdfSharpCore/samples/PageSizes.md
new file mode 100644
index 00000000..69b402db
--- /dev/null
+++ b/docs/PdfSharpCore/samples/PageSizes.md
@@ -0,0 +1,46 @@
+# Page Sizes
+
+This sample shows a document with different page sizes.
+
+Note: You can set the size of a page to any size using the `Width` and `Height` properties. This sample just shows the predefined sizes.
+
+
+## Code
+
+This is the whole source code needed to create the PDF file:
+
+```cs
+// Create a new PDF document
+PdfDocument document = new PdfDocument();
+
+// Create a font
+XFont font = new XFont("Times", 25, XFontStyle.Bold);
+
+PageSize[] pageSizes = (PageSize[])Enum.GetValues(typeof(PageSize));
+foreach (PageSize pageSize in pageSizes)
+{
+ if (pageSize == PageSize.Undefined)
+ continue;
+
+ // One page in Portrait...
+ PdfPage page = document.AddPage();
+ page.Size = pageSize;
+ XGraphics gfx = XGraphics.FromPdfPage(page);
+ gfx.DrawString(pageSize.ToString(), font, XBrushes.DarkRed,
+ new XRect(0, 0, page.Width, page.Height),
+ XStringFormats.Center);
+
+ // ... and one in Landscape orientation.
+ page = document.AddPage();
+ page.Size = pageSize;
+ page.Orientation = PageOrientation.Landscape;
+ gfx = XGraphics.FromPdfPage(page);
+ gfx.DrawString(pageSize + " (landscape)", font,
+ XBrushes.DarkRed, new XRect(0, 0, page.Width, page.Height),
+ XStringFormats.Center);
+}
+
+// Save the document...
+const string filename = "PageSizes_tempfile.pdf";
+document.Save(filename);
+```
diff --git a/docs/PdfSharpCore/samples/Preview.md b/docs/PdfSharpCore/samples/Preview.md
new file mode 100644
index 00000000..2e2b85b8
--- /dev/null
+++ b/docs/PdfSharpCore/samples/Preview.md
@@ -0,0 +1,91 @@
+# Preview
+
+This sample shows how to render graphics in both a preview and a PDF document.
+
+## Code
+
+This is the source code of the Render method that is called for screen, PDF, and printer output:
+
+```cs
+XRect rect;
+XPen pen;
+double x = 50, y = 100;
+XFont fontH1 = new XFont("Times", 18, XFontStyle.Bold);
+XFont font = new XFont("Times", 12);
+XFont fontItalic = new XFont("Times", 12, XFontStyle.BoldItalic);
+double ls = font.GetHeight(gfx);
+
+// Draw some text
+gfx.DrawString("Create PDF on the fly with PDFsharpCore",
+fontH1, XBrushes.Black, x, x);
+gfx.DrawString("With PDFsharpCore you can use the same code to draw graphic, " +
+"text and images on different targets.", font, XBrushes.Black, x, y);
+y += ls;
+gfx.DrawString("The object used for drawing is the XGraphics object.",
+font, XBrushes.Black, x, y);
+y += 2 * ls;
+
+// Draw an arc
+pen = new XPen(XColors.Red, 4);
+pen.DashStyle = XDashStyle.Dash;
+gfx.DrawArc(pen, x + 20, y, 100, 60, 150, 120);
+
+// Draw a star
+XGraphicsState gs = gfx.Save();
+gfx.TranslateTransform(x + 140, y + 30);
+for (int idx = 0; idx < 360; idx += 10)
+{
+ gfx.RotateTransform(10);
+ gfx.DrawLine(XPens.DarkGreen, 0, 0, 30, 0);
+}
+gfx.Restore(gs);
+
+// Draw a rounded rectangle
+rect = new XRect(x + 230, y, 100, 60);
+pen = new XPen(XColors.DarkBlue, 2.5);
+XColor color1 = XColor.FromKnownColor(KnownColor.DarkBlue);
+XColor color2 = XColors.Red;
+XLinearGradientBrush lbrush = new XLinearGradientBrush(rect, color1, color2,
+XLinearGradientMode.Vertical);
+gfx.DrawRoundedRectangle(pen, lbrush, rect, new XSize(10, 10));
+
+// Draw a pie
+pen = new XPen(XColors.DarkOrange, 1.5);
+pen.DashStyle = XDashStyle.Dot;
+gfx.DrawPie(pen, XBrushes.Blue, x + 360, y, 100, 60, -130, 135);
+
+// Draw some more text
+y += 60 + 2 * ls;
+gfx.DrawString("With XGraphics you can draw on a PDF page as well as " +
+"on any System.Drawing.Graphics object.", font, XBrushes.Black, x, y);
+y += ls * 1.1;
+gfx.DrawString("Use the same code to", font, XBrushes.Black, x, y);
+x += 10;
+y += ls * 1.1;
+gfx.DrawString("• draw on a newly created PDF page", font, XBrushes.Black, x, y);
+y += ls;
+gfx.DrawString("• draw above or beneath of the content of an existing PDF page",
+font, XBrushes.Black, x, y);
+y += ls;
+gfx.DrawString("• draw in a window", font, XBrushes.Black, x, y);
+y += ls;
+gfx.DrawString("• draw on a printer", font, XBrushes.Black, x, y);
+y += ls;
+gfx.DrawString("• draw in a bitmap image", font, XBrushes.Black, x, y);
+x -= 10;
+y += ls * 1.1;
+gfx.DrawString("You can also import an existing PDF page and use it like " +
+"an image, e.g. draw it on another PDF page.", font, XBrushes.Black, x, y);
+y += ls * 1.1 * 2;
+gfx.DrawString("Imported PDF pages are neither drawn nor printed; create a " +
+"PDF file to see or print them!", fontItalic, XBrushes.Firebrick, x, y);
+y += ls * 1.1;
+gfx.DrawString("Below this text is a PDF form that will be visible when " +
+"viewed or printed with a PDF viewer.", fontItalic, XBrushes.Firebrick, x, y);
+y += ls * 1.1;
+XGraphicsState state = gfx.Save();
+XRect rcImage = new XRect(100, y, 100, 100 * Math.Sqrt(2));
+gfx.DrawRectangle(XBrushes.Snow, rcImage);
+gfx.DrawImage(XPdfForm.FromFile("../../../../../PDFs/SomeLayout.pdf"), rcImage);
+gfx.Restore(state);
+```
diff --git a/docs/PdfSharpCore/samples/ProtectDocument.md b/docs/PdfSharpCore/samples/ProtectDocument.md
new file mode 100644
index 00000000..6608486c
--- /dev/null
+++ b/docs/PdfSharpCore/samples/ProtectDocument.md
@@ -0,0 +1,42 @@
+# Protect Document
+
+This sample shows how to protect a document with a password.
+
+
+## Code
+
+This is the whole source code needed to create the PDF file:
+
+```cs
+// Get a fresh copy of the sample PDF file
+const string filenameSource = "HelloWorld.pdf";
+const string filenameDest = "HelloWorld_tempfile.pdf";
+File.Copy(Path.Combine("../../../../../PDFs/", filenameSource),
+Path.Combine(Directory.GetCurrentDirectory(), filenameDest), true);
+
+// Open an existing document. Providing an unrequired password is ignored.
+PdfDocument document = PdfReader.Open(filenameDest, "some text");
+
+PdfSecuritySettings securitySettings = document.SecuritySettings;
+
+// Setting one of the passwords automatically sets the security level to
+// PdfDocumentSecurityLevel.Encrypted128Bit.
+securitySettings.UserPassword = "user";
+securitySettings.OwnerPassword = "owner";
+
+// Don't use 40 bit encryption unless needed for compatibility
+//securitySettings.DocumentSecurityLevel = PdfDocumentSecurityLevel.Encrypted40Bit;
+
+// Restrict some rights.
+securitySettings.PermitAccessibilityExtractContent = false;
+securitySettings.PermitAnnotations = false;
+securitySettings.PermitAssembleDocument = false;
+securitySettings.PermitExtractContent = false;
+securitySettings.PermitFormsFill = true;
+securitySettings.PermitFullQualityPrint = false;
+securitySettings.PermitModifyDocument = true;
+securitySettings.PermitPrint = false;
+
+// Save the document...
+document.Save(filenameDest);
+```
diff --git a/docs/PdfSharpCore/samples/SplitDocument.md b/docs/PdfSharpCore/samples/SplitDocument.md
new file mode 100644
index 00000000..25a91329
--- /dev/null
+++ b/docs/PdfSharpCore/samples/SplitDocument.md
@@ -0,0 +1,33 @@
+# Split Document
+
+This sample shows how to convert a PDF document with n pages into n documents with one page each.
+
+
+## Code
+
+This is the whole source code needed to create the PDF file:
+
+````cs
+// Get a fresh copy of the sample PDF file
+const string filename = "Portable Document Format.pdf";
+File.Copy(Path.Combine("../../../../../PDFs/", filename),
+Path.Combine(Directory.GetCurrentDirectory(), filename), true);
+
+// Open the file
+PdfDocument inputDocument = PdfReader.Open(filename, PdfDocumentOpenMode.Import);
+
+string name = Path.GetFileNameWithoutExtension(filename);
+for (int idx = 0; idx < inputDocument.PageCount; idx++)
+{
+ // Create new document
+ PdfDocument outputDocument = new PdfDocument();
+ outputDocument.Version = inputDocument.Version;
+ outputDocument.Info.Title =
+ String.Format("Page {0} of {1}", idx + 1, inputDocument.Info.Title);
+ outputDocument.Info.Creator = inputDocument.Info.Creator;
+
+ // Add the page and save it
+ outputDocument.AddPage(inputDocument.Pages[idx]);
+ outputDocument.Save(String.Format("{0} - Page {1}_tempfile.pdf", name, idx + 1));
+}
+```
diff --git a/docs/PdfSharpCore/samples/TextLayout.md b/docs/PdfSharpCore/samples/TextLayout.md
new file mode 100644
index 00000000..aa347fec
--- /dev/null
+++ b/docs/PdfSharpCore/samples/TextLayout.md
@@ -0,0 +1,52 @@
+# Text Layout
+
+This sample shows how to layout text with the TextFormatter class.
+
+TextFormatter was provided because it was one of the "most wanted" features. But it is better and easier to use MigraDocCore to format paragraphs...
+
+
+## Code
+
+This is the whole source code needed to create the PDF file:
+
+```cs
+const string text =.
+ "Facin exeraessisit la consenim iureet dignibh eu facilluptat vercil dunt autpat. " +
+ "Ecte magna faccum dolor sequisc iliquat, quat, quipiss equipit accummy niate magna " +
+ "facil iure eraesequis am velit, quat atis dolore dolent luptat nulla adio odipissectet " +
+ "lan venis do essequatio conulla facillandrem zzriusci bla ad minim inis nim velit eugait " +
+ "aut aut lor at ilit ut nulla ate te eugait alit augiamet ad magnim iurem il eu feuissi.\n" +
+ "Guer sequis duis eu feugait luptat lum adiamet, si tate dolore mod eu facidunt adignisl in " +
+ "henim dolorem nulla faccum vel inis dolutpatum iusto od min ex euis adio exer sed del " +
+ "dolor ing enit veniamcon vullutat praestrud molenis ciduisim doloborem ipit nulla consequisi.\n" +
+ "Nos adit pratetu eriurem delestie del ut lumsandreet nis exerilisit wis nos alit venit praestrud " +
+ "dolor sum volore facidui blaor erillaortis ad ea augue corem dunt nis iustinciduis euisi.\n" +
+ "Ut ulputate volore min ut nulpute dolobor sequism olorperilit autatie modit wisl illuptat dolore " +
+ "min ut in ute doloboreet ip ex et am dunt at.";
+
+PdfDocument document = new PdfDocument();
+
+PdfPage page = document.AddPage();
+XGraphics gfx = XGraphics.FromPdfPage(page);
+XFont font = new XFont("Times New Roman", 10, XFontStyle.Bold);
+XTextFormatter tf = new XTextFormatter(gfx);
+
+XRect rect = new XRect(40, 100, 250, 220);
+gfx.DrawRectangle(XBrushes.SeaShell, rect);
+//tf.Alignment = ParagraphAlignment.Left;
+tf.DrawString(text, font, XBrushes.Black, rect, XStringFormats.TopLeft);
+
+rect = new XRect(310, 100, 250, 220);
+gfx.DrawRectangle(XBrushes.SeaShell, rect);
+tf.Alignment = XParagraphAlignment.Right;
+tf.DrawString(text, font, XBrushes.Black, rect, XStringFormats.TopLeft);
+
+rect = new XRect(40, 400, 250, 220);
+gfx.DrawRectangle(XBrushes.SeaShell, rect);
+tf.Alignment = XParagraphAlignment.Center;
+tf.DrawString(text, font, XBrushes.Black, rect, XStringFormats.TopLeft);
+
+rect = new XRect(310, 400, 250, 220);
+gfx.DrawRectangle(XBrushes.SeaShell, rect);
+tf.Alignment = XParagraphAlignment.Justify;
+```
diff --git a/docs/PdfSharpCore/samples/TwoPagesOnOne.md b/docs/PdfSharpCore/samples/TwoPagesOnOne.md
new file mode 100644
index 00000000..eb48ace6
--- /dev/null
+++ b/docs/PdfSharpCore/samples/TwoPagesOnOne.md
@@ -0,0 +1,75 @@
+# Two Pages on One
+
+This sample shows how to place two pages of an existing document on one landscape orientated page of a new document.
+
+## Code
+
+This is the whole source code needed to create the PDF file:
+
+```cs
+// Get a fresh copy of the sample PDF file
+string filename = "Portable Document Format.pdf";
+File.Copy(Path.Combine("../../../../../PDFs/", filename),
+Path.Combine(Directory.GetCurrentDirectory(), filename), true);
+
+// Create the output document
+PdfDocument outputDocument = new PdfDocument();
+
+// Show single pages
+// (Note: one page contains two pages from the source document)
+outputDocument.PageLayout = PdfPageLayout.SinglePage;
+
+XFont font = new XFont("Verdana", 8, XFontStyle.Bold);
+XStringFormat format = new XStringFormat();
+format.Alignment = XStringAlignment.Center;
+format.LineAlignment = XLineAlignment.Far;
+XGraphics gfx;
+XRect box;
+
+// Open the external document as XPdfForm object
+XPdfForm form = XPdfForm.FromFile(filename);
+
+for (int idx = 0; idx < form.PageCount; idx += 2)
+{
+ // Add a new page to the output document
+ PdfPage page = outputDocument.AddPage();
+ page.Orientation = PageOrientation.Landscape;
+ double width = page.Width;
+ double height = page.Height;
+
+ int rotate = page.Elements.GetInteger("/Rotate");
+
+ gfx = XGraphics.FromPdfPage(page);
+
+ // Set page number (which is one-based)
+ form.PageNumber = idx + 1;
+
+ box = new XRect(0, 0, width / 2, height);
+ // Draw the page identified by the page number like an image
+ gfx.DrawImage(form, box);
+
+ // Write document file name and page number on each page
+ box.Inflate(0, -10);
+ gfx.DrawString(String.Format("- {1} -", filename, idx + 1),
+ font, XBrushes.Red, box, format);
+
+ if (idx + 1 < form.PageCount)
+ {
+ // Set page number (which is one-based)
+ form.PageNumber = idx + 2;
+
+ box = new XRect(width / 2, 0, width / 2, height);
+ // Draw the page identified by the page number like an image
+ gfx.DrawImage(form, box);
+
+ // Write document file name and page number on each page
+ box.Inflate(0, -10);
+ gfx.DrawString(String.Format("- {1} -", filename, idx + 2),
+ font, XBrushes.Red, box, format);
+ }
+}
+
+// Save the document...
+filename = "TwoPagesOnOne_tempfile.pdf";
+outputDocument.Save(filename);
+```
diff --git a/docs/PdfSharpCore/samples/Unicode.md b/docs/PdfSharpCore/samples/Unicode.md
new file mode 100644
index 00000000..85dc6799
--- /dev/null
+++ b/docs/PdfSharpCore/samples/Unicode.md
@@ -0,0 +1,175 @@
+# Unicode
+
+This sample shows how to use Unicode text in PDFsharpCore.
+
+Languages based on Latin, Greek, or Cyrillic letters should all work with PDFsharpCore.
+
+You'll find code snippets for the following classes:
+* XPdfFontOptions
+* XTextFormatter
+
+
+## Code
+
+Drawing the text is quite easy (just like the Text Layout sample):
+
+```cs
+// Create new document
+PdfDocument document = new PdfDocument();
+
+// Set font encoding to unicode
+XPdfFontOptions options = new XPdfFontOptions(PdfFontEncoding.Unicode, PdfFontEmbedding.Always);
+
+XFont font = new XFont("Times New Roman", 12, XFontStyle.Regular, options);
+
+// Draw text in different languages
+for (int idx = 0; idx < texts.Length; idx++)
+{
+ PdfPage page = document.AddPage();
+ XGraphics gfx = XGraphics.FromPdfPage(page);
+ XTextFormatter tf = new XTextFormatter(gfx);
+ tf.Alignment = XParagraphAlignment.Left;
+
+ tf.DrawString(texts[idx], font, XBrushes.Black,
+ new XRect(100, 100, page.Width - 200, 600), XStringFormats.TopLeft);
+}
+
+const string filename = "Unicode_tempfile.pdf";
+// Save the document...
+document.Save(filename);
+```
+
+Note: the XPdfFontOptions enable both Unicode support and font embedding.
+
+Here's the string array that contains the translations:
+
+```cs
+static readonly string[] texts = new string[]
+{
+ // International version of the text in English.
+ "English\n" +
+ "PDFsharpCore is a .NET library for creating and processing PDF documents 'on the fly'. " +
+ "The library is completely written in C# and based exclusively on safe, managed code. " +
+ "PDFsharpCore offers two powerful abstraction levels to create and process PDF documents.\n" +
+ "For drawing text, graphics, and images there is a set of classes which are modeled similar to the classes " +
+ "of the name space System.Drawing of the .NET framework. With these classes it is not only possible to create " +
+ "the content of PDF pages in an easy way, but they can also be used to draw in a window or on a printer.\n" +
+ "Additionally PDFsharpCore completely models the structure elements PDF is based on. With them existing PDF documents " +
+ "can be modified, merged, or split with ease.\n" +
+ "The source code of PDFsharpCore is Open Source under the MIT license (http://en.wikipedia.org/wiki/MIT_License). " +
+ "Therefore it is possible to use PDFsharpCore without limitations in non open source or commercial projects/products.",
+
+ // German version.
+ "German (deutsch)\n" +
+ "PDFsharpCore ist eine .NET-Bibliothek zum Erzeugen und Verarbeiten von PDF-Dokumenten 'On the Fly'. " +
+ "Die Bibliothek ist vollständig in C# geschrieben und basiert ausschließlich auf sicherem, verwaltetem Code. " +
+ "PDFsharpCore bietet zwei leistungsstarke Abstraktionsebenen zur Erstellung und Verarbeitung von PDF-Dokumenten.\n" +
+ "Zum Zeichnen von Text, Grafik und Bildern gibt es einen Satz von Klassen, die sehr stark an die Klassen " +
+ "des Namensraums System.Drawing des .NET Frameworks angelehnt sind. Mit diesen Klassen ist es nicht " +
+ "nur auf einfache Weise möglich, den Inhalt von PDF-Seiten zu gestalten, sondern sie können auch zum " +
+ "Zeichnen in einem Fenster oder auf einem Drucker verwendet werden.\n" +
+ "Zusätzlich modelliert PDFsharpCore vollständig die Stukturelemente, auf denen PDF basiert. Dadurch können existierende " +
+ "PDF-Dokumente mit Leichtigkeit zerlegt, ergänzt oder umgebaut werden.\n" +
+ "Der Quellcode von PDFsharpCore ist Open-Source unter der MIT-Lizenz (http://de.wikipedia.org/wiki/MIT-Lizenz). " +
+ "Damit kann PDFsharpCore auch uneingeschränkt in Nicht-Open-Source- oder kommerziellen Projekten/Produkten eingesetzt werden.",
+
+ // Greek version.
+ // The text was translated by Babel Fish. We here in Germany have no idea what it means.
+ "Greek (Translated with Babel Fish)\n" +
+ "Το PDFsharpCore είναι βιβλιοθήκη δικτύου α. για τη δημιουργία και την επεξεργασία των εγγράφων PDF 'σχετικά με τη μύγα'. " +
+ "Η βιβλιοθήκη γράφεται εντελώς γ # και βασίζεται αποκλειστικά εκτός από, διοικούμενος κώδικας. " +
+ "Το PDFsharpCore προσφέρει δύο ισχυρά επίπεδα αφαίρεσης για να δημιουργήσει και να επεξεργαστεί τα έγγραφα PDF. " +
+ "Για το κείμενο, τη γραφική παράσταση, και τις εικόνες σχεδίων υπάρχει ένα σύνολο κατηγοριών που διαμορφώνονται " +
+ "παρόμοιος με τις κατηγορίες του διαστημικού σχεδίου συστημάτων ονόματος του. πλαισίου δικτύου. " +
+ "Με αυτές τις κατηγορίες που είναι όχι μόνο δυνατό να δημιουργηθεί το περιεχόμενο των σελίδων PDF με έναν εύκολο " +
+ "τρόπο, αλλά αυτοί μπορεί επίσης να χρησιμοποιηθεί για να επισύρει την προσοχή σε ένα παράθυρο ή σε έναν εκτυπωτή. " +
+ "Επιπλέον PDFsharpCore διαμορφώνει εντελώς τα στοιχεία PDF δομών είναι βασισμένο. Με τους τα υπάρχοντα έγγραφα PDF " +
+ "μπορούν να τροποποιηθούν, συγχωνευμένος, ή να χωρίσουν με την ευκολία. Ο κώδικας πηγής PDFsharpCore είναι ανοικτή πηγή " +
+ "με άδεια MIT (http://en.wikipedia.org/wiki/MIT_License). Επομένως είναι δυνατό να χρησιμοποιηθεί PDFsharpCore χωρίς " +
+ "προβλήματα στη μη ανοικτή πηγή ή τα εμπορικά προγράμματα/τα προϊόντα.",
+
+ // Russian version (by courtesy of Alexey Kuznetsov).
+ "Russian\n" +
+ "PDFsharpCore это .NET библиотека для создания и обработки PDF документов 'налету'. " +
+ "Библиотека полностью написана на языке C# и базируется исключительно на безопасном, управляемом коде. " +
+ "PDFsharpCore использует два мощных абстрактных уровня для создания и обработки PDF документов.\n" +
+ "Для рисования текста, графики, и изображений в ней используется набор классов, которые разработаны аналогично с" +
+ "пакетом System.Drawing, библиотеки .NET framework. С помощью этих классов возможно не только создавать" +
+ "содержимое PDF страниц очень легко, но они так же позволяют рисовать напрямую в окне приложения или на принтере.\n" +
+ "Дополнительно PDFsharpCore имеет полноценные модели структурированных базовых элементов PDF. Они позволяют работать с существующим PDF документами " +
+ "для изменения их содержимого, склеивания документов, или разделения на части.\n" +
+ "Исходный код PDFsharpCore библиотеки это Open Source распространяемый под лицензией MIT (http://ru.wikipedia.org/wiki/MIT_License). " +
+ "Теоретически она позволяет использовать PDFsharpCore без ограничений в не open source проектах или коммерческих проектах/продуктах.",
+
+ // French version (by courtesy of Olivier Dalet).
+ "French (Français)\n" +
+ "PDFSharpCore est une librairie .NET permettant de créer et de traiter des documents PDF 'à la volée'. " +
+ "La librairie est entièrement écrite en C# et exclusivement basée sur du code sûr et géré. " +
+ "PDFSharpCore fournit deux puissants niveaux d'abstraction pour la création et le traitement des documents PDF.\n" +
+ "Un jeu de classes, modélisées afin de ressembler aux classes du namespace System.Drawing du framework .NET, " +
+ "permet de dessiner du texte, des graphiques et des images. Non seulement ces classes permettent la création du " +
+ "contenu des pages PDF de manière aisée, mais elles peuvent aussi être utilisées pour dessiner dans une fenêtre ou pour l'imprimante.\n" +
+ "De plus, PDFSharpCore modélise complètement les éléments structurels de PDF. Ainsi, des documents PDF existants peuvent être " +
+ "facilement modifiés, fusionnés ou éclatés.\n" +
+ "Le code source de PDFSharpCore est Open Source sous licence MIT (http://fr.wikipedia.org/wiki/Licence_MIT). " +
+ "Il est donc possible d'utiliser PDFSharpCore sans limitation aucune dans des projets ou produits non Open Source ou commerciaux.",
+
+ // Dutch version (by giCalle)
+ "Dutch\n" +
+ "PDFsharpCore is een .NET bibliotheek om PDF documenten te creëren en te verwerken. " +
+ "De bibliotheek is volledig geschreven in C# en gebruikt uitsluitend veilige, 'managed code'. " +
+ "PDFsharpCore biedt twee krachtige abstractie niveaus aan om PDF documenten te maken en te verwerken.\n" +
+ "Om tekst, beelden en foto's weer te geven zijn er een reeks klassen beschikbaar, gemodelleerd naar de klassen " +
+ "uit de 'System.Drawing' naamruimte van het .NET framework. Met behulp van deze klassen is het niet enkel mogelijk " +
+ "om de inhoud van PDF pagina's aan te maken op een eenvoudige manier, maar ze kunnen ook gebruikt worden om dingen " +
+ "weer te geven in een venster of naar een printer. Daarbovenop implementeert PDFsharpCore de volledige elementen structuur " +
+ "waarop PDF is gebaseerd. Hiermee kunnen bestaande PDF documenten eenvoudig aangepast, samengevoegd of opgesplitst worden.\n" +
+ "De broncode van PDFsharpCore is opensource onder een MIT licentie (http://nl.wikipedia.org/wiki/MIT-licentie). " +
+ "Daarom is het mogelijk om PDFsharpCore te gebruiken zonder beperkingen in niet open source of commerciële projecten/producten.",
+
+ // Danish version (by courtesy of Mikael Lyngvig).
+ "Danish (Dansk)\n" +
+ "PDFsharpCore er et .NET bibliotek til at dynamisk lave og behandle PDF dokumenter. " +
+ "Biblioteket er skrevet rent i C# og indeholder kun sikker, managed kode. " +
+ "PDFsharpCore tilbyder to stærke abstraktionsniveauer til at lave og behandle PDF dokumenter. " +
+ "Til at tegne tekst, grafik og billeder findes der et sæt klasser som er modelleret ligesom klasserne i navnerummet " +
+ "System.Drawing i .NET biblioteket. Med disse klasser er det ikke kun muligt at udforme indholdet af PDF siderne på en " +
+ "nem måde – de kan også bruges til at tegne i et vindue eller på en printer. " +
+ "Derudover modellerer PDFsharpCore fuldstændigt strukturelementerne som PDF er baseret på. " +
+ "Med dem kan eksisterende PDF dokumenter nemt modificeres, sammenknyttes og adskilles. " +
+ "Kildekoden til PDFsharpCore er Open Source under MIT licensen (http://da.wikipedia.org/wiki/MIT-Licensen). " +
+ "Derfor er det muligt at bruge PDFsharpCore uden begrænsninger i både lukkede og kommercielle projekter og produkter.",
+
+ // Portuguese version (by courtesy of Luís Rodrigues).
+ "Portuguese (Português)\n" +
+ "PDFsharpCore é uma biblioteca .NET para a criação e processamento de documentos PDF 'on the fly'." +
+ "A biblioteca é completamente escrita em C# e baseada exclusivamente em código gerenciado e seguro. " +
+ "O PDFsharpCore oferece dois níveis de abstração poderosa para criar e processar documentos PDF.\n" +
+ "Para desenhar texto, gráficos e imagens, há um conjunto de classes que são modeladas de forma semelhante às classes " +
+ "do espaço de nomes System.Drawing do framework .NET. Com essas classes não só é possível criar " +
+ "o conteúdo das páginas PDF de uma maneira fácil, mas podem também ser usadas para desenhar numa janela ou numa impressora.\n" +
+ "Adicionalmente, o PDFSharpCore modela completamente a estrutura dos elementos em que o PDF é baseado. Com eles, documentos PDF existentes " +
+ "podem ser modificados, unidos, ou divididos com facilidade.\n" +
+ "O código fonte do PDFsharpCore é Open Source sob a licença MIT (http://en.wikipedia.org/wiki/MIT_License). " +
+ "Por isso, é possível usar o PDFsharpCore sem limitações em projetos/produtos não open source ou comerciais.",
+
+ // Polish version (by courtesy of Krzysztof Jędryka)
+ "Polish (polski)\n" +
+ "PDFsharpCore jest biblioteką .NET umożliwiającą tworzenie i przetwarzanie dokumentów PDF 'w locie'. " +
+ "Biblioteka ta została stworzona w całości w języku C# i jest oparta wyłącznie na bezpiecznym i zarządzanym kodzie. " +
+ "PDFsharpCore oferuje dwa rozbudowane poziomy abstrakcji do tworzenia i przetwarzania dokumentów PDF.\n" +
+ "Do rysowania tekstu, grafiki i obrazów stworzono zbiór klas projektowanych na wzór klas przestrzeni nazw System.Drawing" +
+ "platformy .NET. Z pomocą tych klas można tworzyć w wygodny sposób nie tylko zawartość stron dokumentu PDF, ale można również" +
+ "rysować w oknie programu lub generować wydruki.\n" +
+ "Ponadto PDFsharpCore w pełni odwzorowuje strukturę elementów na których opiera się format pliku PDF." +
+ "Używając tych elementów, dokumenty PDF można modyfikować, łączyć lub dzielić z łatwością.\n" +
+ "Kod źródłowy PDFsharpCore jest dostępny na licencji Open Source MIT (http://pl.wikipedia.org/wiki/Licencja_MIT). " +
+ "Zatem można korzystać z PDFsharpCore bez żadnych ograniczeń w projektach niedostępnych dla społeczności Open Source lub komercyjnych.",
+
+ // Your language may come here.
+ "Invitation\n" +
+ "If you use PDFsharpCore and haven't found your native language in this document, we will be pleased to get your translation of the text above and include it here.\n" +
+};
+```
+
+The current implementation of PDFsharpCore is limited to left-to-right languages. Languages like Arabic cannot yet be created even with Unicode fonts. Also the so called CJK (Chinese, Japanese, Korean) support in PDF can also not be addressed with PDF sharp. However, we plan to support as many languages as possible with PDFsharpCore. If you are a programmer and a native speaker of one of these languages and you like to create PDF documents in your language, you can help us to implement it in PDFsharpCore. You don't have to do the programming, but just help us to verify our implementation.
diff --git a/docs/PdfSharpCore/samples/UnprotectDocument.md b/docs/PdfSharpCore/samples/UnprotectDocument.md
new file mode 100644
index 00000000..55df0513
--- /dev/null
+++ b/docs/PdfSharpCore/samples/UnprotectDocument.md
@@ -0,0 +1,79 @@
+# Unprotect Document
+
+This sample shows how to unprotect a document (if you know the password).
+
+Note: that we will not explain nor give any tips how to crack a protected document with PDFsharpCore.
+
+## Code
+
+This code shows how to unprotect a document to allow modification:
+
+```cs
+// Get a fresh copy of the sample PDF file.
+// The passwords are 'user' and 'owner' in this sample.
+const string filenameSource = "HelloWorld (protected).pdf";
+const string filenameDest = "HelloWorld_tempfile.pdf";
+File.Copy(Path.Combine("../../../../../PDFs/", filenameSource),
+Path.Combine(Directory.GetCurrentDirectory(), filenameDest), true);
+
+PdfDocument document;
+
+// Opening a document will fail with an invalid password.
+try
+{
+ document = PdfReader.Open(filenameDest, "invalid password");
+}
+catch (Exception ex)
+{
+ Debug.WriteLine(ex.Message);
+}
+
+// You can specify a delegate, which is called if the document needs a
+// password. If you want to modify the document, you must provide the
+// owner password.
+document = PdfReader.Open(filenameDest, PdfDocumentOpenMode.Modify, PasswordProvider);
+
+// Open the document with the user password.
+document = PdfReader.Open(filenameDest, "user", PdfDocumentOpenMode.ReadOnly);
+
+// Use the property HasOwnerPermissions to decide whether the used password
+// was the user or the owner password. In both cases PDFsharpCore provides full
+// access to the PDF document. It is up to the programmer who uses PDFsharpCore
+// to honor the access rights. PDFsharpCore doesn't try to protect the document
+// because this make little sense for an open source library.
+bool hasOwnerAccess = document.SecuritySettings.HasOwnerPermissions;
+
+// Open the document with the owner password.
+document = PdfReader.Open(filenameDest, "owner");
+hasOwnerAccess = document.SecuritySettings.HasOwnerPermissions;
+
+// A document opened with the owner password is completely unprotected
+// and can be modified.
+XGraphics gfx = XGraphics.FromPdfPage(document.Pages[0]);
+gfx.DrawString("Some text...",
+new XFont("Times New Roman", 12), XBrushes.Firebrick, 50, 100);
+
+// The modified document is saved without any protection applied.
+PdfDocumentSecurityLevel level = document.SecuritySettings.DocumentSecurityLevel;
+
+// If you want to save it protected, you must set the DocumentSecurityLevel
+// or apply new passwords.
+// In the current implementation the old passwords are not automatically
+// reused. See 'ProtectDocument' sample for further information.
+
+// Save the document...
+document.Save(filenameDest);
+```
+
+Here's the source code for the password provider:
+
+```cs
+///
+/// The 'get the password' call back function.
+///
+static void PasswordProvider(PdfPasswordProviderArgs args)
+{
+ // Show a dialog here in a real application
+ args.Password = "owner";
+}
+```
diff --git a/docs/PdfSharpCore/samples/Watermark.md b/docs/PdfSharpCore/samples/Watermark.md
new file mode 100644
index 00000000..73acc7b9
--- /dev/null
+++ b/docs/PdfSharpCore/samples/Watermark.md
@@ -0,0 +1,107 @@
+# Watermark
+
+This sample shows three variations how to add a watermark to an existing PDF file.
+
+Note: Technically the watermarks in this sample are simple graphical output. They have nothing to do with the Watermark Annotations introduced in PDF 1.
+
+
+## Code
+
+Here's the code that creates the first kind of watermarks:
+
+```cs
+// Variation 1: Draw a watermark as a text string.
+
+// Get an XGraphics object for drawing beneath the existing content.
+var gfx = XGraphics.FromPdfPage(page, XGraphicsPdfPageOptions.Prepend);
+
+// Get the size (in points) of the text.
+var size = gfx.MeasureString(watermark, font);
+
+// Define a rotation transformation at the center of the page.
+gfx.TranslateTransform(page.Width / 2, page.Height / 2);
+gfx.RotateTransform(-Math.Atan(page.Height / page.Width) * 180 / Math.PI);
+gfx.TranslateTransform(-page.Width / 2, -page.Height / 2);
+
+// Create a string format.
+var format = new XStringFormat();
+format.Alignment = XStringAlignment.Near;
+format.LineAlignment = XLineAlignment.Near;
+
+// Create a dimmed red brush.
+XBrush brush = new XSolidBrush(XColor.FromArgb(128, 255, 0, 0));
+
+// Draw the string.
+gfx.DrawString(watermark, font, brush,
+new XPoint((page.Width - size.Width) / 2, (page.Height - size.Height) / 2),
+format);
+```
+
+Here's the code that creates the second kind of watermarks:
+
+```cs
+// Variation 2: Draw a watermark as an outlined graphical path.
+// NYI: Does not work in Core build.
+
+// Get an XGraphics object for drawing beneath the existing content.
+var gfx = XGraphics.FromPdfPage(page, XGraphicsPdfPageOptions.Prepend);
+
+// Get the size (in points) of the text.
+var size = gfx.MeasureString(watermark, font);
+
+// Define a rotation transformation at the center of the page.
+gfx.TranslateTransform(page.Width / 2, page.Height / 2);
+gfx.RotateTransform(-Math.Atan(page.Height / page.Width) * 180 / Math.PI);
+gfx.TranslateTransform(-page.Width / 2, -page.Height / 2);
+
+// Create a graphical path.
+var path = new XGraphicsPath();
+
+// Create a string format.
+var format = new XStringFormat();
+format.Alignment = XStringAlignment.Near;
+format.LineAlignment = XLineAlignment.Near;
+
+// Add the text to the path.
+// AddString is not implemented in PDFsharpCore Core.
+path.AddString(watermark, font.FontFamily, XFontStyle.BoldItalic, 150,
+new XPoint((page.Width - size.Width) / 2, (page.Height - size.Height) / 2),
+format);
+
+// Create a dimmed red pen.
+var pen = new XPen(XColor.FromArgb(128, 255, 0, 0), 2);
+
+// Stroke the outline of the path.
+gfx.DrawPath(pen, path);
+```
+
+Here's the code that creates the third kind of watermarks:
+
+```cs
+// Variation 3: Draw a watermark as a transparent graphical path above text.
+// NYI: Does not work in Core build.
+
+// Get an XGraphics object for drawing above the existing content.
+var gfx = XGraphics.FromPdfPage(page, XGraphicsPdfPageOptions.Append);
+
+// Get the size (in points) of the text.
+var size = gfx.MeasureString(watermark, font);
+
+// Define a rotation transformation at the center of the page.
+gfx.TranslateTransform(page.Width / 2, page.Height / 2);
+gfx.RotateTransform(-Math.Atan(page.Height / page.Width) * 180 / Math.PI);
+gfx.TranslateTransform(-page.Width / 2, -page.Height / 2);
+
+// Create a graphical path.
+var path = new XGraphicsPath();
+
+// Create a string format.
+var format = new XStringFormat();
+format.Alignment = XStringAlignment.Near;
+format.LineAlignment = XLineAlignment.Near;
+
+// Add the text to the path.
+// AddString is not implemented in PDFsharpCore Core.
+path.AddString(watermark, font.FontFamily, XFontStyle.BoldItalic, 150,
+new XPoint((page.Width - si
+```
diff --git a/docs/PdfSharpCore/samples/WorkOnPdfObjects.md b/docs/PdfSharpCore/samples/WorkOnPdfObjects.md
new file mode 100644
index 00000000..1de7360f
--- /dev/null
+++ b/docs/PdfSharpCore/samples/WorkOnPdfObjects.md
@@ -0,0 +1,87 @@
+# Work on Pdf Objects
+
+This sample shows how to deal with PDF objects that are not (yet) covered by specialized PDFsharpCore classes (as an example it adds an OpenAction to an existing PDF file).
+
+PDF documents are based internally on objects like dictionaries, arrays, streams etc. This sample shows how to work directly on these underlying PDF objects. Use this functionality to achieve PDF features that are not yet implemented in PDFsharpCore.
+
+
+## Code
+
+Here is the code that shows how to add an OpenAction:
+
+```cs
+// Read document into memory for modification
+PdfDocument document = PdfReader.Open(filename);
+
+// The current version of PDFsharpCore doesn't support the concept of
+// 'actions'. Actions will come in a future version, but if you need them
+// now, you can have them 'handmade'.
+//
+// This sample works on PDF objects directly, therefore some knowledge of
+// the structure of PDF is required.
+// If you are not familiar with the portable document format, first read
+// at least chapter 3 in Adobe's PDF Reference
+// (http://partners.adobe.com/public/developer/pdf/index_reference.html).
+// If you can read German, I recommend chapter 12 of 'Die PostScript &
+// PDF-Bibel', a much more interesting reading than the bone-dry Adobe
+// books (http://www.pdflib.com/developer/technical-documentation/books/postscript-pdf-bibel/).
+//
+// The sample task is to add an 'open action' to the document so that it
+// starts with the content of page 3 magnified just enough to fit the
+// height of the page within the window.
+
+// First we have to create a new dictionary that defines the action.
+PdfDictionary dict = new PdfDictionary(document);
+
+// According to the PDF Reference the dictionary requires two elements.
+// A key /S that specifies the 'GoTo' action,
+// and a key /D that describes the destination.
+
+// Adding a name as value of key /S is easy.
+dict.Elements["/S"] = new PdfName("/GoTo");
+
+// The destination is described by an array.
+PdfArray array = new PdfArray(document);
+
+// Set the array as the value of key /D.
+// This makes the array a direct object of the dictionary.
+dict.Elements["/D"] = array;
+
+// Now add the elements to the array. According to the PDF Reference it
+// must be three for a page as the target of a 'GoTo' action.
+// The first element is an indirect reference to the destination page.
+// To add an indirect reference to the page three, we first need the
+// PdfReference object of that page.
+// (The index in the Pages collection is zero based, therefore Pages[2])
+PdfReference iref = PdfInternals.GetReference(document.Pages[2]);
+
+// Add the reference to the third page as the first array element.
+// Adding the iref (instead of the PdfPage object itself) makes it an
+// indirect reference.
+array.Elements.Add(iref);
+
+// The second element is the name /FitV to indicate 'fit vertically'.
+array.Elements.Add(new PdfName("/FitV"));
+
+// /FitV requires the horizontal coordinate that will be positioned at the
+// left edge of the window. We set -32768 because Acrobat uses this value
+// to show the full page (it means 'left aligned' anyway if the window is
+// so small that a horizontal scroll bar is required).
+array.Elements.Add(new PdfInteger(-32768));
+
+// Now that the action dictionary is complete, we can add it to the
+// document's object table.
+// Adding an object to the object table makes it an indirect object.
+document.Internals.AddObject(dict);
+
+// Finally we must add the action dictionary to the /OpenAction key of
+// the document's catalog as an indirect value.
+document.Internals.Catalog.Elements["/OpenAction"] = PdfInternals.GetReference(dict);
+
+// Using PDFsharpCore we never deal with object numbers. We simply put the
+// objects together and the PDFsharpCore framework does the rest.
+```
+
+Other objects not covered by PDFsharpCore can also be added this way.
+
+Using PDFsharpCore we never deal with object numbers. We simply put the objects together and the PDFsharpCore framework does the rest.
diff --git a/docs/PdfSharpCore/samples/XForms.md b/docs/PdfSharpCore/samples/XForms.md
new file mode 100644
index 00000000..711faf87
--- /dev/null
+++ b/docs/PdfSharpCore/samples/XForms.md
@@ -0,0 +1,66 @@
+# XForms
+
+This sample shows how to create an XForm object from scratch. You can think of such an object as a template, that, once created, can be drawn frequently anywhere in your PDF document.
+
+## Code
+
+Step 1: Create an XForm and draw some graphics on it:
+
+```cs
+// Create an empty XForm object with the specified width and height
+// A form is bound to its target document when it is created. The reason is that the form can
+// share fonts and other objects with its target document.
+XForm form = new XForm(document, XUnit.FromMillimeter(70), XUnit.FromMillimeter(55));
+
+// Create an XGraphics object for drawing the contents of the form.
+XGraphics formGfx = XGraphics.FromForm(form);
+
+// Draw a large transparent rectangle to visualize the area the form occupies
+XColor back = XColors.Orange;
+back.A = 0.2;
+XSolidBrush brush = new XSolidBrush(back);
+formGfx.DrawRectangle(brush, -10000, -10000, 20000, 20000);
+
+// On a form you can draw...
+
+// ... text
+formGfx.DrawString("Text, Graphics, Images, and Forms", new XFont("Verdana", 10, XFontStyle.Regular), XBrushes.Navy, 3, 0, XStringFormats.TopLeft);
+XPen pen = XPens.LightBlue.Clone();
+pen.Width = 2.5;
+
+// ... graphics like Bézier curves
+formGfx.DrawBeziers(pen, XPoint.ParsePoints("30,120 80,20 100,140 175,33.3"));
+
+// ... raster images like GIF files
+XGraphicsState state = formGfx.Save();
+formGfx.RotateAtTransform(17, new XPoint(30, 30));
+formGfx.DrawImage(XImage.FromFile("../../../../../../dev/XGraphicsLab/images/Test.gif"), 20, 20);
+formGfx.Restore(state);
+
+// ... and forms like XPdfForm objects
+state = formGfx.Save();
+formGfx.RotateAtTransform(-8, new XPoint(165, 115));
+formGfx.DrawImage(XPdfForm.FromFile("../../../../../PDFs/SomeLayout.pdf"), new XRect(140, 80, 50, 50 * Math.Sqrt(2)));
+formGfx.Restore(state);
+
+// When you finished drawing on the form, dispose the XGraphic object.
+formGfx.Dispose();
+```
+
+Step 2: Draw the XPdfForm on your PDF page like an image:
+
+```cs
+// Draw the form on the page of the document in its original size
+gfx.DrawImage(form, 20, 50);
+
+// Draw it stretched
+gfx.DrawImage(form, 300, 100, 250, 40);
+
+// Draw and rotate it
+const int d = 25;
+for (int idx = 0; idx < 360; idx += d)
+{
+ gfx.DrawImage(form, 300, 480, 200, 200);
+ gfx.RotateAtTransform(d, new XPoint(300, 480));
+}
+```
diff --git a/docs/PdfSharpCore/samples/index.md b/docs/PdfSharpCore/samples/index.md
new file mode 100644
index 00000000..aa02fbf9
--- /dev/null
+++ b/docs/PdfSharpCore/samples/index.md
@@ -0,0 +1,27 @@
+# PDFsharpCore > Samples
+
+Samples for [PDFsharpCore](../index.md):
+
+* [Hello World](HelloWorld.md)
+* [Graphics](Graphics.md)
+* [Annotations](Annotations.md)
+* [Booklet](Booklet.md)
+* [Bookmarks](Bookmarks.md)
+* [Colors CMYK](ColorsCMYK.md)
+* [Combine Documents](CombineDocuments.md)
+* [Concatenate Documents](ConcatenateDocuments.md)
+* [Export Images](ExportImages.md)
+* [Font Resolver](FontResolver.md)
+* [Multiple Pages](MultiplePages.md)
+* [Page Sizes](PageSizes.md)
+* [Preview](Preview.md)
+* [Protect Document](ProtectDocument.md)
+* [Unprotect Document](UnprotectDocument.md)
+* [Split Document](SplitDocument.md)
+* [Text Layout](TextLayout.md)
+* [Two Pages on One](TwoPagesOnOne.md)
+* [Unicode](Unicode.md)
+* [Watermark](Watermark.md)
+* [Work on Pdf Objects](WorkOnPdfObjects.md)
+* [XForms](XForms.md)
+* [Clock](Clock.md)
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 00000000..343f709a
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,32 @@
+# Welcome to PDFsharpCore & MigraDocCore!
+
+The libraries in this project are published Open Source and under the [MIT license](https://en.wikipedia.org/wiki/MIT_License) and are free to use.
+
+
+## PDFsharpCore
+
+PDFsharpCore is the Open Source .NET library that easily creates and processes PDF documents on the fly.
+The same drawing routines can be used to create PDF documents, draw on the screen, or send output to any printer.
+
+* [PDFsharpCore](PDFsharpCore/index.md)
+
+
+## MigraDocCore
+
+MigraDocCore is the Open Source .NET library that easily creates documents based on an object model with paragraphs, tables, styles, etc. and renders them into PDF by using the PDFsharpCore library.
+
+* [MigraDocCore](MigraDocCore/index.md)
+
+
+## Use PDFsharpCore or MigraDocCore?
+
+Use PDFsharpCore if you want to create PDF files only, but be able to control every pixel and every line that is drawn.
+Use MigraDocCore if you need documents as PDF files and if you want to enjoy the comfort of a word processor.
+
+
+## Mixing PDFsharpCore and MigraDocCore
+
+If MigraDocCore does almost anything you need, then you can use it to create PDF files and post-process them with PDFsharpCore to add some extra features.
+
+Or use PDFsharpCore to create the document but use MigraDocCore to create individual pages.
+This could be the best choice if your application uses lots of graphics, but also needs some layout text.