This is Graphic.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.
*/
/*
* Graphic.m
*
* Version: 2.0
* Author: Ken Fromm
* History:
* 03-07-91 Added this comment.
*/
#import "Graphic.h"
#import "DrawingViewWraps.h"
#import <appkit/defaults.h>
#import <appkit/nextstd.h>
#import <dpsclient/wraps.h>
void initGparms(GParms *gParms)
{
gParms->path_type = STROKE;
gParms->color_type = GRAY;
gParms->gray = NX_BLACK;
gParms->red = gParms->green = gParms->blue = NX_BLACK;
gParms->linewidth = 1;
gParms->miterlimit = 10;
gParms->linejoin = gParms->linecap = 0;
}
@implementation Graphic : Object
+ new
{
self = [super new];
initGparms(&parms);
return self;
}
- free
{
if (path.pts)
NX_FREE(path.pts);
if (path.ops)
NX_FREE(path.ops);
return self;
}
- installGparms:(const GParms *) gParm
{
parms = *gParm;
return self;
}
- installUpath:(const UPath *) aUpath andBounds:(const NXRect *) aRect
{
NX_MALLOC(path.pts, float, aUpath->num_pts+4);
NX_MALLOC(path.ops, char, aUpath->num_ops+1);
bcopy(aUpath->pts, &path.pts[4], aUpath->num_pts * sizeof(float)/sizeof(char));
path.num_pts = aUpath->num_pts + 4;
path.ops[0] = dps_ucache;
bcopy(aUpath->ops, &path.ops[1], aUpath->num_ops);
path.num_ops = aUpath->num_ops + 1;
bounds = *aRect;
path.pts[0] = bounds.origin.x;
path.pts[1] = bounds.origin.y;
path.pts[2] = bounds.origin.x + bounds.size.width;
path.pts[3] = bounds.origin.y + bounds.size.height;
return self;
}
- getBounds:(NXRect *)theRect
{
*theRect = bounds;
return self;
}
/* Public routines. */
- setPathType:(int) value
{
parms.path_type = (unsigned char) value;
return self;
}
- (int)pathType
{
return (int)parms.path_type;
}
- setLineWidth:(float) value
{
parms.linewidth = value;
return self;
}
- (float)lineWidth
{
return parms.linewidth;
}
- setLineJoin:(int) value
{
parms.linejoin = (unsigned char) value;
return self;
}
- (int)lineJoin
{
return (int) parms.linejoin;
}
- setLineCap:(int) value
{
parms.linecap = (unsigned char) value;
return self;
}
- (int)lineCap
{
return (int) parms.linecap;
}
- setMiterLimit:(float) value
{
parms.miterlimit = value;
return self;
}
- (float) miterLimit
{
return parms.miterlimit;
}
- (int) colorType
{
return (int) parms.color_type;
}
- setGray:(float) value
{
parms.gray = value;
parms.color_type = GRAY;
return self;
}
- (float)gray
{
return parms.gray;
}
- setRGBColor:(int)r : (int)g :(int)b
{
parms.red = r;
parms.green = g;
parms.blue = b;
parms.color_type = RGB;
return self;
}
- getRGBColor:(int *)r : (int *)g :(int *)b
{
*r = parms.red;
*g = parms.green;
*b = parms.blue;
return self;
}
- setHGBColor:(int)h :(int)s :(int)b
{
parms.red = h;
parms.green = s;
parms.blue = b;
parms.color_type = HSB;
return self;
}
- getHGBColor:(int *)h :(int *)s :(int *)b
{
*h = parms.red;
*s = parms.green;
*b = parms.blue;
return self;
}
- setCMYKColor:(int)c : (int)m :(int)y :(int)k
{
parms.red = c;
parms.green = m;
parms.blue = y;
parms.gray = k;
parms.color_type = CMYK;
return self;
}
- getCMYKColor:(int *)c : (int *)m :(int *)y :(int *)k
{
*c = parms.red;
*m = parms.green;
*y = parms.blue;
*k = parms.gray;
return self;
}
/* Make this external so that DrawingView can use it. */
void setGraphicState(GParms *curParms, GParms *objParms, int format)
{
DPSContext ctxt;
ctxt = DPSGetCurrentContext();
if (!curParms || objParms->linewidth != curParms->linewidth)
{
if (format == ABBR)
PSWSetlinewidth(objParms->linewidth);
else if (format == BOT)
{
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &objParms->linewidth, sizeof(float));
DPSPrintf(ctxt, "\222\233");
}
else
PSsetlinewidth(objParms->linewidth);
}
if (!curParms || objParms->linejoin != curParms->linejoin)
{
if (format == ABBR)
PSWSetlinejoin((int) objParms->linejoin);
else if (format == BOT)
{
DPSPrintf(ctxt, "\210");
DPSWriteData(ctxt, &objParms->linejoin, sizeof(char));
DPSPrintf(ctxt, "\222\232");
}
else
PSsetlinejoin((int) objParms->linejoin);
}
if (!curParms || objParms->linecap != curParms->linecap)
{
if (format == ABBR)
PSWSetlinecap((int) objParms->linecap);
else if (format == BOT)
{
DPSPrintf(ctxt, "\210");
DPSWriteData(ctxt, &objParms->linecap, sizeof(char));
DPSPrintf(ctxt, "\222\231");
}
else
PSsetlinecap((int) objParms->linecap);
}
if (!curParms || objParms->miterlimit != curParms->miterlimit)
{
if (format == ABBR)
PSWSetmiterlimit(objParms->miterlimit);
else
PSsetmiterlimit(objParms->miterlimit);
}
switch (objParms->color_type)
{
case GRAY:
if (!curParms || objParms->gray != curParms->gray)
{
if (format == ABBR)
PSWSetgray(objParms->gray);
else if (format == BOT)
{
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &objParms->gray, sizeof(float));
DPSPrintf(ctxt, "\222\226");
}
else
PSsetgray(objParms->gray);
}
break;
case RGB:
if (!curParms || objParms->red != curParms->red ||
objParms->green != curParms->green ||
objParms->blue != curParms->blue)
{
if (format == ABBR)
PSWSetrgbcolor(objParms->red, objParms->green, objParms->blue);
else if (format == BOT)
{
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &objParms->red, sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &objParms->green, sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &objParms->blue, sizeof(float));
DPSPrintf(ctxt, "\222\235");
}
else
PSsetrgbcolor(objParms->red, objParms->green, objParms->blue);
}
break;
case HSB:
if (!curParms || objParms->red != curParms->red ||
objParms->green != curParms->green ||
objParms->blue != curParms->blue)
{
if (format == ABBR)
PSWSethsbcolor(objParms->red, objParms->green, objParms->blue);
else if (format == BOT)
{
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &objParms->red, sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &objParms->green, sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &objParms->blue, sizeof(float));
DPSPrintf(ctxt, "\222\230");
}
else
PSsethsbcolor(objParms->red, objParms->green, objParms->blue);
}
break;
case CMYK:
if (!curParms || objParms->red != curParms->red ||
objParms->green != curParms->green ||
objParms->blue != curParms->blue ||
objParms->gray != curParms->gray)
{
if (format == ABBR)
PSWSetcmykcolor(objParms->red, objParms->green, objParms->blue,
objParms->gray);
else if (format == BOT)
{
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &objParms->red, sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &objParms->green, sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &objParms->blue, sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &objParms->gray, sizeof(float));
DPSPrintf(ctxt, "\222\223");
}
else
PSsetcmykcolor(objParms->red, objParms->green, objParms->blue,
objParms->gray);
}
break;
}
if (curParms)
*curParms = *objParms;
}
/*
* Call the appropriate wrap to construct the path. Not the recommended
* approach to drawing paths (user paths are).
*/
static void makeRedBook(UPath *aUpath, int format)
{
int i_op, i_pt;
DPSContext ctxt;
ctxt = DPSGetCurrentContext();
/* Skip the ucache operator. */
i_pt = 4;
for (i_op = 1; i_op < aUpath->num_ops; i_op++)
{
switch (aUpath->ops[i_op])
{
case dps_moveto:
if (format == ABBR)
PSWMoveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
else if (format == BOT)
{
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt], sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt+1], sizeof(float));
DPSPrintf(ctxt, "\222\153");
}
else
PSmoveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
i_pt += 2;
break;
case dps_rmoveto:
if (format == ABBR)
PSWRmoveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
else if (format == BOT)
{
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt], sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt+1], sizeof(float));
DPSPrintf(ctxt, "\222\206");
}
else
PSrmoveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
i_pt += 2;
break;
case dps_lineto:
if (format == ABBR)
PSWLineto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
else if (format == BOT)
{
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt], sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt+1], sizeof(float));
DPSPrintf(ctxt, "\222\143");
}
else
PSlineto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
i_pt += 2;
break;
case dps_rlineto:
if (format == ABBR)
PSWRlineto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
else if (format == BOT)
{
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt], sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt+1], sizeof(float));
DPSPrintf(ctxt, "\222\205");
}
else
PSrlineto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
i_pt += 2;
break;
case dps_curveto:
if (format == ABBR)
PSWCurveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1],
aUpath->pts[i_pt+2], aUpath->pts[i_pt+3],
aUpath->pts[i_pt+4], aUpath->pts[i_pt+5]);
else if (format == BOT)
{
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt], sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt+1], sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt+ 2], sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt+3], sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt+4], sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt+5], sizeof(float));
DPSPrintf(ctxt, "\222\053");
}
else
PScurveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1],
aUpath->pts[i_pt+2], aUpath->pts[i_pt+3],
aUpath->pts[i_pt+4], aUpath->pts[i_pt+5]);
i_pt += 6;
break;
case dps_rcurveto:
if (format == ABBR)
PSWRcurveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1],
aUpath->pts[i_pt+2], aUpath->pts[i_pt+3],
aUpath->pts[i_pt+4], aUpath->pts[i_pt+5]);
else if (format == BOT)
{
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt], sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt+1], sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt+ 2], sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt+3], sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt+4], sizeof(float));
DPSPrintf(ctxt, "\214");
DPSWriteData(ctxt, &aUpath->pts[i_pt+5], sizeof(float));
DPSPrintf(ctxt, "\222\172");
}
else
PSrcurveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1],
aUpath->pts[i_pt+2], aUpath->pts[i_pt+3],
aUpath->pts[i_pt+4], aUpath->pts[i_pt+5]);
i_pt += 6;
break;
case dps_closepath:
if (format == ABBR)
PSWClosepath();
else if (format == BOT)
DPSPrintf(ctxt, "\222\026");
else
PSclosepath();
break;
}
}
}
/*
* Draws the graphic.
*/
- drawObject:(NXRect *) r currentParms:(GParms *) gParms withFormat:(int) format
{
DPSContext ctxt;
ctxt = DPSGetCurrentContext();
if (!r || NXIntersectsRect(r, &bounds))
{
setGraphicState(gParms, &parms, format);
makeRedBook(&path, format);
if (parms.path_type == FILL)
{
if (format == ABBR)
PSWFill();
else if (format == BOT)
DPSPrintf(ctxt, "\222\102");
else
PSfill();
}
else
{
if (format == ABBR)
PSWStroke();
else if (format == BOT)
DPSPrintf(ctxt, "\222\247");
else
PSstroke();
}
}
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.