Browse Source

Feat styled box (#1278)

* Implement StyledBox functionality

* Fix marshaling in SkPaint->paint_set_linear_gradient method Marcin Ziąbek 7 minutes ago

* Add fluent API method for the line element (gradient and dashed pattern)

* Add missing intellisense documentation to StyledBox

* Add Skia native dependency

* Fix StyleBox bugs

* Fix Line bugs

* Implement VisualTest framework

* Implement visual tests for the Line element

* Implement visual tests for the StyledBox element

* Adjust visual tests engine

* Improve visual tests

* Add expected output to visual tests project

* Rename BorderRadius to CornerRadius

* Update nuget dependencies

* Update release notes

* Update Skia native dependency

* Increase the nuget version to 2025.6.0-rc0

* Fix build

* Update main.yml

* Update main.yml

* Remove LangVersion setting from project files

* Downgrade Microsoft.NET.Test.Sdk version to 17.13.0 in multiple project files

* Update main.yml

* Add temporary logging to better understand platform differences in visual testing

* Improve error logging in visual tests

* Add SatelliteResourceLanguages setting to project files - reduce warnings while build

* Visual tests: fix logging

* Enhance visual test failure message to include pixel difference count

* Improve image comparison error handling with detailed assertions

* Disabled visual tests on runtimes different from osx-arm64

* Updated Skia dependency to M138

* Change the icon and its color in the Placeholder element

* Adjust the default behavior of the StyledBox.Border element

* Adjust the default color for the Shadow element

* Add documentation examples for the Shadow element

* Add documentation examples for the RoundedCorners feature

* Enhance documentation examples for the Line element

* Enhance documentation examples for the Border element

* Enhance documentation examples for the Background element

* Update visual tests for Border

* Execute visual tests on all runtimes

* Revert "Execute visual tests on all runtimes"

This reverts commit 5600f3b8b0aa2d4ab64d6b8efaaf00b368f9e0b4.

* Refactor StyledBox properties to encapsulate logic within private accessors
Marcin Ziąbek 5 months ago
parent
commit
c98434f0fa
100 changed files with 981 additions and 146 deletions
  1. 1 0
      .github/workflows/main.yml
  2. 1 0
      Source/QuestPDF.Companion.TestRunner/QuestPDF.Companion.TestRunner.csproj
  3. 67 4
      Source/QuestPDF.DocumentationExamples/BackgroundExamples.cs
  4. 284 22
      Source/QuestPDF.DocumentationExamples/BorderExamples.cs
  5. 174 0
      Source/QuestPDF.DocumentationExamples/LineExamples.cs
  6. 4 3
      Source/QuestPDF.DocumentationExamples/QuestPDF.DocumentationExamples.csproj
  7. 146 0
      Source/QuestPDF.DocumentationExamples/RoundedCornersExamples.cs
  8. 279 0
      Source/QuestPDF.DocumentationExamples/ShadowExamples.cs
  9. 3 2
      Source/QuestPDF.LayoutTests/QuestPDF.LayoutTests.csproj
  10. 5 2
      Source/QuestPDF.LayoutTests/TestEngine/MockChild.cs
  11. 4 4
      Source/QuestPDF.ReportSample/QuestPDF.ReportSample.csproj
  12. 0 43
      Source/QuestPDF.UnitTests/BackgroundTests.cs
  13. 0 59
      Source/QuestPDF.UnitTests/BorderTests.cs
  14. 3 3
      Source/QuestPDF.UnitTests/QuestPDF.UnitTests.csproj
  15. 5 2
      Source/QuestPDF.UnitTests/TestEngine/MockCanvas.cs
  16. 5 2
      Source/QuestPDF.UnitTests/TestEngine/OperationRecordingCanvas.cs
  17. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/Color(#2196F3).png
  18. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/Color(#4CAF50).png
  19. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/Color(#F44336).png
  20. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/Complex.png
  21. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/DashPattern([1.0f, 1.0f]).png
  22. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/DashPattern([1.0f, 2.0f]).png
  23. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/DashPattern([2.0f, 1.0f]).png
  24. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/DashPattern([2.0f, 2.0f]).png
  25. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/DashPattern([4.0f, 4.0f, 12.0f, 4.0f]).png
  26. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/DashPattern([4.0f, 4.0f, 8.0f, 8.0f, 12.0f, ...]).png
  27. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/DashPattern([4.0f, 4.0f]).png
  28. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/DashPattern([8.0f, 8.0f]).png
  29. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/Gradient([#2196F3, #03A9F4, #00BCD4, #009688, #4CAF50]).png
  30. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/Gradient([#F44336, #4CAF50]).png
  31. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/Gradient([#F44336, #FFEB3B, #4CAF50]).png
  32. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/ThicknessHorizontal(1).png
  33. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/ThicknessHorizontal(2).png
  34. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/ThicknessHorizontal(4).png
  35. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/ThicknessHorizontal(8).png
  36. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/ThicknessVertical(1).png
  37. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/ThicknessVertical(2).png
  38. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/ThicknessVertical(4).png
  39. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/Line/ThicknessVertical(8).png
  40. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundColor(#2196F3).png
  41. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundColor(#4CAF50).png
  42. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundColor(#F44336).png
  43. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundGradientAngle(0).png
  44. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundGradientAngle(30).png
  45. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundGradientAngle(45).png
  46. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundGradientAngle(60).png
  47. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundGradientAngle(90).png
  48. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundGradientColors([#2196F3, #03A9F4, #00BCD4, #009688, #4CAF50]).png
  49. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundGradientColors([#F44336, #388E3C]).png
  50. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundGradientColors([#F44336, #FFEB3B, #4CAF50]).png
  51. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundRoundedCorners(0,10,20,40).png
  52. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundRoundedCorners(10,20,40,0).png
  53. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundRoundedCorners(20,40,0,10).png
  54. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundRoundedCorners(40,0,10,20).png
  55. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundUniformRoundedCorners(0).png
  56. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundUniformRoundedCorners(10).png
  57. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundUniformRoundedCorners(100).png
  58. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundUniformRoundedCorners(25).png
  59. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundUniformRoundedCorners(5).png
  60. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundUniformRoundedCorners(50).png
  61. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderAlignmentInside.png
  62. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderAlignmentMiddle.png
  63. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderAlignmentOutside.png
  64. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderColor(#2196F3).png
  65. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderColor(#4CAF50).png
  66. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderColor(#F44336).png
  67. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderGradientAngle(0).png
  68. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderGradientAngle(30).png
  69. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderGradientAngle(45).png
  70. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderGradientAngle(60).png
  71. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderGradientAngle(90).png
  72. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderGradientColors([#2196F3, #03A9F4, #00BCD4, #009688, #4CAF50]).png
  73. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderGradientColors([#F44336, #388E3C]).png
  74. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderGradientColors([#F44336, #FFEB3B, #4CAF50]).png
  75. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersUniform(0).png
  76. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersUniform(10).png
  77. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersUniform(100).png
  78. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersUniform(25).png
  79. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersUniform(5).png
  80. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersUniform(50).png
  81. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,0,0,0,15).png
  82. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,0,0,0,5).png
  83. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,0,0,5,15).png
  84. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,0,0,5,5).png
  85. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,0,5,0,15).png
  86. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,0,5,0,5).png
  87. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,0,5,5,15).png
  88. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,0,5,5,5).png
  89. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,5,0,0,15).png
  90. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,5,0,0,5).png
  91. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,5,0,5,15).png
  92. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,5,0,5,5).png
  93. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,5,5,0,15).png
  94. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,5,5,0,5).png
  95. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,5,5,5,15).png
  96. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,5,5,5,5).png
  97. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(5,0,0,0,15).png
  98. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(5,0,0,0,5).png
  99. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(5,0,0,5,15).png
  100. BIN
      Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(5,0,0,5,5).png

+ 1 - 0
.github/workflows/main.yml

@@ -82,6 +82,7 @@ jobs:
           dotnet build --configuration Release --property WarningLevel=0
           dotnet build --configuration Release --property WarningLevel=0
           dotnet test QuestPDF.UnitTests --configuration Release --runtime ${{ matrix.runtime.name }} --framework net8.0
           dotnet test QuestPDF.UnitTests --configuration Release --runtime ${{ matrix.runtime.name }} --framework net8.0
           dotnet test QuestPDF.LayoutTests --configuration Release --runtime ${{ matrix.runtime.name }} --framework net8.0
           dotnet test QuestPDF.LayoutTests --configuration Release --runtime ${{ matrix.runtime.name }} --framework net8.0
+          dotnet test QuestPDF.VisualTests --configuration Release --runtime ${{ matrix.runtime.name }} --framework net8.0
           dotnet test QuestPDF.DocumentationExamples --configuration Release --runtime ${{ matrix.runtime.name }} --framework net8.0
           dotnet test QuestPDF.DocumentationExamples --configuration Release --runtime ${{ matrix.runtime.name }} --framework net8.0
           dotnet test QuestPDF.ReportSample --configuration Release --runtime ${{ matrix.runtime.name }} --framework net8.0
           dotnet test QuestPDF.ReportSample --configuration Release --runtime ${{ matrix.runtime.name }} --framework net8.0
 
 

+ 1 - 0
Source/QuestPDF.Companion.TestRunner/QuestPDF.Companion.TestRunner.csproj

@@ -5,6 +5,7 @@
         <TargetFramework>net8.0</TargetFramework>
         <TargetFramework>net8.0</TargetFramework>
         <ImplicitUsings>enable</ImplicitUsings>
         <ImplicitUsings>enable</ImplicitUsings>
         <Nullable>enable</Nullable>
         <Nullable>enable</Nullable>
+        <SatelliteResourceLanguages>en</SatelliteResourceLanguages>
     </PropertyGroup>
     </PropertyGroup>
 
 
     <ItemGroup>
     <ItemGroup>

+ 67 - 4
Source/QuestPDF.DocumentationExamples/BackgroundExamples.cs

@@ -7,7 +7,7 @@ namespace QuestPDF.DocumentationExamples;
 public class BackgroundExamples
 public class BackgroundExamples
 {
 {
     [Test]
     [Test]
-    public void Example()
+    public void SolidColor()
     {
     {
         Document
         Document
             .Create(document =>
             .Create(document =>
@@ -17,6 +17,8 @@ public class BackgroundExamples
                     page.MinSize(new PageSize(0, 0));
                     page.MinSize(new PageSize(0, 0));
                     page.MaxSize(new PageSize(1000, 1000));
                     page.MaxSize(new PageSize(1000, 1000));
                     page.DefaultTextStyle(x => x.FontSize(20));
                     page.DefaultTextStyle(x => x.FontSize(20));
+                    page.PageColor(Colors.White);
+                    page.Margin(25);
 
 
                     var colors = new[]
                     var colors = new[]
                     {
                     {
@@ -40,8 +42,8 @@ public class BackgroundExamples
                     };
                     };
                     
                     
                     page.Content()
                     page.Content()
-                        .Height(100)
-                        .Width(280)
+                        .Height(150)
+                        .Width(420)
                         .Row(row =>
                         .Row(row =>
                         {
                         {
                             foreach (var color in colors)
                             foreach (var color in colors)
@@ -49,6 +51,67 @@ public class BackgroundExamples
                         });
                         });
                 });
                 });
             })
             })
-            .GenerateImages(x => "background.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.VeryHigh, RasterDpi = 144 });
+            .GenerateImages(x => "background-solid.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.VeryHigh, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void Gradient() 
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(350, 0));
+                    page.MaxSize(new PageSize(350, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.PageColor(Colors.White);
+                    page.Margin(25);
+
+                    page.Content()
+                        .Column(column =>
+                        {
+                            column.Spacing(25);
+ 
+                            column.Item()
+                                .BackgroundLinearGradient(0, [Colors.Red.Lighten2, Colors.Blue.Lighten2])
+                                .AspectRatio(2);
+
+                            column.Item()
+                                .BackgroundLinearGradient(45, [Colors.Green.Lighten2, Colors.LightGreen.Lighten2, Colors.Yellow.Lighten2])
+                                .AspectRatio(2);
+                            
+                            column.Item()
+                                .BackgroundLinearGradient(90, [Colors.Yellow.Lighten2, Colors.Amber.Lighten2, Colors.Orange.Lighten2])
+                                .AspectRatio(2);
+                        });
+                });
+            })
+            .GenerateImages(x => "background-gradient.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.VeryHigh, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void RoundedCorners() 
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {   
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(1000, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.PageColor(Colors.White);
+                    page.Margin(25);
+
+                    page.Content()
+                        .Shrink()
+                        .Background(Colors.Grey.Lighten2)
+                        .CornerRadius(25)
+                        .Padding(25)
+                        .Text("Content with rounded corners");
+                });
+            })
+            .GenerateImages(x => "background-rounded-corners.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.VeryHigh, RasterDpi = 144 });
     }
     }
 }
 }

+ 284 - 22
Source/QuestPDF.DocumentationExamples/BorderExamples.cs

@@ -8,6 +8,34 @@ public class BorderExamples
 {
 {
     [Test]
     [Test]
     public void SimpleExample()
     public void SimpleExample()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.ContinuousSize(450);
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(25);
+                    page.PageColor(Colors.White);
+                    
+                    page.Content()
+                        .Border(3, Colors.Blue.Darken4)
+                        .Background(Colors.Blue.Lighten5)
+                        .Padding(25) 
+                        .Text(text =>
+                        {
+                            text.DefaultTextStyle(x => x.FontColor(Colors.Blue.Darken4).FontSize(16));
+                            text.Span("TIP: ").Bold();
+                            text.Span("You can use borders to create visual separation between elements in your document. Borders can be applied to any element, including text, images, and containers.");
+                        });
+                });
+            })
+            .GenerateImages(x => "border-simple.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.VeryHigh, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void Multiple()
     {
     {
         Document
         Document
             .Create(document =>
             .Create(document =>
@@ -17,25 +45,148 @@ public class BorderExamples
                     page.MinSize(new PageSize(0, 0));
                     page.MinSize(new PageSize(0, 0));
                     page.MaxSize(new PageSize(1000, 1000));
                     page.MaxSize(new PageSize(1000, 1000));
                     page.DefaultTextStyle(x => x.FontSize(20));
                     page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(25);
+                    page.PageColor(Colors.White);
                     
                     
                     page.Content()
                     page.Content()
-                        .Width(150)
-                        .Padding(25)  
+                        .Shrink()
+                        
+                        .BorderVertical(5)
+                        .BorderColor(Colors.Green.Darken2)
+                        .BorderAlignmentInside()
+
+                        .Container()
+
+                        .BorderHorizontal( 10)
+                        .BorderColor(Colors.Blue.Lighten1)
+                        .BorderAlignmentInside()
+                        
+                        .Background(Colors.Grey.Lighten2)
+                        .PaddingVertical(25)
+                        .PaddingHorizontal(50)
+                        .Text("Content");
+                });
+            })
+            .GenerateImages(x => "border-multiple.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.VeryHigh, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void ConsistentThickness()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(550, 0));
+                    page.MaxSize(new PageSize(550, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(25);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
+                        .Row(row =>
+                        {
+                            row.Spacing(25);
+                            
+                            row.RelativeItem()
+                                .Border(1, Colors.Black)
+                                .Padding(10)
+                                .AlignCenter()
+                                .Text("Thin");
+                            
+                            row.RelativeItem()
+                                .Border(3, Colors.Black)
+                                .Padding(10)
+                                .AlignCenter()
+                                .Text("Medium");
+                            
+                            row.RelativeItem()
+                                .Border(9, Colors.Black)
+                                .Padding(10)
+                                .AlignCenter()
+                                .Text("Bold");
+                        });
+                });
+            })
+            .GenerateImages(x => "border-thickness-consistent.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.VeryHigh, RasterDpi = 144 });
+    }
+
+    [Test]
+    public void VariousThickness()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(1000, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(25);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
                         .BorderLeft(4)
                         .BorderLeft(4)
                         .BorderTop(6)
                         .BorderTop(6)
                         .BorderRight(8) 
                         .BorderRight(8) 
                         .BorderBottom(10)
                         .BorderBottom(10)
-                        .BorderColor(Colors.LightBlue.Darken3)
-                        .Background(Colors.Grey.Lighten3)
-                        .Padding(25) 
-                        .Text("Text");
+                        .Padding(25)
+                        .Text("Sample text");
                 });
                 });
             })
             })
-            .GenerateImages(x => "border-simple.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.VeryHigh, RasterDpi = 144 });
+            .GenerateImages(x => "border-thickness-various.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.VeryHigh, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void Alignment()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(725, 0));
+                    page.MaxSize(new PageSize(725, 1000)); 
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(50);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
+                        .Row(row =>
+                        {
+                            row.Spacing(25);
+                            
+                            row.RelativeItem()
+                                .Background(Colors.Grey.Lighten1)
+                                .Padding(25)
+                                .Text("No Border");
+                            
+                            row.RelativeItem()
+                                .Border(10, Colors.Grey.Darken2)
+                                .BorderAlignmentInside()
+                                .Padding(25)
+                                .Text("Border Inside");
+                            
+                            row.RelativeItem()
+                                .Border(10, Colors.Grey.Darken2)
+                                .BorderAlignmentMiddle()
+                                .Padding(25)
+                                .Text("Border Middle");
+                            
+                            row.RelativeItem()
+                                .Border(10, Colors.Grey.Darken2)
+                                .BorderAlignmentOutside()
+                                .Padding(25)
+                                .Text("Border Outside");
+                        });
+                });
+            })
+            .GenerateImages(x => "border-alignment.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.VeryHigh, RasterDpi = 144 });
     }
     }
     
     
     [Test]
     [Test]
