ftp.nice.ch/peanuts/GeneralData/Documents/adobe/StrAdj.tar.gz#/StrokeView.m

This is StrokeView.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.
 * ************************************************************************
 */


/*
 * StrokeView.m
 * Created by John-Henry Gross and Ken Fromm
 *
 * The purpose of the application is to show the difference when stroke 
 * adjustment is turned on and turned off.  The default state on the 
 * NeXT computer is ON.  Horizontal, vertical, diagonal lines and arcs 
 * are drawn at a set linespacing.  The linewidth can be varied from the 
 * interface.
 *
 * This file contains the methods for the StrokeView class, a subclass 
 * of view.  The important item to note is simply the effect that stroke 
 * adjustment has.  Refer to the documentation for specifics on how 
 * stroke adjustment works.
 *
 */

#import "StrokeView.h"
#import "StrokeViewWraps.h"
#import <appkit/Button.h>
#import <appkit/Control.h>
#import <appkit/Matrix.h>
#import <appkit/TextField.h>
#import <dpsclient/wraps.h>
#include <math.h>

@implementation StrokeView

/* 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.  Place the line 
 * [self setClipping:NO]; after allocating the gstate to see the effect
 *  clipping has.
 *
 * 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]; 
	
	PSWDefs ();

	return self;
}

/* Free the gstate upon quitting. */
- free
{
   	[self  freeGState];
    
   	return [super free];
}

- setTimeDisplay:anObject
{
	timeDisplay = anObject;
	return self;
}

- setFieldWidth:anObject
{
	fieldWidth = anObject;
	return self;
}

- setMatrixLineTypes:anObject
{
	matrixLineTypes = anObject;
	return self;
}

- setStrokeAdjustment:(BOOL)strokeAdjValue
{
	strokeAdjustment = strokeAdjValue;
	return self;
}

/***********************************************************************
 * These static procedures are called within drawSelf:  They simply draw 
 * lines in the rectangle passed in.   They have been separated out of 
 * drawSelf:: mainly for cosmetic reasons. 
 **********************************************************************/

/*  Adds horizontal lines to the path within rect. */
static void makeHorizLines(NXRect  *rect)
{
	float 	ypos, linespacing;
	
	linespacing = rect->size.height/NUMLINESHORIZ;
	for (ypos = rect->origin.y; 
	     ypos <= rect->origin.y + rect->size.height; 
	     ypos += linespacing)
		PSWMakeLine(
		    rect->origin.x, ypos, 
		    rect->origin.x + rect->size.width, ypos);

	PSstroke();
}

/*  Adds verticle lines to the path within rect. */
static void makeVertLines(NXRect  *rect)
{
	float 	xpos, linespacing;
	
	linespacing = rect->size.width/NUMLINESVERT;
	for (xpos = rect->origin.x; 
	     xpos <= rect->origin .x + rect->size.width; 
	     xpos += linespacing)
		PSWMakeLine(
		    xpos, rect->origin.y, 
		    xpos, rect->origin.y + rect->size.height);

	PSstroke();
}

/* Adds diagonal lines to the path within rect.  The rectangle has to be 
 * clipped because the length of the line exceeds the height and the width.
 * Clipping will show only the portion of the lines that fall within the 
 * rectangle. */
static void makeDiagLines(NXRect  *rect)
{
	float		angle, length;
	
	length = (float) sqrt(rect->size.width * 
	                      rect->size.width + 
	                      rect->size.height * 
	                      rect->size.height);

	PSgsave();
		PStranslate(rect->origin.x, rect->origin.y);
	
		for (angle = 0; angle <= 90; angle += DIAGDEGS) 
		{
			PSWMakeLine(0, 0, length, 0);
			PSrotate(DIAGDEGS);
		}
		PSstroke();
	PSgrestore();
}


/*  Adds arcs within rect.  Clipping is necessary because height is greater 
 * than the width and so some arcs will travel outside the rectangle */
static void makeArcs(NXRect  *rect)
{
	float 	radius, maxradius, spacing;
	
	maxradius = (float) sqrt(rect->size.width * rect->size.width +
						 rect->size.height * rect->size.height);
	spacing = maxradius/NUMARCS;
	for (radius = spacing; radius <= maxradius; radius += spacing)
			PSWMakeArc(rect->origin.x, rect->origin.y, radius, 0, 90);

	PSstroke();

}

/* Actions performed:  erase the display times in the interface, obtain 
 * the state of each line type button, clear the view by drawing a new 
 * background, set the values of the drawing variables, draw stroke 
 * adjusted lines and then non-stroke adjusted lines (displaying the
 * times as well), reset the stroke adjustment and then draw the borders
 * around the view. */
- drawSelf:(NXRect *)r :(int) count
{
	int	ElapsedTime;

	[timeDisplay setStringValue:""];

	PSsetgray(BACKGROUND);
	PSrectfill(
	    bounds.origin.x, bounds.origin.y, 
	    bounds.size.width, bounds.size.height);

	PSsetstrokeadjust(YES);
	PSsetlinewidth(BORDERWIDTH);
	PSsetgray(BORDERCOLOR);
	PSrectstroke(
	    bounds.origin.x, bounds.origin.y, 
	    bounds.size.width, bounds.size.height);
	
	PSsetgray(LINECOLOR);
	PSsetlinewidth([fieldWidth floatValue]);
	PSsetstrokeadjust(strokeAdjustment);
	
	PSWMarkTime(); NXPing();	
		if ([[matrixLineTypes cellAt:0 :0] state])
			makeHorizLines(&bounds);		
		 if ([[matrixLineTypes cellAt:0 :1] state])
			makeVertLines(&bounds);		
		 if ([[matrixLineTypes cellAt:1 :0] state])
			makeDiagLines(&bounds);
		if ([[matrixLineTypes cellAt:1 :1] state])
			makeArcs(&bounds);
	PSWReturnTime (&ElapsedTime);

	[timeDisplay setIntValue:ElapsedTime];
				
	return self;
}


@end

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.