Currently a custom font renderer I’m working on is even with optimizations very slow, so I’m looking for help to find ways to optimize it further. Currently I’m using object pooling and pre-defined variables. So here’s the code and incase you guys can help please tell me. (I know it’s broken, it’ll be fixed by the time you see this post)
local letters = string.split([[0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!№;%:?*()_+-=.,/|"'@#$^&{}[]
]], "")
letters[63] = nil
--print(#letters)
local module = {}
local containers = {}
function module:Unapply(label: TextLabel)
local container = containers[label]
if container then
container:Destroy()
containers[label] = nil
label.MaxVisibleGraphemes = -1
warn("Font unapplied successfully!")
else
warn("Unable to unapply font.")
end
end
function module:Apply(label: TextLabel, font)
local POOLT = {}
local mod = game.ReplicatedStorage.Fonts:FindFirstChild(font)
if not mod then warn("Font not found.") return end
local ancestorGui = label:FindFirstAncestorWhichIsA("ScreenGui")
if not ancestorGui then warn("Label is not a descendant of ScreenGui.") return end
local ignoreGuiInset = ancestorGui.IgnoreGuiInset
local required = require(mod)
local imageId = required[1]
local font = required[2]
local info = font.font.info
local face = info._face
local bold = info._bold
local italic = info._italic
local fontSize = tonumber(info._size) * 1.3
local lineHeight = tonumber(font.font.common._lineHeight)
local imgSize = Vector2.new(
tonumber(font.font.common._scaleH),
tonumber(font.font.common._scaleW)
)
local mul = label.TextSize / fontSize
--warn(mul)
local characters = {}
for i, v in pairs(font.font.chars.char) do
if tonumber(v._id) < 1000 then
local char = string.char(v._id)
local rectoffset = Vector2.new(tonumber(v._x), tonumber(v._y))
local rectsize = Vector2.new(tonumber(v._width), tonumber(v._height))
local offset = Vector2.new(tonumber(v._xoffset), tonumber(v._yoffset))
characters[char] = {rectoffset, rectsize, offset, tonumber(v._xadvance)}
end
end
label.MaxVisibleGraphemes = 0
local gui = game.Players.LocalPlayer.PlayerGui:FindFirstChild("Fontinator_Gui")
if not gui then
gui = Instance.new("ScreenGui", game.Players.LocalPlayer.PlayerGui)
gui.Name = "Fontinator_Gui"
gui.ResetOnSpawn = false
gui.IgnoreGuiInset = true
end
local container = Instance.new("Frame", gui)
container.Name = label.Name .. "_Container"
container.Transparency = 1
container.Active = false
container.Interactable = false
containers[label] = container
local padding = Instance.new("UIPadding", container)
local function write(text: string, isPlaceholder)
--container:ClearAllChildren()
--local list = container:GetChildren()
for i=1, #POOLT do
local c = POOLT[i]
if c:IsA("ImageLabel") then
c.Visible = false
end
end
--local split = string.split(text, "")
local x = 0
local y = 0
local idx = 0
local minX = 0
local minY = 0
local maxX = 0
local maxY = 0
local lastLine = -1
local charss = {}
local pool = 0
local len = #text
--print(len)
local wrapped = label.TextWrapped
local col = label.TextColor3
local transp = label.TextTransparency
local placeholderCol = label.PlaceholderColor3
local cSize = container.AbsoluteSize
for i = 1, len do
local c = text:sub(i,i)
local data = characters[c]
idx += 1
if data and (if (string.byte(c) == 32) then (lastLine ~= (idx-1)) else true) then
pool += 1
local img = POOLT[pool] or Instance.new("ImageLabel", container)
POOLT[pool] = img
img.Visible = true
--if POOLT[pool] then
-- img =
--else
-- img = Instance.new("ImageLabel", container)
-- POOLT[pool] = img
--end
--local
table.insert(charss, img)
img.Image = imageId
img.BackgroundTransparency = 1
img.ImageTransparency = transp
img.ImageColor3 = col
if isPlaceholder then
img.ImageColor3 = placeholderCol
end
img.Position = UDim2.fromOffset(x + (data[3].X * mul), y + (data[3].Y * mul))
img.Size = UDim2.fromOffset(data[4] * mul, data[2].Y * mul)
--print(img.AbsoluteSize)
img.ResampleMode = Enum.ResamplerMode.Pixelated
img.ScaleType = Enum.ScaleType.Fit
img.ImageRectOffset = data[1]
img.ImageRectSize = data[2]
--if idx == #split then
-- --warn("LAST CHARACTER!!!")
-- maxX = (img.AbsolutePosition.X - container.AbsolutePosition.X) + img.AbsoluteSize.X
-- maxY = (img.AbsolutePosition.Y - container.AbsolutePosition.Y) + img.AbsoluteSize.Y
--end
--local wrapped = label.TextWrapped
local iSize = Vector2.new(data[4] * mul, data[2].Y * mul)
--local iSize = img.AbsoluteSize
x += iSize.X
--x += data[4] * mul
--if not then return end
if wrapped and ((x + iSize.X) > cSize.X) then
x = 0
y += lineHeight * mul
lastLine = idx
end
--if label.TextWrapped and ((x > container.AbsoluteSize.X) or ((x + img.AbsoluteSize.X) > container.AbsoluteSize.X)) then
-- x = 0
-- y += lineHeight * mul
-- lastLine = idx
--else
-- x += img.AbsoluteSize.X
--end
else
--warn("unknown character", string.byte(c))
end
--task.wait()
end
--local padding = Instance.new("UIPadding", container)
cSize = container.AbsoluteSize
padding.PaddingTop = UDim.new(0, 0)
padding.PaddingLeft = UDim.new(0, 0)
padding.PaddingBottom = UDim.new(0, 0)
padding.PaddingRight = UDim.new(0, 0)
for i=1, #charss do
local v = charss[i]
if v.Visible then
local x = ((v.AbsolutePosition.X - cSize.X) + v.AbsoluteSize.X)
local y = ((v.AbsolutePosition.Y - cSize.Y) + v.AbsoluteSize.Y)
if x > maxX then
maxX = x
end
if y > maxY then
maxY = y
end
end
end
local s = container.AbsoluteSize
if label.TextYAlignment == Enum.TextYAlignment.Bottom then
padding.PaddingTop = UDim.new(
0,
-(maxY - (s.Y))
)
elseif label.TextYAlignment == Enum.TextYAlignment.Center then
padding.PaddingTop = UDim.new(
0,
-0.5 * (maxY - (s.Y))
)
elseif label.TextYAlignment == Enum.TextYAlignment.Top then
padding.PaddingTop = UDim.new(0, 0)
print("resetting Y")
end
if label.TextXAlignment == Enum.TextXAlignment.Center then
padding.PaddingLeft = UDim.new(
0,
-0.5 * (maxX - (s.X))
)
elseif label.TextXAlignment == Enum.TextXAlignment.Right then
padding.PaddingLeft = UDim.new(
0,
-(maxX - (s.X))
)
elseif label.TextXAlignment == Enum.TextXAlignment.Left then
padding.PaddingLeft = UDim.new(0, 0)
print("resetting X")
end
end
local function update()
mul = label.TextSize / fontSize
local pos = label.AbsolutePosition
local size = label.AbsoluteSize
if ignoreGuiInset then
container.Position = UDim2.fromOffset(pos.X, pos.Y)
else
container.Position = UDim2.fromOffset(pos.X, pos.Y + 58)
end
container.Size = UDim2.fromOffset(size.X, size.Y)
container.Rotation = label.Rotation
container.AnchorPoint = label.AnchorPoint
end
--task.spawn(function()
-- while label.Parent and container.Parent do
-- task.wait()
-- update()
-- end
--end)
update()
if label:IsA("TextBox") then
if #label.Text > 0 then
write(label.Text)
else
write(label.PlaceholderText, true)
end
else
write(label.Text)
end
local changes = {
"TextSize",
"Text",
"TextColor3",
"TextTransparency",
"TextWrapped",
"TextXAlignment",
"TextYAlignment",
"AbsoluteSize",
"AbsolutePosition",
"Rotation",
"AnchorPoint"
}
for i=1, #changes do
local c = changes[i]
label:GetPropertyChangedSignal(c):Connect(function()
update()
if label:IsA("TextBox") then
if #label.Text > 0 then
write(label.Text)
else
write(label.PlaceholderText, true)
end
else
write(label.Text)
end
end)
end
--label.Changed:Connect(function(prop)
-- --print(prop)
-- mul = label.TextSize / fontSize
-- --if prop:find("Absolute") then return end
-- if prop == "Rotation" then return end
-- if prop == "TextBounds" then return end
-- if prop == "TextFits" then return end
-- if prop == "ContentText" then return end
-- if prop == "GuiState" then return end
-- if prop == "UniqueId" then return end
-- if prop == "Name" then return end
-- write(label.Text)
--end)
end
function module:ApplyBillboard()
end
return module
Any help is appreciated!