-    public void ManyExample()
+    public void RoundedCorners1()
     {
     {
         Document
         Document
             .Create(document =>
             .Create(document =>
@@ -45,25 +196,136 @@ public class BorderExamples
                     page.MinSize(new PageSize(0, 0));
                     page.MinSize(new PageSize(0, 0));
                     page.MaxSize(new PageSize(1000, 1000));
                     page.MaxSize(new PageSize(1000, 1000));
                     page.DefaultTextStyle(x => x.FontSize(20));
                     page.DefaultTextStyle(x => x.FontSize(20));
-                    
+                    page.Margin(25);
+                    page.PageColor(Colors.White);
+
                     page.Content()
                     page.Content()
-                        .Width(150)
+                        .CornerRadius(10)
+                        .Border(1, Colors.Black)
+                        .Background(Colors.Grey.Lighten2)
                         .Padding(25)
                         .Padding(25)
+                        .Text("Border with rounded corners"); 
+                });
+            })
+            .GenerateImages(x => "border-rounded-corners-1.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.VeryHigh, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void RoundedCorners2()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(1000, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(25);
+                    page.PageColor(Colors.White);
 
 
-                        .BorderTop(5)
-                        .BorderColor(Colors.LightGreen.Darken2)
-
-                        .Container()
-
-                        .BorderBottom(10)
-                        .BorderColor(Colors.LightBlue.Darken2)
-                        
-                        .Background(Colors.Grey.Lighten3)
+                    page.Content()
+                        .CornerRadius(10)
+                        .BorderLeft(10)
+                        .BorderAlignmentInside()
+                        .BorderColor(Colors.Green.Darken2)
+                        .Background(Colors.Green.Lighten4)
                         .Padding(25)
                         .Padding(25)
-                        .Text("Text")
-                        .FontSize(20);
+                        .PaddingLeft(10)
+                        .DefaultTextStyle(x => x.FontColor(Colors.Green.Darken4))
+                        .Column(column =>
+                        {
+                            column.Item().Text("Completed").Bold();
+                            column.Item().Height(5);
+                            column.Item().Text("The invoice has been paid in full.").FontSize(16);
+                        });
+                });
+            })
+            .GenerateImages(x => "border-rounded-corners-2.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.VeryHigh, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void SolidColor()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.ContinuousSize(450);
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(25);
+                    page.PageColor(Colors.White);
+                    
+                    page.Content()
+                        .Row(row =>
+                        {
+                            var colors = new[]
+                            {
+                                Colors.Red.Medium,
+                                Colors.Green.Medium,
+                                Colors.Blue.Medium
+                            };
+                            
+                            row.Spacing(25);
+                            
+                            foreach (var color in colors)
+                            {
+                                row.RelativeItem()
+                                    .Border(5)
+                                    .BorderColor(color)
+                                    .Padding(15)
+                                    .Text(color)
+                                    .FontColor(color);
+                            }
+                        });
+                });
+            })
+            .GenerateImages(x => "border-color-solid.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.VeryHigh, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void Gradient()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(1000, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(25);
+                    page.PageColor(Colors.White);
+                    
+                    page.Content()
+                        .Column(column =>
+                        {
+                            column.Spacing(25);
+                            
+                            column.Item()
+                                .Border(5)
+                                .BorderLinearGradient(0, [Colors.Red.Darken1, Colors.Blue.Darken1])
+                                .BorderAlignmentInside()
+                                .Padding(25)
+                                .Text("Horizontal gradient");
+                            
+                            column.Item()
+                                .Border(10)
+                                .BorderLinearGradient(45, [Colors.Green.Darken1, Colors.LightGreen.Darken1, Colors.Yellow.Darken1])
+                                .BorderAlignmentInside()
+                                .Padding(25)
+                                .Text("Diagonal gradient");
+                            
+                            column.Item()
+                                .Border(10)
+                                .BorderLinearGradient(90, [Colors.Yellow.Darken1, Colors.Amber.Darken1, Colors.Orange.Darken1])
+                                .CornerRadius(20)
+                                .Padding(25)
+                                .Text("Vertical gradient");
+                        });
                 });
                 });
             })
             })
