home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * (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
-