This is XtGState.m in view mode; [Download] [Up]
/* XtGState - Implements graphic state drawing for Xt/Xlib
Copyright (C) 1995 Free Software Foundation, Inc.
Written by: Paul Kunz <Paul_Kunz@SLAC.Stanford.edu>,
Adam Fedor <fedor@boulder.colorado.edu>
Date: Nov 1995
This file is part of the GNU Objective C User Interface Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "XtGStateOps.h"
#include "XtDrawContext.h"
#include "XtDrawObject.h"
#include "xttools.h"
#include <objects/Stack.h>
#include <Foundation/NSGeometry.h>
#include <Foundation/NSValue.h>
#include "appkit/View.h"
#define CHECK_GC \
if (!xgcntxt) \
[self createGraphicContext]
#define COPY_GC_ON_CHANGE \
[self _copyGCOnChange]
#define CHECK_WINDOW \
if (!window.ident) \
if (window.widget) \
window.ident = XtWindow((Widget)window.widget)
#define PUSH_PATH_OBJECT(type) \
[path pushObject: [[XtDrawObject allocWithZone: [self zone]] \
initWithDrawType: type]]
static void
gst_currentpoint(NSPoint point)
{
if (point.x < 0)
fprintf(stderr, "DPS: No current point\n");
}
@interface XtGState (Private)
- (void) _setGCValues: (XGCValues)values withMask: (int)mask;
- (void) _copyGCOnChange;
- (void) _paintPath;
- (void) setClipMask;
@end
@interface XtDrawContext (Private)
- (Region) viewclipRegion;
- (void) setViewclipRegion: (Region)region;
@end
@implementation XtGState
/* Designated initializer. Note that just calling this methods will not
fullly initialize the gstate. One must also call -setWindowDevce:
or setWindowDevice:andView: so that the gstate knows were and how to
draw to the screen */
- initWithDrawContext: (XtDrawContext *)context
{
[super init];
ctxt = context;
path = [Stack new];
point.x = -1;
return self;
}
- (void) _setViewInfo: (View *)aView
{
NXRect r;
window.widget = [aView _widget];
window.ident = XtWindow((Widget)window.widget);
[aView getFrame: &r];
window.frame = NSMakeRect(NX_X(&r), NX_Y(&r), NX_WIDTH(&r), NX_HEIGHT(&r));
draw = (window.buffer) ? window.buffer : window.ident;
/* Flip sets the height of the window, which is what we need to flip
to X-Window coordinates (origin at top-left) from PS coordinates
(origin at bottom-left). However, if the application is using a
separate widget set (window.widget != 0) and this is a non-retained
window (window.buffer == 0), then we want to use the View widget
height for flip */
if (window.widget && !window.buffer)
flip = NSHeight(window.frame);
}
- initWithDrawContext: (XtDrawContext *)context andView: (View *)aView
{
[self initWithDrawContext: context];
[self _setViewInfo: aView];
return self;
}
- (void) dealloc
{
XWContext context = [ctxt XWContext];
if ( sharedGC == NO && xgcntxt )
{
XFreeGC(context->display, xgcntxt);
}
if (clipregion)
XDestroyRegion(clipregion);
[path release];
[super dealloc];
}
- deepen
{
Region new_region;
/* Share the GC rather than copy it */
sharedGC = YES;
path = [path copy];
/* Copy the clipregion */
if (clipregion)
{
new_region = XCreateRegion();
XIntersectRegion(clipregion, clipregion, new_region);
clipregion = new_region;
}
update = NO;
if (_view)
[self _setViewInfo: (View *)_view];
return self;
}
- copyWithZone: (NSZone *)zone
{
return [[super copyWithZone: zone] deepen];
}
- copyWithView: (View *)aView
{
_view = aView;
return [self copy];
}
- (void) setWindowDevice: (window_device_t)device
{
window = device;
draw = (window.buffer) ? window.buffer : window.ident;
flip = NSHeight(window.frame);
}
- (void) setWindowDevice: (window_device_t)device andView: (View *)aView
{
[self setWindowDevice: device];
[self _setViewInfo: aView];
}
- (window_device_t) windowDevice
{
return window;
}
/* Set various characteristics of the graphic context */
- (void) _setGCValues: (XGCValues)values withMask: (int)mask
{
XWContext context;
COPY_GC_ON_CHANGE;
context = [ctxt XWContext];
XChangeGC(context->display, xgcntxt, mask, &values);
}
/* Set the GC clipmask. The clipmask needs to be a combination of the
current clipregion and the viewclipregion (which is part of the
DrawContext). */
- (void) setClipMask
{
XWContext context;
Region viewclip;
Region region;
context = [ctxt XWContext];
viewclip = [ctxt viewclipRegion];
COPY_GC_ON_CHANGE;
if (!clipregion && !viewclip)
{
XSetClipMask(context->display, xgcntxt, None);
return;
}
if (clipregion && viewclip)
{
region = XCreateRegion();
XIntersectRegion(clipregion, [ctxt viewclipRegion], region);
}
else if (!viewclip)
region = clipregion;
else
region = viewclip;
XSetRegion(context->display, xgcntxt, region);
if (clipregion && viewclip)
XDestroyRegion(region);
}
- (void) setColor: (device_color_t)acolor;
{
XWContext context;
context = [ctxt XWContext];
color = acolor;
gcv.foreground = xtColorToPixel(context, color);
[self _setGCValues: gcv withMask: GCForeground];
}
- (void) setFont: (Font)fid
{
gcv.font = fid;
[self _setGCValues: gcv withMask: GCFont];
}
- copyGraphicContext
{
GC source;
X11Window ident;
unsigned long mask;
XWContext context = [ctxt XWContext];
CHECK_WINDOW;
if (!window.ident && !window.root)
{
fprintf(stderr, "DPS: Copying a GC on an unrealized Window\n");
return nil;
}
ident = (window.ident) ? : window.root;
source = xgcntxt;
mask = 0xffffffff; /* Copy everything (Hopefully) */
xgcntxt = XCreateGC(context->display, ident, 0, NULL);
XCopyGC(context->display, source, mask, xgcntxt);
sharedGC = NO;
return self;
}
// Create a default graphics context.
- createGraphicContext
{
Pixel black, white;
X11Window ident;
XWContext context = [ctxt XWContext];
CHECK_WINDOW;
if (!window.ident && !window.root)
{
fprintf(stderr, "DPS: Creating a GC on an unrealized Window\n");
return nil;
}
ident = (window.ident) ? : window.root;
gcv.function = GXcopy;
// gcv.foreground = xtGrayToPixel(context, 0.0); /* NX_BLACK */
// gcv.background = xtGrayToPixel(context, 0.6666); /* NX_LTGRAY */
black = XBlackPixel(context->display, XDefaultScreen(context->display));
white = XWhitePixel(context->display, XDefaultScreen(context->display));
gcv.background = white;
gcv.foreground = black;
gcv.plane_mask = AllPlanes;
gcv.fill_style = FillSolid;
gcv.fill_rule = WindingRule;
xgcntxt = XCreateGC(context->display, ident,
GCFunction | GCForeground | GCBackground | GCPlaneMask
| GCFillStyle | GCFillRule,
&gcv);
[self setClipMask];
sharedGC = NO;
return self;
}
/* Called before access to a X11 Graphic Context (GC). Create
a private copy of the GC. */
- (void) _copyGCOnChange
{
CHECK_GC;
if (sharedGC == YES)
[self copyGraphicContext];
}
- (NSRect)clipRect
{
XRectangle r;
r.width = 0; r.height = 0;
if (clipregion)
XClipBox(clipregion, &r);
return NSMakeRect(r.x, r.y, r.width, r.height);
}
- setNeedsDisplay: (BOOL)flag
{
update = flag;
return self;
}
- setDidUpdate
{
update = YES;
return self;
}
- (BOOL) needsDisplay
{
return update;
}
- (BOOL) didDraw
{
return didDraw;
}
- (BOOL) hasGraphicContext
{
return (xgcntxt) ? YES : NO;
}
- (BOOL) hasDrawable
{
return (draw ? YES : NO);
}
- (Drawable) drawable
{
return draw;
}
- (GC) graphicContext
{
return xgcntxt;
}
- copyDrawable:(Drawable)source fromRect:(NSRect *)aRect
{
NSPoint p;
p.x = 0; p.y = 0;
[self copyDrawable:source fromRect:aRect toPoint:&p];
return self;
};
- copyDrawable:(Drawable)source fromRect:(NSRect *)aRect
toPoint:(NSPoint *)aPoint
{
XWContext context = [ctxt XWContext];
CHECK_GC;
[self convertPointToDrawable:aPoint];
aPoint->y -= NSHeight(*aRect);
XCopyArea(context->display, source, draw, xgcntxt,
aRect->origin.x, aRect->origin.y,
aRect->size.width, aRect->size.height,
aPoint->x, aPoint->y);
[self setDidUpdate];
return self;
}
- copyImage:(XImage *)image ofSize:(NSSize *)size
{
NSPoint p;
XWContext context = [ctxt XWContext];
CHECK_GC;
p.x = 0; p.y = 0;
[self convertPointToDrawable:&p];
p.y -= size->height;
XPutImage(context->display, draw, xgcntxt,
image, 0, 0,
p.x, p.y,
size->width, size->height);
[self setDidUpdate];
return self;
}
- convertRectToDrawable:(NSRect *)aRect
{
NSPoint max;
max.x = NSMaxX(*aRect);
max.y = NSMaxY(*aRect);
aRect->origin = applyCGT(aRect->origin, cgt);
max = applyCGT(max, cgt);
*aRect = NSMakeRect(NSMinX(*aRect), NSMinY(*aRect),
max.x - NSMinX(*aRect), max.y - NSMinY(*aRect));
/* Flip the coordinate system for X-windows */
NX_Y(aRect) = flip - NSMaxY(*aRect);
return self;
}
- convertPointToDrawable:(NSPoint *)aPoint
{
*aPoint = applyCGT(*aPoint, cgt);
aPoint->y = flip - aPoint->y;
return self;
}
- (void) flushRect: (NSRect *)frame
{
XWContext context;
NSRect bounds;
/* Are all variables initialized? Are we doing backing store? */
if (xgcntxt == 0)
return;
CHECK_WINDOW;
if (!window.ident)
return;
if (draw == window.ident)
return;
context = [ctxt XWContext];
if (!frame)
frame = &window.frame;
bounds = NSMakeRect(0, 0, NSWidth(*frame), NSHeight(*frame));
[self convertRectToDrawable:&bounds];
XCopyArea(context->display, draw, window.ident, xgcntxt,
NSMinX(bounds), NSMinY(bounds),
NSWidth(bounds), NSHeight(bounds),
NSMinX(bounds), NSMinY(bounds));
update = NO;
didDraw = YES;
}
- (void) flushRectIfNeeded: (NSRect *)frame
{
if ( update )
[self flushRect: frame];
}
/* Paint the current path using Xlib calls. All coordinates should already
have been transformed to device coordinates (save for the final flip
needed because the X origin is in the top-left). Filling and clipping
may not work correctly because we don't really flatten curves (although
I have code for this - maybe I should add it) - FIXME */
- (void) _doPath: (XPoint *)pts : (int)count draw: (ctxt_object_t)type
{
int fill_rule;
XWContext context;
context = [ctxt XWContext];
COPY_GC_ON_CHANGE;
fill_rule = WindingRule;
switch (type)
{
case path_stroke:
XDrawLines(context->display, draw, xgcntxt, pts, count, CoordModeOrigin);
break;
case path_eofill:
gcv.fill_rule = EvenOddRule;
[self _setGCValues: gcv withMask: GCFillRule];
/* NO BREAK */
case path_fill:
XFillPolygon(context->display, draw, xgcntxt, pts, count, Complex,
CoordModeOrigin);
if (gcv.fill_rule == EvenOddRule)
{
gcv.fill_rule = WindingRule;
[self _setGCValues: gcv withMask: GCFillRule];
}
break;
case path_eoclip:
fill_rule = EvenOddRule;
/* NO BREAK */
case path_clip:
{
Region region, new_region;
region = XPolygonRegion(pts, count, fill_rule);
if (clipregion)
{
XIntersectRegion(clipregion, region, new_region);
XDestroyRegion(region);
XDestroyRegion(clipregion);
} else
new_region = region;
clipregion = new_region;
[self setClipMask];
}
break;
case path_eoviewclip:
fill_rule = EvenOddRule;
/* NO BREAK */
case path_viewclip:
{
Region region;
region = XPolygonRegion(pts, count, fill_rule);
[ctxt setViewclipRegion: region];
[self setClipMask];
}
break;
default:
break;
}
}
- (void) _paintPath
{
int i, count;
id drawobj;
id obj;
XPoint *pts;
Stack *savepath;
drawobj = [path popObject];
/* clip does not delete the current path, so we have to save it here
and reset it after processing. */
if (([drawobj drawType] == path_clip) || ([drawobj drawType] == path_eoclip))
savepath = [path copy];
count = [path count];
OBJC_MALLOC(pts, XPoint, count/2);
i = 0;
while ([path count])
{
NSPoint p, new;
BOOL doit;
doit = NO;
obj = [path removeFirstObject];
switch ([obj drawType])
{
case path_moveto:
new = [[path removeFirstObject] pointValue];
point = new;
doit = YES;
break;
case path_rmoveto:
gst_currentpoint(point);
p = [[path removeFirstObject] pointValue];
new.x += p.x; new.y += p.y;
doit = YES;
break;
case path_lineto:
gst_currentpoint(point);
new = [[path removeFirstObject] pointValue];
break;
case path_rlineto:
gst_currentpoint(point);
p = [[path removeFirstObject] pointValue];
new.x += p.x; new.y += p.y;
break;
case path_arc:
break;
case path_curveto:
break;
case path_charpath:
break;
case path_closepath:
new = point;
doit = YES;
break;
default:
break;
}
point = new;
pts[i].x = new.x; pts[i].y = flip - new.y;
i++;
if (doit && i > 1)
{
[self _doPath: pts : i draw: [drawobj drawType]];
i = 0;
}
} /* while */
if (i > 1)
{
[self _doPath: pts : i draw: [drawobj drawType]];
}
OBJC_FREE(pts);
if (([drawobj drawType] == path_clip) || ([drawobj drawType] == path_eoclip))
{
[path release];
path = savepath;
}
[self setDidUpdate];
}
@end
@implementation XtGState (ColorOps)
- (void)DPScolorimage
{
}
- (void)DPScurrentblackgeneration
{
}
- (void)DPScurrentcmykcolor: (float *)c : (float *)m : (float *)y : (float *)k
{
device_color_t new = color;
if (new.space != cmyk_colorspace)
new = xtConvertToCMYK(new);
*c = new.field[0];
*m = new.field[1];
*y = new.field[2];
*k = new.field[3];
}
- (void)DPScurrentcolorscreen
{
}
- (void)DPScurrentcolortransfer
{
}
- (void)DPScurrentundercolorremoval
{
}
- (void)DPSsetblackgeneration
{
}
- (void)DPSsetcmykcolor: (float)c : (float)m : (float)y : (float)k
{
color.space = cmyk_colorspace;
color.field[0] = c;
color.field[1] = m;
color.field[2] = y;
color.field[3] = k;
[self setColor:color];
}
- (void)DPSsetcolorscreen
{
}
- (void)DPSsetcolortransfer
{
}
- (void)DPSsetundercolorremoval
{
}
@end
@implementation XtGState (GStateOps)
- (void)DPSconcat: (const float *)m
{
cgt_t acgt;
acgt.a = m[0]; acgt.b = m[1]; acgt.c = m[2]; acgt.d = m[3];
acgt.tx = m[4]; acgt.ty = m[5];
cgt = concatCGT(cgt, acgt);
}
- (void)DPScurrentdash
{
}
- (void)DPScurrentflat: (float *)flatness
{
}
- (void)DPScurrentgray: (float *)gray
{
device_color_t gcolor;
gcolor = xtConvertToGray(color);
*gray = gcolor.field[0];
}
- (void)DPScurrenthalftone
{
}
- (void)DPScurrenthalftonephase: (float *)x : (float *)y
{
}
- (void)DPScurrenthsbcolor: (float *)h : (float *)s : (float *)b
{
device_color_t gcolor;
gcolor = xtConvertToHSB(color);
*h = gcolor.field[0]; *s = gcolor.field[1]; *b = gcolor.field[2];
}
- (void)DPScurrentlinecap: (int *)linecap
{
*linecap = gcv.cap_style - CapButt;
}
- (void)DPScurrentlinejoin: (int *)linejoin
{
*linejoin = gcv.join_style - JoinMiter;
}
- (void)DPScurrentlinewidth: (float *)width
{
*width = gcv.line_width;
}
- (void)DPScurrentmatrix: (float *)m
{
m[0] = cgt.a; m[1] = cgt.b; m[2] = cgt.c; m[3] = cgt.d;
m[4] = cgt.tx; m[5] = cgt.ty;
}
- (void)DPScurrentmiterlimit: (float *)limit
{
}
- (void)DPScurrentpoint: (float *)x : (float *)y
{
NSPoint user;
user = applyCGT(point, invertCGT(cgt));
*x = user.x;
*y = user.y;
}
- (void)DPScurrentrgbcolor: (float *)r : (float *)g : (float *)b
{
device_color_t gcolor;
gcolor = xtConvertToRGB(color);
*r = gcolor.field[0]; *g = gcolor.field[1]; *b = gcolor.field[2];
}
- (void)DPScurrentscreen
{
}
- (void)DPScurrentstrokeadjust: (int *)b
{
}
- (void)DPScurrenttransfer
{
}
- (void)DPSinitgraphics
{
cgt = composeCGT(NULL, 0, NULL);
point.x = -1;
if (clipregion)
XDestroyRegion(clipregion);
clipregion = 0;
/* FIXME: reset the GC */
color.space = gray_colorspace; color.field[0] = 0.0;
[self setColor: color];
}
- (void)DPSinitmatrix
{
cgt = composeCGT(NULL, 0, NULL);
}
- (void)DPSrotate: (float)angle
{
cgt = concatCGT(cgt, composeCGT(NULL, angle, NULL));
}
- (void)DPSscale: (float)x : (float)y
{
NSSize scale;
scale.width = x;
scale.height = y;
cgt = concatCGT(cgt, composeCGT(&scale, 0, NULL));
}
- (void)DPSsetdash: (const float *)pat : (int)size : (float)offset
{
}
- (void)DPSsetflat: (float)flatness
{
}
- (void)DPSsetgray: (float)gray
{
color.space = gray_colorspace;
color.field[0] = gray;
[self setColor: color];
}
- (void)DPSsethalftone
{
}
- (void)DPSsethalftonephase: (float)x : (float)y
{
}
- (void)DPSsethsbcolor: (float)h : (float)s : (float)b
{
color.space = hsb_colorspace;
color.field[0] = h; color.field[1] = s; color.field[2] = b;
[self setColor: color];
}
- (void)DPSsetlinecap: (int)linecap
{
gcv.cap_style = linecap + CapButt;
[self _setGCValues: gcv withMask: GCCapStyle];
}
- (void)DPSsetlinejoin: (int)linejoin
{
gcv.join_style = linejoin + JoinMiter;
[self _setGCValues: gcv withMask: GCJoinStyle];
}
- (void)DPSsetlinewidth: (float)width
{
gcv.line_width = width;
[self _setGCValues: gcv withMask: GCLineWidth];
}
- (void)DPSsetmatrix: (const float *)m;
{
cgt.a = m[0]; cgt.b = m[1]; cgt.c = m[2]; cgt.d = m[3];
cgt.tx = m[4]; cgt.ty = m[5];
}
- (void)DPSsetmiterlimit: (float)limit
{
}
- (void)DPSsetrgbcolor: (float)r : (float)g : (float)b
{
color.space = rgb_colorspace;
color.field[0] = r; color.field[1] = g; color.field[2] = b;
[self setColor: color];
}
- (void)DPSsetscreen
{
}
- (void)DPSsetstrokeadjust: (int)b
{
}
- (void)DPSsettransfer
{
}
- (void)DPStranslate: (float)x : (float)y
{
NSPoint p;
p.x = x;
p.y = y;
cgt = concatCGT(cgt, composeCGT(NULL, 0, &p));
}
@end
@implementation XtGState (PaintOps)
typedef enum {
show_delta, show_array_x, show_array_y, show_array_xy
} show_array_t;
/* Omnibus show string routine that combines that characteristics of
ashow, awidthshow, widthshow, xshow, xyshow, and yshow */
- (void) _showString: (const char *)s
xCharAdj: (float)cx yCharAdj: (float)cy char: (char)c
adjArray: (const float *)arr arrType: (show_array_t)type
isRelative: (BOOL)relative;
{
int i;
int len;
int width;
cgt_t trans;
NSSize scale;
XFontStruct *fontinfo;
XWContext context;
/* Transformation should only be delta transformations (no offset) */
trans = cgt;
trans.tx = 0; trans.ty = 0;
len = strlen(s);
context = [ctxt XWContext];
scale = scaleFromCGT(cgt);
fontinfo = XQueryFont(context->display, gcv.font);
COPY_GC_ON_CHANGE;
for (i=0; i < len; i++)
{
NSPoint delta;
width = XTextWidth(fontinfo, s+i, 1);
XDrawString(context->display, draw, xgcntxt, point.x, flip-point.y,
s, 1);
/* Note we update the current point according to the current
transformation scaling, although the text isn't currently
scaled (FIXME). */
if (type == show_array_xy)
{
delta.x = arr[2*i]; delta.y = arr[2*i+1];
}
else if (type == show_array_x)
{
delta.x = arr[i]; delta.y = 0;
}
else if (type == show_array_y)
{
delta.x = 0; delta.y = arr[i];
}
else
{
delta.x = arr[0]; delta.y = arr[1];
}
delta = applyCGT(delta, trans);
if (relative == YES)
{
delta.x += width * scale.width;
delta.y += fontinfo->max_bounds.ascent * scale.height;
}
if (c && *(s+i) == c)
{
NSPoint cdelta;
cdelta.x = cx; cdelta.y = cy;
cdelta = applyCGT(cdelta, trans);
delta.x += cdelta.x; delta.y += cdelta.y;
}
point.x += delta.x;
if (type != show_delta)
point.y += delta.y;
}
[self setDidUpdate];
}
- (void)DPSashow: (float)x : (float)y : (const char *)s
{
float arr[2];
arr[0] = x; arr[1] = y;
[self _showString: s
xCharAdj: 0 yCharAdj: 0 char: 0 adjArray: arr arrType: show_delta
isRelative: YES];
}
- (void)DPSawidthshow: (float)cx : (float)cy : (int)c : (float)ax : (float)ay : (const char *)s
{
float arr[2];
arr[0] = ax; arr[1] = ay;
[self _showString: s
xCharAdj: cx yCharAdj: cy char: c adjArray: arr arrType: show_delta
isRelative: YES];
}
- (void)DPScopypage
{
}
- (void)DPSeofill
{
PUSH_PATH_OBJECT(path_eofill);
[self _paintPath];
}
- (void)DPSerasepage
{
}
- (void)DPSfill
{
PUSH_PATH_OBJECT(path_fill);
[self _paintPath];
}
- (void)DPSimage
{
}
- (void)DPSimagemask
{
}
- (void)DPSkshow: (const char *)s
{
}
- (void)DPSrectfill: (float)x : (float)y : (float)w : (float)h
{
XWContext context = [ctxt XWContext];
NSRect bounds;
COPY_GC_ON_CHANGE;
bounds = NSMakeRect(x, y, w, h);
[self convertRectToDrawable:&bounds];
XFillRectangle(context->display, draw, xgcntxt,
NSMinX(bounds), NSMinY(bounds),
NSWidth(bounds), NSHeight(bounds));
[self setDidUpdate];
}
- (void)DPSrectstroke: (float)x : (float)y : (float)w : (float)h
{
XWContext context = [ctxt XWContext];
NSRect bounds;
COPY_GC_ON_CHANGE;
bounds = NSMakeRect(x, y, w, h);
[self convertRectToDrawable:&bounds];
XDrawRectangle(context->display, draw, xgcntxt,
NSMinX(bounds), NSMinY(bounds),
NSWidth(bounds), NSHeight(bounds));
[self setDidUpdate];
}
- (void)DPSshow: (const char *)s
{
int len;
int width;
NSSize scale;
XFontStruct *fontinfo;
XWContext context;
len = strlen(s);
context = [ctxt XWContext];
fontinfo = XQueryFont(context->display, gcv.font);
width = XTextWidth(fontinfo, s, len);
COPY_GC_ON_CHANGE;
XDrawString(context->display, draw, xgcntxt, point.x, flip-point.y,
s, len);
/* Note we update the current point according to the current
transformation scaling, although the text isn't currently
scaled (FIXME). */
scale = scaleFromCGT(cgt);
point.x += width * scale.width;
[self setDidUpdate];
}
- (void)DPSshowpage
{
}
- (void)DPSstroke
{
PUSH_PATH_OBJECT(path_stroke);
[self _paintPath];
}
- (void)DPSstrokepath
{
}
- (void)DPSueofill: (const char *)nums : (int)n : (const char *)ops : (int)l
{
}
- (void)DPSufill: (const char *)nums : (int)n : (const char *)ops : (int)l
{
}
- (void)DPSustroke: (const char *)nums : (int)n : (const char *)ops : (int)l
{
}
- (void)DPSustrokepath: (const char *)nums : (int)n : (const char *)ops : (int)l
{
}
- (void)DPSwidthshow: (float)x : (float)y : (int)c : (const char *)s
{
float arr[2];
arr[0] = 0; arr[1] = 0;
[self _showString: s
xCharAdj: x yCharAdj: y char: c adjArray: arr arrType: show_delta
isRelative: YES];
}
- (void)DPSxshow: (const char *)s : (const float *)numarray : (int)size
{
[self _showString: s
xCharAdj: 0 yCharAdj: 0 char: 0 adjArray: numarray arrType: show_array_x
isRelative: NO];
}
- (void)DPSxyshow: (const char *)s : (const float *)numarray : (int)size
{
[self _showString: s
xCharAdj: 0 yCharAdj: 0 char: 0 adjArray: numarray arrType: show_array_xy
isRelative: NO];
}
- (void)DPSyshow: (const char *)s : (const float *)numarray : (int)size
{
[self _showString: s
xCharAdj: 0 yCharAdj: 0 char: 0 adjArray: numarray arrType: show_array_y
isRelative: NO];
}
@end
@implementation XtGState (PathOps)
- (void)DPSarc: (float)x : (float)y : (float)r : (float)angle1 : (float)angle2
{
}
- (void)DPSarcn: (float)x : (float)y : (float)r : (float)angle1 : (float)angle2
{
}
- (void)DPSarct: (float)x1 : (float)y1 : (float)x2 : (float)y2 : (float)r
{
}
- (void)DPSarcto: (float)x1 : (float)y1 : (float)x2 : (float)y2 : (float)r : (float *)xt1 : (float *)yt1 : (float *)xt2 : (float *)yt2
{
}
- (void)DPScharpath: (const char *)s : (int)b
{
}
- (void)DPSclip
{
PUSH_PATH_OBJECT(path_clip);
[self _paintPath];
}
- (void)DPSclippath
{
}
- (void)DPSclosepath
{
PUSH_PATH_OBJECT(path_closepath);
}
- (void)DPScurveto: (float)x1 : (float)y1 : (float)x2 : (float)y2 : (float)x3 : (float)y3
{
}
- (void)DPSeoclip
{
PUSH_PATH_OBJECT(path_eoclip);
[self _paintPath];
}
- (void)DPSeoviewclip
{
PUSH_PATH_OBJECT(path_eoviewclip);
[self _paintPath];
}
- (void)DPSflattenpath
{
}
- (void)DPSinitclip
{
if (clipregion)
XDestroyRegion(clipregion);
clipregion = 0;
[self setClipMask];
}
- (void)DPSinitviewclip
{
[ctxt setViewclipRegion: 0];
}
- (void)DPSlineto: (float)x : (float)y
{
NSPoint p;
p.x = x; p.y = y;
p = applyCGT(p, cgt);
PUSH_PATH_OBJECT(path_lineto);
[path pushObject: [NSValue valueWithPoint: p]];
}
- (void)DPSmoveto: (float)x : (float)y
{
NSPoint p;
p.x = x; p.y = y;
p = applyCGT(p, cgt);
PUSH_PATH_OBJECT(path_moveto);
[path pushObject: [NSValue valueWithPoint: p]];
point = p;
}
- (void)DPSnewpath
{
int count;
count = [path count];
while (count--)
[path popObject];
point.x = 0 ; point.y = 0;
}
- (void)DPSpathbbox: (float *)llx : (float *)lly : (float *)urx : (float *)ury
{
}
- (void)DPSpathforall
{
}
- (void)DPSrcurveto: (float)x1 : (float)y1 : (float)x2 : (float)y2 : (float)x3 : (float)y3
{
}
- (void)DPSrectclip: (float)x : (float)y : (float)w : (float)h
{
NSRect bounds;
Region new_region;
XRectangle xrect;
COPY_GC_ON_CHANGE;
bounds = NSMakeRect(x, y, w, h);
[self convertRectToDrawable:&bounds];
xrect.x = NSMinX(bounds); xrect.y = NSMinY(bounds);
xrect.width = NSWidth(bounds); xrect.height = NSHeight(bounds);
new_region = XCreateRegion();
if (!clipregion)
clipregion = XCreateRegion();
XUnionRectWithRegion(&xrect, clipregion, new_region);
XDestroyRegion(clipregion);
clipregion = new_region;
[self setClipMask];
}
- (void)DPSrectviewclip: (float)x : (float)y : (float)w : (float)h
{
NSRect bounds;
Region region, new_region;
XRectangle xrect;
bounds = NSMakeRect(x, y, w, h);
[self convertRectToDrawable:&bounds];
xrect.x = NSMinX(bounds); xrect.y = NSMinY(bounds);
xrect.width = NSWidth(bounds); xrect.height = NSHeight(bounds);
region = XCreateRegion();
new_region = XCreateRegion();
XUnionRectWithRegion(&xrect, region, new_region);
XDestroyRegion(region);
[ctxt setViewclipRegion: new_region];
}
- (void)DPSreversepath
{
}
- (void)DPSrlineto: (float)x : (float)y
{
NSPoint p;
p.x = x; p.y = y;
p = applyCGT(p, cgt);
PUSH_PATH_OBJECT(path_rlineto);
[path pushObject: [NSValue valueWithPoint: p]];
}
- (void)DPSrmoveto: (float)x : (float)y
{
NSPoint p;
p.x = x; p.y = y;
p = applyCGT(p, cgt);
PUSH_PATH_OBJECT(path_rmoveto);
[path pushObject: [NSValue valueWithPoint: p]];
point.x += p.x;
point.y += p.y;
}
- (void)DPSsetbbox: (float)llx : (float)lly : (float)urx : (float)ury
{
}
- (void)DPSsetucacheparams
{
}
- (void)DPSuappend: (const char *)nums : (int)n : (const char *)ops : (int)l
{
}
- (void)DPSucache
{
}
- (void)DPSucachestatus
{
}
- (void)DPSupath: (int)b
{
}
- (void)DPSviewclip
{
PUSH_PATH_OBJECT(path_viewclip);
[self _paintPath];
}
- (void)DPSviewclippath
{
}
@end
@implementation XtGState (WinOps)
- (void)DPSineofill: (float)x : (float)y : (int *)b
{
}
- (void)DPSinfill: (float)x : (float)y : (int *)b
{
}
- (void)DPSinstroke: (float)x : (float)y : (int *)b
{
}
- (void)DPSinueofill: (float)x : (float)y : (const char *)nums : (int)n : (const char *)ops : (int)l : (int *)b
{
}
- (void)DPSinufill: (float)x : (float)y : (const char *)nums : (int)n : (const char *)ops : (int)l : (int *)b
{
}
- (void)DPSinustroke: (float)x : (float)y : (const char *)nums : (int)n : (const char *)ops : (int)l : (int *)b
{
}
- (void)DPSwtranslation: (float *)x : (float *)y
{
}
@end
@implementation XtGState (L2Ops)
- (void)DPScshow: (const char *)s
{
}
- (void)DPScurrentcolor
{
}
- (void)DPScurrentcolorrendering
{
}
- (void)DPScurrentcolorspace
{
}
- (void)DPSsetcolor
{
}
- (void)DPSsetcolorrendering
{
}
- (void)DPSsetcolorspace
{
}
- (void)DPSsetpattern: (int)patternDict
{
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.