/* i-net software provides programming examples for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose. This programming example assumes that you are familiar with the programming language being demonstrated and the tools used to create and debug procedures. i-net software support professionals can help explain the functionality of a particular procedure, but they will not modify these examples to provide added functionality or construct procedures to meet your specific needs. © i-net software 1998-2013 */ using ICSharpCode.SharpZipLib.Zip.Compression; using ICSharpCode.SharpZipLib.Zip.Compression.Streams; using Inet.Viewer.Resources; using System; using System.Drawing; using System.Drawing.Text; using System.IO; using System.Runtime.InteropServices; namespace Inet.Viewer.Data { /// /// Implementation of the Loader to specifically load the Fonts /// public class FontLoader : Loader { private FontData result = null; /// /// Ovrrides the Load function /// /// /// protected internal override bool Load(int token) { switch (token) { case ViewerTokenConstants.TokenFontId: result.Id = ReadInt(); break; case ViewerTokenConstants.TokenFontRev: result.Revision = ReadInt(); break; case ViewerTokenConstants.TokenFontData: bool compressFontData = ReadBoolean(); byte[] fontData = ReadByteArray(); if (compressFontData) { Inflater inflater = new Inflater(); InflaterInputStream input = new InflaterInputStream(new MemoryStream(fontData), inflater); MemoryStream ustream = new MemoryStream(); int b; while ((b=input.ReadByte())!=-1) { ustream.WriteByte((byte)b); } fontData = ustream.ToArray(); } try { LoadFontFamily(fontData); } catch (IOException e) { throw new ViewerException(strings.ErrorMessage_Font_CouldNotCreate + " " + result.Id, e); } break; default: return base.Load(token); } return true; } /// /// This method Reads the byte fontData and returns the FontData of this Font /// /// the font data in form of a byte array /// the parsed FontData instance public virtual FontData ReadFont(byte[] fontData) { this.result = new FontData(); this.Data = fontData; ReadTokens(); if (result.Font == null && result.FontFamily == null) { // set default font result.FontFamily = FontFamily.GenericSansSerif; result.Font = new Font(FontFamily.GenericSansSerif, 150); return result; } if (result.Font == null) { try { result.Font = new Font(result.FontFamily, 150); } catch (ArgumentException) { // mostelikely the Regular style is not available, so we have to look which style is available FontStyle fStyle = GetAvailableStyle(result.FontFamily); result.Font = new Font(result.FontFamily, 150, fStyle); } } return result; } /// /// Returns the available Font Style. /// Doesn't include strikethrough and underline, as all fonts support that /// public static FontStyle GetAvailableStyle(FontFamily family) { // To make sure a fontstyle is set that is supported FontStyle fStyle = FontStyle.Regular; if (family.IsStyleAvailable(FontStyle.Bold)) { fStyle += (int)FontStyle.Bold; } else if (family.IsStyleAvailable(FontStyle.Italic)) { fStyle += (int)FontStyle.Italic; } else if (family.IsStyleAvailable(FontStyle.Bold | FontStyle.Italic)) { fStyle = FontStyle.Bold | FontStyle.Italic; } return fStyle; } /// /// Helper method to load font family from a byte array /// /// the byte array with the font data private void LoadFontFamily(byte[] buffer) { string fileName = result.FileName = Path.GetTempFileName(); using (FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.RandomAccess)) { fs.Write(buffer, 0, buffer.Length); } // Create a temp memory collection PrivateFontCollection fontCollection = result.FontCollection = new PrivateFontCollection(); // To hold a reference fontCollection.AddFontFile(fileName); RemoveFontResourceEx(fileName, 16, IntPtr.Zero); // https://stackoverflow.com/questions/26671026/how-to-delete-the-file-of-a-privatefontcollection-addfontfile result.FontFamily = fontCollection.Families[0]; } [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern int RemoveFontResourceEx(string lpszFilename, int fl, IntPtr pdv); } }