- PB 4.41+
- UNICODE characters supported
- I sued only common gadgets (I removed the openscreenwindow())
- using imageGadgets with alpha-blend
- using thread for rendering
- It contains an Editor and an Tester
- cross-platform (Mac, Linux, Windows.... it does not work with windows version older than XP)
This example will help you to code editor without using any windowed screen.
Thanks to Alpha-channel improvements

http://www.purebasic.fr/blog/?p=131
N.B.: the final version will be included in the Sprite 3D engine FX

Code: Select all
EnableExplicit
CompilerIf #PB_Compiler_Unicode=0
;this program is fully functionnal only if the UNICODE option is enabled
MessageRequester("Compiler Options", "Enable the following option: Create Unicode Executable")
CompilerEndIf
Declare GetSpaceWidth()
Declare DrawExportedChar()
Declare DrawExportedCharList(mode=0)
Declare CreateSettingsMenu()
Global CharList.s
Global CharFntStyle
Global CharFntSize=24
Global CharFntName.s;="Arial"
Global CharColor=RGB(1, 2, 3)
Global CharSpaceWidth
Structure CharMap
;character parameters
c.s{1}
cw.i
ch.i
;character image
x.i
y.i
w.i
h.i
right.i
bottom.i
offx.i
offy.i
;drawing character
posx.i
posy.i
EndStructure
Global NewMap CharMap.CharMap()
Global Dim CharMargin(3)
Global Dim CharMinSize(1)
Global ExportX
Global ExportY
Global ExportLineHeight
Global ExportStopped
Global DrawThread
Global DrawMutex=CreateMutex()
Global Dim ExportSize(4, 1)
Global ScrW=532
Global ScrH=532
Global ScrBackColor
Global ScrPointerColor=RGB(255, 255, 200)
Global ScrGridImg
Global NewMap ScrGridImg()
Enumeration 100
;gadgets
#SplitterTest
#ScrollViewport
#ScrollTest
#ImgPointer
#ImgCharList
#ImgGrid
#ImgTest
#PnlFont
#ComboTextureSize
#ComboFont
#BtnFont
#BtnColor
#BtnScrColor
#BtnCharRange
#BtnCharMargin
#BtnTest
#BtnExport
#CheckMinW
#CheckMinH
#StrMinW
#StrMinH
#CheckBold
#CheckItalic
#SpinSize
#StrCharRange1
#StrCharRange2
#StrCharMargin1
#StrCharMargin2
#StrCharMargin3
#StrCharMargin4
#EditCharRange
#EditTest
#Progress
#Menu_First
#MenuGrid
#MenuGrid1
#MenuGrid2
#MenuGrid3
#MenuGrid4
#MenuGrid5
#MenuGrid6
#MenuPointer1
#MenuPointer2
#MenuPointer3
#MenuScreen1
#MenuScreen2
#Menu_Last
#ListColor
#ListScrColor
#TimerPointer
#TimerDrawingStart
#TimerDrawingInProgress
;fonts
#FntChar
#FntCharNoStyle
#FntCharTest
#FntCharRange
;images
#BmpChar
#BmpCharList
#BmpScrGridTiles
#BmpScrPointer
#BmpTest
;drawing steps
#Draw_Delayed=0
#Draw_Start
#Draw_Thread
#Draw_InProgress
#Draw_End
;window size
#w=820
#h=580
EndEnumeration
Procedure AddMenuColor(ID, name.s, c1, c2=#PB_Ignore)
;create grid icon
Protected w=8, ww=16
Protected menuColor=CreateImage(#PB_Any, ww, ww, 32)
StartDrawing(ImageOutput(menuColor))
If Alpha(c1)
Box(0, 0, ww, ww, RGB(255, 255, 255))
DrawingMode(#PB_2DDrawing_AlphaBlend)
EndIf
Box(0, 0, ww, ww, c1)
If c2<>#PB_Ignore
Box(0, 0, w, w, c2)
Box(w, w, w, w, c2)
EndIf
StopDrawing()
;create grid image
w=32
ww=64
Protected gridImg=CreateImage(#PB_Any, ww, ww, 32)
StartDrawing(ImageOutput(gridImg))
If Alpha(c1)
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0, 0, ww, ww, 0)
DrawingMode(#PB_2DDrawing_AlphaBlend)
EndIf
Box(0, 0, ww, ww, c1)
If c2<>#PB_Ignore
Box(0, 0, w, w, c2)
Box(w, w, w, w, c2)
EndIf
StopDrawing()
;add menu item
MenuItem(ID, name, ImageID(menuColor))
AddMapElement(ScrGridImg(), name)
ScrGridImg()=gridImg
EndProcedure
Procedure AddFontName(fontname.s)
;find if exists
If GetGadgetText(#ComboFont)=fontname
ProcedureReturn
EndIf
;insert font name
Protected i
For i=0 To CountGadgetItems(#ComboFont)-1
If GetGadgetItemText(#ComboFont, i)>fontname
Break
EndIf
Next
AddGadgetItem(#ComboFont, i, fontname)
SetGadgetText(#ComboFont, fontname)
EndProcedure
Procedure AddFontColor(color)
;find if exists
Protected i
For i=0 To CountGadgetItems(#listColor)-1
If GetGadgetItemData(#listColor, i)=color
SetGadgetState(#ListColor, i)
ProcedureReturn
EndIf
Next
;insert font color
Protected colorBox=CreateImage(#PB_Any, 16, 16, 24)
StartDrawing(ImageOutput(colorBox))
Box(0, 0, 16, 16, color)
StopDrawing()
AddGadgetItem(#listColor, -1, RSet(Hex(Red(color)), 2, "0")+RSet(Hex(Green(color)), 2, "0")+RSet(Hex(Blue(color)), 2, "0"), ImageID(colorBox))
SetGadgetItemData(#ListColor, CountGadgetItems(#ListColor)-1, color)
SetGadgetState(#ListColor, CountGadgetItems(#ListColor)-1)
EndProcedure
Procedure SetPointerColor(menuPointer)
;update menu item
Protected m
For m=#MenuPointer1 To #MenuPointer3 : SetMenuItemState(0, m, #False) : Next
SetMenuItemState(0, menuPointer, #True)
;get grid tile image
Protected pointerImg=ScrGridImg(GetMenuItemText(0, menuPointer))
StartDrawing(ImageOutput(pointerImg))
DrawingMode(#PB_2DDrawing_AlphaBlend)
Protected pointerColor=Point(1, 1)
StopDrawing()
If ScrPointerColor<>pointerColor
ScrPointerColor=pointerColor
StartDrawing(ImageOutput(#BmpScrPointer))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0, 0, ImageWidth(#BmpScrPointer), ImageHeight(#BmpScrPointer), 0)
DrawingMode(#PB_2DDrawing_AlphaBlend)
Box(0, 0, ImageWidth(#BmpScrPointer), ImageHeight(#BmpScrPointer), ScrPointerColor)
StopDrawing()
EndIf
EndProcedure
Procedure SetGridColor(menuGrid=#PB_Ignore)
Protected gridImg
If menuGrid=#PB_Ignore
;reset grid tile image
gridImg=ScrGridImg
ScrGridImg=0
Else
;get grid tile image
gridImg=ScrGridImg(GetMenuItemText(0, menuGrid))
;update menu item
Protected m
For m=#MenuGrid1 To #MenuGrid6 : SetMenuItemState(0, m, #False) : Next
SetMenuItemState(0, menuGrid, #True)
EndIf
If ScrGridImg<>gridImg
ScrGridImg=gridImg
;draw tiled grid
CreateImage(#BmpScrGridTiles, ImageWidth(#BmpCharList), ImageHeight(#BmpCharList), 32)
StartDrawing(ImageOutput(#BmpScrGridTiles))
Protected i, j
For j=0 To ImageHeight(#BmpCharList) Step 64
For i=0 To ImageWidth(#BmpCharList) Step 64
DrawImage(ImageID(ScrGridImg), i, j)
Next
Next
StopDrawing()
;refresh grid content
SetGadgetState(#ImgGrid, ImageID(#BmpScrGridTiles))
EndIf
EndProcedure
Procedure SetScreenBack(menuScreen)
;update menu item
Protected m
For m=#MenuScreen1 To #MenuScreen2 : SetMenuItemState(0, m, #False) : Next
SetMenuItemState(0, menuScreen, #True)
;get grid tile image
Protected screenImg=ScrGridImg(GetMenuItemText(0, menuScreen))
Protected screenColor
If menuScreen=#MenuScreen2
screenColor=ColorRequester(ScrBackColor)
If screenColor>-1
StartDrawing(ImageOutput(screenImg))
Box(0, 0, OutputWidth(), OutputHeight(), screenColor)
StopDrawing()
ScrBackColor=screenColor
SetGadgetColor(#ScrollViewport, #PB_Gadget_BackColor, ScrBackColor)
CreateSettingsMenu()
EndIf
ProcedureReturn
EndIf
StartDrawing(ImageOutput(screenImg))
screenColor=Point(1, 1)
StopDrawing()
ScrBackColor=screenColor
SetGadgetColor(#ScrollViewport, #PB_Gadget_BackColor, ScrBackColor)
EndProcedure
Procedure SetCharList(char1.U, char2.U)
If char1>=0 And char1<char2 And char2<=65535
Protected lg=char2-char1+1
Protected unicodeCharList.s=Space(lg)
Protected i.i
For i=1 To lg
PokeU(@unicodeCharList+i*SizeOf(Character), char1+(i-1))
Next
CharList=unicodeCharList
Protected CharListSplitted.s, max=20
Protected CharListOriginal.s=unicodeCharList
While CharListOriginal
CharListSplitted+Left(CharListOriginal, max)+#CRLF$
CharListOriginal=Mid(CharListOriginal, max+1)
Wend
SetGadgetText(#EditCharRange, CharListSplitted)
ProcedureReturn
EndIf
CharList="ERROR"
EndProcedure
Procedure SetCharMargin(left, top=#PB_Ignore, right=#PB_Ignore, bottom=#PB_Ignore)
If top=#PB_Ignore
top=left
right=left
bottom=left
EndIf
If CharMargin(0)<>left Or CharMargin(1)<>top Or CharMargin(2)<>right Or CharMargin(3)<>bottom
CharMargin(0)=left
CharMargin(1)=top
CharMargin(2)=right
CharMargin(3)=bottom
;redraw all characters and refresh image content
DrawExportedCharList()
EndIf
EndProcedure
Procedure SetCharMinSize(MinW, MinH)
If CharMinSize(0)<>MinW Or CharMinSize(1)<>MinH
CharMinSize(0)=MinW
CharMinSize(1)=MinH
;redraw all characters and refresh image content
DrawExportedCharList()
EndIf
EndProcedure
Procedure SetCharColor(color)
If CharColor<>color And color>-1
CharColor=color
;colorise character
StartDrawing(ImageOutput(#BmpChar))
DrawingMode(#PB_2DDrawing_Default)
Box(0, 0, 512, 512, CharColor)
StopDrawing()
;colorise character list
If IsImage(#BmpCharList)
StartDrawing(ImageOutput(#BmpCharList))
DrawingMode(#PB_2DDrawing_Default)
Box(0, 0, ImageWidth(#BmpCharList), ImageHeight(#BmpCharList), CharColor)
StopDrawing()
SetGadgetState(#ImgCharList, ImageID(#BmpCharList))
EndIf
EndIf
EndProcedure
Procedure SetCharFont(fontname.s, fontsize, fontbold, fontitalic)
Protected fontstyle
If fontbold : fontstyle | #PB_Font_Bold : EndIf
If fontitalic : fontstyle | #PB_Font_Italic : EndIf
;check if font has been modified
If CharFntName<>fontname Or CharFntStyle<>fontstyle Or CharFntSize<>fontsize
CharFntName=fontname
CharFntStyle=fontstyle
CharFntSize=fontsize
;load font
LoadFont(#FntChar, CharFntName, CharFntSize, CharFntStyle | #PB_Font_HighQuality)
LoadFont(#FntCharNoStyle, CharFntName, CharFntSize, 0)
LoadFont(#FntCharRange, CharFntName, 8, CharFntStyle | #PB_Font_HighQuality)
LoadFont(#FntCharTest, CharFntName, 32, CharFntStyle | #PB_Font_HighQuality)
;use font for char range
SetGadgetFont(#EditCharRange, FontID(#FntCharRange))
;use font for tested font
SetGadgetFont(#EditTest, FontID(#FntCharTest))
;redraw all characters and refresh image content
DrawExportedCharList()
EndIf
EndProcedure
Procedure GetSpaceWidth()
StartDrawing(ImageOutput(#BmpChar))
DrawingFont(FontID(#FntChar))
Protected w=TextWidth(" ")
StopDrawing()
ProcedureReturn w
EndProcedure
Procedure GetCharSpecial()
StartDrawing(ImageOutput(#BmpChar))
DrawingFont(FontID(#FntChar))
With CharMap()
AddMapElement(CharMap(), " ") : \c=MapKey(CharMap()) : \cw=TextWidth(\c) : \ch=0
AddMapElement(CharMap(), Chr(9)) : \c=MapKey(CharMap()) : \cw=TextWidth(\c) : \ch=0
AddMapElement(CharMap(), Chr(10)) : \c=MapKey(CharMap()) : \cw=0 : \ch=TextHeight(\c)
EndWith
StopDrawing()
EndProcedure
Procedure GetCharParams(c.s)
StartDrawing(ImageOutput(#BmpChar))
;get char metrics (don't use no style)
DrawingFont(FontID(#FntCharNoStyle))
Protected cw=TextWidth(c)
Protected ch=TextHeight(c)
If cw And ch
Protected txt.s=" "+c+" "
Protected txtw=TextWidth(txt)
Protected txth=TextHeight(txt)
Protected w=txtw
Protected h=txth
Protected posx=0
Protected posy=0
;{/// special case for big font (character will be centered and truncated)
If txtw>ImageWidth(#BmpChar)
Protected centerx=(ImageWidth(#BmpChar)-txtw)/2
txtw=ImageWidth(#BmpChar)
w=txtw
EndIf
If txth>ImageHeight(#BmpChar)
Protected centery=(ImageHeight(#BmpChar)-txth)/2
txth=ImageHeight(#BmpChar)
h=txth
EndIf
;}
;{/// draw character mask
DrawingFont(FontID(#FntChar))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0, 0, 512, 512, 0)
FrontColor(RGBA(0, 0, 0, 255))
BackColor(RGBA(0, 0, 0, 0))
DrawText(centerx, centery, txt)
;}
;{/// trim spaces
Protected trimSpaces=1
If trimSpaces
Protected dx1, dx2, dy1, dy2
;left space
dy2=txth-1
dx2=txtw-1
For dx1=0 To dx2
For dy1=0 To dy2
If (Alpha(Point(dx1, dy1)))
Break 2
EndIf
Next
Next
posx=-dx1
;right space
For dx1=dx2 To 0 Step-1
For dy1=0 To dy2
If (Alpha(Point(dx1, dy1)))
Break 2
EndIf
Next
Next
w=(dx1+1)+posx
;top space
For dy1=0 To dy2
For dx1=0 To dx2
If (Alpha(Point(dx1, dy1)))
Break 2
EndIf
Next
Next
posy=-dy1
;bottom space
For dy1=dy2 To 0 Step-1
For dx1=0 To dx2
If (Alpha(Point(dx1, dy1)))
Break 2
EndIf
Next
Next
h=(dy1+1)+posy
EndIf
;}
EndIf
StopDrawing()
If h>0 And w>0
;add margin
posx+CharMargin(0)
posy+CharMargin(1)
w+CharMargin(2)+CharMargin(0)
h+CharMargin(3)+CharMargin(1)
If w<CharMinSize(0)
posx+Round((CharMinSize(0)-w)/2, #PB_Round_Down)
w=CharMinSize(0)
EndIf
If h<CharMinSize(1)
posy+Round((CharMinSize(1)-h)/2, #PB_Round_Down)
h=CharMinSize(1)
EndIf
;new character params
CompilerIf #PB_Compiler_Version>441
CharMap(c)\c=c
CompilerElse
AddMapElement(CharMap(), c)
CharMap()\c=c
CompilerEndIf
CharMap()\cw=cw
CharMap()\ch=ch
;character drawing params
CharMap()\w=w
CharMap()\h=h
CharMap()\offx=posx+centerx+CharSpaceWidth
CharMap()\offy=posy+centery
;export position
CharMap()\posx=posx
CharMap()\posy=posy
DrawExportedChar()
EndIf
EndProcedure
Procedure WaitDrawThreadEnd()
If DrawThread And IsThread(DrawThread)
LockMutex(DrawMutex)
KillThread(DrawThread)
DrawThread=0
UnlockMutex(DrawMutex)
RemoveWindowTimer(0, #TimerDrawingInProgress)
EndIf
EndProcedure
Procedure DrawExportedChar()
StartDrawing(ImageOutput(#BmpCharList))
;jump to next line
If (ExportX+CharMap()\w)>=ImageWidth(#BmpCharList)
ExportX=0
ExportY+ExportLineHeight
ExportLineHeight=0
;if the next line is offsreen...
If (ExportY+CharMap()\h)>=ImageHeight(#BmpCharList)
ExportStopped=#True
EndIf
EndIf
If ExportStopped
DeleteMapElement(CharMap(), CharMap()\c)
Else
;draw exported character
CharMap()\x=ExportX
CharMap()\y=ExportY
CharMap()\right=ExportX+CharMap()\w
CharMap()\bottom=ExportY+CharMap()\h
DrawAlphaImage(ImageID(#BmpChar), CharMap()\x+CharMap()\posx, CharMap()\y+CharMap()\posy)
If ExportLineHeight<CharMap()\h
ExportLineHeight=CharMap()\h
EndIf
;go to next position
ExportX+CharMap()\w
EndIf
StopDrawing()
EndProcedure
Procedure DrawExportedCharList(mode=#Draw_Delayed)
Select mode
Case #Draw_Delayed
AddWindowTimer(0, #TimerDrawingStart, 200)
Case #Draw_Start
RemoveWindowTimer(0, #TimerDrawingStart)
;wait for end of previous drawing thread
WaitDrawThreadEnd()
;reset space width
CharSpaceWidth=GetSpaceWidth()
;reset exporter parameters
ExportX=0
ExportY=0
ExportLineHeight=0
ExportStopped=#False
ClearMap(CharMap())
;clear image to export
StartDrawing(ImageOutput(#BmpCharList))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0, 0, ImageWidth(#BmpCharList), ImageHeight(#BmpCharList), 0)
StopDrawing()
SetGadgetState(#ImgCharList, ImageID(#BmpCharList))
;draw each caracter (=> thread)
DrawThread=CreateThread(@DrawExportedCharList(), #Draw_Thread)
AddWindowTimer(0, #TimerDrawingInProgress, 100)
;update progress bar
SetGadgetState(#Progress, 0)
;disable buttons
DisableGadget(#BtnExport, 1)
Case #Draw_Thread
;draw each caracter (and get char parameters)
Protected i
For i=1 To Len(CharList)
LockMutex(DrawMutex)
GetCharParams(Mid(CharList, i, 1))
UnlockMutex(DrawMutex)
Delay(10)
If ExportStopped : Break : EndIf
Next
LockMutex(DrawMutex)
GetCharSpecial()
UnlockMutex(DrawMutex)
Case #Draw_InProgress
;draw temporary image
;* reduce flickering
;* smooth rendering
LockMutex(DrawMutex)
StartDrawing(WindowOutput(0))
Protected x=GetGadgetAttribute(#ScrollViewport, #PB_ScrollArea_X)
Protected y=GetGadgetAttribute(#ScrollViewport, #PB_ScrollArea_Y)
Protected w=GadgetWidth(#ScrollViewport)
Protected h=GadgetHeight(#ScrollViewport)
If GetGadgetAttribute(#ScrollViewport, #PB_ScrollArea_InnerWidth)>w : w-20 : EndIf
If GetGadgetAttribute(#ScrollViewport, #PB_ScrollArea_InnerHeight)>h : h-20 : EndIf
Protected img=GrabImage(#BmpCharList, #PB_Any, x, y, w, h)
DrawAlphaImage(ImageID(img), 0, 0, 25)
FreeImage(img)
StopDrawing()
;update progress bar
SetGadgetState(#Progress, 100*MapSize(CharMap())/Len(CharList))
UnlockMutex(DrawMutex)
Case #Draw_End
;draw final image
SetGadgetState(#ImgCharList, ImageID(#BmpCharList))
RemoveWindowTimer(0, #TimerDrawingInProgress)
DrawThread=0
;update progress bar
SetGadgetState(#Progress, 100)
;enable buttons
DisableGadget(#BtnExport, 0)
EndSelect
EndProcedure
Procedure DrawTestedFont()
If TryLockMutex(DrawMutex)
StartDrawing(ImageOutput(#BmpTest))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0, 0, OutputWidth(), OutputHeight(), 0)
DrawingMode(#PB_2DDrawing_AlphaBlend)
Protected txt.s=GetGadgetText(#EditTest)
txt=ReplaceString(txt, Chr(13)+Chr(10), Chr(10))
txt=ReplaceString(txt, Chr(13), Chr(10))
Protected x=5, y=5, i
For i=1 To Len(txt)
Protected c.s=Mid(txt, i, 1)
Select c
Case Chr(10)
;special char (linefeed)
y+CharMap(c)\ch
x=5
Case " ", Chr(9)
;special char (spaces)
x+CharMap(c)\cw
Default
;draw common char (if exists)
If FindMapElement(CharMap(), c)
Protected img=GrabImage(#BmpCharList, #PB_Any, CharMap()\x, CharMap()\y, CharMap()\w, CharMap()\h)
DrawImage(ImageID(img), x-CharMap()\offx, y-CharMap()\offy)
FreeImage(img)
x+CharMap()\cw
EndIf
EndSelect
Next
DrawingMode(#PB_2DDrawing_Default)
Box(0, 0, OutputWidth(), OutputHeight(), RGB(255, 255, 255))
StopDrawing()
SetGadgetState(#ImgTest, ImageID(#BmpTest))
UnlockMutex(DrawMutex)
EndIf
EndProcedure
Procedure DrawScreenPointer()
If DrawThread=0 Or IsThread(DrawThread)=0
Protected mx=WindowMouseX(0)+GetGadgetAttribute(#ScrollViewport, #PB_ScrollArea_X)
Protected my=WindowMouseY(0)+GetGadgetAttribute(#ScrollViewport, #PB_ScrollArea_Y)
ForEach CharMap()
If mx>=CharMap()\x And my>=CharMap()\y And mx<CharMap()\right And my<CharMap()\bottom
If GadgetX(#ImgPointer)<>CharMap()\x Or GadgetY(#ImgPointer)<>CharMap()\Y
HideGadget(#ImgPointer, 1)
;position
ResizeGadget(#ImgPointer, CharMap()\x, CharMap()\y, CharMap()\w, CharMap()\h)
;size
ResizeImage(#BmpScrPointer, CharMap()\w, CharMap()\h, #PB_Image_Raw)
;refresh
SetGadgetState(#ImgPointer, ImageID(#BmpScrPointer))
HideGadget(#ImgPointer, 0)
EndIf
ProcedureReturn
EndIf
Next
EndIf
HideGadget(#ImgPointer, 1)
EndProcedure
Procedure ResizeExport(width, height)
If IsImage(#BmpCharList) And width=ImageWidth(#BmpCharList) And height=ImageHeight(#BmpCharList)
ProcedureReturn
EndIf
;wait for end of previous drawing thread
WaitDrawThreadEnd()
;resize export size
CreateImage(#BmpCharList, width, height, 32)
StartDrawing(ImageOutput(#BmpCharList))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0, 0, ImageWidth(#BmpCharList), ImageHeight(#BmpCharList), 0)
StopDrawing()
;resize grid image
SetGridColor()
;redraw all characters and refresh image content
DrawExportedCharList()
;refresh scrollarea
SetGadgetAttribute(#ScrollViewport, #PB_ScrollArea_X, 0)
SetGadgetAttribute(#ScrollViewport, #PB_ScrollArea_Y, 0)
SetGadgetAttribute(#ScrollViewport, #PB_ScrollArea_InnerWidth, ImageWidth(#BmpCharList))
SetGadgetAttribute(#ScrollViewport, #PB_ScrollArea_InnerHeight, ImageHeight(#BmpCharList))
SetGadgetAttribute(#ScrollViewport, #PB_ScrollArea_X, 0)
SetGadgetAttribute(#ScrollViewport, #PB_ScrollArea_Y, 0)
EndProcedure
Procedure ResizeEditor(window, event)
Select window
Case 0
Select event
Case #PB_Event_SizeWindow
;resize font editor
Protected w=WindowWidth(0)
Protected h=WindowHeight(0)
ResizeGadget(#ScrollViewport, 0, 0, w-292, h-30)
ResizeGadget(#BtnExport, #PB_Ignore, h-25, #PB_Ignore, #PB_Ignore)
ResizeGadget(#BtnTest, #PB_Ignore, h-25, #PB_Ignore, #PB_Ignore)
ResizeGadget(#Progress, #PB_Ignore, h-25, w-GadgetX(#Progress)-4, #PB_Ignore)
ResizeGadget(#PnlFont, w-290, 2, #PB_Ignore, h-30)
EndSelect
Case 1
Select event
Case #PB_Event_SizeWindow
;resize test window
ResizeGadget(#SplitterTest, #PB_Ignore, #PB_Ignore, WindowWidth(1)-8, WindowHeight(1)-8)
Case #PB_Event_MinimizeWindow
;hide test window
HideWindow(1, 1)
EndSelect
EndSelect
EndProcedure
Procedure CloseEditor(window, event)
Select window
Case 0
If event=#PB_Event_CloseWindow
End
EndIf
Case 1
If event=#PB_Event_CloseWindow
HideWindow(1, 1)
EndIf
EndSelect
EndProcedure
Procedure CreateFontPanel()
PanelGadget(#PnlFont, WindowWidth(0)-290, 2, WindowWidth(0)-ScrW, WindowHeight(0)-30)
;//////////////////////////////////////
AddGadgetItem(#PnlFont, -1, "Characters")
Define x=5, y=5, w=GetGadgetAttribute(#PnlFont, #PB_Panel_ItemWidth)-x*2
Define xx=10, ww=w-30
Define h=20, hh=h+10, ht=h-4
TextGadget(#PB_Any, x, y, w, ht, "Characters") : y+ht
EditorGadget(#EditCharRange, x, y, w, 250) : y+GadgetHeight(#EditCharRange)+10
Define wr=(w-40)/4-5
TextGadget(#PB_Any, x, y, (wr+5)*3, h, "First Character Code:")
StringGadget(#StrCharRange1, x+(wr+5)*3, y, wr, h, "32", #PB_String_Numeric) : y+h+5
TextGadget(#PB_Any, x, y, (wr+5)*3, h, "Last Character Code:")
StringGadget(#StrCharRange2, x+(wr+5)*3, y, wr, h, "512", #PB_String_Numeric) : y+hh
ButtonGadget(#BtnCharRange, x+(w-45)+5, y, 40, h, "...")
GadgetToolTip(#BtnCharRange, "Generate Character List...")
;//////////////////////////////////////
;AddGadgetItem(#PnlFont, -1, "Export")
;//////////////////////////////////////
;AddGadgetItem(#PnlFont, -1, "Effects")
;//////////////////////////////////////
Define x=5, y=5
AddGadgetItem(#PnlFont, 0, "Font")
SetGadgetState(#PnlFont, 0)
Define x=5, y=5
TextGadget(#PB_Any, x, y, w, ht, "Texture Size") : y+ht
If ComboBoxGadget(#ComboTextureSize, x, y, w, h) : y+hh
AddGadgetItem(#ComboTextureSize, -1, "256 x 256")
AddGadgetItem(#ComboTextureSize, -1, "512 x 256")
AddGadgetItem(#ComboTextureSize, -1, "512 x 512")
AddGadgetItem(#ComboTextureSize, -1, "1024 x 512")
AddGadgetItem(#ComboTextureSize, -1, "1024 x 1024")
SetGadgetState(#ComboTextureSize, 2)
ExportSize(0, 0)=256 : ExportSize(0, 1)=256
ExportSize(1, 0)=512 : ExportSize(1, 1)=256
ExportSize(2, 0)=512 : ExportSize(2, 1)=512
ExportSize(3, 0)=1024 : ExportSize(3, 1)=512
ExportSize(4, 0)=1024 : ExportSize(4, 1)=1024
EndIf
TextGadget(#PB_Any, x, y, w, ht, "Font") : y+ht
If ComboBoxGadget(#ComboFont, x, y, w-45, h) : y+hh
AddGadgetItem(#ComboFont, -1, "Arial")
AddGadgetItem(#ComboFont, -1, "Arial Black")
AddGadgetItem(#ComboFont, -1, "Courier New")
AddGadgetItem(#ComboFont, -1, "Georgia")
AddGadgetItem(#ComboFont, -1, "Impact")
AddGadgetItem(#ComboFont, -1, "Tahoma")
AddGadgetItem(#ComboFont, -1, "Trebuchet MS")
AddGadgetItem(#ComboFont, -1, "Verdana")
SetGadgetState(#ComboFont, 0)
EndIf
ButtonGadget(#BtnFont, x+GadgetWidth(#ComboFont)+5, GadgetY(#ComboFont), 40, h, "...")
GadgetToolTip(#BtnFont, "Select Font...")
TextGadget(#PB_Any, x, y, w, ht, "Size") : y+ht
CompilerIf #PB_Compiler_OS=#PB_OS_MacOS
SpinGadget(#SpinSize, x, y, w, h+5, 8, 200, #PB_Spin_Numeric) : y+hh+5
CompilerElse
SpinGadget(#SpinSize, x, y, w, h, 8, 200, #PB_Spin_Numeric) : y+hh
CompilerEndIf
SetGadgetState(#SpinSize, CharFntSize)
TextGadget(#PB_Any, x, y, w, ht, "Style") : y+ht
Frame3DGadget(#PB_Any, x, y, w, 2.5*h, "", #PB_Frame3D_Double) : y+5
CheckBoxGadget(#CheckBold, xx, y, ww, h, "Bold") : y+h
CheckBoxGadget(#CheckItalic, xx, y, ww, h, "Italic") : y+hh+10
Define wr=(w-40)/4-5
TextGadget(#PB_Any, x, y, w, ht, "Margin") : y+ht
StringGadget(#StrCharMargin1, x+(wr+5)*0, y, wr, h, "2", #PB_String_Numeric) : y+hh
StringGadget(#StrCharMargin2, x+(wr+5)*1, GadgetY(#StrCharMargin1), wr, h, "2", #PB_String_Numeric)
StringGadget(#StrCharMargin3, x+(wr+5)*2, GadgetY(#StrCharMargin1), wr, h, "2", #PB_String_Numeric)
StringGadget(#StrCharMargin4, x+(wr+5)*3, GadgetY(#StrCharMargin1), wr, h, "2", #PB_String_Numeric)
GadgetToolTip(#StrCharMargin1, "LEFT")
GadgetToolTip(#StrCharMargin2, "TOP")
GadgetToolTip(#StrCharMargin3, "RIGHT")
GadgetToolTip(#StrCharMargin4, "BOTTOM")
ButtonGadget(#BtnCharMargin, x+(w-45)+5, GadgetY(#StrCharMargin1), 40, h, "Auto", #PB_Button_Toggle)
SetGadgetState(#BtnCharMargin, 1)
GadgetToolTip(#BtnCharMargin, "Auto Uniform Margin")
CheckBoxGadget(#CheckMinW, x, y, (wr+5)*3, h, "Character Min Width:")
StringGadget(#StrMinW, x+(wr+5)*3, Y, wr, h, "16", #PB_String_Numeric) : y+h+5
CheckBoxGadget(#CheckMinH, x, y, (wr+5)*3, h, "Character Min Height:")
StringGadget(#StrMinH, x+(wr+5)*3, y, wr, h, "16", #PB_String_Numeric) : y+hh
TextGadget(#PB_Any, x, y, w, ht, "Color (R,G,B)") : y+ht
If ListIconGadget(#ListColor, x, y, w-45, 4.5*h, "", 100, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection) : y+4.5*h+10
SetGadgetAttribute(#ListColor, #PB_ListIcon_DisplayMode, #PB_ListIcon_SmallIcon)
AddFontColor(RGB(0, 0, 0))
AddFontColor(RGB(255, 255, 255))
AddFontColor(RGB(255, 0, 0))
AddFontColor(RGB(255, 255, 0))
AddFontColor(RGB(0, 255, 0))
AddFontColor(RGB(0, 0, 255))
AddFontColor(RGB(120, 120, 255))
AddFontColor($DDDDDD)
AddFontColor($BBBBBB)
SetGadgetState(#ListColor, 2)
EndIf
ButtonGadget(#BtnColor, x+GadgetWidth(#ListColor)+5, GadgetY(#ListColor), 40, h, "...")
GadgetToolTip(#BtnColor, "Select Color...")
CloseGadgetList()
EndProcedure
Procedure CreateSettingsMenu()
Protected NewMap MenuStates()
Protected m
If IsMenu(0)
For m=#Menu_First To #Menu_Last
MenuStates(Str(m))=GetMenuItemState(0, m)
Next
EndIf
If CreatePopupImageMenu(0)
MenuItem(#MenuGrid, "Grid")
SetMenuItemState(0, #MenuGrid, 1)
MenuBar()
AddMenuColor(#MenuGrid1, "Soft Grid", RGB(250, 250, 250), RGB(200, 200, 200))
AddMenuColor(#MenuGrid2, "Light Grid", RGB(230, 230, 230), RGB(255, 255, 255))
AddMenuColor(#MenuGrid3, "Dark Grid", RGB(100, 100, 100), RGB(120, 120, 120))
AddMenuColor(#MenuGrid4, "Blue Grid", RGB(8, 128, 247), RGB(58, 154, 249))
AddMenuColor(#MenuGrid5, "Red Grid", RGB(255, 10, 2), RGB(255, 96, 91))
AddMenuColor(#MenuGrid6, "Yellow Grid", RGB(240, 240, 0), RGB(255, 255, 150))
SetMenuItemState(0, #MenuGrid1, 1)
MenuBar()
AddMenuColor(#MenuPointer1, "Yellow Pointer", RGBA(255, 255, 0, 100))
AddMenuColor(#MenuPointer2, "Red Pointer", RGBA(255, 0, 0, 100))
AddMenuColor(#MenuPointer3, "Blue Pointer", RGBA(0, 0, 255, 100))
SetMenuItemState(0, #MenuPointer1, 1)
MenuBar()
AddMenuColor(#MenuScreen1, "Default Background", RGB(100, 100, 120))
AddMenuColor(#MenuScreen2, "Custom Background...", ScrBackColor)
SetMenuItemState(0, #MenuScreen1, 1)
If MapSize(MenuStates())
For m=#Menu_First To #Menu_Last
If FindMapElement(MenuStates(), Str(m))
SetMenuItemState(0, m, MenuStates())
EndIf
Next
EndIf
EndIf
EndProcedure
Procedure CreateViewport()
Protected w=WindowWidth(0)
Protected h=WindowHeight(0)
ScrollAreaGadget(#ScrollViewport, 0, 0, ScrW-4, h-30, 0, 0, 0, #PB_ScrollArea_BorderLess)
ImageGadget(#ImgGrid, 0, 0, 0, 0, 0) : DisableGadget(#ImgGrid, 1)
ImageGadget(#ImgPointer, 0, 0, 0, 0, 0) : DisableGadget(#ImgPointer, 1)
ImageGadget(#ImgCharList, 0, 0, 0, 0, 0)
CloseGadgetList()
Protected y=h-25
Protected x=4
ButtonGadget(#BtnExport, x, y, 100, 20, "Exporter") : x+105
ButtonGadget(#BtnTest, x, y, 100, 20, "Tester") : x+105
ProgressBarGadget(#Progress, x, y, w-x-4, 20, 0, 100)
CreateSettingsMenu()
EndProcedure
Procedure OpenTestWindow()
;show test window if exists
If IsWindow(1)
HideWindow(1, 0)
SetWindowState(1, #PB_Window_Normal)
SetActiveWindow(1)
ProcedureReturn
EndIf
;create window
Protected w=600
Protected h=300
If OpenWindow(1, 0, 0, w, h, "Bitmap Font Tester", #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget | #PB_Window_Invisible | #PB_Window_MaximizeGadget, WindowID(0))
ScrollAreaGadget(#ScrollTest, 0, 0, 0, 0, 1024, 768)
;text editor
EditorGadget(#EditTest, 0, 0, 0, 0)
;text image
CreateImage(#BmpTest, 1024, 768, 32)
StartDrawing(ImageOutput(#BmpTest))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0, 0, OutputWidth(), OutputHeight(), 0)
StopDrawing()
ImageGadget(#ImgTest, 0, 0, 0, 0, 0)
CloseGadgetList()
SetGadgetColor(#ScrollTest, #PB_Gadget_BackColor, RGB(100, 100, 120))
;splitter
SplitterGadget(#SplitterTest, 4, 4, w-8, h-8, #ScrollTest, #EditTest, #PB_Splitter_Separator | #PB_Splitter_SecondFixed)
EndIf
EndProcedure
Procedure OpenExportWindow()
EndProcedure
CreateImage(#BmpCharList, 1, 1, 32)
CreateImage(#BmpChar, 256, 256, 32)
CreateImage(#BmpScrPointer, 256, 256, 32)
OpenWindow(0, 0, 0, #w, #h, "Bitmap Font Generator", #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
SmartWindowRefresh(0, #True)
AddWindowTimer(0, #TimerPointer, 20)
CreateViewport()
CreateFontPanel()
OpenTestWindow()
SetPointerColor(#MenuPointer1)
SetScreenBack(#MenuScreen1)
SetGridColor(#MenuGrid1)
SetCharColor(RGB(255, 0, 0))
SetCharList(32, 512)
SetCharFont("Arial", 24, 0, 0)
SetCharMargin(2)
ResizeExport(512, 512)
Repeat
Define e=WaitWindowEvent()
Define g=EventGadget()
Define w=EventWindow()
Define t=EventType()
Define tm=EventTimer()
Define m=EventMenu()
Select e
Case #PB_Event_Gadget
Select g
Case #ImgCharList
If t=#PB_EventType_RightClick
DisplayPopupMenu(0, WindowID(0))
EndIf
Case #ComboTextureSize
Define ExportSizeSeletion=GetGadgetState(#ComboTextureSize)
Define ExportW=ExportSize(ExportSizeSeletion, 0)
Define ExportH=ExportSize(ExportSizeSeletion, 1)
ResizeExport(ExportW, ExportH)
Case #StrCharMargin1 To #StrCharMargin4
If t=#PB_EventType_Change
If GetGadgetState(#BtnCharMargin)
Define.s FontMarginUniform=Str(Abs(Val(GetGadgetText(g))))
SetGadgetText(#StrCharMargin1, FontMarginUniform)
SetGadgetText(#StrCharMargin2, FontMarginUniform)
SetGadgetText(#StrCharMargin3, FontMarginUniform)
SetGadgetText(#StrCharMargin4, FontMarginUniform)
SetCharMargin(Val(FontMarginUniform))
Else
Define FontMargin1=Val(GetGadgetText(#StrCharMargin1))
Define FontMargin2=Val(GetGadgetText(#StrCharMargin2))
Define FontMargin3=Val(GetGadgetText(#StrCharMargin3))
Define FontMargin4=Val(GetGadgetText(#StrCharMargin4))
SetCharMargin(FontMargin1, FontMargin2, FontMargin3, FontMargin4)
EndIf
EndIf
Case #BtnCharMargin
If GetGadgetState(g)
SetGadgetText(g, "Auto")
GadgetToolTip(g, "Auto Uniform Margin")
Define.s FontMarginUniform=Str(Abs(Val(GetGadgetText(#StrCharMargin1))))
SetGadgetText(#StrCharMargin1, FontMarginUniform)
SetGadgetText(#StrCharMargin2, FontMarginUniform)
SetGadgetText(#StrCharMargin3, FontMarginUniform)
SetGadgetText(#StrCharMargin4, FontMarginUniform)
SetCharMargin(Val(FontMarginUniform))
Else
SetGadgetText(g, "...")
GadgetToolTip(g, "Custom Margins")
EndIf
Case #CheckMinW, #CheckMinH
Define MinW=Val(GetGadgetText(#StrMinW))
Define MinH=Val(GetGadgetText(#StrMinH))
If Not GetGadgetState(#CheckMinW) : MinW=0 : EndIf
If Not GetGadgetState(#CheckMinH) : MinH=0 : EndIf
SetCharMinSize(MinW, MinH)
Case #StrMinW, #StrMinH
If t=#PB_EventType_Change
Define MinW=Val(GetGadgetText(#StrMinW))
Define MinH=Val(GetGadgetText(#StrMinH))
If Not GetGadgetState(#CheckMinW) : MinW=0 : EndIf
If Not GetGadgetState(#CheckMinH) : MinH=0 : EndIf
SetCharMinSize(MinW, MinH)
EndIf
Case #ListColor
Define FontColorSelection=GetGadgetItemData(#ListColor, GetGadgetState(#ListColor))
SetCharColor(FontColorSelection)
Case #BtnColor
Define FontColorSelection=ColorRequester(CharColor)
SetCharColor(FontColorSelection)
AddFontColor(FontColorSelection)
Case #ComboFont, #CheckBold, #CheckItalic, #SpinSize
Define.s FontNameSeletion=GetGadgetText(#ComboFont)
Define FontSizeSelection=GetGadgetState(#SpinSize)
Define FontBoldChecked=GetGadgetState(#CheckBold)
Define FontItalicChecked=GetGadgetState(#CheckItalic)
SetCharFont(FontNameSeletion, FontSizeSelection, FontBoldChecked, FontItalicChecked)
Case #BtnFont
If FontRequester(CharFntName, CharFntSize, 0, CharColor, CharFntStyle)
FontNameSeletion=SelectedFontName()
FontSizeSelection=SelectedFontSize()
FontBoldChecked=SelectedFontStyle() & #PB_Font_Bold
FontItalicChecked=SelectedFontStyle() & #PB_Font_Italic
SetGadgetText(#ComboFont, FontNameSeletion)
AddFontName(FontNameSeletion)
SetGadgetState(#SpinSize, FontSizeSelection)
SetGadgetState(#CheckBold, FontBoldChecked)
SetGadgetState(#CheckItalic, FontItalicChecked)
SetCharFont(FontNameSeletion, FontSizeSelection, FontBoldChecked, FontItalicChecked)
EndIf
Case #BtnExport
OpenExportWindow()
Case #BtnTest
OpenTestWindow()
Case #EditTest
DrawTestedFont()
EndSelect
Case #PB_Event_Timer
Select tm
Case #TimerDrawingStart
DrawExportedCharList(#Draw_Start)
Case #TimerDrawingInProgress
If DrawThread And IsThread(DrawThread)
DrawExportedCharList(#Draw_InProgress)
Else
DrawExportedCharList(#Draw_End)
EndIf
Case #TimerPointer
DrawScreenPointer()
EndSelect
Case #PB_Event_Menu
Select m
Case #MenuGrid
Define gridstate=1-GetMenuItemState(0, m)
SetMenuItemState(0, m, gridstate)
HideGadget(#ImgGrid, 1-gridstate)
Case #MenuGrid1 To #MenuGrid6
SetGridColor(m)
Case #MenuPointer1 To #MenuPointer3
SetPointerColor(m)
Case #MenuScreen1 To #MenuScreen2
SetScreenBack(m)
EndSelect
Case #PB_Event_SizeWindow, #PB_Event_MinimizeWindow
ResizeEditor(w, e)
Case #PB_Event_CloseWindow
CloseEditor(w, e)
Default
DrawScreenPointer()
EndSelect
ForEver
End