Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
True Type Font Baseline — Gideros Forum

True Type Font Baseline

moopfmoopf Guru
edited January 2013 in General questions
Hmmm, have come across a problem with true type font rendering in Gideros with regards to baselines (the line used to site characters upon, with descenders going below etc). The problem is Gideros doesn't give us a reference to this (this appears to be known about, I've found other threads on the forum about it) so, when using French for example and characters such as É (which ascend higher than a normal E) or when using strings with and without descenders, there's a problem in terms of alignment because the created sprites are different heights and not positioned according to the baseline.

@atilim - is there any way you could make the baseline available as a property of TextField, just in the normal 0 to 1 range or a Y reference? We could then use our own routines to position accordingly. As it stands I can't seem to get positioning accurate unless I know exactly what characters are going to be in a string (which you don't always know and for multi-language conversions makes the whole job really messy).

I've tried the baseline fix in the latest GiderosCodingEasy as well and this doesn't seem to make a difference either. And I've tried using getBounds() directly but this always seems to give me 0 for y. Has anybody else found a work around, specifically when dealing with true type fonts?

Any ideas? It's kind of messing things up for me at the moment :(

Comments

  • atilimatilim Maintainer
    @moopf currently you cannot set the baseline but I'll definitely improve the font rendering/handling (including setting the baseline).

    My recommendation is setting the y coordinates of all text fields same and use a constant height based on the font size. Here you shouldn't use getHeight or getBounds because these functions can give different results with different texts.

    Likes: OZApps

    +1 -1 (+1 / -0 )Share on Facebook
  • Hi @atilim, thanks for the reply. Using a constant height based on the font size won't work, unfortunately, as there's no way of knowing if the extra height is due to descenders or something like a diacritic, so there's no way of lining things up accurately.

    I'm really stuck on this at the moment, and it's something that has become really noticeable now I am using translations in languages with with diacritics.
  • I dunno if this would help, I use the textHeight property and subtract it from the Y position that I want to position the object at, it kind of then sits where I want it. However with certain font sizes it does not work very well.

    @Atilim, if you can provide us a but more handle on this or position the text at the top than at the baseline, it could be easier or not? (there has to be a reason why you are using baseline)
    twitter: @ozapps | http://www.oz-apps.com | http://howto.oz-apps.com | http://reviewme.oz-apps.com
    Author of Learn Lua for iOS Game Development from Apress ( http://www.apress.com/9781430246626 )
    Cool Vizify Profile at https://www.vizify.com/oz-apps
  • @OZApps - textHeight property? Is that available for true type fonts or are you talking about bitmap fonts?

    I think all @atilim needs to do is let us know where on y the baseline is for a TextField object. We can then position everything properly regardless.
  • TrueType fonts, I do not use Bitmap fonts.
    local _text = TextField.new(theFont, theText)
    local _tWidth, _tHeight = _text:getWidth(), _text:getHeight()
    twitter: @ozapps | http://www.oz-apps.com | http://howto.oz-apps.com | http://reviewme.oz-apps.com
    Author of Learn Lua for iOS Game Development from Apress ( http://www.apress.com/9781430246626 )
    Cool Vizify Profile at https://www.vizify.com/oz-apps
  • That's just the width and height of the entire object, it wouldn't help in aligning vertically as you still have no concept of where on the y axis the baseline is.
  • yes, I just said that I use it this way and it works for me (more or less)
    twitter: @ozapps | http://www.oz-apps.com | http://howto.oz-apps.com | http://reviewme.oz-apps.com
    Author of Learn Lua for iOS Game Development from Apress ( http://www.apress.com/9781430246626 )
    Cool Vizify Profile at https://www.vizify.com/oz-apps
  • @OZApps - but how do you align tabular data correctly, where you have distinct strings. Or lines where you have a title and then content, e.g. Score title on the left, score on the right? You'd want them all to sit on the same relative baseline which you can't do, giving alignment problems. You can manually fudge it for the most part if you're just dealing with one language, but when you get into multi-language such fudging doesn't work as the different language versions of strings will have different heights and relative baselines.
  • @moopf agreed but again I have not come across that problem as yet so it works for me, maybe soon as I face that problem, I might look for a solution or hopefully @Atilim will offer a solutions for us all :)
    twitter: @ozapps | http://www.oz-apps.com | http://howto.oz-apps.com | http://reviewme.oz-apps.com
    Author of Learn Lua for iOS Game Development from Apress ( http://www.apress.com/9781430246626 )
    Cool Vizify Profile at https://www.vizify.com/oz-apps
  • Agree that to handle something like this should be implemented in Gideros, but at least for now, maybe this hack would help, where you create a test TextField with maximal upper and maximal lower bound text as "Ēj" and measure it's height and provide an offset for other texts in same idiom based on the maximal height?

    Just an idea
  • @ar2rsawseen - Unfortunately I don't think that would work as you wouldn't actually know whether your arbitrary string was the height it was because of descenders or diacritics. You still can't align the baseline because, fundamentally, you don't know the reason for the height.

    The only way that might work is if you measure the height of each character individually and then do some calculations when creating a TextField to get a semi-accurate baseline. It wouldn't be perfect and I think its implementation would be very messy.

    As far as I'm concerned we shouldn't have to do this anyway - I can't believe it's difficult for @atilim to make a property available for TextField objects that indicates where the baseline is. That way he doesn't have to change the rendering, so it doesn't break anybody's code, it's simply an addition that we can use if we want accurate control.

    Likes: OZApps

    +1 -1 (+1 / -0 )Share on Facebook
  • AlexRuAlexRu Member
    edited January 2013
    Somewhere on this forum I found the function align text to the center. I modified it to use in Chapaev: Checkers Battle:
    function centreAt(my_TextField, x, y)
       local w=my_TextField:getWidth()
       local h=my_TextField:getHeight()
     
       --text offset
    	local text_offset = 0
    	local my_text =my_TextField:getText()
     
    	--ц, щ, д
    	if (string.find(my_text, "ц") ~= nil) or (string.find(my_text, "щ") ~= nil) or (string.find(my_text, "д") ~= nil) then
    		text_offset = 3
    	end
    	--Ц, Щ, Д
    	if (string.find(my_text, "Ц") ~= nil) or (string.find(my_text, "Щ") ~= nil) or (string.find(my_text, "Д") ~= nil) then
    		text_offset = 5
    	end
    	--у, ф, р
    	if (string.find(my_text, "у") ~= nil) or (string.find(my_text, "ф") ~= nil) or (string.find(my_text, "р") ~= nil) then
    		text_offset = 5
    	end
    	--q, y, p, g, j
    	if (string.find(my_text, "q") ~= nil) or (string.find(my_text, "y") ~= nil) or (string.find(my_text, "p") ~= nil) or (string.find(my_text, "g") ~= nil) or (string.find(my_text, "j") ~= nil) then
    		text_offset = 5
    	end
     
    	my_TextField:setPosition(math.floor(x-w/2), math.floor(y + h/2) - text_offset)	
     
       return true
    end
    I use it for all TextFields, which I need to set at one line. It's for Russian and English.
  • @AlexRu - Nice idea, but there's a few things to note:

    1. Your solution is font and font size dependant. If you're showing text in multiple sizes, you'd need to make this more complex with different calculations for each font and font size.
    2. It can get very complex if you're dealing with many different diacritics on capitals and lowercase letters (such as cédille) as each one can affect the overall height of the text field so the function would need to be much more complex.
    3. Processing this for large blocks of text, or frequently updated text, may give a performance problem.

    Something like this would be my last choice if the needed change to a TextField object is not forthcoming as it would be the only option of at least getting it more accurate than doing nothing at all!
  • atilimatilim Maintainer
    edited January 2013
    @moopf - I still cannot understand the main problem. afaik, baseline is the most convenient way to align texts (especially when you use different fonts and different sizes). http://en.wikipedia.org/wiki/Baseline_(typography)

    I've prepared a simple example (attached the code). Here the base line of all texts are set to a constant value (40) and they all align correctly. If my text origin would be upper left instead of baseline, I couldn't align them.
    scr.png
    490 x 59 - 9K
    zip
    zip
    baseline.zip
    115K
  • @atilim Hmm OK, I think it's something in GiderosCodingEasy that's causing this. Are you actually using an anchor point internally on TextField to get the alignment right, so that the anchor is always on the baseline? So the position you use with setPosition for y will always be the baseline? If so, that's what I want access to.

    I think GiderosCodingEasy, which is so useful for being able to setAnchorPoints on sprites is in some way interfering with this.

    Likes: tuanleanh

    +1 -1 (+1 / -0 )Share on Facebook
  • atilimatilim Maintainer
    Are you actually using an anchor point internally on TextField to get the alignment right, so that the anchor is always on the baseline? So the position you use with setPosition for y will always be the baseline? If so, that's what I want access to.
    exactly.
  • @atilim - right, can we have access to that then please? It would be really useful if we could :D
  • atilimatilim Maintainer
    Implementing get/setAnchorPoint for TextFields and getting the font metrics are on my todo list for a loong time. Currently they are not available but I'll try to implement them.
  • @atilim - we can set them using GiderosCodingEasy without a problem but I need to know what a TextField uses as default in order to know what to offset my own anchor by to ensure baselines stay where I want them. I just need a get of the value you're using internally.
  • atilimatilim Maintainer
    edited January 2013
    @moopf Unfortunately that value is dependent to the font (and size) and calculated according to the font metrics (I can say it's usually around ~0.7).
  • @atilim - but couldn't you just make it available as a property for each TextField, that's what I'm asking for. After all you must be retaining it, or re-calculating it, when an object receives a setText. It must be there internally, just externalise that one little number and I'll go away about this :D
  • atilimatilim Maintainer
    edited January 2013 Accepted Answer
    Oh yes I can make it available :) (I finally understand you now :) ) Just give me a couple of days.

    Likes: moopf

    +1 -1 (+1 / -0 )Share on Facebook
  • @atilim - Absolutely flipping brilliant, thank you. That's all I need to be able to offset to keep baselines where they should be.
  • @moopf yes and GiderosCodingEasy uses bounding box to wrap TextField and use offset on it, so the positioning of text would be easier as for example to position text at 0,0 coordinates, but it completely against aligning multiple texts.
    Now which situation is more common?
    Or how to allow both situations in GiderosCodingEasy?
  • atilimatilim Maintainer
    @ar2rsawseen let me implement font metrics, so that GiderosCodingEasy can position the text without a problem (according to upper left or baseline)
Sign In or Register to comment.