[comp.sys.mac.programmer] Color QD fill problems

rick@jessica.stanford.edu (Rick Wong) (04/05/89)

Could someone enlightened to the mysteries of Color QuickDraw tell me
what's the problem with using its color fill routines (FillCRect,
FillCOval, etc.)?  The following program crashes on a Mac II:


/* MacHeaders included */

#include <Color.h>

main()
{
CGrafPort	port;
Rect		r;
PixPatHandle	pp;

	InitGraf(&thePort);

	OpenCPort(&port);
	SetRect(&r, 0, 0, 100, 100);

	pp = NewPixPat();
	CopyPixPat(port.pnPixPat, pp);

	FillCRect(&r, pp);	/* This call seems to work */
	FillCRect(&r, pp);	/* This call crashes with a system error 25 */

	CloseCPort(&port);
}


If I instead use MakeRGBPat to initialize the pixpat, the FillCRect calls
seem okay.  Using PaintRect (after calling PenPixPat) also seems to work.

ADVthanksthanksthanksthanksthanksthanksthanksthanksthanksthanksANCE

Rick Wong
Stanford University
rick@jessica.stanford.edu

darin@Apple.COM (Darin Adler) (04/13/89)

In article <1302@Portia.Stanford.EDU> rick@jessica.stanford.edu (Rick Wong) writes:
> 
> Could someone enlightened to the mysteries of Color QuickDraw tell me
> what's the problem with using its color fill routines (FillCRect,
> FillCOval, etc.)?  The following program crashes on a Mac II:
> ...
> CGrafPort	port;
> Rect		r;
> PixPatHandle	pp;
> 	InitGraf(&thePort);
> 	OpenCPort(&port);
> 	SetRect(&r, 0, 0, 100, 100);
> 	pp = NewPixPat();
> 	CopyPixPat(port.pnPixPat, pp);
> 	FillCRect(&r, pp);	/* This call seems to work */
> 	FillCRect(&r, pp);	/* This call crashes with a system error 25 */
> 	CloseCPort(&port);
> ...
> If I instead use MakeRGBPat to initialize the pixpat, the FillCRect calls
> seem okay.  Using PaintRect (after calling PenPixPat) also seems to work.

The problem here is with a special kind of PixPat that QuickDraw creates when
a new port is created, or the PenPat or BackPat, or FillXXX (without a C)
calls (from Classic QuickDraw) are used. The pixPat created is marked
"temporary", which means that it is deleted as soon as the reference to it is
deleted. Handles to these are in pnPixPat, bkPixPat, and fillPixPat, and
whenever Color QuickDraw puts a PixPatHandle into one of these three fields,
the old PixPatHandle is disposed, if it was a "temporary" one. In this case,
you are copying the pnPixPat (a "temporary" one containing black) and the
"temporariness" is copied along with it. When you first call FillCRect, the
PixPatHandle gets stuffed into fillPixPat, when you next call FillCRect, it
is disposed, and QuickDraw crashes, trying to draw with a disposed handle.

This will probably be fixed in a future system release. In any case, this can
be avoided entirely by never using the pnPixPat or bkPixPat fields of a
CGrafPort (you should never use the fillPixPat field at all).

There are actually a number of ways to fix this; I guess it's just one of those
problems you can get in a system that does not use garbage collection.
-- 
--
Darin Adler					              AppleLink: Adler4
UUCP: {amdcad,decwrl,hoptoad,nsc,sun}!apple!darin     Internet: darin@Apple.com