using FastReport.Utils; using System; using System.Collections; using System.Drawing; using System.IO; using System.Runtime.InteropServices; using System.Text; using FastReport.Export.TTF; namespace FastReport.Export.OoXML { /// /// Font container /// internal class XPS_Font : OoXMLBase, IDisposable { #region DLL import [DllImport("Gdi32.dll")] private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj); [DllImport("Gdi32.dll")] private static extern IntPtr DeleteObject(IntPtr hgdiobj); [DllImport("Gdi32.dll", CharSet = CharSet.Auto)] private static extern uint GetFontData(IntPtr hdc, uint dwTable, uint dwOffset, [In, Out] byte[] lpvBuffer, uint cbData); [DllImport("Gdi32.dll", CharSet = CharSet.Auto)] private static extern uint GetFontData(IntPtr hdc, uint dwTable, uint dwOffset, [In, Out] IntPtr lpvBuffer, uint cbData); #endregion #region "Class overrides" public override string RelationType { get { return "http://schemas.microsoft.com/xps/2005/06/required-resource"; } } public override string ContentType { get { return null; } } //"application/vnd.openxmlformats-officedocument.presentationml.slide+xml"; } } public override string FileName { get { return "/Resources/" + generatedName + ".odttf"; } } // public override string FileName { get { return "/Resources/" + GeneratedName + ".ttf"; } } #endregion private Hashtable listOfUsedGlyphs; private FontFamily fontFamily; private ExportTTFFont export_font; internal float size; internal FontStyle style; internal float height; public Guid fontGuid; public string generatedName; internal Font SourceFont { set { fontFamily = value.FontFamily; size = value.Size; style = value.Style; height = value.Height; } } /// /// Font obfuscation procedure /// internal void Obfuscation(byte[] data) { if (data.Length < 32) throw new Exception("Font header error"); byte[] guidByteArray = new byte[16]; string guidString = fontGuid.ToString("N"); for (int i = 0; i < guidByteArray.Length; i++) { guidByteArray[i] = Convert.ToByte(guidString.Substring(i * 2, 2), 16); } for (int j = 0; j < 2; j++) { for (int i = 0; i < 16; i++) { data[i + j * 16] ^= guidByteArray[15 - i]; } } } public byte[] ExportFont(XPSExport export) { float FDpiFX = 96f / DrawUtils.ScreenDpi; byte[] result = null; using (Font current_font = new Font(this.fontFamily, this.size * FDpiFX, this.style)) { try { result = export_font.GetFontData(true); Obfuscation(result); MemoryStream file = new MemoryStream(); file.Write(result, 0, result.Length); file.Position = 0; export.Zip.AddStream(ExportUtils.TruncLeadSlash(this.FileName), file); } finally { } } return result; } public XPS_Font(Font f) { int i, j; this.fontFamily = f.FontFamily; this.size = f.Size; this.style = f.Style; fontGuid = SystemFake.Guid.NewGuid(); export_font = new ExportTTFFont(f); listOfUsedGlyphs = new Hashtable(); string Name = fontGuid.ToString("N"); generatedName = ""; for (i = 0; i < 8; i++) generatedName += Name[i]; generatedName += '-'; for (j = 0; j < 4; j++, i++) generatedName += Name[i]; generatedName += '-'; for (j = 0; j < 4; j++, i++) generatedName += Name[i]; generatedName += '-'; for (j = 0; j < 4; j++, i++) generatedName += Name[i]; generatedName += '-'; for (j = 0; j < 12; j++, i++) generatedName += Name[i]; } // cut off --- Samuray internal string AddString(string str, bool rtl) { StringBuilder sb = new StringBuilder(); foreach (var run in export_font.GetFontRuns(str, rtl)) { if (run.Font == export_font.SourceFont) { export_font.AddUsedGlyphs(run); foreach (ushort c in run.Glyphs) AddGlyph(c); for (int i = 0; i < run.Glyphs.Length; i++) { sb.Append((char)run.Glyphs[i]); } } } return sb.ToString(); } // end cut off private void AddGlyph(ushort symbol) { if (!listOfUsedGlyphs.ContainsKey(symbol)) { int id = listOfUsedGlyphs.Count; listOfUsedGlyphs.Add(symbol, id); } } internal string GetXpsIndexes(string text) { int i; StringBuilder indices = new StringBuilder(text.Length * 4); indices.Append("Indices=\""); //float WIDTH_DIVIDER = 10; for (i = 0; i < text.Length; i++) { indices.Append(((int)text[i]).ToString()). //Append(','). //Append(Converter.ToString(export_font.GetGlyphWidth(text[i]) / WIDTH_DIVIDER)). Append(';'); } indices.Remove(indices.Length - 1, 1); indices.Append("\" "); return indices.ToString(); } #region IDisposable Members public void Dispose() { export_font.Dispose(); } #endregion } }