Fontmachine & WordWrappedText Question

Monkey Forums/Monkey Programming/Fontmachine & WordWrappedText Question

Wylaryzel(Posted 2014) [#1]
I'm using Fontmachine as it is easy to handle.
For my current project I wanted to implement the WordWrappedText Function as it was looking to support what I would be needing but I somehow miss how to calculate the final height of the text. This would be needed to know how far I have to scroll.

The lines() Method doesn't return the real number of lines - I tested it with the sample4 and the printout all the time says 165 even if I play with the width.

Where should I look to get the real textHeight?

And would it be possible to add an overload Method to tell to render only particular lines (similar to to Method for drawing substring texts in the fontmachine module itself)?

Thx in advance
Wyl


Paul - Taiphoz(Posted 2014) [#2]
You could count the number of new line characters found in your string , so if your string has 4 ~n then times that by the heigh of your font's character.

You could also write an override method for DrawText() and just code your own word wrap so that you can see how high things get.


Paul - Taiphoz(Posted 2014) [#3]
Actually on looking , GetTxtHeight() is the method you should be using and it does what I suggested, counts the number of new lines, GetFontHeight returns the hight of the font not the body of text that your working with.


Wylaryzel(Posted 2014) [#4]
Dear Paul,

I had the similar things in mind but the WordWrappedText function has some additional identifiers for splitting lines in the code which I couldn't find to calculate the correct height of the text.

As there is already a wordwrap function in fontmachine which works very well it would be nicer to have the 2 requested options build in - but if I can't add them I will for sure have to roll my own piece of code.

BR
Wyl


ziggy(Posted 2014) [#5]
It.should be very very easy to add. I'll.take a look later


ziggy(Posted 2014) [#6]
I've just added the following methods to the WrappedText class:

* Method WrappedLinesCount:Int()
* Method WrappedTextHeight:Int()

Should be very self explanatory. The first method returns the number of lines of a given wrapped text. Then the, WrappedTextHeight returns the Height of the WrappedText once the text is wrapped

EDIT. I've also added a method called PartialDraw that allows you to draw text at the beginning of a given wrapped line and it allows you to draw only a "count" of lines.
That is, you can draw a wrapped text starting at wrapped line 4, and draw just 10 lines of text. This is controlled programatically and it's very fast, so I think this should cover anything needed to add proper scrolling of text on a game.

That's it:
* Method PartialDraw(firstLine:Int, count:Int, x:Int, y:Int, align:Int = eDrawAlign.LEFT)

To get latest version, just go to the google code repostitory here: https://code.google.com/p/fontmachine/source/browse/ (see there's a Download Zip).


Wylaryzel(Posted 2014) [#7]
Dear ziggy,

that was very fast :-) Implemented the WrappedTextHeight and works like a charm :-)

Will soon integrate the others as well.

Thank you.
Wyl


ziggy(Posted 2014) [#8]
I've just commit a couple of bug fixes. Nothing important, but now word wrap calculation is a bit more precise and should be pixel perfect unless words need to be splitted (this is something I'm not going to implement anytime soon, as it involved localization, silabic separation etc...)


Wylaryzel(Posted 2014) [#9]
Dear ziggy,

can you take a look for the wrapped text if it is aligned CENTER or RIGHT? First I thought my code would be wrong, but if I modified the example4 code to align the text as CENTER it breaks the offsets for the text (same is true for RIGHT)?

Thx
Wyl


ziggy(Posted 2014) [#10]
This has been fixed on the repository.


Wylaryzel(Posted 2014) [#11]
Thats lightning speed :-)

thx for the quick fix.

BR
Wyl


ziggy(Posted 2014) [#12]
I've just reorganized documentation so it is now part of regular Monkey documentation when the module is installed and also added a new sample that shows how to use the WordWrappedText class to allow for fast wrapped text scrolling in games.


therevills(Posted 2014) [#13]
Could you add a small enhancement so you can control the height per line for the wrappedtext. In the Draw method you currently use the Font.GetFontHeight to calculate the gap between the lines. On some fonts this height is too large, for example my current font Fontmachine returns the height as 45, but for wrapped text to look good it only needs to be 33.
I have added a new optional parameter to do this:
	#Rem monkeydoc
		This method draws the WordWrappedText at the given location.
	#END
	Method Draw(x:Float, y:Float, align:Int = eDrawAlign.LEFT, height:Int = 0)
		
		Local i:int = 0
		Local drawpos:= New DrawingPoint
		drawpos.x = x; drawpos.y = y
		If height = 0 Then
			height = Font.GetFontHeight()
		End
		
		Local curline = 0
		For Local index:Int = 0 Until Self.Lines '- 1
			Local tl:TextLine = GetLine(index)
			For Local interval:TxtInterval = EachIn tl.Intervals.contents
				
				Self.Font.DrawText(tl.text, drawpos.x, drawpos.y + i * height, align, interval.InitOffset + 1, interval.EndOffset)
				i += 1
			Next
			curline += 1
		Next
	End



ziggy(Posted 2014) [#14]
I love it when you request something that it's already done (no additional work required!) hehe

You can modify the font vertical kerning.

As instance: myFont.Kerning.y=-5 will decrease vertical spacing of the font by 5 pixels.

Let me know if it worked for you.

Note: You can also modify horizontal kerning if you need to.


Supertino(Posted 2014) [#15]
Hum I should update my version of Font machine, I've been using my own fudged version for months so that I could return the number of lines in wrapped text. Thanks Ziggy.


therevills(Posted 2014) [#16]
As instance: myFont.Kerning.y=-5 will decrease vertical spacing of the font by 5 pixels.

Doesn't seem to do anything...
Local str:String = LoadString("text/stageStory.txt")
storyText = New WordWrappedText
game.font.Kerning.y = -15
If str Then
	storyText.Font = game.font
	storyText.Width = 400
	storyText.Text = str
End


Edit:
Looks like the kerning is only used on the WordWrappedText in the PartialDraw method not the Draw method.
Fix:
Self.Font.DrawText(tl.text, drawpos.x, drawpos.y + i * (Font.GetFontHeight() +Font.Kerning.y), align, interval.InitOffset + 1, interval.EndOffset)



ziggy(Posted 2014) [#17]
Will fix! Nice found