Only "A...Z" and "0..9" created, "a..z" is more challenging.
Code:
Code: Select all
#include "fbgfx.bi"
const SW = 800, SH = 600 'screen size
'https://www.freebasic.net/forum/viewtopic.php?p=281975
'bresenham line + circle
sub thick_line_circle(x0 As Long, y0 As Long, x1 As Long, y1 As Long, _
thickness as Long, _color as ULong, pImage as FB.Image ptr)
'
Dim As Long dx = Abs(x1 - x0), dy = Abs(y1 - y0)
Dim As Long sx = IIf(x0 < x1, 1, -1)
Dim As Long sy = IIf(y0 < y1, 1, -1)
Dim As Long er = IIf(dx > dy, dx, -dy) \ 2, e2
dim as Long radius
radius = thickness \ 2
if thickness <= 0 then exit sub
if radius > 0 then
Do
circle pImage, (x0, y0), radius, _color,, , ,F
If (x0 = x1) And (y0 = y1) Then Exit Do
e2 = er
If e2 > -dx Then Er -= dy : x0 += sx
If e2 < dy Then Er += dx : y0 += sy
Loop
else
line(x0, y0)-(x1, y1), _color
end if
End Sub
'-------------------------------------------------------------------------------
#define isz integer
#define i32 long
#define u32 ulong
#define f32 single
#define f64 double
'-------------------------------------------------------------------------------
function isDigitChar(charval as isz) as boolean
if charval < asc("0") then return false
if charval > asc("9") then return false
return true
end function
function isLetterChar(charval as isz) as boolean
if charval >= asc("A") and charval <= asc("Z") then return true
if charval >= asc("a") and charval <= asc("z") then return true
if charval >= asc("_") then return true
return false
end function
'startPos: 0+
function getIntvalInstr(text as string, searchPos as isz) as isz
dim as isz strLen = len(text)
if searchPos < 0 then return -1 'not good
if searchPos > strLen - 1 then return -2 'not good
'search value start
dim as isz startPos = -1
for i as isz = searchPos to strLen - 1
if isDigitChar(text[i]) = true then startPos = i : exit for
next
if startPos = -1 then return -3 'not good
'search for first non-value char
dim as isz endPos = strLen
for i as isz = startPos to strLen - 1
if isDigitChar(text[i]) = false then endPos = i : exit for
next
'print endPos, startPos, endPos - startPos
return valint(mid(text, startPos + 1, endPos - startPos))
end function
'value as string, set searchPos for next call
'add -/+/. formats
function getValInstr(text as string, byref valStr as string, byref searchPos as isz) as isz
dim as isz strLen = len(text)
if searchPos < 0 then return -1 'not good
if searchPos > strLen - 1 then return -1 'not good
'search value start
dim as isz startPos = -1
for i as isz = searchPos to strLen - 1
if isDigitChar(text[i]) = true then startPos = i : exit for
next
if startPos = -1 then return -1 'not good
'search for first non-value char
dim as isz endPos = strLen
for i as isz = startPos to strLen - 1
if isDigitChar(text[i]) = false then endPos = i : exit for
next
'print endPos, startPos, endPos - startPos
valStr = mid(text, startPos + 1, endPos - startPos)
searchPos = endPos
return 0 'ok
end function
'-------------------------------------------------------------------------------
type config_file_type
dim as string fileName = ""
dim as string fileData(any)
dim as isz lastLine = -1, lastCol = -1
'dim as string labelStr
'functions
declare function loadFile(fileName_ as string) as isz
declare sub printContents()
declare function getIntValueForLabel(varLabel as string, byref retVal as i32) as isz
declare function findLabel(varLabel as string) as isz
declare function getIntValue(byref retVal as i32) as isz
end type
'read contents line by line into data buffer
function config_file_type.loadFile(fileName_ as string) as isz
dim as i32 fileNum = freefile()
dim as string text
if open(fileName_ for input as #1) <> 0 then
print "Error opening: " & fileName_
return -1
else
fileName = fileName_
while not eof(fileNum)
line input #fileNum, text
dim as isz ub = ubound(fileData)
redim preserve fileData(ub + 1)
fileData(ub + 1) = text
wend
close fileNum
end if
return 0 'ok
end function
sub config_file_type.printContents()
for i as isz = 0 to ubound(fileData)
print fileData(i)
next
end sub
'todo: add negative numbers
'no white space alowed before label
'cal again for next line
'case sensitive !
function config_file_type.getIntValueForLabel(varLabel as string, byref retVal as i32) as isz
lastLine += 1
for i as isz = lastLine to ubound(fileData)
dim as isz searchPos = instr(fileData(i), varLabel)
if searchPos = 1 then 'at start of line
'check next char is a non-letter
if isLetterChar(asc(mid(fileData(i), 1 + len(varLabel), 1))) = false then
'label found, get value
retVal = getIntvalInstr(fileData(i), searchPos)
lastLine = i 'for next search
return 0 'ok
end if
end if
next
'lastLine = -1 'reset search
return -1
end function
'find label, set row & col position
function config_file_type.findLabel(varLabel as string) as isz
lastLine += 1
for i as isz = lastLine to ubound(fileData)
dim as isz searchPos = instr(fileData(i), varLabel)
if searchPos = 1 then 'at start of line
'check next char is a non-letter
if isLetterChar(asc(mid(fileData(i), 1 + len(varLabel), 1))) = false then
'label found, save line pos
lastLine = i 'for next search
'go to first non-letter and save col pos
dim as integer col = 1 + len(varLabel)
while isLetterChar(fileData(i)[col])
col += 1
wend
lastCol = col
return 0 'ok
end if
end if
next
'lastLine = 0 'reset search
return -1
end function
'call after findLabel() or previous getIntValue()
function config_file_type.getIntValue(byref retVal as i32) as isz
dim as string retStr
if getValInstr(fileData(lastLine), retStr, lastCol) = 0 then
retVal = valInt(retStr)
return 0
end if
return -1 'not found
end function
'-------------------------------------------------------------------------------
type i32_xy
dim as i32 x, y
end type
type segment_type 'line
dim as i32_xy p(0 to 1)
end type
type char_type
dim as i32 charCode
dim as i32_xy charSize
dim as i32 numSegment
dim as segment_type segment(any)
declare sub printInfo()
declare sub addSegment(segment_ as segment_type)
declare sub draw_(x as i32, y as i32, scale as f64, c as u32)
end type
sub char_type.printInfo()
print "charCode: " & charCode
print "charSize: " & charSize.x & ", " & charSize.y
print "numSegment: " & numSegment
for i as isz = 0 to ubound(segment)
with segment(i)
print "line: " & .p(0).x & ", " & .p(0).y & " - " & .p(1).x & ", " & .p(1).y
end with
next
end sub
sub char_type.addSegment(segment_ as segment_type)
dim as isz ub = ubound(segment)
redim preserve segment(ub + 1)
segment(ub + 1) = segment_
end sub
sub char_type.draw_(x as i32, y as i32, scale as f64, c as u32)
for i as isz = 0 to ubound(segment)
dim as isz x0 = segment(i).p(0).x * scale + x
dim as isz y0 = segment(i).p(0).y * scale + y
dim as isz x1 = segment(i).p(1).x * scale + x
dim as isz y1 = segment(i).p(1).y * scale + y
'line(x0, SH - y0)-(x1, SH - y1), c
thick_line_circle(x0, SH - y0, x1, SH - y1, 6, c, 0)
next
end sub
'-------------------------------------------------------------------------------
function readChar(cfgFile as config_file_type, tface as char_type) as isz
if cfgFile.findLabel("charcode") <> 0 then return -1
if cfgFile.getIntValue(tface.charCode) <> 0 then return -1
if cfgFile.findLabel("charsize") <> 0 then return -1
if cfgFile.getIntValue(tface.charSize.x) <> 0 then return -1
if cfgFile.getIntValue(tface.charSize.y) <> 0 then return -1
if cfgFile.findLabel("numline") <> 0 then return -1
if cfgFile.getIntValue(tface.numSegment) <> 0 then return -1
for i as isz = 0 to tface.numSegment - 1
dim as segment_type segment
if cfgFile.findLabel("line") <> 0 then return -1
'read first point
dim as i32 x0, y0, x1, y1
if cfgFile.getIntValue(x0) <> 0 then return -1
if cfgFile.getIntValue(y0) <> 0 then return -1
'read next
while true
if cfgFile.getIntValue(x1) <> 0 then exit while
if cfgFile.getIntValue(y1) <> 0 then exit while
segment.p(0) = type(x0, y0)
segment.p(1) = type(x1, y1)
tface.addSegment(segment)
x0 = x1
y0 = y1
wend
'if cfgFile.getIntValue(segment.p(0).x) <> 0 then return -1
'if cfgFile.getIntValue(segment.p(0).y) <> 0 then return -1
'if cfgFile.getIntValue(segment.p(1).x) <> 0 then return -1
'if cfgFile.getIntValue(segment.p(1).y) <> 0 then return -1
'tface.addSegment(segment)
next
return 0 'ok
end function
'-------------------------------------------------------------------------------
'const N_CHAR = 2
const W_CHAR = 5, H_CHAR = 7
type tf_type 'type face
dim as char_type char(any)
dim as i32 charmap(0 to 255)
dim as i32 numChar
declare function init(cfgFile as config_file_type) as isz
declare sub print_(x as i32, y as i32, text as string, scale as f64)
end type
function tf_type.init(cfgFile as config_file_type) as isz
if cfgFile.findLabel("numchar") <> 0 then return -1
if cfgFile.getIntValue(numChar) <> 0 then return -1
redim char(numChar - 1)
for i as isz = 0 to ubound(char)
if readChar(cfgFile, char(i)) <> 0 then return -1
char(i).printInfo()
charmap(char(i).charCode) = i 'tf.charmap(asc("A")) = 0
next
return 0
end function
sub tf_type.print_(x as i32, y as i32, text as string, scale as f64)
for i as isz = 0 to len(text) - 1
dim as isz charIdx = charmap(text[i])
char(charIdx).draw_(x + i * (W_CHAR + 1) * scale, y, scale, &hff00ff00)
next
end sub
dim as config_file_type cfgFile
if cfgFile.loadFile("2dfont.cfg") <> 0 then _
print "Error cfgFile.loadFile" : end
print "--------------------"
cfgFile.printContents()
print "--------------------"
dim as tf_type tf
if tf.init(cfgFile) <> 0 then _
print "Error tf.init" : end
print "tf.numChar: "& tf.numChar
screenres SW, SH, 32
width SW\8, SH\16
tf.print_(50, 450, "ABCDEFGHI", 12)
tf.print_(50, 350, "JKLMNOPQR", 12)
tf.print_(50, 250, "STUVWXYZ0", 12)
tf.print_(50, 150, "123456789", 12)
'for i as isz = 0 to ubound(tf.char)
'print i
'tf.char(i).draw_(50+i*50, 50, 10, &hff00ff00)
'tf.char(i).printInfo()
'next
getkey()
'TODO
'~ Font editor
'~ Strip spaces
'~ Rendering
'~ Conversion to triangles + line thickness
Code: Select all
numchar: 36
----------------------------------------
charcode: 65 'A
charsize: 5,7
numline: 2
line: 0,3-4,3
line: 0,0-0,4-2,6-4,4-4,0
charcode: 66 'B
charsize: 5,7
numline: 2
line: 0,0-0,6-3,6-4,5-4,4-3,3-0,3
line: 3,3-4,2-4,1-3,0-0,0
charcode: 67 'C
charsize: 5,7
numline: 1
line: 4,1-3,0-1,0-0,1-0,5-1,6-3,6-4,5
charcode: 68 'D
charsize: 5,7
numline: 1
line: 0,0-3,0-4,1-4,5-3,6-0,6-0,0
charcode: 69 'E
charsize: 5,7
numline: 2
line: 4,0-0,0-0,6-4,6
line: 0,3-3,3
charcode: 70 'F
charsize: 5,7
numline: 2
line: 0,0-0,6-4,6
line: 0,3-3,3
charcode: 71 'G
charsize: 5,7
numline: 1
line: 2,3-4,3-4,1-3,0-1,0-0,1-0,5-1,6-3,6-4-5
charcode: 72 'H
charsize: 5,7
numline: 3
line: 0,3-4,3
line: 0,0-0,6
line: 4,0-4-6
charcode: 73 'I
charsize: 5,7
numline: 3
line: 0,0-4,0
line: 0,6-4,6
line: 2,0-2,6
charcode: 74 'J
charsize: 5,7
numline: 1
line: 0,1-1,0-3,0-4,1-4,6-0,6
charcode: 75 'K
charsize: 5,7
numline: 3
line: 0,0-0,6
line: 0,3-1,3-4,6
line: 1,3-4,0
charcode: 76 'L
charsize: 5,7
numline: 1
line: 0,6-0,0-4,0
charcode: 77 'M
charsize: 5,7
numline: 1
line: 0,0-0,6-2,4-4,6-4,0
charcode: 78 'N
charsize: 5,7
numline: 2
line: 0,0-0,6-4,2
line: 4,0-4,6
charcode: 79 'O
charsize: 5,7
numline: 1
line: 0,1-0,5-1,6-3,6-4,5-4,1-3,0-1,0-0,1
charcode: 80 'P
charsize: 5,7
numline: 1
line: 0,0-0,6-3,6-4,5-4,4-3,3-0,3
charcode: 81 'Q
charsize: 5,7
numline: 2
line: 0,1-0,5-1,6-3,6-4,5-4,2-2,0-1,0-0,1
line: 2,2-4,0
charcode: 82 'R
charsize: 5,7
numline: 2
line: 0,0-0,6-3,6-4,5-4,4-3,3-0,3
line: 3,3-4,2-4,0
charcode: 83 'S
charsize: 5,7
numline: 1
line: 0,1-1,0-3,0-4,1-4,2-3,3-1,3-0,4-0,5-1,6-3,6-4,5
charcode: 84 'T
charsize: 5,7
numline: 2
line: 0,6-4,6
line: 2,0-2,6
charcode: 85 'U
charsize: 5,7
numline: 1
line: 0,6-0,1-1,0-3,0-4,1-4,6
charcode: 86 'V
charsize: 5,7
numline: 1
line: 0,6-0,2-2,0-4,2-4,6
charcode: 87 'W
charsize: 5,7
numline: 2
line: 0,6-0,1-1,0-2,1-3,0-4,1-4,6
line: 2,1-2,3
charcode: 88 'X
charsize: 5,7
numline: 2
line: 0,6-0,5-4,1-4,0
line: 0,0-0,1-4,5-4,6
charcode: 89 'Y
charsize: 5,7
numline: 2
line: 0,6-0,4-2,2-4,4-4-6
line: 2,2-2,0
charcode: 90 'Z
charsize: 5,7
numline: 1
line: 0,6-4,6-4,5-0,1-0,0-4,0
----------------------------------------
charcode: 48 '0
charsize: 5,7
numline: 2
line: 0,1-0,5-1,6-3,6-4,5-4,1-3,0-1,0-0,1
line: 0,1-4,5
charcode: 49 '1
charsize: 5,7
numline: 2
line: 0,4-2,6-2,0
line: 0,0-4,0
charcode: 50 '2
charsize: 5,7
numline: 1
line: 0,5-1,6-3,6-4,5-4,4-0,0-4,0
charcode: 51 '3
charsize: 5,7
numline: 2
line: 0,5-1,6-3,6-4,5-4,4-3,3-4,2-4,1-3,0-1,0-0,1
line: 1,3-3,3
charcode: 52 '4
charsize: 5,7
numline: 2
line: 0,6-0,3-4,3
line: 3,0-3,6
charcode: 53 '5
charsize: 5,7
numline: 1
line: 0,1-1,0-3,0-4,1-4,3-3,4-0,4-0,6-4,6
charcode: 54 '6
charsize: 5,7
numline: 1
line: 4,5-3,6-1,6-0,5-0,1-1,0-3,0-4,1-4,3-3,4-1,4-0,3
charcode: 55 '7
charsize: 5,7
numline: 1
line: 0,6-4,6-4,5-0,1-0,0
charcode: 56 '8
charsize: 5,7
numline: 1
line: 3,3-4,4-4,5-3,6-1,6-0,5-0,4-1,3-3,3-4,2-4,1-3,0-1,0-0,1-0,2-1,3
charcode: 57 '9
charsize: 5,7
numline: 1
line: 0,1-1,0-3,0-4,1-4,5-3,6-1,6-0,5-0,3-1,2-3,2-4,3