Created
September 17, 2025 19:24
-
-
Save sn-0w/46baa6db41d2ba76aa255383cbef32db to your computer and use it in GitHub Desktop.
This Lua Script reads out the Font names from all found Font files and displays them in a list ingame so you can preview and select the font you want to use faster!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| local function ReadUShortBE(f) | |
| local b1 = f:ReadByte() or 0 | |
| local b2 = f:ReadByte() or 0 | |
| return b1 * 256 + b2 | |
| end | |
| local function ReadULongBE(f) | |
| local b1 = f:ReadByte() or 0 | |
| local b2 = f:ReadByte() or 0 | |
| local b3 = f:ReadByte() or 0 | |
| local b4 = f:ReadByte() or 0 | |
| return b1 * 16777216 + b2 * 65536 + b3 * 256 + b4 | |
| end | |
| function GetTTFFontName(filepath) | |
| if not file.Exists(filepath, "GAME") then return nil, "File does not exist" end | |
| local f = file.Open(filepath, "rb", "GAME") | |
| if not f then return nil, "Could not open file" end | |
| f:Seek(4) | |
| local numTables = ReadUShortBE(f) | |
| f:Seek(f:Tell() + 6) --we skip searchRange, entrySelector, rangeShift | |
| local nameOffset, nameLength | |
| for i = 1, numTables do | |
| local tag = f:Read(4) | |
| local checkSum = ReadULongBE(f) | |
| local offset = ReadULongBE(f) | |
| local length = ReadULongBE(f) | |
| if tag == "name" then nameOffset, nameLength = offset, length end | |
| end | |
| if not nameOffset then return nil, "No name table" end | |
| f:Seek(nameOffset) | |
| local version = ReadUShortBE(f) | |
| local count = ReadUShortBE(f) | |
| local storageOffset = ReadUShortBE(f) | |
| for i = 1, count do | |
| local platformID = ReadUShortBE(f) | |
| local encodingID = ReadUShortBE(f) | |
| local languageID = ReadUShortBE(f) | |
| local nameID = ReadUShortBE(f) | |
| local length = ReadUShortBE(f) | |
| local stringOffset = ReadUShortBE(f) | |
| if nameID == 4 or nameID == 1 then | |
| local pos = nameOffset + stringOffset + storageOffset | |
| f:Seek(pos) | |
| local raw = f:Read(length) | |
| if platformID == 0 or platformID == 3 then | |
| local out = {} | |
| for j = 1, #raw, 2 do | |
| local hi = raw:byte(j) | |
| local lo = raw:byte(j + 1) | |
| local code = hi * 256 + lo | |
| if code > 0 and code < 128 then table.insert(out, string.char(code)) end | |
| end | |
| return table.concat(out) | |
| else | |
| return raw | |
| end | |
| end | |
| end | |
| return nil, "Font name not found" | |
| end | |
| local function ListFontFiles() | |
| local fonts, _ = file.Find("resource/fonts/*", "GAME") | |
| print("=== Found Font Files ===") | |
| for _, font in ipairs(fonts) do | |
| if string.match(font, "%.ttf$") then | |
| local name, error = GetTTFFontName("resource/fonts/" .. font) | |
| if name then | |
| print(font .. " - " .. name) | |
| else | |
| print(font .. " (Error: " .. (error or "Unknown") .. ")") | |
| end | |
| end | |
| end | |
| end | |
| concommand.Add("list_font_files", ListFontFiles) | |
| local function OpenFontPreviewer() | |
| local frame = vgui.Create("DFrame") | |
| frame:SetSize(600, 800) | |
| frame:Center() | |
| frame:SetTitle("Font Previewer") | |
| frame:MakePopup() | |
| local textEntry = vgui.Create("DTextEntry", frame) | |
| textEntry:Dock(TOP) | |
| textEntry:SetPlaceholderText("Enter text to preview...") | |
| textEntry:SetText("Sample Text") | |
| local scroll = vgui.Create("DScrollPanel", frame) | |
| scroll:Dock(FILL) | |
| local fonts, _ = file.Find("resource/fonts/*", "GAME") | |
| local createdFonts = {} | |
| local function RefreshList() | |
| scroll:Clear() | |
| local displayText = textEntry:GetText() | |
| local addedfonts = {} | |
| for _, font in ipairs(fonts) do | |
| if font:match("%.ttf$") then | |
| local fontName, err = GetTTFFontName("resource/fonts/" .. font) | |
| if fontName and #fontName < 24 and not table.HasValue(addedfonts, fontName) then | |
| table.insert(addedfonts, fontName) | |
| if not createdFonts[fontName] then | |
| surface.CreateFont("Preview_" .. fontName, { | |
| font = fontName, | |
| size = 24, | |
| weight = 500 | |
| }) | |
| createdFonts[fontName] = true | |
| end | |
| local panel = scroll:Add("DButton") | |
| panel:Dock(TOP) | |
| panel:SetTall(40) | |
| panel:SetText("") | |
| panel:DockMargin(0, 0, 0, 4) | |
| panel.Paint = function(self, w, h) | |
| surface.SetFont("Preview_" .. fontName) | |
| surface.SetTextColor(255, 255, 255) | |
| surface.SetTextPos(5, 10) | |
| surface.DrawText(displayText .. " (" .. fontName .. ")") | |
| end | |
| panel.DoClick = function() print("Selected font: " .. fontName) end | |
| else | |
| local label = scroll:Add("DLabel") | |
| label:Dock(TOP) | |
| label:SetTall(20) | |
| label:SetText(font .. " (Error: " .. (err or "Unknown") .. ")") | |
| end | |
| end | |
| end | |
| end | |
| textEntry.OnChange = RefreshList | |
| RefreshList() | |
| end | |
| concommand.Add("open_font_previewer", OpenFontPreviewer) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I also ported
stb_truetype.h(source engine uses this) to Lua a while ago so you can try it out if you want something more than basic font info.https://github.com/GrayWolf64/imgui-lua/blob/main/lua/imstb_truetype.lua
Btw not tested for general use cases but for imgui font system, since GMod
surface.CreateFont()is too limited