-            .GenerateImages(x => "border-many.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.VeryHigh, RasterDpi = 144 });
+            .GenerateImages(x => "border-color-gradient.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.VeryHigh, RasterDpi = 144 });
     }
     }
 }
 }

+ 174 - 0
Source/QuestPDF.DocumentationExamples/LineExamples.cs

@@ -18,6 +18,7 @@ public class LineExamples
                     page.MaxSize(new PageSize(1000, 1000));
                     page.MaxSize(new PageSize(1000, 1000));
                     page.DefaultTextStyle(x => x.FontSize(20));
                     page.DefaultTextStyle(x => x.FontSize(20));
                     page.Margin(25);
                     page.Margin(25);
+                    page.PageColor(Colors.White);
 
 
                     page.Content()
                     page.Content()
                         .Row(row =>
                         .Row(row =>
@@ -48,6 +49,7 @@ public class LineExamples
                     page.MaxSize(new PageSize(1000, 1000));
                     page.MaxSize(new PageSize(1000, 1000));
                     page.DefaultTextStyle(x => x.FontSize(20));
                     page.DefaultTextStyle(x => x.FontSize(20));
                     page.Margin(25);
                     page.Margin(25);
+                    page.PageColor(Colors.White);
 
 
                     page.Content()
                     page.Content()
                         .Column(column =>
                         .Column(column =>
@@ -65,4 +67,176 @@ public class LineExamples
             })
             })
             .GenerateImages(x => "line-horizontal.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.Best, RasterDpi = 144 });
             .GenerateImages(x => "line-horizontal.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.Best, RasterDpi = 144 });
     }
     }
+    
+    [Test]
+    public void Thickness()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(1000, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(25);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
+                        .Column(column =>
+                        {
+                            column.Spacing(20);
+    
+                            foreach (var thickness in new[] { 1, 2, 4, 8 })
+                            {
+                                column.Item()
+                                    .Width(200)
+                                    .LineHorizontal(thickness);
+                            }
+                        });
+                });
+            })
+            .GenerateImages(x => "line-thickness.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.Best, RasterDpi = 144 });
+    }
+
+    [Test]
+    public void SolidColor()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(1000, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(25);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
+                        .Column(column =>
+                        {
+                            var colors = new[]
+                            {
+                                Colors.Red.Medium,
+                                Colors.Green.Medium,
+                                Colors.Blue.Medium,
+                            };
+                            
+                            column.Spacing(20);
+                
+                            foreach (var color in colors)
+                            {
+                                column.Item()
+                                    .Width(200)
+                                    .LineHorizontal(5)
+                                    .LineColor(color);
+                            }
+                        });
+                });
+            })
+            .GenerateImages(x => "line-color-solid.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.Best, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void Gradient()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(1000, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(25);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
+                        .Column(column =>
+                        {
+                            column.Spacing(20);
+
+                            column.Item()
+                                .Width(200)
+                                .LineHorizontal(5)
+                                .LineGradient([Colors.Red.Medium, Colors.Orange.Medium]);
+                
+                            column.Item()
+                                .Width(200)
+                                .LineHorizontal(5)
+                                .LineGradient([Colors.Orange.Medium, Colors.Yellow.Medium, Colors.Lime.Medium]);
+                
+                            column.Item()
+                                .Width(200)
+                                .LineHorizontal(5)
+                                .LineGradient([Colors.Blue.Lighten2, Colors.LightBlue.Lighten1, Colors.Cyan.Medium, Colors.Teal.Darken1, Colors.Green.Darken2]);
+                        });
+                });
+            })
+            .GenerateImages(x => "line-color-gradient.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.Best, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void DashPattern()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(1000, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(25);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
+                        .Column(column =>
+                        {
+                            column.Spacing(20);
+
+                            column.Item()
+                                .Width(200)
+                                .LineHorizontal(5)
+                                .LineDashPattern([4f, 4f]);
+                
+                            column.Item()
+                                .Width(200)
+                                .LineHorizontal(5)
+                                .LineDashPattern([12f, 12f]);
+                
+                            column.Item()
+                                .Width(200)
+                                .LineHorizontal(5)
+                                .LineDashPattern([4f, 4f, 12f, 4f]);
+                        });
+                });
+            })
+            .GenerateImages(x => "line-dash-pattern.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.Best, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void Complex()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(1000, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(25);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
+                        .Width(300)
+                        .LineHorizontal(8)
+                        .LineDashPattern([4, 4, 8, 8, 12, 12])
+                        .LineGradient([Colors.Red.Medium, Colors.Orange.Medium, Colors.Yellow.Medium]);
+                });
+            })
+            .GenerateImages(x => "line-example.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.Best, RasterDpi = 144 });
+    }
 }
 }

+ 4 - 3
Source/QuestPDF.DocumentationExamples/QuestPDF.DocumentationExamples.csproj

@@ -4,6 +4,7 @@
         <TargetFramework>net8.0</TargetFramework>
         <TargetFramework>net8.0</TargetFramework>
         <ImplicitUsings>enable</ImplicitUsings>
         <ImplicitUsings>enable</ImplicitUsings>
         <Nullable>enable</Nullable>
         <Nullable>enable</Nullable>
+        <SatelliteResourceLanguages>en</SatelliteResourceLanguages>
 
 
         <IsPackable>false</IsPackable>
         <IsPackable>false</IsPackable>
         <IsTestProject>true</IsTestProject>
         <IsTestProject>true</IsTestProject>
