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.
- */
-
- /*
- * DialView.m
- * Created by Ken Fromm
- *
- * This application draws hash marks on a dial in several ways. The first way
- * draws using wraps and the rotate operator. The second draws with wraps
- * but calculates the trig for the beginning and ending points of the line segments.
- * The third calculates the trig and sends the line segments to the server with
- * user paths. This is the fastest drawing approach and is recommended
- * for all but the simplest drawing. The last method stores the user path in the
- * server instead of calculating the points anew. This is may be useful in a few
- * cases where the paths are large, imaged frequently and do not change.
- * In most cases, though, the overhead of managing paths in the server
- * overrides any savings.
- *
- * Version: 2.0
- * Author: Ken Fromm
- * History:
- * 03-07-91 Added this comment.
- * 05-10-91 Simplified the application from six methods to
- * four. (The two taken out were variations of
- * user path drawing and tended to cloud the
- * message of the application.)
- */
-
- #import "DialView.h"
- #import "DialViewWraps.h"
- #import <appkit/Button.h>
- #import <appkit/Control.h>
- #import <appkit/Matrix.h>
- #import <appkit/TextField.h>
- #import <appkit/nextstd.h>
- #import <math.h>
- #import <dpsclient/wraps.h>
-
- @implementation DialView
-
- /*
- * These definitions are for the names of the user path arrays in the server. Providing
- * names like this is only to simplify the example. An optimized solution would probably use
- * user objects and forego names altogether.
- */
- static char *upath1 = "upath1";
- static char *upath10 = "upath10";
- static char *upath45 = "upath45";
- static char *upath90 = "upath90";
-
- /*
- * Allocate a gstate and set clipping to NO. The gstate is allocated because we do not
- * want to reset the individual drawing variables when the context is switched back to this
- * view. The clipping is set to NO because the drawing methods do not need clipping so
- * its a way to save display time.
- *
- * The dimensions of the dial are calculated. The bounds of the DialView is the starting
- * point. Arrays to hold user path point and operator values are allocated.
- *
- * The PSWDefs() call sends some definitions used in the wraps to the interpreter. They
- * will be available in the interpreter when the wraps call them.
- */
-
- + newFrame:(NXRect *) frm
- {
- self = [super newFrame:frm];
- [self allocateGState];
- [self setClipping:NO];
-
- viewcenter.x = bounds.size.width/2;
- viewcenter.y = bounds.size.height/2;
- if (viewcenter.x > viewcenter.y)
- maxdim = viewcenter.y - WIDCIRCBRD/2 - CIRCFF ;
- else
- maxdim = viewcenter.x - WIDCIRCBRD/2 -CIRCFF;
- viewcenter.x += bounds.origin.x;
- viewcenter.y += bounds.origin.y;
-
- NX_MALLOC(pts, float, MAX_PTS);
- NX_MALLOC(ops, char, MAX_OPS);
-
- PSWDefs ();
- [self setupUpaths];
-
- drawFlags.field = 0x80;
-
- return self;
- }
-
- /* Free the arrays upon quitting. */
- - free
- {
- if (pts)
- NX_FREE(pts);
- if (ops)
- NX_FREE(ops);
-
- return [super free];
- }
-
- /* Created by interface. Used to obtain the id's of objects that will be messaged. */
- - setMatrixDegreeTypes:anObject
- {
- matrixDegreeTypes = anObject;
- return self;
- }
-
- - setMatrixDisplayTimes:anObject
- {
- matrixDisplayTimes = anObject;
- return self;
- }
-
- /*
- * Calculate the start and end points and place in user path format.
- * Send the user path to the server and define it in the server. Execute
- * the user path for drawing.
- */
- static void setupUpathTrig (pts, ops, x, y, startlen, endlen, deg, upathname, bbox)
- float pts[];
- char ops[];
- float x, y, startlen, endlen, deg;
- char *upathname;
- float bbox[4];
- {
- int i , j, angle;
-
- i = j = 0;
- for (angle = 0; angle < 360; angle += deg)
- {
- pts[i++] = x + (float) cos(angle * RADIANS) * startlen;
- pts[i++] = y + (float) sin(angle * RADIANS) * startlen;
- ops[j++] = dps_moveto;
-
- pts[i++] = x + (float) cos(angle * RADIANS) * endlen;
- pts[i++] = y + (float) sin(angle * RADIANS) * endlen;
- ops[j++] = dps_lineto;
- }
-
- PSWPlaceName(upathname);
- DPSDoUserPath(pts, i, dps_float, ops, j, bbox, dps_def);
- }
-
- - setupUpaths
- {
- float bbox[4];
-
- bbox[0] = bounds.origin.x;
- bbox[1] = bounds.origin.y;
- bbox[2] = bounds.origin.x + bounds.size.width;
- bbox[3] = bounds.origin.y + bounds.size.height;
-
- setupUpathTrig(pts, ops, viewcenter.x, viewcenter.y,
- maxdim * LEN1, maxdim, DEG1, upath1, bbox);
- setupUpathTrig(pts, ops, viewcenter.x, viewcenter.y,
- maxdim * LEN10, maxdim, DEG10, upath10, bbox);
- setupUpathTrig(pts, ops, viewcenter.x, viewcenter.y,
- maxdim * LEN45, maxdim, DEG45, upath45, bbox);
- setupUpathTrig(pts, ops, viewcenter.x, viewcenter.y,
- maxdim * LEN90, maxdim, DEG90, upath90, bbox);
-
- return self;
- }
-
- /*
- * This method changes the title of the menu cell according to the
- * value of the trace variable.
- */
- -trace:sender
- {
- if (trace == NO)
- [[sender selectedCell] setTitle:"Trace On"];
- else
- [[sender selectedCell] setTitle:"Trace Off"];
- trace = !trace;
-
- return self;
- }
-
- - eraseTimes:sender
- {
- int i;
-
- for (i = 0; i < [matrixDisplayTimes cellCount]; i++)
- [[matrixDisplayTimes cellAt:i :0] setStringValue:""];
-
- return self;
- }
-
- -drawViewOne:sender
- {
- drawFlags.field = 0x80 >> [sender selectedRow];
- [self display];
-
- return self;
- }
-
- -drawViewAll:sender
- {
- drawFlags.field = DRAWALL;
- [self display];
-
- return self;
- }
-
- /* Use the same line dimensions except rotate the graphics state before each line. */
- static void drawWrapsRotate (clr, wid, startlen, endlen, deg)
- float clr, wid, startlen, endlen, deg;
- {
- int angle;
-
- PSWSetColorWidth(clr, wid);
- for (angle = 0; angle < 360; angle += deg)
- PSWRotate_MakeLine(deg, startlen, 0, endlen, 0);
- PSstroke();
- }
-
- - drawWrapsRotate:(int) cell
- {
- int ElapsedTime;
-
- [[matrixDisplayTimes cellAt:cell :0] setStringValue:""];
- PSWEraseView (CLRVIEW, bounds.origin.x, bounds.origin.y,
- bounds.size.width, bounds.size.height);
- PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim);
- PSWFillPath(CLRCIRC);
-
- PSWMarkTime (); NXPing ();
- if (trace)
- DPSTraceContext(DPSGetCurrentContext(), YES);
- PSgsave();
- PStranslate(viewcenter.x, viewcenter.y);
- if ([[matrixDegreeTypes cellAt:1 :1] state]) drawWrapsRotate(CLR1, WID1, maxdim * LEN1, maxdim, DEG1);
- if ([[matrixDegreeTypes cellAt:0 :1] state]) drawWrapsRotate(CLR10, WID10, maxdim * LEN10, maxdim, DEG10);
- if ([[matrixDegreeTypes cellAt:1 :0] state]) drawWrapsRotate(CLR45, WID45, maxdim * LEN45, maxdim, DEG45);
- if ([[matrixDegreeTypes cellAt:0 :0] state]) drawWrapsRotate(CLR90, WID90, maxdim * LEN90, maxdim, DEG90);
- PSgrestore();
- if (trace)
- DPSTraceContext(DPSGetCurrentContext(), NO);
- PSWReturnTime (&ElapsedTime);
-
- PSWSetColorWidth(CLRCIRCBRD, WIDCIRCBRD);
- PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim);
- PSstroke();
-
- [[matrixDisplayTimes cellAt:cell :0] setIntValue:ElapsedTime];
-
- return self;
- }
-
- /*
- * Calculate the position of the start and end points and add the line to the
- * current path. Not bad for this particular object but the calculations could
- * become ugly for something more complex.
- */
- static void drawWrapsTrig (clr, wid, x, y, startlen, endlen, deg)
- float clr, wid, x, y, startlen, endlen, deg;
- {
- int angle;
-
- PSWSetColorWidth(clr, wid);
- for (angle = 0; angle < 360; angle += deg)
- PSWMakeLine(x + (float) cos(angle * RADIANS) * startlen,
- y + (float) sin(angle * RADIANS) * startlen,
- x + (float) cos(angle * RADIANS) * endlen,
- y + (float) sin(angle * RADIANS) * endlen);
- PSstroke();
- }
-
- - drawWrapsTrig:(int) cell
- {
- int ElapsedTime;
-
- [[matrixDisplayTimes cellAt:cell :0] setStringValue:""];
- PSWEraseView (CLRVIEW, bounds.origin.x, bounds.origin.y,
- bounds.size.width, bounds.size.height);
- PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim);
- PSWFillPath(CLRCIRC);
-
- PSWMarkTime (); NXPing ();
- if (trace)
- DPSTraceContext(DPSGetCurrentContext(), YES);
- if ([[matrixDegreeTypes cellAt:1 :1] state]) drawWrapsTrig(CLR1, WID1, viewcenter.x, viewcenter.y,
- maxdim * LEN1, maxdim, DEG1);
- if ([[matrixDegreeTypes cellAt:0 :1] state]) drawWrapsTrig(CLR10, WID10, viewcenter.x, viewcenter.y,
- maxdim * LEN10, maxdim, DEG10);
- if ([[matrixDegreeTypes cellAt:1 :0] state]) drawWrapsTrig(CLR45, WID45, viewcenter.x, viewcenter.y,
- maxdim * LEN45, maxdim, DEG45);
- if ([[matrixDegreeTypes cellAt:0 :0] state]) drawWrapsTrig(CLR90, WID90, viewcenter.x, viewcenter.y,
- maxdim * LEN90, maxdim, DEG90);
- if (trace)
- DPSTraceContext(DPSGetCurrentContext(), NO);
- PSWReturnTime (&ElapsedTime);
-
- PSWSetColorWidth(CLRCIRCBRD, WIDCIRCBRD);
- PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim);
- PSstroke();
-
- [[matrixDisplayTimes cellAt:cell :0] setIntValue:ElapsedTime];
-
- return self;
- }
-
- /*
- * Calculate the start and end points and place in user path format.
- * Send the entire user path at once using the DPSDoUserPath() call.
- */
- static void drawUpathsTrig (pts, ops, clr, wid, x, y, startlen, endlen, deg, bbox)
- float pts[];
- char ops[];
- float clr, wid, x, y, startlen, endlen, deg;
- float bbox[4];
- {
- int i , j, angle;
-
- i = j = 0;
- for (angle = 0; angle < 360; angle += deg)
- {
- pts[i++] = x + (float) cos(angle * RADIANS) * startlen;
- pts[i++] = y + (float) sin(angle * RADIANS) * startlen;
- ops[j++] = dps_moveto;
-
- pts[i++] = x + (float) cos(angle * RADIANS) * endlen;
- pts[i++] = y + (float) sin(angle * RADIANS) * endlen;
- ops[j++] = dps_lineto;
- }
-
- PSWSetColorWidth(clr, wid);
- DPSDoUserPath(pts, i, dps_float, ops, j, bbox, dps_ustroke);
- }
-
- - drawUpathsTrig:(int) cell;
- {
- int ElapsedTime;
-
- float bbox[4];
-
- [[matrixDisplayTimes cellAt:cell :0] setStringValue:""];
- PSWEraseView (CLRVIEW, bounds.origin.x, bounds.origin.y,
- bounds.size.width, bounds.size.height);
- PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim);
- PSWFillPath(CLRCIRC);
-
- PSWMarkTime (); NXPing ();
- bbox[0] = bounds.origin.x;
- bbox[1] = bounds.origin.y;
- bbox[2] = bounds.origin.x + bounds.size.width;
- bbox[3] = bounds.origin.y + bounds.size.height;
-
- if (trace)
- DPSTraceContext(DPSGetCurrentContext(), YES);
- if ([[matrixDegreeTypes cellAt:1 :1] state]) drawUpathsTrig(pts, ops, CLR1, WID1, viewcenter.x, viewcenter.y,
- maxdim * LEN1, maxdim, DEG1, bbox);
- if ([[matrixDegreeTypes cellAt:0 :1] state]) drawUpathsTrig(pts, ops, CLR10, WID10, viewcenter.x, viewcenter.y,
- maxdim * LEN10, maxdim, DEG10, bbox);
- if ([[matrixDegreeTypes cellAt:1 :0] state]) drawUpathsTrig(pts, ops, CLR45, WID45, viewcenter.x, viewcenter.y,
- maxdim * LEN45, maxdim, DEG45, bbox);
- if ([[matrixDegreeTypes cellAt:0 :0] state]) drawUpathsTrig(pts, ops, CLR90, WID90, viewcenter.x, viewcenter.y,
- maxdim * LEN90, maxdim, DEG90, bbox);
- if (trace)
- DPSTraceContext(DPSGetCurrentContext(), NO);
- PSWReturnTime (&ElapsedTime);
-
- PSWSetColorWidth(CLRCIRCBRD, WIDCIRCBRD);
- PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim);
- PSstroke();
-
- [[matrixDisplayTimes cellAt:cell :0] setIntValue:ElapsedTime];
-
- return self;
- }
-
- - drawUpathsServer:(int) cell
- {
- int ElapsedTime;
-
- [[matrixDisplayTimes cellAt:cell :0] setStringValue:""];
- PSWEraseView (CLRVIEW, bounds.origin.x, bounds.origin.y,
- bounds.size.width, bounds.size.height);
- PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim);
- PSWFillPath(CLRCIRC);
-
- PSWMarkTime (); NXPing ();
- if (trace)
- DPSTraceContext(DPSGetCurrentContext(), YES);
- if ([[matrixDegreeTypes cellAt:1 :1] state]) {
- PSWSetColorWidth(CLR1, WID1);
- PSWDrawUserPath(upath1);
- }
- if ([[matrixDegreeTypes cellAt:0 :1] state]) {
- PSWSetColorWidth(CLR10, WID10);
- PSWDrawUserPath(upath10);
- }
- if ([[matrixDegreeTypes cellAt:1 :0] state]) {
- PSWSetColorWidth(CLR45, WID45);
- PSWDrawUserPath(upath45);
- }
- if ([[matrixDegreeTypes cellAt:0 :0] state])
- {
- PSWSetColorWidth(CLR90, WID90);
- PSWDrawUserPath(upath90);
- }
- if (trace)
- DPSTraceContext(DPSGetCurrentContext(), NO);
- PSWReturnTime (&ElapsedTime);
-
- PSWSetColorWidth(CLRCIRCBRD, WIDCIRCBRD);
- PSWMakeCircle(viewcenter.x, viewcenter.y, maxdim);
- PSstroke();
-
- [[matrixDisplayTimes cellAt:cell :0] setIntValue:ElapsedTime];
-
- return self;
- }
-
- - drawSelf:(NXRect *)r :(int) count
- {
- PSWEraseView (CLRVIEW, bounds.origin.x, bounds.origin.y,
- bounds.size.width, bounds.size.height);
-
- if (drawFlags.flags.wrapsrotate)
- [self drawWrapsRotate:0];
- if (drawFlags.flags.wrapstrig)
- [self drawWrapsTrig:1];
- if (drawFlags.flags.upathstrig)
- [self drawUpathsTrig:2];
- if (drawFlags.flags.upathsserver)
- [self drawUpathsServer:3];
-
- return self;
- }
-
- @end
-