Browse Source

Added CheckUnresolvedGlyphs

Marcin Ziąbek 1 year ago
parent
commit
d8ca22bdaf

+ 1 - 5
Source/QuestPDF.Examples/TextExamples.cs

@@ -960,11 +960,7 @@ namespace QuestPDF.Examples
                         page.DefaultTextStyle(x => x
                             .FontSize(24)
                             .Bold()
-                            .FontFamily("Times New Roman")
-                            .Fallback(y => y
-                                .FontFamily("Microsoft YaHei")
-                                .Underline()
-                                .BackgroundColor(Colors.Red.Lighten2)));
+                            .FontFamily("Times New Roman"));
 
                         page.Content().Text(text =>
                         {

+ 6 - 3
Source/QuestPDF/Drawing/FontManager.cs

@@ -1,6 +1,5 @@
 using System;
 using System.IO;
-using System.Linq;
 using System.Reflection;
 using QuestPDF.Helpers;
 using QuestPDF.Infrastructure;
@@ -16,8 +15,12 @@ namespace QuestPDF.Drawing
     /// </summary>
     public static class FontManager
     {
-        internal static SkTypefaceProvider TypefaceProvider { get; } = new SkTypefaceProvider();
-        internal static SkFontCollection FontCollection { get; } = SkFontCollection.Create(FontManager.TypefaceProvider, true, true);
+        internal static SkTypefaceProvider TypefaceProvider { get; } = new();
+        
+        private static SkFontCollection LocalFontCollection { get; } = SkFontCollection.Create(FontManager.TypefaceProvider, false, true);
+        private static SkFontCollection GlobalFontCollection { get; } = SkFontCollection.Create(FontManager.TypefaceProvider, true, true);
+        
+        internal static SkFontCollection FontCollection => Settings.UseEnvironmentFonts ? GlobalFontCollection : LocalFontCollection;
         
         static FontManager()
         {

+ 34 - 0
Source/QuestPDF/Elements/Text/TextBlock.cs

@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Linq;
 using QuestPDF.Drawing;
+using QuestPDF.Drawing.Exceptions;
 using QuestPDF.Elements.Text.Items;
 using QuestPDF.Infrastructure;
 using QuestPDF.Skia;
@@ -49,7 +50,10 @@ namespace QuestPDF.Elements.Text
             if (Math.Abs(WidthForLineMetricsCalculation - availableSpace.Width) > Size.Epsilon)
             {
                 WidthForLineMetricsCalculation = availableSpace.Width;
+                
                 Paragraph.PlanLayout(availableSpace.Width + 1);
+                CheckUnresolvedGlyphs();
+                
                 LineMetrics = Paragraph.GetLineMetrics();
                 PlaceholderPositions = Paragraph.GetPlaceholderPositions();
                 MaximumWidth = LineMetrics.Max(x => x.Width);
@@ -293,5 +297,35 @@ namespace QuestPDF.Elements.Text
                 };
             }
         }
+        
+        private void CheckUnresolvedGlyphs()
+        {
+            if (!Settings.CheckIfAllTextGlyphsAreAvailable)
+                return;
+                
+            var unsupportedGlyphs = Paragraph.GetUnresolvedCodepoints();
+                   
+            if (!unsupportedGlyphs.Any())
+                return;
+                
+            var formattedGlyphs = unsupportedGlyphs    
+                .Select(codepoint =>
+                {
+                    var character = char.ConvertFromUtf32(codepoint);
+                    return $"U-{codepoint:X4} '{character}'";
+                });
+                
+            var glyphs = string.Join("\n", formattedGlyphs);
+
+            throw new DocumentDrawingException(
+                $"Could not find an appropriate font fallback for the following glyphs: \n" +
+                $"${glyphs} \n\n" +
+                $"Possible solutions: \n" +
+                $"1) Install fonts that contain missing glyphs in your runtime environment. \n" +
+                $"2) Configure the fallback TextStyle using the 'TextStyle.FontFamilyFallback' method. \n" +
+                $"3) Register additional application specific fonts using the 'FontManager.RegisterFont' method. \n\n" +
+                $"You can disable this check by setting the 'Settings.CheckIfAllTextGlyphsAreAvailable' option to 'false'. \n" +
+                $"However, this may result with text glyphs being incorrectly rendered without any warning.");
+        }
     }
 }

+ 10 - 0
Source/QuestPDF/Settings.cs

@@ -40,6 +40,16 @@ namespace QuestPDF
         /// <remarks>By default, this flag is enabled only when the debugger IS attached.</remarks>
         public static bool CheckIfAllTextGlyphsAreAvailable { get; set; } = System.Diagnostics.Debugger.IsAttached;
 
+        /// <summary>
+        /// Decides whether the application should use the fonts available in the environment.
+        /// </summary>
+        /// <remarks>
+        /// <para>When set to <c>true</c>, the application will use the fonts installed on the system where it is running. This is the default behavior.</para>
+        /// <para>When set to <c>false</c>, the application will only use the fonts that have been registered using the <c>FontManager</c> class in the QuestPDF library.</para>
+        /// <para>This property is useful when you want to control the fonts used by your application, especially in cases where the environment might not have the necessary fonts installed.</para>
+        /// </remarks>
+        public static bool UseEnvironmentFonts { get; set; } = true;
+        
         static Settings()
         {
             NativeDependencyCompatibilityChecker.Test();