home *** CD-ROM | disk | FTP | other *** search
/ Superpower (Alt) / SUPERPOWER.iso / q / source / userpath.m < prev    next >
Encoding:
Text File  |  1996-08-08  |  5.2 KB  |  210 lines

  1. /* 
  2.  * UserPath.m by Bruce Blumberg, NeXT Computer, Inc.
  3.  *
  4.  * You may freely copy,distribute and re-use the code in this example. NeXT
  5.  * disclaims any warranty of any kind, expressed or implied, as to its fitness
  6.  * for any particular purpose
  7.  *
  8.  */
  9.  
  10. #import "UserPath.h"
  11. #import <mach/mach_init.h>
  12. #import <appkit/graphics.h>
  13. #import <appkit/errors.h>
  14. #import <math.h>
  15. #import <libc.h>
  16.  
  17. static NXZone      *upZone = NULL;
  18.  
  19. NXZone *userPathZone()
  20. /* Creates a unique zone for use by all user paths */
  21. {
  22.     if (!upZone) {
  23.     upZone = NXCreateZone(vm_page_size, vm_page_size, 1);
  24.     }
  25.     
  26.     return upZone;
  27. }
  28.  
  29. UserPath *newUserPath()
  30. /* Creates a new User Path in the zone returned by userPathZone */
  31. {
  32.     UserPath    *up;
  33.  
  34.     up = (UserPath *)NXZoneMalloc(userPathZone(), sizeof(UserPath));
  35.     up->max = 8192;    // JDC
  36.     up->points = (float *)NXZoneMalloc(userPathZone(),
  37.                            sizeof(float) * up->max);
  38.     up->ops = (char *)NXZoneMalloc(userPathZone(),
  39.                        (2 + (up->max / 2)) * sizeof(char));
  40.     up->ping = NO;
  41.     
  42.     return up;
  43. }
  44.  
  45. void freeUserPath(UserPath *up)
  46. /* Frees User Path and its associated buffers */
  47. {
  48.     free(up->points);
  49.     free(up->ops);
  50.     free(up);
  51.     
  52.     return;
  53. }
  54.  
  55. void growUserPath(UserPath *up)
  56. /*
  57.  * grows the  associated buffers as necessary. buffer size doubles on each
  58.  * call. You never need to call grow directly as it is called as needed by the
  59.  * methods and functions which add elements into the buffer
  60.  */
  61. {
  62.  /* double the size of the internal buffers */
  63. printf ("growUserPath\n");
  64.     up->max *= 2;
  65.     up->points = (float *)NXZoneRealloc(userPathZone(), up->points,
  66.                     sizeof(float) * up->max);
  67.     up->ops = (char *)NXZoneRealloc(userPathZone(), up->ops,
  68.                         (2 + (up->max / 2)) * sizeof(char));
  69.  
  70.     return;
  71. }
  72.  
  73. void beginUserPath(UserPath *up, BOOL cache)
  74. /*
  75.  * Call this to start generating a user path. The cache argument specifies if
  76.  * you want the user path cached at the server (i.e. dps_ucache). In either
  77.  * case, the UserPath object will automatically calculate the bounding box for
  78.  * the path and add the dps_setbbox operator.
  79.  */
  80. {
  81.     up->numberOfPoints = up->numberOfOps = 0;
  82.     up->cp.x = up->cp.y = 0;
  83.     up->bbox[0] = up->bbox[1] = 1.0e6;
  84.     up->bbox[2] = up->bbox[3] = -1.0e6;
  85.     if (cache) {
  86.     up->ops[up->numberOfOps++] = dps_ucache;
  87.     }
  88.     up->ops[up->numberOfOps++] = dps_setbbox;
  89.     up->opForUserPath = 0;
  90.     
  91.     return;
  92. }
  93.  
  94. void endUserPath(UserPath *up, int op)
  95. /*
  96.  * Call this to stop filling the path. Note this does not send the userpath to
  97.  * the server -- use sendUserPath. The op argument should be one of the
  98.  * following:
  99.  *    dps_uappend, dps_ufill ,dps_ueofill, dps_ustroke, dps_ustrokepath,
  100.  *    dps_inufill, dps_inueofill, dps_inustroke, dps_def, dps_put.
  101.  * These are defined in <dpsclient/dpsNext.h.  
  102.  */
  103. {
  104.     up->opForUserPath = op;
  105.     
  106.     return;
  107. }
  108.  
  109.  
  110. void UPdebug(UserPath *up, BOOL shouldPing)
  111. /*
  112.  * Sets ping to YES so that after each time a user path is sent down to the
  113.  * window server, an NXPing() is sent after. The purpose is to catch PostScript
  114.  * errors that may be generated by the user path. sendUserPath brackets the
  115.  * download and the NXPing() in an NX_DURING... NX_HANDLER construct. Normally
  116.  * ping is NO. 
  117.  */
  118. {
  119.     up->ping = shouldPing;
  120.     
  121.     return;
  122. }
  123.  
  124. int sendUserPath(UserPath *up)
  125. /*
  126.  * Call this to send the path down to the server. If ping==YES (set via
  127.  * debug:), the function will send an NXPing() after the Path. In any event,
  128.  * code is bracketed by a NX_DURING ... NX_HANDLER construct which will try to
  129.  * catch postscript errors.  If ping==NO (the default) it is unlikely to catch
  130.  * errors, with ping==YES it will. Whether you can recover or not is another
  131.  * matter. sendUserPath returns 0 on success and -1 on failure. If no previous
  132.  * endUserPath: has been sent, will return -2 and will not send the path to the
  133.  * server.
  134.  */
  135. {
  136.     NXHandler           exception;
  137.  
  138.     exception.code = 0;
  139.     if (up->opForUserPath != 0) {
  140.       NX_DURING
  141.     DPSDoUserPath(up->points, up->numberOfPoints, dps_float, up->ops,
  142.               up->numberOfOps, up->bbox, up->opForUserPath);
  143.     if (up->ping) {
  144.         NXPing();
  145.     }
  146.     
  147.       NX_HANDLER
  148.     exception = NXLocalHandler;
  149.       NX_ENDHANDLER
  150.     if (exception.code) {
  151.         NXReportError(&exception);
  152.         if (exception.code == dps_err_ps) {
  153.         return -1;
  154.         }
  155.     } else {
  156.         return 0;
  157.     }
  158.     }
  159.     
  160.     return -1;
  161. }
  162.  
  163.  
  164. void UPmoveto(UserPath *up, float x, float y)
  165. /* adds <x y moveto> to user path and updates bounding box */
  166. {
  167.     up->ops[up->numberOfOps++] = dps_moveto;
  168.     up->points[up->numberOfPoints++] = x;
  169.     up->points[up->numberOfPoints++] = y;
  170.  
  171.     if (x < up->bbox[0]) {
  172.     up->bbox[0] = x;
  173.     }
  174.     if (y < up->bbox[1]) {
  175.     up->bbox[1] = y;
  176.     }
  177.     if (x > up->bbox[2]) {
  178.     up->bbox[2] = x;
  179.     }
  180.     if (y > up->bbox[3]) {
  181.     up->bbox[3] = y;
  182.     }
  183.    
  184.     return;
  185. }
  186.  
  187.  
  188. void UPlineto(UserPath *up, float x, float y)
  189. /* adds <x y lineto> to user path and updates bounding box */
  190. {
  191.     up->ops[up->numberOfOps++] = dps_lineto;
  192.     up->points[up->numberOfPoints++] = x;
  193.     up->points[up->numberOfPoints++] = y;
  194.  
  195.     if (x < up->bbox[0]) {
  196.     up->bbox[0] = x;
  197.     }
  198.     if (y < up->bbox[1]) {
  199.     up->bbox[1] = y;
  200.     }
  201.     if (x > up->bbox[2]) {
  202.     up->bbox[2] = x;
  203.     }
  204.     if (y > up->bbox[3]) {
  205.     up->bbox[3] = y;
  206.     }
  207.     return;
  208. }
  209.  
  210.