[Drawkit] clipping paths?
Graham Cox
graham.cox at bigpond.com
Wed Aug 12 17:40:46 PDT 2009
On 13/08/2009, at 7:11 AM, Rudy Richter wrote:
> For the work i've got in front of me i'm not actually using the
> entirety of DrawKit. I'm using the demo app as a quick and easy way
> for our artist to create objects en masse, I'm then taking the
> resulting save file and reading that in in my app using DKDrawing
> drawingWithData to read it all in. Once i've got my DKDrawing
> instance i can pick through the layers and extract the objects and
> styles he's created. I've run into a case where i want to be able
> to take as an example the donut shape and create a clipping path
> from it that i can use to mask other drawing. what ends up
> happening if i take the inverse of the donut's path and add it to
> the clipping path is i get the donut hole as i would expect, but i
> unfortunately additionally get the areas outside the donut that are
> part of the enclosing rectangle. Within the scope of not changing
> DrawKit too much (to maintain my ability to easily sync with the
> DrawKit releases) is there any way i should look at hooking into
> DrawKit to accomplish the goal of only having the donut hole as the
> clipping path?
>
> One thing i was looking at was possibly seeing if i could create
> something akin to DKFill/Stroke to allow specification of a clipping
> path for my use case. any suggestions on how i might accomplish
> those goals?
I'm trying to visualise what you want exactly - you want graphics to
be visible through the central hole of the donut (by which I assume
you mean the ring shape) and what else? The rest of the donut drawn
normally and the region outside of it blank? Like this?:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Picture 3.png
Type: image/png
Size: 56083 bytes
Desc: not available
URL: <http://lists.apptree.net/pipermail/drawkit-apptree.net/attachments/20090813/a868b510/attachment-0001.png>
-------------- next part --------------
To achieve this automatically (rather than faked, as here) this you'd
need to extract the central hole from the donut as a separate path. DK
can break paths down using the -subPaths method in the NSBezierPath
+Geometry category, though there's no guarantee exactly which path is
which - you might have to do a bit of further work to figure out which
is the outer and which is the inner path by comparing the bounding
rects. Once you have that path you can set add it as a clipping path
which will clip drawing to the hole.
The next step would be to draw things in the right order so that the
clipping was applied when you need it, and not when you don't - you
don't want to clip the donut itself for example otherwise its outline
won't show. Without subclassing parts of the existing drawing model in
DK, this is quite tricky, because really what you want here is a
'containment' relationship between the donut and the other objects it
is clipping, because the clipping path must remain in place while
those other objects are drawn, and removed afterwards. Several objects
support a containment relationship - notably DKLayerGroup and
DKShapeGroup. DKShapeGroup already supports a clipping path property
so this would probably be the easiest object to start with - just
needing the addition of an additional shape - the donut - drawn on top
to provide a frame for the group's contents. You could also do a
similar thing at the layer level to clip an entire layer's content
though that might be a little more work than the group approach.
Without a containment relationship, you could still set a clipping
path when your donut object gets its shot at drawing, but it will only
clip objects drawn afterwards, so the Z-position of the object becomes
a factor. Also, it's important to remove the clipping path you set
after drawing completes (for that layer) so somehow your donut has to
hook into the layer's drawing methods so it can restore the graphics
context. If you don't do this, things will get screwed up for the
whole window.
It would be possible to define a rasterizer to set a clipping path, so
clipping would be a style property, but there's no magic about that -
you'd still have to manage drawing as above, so in the long run it's
probably not worth the trouble.
--Graham
More information about the Drawkit
mailing list