Text anti-aliasing looks different when drawn to image

Can anyone explain why these two scenarios would produce noticeably different results on a retina display?

A. AttributedString drawn directly to graphics context via draw()


B. AttributedString drawn to Image (appropriately scaled) which is then drawn to the original context.

In scenario B, drawing to the Image is performed in this way:

float scale = g.getInternalContext().getPhysicalPixelScaleFactor();

m_textImage = Image(Image::ARGB, r.getWidth() * scale, r.getHeight() * scale, true);

Graphics textGraphics(m_textImage);
textGraphics.addTransform(AffineTransform::scale(scale, scale));

text.draw(textGraphics, r); 

Scenario B produces noticeably more jagged edges, but the difference is more subtle than just drawing a non-retina image.

Image rendering is done in software, normal window rendering may be done in hardware and possibly also using subpixel antialiasing vs. normal antialiasing.

Is that the case even when using an OpenGL renderer?

Especially so. OpenGL renderer is done in “hardware”.

Yes, of course, but I was under the impression that Images would also be backed by an OpenGL texture, and thus Image rendering would also be hardware rendering. It seems that’s not the case though.

Looking into this more, it appears the Image I’m getting on Mac is actually a CoreGraphicsImage. If scenario A is rendered with CoreGraphics, why would it differ from scenario B rendered to a CoreGraphicsImage?

The type of the image is not necessarily related to the engine rendering to it, I believe. It does make sense when you think about it: The software renderer is the lowest common denominator. While the hardware/OS contexts can take advantage of i.e. your LCD layout and apply suitable subpixel antialiasing, doing the same for a rendered image would look wrong on another monitor.

1 Like

Thanks for the continued info here. So even though they are both being drawn with CoreGraphicsContext::drawGlyph, they may look different because one is actually being drawn to screen?

If you create an Image with OpenGLImageType it’ll use the GL renderer.

1 Like

Can an OpenGLImageType be used within a normal paint call?

Yes, but there’ll be a performance penalty.