@@ -16,14 +17,14 @@
         </PackageReference>
         </PackageReference>
         <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
         <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
         <PackageReference Include="NUnit" Version="3.14.0"/>
         <PackageReference Include="NUnit" Version="3.14.0"/>
-        <PackageReference Include="NUnit.Analyzers" Version="4.7.0">
+        <PackageReference Include="NUnit.Analyzers" Version="4.9.2">
           <PrivateAssets>all</PrivateAssets>
           <PrivateAssets>all</PrivateAssets>
           <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
           <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
         </PackageReference>
         </PackageReference>
         <PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
         <PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
         <PackageReference Include="ScottPlot" Version="5.0.55" />
         <PackageReference Include="ScottPlot" Version="5.0.55" />
-        <PackageReference Include="SkiaSharp" Version="3.116.1" />
-        <PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="3.116.1" />
+        <PackageReference Include="SkiaSharp" Version="3.119.0" />
+        <PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="3.119.0" />
         <PackageReference Include="ZXing.Net" Version="0.16.10" />
         <PackageReference Include="ZXing.Net" Version="0.16.10" />
     </ItemGroup>
     </ItemGroup>
 
 

+ 146 - 0
Source/QuestPDF.DocumentationExamples/RoundedCornersExamples.cs

@@ -0,0 +1,146 @@
+using QuestPDF.Fluent;
+using QuestPDF.Helpers;
+using QuestPDF.Infrastructure;
+
+namespace QuestPDF.DocumentationExamples;
+
+public class RoundedCornersExamples
+{
+    [Test]
+    public void Consistent()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(1000, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(25);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
+                        .Border(1, Colors.Black)
+                        .Background(Colors.Grey.Lighten3)
+                        .CornerRadius(25)
+                        .Padding(25)
+                        .Text("Container with consistently rounded corners");
+                });
+            })
+            .GenerateImages(x => "rounded-corners-consistent.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.Best, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void Various()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(1000, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(25);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
+                        .Border(1, Colors.Black)
+                        .Background(Colors.Grey.Lighten3)
+                        .CornerRadiusTopLeft(5)
+                        .CornerRadiusTopRight(10)
+                        .CornerRadiusBottomRight(20)
+                        .CornerRadiusBottomLeft(40)
+                        .Padding(25)
+                        .Text("Container with rounded corners");
+                });
+            })
+            .GenerateImages(x => "rounded-corners-various.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.Best, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void Complex()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(550, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(25);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
+                        .Border(1, Colors.Black)
+                        .CornerRadius(15)
+                        .Table(table =>
+                        {
+                            table.ColumnsDefinition(columns =>
+                            {
+                                columns.ConstantColumn(100);
+                                columns.RelativeColumn();
+                                columns.ConstantColumn(150);
+                            });
+                            
+                            table.Header(header =>
+                            {
+                                header.Cell().Element(Style).Text("Index");
+                                header.Cell().Element(Style).Text("Label");
+                                header.Cell().Element(Style).Text("Price");
+
+                                IContainer Style(IContainer container)
+                                {
+                                    return container
+                                        .Border(1, Colors.Grey.Darken2)
+                                        .Background(Colors.Grey.Lighten3)
+                                        .PaddingVertical(10)
+                                        .PaddingHorizontal(15)
+                                        .DefaultTextStyle(x => x.Bold());
+                                }
+                            });
+
+                            foreach (var index in Enumerable.Range(1, 5))
+                            {
+                                table.Cell().Element(Style).Text(index.ToString());
+                                table.Cell().Element(Style).Text(Placeholders.Label());
+                                table.Cell().Element(Style).Text(Placeholders.Price());
+                                
+                                IContainer Style(IContainer container)
+                                {
+                                    return container
+                                        .Border(1, Colors.Grey.Darken2)
+                                        .PaddingVertical(10)
+                                        .PaddingHorizontal(15);
+                                }
+                            }
+                        });
+                });
+            })
+            .GenerateImages(x => "rounded-corners-complex.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.Best, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void Image()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(450, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(25);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
+                        .CornerRadius(25)
+                        .Image("Resources/landscape.jpg");
+                });
+            })
+            .GenerateImages(x => "rounded-corners-image.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.Best, RasterDpi = 144 });
+    }
+}

+ 279 - 0
Source/QuestPDF.DocumentationExamples/ShadowExamples.cs

