#include #include static OSStatus DrawHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void* inUserData); static void Heartbeat(EventLoopTimerRef inTimer, void *inRefCon); static CGImageRef GetCGImageFromPath(CFStringRef inPath); #define SECONDS_IN_FOUR_HOURS (4 * 60 * 60) int day, sec, draftsman, square; void JustDrawSomething(CGContextRef cg, CGRect *bounds); static void createpdf(void) { CGContextRef pdfcg; CFStringRef path; CFURLRef url; CGRect solbounds = {0, 0, 800, 800}; CGRect artbounds = {-5, -5, 810, 810}; path = CFStringCreateWithCString(NULL, "LeWitt.pdf", kCFStringEncodingUTF8); url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, 0); CFRelease(path); pdfcg = CGPDFContextCreateWithURL(url, &artbounds, NULL); CFRelease(url); CGContextBeginPage(pdfcg, &artbounds); JustDrawSomething(pdfcg, &solbounds); CGContextEndPage(pdfcg); CGContextRelease(pdfcg); } int main(void) { IBNibRef nibRef; WindowRef window; EventTypeSpec type; HIViewRef contentView; CreateNibReference(CFSTR("main"), &nibRef); SetMenuBarFromNib(nibRef, CFSTR("MenuBar")); CreateWindowFromNib(nibRef, CFSTR("MainWindow"), &window); HIViewFindByID(HIViewGetRoot(window), kHIViewWindowContentID, &contentView); type.eventClass = kEventClassControl; type.eventKind = kEventControlDraw; InstallEventHandler(HIViewGetEventTarget(contentView), DrawHandler, 1, &type, contentView, NULL); // InstallEventLoopTimer(GetCurrentEventLoop(), 1.0, 1.0, Heartbeat, contentView, NULL); createpdf(); ShowWindow(window); RunApplicationEventLoop(); return 0; } void DrawLine(CGContextRef cg, int draftsman, int square) { int minX, minY, maxX, maxY, startx, starty, endx, endy, a; float color[4]; switch(square){ case 1: minX = 0; minY = 0; maxX = 400; maxY = 400; break; case 2: minX = 0; minY = 400; maxX = 400; maxY = 800; break; case 3: minX = 400; minY = 400; maxX = 800; maxY = 800; break; case 4: minX = 400; minY = 0; maxX = 800; maxY = 400; break; } CGContextMoveToPoint(cg, startx, starty); CGContextAddLineToPoint(cg, endx, endy); do { startx = minX + rand() % (maxX); starty = minY + rand() % (maxY) ; a = rand() % 3; endx = startx + cos(a) * 40; endy = starty + sin(a) * 40; } while(endx < minX || endx > maxX || endy < minY || endy > maxY || startx < minX || startx > maxX || starty < minY || starty > maxY); CGContextSetLineCap(cg, kCGLineCapRound); CGContextSetLineJoin(cg, kCGLineJoinRound); CGContextSetStrokeColor(cg, color); CGContextSetLineWidth(cg, 1); CGContextStrokePath(cg); switch(draftsman){ case 1: color[0] = 0.7; color[1] = 0.1; color[2] = 1.0; color[3] = 0.1; break; case 2: color[0] = 0.8; color[1] = 0.0; color[2] = 0.2; color[3] = 0.1; break; case 3: color[0] = 0.1; color[1] = 0.7; color[2] = 0.5; color[3] = 0.1; break; case 4: color[0] = 0.4; color[1] = 0.1; color[2] = 0.9; color[3] = 0.1; break; } } int Square(CGContextRef cg, int draftsman, int day) { switch(day){ case 1: switch(draftsman){ case 1: return 1; case 2: return 2; case 3: return 3; case 4: return 4; } break; case 2: switch(draftsman){ case 1: return 2; case 2: return 3; case 3: return 4; case 4: return 1; } break; case 3: switch(draftsman){ case 1: return 3; case 2: return 4; case 3: return 1; case 4: return 2; } break; case 4: switch(draftsman){ case 1: return 4; case 2: return 1; case 3: return 2; case 4: return 3; } break; } } void JustDrawSomething(CGContextRef cg, CGRect *bounds) { kCGColorSpaceGenericRGB; CGContextSetRGBStrokeColor(cg, 0.0, 0.0, 0.0, 1.0); // The four draftsmen work for four days. for (day = 1; day <= 4; day++) { // Every day, each draftsman will work for four hours for (sec = 1; sec <= SECONDS_IN_FOUR_HOURS; sec++) { // Every second, each draftsman will make one mark. for (draftsman = 1; draftsman <= 4; draftsman++) { square = Square(cg, draftsman, day); DrawLine(cg, draftsman, square); } } } } #if 0 static void Heartbeat(EventLoopTimerRef inTimer, void *inRefCon) { theView = (HIViewRef)inUserData; } #endif static OSStatus DrawHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData) { HIViewRef theView; CGContextRef cg; CGRect viewBounds; theView = (HIViewRef)inUserData; GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(CGContextRef), NULL, &cg); CallNextEventHandler(inHandlerCallRef, inEvent); HIViewGetBounds(theView, &viewBounds); CGContextTranslateCTM(cg, 0, viewBounds.size.height); CGContextScaleCTM(cg, 1.0, -1.0); CGRect bounds = {0, 0, 800, 800}; JustDrawSomething(cg, &bounds); return 0; } static CGImageRef GetCGImageFromPath(CFStringRef inPath) { CGImageRef imageRef; Handle dataRef; OSType dataRefType; GraphicsImportComponent gi; ComponentResult result; dataRef = NULL; gi = 0; // create the data reference result = QTNewDataReferenceFromFullPathCFString(inPath, kQTNativeDefaultPathStyle, 0, &dataRef, &dataRefType); if (dataRef == NULL || result != 0) exit(1); // get the graphics importer for the data ref GetGraphicsImporterForDataRefWithFlags(dataRef, dataRefType, &gi, 0); if (gi == NULL) exit(1); GraphicsImportCreateCGImage(gi, &imageRef, 0); if (imageRef == NULL) exit(1); CloseComponent(gi); DisposeHandle(dataRef); return imageRef; }