From 10838f33a9c7f7f68a7b54704d42e5b29f8284a2 Mon Sep 17 00:00:00 2001
From: NinjaPug <36635276+programmingPug@users.noreply.github.com>
Date: Fri, 4 Apr 2025 19:26:10 -0400
Subject: [PATCH] Initial upload of project
---
.gitignore | 3 +
FontGlyphExporter.csproj | 8 ++
FontGlyphExporter.sln | 25 ++++
MainForm.Designer.cs | 191 +++++++++++++++++++++++++
MainForm.cs | 291 +++++++++++++++++++++++++++++++++++++++
Program.cs | 16 +++
readme.md | 120 ++++++++++++++++
7 files changed, 654 insertions(+)
create mode 100644 .gitignore
create mode 100644 FontGlyphExporter.csproj
create mode 100644 FontGlyphExporter.sln
create mode 100644 MainForm.Designer.cs
create mode 100644 MainForm.cs
create mode 100644 Program.cs
create mode 100644 readme.md
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7a848e2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+/bin
+/obj
+/.vs
diff --git a/FontGlyphExporter.csproj b/FontGlyphExporter.csproj
new file mode 100644
index 0000000..4eb9ee6
--- /dev/null
+++ b/FontGlyphExporter.csproj
@@ -0,0 +1,8 @@
+
+
+
+ WinExe
+ net6.0-windows
+ true
+
+
diff --git a/FontGlyphExporter.sln b/FontGlyphExporter.sln
new file mode 100644
index 0000000..ffc3f54
--- /dev/null
+++ b/FontGlyphExporter.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.13.35828.75 d17.13
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FontGlyphExporter", "FontGlyphExporter.csproj", "{2E8081B2-DFAC-3227-72D0-366CF7F45501}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2E8081B2-DFAC-3227-72D0-366CF7F45501}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2E8081B2-DFAC-3227-72D0-366CF7F45501}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2E8081B2-DFAC-3227-72D0-366CF7F45501}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2E8081B2-DFAC-3227-72D0-366CF7F45501}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {17BAE8BB-58F1-4268-9740-4AA4ACE38243}
+ EndGlobalSection
+EndGlobal
diff --git a/MainForm.Designer.cs b/MainForm.Designer.cs
new file mode 100644
index 0000000..055fef6
--- /dev/null
+++ b/MainForm.Designer.cs
@@ -0,0 +1,191 @@
+namespace FontGlyphExporter
+{
+ partial class MainForm
+ {
+ private System.ComponentModel.IContainer components = null;
+ private System.Windows.Forms.TextBox txtTTF;
+ private System.Windows.Forms.TextBox txtCSS;
+ private System.Windows.Forms.Button btnBrowseTTF;
+ private System.Windows.Forms.Button btnBrowseCSS;
+ private System.Windows.Forms.Button btnLoad;
+ private System.Windows.Forms.Button btnExport;
+ private System.Windows.Forms.FlowLayoutPanel iconFlowPanel;
+ private System.Windows.Forms.Label lblCounter;
+ private System.Windows.Forms.ComboBox cboRegexPattern;
+ private System.Windows.Forms.Label lblRegexPattern;
+ private System.Windows.Forms.TextBox txtCustomRegex;
+ private System.Windows.Forms.Label lblCustomRegex;
+ private System.Windows.Forms.Panel pnlSizes;
+ private System.Windows.Forms.Label lblSizes;
+ private System.Windows.Forms.CheckBox chkSize4;
+ private System.Windows.Forms.CheckBox chkSize8;
+ private System.Windows.Forms.CheckBox chkSize12;
+ private System.Windows.Forms.CheckBox chkSize24;
+ private System.Windows.Forms.Label lblSelectedSizes;
+
+ private void InitializeComponent()
+ {
+ this.txtTTF = new System.Windows.Forms.TextBox();
+ this.txtCSS = new System.Windows.Forms.TextBox();
+ this.btnBrowseTTF = new System.Windows.Forms.Button();
+ this.btnBrowseCSS = new System.Windows.Forms.Button();
+ this.btnLoad = new System.Windows.Forms.Button();
+ this.btnExport = new System.Windows.Forms.Button();
+ this.lblCounter = new System.Windows.Forms.Label();
+ this.iconFlowPanel = new System.Windows.Forms.FlowLayoutPanel();
+ this.cboRegexPattern = new System.Windows.Forms.ComboBox();
+ this.lblRegexPattern = new System.Windows.Forms.Label();
+ this.txtCustomRegex = new System.Windows.Forms.TextBox();
+ this.lblCustomRegex = new System.Windows.Forms.Label();
+ this.pnlSizes = new System.Windows.Forms.Panel();
+ this.lblSizes = new System.Windows.Forms.Label();
+ this.chkSize4 = new System.Windows.Forms.CheckBox();
+ this.chkSize8 = new System.Windows.Forms.CheckBox();
+ this.chkSize12 = new System.Windows.Forms.CheckBox();
+ this.chkSize24 = new System.Windows.Forms.CheckBox();
+ this.lblSelectedSizes = new System.Windows.Forms.Label();
+ this.pnlSizes.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // txtTTF
+ this.txtTTF.Location = new System.Drawing.Point(12, 12);
+ this.txtTTF.Size = new System.Drawing.Size(400, 23);
+ //
+ // btnBrowseTTF
+ this.btnBrowseTTF.Location = new System.Drawing.Point(418, 12);
+ this.btnBrowseTTF.Size = new System.Drawing.Size(100, 23);
+ this.btnBrowseTTF.Text = "Browse TTF";
+ this.btnBrowseTTF.Click += new System.EventHandler(this.btnBrowseTTF_Click);
+ //
+ // txtCSS
+ this.txtCSS.Location = new System.Drawing.Point(12, 41);
+ this.txtCSS.Size = new System.Drawing.Size(400, 23);
+ //
+ // btnBrowseCSS
+ this.btnBrowseCSS.Location = new System.Drawing.Point(418, 41);
+ this.btnBrowseCSS.Size = new System.Drawing.Size(100, 23);
+ this.btnBrowseCSS.Text = "Browse CSS";
+ this.btnBrowseCSS.Click += new System.EventHandler(this.btnBrowseCSS_Click);
+ //
+ // lblRegexPattern
+ this.lblRegexPattern.Location = new System.Drawing.Point(540, 12);
+ this.lblRegexPattern.Size = new System.Drawing.Size(80, 23);
+ this.lblRegexPattern.Text = "Regex Pattern:";
+ this.lblRegexPattern.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // cboRegexPattern
+ this.cboRegexPattern.Location = new System.Drawing.Point(625, 12);
+ this.cboRegexPattern.Size = new System.Drawing.Size(150, 23);
+ this.cboRegexPattern.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cboRegexPattern.Items.AddRange(new object[] {
+ "Font Awesome 5/6",
+ "Font Awesome 4",
+ "Material Icons",
+ "Custom"
+ });
+ this.cboRegexPattern.SelectedIndexChanged += new System.EventHandler(this.cboRegexPattern_SelectedIndexChanged);
+ //
+ // lblCustomRegex
+ this.lblCustomRegex.Location = new System.Drawing.Point(540, 41);
+ this.lblCustomRegex.Size = new System.Drawing.Size(80, 23);
+ this.lblCustomRegex.Text = "Custom Regex:";
+ this.lblCustomRegex.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.lblCustomRegex.Visible = false;
+ //
+ // txtCustomRegex
+ this.txtCustomRegex.Location = new System.Drawing.Point(625, 41);
+ this.txtCustomRegex.Size = new System.Drawing.Size(150, 23);
+ this.txtCustomRegex.Visible = false;
+ //
+ // lblSizes
+ this.lblSizes.Location = new System.Drawing.Point(418, 70);
+ this.lblSizes.Size = new System.Drawing.Size(100, 23);
+ this.lblSizes.Text = "Export Sizes:";
+ this.lblSizes.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // pnlSizes
+ this.pnlSizes.Location = new System.Drawing.Point(520, 70);
+ this.pnlSizes.Size = new System.Drawing.Size(255, 25);
+ //
+ // chkSize4
+ this.chkSize4.Location = new System.Drawing.Point(5, 3);
+ this.chkSize4.Size = new System.Drawing.Size(50, 20);
+ this.chkSize4.Text = "4x4";
+ this.chkSize4.CheckedChanged += new System.EventHandler(this.sizeCheckbox_CheckedChanged);
+ this.pnlSizes.Controls.Add(this.chkSize4);
+ //
+ // chkSize8
+ this.chkSize8.Location = new System.Drawing.Point(65, 3);
+ this.chkSize8.Size = new System.Drawing.Size(50, 20);
+ this.chkSize8.Text = "8x8";
+ this.chkSize8.CheckedChanged += new System.EventHandler(this.sizeCheckbox_CheckedChanged);
+ this.pnlSizes.Controls.Add(this.chkSize8);
+ //
+ // chkSize12
+ this.chkSize12.Location = new System.Drawing.Point(125, 3);
+ this.chkSize12.Size = new System.Drawing.Size(60, 20);
+ this.chkSize12.Text = "12x12";
+ this.chkSize12.CheckedChanged += new System.EventHandler(this.sizeCheckbox_CheckedChanged);
+ this.pnlSizes.Controls.Add(this.chkSize12);
+ //
+ // chkSize24
+ this.chkSize24.Location = new System.Drawing.Point(195, 3);
+ this.chkSize24.Size = new System.Drawing.Size(60, 20);
+ this.chkSize24.Text = "24x24";
+ this.chkSize24.CheckedChanged += new System.EventHandler(this.sizeCheckbox_CheckedChanged);
+ this.pnlSizes.Controls.Add(this.chkSize24);
+ //
+ // lblSelectedSizes
+ this.lblSelectedSizes.Location = new System.Drawing.Point(520, 95);
+ this.lblSelectedSizes.Size = new System.Drawing.Size(255, 15);
+ this.lblSelectedSizes.Text = "Selected sizes: 12, 24px";
+ //
+ // btnLoad
+ this.btnLoad.Location = new System.Drawing.Point(12, 70);
+ this.btnLoad.Size = new System.Drawing.Size(100, 23);
+ this.btnLoad.Text = "Load Icons";
+ this.btnLoad.Click += new System.EventHandler(this.btnLoad_Click);
+ //
+ // btnExport
+ this.btnExport.Location = new System.Drawing.Point(118, 70);
+ this.btnExport.Size = new System.Drawing.Size(120, 23);
+ this.btnExport.Text = "Export Selected";
+ this.btnExport.Click += new System.EventHandler(this.btnExport_Click);
+ //
+ // lblCounter
+ this.lblCounter.Location = new System.Drawing.Point(250, 70);
+ this.lblCounter.Size = new System.Drawing.Size(150, 23);
+ this.lblCounter.Text = "Selected: 0 / 0";
+ //
+ // iconFlowPanel
+ this.iconFlowPanel.Location = new System.Drawing.Point(12, 120);
+ this.iconFlowPanel.Size = new System.Drawing.Size(760, 430);
+ this.iconFlowPanel.AutoScroll = true;
+ this.iconFlowPanel.WrapContents = true;
+ this.iconFlowPanel.FlowDirection = System.Windows.Forms.FlowDirection.LeftToRight;
+ //
+ // MainForm
+ this.ClientSize = new System.Drawing.Size(784, 561);
+ this.Controls.Add(this.txtTTF);
+ this.Controls.Add(this.btnBrowseTTF);
+ this.Controls.Add(this.txtCSS);
+ this.Controls.Add(this.btnBrowseCSS);
+ this.Controls.Add(this.lblRegexPattern);
+ this.Controls.Add(this.cboRegexPattern);
+ this.Controls.Add(this.lblCustomRegex);
+ this.Controls.Add(this.txtCustomRegex);
+ this.Controls.Add(this.lblSizes);
+ this.Controls.Add(this.pnlSizes);
+ this.Controls.Add(this.lblSelectedSizes);
+ this.Controls.Add(this.btnLoad);
+ this.Controls.Add(this.btnExport);
+ this.Controls.Add(this.lblCounter);
+ this.Controls.Add(this.iconFlowPanel);
+ this.Name = "MainForm";
+ this.Text = "Font Awesome Icon Exporter";
+ this.pnlSizes.ResumeLayout(false);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+ }
+ }
+}
\ No newline at end of file
diff --git a/MainForm.cs b/MainForm.cs
new file mode 100644
index 0000000..8f032df
--- /dev/null
+++ b/MainForm.cs
@@ -0,0 +1,291 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Text;
+using System.IO;
+using System.Text.Json;
+using System.Text.RegularExpressions;
+using System.Windows.Forms;
+
+namespace FontGlyphExporter
+{
+ public partial class MainForm : Form
+ {
+ private string fontPath = "";
+ private string cssPath = "";
+ private List allIcons = new();
+ private List selectedIcons = new();
+ private PrivateFontCollection fontCollection = new();
+ private Font font;
+ private Dictionary regexPatterns = new();
+ private List selectedSizes = new();
+
+ public MainForm()
+ {
+ InitializeComponent();
+ InitializeRegexPatterns();
+ InitializeSizeCheckboxes();
+ cboRegexPattern.SelectedIndex = 0;
+ }
+
+ private void InitializeRegexPatterns()
+ {
+ regexPatterns.Add("Font Awesome 5/6", @"\.fa-([a-z0-9-]+)\s*{[^}]*--fa:\s*""\\(f[a-f0-9]{3,4})""");
+ regexPatterns.Add("Font Awesome 4", @"\.fa-([a-z0-9-]+):before\s*{[^}]*content:\s*""\\(f[a-f0-9]{3,4})""");
+ regexPatterns.Add("Material Icons", @"\.material-icons-([a-z0-9-]+):before\s*{[^}]*content:\s*""\\(e[a-f0-9]{3,4})""");
+ regexPatterns.Add("Custom", "");
+ }
+
+ private void InitializeSizeCheckboxes()
+ {
+ chkSize4.Tag = 4;
+ chkSize8.Tag = 8;
+ chkSize12.Tag = 12;
+ chkSize24.Tag = 24;
+
+ // Default selection
+ chkSize12.Checked = true;
+ chkSize24.Checked = true;
+ UpdateSelectedSizes();
+ }
+
+ private void UpdateSelectedSizes()
+ {
+ selectedSizes.Clear();
+
+ foreach (Control c in pnlSizes.Controls)
+ {
+ if (c is CheckBox chk && chk.Checked && chk.Tag is int size)
+ {
+ selectedSizes.Add(size);
+ }
+ }
+
+ // Update the selected sizes label
+ lblSelectedSizes.Text = selectedSizes.Count > 0
+ ? $"Selected sizes: {string.Join(", ", selectedSizes)}px"
+ : "No sizes selected";
+ }
+
+ private void btnBrowseTTF_Click(object sender, EventArgs e)
+ {
+ using OpenFileDialog ofd = new() { Filter = "Font Files (*.ttf)|*.ttf" };
+ if (ofd.ShowDialog() == DialogResult.OK)
+ {
+ fontPath = ofd.FileName;
+ txtTTF.Text = fontPath;
+ }
+ }
+
+ private void btnBrowseCSS_Click(object sender, EventArgs e)
+ {
+ using OpenFileDialog ofd = new() { Filter = "CSS Files (*.css)|*.css" };
+ if (ofd.ShowDialog() == DialogResult.OK)
+ {
+ cssPath = ofd.FileName;
+ txtCSS.Text = cssPath;
+ }
+ }
+
+ private void btnLoad_Click(object sender, EventArgs e)
+ {
+ if (!File.Exists(fontPath) || !File.Exists(cssPath))
+ {
+ MessageBox.Show("Please select valid CSS and TTF files.");
+ return;
+ }
+
+ fontCollection = new PrivateFontCollection();
+ fontCollection.AddFontFile(fontPath);
+ font = new Font(fontCollection.Families[0], 16);
+
+ string css = File.ReadAllText(cssPath);
+ string patternToUse;
+
+ if (cboRegexPattern.SelectedItem.ToString() == "Custom")
+ {
+ patternToUse = txtCustomRegex.Text;
+ if (string.IsNullOrWhiteSpace(patternToUse))
+ {
+ MessageBox.Show("Please enter a valid regex pattern.");
+ return;
+ }
+ }
+ else
+ {
+ patternToUse = regexPatterns[cboRegexPattern.SelectedItem.ToString()];
+ }
+
+ try
+ {
+ var matches = Regex.Matches(css, patternToUse, RegexOptions.IgnoreCase);
+
+ allIcons.Clear();
+ foreach (Match match in matches)
+ {
+ if (match.Groups.Count < 3) continue;
+ string name = match.Groups[1].Value;
+ string unicode = match.Groups[2].Value;
+ allIcons.Add(new IconInfo { name = name, unicode = unicode });
+ }
+
+ if (allIcons.Count == 0)
+ {
+ MessageBox.Show("No icons found with the selected pattern. Try a different pattern or check your CSS file.");
+ return;
+ }
+
+ PopulateGrid();
+ }
+ catch (ArgumentException ex)
+ {
+ MessageBox.Show($"Invalid regex pattern: {ex.Message}");
+ }
+ }
+
+ private void PopulateGrid()
+ {
+ iconFlowPanel.Controls.Clear();
+ selectedIcons.Clear();
+ UpdateCounter();
+
+ foreach (var icon in allIcons)
+ {
+ var panel = new Panel
+ {
+ Width = 80,
+ Height = 100,
+ Margin = new Padding(5),
+ BorderStyle = BorderStyle.FixedSingle,
+ Tag = icon
+ };
+
+ var bmp = new Bitmap(48, 48);
+ using (Graphics g = Graphics.FromImage(bmp))
+ {
+ g.Clear(Color.White);
+ g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
+ string glyph = char.ConvertFromUtf32(Convert.ToInt32(icon.unicode, 16));
+ g.DrawString(glyph, font, Brushes.Black, 0, 0);
+ }
+
+ var pic = new PictureBox
+ {
+ Image = bmp,
+ SizeMode = PictureBoxSizeMode.CenterImage,
+ Width = 48,
+ Height = 48,
+ Top = 5,
+ Left = 15
+ };
+
+ var lbl = new Label
+ {
+ Text = icon.name,
+ Width = 70,
+ Top = 60,
+ Left = 5,
+ TextAlign = ContentAlignment.MiddleCenter
+ };
+
+ panel.Controls.Add(pic);
+ panel.Controls.Add(lbl);
+
+ panel.Click += (s, e) =>
+ {
+ if (selectedIcons.Contains(icon))
+ {
+ selectedIcons.Remove(icon);
+ panel.BackColor = SystemColors.Control;
+ }
+ else
+ {
+ selectedIcons.Add(icon);
+ panel.BackColor = Color.LightBlue;
+ }
+ UpdateCounter();
+ };
+
+ iconFlowPanel.Controls.Add(panel);
+ }
+ }
+
+ private void UpdateCounter()
+ {
+ lblCounter.Text = $"Selected: {selectedIcons.Count} / {allIcons.Count}";
+ }
+
+ private void btnExport_Click(object sender, EventArgs e)
+ {
+ if (selectedIcons.Count == 0)
+ {
+ MessageBox.Show("Please select at least one icon to export.");
+ return;
+ }
+
+ if (selectedSizes.Count == 0)
+ {
+ MessageBox.Show("Please select at least one size for export.");
+ return;
+ }
+
+ var icons = new List