FontFallbacks.cs
  1. //
  2. // This code is part of Document Solutions for PDF demos.
  3. // Copyright (c) MESCIUS inc. All rights reserved.
  4. //
  5. using System;
  6. using System.IO;
  7. using System.Drawing;
  8. using GrapeCity.Documents.Pdf;
  9. using GrapeCity.Documents.Text;
  10. using GCTEXT = GrapeCity.Documents.Text;
  11. using GCDRAW = GrapeCity.Documents.Drawing;
  12.  
  13. namespace DsPdfWeb.Demos.Basics
  14. {
  15. // Fallback fonts are fonts used to draw glyphs that are not present
  16. // in a font specified by the application.
  17. // DsPdf provides a default list of fallback font families
  18. // that is automatically initialized, and includes large fonts
  19. // that are usually suitable to be used as fallbacks for many
  20. // languages for which some common fonts do not have the glyphs.
  21. // These automatically added fallback font families are available
  22. // via methods on the FontCollection.SystemFonts static collection.
  23. // You can customize the default (and system-dependent) behavior
  24. // by providing your own fallback fonts, and by adding them either
  25. // to fallbacks managed by the global FontCollection.SystemFonts,
  26. // by adding them to your own instance of the FontCollection,
  27. // or to specific fonts that you are using.
  28. // In this way the fallback font behavior can be finely tuned
  29. // and be completely system-independent.
  30. //
  31. // This sample demonstrates the basic fallback behavior -
  32. // clearing system fallbacks and re-adding them again.
  33. // Additionally, it prints the list of fallback fonts
  34. // found on the current system.
  35. public class FontFallbacks
  36. {
  37. public int CreatePDF(Stream stream)
  38. {
  39. // Set up GcPdfDocument:
  40. var doc = new GcPdfDocument();
  41. var g = doc.NewPage().Graphics;
  42.  
  43. // Set up some helper vars for rendering lines of text:
  44. const float margin = 36;
  45. // Insertion point (DsPdf's default resolution is 72dpi, use 1/2" margins all around):
  46. var ip = new PointF(margin, margin);
  47. // Init a text format with one of the standard fonts. Standard fonts are minimal
  48. // and contain very few glyphs for non-Latin characters.
  49. var tf = new TextFormat() { Font = StandardFonts.Courier, FontSize = 14 };
  50.  
  51. // Get the list of fallback font families:
  52. string[] fallbacks = FontCollection.SystemFonts.GetFallbackFontFamilies();
  53.  
  54. // Clear global fallbacks list:
  55. FontCollection.SystemFonts.ClearFallbackFontFamilies();
  56. FontCollection.SystemFonts.ClearFallbackFonts();
  57.  
  58. // Now there are no global fallback fonts, so Japanese text rendered using
  59. // a standard font will produce 'blank boxes' instead of real Japanese characters:
  60. g.DrawString("A Japanese text that won't render: あなたは日本語を話せますか?", tf, ip);
  61. ip.Y += 36;
  62.  
  63. // Re-add the original list of fallback font families to global SystemFonts:
  64. FontCollection.SystemFonts.AppendFallbackFontFamilies(fallbacks);
  65. // On some systems, default system fallbacks might not provide Japanese glyphs,
  66. // so we add our own fallback just in case:
  67. var arialuni = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "arialuni.ttf"));
  68. FontCollection.SystemFonts.AppendFallbackFonts(arialuni);
  69.  
  70. // Now that fallback fonts are available again, the same Japanese text will render
  71. // correctly as an appropriate fallback will have been found:
  72. g.DrawString("Same text with fallbacks available: あなたは日本語を話せますか?", tf, ip);
  73. ip.Y += 36;
  74.  
  75. // Finally, we list all fallbacks and print a test line using each:
  76. Action<string> drawTestLine = (fnt_) =>
  77. {
  78. var tf1 = new TextFormat() { FontName = fnt_ };
  79. var tstr = $"{fnt_}: The quick brown fox jumps over the lazy dog.";
  80. var s = g.MeasureString(tstr, tf1, doc.PageSize.Width - margin * 2);
  81. g.DrawString(tstr, tf1, new RectangleF(ip, s));
  82. ip.Y += s.Height * 1.5f;
  83. if (ip.Y > doc.Pages.Last.Size.Height - margin * 2)
  84. {
  85. g = doc.NewPage().Graphics;
  86. ip.Y = 36;
  87. }
  88. };
  89. foreach (var fnt in fallbacks)
  90. drawTestLine(fnt);
  91.  
  92. // Done:
  93. doc.Save(stream);
  94. return doc.Pages.Count;
  95. }
  96. }
  97. }
  98.