FontMachine TextBox

Monkey Forums/Monkey Code/FontMachine TextBox

Paul - Taiphoz(Posted 2012) [#1]
EDIT [read wordwrap not textbox] sorry for the confusion.

The following is a mod/edit to the Font Machine module to allow text to be drawn inside a width, I needed this for my current project where I display a line of text and wrap that line around so it fits in my screen.

Usage :
Font.DrawText("A really long bit of text....", x, y, align,width)

TLDR - What it does :
Takes a long line of text, breaks it up into words split by " ", it then builds lines making sure never to go over your width, it then returns an array of lines for rendering, but all that's done in the background.


Open Bitmapfont.monkey

FIND
[monkeycode]
#rem
summary:This Method allows you To draw a String on the graphics canvas.
This Method is a simplified version of the DrawText command that asumes left aligment of text.
#End
Method DrawText(text:String, x#, y#)
Self.DrawText(text,x,y,eDrawAlign.LEFT )
End
[/monkeycode]

ADD AFTER ...

[monkeycode]



#rem
summary:This Method draws TEXT within a given Width.
Draw's Text inside a given width, allowing for textbox like rendering.
Code by Taiphoz.
#End

Method DrawText(text:String, x#, y#, align:Int,Tai_width:Int)


Local Tai_TextLines:String[]

If Self.GetTxtWidth(text)>Tai_width

Tai_TextLines = Self.SplitLines(text,Tai_width)

'Render the Lines from the String Araay.
Local Tai_Drop:Int = Self.GetFontHeight()

Local Tai_Count:Int =0

For Local Tai_CurLine:String = Eachin Tai_TextLines
If Tai_CurLine<>""
If DrawShadow Then DrawCharsText (Tai_CurLine,x,y+(Tai_Count*Tai_Drop),eDrawMode.SHADOW, align )
If DrawBorder Then DrawCharsText (Tai_CurLine,x,y+(Tai_Count*Tai_Drop),eDrawMode.BORDER, align )
DrawCharsText (Tai_CurLine,x,y+(Tai_Count*Tai_Drop),eDrawMode.FACE ,align)
Tai_Count+=1
End if
Next

Else
if DrawShadow Then DrawCharsText (text,x,y,eDrawMode.SHADOW, align )
If DrawBorder Then DrawCharsText (text,x,y,eDrawMode.BORDER, align )
DrawCharsText (text,x,y,eDrawMode.FACE ,align)
End If




End Method

#rem
'summary split given text into an array of lines based on provided with.
Code by Taiphoz
#End

Method SplitLines:String[](_text:String,_width:Int)

Local Tai_textdata:String[] = _text.Split(" ")




'temp vars for building lines.
Local Tai_tmptext:String=""
Local Tai_words:Int=Tai_textdata.Length()
Local Tai_textlines:String[Tai_words] 'its a fudge. but number of lines will possibly match number of words.

Local Tai_line:Int = 0

For Local Tai_word:Int = 0 To Tai_words-1

Tai_tmptext+=Tai_textdata[Tai_word]+" "

If Self.GetTxtWidth(Tai_tmptext)<_width
Tai_textlines[Tai_line]=Tai_tmptext
Else
Tai_line+=1
Tai_tmptext=(Tai_textdata[Tai_word]+" ")
End If

Next

Return Tai_textlines
End Method
[/monkeycode]


Paul - Taiphoz(Posted 2012) [#2]
never mind, fixed it.


ziggy(Posted 2012) [#3]
Looks cool. I'll be adding something like this to official source soon. (Just thinking a way to do the same without creatind an array and new strings, as XNA Garbage Collector can produce some jitter when there are lots of allocations per frame)


Tibit(Posted 2012) [#4]
Is there an update for this, we are using the modification above but it is a bit clumsy to share code written using it.


fictorial(Posted 2013) [#5]
Has this been integrated into The Font Machine?


ziggy(Posted 2013) [#6]
No, it's not. I'm building my own wordwrap functionality on junglegui and it is a bit different.
This implementation, while it works properly, it generates substrings to operate. This generates garbage and, if it is done on a per-frame basis, it could damage performance.
I'm doing my own WordWrap functionality on junglegui and may add this to fontmachine in the future.

You can see a sample of a WIP version of it here:
http://www.jungleide.com/samples/junglegui06/MonkeyGame.html

Open the TextBox demo, and resize the window to see it recalculating wordwrap realtime. It's all HTML5, so it's not very optimal at execution time (yet).


Paul - Taiphoz(Posted 2013) [#7]
Ah sweet, my code was never anything more than a quick hack until ziggy got round to a proper implementation and that textbox example looks perfect, is that in the current code or are you still working on it ?


Raph(Posted 2013) [#8]
I did a version of this today that only uses slices. Dunno if that makes it faster/more efficient. Do slices generate substrings?




ziggy(Posted 2013) [#9]
Yes, slices ARE substrings. You could take a look at the latest FontMachine version at google code. It contains a wrap class that is meant to allow wordwrap drawing of text.
It's an object you can attach a font, a text and a maximum width, and it has a Draw operation that handles all the drawing without messing with the GC.
It has not been promoted to official yet, but it'll be very soon, as I've been using it for the IWC app and it works pretty well. Specially becouse it does not require the spacing to be recalculated in a per-frame basis, it only recalculates if the text, font or width changes.