@@ -0,0 +1,279 @@
+using QuestPDF.Fluent;
+using QuestPDF.Helpers;
+using QuestPDF.Infrastructure;
+
+namespace QuestPDF.DocumentationExamples;
+
+public class ShadowExamples
+{
+    [Test]
+    public void Simple()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(1000, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(50);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
+                        .Border(1, Colors.Black)
+                        .Shadow(new BoxShadowStyle
+                        {
+                            Color = Colors.Grey.Medium, 
+                            Blur = 5, 
+                            Spread = 5,
+                            OffsetX = 5, 
+                            OffsetY = 5
+                        })
+                        .Background(Colors.White)
+                        .Padding(15)
+                        .Text("Important content");
+                });
+            })
+            .GenerateImages(x => $"shadow-simple.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.Best, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void OffsetX()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(1000, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(50);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
+                        .Row(row =>
+                        {
+                            row.Spacing(50);
+                            
+                            foreach (var offsetX in new[] { -10, 0, 10 })
+                            {
+                                row.ConstantItem(100)
+                                    .AspectRatio(1)
+                                    .Shadow(new BoxShadowStyle
+                                    {
+                                        Color = Colors.Grey.Darken1,
+                                        Blur = 10,
+                                        OffsetX = offsetX
+                                    })
+                                    .Background(Colors.White);
+                            }
+                        });
+                });
+            })
+            .GenerateImages(x => $"shadow-offset-x.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.Best, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void OffsetY()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(1000, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(50);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
+                        .Row(row =>
+                        {
+                            row.Spacing(50);
+                            
+                            foreach (var offsetY in new[] { -10, 0, 10 })
+                            {
+                                row.ConstantItem(100)
+                                    .AspectRatio(1)
+                                    .Shadow(new BoxShadowStyle
+                                    {
+                                        Color = Colors.Grey.Darken2,
+                                        Blur = 10,
+                                        OffsetY = offsetY
+                                    })
+                                    .Background(Colors.White);
+                            }
+                        });
+                });
+            })
+            .GenerateImages(x => $"shadow-offset-y.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.Best, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void Color()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(1000, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(50);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
+                        .Row(row =>
+                        {
+                            row.Spacing(50);
+                            
+                            var colors = new[]
+                            {
+                                Colors.Red.Darken2,
+                                Colors.Green.Darken2,
+                                Colors.Blue.Darken2
+                            };
+                            
+                            foreach (var color in colors)
+                            {
+                                row.ConstantItem(100)
+                                    .AspectRatio(1)
+                                    .Shadow(new BoxShadowStyle
+                                    {
+                                        Color = color,
+                                        Blur = 10
+                                    })
+                                    .Background(Colors.White);
+                            }
+                        });
+                });
+            })
+            .GenerateImages(x => $"shadow-color.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.Best, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void Blur()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(1000, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(50);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
+                        .Row(row =>
+                        {
+                            row.Spacing(50);
+
+                            foreach (var blur in new[] { 5, 10, 20 })
+                            {
+                                row.ConstantItem(100)
+                                    .AspectRatio(1)
+                                    .Shadow(new BoxShadowStyle
+                                    {
+                                        Color = Colors.Grey.Darken1,
+                                        Blur = blur
+                                    })
+                                    .Background(Colors.White);
+                            }
+                        });
+                });
+            })
+            .GenerateImages(x => $"shadow-blur.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.Best, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void Spread()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(1000, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(50);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
+                        .Row(row =>
+                        {
+                            row.Spacing(50);
+
+                            foreach (var spread in new[] { 0, 5, 10 })
+                            {
+                                row.ConstantItem(100)
+                                    .AspectRatio(1)
+                                    .Shadow(new BoxShadowStyle
+                                    {
+                                        Color = Colors.Grey.Darken1,
+                                        Blur = 5,
+                                        Spread = spread
+                                    })
+                                    .Background(Colors.White);
+                            }
+                        });
+                });
+            })
+            .GenerateImages(x => $"shadow-spread.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.Best, RasterDpi = 144 });
+    }
+    
+    [Test]
+    public void NoBlur()
+    {
+        Document
+            .Create(document =>
+            {
+                document.Page(page =>
+                {
+                    page.MinSize(new PageSize(0, 0));
+                    page.MaxSize(new PageSize(1000, 1000));
+                    page.DefaultTextStyle(x => x.FontSize(20));
+                    page.Margin(50);
+                    page.PageColor(Colors.White);
+
+                    page.Content()
+                        .Row(row =>
+                        {
+                            row.Spacing(50);
+
+                            row.ConstantItem(100)
+                                .AspectRatio(1)
+                                .Shadow(new BoxShadowStyle
+                                {
+                                    Color = Colors.Grey.Lighten1,
+                                    Blur = 0, 
+                                    OffsetX = 8,
+                                    OffsetY = 8
+                                })
+                                .Border(1, Colors.Black)
+                                .Background(Colors.White);
+                            
+                            row.ConstantItem(100)
+                                .AspectRatio(1)
+                                .Shadow(new BoxShadowStyle
+                                {
+                                    Color = Colors.Grey.Lighten1,
+                                    Blur = 0,
+                                    OffsetX = 8,
+                                    OffsetY = 8
+                                })
+                                .Border(1, Colors.Black)
+                                .CornerRadius(16)
+                                .Background(Colors.White);
+                        });
+                });
+            })
+            .GenerateImages(x => $"shadow-no-blur.webp", new ImageGenerationSettings() { ImageFormat = ImageFormat.Webp, ImageCompressionQuality = ImageCompressionQuality.Best, RasterDpi = 144 });
+    }
+}

+ 3 - 2
Source/QuestPDF.LayoutTests/QuestPDF.LayoutTests.csproj

@@ -4,6 +4,7 @@
         <TargetFramework>net8.0</TargetFramework>
         <TargetFramework>net8.0</TargetFramework>
         <ImplicitUsings>enable</ImplicitUsings>
         <ImplicitUsings>enable</ImplicitUsings>
         <Nullable>enable</Nullable>
         <Nullable>enable</Nullable>
+        <SatelliteResourceLanguages>en</SatelliteResourceLanguages>
 
 
         <IsPackable>false</IsPackable>
         <IsPackable>false</IsPackable>
     </PropertyGroup>
     </PropertyGroup>
@@ -12,8 +13,8 @@
         <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
         <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
         <PackageReference Include="NUnit" Version="4.2.2" />
         <PackageReference Include="NUnit" Version="4.2.2" />
         <PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
         <PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
-        <PackageReference Include="SkiaSharp" Version="3.116.1" />
-        <PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="3.116.1" />
+        <PackageReference Include="SkiaSharp" Version="3.119.0" />
+        <PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="3.119.0" />
     </ItemGroup>
     </ItemGroup>
 
 
     <ItemGroup>
     <ItemGroup>

+ 5 - 2
Source/QuestPDF.LayoutTests/TestEngine/MockChild.cs

@@ -1,6 +1,7 @@
 using QuestPDF.Drawing;
 using QuestPDF.Drawing;
 using QuestPDF.Helpers;
 using QuestPDF.Helpers;
 using QuestPDF.Infrastructure;
 using QuestPDF.Infrastructure;
+using QuestPDF.Skia;
 
 
 namespace QuestPDF.LayoutTests.TestEngine;
 namespace QuestPDF.LayoutTests.TestEngine;
 
 
@@ -48,8 +49,10 @@ internal class ElementMock : Element
         var size = new Size(TotalWidth, height);
         var size = new Size(TotalWidth, height);
         
         
         HeightOffset += height;
         HeightOffset += height;
-        
-        Canvas.DrawFilledRectangle(Position.Zero, size, Colors.Grey.Medium);
+
+        using var paint = new SkPaint();
+        paint.SetSolidColor(Colors.Grey.Medium);
+        Canvas.DrawRectangle(Position.Zero, size, paint);
         
         
         var matrix = Canvas.GetCurrentMatrix();
         var matrix = Canvas.GetCurrentMatrix();
         
         

+ 4 - 4
Source/QuestPDF.ReportSample/QuestPDF.ReportSample.csproj

@@ -2,18 +2,18 @@
 
 
     <PropertyGroup>
     <PropertyGroup>
         <TargetFramework>net8.0</TargetFramework>
         <TargetFramework>net8.0</TargetFramework>
+        <SatelliteResourceLanguages>en</SatelliteResourceLanguages>
         <IsPackable>false</IsPackable>
         <IsPackable>false</IsPackable>
-        <LangVersion>10</LangVersion>
         <RootNamespace>QuestPDF.ReportSample</RootNamespace>
         <RootNamespace>QuestPDF.ReportSample</RootNamespace>
     </PropertyGroup>
     </PropertyGroup>
 
 
     <ItemGroup>
     <ItemGroup>
-        <PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
+        <PackageReference Include="BenchmarkDotNet" Version="0.15.2" />
         <PackageReference Include="nunit" Version="4.2.2" />
         <PackageReference Include="nunit" Version="4.2.2" />
         <PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
         <PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
         <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
         <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
-        <PackageReference Include="SkiaSharp" Version="3.116.1" />
-        <PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="3.116.1" />
+        <PackageReference Include="SkiaSharp" Version="3.119.0" />
+        <PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="3.119.0" />
     </ItemGroup>
     </ItemGroup>
 
 
     <ItemGroup>
     <ItemGroup>

