Re: 1-bit NSBitmapImageRep?
Re: 1-bit NSBitmapImageRep?
- Subject: Re: 1-bit NSBitmapImageRep?
- From: "Michael Ash" <email@hidden>
- Date: Thu, 17 Apr 2008 22:07:33 -0400
On Thu, Apr 17, 2008 at 8:41 PM, Graham Cox <email@hidden> wrote:
> If only life were that simple...
>
> The requirement is to hit-test a stroked or filled path to pixel-perfect
> accuracy. Yes there is containsPoint: and that other one in CG for
> hit-testing a stroke, but these are blunt instruments when it comes to all
> the possible stylistic variations that can be applied to a path, including
> shadows, images arranged along the path, text and so forth. (I use these
> methods as a first "weed out" of the hit). There is also no built-in way to
> test whether a rect intersects the pixels in a path.
>
> So, each graphic object currently caches an offscreen image of itself
> (created lazily when an accurate hit test is needed) and tests the pixel at
> the given point (or scans within a given rect) for pixels that are turned
> on. This only *needs* to be a 1-bit image, because either a point hits or it
> doesn't. But because the pixels themselves are drawn using Quartz, the
> offscreen context needs to be writable by Quartz, which a 1-bit rep isn't,
> as I have discovered. Thus the smallest supported bit depth is 8 bits,
> leading to the eightfold overkill in terms of memory storage - and given
> that there can be thousands of graphic objects this does add up.
>
> Heinrich's suggestion would work, but each time the offscreen cache needs
> to be updated (which can be often in an interactive editing situation) a
> temporary 8-bit image needs to be made then hand-copied and thresholded down
> to the 1-bit version. While this is going to save the memory in the long run
> the penalty is likely to be much more sluggish interaction - the classic
> trade-off. That said I might try it and see if the performance is
> acceptable.
>
> If I'm missing anything obvious, I hope someone will point it out!
There is an easy, although deeply non-obvious, way to do 100% correct
hit testing with any stylistic variations, and even to hit test with
fill versus stroke. In fact, you're almost there, and just need to
take it a little bit further.
The answer is, instead of drawing into a big context and then checking
the pixel value of the location in question, you draw into a very
teeny context with a proper transform set up. Create a 1x1 context,
set up the proper affine transform to make that pixel be the one
you're hit testing, then draw whatever it is you're drawing.
Afterwards, check your one pixel: if it's dark, you hit, if it's
light, you missed.
You're still wasting the memory for an 8-bit context, but at least
it's only 7 bits wasted. :)
Mike
_______________________________________________
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