Re: CALayer and pixel alignment
Re: CALayer and pixel alignment
- Subject: Re: CALayer and pixel alignment
- From: Matt Neuburg <email@hidden>
- Date: Wed, 22 Dec 2010 11:16:22 -0800
On Wed, 22 Dec 2010 10:09:04 +1000, Gideon King <email@hidden> said:
>I am drawing some CALayers, and use code like what I have below so I can draw exactly on pixels.
Your asking this question this way, and your use of ".5" in your code, makes me want to riff on the distinction between points and pixels. Explaining the distinction is a little scary, as one is apt to get one's head chopped off (rather like accidentally describing homoousia as homoiousia), but basically the numbers used for describing a drawing are points, whereas a pixel is a rectangular area of minimal illumination on a physical screen. The translation of points to pixels (software to hardware, really) happens behind the scenes. If you draw a zero-width line at an integral value, you can wind up with a two-pixel-thick line, because what's the poor old hardware to do? It must show *something*, which means illuminating *some* pixel, and you haven't said which side of the line you really want illuminated. The way to get pixel-correct drawing, therefore, is not to fudge with ".5" but to describe the boundaries of everything correctly to start with. I would recommend that you actually *remove* the ".5" stuff, as it probably masks the real source of the difficulty. m.
>
>When I draw it in my CALayer drawing code, it's not always pixel aligned. It's certainly better than if I had done no rounding, but still it is not correct. Is there something I'm not doing right? Why I think it may be CALayer based is because when I draw a whole bunch of these squares on layers, on some layers they are all aligned, and on other layers they are not - they are all affected at the same time. I do not have any scale transforms anywhere - only translations.
>
>
>
>CGContextSaveGState(gcontext);
>CGRect rect = CGRectMake(55.0f, -2.5f, 5.0f, 5.0f);
>CGRect deviceRect = CGContextConvertRectToDeviceSpace(gcontext, rect);
>
>NSDecimalNumberHandler *handler = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain scale:0 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO];
>
>deviceRect.origin.x = [[(NSDecimalNumber *)[NSDecimalNumber numberWithFloat:deviceRect.origin.x + 0.5f] decimalNumberByRoundingAccordingToBehavior:handler] floatValue] - 0.5f;
>deviceRect.origin.y = [[(NSDecimalNumber *)[NSDecimalNumber numberWithFloat:deviceRect.origin.y + 0.5f] decimalNumberByRoundingAccordingToBehavior:handler] floatValue] - 0.5f;
>deviceRect.size.width = [[(NSDecimalNumber *)[NSDecimalNumber numberWithFloat:deviceRect.size.width] decimalNumberByRoundingAccordingToBehavior:handler] floatValue];
>deviceRect.size.height = [[(NSDecimalNumber *)[NSDecimalNumber numberWithFloat:deviceRect.size.height] decimalNumberByRoundingAccordingToBehavior:handler] floatValue];
>
>CGRect drawingRect = CGContextConvertRectToUserSpace(gcontext, deviceRect);
>
>CGContextSetRGBStrokeColor(gcontext, 0.0f, 0.0f, 0.0f, 1.0f);
>CGContextSetRGBFillColor(gcontext, 1.0f, 1.0f, 1.0f, 1.0f);
>
>CGContextAddRect(gcontext, drawingRect);
>CGContextDrawPath(gcontext, kCGPathFillStroke);
>
>CGContextRestoreGState(gcontext);
>
>
>
>Regards
>
>Gideon
>
>
>
>
>
>
--
matt neuburg, phd = email@hidden, <http://www.apeth.net/matt/>
A fool + a tool + an autorelease pool = cool!
AppleScript: the Definitive Guide - Second Edition!
http://www.apeth.net/matt/default.html#applescriptthings_______________________________________________
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