### RNetworkResponse Example Usage Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/NetworkLoaders.md Shows how to use a network loader to get a resource stream and process the response, checking for a non-null ResourceStream. ```csharp var loader = new HttpClientNetworkLoader(httpClient, "https://example.com"); var response = await loader.GetResourceStream(new RUri("https://example.com/image.png")); if (response?.ResourceStream != null) { using var reader = new StreamReader(response.ResourceStream); var content = await reader.ReadToEndAsync(); } ``` -------------------------------- ### Complete Font Setup in PeachPDF Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/FontManagement.md Illustrates a comprehensive font setup within PeachPDF, including remapping platform-specific fonts and loading custom font files from the file system. Ensure font files exist at the specified paths. ```csharp public class PdfFactory { private readonly PdfGenerator _generator; public PdfFactory() { _generator = new PdfGenerator(); ConfigureFonts(); } private void ConfigureFonts() { // Remap platform-specific fonts _generator.AddFontFamilyMapping("Segoe UI", "Arial"); _generator.AddFontFamilyMapping("Helvetica", "Arial"); _generator.AddFontFamilyMapping("Courier", "Courier New"); // Load custom fonts var customFonts = new[] { "fonts/CustomFont-Regular.ttf", "fonts/CustomFont-Bold.ttf", "fonts/CustomFont-Italic.ttf" }; foreach (var fontPath in customFonts) { if (File.Exists(fontPath)) { using var stream = File.OpenRead(fontPath); _generator.AddFontFromStream(stream).Wait(); } } } public async Task GenerateReportPdf(string html) { var config = new PdfGenerateConfig { PageSize = PageSize.A4, PageOrientation = PageOrientation.Portrait }; return await _generator.GeneratePdf(html, config); } } ``` -------------------------------- ### RUri Example Usage Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/NetworkLoaders.md Illustrates creating RUri objects for absolute and data URIs, showing how to access properties like AbsoluteUri and Scheme. ```csharp var baseUri = new RUri("https://example.com/images/"); var imageUri = new RUri(baseUri, "logo.png"); // imageUri.AbsoluteUri == "https://example.com/images/logo.png" var dataUri = new RUri("data:image/png;base64,iVBORw0KGgo="); // dataUri.Scheme == "data" ``` -------------------------------- ### MimeKitNetworkLoader Usage Example Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/NetworkLoaders.md Example of using `MimeKitNetworkLoader` to load content from an MHTML file. The loader reads the entire webpage and its resources from the provided stream. ```csharp var stream = File.OpenRead("webpage.mhtml"); var loader = new MimeKitNetworkLoader(stream); var config = new PdfGenerateConfig { PageSize = PageSize.A4, NetworkLoader = loader }; var doc = await generator.GeneratePdf(null, config); ``` -------------------------------- ### Install PeachPDF Package Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/quick-start.md Add the PeachPDF NuGet package to your .NET project. Requires .NET 8 or later. ```bash dotnet add package PeachPDF ``` -------------------------------- ### HttpClientNetworkLoader Usage Example Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/NetworkLoaders.md Example of using `HttpClientNetworkLoader` to load content from an HTTP URL. The loader fetches the primary HTML if `null` is passed, and automatically resolves relative URLs. ```csharp var httpClient = new HttpClient(); var loader = new HttpClientNetworkLoader( httpClient, new Uri("https://example.com/page.html") ); var config = new PdfGenerateConfig { PageSize = PageSize.A4, NetworkLoader = loader }; // Pass null as HTML - the loader will fetch it var doc = await generator.GeneratePdf(null, config); ``` -------------------------------- ### Complete Advanced Configuration Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/configuration.md An example demonstrating a comprehensive configuration with custom page size, margins, rendering quality, content scaling, resource loading via HTTP, and compression settings. ```csharp var httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(30) }; var config = new PdfGenerateConfig { // Page sizing PageSize = PageSize.A4, PageOrientation = PageOrientation.Portrait, // Margins MarginTop = 25, MarginBottom = 25, MarginLeft = 30, MarginRight = 20, // Rendering quality PixelsPerInch = 150, // Content scaling ShrinkToFit = true, // Resource loading NetworkLoader = new HttpClientNetworkLoader( httpClient, "https://cdn.example.com/assets/" ), // PDF options CompressContentStreams = true }; var doc = await generator.GeneratePdf(html, config); ``` -------------------------------- ### Implement Custom Database Network Loader Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/NetworkLoaders.md Create a custom network loader by inheriting from RNetworkLoader and implementing GetPrimaryContents and GetResourceStream. This example demonstrates loading content from a database. ```csharp public class CustomDatabaseLoader : RNetworkLoader { private readonly IContentRepository _repository; public CustomDatabaseLoader(IContentRepository repository) { _repository = repository; } public override RUri? BaseUri => null; public override async Task GetPrimaryContents() { return await _repository.GetHtmlAsync(); } public override async Task GetResourceStream(RUri uri) { var resource = await _repository.GetResourceAsync(uri.AbsoluteUri); if (resource == null) return null; return new RNetworkResponse( new MemoryStream(resource.Data), resource.Headers ); } } ``` -------------------------------- ### Instantiate PdfGenerator Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/API-OVERVIEW.md Create a new instance of the PdfGenerator class. No specific setup is required for basic usage. ```csharp public PdfGenerator() ``` -------------------------------- ### Abstract Method to Get Resource Stream Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/NetworkLoaders.md Abstract method to fetch a resource (image, stylesheet, font) as a stream. Implementations should handle resource retrieval and return an `RNetworkResponse` or null if not found. ```csharp public abstract Task GetResourceStream(RUri uri) ``` -------------------------------- ### Map Default Font on Non-Windows Platforms Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/FontManagement.md Provides examples for mapping the default font 'Segoe UI' to alternative fonts like 'Arial' or 'DejaVu Sans' on non-Windows operating systems. This is necessary because Segoe UI is not standard on macOS or Linux. ```csharp var generator = new PdfGenerator(); // Required on non-Windows platforms generator.AddFontFamilyMapping("Segoe UI", "Arial"); // Or on Linux/Mac, remove references to Segoe UI generator.AddFontFamilyMapping("Segoe UI", "DejaVu Sans"); ``` -------------------------------- ### HTML for PDF Metadata Source: https://github.com/jhaygood86/peachpdf/blob/main/docs/index.md Example HTML demonstrating how to include metadata tags in the head section for PDF info fields like Title, Author, Subject, Keywords, and Date. ```html Quarterly Report ``` -------------------------------- ### Abstract Method to Get Primary Contents Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/NetworkLoaders.md Abstract method to retrieve the main HTML content. Implementations must provide the logic for fetching this content. ```csharp public abstract Task GetPrimaryContents() ``` -------------------------------- ### Implement Retry Logic for PDF Generation Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/advanced-usage.md Create a resilient PDF generator that automatically retries generation on specific exceptions. This example includes logic to adjust configuration (like DPI) based on the error type encountered during retries. ```csharp public class ResilientPdfGenerator { private readonly PdfGenerator _generator; private readonly int _maxRetries = 3; public async Task GenerateWithRetry( string html, PdfGenerateConfig config ) { int attempt = 0; while (attempt < _maxRetries) { try { return await _generator.GeneratePdf(html, config); } catch (HtmlRenderException ex) when (attempt < _maxRetries - 1) { attempt++; Console.WriteLine( $"Attempt {attempt} failed ({ex.RenderErrorType}), retrying..." ); // Adjust config on retry if (ex.RenderErrorType == HtmlRenderErrorType.Image) { // Retry with extended timeout await Task.Delay(1000); } else if (ex.RenderErrorType == HtmlRenderErrorType.Layout) { // Reduce DPI and try again config.PixelsPerInch *= 0.8; } } } throw new InvalidOperationException( $"Failed to generate PDF after {_maxRetries} attempts" ); } } ``` -------------------------------- ### ASP.NET Core PDF Generation API Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/advanced-usage.md Example of integrating PeachPDF into an ASP.NET Core Web API to generate PDFs from HTML content. This snippet demonstrates setting up a controller, handling requests, and returning PDF files. ```csharp [ApiController] [Route("api/[controller]")] public class PdfController : ControllerBase { private readonly PdfService _pdfService; public PdfController(PdfService pdfService) { _pdfService = pdfService; } [HttpPost("generate")] [Consumes("application/json")] [Produces("application/pdf")] public async Task GeneratePdf([FromBody] PdfRequest request) { try { var pdfBytes = await _pdfService.GeneratePdf(request.Html); return File( pdfBytes, "application/pdf", $"document-{DateTime.UtcNow:yyyyMMdd-HHmmss}.pdf" ); } catch (HtmlRenderException ex) { return BadRequest(new { error = $"Rendering error: {ex.Message}" }); } } } public class PdfRequest { public string Html { get; set; } = ""; } // Startup configuration services.AddSingleton(); ``` -------------------------------- ### Handle Image Loading Errors in C# Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/advanced-usage.md Implement resilient PDF generation by handling `HtmlRenderException` specifically for image loading failures. This example shows how to replace missing images with a placeholder or remove them entirely to ensure document generation succeeds. ```csharp public class ResilientPdfGenerator { public async Task GenerateWithFallbacks( string htmlTemplate, string imageDirectory ) { var generator = new PdfGenerator(); // Replace missing images with placeholder var cleanedHtml = ReplaceMissingImages(htmlTemplate, imageDirectory); try { var config = new PdfGenerateConfig { PageSize = PageSize.A4 }; return await generator.GeneratePdf(cleanedHtml, config); } catch (HtmlRenderException ex) when (ex.RenderErrorType == HtmlRenderErrorType.Image) { // Retry with even more aggressive fallbacks var withPlaceholders = RemoveImages(htmlTemplate); var config = new PdfGenerateConfig { PageSize = PageSize.A4 }; return await generator.GeneratePdf(withPlaceholders, config); } } private string ReplaceMissingImages(string html, string imageDir) { var doc = new HtmlDocument(); doc.LoadHtml(html); foreach (HtmlNode img in doc.DocumentNode.SelectNodes("//img")) { var src = img.GetAttributeValue("src", ""); if (!File.Exists(Path.Combine(imageDir, src))) { img.SetAttributeValue("src", GetPlaceholderImage()); } } return doc.DocumentNode.OuterHtml; } private string RemoveImages(string html) { var doc = new HtmlDocument(); doc.LoadHtml(html); var imagesToRemove = doc.DocumentNode .SelectNodes("//img") .ToList(); foreach (var img in imagesToRemove) { img.Remove(); } return doc.DocumentNode.OuterHtml; } private string GetPlaceholderImage() { // Base64-encoded 1x1 pixel placeholder return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="; } } ``` -------------------------------- ### Create a Simple PDF with Text Source: https://github.com/jhaygood86/peachpdf/blob/main/src/PeachPDF/PdfSharpCore/README.md This snippet demonstrates how to create a basic PDF file with 'Hello World!' text. Ensure you have the necessary using statements and configure the font resolver. ```csharp using PeachPDF.PdfSharpCore.Drawing; using PeachPDF.PdfSharpCore.Fonts; using PeachPDF.PdfSharpCore.Pdf; using PeachPDF.PdfSharpCore.Utils; GlobalFontSettings.FontResolver = new FontResolver(); var document = new PdfDocument(); var page = document.AddPage(); var gfx = XGraphics.FromPdfPage(page); var font = new XFont("Arial", 20, XFontStyle.Bold); var textColor = XBrushes.Black; var layout = new XRect(20, 20, page.Width, page.Height); var format = XStringFormats.Center; gfx.DrawString("Hello World!", font, textColor, layout, format); document.Save("helloworld.pdf"); ``` -------------------------------- ### PeachPdfDocument.PageCount Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/PeachPdfDocument.md Gets the total number of pages in the PDF document. This is a read-only property. ```APIDOC ## PeachPdfDocument.PageCount ### Description Gets the total number of pages in the PDF document. This is a read-only property. ### Type `int` ### Example ```csharp var doc = await generator.GeneratePdf(html, PageSize.A4); Console.WriteLine($"Document has {doc.PageCount} pages"); ``` ``` -------------------------------- ### Conic Gradient List Style (From 90deg) Source: https://github.com/jhaygood86/peachpdf/blob/main/src/PeachPDF.TestHarness/test_list_style_image.html Applies a conic gradient starting from the 90-degree mark. ```CSS list-style-image: conic-gradient(from 90deg, red, yellow, blue); ``` -------------------------------- ### Initialize DataUriNetworkLoader Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/API-OVERVIEW.md Instantiate a network loader specifically designed to handle data URIs. This loader does not require any initial configuration. ```csharp public DataUriNetworkLoader() ``` -------------------------------- ### RUri Constructors Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/NetworkLoaders.md Demonstrates the different ways to construct an RUri object, including from strings, relative URIs, and existing Uri objects. ```csharp public RUri(string uriString) ``` ```csharp public RUri(string uriString, UriKind uriKind) ``` ```csharp public RUri(RUri baseUri, string relativeUri) ``` ```csharp public RUri(RUri baseUri, RUri relativeUri) ``` ```csharp public RUri(Uri uri) ``` -------------------------------- ### Overlapping Radii Reduction: 100px Source: https://github.com/jhaygood86/peachpdf/blob/main/src/PeachPDF.TestHarness/test_border_radius.html Shows an example where the specified radius exceeds the element's dimensions and is capped by the browser. ```css border-radius: 100px ``` -------------------------------- ### Configure for High-Quality PDF Output Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/configuration.md Use a higher `PixelsPerInch` (e.g., 300) and enable `ScaleToPageSize` and `CompressContentStreams` for high-quality, well-sized output. ```csharp var config = new PdfGenerateConfig { PageSize = PageSize.A4, PixelsPerInch = 300, // High DPI ScaleToPageSize = true, // Fit content perfectly CompressContentStreams = true // Better file size }; ``` -------------------------------- ### Save PDF Document Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/API-OVERVIEW.md Access the generated PDF document to retrieve page count and save it to a stream, for example, to a file. ```csharp var document = await generator.GeneratePdf(html, PageSize.A4); Console.WriteLine(document.PageCount); using var stream = File.Create("output.pdf"); document.Save(stream); ``` -------------------------------- ### Get Page Count of PeachPdfDocument Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/PeachPdfDocument.md Retrieve the total number of pages in a PeachPdfDocument. This is useful for logging or validation after generating or modifying a PDF. ```csharp var doc = await generator.GeneratePdf(html, PageSize.A4); Console.WriteLine($ ``` -------------------------------- ### Configure PDF Generation Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/API-OVERVIEW.md Set up configuration options for PDF generation, including page size, orientation, margins, and network loading behavior. Use SetMargins for a quick way to apply uniform margins. ```csharp public class PdfGenerateConfig { // Properties like PageSize, PageOrientation, MarginTop, etc. public void SetMargins(int value) { // Implementation to set all margins } } ``` -------------------------------- ### Initialize MimeKitNetworkLoader Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/API-OVERVIEW.md Create a network loader from a stream, typically used for loading resources embedded within MIME multipart messages. ```csharp public MimeKitNetworkLoader(Stream stream) ``` -------------------------------- ### Load Custom Font From File Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/FontManagement.md Demonstrates loading a custom font from a local file using its file path. Ensure the font file is accessible and in a supported format. ```csharp var generator = new PdfGenerator(); using var fontStream = File.OpenRead("CustomFont.ttf"); await generator.AddFontFromStream(fontStream); var html = @" Text in custom font "; var doc = await generator.GeneratePdf(html, PageSize.A4); ``` -------------------------------- ### Repeating Conic Gradient Source: https://github.com/jhaygood86/peachpdf/blob/main/src/PeachPDF.TestHarness/test_gradients.html Shows repeating conic gradients for tiled effects, including examples with directional rotation, checkerboard patterns, and narrow slices. ```css repeating-conic-gradient(red 0deg 30deg, blue 30deg 60deg) ``` ```css repeating-conic-gradient(from 45deg, red 0deg, blue 60deg) ``` ```css repeating-conic-gradient(#000 0 25%, #fff 25% 50%) ``` ```css repeating-conic-gradient(red 0 5deg, blue 5deg 10deg) ``` -------------------------------- ### Implement a Custom NetworkLoader Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/configuration.md Create a custom network loader by inheriting from RNetworkLoader and implementing GetPrimaryContents and GetResourceStream to load content from custom sources. ```csharp public class CustomLoader : RNetworkLoader { public override RUri? BaseUri => null; public override async Task GetPrimaryContents() { // Load HTML from custom source return "..."; } public override async Task GetResourceStream(RUri uri) { // Load resources from custom source return new RNetworkResponse(stream, headers); } } ``` -------------------------------- ### Map Font Family Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/FontManagement.md Use this to map a requested font name to a substitute font available on the system. This is useful when the desired font is not installed or accessible. ```csharp var generator = new PdfGenerator(); generator.AddFontFamilyMapping("RequestedFont", "SubstituteFont"); ``` -------------------------------- ### Generate a Simple PDF Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/README.md Use this snippet to create a basic PDF document from HTML content. Ensure you have a PdfGenerator instance and specify the desired page size. ```csharp var generator = new PdfGenerator(); var html = "

