Ok, making some progress here. I've got the vb.net program writing Spin programs. It works for any font. I've been working on squeezing fonts into 1 byte per line as that halves the size of the font files compared with one word per line. The way it works out is that 16 point fonts fit in this size if they are fixed width fonts. So I've done Courier New in 16 point and the Parallax font in 16 point. I also experimented with variable width fonts. The widest character is generally the "@", and sometimes the %. Arial Narrow at 15 point is the largest one that fits. Times is getting a bit illegible in this size but works fine if you have one word per line. In the zip is an example of the DAT section only for Times 18.
And the nice thing about storing fonts in this format is you can see the font, and hence you can edit it easily. If anyone wants me to process some other fonts let me know. To process a file start with http://www.angelcode.com/products/bmfont/ Turn off aliasing and if you look at the visualise window and zoom in you can count the pixels and get a feel for the width and height.
Then run it through a vb.net program to write the spin code. This loads the output from the bmfont program
PrivateSub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim Filepath, Sourcefile, DestinationFile, pngfile AsString
Filepath = TextBox2.Text' directory
OpenFileDialog1.Multiselect = False
OpenFileDialog1.InitialDirectory = Filepath
OpenFileDialog1.FileName = "*.fnt"' select .fnt file.
OpenFileDialog1.ShowDialog() ' open the openfile dialog
Sourcefile = OpenFileDialog1.FileName ' get the filename
Sourcefile = Strings.Mid(Sourcefile, Strings.Len(Filepath) + 2) ' strip off directory
pngfile = Strings.Left(Sourcefile, Strings.Len(Sourcefile) - 4) + "_0.png"Dim img As Image
Dim fs AsNew FileStream(Filepath + "\" + pngfile, IO.FileMode.Open) ' open the picture
img = Image.FromStream(fs) ' load in the file
fs.Close() ' close the picture
PictureBox3.Image = img ' display the picture
RichTextBox1.LoadFile(Filepath + "\" + Sourcefile, RichTextBoxStreamType.PlainText)
TextBox3.Text = Sourcefile
TextBox4.Text = Strings.Left(Sourcefile, Strings.Len(Sourcefile) - 4) + ".ifn"
TextBox5.Text = Strings.Left(Sourcefile, Strings.Len(Sourcefile) - 4) + ".spin"EndSub
and this produces the spin code
PrivateSub Button7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click
Dim SpinProgram(10000) AsStringDim Ascii, x, y, i, j, Width, Height, Xoffset, Yoffset, Xadvance, Fontvalue, Base AsLongDim Mycolor As Color
Dim MyBitmap AsNew System.Drawing.Bitmap(PictureBox3.Image) 'image from picture boxDim LineOfText AsStringDim FontHeight AsByteDim Counter AsLong = 0Dim start1, start2, finish1, finish2, loopstep1, loopstep2 AsLongDim FontString, Destinationfile AsStringDim ByteWord AsString = "Word"' if font is narrow 1 to 8 pixels wide, use "Byte" otherwise use WordIf CheckBox1.Checked = TrueThen ByteWord = "Byte"' small fonts
AddSpinline(SpinProgram, Counter, "CON")
AddSpinline(SpinProgram, Counter, " _clkmode = xtal1 + pll16x ' use crystal x 16 ")
AddSpinline(SpinProgram, Counter, " _xinfreq = 5_000_000")
AddSpinline(SpinProgram, Counter, "VAR")
AddSpinline(SpinProgram, Counter, "byte FontHeight")
AddSpinline(SpinProgram, Counter, "word CursorX")
AddSpinline(SpinProgram, Counter, "word CursorY")
AddSpinline(SpinProgram, Counter, "OBJ")
AddSpinline(SpinProgram, Counter, "tch: " + Strings.Chr(34) + "Touch" + Strings.Chr(34) + " ' touchscreen driver ")
AddSpinline(SpinProgram, Counter, "PUB Main | i,f ' debug value")
AddSpinline(SpinProgram, Counter, " tch.BeginProgram")
AddSpinline(SpinProgram, Counter, " tch.Clearscreen($FFFF) ' clear the screen to white")
AddSpinline(SpinProgram, Counter, " CursorX := 0")
AddSpinline(SpinProgram, Counter, " CursorY := 0")
AddSpinline(SpinProgram, Counter, " FontHeight := FontBitmap[0]")
AddSpinline(SpinProgram, Counter, " PrintString(string(" + Strings.Chr(34) + "Hello World" + Strings.Chr(34) + "))")
AddSpinline(SpinProgram, Counter, vbCrLf)
AddSpinline(SpinProgram, Counter, "PUB PrintString(stringptr) ' print a string on the screen")
AddSpinline(SpinProgram, Counter, " repeat strsize(stringptr)")
AddSpinline(SpinProgram, Counter, " Text(byte[stringptr++])")
AddSpinline(SpinProgram, Counter, vbCrLf)
AddSpinline(SpinProgram, Counter, "PUB Text(Ascii) | w,i,row,f")
AddSpinline(SpinProgram, Counter, " i := 2 + (Ascii - 32)* (FontHeight+1) ' fontheight + 1 as there is the xadvance byte")
AddSpinline(SpinProgram, Counter, " w := FontBitmap[i] ' xadvance for this character")
AddSpinline(SpinProgram, Counter, " tch.Draw(CursorX,CursorY,CursorX+w-1,CursorY+FontHeight-1) ' set up drawing location")
AddSpinline(SpinProgram, Counter, " i += 1 ' increment pointer")
AddSpinline(SpinProgram, Counter, " repeat row from 1 to FontHeight")
AddSpinline(SpinProgram, Counter, " f := FontBitmap[i] ' get row of pixels")
AddSpinline(SpinProgram, Counter, " i += 1 ' increment pointer")
AddSpinline(SpinProgram, Counter, " repeat w")
AddSpinline(SpinProgram, Counter, " if f & %10000000 ' change this if using words")
AddSpinline(SpinProgram, Counter, " tch.pixel($0000) ' black")
AddSpinline(SpinProgram, Counter, " else")
AddSpinline(SpinProgram, Counter, " tch.pixel($FFFF) ' white background")
AddSpinline(SpinProgram, Counter, " f := f << 1 ' bitshift")
AddSpinline(SpinProgram, Counter, " CursorX += w ' move cursor by this character width")
AddSpinline(SpinProgram, Counter, " If CursorX > 230 ' end of the line")
AddSpinline(SpinProgram, Counter, " CursorX := 0")
AddSpinline(SpinProgram, Counter, " CursorY += FontHeight ' move down a line")
AddSpinline(SpinProgram, Counter, vbCrLf)
AddSpinline(SpinProgram, Counter, "DAT")
AddSpinline(SpinProgram, Counter, " FontBitmap")
ForEach Line AsStringIn RichTextBox1.Lines ' much faster than for i=0 to richtextbox1.lines.length
LineOfText = Line
If Strings.Left(LineOfText, 6) = "common"Then
FontHeight = Strings.Val(Strings.Mid(LineOfText, 19, 2))
Base = Strings.Val(Strings.Mid(LineOfText, 27, 2)) ' base is a better measure of height
AddSpinline(SpinProgram, Counter, "Byte " + Strings.Str(FontHeight) + " ' font height")
AddSpinline(SpinProgram, Counter, "Byte " + Strings.Str(Base) + " ' base")
EndIfIf Strings.Left(LineOfText, 7) = "char id"Then'char id=32 x=96 y=21 width=1 height=1 xoffset=0 yoffset=23 xadvance=7 page=0 chnl=15
Ascii = Strings.Val(Strings.Mid(LineOfText, 9, 3)) ' sub 17
x = Strings.Val(Strings.Mid(LineOfText, 16, 3))
y = Strings.Val(Strings.Mid(LineOfText, 24, 3))
Width = Strings.Val(Strings.Mid(LineOfText, 36, 3))
Height = Strings.Val(Strings.Mid(LineOfText, 49, 3))
Xoffset = Strings.Val(Strings.Mid(LineOfText, 63, 3))
Yoffset = Strings.Val(Strings.Mid(LineOfText, 77, 3))
Xadvance = Strings.Val(Strings.Mid(LineOfText, 92, 3))
start1 = y ' outside loop
start2 = x ' inside loop
finish1 = y + Height - 1
finish2 = x + Width - 1
loopstep1 = 1' add 1 to each step
loopstep2 = 1If Width > 8And ByteWord = "Byte"Then
MsgBox("Ascii '" + Strings.Chr(Ascii) + "' too wide to fit in a Byte, use Words instead")
ExitSubEndIf
AddSpinline(SpinProgram, Counter, "' character " + Strings.Str(Ascii) + " " + Strings.Chr(Ascii))
AddSpinline(SpinProgram, Counter, "Byte " + Strings.Str(Xadvance) + " ' xadvance")
' add in lines with no pixels so all characters the same heightFor i = 1To Yoffset
If ByteWord = "Byte"Then
AddSpinline(SpinProgram, Counter, ByteWord + " %00000000")
Else
AddSpinline(SpinProgram, Counter, ByteWord + " %0000000000000000")
EndIfNextFor j = start1 To finish1 Step loopstep1
FontString = ""' now add in the font dataFor i = 1To Xoffset
FontString += "0"' add leading spaces if anyNextFor i = start2 To finish2 Step loopstep2
Mycolor = MyBitmap.GetPixel(i, j) ' get the color
Fontvalue = Mycolor.R ' grayscale so RGB should be the sameIf Fontvalue > 128Then
FontString += "1"Else
FontString += "0"EndIfNext
FontString = Strings.Left(FontString + "0000000000000000", 16) ' pad with zerosIf ByteWord = "Byte"Then
FontString = Strings.Left(FontString, 8) ' only 8 wide if using bytesEndIf
FontString = ByteWord + " %" + FontString
AddSpinline(SpinProgram, Counter, FontString)
Next' add in lines at the bottomFor i = 1To FontHeight - (Height + Yoffset)
If ByteWord = "Byte"Then
AddSpinline(SpinProgram, Counter, ByteWord + " %00000000")
Else
AddSpinline(SpinProgram, Counter, ByteWord + " %0000000000000000")
EndIfNext i
EndIfNext
Destinationfile = TextBox2.Text + "\" + TextBox5.Text
FileOpen(1, Destinationfile, OpenMode.Output)
For i = 0To Counter
Print(1, SpinProgram(i) + vbCrLf) ' send to diskNext
FileClose(1)
EndSubPrivateSub AddSpinline(ByVal Spinprogram() AsString, ByRef Counter AsLong, ByVal LineOfText AsString)
' use byref to return counter to the calling program
Spinprogram(Counter) = LineOfText
Counter += 1EndSub
I have attached the three spin files as an example. Also an example of what it would look like with words - just the DAT section for Times Roman 18 point.
Example Hello World in Arial Narrow 15 point
CON_clkmode = xtal1 + pll16x' use crystal x 16 _xinfreq = 5_000_000VARbyte FontHeight
word CursorX
word CursorY
OBJ
tch: "Touch"' touchscreen driver PUBMain | i,f' debug value
tch.BeginProgram
tch.Clearscreen($FFFF) ' clear the screen to white
CursorX := 0
CursorY := 0
FontHeight := FontBitmap[0]
PrintString(string("Hello World"))
PUBPrintString(stringptr)' print a string on the screenrepeatstrsize(stringptr)
Text(byte[stringptr++])
PUBText(Ascii) | w,i,row,f
i := 2 + (Ascii - 32)* (FontHeight+1) ' fontheight + 1 as there is the xadvance byte
w := FontBitmap[i] ' xadvance for this character
tch.Draw(CursorX,CursorY,CursorX+w-1,CursorY+FontHeight-1) ' set up drawing location
i += 1' increment pointerrepeat row from1to FontHeight
f := FontBitmap[i] ' get row of pixels
i += 1' increment pointerrepeat w
if f & %10000000' change this if using words
tch.pixel($0000) ' blackelse
tch.pixel($FFFF) ' white background
f := f << 1' bitshift
CursorX += w ' move cursor by this character widthIf CursorX > 230' end of the line
CursorX := 0
CursorY += FontHeight ' move down a lineDAT
FontBitmap
Byte15' font heightByte12' base' character 32 Byte3' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000' character 33 !Byte3' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%00000000Byte%01000000Byte%00000000Byte%00000000Byte%00000000' character 34 "Byte3' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10100000Byte%10100000Byte%10100000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000' character 35 #Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01010000Byte%01010000Byte%11111000Byte%01010000Byte%10100000Byte%11111000Byte%10100000Byte%10100000Byte%00000000Byte%00000000Byte%00000000' character 36 $Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00100000Byte%01110000Byte%10101000Byte%10100000Byte%01110000Byte%00101000Byte%00101000Byte%10101000Byte%01110000Byte%00100000Byte%00000000Byte%00000000' character 37 %Byte8' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01000100Byte%10101000Byte%10101000Byte%01010000Byte%00010100Byte%00011010Byte%00101010Byte%00100100Byte%00000000Byte%00000000Byte%00000000' character 38 &Byte6' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00100000Byte%01010000Byte%01010000Byte%00100000Byte%11101000Byte%10011000Byte%10011000Byte%01100000Byte%00000000Byte%00000000Byte%00000000' character 39 'Byte2' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10000000Byte%10000000Byte%10000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000' character 40 (Byte3' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%01000000Byte%00000000' character 41 )Byte3' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%10000000Byte%00000000' character 42 *Byte4' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01000000Byte%11100000Byte%01000000Byte%10100000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000' character 43 +Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00100000Byte%00100000Byte%11111000Byte%00100000Byte%00100000Byte%00000000Byte%00000000Byte%00000000Byte%00000000' character 44 ,Byte3' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01000000Byte%01000000Byte%10000000Byte%00000000' character 45 -Byte3' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%11000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000' character 46 .Byte3' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01000000Byte%00000000Byte%00000000Byte%00000000' character 47 /Byte3' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00100000Byte%00100000Byte%00100000Byte%01000000Byte%01000000Byte%10000000Byte%10000000Byte%10000000Byte%00000000Byte%00000000Byte%00000000' character 48 0Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01100000Byte%10010000Byte%10010000Byte%10010000Byte%10010000Byte%10010000Byte%10010000Byte%01100000Byte%00000000Byte%00000000Byte%00000000' character 49 1Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00100000Byte%01100000Byte%10100000Byte%00100000Byte%00100000Byte%00100000Byte%00100000Byte%00100000Byte%00000000Byte%00000000Byte%00000000' character 50 2Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01100000Byte%10010000Byte%00010000Byte%00010000Byte%00100000Byte%01000000Byte%10000000Byte%11110000Byte%00000000Byte%00000000Byte%00000000' character 51 3Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01100000Byte%10010000Byte%00010000Byte%01100000Byte%00010000Byte%00010000Byte%10010000Byte%01100000Byte%00000000Byte%00000000Byte%00000000' character 52 4Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00010000Byte%00110000Byte%01010000Byte%01010000Byte%10010000Byte%11111000Byte%00010000Byte%00010000Byte%00000000Byte%00000000Byte%00000000' character 53 5Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01110000Byte%01000000Byte%10000000Byte%11100000Byte%00010000Byte%00010000Byte%10010000Byte%01100000Byte%00000000Byte%00000000Byte%00000000' character 54 6Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01100000Byte%10010000Byte%10000000Byte%10100000Byte%11010000Byte%10010000Byte%10010000Byte%01100000Byte%00000000Byte%00000000Byte%00000000' character 55 7Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%11110000Byte%00010000Byte%00100000Byte%00100000Byte%00100000Byte%01000000Byte%01000000Byte%01000000Byte%00000000Byte%00000000Byte%00000000' character 56 8Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01100000Byte%10010000Byte%10010000Byte%01100000Byte%10010000Byte%10010000Byte%10010000Byte%01100000Byte%00000000Byte%00000000Byte%00000000' character 57 9Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01100000Byte%10010000Byte%10010000Byte%10110000Byte%01010000Byte%00010000Byte%10010000Byte%01100000Byte%00000000Byte%00000000Byte%00000000' character 58 :Byte3' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01000000Byte%00000000Byte%00000000Byte%00000000' character 59 ;Byte3' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01000000Byte%01000000Byte%10000000Byte%00000000' character 60 <Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00010000Byte%01100000Byte%10000000Byte%01100000Byte%00010000Byte%00000000Byte%00000000Byte%00000000Byte%00000000' character 61 =Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%11110000Byte%00000000Byte%11110000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000' character 62 >Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10000000Byte%01100000Byte%00010000Byte%01100000Byte%10000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000' character 63 ?Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01100000Byte%10010000Byte%00010000Byte%00100000Byte%01000000Byte%01000000Byte%00000000Byte%01000000Byte%00000000Byte%00000000Byte%00000000' character 64 @Byte9' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00011100Byte%00100010Byte%01011011Byte%10100101Byte%10100101Byte%10100101Byte%10100101Byte%10011110Byte%01000001Byte%00100010Byte%00011100' character 65 AByte6' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00100000Byte%01010000Byte%01010000Byte%01010000Byte%01010000Byte%01110000Byte%10001000Byte%10001000Byte%00000000Byte%00000000Byte%00000000' character 66 BByte6' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%11110000Byte%10001000Byte%10001000Byte%11110000Byte%10001000Byte%10001000Byte%10001000Byte%11110000Byte%00000000Byte%00000000Byte%00000000' character 67 CByte7' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00111000Byte%01000100Byte%10000100Byte%10000000Byte%10000000Byte%10000100Byte%01000100Byte%00111000Byte%00000000Byte%00000000Byte%00000000' character 68 DByte6' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%11100000Byte%10010000Byte%10001000Byte%10001000Byte%10001000Byte%10001000Byte%10010000Byte%11100000Byte%00000000Byte%00000000Byte%00000000' character 69 EByte6' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%11111000Byte%10000000Byte%10000000Byte%11111000Byte%10000000Byte%10000000Byte%10000000Byte%11111000Byte%00000000Byte%00000000Byte%00000000' character 70 FByte6' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01111000Byte%01000000Byte%01000000Byte%01110000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%00000000Byte%00000000Byte%00000000' character 71 GByte7' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00111000Byte%01000100Byte%10000100Byte%10000000Byte%10011100Byte%10000100Byte%01000100Byte%00111000Byte%00000000Byte%00000000Byte%00000000' character 72 HByte6' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10001000Byte%10001000Byte%10001000Byte%11111000Byte%10001000Byte%10001000Byte%10001000Byte%10001000Byte%00000000Byte%00000000Byte%00000000' character 73 IByte2' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%00000000Byte%00000000Byte%00000000' character 74 JByte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00010000Byte%00010000Byte%00010000Byte%00010000Byte%00010000Byte%10010000Byte%10010000Byte%01100000Byte%00000000Byte%00000000Byte%00000000' character 75 KByte6' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10001000Byte%10010000Byte%10100000Byte%11100000Byte%10100000Byte%10010000Byte%10010000Byte%10001000Byte%00000000Byte%00000000Byte%00000000' character 76 LByte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%11110000Byte%00000000Byte%00000000Byte%00000000' character 77 MByte8' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10000010Byte%11000110Byte%11000110Byte%10101010Byte%10101010Byte%10101010Byte%10101010Byte%10010010Byte%00000000Byte%00000000Byte%00000000' character 78 NByte7' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10000100Byte%11000100Byte%10100100Byte%10100100Byte%10010100Byte%10010100Byte%10001100Byte%10000100Byte%00000000Byte%00000000Byte%00000000' character 79 OByte7' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00110000Byte%01001000Byte%10000100Byte%10000100Byte%10000100Byte%10000100Byte%01001000Byte%00110000Byte%00000000Byte%00000000Byte%00000000' character 80 PByte6' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%11110000Byte%10001000Byte%10001000Byte%10001000Byte%11110000Byte%10000000Byte%10000000Byte%10000000Byte%00000000Byte%00000000Byte%00000000' character 81 QByte7' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00110000Byte%01001000Byte%10000100Byte%10000100Byte%10000100Byte%10000100Byte%01011000Byte%00110100Byte%00000100Byte%00000000Byte%00000000' character 82 RByte7' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01111000Byte%01000100Byte%01000100Byte%01111000Byte%01010000Byte%01001000Byte%01000100Byte%01000010Byte%00000000Byte%00000000Byte%00000000' character 83 SByte6' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01110000Byte%10001000Byte%10000000Byte%01110000Byte%00001000Byte%10001000Byte%10001000Byte%01110000Byte%00000000Byte%00000000Byte%00000000' character 84 TByte6' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%11111000Byte%00100000Byte%00100000Byte%00100000Byte%00100000Byte%00100000Byte%00100000Byte%00100000Byte%00000000Byte%00000000Byte%00000000' character 85 UByte7' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10000100Byte%10000100Byte%10000100Byte%10000100Byte%10000100Byte%10000100Byte%01001000Byte%00110000Byte%00000000Byte%00000000Byte%00000000' character 86 VByte6' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10001000Byte%10001000Byte%01010000Byte%01010000Byte%01010000Byte%01010000Byte%01010000Byte%00100000Byte%00000000Byte%00000000Byte%00000000' character 87 WByte8' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10010010Byte%10101010Byte%10101010Byte%10101010Byte%10101010Byte%10101010Byte%10101010Byte%01000100Byte%00000000Byte%00000000Byte%00000000' character 88 XByte6' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10000100Byte%01001000Byte%01001000Byte%00110000Byte%00110000Byte%01001000Byte%01001000Byte%10000100Byte%00000000Byte%00000000Byte%00000000' character 89 YByte6' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10001000Byte%01010000Byte%01010000Byte%00100000Byte%00100000Byte%00100000Byte%00100000Byte%00100000Byte%00000000Byte%00000000Byte%00000000' character 90 ZByte6' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%11111000Byte%00001000Byte%00010000Byte%00100000Byte%00100000Byte%01000000Byte%10000000Byte%11111000Byte%00000000Byte%00000000Byte%00000000' character 91 [Byte3' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%11000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%11000000Byte%00000000' character 92 \Byte3' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10000000Byte%10000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%00100000Byte%00100000Byte%00000000Byte%00000000Byte%00000000' character 93 ]Byte3' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%11000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%11000000Byte%00000000' character 94 ^Byte4' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01000000Byte%10100000Byte%10100000Byte%10100000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000' character 95 _Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%11111000Byte%00000000Byte%00000000' character 96 `Byte3' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10000000Byte%01000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000' character 97 aByte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%11100000Byte%00010000Byte%01110000Byte%10010000Byte%10010000Byte%01110000Byte%00000000Byte%00000000Byte%00000000' character 98 bByte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10000000Byte%10000000Byte%10100000Byte%11010000Byte%10010000Byte%10010000Byte%11010000Byte%10100000Byte%00000000Byte%00000000Byte%00000000' character 99 cByte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01100000Byte%10010000Byte%10000000Byte%10000000Byte%10010000Byte%01100000Byte%00000000Byte%00000000Byte%00000000' character 100 dByte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00010000Byte%00010000Byte%01010000Byte%10110000Byte%10010000Byte%10010000Byte%10110000Byte%01010000Byte%00000000Byte%00000000Byte%00000000' character 101 eByte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01100000Byte%10010000Byte%11110000Byte%10000000Byte%10010000Byte%01100000Byte%00000000Byte%00000000Byte%00000000' character 102 fByte2' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01100000Byte%01000000Byte%11100000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%00000000Byte%00000000Byte%00000000' character 103 gByte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01010000Byte%10110000Byte%10010000Byte%10010000Byte%10110000Byte%01010000Byte%00010000Byte%11100000Byte%00000000' character 104 hByte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10000000Byte%10000000Byte%10100000Byte%11010000Byte%10010000Byte%10010000Byte%10010000Byte%10010000Byte%00000000Byte%00000000Byte%00000000' character 105 iByte2' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10000000Byte%00000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%00000000Byte%00000000Byte%00000000' character 106 jByte2' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01000000Byte%00000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%11000000Byte%00000000' character 107 kByte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10000000Byte%10000000Byte%10010000Byte%10100000Byte%11000000Byte%10100000Byte%10010000Byte%10010000Byte%00000000Byte%00000000Byte%00000000' character 108 lByte2' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%00000000Byte%00000000Byte%00000000' character 109 mByte8' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10100110Byte%11011010Byte%10010010Byte%10010010Byte%10010010Byte%10010010Byte%00000000Byte%00000000Byte%00000000' character 110 nByte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10100000Byte%11010000Byte%10010000Byte%10010000Byte%10010000Byte%10010000Byte%00000000Byte%00000000Byte%00000000' character 111 oByte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01100000Byte%10010000Byte%10010000Byte%10010000Byte%10010000Byte%01100000Byte%00000000Byte%00000000Byte%00000000' character 112 pByte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10100000Byte%11010000Byte%10010000Byte%10010000Byte%11010000Byte%10100000Byte%10000000Byte%10000000Byte%00000000' character 113 qByte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01010000Byte%10110000Byte%10010000Byte%10010000Byte%10110000Byte%01010000Byte%00010000Byte%00010000Byte%00000000' character 114 rByte3' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10100000Byte%11000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%00000000Byte%00000000Byte%00000000' character 115 sByte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%11100000Byte%10010000Byte%01000000Byte%00100000Byte%10010000Byte%01100000Byte%00000000Byte%00000000Byte%00000000' character 116 tByte2' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01000000Byte%01000000Byte%11100000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%01100000Byte%00000000Byte%00000000Byte%00000000' character 117 uByte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10010000Byte%10010000Byte%10010000Byte%10010000Byte%10110000Byte%01010000Byte%00000000Byte%00000000Byte%00000000' character 118 vByte6' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10001000Byte%10001000Byte%01010000Byte%01010000Byte%01010000Byte%00100000Byte%00000000Byte%00000000Byte%00000000' character 119 wByte8' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10010010Byte%10101010Byte%10101010Byte%10101010Byte%10101010Byte%01000100Byte%00000000Byte%00000000Byte%00000000' character 120 xByte6' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10001000Byte%01010000Byte%00100000Byte%00100000Byte%01010000Byte%10001000Byte%00000000Byte%00000000Byte%00000000' character 121 yByte6' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10001000Byte%01010000Byte%01010000Byte%01010000Byte%00100000Byte%00100000Byte%00100000Byte%01000000Byte%00000000' character 122 zByte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%11110000Byte%00010000Byte%00100000Byte%01000000Byte%10000000Byte%11110000Byte%00000000Byte%00000000Byte%00000000' character 123 {Byte3' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%01100000Byte%01000000Byte%01000000Byte%01000000Byte%10000000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%00100000Byte%00000000' character 124 |Byte2' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%10000000Byte%00000000' character 125 }Byte3' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%11000000Byte%01000000Byte%01000000Byte%01000000Byte%00100000Byte%01000000Byte%01000000Byte%01000000Byte%01000000Byte%11000000Byte%00000000' character 126 ~Byte5' xadvanceByte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%11101000Byte%10110000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000Byte%00000000
Personally, I prefer the binary file so that the font is only 3 lines of code in the main program and not hundreds of lines...
That format is nice to see the font, but I started this thread to show work and get ideas on my font editor that lets you visualize the font, create it, and edit it.
But, I'll provide text output options for Spin and C for cases where you'd rather have the font that way...
Guess the downside the binary format is that it doesn't include any info on height, width, etc....
Perhaps we need an optional 8 (or so) byte header that describes the font.
That way, the code can automatically know the font type and it can be imported back into the editor easily...
Think it needs: height, width, bpp, start char, end char, type (fixed, variable, etc).
Maybe make it 12 bytes with the first 4 bytes equalling "Font" for easy recognition...
Guess the downside the binary format is that it doesn't include any info on height, width, etc....
Perhaps we need an optional 8 (or so) byte header that describes the font.
That way, the code can automatically know the font type and it can be imported back into the editor easily...
Think it needs: height, width, bpp, start char, end char, type (fixed, variable, etc).
Maybe make it 12 bytes with the first 4 bytes equalling "Font" for easy recognition...
Here you uncover the reason few use Binary files, unless they really have to.
They do not self-document, and so you need to store/archive/post TWO lots of information, the Binary file and then also the record format.
Since this font info is going thru a tool-chain step I don' t quite see that you are forced to use Binary ?
More useful to me, is an ASCII-round-trip ability - ie to Load/Edit/Save of a simple ASCII format, that can be handled by other scripts.
These are good points. I just don't want to clutter up my main program with hundreds of lines of code that are just the font...
Maybe there's a way to make a font object file so that the text could go there...
I'm not sure what you mean by "ASM" Do you mean Propeller assembly?
BTW: In spin, you can include binary files, but not text files (at least, with the Prop Tool).
Here's what I'm thinking of for text export options (Am I missing anything?):
These are good points. I just don't want to clutter up my main program with hundreds of lines of code that are just the font...
Maybe there's a way to make a font object file so that the text could go there...
BTW: In spin, you can include binary files, but not text files (at least, with the Prop Tool).
There do seem to be solutions now to this, and surely such a shortcoming will quickly be fixed ?
I'm not sure what you mean by "ASM" Do you mean Propeller assembly?
Both Prop PASM, and more general ASM, as options - the more general ASM is useful for creating SPI Flash images.
All the std assemblers I know support ; as comment, and DB as DataByte, so those are the only two syntax elements needed, and I have found some ASMs do not like very long lines.
Here's what I'm thinking of for text export options (Am I missing anything?):
I can see a Prop-case where it might be useful to have the Widths in a table before the Chars ?
(that would allow a quick-sum to find the char start )
With an index, you need to define size and byte order.
24 bits seems std for SPI flash up to 128MBit, but you also need a means to merge multiple fonts into that SPI flash pgm file.
(which is where the General ASM support helps ).
I'll check some ASMs, for larger Font handling, - NASM looks like a good candidate, small enough, (single EXE and < 1MB download), and supported on many OS's. http://www.nasm.us/
NASM looks to create BIN or Intel Hex etc files, and allows includes.
Not sure about 24 bit DB - but 8/16/32/64 are all there - simplest is DD LabelName for 32 bit, little endian index.
But, I'll provide text output options for Spin and C for cases where you'd rather have the font that way...
Guess the downside the binary format is that it doesn't include any info on height, width, etc....
Perhaps we need an optional 8 (or so) byte header that describes the font.
That way, the code can automatically know the font type and it can be imported back into the editor easily...
Think it needs: height, width, bpp, start char, end char, type (fixed, variable, etc).
Maybe make it 12 bytes with the first 4 bytes equalling "Font" for easy recognition...
All good points.
I suppose one big decision is whether you are going to have an SD card available. If yes, then it makes sense to put the font on the SD card as a file, in which case the file can be a lot larger. But the downside is you need SD driver code, which can take up 1/3 of hub ram. On the other hand, if you didn't have an SD card, then you might be more tempted to put the font in the code.
I'm not sure whether one is better than the other. Maybe one needs to output both binary and text?
Re descriptions of characters, the demo I wrote above is not the most efficient for memory. Fonts are padded out to 8 wide, and the height is larger than it needs to be for most characters. So you can either store the width, height, xoffset, yoffset, xadvance for each character, or you can pad them and then you only need to store the xadvance.
For the touchscreens I am using, it is quicker to dump a whole picture than it is to send the individual pixels. So a full picture of a character fully aliased is the quickest. But I don't think that is the case for TV and VGA so I think it leads you down a different path there. Certainly editing is easier with unaliased fonts. And I don't know much about true type fonts - I think characters are described with curves and lines rather than with pixels.
I guess one thing I found is there are some great online libraries of free fonts out there on the interweb.
More on using NASM to create Font files for SPI Flash (etc)
Not sure about 24 bit DB - but 8/16/32/64 are all there - simplest is DD LabelName for 32 bit, little endian index.
Turns out the 'non scalar' error messages I got here, on the obvious (SomeLabel >> 8), are explained here :
forum.nasm.us
and NASM uses a Section Relative system, using this rule The difference between two labels (in the same section!) is a "scalar value". The linker/loader can change the two values, but the distance between them remains the same. Therefore, we can do a calculation on it
This is not actually a problem, as a multi-file font merge, would use difference approach anyway, it just needs a specific difference syntax.
Here are some NASM examples, that work, and it can create large bin/hex files, from a simple or multiple FONT sources.
1800000001 [2148] DW LastByte ; Gives warning as Address > 2 Byte
1900000003 [21480100] DD LastByte
2000000007 [2148010000000000] DQ LastByte
21262700000014 [00000000] DD $$ ; $ is PC, $$ is Section start, here it is Zero
28 00000018 01 DB (LastByte-$$) & 07H
29 00000019 2008 DW (LastByte-$$) & 0FF0H
3031 ; Generate a 24 bit relative index
32 0000001B 28 DB ((F8x8_Char5-FONT8x8_Start) >> 0) & 0FFH
33 0000001C 00 DB ((F8x8_Char5-FONT8x8_Start) >> 8) & 0FFH
34 0000001D 00 DB ((F8x8_Char5-FONT8x8_Start) >> 16) & 0FFH
3536 ; another section relative index, other endian, 24 bits.
37 0000001E 01 DB ((LastByte-$$) >> 16) & 0FFH
38 0000001F 48 DB ((LastByte-$$) >> 8) & 0FFH
390000002021 DB ((LastByte-$$) >> 0) & 0FFH
The command line is simply
..\nasm -f ith F8X8.ASM -l F8x8.lst
ith = intel hex, or bin for binary file.
Ok, I can provide text output in the 8088 assembly syntax.
There may be people who would use this for 8051 programming anyway...
But, the output of your assembler would just be the binary file we talked about earlier...
You could just use some tool to concatenate binary files instead of going through the whole assembly process.
But maybe what we really need is a simple file system for flash...
I worked a little on one, but that's a different project...
But, the output of your assembler would just be the binary file we talked about earlier...
You could just use some tool to concatenate binary files instead of going through the whole assembly process.
It can optionally be binary, which allows present PropTool include, but it can also be HEX, or the ASM might link into a HLL project
on AVR/8051/etc.
"concatenate binary files" is not so simple, as you usually need some means to index across fonts.
With ASM, you can easily manage that, and choose if you want relative, or absolute addresses.
ASM could also create a simple File system header, with some font info comments.
This would be a simple, master ASM that was a stack of %include's for each font, and with some index DB's added.
NASM (which I had not looked at for a while..) seems quite good for this, as it has a 'hidden' linker, and can build (very) large binary/hex files, and you can just point a single command line, and Assemble/Include any desired set of font files, all under the control of a Text editor, and with full version control. You also get a LST file, as confirmation of what happened.
Minor comments :
I would add the export settings as comments too, especially the scan ones.
I would also add a couple of ASM labels, eg
ProGoCo_8x16_Font:
so that a user can %include any series of font files, and build a simple font index using those labels.
Any Width/Offset tables, should also have labels.
Idea is they can Grab any saved Font, wiggle some pixels, export and build, without needing to edit the export file.
I guess here some means to export-the-same-as-before would be useful ?
Maybe a backup/rename of old file, could help protect users ?
I did notice there is no save-as, and save does not have an over-write warning.
Do you plan to support import/export in the xml file of glcd-font-creator ?
That would allow access to larger user base, as I get the impression that glcd is inherited and somewhat frozen.
(because they have other packages for $$$, no surprise..)
jmg, can you please test the attached version and see if it can import your xml font?
Also, if you could post a couple full xml files, that might help me figure out how to make it work.
Especially, a variable pitch font...RaysFontEditor_15Aug12.zip
I tried a paste, but I think it ran out of paste-space as the last text was not the XML end - easy to fix...
Attached is xml_font_examples.zip, which is three font files.
Not sure if the simple LCD font manager can cope with variable spaced fonts ?
I did try this - which is quickly add a width modifier to 3 lines, & height to 1, and GLCD Font Creator will read this fine.
(ie it simply ignored the added WIDTH="7", HEIGHT="13" etc )
Of course, on save it removes the ignored text, but it does tolerate it nicely, so you may have a safe superset there.
Notice I did not trim the pixel lines, and doing that does confuse GLCD Font Creator. (no surprise)
So I think the compatibility rule is to use a largest-box for the header, and always export to that size, but allow the width modifier per character to optionally trim below that. ( left justified ? )
I guess also Height could be variable too..
So you can load any of their files and save read-compatible, but add Width to this format.
I spotted three easily fixed issues in a quick glance at the file
- Missing tail lines
</CHARS>
</FONT>
- bonus CR instead of CRLF
- Extra quote in the <RANGE FROM="32" TO="127""/>
I also see Import 'clobbers' the currently open font, without prompting for a new option. Not a nice default.
It crashed once, when I was checking save / save-as with a few fonts open.
Not easy to reproduce, but I suspect some 'cross pollination' effect as the message said something about Sizes
Let me know if you can figure out what makes it crash...
See attached screen shot.
This was after a XML import from a GLCD font, and fails @ save.
Some seem to XML import/save ok, some do not.
I also see that a 21x22 font imported, renders fine, but double-click to edit, selects a char somewhere else...
(ie the selected-char decision, is not quite properly applying the real font size )
I have not seen a crash on load (except on a file that crashed on save, and that's not a fair test..)
So the LCD files seem to import, and render as I would expect, but maybe some info needed for save, is not
properly updated ?
If you download GLCD and NewFont.ImportSystemFont, you can quickly create a series of .LCD test files, of various XY sizes.
Suggestion:
The whole font preview is great, but as it zooms, it crops off the screen, even tho there is plenty of render space.
A simple binary size makes sense, but fitting all the chars is also important.
Perhaps a user Chars-per-row, and even a re-size option on the render area ?
I'm thinking of a screen-grab as a quick and simple means to document fonts and changes.
(I've added a font grab example, of a screen grab saved as .png )
Ok, I've added a lot of features today (of course that is just more things that might not work right...)
Anyway, I think I've fixed all the things you found...
Also, it can now export variable pitch in a way that I think Dr_Acula wanted...
Looks more stable. Import/export round trip is OK, and I can now GLCD load a exported .lcd Nice.
Some house-keeping issues :
a) When I select XML format, it should flip the import default from .txt, to .lcd { Saves mouse clicks...}
b) Import into a blank sheet, should apply the imported name.
c) I see the cursor shows Dec/Hex Chr value, - would be nice if the Character Editor did that too, maybe in the top line ?
d) Copy / Paste of chars is nifty, but it only works in a pre-valid slot ?
If I import a file < 256, and copy/paste 'Q' into a visible, but not white BG cell, it does nothing.
I can copy-over into any white BG cell.
e) I see the Editor has the same issue - It opens, and I can flip pixels, but it will not save into a not white BG cell
(ie does not create a new Char position)
I'm not sure needing a blank page before import is a good idea.
Import should be like any text editor, it should default to a NEW page, (named as the import file ), but allow experienced users to merge-import over the top of an open font. (with warnings)
Right now, it does not merge import over an open font, it wipes the whole sheet.
ie I quickly edited a XML file, to place 'Q' in CHR0 location, and I should be able to import that, into an open font (of the same XY) and have 'Q' pop into @0, with the rest of the font untouched.
Single char import works, apart from the unwanted clear-all first.
Edit: To clarify, the import file may have one or more chars, and even be sparse, and they should merge-over and create new chars if needed. Export should be only of defined chars, and may also be sparse.
A common use is to harvest std forts for the lower 128, and use more custom sources for > 128 and sometimes < 32.
Just one thing... There's now a "font settings" menu... If you change the valid character range, you should be able to paste there.
Actually, I think it did paste before, you just can't see it because of the font's character range setting...
I do want the imports not to clear the existing font before importing... I'll have to figure out how to do that..
Just one thing... There's now a "font settings" menu... If you change the valid character range, you should be able to paste there.
Actually, I think it did paste before, you just can't see it because of the font's character range setting...
Yes, I can paste into hidden chars, and then on manual adjust of the limits, they become visible.
So, perhaps a user paste could auto-adjust-limits, to make it WYSIWYG ?
Looks nice.
Paste Auto adjusts nicely.
However, I see manual edit does not. Even tho Edit.OK works, I have to manually go into FontSettings, to 'see' the newly edited char, if it is outside the bounds. This should auto-adjust-limits the same as paste.
Width control is good, but this will also need a means to move the whole char ( << Char and Char >> ? )
and I guess height and Char Up Char Dn set, almost complete the tile controls.
One feature I have frequently wanted, is an font insert/delete row/column, (just like in a spread sheet).
Applied to a font it would default to copy of the indicated row/column - used to easily stretch/trim characters, that are almost a fit.
Import still over-writes a non-empty slate, and import merge instead clears - still on the to-do list I guess.
Thanks for checking this out jmg. I think I'm with you on the first two things. Can you please explain more the last two things?
I thought I had the import the way you wanted it...
Thanks for checking this out jmg. I think I'm with you on the first two things. Can you please explain more the last two things?
I thought I had the import the way you wanted it...
I have a single Char .lcd file (actually Q in Chr(0) ), and import of that into an open-font, still clears the whole font ?
Also, import into any open (non blank) font, should ask if the user wants a new window (default) or Merge/replace.
ie It is too easy to over-write an existing font.
Ok, I see what you mean now... I fixed it for "Capture System Font", but not for "Import Font"...
I'll try to get to that today or early tomorrow... Thanks.
There should be a tiny "about" button close to the top right corner of the window...
One feature I have frequently wanted, is an font insert/delete row/column, (just like in a spread sheet).
Applied to a font it would default to copy of the indicated row/column - used to easily stretch/trim characters, that are almost a fit.
I'm trying to figure out how to do this... Can you please explain some more exactly what you'd like?
Do you want to add a blank column? Or, do you want to insert a copy of a column to the left or right?
Do you want this to operate on the whole font, or just one character?
I'm trying to figure out how to do this... Can you please explain some more exactly what you'd like?
Do you want to add a blank column? Or, do you want to insert a copy of a column to the left or right?
Do you want this to operate on the whole font, or just one character?
Where I've done this, is to clean-up, or scale imported fonts.
The LCD editor pgm mentioned before, adds blank rows/columns but this is limited to edges. - so it is part way there.
A Move Char U/D/L/R would effectively add a blank row on one edge, and remove on the other, keeping tile size
Works like the 'Hand' control in Acrobat - the Font just moves within the tile
A insert Row/Col, would take the cursor as a prompt, and usually copy, the selected R/C, but blank might be a user option
SW based Insert saves a LOT of clicks over 'insert manually'.
Of course, the question then rises of which surplus stripe is trimmed, after insert
Since variable width is supported, maybe a delete row/col is all that is needed, but a user might accidently make a 17x8 tile ?
The spread sheet method, users should already know/understand and that is a simple insert/delete, and there you can select/copy any r/c if you want a copy.
Pixel-rectangle select/copy/paste would be sweet, but might be over-engineering this ?
Comments
And the nice thing about storing fonts in this format is you can see the font, and hence you can edit it easily. If anyone wants me to process some other fonts let me know. To process a file start with http://www.angelcode.com/products/bmfont/ Turn off aliasing and if you look at the visualise window and zoom in you can count the pixels and get a feel for the width and height.
Then run it through a vb.net program to write the spin code. This loads the output from the bmfont program
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim Filepath, Sourcefile, DestinationFile, pngfile As String Filepath = TextBox2.Text ' directory OpenFileDialog1.Multiselect = False OpenFileDialog1.InitialDirectory = Filepath OpenFileDialog1.FileName = "*.fnt" ' select .fnt file. OpenFileDialog1.ShowDialog() ' open the openfile dialog Sourcefile = OpenFileDialog1.FileName ' get the filename Sourcefile = Strings.Mid(Sourcefile, Strings.Len(Filepath) + 2) ' strip off directory pngfile = Strings.Left(Sourcefile, Strings.Len(Sourcefile) - 4) + "_0.png" Dim img As Image Dim fs As New FileStream(Filepath + "\" + pngfile, IO.FileMode.Open) ' open the picture img = Image.FromStream(fs) ' load in the file fs.Close() ' close the picture PictureBox3.Image = img ' display the picture RichTextBox1.LoadFile(Filepath + "\" + Sourcefile, RichTextBoxStreamType.PlainText) TextBox3.Text = Sourcefile TextBox4.Text = Strings.Left(Sourcefile, Strings.Len(Sourcefile) - 4) + ".ifn" TextBox5.Text = Strings.Left(Sourcefile, Strings.Len(Sourcefile) - 4) + ".spin" End Sub
and this produces the spin code
Private Sub Button7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click Dim SpinProgram(10000) As String Dim Ascii, x, y, i, j, Width, Height, Xoffset, Yoffset, Xadvance, Fontvalue, Base As Long Dim Mycolor As Color Dim MyBitmap As New System.Drawing.Bitmap(PictureBox3.Image) 'image from picture box Dim LineOfText As String Dim FontHeight As Byte Dim Counter As Long = 0 Dim start1, start2, finish1, finish2, loopstep1, loopstep2 As Long Dim FontString, Destinationfile As String Dim ByteWord As String = "Word" ' if font is narrow 1 to 8 pixels wide, use "Byte" otherwise use Word If CheckBox1.Checked = True Then ByteWord = "Byte" ' small fonts AddSpinline(SpinProgram, Counter, "CON") AddSpinline(SpinProgram, Counter, " _clkmode = xtal1 + pll16x ' use crystal x 16 ") AddSpinline(SpinProgram, Counter, " _xinfreq = 5_000_000") AddSpinline(SpinProgram, Counter, "VAR") AddSpinline(SpinProgram, Counter, "byte FontHeight") AddSpinline(SpinProgram, Counter, "word CursorX") AddSpinline(SpinProgram, Counter, "word CursorY") AddSpinline(SpinProgram, Counter, "OBJ") AddSpinline(SpinProgram, Counter, "tch: " + Strings.Chr(34) + "Touch" + Strings.Chr(34) + " ' touchscreen driver ") AddSpinline(SpinProgram, Counter, "PUB Main | i,f ' debug value") AddSpinline(SpinProgram, Counter, " tch.BeginProgram") AddSpinline(SpinProgram, Counter, " tch.Clearscreen($FFFF) ' clear the screen to white") AddSpinline(SpinProgram, Counter, " CursorX := 0") AddSpinline(SpinProgram, Counter, " CursorY := 0") AddSpinline(SpinProgram, Counter, " FontHeight := FontBitmap[0]") AddSpinline(SpinProgram, Counter, " PrintString(string(" + Strings.Chr(34) + "Hello World" + Strings.Chr(34) + "))") AddSpinline(SpinProgram, Counter, vbCrLf) AddSpinline(SpinProgram, Counter, "PUB PrintString(stringptr) ' print a string on the screen") AddSpinline(SpinProgram, Counter, " repeat strsize(stringptr)") AddSpinline(SpinProgram, Counter, " Text(byte[stringptr++])") AddSpinline(SpinProgram, Counter, vbCrLf) AddSpinline(SpinProgram, Counter, "PUB Text(Ascii) | w,i,row,f") AddSpinline(SpinProgram, Counter, " i := 2 + (Ascii - 32)* (FontHeight+1) ' fontheight + 1 as there is the xadvance byte") AddSpinline(SpinProgram, Counter, " w := FontBitmap[i] ' xadvance for this character") AddSpinline(SpinProgram, Counter, " tch.Draw(CursorX,CursorY,CursorX+w-1,CursorY+FontHeight-1) ' set up drawing location") AddSpinline(SpinProgram, Counter, " i += 1 ' increment pointer") AddSpinline(SpinProgram, Counter, " repeat row from 1 to FontHeight") AddSpinline(SpinProgram, Counter, " f := FontBitmap[i] ' get row of pixels") AddSpinline(SpinProgram, Counter, " i += 1 ' increment pointer") AddSpinline(SpinProgram, Counter, " repeat w") AddSpinline(SpinProgram, Counter, " if f & %10000000 ' change this if using words") AddSpinline(SpinProgram, Counter, " tch.pixel($0000) ' black") AddSpinline(SpinProgram, Counter, " else") AddSpinline(SpinProgram, Counter, " tch.pixel($FFFF) ' white background") AddSpinline(SpinProgram, Counter, " f := f << 1 ' bitshift") AddSpinline(SpinProgram, Counter, " CursorX += w ' move cursor by this character width") AddSpinline(SpinProgram, Counter, " If CursorX > 230 ' end of the line") AddSpinline(SpinProgram, Counter, " CursorX := 0") AddSpinline(SpinProgram, Counter, " CursorY += FontHeight ' move down a line") AddSpinline(SpinProgram, Counter, vbCrLf) AddSpinline(SpinProgram, Counter, "DAT") AddSpinline(SpinProgram, Counter, " FontBitmap") For Each Line As String In RichTextBox1.Lines ' much faster than for i=0 to richtextbox1.lines.length LineOfText = Line If Strings.Left(LineOfText, 6) = "common" Then FontHeight = Strings.Val(Strings.Mid(LineOfText, 19, 2)) Base = Strings.Val(Strings.Mid(LineOfText, 27, 2)) ' base is a better measure of height AddSpinline(SpinProgram, Counter, "Byte " + Strings.Str(FontHeight) + " ' font height") AddSpinline(SpinProgram, Counter, "Byte " + Strings.Str(Base) + " ' base") End If If Strings.Left(LineOfText, 7) = "char id" Then 'char id=32 x=96 y=21 width=1 height=1 xoffset=0 yoffset=23 xadvance=7 page=0 chnl=15 Ascii = Strings.Val(Strings.Mid(LineOfText, 9, 3)) ' sub 17 x = Strings.Val(Strings.Mid(LineOfText, 16, 3)) y = Strings.Val(Strings.Mid(LineOfText, 24, 3)) Width = Strings.Val(Strings.Mid(LineOfText, 36, 3)) Height = Strings.Val(Strings.Mid(LineOfText, 49, 3)) Xoffset = Strings.Val(Strings.Mid(LineOfText, 63, 3)) Yoffset = Strings.Val(Strings.Mid(LineOfText, 77, 3)) Xadvance = Strings.Val(Strings.Mid(LineOfText, 92, 3)) start1 = y ' outside loop start2 = x ' inside loop finish1 = y + Height - 1 finish2 = x + Width - 1 loopstep1 = 1 ' add 1 to each step loopstep2 = 1 If Width > 8 And ByteWord = "Byte" Then MsgBox("Ascii '" + Strings.Chr(Ascii) + "' too wide to fit in a Byte, use Words instead") Exit Sub End If AddSpinline(SpinProgram, Counter, "' character " + Strings.Str(Ascii) + " " + Strings.Chr(Ascii)) AddSpinline(SpinProgram, Counter, "Byte " + Strings.Str(Xadvance) + " ' xadvance") ' add in lines with no pixels so all characters the same height For i = 1 To Yoffset If ByteWord = "Byte" Then AddSpinline(SpinProgram, Counter, ByteWord + " %00000000") Else AddSpinline(SpinProgram, Counter, ByteWord + " %0000000000000000") End If Next For j = start1 To finish1 Step loopstep1 FontString = "" ' now add in the font data For i = 1 To Xoffset FontString += "0" ' add leading spaces if any Next For i = start2 To finish2 Step loopstep2 Mycolor = MyBitmap.GetPixel(i, j) ' get the color Fontvalue = Mycolor.R ' grayscale so RGB should be the same If Fontvalue > 128 Then FontString += "1" Else FontString += "0" End If Next FontString = Strings.Left(FontString + "0000000000000000", 16) ' pad with zeros If ByteWord = "Byte" Then FontString = Strings.Left(FontString, 8) ' only 8 wide if using bytes End If FontString = ByteWord + " %" + FontString AddSpinline(SpinProgram, Counter, FontString) Next ' add in lines at the bottom For i = 1 To FontHeight - (Height + Yoffset) If ByteWord = "Byte" Then AddSpinline(SpinProgram, Counter, ByteWord + " %00000000") Else AddSpinline(SpinProgram, Counter, ByteWord + " %0000000000000000") End If Next i End If Next Destinationfile = TextBox2.Text + "\" + TextBox5.Text FileOpen(1, Destinationfile, OpenMode.Output) For i = 0 To Counter Print(1, SpinProgram(i) + vbCrLf) ' send to disk Next FileClose(1) End Sub Private Sub AddSpinline(ByVal Spinprogram() As String, ByRef Counter As Long, ByVal LineOfText As String) ' use byref to return counter to the calling program Spinprogram(Counter) = LineOfText Counter += 1 End Sub
I have attached the three spin files as an example. Also an example of what it would look like with words - just the DAT section for Times Roman 18 point.
Example Hello World in Arial Narrow 15 point
CON _clkmode = xtal1 + pll16x ' use crystal x 16 _xinfreq = 5_000_000 VAR byte FontHeight word CursorX word CursorY OBJ tch: "Touch" ' touchscreen driver PUB Main | i,f ' debug value tch.BeginProgram tch.Clearscreen($FFFF) ' clear the screen to white CursorX := 0 CursorY := 0 FontHeight := FontBitmap[0] PrintString(string("Hello World")) PUB PrintString(stringptr) ' print a string on the screen repeat strsize(stringptr) Text(byte[stringptr++]) PUB Text(Ascii) | w,i,row,f i := 2 + (Ascii - 32)* (FontHeight+1) ' fontheight + 1 as there is the xadvance byte w := FontBitmap[i] ' xadvance for this character tch.Draw(CursorX,CursorY,CursorX+w-1,CursorY+FontHeight-1) ' set up drawing location i += 1 ' increment pointer repeat row from 1 to FontHeight f := FontBitmap[i] ' get row of pixels i += 1 ' increment pointer repeat w if f & %10000000 ' change this if using words tch.pixel($0000) ' black else tch.pixel($FFFF) ' white background f := f << 1 ' bitshift CursorX += w ' move cursor by this character width If CursorX > 230 ' end of the line CursorX := 0 CursorY += FontHeight ' move down a line DAT FontBitmap Byte 15 ' font height Byte 12 ' base ' character 32 Byte 3 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 33 ! Byte 3 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %00000000 Byte %01000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 34 " Byte 3 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10100000 Byte %10100000 Byte %10100000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 35 # Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01010000 Byte %01010000 Byte %11111000 Byte %01010000 Byte %10100000 Byte %11111000 Byte %10100000 Byte %10100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 36 $ Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00100000 Byte %01110000 Byte %10101000 Byte %10100000 Byte %01110000 Byte %00101000 Byte %00101000 Byte %10101000 Byte %01110000 Byte %00100000 Byte %00000000 Byte %00000000 ' character 37 % Byte 8 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01000100 Byte %10101000 Byte %10101000 Byte %01010000 Byte %00010100 Byte %00011010 Byte %00101010 Byte %00100100 Byte %00000000 Byte %00000000 Byte %00000000 ' character 38 & Byte 6 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00100000 Byte %01010000 Byte %01010000 Byte %00100000 Byte %11101000 Byte %10011000 Byte %10011000 Byte %01100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 39 ' Byte 2 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 40 ( Byte 3 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %01000000 Byte %00000000 ' character 41 ) Byte 3 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %10000000 Byte %00000000 ' character 42 * Byte 4 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01000000 Byte %11100000 Byte %01000000 Byte %10100000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 43 + Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00100000 Byte %00100000 Byte %11111000 Byte %00100000 Byte %00100000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 44 , Byte 3 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01000000 Byte %01000000 Byte %10000000 Byte %00000000 ' character 45 - Byte 3 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %11000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 46 . Byte 3 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 47 / Byte 3 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00100000 Byte %00100000 Byte %00100000 Byte %01000000 Byte %01000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 48 0 Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01100000 Byte %10010000 Byte %10010000 Byte %10010000 Byte %10010000 Byte %10010000 Byte %10010000 Byte %01100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 49 1 Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00100000 Byte %01100000 Byte %10100000 Byte %00100000 Byte %00100000 Byte %00100000 Byte %00100000 Byte %00100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 50 2 Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01100000 Byte %10010000 Byte %00010000 Byte %00010000 Byte %00100000 Byte %01000000 Byte %10000000 Byte %11110000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 51 3 Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01100000 Byte %10010000 Byte %00010000 Byte %01100000 Byte %00010000 Byte %00010000 Byte %10010000 Byte %01100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 52 4 Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00010000 Byte %00110000 Byte %01010000 Byte %01010000 Byte %10010000 Byte %11111000 Byte %00010000 Byte %00010000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 53 5 Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01110000 Byte %01000000 Byte %10000000 Byte %11100000 Byte %00010000 Byte %00010000 Byte %10010000 Byte %01100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 54 6 Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01100000 Byte %10010000 Byte %10000000 Byte %10100000 Byte %11010000 Byte %10010000 Byte %10010000 Byte %01100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 55 7 Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %11110000 Byte %00010000 Byte %00100000 Byte %00100000 Byte %00100000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 56 8 Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01100000 Byte %10010000 Byte %10010000 Byte %01100000 Byte %10010000 Byte %10010000 Byte %10010000 Byte %01100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 57 9 Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01100000 Byte %10010000 Byte %10010000 Byte %10110000 Byte %01010000 Byte %00010000 Byte %10010000 Byte %01100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 58 : Byte 3 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 59 ; Byte 3 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01000000 Byte %01000000 Byte %10000000 Byte %00000000 ' character 60 < Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00010000 Byte %01100000 Byte %10000000 Byte %01100000 Byte %00010000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 61 = Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %11110000 Byte %00000000 Byte %11110000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 62 > Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10000000 Byte %01100000 Byte %00010000 Byte %01100000 Byte %10000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 63 ? Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01100000 Byte %10010000 Byte %00010000 Byte %00100000 Byte %01000000 Byte %01000000 Byte %00000000 Byte %01000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 64 @ Byte 9 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00011100 Byte %00100010 Byte %01011011 Byte %10100101 Byte %10100101 Byte %10100101 Byte %10100101 Byte %10011110 Byte %01000001 Byte %00100010 Byte %00011100 ' character 65 A Byte 6 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00100000 Byte %01010000 Byte %01010000 Byte %01010000 Byte %01010000 Byte %01110000 Byte %10001000 Byte %10001000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 66 B Byte 6 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %11110000 Byte %10001000 Byte %10001000 Byte %11110000 Byte %10001000 Byte %10001000 Byte %10001000 Byte %11110000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 67 C Byte 7 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00111000 Byte %01000100 Byte %10000100 Byte %10000000 Byte %10000000 Byte %10000100 Byte %01000100 Byte %00111000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 68 D Byte 6 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %11100000 Byte %10010000 Byte %10001000 Byte %10001000 Byte %10001000 Byte %10001000 Byte %10010000 Byte %11100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 69 E Byte 6 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %11111000 Byte %10000000 Byte %10000000 Byte %11111000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %11111000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 70 F Byte 6 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01111000 Byte %01000000 Byte %01000000 Byte %01110000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 71 G Byte 7 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00111000 Byte %01000100 Byte %10000100 Byte %10000000 Byte %10011100 Byte %10000100 Byte %01000100 Byte %00111000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 72 H Byte 6 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10001000 Byte %10001000 Byte %10001000 Byte %11111000 Byte %10001000 Byte %10001000 Byte %10001000 Byte %10001000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 73 I Byte 2 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 74 J Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00010000 Byte %00010000 Byte %00010000 Byte %00010000 Byte %00010000 Byte %10010000 Byte %10010000 Byte %01100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 75 K Byte 6 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10001000 Byte %10010000 Byte %10100000 Byte %11100000 Byte %10100000 Byte %10010000 Byte %10010000 Byte %10001000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 76 L Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %11110000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 77 M Byte 8 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10000010 Byte %11000110 Byte %11000110 Byte %10101010 Byte %10101010 Byte %10101010 Byte %10101010 Byte %10010010 Byte %00000000 Byte %00000000 Byte %00000000 ' character 78 N Byte 7 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10000100 Byte %11000100 Byte %10100100 Byte %10100100 Byte %10010100 Byte %10010100 Byte %10001100 Byte %10000100 Byte %00000000 Byte %00000000 Byte %00000000 ' character 79 O Byte 7 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00110000 Byte %01001000 Byte %10000100 Byte %10000100 Byte %10000100 Byte %10000100 Byte %01001000 Byte %00110000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 80 P Byte 6 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %11110000 Byte %10001000 Byte %10001000 Byte %10001000 Byte %11110000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 81 Q Byte 7 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00110000 Byte %01001000 Byte %10000100 Byte %10000100 Byte %10000100 Byte %10000100 Byte %01011000 Byte %00110100 Byte %00000100 Byte %00000000 Byte %00000000 ' character 82 R Byte 7 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01111000 Byte %01000100 Byte %01000100 Byte %01111000 Byte %01010000 Byte %01001000 Byte %01000100 Byte %01000010 Byte %00000000 Byte %00000000 Byte %00000000 ' character 83 S Byte 6 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01110000 Byte %10001000 Byte %10000000 Byte %01110000 Byte %00001000 Byte %10001000 Byte %10001000 Byte %01110000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 84 T Byte 6 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %11111000 Byte %00100000 Byte %00100000 Byte %00100000 Byte %00100000 Byte %00100000 Byte %00100000 Byte %00100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 85 U Byte 7 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10000100 Byte %10000100 Byte %10000100 Byte %10000100 Byte %10000100 Byte %10000100 Byte %01001000 Byte %00110000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 86 V Byte 6 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10001000 Byte %10001000 Byte %01010000 Byte %01010000 Byte %01010000 Byte %01010000 Byte %01010000 Byte %00100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 87 W Byte 8 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10010010 Byte %10101010 Byte %10101010 Byte %10101010 Byte %10101010 Byte %10101010 Byte %10101010 Byte %01000100 Byte %00000000 Byte %00000000 Byte %00000000 ' character 88 X Byte 6 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10000100 Byte %01001000 Byte %01001000 Byte %00110000 Byte %00110000 Byte %01001000 Byte %01001000 Byte %10000100 Byte %00000000 Byte %00000000 Byte %00000000 ' character 89 Y Byte 6 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10001000 Byte %01010000 Byte %01010000 Byte %00100000 Byte %00100000 Byte %00100000 Byte %00100000 Byte %00100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 90 Z Byte 6 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %11111000 Byte %00001000 Byte %00010000 Byte %00100000 Byte %00100000 Byte %01000000 Byte %10000000 Byte %11111000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 91 [ Byte 3 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %11000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %11000000 Byte %00000000 ' character 92 \ Byte 3 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10000000 Byte %10000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %00100000 Byte %00100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 93 ] Byte 3 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %11000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %11000000 Byte %00000000 ' character 94 ^ Byte 4 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01000000 Byte %10100000 Byte %10100000 Byte %10100000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 95 _ Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %11111000 Byte %00000000 Byte %00000000 ' character 96 ` Byte 3 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10000000 Byte %01000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 97 a Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %11100000 Byte %00010000 Byte %01110000 Byte %10010000 Byte %10010000 Byte %01110000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 98 b Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10000000 Byte %10000000 Byte %10100000 Byte %11010000 Byte %10010000 Byte %10010000 Byte %11010000 Byte %10100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 99 c Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01100000 Byte %10010000 Byte %10000000 Byte %10000000 Byte %10010000 Byte %01100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 100 d Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00010000 Byte %00010000 Byte %01010000 Byte %10110000 Byte %10010000 Byte %10010000 Byte %10110000 Byte %01010000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 101 e Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01100000 Byte %10010000 Byte %11110000 Byte %10000000 Byte %10010000 Byte %01100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 102 f Byte 2 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01100000 Byte %01000000 Byte %11100000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 103 g Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01010000 Byte %10110000 Byte %10010000 Byte %10010000 Byte %10110000 Byte %01010000 Byte %00010000 Byte %11100000 Byte %00000000 ' character 104 h Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10000000 Byte %10000000 Byte %10100000 Byte %11010000 Byte %10010000 Byte %10010000 Byte %10010000 Byte %10010000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 105 i Byte 2 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10000000 Byte %00000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 106 j Byte 2 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01000000 Byte %00000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %11000000 Byte %00000000 ' character 107 k Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10000000 Byte %10000000 Byte %10010000 Byte %10100000 Byte %11000000 Byte %10100000 Byte %10010000 Byte %10010000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 108 l Byte 2 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 109 m Byte 8 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10100110 Byte %11011010 Byte %10010010 Byte %10010010 Byte %10010010 Byte %10010010 Byte %00000000 Byte %00000000 Byte %00000000 ' character 110 n Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10100000 Byte %11010000 Byte %10010000 Byte %10010000 Byte %10010000 Byte %10010000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 111 o Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01100000 Byte %10010000 Byte %10010000 Byte %10010000 Byte %10010000 Byte %01100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 112 p Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10100000 Byte %11010000 Byte %10010000 Byte %10010000 Byte %11010000 Byte %10100000 Byte %10000000 Byte %10000000 Byte %00000000 ' character 113 q Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01010000 Byte %10110000 Byte %10010000 Byte %10010000 Byte %10110000 Byte %01010000 Byte %00010000 Byte %00010000 Byte %00000000 ' character 114 r Byte 3 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10100000 Byte %11000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 115 s Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %11100000 Byte %10010000 Byte %01000000 Byte %00100000 Byte %10010000 Byte %01100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 116 t Byte 2 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01000000 Byte %01000000 Byte %11100000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 117 u Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10010000 Byte %10010000 Byte %10010000 Byte %10010000 Byte %10110000 Byte %01010000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 118 v Byte 6 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10001000 Byte %10001000 Byte %01010000 Byte %01010000 Byte %01010000 Byte %00100000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 119 w Byte 8 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10010010 Byte %10101010 Byte %10101010 Byte %10101010 Byte %10101010 Byte %01000100 Byte %00000000 Byte %00000000 Byte %00000000 ' character 120 x Byte 6 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10001000 Byte %01010000 Byte %00100000 Byte %00100000 Byte %01010000 Byte %10001000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 121 y Byte 6 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10001000 Byte %01010000 Byte %01010000 Byte %01010000 Byte %00100000 Byte %00100000 Byte %00100000 Byte %01000000 Byte %00000000 ' character 122 z Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %11110000 Byte %00010000 Byte %00100000 Byte %01000000 Byte %10000000 Byte %11110000 Byte %00000000 Byte %00000000 Byte %00000000 ' character 123 { Byte 3 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %01100000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %10000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %00100000 Byte %00000000 ' character 124 | Byte 2 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %10000000 Byte %00000000 ' character 125 } Byte 3 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %11000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %00100000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %01000000 Byte %11000000 Byte %00000000 ' character 126 ~ Byte 5 ' xadvance Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %11101000 Byte %10110000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000 Byte %00000000
That format is nice to see the font, but I started this thread to show work and get ideas on my font editor that lets you visualize the font, create it, and edit it.
But, I'll provide text output options for Spin and C for cases where you'd rather have the font that way...
Guess the downside the binary format is that it doesn't include any info on height, width, etc....
Perhaps we need an optional 8 (or so) byte header that describes the font.
That way, the code can automatically know the font type and it can be imported back into the editor easily...
Think it needs: height, width, bpp, start char, end char, type (fixed, variable, etc).
Maybe make it 12 bytes with the first 4 bytes equalling "Font" for easy recognition...
but you can include a file, so why does how many lines that file has, matter ?
and also ASM ? (as then you can create a combination of Fonts into a Font ROM image )
Here you uncover the reason few use Binary files, unless they really have to.
They do not self-document, and so you need to store/archive/post TWO lots of information, the Binary file and then also the record format.
Since this font info is going thru a tool-chain step I don' t quite see that you are forced to use Binary ?
More useful to me, is an ASCII-round-trip ability - ie to Load/Edit/Save of a simple ASCII format, that can be handled by other scripts.
Maybe there's a way to make a font object file so that the text could go there...
I'm not sure what you mean by "ASM" Do you mean Propeller assembly?
BTW: In spin, you can include binary files, but not text files (at least, with the Prop Tool).
Here's what I'm thinking of for text export options (Am I missing anything?):
There do seem to be solutions now to this, and surely such a shortcoming will quickly be fixed ?
http://forums.parallax.com/showthread.php?95031-PreSpin-a-Preprocessor-for-Spin&p=655470#post655470
I see #include is top of the list here
http://propeller.wikispaces.com/Propeller+Tool+-+Enhancement+Requests
Both Prop PASM, and more general ASM, as options - the more general ASM is useful for creating SPI Flash images.
All the std assemblers I know support ; as comment, and DB as DataByte, so those are the only two syntax elements needed, and I have found some ASMs do not like very long lines.
I can see a Prop-case where it might be useful to have the Widths in a table before the Chars ?
(that would allow a quick-sum to find the char start )
With an index, you need to define size and byte order.
24 bits seems std for SPI flash up to 128MBit, but you also need a means to merge multiple fonts into that SPI flash pgm file.
(which is where the General ASM support helps ).
I'll check some ASMs, for larger Font handling, - NASM looks like a good candidate, small enough, (single EXE and < 1MB download), and supported on many OS's.
http://www.nasm.us/
NASM looks to create BIN or Intel Hex etc files, and allows includes.
Not sure about 24 bit DB - but 8/16/32/64 are all there - simplest is DD LabelName for 32 bit, little endian index.
All good points.
I suppose one big decision is whether you are going to have an SD card available. If yes, then it makes sense to put the font on the SD card as a file, in which case the file can be a lot larger. But the downside is you need SD driver code, which can take up 1/3 of hub ram. On the other hand, if you didn't have an SD card, then you might be more tempted to put the font in the code.
I'm not sure whether one is better than the other. Maybe one needs to output both binary and text?
Re descriptions of characters, the demo I wrote above is not the most efficient for memory. Fonts are padded out to 8 wide, and the height is larger than it needs to be for most characters. So you can either store the width, height, xoffset, yoffset, xadvance for each character, or you can pad them and then you only need to store the xadvance.
For the touchscreens I am using, it is quicker to dump a whole picture than it is to send the individual pixels. So a full picture of a character fully aliased is the quickest. But I don't think that is the case for TV and VGA so I think it leads you down a different path there. Certainly editing is easier with unaliased fonts. And I don't know much about true type fonts - I think characters are described with curves and lines rather than with pixels.
I guess one thing I found is there are some great online libraries of free fonts out there on the interweb.
Not sure about 24 bit DB - but 8/16/32/64 are all there - simplest is DD LabelName for 32 bit, little endian index.
Turns out the 'non scalar' error messages I got here, on the obvious (SomeLabel >> 8), are explained here :
forum.nasm.us
and NASM uses a Section Relative system, using this rule
The difference between two labels (in the same section!) is a "scalar value". The linker/loader can change the two values, but the distance between them remains the same. Therefore, we can do a calculation on it
This is not actually a problem, as a multi-file font merge, would use difference approach anyway, it just needs a specific difference syntax.
Here are some NASM examples, that work, and it can create large bin/hex files, from a simple or multiple FONT sources.
18 00000001 [2148] DW LastByte ; Gives warning as Address > 2 Byte 19 00000003 [21480100] DD LastByte 20 00000007 [2148010000000000] DQ LastByte 21 26 27 00000014 [00000000] DD $$ ; $ is PC, $$ is Section start, here it is Zero 28 00000018 01 DB (LastByte-$$) & 07H 29 00000019 2008 DW (LastByte-$$) & 0FF0H 30 31 ; Generate a 24 bit relative index 32 0000001B 28 DB ((F8x8_Char5-FONT8x8_Start) >> 0) & 0FFH 33 0000001C 00 DB ((F8x8_Char5-FONT8x8_Start) >> 8) & 0FFH 34 0000001D 00 DB ((F8x8_Char5-FONT8x8_Start) >> 16) & 0FFH 35 36 ; another section relative index, other endian, 24 bits. 37 0000001E 01 DB ((LastByte-$$) >> 16) & 0FFH 38 0000001F 48 DB ((LastByte-$$) >> 8) & 0FFH 39 00000020 21 DB ((LastByte-$$) >> 0) & 0FFH
The command line is simply
..\nasm -f ith F8X8.ASM -l F8x8.lst
ith = intel hex, or bin for binary file.
There may be people who would use this for 8051 programming anyway...
But, the output of your assembler would just be the binary file we talked about earlier...
You could just use some tool to concatenate binary files instead of going through the whole assembly process.
But maybe what we really need is a simple file system for flash...
I worked a little on one, but that's a different project...
Sounds good.
It can optionally be binary, which allows present PropTool include, but it can also be HEX, or the ASM might link into a HLL project
on AVR/8051/etc.
"concatenate binary files" is not so simple, as you usually need some means to index across fonts.
With ASM, you can easily manage that, and choose if you want relative, or absolute addresses.
ASM could also create a simple File system header, with some font info comments.
This would be a simple, master ASM that was a stack of %include's for each font, and with some index DB's added.
NASM (which I had not looked at for a while..) seems quite good for this, as it has a 'hidden' linker, and can build (very) large binary/hex files, and you can just point a single command line, and Assemble/Include any desired set of font files, all under the control of a Text editor, and with full version control. You also get a LST file, as confirmation of what happened.
The new version is in the top post.
It now saves as .rfd files, but you can still import and export Windows Bitmaps.
There are a lot of text output options now...
Haven't gotten to variable pitch yet...
Minor comments :
I would add the export settings as comments too, especially the scan ones.
I would also add a couple of ASM labels, eg
ProGoCo_8x16_Font:
so that a user can %include any series of font files, and build a simple font index using those labels.
Any Width/Offset tables, should also have labels.
Idea is they can Grab any saved Font, wiggle some pixels, export and build, without needing to edit the export file.
I guess here some means to export-the-same-as-before would be useful ?
Maybe a backup/rename of old file, could help protect users ?
I did notice there is no save-as, and save does not have an over-write warning.
Do you plan to support import/export in the xml file of glcd-font-creator ?
That would allow access to larger user base, as I get the impression that glcd is inherited and somewhat frozen.
(because they have other packages for $$$, no surprise..)
Also, if you could post a couple full xml files, that might help me figure out how to make it work.
Especially, a variable pitch font...RaysFontEditor_15Aug12.zip
Attached is xml_font_examples.zip, which is three font files.
Not sure if the simple LCD font manager can cope with variable spaced fonts ?
I did try this - which is quickly add a width modifier to 3 lines, & height to 1, and GLCD Font Creator will read this fine.
(ie it simply ignored the added WIDTH="7", HEIGHT="13" etc )
Of course, on save it removes the ignored text, but it does tolerate it nicely, so you may have a safe superset there.
<FONTSIZE WIDTH="8" HEIGHT="15" PROPORTIONAL="0" FONTKIND="0"/> <RANGE FROM="32" TO="127"/> <CHARS> <CHAR CODE="32" WIDTH="7" HEIGHT="13" PIXELS="16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215"/> <CHAR CODE="33" WIDTH="8" PIXELS="16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,0,0,0,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,0,0,0,0,0,0,0,16777215,0,0,16777215,16777215,16777215,16777215,16777215,0,0,0,0,0,0,0,16777215,0,0,16777215,16777215,16777215,16777215,16777215,16777215,0,0,0,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215"/> <CHAR CODE="34" WIDTH="9" PIXELS="16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,0,0,0,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,0,0,0,0,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,0,0,0,0,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,0,0,0,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215"/> <CHAR CODE="35" PIXELS="16777215,16777215,16777215,16777215,16777215,0,16777215,16777215,16777215,0,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,0,0,0,0,0,0,0,0,0,16777215,16777215,16777215,16777215,16777215,16777215,0,0,0,0,0,0,0,0,0,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,0,16777215,16777215,16777215,0,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,0,0,0,0,0,0,0,0,0,16777215,16777215,16777215,16777215,16777215,16777215,0,0,0,0,0,0,0,0,0,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,0,16777215,16777215,16777215,0,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215,16777215"/>
Notice I did not trim the pixel lines, and doing that does confuse GLCD Font Creator. (no surprise)
So I think the compatibility rule is to use a largest-box for the header, and always export to that size, but allow the width modifier per character to optionally trim below that. ( left justified ? )
I guess also Height could be variable too..
So you can load any of their files and save read-compatible, but add Width to this format.
Made an intial stab at variable pitch capture too...
Try this one: RaysFontEditor_16Aug12.zip
I'm getting close to calling it done...
Just need to implement the variable pitch export options and add some additional controls...
Comments:
Import via paste still fails, looks like a simple paste-limit issue.
Import via Read from File looks OK.
Export into GLCK Font creator locks up.
You can get a free copy here :
http://www.mikroe.com/eng/downloads/get/1654/glcd_font_creator_v120.zip
I spotted three easily fixed issues in a quick glance at the file
- Missing tail lines
</CHARS>
</FONT>
- bonus CR instead of CRLF
- Extra quote in the <RANGE FROM="32" TO="127""/>
I also see Import 'clobbers' the currently open font, without prompting for a new option. Not a nice default.
It crashed once, when I was checking save / save-as with a few fonts open.
Not easy to reproduce, but I suspect some 'cross pollination' effect as the message said something about Sizes
Also, I'll add an "undo" and "redo" option that should address your clobbering...
Let me know if you can figure out what makes it crash...
See attached screen shot.
This was after a XML import from a GLCD font, and fails @ save.
Some seem to XML import/save ok, some do not.
I also see that a 21x22 font imported, renders fine, but double-click to edit, selects a char somewhere else...
(ie the selected-char decision, is not quite properly applying the real font size )
I have not seen a crash on load (except on a file that crashed on save, and that's not a fair test..)
So the LCD files seem to import, and render as I would expect, but maybe some info needed for save, is not
properly updated ?
If you download GLCD and NewFont.ImportSystemFont, you can quickly create a series of .LCD test files, of various XY sizes.
Suggestion:
The whole font preview is great, but as it zooms, it crops off the screen, even tho there is plenty of render space.
A simple binary size makes sense, but fitting all the chars is also important.
Perhaps a user Chars-per-row, and even a re-size option on the render area ?
I'm thinking of a screen-grab as a quick and simple means to document fonts and changes.
(I've added a font grab example, of a screen grab saved as .png )
Anyway, I think I've fixed all the things you found...
Also, it can now export variable pitch in a way that I think Dr_Acula wanted...
Please try this version: RaysFontEditor_17Aug12.zip
Some house-keeping issues :
a) When I select XML format, it should flip the import default from .txt, to .lcd { Saves mouse clicks...}
b) Import into a blank sheet, should apply the imported name.
c) I see the cursor shows Dec/Hex Chr value, - would be nice if the Character Editor did that too, maybe in the top line ?
d) Copy / Paste of chars is nifty, but it only works in a pre-valid slot ?
If I import a file < 256, and copy/paste 'Q' into a visible, but not white BG cell, it does nothing.
I can copy-over into any white BG cell.
e) I see the Editor has the same issue - It opens, and I can flip pixels, but it will not save into a not white BG cell
(ie does not create a new Char position)
I'm not sure needing a blank page before import is a good idea.
Import should be like any text editor, it should default to a NEW page, (named as the import file ), but allow experienced users to merge-import over the top of an open font. (with warnings)
Right now, it does not merge import over an open font, it wipes the whole sheet.
ie I quickly edited a XML file, to place 'Q' in CHR0 location, and I should be able to import that, into an open font (of the same XY) and have 'Q' pop into @0, with the rest of the font untouched.
Single char import works, apart from the unwanted clear-all first.
Edit: To clarify, the import file may have one or more chars, and even be sparse, and they should merge-over and create new chars if needed. Export should be only of defined chars, and may also be sparse.
A common use is to harvest std forts for the lower 128, and use more custom sources for > 128 and sometimes < 32.
Actually, I think it did paste before, you just can't see it because of the font's character range setting...
I do want the imports not to clear the existing font before importing... I'll have to figure out how to do that..
Yes, I can paste into hidden chars, and then on manual adjust of the limits, they become visible.
So, perhaps a user paste could auto-adjust-limits, to make it WYSIWYG ?
RaysFontEditor_20Aug12.zip
Looks nice.
Paste Auto adjusts nicely.
However, I see manual edit does not. Even tho Edit.OK works, I have to manually go into FontSettings, to 'see' the newly edited char, if it is outside the bounds. This should auto-adjust-limits the same as paste.
Width control is good, but this will also need a means to move the whole char ( << Char and Char >> ? )
and I guess height and Char Up Char Dn set, almost complete the tile controls.
One feature I have frequently wanted, is an font insert/delete row/column, (just like in a spread sheet).
Applied to a font it would default to copy of the indicated row/column - used to easily stretch/trim characters, that are almost a fit.
Import still over-writes a non-empty slate, and import merge instead clears - still on the to-do list I guess.
I thought I had the import the way you wanted it...
I have a single Char .lcd file (actually Q in Chr(0) ), and import of that into an open-font, still clears the whole font ?
Also, import into any open (non blank) font, should ask if the user wants a new window (default) or Merge/replace.
ie It is too easy to over-write an existing font.
I don't see a 'about' or build version anywhere ?
Edit:
This is what I mean, is that supposed to be working on this build ?
I'll try to get to that today or early tomorrow... Thanks.
There should be a tiny "about" button close to the top right corner of the window...
I'm trying to figure out how to do this... Can you please explain some more exactly what you'd like?
Do you want to add a blank column? Or, do you want to insert a copy of a column to the left or right?
Do you want this to operate on the whole font, or just one character?
Here's the latest version with many of the suggestions implemented:
RaysFontEditor_22Aug12.zip
Where I've done this, is to clean-up, or scale imported fonts.
The LCD editor pgm mentioned before, adds blank rows/columns but this is limited to edges. - so it is part way there.
A Move Char U/D/L/R would effectively add a blank row on one edge, and remove on the other, keeping tile size
Works like the 'Hand' control in Acrobat - the Font just moves within the tile
A insert Row/Col, would take the cursor as a prompt, and usually copy, the selected R/C, but blank might be a user option
SW based Insert saves a LOT of clicks over 'insert manually'.
Of course, the question then rises of which surplus stripe is trimmed, after insert
Since variable width is supported, maybe a delete row/col is all that is needed, but a user might accidently make a 17x8 tile ?
The spread sheet method, users should already know/understand and that is a simple insert/delete, and there you can select/copy any r/c if you want a copy.
Pixel-rectangle select/copy/paste would be sweet, but might be over-engineering this ?