Text artifacts on IOS

45 views
Skip to first unread message

Evgeni Gordejev

unread,
May 20, 2013, 10:54:57 AM5/20/13
to pl...@googlegroups.com
Hi,
I'm having some trouble with text rendering on iOS, you can see on the attached screenshot that there are some artifact lines on top of rendered text.
ios_text_artifact.png

Evgeni Gordejev

unread,
May 20, 2013, 11:53:42 AM5/20/13
to pl...@googlegroups.com
I found solution it was because float height, it got fixed when I casted float to int. 

CanvasImage textImage = graphics().createImage((int)layout.width(), (int)layout.height());

Maybe Michael can explain theory behind this issue :)

Michael Bayne

unread,
May 20, 2013, 12:25:44 PM5/20/13
to pl...@googlegroups.com
I've seen that in the simulator but never on device.

-- m...@samskivert.com

On May 20, 2013, at 7:55 AM, Evgeni Gordejev <evgeni....@gmail.com> wrote:

Hi,
I'm having some trouble with text rendering on iOS, you can see on the attached screenshot that there are some artifact lines on top of rendered text.

--
 
---
You received this message because you are subscribed to the Google Groups "PlayN" group.
To unsubscribe from this group and stop receiving emails from it, send an email to playn+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 
<ios_text_artifact.png>

Evgeni Gordejev

unread,
May 20, 2013, 12:50:59 PM5/20/13
to pl...@googlegroups.com
line is very narrow on retina displays, it is much easier to notice on basic iphone devices

Michael Bayne

unread,
May 20, 2013, 12:56:50 PM5/20/13
to pl...@googlegroups.com

On Mon, May 20, 2013 at 8:53 AM, Evgeni Gordejev <evgeni....@gmail.com> wrote:
I found solution it was because float height, it got fixed when I casted float to int. 

CanvasImage textImage = graphics().createImage((int)layout.width(), (int)layout.height());

Maybe Michael can explain theory behind this issue :)


That's a bit strange because under the hood, createImage quantizes the floats as well, it just rounds up instead of down. So if your width and height are 30.5 and 15.5 your code will create a 30x15 image and the default code will create a 31x16 image.

If you then render your text vertically centered in the image, like say:

  textImage.canvas().fillText(layout, 0, (textImage.height() - layout.height())/2);

then there could be a difference between your code and the default code. However, it seems odd that you would be creating an image to fit the text and then rendering the text anywhere except at 0, 0. (Other than perhaps right aligning it, but you don't seem to be doing that.)

Can you show more of the code?

-- m...@samskivert.com

Michael Bayne

unread,
May 20, 2013, 12:59:18 PM5/20/13
to pl...@googlegroups.com

On Mon, May 20, 2013 at 9:50 AM, Evgeni Gordejev <evgeni....@gmail.com> wrote:
line is very narrow on retina displays, it is much easier to notice on basic iphone devices

Interesting, maybe I've only seen it on the simulator because of that. I don't even have a non-Retina device any more. I have an iPod Touch 3rd Gen (Retina screen, but slower CPU/GPU than iPhone 4 and less RAM) that I use for "oldest device" testing.

-- m...@samskivert.com

Evgeni Gordejev

unread,
May 20, 2013, 1:07:36 PM5/20/13
to pl...@googlegroups.com
I have tried also with 

CanvasImage textImage = graphics().createImage(Math.round(layout.width()), Math.round(layout.height()));

and it works as well, but not without quantization. By the way I'm using Playn 1.7

Michael Bayne

unread,
May 20, 2013, 1:09:09 PM5/20/13
to pl...@googlegroups.com

On Mon, May 20, 2013 at 10:07 AM, Evgeni Gordejev <evgeni....@gmail.com> wrote:
I have tried also with 

CanvasImage textImage = graphics().createImage(Math.round(layout.width()), Math.round(layout.height()));

and it works as well, but not without quantization. By the way I'm using Playn 1.7


Your sizes may be less than half a pixel on the edge. PlayN always rounds up, because it assumes you don't want your image to be clipped even if you only have 1/4 of a pixel (for example) to draw. If you use ceil() then you'll probably see the artifacts.

-- m...@samskivert.com

Evgeni Gordejev

unread,
May 20, 2013, 1:13:05 PM5/20/13
to pl...@googlegroups.com
Nope, no artifacts with ceil here is complete code:

private Layer createTextLayer(String text, float w, float h){

Font font = graphics().createFont("CoolveticaRg", Font.Style.PLAIN, h/3f);

TextLayout layout = graphics().layoutText(text, new TextFormat().withFont(font));

CanvasImage textImage = graphics().createImage((float)Math.ceil(layout.width()), (float)Math.ceil(layout.height()));


textImage.canvas().setFillColor(iconColor);

textImage.canvas().fillText(layout, 0, 0);

ImageLayer txtLayer = graphics().createImageLayer(textImage);

txtLayer.setOrigin(0, layout.height()/2f);

return txtLayer;

Michael Bayne

unread,
May 20, 2013, 2:10:19 PM5/20/13
to pl...@googlegroups.com

On Mon, May 20, 2013 at 10:13 AM, Evgeni Gordejev <evgeni....@gmail.com> wrote:

txtLayer.setOrigin(0, layout.height()/2f);

That's really weird. There's still one difference between your ceil code and the stock code, which is that the stock code keeps the unrounded dimensions around and reports those via width() and height(), even though the actual size of the internal bitmap for the canvas image is rounded up.

I have seen issues where text looks blurry when you don't anchor it on pixel boundaries (which is not surprising). So the above code is probably problematic. But it shouldn't cause artifacting.

Try creating the image using the raw sizes (don't quantize) and then quantize your origin instead:

txtLayer.setOrigin(0, (int)(layout.height()/2f));

If that fixes the artifacting, then maybe it's some weird issue with iOS drawing a bitmap on non-pixel boundaries. Though that would be weird too, because surely lots of images are drawn with non-pixel boundaries.

I guess another thing to try would be drawing a circle or some non-text into the canvas and seeing whether that also had artifacting.

-- m...@samskivert.com

Evgeni Gordejev

unread,
May 20, 2013, 2:34:05 PM5/20/13
to pl...@googlegroups.com
You are almost right, I tried to quantize origin but it just shifted line little bit, but then I tried to quantize font size and it worked(artifact was gone). And my text is blurry, do you have any hints how to fix that?

Michael Bayne

unread,
May 20, 2013, 2:57:36 PM5/20/13
to pl...@googlegroups.com

On Mon, May 20, 2013 at 11:34 AM, Evgeni Gordejev <evgeni....@gmail.com> wrote:
And my text is blurry, do you have any hints how to fix that?

Make sure the image that contains the text is positioned on an even pixel boundary.
Reply all
Reply to author
Forward
0 new messages