ExportFont.LinuxDefault.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #if WITHOUT_UNISCRIBE
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Drawing;
  5. using FastReport.Fonts;
  6. using FastReport.Utils;
  7. using System.IO;
  8. #if !SKIA
  9. using System.Runtime.InteropServices;
  10. using FastReport.RichTextParser;
  11. using FastReport.Export.TTF;
  12. #endif
  13. using System.Diagnostics;
  14. namespace FastReport.Export.TTF
  15. {
  16. internal partial class ExportTTFFont
  17. {
  18. #if !SKIA
  19. internal static FontStream GetFontStream(Font source_font)
  20. {
  21. MemoryStream mem_stream;
  22. string fastFont = TrueTypeFont.GetFontKey(source_font);
  23. string path;
  24. bool fontFound = TrueTypeCollection.FontHash.TryGetValue(fastFont, out path);
  25. while(!fontFound)
  26. {
  27. var font = FontManager.GetFontStream(fastFont);
  28. if (font != null)
  29. {
  30. font.Position = 0;
  31. return new FontStream(font);
  32. }
  33. string substFont1 =
  34. source_font.FontFamily.Name +
  35. (!source_font.Bold ? "-B" : string.Empty) +
  36. (source_font.Italic ? "-I" : string.Empty);
  37. string substFont2 =
  38. source_font.FontFamily.Name +
  39. (source_font.Bold ? "-B" : string.Empty) +
  40. (!source_font.Italic ? "-I" : string.Empty);
  41. string substFont3 =
  42. source_font.FontFamily.Name +
  43. (!source_font.Bold ? "-B" : string.Empty) +
  44. (!source_font.Italic ? "-I" : string.Empty);
  45. lock (TrueTypeCollection.FontHash)
  46. {
  47. if (TrueTypeCollection.FontHash.IsEmpty)
  48. {
  49. TrueTypeCollection.CheckFontList(Utils.Config.FontListFolder);
  50. }
  51. }
  52. fontFound = TrueTypeCollection.FontHash.TryGetValue(fastFont, out path);
  53. if (fontFound)
  54. break;
  55. fontFound = TrueTypeCollection.FontHash.TryGetValue(substFont1, out path);
  56. if (fontFound)
  57. {
  58. TrueTypeCollection.FontHash.TryAdd(fastFont, path);
  59. break;
  60. }
  61. fontFound = TrueTypeCollection.FontHash.TryGetValue(substFont2, out path);
  62. if (fontFound)
  63. {
  64. TrueTypeCollection.FontHash.TryAdd(fastFont, path);
  65. break;
  66. }
  67. fontFound = TrueTypeCollection.FontHash.TryGetValue(substFont3, out path);
  68. if (fontFound)
  69. {
  70. TrueTypeCollection.FontHash.TryAdd(fastFont, path);
  71. break;
  72. }
  73. string substFont4 =
  74. DrawUtils.DefaultFont.FontFamily.Name +
  75. (DrawUtils.DefaultFont.Bold ? "-B" : string.Empty) +
  76. (DrawUtils.DefaultFont.Italic ? "-I" : string.Empty);
  77. fontFound = TrueTypeCollection.FontHash.TryGetValue(substFont4, out path);
  78. if(fontFound)
  79. {
  80. TrueTypeCollection.FontHash.TryAdd(fastFont, path);
  81. Debug.WriteLine("Font '{0}' not found. Trying substitue to default font", fastFont); // LOG
  82. break;
  83. }
  84. Debug.WriteLine("Default font not found. Set random font to avoid file not found exception"); // LOG
  85. var en = TrueTypeCollection.FontHash.GetEnumerator();
  86. en.MoveNext();
  87. path = en.Current.Value;
  88. break;
  89. }
  90. using (FileStream fontStream = new FileStream(path, FileMode.Open, FileAccess.Read))
  91. {
  92. mem_stream = new MemoryStream();
  93. fontStream.CopyTo(mem_stream);
  94. }
  95. mem_stream.Position = 0;
  96. return new FontStream(mem_stream);
  97. }
  98. public void FillOutlineTextMetrix()
  99. {
  100. if (sourceFont != null)
  101. {
  102. using (var fontState = new TTFState(sourceFont))
  103. {
  104. var ttf = fontState.Value;
  105. ttf.GetOutlineTextMetrics(ref textMetric);
  106. postscript_name = ttf.PostscriptName;
  107. NeedSimulateBold = SourceFont.Bold && !ttf.Bold;
  108. NeedSimulateItalic = SourceFont.Italic && !ttf.Italic;
  109. }
  110. }
  111. }
  112. // libgdiplus version has no support for font fallback and returns one run.
  113. // Also support of complex scripts is almost non-existing.
  114. private List<RunInfo> LayoutString(string str, bool rtl, Font originalFont)
  115. {
  116. int maxGlyphs = str.Length * 3;
  117. var run = new RunInfo(maxGlyphs)
  118. {
  119. Font = originalFont,
  120. };
  121. for (int i = 0, j = 0; i < str.Length; i++)
  122. {
  123. if (str[i] > 0xD800 && str[i] < 0xDBFF && run.GlyphToUnicode[j] == null)
  124. {
  125. run.GlyphToUnicode[j] = str[i].ToString();
  126. }
  127. else if (str[i] > 0xDC00 && str[i] < 0xDFFF && run.GlyphToUnicode[j] != null)
  128. {
  129. run.GlyphToUnicode[j++] += str[i].ToString();
  130. }
  131. else
  132. {
  133. if (run.GlyphToUnicode[j] != null)
  134. j++;
  135. run.GlyphToUnicode[j++] = str[i].ToString();
  136. }
  137. }
  138. using(var fontState = new TTFState(sourceFont))
  139. {
  140. var ttf = fontState.Value;
  141. {
  142. // Why? Why we are switching font to arab script,
  143. if (rtl)
  144. ttf.Script = "arab";
  145. int actualLength = ttf.GetGlyphIndices(str, sourceFont.Size / 0.75f, out run.Glyphs, out run.Widths, out run.Kernings, rtl);
  146. Array.Resize<ushort>(ref run.Glyphs, actualLength);
  147. Array.Resize<string>(ref run.GlyphToUnicode, actualLength);
  148. Array.Resize<float>(ref run.Widths, actualLength);
  149. Array.Resize<float>(ref run.Kernings, actualLength);
  150. }
  151. }
  152. List<RunInfo> result = new List<RunInfo>();
  153. result.Add(run);
  154. return result;
  155. }
  156. private void InternalInit()
  157. {
  158. dpiFX = 1;
  159. }
  160. partial void InternalDispose();
  161. #endif
  162. }
  163. }
  164. #endif