Re: CGShading & Printing conflicts
Re: CGShading & Printing conflicts
- Subject: Re: CGShading & Printing conflicts
- From: "Martin" <email@hidden>
- Date: Thu, 12 May 2005 18:09:12 -0700
> I'm using the CoreGraphics functions to draw a color gradient in a view.
> It works perfectly well on screen. But it crashes (EXC_BAD_ACCESS in
> PDFFunctionEmitReference) as soon as the view is printed...
I'm replying to an old email I found in the list archives because I had the same problem and saw a few messages asking about the same thing with no answers given.
The problem was related to using CGContextDrawShading. Specifically the shading appeared fine on screen but drew all black (or garbage) when saving as PDF.
So, if you're using CGContextDrawShading you're probably using the user info to stuff away color information that your interpolation callback can use to generate the gradient. Probably your code looks something like this:
void MYDrawGradient( float red, float green, etc )
{
MYInfo myInfo = (red, green, etc);
CGFunctionCallbacks funcCallbacks = { 0, MYGradientIterpolator, NULL };
// some setup omitted for brevity, but the main parts are here
CGFunctionRef shadeFunc = CGFunctionCreate( &myInfo, 1, NULL, 4, NULL, &funcCallbacks );
CGShadingRef shadeRef = CGShadingCreateAxial( colorSpace, sourcePt, destPt, shadeFunc, 0, 0 );
CGContextDrawShading( context, shadeRef );
// cleanup omitted
}
When drawing to the screen your color calculation callback was called and it generated the proper colors.
The problem for me was that when drawing to PDF my callback was given what looked to be a garbage user info struct. I noticed that the function "MYDrawGradient" was NOT active on the stack when doing this drawing. Since my user info struct was allocated on the stack, it must have been overwritten at this point.
Perhaps this is obvious for people who program with CoreGraphics more often, but it seems that CGFunctionCreate() assumes the user info you pass to it will persist outside of the scope in which you create the function. That is, your user info must persist until the CGFunctionReleaseInfoCallback is invoked. The setup code can then be modified to:
MYInfo* myInfoPtr = calloc( 1, sizeof(MYInfo) );
*myInfoPtr = (red, green, etc);
CGFunctionCallbacks funcCallbacks = { 0, MYGradientIterpolator, free };
Now your gradient should draw just fine.
>From this behavior I would guess that the PDF drawing routines bundle up drawing operations for some purpose. Can anyone comment? I find it odd that no mention of the requirements this places on your user info are made for CGFunctionCreate, so I've filed a documentation bug.
~Martin
_______________________________________________
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