Browse Source

Add custom font discovery paths

Introduce a new setting `FontDiscoveryPaths` to specify directories for automatic font registration. Refactor font search implementation to handle multiple paths and limit the number of scanned files to prevent performance issues.
Marcin Ziąbek 1 year ago
parent
commit
30dd0f4b9b

+ 23 - 4
Source/QuestPDF/Drawing/FontManager.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Reflection;
@@ -70,10 +71,7 @@ namespace QuestPDF.Drawing
         
         private static void RegisterLibraryDefaultFonts()
         {
-            var supportedFontExtensions = new[] { "*.ttf", "*.otf", "*.ttc", "*.pfb" };
-            
-            var fontFilePaths = supportedFontExtensions
-                .SelectMany(extension => Directory.GetFiles(Helpers.Helpers.ApplicationFilesPath, extension, SearchOption.AllDirectories));
+            var fontFilePaths = SearchFontFiles();
             
             foreach (var fileName in fontFilePaths)
             {
@@ -87,6 +85,27 @@ namespace QuestPDF.Drawing
                     
                 }
             }
+
+            ICollection<string> SearchFontFiles()
+            {
+                const int maxFilesToScan = 100_000;
+                
+                var applicationFiles = Settings
+                    .FontDiscoveryPaths
+                    .Select(path => Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
+                    .SelectMany(file => file)
+                    .Take(maxFilesToScan)
+                    .ToList();
+                
+                if (applicationFiles.Count == maxFilesToScan)
+                    throw new InvalidOperationException($"The library has reached the limit of {maxFilesToScan} files to scan for font files. Please adjust the {nameof(Settings.FontDiscoveryPaths)} collection to include only the necessary directories. The reason of this exception is to prevent scanning too many files and avoid performance issues on the application startup.");
+                
+                var supportedFontExtensions = new[] { ".ttf", ".otf", ".ttc", ".pfb" };
+                
+                return applicationFiles
+                    .Where(x => supportedFontExtensions.Contains(Path.GetExtension(x).ToLowerInvariant()))
+                    .ToList();
+            }
         }
     }
 }

+ 4 - 0
Source/QuestPDF/Resources/ReleaseNotes.txt

@@ -25,3 +25,7 @@ Version 2024.7.1
 
 Version 2024.7.2
 - Fixed a memory leak issue when generating documents as images using the `GenerateImages` method.
+
+
+Version 2024.7.3
+- Introduced FontDiscoveryPaths setting for specifying directories for automatic font registration and improved font search performance.

+ 13 - 0
Source/QuestPDF/Settings.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using QuestPDF.Helpers;
 using QuestPDF.Infrastructure;
 
@@ -50,6 +51,18 @@ namespace QuestPDF
         /// </remarks>
         public static bool UseEnvironmentFonts { get; set; } = true;
         
+        /// <summary>
+        /// Specifies the collection of paths where the library will automatically search for font files to register.
+        /// </summary>
+        /// <remarks>
+        /// <para>By default, this collection contains the application files path.</para>
+        /// <para>You can add additional paths to this collection to include more directories for automatic font registration.</para>
+        /// </remarks>
+        public static ICollection<string> FontDiscoveryPaths { get; } = new List<string>()
+        {
+            Helpers.Helpers.ApplicationFilesPath
+        };
+        
         static Settings()
         {
             NativeDependencyCompatibilityChecker.Test();