Example code programming Objective-C with Cocoa in Xcode and Interface Builder (Leopard)

31: Simple drawing using quartz

Problem: To draw a number of shapes onto a screen window using Quartz.

Solution: Use Interface Builder to define a NSWindow and a custom NSView. In the NSView drawRect method obtain a CGContextRef from the NSGraphicsContext currentContext, and then use the basic Quartz drawing functions to produce the picture.

Start by defining the CGContextSetStrokeColorSpace and CGContextSetFillColorSpace(s). Use CGContextSetFillColor from a CGFloat array of colour values and then draw a rectangle of the same size as the custom view rect.

Use paths to define a number of curves then use CGContextDrawPath to display them on-screen.

Here is the 2.3MB source of this OS X 10.5 Leopard program.

The Quartz drawing

The finished Quartz drawing


Create a new project in XCode: File->New Project->Cocoa Application
Call it: 031_CGContext

Now create the class: MyNSView of type NSView.
Code it as shown below and save.

// MyNSView.h // Created by julius on 10/11/2008. #import <Cocoa/Cocoa.h> @interface MyNSView : NSView { CGColorSpaceRef cgColourSpaceRef; } - (CGColorSpaceRef) obtainTheRGBColorSpace; @end // MyNSView.m #import "MyNSView.h" @implementation MyNSView - (id)initWithFrame:(NSRect)frame { if ( !(self = [super initWithFrame:frame]) ) { return self; } // end if return self; } - (void)awakeFromNib { cgColourSpaceRef = [self obtainTheRGBColorSpace]; } // end awakeFromNib - (CGColorSpaceRef) obtainTheRGBColorSpace { // pp 159 Programming with Quartz, Celphman and Laden CMProfileRef zGenericRGBProfile = NULL; OSStatus zOSStatusError = noErr; CMProfileLocation zLoc; // build up a profile location for ColorSync zLoc.locType = cmPathBasedProfile; //strcpy(zLoc.u.pathLoc.path, kGenericRGBProfilePathStr); // did not spend time making it work strcpy(zLoc.u.pathLoc.path, "/System/Library/ColorSync/Profiles/Generic RGB Profile.icc"); // Open the profile with ColourSync zOSStatusError = CMOpenProfile(&zGenericRGBProfile, &zLoc); if( !(zOSStatusError == noErr) ) { NSLog(@"MyPictureView *** ERROR *** getTheDisplayColorSpace CMOpenProfile"); exit(1); } // CGColorSpaceRef zCgColorSpaceRefDisplay = CGColorSpaceCreateWithPlatformColorSpace(zGenericRGBProfile); if(zCgColorSpaceRefDisplay == NULL) { NSLog(@"MyPictureView *** ERROR *** getTheDisplayColorSpace zCgColorSpaceRefDisplay"); exit(1); } // end if return zCgColorSpaceRefDisplay; } // end obtainTheRGBColorSpace - (void)drawRect:(NSRect)rect { NSGraphicsContext * nsGraphicsContext = [NSGraphicsContext currentContext]; CGContextRef zCgContextRef = (CGContextRef) [nsGraphicsContext graphicsPort]; CGContextSetFillColorSpace(zCgContextRef,cgColourSpaceRef); CGContextSetStrokeColorSpace(zCgContextRef,cgColourSpaceRef); CGFloat zFillColour1[4] = {0.98,0.9,0.88,1.0}; CGContextSetFillColor (zCgContextRef,zFillColour1); CGContextFillRect (zCgContextRef, CGRectMake (0.0, 0.0, rect.size.width, rect.size.height )); CGContextBeginPath(zCgContextRef); CGFloat zStrokeColour1[4] = {0.0,0.0,1.0,1.0}; CGContextSetStrokeColor(zCgContextRef,zStrokeColour1); CGContextSetLineWidth(zCgContextRef,2.0); CGContextAddArc (zCgContextRef, 50.0, 150.0, 10.0, 0.0, 2.0 * 3.142,YES); CGContextDrawPath(zCgContextRef,kCGPathStroke); // another way of specifying the colour CGContextSetRGBStrokeColor(zCgContextRef,0.0,0.0,0.6,1.0); CGContextBeginPath(zCgContextRef); CGContextMoveToPoint(zCgContextRef,180.0,180.0); CGContextAddCurveToPoint(zCgContextRef, 60.0, 180, 50.0, 170.0, 100.0, 100.0); CGContextAddCurveToPoint(zCgContextRef, 130.0, 80.0, 120.0, 60.0, 80.0, 80.0); CGContextDrawPath(zCgContextRef,kCGPathStroke); CGContextBeginPath(zCgContextRef); CGContextMoveToPoint(zCgContextRef,170.0,150.0); CGContextAddQuadCurveToPoint(zCgContextRef, 145.0, 110.0, 120.0, 150.0); CGFloat zStrokeColour2[] = {0.0,0.0,0.4,1.0}; CGContextSetStrokeColor(zCgContextRef,zStrokeColour2); CGContextDrawPath(zCgContextRef,kCGPathStroke); CGContextBeginPath(zCgContextRef); CGContextMoveToPoint(zCgContextRef,40.0,100.0); CGContextAddQuadCurveToPoint(zCgContextRef, 30.0, 10.0, 170.0, 60.0); CGFloat zStrokeColour3[] = {1.0,0.0,0.0,1.0}; CGContextSetStrokeColor(zCgContextRef,zStrokeColour3); CGContextSetLineWidth(zCgContextRef,3.0); CGContextDrawPath(zCgContextRef,kCGPathStroke); } @end

Custom View for drawing with Quartz

Define the Custom View to display the Quartz drawing

Double click MainMenu.xib to bring it up.

Customise the view as shown above.

Select the custom view and in the Identity pane of the Inspector set its class to MyNSView.

Save and Run.

The Quartz drawing

The finished Quartz drawing

If you want to download the code

Click the Download Link to obtain 031_CGContext.zip file of this whole OS X 10.5 Leopard program.

Download 031_CGContext.zip (2.3 MB)

Please send me your comments

If you include your e-mail I may reply!  

Page last modified: 18:58 Sunday 12th. May 2013

Julius Guzy

Paintings & Drawings

  • Link to drawing made from painting by Rubens of the Feast of Venus