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.