Hello World

"; var doc = await generator.GeneratePdf(html, PageSize.A4); using var stream = File.Create("output.pdf"); doc.Save(stream); ``` -------------------------------- ### Initialize HttpClientNetworkLoader Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/API-OVERVIEW.md Create a network loader using an HttpClient instance. This loader is used to fetch resources like images and stylesheets over HTTP/S. ```csharp public HttpClientNetworkLoader(HttpClient httpClient, Uri primaryContentsUri) ``` ```csharp public HttpClientNetworkLoader(HttpClient httpClient, string primaryContentsUri) ``` -------------------------------- ### Repeating Radial Gradient Source: https://github.com/jhaygood86/peachpdf/blob/main/src/PeachPDF.TestHarness/test_gradients.html Demonstrates repeating radial gradients, creating effects like rings and checkerboards. Includes examples with fading rings and elliptical shapes. ```css repeating-radial-gradient(circle, red 0 10px, blue 10px 20px) ``` ```css repeating-radial-gradient(circle, red 0, blue 25px) ``` ```css repeating-radial-gradient(red 0 8px, white 8px 16px) ``` ```css repeating-radial-gradient(circle, rgba(255,0,0,0.8) 0 10px, rgba(0,0,255,0.8) 10px 20px) ``` -------------------------------- ### HTML for Named Pages Source: https://github.com/jhaygood86/peachpdf/blob/main/docs/html-css-support.md Example HTML structure to demonstrate the activation of named page styles. The 'page' CSS property on an element links it to a named @page rule. ```html

Chapter 1

Content...

``` -------------------------------- ### Create a Custom Network Loader for PDF Generation Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/advanced-usage.md Implement a custom network loader by inheriting from RNetworkLoader to fetch content from specific data sources like databases. This allows for specialized resource loading during PDF generation. ```csharp public class DatabaseNetworkLoader : RNetworkLoader { private readonly IContentRepository _repository; private readonly string _baseUrl; public DatabaseNetworkLoader(IContentRepository repository, string baseUrl) { _repository = repository; _baseUrl = baseUrl; } public override RUri? BaseUri => new RUri(_baseUrl); public override async Task GetPrimaryContents() { return await _repository.GetHtmlAsync(); } public override async Task GetResourceStream(RUri uri) { var resource = await _repository.GetResourceAsync(uri.AbsoluteUri); if (resource == null) return null; return new RNetworkResponse( new MemoryStream(resource.Data), resource.Headers ); } } // Usage: var config = new PdfGenerateConfig { PageSize = PageSize.A4, NetworkLoader = new DatabaseNetworkLoader( contentRepository, "https://app.example.com/reports/" ) }; var doc = await generator.GeneratePdf(null, config); ``` -------------------------------- ### Basic PDF Generation Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/API-OVERVIEW.md Use this for simple PDF creation from HTML content. Requires an instance of PdfGenerator and saves the output to a file. ```csharp var generator = new PdfGenerator(); var doc = await generator.GeneratePdf(html, PageSize.A4); doc.Save(File.Create("output.pdf")); ``` -------------------------------- ### Define Custom Page Dimensions Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/PdfGenerateConfig.md Sets custom page dimensions in PDF points when PageSize is set to Undefined. This example uses dimensions for an 8.5x11 inch page. ```csharp var config = new PdfGenerateConfig { PageSize = PageSize.Undefined, ManualPageWidth = 612, // 8.5 inches ManualPageHeight = 792 // 11 inches }; ``` -------------------------------- ### CSS Font Fallback Chain Example Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/FontManagement.md Demonstrates how to define a font fallback chain using the CSS font-family property. PeachPDF will use the first available font in the specified order. ```html ``` -------------------------------- ### Configure PDF Generation Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/API-OVERVIEW.md Set up PDF generation parameters such as page size, orientation, margins, and resolution using PdfGenerateConfig. ```csharp var config = new PdfGenerateConfig { PageSize = PageSize.A4, PageOrientation = PageOrientation.Portrait, MarginTop = 20, PixelsPerInch = 96 }; ``` -------------------------------- ### Conic Gradient: Alpha and From+At Source: https://github.com/jhaygood86/peachpdf/blob/main/src/PeachPDF.TestHarness/test_gradients.html Demonstrates conic gradients with alpha transparency, combined 'from' and 'at' positioning, and complex color wheels/starburst patterns. ```css conic-gradient(rgba(255,0,0,0), red) ``` ```css conic-gradient(from 45deg at 30% 70%, red, blue) ``` ```css conic-gradient(red, yellow, lime, cyan, blue, magenta, red) ``` ```css conic-gradient(gold 0 10%, white 10% 20%, gold 20% 30%, white 30% 40%, gold 40% 50%, white 50% 60%, gold 60% 70%, white 70% 80%, gold 80% 90%, white 90% 100%) ``` -------------------------------- ### Add Font Family Mapping - PeachPDF Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/FontManagement.md Register a font family fallback. Use this when a CSS font-family is not found and you want to substitute it with an available system font. Ensure that the 'toFamily' font is installed on the system. ```csharp var generator = new PdfGenerator(); // Remap unavailable fonts to system fonts generator.AddFontFamilyMapping("Segoe UI", "Arial"); generator.AddFontFamilyMapping("Helvetica", "Arial"); generator.AddFontFamilyMapping("Courier", "Courier New"); var config = new PdfGenerateConfig { PageSize = PageSize.A4 }; var doc = await generator.GeneratePdf(html, config); ``` -------------------------------- ### Configure for Fast PDF Generation Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/configuration.md Set `PixelsPerInch` to 72 and `ScaleToPageSize` to false for the fastest PDF generation. `CompressContentStreams` is also disabled for speed. ```csharp var config = new PdfGenerateConfig { PageSize = PageSize.A4, PixelsPerInch = 72, // Standard DPI only ScaleToPageSize = false, // No extra layout pass ShrinkToFit = false, CompressContentStreams = false // Faster write }; ``` -------------------------------- ### Generate PDF from HTML Template with Placeholders Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/advanced-usage.md Use this class to generate PDFs from an HTML template file. It reads the template, replaces placeholders defined in a dictionary with corresponding values, and then generates the PDF. Ensure the template file exists at the specified path. ```csharp public class TemplatedReportGenerator { private readonly PdfGenerator _generator; private readonly string _templateHtml; public TemplatedReportGenerator(string templatePath) { _generator = new PdfGenerator(); _templateHtml = File.ReadAllText(templatePath); } public async Task GenerateFromData( Dictionary data ) { var html = _templateHtml; // Replace placeholders foreach (var kvp in data) { html = html.Replace($"{{{{{kvp.Key}}}}}", kvp.Value); } var config = new PdfGenerateConfig { PageSize = PageSize.A4 }; return await _generator.GeneratePdf(html, config); } } // Usage: var generator = new TemplatedReportGenerator("invoice-template.html"); var data = new Dictionary { { "InvoiceNumber", "INV-2024-001" }, { "CustomerName", "Acme Corp" }, { "Amount", "$1,000.00" }, { "DueDate", "2024-02-01" } }; var doc = await generator.GenerateFromData(data); ``` -------------------------------- ### Common Configuration Patterns Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/PdfGenerateConfig.md Illustrates various ways to configure PdfGenerateConfig for different PDF generation scenarios. ```APIDOC ## Common Configuration Patterns ### Simple Document with Standard Margins ```csharp var config = new PdfGenerateConfig { PageSize = PageSize.Letter, PageOrientation = PageOrientation.Portrait }; config.SetMargins(15); var doc = await generator.GeneratePdf(html, config); ``` ### High-Quality Output ```csharp var config = new PdfGenerateConfig { PageSize = PageSize.A4, PixelsPerInch = 300 }; var doc = await generator.GeneratePdf(html, config); ``` ### Auto-Fitting Content ```csharp var config = new PdfGenerateConfig { PageSize = PageSize.A4, ShrinkToFit = true // Shrink if content is wider than page }; var doc = await generator.GeneratePdf(html, config); ``` ### Loading from Remote URL ```csharp var httpClient = new HttpClient(); var config = new PdfGenerateConfig { PageSize = PageSize.A4, NetworkLoader = new HttpClientNetworkLoader( httpClient, "https://example.com/report" ) }; var doc = await generator.GeneratePdf(null, config); ``` ### Loading from MHTML File ```csharp var config = new PdfGenerateConfig { PageSize = PageSize.A4, NetworkLoader = new MimeKitNetworkLoader( File.OpenRead("document.mhtml") ) }; var doc = await generator.GeneratePdf(null, config); ``` ``` -------------------------------- ### Override Page Size with CSS in PeachPDF Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/configuration.md Shows a C# example where a PdfGenerateConfig is set to A4, but the HTML content includes CSS that specifies A3 page size. The CSS rule will take precedence, resulting in an A3 PDF. ```csharp var html = @" Content"; var config = new PdfGenerateConfig { PageSize = PageSize.A4 // Will be overridden by CSS }; var doc = await generator.GeneratePdf(html, config); // Resulting PDF will be A3, not A4 ``` -------------------------------- ### Configure HttpClientNetworkLoader Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/configuration.md Use HttpClientNetworkLoader to specify a base URI and an HttpClient for fetching resources over HTTP/S. The HttpClient can be pre-configured with custom settings like timeouts and decompression methods. ```csharp var httpClient = new HttpClient(); var loader = new HttpClientNetworkLoader( httpClient, new Uri("https://example.com") ); var config = new PdfGenerateConfig { PageSize = PageSize.A4, NetworkLoader = loader }; ``` ```csharp var httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(30) }; var handler = new HttpClientHandler { AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate }; var httpClient = new HttpClient(handler); var loader = new HttpClientNetworkLoader(httpClient, baseUri); ``` -------------------------------- ### Configure MimeKitNetworkLoader Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/configuration.md Use MimeKitNetworkLoader to load HTML and resources from a MHTML stream. ```csharp using var stream = File.OpenRead("webpage.mhtml"); var loader = new MimeKitNetworkLoader(stream); var config = new PdfGenerateConfig { PageSize = PageSize.A4, NetworkLoader = loader }; ``` -------------------------------- ### Generate PDF from HTML String Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/quick-start.md Create a PDF document from an HTML string using default configurations. The generated PDF is saved to 'output.pdf'. ```csharp using PeachPDF; var generator = new PdfGenerator(); var html = "

Hello, World!

"; var config = new PdfGenerateConfig { PageSize = PageSize.A4 }; var document = await generator.GeneratePdf(html, config); using var stream = File.Create("output.pdf"); document.Save(stream); ``` -------------------------------- ### Configure Network Loader with HttpClient Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/PdfGenerateConfig.md Sets a custom network loader using HttpClient to load resources from HTTP/HTTPS URLs. It requires an HttpClient instance and a base URI. ```csharp var httpClient = new HttpClient(); var config = new PdfGenerateConfig { PageSize = PageSize.A4, NetworkLoader = new HttpClientNetworkLoader( httpClient, new Uri("https://example.com") ) }; var doc = await generator.GeneratePdf(null, config); ``` -------------------------------- ### Radial Gradient: Size Keywords and Explicit Source: https://github.com/jhaygood86/peachpdf/blob/main/src/PeachPDF.TestHarness/test_gradients.html Demonstrates radial gradients using size keywords like 'farthest-corner', 'closest-side', and 'farthest-side', as well as explicit pixel values for size. ```css radial-gradient(farthest-corner at 30% 30%, red, blue) ``` ```css radial-gradient(closest-side at 30% 30%, red, blue) ``` ```css radial-gradient(farthest-side at 30% 30%, red, blue) ``` ```css radial-gradient(30px at center, red, blue) ``` -------------------------------- ### Configure Content Shrinking to Fit Page Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/configuration.md When content exceeds the page width, set `ShrinkToFit` to `true` to reduce its size. `MinContentWidth` can be set to 0 to allow maximum shrinking. ```csharp // Try shrinking or scaling var config = new PdfGenerateConfig { PageSize = PageSize.A4, ShrinkToFit = true, // Reduce if too wide MinContentWidth = 0 // No minimum }; ``` -------------------------------- ### Configure Network Loader for Remote Images Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/configuration.md If your HTML content includes remote images, configure `NetworkLoader` with an `HttpClientNetworkLoader` instance. Ensure the `HttpClient` is properly initialized and the base URL is provided. ```csharp // Ensure NetworkLoader is configured if using remote images var config = new PdfGenerateConfig { PageSize = PageSize.A4, NetworkLoader = new HttpClientNetworkLoader( httpClient, "https://example.com/base/" ) }; ``` -------------------------------- ### Loading Content from Remote URL Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/PdfGenerateConfig.md Sets up PDF generation to load HTML content from a remote URL using an HttpClient. Requires an instance of HttpClient and the URL of the content. ```csharp var httpClient = new HttpClient(); var config = new PdfGenerateConfig { PageSize = PageSize.A4, NetworkLoader = new HttpClientNetworkLoader( httpClient, "https://example.com/report" ) }; var doc = await generator.GeneratePdf(null, config); ``` -------------------------------- ### Disc List Style (No Image) Source: https://github.com/jhaygood86/peachpdf/blob/main/src/PeachPDF.TestHarness/test_list_style_image.html Demonstrates the default 'disc' list-style-type when no image is specified. ```CSS list-style-type: disc; ``` -------------------------------- ### Implement Progress Tracking for PDF Generation Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/advanced-usage.md Use this class to monitor the progress of multi-page PDF generation. It reports progress for each page processed and can be extended to provide custom event handling. ```csharp public class ProgressTrackingGenerator { private readonly PdfGenerator _generator; public event EventHandler? PageProcessed; public async Task GenerateWithProgress( string[] pageHtmls, IProgress progress ) { var doc = await _generator.GeneratePdf(pageHtmls[0], PageSize.A4); progress.Report(1); for (int i = 1; i < pageHtmls.Length; i++) { await _generator.AddPdfPages(doc, pageHtmls[i], PageSize.A4); progress.Report(i + 1); PageProcessed?.Invoke(this, new PageProcessedEventArgs { PageNumber = i + 1, TotalPages = pageHtmls.Length }); } return doc; } } public class PageProcessedEventArgs : EventArgs { public int PageNumber { get; set; } public int TotalPages { get; set; } public int PercentComplete => (PageNumber * 100) / TotalPages; } // Usage: var generator = new ProgressTrackingGenerator(); var progress = new Progress(p => Console.WriteLine($"Progress: {p}%")); generator.PageProcessed += (s, e) => { Console.WriteLine($"Processed page {e.PageNumber} of {e.TotalPages}"); }; var pages = new[] { page1Html, page2Html, page3Html }; var doc = await generator.GenerateWithProgress(pages, progress); ``` -------------------------------- ### Set Margin Top in PDF Points Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/README.md Demonstrates how to set the top margin of a PDF document using different units, all converted to PDF points. ```csharp config.MarginTop = 20; // 20 points config.MarginTop = 28; // ~0.39 inches config.MarginTop = 10; // ~3.5 mm ``` -------------------------------- ### Decimal List Style (No Image) Source: https://github.com/jhaygood86/peachpdf/blob/main/src/PeachPDF.TestHarness/test_list_style_image.html Demonstrates the default 'decimal' list-style-type when no image is specified. ```CSS list-style-type: decimal; ``` -------------------------------- ### Abstract Base Class for Network Loaders Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/NetworkLoaders.md Implement this abstract class to define custom logic for loading network resources. ```csharp public abstract class RNetworkLoader ``` -------------------------------- ### Generate PDF with Detailed Configuration Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/PdfGenerator.md This overload allows for detailed PDF generation using a configuration object that specifies page size, orientation, scaling, and network loading options. It can also accept custom CSS. ```csharp var config = new PdfGenerateConfig { PageSize = PageSize.A4, PageOrientation = PageOrientation.Landscape, ScaleToPageSize = true }; var document = await generator.GeneratePdf(html, config); ``` -------------------------------- ### HTML with CSS for Headers and Footers Source: https://github.com/jhaygood86/peachpdf/blob/main/docs/html-css-support.md Demonstrates how to define custom headers and footers for different pages using CSS @page rules. Includes suppressing headers on the first page and setting dynamic content like chapter titles and page numbers. ```html

