Re: An NSShadow question
Re: An NSShadow question
- Subject: Re: An NSShadow question
- From: Chris Meyer <email@hidden>
- Date: Fri, 2 Apr 2004 17:06:02 -0800
What is really needed is a way to get a Bezier path representing the
stroke of another path such that filling the new path will be the same
as stroking the old path. Then you could accurately determine the outer
bounding path of the overall graphic and just create a shadow from that
by filling those outer bounds instead of trying to draw one shadow for
the fill and one for the stroke. (OK - it's a little more complicated
since you need to fill the 'hole'... anyway you get the idea).
If you're using a simple shape (like a rectangle) you may be able to do
it yourself. More complex shapes will either require OS support or lots
of math.
I've recently (today) requested the 'bezier path representing stroked
path' in in Radar (rdar://3610659).
On Apr 2, 2004, at 12:39 PM, Steve Sims wrote:
Hi Douglas,
Here's some code to demonstrate the problem I was talking about.
You'll need to create a new cocoa app, in IB make a new class based on
NSView, slap it into a window, create it's files, and then paste this
in to replace the drawRect method.
- (void)drawRect:(NSRect)rect
{
// Get a white background
[[NSColor whiteColor] set];
NSRectFill([self bounds]);
// Code that actually works - the CG way
/* CGContextRef context = [[NSGraphicsContext currentContext]
graphicsPort];
CGSize cgshOffset = { width: 20.0, height: 20.0};
CGContextSetShadow(context,cgshOffset,2.0);
CGContextBeginTransparencyLayer(context, NULL);
*/
// The NSShadow way...
NSShadow *shadow = [[NSShadow alloc] init];
NSSize shOffset = { width: 20.0, height: 20.0};
[shadow setShadowOffset:shOffset];
[shadow set];
// Draw and fill a bezier
NSRect bezRect = { origin: {10,10}, size: {50,50}};
NSBezierPath *bez = [NSBezierPath bezierPathWithRect: bezRect];
[bez setLineWidth: 10.0];
[[NSColor redColor] set];
[bez stroke];
[[NSColor blueColor] set];
[bez fill];
// Turn off our transparency layer for CG version
// CGContextEndTransparencyLayer(context);
}
The code above demonstrates the problem I'm getting with NSShadow,
i.e. a shadow with a dark border, and the fill shadow overlapping the
stroked path. For a more pronounced demonstration of this effect swap
the fill and stroke around and you'll see the line shadow over the
fill.
This code actually produces worse results than I was seeing before
with a more complex bezier - in this example the fill shadow is only
rendered as far as the top of the fill.
As you can see I've also included the CG way (which uses a
transparency layer as well as a shadow) commented out. If you
un-comment this and comment out the four lines that do things the
NSShadow way you'll see the results I had expected to be able to get
from NSShadow. The CG version renders the shadow perfectly.
The behaviour of the two is inconsistent, thus it seems that NSShadow
is not quite a simple wrapper around CGContextSetShadow.
I also tried to use a combination of the two techniques in the above
code using the CG calls without the CGContextSetShadow call and using
the NSShadow calls instead, but I get the same results as if the CG
calls were not there. Curiously if you leave in the
CGContextSetShadow call and also use NSShadow you get a double shadow
effect, thus further implying that NSShadow is not a simple wrapper.
I hope this better explains the unexpected behaviour I've been seeing.
Regards,
Steve
On 2 Apr 2004, at 14:42, Douglas Davidson wrote:
On Apr 1, 2004, at 10:17 PM, Steve Sims wrote:
Here's the problem. I have a closed bezier in an NSBezierPath
object with a wide outline (about 10 units). I set up an NSShadow
with a reasonable offset (about 20, 20 units) and apply it using the
set method so that when I draw my bezier I'll get a shadow. I then
draw my bezier using stroke then fill. The shadow that gets drawn
has a darker section of shadow where the stroke and fill overlap.
Also the shadow for the fill is rendered on top of the stroked path.
This looks bizarre and is not what I want.
Now the Quartz TLayer sample code kind of solves this problem with
all shadows being drawn behind all other drawn objects, however it
manages this by not using NSShadow, but rather using CG API calls.
It does this by using a transparency layer.
I tried to use the same CG API calls that TLayer uses together with
NSShadow, but this does not work - the CG calls seem to be ignored.
My solution has been to abandon using NSShadow.
-[NSShadow set] is basically a Cocoa wrapper around
CGContextSetShadow/CGContextSetShadowWithColor; you should be able to
do essentially the same things with either one. If you're seeing a
situation where that's not the case, perhaps you could post enough of
the details to reproduce it.
Douglas Davidson
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.