You can test it on MAC / Linux. I want to check if there's any problem with the windowed screen.
Code: Select all
EnableExplicit
CompilerIf #PB_Compiler_Unicode=0
MessageRequester("Warning", "You didn't compile an UNICODE executable!", #PB_MessageRequester_Ok)
End
CompilerEndIf
CompilerIf Subsystem("DirectX9")
MessageRequester("Warning", "Don't use the DirectX9 subsystem!", #PB_MessageRequester_Ok)
End
CompilerEndIf
Enumeration
#win
#status
#scrollX
#scrollY
#editCharList
#splitParams
#panelParams
#spinFontSize
#checkBold
#checkItalic
#comboTexture
#buttonGenerate
#buttonFont
#buttonFontColor
#buttonBackColor
#timerRedrawPreview
#timerStatusProgress
#timerRedrawSelection
#listColorGrid
#fnt
#imageFont
#imageGrid
#imageFontColor
#imageBackColor
EndEnumeration
Structure charVisible
;char code (UNICODE)
code.U
;char position
cx.i
cy.i
cw.i
ch.i
EndStructure
Global NewList charVisible.charVisible()
Global charList.s
Global fnt.s="Arial"
Global fntSize=12
Global fntStyle=0
Global fntColor=RGB(255, 0, 0)
Global colorBack=RGB(100, 100, 120)
Global gridW=512
Global gridH=512
Structure colorGrid
name.s
c1.i
c2.i
imageGrid.i
EndStructure
Global NewList colorGrid.colorGrid()
With colorGrid()
AddElement(colorGrid()) : \name="Normal" : \c1=RGB(250, 250, 250) : \c2=RGB(200, 200, 200)
AddElement(colorGrid()) : \name="Dark " : \c1=RGB(120, 120, 120) : \c2=RGB(100, 100, 100)
AddElement(colorGrid()) : \name="Light " : \c1=RGB(255, 255, 255) : \c2=RGB(230, 230, 230)
AddElement(colorGrid()) : \name="Red " : \c1=RGB(255, 50, 50) : \c2=RGB(200, 0, 0)
AddElement(colorGrid()) : \name="Blue " : \c1=RGB(70, 70, 255) : \c2=RGB(50, 50, 200)
AddElement(colorGrid()) : \name="Green " : \c1=RGB(70, 255, 70) : \c2=RGB(50, 200, 50)
EndWith
;{/// IMAGE FUNCTIONS
Procedure SaveCharPosition(code.U, cx, cy, cw, ch)
AddElement(charVisible())
charVisible()\code=code
charVisible()\cx=cx
charVisible()\cy=cy
charVisible()\cw=cw
charVisible()\ch=ch
EndProcedure
Procedure NextCharPosition(cx, cy, ch)
Protected px=cx
Protected py
Protected checkPixel=fntStyle & #PB_Font_Italic
While checkPixel
checkPixel=0
For py=cy To cy+ch-1
If px>=ImageWidth(#imageFont) Or py>=ImageHeight(#imageFont)
;stop if outside image output
Break
Else
;check pixel (after drawing italic character)
If (Point(px, py) & $FF000000)
px+1
checkPixel=1
Break
EndIf
EndIf
Next
Wend
ProcedureReturn px
EndProcedure
Procedure DrawGrid()
Protected w=gridW
Protected h=gridH
With colorGrid()
;{/// draw grid image templates
If \imageGrid=0
Protected dw=1024
Protected dh=1024
ForEach colorGrid()
\imageGrid=CreateImage(#PB_Any, dw, dh, 32)
StartDrawing(ImageOutput(\imageGrid))
DrawingMode(#PB_2DDrawing_Default)
FrontColor(\c1)
Box(0, 0, dw, dh)
FrontColor(\c2)
Protected k=0
Protected x, y
For y=0 To dh Step 32
If k=32 : k=0 : Else : k=32 : EndIf
For x=k To dw Step 64
Box(x, y, 32, 32)
Next
Next
StopDrawing()
Next
EndIf
;}
;{/// draw grid
CreateImage(#imageGrid, w, h, 32)
StartDrawing(ImageOutput(#imageGrid))
DrawingMode(#PB_2DDrawing_Default)
DrawImage(ImageID(\imageGrid), 0, 0)
StopDrawing()
;}
EndWith
EndProcedure
Procedure DrawFont()
Protected w=ImageWidth(#imageGrid)
Protected h=ImageHeight(#imageGrid)
CreateImage(#imageFont, w, h, 32)
StartDrawing(ImageOutput(#imageFont))
If IsFont(#fnt)
DrawingFont(FontID(#fnt))
EndIf
#mw=4
#mh=4
DrawingMode(#PB_2DDrawing_Default)
Box(0, 0, w, h, fntColor)
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0, 0, w, h, 0)
FrontColor(RGBA(255, 255, 255, 255))
BackColor(RGBA(255, 0, 0, 0))
ClearList(charVisible())
If charList
Protected c.s, cw, ch, cx=#mw, cy=#mh, lineHeight
Protected charIndex.i
Protected charLast=Len(charList)
For charIndex=1 To charLast
c=Mid(charList, charIndex, 1)
cw=TextWidth(c)
ch=TextHeight(c)
If cw=0 Or ch=0 : Continue : EndIf
;draw char
DrawText(cx, cy, c+" ")
cw=NextCharPosition(cx+cw, cy, ch)-cx
;save char position
SaveCharPosition(charIndex, cx-#mw, cy-#mh, cw+2*#mw, ch+2*#mh)
;update drawing position
cx+cw+#mw*2
;update height of current line
If lineHeight<ch : lineHeight=ch : EndIf
;check next char position
If charIndex<charLast
c=Mid(charList, charIndex+1, 1)
cw=TextWidth(c)
ch=TextHeight(c)
If (cx+cw+#mw*2)>=w
cx=#mw
cy+(lineHeight+#mh*2)
If (cy+ch+#mh*2)>=h : Break : EndIf
lineHeight=0
EndIf
EndIf
Next
EndIf
StopDrawing()
EndProcedure
Procedure DrawPreview()
Global GlobalSelection
Global screenOffsetX=-GetGadgetState(#scrollx)
Global screenOffsetY=-GetGadgetState(#scrolly)
ClearScreen(colorBack)
StartDrawing(ScreenOutput())
DrawingMode(#PB_2DDrawing_Default)
DrawImage(ImageID(#imageGrid), screenOffsetX, screenOffsetY)
If GlobalSelection>0
Box(charVisible()\cx+screenOffsetX, charVisible()\cy+screenOffsetY, charVisible()\cw, charVisible()\ch, RGB(255, 255, 0))
EndIf
DrawAlphaImage(ImageID(#imageFont), screenOffsetX, screenOffsetY)
StopDrawing()
FlipBuffers()
EndProcedure
Procedure CreateColorBox(ID, color, w=#PB_Ignore, h=#PB_Ignore)
If w=#PB_Ignore
w=ImageWidth(ID)
h=ImageHeight(ID)
Else
Select #PB_Compiler_OS
Case #PB_OS_Windows
Case #PB_OS_Linux
Case #PB_OS_MacOS
w-20
h-8
EndSelect
EndIf
CreateImage(ID, w, h, 32)
StartDrawing(ImageOutput(ID))
Box(0, 0, w, h, color)
StopDrawing()
EndProcedure
Procedure CreateGridBox(color1, color2)
Protected ID=CreateImage(#PB_Any, 32, 32, 32)
StartDrawing(ImageOutput(ID))
Box(0, 0, 32, 32, color1)
Box(0, 0, 16, 16, color2)
Box(16, 16, 16, 16, color2)
StopDrawing()
ProcedureReturn ImageID(ID)
EndProcedure
;}
;{/// INVOKE FUNCTIONS
Procedure InvokeUpdateScreen(timeout=-1)
If timeout<0
RemoveWindowTimer(#win, #timerRedrawPreview)
Else
AddWindowTimer(#win, #timerRedrawPreview, timeout+1)
EndIf
EndProcedure
Procedure InvokeUpdateStatusBar(timeout=-1)
Global GlobalStatusTimer
If timeout<0
RemoveWindowTimer(#win, #timerStatusProgress)
StatusBarText(#status, 1, "Characters visible on screen: "+Str(ListSize(charVisible()))+" / "+Str(Len(charList)))
StatusBarText(#status, 2, "Texture Size: "+Str(ImageWidth(#imageGrid))+" x "+Str(ImageHeight(#imageGrid)))
StatusBarText(#status, 3, "")
Else
AddWindowTimer(#win, #timerStatusProgress, timeout+1)
EndIf
GlobalStatusTimer=0
StatusBarProgress(#status, 0, GlobalStatusTimer, 0, 0, 100)
EndProcedure
Procedure UpdateStatusBar()
Global GlobalStatusTimer
GlobalStatusTimer=(GlobalStatusTimer+10) % 100
StatusBarProgress(#status, 0, GlobalStatusTimer, 0, 0, 100)
EndProcedure
Procedure UpdateScreen(fastRedraw=#False)
Global GlobalSelection
Global screenOffsetX
Global screenOffsetY
If fastRedraw
;find new selection
Protected newSelection=0
Protected mx=WindowMouseX(#win)-screenOffsetX
Protected my=WindowMouseY(#win)-screenOffsetY
ForEach charVisible()
With charVisible()
If (mx>=\cx And mx<(\cx+\cw)) And (my>=\cy And my<(\cy+\ch))
newSelection=ListIndex(charVisible())+1
Break
EndIf
EndWith
Next
;redraw only if selection changed
If GlobalSelection<>newSelection
GlobalSelection=newSelection
DrawPreview()
EndIf
Else
;redraw preview (and update font)
LoadFont(#fnt, fnt, fntSize, fntStyle)
DrawFont()
DrawPreview()
EndIf
EndProcedure
;}
;{/// UNICODE FUNCTIONS
Procedure.s UnicodeCharList(first.U, last.U)
If first>=0 And first<last
Protected len.i=last-first+1
Protected charList.s=Space(len)
Protected i.i
For i=0 To len-1
PokeU(@charlist+i*SizeOf(Character), first+i)
Next
ProcedureReturn charList
EndIf
EndProcedure
Procedure.s UChr(code.U)
If code>=0 And code<65536
Protected unicodeChar.s=" "
PokeU(@unicodeChar, code)
ProcedureReturn unicodeChar
EndIf
EndProcedure
Procedure.s SplitString(s.s, max)
Protected splittedString.s=""
While s
splittedString+Left(s, max)+#CRLF$
s=Mid(s, max+1)
Wend
ProcedureReturn splittedString
EndProcedure
;}
#w=800
#h=560
InitSprite()
OpenWindow(#win, 0, 0, #w, #h, "Bitmap Font Generator", #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
SetWindowState(#win, #PB_Window_Maximize)
SmartWindowRefresh(#win, 1)
WindowBounds(#win, #w, #h, #PB_Ignore, #PB_Ignore)
;{/// STATUS
If CreateStatusBar(#status, UseGadgetList(0))
AddStatusBarField(64)
AddStatusBarField(350)
AddStatusBarField(#PB_Ignore)
EndIf
;}
;{/// PREVIEW
If OpenWindowedScreen(WindowID(#win), 0, 0, 256, 256, 0, 0, 0)
ScrollBarGadget(#scrollX, 0, 0, 0, 0, 0, 0, 0)
ScrollBarGadget(#scrollY, 0, 0, 0, 0, 0, 0, 0, #PB_ScrollBar_Vertical)
EndIf
;}
;{/// CHAR LIST
If EditorGadget(#editCharList, 0, 0, 0, 0)
SetGadgetText(#editCharList, SplitString(UnicodeCharList(15, 512), 30))
EndIf
;}
If PanelGadget(#panelParams, 0, 0, 0, 0)
AddGadgetItem(#panelParams, -1, "Generator")
;{/// FONT EDITOR
Global x=2, y=2, w=53, h=20
Global w2=198, h2=22
Global w3=80, h3=22
Global hg=25
TextGadget(#PB_Any, x, y+2, w, h, "Texture:")
ComboBoxGadget(#comboTexture, x+w, y, w2, h2) : y+hg
AddGadgetItem(#comboTexture, -1, "256 x 256")
AddGadgetItem(#comboTexture, -1, "512 x 256")
AddGadgetItem(#comboTexture, -1, "512 x 512")
AddGadgetItem(#comboTexture, -1, "1024 x 512")
AddGadgetItem(#comboTexture, -1, "1024 x 1024")
SetGadgetState(#comboTexture, 2)
TextGadget(#PB_Any, x, y+2, w, h, "Font:")
ButtonGadget(#buttonFont, x+w, y, w2, h2, fnt) : y+hg
TextGadget(#PB_Any, x, y+2, w, h, "Color:")
CreateColorBox(#imageFontColor, fntColor, w3, h3)
ButtonImageGadget(#buttonFontColor, x+w, y, w3, h3, ImageID(#imageFontColor)) : y+hg
TextGadget(#PB_Any, x, y+2, w, h, "Size:")
SpinGadget(#spinFontSize, x+w, y, w3, h3, 8, 32, #PB_Spin_Numeric) : y+hg
SetGadgetState(#spinFontSize, fntSize)
TextGadget(#PB_Any, x, y+2, w, h, "Style:")
CheckBoxGadget(#checkBold, x+w, y, w2, 16, "Bold") : y+16
CheckBoxGadget(#checkItalic, x+w, y, w2, 16, "Italic") : y+16
SetGadgetState(#checkItalic, fntStyle & #PB_Font_Italic)
SetGadgetState(#checkBold, fntStyle & #PB_Font_Bold)
;}
AddGadgetItem(#panelParams, -1, "Settings")
;{///SETTINGS
x=2
y=2
TextGadget(#PB_Any, x, y+2, w, h, "Screen:")
CreateColorBox(#imageBackColor, colorBack, w3, h3)
ButtonImageGadget(#buttonBackColor, x+w, y, w3, h3, ImageID(#imageBackColor)) : y+hg
TextGadget(#PB_Any, x, y+2, w, h, "Grid:")
ListIconGadget(#listColorGrid, x+w, y, w2, 73, "test", 50, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
SetGadgetAttribute(#listColorGrid, #PB_ListIcon_DisplayMode, #PB_ListIcon_List)
ForEach colorGrid()
AddGadgetItem(#listColorGrid, -1, colorGrid()\name, CreateGridBox(colorGrid()\c1, colorGrid()\c2))
Next
;}
CloseGadgetList()
EndIf
Repeat
Global e=WaitWindowEvent(0)
Global w=EventWindow()
Global t=EventType()
Select e
Case #PB_Event_ActivateWindow
Case #PB_Event_CloseWindow
Break
Case #PB_Event_SizeWindow
;{/// RESIZE EVENTS
If w=#win
Global totalH=WindowHeight(#win)-StatusBarHeight(#status)
Global panelW=263
Global panelH=200
Global panelY=2
Global panelX=WindowWidth(#win)-panelW
Global screenW=WindowWidth(#win)-panelW-18
Global screenH=WindowHeight(#win)-StatusBarHeight(#status)-18
If OpenWindowedScreen(WindowID(#win), 0, 0, screenW, screenH, 0, 0, 0)
DrawGrid()
DrawFont()
DrawPreview()
InvokeUpdateScreen(0)
AddWindowTimer(#win, #timerRedrawSelection, 100)
ResizeGadget(#scrollX, 0, screenH, screenW, 16)
ResizeGadget(#scrollY, screenW, 0, 16, screenH)
SetGadgetAttribute(#scrollX, #PB_ScrollBar_Maximum, gridW)
SetGadgetAttribute(#scrollX, #PB_ScrollBar_Minimum, 0)
SetGadgetAttribute(#scrollX, #PB_ScrollBar_PageLength, screenW)
SetGadgetAttribute(#scrollY, #PB_ScrollBar_Maximum, gridH)
SetGadgetAttribute(#scrollY, #PB_ScrollBar_Minimum, 0)
SetGadgetAttribute(#scrollY, #PB_ScrollBar_PageLength, screenH)
EndIf
ResizeGadget(#editCharList, panelX, panelY, panelW-2, totalH-panelH-5)
ResizeGadget(#panelParams, panelX, totalH-panelH, panelW, panelH)
EndIf
;}
Case #PB_Event_Gadget
;{/// GADGET EVENTS
Select EventGadget()
Case #editCharList
Global charListNew.s=RemoveString(RemoveString(GetGadgetText(#editCharList), #CR$), #LF$)
If charList<>charListNew
charList=charListNew
;invoke redraw
InvokeUpdateScreen(500)
InvokeUpdateStatusBar(50)
EndIf
Case #buttonFont
If FontRequester(fnt, fntSize, 0, fntColor, fntStyle)
fnt=SelectedFontName()
fntSize=SelectedFontSize()
fntStyle=SelectedFontStyle()
SetGadgetText(#buttonFont, fnt)
SetGadgetState(#spinFontSize, fntSize)
SetGadgetState(#checkBold, fntStyle & #PB_Font_Bold)
SetGadgetState(#checkItalic, fntStyle & #PB_Font_Italic)
;invoke redraw
InvokeUpdateScreen(100)
InvokeUpdateStatusBar(5)
EndIf
Case #buttonFontColor
Global newColor=ColorRequester(fntColor)
If newColor>-1
fntColor=newColor
CreateColorBox(#imageFontColor, fntColor)
SetGadgetAttribute(#buttonFontColor, #PB_Button_Image, ImageID(#imageFontColor))
;invoke redraw
InvokeUpdateScreen(100)
InvokeUpdateStatusBar(50)
EndIf
Case #buttonBackColor
Global newColor=ColorRequester(colorBack)
If newColor>-1
colorBack=newColor
CreateColorBox(#imageBackColor, colorBack)
SetGadgetAttribute(#buttonBackColor, #PB_Button_Image, ImageID(#imageBackColor))
;invoke redraw
InvokeUpdateScreen(100)
InvokeUpdateStatusBar(50)
EndIf
Case #listColorGrid
If GetGadgetState(#listColorGrid)<>ListIndex(colorGrid())
SelectElement(colorGrid(), GetGadgetState(#listColorGrid))
EndIf
DrawGrid()
;invoke redraw
InvokeUpdateScreen(50)
InvokeUpdateStatusBar(5)
Case #comboTexture
Select GetGadgetState(#comboTexture)
Case 0
gridW=256
gridH=256
Case 1
gridW=512
gridH=256
Case 2
gridW=512
gridH=512
Case 3
gridW=1024
gridH=512
Case 4
gridW=1024
gridH=1024
EndSelect
If gridW<>ImageWidth(#imageGrid) Or gridH<>ImageHeight(#imageGrid)
DrawGrid()
;invoke redraw
InvokeUpdateScreen(100)
InvokeUpdateStatusBar(20)
SetGadgetAttribute(#scrollX, #PB_ScrollBar_Maximum, gridW)
SetGadgetAttribute(#scrollX, #PB_ScrollBar_Minimum, 0)
SetGadgetAttribute(#scrollX, #PB_ScrollBar_PageLength, screenW)
SetGadgetAttribute(#scrollY, #PB_ScrollBar_Maximum, gridH)
SetGadgetAttribute(#scrollY, #PB_ScrollBar_Minimum, 0)
SetGadgetAttribute(#scrollY, #PB_ScrollBar_PageLength, screenH)
EndIf
Case #spinFontSize
If fntSize<>GetGadgetState(#spinFontSize)
fntSize=GetGadgetState(#spinFontSize)
;invoke redraw
InvokeUpdateScreen(500)
InvokeUpdateStatusBar(50)
EndIf
Case #checkBold, #checkItalic
fntStyle=0
If GetGadgetState(#checkBold) : fntStyle | #PB_Font_Bold : EndIf
If GetGadgetState(#checkItalic) : fntStyle | #PB_Font_Italic : EndIf
;invoke redraw
InvokeUpdateScreen(200)
InvokeUpdateStatusBar(20)
Case #scrollX, #scrollY
;refresh image preview
DrawPreview()
Case #buttonGenerate
;invoke redraw
InvokeUpdateScreen(10)
EndSelect
;}
Case #PB_Event_Timer
;{///TIMER EVENTS
Select EventTimer()
Case #timerStatusProgress
;refresh statusbar
UpdateStatusBar()
Case #timerRedrawPreview
;refresh image preview
UpdateScreen()
;reset timers
InvokeUpdateScreen()
InvokeUpdateStatusBar()
Case #timerRedrawSelection
;refresh image preview
UpdateScreen(#True)
EndSelect
;}
Case #PB_Event_SysTray
Case #PB_Event_GadgetDrop
Default
;refresh image preview
UpdateScreen(#True)
EndSelect
ForEver
End