+ 0 - 43
Source/QuestPDF.UnitTests/BackgroundTests.cs

@@ -1,43 +0,0 @@
-using NUnit.Framework;
-using QuestPDF.Elements;
-using QuestPDF.Helpers;
-using QuestPDF.Infrastructure;
-using QuestPDF.UnitTests.TestEngine;
-
-namespace QuestPDF.UnitTests
-{
-    [TestFixture]
-    public class BackgroundTests
-    {
-        [Test]
-        public void Measure() => SimpleContainerTests.Measure<Background>();
-        
-        [Test]
-        public void Draw_ShouldHandleNullChild()
-        {
-            TestPlan
-                .For(x => new Background
-                {
-                    Color = Colors.Red.Medium
-                })
-                .DrawElement(new Size(400, 300))
-                .ExpectCanvasDrawRectangle(new Position(0, 0), new Size(400, 300), Colors.Red.Medium)
-                .CheckDrawResult();
-        }
-        
-        [Test]
-        public void Draw_ShouldHandleChild()
-        {
-            TestPlan
-                .For(x => new Background
-                {
-                    Color = Colors.Red.Medium,
-                    Child = x.CreateChild()
-                })
-                .DrawElement(new Size(400, 300))
-                .ExpectCanvasDrawRectangle(new Position(0, 0), new Size(400, 300), Colors.Red.Medium)
-                .ExpectChildDraw(new Size(400, 300))
-                .CheckDrawResult();
-        }
-    }
-}

+ 0 - 59
Source/QuestPDF.UnitTests/BorderTests.cs

@@ -1,59 +0,0 @@
-using NUnit.Framework;
-using QuestPDF.Drawing;
-using QuestPDF.Elements;
-using QuestPDF.Helpers;
-using QuestPDF.Infrastructure;
-using QuestPDF.UnitTests.TestEngine;
-
-namespace QuestPDF.UnitTests
-{
-    [TestFixture]
-    public class BorderTests
-    {
-        [Test]
-        public void Measure() => SimpleContainerTests.Measure<Border>();
-        
-        [Test]
-        public void ComponentShouldNotAffectLayout()
-        {
-            TestPlan
-                .For(x => new Border
-                {
-                    Top = 10,
-                    Right = 20,
-                    Bottom = 30,
-                    Left = 40,
-                    
-                    Child = x.CreateChild()
-                })
-                .MeasureElement(new Size(400, 300))
-                .ExpectChildMeasure(expectedInput: new Size(400, 300), returns: SpacePlan.FullRender(new Size(100, 50)))
-                .CheckMeasureResult( SpacePlan.FullRender(new Size(100, 50)));
-        }
-        
-        [Test]
-        public void Draw_HorizontalRight_VerticalTop()
-        {
-            TestPlan
-                .For(x => new Border
-                {
-                    Top = 10,
-                    Right = 20,
-                    Bottom = 30,
-                    Left = 40,
-                    
-                    Color = Colors.Red.Medium,
-                    
-                    Child = x.CreateChild()
-                })
-                .DrawElement(new Size(400, 300))
-                .ExpectChildDraw(new Size(400, 300))
-                .ExpectCanvasDrawRectangle(new Position(-20, -5), new Size(430, 10), Colors.Red.Medium) // top
-                .ExpectCanvasDrawRectangle(new Position(-20, -5), new Size(40, 320), Colors.Red.Medium) // left
-                .ExpectCanvasDrawRectangle(new Position(-20, 285), new Size(430, 30), Colors.Red.Medium) // bottom
-                .ExpectCanvasDrawRectangle(new Position(390, -5), new Size(20, 320), Colors.Red.Medium) // right
-                .ExpectChildDraw(new Size(400, 300))
-                .CheckDrawResult();
-        }
-    }
-}

+ 3 - 3
Source/QuestPDF.UnitTests/QuestPDF.UnitTests.csproj

@@ -2,8 +2,8 @@
 
 
     <PropertyGroup>
     <PropertyGroup>
         <TargetFramework>net8.0</TargetFramework>
         <TargetFramework>net8.0</TargetFramework>
+        <SatelliteResourceLanguages>en</SatelliteResourceLanguages>
         <IsPackable>false</IsPackable>
         <IsPackable>false</IsPackable>
-        <LangVersion>10</LangVersion>
         <IsTestProject>true</IsTestProject>
         <IsTestProject>true</IsTestProject>
     </PropertyGroup>
     </PropertyGroup>
 
 
@@ -11,8 +11,8 @@
         <PackageReference Include="nunit" Version="4.3.2" />
         <PackageReference Include="nunit" Version="4.3.2" />
         <PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
         <PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
         <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
         <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
-        <PackageReference Include="SkiaSharp" Version="3.116.1" />
-        <PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="3.116.1" />
+        <PackageReference Include="SkiaSharp" Version="3.119.0" />
+        <PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="3.119.0" />
     </ItemGroup>
     </ItemGroup>
 
 
     <ItemGroup>
     <ItemGroup>

+ 5 - 2
Source/QuestPDF.UnitTests/TestEngine/MockCanvas.cs

@@ -31,8 +31,10 @@ 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 Rotate(float angle) => RotateFunc(angle);
         public void Rotate(float angle) => RotateFunc(angle);
 
 
-        public void DrawFilledRectangle(Position vector, Size size, Color color) => DrawRectFunc(vector, size, color);
-        public void DrawStrokeRectangle(Position vector, Size size, float strokeWidth, Color color) => throw new NotImplementedException();
+        public void DrawLine(Position start, Position end, SkPaint paint) => throw new NotImplementedException();
+        public void DrawRectangle(Position vector, Size size, SkPaint paint) => throw new NotImplementedException();
+        public void DrawComplexBorder(SkRoundedRect innerRect, SkRoundedRect outerRect, SkPaint paint) => throw new NotImplementedException();
+        public void DrawShadow(SkRoundedRect shadowRect, SkBoxShadow shadow) => throw new NotImplementedException();
         public void DrawParagraph(SkParagraph paragraph, int lineFrom, int lineTo) => throw new NotImplementedException();
         public void DrawParagraph(SkParagraph paragraph, int lineFrom, int lineTo) => throw new NotImplementedException();
         public void DrawImage(SkImage image, Size size) => DrawImageFunc(image, Position.Zero, size);
         public void DrawImage(SkImage image, Size size) => DrawImageFunc(image, Position.Zero, size);
         public void DrawPicture(SkPicture picture) => throw new NotImplementedException();
         public void DrawPicture(SkPicture picture) => throw new NotImplementedException();
@@ -42,6 +44,7 @@ namespace QuestPDF.UnitTests.TestEngine
         public void DrawOverflowArea(SkRect area) => throw new NotImplementedException();
         public void DrawOverflowArea(SkRect area) => throw new NotImplementedException();
         public void ClipOverflowArea(SkRect availableSpace, SkRect requiredSpace) => throw new NotImplementedException();
         public void ClipOverflowArea(SkRect availableSpace, SkRect requiredSpace) => throw new NotImplementedException();
         public void ClipRectangle(SkRect clipArea) => throw new NotImplementedException();
         public void ClipRectangle(SkRect clipArea) => throw new NotImplementedException();
