Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- USAGE:
- Start a new font:
- makeFont(Font width (number), Font height (number), Font name (string))
- -Makes a new file usable by the texter
- -Sets up the font data used throughout the program
- Make all the letters in a font:
- autoGen()
- GUI Usage:
- Click a pixel to toggle it
- Click outside of the GUI to move to the next character
- At the top-right corner of the GUI, there is:
- a) A display telling you which character you are on, and
- b) A pixel preview of your letter at a 1:1 scale.
- To exit the GUI before you have completed your font:
- Type 'done()' into the console. It will exit the GUI, finish your font, and write it to a file.
- ]]
- -- Make a matrix of all the characters
- local charchart = {}
- -- Make the file opened wit makeFont visible to other functions that need it
- local f
- -- Set up the info needed to make a font file
- function makeFont(w, h, name)
- -- Globally visible metrics data
- ftf_w = w
- ftf_h = h
- -- Globally visible font name
- ftf_name = name
- -- Generic character header - 'char' will be replaced by the character name,
- -- and '_KERN' with the kerning data. 'texter_font' is replaced by the font
- -- name.
- charStr = ({string.gsub([[
- texter_font[char] = {
- ['descender'] = -2,
- ['kerning'] = _KERN,
- ['pixels'] = {
- ]], 'texter_font', name)})[1]
- f = io.open(name .. '.txt', 'w')
- -- Write the font header - '_NAME' is replaced by the font name, '_W is
- -- replaced by the default character width (when kerning is set to 0), and
- -- '_H' is replaced with the font height.
- f:write(tostring(({string.gsub(string.gsub(string.gsub([[
- _NAME = {}
- _NAME['width'] = _W
- _NAME['height'] = _H
- ]], '_NAME', name), '_W', w), '_H', h)})[1]))
- end
- -- Takes a table returned by the GUI and converts it to readable character data
- local function makeLetterFromGui(char, currentfont_pixels)
- -- Kerning data
- local kern, doBreak
- -- Calculate the kerning for the character
- for x = 0, ftf_w - 1 do
- for y = 1, ftf_h do
- if currentfont_pixels[y][ftf_w - x - 1] == 1 then
- kern = -x
- doBreak = true -- Break out of for loops?
- break
- end
- if doBreak == true then
- break
- end
- end
- if doBreak == true then
- break
- end
- end
- -- Default kerning to 0
- if not kern then kern = 0 end
- -- Replace the '_KERN' in the character header with real kerning data
- local charStr = ({string.gsub(charStr, '_KERN', kern)})[1]
- -- Replace the 'char' in the character header with the character name and write it
- f:write(({string.gsub(charStr, 'char', string.format('%q', char))})[1])
- for y = 1, ftf_h + 2 do
- for x = 1, ftf_w do
- -- Writing font data to the file
- if x == 1 then
- -- First pixel in a row
- f:write('\t\t{', currentfont_pixels[y][x] and tostring(currentfont_pixels[y][x]) or '0', ', ')
- elseif x == ftf_w then
- -- Last pixel
- if y == ftf_h + 2 then
- f:write('\n')
- -- Other edge pixels
- else
- f:write(',\n')
- end
- else
- -- All the other pixels
- f:write(currentfont_pixels[y][x] and tostring(currentfont_pixels[y][x]) or '0', ', ')
- end
- end
- end
- -- Close off the character data
- f:write('\t}\n}\n')
- end
- -- Autopilot Character Set
- local charstr = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~`!@#$%^&*()-_=+[{]}\\|;:\'",<.>/?'
- -- Current character in the autopilot
- local n = 0
- -- GUI Stopper
- local endMatGet
- -- Weird bugfix, if you delete this, it breaks, but I have no idea why.
- local getmcoords, rectSetGui, rectDrawGui, testForEnd
- -- The GUI!
- function autoGen()
- n = n + 1
- -- Current character
- local char = string.sub(charstr, n, n)
- -- Width and height data
- local w, h = ftf_w, ftf_h + 2
- -- Distance between rectangles
- local rstep = 340 / h
- -- Size of rectangles
- local wsize = w * rstep
- -- Character data table
- local mat = {}
- -- Make the character data table 2-D
- for k = 1, h + 2 do
- mat[k] = {}
- end
- -- Predefine the mouse coords - I don't know why, but sometimes they don't get defined
- local rectInMX, rectInMY = 1, 1
- -- Calculate which box the cursor is on
- function getmcoords()
- rectInMX = math.floor((tpt.mousex + rstep) / rstep) - 1
- rectInMY = math.floor((tpt.mousey + rstep) / rstep) - 1
- end
- tpt.register_step(getmcoords)
- -- Variable, not important
- -- Modify the table as you click!
- function rectSetGui(x, y, button, event)
- if event == 2 then
- if mat[rectInMY][rectInMX] ~= 1 then
- mat[rectInMY][rectInMX] = 1
- else
- mat[rectInMY][rectInMX] = 0
- end
- -- Stop the GUI if you click outside the character map
- if rectInMX > w or rectInMY > h then endMatGet = true end
- end
- return false
- end
- tpt.register_mouseclick(rectSetGui)
- -- Draw the GUI itself
- function rectDrawGui()
- for y = 1, h do
- for x = 1, w do
- -- Drawing rectangles, boring stuff
- tpt.drawrect(x * rstep, y * rstep, rstep - 2, rstep - 2, 255, 255, 255, 255)
- tpt.fillrect(rectInMX * rstep, rectInMY * rstep, rstep - 2, rstep - 2, 75, 75, 75)
- -- Draw the current character
- if mat[y][x] == 1 then
- tpt.fillrect(x * rstep, y * rstep, rstep - 2, rstep - 2, 125, 125, 125)
- -- Pixel Preview
- tpt.drawpixel(w * rstep + rstep + 2 + x, 46 + y, 255, 255, 255, 255)
- end
- end
- end
- -- Tell the user which character they are drawing
- tpt.drawtext(w * rstep + rstep + 2, 38, 'Current character: ' .. char, 255, 255, 0, 255)
- end
- tpt.register_step(rectDrawGui)
- -- Check whether the program should be stopping
- function testForEnd()
- if endMatGet then
- -- Stop all the GUI stuff
- tpt.unregister_step(getmcoords)
- tpt.unregister_step(rectDrawGui)
- tpt.unregister_mouseclick(rectSetGui)
- -- Save the current character unless done() has closed the file
- if endMatGet ~= 'DONE' then
- makeLetterFromGui(string.sub(charstr, n, n), mat)
- end
- -- Recurse until it reaches the end of the character list or until done() is called
- if n <= #charstr and endMatGet ~= 'DONE' then
- autoGen()
- endMatGet = nil
- end
- end
- end
- tpt.register_step(testForEnd)
- end
- -- Finish up the font and write it
- function done()
- -- Write the NULL character, it can break without it
- f:write('\n' .. ftf_name .. [[['NULL'] = {
- ['descender'] = 0,
- ['kerning'] = 0,
- ['pixels'] = {
- {1, 1, 1, 1, 1},
- {1, 0, 0, 1, 1},
- {1, 1, 1, 0, 1},
- {1, 1, 0, 1, 1},
- {1, 1, 1, 1, 1},
- {1, 1, 0, 1, 1},
- {1, 1, 1, 1, 1},
- {0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0}
- }
- }]])
- -- Stop the GUI
- endMatGet = 'DONE'
- tpt.unregister_step(testForEnd)
- -- Close the file
- f:close()
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement