Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

zeppenwolf

macrumors regular
Original poster
Nov 17, 2009
129
3
I'm carbonatiing, tweaking, and ultimately cocoafying an old pre-carbon PPC app. It's a computation intensive thing whose main output is a square, tesselating 2D graphics image, much like the "Texture Explorer" in Kai's Power Tools.

It's going fine, mostly; I've been able to copy the pre-Carb GWorld output to a Cocoa window, using code that I got from some PDF in the Carbon documentation, whose name I can't remember now. (see below).

It draws fine into the Cocoa window, ultimately I get the whole image in there and it's perfect. The only problem is that the image won't show up in the window until I first cover it up with another window. Until I cover it up and then reveal it again, it's just white space, or the previous image, depending. Is there some kind of "Flush()" function I need to call?

I admit that I'm trying to straddle the fence here-- I'm trying to add "Cocoaness", while the main Event Loop is still that same old legacy thing... But my strategy is to take this thing in steps; I'm keeping the legacy app code running while I tweak the code to the newer tech...

Code:
void DrawMainWinBox(void) {

	if (!gMainWinP)
		return;

	if (!gCurrentPattern)
		return;
		
	CGrafPtr		mainGrafP		= GetWindowPort( gMainWinP );
	CGContextRef	contextR;
	OSErr			err				= CreateCGContextForPort( mainGrafP , &contextR );
	if (err)
		numDbg( err );
		
	Rect			mainRect;
	GetPortBounds( mainGrafP, &mainRect );
	InvalWindowRect( gMainWinP, &mainRect );
	
	GWorldPtr		gWorldP		= PeekMacGeneratorWorld();
	PixMapHandle	pixMapH		= GetGWorldPixMap( gWorldP );

	long			bytesPerRow	= GetPixRowBytes( pixMapH );
	Ptr				baseP		= GetPixBaseAddr( pixMapH );

	Draw32BitARGBToContext( baseP, mainRect, bytesPerRow, contextR );
}

Oops-- looks like tabs=8 here; sorry!

Here is what I copied, mostly, from some Apple PDF:

Code:
void	Draw32BitARGBToContext( void* iBitsP, Rect placeRect, size_t iBytesPerRow, CGContextRef contextR ) {

	CGRect				placeCGRect;
	CGDataProviderRef	provider;
	CGColorSpaceRef		colorSpace;
	size_t				size;
	CGImageRef			image;
	float				width, height;
	
	width		= placeRect.right	- placeRect.left;
	height		= placeRect.bottom	- placeRect.top;
	size		= iBytesPerRow * height;

	// Create a data provider with a pointer to the memory bits
	provider	= CGDataProviderCreateWithData( NULL, iBitsP, size, NULL );

	// Colorspace can be device, calibrated, or ICC profile based
	colorSpace	= CGColorSpaceCreateDeviceRGB();

	image	= CGImageCreate (
	   width,								//size_t width,
	   height,								//size_t height,
	   8,									//size_t bitsPerComponent,
	   32,									//size_t bitsPerPixel,
	   iBytesPerRow,						//size_t bytesPerRow,
	   colorSpace,							//CGColorSpaceRef colorspace,
	   kCGImageAlphaNoneSkipFirst,			//CGBitmapInfo bitmapInfo,
	   provider,							//CGDataProviderRef provider,
	   NULL,								//const CGFloat decode[],
	   false,								//bool shouldInterpolate,
	   kCGRenderingIntentDefault			//CGColorRenderingIntent intent
	);

	//	Once the image is created we can release our reference to the provider and the colorspace.
	// They will be retained by the image.
	CGDataProviderRelease( provider );
	CGColorSpaceRelease( colorSpace );

	// Determine the location where the image will be drawn in userspace.
	placeCGRect	= CGRectMake( placeRect.left, placeRect.top, width, height );
 
	//	Draw the image to the Core Graphics context
	CGContextDrawImage( contextR, placeCGRect, image );

	CGImageRelease( image );

}
 
IMO, if you're converting this to Cocoa, you should just start with a fresh new Cocoa project instead of trying to slowly morph your existing one. I'm guessing your Cocoa UI will be several times smaller than your Carbon one as you'll end up doing a lot of things in the nib.

Regarding your code, where does DrawMainWinBox() get called? You could try CGContextFlush() but I don't think that's what you want. If you were to switch to an NSView it does the flushing for you appropriately, and if you're already switching to Cocoa windows, you should use NSView instead of drawing into the window's graphics context directly.

Edit: seems like Xcode 3.2 has removed a lot of Carbon documentation which makes it a pita to look up functions.
 
IMO, if you're converting this to Cocoa, you should just start with a fresh new Cocoa project instead of trying to slowly morph your existing one. I'm guessing your Cocoa UI will be several times smaller than your Carbon one as you'll end up doing a lot of things in the nib.

From my own POV, it has been a long, hard slog, but also much easier, (and more educational), tackling a thousand cuts one at a time, rather than all at once.

You could try CGContextFlush() but I don't think that's what you want.

That's it!! How hilarious that I even used the word "Flush" to ask for help, never once imagining that I could have searched for that word and solved the problem. I associated that word with old file system stuff on UNIX... That really is funny.

If you were to switch to an NSView it does the flushing for you appropriately, and if you're already switching to Cocoa windows, you should use NSView instead of drawing into the window's graphics context directly.

Well that whole biznis is part of the master plan, don't worry! But for now, thanks a million.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.