This is ControlView.m in view mode; [Download] [Up]
/* * (a) (C) 1990 by Adobe Systems Incorporated. All rights reserved. * * (b) If this Sample Code is distributed as part of the Display PostScript * System Software Development Kit from Adobe Systems Incorporated, * then this copy is designated as Development Software and its use is * subject to the terms of the License Agreement attached to such Kit. * * (c) If this Sample Code is distributed independently, then the following * terms apply: * * (d) This file may be freely copied and redistributed as long as: * 1) Parts (a), (d), (e) and (f) continue to be included in the file, * 2) If the file has been modified in any way, a notice of such * modification is conspicuously indicated. * * (e) PostScript, Display PostScript, and Adobe are registered trademarks of * Adobe Systems Incorporated. * * (f) 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 NONINFRINGEMENT * OF THIRD PARTY RIGHTS. */ /* * ControlView.m * * Version: 2.0 * Author: Ken Fromm * History: * 03-07-91 Added this comment. */ #import "ControlPoint.h" #import "ControlView.h" #import "ControlViewWraps.h" #import <appkit/Button.h> #import <appkit/Control.h> #import <appkit/Matrix.h> #import <appkit/NXImage.h> #import <appkit/TextField.h> #import <dpsclient/wraps.h> @implementation ControlView - initFrame:(const NXRect *) frameRect { float ViewRect[4]; NXSize size; [super initFrame:frameRect]; [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; size.width = size.height = FIGURESIZE; imageId = [[[NXImage alloc] initSize:&size] setFlipped: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:"Trace On"]; else [[sender selectedCell] setTitle:"Trace Off"]; PSTrace = !PSTrace; return self; } -configureDependence:sender { [controlPoint deviceDependence:[sender state]]; [self eraseTimes:self]; return self; } -configurePoints:sender { numberOfPoints = [numberPointsMatrix selectedTag]; /* Choose a 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; } /* Draw using the method selected. */ -drawViewOne:sender { int i, row; row = [sender selectedRow]; drawFlags.field = 0x80 >> row; [self display]; return self; } /* Draw using all the methods. */ -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.15); 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(); /* * Places a user path description for a generic control * point into the OpsBuffer and XYBuffer. */ i_op = i_pt = 0; OpsBuffer[i_op++] = dps_ucache; /* The bounding box is the size of the control point. */ 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]; /* * Performs an initial translate to the first location * and then performs a relative translation thereafter. */ 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(); /* Place the bounding box in the user path description. */ 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) { /* * This check sends the array to the server if the array * limit has been reached. */ 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; } /* * Here we have to calculate the offset from the center because * rectfill starts drawing at the location passed in. */ -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); /* Draw the rectangles if the array limit has been reached. */ for (i = indexOfPoints, j = 0; i < indexOfPoints + (numberOfPoints*2); i = i+2, j = j+4) { /* Flush the buffer if full. */ 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 NXImage and then composites it at each * control point location. */ -drawComposite:(int) cell { int ElapsedTime, i; NXPoint point; [controlPoint drawImage:imageId]; [[displayTimesMatrix cellAt:cell :0] setStringValue:""]; PSWEraseView(); PSWMarkTime (); NXPing(); if (PSTrace) DPSTraceContext(DPSGetCurrentContext(), YES); /* The adjustment centers the rectangle on the point location. */ for (i = indexOfPoints; i < indexOfPoints + (numberOfPoints*2); i = i+2) { point.x = XYPoints[i] - FIGUREHALFSIZE; point.y = XYPoints[i+1] - FIGUREHALFSIZE; [imageId 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]; /* * Place the characters into the character string for xyshow. * Terminate the string with a NULL character. */ for (i = 0; i < numberOfPoints; i++) OpsBuffer[i] = fontchar; OpsBuffer[i] = 0; [controlPoint selectFont:FONTSIZE]; [[displayTimesMatrix cellAt:cell :0] setStringValue:""]; PSgsave(); PSWEraseView(); PSWMarkTime (); NXPing(); /* Calculate the displacement from the previous character. */ for (i = indexOfPoints+2, j = 0; i < indexOfPoints + (numberOfPoints*2); i++, j++) XYBuffer[j] = XYPoints[i] - XYPoints[i-2]; /* * Provide a dummy set of displacements for the move after * the last character has been shown. */ XYBuffer[j++] = 0; XYBuffer[j++] = 0; if (PSTrace) DPSTraceContext(DPSGetCurrentContext(), YES); /* Establish a current point and then execute the xyshow. */ 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.