Re: turning off anti-aliasing
Re: turning off anti-aliasing
- Subject: Re: turning off anti-aliasing
- From: Scott Thompson <email@hidden>
- Date: Wed, 5 Jul 2006 08:21:10 -0500
On Jul 5, 2006, at 1:21 AM, Rob Ross wrote:
am drawing some simple path shapes (circles, squares, sine wave,
etc), and I wanted to draw a cartesian coordinate grid behind them.
But my grid lines were coming out "fuzzy". I was stroking them as 1-
unit wide, but as I resized the Window containing the view, they
would "smear" and every other pixel growth of the window,
vertically or horizontally, I would see the grid lines change from
one to two pixels in width. After doing some research I thought the
problem was due to antialiasing. (Another mystery to me is why,
although the scale factor is 1,1, when I change the size of my
window by a single pixel, the new window size as reported by bounds
has increased by .5 of a pixel.)
This is probably the case. In my book I call it the half-pixel line
problem.
When Quartz sets up a context on a bitmap (like the screen) it aligns
user space so that the whole number coordinate values correspond to
the lower, left edges of pixels. If you draw a one point wide line,
then, it actually overlaps over two pixels (half a pixel on either
side of the boundary). One way to "fix" this is to offset your
coordinate system by 0.5, 0.5 before drawing. While this technique
works today, it may not work as well when we have scaleable UI and
high density monitors. You'll have to decide whether or not it's a
valid tradeoff for your application.
How are you drawing your grid lines?
I tried turning off antialiasing before drawing the grid via
[nsGraphicsContextInstance setShouldAntialias:NO] but that didn't
seem to do anything at all. What is this purpose of this method?
It should disable antialiasing as part of the current graphics state.
I wrote the following drawRect into a custom view:
- (void)drawRect:(NSRect)rect {
NSRect leftRect, rightRect;
NSDivideRect([self bounds], &leftRect, &rightRect, [self
bounds].size.width / 2.0, NSMinXEdge);
[[NSColor redColor] set];
leftRect = NSInsetRect(leftRect, 5, 5);
rightRect = NSInsetRect(rightRect, 5, 5);
[[NSGraphicsContext currentContext] saveGraphicsState];
[[NSGraphicsContext currentContext] setShouldAntialias: NO];
NSBezierPath *oval1Path = [NSBezierPath bezierPathWithOvalInRect:
leftRect];
[oval1Path stroke];
[[NSGraphicsContext currentContext] restoreGraphicsState];
NSBezierPath *oval2Path = [NSBezierPath bezierPathWithOvalInRect:
rightRect];
[oval2Path stroke];
}
And it does what I expect, the left oval is not antialiased, the
right one is. I can't imagine why it doesn't work for you. You might
need to be very careful about your saves and restores.
But I found a method in Quartz 2D (or Core Graphics? - not sure
what the proper term is ) that seems to do the trick, so before
drawing my grid lines I call this method:
Quartz 2D refers to the 2D, PDF-derived drawing library that is a
part of Core Graphics. Core Graphics, in turn, describes the entire
Mac OS X graphics system that is shared by applications. In addition
to Quartz 2D, Core Graphics contains the window compositor, routines
for managing the display(s), routines for interacting with the window
server (sending mocked-up events and the like) and similar tools.
If you want to be very specific about just the drawing library you
can use the term "Quartz 2D", however, in casual conversation, when
the context is understood, the term "Core Graphics" is often
substituted.
:-)
- (void)setAntialiasing:(BOOL)flag
{
NSGraphicsContext *nsctx = [NSGraphicsContext currentContext];
CGContextRef context = (CGContextRef)[nsctx graphicsPort];
[nsctx setShouldAntialias:flag];
CGContextSetAllowsAntialiasing(context,flag);
}
with YES, and after I draw the grids I call it with NO.
This is a very "heavy handed" mechanism for achieving the same effect
you should be getting from setShouldAntialias.
CGContextSetAllowsAntialiasing turns of the context's ability to
antialias (irrespective of the graphics state). In other words, if
you call CGContextSetAllowsAntialiasing then you won't get
antialiasing (or font smoothing) in that context until you turn it
back on.
My question is, is there a pure Cocoa way of doing this without
using the CGContextSetAllowsAntialiasing method? Or is this the way
I should be doing it? And why doesn't "setShouldAntialias:NO" by
itself work?
So far as I know, it should. :-(
Scott
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden