XPS_Font.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. using FastReport.Utils;
  2. using System;
  3. using System.Collections;
  4. using System.Drawing;
  5. using System.IO;
  6. using System.Runtime.InteropServices;
  7. using System.Text;
  8. using FastReport.Export.TTF;
  9. namespace FastReport.Export.OoXML
  10. {
  11. /// <summary>
  12. /// Font container
  13. /// </summary>
  14. internal class XPS_Font : OoXMLBase, IDisposable
  15. {
  16. #region DLL import
  17. [DllImport("Gdi32.dll")]
  18. private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
  19. [DllImport("Gdi32.dll")]
  20. private static extern IntPtr DeleteObject(IntPtr hgdiobj);
  21. [DllImport("Gdi32.dll", CharSet = CharSet.Auto)]
  22. private static extern uint GetFontData(IntPtr hdc, uint dwTable, uint dwOffset, [In, Out] byte[] lpvBuffer, uint cbData);
  23. [DllImport("Gdi32.dll", CharSet = CharSet.Auto)]
  24. private static extern uint GetFontData(IntPtr hdc, uint dwTable, uint dwOffset, [In, Out] IntPtr lpvBuffer, uint cbData);
  25. #endregion
  26. #region "Class overrides"
  27. public override string RelationType { get { return "http://schemas.microsoft.com/xps/2005/06/required-resource"; } }
  28. public override string ContentType { get { return null; } } //"application/vnd.openxmlformats-officedocument.presentationml.slide+xml"; } }
  29. public override string FileName { get { return "/Resources/" + generatedName + ".odttf"; } }
  30. // public override string FileName { get { return "/Resources/" + GeneratedName + ".ttf"; } }
  31. #endregion
  32. private Hashtable listOfUsedGlyphs;
  33. private FontFamily fontFamily;
  34. private ExportTTFFont export_font;
  35. internal float size;
  36. internal FontStyle style;
  37. internal float height;
  38. public Guid fontGuid;
  39. public string generatedName;
  40. internal Font SourceFont
  41. {
  42. set
  43. {
  44. fontFamily = value.FontFamily;
  45. size = value.Size;
  46. style = value.Style;
  47. height = value.Height;
  48. }
  49. }
  50. /// <summary>
  51. /// Font obfuscation procedure
  52. /// </summary>
  53. internal void Obfuscation(byte[] data)
  54. {
  55. if (data.Length < 32) throw new Exception("Font header error");
  56. byte[] guidByteArray = new byte[16];
  57. string guidString = fontGuid.ToString("N");
  58. for (int i = 0; i < guidByteArray.Length; i++)
  59. {
  60. guidByteArray[i] = Convert.ToByte(guidString.Substring(i * 2, 2), 16);
  61. }
  62. for (int j = 0; j < 2; j++)
  63. {
  64. for (int i = 0; i < 16; i++)
  65. {
  66. data[i + j * 16] ^= guidByteArray[15 - i];
  67. }
  68. }
  69. }
  70. public byte[] ExportFont(XPSExport export)
  71. {
  72. float FDpiFX = 96f / DrawUtils.ScreenDpi;
  73. byte[] result = null;
  74. using (Font current_font = new Font(this.fontFamily, this.size * FDpiFX, this.style))
  75. {
  76. try
  77. {
  78. result = export_font.GetFontData(true);
  79. Obfuscation(result);
  80. MemoryStream file = new MemoryStream();
  81. file.Write(result, 0, result.Length);
  82. file.Position = 0;
  83. export.Zip.AddStream(ExportUtils.TruncLeadSlash(this.FileName), file);
  84. }
  85. finally
  86. {
  87. }
  88. }
  89. return result;
  90. }
  91. public XPS_Font(Font f)
  92. {
  93. int i, j;
  94. this.fontFamily = f.FontFamily;
  95. this.size = f.Size;
  96. this.style = f.Style;
  97. fontGuid = SystemFake.Guid.NewGuid();
  98. export_font = new ExportTTFFont(f);
  99. listOfUsedGlyphs = new Hashtable();
  100. string Name = fontGuid.ToString("N");
  101. generatedName = "";
  102. for (i = 0; i < 8; i++) generatedName += Name[i];
  103. generatedName += '-';
  104. for (j = 0; j < 4; j++, i++) generatedName += Name[i];
  105. generatedName += '-';
  106. for (j = 0; j < 4; j++, i++) generatedName += Name[i];
  107. generatedName += '-';
  108. for (j = 0; j < 4; j++, i++) generatedName += Name[i];
  109. generatedName += '-';
  110. for (j = 0; j < 12; j++, i++) generatedName += Name[i];
  111. }
  112. // cut off --- Samuray
  113. internal string AddString(string str, bool rtl)
  114. {
  115. StringBuilder sb = new StringBuilder();
  116. foreach (var run in export_font.GetFontRuns(str, rtl))
  117. {
  118. if (run.Font == export_font.SourceFont)
  119. {
  120. export_font.AddUsedGlyphs(run);
  121. foreach (ushort c in run.Glyphs)
  122. AddGlyph(c);
  123. for (int i = 0; i < run.Glyphs.Length; i++)
  124. {
  125. sb.Append((char)run.Glyphs[i]);
  126. }
  127. }
  128. }
  129. return sb.ToString();
  130. }
  131. // end cut off
  132. private void AddGlyph(ushort symbol)
  133. {
  134. if (!listOfUsedGlyphs.ContainsKey(symbol))
  135. {
  136. int id = listOfUsedGlyphs.Count;
  137. listOfUsedGlyphs.Add(symbol, id);
  138. }
  139. }
  140. internal string GetXpsIndexes(string text)
  141. {
  142. int i;
  143. StringBuilder indices = new StringBuilder(text.Length * 4);
  144. indices.Append("Indices=\"");
  145. //float WIDTH_DIVIDER = 10;
  146. for (i = 0; i < text.Length; i++)
  147. {
  148. indices.Append(((int)text[i]).ToString()).
  149. //Append(',').
  150. //Append(Converter.ToString(export_font.GetGlyphWidth(text[i]) / WIDTH_DIVIDER)).
  151. Append(';');
  152. }
  153. indices.Remove(indices.Length - 1, 1);
  154. indices.Append("\" ");
  155. return indices.ToString();
  156. }
  157. #region IDisposable Members
  158. public void Dispose()
  159. {
  160. export_font.Dispose();
  161. }
  162. #endregion
  163. }
  164. }