This is DrawView.m in view mode; [Download] [Up]
/* Generated by Interface Builder */ #import "DrawView.h" #define PRINTER_PIXEL_FACTOR 67.0 // dpi of screen when printed #define LINE_WIDTH_FACTOR 1.08 // fudge factor to avoid aliasing @implementation DrawView + newFrame: (NXRect *)rect { self = [super newFrame:rect]; [self initialValues]; return self; } - (PROC) initialValues { xmax = 2.0; xmin = -2.0; ymax = 2.0; ymin = -2.0; xc = 0.0; yc = 1.0; iterates = 12; large = 10.0; running = NO; pixelSize = 6; colors = 7; } - (BOOL) continue // Ignores all mousedown events until Stop is pressed { NXEvent *peekedEvent; peekedEvent = [NXApp peekAndGetNextEvent:NX_MOUSEDOWNMASK]; if (peekedEvent IS NULL) return YES; else if (NXPointInRect(&(peekedEvent->location), &stopRect)) { [stopButton highlight:YES]; running = NO; [stopButton highlight:NO]; return NO; } else return YES; } - drawSelf: (NXRect *)rect : (int) count { NXRect frameRect; int p, q, // pixel coords pmax, qmax, // pixels in screen pstart; // start of line to draw float x, y, // actual coords dx, dy, // distance between pixels oldCol, newCol, // colours of adjacent pixels printerDot, // distance between printer dots lineWidth, // width 1 on printer is PRINTER_PIXEL_FACTOR qHeight; // vertical position of line to be drawn NXEraseRect(&bounds); if ((NXDrawingStatus IS NX_DRAWING) AND running) { [self getParams]; [self getFrame:&frameRect]; pmax = (int) frameRect.size.width; qmax = (int) frameRect.size.height; dx = (xmax - xmin)/pmax; dy = (ymax - ymin)/qmax; PSsetlinewidth(1.0); for (q = 0, y = ymin; (q <= qmax) AND [self continue]; q++, y += dy) { for (p = 0, pstart = 0, x = xmin, oldCol = NX_WHITE; p <= pmax; p++, x += dx) { newCol = [self pixelCol:x :y]; if (newCol IS_NOT oldCol) { if (oldCol IS_NOT NX_WHITE) [self drawline:oldCol :pstart :(p-1) :q]; pstart = p; oldCol = newCol; } } if (oldCol IS_NOT NX_WHITE) [self drawline:oldCol :pstart :p :q]; [window flushWindow]; } } else if (NXDrawingStatus IS NX_PRINTING) { [self getParams]; [self getFrame:&frameRect]; printerDot = PRINTER_PIXEL_FACTOR/ atoi(NXGetDefaultValue("System", "PrinterResolution")); lineWidth = printerDot*pixelSize; pmax = (int) ((frameRect.size.width)/lineWidth); qmax = (int) ((frameRect.size.height)/lineWidth); dx = (xmax - xmin)/pmax; dy = (ymax - ymin)/qmax; if (pixelSize > 1) PSsetlinewidth(lineWidth*LINE_WIDTH_FACTOR); else PSsetlinewidth(0); for (q = 0, y = ymin; (q <= qmax); q++, y += dy) { qHeight = (q + 0.5)*lineWidth; for (p = 0, pstart = 0, x = xmin, oldCol = NX_WHITE; p <= pmax; p++, x += dx) { newCol = [self pixelCol:x :y]; if (newCol IS_NOT oldCol) { if (oldCol IS_NOT NX_WHITE) [self drawline :oldCol :(pstart*lineWidth) :(p*lineWidth - printerDot) :qHeight]; pstart = p; oldCol = newCol; } } if (oldCol IS_NOT NX_WHITE) [self drawline:oldCol :(pstart*lineWidth) :(p*lineWidth) :qHeight]; [window flushWindow]; } } return self; } - (PROC) drawline:(float) col :(float) p1 :(float) p2 :(float) q { PSnewpath(); PSmoveto(p1, q); PSlineto(p2, q); PSsetgray(col); PSstroke(); } - (float) pixelCol:(float) x :(float) y { int power; float xx, yy; xx = x*x; yy = y*y; power = 0; while (((xx + yy) < large) AND (power < iterates)) { ++power; y = 2*x*y + yc; x = xx - yy + xc; // f(z) = z*z + c xx = x*x; yy = y*y; } if (power >= iterates) return NX_BLACK; else return (1.0 + (power MOD (colors - 1)))/(colors - 1); } - setParamsForm:anObject { paramsForm = anObject; [paramsForm setFloatValue:xc at:0]; [paramsForm setFloatValue:yc at:1]; [paramsForm setFloatValue:xmin at:2]; [paramsForm setFloatValue:ymin at:3]; [paramsForm setFloatValue:xmax at:4]; [paramsForm setFloatValue:ymax at:5]; [paramsForm setIntValue:iterates at:6]; [paramsForm setFloatValue:large at:7]; [paramsForm setIntValue:colors at:8]; return self; } - setPopUpButton:anObject { id aPopUp; popUpButton = anObject; aPopUp = [PopUpList new]; [aPopUp addItem:"1 dot"]; [aPopUp addItem:"2x2 dots"]; [aPopUp addItem:"3x3 dots"]; [aPopUp addItem:"4x4 dots"]; [aPopUp addItem:"5x5 dots"]; [aPopUp addItem:"6x6 dots"]; [[aPopUp itemList] selectCellAt:pixelSize - 1:0]; NXAttachPopUpList(popUpButton, aPopUp); [aPopUp setTarget:self]; [aPopUp setAction:@selector(pixelSize:)]; return self; } - setStopButton:anObject { stopButton = anObject; [stopButton getFrame:&stopRect]; return self; } - getParams { xc = [paramsForm floatValueAt:0]; yc = [paramsForm floatValueAt:1]; xmin = [paramsForm floatValueAt:2]; ymin = [paramsForm floatValueAt:3]; xmax = [paramsForm floatValueAt:4]; ymax = [paramsForm floatValueAt:5]; iterates = [paramsForm intValueAt:6]; large = [paramsForm floatValueAt:7]; colors = [paramsForm intValueAt:8]; if (colors < 2) colors = 2; return self; } - start:sender { running = YES; [self display]; return self; } - pixelSize:sender { pixelSize = 1 + [sender selectedRow]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.