mirror of
https://github.com/gnustep/libs-back.git
synced 2025-02-23 20:01:22 +00:00
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@26620 72102866-910b-0410-8b05-ffd578937521
751 lines
17 KiB
Objective-C
751 lines
17 KiB
Objective-C
/*
|
|
NSDPSContext.m
|
|
|
|
Encapsulation of Display Postscript contexts
|
|
|
|
Copyright (C) 1996 Free Software Foundation, Inc.
|
|
|
|
Author: Scott Christley <scottc@net-community.com>
|
|
Date: 1996
|
|
|
|
This file is part of the GNUstep GUI Library.
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser 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
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; see the file COPYING.LIB.
|
|
If not, see <http://www.gnu.org/licenses/> or write to the
|
|
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include <math.h>
|
|
#include <Foundation/NSString.h>
|
|
#include <Foundation/NSThread.h>
|
|
#include <Foundation/NSLock.h>
|
|
#include <Foundation/NSData.h>
|
|
#include <Foundation/NSDictionary.h>
|
|
|
|
#include <AppKit/NSAffineTransform.h>
|
|
#include <AppKit/NSView.h>
|
|
#include <AppKit/NSWindow.h>
|
|
#include <AppKit/NSWindow.h>
|
|
#include <GNUstepGUI/GSFontInfo.h>
|
|
|
|
#include "x11/XGServer.h"
|
|
#include "xdps/NSDPSContext.h"
|
|
|
|
#define BOOL XWINDOWSBOOL
|
|
#include <DPS/dpsXclient.h>
|
|
#include <DPS/dpsXshare.h>
|
|
#undef BOOL
|
|
|
|
#ifdef HAVE_WRASTER_H
|
|
#include "wraster.h"
|
|
#else
|
|
#include "x11/wraster.h"
|
|
#endif
|
|
|
|
#include "general.h"
|
|
#include "extensions.h"
|
|
#include "drawingfuncs.h"
|
|
#include "AFMFileFontInfo.h"
|
|
|
|
//
|
|
// DPS exceptions
|
|
//
|
|
NSString *DPSPostscriptErrorException = @"DPSPostscriptErrorException";
|
|
NSString *DPSNameTooLongException = @"DPSNameTooLongException";
|
|
NSString *DPSResultTagCheckException = @"DPSResultTagCheckException";
|
|
NSString *DPSResultTypeCheckException = @"DPSResultTypeCheckException";
|
|
NSString *DPSInvalidContextException = @"DPSInvalidContextException";
|
|
NSString *DPSSelectException = @"DPSSelectException";
|
|
NSString *DPSConnectionClosedException = @"DPSConnectionClosedException";
|
|
NSString *DPSReadException = @"DPSReadException";
|
|
NSString *DPSWriteException = @"DPSWriteException";
|
|
NSString *DPSInvalidFDException = @"DPSInvalidFDException";
|
|
NSString *DPSInvalidTEException = @"DPSInvalidTEException";
|
|
NSString *DPSInvalidPortException = @"DPSInvalidPortException";
|
|
NSString *DPSOutOfMemoryException = @"DPSOutOfMemoryException";
|
|
NSString *DPSCantConnectException = @"DPSCantConnectException";
|
|
|
|
#define XDPY (((RContext *)context)->dpy)
|
|
#define XDRW (((RContext *)context)->drawable)
|
|
|
|
enum {
|
|
A_COEFF = 0,
|
|
B_COEFF,
|
|
C_COEFF,
|
|
D_COEFF,
|
|
TX_CONS,
|
|
TY_CONS
|
|
};
|
|
|
|
//
|
|
// Class variables
|
|
//
|
|
static BOOL GNU_CONTEXT_TRACED = NO;
|
|
static BOOL GNU_CONTEXT_SYNCHRONIZED = NO;
|
|
|
|
static NSDPSContext *context_list = nil;
|
|
static FILE *gstream = NULL;
|
|
|
|
/* Text handler for text contexts */
|
|
static void
|
|
GNUstepOutputTextProc (DPSContext ctxt, char *buf, long unsigned int count)
|
|
{
|
|
/* FIXME: If there's a possibility of having more than one text context
|
|
we should have some simple hash to determine what stream to write to */
|
|
if (gstream)
|
|
fwrite(buf, 1, count, gstream);
|
|
else
|
|
DPSDefaultTextBackstop (ctxt, buf, count);
|
|
}
|
|
|
|
/* Text handler for screen contexts */
|
|
static void
|
|
GNUstepTextProc (DPSContext ctxt, char *buf, long unsigned int count)
|
|
{
|
|
DPSDefaultTextBackstop (ctxt, buf, count);
|
|
}
|
|
|
|
/* Error handler for all types of contexts */
|
|
static void
|
|
GNUstepErrorProc (DPSContext ctxt, DPSErrorCode errCode,
|
|
unsigned arg1, unsigned args)
|
|
{
|
|
DPSDefaultErrorProc (ctxt, errCode, arg1, arg1);
|
|
}
|
|
|
|
@interface NSDPSContext (Private)
|
|
- (void) createDPSContext;
|
|
- (void) createTextContext;
|
|
@end
|
|
|
|
@implementation NSDPSContext
|
|
|
|
+ (void)initialize
|
|
{
|
|
if (self == [NSDPSContext class])
|
|
{
|
|
// Set initial version
|
|
[self setVersion: 1];
|
|
|
|
GNU_CONTEXT_TRACED = NO;
|
|
GNU_CONTEXT_SYNCHRONIZED = NO;
|
|
}
|
|
}
|
|
|
|
/* Initialize AppKit backend */
|
|
+ (void)initializeBackend
|
|
{
|
|
NSDebugLog(@"Initializing GNUstep GUI X/DPS Backend.\n");
|
|
[NSGraphicsContext setDefaultContextClass: [NSDPSContext class]];
|
|
[GSFontEnumerator setDefaultClass: [PXKFontEnumerator class]];
|
|
[GSFontInfo setDefaultClass: [AFMFileFontInfo class]];
|
|
}
|
|
|
|
+ (void) setCurrentContext: (NSGraphicsContext *)aContext
|
|
{
|
|
[super setCurrentContext: aContext];
|
|
DPSSetContext([(NSDPSContext *)aContext xDPSContext]);
|
|
}
|
|
|
|
//
|
|
// Initializing a Context
|
|
//
|
|
- init
|
|
{
|
|
return [self initWithContextInfo: nil];
|
|
}
|
|
|
|
- (id) initWithContextInfo: (NSDictionary *)info
|
|
{
|
|
NSString *contextType;
|
|
|
|
[super initWithContextInfo: info];
|
|
|
|
/* A context is only associated with one server. Do not retain
|
|
the server, however */
|
|
server = GSCurrentServer();
|
|
|
|
chained_parent = nil;
|
|
chained_child = nil;
|
|
contextType = [info objectForKey:
|
|
NSGraphicsContextRepresentationFormatAttributeName];
|
|
if (contextType && [contextType isEqual: NSGraphicsContextPSFormat])
|
|
{
|
|
NSString *path;
|
|
is_screen_context = NO;
|
|
error_proc = GNUstepErrorProc;
|
|
text_proc = GNUstepOutputTextProc;
|
|
path = [info objectForKey: @"NSOutputFile"];
|
|
if (path == nil)
|
|
{
|
|
NSLog(@"Warning: No path set for stream context, default temp.ps");
|
|
path = @"temp.ps";
|
|
}
|
|
gstream = fopen([path cString], "w");
|
|
if (gstream == NULL)
|
|
{
|
|
NSLog(@"Error: Could not open output path for stream context");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
is_screen_context = YES;
|
|
error_proc = GNUstepErrorProc;
|
|
text_proc = GNUstepTextProc;
|
|
}
|
|
|
|
/*
|
|
* Create the context
|
|
*/
|
|
if (is_screen_context)
|
|
{
|
|
[self createDPSContext];
|
|
}
|
|
else
|
|
{
|
|
[self createTextContext];
|
|
}
|
|
|
|
if (dps_context == NULL)
|
|
{
|
|
[self dealloc];
|
|
return nil;
|
|
}
|
|
|
|
/* Add context to global list of contexts */
|
|
next_context = context_list;
|
|
context_list = self;
|
|
|
|
if (GSDebugSet(@"NSDPSContext") == YES)
|
|
{
|
|
NSLog(@"NSDPSContext: Tracing Postscript \n");
|
|
[self setOutputTraced: YES];
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
DESTROY(chained_child);
|
|
|
|
DPSDestroySpace(DPSSpaceFromContext(dps_context));
|
|
if (is_screen_context == 0)
|
|
{
|
|
if (gstream)
|
|
fclose(gstream);
|
|
}
|
|
/* Remove context from global list of contexts */
|
|
{
|
|
NSDPSContext *ctxt = context_list, *previous=nil;
|
|
|
|
while (ctxt)
|
|
{
|
|
if (ctxt == self)
|
|
break;
|
|
previous = ctxt;
|
|
ctxt = ctxt->next_context;
|
|
}
|
|
if (!ctxt)
|
|
NSLog(@"Internal Error: Couldn't find context to delete");
|
|
else
|
|
{
|
|
if (previous)
|
|
previous->next_context = next_context;
|
|
else
|
|
context_list = next_context;
|
|
}
|
|
}
|
|
[super dealloc];
|
|
}
|
|
|
|
//
|
|
// Testing the Drawing Destination
|
|
//
|
|
- (BOOL)isDrawingToScreen
|
|
{
|
|
return is_screen_context;
|
|
}
|
|
|
|
- (NSDPSContext *)DPSContext
|
|
{
|
|
return self;
|
|
}
|
|
|
|
- (void)wait
|
|
{
|
|
DPSWaitContext (dps_context);
|
|
}
|
|
|
|
+ (void) waitAllContexts
|
|
{
|
|
NSDPSContext *ctxt;
|
|
ctxt = context_list;
|
|
while (ctxt)
|
|
{
|
|
[ctxt wait];
|
|
ctxt = ctxt->next_context;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Managing Returned Text and Errors
|
|
//
|
|
+ (NSString *)stringForDPSError:(const DPSBinObjSeqRec *)error
|
|
{
|
|
return nil;
|
|
}
|
|
|
|
- (DPSErrorProc)errorProc
|
|
{
|
|
return error_proc;
|
|
}
|
|
|
|
- (void)setErrorProc:(DPSErrorProc)proc
|
|
{
|
|
error_proc = proc;
|
|
}
|
|
|
|
- (void)setTextProc:(DPSTextProc)proc
|
|
{
|
|
text_proc = proc;
|
|
}
|
|
|
|
- (DPSTextProc)textProc
|
|
{
|
|
return text_proc;
|
|
}
|
|
|
|
//
|
|
// Managing Chained Contexts
|
|
//
|
|
- (void)setParentContext:(NSDPSContext *)parent
|
|
{
|
|
chained_parent = parent;
|
|
}
|
|
|
|
- (void)chainChildContext:(NSDPSContext *)child
|
|
{
|
|
if (child)
|
|
{
|
|
chained_child = [child retain];
|
|
[child setParentContext: self];
|
|
}
|
|
}
|
|
|
|
- (NSDPSContext *)childContext
|
|
{
|
|
return chained_child;
|
|
}
|
|
|
|
- (NSDPSContext *)parentContext
|
|
{
|
|
return chained_parent;
|
|
}
|
|
|
|
- (void)unchainContext
|
|
{
|
|
if (chained_child)
|
|
{
|
|
[chained_child setParentContext: nil];
|
|
[chained_child release];
|
|
chained_child = nil;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Debugging Aids
|
|
//
|
|
+ (BOOL)areAllContextsOutputTraced
|
|
{
|
|
return GNU_CONTEXT_TRACED;
|
|
}
|
|
|
|
+ (BOOL)areAllContextsSynchronized
|
|
{
|
|
return GNU_CONTEXT_SYNCHRONIZED;
|
|
}
|
|
|
|
+ (void)setAllContextsOutputTraced:(BOOL)flag
|
|
{
|
|
GNU_CONTEXT_TRACED = flag;
|
|
}
|
|
|
|
+ (void)setAllContextsSynchronized:(BOOL)flag
|
|
{
|
|
GNU_CONTEXT_SYNCHRONIZED = flag;
|
|
}
|
|
|
|
- (BOOL)isOutputTraced
|
|
{
|
|
return is_output_traced;
|
|
}
|
|
|
|
- (BOOL)isSynchronized
|
|
{
|
|
return is_synchronized;
|
|
}
|
|
|
|
- (void)setOutputTraced:(BOOL)flag
|
|
{
|
|
is_output_traced = flag;
|
|
XDPSChainTextContext(dps_context, flag);
|
|
}
|
|
|
|
- (void)setSynchronized:(BOOL)flag
|
|
{
|
|
is_synchronized = flag;
|
|
}
|
|
|
|
@end
|
|
|
|
//
|
|
// Methods for XWindows implementation
|
|
//
|
|
@implementation NSDPSContext (GNUstepXDPS)
|
|
|
|
- (Display*)xDisplay
|
|
{
|
|
if (is_screen_context)
|
|
return [(XGServer *)server xDisplay];
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
- (DPSContext)xDPSContext
|
|
{
|
|
return dps_context;
|
|
}
|
|
|
|
- (void)createDPSContext
|
|
{
|
|
int x, y, supported;
|
|
unsigned long valuemask;
|
|
XGCValues values;
|
|
|
|
// Where should the screen number come from?
|
|
context = [(XGServer *)server xrContextForScreen: 0];
|
|
if (!XDPSExtensionPresent(XDPY))
|
|
{
|
|
#if HAVE_DPS_DPSNXARGS_H
|
|
/* Make it possible for this client to start a DPS NX agent */
|
|
XDPSNXSetClientArg(XDPSNX_AUTO_LAUNCH, (void *)True);
|
|
#else
|
|
NSLog (@"DPS extension not in server!");
|
|
exit (1);
|
|
#endif
|
|
}
|
|
|
|
/* Create a GC for the initial window */
|
|
values.foreground = ((RContext *)context)->black;
|
|
values.background = ((RContext *)context)->white;
|
|
values.function = GXcopy;
|
|
values.plane_mask = AllPlanes;
|
|
values.clip_mask = None;
|
|
valuemask = (GCFunction | GCPlaneMask | GCClipMask
|
|
| GCForeground|GCBackground);
|
|
((RContext *)context)->copy_gc =
|
|
XCreateGC(XDPY, XDRW, valuemask, &values);
|
|
|
|
/* Create the context if need be */
|
|
if (!dps_context)
|
|
{
|
|
/* Pass None as the drawable argument; the program will execute correctly
|
|
but will not render any text or graphics. */
|
|
dps_context = XDPSCreateSimpleContext(XDPY, None,
|
|
((RContext *)context)->copy_gc,
|
|
0, 0,
|
|
text_proc,
|
|
error_proc,
|
|
NULL);
|
|
if (dps_context == NULL)
|
|
{
|
|
NSLog(@"Could not connect to DPS\n");
|
|
NSLog(@"Trying again...\n");
|
|
dps_context = XDPSCreateSimpleContext(XDPY, None,
|
|
((RContext *)context)->copy_gc,
|
|
0, 0,
|
|
text_proc,
|
|
error_proc,
|
|
NULL);
|
|
|
|
if (dps_context == NULL)
|
|
{
|
|
NSLog(@"DPS is not available\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
// Make it the active context
|
|
DPSSetContext(dps_context);
|
|
XDPSRegisterContext(dps_context, NO);
|
|
|
|
// Use pass-through event handling
|
|
XDPSSetEventDelivery(XDPY, dps_event_pass_through);
|
|
}
|
|
|
|
PSWinitcontext (XGContextFromGC (((RContext *)context)->copy_gc),
|
|
XDRW, 0, 0);
|
|
PSWGetTransform (dps_context, ctm, invctm, &x, &y);
|
|
PSWinitcontext (XGContextFromGC (((RContext *)context)->copy_gc),
|
|
None, 0, 0);
|
|
PSWRevision(&dps_revision);
|
|
|
|
/* Check for operator extensions */
|
|
DPSWKnownExtensions(dps_context, &ext_flags);
|
|
/* Check if composite-related extensions work */
|
|
/* FIXME: This crashes DPS on some implementations */
|
|
//DPSWWorkingExtensions(dps_context, &supported);
|
|
supported = 0;
|
|
if (supported == 0)
|
|
ext_flags = (ext_flags
|
|
& ~(COMPOSITE_EXT | ALPHAIMAGE_EXT | COMPOSITERECT_EXT
|
|
| DISSOLVE_EXT | READIMAGE_EXT | SETALPHA_EXT));
|
|
/* FIXME: alphaimage and composite work badly in DGS 5.50. Perhaps when
|
|
we find a version that works we can put an additional test here. For now,
|
|
just turn them off.
|
|
*/
|
|
ext_flags = (ext_flags & ~(COMPOSITE_EXT | ALPHAIMAGE_EXT | DISSOLVE_EXT));
|
|
|
|
NSDebugLLog(@"NSDPSContext", @"Using DPS Revision: %d\n", dps_revision);
|
|
NSDebugLLog(@"NSDPSContext", @"DPS Default Matrix: [%f %f %f %f %f %f]\n",
|
|
ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
|
|
NSDebugLLog(@"NSDPSContext", @"DPS Extensions flags: %d\n", ext_flags);
|
|
if ([[NSUserDefaults standardUserDefaults] boolForKey: @"DPSDefaultMatrix"]
|
|
== NO)
|
|
{
|
|
NSDebugLog(@"Reseting default matrix\n");
|
|
ctm[0] /= fabs(ctm[0]);
|
|
ctm[3] /= fabs(ctm[3]);
|
|
PSWSetMatrix(ctm);
|
|
}
|
|
}
|
|
|
|
- (void)createTextContext
|
|
{
|
|
if (dps_context)
|
|
return;
|
|
|
|
dps_context = DPSCreateTextContext(text_proc, error_proc);
|
|
if (dps_context == NULL)
|
|
{
|
|
NSLog(@"Could not create DPS text context");
|
|
return;
|
|
}
|
|
}
|
|
|
|
- (void) flushGraphics
|
|
{
|
|
DPSFlushContext(dps_context);
|
|
XFlush([(XGServer *)server xDisplay]);
|
|
}
|
|
|
|
- (void) _localTransform: (float *)local_ctm inverse: (float *)local_inv
|
|
offset: (NSPoint *)offset
|
|
{
|
|
int x, y;
|
|
if (local_ctm == NULL || local_inv == NULL)
|
|
return;
|
|
PSWGetTransform (dps_context, local_ctm, local_inv, &x, &y);
|
|
if (offset)
|
|
{
|
|
offset->x = x;
|
|
offset->y = y;
|
|
}
|
|
}
|
|
|
|
- (NSPoint)userPointFromXPoint:(NSPoint)xPoint
|
|
{
|
|
float lctm[6], linv[6];
|
|
NSPoint offset, userPoint;
|
|
|
|
[self _localTransform: lctm inverse: linv offset: &offset];
|
|
//xPoint.x -= offset.x;
|
|
//xPoint.y -= offset.y;
|
|
userPoint.x = linv[A_COEFF] * xPoint.x + linv[C_COEFF] * xPoint.y
|
|
+ linv[TX_CONS];
|
|
userPoint.y = linv[B_COEFF] * xPoint.x + linv[D_COEFF] * xPoint.y
|
|
+ linv[TY_CONS];
|
|
return userPoint;
|
|
}
|
|
|
|
- (NSPoint)XPointFromUserPoint:(NSPoint)userPoint
|
|
{
|
|
float lctm[6], linv[6];
|
|
NSPoint offset, xPoint;
|
|
|
|
[self _localTransform: lctm inverse: linv offset: &offset];
|
|
xPoint.x = lctm[A_COEFF] * userPoint.x + lctm[C_COEFF] * userPoint.y
|
|
+ lctm[TX_CONS] + offset.x;
|
|
xPoint.y = lctm[B_COEFF] * userPoint.x + lctm[D_COEFF] * userPoint.y
|
|
+ lctm[TY_CONS] + offset.y;
|
|
xPoint.x = floor (xPoint.x);
|
|
xPoint.y = floor (xPoint.y);
|
|
NSDebugLLog(@"CTM", @"Matrix [%f,%f,%f,%f,%f,%f] (%f,%f)\n",
|
|
lctm[A_COEFF], lctm[B_COEFF], lctm[C_COEFF], lctm[D_COEFF],
|
|
lctm[TX_CONS], lctm[TY_CONS], offset.x, offset.y);
|
|
return xPoint;
|
|
}
|
|
|
|
- (NSRect)userRectFromXRect:(NSRect)xrect
|
|
{
|
|
float lctm[6], linv[6];
|
|
float x, y, w, h;
|
|
|
|
[self _localTransform: lctm inverse: linv offset: NULL];
|
|
x = linv[A_COEFF] * NSMinX(xrect) + linv[C_COEFF] * NSMinY(xrect)
|
|
+ linv[TX_CONS];
|
|
y = linv[B_COEFF] * NSMinX(xrect) + linv[D_COEFF] * NSMinY(xrect)
|
|
+ linv[TY_CONS];
|
|
w = linv[A_COEFF] * NSWidth(xrect) + linv[C_COEFF] * NSHeight(xrect);
|
|
h = linv[B_COEFF] * NSWidth(xrect) + linv[D_COEFF] * NSHeight(xrect);
|
|
if (h < 0)
|
|
y -= h;
|
|
h = fabs(h);
|
|
if (w < 0)
|
|
x -= w;
|
|
w = fabs(w);
|
|
return NSMakeRect(x, y, w, h);
|
|
}
|
|
|
|
- (NSRect)XRectFromUserRect:(NSRect)urect
|
|
{
|
|
NSPoint offset;
|
|
float lctm[6], linv[6];
|
|
float x, y, w, h;
|
|
|
|
[self _localTransform: lctm inverse: linv offset: &offset];
|
|
x = lctm[A_COEFF] * NSMinX(urect) + lctm[C_COEFF] * NSMinY(urect)
|
|
+ lctm[TX_CONS] + offset.x;
|
|
y = lctm[B_COEFF] * NSMinX(urect) + lctm[D_COEFF] * NSMinY(urect)
|
|
+ lctm[TY_CONS] + offset.y;
|
|
w = lctm[A_COEFF] * NSWidth(urect) + lctm[C_COEFF] * NSHeight(urect);
|
|
h = lctm[B_COEFF] * NSWidth(urect) + lctm[D_COEFF] * NSHeight(urect);
|
|
NSDebugLLog(@"CTM", @"Matrix [%f,%f,%f,%f,%f,%f] (%f,%f)\n",
|
|
lctm[A_COEFF], lctm[B_COEFF], lctm[C_COEFF], lctm[D_COEFF],
|
|
lctm[TX_CONS], lctm[TY_CONS], offset.x, offset.y);
|
|
if (h < 0)
|
|
y += h;
|
|
h = fabs(floor(h));
|
|
if (w < 0)
|
|
x += w;
|
|
w = fabs(floor(w));
|
|
x = floor(x);
|
|
y = floor(y);
|
|
return NSMakeRect(x, y, w, h);
|
|
}
|
|
|
|
- (op_extensions_t) operatorExtensions
|
|
{
|
|
return ext_flags;
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation NSDPSContext (NSGraphics)
|
|
|
|
/* Optimized drawing functions */
|
|
- (void) NSRectFillList: (const NSRect *)rects : (int) count
|
|
{
|
|
int i;
|
|
float rectvals[count*4];
|
|
|
|
if (count*4 > 65536)
|
|
{
|
|
NSLog(@"DPS Rendering Error: RectFillList with > 16384 rects");
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
rectvals[i*4 ] = NSMinX(rects[i]);
|
|
rectvals[i*4 + 1] = NSMinY(rects[i]);
|
|
rectvals[i*4 + 2] = NSWidth(rects[i]);
|
|
rectvals[i*4 + 3] = NSHeight(rects[i]);
|
|
}
|
|
PSWRectFillList(rectvals, count*4);
|
|
}
|
|
|
|
- (void) NSRectFillListWithGrays: (const NSRect *)rects : (const float *)grays
|
|
:(int) count
|
|
{
|
|
#if 1
|
|
int i;
|
|
float rectvals[count*5];
|
|
|
|
if (count*5 > 65536)
|
|
{
|
|
NSLog(@"DPS Rendering Error: RectFillListGray with > 13107 rects");
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
rectvals[i*5 ] = NSMinX(rects[i]);
|
|
rectvals[i*5 + 1] = NSMinY(rects[i]);
|
|
rectvals[i*5 + 2] = NSWidth(rects[i]);
|
|
rectvals[i*5 + 3] = NSHeight(rects[i]);
|
|
rectvals[i*5 + 4] = grays[i];
|
|
}
|
|
PSWRectFillListGray(rectvals, count*5);
|
|
#else
|
|
int i, last_gray, tcount;
|
|
|
|
PSsetgray(grays[0]);
|
|
last_gray = grays[0];
|
|
tcount = 0;
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
if (grays[i] != last_gray)
|
|
{
|
|
NSRectFillList(&rects[i-tcount], tcount);
|
|
tcount = 0;
|
|
PSsetgray(grays[i]);
|
|
last_gray = grays[i];
|
|
}
|
|
else
|
|
tcount++;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
- (void) NSDottedFrameRect: (const NSRect) aRect
|
|
{
|
|
PSWDottedFrameRect (aRect.origin.x, aRect.origin.y,
|
|
aRect.size.width, aRect.size.height);
|
|
}
|
|
|
|
- (void) NSFrameRect: (const NSRect) aRect
|
|
{
|
|
PSWFrameRect (aRect.origin.x, aRect.origin.y,
|
|
aRect.size.width, aRect.size.height);
|
|
}
|
|
|
|
- (void) NSFrameRectWithWidth: (const NSRect) aRect : (float) frameWidth
|
|
{
|
|
PSWFrameRectWithWidth (aRect.origin.x, aRect.origin.y,
|
|
aRect.size.width, aRect.size.height, frameWidth);
|
|
}
|
|
|
|
//
|
|
// Read the Color at a Screen Position
|
|
//
|
|
- (NSColor *) NSReadPixel: (NSPoint) location
|
|
{
|
|
return nil;
|
|
}
|
|
|
|
@end
|