Rendering text to Image more blurry than rending in paint?


#1

I was trying to speed up some drawing code that draws a lot of numbers by prerendering the numbers to small images, then render the images with g.drawImageAt instead of g.drawText. But the text on the images comes out blurry, whereas the text drawn directly in paint methods comes nice and crisp. In both cases the graphics contexts used is a coregraphics one.

Why is there a difference here? 


#2

maybe the direct to screen rendering uses sub-pixel rendering 


#3

I noticed the same thing a while ago.  My guess was that a font rendered in the paint method uses hinting to align the characters to pixels in such a way that everything looks crisp.  If you're rendering to an image, maybe that doesn't happen, or maybe the pixels in the image don't map to screen pixels perfectly?  


#4

What type of screen are you using? My guess would be that you are creating your images and not taking into acount the graphics context's scaling factor e.g. Graphics::getInternalContext().getPhysicalPixelScaleFactor().

But are you sure drawing the text as images is actually faster? Have you profiled it? You might be better off using something like a GlyphArrangement to avoid the overhead of adding the text each time. Actually drawing the paths should be pretty quick.


#5

If you’re running Windows, try defining JUCE_USE_DIRECTWRITE in AppConfig.h – is that any better?

#ifndef    JUCE_USE_DIRECTWRITE
 #define JUCE_USE_DIRECTWRITE	  1
#endif

Rail


#6

FYI, DirectWrite isn't used for rendering, it's only used for layout of unicode strings.


#7

I was having a similar experience… I found that using

Graphics::drawText (const String& text, const Rectangle<float>& area, Justification justificationType, bool useEllipsesIfTooBig)
instead of

drawText (const String& text, const int x, const int y, const int width, const int height, Justification justificationType, const bool useEllipsesIfTooBig)
the text was rendered better on both OSX and Windows… using the same values.

Rail


#8

Ok, i finally had time to look into this again and the problem was indeed as dave96 suggested that im on a retina Mac that have Graphics::getInternalContext().getPhysicalPixelScaleFactor() == 2. So images needed the double resolution.

Now, after scaling, it looks good but I think its not possible to blit it efficiently to the graphics context as drawImageAt will draw it double size and thus i'd have to going though drawImage and affine transforms.

My conclusion so far is that it isnt possible to speed up text drawing this way.  


#9

Some profiling proved my post above wrong:

Rendering small text...

   - as opaque ARGB using g.drawImage():  15 microsecs.

   - as using g.drawText():  23 microsecs.

... even though the images are 4 times bigger due to a physical (retina) scale factor of 2. On a standard display it should be even faster.