EASILY Make Your Text Sharp on Retina Displays

UPDATE:

Here’s an even better solution:

[blockcode]
require “widget”
display.newText(…
[/blockcode]

OLD POST:
Posted this to my blog, shows how you can get text objects to show up crystal clear on iPhone4/iPod touch 4:

http://jonbeebe.tumblr.com/post/2351470837/beebegames-class-newretinatext-tutorial

By default, display.newText() shows up blurry on iPhone4’s and iPod touch 4’s. My newRetinaText() function fixes that, and text looks amazing. [import]uid: 7849 topic_id: 4573 reply_id: 304573[/import]

I’m interested in HOW this works exactly. From a cursory look it seems you’re just doubling the font size and then scaling the text in half. Is that all it takes to get the text to look sharp on iphone4? If so, that’s pretty sweet and good find. If there’s anything else I’m missing it’d be cool if you could comment on it. Thanks. [import]uid: 10835 topic_id: 4573 reply_id: 14488[/import]

Yup, that’s exactly it! Lol, but it works. If you don’t have the text centered on the screen though, alignment can be thrown off. The function takes away all the guesswork tho and allows you to get beautiful text thats compatible win any display to “just work” tho.

Enjoy :slight_smile: [import]uid: 7849 topic_id: 4573 reply_id: 14489[/import]

Thanks! It’s a cool find (and I should have though about it, I’m basically doing the same with spritesheets).However it’s faster to just change the values in my code than to rewrite everything to use your class, though I would have gone for it if I was starting from scratch.

Edit: While we’re on the subject, do you know how to make an outer stoke on the text (say black borders on colored text)? Right now I’m sandwiching the text in between black text to give the illusion of an outer stroke. However using this method, now on retina displays the stroke is barely visible (since it’s just one pixel wide).

The whole work around I’m doing is really annoying and worthless if there’s a parameter to set the stroke. Does that exist? [import]uid: 10835 topic_id: 4573 reply_id: 14490[/import]

Hey Jon,
Thanks for the Retina text function. Works nicely! Did you consider streamlining it by using setReferencePoint instead of doing the math to align it left, right, or center? I tinkered with the function on my side, changed a few things, and using reference points seems to eliminate the need for the math.

I haven’t tested it extensively, but check it out… obviously there is additional code (that you wrote) before and after this little chunk, easily pieced back together.

textObject.text = textString  
textObject.xScale = 0.5 ; textObject.yScale = 0.5  
  
if alignment == "left" then  
 textObject:setReferencePoint(display.CenterLeftReferencePoint)  
elseif alignment == "right" then  
 textObject:setReferencePoint(display.CenterRightReferencePoint)  
end  
textObject.x = x  

Notice that the “center” option is removed from the IF statement, because center is default for reference point alignment. Also, you can change “CenterLeftReferencePoint” to “TopLeftReferencePoint” if you want the very top of the text line at your X position, versus its center axis (i.e. if your text was “Tilt Monster”, the top of the “T” would be at your X value, versus the central axis).

Let me know if this works for you! It works on my side.

Brent
[import]uid: 9747 topic_id: 4573 reply_id: 14763[/import]

Maybe it got fixed with the latest update, but when I first discovered how to get text looking sharp on retina displays, the setReferencePoint() function didn’t work properly when it came to text that wasn’t aligned with the center of the screen, particularly when it came to updating an existing text object with a new or modified string.

For that reason, I created the updateText function which should preserve all of your text and ensure is everything where you initially set it.

Like I said, the reference point thing might work fine now, so whichever you want to use should be fine. For text that needs to be updated constantly (through an enterframe listener, for example), then the reference point fix might be better (if it works properly with left/right aligned text) for performance. [import]uid: 7849 topic_id: 4573 reply_id: 14764[/import]

Hi Jonathan,

Just a quick heads up: I encountered a possible bug with the Retina Text function. Using a custom font (configured correctly in build.settings), I encountered a solid rectangle on an 3rd-gen iPod Touch which I use for low-end testing… this is not the newer Touch with Retina display, but the previous model.

From my testing, I can vouch that the rectangle was caused by the “scaleX” and “scaleY” downsize which is focal to the function. Displaying the text at normal size yielded the proper text (as in, passing arguments to the function and getting text back in return). Displaying it double size and scaling it down yielded a rectangle of the proper color, position on the screen, etc… just not the text. Using the “Update” sub-function did not help.

Anyway, just keep this in mind… this seems more like a Corona bug versus an Apple configuration bug. If you’re using the Retina function extensively in your next game, maybe hold off until the next release of Corona, using normal text instead…

As always, thanks for your contributions to the community!

Brent
[import]uid: 9747 topic_id: 4573 reply_id: 15133[/import]

Hi Brent,

I use the same function in Dungeon Tap to display a custom font and it works fine, and I use the same code in Tilt Monster (non custom font) and also works good on older devices (tested on original iPhone and iPod touch 2nd generation).

Could it possibly be the custom font you’re using? Try using a different one and see if the problem still occurs…

Thanks Brent,

Jonathan
[import]uid: 7849 topic_id: 4573 reply_id: 15134[/import]

Doh! It was indeed the specific font… no idea why… it appears perfectly at size 72 on the device, but at size 144 scaled down by half, it shows the rectangle. I’ll need to test this further, and maybe seek out the OpenType version of the font versus the TrueType.

Take care! [import]uid: 9747 topic_id: 4573 reply_id: 15156[/import]

Does this problem still apply? I’m assuming so, since it’s only been a few weeks since the last activity in this thread, I’m just checking.

Also, does this fix need to be applied to ui.lua as well? Again I’m assuming so, since ui.lua creates display.newText objects. [import]uid: 12108 topic_id: 4573 reply_id: 18163[/import]

Yup, still applies. Download the Ghosts vs. Monsters sample app, the ui.lua file there is updated to work with retina displays (no need for the newRetinaText function for that ui.lua file either). [import]uid: 7849 topic_id: 4573 reply_id: 18164[/import]

oh you already implemented this fix in ui.lua? sweet

btw did you see the hitTestObjects function I put in Code Exchange? I imagine that would make a good addition to your beebegames class. [import]uid: 12108 topic_id: 4573 reply_id: 18173[/import]

So this is a Corona bug? Do Ansca know about it, would be nice to have it fixed but thanks for the workaround… [import]uid: 9371 topic_id: 4573 reply_id: 19422[/import]

Doesn’t work with the list view :frowning: [import]uid: 9371 topic_id: 4573 reply_id: 20354[/import]

Yup, still applies. Download the Ghosts vs. Monsters sample app, the ui.lua file there is updated to work with retina displays (no need for the newRetinaText function for that ui.lua file either).

Jon, I know this is an old thread however I noticed the terrible looking text recently in my game. I downloaded the ghosts vs. monsters sample and can’t find any difference in the ui.lua file. I was hoping not to have to re-write all my current code to use your newRetinaText function. Do you have a copy of that ui.lua file that I could use? Would be much appreciated. [import]uid: 31262 topic_id: 4573 reply_id: 38280[/import]

No need to replace any of your code. Here’s a patched version of display.newText that is not only compatible with retina devices, but will NOT do anything on devices that aren’t retina-display capable (thus, preserving texture memory).

Just add the following code to the top of your main.lua file (before any calls to display.newText):

[blockcode]
local OldnewText = display.newText

display.newText = function( text, xPos, yPos, font, size )
local actualText = text or “”
local actualFont = font or “Helvetica”
local actualSize = size or 16

local xScale, yScale = display.contentScaleX, display.contentScaleY
local sizeMultiply = 1

if xScale < 1.0 or yScale < 1.0 then
sizeMultiply = 2
end

local t = OldnewText( actualText, 0, 0, actualFont, actualSize * sizeMultiply )
t:setReferencePoint( display.TopLeftReferencePoint )

t.xScale, t.yScale = xScale, yScale
t.x, t.y = xPos, yPos or 0, 0

return t
end
[/blockcode]

Using the function above, you shouldn’t have to rewrite any of your code (as long as you’re using display.newText to create text). It “just works” as a replacement to the old newText function.

The patched display.newText above completely replaces the need for the newRetinaText() function I mentioned at the start of this thread.

Btw: this patched function should behave exactly the same as the old newText() function (positioning should be the same across the board, etc.) so it shouldn’t break any code. [import]uid: 52430 topic_id: 4573 reply_id: 38284[/import]

Thanks Jon. Although this is the first time you have directly answered a question of mine, you have helped in so many other ways that you won’t see through your shared code and forum posts. I’m sure it’s the same with many other people. Appreciate everything my friend. [import]uid: 31262 topic_id: 4573 reply_id: 38286[/import]

Thanks for this nice piece of code, all my text looks great now on the iPad and iPhone/iTouch :). Just a quick note, it looks like when you call the the width or height property on a retinaText the width and hight will be doubled (since you’re doubling the size of the text). Just something to consider if you are manually aligning the text to something. [import]uid: 13780 topic_id: 4573 reply_id: 43271[/import]

This works great for iPhone3G(s) and iPhone4 but if I simulate my code on a Droid now (I’m using letterbox scaling) the text seems to be too large. Is this supposed to work on Android as well?
The Droid has a resolution of 480 x 854 which is smaller than double iPhone3G so my text is too large.

Any ideas how to fix this?

EDIT: If I change:
sizeMultiply = 2

to

sizeMultiply = 1 / xScale;

That would work right? It seems to work at least. [import]uid: 35378 topic_id: 4573 reply_id: 52690[/import]

Would someone please answer Urme and let us know if you believe his math adjustment is safe to use across supported devices?

Also, for anyone else who’s planning to use JB override of display.newText above, you need to fix this line:
[lua]t.x, t.y = xPos, yPos or 0, 0
– to be
t.x, t.y = xPos or 0, yPos or 0[/lua]
unless I mis-understand what he’s trying to do… [import]uid: 6175 topic_id: 4573 reply_id: 54300[/import]