Skip to content

Commit b032bd0

Browse files
committed
Allow registring of custom font mappings and directories
1 parent 6942135 commit b032bd0

3 files changed

Lines changed: 56 additions & 16 deletions

File tree

Source/HtmlRenderer.PdfSharp/Adapters/PdfSharpAdapter.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ internal sealed class PdfSharpAdapter : RAdapter
3333
/// </summary>
3434
private static readonly PdfSharpAdapter _instance = new PdfSharpAdapter();
3535

36+
/// <summary>
37+
/// Font resolver instance for managing font discovery and resolution.
38+
/// </summary>
39+
private FontResolver _fontResolver;
40+
3641
#endregion
3742

3843

@@ -41,12 +46,12 @@ internal sealed class PdfSharpAdapter : RAdapter
4146
/// </summary>
4247
private PdfSharpAdapter()
4348
{
44-
var fontResolver = FontResolver.Register();
49+
_fontResolver = FontResolver.Register();
4550

4651
AddFontFamilyMapping("monospace", "Courier New");
4752
AddFontFamilyMapping("Helvetica", "Arial");
4853

49-
var fontFamilies = fontResolver.DiscoverFontFamilies();
54+
var fontFamilies = _fontResolver.DiscoverFontFamilies();
5055

5156
foreach (var fontFamily in fontFamilies)
5257
{
@@ -62,6 +67,14 @@ public static PdfSharpAdapter Instance
6267
get { return _instance; }
6368
}
6469

70+
/// <summary>
71+
/// Get the FontResolver instance for advanced font management.
72+
/// </summary>
73+
internal FontResolver FontResolver
74+
{
75+
get { return _fontResolver; }
76+
}
77+
6578
protected override RColor GetColorInt(string colorName)
6679
{
6780
try

Source/HtmlRenderer.PdfSharp/FontResolution/FontResolver.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ public byte[] GetFont(string faceName)
101101
public void RegisterCustomFontDirectory(string fontDirectory)
102102
{
103103
_fontDiscoveryService.RegisterCustomFontDirectory(fontDirectory);
104+
105+
// Invalidate the cache to trigger discovery
106+
_fontMetadataCache.Clear();
104107
}
105108

106109
public List<string> DiscoverFontFamilies()

Source/HtmlRenderer.PdfSharp/PdfGenerator.cs

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
using PdfSharp.Drawing;
1515
using PdfSharp.Pdf;
1616
using System;
17+
using TheArtOfDev.HtmlRenderer.Adapters;
1718
using TheArtOfDev.HtmlRenderer.Core;
1819
using TheArtOfDev.HtmlRenderer.Core.Entities;
1920
using TheArtOfDev.HtmlRenderer.Core.Utils;
@@ -28,11 +29,11 @@ public static class PdfGenerator
2829
{
2930
/// <summary>
3031
/// Adds a font mapping from <paramref name="fromFamily"/> to <paramref name="toFamily"/> iff the <paramref name="fromFamily"/> is not found.<br/>
31-
/// When the <paramref name="fromFamily"/> font is used in rendered html and is not found in existing
32+
/// When the <paramref name="fromFamily"/> font is used in rendered HTML and is not found in existing
3233
/// fonts (installed or added) it will be replaced by <paramref name="toFamily"/>.<br/>
3334
/// </summary>
3435
/// <remarks>
35-
/// This fonts mapping can be used as a fallback in case the requested font is not installed in the client system.
36+
/// This font mapping can be used as a fallback in case the requested font is not installed in the client system.
3637
/// </remarks>
3738
/// <param name="fromFamily">the font family to replace</param>
3839
/// <param name="toFamily">the font family to replace with</param>
@@ -44,15 +45,38 @@ public static void AddFontFamilyMapping(string fromFamily, string toFamily)
4445
PdfSharpAdapter.Instance.AddFontFamilyMapping(fromFamily, toFamily);
4546
}
4647

48+
/// <summary>
49+
/// Registers a custom directory to search for font files (TTF/OTF).<br/>
50+
/// Fonts in this directory will be discovered and made available for rendering.
51+
/// </summary>
52+
/// <remarks>
53+
/// This will automatically trigger a rediscovery of all fonts.
54+
/// </remarks>
55+
/// <param name="fontDirectory">the directory path containing font files</param>
56+
public static void RegisterCustomFontDirectory(string fontDirectory)
57+
{
58+
ArgChecker.AssertArgNotNullOrEmpty(fontDirectory, "fontDirectory");
59+
60+
PdfSharpAdapter.Instance.FontResolver.RegisterCustomFontDirectory(fontDirectory);
61+
62+
// Trigger a rediscovery
63+
var fontFamilies = PdfSharpAdapter.Instance.FontResolver.DiscoverFontFamilies();
64+
65+
foreach (var fontFamily in fontFamilies)
66+
{
67+
PdfSharpAdapter.Instance.AddFontFamily(new FontFamilyAdapter(new XFontFamily(fontFamily)));
68+
}
69+
}
70+
4771
/// <summary>
4872
/// Parse the given stylesheet to <see cref="CssData"/> object.<br/>
49-
/// If <paramref name="combineWithDefault"/> is true the parsed css blocks are added to the
50-
/// default css data (as defined by W3), merged if class name already exists. If false only the data in the given stylesheet is returned.
73+
/// If <paramref name="combineWithDefault"/> is true the parsed CSS blocks are added to the
74+
/// default CSS data (as defined by W3), merged if class name already exists. If false only the data in the given stylesheet is returned.
5175
/// </summary>
5276
/// <seealso cref="http://www.w3.org/TR/CSS21/sample.html"/>
5377
/// <param name="stylesheet">the stylesheet source to parse</param>
54-
/// <param name="combineWithDefault">true - combine the parsed css data with default css data, false - return only the parsed css data</param>
55-
/// <returns>the parsed css data</returns>
78+
/// <param name="combineWithDefault">true - combine the parsed CSS data with default CSS data, false - return only the parsed CSS data</param>
79+
/// <returns>the parsed CSS data</returns>
5680
public static CssData ParseStyleSheet(string stylesheet, bool combineWithDefault = true)
5781
{
5882
return CssData.Parse(PdfSharpAdapter.Instance, stylesheet, combineWithDefault);
@@ -64,10 +88,10 @@ public static CssData ParseStyleSheet(string stylesheet, bool combineWithDefault
6488
/// <param name="html">HTML source to create PDF from</param>
6589
/// <param name="pageSize">the page size to use for each page in the generated pdf </param>
6690
/// <param name="margin">the margin to use between the HTML and the edges of each page</param>
67-
/// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
91+
/// <param name="cssData">optional: the style to use for HTML rendering (default - use W3 default style)</param>
6892
/// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
6993
/// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
70-
/// <returns>the generated image of the html</returns>
94+
/// <returns>the generated image of the HTML</returns>
7195
public static PdfDocument GeneratePdf(string html, PageSize pageSize, int margin = 20, CssData cssData = null, EventHandler<HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler<HtmlImageLoadEventArgs> imageLoad = null)
7296
{
7397
var config = new PdfGenerateConfig();
@@ -81,10 +105,10 @@ public static PdfDocument GeneratePdf(string html, PageSize pageSize, int margin
81105
/// </summary>
82106
/// <param name="html">HTML source to create PDF from</param>
83107
/// <param name="config">the configuration to use for the PDF generation (page size/page orientation/margins/etc.)</param>
84-
/// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
108+
/// <param name="cssData">optional: the style to use for HTML rendering (default - use W3 default style)</param>
85109
/// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
86110
/// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
87-
/// <returns>the generated image of the html</returns>
111+
/// <returns>the generated image of the HTML</returns>
88112
public static PdfDocument GeneratePdf(string html, PdfGenerateConfig config, CssData cssData = null, EventHandler<HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler<HtmlImageLoadEventArgs> imageLoad = null)
89113
{
90114
// create PDF document to render the HTML into
@@ -103,10 +127,10 @@ public static PdfDocument GeneratePdf(string html, PdfGenerateConfig config, Css
103127
/// <param name="html">HTML source to create PDF from</param>
104128
/// <param name="pageSize">the page size to use for each page in the generated pdf </param>
105129
/// <param name="margin">the margin to use between the HTML and the edges of each page</param>
106-
/// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
130+
/// <param name="cssData">optional: the style to use for HTML rendering (default - use W3 default style)</param>
107131
/// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
108132
/// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
109-
/// <returns>the generated image of the html</returns>
133+
/// <returns>the generated image of the HTML</returns>
110134
public static void AddPdfPages(PdfDocument document, string html, PageSize pageSize, int margin = 20, CssData cssData = null, EventHandler<HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler<HtmlImageLoadEventArgs> imageLoad = null)
111135
{
112136
var config = new PdfGenerateConfig();
@@ -121,10 +145,10 @@ public static void AddPdfPages(PdfDocument document, string html, PageSize pageS
121145
/// <param name="document">PDF document to append pages to</param>
122146
/// <param name="html">HTML source to create PDF from</param>
123147
/// <param name="config">the configuration to use for the PDF generation (page size/page orientation/margins/etc.)</param>
124-
/// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
148+
/// <param name="cssData">optional: the style to use for HTML rendering (default - use W3 default style)</param>
125149
/// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
126150
/// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
127-
/// <returns>the generated image of the html</returns>
151+
/// <returns>the generated image of the HTML</returns>
128152
public static void AddPdfPages(PdfDocument document, string html, PdfGenerateConfig config, CssData cssData = null, EventHandler<HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler<HtmlImageLoadEventArgs> imageLoad = null)
129153
{
130154
XSize orgPageSize;

0 commit comments

Comments
 (0)