FontStreamPool.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using FastReport.RichTextParser;
  2. using System.Collections.Concurrent;
  3. using System.Drawing;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Runtime.InteropServices;
  7. using FastReport.Export.TTF;
  8. using FastReport.Utils;
  9. using System.Diagnostics;
  10. using System;
  11. using System.Collections.Generic;
  12. using FastReport.Barcode.QRCode;
  13. namespace FastReport.Fonts
  14. {
  15. using FontStreamList = ConcurrentQueue<TrueTypeFont>;
  16. internal class FontStreamPool
  17. {
  18. const int MAX_STREAMS_PER_FONT = 2;
  19. static readonly ConcurrentDictionary<string, FontStreamList> pool = new ConcurrentDictionary<string, FontStreamList>();
  20. #if SKIA
  21. internal static FontStream GetFontStream(Font source_font)
  22. {
  23. SkiaSharp.SKStreamAsset skStream = source_font.InternalTypeface.OpenStream();
  24. Byte[] mb = new byte[skStream.Length];
  25. skStream.Read(mb, mb.Length);
  26. MemoryStream memoryStream = new MemoryStream(mb);
  27. return new FontStream(memoryStream, true);
  28. }
  29. #endif
  30. internal static TrueTypeFont GetTTF(string fast_font, Font source_font)
  31. {
  32. TrueTypeFont result = null;
  33. pool.TryAdd(fast_font, new FontStreamList());
  34. bool success = pool[fast_font].TryDequeue(out result);
  35. if (!success)
  36. {
  37. #if !SKIA
  38. FontStream font_stream = ExportTTFFont.GetFontStream(source_font);
  39. #else
  40. FontStream font_stream = GetFontStream(source_font);
  41. #endif
  42. if (font_stream == null)
  43. throw new Exception("Unable get font stream");
  44. TrueTypeFont last_ttf = null;
  45. foreach (TrueTypeFont ttf in TrueTypeCollection.CreateFonts(font_stream))
  46. {
  47. TrueTypeCollection.ParseFont(ttf, "");
  48. if (ttf.Family == source_font.FontFamily.Name)
  49. {
  50. result = ttf;
  51. break;
  52. }
  53. var families = ttf.GetNames(NameTableClass.NameID.FamilyName);
  54. foreach (string family in families)
  55. {
  56. if (family == source_font.FontFamily.Name)
  57. {
  58. result = ttf;
  59. break;
  60. }
  61. last_ttf = ttf;
  62. }
  63. }
  64. if (result == null)
  65. {
  66. result = last_ttf;
  67. #if DEBUG
  68. Debug.WriteLine(source_font.FontFamily.Name, "Font family not found. Substituted ", result.Family);
  69. #endif
  70. }
  71. result.Stream.StreamFontFastName = fast_font;
  72. }
  73. result.Stream.Position = 0;
  74. return result;
  75. }
  76. internal static void ReleaseFontStream(TrueTypeFont fontStream)
  77. {
  78. if (! pool.TryGetValue(fontStream.Stream.StreamFontFastName, out var collection))
  79. throw new System.ExecutionEngineException("pool of fonts error in ReleaseFontStream");
  80. if (collection.Count < MAX_STREAMS_PER_FONT)
  81. {
  82. fontStream.Stream.Position = 0;
  83. fontStream.Stream.LeaveOpen = true;
  84. collection.Enqueue(fontStream);
  85. }
  86. else
  87. fontStream.Dispose(true);
  88. }
  89. FontStreamPool()
  90. {
  91. Debug.WriteLine("Problem");
  92. }
  93. }
  94. }