From 623d3ca0cbd8fbd38edf31f7cffb089d8ca881b1 Mon Sep 17 00:00:00 2001 From: Michele Date: Tue, 4 Feb 2020 19:27:00 -0800 Subject: [PATCH] Add BFOTF to open dialog Currently it's just a modification of BFTTF.cs, unsure if it's possible to have that file show both formats in the open dialog --- File_Format_Library/FileFormats/Font/BFOTF.cs | 162 ++++++++++++++++++ .../File_Format_Library.csproj | 1 + File_Format_Library/Main.cs | 1 + 3 files changed, 164 insertions(+) create mode 100644 File_Format_Library/FileFormats/Font/BFOTF.cs diff --git a/File_Format_Library/FileFormats/Font/BFOTF.cs b/File_Format_Library/FileFormats/Font/BFOTF.cs new file mode 100644 index 00000000..6c52fcd4 --- /dev/null +++ b/File_Format_Library/FileFormats/Font/BFOTF.cs @@ -0,0 +1,162 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.InteropServices; +using Toolbox; +using System.Windows.Forms; +using Toolbox.Library; +using Toolbox.Library.IO; +using Toolbox.Library.Forms; + +namespace FirstPlugin +{ + public class BFOTF : TreeNodeFile, IFileFormat, IContextMenuNode + { + public FileType FileType { get; set; } = FileType.Font; + + public bool CanSave { get; set; } + public string[] Description { get; set; } = new string[] { "Binary Cafe Open Type Font" }; + public string[] Extension { get; set; } = new string[] { "*.bfotf" }; + public string FileName { get; set; } + public string FilePath { get; set; } + public IFileInfo IFileInfo { get; set; } + + public bool Identify(System.IO.Stream stream) + { + using (var reader = new Toolbox.Library.IO.FileReader(stream, true)) + { + uint magic = reader.ReadUInt32(); + reader.Position = 0; + return magic == 0x1A879BD9 || magic == 0x1E1AF836 || magic == 0xC1DE68F3; + } + } + + public Type[] Types + { + get + { + List types = new List(); + return types.ToArray(); + } + } + + [DllImport("gdi32.dll")] + private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, IntPtr pdv, [In] ref uint pcFonts); + + public byte[] DecryptedFont { get; set; } + + //Decryption process from https://github.com/TheFearsomeDzeraora/BFTTFutil/blob/master/Program.cs + public void Load(System.IO.Stream stream) + { + Text = FileName; + + using (var reader = new FileReader(stream)) + { + uint decryptionKey = 0; + + uint magic = reader.ReadUInt32(); + switch (magic) + { + case 0x1A879BD9: decryptionKey = 2785117442U; break; + case 0x1E1AF836: decryptionKey = 1231165446U; break; + case 0xC1DE68F3: decryptionKey = 2364726489U; break; + default: + Console.WriteLine("Err 0x2: Input file isn't a BFTTF\\BFOTF"); + break; + } + + byte[] inFile = reader.getSection(0, (int)reader.BaseStream.Length); + if (inFile.Length <= 8) return; + uint value = GetUInt32(inFile, 4) ^ decryptionKey; + if (inFile.Length < value) return; + byte[] outFile = new byte[inFile.Length - 8]; + int pos = 8; + while (pos < inFile.Length) + { + SetToUInt32(GetUInt32(inFile, pos) ^ decryptionKey, outFile, pos - 8); + pos += 4; + } + + DecryptedFont = outFile; + } + } + + public ToolStripItem[] GetContextMenuItems() + { + List Items = new List(); + Items.Add(new STToolStipMenuItem("Export", null, ExportAction, Keys.Control | Keys.E)); + return Items.ToArray(); + } + + private void ExportAction(object sender, EventArgs args) + { + SaveFileDialog sfd = new SaveFileDialog(); + sfd.FileName = Text; + sfd.DefaultExt = System.IO.Path.GetExtension(Text); + sfd.Filter = "Open Type Font |*.otf;"; + + if (sfd.ShowDialog() == DialogResult.OK) + { + System.IO.File.WriteAllBytes(sfd.FileName, DecryptedFont); + } + } + + public System.Drawing.Font ToFont(float Size = 72) + { + System.Drawing.Text.PrivateFontCollection privateFonts = new System.Drawing.Text.PrivateFontCollection(); + + // We HAVE to do this to register the font to the system (Weird .NET bug !) + var fontDataPtr = Marshal.AllocCoTaskMem(DecryptedFont.Length); + Marshal.Copy(DecryptedFont, 0, fontDataPtr, DecryptedFont.Length); + + uint cFonts = 0; + AddFontMemResourceEx(fontDataPtr, (uint)DecryptedFont.Length, IntPtr.Zero, ref cFonts); + + privateFonts.AddMemoryFont(fontDataPtr, DecryptedFont.Length); + + return new System.Drawing.Font(privateFonts.Families[0], Size); + } + + public override void OnClick(TreeView treeview) + { + var font = ToFont(); + + var texbox = new RichTextBox() { Multiline = true, BorderStyle = BorderStyle.None, Dock = DockStyle.Fill }; + texbox.BackColor = FormThemes.BaseTheme.FormBackColor; + texbox.ForeColor = FormThemes.BaseTheme.FormForeColor; + + UserControl editor = new UserControl(); + editor.Controls.Add(texbox); + LibraryGUI.LoadEditor(editor); + + editor.Text = Text; + editor.Dock = DockStyle.Fill; + editor.Font = font; + texbox.Text = "Preview Text!"; + } + + private static UInt32 GetUInt32(byte[] data, int pos) + { + return (UInt32)(data[pos + 3] | data[pos + 2] << 8 | data[pos + 1] << 16 | data[pos] << 24); + } + + private static void SetToUInt32(uint val, byte[] data, int pos) + { + data[pos + 3] = (byte)(val & (uint)byte.MaxValue); + data[pos + 2] = (byte)(val >> 8 & (uint)byte.MaxValue); + data[pos + 1] = (byte)(val >> 16 & (uint)byte.MaxValue); + data[pos] = (byte)(val >> 24 & (uint)byte.MaxValue); + } + + public void Unload() + { + DecryptedFont = null; + GC.WaitForPendingFinalizers(); + } + + public void Save(System.IO.Stream stream) + { + } + } +} diff --git a/File_Format_Library/File_Format_Library.csproj b/File_Format_Library/File_Format_Library.csproj index 1940af2c..29b63407 100644 --- a/File_Format_Library/File_Format_Library.csproj +++ b/File_Format_Library/File_Format_Library.csproj @@ -328,6 +328,7 @@ + diff --git a/File_Format_Library/Main.cs b/File_Format_Library/Main.cs index 1f1fca9c..127d5a0a 100644 --- a/File_Format_Library/Main.cs +++ b/File_Format_Library/Main.cs @@ -406,6 +406,7 @@ namespace FirstPlugin Formats.Add(typeof(GCDisk)); Formats.Add(typeof(TPL)); Formats.Add(typeof(BFTTF)); + Formats.Add(typeof(BFOTF)); Formats.Add(typeof(HedgehogLibrary.PACx)); Formats.Add(typeof(BinGzArchive)); Formats.Add(typeof(GAR));