+        public void ClipRoundedRectangle(SkRoundedRect clipArea) => throw new NotImplementedException();
         
         
         public void DrawHyperlink(string url, Size size) => throw new NotImplementedException();
         public void DrawHyperlink(string url, Size size) => throw new NotImplementedException();
         public void DrawSectionLink(string sectionName, Size size) => throw new NotImplementedException();
         public void DrawSectionLink(string sectionName, Size size) => throw new NotImplementedException();

+ 5 - 2
Source/QuestPDF.UnitTests/TestEngine/OperationRecordingCanvas.cs

@@ -28,8 +28,10 @@ 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 Rotate(float angle) => Operations.Add(new CanvasRotateOperation(angle));
         public void Rotate(float angle) => Operations.Add(new CanvasRotateOperation(angle));
 
 
-        public void DrawFilledRectangle(Position vector, Size size, Color color) => Operations.Add(new CanvasDrawRectangleOperation(vector, size, color));
-        public void DrawStrokeRectangle(Position vector, Size size, float strokeWidth, Color color) => throw new NotImplementedException();
+        public void DrawLine(Position start, Position end, SkPaint paint) => throw new NotImplementedException();
+        public void DrawRectangle(Position vector, Size size, SkPaint paint) => throw new NotImplementedException();
+        public void DrawComplexBorder(SkRoundedRect innerRect, SkRoundedRect outerRect, SkPaint paint) => throw new NotImplementedException();
+        public void DrawShadow(SkRoundedRect shadowRect, SkBoxShadow shadow) => throw new NotImplementedException();
         public void DrawParagraph(SkParagraph paragraph, int lineFrom, int lineTo) => throw new NotImplementedException();
         public void DrawParagraph(SkParagraph paragraph, int lineFrom, int lineTo) => throw new NotImplementedException();
         public void DrawImage(SkImage image, Size size) => Operations.Add(new CanvasDrawImageOperation(Position.Zero, size));
         public void DrawImage(SkImage image, Size size) => Operations.Add(new CanvasDrawImageOperation(Position.Zero, size));
         public void DrawPicture(SkPicture picture) => throw new NotImplementedException();
         public void DrawPicture(SkPicture picture) => throw new NotImplementedException();
@@ -39,6 +41,7 @@ namespace QuestPDF.UnitTests.TestEngine
         public void DrawOverflowArea(SkRect area) => throw new NotImplementedException();
         public void DrawOverflowArea(SkRect area) => throw new NotImplementedException();
         public void ClipOverflowArea(SkRect availableSpace, SkRect requiredSpace) => throw new NotImplementedException();
         public void ClipOverflowArea(SkRect availableSpace, SkRect requiredSpace) => throw new NotImplementedException();
         public void ClipRectangle(SkRect clipArea) => throw new NotImplementedException();
         public void ClipRectangle(SkRect clipArea) => throw new NotImplementedException();
+        public void ClipRoundedRectangle(SkRoundedRect clipArea) => throw new NotImplementedException();
         
         
         public void DrawHyperlink(string url, Size size) => throw new NotImplementedException();
         public void DrawHyperlink(string url, Size size) => throw new NotImplementedException();
         public void DrawSectionLink(string sectionName, Size size) => throw new NotImplementedException();
         public void DrawSectionLink(string sectionName, Size size) => throw new NotImplementedException();

BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/Color(#2196F3).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/Color(#4CAF50).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/Color(#F44336).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/Complex.png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/DashPattern([1.0f, 1.0f]).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/DashPattern([1.0f, 2.0f]).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/DashPattern([2.0f, 1.0f]).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/DashPattern([2.0f, 2.0f]).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/DashPattern([4.0f, 4.0f, 12.0f, 4.0f]).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/DashPattern([4.0f, 4.0f, 8.0f, 8.0f, 12.0f, ...]).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/DashPattern([4.0f, 4.0f]).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/DashPattern([8.0f, 8.0f]).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/Gradient([#2196F3, #03A9F4, #00BCD4, #009688, #4CAF50]).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/Gradient([#F44336, #4CAF50]).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/Gradient([#F44336, #FFEB3B, #4CAF50]).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/ThicknessHorizontal(1).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/ThicknessHorizontal(2).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/ThicknessHorizontal(4).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/ThicknessHorizontal(8).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/ThicknessVertical(1).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/ThicknessVertical(2).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/ThicknessVertical(4).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/Line/ThicknessVertical(8).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundColor(#2196F3).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundColor(#4CAF50).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundColor(#F44336).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundGradientAngle(0).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundGradientAngle(30).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundGradientAngle(45).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundGradientAngle(60).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundGradientAngle(90).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundGradientColors([#2196F3, #03A9F4, #00BCD4, #009688, #4CAF50]).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundGradientColors([#F44336, #388E3C]).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundGradientColors([#F44336, #FFEB3B, #4CAF50]).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundRoundedCorners(0,10,20,40).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundRoundedCorners(10,20,40,0).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundRoundedCorners(20,40,0,10).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundRoundedCorners(40,0,10,20).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundUniformRoundedCorners(0).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundUniformRoundedCorners(10).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundUniformRoundedCorners(100).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundUniformRoundedCorners(25).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundUniformRoundedCorners(5).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BackgroundUniformRoundedCorners(50).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderAlignmentInside.png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderAlignmentMiddle.png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderAlignmentOutside.png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderColor(#2196F3).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderColor(#4CAF50).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderColor(#F44336).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderGradientAngle(0).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderGradientAngle(30).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderGradientAngle(45).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderGradientAngle(60).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderGradientAngle(90).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderGradientColors([#2196F3, #03A9F4, #00BCD4, #009688, #4CAF50]).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderGradientColors([#F44336, #388E3C]).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderGradientColors([#F44336, #FFEB3B, #4CAF50]).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersUniform(0).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersUniform(10).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersUniform(100).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersUniform(25).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersUniform(5).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersUniform(50).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,0,0,0,15).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,0,0,0,5).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,0,0,5,15).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,0,0,5,5).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,0,5,0,15).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,0,5,0,5).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,0,5,5,15).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,0,5,5,5).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,5,0,0,15).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,5,0,0,5).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,5,0,5,15).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,5,0,5,5).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,5,5,0,15).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,5,5,0,5).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,5,5,5,15).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(0,5,5,5,5).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(5,0,0,0,15).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(5,0,0,0,5).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(5,0,0,5,15).png


BIN
Source/QuestPDF.VisualTests/ExpectedOutput/StyledBox/BorderRoundedCornersWithVariousCornerRadius(5,0,0,5,5).png


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