123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- /*
- * UserPath.m by Bruce Blumberg, NeXT Computer, Inc.
- *
- * You may freely copy,distribute and re-use the code in this example. NeXT
- * disclaims any warranty of any kind, expressed or implied, as to its fitness
- * for any particular purpose
- *
- */
- #import "UserPath.h"
- #import <mach/mach_init.h>
- #import <appkit/graphics.h>
- #import <appkit/errors.h>
- #import <math.h>
- #import <libc.h>
- static NXZone *upZone = NULL;
- NXZone *userPathZone()
- /* Creates a unique zone for use by all user paths */
- {
- if (!upZone) {
- upZone = NXCreateZone(vm_page_size, vm_page_size, 1);
- }
-
- return upZone;
- }
- UserPath *newUserPath()
- /* Creates a new User Path in the zone returned by userPathZone */
- {
- UserPath *up;
- up = (UserPath *)NXZoneMalloc(userPathZone(), sizeof(UserPath));
- up->max = 8192; // JDC
- up->points = (float *)NXZoneMalloc(userPathZone(),
- sizeof(float) * up->max);
- up->ops = (char *)NXZoneMalloc(userPathZone(),
- (2 + (up->max / 2)) * sizeof(char));
- up->ping = NO;
-
- return up;
- }
- void freeUserPath(UserPath *up)
- /* Frees User Path and its associated buffers */
- {
- free(up->points);
- free(up->ops);
- free(up);
-
- return;
- }
- void growUserPath(UserPath *up)
- /*
- * grows the associated buffers as necessary. buffer size doubles on each
- * call. You never need to call grow directly as it is called as needed by the
- * methods and functions which add elements into the buffer
- */
- {
- /* double the size of the internal buffers */
- printf ("growUserPath\n");
- up->max *= 2;
- up->points = (float *)NXZoneRealloc(userPathZone(), up->points,
- sizeof(float) * up->max);
- up->ops = (char *)NXZoneRealloc(userPathZone(), up->ops,
- (2 + (up->max / 2)) * sizeof(char));
- return;
- }
- void beginUserPath(UserPath *up, BOOL cache)
- /*
- * Call this to start generating a user path. The cache argument specifies if
- * you want the user path cached at the server (i.e. dps_ucache). In either
- * case, the UserPath object will automatically calculate the bounding box for
- * the path and add the dps_setbbox operator.
- */
- {
- up->numberOfPoints = up->numberOfOps = 0;
- up->cp.x = up->cp.y = 0;
- up->bbox[0] = up->bbox[1] = 1.0e6;
- up->bbox[2] = up->bbox[3] = -1.0e6;
- if (cache) {
- up->ops[up->numberOfOps++] = dps_ucache;
- }
- up->ops[up->numberOfOps++] = dps_setbbox;
- up->opForUserPath = 0;
-
- return;
- }
- void endUserPath(UserPath *up, int op)
- /*
- * Call this to stop filling the path. Note this does not send the userpath to
- * the server -- use sendUserPath. The op argument should be one of the
- * following:
- * dps_uappend, dps_ufill ,dps_ueofill, dps_ustroke, dps_ustrokepath,
- * dps_inufill, dps_inueofill, dps_inustroke, dps_def, dps_put.
- * These are defined in <dpsclient/dpsNext.h.
- */
- {
- up->opForUserPath = op;
-
- return;
- }
- void UPdebug(UserPath *up, BOOL shouldPing)
- /*
- * Sets ping to YES so that after each time a user path is sent down to the
- * window server, an NXPing() is sent after. The purpose is to catch PostScript
- * errors that may be generated by the user path. sendUserPath brackets the
- * download and the NXPing() in an NX_DURING... NX_HANDLER construct. Normally
- * ping is NO.
- */
- {
- up->ping = shouldPing;
-
- return;
- }
- int sendUserPath(UserPath *up)
- /*
- * Call this to send the path down to the server. If ping==YES (set via
- * debug:), the function will send an NXPing() after the Path. In any event,
- * code is bracketed by a NX_DURING ... NX_HANDLER construct which will try to
- * catch postscript errors. If ping==NO (the default) it is unlikely to catch
- * errors, with ping==YES it will. Whether you can recover or not is another
- * matter. sendUserPath returns 0 on success and -1 on failure. If no previous
- * endUserPath: has been sent, will return -2 and will not send the path to the
- * server.
- */
- {
- NXHandler exception;
- exception.code = 0;
- if (up->opForUserPath != 0) {
- NX_DURING
- DPSDoUserPath(up->points, up->numberOfPoints, dps_float, up->ops,
- up->numberOfOps, up->bbox, up->opForUserPath);
- if (up->ping) {
- NXPing();
- }
-
- NX_HANDLER
- exception = NXLocalHandler;
- NX_ENDHANDLER
- if (exception.code) {
- NXReportError(&exception);
- if (exception.code == dps_err_ps) {
- return -1;
- }
- } else {
- return 0;
- }
- }
-
- return -1;
- }
- void UPmoveto(UserPath *up, float x, float y)
- /* adds <x y moveto> to user path and updates bounding box */
- {
- up->ops[up->numberOfOps++] = dps_moveto;
- up->points[up->numberOfPoints++] = x;
- up->points[up->numberOfPoints++] = y;
-
- if (x < up->bbox[0]) {
- up->bbox[0] = x;
- }
- if (y < up->bbox[1]) {
- up->bbox[1] = y;
- }
- if (x > up->bbox[2]) {
- up->bbox[2] = x;
- }
- if (y > up->bbox[3]) {
- up->bbox[3] = y;
- }
-
- return;
- }
- void UPlineto(UserPath *up, float x, float y)
- /* adds <x y lineto> to user path and updates bounding box */
- {
- up->ops[up->numberOfOps++] = dps_lineto;
- up->points[up->numberOfPoints++] = x;
- up->points[up->numberOfPoints++] = y;
-
- if (x < up->bbox[0]) {
- up->bbox[0] = x;
- }
- if (y < up->bbox[1]) {
- up->bbox[1] = y;
- }
- if (x > up->bbox[2]) {
- up->bbox[2] = x;
- }
- if (y > up->bbox[3]) {
- up->bbox[3] = y;
- }
- return;
- }
|