Annual Report 2025

Cover page — header is suppressed by @page :first

Introduction

Running header now shows "Introduction" in the top-center margin.

``` -------------------------------- ### Simple Document with Standard Margins Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/PdfGenerateConfig.md Configures PDF generation with standard letter size, portrait orientation, and uniform 15-point margins. ```csharp var config = new PdfGenerateConfig { PageSize = PageSize.Letter, PageOrientation = PageOrientation.Portrait }; config.SetMargins(15); var doc = await generator.GeneratePdf(html, config); ``` -------------------------------- ### Auto-Fit Content to Page Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/quick-start.md Enable content scaling to fit within the page boundaries. If the content is too wide, it will be scaled down automatically. ```csharp var config = new PdfGenerateConfig { PageSize = PageSize.A4, ShrinkToFit = true // Scale down if too wide }; var document = await generator.GeneratePdf(html, config); ``` -------------------------------- ### Load from MHTML File for PDF Generation Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/quick-start.md Generate a PDF by loading content from an MHTML file using a MimeKitNetworkLoader. ```csharp var config = new PdfGenerateConfig { PageSize = PageSize.A4, NetworkLoader = new MimeKitNetworkLoader( File.OpenRead("saved.mhtml") ) }; var document = await generator.GeneratePdf(null, config); ``` -------------------------------- ### Combine background-origin and background-clip Source: https://github.com/jhaygood86/peachpdf/blob/main/src/PeachPDF.TestHarness/test_background_origin_clip.html Demonstrates combinations of background-origin and background-clip properties. ```css origin: border-box; clip: border-box ``` ```css origin: padding-box; clip: padding-box ``` ```css origin: content-box; clip: content-box ``` ```css origin: border-box; clip: padding-box ``` ```css origin: border-box; clip: content-box ``` ```css origin: padding-box; clip: content-box ``` ```css origin: content-box; clip: padding-box ``` ```css origin: content-box; clip: border-box ``` -------------------------------- ### Create Multi-Page PDF Document Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/quick-start.md Generate an initial PDF document and then append additional pages from different HTML content. The final document contains all appended pages. ```csharp var generator = new PdfGenerator(); // Create initial document var doc = await generator.GeneratePdf(html1, PageSize.A4); // Add more pages await generator.AddPdfPages(doc, html2, PageSize.A4); await generator.AddPdfPages(doc, html3, PageSize.A4); // Save complete document using var stream = File.Create("report.pdf"); doc.Save(stream); ``` -------------------------------- ### PeachPdfDocument Usage Pattern Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/PeachPdfDocument.md Demonstrates the typical workflow for generating, potentially adding pages to, and saving a PDF document using PdfGenerator and PeachPdfDocument. ```csharp var generator = new PdfGenerator(); // Generate a new document var doc = await generator.GeneratePdf(html, PageSize.A4); // Optionally add more pages await generator.AddPdfPages(doc, moreHtml, PageSize.A4); // Save to file using var stream = File.Create("document.pdf"); doc.Save(stream); Console.WriteLine($"Saved {doc.PageCount}-page PDF"); ``` -------------------------------- ### Configure for Minimal PDF File Size Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/configuration.md To minimize file size, ensure `CompressContentStreams` is enabled. `PixelsPerInch` is set to 72 for standard quality. ```csharp var config = new PdfGenerateConfig { PageSize = PageSize.A4, PixelsPerInch = 72, CompressContentStreams = true // Always compress }; ``` -------------------------------- ### Render PDF from Web URI Source: https://github.com/jhaygood86/peachpdf/blob/main/README.md Renders HTML content from a given web URI to a PDF document. Uses HttpClientNetworkLoader for fetching content. Pass null for HTML to load from the network loader. ```csharp HttpClient httpClient = new(); PdfGenerateConfig pdfConfig = new(){ PageSize = PageSize.Letter, PageOrientation = PageOrientation.Portrait, NetworkLoader = new HttpClientNetworkLoader(httpClient, new Uri("https://www.example.com")) }; PdfGenerator generator = new(); var stream = new MemoryStream(); // Passing null to GeneratePdf will load the HTML from the provided network loader instance instead var document = await generator.GeneratePdf(null, pdfConfig); document.Save(stream); ``` -------------------------------- ### Implement Custom Network Loader in C# Source: https://github.com/jhaygood86/peachpdf/blob/main/docs/architecture.md Subclass RNetworkLoader to integrate custom resource resolution logic, such as reading assets from cloud storage or in-memory dictionaries. Set the instance on PdfGenerateConfig.NetworkLoader. ```csharp public class MyLoader : RNetworkLoader { public override RUri? BaseUri => null; public override Task GetPrimaryContents() => Task.FromResult("…"); public override Task GetResourceStream(RUri uri) { var bytes = MyAssetStore.Load(uri.OriginalString); if (bytes is null) return Task.FromResult(null); return Task.FromResult( new RNetworkResponse(new MemoryStream(bytes), null)); } } ``` -------------------------------- ### Linear Gradient in oklab with Multiple Stops Source: https://github.com/jhaygood86/peachpdf/blob/main/src/PeachPDF.TestHarness/test_gradients.html Creates a linear gradient transitioning from red to yellow to blue within the oklab color space. ```css linear-gradient(in oklab to right, red, yellow, blue) ``` -------------------------------- ### Fitting to Minimum Width Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/configuration.md Scales content to fit a minimum specified width in pixels, useful for responsive design considerations. ```csharp var config = new PdfGenerateConfig { PageSize = PageSize.A4, MinContentWidth = 750 // Scale to fit 750px width }; ``` -------------------------------- ### Load Complete Web Page using HttpClientNetworkLoader Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/api-reference/NetworkLoaders.md Load an entire web page, including all its resources, by providing the URL to HttpClientNetworkLoader. Pass null for the HTML content to indicate a full page load. ```csharp var httpClient = new HttpClient(); var loader = new HttpClientNetworkLoader( httpClient, "https://example.com/report" ); var config = new PdfGenerateConfig { PageSize = PageSize.A4, NetworkLoader = loader }; var doc = await generator.GeneratePdf(null, config); ``` -------------------------------- ### Configure Network Loader for Images Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/errors.md Configure a network loader with a base URL to resolve relative image paths. This is a mitigation strategy for image loading errors. ```csharp // Ensure images are accessible var config = new PdfGenerateConfig { PageSize = PageSize.A4, NetworkLoader = new HttpClientNetworkLoader( httpClient, "https://example.com/documents/" ) }; // Or use embedded data: URIs var embeddedImage = "data:image/png;base64,iVBORw0go..."; ``` -------------------------------- ### Conic Gradient in oklab Source: https://github.com/jhaygood86/peachpdf/blob/main/src/PeachPDF.TestHarness/test_gradients.html Creates a conic gradient transitioning from red to blue within the oklab color space. ```css conic-gradient(in oklab, red, blue) ``` -------------------------------- ### Configure PDF Generation with PdfGenerateConfig Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/types.md Configuration object for PDF generation. Allows setting page size, orientation, margins, and network loaders for external resources. ```csharp public sealed class PdfGenerateConfig { public PageSize PageSize { get; set; } public PageOrientation PageOrientation { get; set; } public double ManualPageWidth { get; set; } public double ManualPageHeight { get; set; } public int MarginTop { get; set; } public int MarginBottom { get; set; } public int MarginLeft { get; set; } public int MarginRight { get; set; } public double PixelsPerInch { get; set; } public bool ScaleToPageSize { get; set; } public bool ShrinkToFit { get; set; } public double MinContentWidth { get; set; } public RNetworkLoader? NetworkLoader { get; set; } public bool CompressContentStreams { get; set; } public void SetMargins(int value); } ``` -------------------------------- ### Linear Gradient in oklab Source: https://github.com/jhaygood86/peachpdf/blob/main/src/PeachPDF.TestHarness/test_gradients.html Creates a linear gradient transitioning from red to green within the oklab color space. ```css linear-gradient(in oklab to right, red, green) ``` -------------------------------- ### Radial Gradient in oklab Source: https://github.com/jhaygood86/peachpdf/blob/main/src/PeachPDF.TestHarness/test_gradients.html Creates a radial gradient transitioning from red to blue in a circle within the oklab color space. ```css radial-gradient(in oklab circle, red, blue) ``` -------------------------------- ### Assemble Multi-Page Document Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/README.md Create a PDF document composed of multiple HTML pages. Generate the first page and then use AddPdfPages to append subsequent pages. ```csharp var doc = await generator.GeneratePdf(page1Html, PageSize.A4); await generator.AddPdfPages(doc, page2Html, PageSize.A4); await generator.AddPdfPages(doc, page3Html, PageSize.A4); using var stream = File.Create("report.pdf"); doc.Save(stream); ``` -------------------------------- ### Load HTML from URL for PDF Generation Source: https://github.com/jhaygood86/peachpdf/blob/main/_autodocs/quick-start.md Generate a PDF by loading HTML content directly from a URL using an HttpClient. Pass null for the HTML content when using a NetworkLoader. ```csharp var httpClient = new HttpClient(); var config = new PdfGenerateConfig { PageSize = PageSize.A4, NetworkLoader = new HttpClientNetworkLoader( httpClient, "https://example.com/page" ) }; // Pass null - HTML comes from NetworkLoader var document = await generator.GeneratePdf(null, config); ``` -------------------------------- ### Render PDF from MHTML File Source: https://github.com/jhaygood86/peachpdf/blob/main/README.md Generates a PDF from a self-contained MHTML file using MimeKitNetworkLoader. Pass null for HTML to load from the network loader. ```csharp PdfGenerateConfig pdfConfig = new(){ PageSize = PageSize.Letter, PageOrientation = PageOrientation.Portrait, NetworkLoader = new MimeKitNetworkLoader(File.OpenRead("example.mhtml")) }; PdfGenerator generator = new(); var stream = new MemoryStream(); // Passing null to GeneratePdf will load the HTML from the provided network loader instance instead var document = await generator.GeneratePdf(null, pdfConfig); document.Save(stream); ```