diff --git a/QuestPDF.Examples/TextBenchmark.cs b/QuestPDF.Examples/TextBenchmark.cs
index fb4c105..a5d1fb9 100644
--- a/QuestPDF.Examples/TextBenchmark.cs
+++ b/QuestPDF.Examples/TextBenchmark.cs
@@ -31,7 +31,7 @@ namespace QuestPDF.Examples
{
var chapters = GetBookChapters().ToList();
- var results = PerformTest(16).ToList();
+ var results = PerformTest(128).ToList();
Console.WriteLine($"Min: {results.Min():F}");
Console.WriteLine($"Max: {results.Max():F}");
diff --git a/QuestPDF.Examples/TextExamples.cs b/QuestPDF.Examples/TextExamples.cs
index 5f4ee30..c562b10 100644
--- a/QuestPDF.Examples/TextExamples.cs
+++ b/QuestPDF.Examples/TextExamples.cs
@@ -12,11 +12,11 @@ namespace QuestPDF.Examples
public class TextExamples
{
[Test]
- public void SimpleTextBlock()
+ public void SimpleText()
{
RenderingTest
.Create()
- .PageSize(500, 300)
+ .PageSize(500, 100)
.ProduceImages()
.ShowResults()
@@ -27,6 +27,27 @@ namespace QuestPDF.Examples
.MinimalBox()
.Border(1)
.Padding(10)
+ .Text(Placeholders.Paragraph());
+ });
+ }
+
+ [Test]
+ public void SimpleTextBlock()
+ {
+ RenderingTest
+ .Create()
+ .PageSize(600, 300)
+
+ .ProduceImages()
+ .ShowResults()
+ .Render(container =>
+ {
+ container
+ .Padding(5)
+ .MinimalBox()
+ .Border(1)
+ .MaxWidth(300)
+ .Padding(10)
.Text(text =>
{
text.DefaultTextStyle(TextStyle.Default.FontSize(20));
@@ -191,7 +212,7 @@ namespace QuestPDF.Examples
{
RenderingTest
.Create()
- .PageSize(500, 300)
+ .PageSize(500, 500)
.ProduceImages()
.ShowResults()
.Render(container =>
@@ -203,13 +224,7 @@ namespace QuestPDF.Examples
.Padding(10)
.Text(text =>
{
- text.ParagraphSpacing(10);
-
- foreach (var i in Enumerable.Range(1, 3))
- {
- text.Span($"Paragraph {i}: ").SemiBold();
- text.Line(Placeholders.Paragraph());
- }
+ text.Line(Placeholders.Paragraph());
});
});
}
@@ -388,7 +403,7 @@ namespace QuestPDF.Examples
.Padding(10)
.Text(text =>
{
- text.DefaultTextStyle(TextStyle.Default.FontSize(20));
+ text.DefaultTextStyle(TextStyle.Default.FontSize(20).BackgroundColor(Colors.Red.Lighten4));
text.AlignLeft();
text.ParagraphSpacing(10);
@@ -407,7 +422,7 @@ namespace QuestPDF.Examples
{
text.Line($"{i}: {Placeholders.Paragraph()}");
- text.Hyperlink("Please visit QuestPDF website", "https://www.questpdf.com");
+ text.Hyperlink("Please visit QuestPDF website. ", "https://www.questpdf.com");
text.Span("This is page number ");
text.CurrentPageNumber();
diff --git a/QuestPDF.Examples/TextShapingTests.cs b/QuestPDF.Examples/TextShapingTests.cs
new file mode 100644
index 0000000..90fa8a8
--- /dev/null
+++ b/QuestPDF.Examples/TextShapingTests.cs
@@ -0,0 +1,79 @@
+using NUnit.Framework;
+using QuestPDF.Examples.Engine;
+using QuestPDF.Fluent;
+using SkiaSharp;
+using SkiaSharp.HarfBuzz;
+
+namespace QuestPDF.Examples
+{
+ public class TextShapingTests
+ {
+ // [Test]
+ // public void ShapeText()
+ // {
+ // using var textPaint = new SKPaint
+ // {
+ // Color = SKColors.Black,
+ // Typeface = SKTypeface.CreateDefault(),
+ // IsAntialias = true,
+ // TextSize = 20
+ // };
+ //
+ // using var backgroundPaint = new SKPaint
+ // {
+ // Color = SKColors.LightGray
+ // };
+ //
+ // RenderingTest
+ // .Create()
+ // .PageSize(550, 250)
+ // .ProduceImages()
+ // .ShowResults()
+ // .Render(container =>
+ // {
+ // //var lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec odio ipsum, aliquam a neque a, lacinia vehicula lectus.";
+ // //var arabic = "ينا الألم. في بعض الأحيان ونظراً للالتزامات التي يفرضها علينا الواجب والعمل سنتنازل غالباً ونرفض الشعور";
+ //
+ // var lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
+ // var arabic = "ينا الألم. في بعض الأحيان ونظراً للالتزامات التي يفرضها علينا";
+ //
+ // var text = arabic;
+ // var metrics = textPaint.FontMetrics;
+ //
+ // container
+ // .Padding(25)
+ // .Canvas((canvas, space) =>
+ // {
+ // canvas.Translate(0, 20);
+ //
+ // var width = MeasureText(text, textPaint);
+ // var widthReal = textPaint.MeasureText(text);
+ // canvas.DrawRect(0, metrics.Descent, width, metrics.Ascent - metrics.Descent, backgroundPaint);
+ //
+ // canvas.DrawShapedText(text, 0, 0, textPaint);
+ //
+ // canvas.Translate(0, 40);
+ // canvas.DrawText(text, 0, 0, textPaint);
+ // });
+ // });
+ // }
+
+ [Test]
+ public void MeasureTest()
+ {
+ using var textPaint = new SKPaint
+ {
+ Color = SKColors.Black,
+ Typeface = SKTypeface.CreateDefault(),
+ IsAntialias = true,
+ TextSize = 20
+ };
+
+ var lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec odio ipsum, aliquam a neque a, lacinia vehicula lectus.";
+ var arabic = "ينا الألم. في بعض الأحيان ونظراً للالتزامات التي يفرضها علينا";
+ // 012345678901234567890123456789012345678901234567890123456
+ var shaper = new SKShaper(textPaint.Typeface);
+ var result = shaper.Shape(lorem, textPaint);
+ }
+ }
+}
\ No newline at end of file
diff --git a/QuestPDF.Previewer/CommunicationService.cs b/QuestPDF.Previewer/CommunicationService.cs
index 0a78ef5..d988fa1 100644
--- a/QuestPDF.Previewer/CommunicationService.cs
+++ b/QuestPDF.Previewer/CommunicationService.cs
@@ -1,5 +1,6 @@
using System.Text.Json;
using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@@ -29,6 +30,7 @@ class CommunicationService
{
var builder = WebApplication.CreateBuilder();
builder.Services.AddLogging(x => x.ClearProviders());
+ builder.WebHost.UseKestrel(options => options.Limits.MaxRequestBodySize = null);
Application = builder.Build();
Application.MapGet("ping", HandlePing);
diff --git a/QuestPDF.Previewer/QuestPDF.Previewer.csproj b/QuestPDF.Previewer/QuestPDF.Previewer.csproj
index 5aeb9fa..9ada0f5 100644
--- a/QuestPDF.Previewer/QuestPDF.Previewer.csproj
+++ b/QuestPDF.Previewer/QuestPDF.Previewer.csproj
@@ -4,7 +4,7 @@
MarcinZiabek
CodeFlint
QuestPDF.Previewer
- 2022.5.0
+ 2022.6.0
true
questpdf-previewer
QuestPDF is an open-source, modern and battle-tested library that can help you with generating PDF documents by offering friendly, discoverable and predictable C# fluent API.
diff --git a/QuestPDF.UnitTests/TestEngine/MockCanvas.cs b/QuestPDF.UnitTests/TestEngine/MockCanvas.cs
index 6e4926e..68bbc07 100644
--- a/QuestPDF.UnitTests/TestEngine/MockCanvas.cs
+++ b/QuestPDF.UnitTests/TestEngine/MockCanvas.cs
@@ -1,4 +1,5 @@
using System;
+using QuestPDF.Drawing;
using QuestPDF.Infrastructure;
using SkiaSharp;
@@ -10,7 +11,6 @@ namespace QuestPDF.UnitTests.TestEngine
public Action RotateFunc { get; set; }
public Action ScaleFunc { get; set; }
public Action DrawImageFunc { get; set; }
- public Action DrawTextFunc { get; set; }
public Action DrawRectFunc { get; set; }
public void Translate(Position vector) => TranslateFunc(vector);
@@ -18,7 +18,7 @@ namespace QuestPDF.UnitTests.TestEngine
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 DrawText(string text, Position position, TextStyle style) => DrawTextFunc(text, position, style);
+ public void DrawText(SKTextBlob skTextBlob, Position position, TextStyle style) => throw new NotImplementedException();
public void DrawImage(SKImage image, Position position, Size size) => DrawImageFunc(image, position, size);
public void DrawHyperlink(string url, Size size) => throw new NotImplementedException();
diff --git a/QuestPDF.UnitTests/TestEngine/OperationRecordingCanvas.cs b/QuestPDF.UnitTests/TestEngine/OperationRecordingCanvas.cs
index 4fbedfe..5ca55aa 100644
--- a/QuestPDF.UnitTests/TestEngine/OperationRecordingCanvas.cs
+++ b/QuestPDF.UnitTests/TestEngine/OperationRecordingCanvas.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using QuestPDF.Drawing;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine.Operations;
using SkiaSharp;
@@ -15,7 +16,7 @@ namespace QuestPDF.UnitTests.TestEngine
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 DrawText(string text, Position position, TextStyle style) => Operations.Add(new CanvasDrawTextOperation(text, position, style));
+ public void DrawText(SKTextBlob skTextBlob, Position position, TextStyle style) => throw new NotImplementedException();
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();
diff --git a/QuestPDF.UnitTests/TestEngine/TestPlan.cs b/QuestPDF.UnitTests/TestEngine/TestPlan.cs
index 1ec5fe9..bd803e5 100644
--- a/QuestPDF.UnitTests/TestEngine/TestPlan.cs
+++ b/QuestPDF.UnitTests/TestEngine/TestPlan.cs
@@ -82,19 +82,6 @@ namespace QuestPDF.UnitTests.TestEngine
Assert.AreEqual(expected.Color, color, "Draw rectangle: color");
},
- DrawTextFunc = (text, position, style) =>
- {
- var expected = GetExpected();
-
- 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.FontFamily, style.FontFamily, "Draw text: font");
- Assert.AreEqual(expected.Style.Size, style.Size, "Draw text: size");
- },
DrawImageFunc = (image, position, size) =>
{
var expected = GetExpected();
@@ -201,11 +188,6 @@ namespace QuestPDF.UnitTests.TestEngine
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)
{
return AddOperation(new CanvasDrawImageOperation(position, size));
diff --git a/QuestPDF/Drawing/DocumentGenerator.cs b/QuestPDF/Drawing/DocumentGenerator.cs
index cd9b339..3fe373c 100644
--- a/QuestPDF/Drawing/DocumentGenerator.cs
+++ b/QuestPDF/Drawing/DocumentGenerator.cs
@@ -135,11 +135,10 @@ namespace QuestPDF.Drawing
$"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." +
$"Please analyze your documents structure to detect this element and fix its size constraints.";
-
- throw new DocumentLayoutException(message)
- {
- ElementTrace = debuggingState?.BuildTrace() ?? "Debug trace is available only in the DEBUG mode."
- };
+
+ var elementTrace = debuggingState?.BuildTrace() ?? "Debug trace is available only in the DEBUG mode.";
+
+ throw new DocumentLayoutException(message, elementTrace);
}
}
diff --git a/QuestPDF/Drawing/Exceptions/DocumentComposeException.cs b/QuestPDF/Drawing/Exceptions/DocumentComposeException.cs
index 972dbe8..eeefb4e 100644
--- a/QuestPDF/Drawing/Exceptions/DocumentComposeException.cs
+++ b/QuestPDF/Drawing/Exceptions/DocumentComposeException.cs
@@ -4,17 +4,7 @@ namespace QuestPDF.Drawing.Exceptions
{
public class DocumentComposeException : Exception
{
- public DocumentComposeException()
- {
-
- }
-
- public DocumentComposeException(string message) : base(message)
- {
-
- }
-
- public DocumentComposeException(string message, Exception inner) : base(message, inner)
+ internal DocumentComposeException(string message) : base(message)
{
}
diff --git a/QuestPDF/Drawing/Exceptions/DocumentDrawingException.cs b/QuestPDF/Drawing/Exceptions/DocumentDrawingException.cs
index cebb76c..a650d90 100644
--- a/QuestPDF/Drawing/Exceptions/DocumentDrawingException.cs
+++ b/QuestPDF/Drawing/Exceptions/DocumentDrawingException.cs
@@ -4,17 +4,7 @@ namespace QuestPDF.Drawing.Exceptions
{
public class DocumentDrawingException : Exception
{
- public DocumentDrawingException()
- {
-
- }
-
- public DocumentDrawingException(string message) : base(message)
- {
-
- }
-
- public DocumentDrawingException(string message, Exception inner) : base(message, inner)
+ internal DocumentDrawingException(string message, Exception inner) : base(message, inner)
{
}
diff --git a/QuestPDF/Drawing/Exceptions/DocumentLayoutException.cs b/QuestPDF/Drawing/Exceptions/DocumentLayoutException.cs
index ff83755..acdc1f0 100644
--- a/QuestPDF/Drawing/Exceptions/DocumentLayoutException.cs
+++ b/QuestPDF/Drawing/Exceptions/DocumentLayoutException.cs
@@ -4,21 +4,11 @@ namespace QuestPDF.Drawing.Exceptions
{
public class DocumentLayoutException : Exception
{
- public string ElementTrace { get; set; }
-
- public DocumentLayoutException()
- {
-
- }
+ public string? ElementTrace { get; }
- public DocumentLayoutException(string message) : base(message)
+ internal DocumentLayoutException(string message, string? elementTrace = null) : base(message)
{
-
- }
-
- public DocumentLayoutException(string message, Exception inner) : base(message, inner)
- {
-
+ ElementTrace = elementTrace;
}
}
}
\ No newline at end of file
diff --git a/QuestPDF/Drawing/Exceptions/InitializationException.cs b/QuestPDF/Drawing/Exceptions/InitializationException.cs
new file mode 100644
index 0000000..5be5dd2
--- /dev/null
+++ b/QuestPDF/Drawing/Exceptions/InitializationException.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace QuestPDF.Drawing.Exceptions
+{
+ public class InitializationException : Exception
+ {
+ internal InitializationException(string documentType, Exception innerException) : base(CreateMessage(documentType), innerException)
+ {
+
+ }
+
+ private static string CreateMessage(string documentType)
+ {
+ return $"Cannot create the {documentType} document using the SkiaSharp library. " +
+ $"This exception usually means that, on your operating system where you run the application, SkiaSharp requires installing additional dependencies. " +
+ $"Such dependencies are available as additional nuget packages, for example SkiaSharp.NativeAssets.Linux. " +
+ $"Please refer to the SkiaSharp documentation for more details.";
+ }
+ }
+}
\ No newline at end of file
diff --git a/QuestPDF/Drawing/FontManager.cs b/QuestPDF/Drawing/FontManager.cs
index 3c699a9..fe37924 100644
--- a/QuestPDF/Drawing/FontManager.cs
+++ b/QuestPDF/Drawing/FontManager.cs
@@ -2,9 +2,11 @@
using System.Collections.Concurrent;
using System.IO;
using System.Linq;
+using HarfBuzzSharp;
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
using SkiaSharp;
+using SkiaSharp.HarfBuzz;
namespace QuestPDF.Drawing
{
@@ -12,8 +14,11 @@ namespace QuestPDF.Drawing
{
private static ConcurrentDictionary StyleSets = new();
private static ConcurrentDictionary