Microsoft Small Basic

Program Listing: NJB522-0
' Measure All Character Widths in Pixels
' Version 0.2
' Copyright © 2014-2016 Nonki Takahashi. The MIT License.
'
' History:
' 0.2 2016-08-08 Changed character set and output format. (NJB522-0)
' 0.1 2014-06-23 Created from KTK906-1. (NJB522)
'
GraphicsWindow.Title = "Measure All Character Widths in Pixels 0.2"
Init()
Main()

Sub Init
CRLF = Text.GetCharacter(13) + Text.GetCharacter(10)
WQ = Text.GetCharacter(34)
c = "32= ;33=!;34=" + WQ + ";35=#;36=$;37=%;38=&;39=';40=(;41=);42=*;43=+;44=,;45=-;46=.;47=/;"
c = c + "48=0;49=1;50=2;51=3;52=4;53=5;54=6;55=7;56=8;57=9;58=:;59=\;;60=<;61=\=;62=>;63=?;"
c = c + "64=@;65=A;66=B;67=C;68=D;69=E;70=F;71=G;72=H;73=I;74=J;75=K;76=L;77=M;78=N;79=O;"
c = c + "80=P;81=Q;82=R;83=S;84=T;85=U;86=V;87=W;88=X;89=Y;90=Z;91=[;92=\\;93=];94=^;95=_;"
c = c + "96=`;97=a;98=b;99=c;100=d;101=e;102=f;103=g;104=h;105=i;106=j;107=k;108=l;109=m;110=n;111=o;"
c = c + "112=p;113=q;114=r;115=s;116=t;117=u;118=v;119=w;120=x;121=y;122=z;123={;124=|;125=};126=~;"
c = c + "160= ;161=¡;162=¢;163=£;164=¤;165=¥;166=¦;167=§;168=¨;169=©;170=ª;171=«;172=¬;173=­;174=®;175=¯;"
c = c + "176=°;177=±;178=²;179=³;180=´;181=µ;182=¶;183=·;184=¸;185=¹;186=º;187=»;188=¼;189=½;190=¾;191=¿;"
c = c + "192=À;193=Á;194=Â;195=Ã;196=Ä;197=Å;198=Æ;199=Ç;200=È;201=É;202=Ê;203=Ë;204=Ì;205=Í;206=Î;207=Ï;"
c = c + "208=Ð;209=Ñ;210=Ò;211=Ó;212=Ô;213=Õ;214=Ö;215=×;216=Ø;217=Ù;218=Ú;219=Û;220=Ü;221=Ý;222=Þ;223=ß;"
c = c + "224=à;225=á;226=â;227=ã;228=ä;229=å;230=æ;231=ç;232=è;233=é;234=ê;235=ë;236=ì;237=í;238=î;239=ï;"
c = c + "240=ð;241=ñ;242=ò;243=ó;244=ô;245=õ;246=ö;247=÷;248=ø;249=ù;250=ú;251=û;252=ü;253=ý;254=þ;255=ÿ;"
Not = "False=True;True=False"
gw = 598
gh = 428
GraphicsWindow.Width = gw
GraphicsWindow.Height = gh
GraphicsWindow.BrushColor = "LightGray"
yc = 140
GraphicsWindow.FillRectangle(0, 0, gw, yc)
GraphicsWindow.BrushColor = "Black"
GraphicsWindow.DrawText(10, 10, "Font")
font = Controls.AddTextBox(50, 10)
fontname = "Arial" 'GraphicsWindow.FontName
Controls.SetTextBoxText(font, fontname)
GraphicsWindow.DrawText(10, 40, "Size")
size = Controls.AddTextBox(50, 40)
Controls.SetTextBoxText(size, 100) 'GraphicsWindow.FontSize)
GraphicsWindow.DrawText(260, 10, "Bold")
bold = Controls.AddTextBox(300, 10)
Controls.SetTextBoxText(bold, GraphicsWindow.FontBold)
btn = Controls.AddButton("Measure", 10, 100)
GraphicsWindow.DrawText(260, 40, "Width")
width = Controls.AddMultiLineTextBox(300, 40)
clicked = "False"
Controls.ButtonClicked = OnButtonClicked
EndSub

Sub OnButtonClicked
clicked = "True"
EndSub

Sub Main
While "True"
If clicked Then
GraphicsWindow.BrushColor = "White"
GraphicsWindow.FillRectangle(0, yc, gw, gh - yc)
fs = Controls.GetTextBoxText(size)
GraphicsWindow.FontSize = fs
GraphicsWindow.FontName = Controls.GetTextBoxText(font)
GraphicsWindow.FontBold = Controls.GetTextBoxText(bold)
GraphicsWindow.BrushColor = "Black"
GraphicsWindow.DrawText(0, yc, "||")
y0 = yc
y1 = yc + fs
x0 = 0
x1 = fs * 2
If gw < x1 Then
x1 = gw - 1
EndIf
Measure()
px0 = px
n = Array.GetItemCount(c)
index = Array.GetAllIndices(c)
cw = ""
For i = 1 To n
GraphicsWindow.BrushColor = "White"
GraphicsWindow.FillRectangle(0, yc, gw, gh - yc)
GraphicsWindow.BrushColor = "Gray"
GraphicsWindow.FillRectangle(0, yc + fs, gw, 1)
str = "|" + c[index[i]] + "|"
GraphicsWindow.BrushColor = "Black"
GraphicsWindow.DrawText(0, yc, str)
x1 = fs * Text.GetLength(str)
If gw < x1 Then
x1 = gw - 1
EndIf
Measure()
cw[Text.GetCharacterCode(c[index[i]])] = px
EndFor
Format()
Controls.SetTextBoxText(width, output)
clicked = "False"
Else
Program.Delay(100)
EndIf
EndWhile
EndSub

Sub Format
' param cw - character width array
' param fontname - font name
' return output - output text
n = Array.GetItemCount(cw)
index = Array.GetAllIndices(cw)
header = "ratio = ratio + " + WQ
output = "' width/height [%] of each character in " + fontname + " font" + CRLF
output = output + "GraphicsWindow.FontName = " + WQ + fontname + WQ + CRLF
output = output + "ratio = " + WQ
ll = 9 ' length of line
For i = 1 To n
entry = index[i] + "=" + cw[index[i]] + ";"
le = Text.GetLength(entry) ' length of entry
If 70 < ll + le + 1 Then
output = output + WQ + CRLF + header
ll = Text.GetLength(header)
EndIf
output = output + entry
ll = ll + le
EndFor
output = output + WQ
EndSub

Sub Measure
' return px
y = Math.Floor((y0 + y1) / 2)
For x = x0 To x1
color = GraphicsWindow.GetPixel(x, y)
If Not[Text.EndsWith(color, "FFFFFF")] Then
left = x
x = x1 ' break
EndIf
EndFor
For x = x1 To x0 Step -1
color = GraphicsWindow.GetPixel(x, y)
If Not[Text.EndsWith(color, "FFFFFF")] Then
right = x
x = x0 ' break
EndIf
EndFor
For x = right To x0 Step -1
color = GraphicsWindow.GetPixel(x, y)
If Text.EndsWith(color, "FFFFFF") Then
right = x + 1
x = x0 ' break
EndIf
EndFor
px = right - left
EndSub