This is ControlView.m in view mode; [Download] [Up]
/* * (C) 1990 by Adobe Systems Incorporated. All rights reserved. * * This file may be freely copied and redistributed as long as: * 1) This entire notice continues to be included in the file, * 2) If the file has been modified in any way, a notice of such * modification is conspicuously indicated. * * PostScript, Display PostScript, and Adobe are registered trademarks of * Adobe Systems Incorporated. * * ************************************************************************ * THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO CHANGE WITHOUT * NOTICE, AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY ADOBE SYSTEMS * INCORPORATED. ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY OR * LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO WARRANTY OF ANY * KIND (EXPRESS, IMPLIED OR STATUTORY) WITH RESPECT TO THIS INFORMATION, * AND EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY, * FITNESS FOR PARTICULAR PURPOSES AND NONINFINGEMENT OF THIRD PARTY RIGHTS. * ************************************************************************ */ /* * ControlView.m */ #import "ControlPoint.h" #import "ControlView.h" #import "ControlViewWraps.h" #import <appkit/Bitmap.h> #import <appkit/Button.h> #import <appkit/Control.h> #import <appkit/Matrix.h> #import <appkit/TextField.h> #import <dpsclient/wraps.h> @implementation ControlView +newFrame:(NXRect *) frm { float ViewRect[4]; self = [super newFrame:frm]; [self allocateGState]; NX_MALLOC(XYPoints, float, MAX_ARRAY); NX_MALLOC(OpsBuffer, char, MAX_UPATHOPS); NX_MALLOC(XYBuffer, float, (MAX_UPATHPTS)); ViewRect[0] = ViewRect[1] = 0.0; ViewRect[2] = bounds.size.width; ViewRect[3] = bounds.size.height; PSWDefsView (BGCOLOR, BGCOLORSTR, BGWIDTHSTR, ViewRect); srand(1); indexOfPoints = 0; bitMap = [[Bitmap newSize:FIGURESIZE :FIGURESIZE type:NX_UNIQUEBITMAP] setFlip:NO]; [self makePoints:self]; return self; } /* * Free the buffers */ - free { if (OpsBuffer) NX_FREE(OpsBuffer); if (XYPoints) NX_FREE(XYPoints); if (XYBuffer) NX_FREE(XYBuffer); return [super free]; } /* The following methods are used to obtain the ids of the appropriate * text fields. They were created by interface builder. */ -setDrawMethodsMatrix:anObject { drawMethodsMatrix = anObject; return self; } -setDisplayTimesMatrix:anObject { displayTimesMatrix = anObject; return self; } -setNumberPointsMatrix:anObject { numberPointsMatrix = anObject; numberOfPoints = [numberPointsMatrix selectedTag]; return self; } -setControlPoint:anObject { controlPoint = anObject; return self; } -setButtonTitle:(OP) title { if (title == FILL) { [[drawMethodsMatrix cellAt:2 :0] setTitle:"ufill"]; [[drawMethodsMatrix cellAt:3 :0]setTitle:"rectfill"]; } else { [[drawMethodsMatrix cellAt:2 :0] setTitle:"ustroke"]; [[drawMethodsMatrix cellAt:3 :0]setTitle:"rectstroke"]; } return self; } -setButtonEnable:(BOOL) enable { [[drawMethodsMatrix cellAt:3 :0] setEnabled:enable]; return self; } -psTrace:sender { if (PSTrace == NO) [[sender selectedCell] setTitle:"PS Trace On"]; else [[sender selectedCell] setTitle:"PS Trace Off"]; PSTrace = !PSTrace; return self; } -configureDependence:sender { [controlPoint deviceDependence:[sender state]]; [self eraseTimes:self]; return self; } -configurePoints:sender { numberOfPoints = [numberPointsMatrix selectedTag]; /* Choose new starting index to instill a little change in the display. */ indexOfPoints = (rand () % (MAX_POINTS - numberOfPoints + 1)) * 2; [self eraseTimes:self]; return self; } /* * This method fills up the array of points randomly. If the number of * points to draw is different from the previous time, then a new place * in the array will be selected for the points (except for the case of * the largest number of points, in this instance the 0 index will be used). * This random selection of indices introduces a little bit of change in * the display. */ -makePoints:sender { int i; for (i = 0; i < MAX_ARRAY; i = i +2) { XYPoints[i] = (rand () % (long)((bounds.size.width -8) * 100) + 400) * 0.01; XYPoints[i+1] = (rand () % (long)((bounds.size.height -8) * 100) + 400) * 0.01; } return self; } -eraseTimes:sender { int i; for (i = 0; i < [displayTimesMatrix cellCount]; i++) [[displayTimesMatrix cellAt:i :0] setStringValue:""]; return self; } -drawViewOne:sender { int i, row; row = [sender selectedRow]; drawFlags.field = 0x80 >> row; [self display]; return self; } -drawViewAll:sender { drawFlags.field = DRAWALL; [self display]; return self; } /* * Below are six methods that use different approaches to drawing control * points. */ /* The drawing will center around the point passed in.*/ -drawBasic:(int) cell { int ElapsedTime, i; char *basicProc, *basicOp; basicProc = [controlPoint getBasicProc]; basicOp = [controlPoint getBasicOp]; [[displayTimesMatrix cellAt:cell :0] setStringValue:""]; PSWEraseView(); PSsetlinewidth(0); PSWMarkTime(); NXPing(); if (PSTrace) DPSTraceContext(DPSGetCurrentContext(), YES); for (i = indexOfPoints; i < indexOfPoints + (numberOfPoints*2); i = i+2) PSWBasic(XYPoints[i], XYPoints[i+1], basicProc, basicOp); if (PSTrace) DPSTraceContext(DPSGetCurrentContext(), NO); PSWReturnTime (&ElapsedTime); [[displayTimesMatrix cellAt:cell :0] setIntValue:ElapsedTime]; return self; } /* * Cache a single user path. Translate to each location and then * image the user path. */ -drawUserCache:(int) cell { int ElapsedTime, i, i_pt, i_op, j; char *userOp, *userOpsArray; float *userPtsArray; userPtsArray = [controlPoint getUserPtsArray]; userOpsArray = [controlPoint getUserOpsArray]; userOp = [controlPoint getUserOp]; [[displayTimesMatrix cellAt:cell :0] setStringValue:""]; PSWEraseView(); PSsetlinewidth(0.15); PSWMarkTime (); NXPing(); i_op = i_pt = 0; OpsBuffer[i_op++] = dps_ucache; XYBuffer[i_pt++] = -FIGURESIZE/2; XYBuffer[i_pt++] = -FIGURESIZE/2; XYBuffer[i_pt++] = FIGURESIZE/2; XYBuffer[i_pt++] = FIGURESIZE/2; OpsBuffer[i_op++] = dps_setbbox; XYBuffer[i_pt++] = 0; XYBuffer[i_pt++] = 0; OpsBuffer[i_op++] = dps_moveto; for (j = 1; j <= userPtsArray[0]; j++) XYBuffer[i_pt++] = userPtsArray[j]; for (j = 1; j <= (int) userOpsArray[0]; j++) OpsBuffer[i_op++] = userOpsArray[j]; PSgsave(); if (PSTrace) DPSTraceContext(DPSGetCurrentContext(), YES); PStranslate(XYPoints[indexOfPoints], XYPoints[indexOfPoints+1]); for (i = indexOfPoints; i < indexOfPoints + (numberOfPoints*2); i = i+2) { PSWUserPath(XYBuffer, i_pt, OpsBuffer, i_op, userOp); PStranslate( XYPoints[i+2] - XYPoints[i], XYPoints[i+3] - XYPoints[i+1]); } if (PSTrace) DPSTraceContext(DPSGetCurrentContext(), NO); PSgrestore(); PSWReturnTime (&ElapsedTime); [[displayTimesMatrix cellAt:cell :0] setIntValue:ElapsedTime]; return self; } /* Represents the control points as a large user path comprised of a * set of sub user paths. */ -drawUserPath:(int) cell { int ElapsedTime, i, i_pt, i_op, j; char *userOp, *userOpsArray; float *userPtsArray; userPtsArray = [controlPoint getUserPtsArray]; userOpsArray = [controlPoint getUserOpsArray]; userOp = [controlPoint getUserOp]; [[displayTimesMatrix cellAt:cell :0] setStringValue:""]; PSWEraseView(); PSsetlinewidth(0); PSWMarkTime (); NXPing(); XYBuffer[0] = bounds.origin.x; XYBuffer[1] = bounds.origin.y; XYBuffer[2] = bounds.origin.x + bounds.size.width; XYBuffer[3] = bounds.origin.y + bounds.size.height; OpsBuffer[0] = dps_setbbox; if (PSTrace) DPSTraceContext(DPSGetCurrentContext(), YES); i = 0; i_pt = 4; i_op = 1; while (i < numberOfPoints * 2) { if ((i_pt + userPtsArray[0] > MAX_UPATHPTS) || (i_op + (int) userOpsArray[0] > MAX_UPATHOPS)) { PSWUserPath(XYBuffer, i_pt, OpsBuffer, i_op, userOp); i_pt = 4; i_op = 1; } XYBuffer[i_pt++] = XYPoints[indexOfPoints + i++]; XYBuffer[i_pt++] = XYPoints[indexOfPoints + i++]; OpsBuffer[i_op++] = dps_moveto; for (j = 1; j <= userPtsArray[0]; j++, i_pt++) XYBuffer[i_pt] = userPtsArray[j]; for (j = 1; j <= (int) userOpsArray[0]; j++, i_op++) OpsBuffer[i_op] = userOpsArray[j]; } PSWUserPath(XYBuffer, i_pt, OpsBuffer, i_op, userOp); if (PSTrace) DPSTraceContext(DPSGetCurrentContext(), NO); PSWReturnTime (&ElapsedTime); [[displayTimesMatrix cellAt:cell :0] setIntValue:ElapsedTime]; return self; } /* * We have to calculate the offset from the center because where we * say draw, rectfill draws. */ -drawRectOp:(int) cell { int ElapsedTime, i, j; char *rectOp; rectOp = [controlPoint getRectOp]; [[displayTimesMatrix cellAt:cell :0] setStringValue:""]; PSWEraseView(); PSsetlinewidth(0); PSWMarkTime (); NXPing(); if (PSTrace) DPSTraceContext(DPSGetCurrentContext(), YES); for (i = indexOfPoints, j = 0; i < indexOfPoints + (numberOfPoints*2); i = i+2, j = j+4) { if (j+3 > MAX_RECTPTS) { PSWRectDraw (XYBuffer, j, rectOp); j = 0; } XYBuffer[j] = XYPoints[i] - RECTOFFSET; XYBuffer[j+1] = XYPoints[i+1] - RECTOFFSET; XYBuffer[j+2] = RECTSIZE; XYBuffer[j+3] = RECTSIZE; } PSWRectDraw (XYBuffer, j, rectOp); if (PSTrace) DPSTraceContext(DPSGetCurrentContext(), NO); PSWReturnTime (&ElapsedTime); [[displayTimesMatrix cellAt:cell :0] setIntValue:ElapsedTime]; return self; } /* * Draws the control point into the bitmap and then composites it at each * control point location. */ -drawComposite:(int) cell { int ElapsedTime, i; NXPoint point; [controlPoint drawBitMap:bitMap]; [[displayTimesMatrix cellAt:cell :0] setStringValue:""]; PSWEraseView(); PSWMarkTime (); NXPing(); if (PSTrace) DPSTraceContext(DPSGetCurrentContext(), YES); for (i = indexOfPoints; i < indexOfPoints + (numberOfPoints*2); i = i+2) { point.x = XYPoints[i] - FIGURESIZE/2; point.y = XYPoints[i+1] - FIGURESIZE/2; [bitMap composite:NX_SOVER toPoint:&point]; } if (PSTrace) DPSTraceContext(DPSGetCurrentContext(), NO); PSWReturnTime (&ElapsedTime); [[displayTimesMatrix cellAt:cell :0] setIntValue:ElapsedTime]; return self; } /* * Performs a moveto show for each control point. */ -drawShow:(int) cell { int ElapsedTime, i; char fontchar[2]; fontchar[0] = [controlPoint getChar]; fontchar[1] = 0; [controlPoint selectFont:FONTSIZE]; [[displayTimesMatrix cellAt:cell :0] setStringValue:""]; PSgsave(); PSWEraseView(); PSWMarkTime (); NXPing(); if (PSTrace) DPSTraceContext(DPSGetCurrentContext(), YES); for (i = indexOfPoints; i < indexOfPoints + (numberOfPoints*2); i = i+2) PSWShow(XYPoints[i], XYPoints[i+1], fontchar); if (PSTrace) DPSTraceContext(DPSGetCurrentContext(), NO); PSWReturnTime (&ElapsedTime); PSgrestore(); [[displayTimesMatrix cellAt:cell :0] setIntValue:ElapsedTime]; return self; } /* * Places the characters and relative offsets into arrays and executes * a single xyshow. */ -drawXYShow:(int) cell { int ElapsedTime, i, j; char fontchar; fontchar = [controlPoint getChar]; for (i = 0; i < numberOfPoints; i++) OpsBuffer[i] = fontchar; OpsBuffer[i] = 0; [controlPoint selectFont:FONTSIZE]; [[displayTimesMatrix cellAt:cell :0] setStringValue:""]; PSgsave(); PSWEraseView(); PSWMarkTime (); NXPing(); for (i = indexOfPoints+2, j = 0; i < indexOfPoints + (numberOfPoints*2); i++, j++) XYBuffer[j] = XYPoints[i] - XYPoints[i-2]; XYBuffer[j++] = 0; XYBuffer[j++] = 0; if (PSTrace) DPSTraceContext(DPSGetCurrentContext(), YES); PSWXYShow(XYPoints[indexOfPoints], XYPoints[indexOfPoints+1], OpsBuffer, XYBuffer, j); if (PSTrace) DPSTraceContext(DPSGetCurrentContext(), NO); PSWReturnTime (&ElapsedTime); PSgrestore(); [[displayTimesMatrix cellAt:cell :0] setIntValue:ElapsedTime]; return self; } /* * Messaged by the "display" method. This method should not be called * directly. */ -drawSelf:(NXRect *)r :(int) count { PSWEraseView(); PSsetgray(NX_BLACK); if (drawFlags.flags.basic) [self drawBasic:0]; if (drawFlags.flags.usercache) [self drawUserCache:1]; if (drawFlags.flags.userpath) [self drawUserPath:2]; if (drawFlags.flags.rectop && [[drawMethodsMatrix cellAt:3 :0] isEnabled]) [self drawRectOp:3]; if (drawFlags.flags.composite) [self drawComposite:4]; if (drawFlags.flags.show) [self drawShow:5]; if (drawFlags.flags.xyshow) [self drawXYShow:6]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.