FontManager.LinuxDefault.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // available only in FastReport.Core (non Skia) and Mono (for Linux)
  2. #if !SKIA && ((MONO && !WPF) || FRCORE)
  3. using FastReport.Fonts;
  4. using FastReport.Utils;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Diagnostics;
  8. using System.Drawing;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Runtime.InteropServices;
  12. namespace FastReport
  13. {
  14. public static partial class FontManager
  15. {
  16. private static readonly Dictionary<string, DictionaryFont> _fonts = new();
  17. private static void RegisterFontInternal(string filename)
  18. {
  19. IList<TrueTypeFont> ttfs = TrueTypeCollection.CheckFile(Fonts.TrueTypeCollection.CacheOptions.DoNotUpdate, filename);
  20. foreach (TrueTypeFont font in ttfs)
  21. {
  22. string fontName = font.FastName;
  23. string family2016 = TrueTypeFont.GetFontKey(font.Family2016, font);
  24. if (!_fonts.ContainsKey(fontName))
  25. {
  26. _fonts.Add(fontName, new FontFromFile(filename));
  27. }
  28. else
  29. {
  30. Debug.WriteLine($"Font '{fontName}' already present in collection.\n Files:\n {_fonts[fontName]}\n {filename}\n");
  31. }
  32. if (!_fonts.ContainsKey(family2016))
  33. {
  34. _fonts.Add(family2016, new FontFromFile(filename));
  35. }
  36. }
  37. }
  38. /// <summary>
  39. /// Checks if the font name is contained in this collection.
  40. /// </summary>
  41. /// <param name="fontName">The name of the font.</param>
  42. /// <returns>true if the font is contained in this collection.</returns>
  43. public static bool HasFont(string fontName)
  44. {
  45. return _fonts.ContainsKey(fontName);
  46. }
  47. /// <summary>
  48. /// Returns the font's stream.
  49. /// </summary>
  50. /// <param name="fontName">The name of the font.</param>
  51. /// <returns>Either FileStream or MemoryStream containing font data.</returns>
  52. public static Stream GetFontStream(string fontName)
  53. {
  54. if (_fonts.TryGetValue(fontName, out var font))
  55. {
  56. return font.GetFontStream();
  57. }
  58. return null;
  59. }
  60. /// <summary>
  61. /// Adds a font from the specified file to this collection.
  62. /// </summary>
  63. /// <param name="filename">A System.String that contains the file name of the font to add.</param>
  64. /// <returns>true if the font is registered by application.</returns>
  65. public static bool AddFont(string filename)
  66. {
  67. bool success = false;
  68. if (File.Exists(filename))
  69. {
  70. if (!_fonts.Values.OfType<FontFromFile>().Any(fontFile => fontFile._filepath == filename))
  71. {
  72. PrivateFontCollection.AddFontFile(filename);
  73. RegisterFontInternal(filename);
  74. success = true;
  75. }
  76. else
  77. {
  78. Debug.WriteLine($"Font file '{filename}' already present in collection");
  79. }
  80. }
  81. else
  82. {
  83. Debug.WriteLine($"Font file '{filename}' not found");
  84. }
  85. return success;
  86. }
  87. /// <summary>
  88. /// Adds a font contained in system memory to this collection.
  89. /// </summary>
  90. /// <param name="memory">The memory address of the font to add.</param>
  91. /// <param name="length">The memory length of the font to add.</param>
  92. public static void AddFont(IntPtr memory, int length)
  93. {
  94. PrivateFontCollection.AddMemoryFont(memory, length);
  95. string fontName = PrivateFontCollection.Families[PrivateFontCollection.Families.Length - 1].Name;
  96. if (!_fonts.ContainsKey(fontName))
  97. _fonts.Add(fontName, new MemoryFont(memory, length));
  98. }
  99. private abstract class DictionaryFont
  100. {
  101. public abstract Stream GetFontStream();
  102. }
  103. private sealed class FontFromFile : DictionaryFont
  104. {
  105. internal readonly string _filepath;
  106. public FontFromFile(string filepath)
  107. {
  108. _filepath = filepath;
  109. }
  110. public override Stream GetFontStream()
  111. {
  112. return new FileStream(_filepath, FileMode.Open, FileAccess.Read);
  113. }
  114. public override string ToString()
  115. {
  116. return _filepath;
  117. }
  118. }
  119. private sealed class FontFromStream : DictionaryFont
  120. {
  121. private readonly Stream _stream;
  122. public FontFromStream(Stream stream)
  123. {
  124. _stream = stream;
  125. }
  126. public override Stream GetFontStream()
  127. {
  128. var newStream = new MemoryStream();
  129. _stream.CopyTo(newStream);
  130. _stream.Position = 0;
  131. newStream.Position = 0;
  132. return newStream;
  133. }
  134. }
  135. private sealed class MemoryFont : DictionaryFont
  136. {
  137. private readonly IntPtr Memory;
  138. private readonly int Length;
  139. public MemoryFont(IntPtr memory, int length)
  140. {
  141. Memory = memory;
  142. Length = length;
  143. }
  144. public override Stream GetFontStream()
  145. {
  146. byte[] buffer = new byte[Length];
  147. Marshal.Copy(Memory, buffer, 0, Length);
  148. return new MemoryStream(buffer);
  149. }
  150. }
  151. }
  152. }
  153. #endif