home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / s / stex2-18.zip / SeeTeX / Xtex / DviPageDPS.c < prev    next >
C/C++ Source or Header  |  1992-06-25  |  8KB  |  311 lines

  1. /*
  2.  * Copyright 1989 Dirk Grunwald
  3.  * 
  4.  * Permission to use, copy, modify, distribute, and sell this software
  5.  * and its documentation for any purpose is hereby granted without fee,
  6.  * provided that the above copyright notice appear in all copies and that
  7.  * both that copyright notice and this permission notice appear in
  8.  * supporting documentation, and that the name of Dirk Grunwald or M.I.T.
  9.  * not be used in advertising or publicity pertaining to distribution of
  10.  * the software without specific, written prior permission.  Dirk
  11.  * Grunwald and M.I.T. makes no representations about the suitability of
  12.  * this software for any purpose.  It is provided "as is" without express
  13.  * or implied warranty.
  14.  * 
  15.  * DIRK GRUNWALD AND M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  16.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17.  * FITNESS, IN NO EVENT SHALL M.I.T.  BE LIABLE FOR ANY SPECIAL, INDIRECT
  18.  * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  19.  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  20.  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  21.  * OR PERFORMANCE OF THIS SOFTWARE.
  22.  * 
  23.  * Author:
  24.  *     Dr. Dirk Grunwald
  25.  *     Dept. of Computer Science
  26.  *     Campus Box 430
  27.  *     Univ. of Colorado, Boulder
  28.  *     Boulder, CO 80309
  29.  * 
  30.  *     grunwald@colorado.edu
  31.  *     
  32.  */ 
  33.  
  34. #include <stdio.h>
  35. #include <sys/time.h>
  36. #include <X11/IntrinsicP.h>
  37. #include <X11/StringDefs.h>
  38. #include <stdio.h>
  39. #include <assert.h>
  40. #include <varargs.h>
  41. #include <math.h>
  42. #include <ctype.h>
  43. #include <sys/param.h>
  44.  
  45. #include "xtex.h"
  46. #include "dvi-simple.h"
  47. #include "DviPageP.h"
  48.  
  49. #include "DviPageDPS.h"
  50.  
  51. void initDPS()
  52. {
  53. /* we don't do anthing for DPS */
  54. }
  55.  
  56. static void
  57.   HandleStatus(ctx, status)
  58. DPSContext ctx;
  59. int status;
  60. {
  61.   char *ptr, buf[1000];
  62.   switch (status) {
  63.   case PSRUNNING:    ptr = "[DPS status] running\n"; break;
  64.   case PSNEEDSINPUT:    ptr = "[DPS status] needs input\n"; break;
  65.   case PSZOMBIE:    ptr = "[DPS status] zombie\n"; break;
  66.   case PSFROZEN:    ptr = "[DPS status] frozen\n"; break;
  67.   default:        ptr = "[DPS status] unknown status\n"; break;
  68.   }
  69.   error(0,0,status);
  70.   if (status == PSFROZEN) {
  71.     XDPSUnfreezeContext(ctx);
  72.   }
  73. }
  74.  
  75. static void TextOut(ctx, buffer, count)
  76.      DPSContext ctx;
  77.      char *buffer;
  78.      unsigned count;
  79. {
  80.   char buff[1024];
  81.   while ( count > 0 ) {
  82.     int n = count;
  83.     if ( count > 1023 ) {
  84.       n = 1023;
  85.     }
  86.     memcpy(buff, buffer, n);
  87.     buff[n] = 0;
  88.     error(0,0,buffer);
  89.     count -= n;
  90.   }
  91. }
  92.  
  93. /*
  94.  * USE_GSAVE and ALWAYS_KILL were used for debugging memory leaks with
  95.  * the Display Postscript server.
  96.  */
  97.  
  98. /* USE_GSAVE means to wrap each user invocation in a gsave/grestore pair */
  99.  
  100. #define USE_GSAVE
  101.  
  102. /* ALWAYS_KILL means to kill the DPS context after each use, causing a
  103.    new one to be create for the next DPS figure */
  104.  
  105. #undef ALWAYS_KILL
  106.  
  107.  
  108. /* DPS postscript figure rendering */
  109. void
  110.   psfigBeginDPS(w,cp,fudge_height)
  111. DviPageWidget w;
  112. char *cp;
  113. int fudge_height;
  114. {
  115.   int bbllx, bblly;
  116.   int bburx, bbury;
  117.   int width, height;
  118.   int rawWidth, rawHeight;
  119.   int haveExtensions;
  120.   
  121.   int rx = fastFromSpHoriz(w, w -> dviPage.dviStackPointer -> h);
  122.   int ry = fastFromSpVert(w, w -> dviPage.dviStackPointer -> v);
  123.  
  124.   
  125.   sscanf(cp, " %d %d %d %d %d %d ",
  126.      &rawWidth, &rawHeight,
  127.      &bbllx, &bblly,
  128.      &bburx, &bbury);
  129.   
  130.   width = fastFromSpHoriz(w, rawWidth);
  131.   height = fastFromSpVert(w, rawHeight);
  132.  
  133.   /*
  134.    * \epsfbox{} apparently causes a situation where the image is
  135.    * expected to grow upward, rather than down from the position on the
  136.    * page, so we fake it here
  137.    */
  138.   if( fudge_height ) ry -= height;
  139.   
  140.  
  141.   if ( XRectInRegion( w -> dviPage.updateRegion,
  142.              rx, ry, width, height) == RectangleOut) {
  143.     w -> dviPage.dpsVisible = False;
  144.     return;
  145.   }
  146.   else {
  147.     w -> dviPage.dpsVisible = True;
  148.   }
  149.   
  150.   if ( w -> dviPage.ctx == NULL ) {
  151.     w -> dviPage.ctx = XDPSCreateSimpleContext(XtDisplay(w),
  152.                            XtWindow(w),
  153.                            DefaultGC(XtDisplay(w), 0),
  154.                            rx, ry,
  155.                            TextOut, DPSDefaultErrorProc,
  156.                            NULL);
  157.   }
  158.  
  159.   if ( w -> dviPage.ctx != NULL ) {
  160.     XDPSRegisterStatusProc(w -> dviPage.ctx, HandleStatus);
  161.     DPSPrintf(w -> dviPage.ctx, "\n resyncstart\n");
  162.     DPSWritePostScript(w -> dviPage.ctx,
  163.                w -> dviPage.dpsPreamble,
  164.                strlen(w -> dviPage.dpsPreamble));
  165.       
  166.  
  167.   }
  168.  
  169.   haveExtensions = w -> dviPage.ctx != NULL;
  170.  
  171.   /* check if server has DPS extension */
  172.   
  173.   if ( !haveExtensions ) {
  174.     XDrawLine(XtDisplay(w), XtWindow(w),
  175.           w -> dviPage.paintGC,
  176.           rx, ry, rx + width, ry );
  177.     XDrawLine(XtDisplay(w), XtWindow(w),
  178.           w -> dviPage.paintGC,
  179.           rx + width, ry, rx + width, ry + height);
  180.     XDrawLine(XtDisplay(w), XtWindow(w),
  181.           w -> dviPage.paintGC,
  182.           rx + width, ry + height, rx, ry + height);
  183.     XDrawLine(XtDisplay(w), XtWindow(w),
  184.           w -> dviPage.paintGC,
  185.           rx, ry + height, rx, ry);
  186.   }
  187.  
  188.   if ( haveExtensions ) {
  189.       int maxWidth = XtScreen(w) -> width;
  190.       int mmWidth = WidthMMOfScreen( XtScreen(w) );
  191.       
  192.       double dpi = (w -> dviPage.dpiHoriz * w -> dviPage.userMag) / 1000;
  193.       double trueDpi;
  194.       double scale;
  195.       
  196.       if ( w -> dviPage.trueDpi == 0.0 ) {
  197.     trueDpi = (maxWidth * 25.4) / mmWidth;
  198.       }
  199.       else {
  200.     trueDpi = w -> dviPage.trueDpi;
  201.       }
  202.       scale = dpi / trueDpi;
  203.       
  204.  
  205. #ifdef USE_GSAVE
  206.       DPSPrintf(w -> dviPage.ctx, "\n gsave save\n");
  207. #else
  208.       DPSPrintf(w -> dviPage.ctx, "\n \n");
  209. #endif
  210.  
  211.       DPSPrintf( w -> dviPage.ctx, "%lu %lu %lu %lu setXgcdrawable\n",
  212.         XGContextFromGC(DefaultGC(XtDisplay(w),0)),
  213.         XtWindow(w),
  214.         rx, ry);      
  215.  
  216.       DPSPrintf(w -> dviPage.ctx,"\n%d %f @start\n",
  217.         w -> dviPage.pixelsPerInchHoriz,
  218.         scale);
  219.       
  220.       DPSPrintf(w -> dviPage.ctx, " %d %d %d %d %d %d startTexFig\n",
  221.         rawWidth, rawHeight, bbllx, bblly, bburx, bbury);
  222.     }
  223. }
  224.  
  225. void
  226.   psfigPlotfileDPS(w,cp)
  227. DviPageWidget w;
  228. char *cp;
  229. {
  230.     if ( w -> dviPage.ctx  && w -> dviPage.dpsVisible ) 
  231.       {
  232.     while ( cp && *cp && isspace(*cp) ) cp++; /* skip white */
  233.     if (strncmp(cp,"plotfile",8) == 0 ) {
  234.       char *filename;
  235.       FILE *psfile;
  236.       
  237.       cp += 8; /* skip plotfile */
  238.       while ( cp && *cp && isspace(*cp) ) cp++; /* skip white */
  239.       filename = cp;
  240.       while ( cp && *cp && !isspace(*cp) ) cp++; /* skip non-white */
  241.       *cp = 0; /* terminate file name */
  242.       
  243.       if ( (psfile = fopen(filename, "r")) ) {
  244.         char buffer[1024];
  245.         int len;
  246.         
  247.         DPSFlushContext(w -> dviPage.ctx);
  248.         DPSWaitContext(w -> dviPage.ctx);
  249.         
  250.         for (;;) { 
  251.           len = fread(buffer, sizeof(char), 1024, psfile);
  252.           if  ( len == 0 ) break;
  253.           DPSWritePostScript(w -> dviPage.ctx, buffer, len);
  254.         }      
  255.         fclose(psfile);
  256.         DPSFlushContext(w -> dviPage.ctx);
  257.         DPSWaitContext(w -> dviPage.ctx);
  258.       }
  259.     }
  260.     
  261.     DPSPrintf( w -> dviPage.ctx, "\n endTexFig\n");
  262.     
  263. # ifdef USE_GSAVE
  264.     DPSPrintf( w -> dviPage.ctx, "\n restore grestore\n");
  265.     DPSFlushContext(w -> dviPage.ctx);
  266.     DPSWaitContext(w -> dviPage.ctx);
  267. # endif
  268.     
  269. # ifdef ALWAYS_KILL
  270.     DPSDestroySpace( DPSSpaceFromContext( w -> dviPage.ctx ));
  271.     w -> dviPage.ctx = 0;
  272. # endif
  273.     
  274.       }
  275. }
  276.  
  277. void
  278.   psfigEndDPS(w,cp)
  279. DviPageWidget w;
  280. char *cp;
  281. {
  282.   if ( w -> dviPage.ctx  && w -> dviPage.dpsVisible ) { 
  283.     DPSFlushContext( w -> dviPage.ctx );
  284.     DPSWaitContext( w -> dviPage.ctx );
  285.     /* context is destroyed when widget is destroyed */
  286.   }
  287. }
  288.  
  289. int checkDPS()
  290. {
  291.  
  292.   DPSContext ctx;
  293.  
  294.   ctx = XDPSCreateSimpleContext(XtDisplay(TopLevelWidget),
  295.                                 XtWindow(TopLevelWidget),
  296.                                 DefaultGC(XtDisplay(TopLevelWidget), 0),
  297.                                 0, 0,
  298.                                 TextOut, DPSDefaultErrorProc,
  299.                                 NULL);
  300.   if( ctx != NULL ){
  301.      DPSFlushContext( ctx );
  302.      DPSWaitContext( ctx );
  303.      DPSDestroySpace( DPSSpaceFromContext( ctx ));
  304.      return 1;
  305.   }
  306.  
  307.   return 0;
  308.  
  309. }
  310.  
  311.