Is it possible to know if the text is too long for display.newText()?

For some reason, I have to display texts retrieved online and the texts sometimes might be too long to be displayed due to texture memory limitation. 

I got warnings like this one:

WARNING: The text object containing the following text will not render correctly because the height (19004) exceeds max texture dimensions (16384)

However, there is no error returned in the Lua code.

Is it possible to detect this warning/error in my code? so that I can display some warning/error message in my app?

If not, the whole area becomes a long “empty” space, a very strange/bad user experience.

The texture memory limitations vary between devices, therefore I cannot just set a “fixed” maximum number of texts to be displayed. 

I don’t think there is, but you should log a feature request or bug for this as I think it should, too.

You should definitely have some maximum size of text set because it will cause memory problems, as the warning says.  I would define a width and height as often as you can, because you do know the screen dimensions and that is a natural, device-specific, limit on memory use which you can easily implement.

I’ve found that the best way to render a lot of text is not to use the newText function but to render to a local HTML file and put up a web view. This passes the buck of memory handling to the system and lets you forget about things like scrolling, if you want to. Don’t worry, it is totally possible to make a web view look just like your normal newText output.

http://docs.coronalabs.com/daily/api/library/native/newWebView.html

@horacebury

Thanks for the detailed reply & info.

I did try with webView to load a local file to display some info. However, it’s not as fast as using the native display objects. Even the data is from a local file, there is still a slight delay.

Besides, webView is always on top, it’s going to have a big headache for me to do other UI (such as menus). This is the main reason I can never use webView to render my screen.

I do not have specific width & height because I am using scrollView to display these texts. Therefore, I think I still need the error to be returned from Corona when the texts are too long to be handled.

I did file a bug report before and Corona says it works as design. I think it has to be a new feature then…

How about using the device width/height as a limit as horace said… Calculate how many characters can fit on a screen by using fontSize * chars to give you a rough idea…

Then for each time the text exceeds the screen limits (w/h) (the text from the network request) you split the string and make a new text object to insert into your scrollview, that is positioned below the previous text object.

It might not look 100% perfect but you should be able to get it pretty good if you use some string magic and decide where to make the cut off before splitting the string ( perhaps split it after the last period found in the string before the cut off limit).

Hope this helps.

It’s gonna look weird for every splitting places because I don’t think I can put splitting texts seamlessly together.

I have to deal with the URLs inside the texts already. I have been splitting texts but whenever there is an URL, it has to be a new line. There is no way I know exactly the (x,y) for the last character after I call display.newText().

I still think Corona should just give me an error indication when the texts are too long to be handled.

Can you boil the code down to something we can try working on, with a sample text?

There is this block of code that can help you auto-resize text (by changing the font size) by running tests on the text block to see if it will fit in the allotted space:

https://developer.coronalabs.com/code/text-wrapper-class

It works great in iOS, but works less great on Android devices.  I took some of the code and made a smaller function that does most of the same thing and it works better on Android:

function sizeText(t, w, h, fontname, fontsizeMin, fontsizeMax, increment) local tempGroup local tempHeight fontsize = fontsizeMax while 1 do tempGroup = display.newText(t, 0, display.pixelHeight + 20, w, 0, fontname, fontsize) tempHeight = tempGroup.height tempGroup:removeSelf() if ( tempHeight \< h ) or ( fontsize - increment \< fontsizeMin ) then break else fontsize = fontsize - increment end end return fontsize end

It will return the font size that you should use for the specified font to get it to fit in the designated space.

So the usage would be:

categoryFontSize = sizeText(categoryString, 740, 70, "Courier", 58, 64, 1) playerCategoryText = display.newText(categoryString, 0, 0, 740, 70, "Courier", categoryFontSize )

That would run through and see if the font size could be as large as 64 and still fit in the allotted width, and if not, keep shrinking the font size by 1, until it gets to the largest number (58 and over) that fits.

Not sure if that will help you or not, but thought I would pass it on.

@thedog

Thanks for sharing the code, but it’s not going to solve my problem. The max number of texts can be displayed varies among actual devices. So I cannot limit a “fixed” area first and also I want to maintain the same font size (my app is a RSS reader app).

I have submitted a feature request for this:

http://feedback.coronalabs.com/forums/188732-corona-sdk-feature-requests-feedback/suggestions/5431593-newtext-should-return-error-when-the-number-of-t

If you ever would encounter the situation that long texts will be displayed in your app, you may consider to give it some votes. If I can get the error, I can show something else to the user to create a better UI experience. Otherwise, for now, I don’t know the texts cannot be displayed & Corona create a long & empty space.

And from my testing, iPhone 5S can display many more texts than a Galaxy Tab 3 8-inch. This difference is also the main reason that I cannot set a fixed maximum texts to be displayed.

Thanks.

You can get the max texture size supported by the device using

system.getInfo(“maxTextureSize”)

Then with a little trial and error you can probably figure out how much text will fit on any particular size texture and then break up your text into multiple objects so each section is always a bit smaller than that max size.

Or, more simply, you could figure out how much text will fit on the device with the smallest max texture size and then break up the text on all devices in exactly the same way to always fit that small texture, piecing them all together in exactly the same way on every device.  Sure, some devices won’t be using their particular maximum texture size to display the text, but so what?

In terms of alignment of each text block, you might be able to use the object.contentBounds table on a text object to find where the text ends and then insert the next object a fixed distance below that.

I always hate when this is suggested to “workaround” other text issues, but have you thought of getting the text and writing it to a local HTML file and then using WebView to display it instead of display.newText()?

Honestly, can’t say that I have ever considered doing that or have any knowledge on how it would actually work.  But it seems like it might address the issue you are having since my understanding was that WebView didn’t create an image of the text and therefore wouldn’t be limited by texture size.

@thedog

I have replied about using webView to display long texts in my earlier post since horacebury also mentioned about using webView.

Here is my reply again:

I did try with webView to load a local file to display some info. However, it’s not as fast as using the native display objects. Even the data is from a local file, there is still a slight delay.

 

Besides, webView is always on top, it’s going to have a big headache for me to do other UI (such as menus). This is the main reason I can never use webView to render my screen.

For more additional information, my app is a RSS-type of reader app. I do have a webView to display web pages, however when I want to display some summary texts, I don’t think webView fits my case.

Sorry, I did read that earlier and had forgotten when I posted that last message.  It’s late.   :slight_smile:

Frankly, you are basically fighting the content vs resources fight. At some point you need to relent and find a work around. In this case, you are working with the mobile phone equivalent of an old copy of PhotoShop trying to edit a 10000x10000 image - sometimes the memory provided by the system just won’t let you do it.

The specific resource in this case is video memory, because the text returned by the newText function is actually an image, not text.

(1) Let’s say after calculation, the first block contains 100 characters (words). After displaying the first 100 characters(words), where to put the 101st character (word)? a new line? how to maintain the original paragraphs/formats?

(2) If there is texture limitation, all texts can be displayed in a single scrollView by breaking up the text?

I am not trying to fight the resource problem and it’s ok I cannot display long text due to memory limitation. I am not trying to get a workaround to display long text either.

However, I just want Corona to return some error indication when the text is too long to be displayed so that I can show something else to the user. (for example, a clickable hyper link)

I don’t think there is, but you should log a feature request or bug for this as I think it should, too.

You should definitely have some maximum size of text set because it will cause memory problems, as the warning says.  I would define a width and height as often as you can, because you do know the screen dimensions and that is a natural, device-specific, limit on memory use which you can easily implement.

I’ve found that the best way to render a lot of text is not to use the newText function but to render to a local HTML file and put up a web view. This passes the buck of memory handling to the system and lets you forget about things like scrolling, if you want to. Don’t worry, it is totally possible to make a web view look just like your normal newText output.

http://docs.coronalabs.com/daily/api/library/native/newWebView.html

@horacebury

Thanks for the detailed reply & info.

I did try with webView to load a local file to display some info. However, it’s not as fast as using the native display objects. Even the data is from a local file, there is still a slight delay.

Besides, webView is always on top, it’s going to have a big headache for me to do other UI (such as menus). This is the main reason I can never use webView to render my screen.

I do not have specific width & height because I am using scrollView to display these texts. Therefore, I think I still need the error to be returned from Corona when the texts are too long to be handled.

I did file a bug report before and Corona says it works as design. I think it has to be a new feature then…

How about using the device width/height as a limit as horace said… Calculate how many characters can fit on a screen by using fontSize * chars to give you a rough idea…

Then for each time the text exceeds the screen limits (w/h) (the text from the network request) you split the string and make a new text object to insert into your scrollview, that is positioned below the previous text object.

It might not look 100% perfect but you should be able to get it pretty good if you use some string magic and decide where to make the cut off before splitting the string ( perhaps split it after the last period found in the string before the cut off limit).

Hope this helps.

It’s gonna look weird for every splitting places because I don’t think I can put splitting texts seamlessly together.

I have to deal with the URLs inside the texts already. I have been splitting texts but whenever there is an URL, it has to be a new line. There is no way I know exactly the (x,y) for the last character after I call display.newText().

I still think Corona should just give me an error indication when the texts are too long to be handled.