y-alignment of fonts - iPhone does not consider metrics.leading

Dear Corona-community,

I am still working on my emoji-module, currently facing a weird behaviour with y-alignment of fonts.

Here is what I’d like to do:

I’d like to align display.newText() - elements and display.newImageRect() - elements.

What I’ve done so far:

Spent the last 14 hours on researching the graphics.getfontMetrics API plus textObject.baselineOffset - method.

This is a very simplified version, demonstration the issue I’d like to address:

----------------------------------------------------------------------------------------- -- -- main.lua -- ----------------------------------------------------------------------------------------- -- Your code here local top = display.screenOriginY local center = display.screenOriginX + display.contentWidth/2 local fontSize = 14 -- create white squares with fontSize as height local line1 = display.newRect(center, top + 50, display.contentWidth, fontSize) line1:setFillColor(1) local line2 = display.newRect(center, top + 100, display.contentWidth, fontSize) line2:setFillColor(1) local line3 = display.newRect(center, top + 150, display.contentWidth, fontSize) line3:setFillColor(1) local line4 = display.newRect(center, top + 200, display.contentWidth, fontSize) line4:setFillColor(1) local line5 = display.newRect(center, top + 250, display.contentWidth, fontSize) line5:setFillColor(1) -- get font-metrics local metrics1 = graphics.getFontMetrics( native.systemFont, fontSize ) local metrics2 = graphics.getFontMetrics( "AvenirLTStd-Roman.otf", fontSize ) local metrics3 = graphics.getFontMetrics( "BreeSerif-Regular.ttf", fontSize ) local metrics4 = graphics.getFontMetrics( "FredokaOne-Regular.ttf", fontSize ) local metrics5 = graphics.getFontMetrics( "PatrickHand-Regular.ttf", fontSize ) -- create text-objects local text1 = display.newText("Asc: " .. string.sub(metrics1.ascent, 1, 5) .. " Desc: " .. string.sub(metrics1.descent, 1, 5) .. " Hght: " .. string.sub(metrics1.height, 1, 5) .. " Lding: " .. string.sub(metrics1.leading, 1, 5), line1.x, line1.y, native.systemFont, fontSize) text1:setFillColor(0) local text2 = display.newText("Asc: " .. string.sub(metrics2.ascent, 1, 5) .. " Desc: " .. string.sub(metrics2.descent, 1, 5) .. " Hght: " .. string.sub(metrics2.height, 1, 5) .. " Lding: " .. string.sub(metrics2.leading, 1, 5), line2.x, line2.y, "AvenirLTStd-Roman.otf", fontSize) text2:setFillColor(0) local text3 = display.newText("Asc: " .. string.sub(metrics3.ascent, 1, 5) .. " Desc: " .. string.sub(metrics3.descent, 1, 5) .. " Hght: " .. string.sub(metrics3.height, 1, 5) .. " Lding: " .. string.sub(metrics3.leading, 1, 5), line3.x, line3.y, "BreeSerif-Regular.ttf", fontSize) text3:setFillColor(0) local text4 = display.newText("Asc: " .. string.sub(metrics4.ascent, 1, 5) .. " Desc: " .. string.sub(metrics4.descent, 1, 5) .. " Hght: " .. string.sub(metrics4.height, 1, 5) .. " Lding: " .. string.sub(metrics4.leading, 1, 5), line4.x, line4.y, "FredokaOne-Regular.ttf", fontSize) text4:setFillColor(0) local text5 = display.newText("Asc: " .. string.sub(metrics5.ascent, 1, 5) .. " Desc: " .. string.sub(metrics5.descent, 1, 5) .. " Hght: " .. string.sub(metrics5.height, 1, 5) .. " Lding: " .. string.sub(metrics5.leading, 1, 5), line5.x, line5.y, "PatrickHand-Regular.ttf", fontSize) text5:setFillColor(0)

You can download a zipped version with fonts included here:

Now, this is how it looks on Android devices:

That looks perfectly fine to me. Notice that the second line is the only line where metrics.leading has an actual value other than 0. But still, this line is aligned fine. Now check out how it looks on an iPhone:

Notice how this same second line is not aligned any more as it is supposed to be. If you add the metrics.ascending value and the metrics.descending value, you get the metrics.height value, but the metrics.leading value is not considered, in contrast to Android, where metrics.leading is part of metrics.height. Hope it gets clear what I’m trying to say.

I don’t see this is expected behaviour, but maybe I’m overseeing something :slight_smile:

Could anyone have a look at this?

Thanks

Maybe I misunderstood your question, but the screenshots in my original post demonstrate exactly what happens when I use other fonts. I my screenshots I use five different fonts and they all work except for the one the has metrics.leading in it. While Android has no problem dealing with that, iOS does.

@CoronaChris, I’m looking to see what I can find about this. Corona is dependant on the operating system the app is running on to render the text, so differences are to be expected.  “Leading” is the space between lines of text (not the same as spacing). It looks like iOS is applying the leading to the rendered image. Corona uses native features to take a string of text and turn it into a rectangular image that can be fed to the graphics pipeline.

I’m not sure if this is just “how that os works”, or if we are not passing some piece of information to the renderer correctly. Let me see what I can find out. But you should be able to use the font metrics and align your objects on their baseline.

See: http://docs.coronalabs.com/api/library/graphics/getFontMetrics.html

Rob

Thanks Rob. I’ve read though those docs many many times and here is the thing: According to this image right here:

“height” = “ascent” + “descent”.

“Leading” is not included in “height”.

That’s exactly what happens on iOS. See the values in second line:

Ascending 10.58 + Descending 3.41 equals height 14.

On Android though, the “height” value consists of “Ascending”, Descending" plus"leading":

Ascending 10.58 + Descending 1.41 plus leading 2.7 equals height 16.8

So, the docs dont match what happens on Android.

iOS: height = ascending + descending

Android: height = ascending + descending + leading.

Hope it got clear :slight_smile:

Maybe I misunderstood your question, but the screenshots in my original post demonstrate exactly what happens when I use other fonts. I my screenshots I use five different fonts and they all work except for the one the has metrics.leading in it. While Android has no problem dealing with that, iOS does.

@CoronaChris, I’m looking to see what I can find about this. Corona is dependant on the operating system the app is running on to render the text, so differences are to be expected.  “Leading” is the space between lines of text (not the same as spacing). It looks like iOS is applying the leading to the rendered image. Corona uses native features to take a string of text and turn it into a rectangular image that can be fed to the graphics pipeline.

I’m not sure if this is just “how that os works”, or if we are not passing some piece of information to the renderer correctly. Let me see what I can find out. But you should be able to use the font metrics and align your objects on their baseline.

See: http://docs.coronalabs.com/api/library/graphics/getFontMetrics.html

Rob

Thanks Rob. I’ve read though those docs many many times and here is the thing: According to this image right here:

“height” = “ascent” + “descent”.

“Leading” is not included in “height”.

That’s exactly what happens on iOS. See the values in second line:

Ascending 10.58 + Descending 3.41 equals height 14.

On Android though, the “height” value consists of “Ascending”, Descending" plus"leading":

Ascending 10.58 + Descending 1.41 plus leading 2.7 equals height 16.8

So, the docs dont match what happens on Android.

iOS: height = ascending + descending

Android: height = ascending + descending + leading.

Hope it got clear :slight_smile: