Any way to manually fix NSTextView's font rendering bug?
Any way to manually fix NSTextView's font rendering bug?
- Subject: Any way to manually fix NSTextView's font rendering bug?
- From: Keith Blount <email@hidden>
- Date: Fri, 23 Apr 2010 01:50:47 -0700 (PDT)
Hello,
I'm looking for a way to fix a minor but unsightly bug in NSTextView (I've reported it as bug ID 7898471, but it may be the same bug as an older one with ID 6987764). It's a bug that seems to have been present since Tiger, so I'd like to find a solution myself rather than wait and hope it gets fixed. :) The bug is simply that when drawing certain fonts, NSTextView clips their ascenders or descenders, apparently because the ascender or descender cannot all be contained in the current line fragment. If you'd like to see it for yourself, it's pretty easy to reproduce:
1) Open TextEdit and create a new document.
2) Change the font to Optima 13-point.
3) Type a lowercase letter "g".
Note how the descender is clipped - the very last pixel is not drawn. If you then hit return, you'll see that it does get drawn properly now that the next line has been displayed, so it seems that the last pixel is pushed into the next line fragment rect. (If you then type another lowercase "g", then hit return again, then backspace twice to get rid of the return character and the second "g", you will see that the "g" gets deleted but the single pixel-high part of its descender that was on the next line is left behind as a sort of drawing artefact.)
So, essentially all I want to do is force a little extra drawing to get rid of these drawing bugs, but it seems forcing this extra drawing is a little more complicated than I had at first thought. For the past three years, my shipping app has worked around this bug by overriding -setNeedsDisplayInRect:avoidAdditionalLayout: in a custom NSTextView to force a little extra vertical drawing, e.g:
- (void)setNeedsDisplayInRect:(NSRect)aRect avoidAdditionalLayout:(BOOL)flag
{
// Redraw an extra six pixels above and below to avoid font-rendering bugs.
if (flag)
aRect = NSIntersectionRect(NSInsetRect(aRect, 0, -6), [self visibleRect]);
[super setNeedsDisplayInRect:aRect avoidAdditionalLayout:flag];
}
Until now, this has worked fine. However, for the next version of my software I've introduced a page layout view with zoom in/zoom out, which works much the same as the multiple-text-container wrap-to-page mode in TextEdit, and I noticed that at certain scales (e.g. 110%), I would get single-pixel blank lines drawn through the text in some places. Upon investigating, it turned out that my -setNeedsDisplayInRect:avoidAdditionalLayout: method was to blame - drawing an extra six pixels above and below would cause problems when drawing at some scales. (I had arbitrarily chosen six extra pixels hoping to provide enough extra padding for all fonts.)
Has anyone else combatted this bug and found a way around it? What is the correct way to force NSTextView to draw a little extra around each line in such a way that it won't cause any problems? (Perhaps I need to address it at the NSLayoutManager level?) It may be that I can just use the above code and change the extra padding to redraw only one extra pixel above and below, but I'm nervous about doing that given the problems described above.
Many thanks in advance for any suggestions.
All the best,
Keith
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden