Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 97e4572c39 |
@@ -1,70 +0,0 @@
|
|||||||
# For most projects, this workflow file will not need changing; you simply need
|
|
||||||
# to commit it to your repository.
|
|
||||||
#
|
|
||||||
# You may wish to alter this file to override the set of languages analyzed,
|
|
||||||
# or to provide custom queries or build logic.
|
|
||||||
#
|
|
||||||
# ******** NOTE ********
|
|
||||||
# We have attempted to detect the languages in your repository. Please check
|
|
||||||
# the `language` matrix defined below to confirm you have the correct set of
|
|
||||||
# supported CodeQL languages.
|
|
||||||
#
|
|
||||||
name: "CodeQL"
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ main ]
|
|
||||||
pull_request:
|
|
||||||
# The branches below must be a subset of the branches above
|
|
||||||
branches: [ main ]
|
|
||||||
schedule:
|
|
||||||
- cron: '22 16 * * 5'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
analyze:
|
|
||||||
name: Analyze
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
actions: read
|
|
||||||
contents: read
|
|
||||||
security-events: write
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
language: [ 'csharp' ]
|
|
||||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
|
||||||
# Learn more about CodeQL language support at https://git.io/codeql-language-support
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
|
||||||
- name: Initialize CodeQL
|
|
||||||
uses: github/codeql-action/init@v1
|
|
||||||
with:
|
|
||||||
languages: ${{ matrix.language }}
|
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
|
||||||
# By default, queries listed here will override any specified in a config file.
|
|
||||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
|
||||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
|
||||||
|
|
||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
|
||||||
- name: Autobuild
|
|
||||||
uses: github/codeql-action/autobuild@v1
|
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
|
||||||
# 📚 https://git.io/JvXDl
|
|
||||||
|
|
||||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
|
||||||
# and modify them (or add more) to build your code if your project
|
|
||||||
# uses a compiled language
|
|
||||||
|
|
||||||
#- run: |
|
|
||||||
# make bootstrap
|
|
||||||
# make release
|
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
|
||||||
uses: github/codeql-action/analyze@v1
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
name: Build And Create Nuget Package
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ main ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ main ]
|
|
||||||
workflow_dispatch:
|
|
||||||
schedule:
|
|
||||||
- cron: '3 0 * * 0'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
main:
|
|
||||||
runs-on: ${{ matrix.environment }}
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
environment:
|
|
||||||
- macos-latest
|
|
||||||
- ubuntu-latest
|
|
||||||
- windows-latest
|
|
||||||
env:
|
|
||||||
DOTNET_NOLOGO: 1
|
|
||||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
|
||||||
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
|
|
||||||
UNIT_TEST_PROJECT: QuestPDF.UnitTests/QuestPDF.UnitTests.csproj
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: 📝 Fetch Sources 📝
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: ⚙ Setup .NET 6.0 SDK ⚙
|
|
||||||
uses: actions/setup-dotnet@v1
|
|
||||||
with:
|
|
||||||
dotnet-version: '6.0.x'
|
|
||||||
|
|
||||||
- name: 🔄 Restore Nuget Packages 🔄
|
|
||||||
shell: bash
|
|
||||||
run: dotnet restore
|
|
||||||
working-directory: ./Source
|
|
||||||
|
|
||||||
- name: 🛠 Build Solution 🛠
|
|
||||||
shell: bash
|
|
||||||
run: dotnet build -c Release --no-restore
|
|
||||||
working-directory: ./Source
|
|
||||||
|
|
||||||
- name: Upload build artifacts
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
if: ${{ matrix.environment == 'windows-latest' }}
|
|
||||||
with:
|
|
||||||
name: Build Package
|
|
||||||
path: |
|
|
||||||
**/*.nupkg
|
|
||||||
**/*.snupkg
|
|
||||||
!.nuget
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
github: QuestPDF
|
|
||||||
@@ -13,11 +13,11 @@ namespace QuestPDF.Examples
|
|||||||
[Test]
|
[Test]
|
||||||
public void Example()
|
public void Example()
|
||||||
{
|
{
|
||||||
FontManager.RegisterFont(File.OpenRead("LibreBarcode39-Regular.ttf"));
|
FontManager.RegisterFontType("LibreBarcode39", File.OpenRead("LibreBarcode39-Regular.ttf"));
|
||||||
|
|
||||||
RenderingTest
|
RenderingTest
|
||||||
.Create()
|
.Create()
|
||||||
.PageSize(400, 200)
|
.PageSize(400, 100)
|
||||||
.ShowResults()
|
.ShowResults()
|
||||||
.Render(container =>
|
.Render(container =>
|
||||||
{
|
{
|
||||||
@@ -25,9 +25,7 @@ namespace QuestPDF.Examples
|
|||||||
.Background(Colors.White)
|
.Background(Colors.White)
|
||||||
.AlignCenter()
|
.AlignCenter()
|
||||||
.AlignMiddle()
|
.AlignMiddle()
|
||||||
.Text("*QuestPDF*")
|
.Text("*QuestPDF*", TextStyle.Default.FontType("LibreBarcode39").Size(64));
|
||||||
.FontFamily("Libre Barcode 39")
|
|
||||||
.FontSize(64);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,10 +49,7 @@ namespace QuestPDF.Examples
|
|||||||
.PrimaryLayer()
|
.PrimaryLayer()
|
||||||
.PaddingVertical(10)
|
.PaddingVertical(10)
|
||||||
.PaddingHorizontal(20)
|
.PaddingHorizontal(20)
|
||||||
.Text("Sample text")
|
.Text("Sample text", TextStyle.Default.Size(16).Color(Colors.Blue.Darken2).SemiBold());
|
||||||
.FontSize(16)
|
|
||||||
.FontColor(Colors.Blue.Darken2)
|
|
||||||
.SemiBold();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -57,10 +57,7 @@ namespace QuestPDF.Examples
|
|||||||
column
|
column
|
||||||
.Item()
|
.Item()
|
||||||
.PaddingBottom(10)
|
.PaddingBottom(10)
|
||||||
.Text("Chart example")
|
.Text("Chart example", TextStyle.Default.Size(20).SemiBold().Color(Colors.Blue.Medium));
|
||||||
.FontSize(20)
|
|
||||||
.SemiBold()
|
|
||||||
.FontColor(Colors.Blue.Medium);
|
|
||||||
|
|
||||||
column
|
column
|
||||||
.Item()
|
.Item()
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
using System;
|
using NUnit.Framework;
|
||||||
using System.Linq;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using QuestPDF.Examples.Engine;
|
using QuestPDF.Examples.Engine;
|
||||||
using QuestPDF.Fluent;
|
using QuestPDF.Fluent;
|
||||||
using QuestPDF.Helpers;
|
using QuestPDF.Helpers;
|
||||||
@@ -22,35 +20,18 @@ namespace QuestPDF.Examples
|
|||||||
{
|
{
|
||||||
container.Column(column =>
|
container.Column(column =>
|
||||||
{
|
{
|
||||||
foreach (var i in Enumerable.Range(0, 10))
|
column.Item().Element(Block);
|
||||||
column.Item().Element(Block);
|
|
||||||
|
|
||||||
static void Block(IContainer container)
|
static void Block(IContainer container)
|
||||||
{
|
{
|
||||||
container
|
container
|
||||||
.Width(72)
|
.Width(72)
|
||||||
.Height(3.5f, Unit.Inch)
|
.Height(3.5f)
|
||||||
.Height(1.5f, Unit.Inch)
|
.Height(1.5f)
|
||||||
.Background(Placeholders.BackgroundColor());
|
.Background(Placeholders.BackgroundColor());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Stability_NoItems()
|
|
||||||
{
|
|
||||||
RenderingTest
|
|
||||||
.Create()
|
|
||||||
.ProducePdf()
|
|
||||||
.MaxPages(100)
|
|
||||||
.PageSize(250, 150)
|
|
||||||
.Render(container =>
|
|
||||||
{
|
|
||||||
container
|
|
||||||
.Padding(25)
|
|
||||||
.Column(column => { });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -16,7 +16,7 @@ namespace QuestPDF.Examples
|
|||||||
.PageSize(PageSizes.A4)
|
.PageSize(PageSizes.A4)
|
||||||
.ProducePdf()
|
.ProducePdf()
|
||||||
.ShowResults()
|
.ShowResults()
|
||||||
.Render(x => GenerateStructure(x, 12));
|
.Render(x => GenerateStructure(x, 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateStructure(IContainer container, int level)
|
private void GenerateStructure(IContainer container, int level)
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using QuestPDF.Examples.Engine;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
|
||||||
|
namespace QuestPDF.Examples
|
||||||
|
{
|
||||||
|
internal class MyComponent : IComponent
|
||||||
|
{
|
||||||
|
public ISlot Header { get; set; }
|
||||||
|
public ISlot<string> Content { get; set; }
|
||||||
|
|
||||||
|
public void Compose(IContainer container)
|
||||||
|
{
|
||||||
|
container
|
||||||
|
.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().Slot(Header);
|
||||||
|
|
||||||
|
foreach (var i in Enumerable.Range(1, 10))
|
||||||
|
column.Item().Slot(Content, i.ToString());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ComponentExamples
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void ComplexLayout()
|
||||||
|
{
|
||||||
|
RenderingTest
|
||||||
|
.Create()
|
||||||
|
.PageSize(PageSizes.A4)
|
||||||
|
.ProducePdf()
|
||||||
|
.ShowResults()
|
||||||
|
.Render(content =>
|
||||||
|
{
|
||||||
|
content
|
||||||
|
.Padding(10)
|
||||||
|
.Border(1)
|
||||||
|
.BorderColor(Colors.Grey.Medium)
|
||||||
|
.Component<MyComponent>(component =>
|
||||||
|
{
|
||||||
|
component
|
||||||
|
.Slot(x => x.Header)
|
||||||
|
.Text("This is my text");
|
||||||
|
|
||||||
|
component.Slot(x => x.Content, (input, container) =>
|
||||||
|
{
|
||||||
|
container
|
||||||
|
.Background(Placeholders.BackgroundColor())
|
||||||
|
.Padding(5)
|
||||||
|
.Text(input);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,7 +25,7 @@ namespace QuestPDF.Examples
|
|||||||
page.Content().PaddingVertical(10).Border(1).Padding(10).Column(column =>
|
page.Content().PaddingVertical(10).Border(1).Padding(10).Column(column =>
|
||||||
{
|
{
|
||||||
foreach (var index in Enumerable.Range(1, 100))
|
foreach (var index in Enumerable.Range(1, 100))
|
||||||
column.Item().Text($"Line {index}").FontColor(Placeholders.Color());
|
column.Item().Text($"Line {index}", TextStyle.Default.Color(Placeholders.Color()));
|
||||||
});
|
});
|
||||||
|
|
||||||
page.Footer().Text("Footer");
|
page.Footer().Text("Footer");
|
||||||
+2
-2
@@ -24,7 +24,7 @@ namespace QuestPDF.Examples
|
|||||||
|
|
||||||
page.Margin(20);
|
page.Margin(20);
|
||||||
page.Size(PageSizes.A4);
|
page.Size(PageSizes.A4);
|
||||||
page.PageColor(Colors.White);
|
page.Background(Colors.White);
|
||||||
|
|
||||||
page.Content().Column(column =>
|
page.Content().Column(column =>
|
||||||
{
|
{
|
||||||
@@ -38,7 +38,7 @@ namespace QuestPDF.Examples
|
|||||||
text.Line(Placeholders.Sentence());
|
text.Line(Placeholders.Sentence());
|
||||||
|
|
||||||
// this text has size 20 but also semibold and red
|
// this text has size 20 but also semibold and red
|
||||||
text.Span(Placeholders.Sentence()).FontColor(Colors.Red.Medium);
|
text.Span(Placeholders.Sentence(), TextStyle.Default.Color(Colors.Red.Medium));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
+3
-5
@@ -1,5 +1,4 @@
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using QuestPDF.Examples.Engine;
|
using QuestPDF.Examples.Engine;
|
||||||
@@ -27,8 +26,8 @@ namespace QuestPDF.Examples
|
|||||||
.DefaultTextStyle(TextStyle.Default.Bold().Underline())
|
.DefaultTextStyle(TextStyle.Default.Bold().Underline())
|
||||||
.Column(column =>
|
.Column(column =>
|
||||||
{
|
{
|
||||||
column.Item().Text("Default style applies to all children");
|
column.Item().Text("Default style applies to all children", TextStyle.Default);
|
||||||
column.Item().Text("You can override certain styles").Underline(false).FontColor(Colors.Green.Darken2);
|
column.Item().Text("You can override certain styles", TextStyle.Default.Underline(false).Color(Colors.Green.Darken2));
|
||||||
|
|
||||||
column.Item().PaddingTop(10).Border(1).Grid(grid =>
|
column.Item().PaddingTop(10).Border(1).Grid(grid =>
|
||||||
{
|
{
|
||||||
@@ -44,8 +43,7 @@ namespace QuestPDF.Examples
|
|||||||
.Height(50)
|
.Height(50)
|
||||||
.AlignCenter()
|
.AlignCenter()
|
||||||
.AlignMiddle()
|
.AlignMiddle()
|
||||||
.Text(i.ToString(CultureInfo.InvariantCulture))
|
.Text(i, TextStyle.Default.Size(16 + i / 4));
|
||||||
.FontSize(16 + i / 4);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
+1
-1
@@ -24,7 +24,7 @@ namespace QuestPDF.Examples
|
|||||||
{
|
{
|
||||||
page.Size(PageSizes.A6);
|
page.Size(PageSizes.A6);
|
||||||
page.Margin(5);
|
page.Margin(5);
|
||||||
page.PageColor(Colors.White);
|
page.Background(Colors.White);
|
||||||
|
|
||||||
page.Header().Column(column =>
|
page.Header().Column(column =>
|
||||||
{
|
{
|
||||||
+12
-24
@@ -43,9 +43,7 @@ namespace QuestPDF.Examples
|
|||||||
.Before()
|
.Before()
|
||||||
.Background(Colors.Grey.Medium)
|
.Background(Colors.Grey.Medium)
|
||||||
.Padding(10)
|
.Padding(10)
|
||||||
.Text("Notes")
|
.Text("Notes", TextStyle.Default.Size(16).Color("#FFF"));
|
||||||
.FontSize(16)
|
|
||||||
.FontColor("#FFF");
|
|
||||||
|
|
||||||
decoration
|
decoration
|
||||||
.Content()
|
.Content()
|
||||||
@@ -282,15 +280,12 @@ namespace QuestPDF.Examples
|
|||||||
.Layer()
|
.Layer()
|
||||||
.AlignCenter()
|
.AlignCenter()
|
||||||
.AlignMiddle()
|
.AlignMiddle()
|
||||||
.Text("Watermark")
|
.Text("Watermark", TextStyle.Default.Size(48).Bold().Color(Colors.Green.Lighten3));
|
||||||
.FontSize(48)
|
|
||||||
.Bold()
|
|
||||||
.FontColor(Colors.Green.Lighten3);
|
|
||||||
|
|
||||||
layers
|
layers
|
||||||
.Layer()
|
.Layer()
|
||||||
.AlignBottom()
|
.AlignBottom()
|
||||||
.Text(text => text.CurrentPageNumber().FontSize(16).FontColor(Colors.Green.Medium));
|
.Text(text => text.CurrentPageNumber(TextStyle.Default.Size(16).Color(Colors.Green.Medium)));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -421,9 +416,7 @@ namespace QuestPDF.Examples
|
|||||||
.Border(1)
|
.Border(1)
|
||||||
.BorderColor(Colors.Grey.Medium)
|
.BorderColor(Colors.Grey.Medium)
|
||||||
.Padding(10)
|
.Padding(10)
|
||||||
.Text(font)
|
.Text(font, TextStyle.Default.FontType(font).Size(16));
|
||||||
.FontFamily(font)
|
|
||||||
.FontSize(16);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -463,7 +456,7 @@ namespace QuestPDF.Examples
|
|||||||
});
|
});
|
||||||
|
|
||||||
layers.Layer().Background("#8F00").Extend();
|
layers.Layer().Background("#8F00").Extend();
|
||||||
layers.Layer().PaddingTop(40).Text("It works!").FontSize(24);
|
layers.Layer().PaddingTop(40).Text("It works!", TextStyle.Default.Size(24));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -484,7 +477,7 @@ namespace QuestPDF.Examples
|
|||||||
//.MinimalBox()
|
//.MinimalBox()
|
||||||
.Background(Colors.Grey.Lighten2)
|
.Background(Colors.Grey.Lighten2)
|
||||||
.Padding(15)
|
.Padding(15)
|
||||||
.Text("Test of the \n box element").FontSize(20);
|
.Text("Test of the \n box element", TextStyle.Default.Size(20));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,8 +503,7 @@ namespace QuestPDF.Examples
|
|||||||
decoration
|
decoration
|
||||||
.Before()
|
.Before()
|
||||||
.PaddingBottom(10)
|
.PaddingBottom(10)
|
||||||
.Text("Example: scale component")
|
.Text("Example: scale component", headerFontStyle);
|
||||||
.Style(headerFontStyle);
|
|
||||||
|
|
||||||
decoration
|
decoration
|
||||||
.Content()
|
.Content()
|
||||||
@@ -533,8 +525,7 @@ namespace QuestPDF.Examples
|
|||||||
.Background(fontColor)
|
.Background(fontColor)
|
||||||
.Scale(scale)
|
.Scale(scale)
|
||||||
.Padding(5)
|
.Padding(5)
|
||||||
.Text($"Content with {scale} scale.")
|
.Text($"Content with {scale} scale.", fontStyle);
|
||||||
.Style(fontStyle);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -564,8 +555,7 @@ namespace QuestPDF.Examples
|
|||||||
.BorderColor(Colors.Green.Darken1)
|
.BorderColor(Colors.Green.Darken1)
|
||||||
|
|
||||||
.Padding(50)
|
.Padding(50)
|
||||||
.Text("Moved text")
|
.Text("Moved text", TextStyle.Default.Size(25));
|
||||||
.FontSize(25);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -601,8 +591,7 @@ namespace QuestPDF.Examples
|
|||||||
.MinimalBox()
|
.MinimalBox()
|
||||||
.Background(Colors.White)
|
.Background(Colors.White)
|
||||||
.Padding(10)
|
.Padding(10)
|
||||||
.Text($"Rotated {turns * 90}°")
|
.Text($"Rotated {turns * 90}°", TextStyle.Default.Size(16));
|
||||||
.FontSize(16);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -700,8 +689,7 @@ namespace QuestPDF.Examples
|
|||||||
.MinimalBox()
|
.MinimalBox()
|
||||||
.Background(Colors.White)
|
.Background(Colors.White)
|
||||||
.Padding(10)
|
.Padding(10)
|
||||||
.Text($"Flipped {turns}")
|
.Text($"Flipped {turns}", TextStyle.Default.Size(16));
|
||||||
.FontSize(16);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -742,7 +730,7 @@ namespace QuestPDF.Examples
|
|||||||
{
|
{
|
||||||
container
|
container
|
||||||
.Padding(25)
|
.Padding(25)
|
||||||
.PaddingLeft(50)
|
.PaddingLeft(75)
|
||||||
.Column(column =>
|
.Column(column =>
|
||||||
{
|
{
|
||||||
column.Item().Width(300).Height(150).Background(Colors.Blue.Lighten4);
|
column.Item().Width(300).Height(150).Background(Colors.Blue.Lighten4);
|
||||||
+2
-4
@@ -24,8 +24,6 @@ namespace QuestPDF.Examples.Engine
|
|||||||
private bool ApplyDebugging { get; set; }
|
private bool ApplyDebugging { get; set; }
|
||||||
private RenderingTestResult ResultType { get; set; } = RenderingTestResult.Images;
|
private RenderingTestResult ResultType { get; set; } = RenderingTestResult.Images;
|
||||||
|
|
||||||
private bool ShowingResultsEnabled = true;
|
|
||||||
|
|
||||||
private RenderingTest()
|
private RenderingTest()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -116,7 +114,7 @@ namespace QuestPDF.Examples.Engine
|
|||||||
Func<int, string> fileNameSchema = i => $"{FileNamePrefix}-${i}.png";
|
Func<int, string> fileNameSchema = i => $"{FileNamePrefix}-${i}.png";
|
||||||
document.GenerateImages(fileNameSchema);
|
document.GenerateImages(fileNameSchema);
|
||||||
|
|
||||||
if (ShowResult && ShowingResultsEnabled)
|
if (ShowResult)
|
||||||
Process.Start("explorer", fileNameSchema(0));
|
Process.Start("explorer", fileNameSchema(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +123,7 @@ namespace QuestPDF.Examples.Engine
|
|||||||
var fileName = $"{FileNamePrefix}.pdf";
|
var fileName = $"{FileNamePrefix}.pdf";
|
||||||
document.GeneratePdf(fileName);
|
document.GeneratePdf(fileName);
|
||||||
|
|
||||||
if (ShowResult && ShowingResultsEnabled)
|
if (ShowResult)
|
||||||
Process.Start("explorer", fileName);
|
Process.Start("explorer", fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -21,9 +21,9 @@ namespace QuestPDF.Examples
|
|||||||
{
|
{
|
||||||
page.Margin(20);
|
page.Margin(20);
|
||||||
page.Size(PageSizes.A7.Landscape());
|
page.Size(PageSizes.A7.Landscape());
|
||||||
page.PageColor(Colors.White);
|
page.Background(Colors.White);
|
||||||
|
|
||||||
page.Header().Text("With ensure space").SemiBold();
|
page.Header().Text("With ensure space", TextStyle.Default.SemiBold());
|
||||||
|
|
||||||
page.Content().Column(column =>
|
page.Content().Column(column =>
|
||||||
{
|
{
|
||||||
@@ -17,9 +17,9 @@ namespace QuestPDF.Examples
|
|||||||
.Padding(5);
|
.Padding(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LabelCell(this IContainer container, string text) => container.Cell(true).Text(text).SemiBold();
|
public static void LabelCell(this IContainer container, string text) => container.Cell(true).Text(text, TextStyle.Default.SemiBold());
|
||||||
public static IContainer ValueCell(this IContainer container) => container.Cell(false);
|
public static IContainer ValueCell(this IContainer container) => container.Cell(false);
|
||||||
public static void ValueCell(this IContainer container, string text) => container.ValueCell().Text(text);
|
public static void ValueCell(this IContainer container, string text) => container.ValueCell().Text(text, TextStyle.Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FrameExample
|
public class FrameExample
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
using System;
|
using System.IO;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using QuestPDF.Drawing.Exceptions;
|
using QuestPDF.Drawing.Exceptions;
|
||||||
using QuestPDF.Examples.Engine;
|
using QuestPDF.Examples.Engine;
|
||||||
using QuestPDF.Fluent;
|
using QuestPDF.Fluent;
|
||||||
using QuestPDF.Helpers;
|
using QuestPDF.Helpers;
|
||||||
using QuestPDF.Infrastructure;
|
|
||||||
|
|
||||||
namespace QuestPDF.Examples
|
namespace QuestPDF.Examples
|
||||||
{
|
{
|
||||||
@@ -37,21 +34,6 @@ namespace QuestPDF.Examples
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void DynamicImage()
|
|
||||||
{
|
|
||||||
RenderingTest
|
|
||||||
.Create()
|
|
||||||
.PageSize(450, 350)
|
|
||||||
.ProducePdf()
|
|
||||||
.ShowResults()
|
|
||||||
.Render(page =>
|
|
||||||
{
|
|
||||||
page.Padding(25)
|
|
||||||
.Image(Placeholders.Image);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Exception()
|
public void Exception()
|
||||||
{
|
{
|
||||||
@@ -65,25 +47,5 @@ namespace QuestPDF.Examples
|
|||||||
.Render(page => page.Image("non_existent.png"));
|
.Render(page => page.Image("non_existent.png"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ImageResolutionScaling()
|
|
||||||
{
|
|
||||||
var image = Image.FromFile("large-image.jpg");
|
|
||||||
|
|
||||||
Document
|
|
||||||
.Create(document =>
|
|
||||||
{
|
|
||||||
document.Page(page =>
|
|
||||||
{
|
|
||||||
page.Size(210, 210);
|
|
||||||
page.Margin(50);
|
|
||||||
page.Content().Image(image);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.GeneratePdf($"test.pdf");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,8 +74,7 @@ namespace QuestPDF.Examples
|
|||||||
.PrimaryLayer()
|
.PrimaryLayer()
|
||||||
.AlignCenter()
|
.AlignCenter()
|
||||||
.AlignMiddle()
|
.AlignMiddle()
|
||||||
.Text(sizeText)
|
.Text(sizeText, TextStyle.Default.Size(15));
|
||||||
.FontSize(15);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -120,42 +119,5 @@ namespace QuestPDF.Examples
|
|||||||
.Background(Placeholders.BackgroundColor());
|
.Background(Placeholders.BackgroundColor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void RepeatingInlinedInHeader_Test()
|
|
||||||
{
|
|
||||||
RenderingTest
|
|
||||||
.Create()
|
|
||||||
.ProduceImages()
|
|
||||||
.ShowResults()
|
|
||||||
.RenderDocument(document =>
|
|
||||||
{
|
|
||||||
document.Page(page =>
|
|
||||||
{
|
|
||||||
page.Size(PageSizes.A4);
|
|
||||||
page.Margin(1, Unit.Inch);
|
|
||||||
page.PageColor(Colors.White);
|
|
||||||
|
|
||||||
page.Header()
|
|
||||||
.Inlined(inlined =>
|
|
||||||
{
|
|
||||||
inlined.Spacing(10);
|
|
||||||
|
|
||||||
foreach (var i in Enumerable.Range(5, 5))
|
|
||||||
inlined.Item().Width(i * 10).Height(20).Background(Colors.Red.Medium);
|
|
||||||
});
|
|
||||||
|
|
||||||
page.Content()
|
|
||||||
.PaddingVertical(20)
|
|
||||||
.Column(column =>
|
|
||||||
{
|
|
||||||
column.Spacing(25);
|
|
||||||
|
|
||||||
foreach (var i in Enumerable.Range(10, 20))
|
|
||||||
column.Item().Width(i * 10).Height(50).Background(Colors.Grey.Lighten2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
using System.IO;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using QuestPDF.Examples.Engine;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
|
||||||
|
namespace QuestPDF.Examples
|
||||||
|
{
|
||||||
|
public class LineExamples
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void LineHorizontal()
|
||||||
|
{
|
||||||
|
RenderingTest
|
||||||
|
.Create()
|
||||||
|
.PageSize(PageSizes.A5)
|
||||||
|
.ProducePdf()
|
||||||
|
.ShowResults()
|
||||||
|
.Render(container =>
|
||||||
|
{
|
||||||
|
container.Padding(25).Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().Text("Above text");
|
||||||
|
column.Item().PaddingVertical(10).LineHorizontal(1).LineColor(Colors.Blue.Accent1);
|
||||||
|
column.Item().Text("Below text");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void LineVertical()
|
||||||
|
{
|
||||||
|
RenderingTest
|
||||||
|
.Create()
|
||||||
|
.PageSize(PageSizes.A5)
|
||||||
|
.ProducePdf()
|
||||||
|
.ShowResults()
|
||||||
|
.Render(container =>
|
||||||
|
{
|
||||||
|
container.Padding(25).Inlined(inlined =>
|
||||||
|
{
|
||||||
|
inlined.Spacing(5);
|
||||||
|
inlined.Item().Text("Above text");
|
||||||
|
inlined.Item().LineVertical(1).LineColor(Colors.Blue.Accent1);
|
||||||
|
inlined.Item().Text("Below text");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-3
@@ -19,12 +19,10 @@ namespace QuestPDF.Examples
|
|||||||
{
|
{
|
||||||
var url = "https://picsum.photos/300/200";
|
var url = "https://picsum.photos/300/200";
|
||||||
|
|
||||||
if (Greyscale)
|
if(Greyscale)
|
||||||
url += "?grayscale";
|
url += "?grayscale";
|
||||||
|
|
||||||
using var client = new WebClient();
|
using var client = new WebClient();
|
||||||
client.Headers.Add("user-agent", "QuestPDF/1.0 Unit Testing");
|
|
||||||
|
|
||||||
var response = client.DownloadData(url);
|
var response = client.DownloadData(url);
|
||||||
container.Image(response);
|
container.Image(response);
|
||||||
}
|
}
|
||||||
@@ -50,8 +50,7 @@ namespace QuestPDF.Examples
|
|||||||
.Background("FFF")
|
.Background("FFF")
|
||||||
.Padding(5)
|
.Padding(5)
|
||||||
.AlignCenter()
|
.AlignCenter()
|
||||||
.Text("Sample text")
|
.Text("Sample text", TextStyle.Default.FontType("Segoe UI emoji"));
|
||||||
.FontFamily("Segoe UI emoji");
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
+6
-16
@@ -1,18 +1,17 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
|
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
|
||||||
<PackageReference Include="microcharts" Version="0.9.5.9" />
|
<PackageReference Include="microcharts" Version="0.9.5.9" />
|
||||||
<PackageReference Include="nunit" Version="3.13.3" />
|
<PackageReference Include="nunit" Version="3.13.2" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.3.1" />
|
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
|
||||||
<PackageReference Include="SkiaSharp" Version="2.88.3" />
|
<PackageReference Include="SkiaSharp" Version="2.80.3" />
|
||||||
<PackageReference Include="Svg.Skia" Version="0.5.18" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -29,15 +28,6 @@
|
|||||||
<None Update="logo.png">
|
<None Update="logo.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Update="pdf-icon.svg">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Update="large-image.png">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Update="large-image.jpg">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -89,57 +89,5 @@ namespace QuestPDF.Examples
|
|||||||
.ShowOnce();
|
.ShowOnce();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Stability_NoItems()
|
|
||||||
{
|
|
||||||
RenderingTest
|
|
||||||
.Create()
|
|
||||||
.ProducePdf()
|
|
||||||
.MaxPages(100)
|
|
||||||
.PageSize(250, 150)
|
|
||||||
.Render(container =>
|
|
||||||
{
|
|
||||||
container
|
|
||||||
.Padding(25)
|
|
||||||
.Row(row => { });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void RowElementForRelativeHeightDivision()
|
|
||||||
{
|
|
||||||
RenderingTest
|
|
||||||
.Create()
|
|
||||||
.ProduceImages()
|
|
||||||
.ShowResults()
|
|
||||||
.MaxPages(100)
|
|
||||||
.PageSize(250, 400)
|
|
||||||
.Render(container =>
|
|
||||||
{
|
|
||||||
container
|
|
||||||
.Padding(25)
|
|
||||||
.AlignLeft()
|
|
||||||
.RotateRight()
|
|
||||||
.Row(row =>
|
|
||||||
{
|
|
||||||
row.Spacing(20);
|
|
||||||
|
|
||||||
row.RelativeItem(1).Element(Content);
|
|
||||||
row.RelativeItem(2).Element(Content);
|
|
||||||
row.RelativeItem(3).Element(Content);
|
|
||||||
|
|
||||||
void Content(IContainer container)
|
|
||||||
{
|
|
||||||
container
|
|
||||||
.RotateLeft()
|
|
||||||
.Border(1)
|
|
||||||
.Background(Placeholders.BackgroundColor())
|
|
||||||
.Padding(5)
|
|
||||||
.Text(Placeholders.Label());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-4
@@ -15,7 +15,7 @@ namespace QuestPDF.Examples
|
|||||||
RenderingTest
|
RenderingTest
|
||||||
.Create()
|
.Create()
|
||||||
.PageSize(PageSizes.A4)
|
.PageSize(PageSizes.A4)
|
||||||
.ProduceImages()
|
.ProducePdf()
|
||||||
.ShowResults()
|
.ShowResults()
|
||||||
.Render(container =>
|
.Render(container =>
|
||||||
{
|
{
|
||||||
@@ -23,15 +23,15 @@ namespace QuestPDF.Examples
|
|||||||
{
|
{
|
||||||
var text = Placeholders.Paragraph();
|
var text = Placeholders.Paragraph();
|
||||||
|
|
||||||
foreach (var i in Enumerable.Range(2, 5))
|
foreach (var i in Enumerable.Range(0, 16))
|
||||||
{
|
{
|
||||||
column
|
column
|
||||||
.Item()
|
.Item()
|
||||||
.MinimalBox()
|
.MinimalBox()
|
||||||
.Border(1)
|
.Border(1)
|
||||||
.Padding(5)
|
.Padding(5)
|
||||||
.Width(i * 40)
|
.Width(50 + i * 25)
|
||||||
.Height(i * 20)
|
.Height(25 + i * 5)
|
||||||
.ScaleToFit()
|
.ScaleToFit()
|
||||||
.Text(text);
|
.Text(text);
|
||||||
}
|
}
|
||||||
@@ -21,9 +21,9 @@ namespace QuestPDF.Examples
|
|||||||
{
|
{
|
||||||
page.Margin(20);
|
page.Margin(20);
|
||||||
page.Size(PageSizes.A7.Landscape());
|
page.Size(PageSizes.A7.Landscape());
|
||||||
page.PageColor(Colors.White);
|
page.Background(Colors.White);
|
||||||
|
|
||||||
page.Header().Text("With show once").SemiBold();
|
page.Header().Text("With show once", TextStyle.Default.SemiBold());
|
||||||
|
|
||||||
page.Content().PaddingVertical(5).Row(row =>
|
page.Content().PaddingVertical(5).Row(row =>
|
||||||
{
|
{
|
||||||
@@ -21,7 +21,7 @@ namespace QuestPDF.Examples
|
|||||||
{
|
{
|
||||||
page.Margin(20);
|
page.Margin(20);
|
||||||
page.Size(PageSizes.A7.Landscape());
|
page.Size(PageSizes.A7.Landscape());
|
||||||
page.PageColor(Colors.White);
|
page.Background(Colors.White);
|
||||||
|
|
||||||
page.Header().Column(column =>
|
page.Header().Column(column =>
|
||||||
{
|
{
|
||||||
@@ -31,8 +31,7 @@ namespace QuestPDF.Examples
|
|||||||
|
|
||||||
page.Content()
|
page.Content()
|
||||||
.PaddingVertical(10)
|
.PaddingVertical(10)
|
||||||
.Text(Placeholders.Paragraphs())
|
.Text(Placeholders.Paragraphs(), TextStyle.Default.Color(Colors.Grey.Medium));
|
||||||
.FontColor(Colors.Grey.Medium);
|
|
||||||
|
|
||||||
page.Footer().Text(text =>
|
page.Footer().Text(text =>
|
||||||
{
|
{
|
||||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using QuestPDF.Drawing;
|
using QuestPDF.Drawing;
|
||||||
@@ -50,39 +49,6 @@ namespace QuestPDF.Examples
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void PagingSupport()
|
|
||||||
{
|
|
||||||
RenderingTest
|
|
||||||
.Create()
|
|
||||||
.ProducePdf()
|
|
||||||
.PageSize(420, 220)
|
|
||||||
.ShowResults()
|
|
||||||
.Render(container =>
|
|
||||||
{
|
|
||||||
container
|
|
||||||
.Padding(10)
|
|
||||||
.MinimalBox()
|
|
||||||
.Border(1)
|
|
||||||
.Table(table =>
|
|
||||||
{
|
|
||||||
table.ColumnsDefinition(columns =>
|
|
||||||
{
|
|
||||||
columns.RelativeColumn();
|
|
||||||
columns.RelativeColumn();
|
|
||||||
columns.RelativeColumn();
|
|
||||||
columns.RelativeColumn();
|
|
||||||
});
|
|
||||||
|
|
||||||
// by using custom 'Element' method, we can reuse visual configuration
|
|
||||||
table.Cell().Element(Block).Text(Placeholders.Label());
|
|
||||||
table.Cell().Element(Block).Text(Placeholders.Label());
|
|
||||||
table.Cell().Element(Block).Text(Placeholders.Paragraph());
|
|
||||||
table.Cell().Element(Block).Text(Placeholders.Label());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void DefaultCellStyle()
|
public void DefaultCellStyle()
|
||||||
{
|
{
|
||||||
@@ -251,7 +217,7 @@ namespace QuestPDF.Examples
|
|||||||
RenderingTest
|
RenderingTest
|
||||||
.Create()
|
.Create()
|
||||||
.ProduceImages()
|
.ProduceImages()
|
||||||
.PageSize(220, 170)
|
.PageSize(220, 220)
|
||||||
.ShowResults()
|
.ShowResults()
|
||||||
.Render(container =>
|
.Render(container =>
|
||||||
{
|
{
|
||||||
@@ -300,18 +266,17 @@ namespace QuestPDF.Examples
|
|||||||
columns.RelativeColumn();
|
columns.RelativeColumn();
|
||||||
columns.RelativeColumn();
|
columns.RelativeColumn();
|
||||||
columns.RelativeColumn();
|
columns.RelativeColumn();
|
||||||
columns.RelativeColumn();
|
|
||||||
columns.RelativeColumn();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var image = Placeholders.Image(400, 300);
|
table.Cell().RowSpan(4).Element(Block).Text("1");
|
||||||
|
|
||||||
table.Cell().Image(image);
|
table.Cell().RowSpan(2).Element(Block).Text("2");
|
||||||
table.Cell().Image(image);
|
table.Cell().RowSpan(1).Element(Block).Text("3");
|
||||||
table.Cell().Image(image);
|
table.Cell().RowSpan(1).Element(Block).Text("4");
|
||||||
table.Cell().Image(image);
|
|
||||||
table.Cell().Image(image);
|
table.Cell().RowSpan(2).Element(Block).Text("5");
|
||||||
table.Cell().Image(image);
|
table.Cell().RowSpan(1).Element(Block).Text("6");
|
||||||
|
table.Cell().RowSpan(1).Element(Block).Text("7");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -391,12 +356,12 @@ namespace QuestPDF.Examples
|
|||||||
table.Cell().Element(CellStyle).ExtendHorizontal().AlignLeft().Text(page.name);
|
table.Cell().Element(CellStyle).ExtendHorizontal().AlignLeft().Text(page.name);
|
||||||
|
|
||||||
// inches
|
// inches
|
||||||
table.Cell().Element(CellStyle).Text(page.width.ToString(CultureInfo.InvariantCulture));
|
table.Cell().Element(CellStyle).Text(page.width);
|
||||||
table.Cell().Element(CellStyle).Text(page.height.ToString(CultureInfo.InvariantCulture));
|
table.Cell().Element(CellStyle).Text(page.height);
|
||||||
|
|
||||||
// points
|
// points
|
||||||
table.Cell().Element(CellStyle).Text((page.width * inchesToPoints).ToString(CultureInfo.InvariantCulture));
|
table.Cell().Element(CellStyle).Text(page.width * inchesToPoints);
|
||||||
table.Cell().Element(CellStyle).Text((page.height * inchesToPoints).ToString(CultureInfo.InvariantCulture));
|
table.Cell().Element(CellStyle).Text(page.height * inchesToPoints);
|
||||||
|
|
||||||
IContainer CellStyle(IContainer container) => DefaultCellStyle(container, Colors.White);
|
IContainer CellStyle(IContainer container) => DefaultCellStyle(container, Colors.White);
|
||||||
}
|
}
|
||||||
@@ -415,7 +380,7 @@ namespace QuestPDF.Examples
|
|||||||
.EnableCaching()
|
.EnableCaching()
|
||||||
.EnableDebugging(false)
|
.EnableDebugging(false)
|
||||||
.ShowResults()
|
.ShowResults()
|
||||||
.Render(container => GeneratePerformanceStructure(container, 250));
|
.Render(container => GeneratePerformanceStructure(container, 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void GeneratePerformanceStructure(IContainer container, int repeats)
|
public static void GeneratePerformanceStructure(IContainer container, int repeats)
|
||||||
@@ -491,10 +456,8 @@ namespace QuestPDF.Examples
|
|||||||
return container
|
return container
|
||||||
.Border(1)
|
.Border(1)
|
||||||
.Background(Colors.Grey.Lighten3)
|
.Background(Colors.Grey.Lighten3)
|
||||||
.ShowOnce()
|
|
||||||
.MinWidth(50)
|
.MinWidth(50)
|
||||||
.MinHeight(50)
|
.MinHeight(50)
|
||||||
.Padding(10)
|
|
||||||
.AlignCenter()
|
.AlignCenter()
|
||||||
.AlignMiddle();
|
.AlignMiddle();
|
||||||
}
|
}
|
||||||
@@ -23,7 +23,7 @@ namespace QuestPDF.Examples
|
|||||||
.PageSize(PageSizes.A4)
|
.PageSize(PageSizes.A4)
|
||||||
.ProducePdf()
|
.ProducePdf()
|
||||||
.ShowResults()
|
.ShowResults()
|
||||||
.RenderDocument(x => ComposeBook(x, chapters));
|
.Render(x => ComposeBook(x, chapters));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -31,7 +31,7 @@ namespace QuestPDF.Examples
|
|||||||
{
|
{
|
||||||
var chapters = GetBookChapters().ToList();
|
var chapters = GetBookChapters().ToList();
|
||||||
|
|
||||||
var results = PerformTest(128).ToList();
|
var results = PerformTest(16).ToList();
|
||||||
|
|
||||||
Console.WriteLine($"Min: {results.Min():F}");
|
Console.WriteLine($"Min: {results.Min():F}");
|
||||||
Console.WriteLine($"Max: {results.Max():F}");
|
Console.WriteLine($"Max: {results.Max():F}");
|
||||||
@@ -42,8 +42,8 @@ namespace QuestPDF.Examples
|
|||||||
RenderingTest
|
RenderingTest
|
||||||
.Create()
|
.Create()
|
||||||
.PageSize(PageSizes.A4)
|
.PageSize(PageSizes.A4)
|
||||||
.ProducePdf()
|
.ProducePdf()
|
||||||
.RenderDocument(x => ComposeBook(x, chapters));
|
.Render(x => ComposeBook(x, chapters));
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<float> PerformTest(int attempts)
|
IEnumerable<float> PerformTest(int attempts)
|
||||||
@@ -102,29 +102,36 @@ namespace QuestPDF.Examples
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ComposeBook(IDocumentContainer container, ICollection<BookChapter> chapters)
|
private void ComposeBook(IContainer container, ICollection<BookChapter> chapters)
|
||||||
{
|
{
|
||||||
var subtitleStyle = TextStyle.Default.Size(24).SemiBold().Color(Colors.Blue.Medium);
|
var subtitleStyle = TextStyle.Default.Size(24).SemiBold().Color(Colors.Blue.Medium);
|
||||||
var normalStyle = TextStyle.Default.Size(14);
|
var normalStyle = TextStyle.Default.Size(14);
|
||||||
|
|
||||||
container.Page(page =>
|
ComposePage(container);
|
||||||
|
|
||||||
|
void ComposePage(IContainer container)
|
||||||
{
|
{
|
||||||
page.Margin(50);
|
container
|
||||||
|
.Padding(50)
|
||||||
|
.Decoration(decoration =>
|
||||||
|
{
|
||||||
|
decoration
|
||||||
|
.Content()
|
||||||
|
.Column(column =>
|
||||||
|
{
|
||||||
|
column.Item().Element(Title);
|
||||||
|
column.Item().PageBreak();
|
||||||
|
column.Item().Element(TableOfContents);
|
||||||
|
column.Item().PageBreak();
|
||||||
|
|
||||||
page.Content().PaddingVertical(10).Column(column =>
|
Chapters(column);
|
||||||
{
|
|
||||||
column.Item().Element(Title);
|
|
||||||
column.Item().PageBreak();
|
|
||||||
column.Item().Element(TableOfContents);
|
|
||||||
column.Item().PageBreak();
|
|
||||||
|
|
||||||
Chapters(column);
|
column.Item().Element(Acknowledgements);
|
||||||
|
});
|
||||||
|
|
||||||
column.Item().Element(Acknowledgements);
|
decoration.After().Element(Footer);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
page.Footer().Element(Footer);
|
|
||||||
});
|
|
||||||
|
|
||||||
void Title(IContainer container)
|
void Title(IContainer container)
|
||||||
{
|
{
|
||||||
@@ -134,8 +141,8 @@ namespace QuestPDF.Examples
|
|||||||
.AlignBottom()
|
.AlignBottom()
|
||||||
.Column(column =>
|
.Column(column =>
|
||||||
{
|
{
|
||||||
column.Item().Text("Quo Vadis").FontSize(72).Bold().FontColor(Colors.Blue.Darken2);
|
column.Item().Text("Quo Vadis", TextStyle.Default.Size(72).Bold().Color(Colors.Blue.Darken2));
|
||||||
column.Item().Text("Henryk Sienkiewicz").FontSize(24).FontColor(Colors.Grey.Darken2);
|
column.Item().Text("Henryk Sienkiewicz", TextStyle.Default.Size(24).Color(Colors.Grey.Darken2));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,8 +156,8 @@ namespace QuestPDF.Examples
|
|||||||
{
|
{
|
||||||
column.Item().InternalLink(chapter.Title).Row(row =>
|
column.Item().InternalLink(chapter.Title).Row(row =>
|
||||||
{
|
{
|
||||||
row.RelativeItem().Text(chapter.Title).Style(normalStyle);
|
row.RelativeItem().Text(chapter.Title, normalStyle);
|
||||||
row.ConstantItem(100).AlignRight().Text(text => text.BeginPageNumberOfSection(chapter.Title).Style(normalStyle));
|
row.ConstantItem(100).AlignRight().Text(text => text.PageNumberOfLocation(chapter.Title, normalStyle));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -173,7 +180,7 @@ namespace QuestPDF.Examples
|
|||||||
column.Item().Text(text =>
|
column.Item().Text(text =>
|
||||||
{
|
{
|
||||||
text.ParagraphSpacing(5);
|
text.ParagraphSpacing(5);
|
||||||
text.Span(content).Style(normalStyle);
|
text.Span(content, normalStyle);
|
||||||
});
|
});
|
||||||
|
|
||||||
column.Item().PageBreak();
|
column.Item().PageBreak();
|
||||||
@@ -191,7 +198,7 @@ namespace QuestPDF.Examples
|
|||||||
text.DefaultTextStyle(normalStyle);
|
text.DefaultTextStyle(normalStyle);
|
||||||
|
|
||||||
text.Span("Ten dokument został wygenerowany na podstawie książki w formacie TXT opublikowanej w serwisie ");
|
text.Span("Ten dokument został wygenerowany na podstawie książki w formacie TXT opublikowanej w serwisie ");
|
||||||
text.Hyperlink("wolnelektury.pl", "https://wolnelektury.pl/").FontColor(Colors.Blue.Medium).Underline();
|
text.ExternalLocation("wolnelektury.pl", "https://wolnelektury.pl/", normalStyle.Color(Colors.Blue.Medium).Underline());
|
||||||
text.Span(". Dziękuję za wspieranie polskiego czytelnictwa!");
|
text.Span(". Dziękuję za wspieranie polskiego czytelnictwa!");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -199,7 +206,7 @@ namespace QuestPDF.Examples
|
|||||||
|
|
||||||
void SectionTitle(ColumnDescriptor column, string text)
|
void SectionTitle(ColumnDescriptor column, string text)
|
||||||
{
|
{
|
||||||
column.Item().Location(text).Text(text).Style(subtitleStyle);
|
column.Item().Location(text).Text(text, subtitleStyle);
|
||||||
column.Item().PaddingTop(10).PaddingBottom(50).BorderBottom(1).BorderColor(Colors.Grey.Lighten2).ExtendHorizontal();
|
column.Item().PaddingTop(10).PaddingBottom(50).BorderBottom(1).BorderColor(Colors.Grey.Lighten2).ExtendHorizontal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,271 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using QuestPDF.Examples.Engine;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
|
||||||
|
namespace QuestPDF.Examples
|
||||||
|
{
|
||||||
|
public class TextExamples
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void SimpleTextBlock()
|
||||||
|
{
|
||||||
|
RenderingTest
|
||||||
|
.Create()
|
||||||
|
.PageSize(500, 300)
|
||||||
|
|
||||||
|
.ProduceImages()
|
||||||
|
.ShowResults()
|
||||||
|
.Render(container =>
|
||||||
|
{
|
||||||
|
container
|
||||||
|
.Padding(5)
|
||||||
|
.MinimalBox()
|
||||||
|
.Border(1)
|
||||||
|
.Padding(10)
|
||||||
|
.Text(text =>
|
||||||
|
{
|
||||||
|
text.DefaultTextStyle(TextStyle.Default.Size(20));
|
||||||
|
text.Span("This is a normal text, followed by an ");
|
||||||
|
text.Span("underlined red text.", TextStyle.Default.Size(20).Color(Colors.Red.Medium).Underline());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ParagraphSpacing()
|
||||||
|
{
|
||||||
|
RenderingTest
|
||||||
|
.Create()
|
||||||
|
.PageSize(500, 300)
|
||||||
|
.ProduceImages()
|
||||||
|
.ShowResults()
|
||||||
|
.Render(container =>
|
||||||
|
{
|
||||||
|
container
|
||||||
|
.Padding(5)
|
||||||
|
.MinimalBox()
|
||||||
|
.Border(1)
|
||||||
|
.Padding(10)
|
||||||
|
.Text(text =>
|
||||||
|
{
|
||||||
|
text.ParagraphSpacing(10);
|
||||||
|
|
||||||
|
foreach (var i in Enumerable.Range(1, 3))
|
||||||
|
{
|
||||||
|
text.Span($"Paragraph {i}: ", TextStyle.Default.SemiBold());
|
||||||
|
text.Line(Placeholders.Paragraph());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CustomElement()
|
||||||
|
{
|
||||||
|
RenderingTest
|
||||||
|
.Create()
|
||||||
|
.PageSize(500, 200)
|
||||||
|
.ProduceImages()
|
||||||
|
.ShowResults()
|
||||||
|
.Render(container =>
|
||||||
|
{
|
||||||
|
container
|
||||||
|
.Padding(5)
|
||||||
|
.MinimalBox()
|
||||||
|
.Border(1)
|
||||||
|
.Padding(10)
|
||||||
|
.Text(text =>
|
||||||
|
{
|
||||||
|
text.DefaultTextStyle(TextStyle.Default.Size(20));
|
||||||
|
text.Span("This is a random image aligned to the baseline: ");
|
||||||
|
|
||||||
|
text.Element()
|
||||||
|
.PaddingBottom(-6)
|
||||||
|
.Height(24)
|
||||||
|
.Width(48)
|
||||||
|
.Image(Placeholders.Image);
|
||||||
|
|
||||||
|
text.Span(".");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TextElements()
|
||||||
|
{
|
||||||
|
RenderingTest
|
||||||
|
.Create()
|
||||||
|
.PageSize(PageSizes.A4)
|
||||||
|
.ProducePdf()
|
||||||
|
.ShowResults()
|
||||||
|
.Render(container =>
|
||||||
|
{
|
||||||
|
container
|
||||||
|
.Padding(20)
|
||||||
|
.Padding(10)
|
||||||
|
.MinimalBox()
|
||||||
|
.Border(1)
|
||||||
|
.Padding(5)
|
||||||
|
.Padding(10)
|
||||||
|
.Text(text =>
|
||||||
|
{
|
||||||
|
text.DefaultTextStyle(TextStyle.Default);
|
||||||
|
text.AlignLeft();
|
||||||
|
text.ParagraphSpacing(10);
|
||||||
|
|
||||||
|
text.Line(Placeholders.LoremIpsum());
|
||||||
|
|
||||||
|
text.Span($"This is target text that should show up. {DateTime.UtcNow:T} > This is a short sentence that will be wrapped into second line hopefully, right? <", TextStyle.Default.Underline());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Textcolumn()
|
||||||
|
{
|
||||||
|
RenderingTest
|
||||||
|
.Create()
|
||||||
|
.PageSize(PageSizes.A4)
|
||||||
|
.ProducePdf()
|
||||||
|
.ShowResults()
|
||||||
|
.Render(container =>
|
||||||
|
{
|
||||||
|
container
|
||||||
|
.Padding(20)
|
||||||
|
.Padding(10)
|
||||||
|
.MinimalBox()
|
||||||
|
.Border(1)
|
||||||
|
.Padding(5)
|
||||||
|
.Padding(10)
|
||||||
|
.Text(text =>
|
||||||
|
{
|
||||||
|
text.DefaultTextStyle(TextStyle.Default);
|
||||||
|
text.AlignLeft();
|
||||||
|
text.ParagraphSpacing(10);
|
||||||
|
|
||||||
|
foreach (var i in Enumerable.Range(1, 100))
|
||||||
|
text.Line($"{i}: {Placeholders.Paragraph()}");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void SpaceIssue()
|
||||||
|
{
|
||||||
|
RenderingTest
|
||||||
|
.Create()
|
||||||
|
.PageSize(PageSizes.A4)
|
||||||
|
.ProducePdf()
|
||||||
|
.ShowResults()
|
||||||
|
.Render(container =>
|
||||||
|
{
|
||||||
|
container
|
||||||
|
.Padding(20)
|
||||||
|
.Padding(10)
|
||||||
|
.MinimalBox()
|
||||||
|
.Border(1)
|
||||||
|
.Padding(5)
|
||||||
|
.Padding(10)
|
||||||
|
.Text(text =>
|
||||||
|
{
|
||||||
|
text.DefaultTextStyle(TextStyle.Default);
|
||||||
|
text.AlignLeft();
|
||||||
|
text.ParagraphSpacing(10);
|
||||||
|
|
||||||
|
text.Span(Placeholders.LoremIpsum());
|
||||||
|
|
||||||
|
text.EmptyLine();
|
||||||
|
|
||||||
|
text.Span("This text is a normal text, ");
|
||||||
|
text.Span("this is a bold text, ", TextStyle.Default.Bold());
|
||||||
|
text.Span("this is a red and underlined text, ", TextStyle.Default.Color(Colors.Red.Medium).Underline());
|
||||||
|
text.Span("and this is slightly bigger text.", TextStyle.Default.Size(16));
|
||||||
|
|
||||||
|
text.EmptyLine();
|
||||||
|
|
||||||
|
text.Span("The new text element also supports injecting custom content between words: ");
|
||||||
|
text.Element().PaddingBottom(-10).Height(16).Width(32).Image(Placeholders.Image);
|
||||||
|
text.Span(".");
|
||||||
|
|
||||||
|
text.EmptyLine();
|
||||||
|
|
||||||
|
text.Span("This is page number ");
|
||||||
|
text.CurrentPageNumber();
|
||||||
|
text.Span(" out of ");
|
||||||
|
text.TotalPages();
|
||||||
|
|
||||||
|
text.EmptyLine();
|
||||||
|
|
||||||
|
text.ExternalLocation("Please visit QuestPDF website", "https://www.questpdf.com");
|
||||||
|
|
||||||
|
text.EmptyLine();
|
||||||
|
|
||||||
|
text.Span(Placeholders.Paragraphs());
|
||||||
|
|
||||||
|
|
||||||
|
text.EmptyLine();
|
||||||
|
|
||||||
|
text.Span(Placeholders.Paragraphs(), TextStyle.Default.Italic());
|
||||||
|
|
||||||
|
text.Line("This is target text that does not show up. " + Placeholders.Paragraph());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void HugeList()
|
||||||
|
{
|
||||||
|
RenderingTest
|
||||||
|
.Create()
|
||||||
|
.PageSize(PageSizes.A4)
|
||||||
|
.ProducePdf()
|
||||||
|
.ShowResults()
|
||||||
|
.Render(container =>
|
||||||
|
{
|
||||||
|
container
|
||||||
|
.Padding(20)
|
||||||
|
.Padding(10)
|
||||||
|
.MinimalBox()
|
||||||
|
.Border(1)
|
||||||
|
.Padding(5)
|
||||||
|
.Padding(10)
|
||||||
|
.Text(text =>
|
||||||
|
{
|
||||||
|
text.DefaultTextStyle(TextStyle.Default);
|
||||||
|
text.AlignLeft();
|
||||||
|
text.ParagraphSpacing(10);
|
||||||
|
|
||||||
|
text.Span("This text is a normal text, ");
|
||||||
|
text.Span("this is a bold text, ", TextStyle.Default.Bold());
|
||||||
|
text.Span("this is a red and underlined text, ", TextStyle.Default.Color(Colors.Red.Medium).Underline());
|
||||||
|
text.Span("and this is slightly bigger text.", TextStyle.Default.Size(16));
|
||||||
|
|
||||||
|
text.Span("The new text element also supports injecting custom content between words: ");
|
||||||
|
text.Element().PaddingBottom(-10).Height(16).Width(32).Image(Placeholders.Image);
|
||||||
|
text.Span(".");
|
||||||
|
|
||||||
|
text.EmptyLine();
|
||||||
|
|
||||||
|
foreach (var i in Enumerable.Range(1, 100))
|
||||||
|
{
|
||||||
|
text.Line($"{i}: {Placeholders.Paragraph()}");
|
||||||
|
|
||||||
|
text.ExternalLocation("Please visit QuestPDF website", "https://www.questpdf.com");
|
||||||
|
|
||||||
|
text.Span("This is page number ");
|
||||||
|
text.CurrentPageNumber();
|
||||||
|
text.Span(" out of ");
|
||||||
|
text.TotalPages();
|
||||||
|
|
||||||
|
text.EmptyLine();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using SkiaSharp;
|
||||||
|
|
||||||
|
namespace QuestPDF.ReportSample
|
||||||
|
{
|
||||||
|
public static class Helpers
|
||||||
|
{
|
||||||
|
public static Random Random { get; } = new Random(1);
|
||||||
|
|
||||||
|
public static string GetTestItem(string path) => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", path);
|
||||||
|
|
||||||
|
public static byte[] GetImage(string name)
|
||||||
|
{
|
||||||
|
var photoPath = GetTestItem(name);
|
||||||
|
return SKImage.FromEncodedData(photoPath).EncodedData.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Location RandomLocation()
|
||||||
|
{
|
||||||
|
return new Location
|
||||||
|
{
|
||||||
|
Longitude = Helpers.Random.NextDouble() * 360f - 180f,
|
||||||
|
Latitude = Helpers.Random.NextDouble() * 180f - 90f
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -30,12 +30,12 @@ namespace QuestPDF.ReportSample.Layouts
|
|||||||
{
|
{
|
||||||
column.Item().ShowOnce().Padding(5).AlignMiddle().Row(row =>
|
column.Item().ShowOnce().Padding(5).AlignMiddle().Row(row =>
|
||||||
{
|
{
|
||||||
row.RelativeItem(2).AlignMiddle().Text("PRIMARY HEADER").FontColor(Colors.Grey.Darken3).FontSize(30).Bold();
|
row.RelativeItem(2).AlignMiddle().Text("PRIMARY HEADER", TextStyle.Default.Color(Colors.Grey.Darken3).Size(30).Bold());
|
||||||
row.RelativeItem(1).AlignRight().MinimalBox().AlignMiddle().Background(Colors.Blue.Darken2).Padding(30);
|
row.RelativeItem(1).AlignRight().MinimalBox().AlignMiddle().Background(Colors.Blue.Darken2).Padding(30);
|
||||||
});
|
});
|
||||||
column.Item().SkipOnce().Padding(5).Row(row =>
|
column.Item().SkipOnce().Padding(5).Row(row =>
|
||||||
{
|
{
|
||||||
row.RelativeItem(2).Text("SECONDARY HEADER").FontColor(Colors.Grey.Darken3).FontSize(30).Bold();
|
row.RelativeItem(2).Text("SECONDARY HEADER", TextStyle.Default.Color(Colors.Grey.Darken3).Size(30).Bold());
|
||||||
row.RelativeItem(1).AlignRight().MinimalBox().Background(Colors.Blue.Lighten4).Padding(15);
|
row.RelativeItem(1).AlignRight().MinimalBox().Background(Colors.Blue.Lighten4).Padding(15);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using QuestPDF.Fluent;
|
using QuestPDF.Fluent;
|
||||||
using QuestPDF.Helpers;
|
using QuestPDF.Helpers;
|
||||||
using QuestPDF.Infrastructure;
|
using QuestPDF.Infrastructure;
|
||||||
+2
-3
@@ -23,8 +23,7 @@ namespace QuestPDF.ReportSample.Layouts
|
|||||||
decoration
|
decoration
|
||||||
.Before()
|
.Before()
|
||||||
.PaddingBottom(5)
|
.PaddingBottom(5)
|
||||||
.Text(Model.Title)
|
.Text(Model.Title, Typography.Headline);
|
||||||
.Style(Typography.Headline);
|
|
||||||
|
|
||||||
decoration.Content().Border(0.75f).BorderColor(Colors.Grey.Medium).Column(column =>
|
decoration.Content().Border(0.75f).BorderColor(Colors.Grey.Medium).Column(column =>
|
||||||
{
|
{
|
||||||
@@ -70,7 +69,7 @@ namespace QuestPDF.ReportSample.Layouts
|
|||||||
{
|
{
|
||||||
if (model.PhotoCount == 0)
|
if (model.PhotoCount == 0)
|
||||||
{
|
{
|
||||||
container.Text("No photos").Style(Typography.Normal);
|
container.Text("No photos", Typography.Normal);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
+7
-7
@@ -39,9 +39,9 @@ namespace QuestPDF.ReportSample.Layouts
|
|||||||
|
|
||||||
page.Footer().AlignCenter().Text(text =>
|
page.Footer().AlignCenter().Text(text =>
|
||||||
{
|
{
|
||||||
text.CurrentPageNumber().Format(x => x?.FormatAsRomanNumeral() ?? "-----");
|
text.CurrentPageNumber();
|
||||||
text.Span(" / ");
|
text.Span(" / ");
|
||||||
text.TotalPages().Format(x => x?.FormatAsRomanNumeral() ?? "-----");
|
text.TotalPages();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -54,8 +54,8 @@ namespace QuestPDF.ReportSample.Layouts
|
|||||||
{
|
{
|
||||||
row.Spacing(50);
|
row.Spacing(50);
|
||||||
|
|
||||||
row.RelativeItem().PaddingTop(-10).Text(Model.Title).Style(Typography.Title);
|
row.RelativeItem().PaddingTop(-10).Text(Model.Title, Typography.Title);
|
||||||
row.ConstantItem(90).Hyperlink("https://www.questpdf.com").MaxHeight(30).Component<ImagePlaceholder>();
|
row.ConstantItem(90).ExternalLink("https://www.questpdf.com").MaxHeight(30).Component<ImagePlaceholder>();
|
||||||
});
|
});
|
||||||
|
|
||||||
column.Item().ShowOnce().PaddingVertical(15).Border(1f).BorderColor(Colors.Grey.Lighten1).ExtendHorizontal();
|
column.Item().ShowOnce().PaddingVertical(15).Border(1f).BorderColor(Colors.Grey.Lighten1).ExtendHorizontal();
|
||||||
@@ -69,7 +69,7 @@ namespace QuestPDF.ReportSample.Layouts
|
|||||||
{
|
{
|
||||||
grid.Item().Text(text =>
|
grid.Item().Text(text =>
|
||||||
{
|
{
|
||||||
text.Span($"{field.Label}: ").SemiBold();
|
text.Span($"{field.Label}: ", TextStyle.Default.SemiBold());
|
||||||
text.Span(field.Value);
|
text.Span(field.Value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -88,10 +88,10 @@ namespace QuestPDF.ReportSample.Layouts
|
|||||||
column.Item().PageBreak();
|
column.Item().PageBreak();
|
||||||
|
|
||||||
foreach (var section in Model.Sections)
|
foreach (var section in Model.Sections)
|
||||||
column.Item().Section(section.Title).Component(new SectionTemplate(section));
|
column.Item().Location(section.Title).Component(new SectionTemplate(section));
|
||||||
|
|
||||||
column.Item().PageBreak();
|
column.Item().PageBreak();
|
||||||
column.Item().Section("Photos");
|
column.Item().Location("Photos");
|
||||||
|
|
||||||
foreach (var photo in Model.Photos)
|
foreach (var photo in Model.Photos)
|
||||||
column.Item().Component(new PhotoTemplate(photo));
|
column.Item().Component(new PhotoTemplate(photo));
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
|
||||||
|
namespace QuestPDF.ReportSample.Layouts
|
||||||
|
{
|
||||||
|
public class TableOfContentsTemplate : IComponent
|
||||||
|
{
|
||||||
|
private List<ReportSection> Sections { get; }
|
||||||
|
|
||||||
|
public TableOfContentsTemplate(List<ReportSection> sections)
|
||||||
|
{
|
||||||
|
Sections = sections;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Compose(IContainer container)
|
||||||
|
{
|
||||||
|
container
|
||||||
|
.Decoration(decoration =>
|
||||||
|
{
|
||||||
|
decoration
|
||||||
|
.Before()
|
||||||
|
.PaddingBottom(5)
|
||||||
|
.Text("Table of contents", Typography.Headline);
|
||||||
|
|
||||||
|
decoration.Content().Column(column =>
|
||||||
|
{
|
||||||
|
column.Spacing(5);
|
||||||
|
|
||||||
|
for (var i = 0; i < Sections.Count; i++)
|
||||||
|
column.Item().Element(c => DrawLink(c, i+1, Sections[i].Title));
|
||||||
|
|
||||||
|
column.Item().Element(c => DrawLink(c, Sections.Count+1, "Photos"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawLink(IContainer container, int number, string locationName)
|
||||||
|
{
|
||||||
|
container
|
||||||
|
.InternalLink(locationName)
|
||||||
|
.Row(row =>
|
||||||
|
{
|
||||||
|
row.ConstantItem(25).Text($"{number}.");
|
||||||
|
row.RelativeItem().Text(locationName);
|
||||||
|
row.ConstantItem(150).AlignRight().Text(text => text.PageNumberOfLocation(locationName));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using BenchmarkDotNet.Attributes;
|
||||||
|
using BenchmarkDotNet.Configs;
|
||||||
|
using BenchmarkDotNet.Engines;
|
||||||
|
using BenchmarkDotNet.Running;
|
||||||
|
using Microsoft.VisualStudio.TestPlatform.TestHost;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using QuestPDF.Drawing;
|
||||||
|
using QuestPDF.Drawing.Proxy;
|
||||||
|
using QuestPDF.Elements;
|
||||||
|
using QuestPDF.Helpers;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using QuestPDF.ReportSample.Layouts;
|
||||||
|
|
||||||
|
namespace QuestPDF.ReportSample
|
||||||
|
{
|
||||||
|
[SimpleJob(RunStrategy.Monitoring, launchCount: 0, warmupCount: 1, targetCount: 256)]
|
||||||
|
[MinColumn, MaxColumn, MeanColumn, MedianColumn]
|
||||||
|
public class PerformanceTests
|
||||||
|
{
|
||||||
|
private PageContext PageContext { get; set; }
|
||||||
|
private DocumentMetadata Metadata { get; set; }
|
||||||
|
private Container Content { get; set; }
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Run()
|
||||||
|
{
|
||||||
|
ImagePlaceholder.Solid = true;
|
||||||
|
|
||||||
|
var configuration = ManualConfig
|
||||||
|
.Create(DefaultConfig.Instance)
|
||||||
|
.WithOptions(ConfigOptions.DisableOptimizationsValidator);
|
||||||
|
|
||||||
|
BenchmarkRunner.Run<PerformanceTests>(configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
[IterationSetup]
|
||||||
|
public void GenerateReportData()
|
||||||
|
{
|
||||||
|
ImagePlaceholder.Solid = true;
|
||||||
|
|
||||||
|
var model = DataSource.GetReport();
|
||||||
|
var report = new StandardReport(model);
|
||||||
|
Metadata = report.GetMetadata();
|
||||||
|
|
||||||
|
var documentContainer = new DocumentContainer();
|
||||||
|
report.Compose(documentContainer);
|
||||||
|
Content = documentContainer.Compose();
|
||||||
|
|
||||||
|
PageContext = new PageContext();
|
||||||
|
DocumentGenerator.RenderPass(PageContext, new FreeCanvas(), Content, Metadata, null);
|
||||||
|
|
||||||
|
var sw = new Stopwatch();
|
||||||
|
sw.Start();
|
||||||
|
|
||||||
|
Content.VisitChildren(x =>
|
||||||
|
{
|
||||||
|
if (x is ICacheable)
|
||||||
|
x.CreateProxy(y => new CacheProxy(y));
|
||||||
|
});
|
||||||
|
|
||||||
|
sw.Stop();
|
||||||
|
Console.WriteLine($"Creating cache took: {sw.ElapsedMilliseconds}");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public void GenerationTest()
|
||||||
|
{
|
||||||
|
DocumentGenerator.RenderPass(PageContext, new FreeCanvas(), Content, Metadata, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-4
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
<LangVersion>8</LangVersion>
|
<LangVersion>8</LangVersion>
|
||||||
<RootNamespace>QuestPDF.ReportSample</RootNamespace>
|
<RootNamespace>QuestPDF.ReportSample</RootNamespace>
|
||||||
@@ -10,9 +10,9 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
|
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
|
||||||
<PackageReference Include="nunit" Version="3.13.2" />
|
<PackageReference Include="nunit" Version="3.13.2" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.3.1" />
|
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
|
||||||
<PackageReference Include="SkiaSharp" Version="2.88.3" />
|
<PackageReference Include="SkiaSharp" Version="2.80.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
Before Width: | Height: | Size: 993 B After Width: | Height: | Size: 993 B |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
@@ -38,5 +38,21 @@ namespace QuestPDF.ReportSample
|
|||||||
Report.GenerateXps(path);
|
Report.GenerateXps(path);
|
||||||
Process.Start("explorer.exe", path);
|
Process.Start("explorer.exe", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Profile()
|
||||||
|
{
|
||||||
|
ImagePlaceholder.Solid = true;
|
||||||
|
|
||||||
|
var container = new DocumentContainer();
|
||||||
|
Report.Compose(container);
|
||||||
|
var content = container.Compose();
|
||||||
|
|
||||||
|
var metadata = Report.GetMetadata();
|
||||||
|
var pageContext = new PageContext();
|
||||||
|
|
||||||
|
DocumentGenerator.RenderPass(pageContext, new FreeCanvas(), content, metadata, null);
|
||||||
|
DocumentGenerator.RenderPass(pageContext, new FreeCanvas(), content, metadata, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,8 +6,8 @@ namespace QuestPDF.ReportSample
|
|||||||
{
|
{
|
||||||
public static class Typography
|
public static class Typography
|
||||||
{
|
{
|
||||||
public static TextStyle Title => TextStyle.Default.FontFamily(Fonts.Lato).FontColor(Colors.Blue.Darken3).FontSize(26).Black();
|
public static TextStyle Title => TextStyle.Default.FontType(Fonts.Calibri).Color(Colors.Blue.Darken3).Size(26).Black();
|
||||||
public static TextStyle Headline => TextStyle.Default.FontFamily(Fonts.Lato).FontColor(Colors.Blue.Medium).FontSize(16).SemiBold();
|
public static TextStyle Headline => TextStyle.Default.FontType(Fonts.Calibri).Color(Colors.Blue.Medium).Size(16).SemiBold();
|
||||||
public static TextStyle Normal => TextStyle.Default.FontFamily(Fonts.Lato).FontColor(Colors.Black).FontSize(10).LineHeight(1.2f);
|
public static TextStyle Normal => TextStyle.Default.FontType(Fonts.Verdana).Color(Colors.Black).Size(10).LineHeight(1.2f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,43 +86,5 @@ namespace QuestPDF.UnitTests
|
|||||||
.ExpectCanvasTranslate(new Position(-300, 0))
|
.ExpectCanvasTranslate(new Position(-300, 0))
|
||||||
.CheckDrawResult();
|
.CheckDrawResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Draw_HorizontalCenter_VerticalNone()
|
|
||||||
{
|
|
||||||
TestPlan
|
|
||||||
.For(x => new Alignment
|
|
||||||
{
|
|
||||||
Horizontal = HorizontalAlignment.Center,
|
|
||||||
Vertical = null,
|
|
||||||
|
|
||||||
Child = x.CreateChild()
|
|
||||||
})
|
|
||||||
.DrawElement(new Size(400, 300))
|
|
||||||
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: SpacePlan.FullRender(new Size(100, 50)))
|
|
||||||
.ExpectCanvasTranslate(new Position(150, 0))
|
|
||||||
.ExpectChildDraw(new Size(100, 300))
|
|
||||||
.ExpectCanvasTranslate(new Position(-150, 0))
|
|
||||||
.CheckDrawResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Draw_HorizontalNone_VerticalMiddle()
|
|
||||||
{
|
|
||||||
TestPlan
|
|
||||||
.For(x => new Alignment
|
|
||||||
{
|
|
||||||
Horizontal = null,
|
|
||||||
Vertical = VerticalAlignment.Middle,
|
|
||||||
|
|
||||||
Child = x.CreateChild()
|
|
||||||
})
|
|
||||||
.DrawElement(new Size(400, 300))
|
|
||||||
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: SpacePlan.FullRender(new Size(100, 50)))
|
|
||||||
.ExpectCanvasTranslate(new Position(0, 125))
|
|
||||||
.ExpectChildDraw(new Size(400, 50))
|
|
||||||
.ExpectCanvasTranslate(new Position(0, -125))
|
|
||||||
.CheckDrawResult();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
-40
@@ -153,9 +153,7 @@ namespace QuestPDF.UnitTests
|
|||||||
Ratio = 2f
|
Ratio = 2f
|
||||||
})
|
})
|
||||||
.DrawElement(new Size(500, 200))
|
.DrawElement(new Size(500, 200))
|
||||||
.ExpectCanvasTranslate(0, 0)
|
|
||||||
.ExpectChildDraw(new Size(400, 200))
|
.ExpectChildDraw(new Size(400, 200))
|
||||||
.ExpectCanvasTranslate(0, 0)
|
|
||||||
.CheckDrawResult();
|
.CheckDrawResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,45 +168,7 @@ namespace QuestPDF.UnitTests
|
|||||||
Ratio = 2f
|
Ratio = 2f
|
||||||
})
|
})
|
||||||
.DrawElement(new Size(400, 300))
|
.DrawElement(new Size(400, 300))
|
||||||
.ExpectCanvasTranslate(0, 0)
|
|
||||||
.ExpectChildDraw(new Size(400, 200))
|
.ExpectChildDraw(new Size(400, 200))
|
||||||
.ExpectCanvasTranslate(0, 0)
|
|
||||||
.CheckDrawResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void DrawChild_PerWidth_RightToLeft()
|
|
||||||
{
|
|
||||||
TestPlan
|
|
||||||
.For(x => new AspectRatio
|
|
||||||
{
|
|
||||||
Child = x.CreateChild(),
|
|
||||||
Option = AspectRatioOption.FitArea,
|
|
||||||
Ratio = 2f,
|
|
||||||
ContentDirection = ContentDirection.RightToLeft
|
|
||||||
})
|
|
||||||
.DrawElement(new Size(500, 200))
|
|
||||||
.ExpectCanvasTranslate(100, 0)
|
|
||||||
.ExpectChildDraw(new Size(400, 200))
|
|
||||||
.ExpectCanvasTranslate(-100, 0)
|
|
||||||
.CheckDrawResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void DrawChild_PerHeight_RightToLeft()
|
|
||||||
{
|
|
||||||
TestPlan
|
|
||||||
.For(x => new AspectRatio
|
|
||||||
{
|
|
||||||
Child = x.CreateChild(),
|
|
||||||
Option = AspectRatioOption.FitArea,
|
|
||||||
Ratio = 2f,
|
|
||||||
ContentDirection = ContentDirection.RightToLeft
|
|
||||||
})
|
|
||||||
.DrawElement(new Size(400, 300))
|
|
||||||
.ExpectCanvasTranslate(0, 0)
|
|
||||||
.ExpectChildDraw(new Size(400, 200))
|
|
||||||
.ExpectCanvasTranslate(0, 0)
|
|
||||||
.CheckDrawResult();
|
.CheckDrawResult();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -35,9 +35,7 @@ namespace QuestPDF.UnitTests
|
|||||||
})
|
})
|
||||||
.MeasureElement(new Size(400, 300))
|
.MeasureElement(new Size(400, 300))
|
||||||
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: SpacePlan.PartialRender(200, 100))
|
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: SpacePlan.PartialRender(200, 100))
|
||||||
.ExpectCanvasTranslate(0, 0)
|
|
||||||
.ExpectChildDraw(new Size(200, 100))
|
.ExpectChildDraw(new Size(200, 100))
|
||||||
.ExpectCanvasTranslate(0, 0)
|
|
||||||
.CheckDrawResult();
|
.CheckDrawResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,43 +49,7 @@ namespace QuestPDF.UnitTests
|
|||||||
})
|
})
|
||||||
.MeasureElement(new Size(500, 400))
|
.MeasureElement(new Size(500, 400))
|
||||||
.ExpectChildMeasure(expectedInput: new Size(500, 400), returns: SpacePlan.FullRender(300, 200))
|
.ExpectChildMeasure(expectedInput: new Size(500, 400), returns: SpacePlan.FullRender(300, 200))
|
||||||
.ExpectCanvasTranslate(0, 0)
|
|
||||||
.ExpectChildDraw(new Size(300, 200))
|
.ExpectChildDraw(new Size(300, 200))
|
||||||
.ExpectCanvasTranslate(0, 0)
|
|
||||||
.CheckDrawResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Measure_PartialRender_RightToLeft()
|
|
||||||
{
|
|
||||||
TestPlan
|
|
||||||
.For(x => new MinimalBox
|
|
||||||
{
|
|
||||||
Child = x.CreateChild(),
|
|
||||||
ContentDirection = ContentDirection.RightToLeft
|
|
||||||
})
|
|
||||||
.MeasureElement(new Size(400, 300))
|
|
||||||
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: SpacePlan.PartialRender(200, 100))
|
|
||||||
.ExpectCanvasTranslate(200, 0)
|
|
||||||
.ExpectChildDraw(new Size(200, 100))
|
|
||||||
.ExpectCanvasTranslate(-200, 0)
|
|
||||||
.CheckDrawResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Measure_FullRender_RightToLeft()
|
|
||||||
{
|
|
||||||
TestPlan
|
|
||||||
.For(x => new MinimalBox
|
|
||||||
{
|
|
||||||
Child = x.CreateChild(),
|
|
||||||
ContentDirection = ContentDirection.RightToLeft
|
|
||||||
})
|
|
||||||
.MeasureElement(new Size(500, 400))
|
|
||||||
.ExpectChildMeasure(expectedInput: new Size(500, 400), returns: SpacePlan.FullRender(350, 200))
|
|
||||||
.ExpectCanvasTranslate(150, 0)
|
|
||||||
.ExpectChildDraw(new Size(350, 200))
|
|
||||||
.ExpectCanvasTranslate(-150, 0)
|
|
||||||
.CheckDrawResult();
|
.CheckDrawResult();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -8,7 +8,7 @@ namespace QuestPDF.UnitTests
|
|||||||
public class ExternalLinkTests
|
public class ExternalLinkTests
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void Measure() => SimpleContainerTests.Measure<Hyperlink>();
|
public void Measure() => SimpleContainerTests.Measure<ExternalLink>();
|
||||||
|
|
||||||
// TODO: consider tests for the Draw method
|
// TODO: consider tests for the Draw method
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
using NUnit.Framework;
|
||||||
|
using QuestPDF.Drawing;
|
||||||
|
using QuestPDF.Elements;
|
||||||
|
using QuestPDF.Fluent;
|
||||||
|
using QuestPDF.Infrastructure;
|
||||||
|
using QuestPDF.UnitTests.TestEngine;
|
||||||
|
using SkiaSharp;
|
||||||
|
|
||||||
|
namespace QuestPDF.UnitTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class ImageTests
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void Measure_TakesAvailableSpaceRegardlessOfSize()
|
||||||
|
{
|
||||||
|
TestPlan
|
||||||
|
.For(x => new Image
|
||||||
|
{
|
||||||
|
InternalImage = GenerateImage(400, 300)
|
||||||
|
})
|
||||||
|
.MeasureElement(new Size(300, 200))
|
||||||
|
.CheckMeasureResult(SpacePlan.FullRender(300, 200));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Draw_TakesAvailableSpaceRegardlessOfSize()
|
||||||
|
{
|
||||||
|
TestPlan
|
||||||
|
.For(x => new Image
|
||||||
|
{
|
||||||
|
InternalImage = GenerateImage(400, 300)
|
||||||
|
})
|
||||||
|
.DrawElement(new Size(300, 200))
|
||||||
|
.ExpectCanvasDrawImage(new Position(0, 0), new Size(300, 200))
|
||||||
|
.CheckDrawResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Fluent_RecognizesImageProportions()
|
||||||
|
{
|
||||||
|
var image = GenerateImage(600, 200).Encode(SKEncodedImageFormat.Png, 100).ToArray();
|
||||||
|
|
||||||
|
TestPlan
|
||||||
|
.For(x =>
|
||||||
|
{
|
||||||
|
var container = new Container();
|
||||||
|
container.Image(image);
|
||||||
|
return container;
|
||||||
|
})
|
||||||
|
.MeasureElement(new Size(300, 200))
|
||||||
|
.CheckMeasureResult(SpacePlan.FullRender(300, 100));;
|
||||||
|
}
|
||||||
|
|
||||||
|
SKImage GenerateImage(int width, int height)
|
||||||
|
{
|
||||||
|
var imageInfo = new SKImageInfo(width, height);
|
||||||
|
using var surface = SKSurface.Create(imageInfo);
|
||||||
|
return surface.Snapshot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -8,7 +8,7 @@ namespace QuestPDF.UnitTests
|
|||||||
public class InternalLinkTests
|
public class InternalLinkTests
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void Measure() => SimpleContainerTests.Measure<SectionLink>();
|
public void Measure() => SimpleContainerTests.Measure<InternalLink>();
|
||||||
|
|
||||||
// TODO: consider tests for the Draw method
|
// TODO: consider tests for the Draw method
|
||||||
}
|
}
|
||||||
+1
-1
@@ -8,7 +8,7 @@ namespace QuestPDF.UnitTests
|
|||||||
public class InternalLocationTests
|
public class InternalLocationTests
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void Measure() => SimpleContainerTests.Measure<SectionLink>();
|
public void Measure() => SimpleContainerTests.Measure<InternalLink>();
|
||||||
|
|
||||||
// TODO: consider tests for the Draw method
|
// TODO: consider tests for the Draw method
|
||||||
}
|
}
|
||||||
+5
-14
@@ -1,29 +1,20 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="FluentAssertions" Version="6.8.0" />
|
<PackageReference Include="FluentAssertions" Version="6.1.0" />
|
||||||
<PackageReference Include="nunit" Version="3.13.2" />
|
<PackageReference Include="nunit" Version="3.13.2" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.3.1" />
|
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.0" />
|
||||||
<PackageReference Include="SkiaSharp" Version="2.88.3" />
|
<PackageReference Include="SkiaSharp" Version="2.80.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\QuestPDF\QuestPDF.csproj" />
|
<ProjectReference Include="..\QuestPDF\QuestPDF.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Content Include="Resources\FontContent.ttf">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<EmbeddedResource Include="Resources\FontEmbeddedResource.ttf">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</EmbeddedResource>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
+5
-5
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using QuestPDF.Drawing;
|
|
||||||
using QuestPDF.Infrastructure;
|
using QuestPDF.Infrastructure;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
@@ -11,6 +10,7 @@ namespace QuestPDF.UnitTests.TestEngine
|
|||||||
public Action<float> RotateFunc { get; set; }
|
public Action<float> RotateFunc { get; set; }
|
||||||
public Action<float, float> ScaleFunc { get; set; }
|
public Action<float, float> ScaleFunc { get; set; }
|
||||||
public Action<SKImage, Position, Size> DrawImageFunc { get; set; }
|
public Action<SKImage, Position, Size> DrawImageFunc { get; set; }
|
||||||
|
public Action<string, Position, TextStyle> DrawTextFunc { get; set; }
|
||||||
public Action<Position, Size, string> DrawRectFunc { get; set; }
|
public Action<Position, Size, string> DrawRectFunc { get; set; }
|
||||||
|
|
||||||
public void Translate(Position vector) => TranslateFunc(vector);
|
public void Translate(Position vector) => TranslateFunc(vector);
|
||||||
@@ -18,11 +18,11 @@ namespace QuestPDF.UnitTests.TestEngine
|
|||||||
public void Scale(float scaleX, float scaleY) => ScaleFunc(scaleX, scaleY);
|
public void Scale(float scaleX, float scaleY) => ScaleFunc(scaleX, scaleY);
|
||||||
|
|
||||||
public void DrawRectangle(Position vector, Size size, string color) => DrawRectFunc(vector, size, color);
|
public void DrawRectangle(Position vector, Size size, string color) => DrawRectFunc(vector, size, color);
|
||||||
public void DrawText(SKTextBlob skTextBlob, Position position, TextStyle style) => throw new NotImplementedException();
|
public void DrawText(string text, Position position, TextStyle style) => DrawTextFunc(text, position, style);
|
||||||
public void DrawImage(SKImage image, Position position, Size size) => DrawImageFunc(image, position, size);
|
public void DrawImage(SKImage image, Position position, Size size) => DrawImageFunc(image, position, size);
|
||||||
|
|
||||||
public void DrawHyperlink(string url, Size size) => throw new NotImplementedException();
|
public void DrawExternalLink(string url, Size size) => throw new NotImplementedException();
|
||||||
public void DrawSectionLink(string sectionName, Size size) => throw new NotImplementedException();
|
public void DrawLocationLink(string locationName, Size size) => throw new NotImplementedException();
|
||||||
public void DrawSection(string sectionName) => throw new NotImplementedException();
|
public void DrawLocation(string locationName) => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-5
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using QuestPDF.Drawing;
|
|
||||||
using QuestPDF.Infrastructure;
|
using QuestPDF.Infrastructure;
|
||||||
using QuestPDF.UnitTests.TestEngine.Operations;
|
using QuestPDF.UnitTests.TestEngine.Operations;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
@@ -16,11 +15,11 @@ namespace QuestPDF.UnitTests.TestEngine
|
|||||||
public void Scale(float scaleX, float scaleY) => Operations.Add(new CanvasScaleOperation(scaleX, scaleY));
|
public void Scale(float scaleX, float scaleY) => Operations.Add(new CanvasScaleOperation(scaleX, scaleY));
|
||||||
|
|
||||||
public void DrawRectangle(Position vector, Size size, string color) => Operations.Add(new CanvasDrawRectangleOperation(vector, size, color));
|
public void DrawRectangle(Position vector, Size size, string color) => Operations.Add(new CanvasDrawRectangleOperation(vector, size, color));
|
||||||
public void DrawText(SKTextBlob skTextBlob, Position position, TextStyle style) => throw new NotImplementedException();
|
public void DrawText(string text, Position position, TextStyle style) => Operations.Add(new CanvasDrawTextOperation(text, position, style));
|
||||||
public void DrawImage(SKImage image, Position position, Size size) => Operations.Add(new CanvasDrawImageOperation(position, size));
|
public void DrawImage(SKImage image, Position position, Size size) => Operations.Add(new CanvasDrawImageOperation(position, size));
|
||||||
|
|
||||||
public void DrawHyperlink(string url, Size size) => throw new NotImplementedException();
|
public void DrawExternalLink(string url, Size size) => throw new NotImplementedException();
|
||||||
public void DrawSectionLink(string sectionName, Size size) => throw new NotImplementedException();
|
public void DrawLocationLink(string locationName, Size size) => throw new NotImplementedException();
|
||||||
public void DrawSection(string sectionName) => throw new NotImplementedException();
|
public void DrawLocation(string locationName) => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+24
-6
@@ -82,6 +82,19 @@ namespace QuestPDF.UnitTests.TestEngine
|
|||||||
|
|
||||||
Assert.AreEqual(expected.Color, color, "Draw rectangle: color");
|
Assert.AreEqual(expected.Color, color, "Draw rectangle: color");
|
||||||
},
|
},
|
||||||
|
DrawTextFunc = (text, position, style) =>
|
||||||
|
{
|
||||||
|
var expected = GetExpected<CanvasDrawTextOperation>();
|
||||||
|
|
||||||
|
Assert.AreEqual(expected.Text, text);
|
||||||
|
|
||||||
|
Assert.AreEqual(expected.Position.X, position.X, "Draw text: X");
|
||||||
|
Assert.AreEqual(expected.Position.Y, position.Y, "Draw text: Y");
|
||||||
|
|
||||||
|
Assert.AreEqual(expected.Style.Color, style.Color, "Draw text: color");
|
||||||
|
Assert.AreEqual(expected.Style.FontType, style.FontType, "Draw text: font");
|
||||||
|
Assert.AreEqual(expected.Style.Size, style.Size, "Draw text: size");
|
||||||
|
},
|
||||||
DrawImageFunc = (image, position, size) =>
|
DrawImageFunc = (image, position, size) =>
|
||||||
{
|
{
|
||||||
var expected = GetExpected<CanvasDrawImageOperation>();
|
var expected = GetExpected<CanvasDrawImageOperation>();
|
||||||
@@ -188,6 +201,11 @@ namespace QuestPDF.UnitTests.TestEngine
|
|||||||
return AddOperation(new CanvasDrawRectangleOperation(position, size, color));
|
return AddOperation(new CanvasDrawRectangleOperation(position, size, color));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TestPlan ExpectCanvasDrawText(string text, Position position, TextStyle style)
|
||||||
|
{
|
||||||
|
return AddOperation(new CanvasDrawTextOperation(text, position, style));
|
||||||
|
}
|
||||||
|
|
||||||
public TestPlan ExpectCanvasDrawImage(Position position, Size size)
|
public TestPlan ExpectCanvasDrawImage(Position position, Size size)
|
||||||
{
|
{
|
||||||
return AddOperation(new CanvasDrawImageOperation(position, size));
|
return AddOperation(new CanvasDrawImageOperation(position, size));
|
||||||
@@ -195,7 +213,7 @@ namespace QuestPDF.UnitTests.TestEngine
|
|||||||
|
|
||||||
public TestPlan CheckMeasureResult(SpacePlan expected)
|
public TestPlan CheckMeasureResult(SpacePlan expected)
|
||||||
{
|
{
|
||||||
Element.InjectDependencies(null, Canvas);
|
Element.VisitChildren(x => x?.Initialize(null, Canvas));
|
||||||
|
|
||||||
var actual = Element.Measure(OperationInput);
|
var actual = Element.Measure(OperationInput);
|
||||||
|
|
||||||
@@ -210,7 +228,7 @@ namespace QuestPDF.UnitTests.TestEngine
|
|||||||
|
|
||||||
public TestPlan CheckDrawResult()
|
public TestPlan CheckDrawResult()
|
||||||
{
|
{
|
||||||
Element.InjectDependencies(null, Canvas);
|
Element.VisitChildren(x => x?.Initialize(null, Canvas));
|
||||||
Element.Draw(OperationInput);
|
Element.Draw(OperationInput);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -253,10 +271,10 @@ namespace QuestPDF.UnitTests.TestEngine
|
|||||||
availableSpace ??= new Size(400, 300);
|
availableSpace ??= new Size(400, 300);
|
||||||
|
|
||||||
var canvas = new FreeCanvas();
|
var canvas = new FreeCanvas();
|
||||||
value.InjectDependencies(null, canvas);
|
value.VisitChildren(x => x.Initialize(null, canvas));
|
||||||
var valueMeasure = value.Measure(availableSpace.Value);
|
var valueMeasure = value.Measure(availableSpace.Value);
|
||||||
|
|
||||||
expected.InjectDependencies(null, canvas);
|
expected.VisitChildren(x => x.Initialize(null, canvas));
|
||||||
var expectedMeasure = expected.Measure(availableSpace.Value);
|
var expectedMeasure = expected.Measure(availableSpace.Value);
|
||||||
|
|
||||||
valueMeasure.Should().BeEquivalentTo(expectedMeasure);
|
valueMeasure.Should().BeEquivalentTo(expectedMeasure);
|
||||||
@@ -267,11 +285,11 @@ namespace QuestPDF.UnitTests.TestEngine
|
|||||||
availableSpace ??= new Size(400, 300);
|
availableSpace ??= new Size(400, 300);
|
||||||
|
|
||||||
var valueCanvas = new OperationRecordingCanvas();
|
var valueCanvas = new OperationRecordingCanvas();
|
||||||
value.InjectDependencies(null, valueCanvas);
|
value.VisitChildren(x => x.Initialize(null, valueCanvas));
|
||||||
value.Draw(availableSpace.Value);
|
value.Draw(availableSpace.Value);
|
||||||
|
|
||||||
var expectedCanvas = new OperationRecordingCanvas();
|
var expectedCanvas = new OperationRecordingCanvas();
|
||||||
expected.InjectDependencies(null, expectedCanvas);
|
expected.VisitChildren(x => x.Initialize(null, expectedCanvas));
|
||||||
expected.Draw(availableSpace.Value);
|
expected.Draw(availableSpace.Value);
|
||||||
|
|
||||||
valueCanvas.Operations.Should().BeEquivalentTo(expectedCanvas.Operations);
|
valueCanvas.Operations.Should().BeEquivalentTo(expectedCanvas.Operations);
|
||||||
-38
@@ -77,9 +77,7 @@ namespace QuestPDF.UnitTests
|
|||||||
})
|
})
|
||||||
.DrawElement(new Size(900, 800))
|
.DrawElement(new Size(900, 800))
|
||||||
.ExpectChildMeasure(Size.Max, SpacePlan.PartialRender(1200, 1600))
|
.ExpectChildMeasure(Size.Max, SpacePlan.PartialRender(1200, 1600))
|
||||||
.ExpectCanvasTranslate(0, 0)
|
|
||||||
.ExpectChildDraw(new Size(1200, 1600))
|
.ExpectChildDraw(new Size(1200, 1600))
|
||||||
.ExpectCanvasTranslate(0, 0)
|
|
||||||
.CheckDrawResult();
|
.CheckDrawResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,43 +91,7 @@ namespace QuestPDF.UnitTests
|
|||||||
})
|
})
|
||||||
.DrawElement(new Size(900, 800))
|
.DrawElement(new Size(900, 800))
|
||||||
.ExpectChildMeasure(Size.Max, SpacePlan.FullRender(1600, 1000))
|
.ExpectChildMeasure(Size.Max, SpacePlan.FullRender(1600, 1000))
|
||||||
.ExpectCanvasTranslate(0, 0)
|
|
||||||
.ExpectChildDraw(new Size(1600, 1000))
|
.ExpectChildDraw(new Size(1600, 1000))
|
||||||
.ExpectCanvasTranslate(0, 0)
|
|
||||||
.CheckDrawResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Draw_WhenChildPartiallyRenders_RightToLeft()
|
|
||||||
{
|
|
||||||
TestPlan
|
|
||||||
.For(x => new Unconstrained
|
|
||||||
{
|
|
||||||
Child = x.CreateChild(),
|
|
||||||
ContentDirection = ContentDirection.RightToLeft
|
|
||||||
})
|
|
||||||
.DrawElement(new Size(900, 800))
|
|
||||||
.ExpectChildMeasure(Size.Max, SpacePlan.PartialRender(1200, 1600))
|
|
||||||
.ExpectCanvasTranslate(-1200, 0)
|
|
||||||
.ExpectChildDraw(new Size(1200, 1600))
|
|
||||||
.ExpectCanvasTranslate(1200, 0)
|
|
||||||
.CheckDrawResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Draw_WhenChildFullyRenders_RightToLeft()
|
|
||||||
{
|
|
||||||
TestPlan
|
|
||||||
.For(x => new Unconstrained
|
|
||||||
{
|
|
||||||
Child = x.CreateChild(),
|
|
||||||
ContentDirection = ContentDirection.RightToLeft
|
|
||||||
})
|
|
||||||
.DrawElement(new Size(900, 800))
|
|
||||||
.ExpectChildMeasure(Size.Max, SpacePlan.FullRender(1600, 1000))
|
|
||||||
.ExpectCanvasTranslate(-1600, 0)
|
|
||||||
.ExpectChildDraw(new Size(1600, 1000))
|
|
||||||
.ExpectCanvasTranslate(1600, 0)
|
|
||||||
.CheckDrawResult();
|
.CheckDrawResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8,15 +8,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestPDF.UnitTests", "Quest
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestPDF.Examples", "QuestPDF.Examples\QuestPDF.Examples.csproj", "{8BD0A2B4-2DC1-47BA-9724-C158320D9CAE}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestPDF.Examples", "QuestPDF.Examples\QuestPDF.Examples.csproj", "{8BD0A2B4-2DC1-47BA-9724-C158320D9CAE}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestPDF.Previewer.Examples", "QuestPDF.Previewer.Examples\QuestPDF.Previewer.Examples.csproj", "{CA413A39-038F-4A9F-B56F-0E5413B6B158}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Configuration", "Configuration", "{73123649-216A-47B4-BFB2-DADF13FBE75D}"
|
|
||||||
ProjectSection(SolutionItems) = preProject
|
|
||||||
.editorconfig = .editorconfig
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuestPDF.Previewer", "QuestPDF.Previewer\QuestPDF.Previewer.csproj", "{B2FF6003-3A45-4A78-A85D-B86C7F01D054}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -39,13 +30,5 @@ Global
|
|||||||
{8BD0A2B4-2DC1-47BA-9724-C158320D9CAE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{8BD0A2B4-2DC1-47BA-9724-C158320D9CAE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{8BD0A2B4-2DC1-47BA-9724-C158320D9CAE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{8BD0A2B4-2DC1-47BA-9724-C158320D9CAE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{8BD0A2B4-2DC1-47BA-9724-C158320D9CAE}.Release|Any CPU.Build.0 = Release|Any CPU
|
{8BD0A2B4-2DC1-47BA-9724-C158320D9CAE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{CA413A39-038F-4A9F-B56F-0E5413B6B158}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{CA413A39-038F-4A9F-B56F-0E5413B6B158}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{CA413A39-038F-4A9F-B56F-0E5413B6B158}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{CA413A39-038F-4A9F-B56F-0E5413B6B158}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{B2FF6003-3A45-4A78-A85D-B86C7F01D054}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{B2FF6003-3A45-4A78-A85D-B86C7F01D054}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{B2FF6003-3A45-4A78-A85D-B86C7F01D054}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{B2FF6003-3A45-4A78-A85D-B86C7F01D054}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
|
||||||
|
[assembly: InternalsVisibleTo("QuestPDF.UnitTests")]
|
||||||
|
[assembly: InternalsVisibleTo("QuestPDF.Examples")]
|
||||||
|
[assembly: InternalsVisibleTo("QuestPDF.ReportSample")]
|
||||||
+32
-91
@@ -10,7 +10,6 @@ using QuestPDF.Elements.Text.Items;
|
|||||||
using QuestPDF.Fluent;
|
using QuestPDF.Fluent;
|
||||||
using QuestPDF.Helpers;
|
using QuestPDF.Helpers;
|
||||||
using QuestPDF.Infrastructure;
|
using QuestPDF.Infrastructure;
|
||||||
using Image = QuestPDF.Elements.Image;
|
|
||||||
|
|
||||||
namespace QuestPDF.Drawing
|
namespace QuestPDF.Drawing
|
||||||
{
|
{
|
||||||
@@ -18,72 +17,53 @@ namespace QuestPDF.Drawing
|
|||||||
{
|
{
|
||||||
internal static void GeneratePdf(Stream stream, IDocument document)
|
internal static void GeneratePdf(Stream stream, IDocument document)
|
||||||
{
|
{
|
||||||
CheckIfStreamIsCompatible(stream);
|
|
||||||
|
|
||||||
var metadata = document.GetMetadata();
|
var metadata = document.GetMetadata();
|
||||||
var canvas = new PdfCanvas(stream, metadata);
|
var writeOnlyStream = new WriteOnlyStream(stream);
|
||||||
RenderDocument(canvas, document, metadata);
|
var canvas = new PdfCanvas(writeOnlyStream, metadata);
|
||||||
|
RenderDocument(canvas, document);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void GenerateXps(Stream stream, IDocument document)
|
internal static void GenerateXps(Stream stream, IDocument document)
|
||||||
{
|
{
|
||||||
CheckIfStreamIsCompatible(stream);
|
|
||||||
|
|
||||||
var metadata = document.GetMetadata();
|
var metadata = document.GetMetadata();
|
||||||
var canvas = new XpsCanvas(stream, metadata);
|
var writeOnlyStream = new WriteOnlyStream(stream);
|
||||||
RenderDocument(canvas, document, metadata);
|
var canvas = new XpsCanvas(writeOnlyStream, metadata);
|
||||||
}
|
RenderDocument(canvas, document);
|
||||||
|
|
||||||
private static void CheckIfStreamIsCompatible(Stream stream)
|
|
||||||
{
|
|
||||||
if (!stream.CanWrite)
|
|
||||||
throw new ArgumentException("The library requires a Stream object with the 'write' capability available (the CanWrite flag). Please consider using the MemoryStream class.");
|
|
||||||
|
|
||||||
if (!stream.CanSeek)
|
|
||||||
throw new ArgumentException("The library requires a Stream object with the 'seek' capability available (the CanSeek flag). Please consider using the MemoryStream class.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static ICollection<byte[]> GenerateImages(IDocument document)
|
internal static ICollection<byte[]> GenerateImages(IDocument document)
|
||||||
{
|
{
|
||||||
var metadata = document.GetMetadata();
|
var metadata = document.GetMetadata();
|
||||||
var canvas = new ImageCanvas(metadata);
|
var canvas = new ImageCanvas(metadata);
|
||||||
RenderDocument(canvas, document, metadata);
|
RenderDocument(canvas, document);
|
||||||
|
|
||||||
return canvas.Images;
|
return canvas.Images;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static ICollection<PreviewerPicture> GeneratePreviewerPictures(IDocument document)
|
private static void RenderDocument<TCanvas>(TCanvas canvas, IDocument document)
|
||||||
{
|
|
||||||
var metadata = document.GetMetadata();
|
|
||||||
var canvas = new SkiaPictureCanvas();
|
|
||||||
RenderDocument(canvas, document, metadata);
|
|
||||||
return canvas.Pictures;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void RenderDocument<TCanvas>(TCanvas canvas, IDocument document, DocumentMetadata metadata)
|
|
||||||
where TCanvas : ICanvas, IRenderingCanvas
|
where TCanvas : ICanvas, IRenderingCanvas
|
||||||
{
|
{
|
||||||
var container = new DocumentContainer();
|
var container = new DocumentContainer();
|
||||||
document.Compose(container);
|
document.Compose(container);
|
||||||
var content = container.Compose();
|
var content = container.Compose();
|
||||||
ApplyDefaultImageDpi(content, metadata.RasterDpi, metadata.ImageQuality);
|
|
||||||
ApplyDefaultTextStyle(content, TextStyle.LibraryDefault);
|
ApplyDefaultTextStyle(content, TextStyle.LibraryDefault);
|
||||||
ApplyContentDirection(content, ContentDirection.LeftToRight);
|
|
||||||
|
|
||||||
var debuggingState = Settings.EnableDebugging ? ApplyDebugging(content) : null;
|
var metadata = document.GetMetadata();
|
||||||
|
var pageContext = new PageContext();
|
||||||
|
|
||||||
if (Settings.EnableCaching)
|
var debuggingState = metadata.ApplyDebugging ? ApplyDebugging(content) : null;
|
||||||
|
|
||||||
|
if (metadata.ApplyCaching)
|
||||||
ApplyCaching(content);
|
ApplyCaching(content);
|
||||||
|
|
||||||
var pageContext = new PageContext();
|
RenderPass(pageContext, new FreeCanvas(), content, metadata, debuggingState);
|
||||||
RenderPass(pageContext, new FreeCanvas(), content, debuggingState);
|
RenderPass(pageContext, canvas, content, metadata, debuggingState);
|
||||||
RenderPass(pageContext, canvas, content, debuggingState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void RenderPass<TCanvas>(PageContext pageContext, TCanvas canvas, Container content, DebuggingState? debuggingState)
|
internal static void RenderPass<TCanvas>(PageContext pageContext, TCanvas canvas, Container content, DocumentMetadata documentMetadata, DebuggingState? debuggingState)
|
||||||
where TCanvas : ICanvas, IRenderingCanvas
|
where TCanvas : ICanvas, IRenderingCanvas
|
||||||
{
|
{
|
||||||
InjectDependencies(content, pageContext, canvas);
|
content.VisitChildren(x => x?.Initialize(pageContext, canvas));
|
||||||
content.VisitChildren(x => (x as IStateResettable)?.ResetState());
|
content.VisitChildren(x => (x as IStateResettable)?.ResetState());
|
||||||
|
|
||||||
canvas.BeginDocument();
|
canvas.BeginDocument();
|
||||||
@@ -116,7 +96,7 @@ namespace QuestPDF.Drawing
|
|||||||
|
|
||||||
canvas.EndPage();
|
canvas.EndPage();
|
||||||
|
|
||||||
if (currentPage >= Settings.DocumentLayoutExceptionThreshold)
|
if (currentPage >= documentMetadata.DocumentLayoutExceptionThreshold)
|
||||||
{
|
{
|
||||||
canvas.EndDocument();
|
canvas.EndDocument();
|
||||||
ThrowLayoutException();
|
ThrowLayoutException();
|
||||||
@@ -133,29 +113,18 @@ namespace QuestPDF.Drawing
|
|||||||
void ThrowLayoutException()
|
void ThrowLayoutException()
|
||||||
{
|
{
|
||||||
var message = $"Composed layout generates infinite document. This may happen in two cases. " +
|
var message = $"Composed layout generates infinite document. This may happen in two cases. " +
|
||||||
$"1) Your document and its layout configuration is correct but the content takes more than {Settings.DocumentLayoutExceptionThreshold} pages. " +
|
$"1) Your document and its layout configuration is correct but the content takes more than {documentMetadata.DocumentLayoutExceptionThreshold} pages. " +
|
||||||
$"In this case, please increase the value {nameof(QuestPDF)}.{nameof(Settings)}.{nameof(Settings.DocumentLayoutExceptionThreshold)} static property. " +
|
$"In this case, please increase the value {nameof(DocumentMetadata)}.{nameof(DocumentMetadata.DocumentLayoutExceptionThreshold)} property configured in the {nameof(IDocument.GetMetadata)} method. " +
|
||||||
$"2) The layout configuration of your document is invalid. Some of the elements require more space than is provided." +
|
$"2) The layout configuration of your document is invalid. Some of the elements require more space than is provided." +
|
||||||
$"Please analyze your documents structure to detect this element and fix its size constraints.";
|
$"Please analyze your documents structure to detect this element and fix its size constraints.";
|
||||||
|
|
||||||
var elementTrace = debuggingState?.BuildTrace() ?? "Debug trace is available only in the DEBUG mode.";
|
throw new DocumentLayoutException(message)
|
||||||
|
{
|
||||||
throw new DocumentLayoutException(message, elementTrace);
|
ElementTrace = debuggingState?.BuildTrace() ?? "Debug trace is available only in the DEBUG mode."
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void InjectDependencies(this Element content, IPageContext pageContext, ICanvas canvas)
|
|
||||||
{
|
|
||||||
content.VisitChildren(x =>
|
|
||||||
{
|
|
||||||
if (x == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
x.PageContext = pageContext;
|
|
||||||
x.Canvas = canvas;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ApplyCaching(Container content)
|
private static void ApplyCaching(Container content)
|
||||||
{
|
{
|
||||||
content.VisitChildren(x =>
|
content.VisitChildren(x =>
|
||||||
@@ -177,37 +146,7 @@ namespace QuestPDF.Drawing
|
|||||||
return debuggingState;
|
return debuggingState;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void ApplyDefaultImageDpi(this Element? content, int targetDpi, int targetImageQuality)
|
private static void ApplyDefaultTextStyle(this Element? content, TextStyle documentDefaultTextStyle)
|
||||||
{
|
|
||||||
content.VisitChildren(x =>
|
|
||||||
{
|
|
||||||
if (x is not Image { DocumentImage: { } image })
|
|
||||||
return;
|
|
||||||
|
|
||||||
image.TargetDpi ??= targetDpi;
|
|
||||||
image.ImageQuality ??= targetImageQuality;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void ApplyContentDirection(this Element? content, ContentDirection direction)
|
|
||||||
{
|
|
||||||
if (content == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (content is ContentDirectionSetter contentDirectionSetter)
|
|
||||||
{
|
|
||||||
ApplyContentDirection(contentDirectionSetter.Child, contentDirectionSetter.ContentDirection);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (content is IContentDirectionAware contentDirectionAware)
|
|
||||||
contentDirectionAware.ContentDirection = direction;
|
|
||||||
|
|
||||||
foreach (var child in content.GetChildren())
|
|
||||||
ApplyContentDirection(child, direction);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void ApplyDefaultTextStyle(this Element? content, TextStyle documentDefaultTextStyle)
|
|
||||||
{
|
{
|
||||||
if (content == null)
|
if (content == null)
|
||||||
return;
|
return;
|
||||||
@@ -218,7 +157,7 @@ namespace QuestPDF.Drawing
|
|||||||
{
|
{
|
||||||
if (textBlockItem is TextBlockSpan textSpan)
|
if (textBlockItem is TextBlockSpan textSpan)
|
||||||
{
|
{
|
||||||
textSpan.Style = textSpan.Style.ApplyGlobalStyle(documentDefaultTextStyle);
|
textSpan.Style.ApplyGlobalStyle(documentDefaultTextStyle);
|
||||||
}
|
}
|
||||||
else if (textBlockItem is TextBlockElement textElement)
|
else if (textBlockItem is TextBlockElement textElement)
|
||||||
{
|
{
|
||||||
@@ -229,14 +168,16 @@ namespace QuestPDF.Drawing
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (content is DynamicHost dynamicHost)
|
var targetTextStyle = documentDefaultTextStyle;
|
||||||
dynamicHost.TextStyle = dynamicHost.TextStyle.ApplyGlobalStyle(documentDefaultTextStyle);
|
|
||||||
|
|
||||||
if (content is DefaultTextStyle defaultTextStyleElement)
|
if (content is DefaultTextStyle defaultTextStyleElement)
|
||||||
documentDefaultTextStyle = defaultTextStyleElement.TextStyle.ApplyGlobalStyle(documentDefaultTextStyle);
|
{
|
||||||
|
defaultTextStyleElement.TextStyle.ApplyParentStyle(documentDefaultTextStyle);
|
||||||
|
targetTextStyle = defaultTextStyleElement.TextStyle;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var child in content.GetChildren())
|
foreach (var child in content.GetChildren())
|
||||||
ApplyDefaultTextStyle(child, documentDefaultTextStyle);
|
ApplyDefaultTextStyle(child, targetTextStyle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace QuestPDF.Drawing
|
||||||
|
{
|
||||||
|
public class DocumentMetadata
|
||||||
|
{
|
||||||
|
public int ImageQuality { get; set; } = 101;
|
||||||
|
public int RasterDpi { get; set; } = 72;
|
||||||
|
public bool PdfA { get; set; }
|
||||||
|
|
||||||
|
public string? Title { get; set; }
|
||||||
|
public string? Author { get; set; }
|
||||||
|
public string? Subject { get; set; }
|
||||||
|
public string? Keywords { get; set; }
|
||||||
|
public string? Creator { get; set; }
|
||||||
|
public string? Producer { get; set; }
|
||||||
|
|
||||||
|
public DateTime CreationDate { get; set; } = DateTime.Now;
|
||||||
|
public DateTime ModifiedDate { get; set; } = DateTime.Now;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the number of generated pages exceeds this threshold
|
||||||
|
/// (likely due to infinite layout), the exception is thrown.
|
||||||
|
/// </summary>
|
||||||
|
public int DocumentLayoutExceptionThreshold { get; set; } = 250;
|
||||||
|
|
||||||
|
public bool ApplyCaching { get; set; } = !System.Diagnostics.Debugger.IsAttached;
|
||||||
|
public bool ApplyDebugging { get; set; } = System.Diagnostics.Debugger.IsAttached;
|
||||||
|
|
||||||
|
public static DocumentMetadata Default => new DocumentMetadata();
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user