home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff386.lzh / XLispStat / src3.lzh / Mac / maciviewwindow3.c < prev    next >
C/C++ Source or Header  |  1990-07-30  |  27KB  |  1,036 lines

  1. #ifdef MPWC
  2. #include <Windows.h>
  3. #include <Menus.h>
  4. #include <ToolUtils.h>
  5. #include <Events.h>
  6. #include <Controls.h>
  7. #include <Fonts.h>
  8. #include <Memory.h>
  9. #include <Scrap.h>
  10. #else
  11. #include <WindowMgr.h>
  12. #include <MenuMgr.h>
  13. #include <ToolboxUtil.h>
  14. #include <EventMgr.h>
  15. #include <ControlMgr.h>
  16. #include <FontMgr.h>
  17. #include <ColorToolbox.h>
  18. #endif MPWC
  19.  
  20. #include "StGWWindow.h"
  21. #include "macgraphwindow.h"
  22. #include "stdio.h"
  23.  
  24. /**************************************************************************/
  25. /**                                                                      **/
  26. /**                            Global Variables                          **/
  27. /**                                                                      **/
  28. /**************************************************************************/
  29.  
  30. static CGrafPort CWP;
  31. static CGrafPtr CWorkPort;
  32. static GrafPort WP;
  33. static GrafPtr WorkPort;
  34. static char **WorkRowStarts;
  35. static int WorkPortWidth, WorkPortHeight;
  36.  
  37. static int buffering = FALSE;
  38. static int copying_to_clip = FALSE;
  39. static int bufflevel = 0;
  40.  
  41. static WindowPtr get_port() { return(thePort); }
  42.  
  43. static set_port(port)
  44.     WindowPtr port;
  45. {
  46.   if (port != thePort) SetPort(port);
  47. }
  48.  
  49. reset_clip_rect(gwinfo)
  50.     StGWWinInfo *gwinfo;
  51. {
  52.   WindowPtr w;
  53.   GrafPtr savePort;
  54.   Rect r;
  55.   
  56.   if (gwinfo == nil || (w = gwinfo->window) == nil) return;  
  57.   GetPort(&savePort);
  58.   SetPort(w);
  59.   r = w->portRect;
  60.   r.right -= 15;
  61.   if (gwinfo->hasHscroll) r.bottom -= 15;
  62.   if (gwinfo->clipped) {
  63.     gwinfo->clip_rect.right = min(gwinfo->clip_rect.right, r.right);
  64.     gwinfo->clip_rect.bottom = min(gwinfo->clip_rect.bottom, r.bottom);
  65.     r = gwinfo->clip_rect;
  66.   }
  67.   ClipRect(&r);
  68.   if (buffering) {
  69.     SetDrawingPort(w);
  70.     ClipRect(&r);
  71.   }
  72.   SetPort(savePort);
  73. }
  74.  
  75. /**************************************************************************/
  76. /**                                                                      **/
  77. /**                       Initialization Functions                       **/
  78. /**                                                                      **/
  79. /**************************************************************************/
  80.  
  81. initialize_static_globals()
  82. {
  83.   int portSize;
  84.   long i;  /* long to force row start calculation to be done long */
  85.   
  86.   WorkPort = &WP;
  87.   OpenPort(WorkPort);
  88.   WorkPort->portBits = screenBits;
  89.   portSize = WorkPort->portBits.bounds.bottom 
  90.            - WorkPort->portBits.bounds.top;
  91.   WorkPort->portBits.baseAddr = 
  92.       StCalloc(portSize, WorkPort->portBits.rowBytes);
  93.   if (WorkPort->portBits.baseAddr == nil) {
  94.       StPerror("Buffer allocation failed");
  95.       exit(1);
  96.   }
  97.   WorkPortWidth = WorkPort->portBits.bounds.right 
  98.                 - WorkPort->portBits.bounds.left;
  99.   WorkPortHeight = WorkPort->portBits.bounds.bottom 
  100.                  - WorkPort->portBits.bounds.top;
  101.   WorkRowStarts = (char **) StCalloc(sizeof(char *), portSize);
  102.   for (i = 0; i < portSize; i++)
  103.     WorkRowStarts[i] = WorkPort->portBits.baseAddr
  104.                      + i * WorkPort->portBits.rowBytes;
  105.   MakeSymbols();
  106.  
  107.   CWorkPort = (CGrafPtr) WorkPort;
  108.   if (StScreenHasColor()) {
  109.     char *p;
  110.     Rect r;
  111.     struct row_bytes {
  112.       unsigned int flags : 3;
  113.       unsigned int data  : 13;
  114.     } *rowBytes;
  115.  
  116.     CWorkPort = &CWP;
  117.     OpenCPort(CWorkPort);
  118.     
  119.     r = (*CWorkPort->portPixMap)->bounds;
  120.     rowBytes = (struct row_bytes *) &(*CWorkPort->portPixMap)->rowBytes;
  121.     portSize = r.bottom - r.top;
  122.     
  123.     if (FreeMem() < portSize + 1000000) {
  124.       stdputstr("not enough memory to allocate color port\n");
  125.       CWorkPort = (CGrafPtr) WorkPort;
  126.     }
  127.     else {
  128.       HLock((Handle) *CWorkPort->portPixMap);
  129.       /* I do't know why I need this two-step business */
  130.       p = StCalloc(portSize, rowBytes->data);
  131.       (*CWorkPort->portPixMap)->baseAddr = p;
  132.       HUnlock((Handle) *CWorkPort->portPixMap);
  133.     }
  134.   }
  135. }
  136.  
  137. adjust_graph_workport(gwinfo)
  138.     StGWWinInfo *gwinfo;
  139. {
  140.   GrafPtr savePort, workPort;
  141.   WindowPtr w;
  142.   
  143.   if (buffering && gwinfo != nil && (w = gwinfo->window) != nil) {
  144.     workPort = (StGWUseColor(gwinfo)) ? (GrafPtr) CWorkPort : WorkPort;
  145.     GetPort(&savePort);
  146.     SetPort(workPort);
  147.     if (gwinfo->lineType != 0) PenPat(gray);
  148.     else PenPat(black);
  149.     PenMode(w->pnMode);
  150.     TextMode(w->txMode);
  151.     PenSize(w->pnSize.h, w->pnSize.h);
  152.     set_fore_color(gwinfo);
  153.     set_back_color(gwinfo);
  154.     SetPort(savePort);
  155.   }
  156. }
  157.  
  158. /**************************************************************************/
  159. /**                                                                      **/
  160. /**                  Line and Rectangle Drawing Functions                **/
  161. /**                                                                      **/
  162. /**************************************************************************/
  163.  
  164. static SetDrawingPort(w)
  165.      WindowPtr w;
  166. {
  167.   StGWWinInfo *gwinfo = (StGWWinInfo *) GetWRefCon(w);
  168.  
  169.   set_port((buffering) ? ((gwinfo->use_color) ? (GrafPtr) CWorkPort: WorkPort) : w);
  170. }
  171.  
  172. static draw_object(gwinfo, what, how, a, b, c, d)
  173.     StGWWinInfo *gwinfo;
  174.     int what, how, a, b, c, d;
  175. {
  176.   GrafPtr savePort;
  177.   Rect r;
  178.   WindowPtr w;
  179.   
  180.   if (gwinfo == nil || (w = gwinfo->window) == nil) return;
  181.   savePort = get_port();
  182.   SetDrawingPort(w);
  183.     
  184.   switch (what) {
  185.   case 'L': MoveTo(a, b); LineTo(c, d); break;
  186.   case 'P': MoveTo(a, b); Line(0, 0); break;
  187.   case 'R':
  188.     SetRect(&r, a, b, a + c, b + d);
  189.     switch (how) {
  190.     case 'E': EraseRect(&r); break;
  191.     case 'F': FrameRect(&r); break;
  192.     case 'P': PaintRect(&r); break;
  193.     }
  194.     break;
  195.   case 'O':
  196.     SetRect(&r, a, b, a + c, b + d);
  197.     switch (how) {
  198.     case 'E': EraseOval(&r); break;
  199.     case 'F': FrameOval(&r); break;
  200.     case 'P': PaintOval(&r); break;
  201.     }
  202.     break;
  203.   }  
  204.   set_port(savePort);
  205. }
  206.  
  207. static draw_arc(gwinfo, how, a, b, c, d, angle1, angle2)
  208.     StGWWinInfo *gwinfo;
  209.     int how, a, b, c, d;
  210.     double angle1, angle2;
  211. {
  212.   GrafPtr savePort;
  213.   Rect r;
  214.   int a1, a2;
  215.   WindowPtr w;
  216.   
  217.   if (gwinfo == nil || (w = gwinfo->window) == nil) return;
  218.   savePort = get_port();
  219.   SetDrawingPort(w);
  220.     
  221.   SetRect(&r, a, b, a + c, b + d);
  222.   a1 = 90 - angle1;
  223.   a2 = -angle2;
  224.   switch (how) {
  225.   case 'E': EraseArc(&r, a1, a2); break;
  226.   case 'F': FrameArc(&r, a1, a2); break;
  227.   case 'P': PaintArc(&r, a1, a2); break;
  228.   }
  229.   set_port(savePort);
  230. }
  231.  
  232. static draw_poly(gwinfo, how, n, p, from_origin)
  233.     StGWWinInfo *gwinfo;
  234.     int how, n, from_origin;
  235.     short *p;
  236. {
  237.   GrafPtr savePort;
  238.   int i;
  239.   WindowPtr w;
  240.   PolyHandle poly;
  241.   
  242.   if (gwinfo == nil || (w = gwinfo->window) == nil || n <= 0) return;
  243.   savePort = get_port();
  244.   SetDrawingPort(w);
  245.   
  246.   poly = OpenPoly();
  247.   MoveTo((int) p[0], (int) p[1]);
  248.   for (i = 1; i < n; i++) {
  249.     if (from_origin) LineTo((int) p[2 * i], (int) p[2 * i + 1]);
  250.     else Line((int) p[2 * i], (int) p[2 * i + 1]);
  251.   }
  252.   ClosePoly();
  253.   switch (how) {
  254.   case 'E': ErasePoly(poly); break;
  255.   case 'F': FramePoly(poly); break;
  256.   case 'P': PaintPoly(poly); break;
  257.   }
  258.   KillPoly(poly);
  259.   set_port(savePort);
  260. }    
  261.   
  262. StGWDrawLine(gwinfo, x1, y1, x2, y2)
  263.     StGWWinInfo *gwinfo;
  264.     int x1, y1, x2, y2;
  265. {
  266.   draw_object(gwinfo, 'L', '0', x1, y1, x2, y2);
  267. }
  268.  
  269. StGWDrawPoint(gwinfo, x, y)
  270.     StGWWinInfo *gwinfo;
  271.     int x, y;
  272. {
  273.   draw_object(gwinfo, 'P', '0', x, y, 0, 0);
  274. }
  275.  
  276. StGWEraseRect(gwinfo, left, top, width, height)
  277.     StGWWinInfo *gwinfo;
  278.     int left, top, width, height;
  279. {
  280.   draw_object(gwinfo, 'R', 'E', left, top, width, height);
  281. }
  282.  
  283. StGWFrameRect(gwinfo, left, top, width, height)
  284.     StGWWinInfo *gwinfo;
  285.     int left, top, width, height;
  286. {
  287.   draw_object(gwinfo, 'R', 'F', left, top, width, height);
  288.  
  289. StGWPaintRect(gwinfo, left, top, width, height)
  290.     StGWWinInfo *gwinfo;
  291.     int left, top, width, height;
  292. {
  293.   draw_object(gwinfo, 'R', 'P', left, top, width, height);
  294. }
  295.  
  296. StGWEraseOval(gwinfo, left, top, width, height)
  297.     StGWWinInfo *gwinfo;
  298.     int left, top, width, height;
  299. {
  300.   draw_object(gwinfo, 'O', 'E', left, top, width, height);
  301. }
  302.  
  303. StGWFrameOval(gwinfo, left, top, width, height)
  304.     StGWWinInfo *gwinfo;
  305.     int left, top, width, height;
  306. {
  307.   draw_object(gwinfo, 'O', 'F', left, top, width, height);
  308. }
  309.  
  310. StGWPaintOval(gwinfo, left, top, width, height)
  311.     StGWWinInfo *gwinfo;
  312.     int left, top, width, height;
  313. {
  314.   draw_object(gwinfo, 'O', 'P', left, top, width, height);
  315. }
  316.  
  317. StGWEraseArc(gwinfo, left, top, width, height, angle1, angle2)
  318.     StGWWinInfo *gwinfo;
  319.     int left, top, width, height;
  320.     double angle1, angle2;
  321. {
  322.   draw_arc(gwinfo, 'E', left, top, width, height, angle1, angle2);
  323. }
  324.  
  325. StGWFrameArc(gwinfo, left, top, width, height, angle1, angle2)
  326.     StGWWinInfo *gwinfo;
  327.     int left, top, width, height;
  328.     double angle1, angle2;
  329. {
  330.   draw_arc(gwinfo, 'F', left, top, width, height, angle1, angle2);
  331. }
  332.  
  333. StGWPaintArc(gwinfo, left, top, width, height, angle1, angle2)
  334.     StGWWinInfo *gwinfo;
  335.     int left, top, width, height;
  336.     double angle1, angle2;
  337. {
  338.   draw_arc(gwinfo, 'P', left, top, width, height, angle1, angle2);
  339. }
  340.  
  341. StGWErasePoly(gwinfo, n, p, from_origin)
  342.     StGWWinInfo *gwinfo;
  343.     int n, from_origin;
  344.     short *p;
  345. {
  346.   draw_poly(gwinfo, 'E', n, p, from_origin);
  347. }
  348.  
  349. StGWFramePoly(gwinfo, n, p, from_origin)
  350.     StGWWinInfo *gwinfo;
  351.     int n, from_origin;
  352.     short *p;
  353. {
  354.   draw_poly(gwinfo, 'F', n, p, from_origin);
  355. }
  356.  
  357. StGWPaintPoly(gwinfo, n, p, from_origin)
  358.     StGWWinInfo *gwinfo;
  359.     int n, from_origin;
  360.     short *p;
  361. {
  362.   draw_poly(gwinfo, 'P', n, p, from_origin);
  363. }
  364.  
  365. /**************************************************************************/
  366. /**                                                                      **/
  367. /**                            Text Functions                            **/
  368. /**                                                                      **/
  369. /**************************************************************************/
  370.  
  371. static text_size(gwinfo, ascent)
  372.     StGWWinInfo *gwinfo;
  373.     int ascent;
  374. {
  375.   WindowPtr w;
  376.   GrafPtr savePort;
  377.   FontInfo info;
  378.   
  379.   if (gwinfo == nil || (w = gwinfo->window) == nil)
  380.       w = (StGWUseColor(gwinfo)) ? (WindowPtr) CWorkPort : (WindowPtr) WorkPort;
  381.  
  382.   savePort = get_port();
  383.   set_port(w);
  384.     
  385.   GetFontInfo(&info);
  386.   
  387.   set_port(savePort);
  388.   return((ascent) ? info.ascent : info.descent);
  389. }
  390.  
  391. StGWTextAscent(gwinfo) StGWWinInfo *gwinfo;  { return(text_size(gwinfo, TRUE));  }
  392. StGWTextDescent(gwinfo) StGWWinInfo *gwinfo; { return(text_size(gwinfo, FALSE)); }
  393.  
  394. StGWTextWidth(gwinfo, text)
  395.     StGWWinInfo *gwinfo;
  396.     char *text;
  397. {
  398.   WindowPtr w;
  399.   GrafPtr savePort;
  400.   int string_width;
  401.   
  402.   if (gwinfo == nil || (w = gwinfo->window) == nil)
  403.       w = (StGWUseColor(gwinfo)) ? (WindowPtr) CWorkPort : (WindowPtr) WorkPort;
  404.  
  405.   savePort = get_port();
  406.   set_port(w);
  407.     
  408.   CtoPstr(text);
  409.   string_width = StringWidth(text);
  410.   PtoCstr(text);
  411.   
  412.   set_port(savePort);
  413.   return(string_width);
  414. }
  415.  
  416. StGWDrawString(gwinfo, s, x, y)
  417.     StGWWinInfo *gwinfo;
  418.     char *s;
  419.     int x, y;
  420. {
  421.   GrafPtr savePort;
  422.   WindowPtr w;
  423.   
  424.   if (s == nil || gwinfo == nil || (w = gwinfo->window) == nil) return;
  425.   
  426.   savePort = get_port();
  427.   SetDrawingPort(w);
  428.     
  429.   MoveTo(x, y);
  430.   CtoPstr(s);
  431.   DrawString(s);
  432.   PtoCstr(s);
  433.   
  434.   set_port(savePort);
  435. }
  436.  
  437. StGWDrawText(gwinfo, text, x, y, h, v)
  438.     StGWWinInfo *gwinfo;
  439.     char *text;
  440.     int x, y, h, v;
  441. {
  442.   int FontAscent, string_width;
  443.  
  444.   if (text == nil || gwinfo == nil) return;
  445.   
  446.   FontAscent = StGWTextAscent(gwinfo);
  447.   string_width = StGWTextWidth(gwinfo, text);
  448.  
  449.   if (v == 1) y += FontAscent;
  450.   if (h == 1) x -= string_width / 2;
  451.   if (h == 2) x -= string_width;
  452.  
  453.   StGWDrawString(gwinfo, text, x, y);
  454. }
  455.  
  456. static DrawCharUp(w, myChar, x, y)
  457.     WindowPtr w;
  458.     char myChar;
  459.     int x, y;
  460. {
  461.   static GrafPort gp;
  462.   static GrafPtr charPort;
  463.   static is_open = FALSE;
  464.   char myImage[32], myTarget[32];
  465.   BitMap myMap, saveBits;
  466.   GrafPtr savePort;
  467.   Rect r;
  468.   
  469.   register int i, j;
  470.   
  471.   savePort = get_port();
  472.   
  473.   if (! is_open) {
  474.     charPort = &gp;
  475.     OpenPort(charPort);
  476.     is_open = TRUE;
  477.   }
  478.   set_port(charPort);
  479.   
  480.   charPort->txFont = w->txFont;
  481.   charPort->txFace = w->txFace;
  482.   charPort->txMode = w->txMode;
  483.   charPort->txSize = w->txSize;
  484.   charPort->spExtra = w->spExtra;
  485.   
  486.   myMap.baseAddr = myImage;
  487.   myMap.rowBytes = 2;
  488.   SetRect(&myMap.bounds, 0, 0, 15, 15);
  489.   
  490.   for (i = 0; i < 32; i++) {
  491.     myImage[i] = '\0';
  492.     myTarget[i] = '\0';
  493.   }
  494.   
  495.   saveBits = charPort->portBits;
  496.   charPort->portBits = myMap;
  497.   MoveTo(3, 12);
  498.   DrawChar(myChar);
  499.   charPort->portBits = saveBits;
  500.   set_port(savePort);
  501.   
  502.   for (i = 0; i < 16; i++)
  503.     for (j = 0; j < 16; j++)
  504.       if (BitTst(myImage, 16 * i + j)) BitSet(myTarget, i + (16 - j) * 16);
  505.   
  506.   r = myMap.bounds;
  507.   OffsetRect(&r, x - 12, y + 3 - (r.bottom - r.top));
  508.   myMap.baseAddr = myTarget;
  509.   
  510.   SetDrawingPort(w);
  511.   CopyBits(&myMap, &thePort->portBits, &myMap.bounds,  &r, w->txMode, nil);
  512.   set_port(savePort);
  513. }
  514.  
  515. StGWDrawStringUp(gwinfo, s, x, y)
  516.     StGWWinInfo *gwinfo;
  517.     char *s;
  518.     int x, y;
  519. {
  520.   WindowPtr w;
  521.   char str[2];
  522.   int n;
  523.   
  524.   if (s == nil || gwinfo == nil || (w = gwinfo->window) == nil) return;
  525.   str[1] = '\0';
  526.   
  527.   for (n = strlen(s); n > 0; n--, s++) {
  528.       DrawCharUp(w, *s, x, y);
  529.       str[0] = *s;
  530.       y -= StGWTextWidth(gwinfo, str);
  531.   }
  532. }
  533.  
  534. StGWDrawTextUp(gwinfo, text, x, y, h, v)
  535.     StGWWinInfo *gwinfo;
  536.      char *text;
  537.      int x, y, h, v;
  538. {
  539.   int FontAscent, string_width;
  540.  
  541.   if (text == nil || gwinfo == nil) return;
  542.   
  543.   FontAscent = StGWTextAscent(gwinfo);
  544.   string_width = StGWTextWidth(gwinfo, text);
  545.  
  546.   if (v == 1) x += FontAscent;
  547.   if (h == 1) y += string_width / 2;
  548.   if (h == 2) y += string_width;
  549.  
  550.   StGWDrawStringUp(gwinfo, text, x, y);
  551. }
  552.  
  553. /**************************************************************************/
  554. /**                                                                      **/
  555. /**                           Symbol Functions                           **/
  556. /**                                                                      **/
  557. /**************************************************************************/
  558.  
  559. #define NUMSYMBOLS 18
  560. #define SYMROWS 5
  561.  
  562. typedef struct {
  563.   unsigned bit0 :1;
  564.   unsigned bit1 :1;
  565.   unsigned bit2 :1;
  566.   unsigned bit3 :1;
  567.   unsigned bit4 :1;
  568. } SymBits;
  569.  
  570. typedef struct {
  571.   BitMap map;
  572.   int left, top;
  573.   short image[SYMROWS];
  574.   long refcon;
  575. } Symbol;
  576.  
  577. static Symbol Symbols[NUMSYMBOLS];
  578.  
  579. StGWSetSymRefCon(index, rc)
  580.     unsigned int index;
  581.     long rc;
  582. {
  583.   if (index < NUMSYMBOLS) Symbols[index].refcon = rc;
  584. }
  585.  
  586. long StGWGetSymRefCon(index)
  587.     unsigned int index;
  588. {    
  589.   if (index < NUMSYMBOLS) return(Symbols[index].refcon);
  590.   else return(nil);
  591. }
  592.  
  593. static InitSymbol(sym, left, top, width, height)
  594.      int sym, left, top, width, height;
  595. {
  596.   SetRect(&Symbols[sym].map.bounds, 0, 0, width, height);
  597.   Symbols[sym].map.rowBytes = 2;
  598.   Symbols[sym].map.baseAddr = (Ptr) &Symbols[sym].image;
  599.   Symbols[sym].left = left;
  600.   Symbols[sym].top = top;
  601. }
  602.  
  603. StGWGetSymbolSize(sym, width, height)
  604.     int sym, *width, *height;
  605. {
  606.   *width = Symbols[sym].map.bounds.right;
  607.   *height = Symbols[sym].map.bounds.bottom;
  608. }
  609.  
  610. static SetSymbolData(sym, row, bit0, bit1, bit2, bit3, bit4)
  611.      int sym, row;
  612.      int bit0, bit1, bit2, bit3, bit4;
  613. {
  614.   SymBits *d = (SymBits *) &(Symbols[sym].image[row]);
  615.   d->bit0 = bit0;
  616.   d->bit1 = bit1;
  617.   d->bit2 = bit2;
  618.   d->bit3 = bit3;
  619.   d->bit4 = bit4;
  620. }
  621.  
  622. static MakeSymbols()
  623. {
  624.   InitSymbol(0, 0, 0, 2, 2);
  625.   SetSymbolData(0, 0, 1, 0, 0, 0, 0);
  626.   SetSymbolData(0, 1, 0, 0, 0, 0, 0);
  627.   SetSymbolData(0, 2, 0, 0, 0, 0, 0);
  628.   SetSymbolData(0, 3, 0, 0, 0, 0, 0);
  629.   SetSymbolData(0, 4, 0, 0, 0, 0, 0);
  630.  
  631.   InitSymbol(1, 0, 0, 2, 2);
  632.   SetSymbolData(1, 0, 1, 1, 0, 0, 0);
  633.   SetSymbolData(1, 1, 0, 0, 0, 0, 0);
  634.   SetSymbolData(1, 2, 0, 0, 0, 0, 0);
  635.   SetSymbolData(1, 3, 0, 0, 0, 0, 0);
  636.   SetSymbolData(1, 4, 0, 0, 0, 0, 0);
  637.  
  638.   InitSymbol(2, 0, 0, 2, 2);
  639.   SetSymbolData(2, 0, 1, 1, 0, 0, 0);
  640.   SetSymbolData(2, 1, 1, 0, 0, 0, 0);
  641.   SetSymbolData(2, 2, 0, 0, 0, 0, 0);
  642.   SetSymbolData(2, 3, 0, 0, 0, 0, 0);
  643.   SetSymbolData(2, 4, 0, 0, 0, 0, 0);
  644.  
  645.   InitSymbol(3, 0, 0, 2, 2);
  646.   SetSymbolData(3, 0, 1, 1, 0, 0, 0);
  647.   SetSymbolData(3, 1, 1, 1, 0, 0, 0);
  648.   SetSymbolData(3, 2, 0, 0, 0, 0, 0);
  649.   SetSymbolData(3, 3, 0, 0, 0, 0, 0);
  650.   SetSymbolData(3, 4, 0, 0, 0, 0, 0);
  651.  
  652.   InitSymbol(4, 2, 2, 4, 4);
  653.   SetSymbolData(4, 0, 0, 1, 1, 0, 0);
  654.   SetSymbolData(4, 1, 1, 0, 0, 1, 0);
  655.   SetSymbolData(4, 2, 1, 0, 0, 1, 0);
  656.   SetSymbolData(4, 3, 0, 1, 1, 0, 0);
  657.   SetSymbolData(4, 4, 0, 0, 0, 0, 0);
  658.  
  659.   InitSymbol(5, 2, 2, 4, 4);
  660.   SetSymbolData(5, 0, 0, 1, 1, 0, 0);
  661.   SetSymbolData(5, 1, 1, 1, 1, 1, 0);
  662.   SetSymbolData(5, 2, 1, 1, 1, 1, 0);
  663.   SetSymbolData(5, 3, 0, 1, 1, 0, 0);
  664.   SetSymbolData(5, 4, 0, 0, 0, 0, 0);
  665.  
  666.   InitSymbol(6, 3, 3, 5, 5);
  667.   SetSymbolData(6, 0, 0, 0, 1, 0, 0);
  668.   SetSymbolData(6, 1, 0, 1, 0, 1, 0);
  669.   SetSymbolData(6, 2, 1, 0, 0, 0, 1);
  670.   SetSymbolData(6, 3, 0, 1, 0, 1, 0);
  671.   SetSymbolData(6, 4, 0, 0, 1, 0, 0);
  672.  
  673.   InitSymbol(7, 3, 3, 5, 5);
  674.   SetSymbolData(7, 0, 0, 0, 1, 0, 0);
  675.   SetSymbolData(7, 1, 0, 1, 1, 1, 0);
  676.   SetSymbolData(7, 2, 1, 1, 1, 1, 1);
  677.   SetSymbolData(7, 3, 0, 1, 1, 1, 0);
  678.   SetSymbolData(7, 4, 0, 0, 1, 0, 0);
  679.  
  680.   InitSymbol(8, 3, 3, 5, 5);
  681.   SetSymbolData(8, 0, 0, 0, 1, 0, 0);
  682.   SetSymbolData(8, 1, 0, 0, 1, 0, 0);
  683.   SetSymbolData(8, 2, 1, 1, 1, 1, 1);
  684.   SetSymbolData(8, 3, 0, 0, 1, 0, 0);
  685.   SetSymbolData(8, 4, 0, 0, 1, 0, 0);
  686.  
  687.   InitSymbol(9, 3, 3, 5, 5);
  688.   SetSymbolData(9, 0, 0, 1, 1, 1, 0);
  689.   SetSymbolData(9, 1, 1, 0, 1, 0, 1);
  690.   SetSymbolData(9, 2, 1, 1, 1, 1, 1);
  691.   SetSymbolData(9, 3, 1, 0, 1, 0, 1);
  692.   SetSymbolData(9, 4, 0, 1, 1, 1, 0);
  693.  
  694.   InitSymbol(10, 2, 2, 4, 4);
  695.   SetSymbolData(10, 0, 1, 1, 1, 1, 0);
  696.   SetSymbolData(10, 1, 1, 0, 0, 1, 0);
  697.   SetSymbolData(10, 2, 1, 0, 0, 1, 0);
  698.   SetSymbolData(10, 3, 1, 1, 1, 1, 0);
  699.   SetSymbolData(10, 4, 0, 0, 0, 0, 0);
  700.  
  701.   InitSymbol(11, 2, 2, 4, 4);
  702.   SetSymbolData(11, 0, 1, 1, 1, 1, 0);
  703.   SetSymbolData(11, 1, 1, 1, 1, 1, 0);
  704.   SetSymbolData(11, 2, 1, 1, 1, 1, 0);
  705.   SetSymbolData(11, 3, 1, 1, 1, 1, 0);
  706.   SetSymbolData(11, 4, 0, 0, 0, 0, 0);
  707.  
  708.   InitSymbol(12, 3, 3, 5, 5);
  709.   SetSymbolData(12, 0, 0, 1, 1, 1, 0);
  710.   SetSymbolData(12, 1, 1, 0, 0, 0, 1);
  711.   SetSymbolData(12, 2, 1, 0, 0, 0, 1);
  712.   SetSymbolData(12, 3, 0, 1, 0, 1, 0);
  713.   SetSymbolData(12, 4, 0, 0, 1, 0, 0);
  714.  
  715.   InitSymbol(13, 3, 3, 5, 5);
  716.   SetSymbolData(13, 0, 0, 1, 1, 1, 0);
  717.   SetSymbolData(13, 1, 1, 1, 1, 1, 1);
  718.   SetSymbolData(13, 2, 1, 1, 1, 1, 1);
  719.   SetSymbolData(13, 3, 0, 1, 1, 1, 0);
  720.   SetSymbolData(13, 4, 0, 0, 1, 0, 0);
  721.  
  722.   InitSymbol(14, 3, 3, 5, 5);
  723.   SetSymbolData(14, 0, 0, 0, 1, 0, 0);
  724.   SetSymbolData(14, 1, 0, 1, 0, 1, 0);
  725.   SetSymbolData(14, 2, 1, 0, 0, 0, 1);
  726.   SetSymbolData(14, 3, 1, 0, 0, 0, 1);
  727.   SetSymbolData(14, 4, 0, 1, 1, 1, 0);
  728.  
  729.   InitSymbol(15, 3, 3, 5, 5);
  730.   SetSymbolData(15, 0, 0, 0, 1, 0, 0);
  731.   SetSymbolData(15, 1, 0, 1, 1, 1, 0);
  732.   SetSymbolData(15, 2, 1, 1, 1, 1, 1);
  733.   SetSymbolData(15, 3, 1, 1, 1, 1, 1);
  734.   SetSymbolData(15, 4, 0, 1, 1, 1, 0);
  735.  
  736.   InitSymbol(16, 3, 3, 5, 5);
  737.   SetSymbolData(16, 0, 1, 0, 0, 0, 1);
  738.   SetSymbolData(16, 1, 0, 1, 0, 1, 0);
  739.   SetSymbolData(16, 2, 0, 0, 1, 0, 0);
  740.   SetSymbolData(16, 3, 0, 1, 0, 1, 0);
  741.   SetSymbolData(16, 4, 1, 0, 0, 0, 1);
  742.  
  743.   InitSymbol(17, 3, 3, 5, 5);
  744.   SetSymbolData(17, 0, 1, 1, 0, 1, 1);
  745.   SetSymbolData(17, 1, 1, 1, 0, 1, 1);
  746.   SetSymbolData(17, 2, 0, 0, 1, 0, 0);
  747.   SetSymbolData(17, 3, 1, 1, 0, 1, 1);
  748.   SetSymbolData(17, 4, 1, 1, 0, 1, 1);
  749. }
  750.  
  751. StGWDrawSymbol(gwinfo, sym, x, y)
  752.     StGWWinInfo *gwinfo;
  753.     int sym, x, y;
  754. {
  755.   WindowPtr w;
  756.   GrafPtr savePort;
  757.   Rect r;
  758.   
  759.   if (gwinfo == nil || (w = gwinfo->window) == nil) return;
  760.   
  761.   savePort = get_port();
  762.   SetDrawingPort(w);
  763.   
  764.   if (! copying_to_clip && buffering && sym < 4 && ! gwinfo->use_color) {
  765.     BufferMarkPoint(x - gwinfo->view_h, y - gwinfo->view_v, 
  766.                     sym, gwinfo->drawColor);
  767.     return;
  768.   }
  769.  
  770.   if (sym < 0 || sym >= NUMSYMBOLS) return;
  771.   x -= Symbols[sym].left;
  772.   y -= Symbols[sym].top;
  773.   r = Symbols[sym].map.bounds;
  774.   OffsetRect(&r, x, y);
  775.   
  776.   CopyBits(&Symbols[sym].map, &thePort->portBits,
  777.            &Symbols[sym].map.bounds, &r, gwinfo->symbolMode, nil);
  778.            
  779.   set_port(savePort);
  780. }
  781.  
  782. static BufferMarkPoint(x, y, sym, color)
  783.     unsigned x, y, sym, color;
  784. {
  785.   if (x >= WorkPortWidth || y >= WorkPortHeight) return;
  786.   if (color != 0) {
  787.     BitSet(WorkRowStarts[y], x);     if (sym == 0) return;
  788.     BitSet(WorkRowStarts[y], x + 1); if (sym == 1) return;
  789.     BitSet(WorkRowStarts[y + 1], x); if (sym == 2) return;
  790.     BitSet(WorkRowStarts[y + 1], x + 1);
  791.   }
  792.   else {
  793.     BitClr(WorkRowStarts[y], x);     if (sym == 0) return;
  794.     BitClr(WorkRowStarts[y], x + 1); if (sym == 1) return;
  795.     BitClr(WorkRowStarts[y + 1], x); if (sym == 2) return;
  796.     BitClr(WorkRowStarts[y + 1], x + 1);
  797.   }  
  798. }
  799.  
  800. StGWReplaceSymbol(gwinfo, oldsym, newsym, x, y)
  801.     StGWWinInfo *gwinfo;
  802.     unsigned oldsym, newsym;
  803.     int x, y;
  804. {
  805.   int oldwidth, oldheight, newwidth, newheight;
  806.   
  807.   if (oldsym >= NUMSYMBOLS || newsym >= NUMSYMBOLS) return;
  808.   
  809.   StGWGetSymbolSize(oldsym, &oldwidth, &oldheight);
  810.   StGWGetSymbolSize(newsym, &newwidth, &newheight);
  811.   if (oldwidth > newwidth || oldheight > newheight)
  812.     StGWEraseRect(gwinfo, x - Symbols[oldsym].left, y - Symbols[oldsym].top,
  813.                   oldwidth, oldheight);
  814.   StGWDrawSymbol(gwinfo, newsym, x, y);
  815. }
  816.  
  817. /**************************************************************************/
  818. /**                                                                      **/
  819. /**                           Bitmap Functions                           **/
  820. /**                                                                      **/
  821. /**************************************************************************/
  822.  
  823. static make_bitmap(width, height, image, pbm)
  824.     int width, height;
  825.     char *image;
  826.     BitMap *pbm;
  827. {
  828.   int i, j;
  829.   char *rowdata;
  830.   
  831.   pbm->rowBytes = 2 * ((width % 16 == 0) ? width / 16 : width / 16 + 1);
  832.   if (pbm->rowBytes * height <= 0) return(FALSE);
  833.   
  834.   pbm->baseAddr = StCalloc(pbm->rowBytes * height, 1);
  835.   if (pbm->baseAddr == nil) return(FALSE);
  836.   
  837.   for (i = 0; i < height; i++) {
  838.     rowdata = pbm->baseAddr + i * pbm->rowBytes;
  839.     for (j = 0; j < width; j++)
  840.       if (image[i * width + j] != 0) BitSet(rowdata, j);
  841.   }
  842.   pbm->bounds.left = 0; pbm->bounds.top = 0;
  843.   pbm->bounds.right = width; pbm->bounds.bottom = height;
  844.   return(TRUE);
  845. }
  846.  
  847. static free_bitmap(pbm)
  848.     BitMap *pbm;
  849. {
  850.   if (pbm->baseAddr != nil) StFree(pbm->baseAddr);
  851. }
  852.     
  853. StGWDrawBitmap(gwinfo, left, top, width, height, image)
  854.     StGWWinInfo *gwinfo;
  855.     int left, top, width, height;
  856.     char *image;
  857. {
  858.   WindowPtr w;
  859.   BitMap bm;
  860.   GrafPtr savePort;
  861.   Rect r;
  862.   
  863.   if (gwinfo == nil || (w = gwinfo->window) == nil) return;
  864.   
  865.   savePort = get_port();
  866.   SetDrawingPort(w);
  867.   if (make_bitmap(width, height, image, &bm)) {
  868.     r = bm.bounds;
  869.     OffsetRect(&r, left, top);
  870.     CopyBits(&bm, &thePort->portBits, &bm.bounds, &r, gwinfo->symbolMode, nil);
  871.     free_bitmap(&bm);
  872.   }
  873.   set_port(savePort);
  874. }
  875.  
  876. /**************************************************************************/
  877. /**                                                                      **/
  878. /**                         Buffering Functions                          **/
  879. /**                                                                      **/
  880. /**************************************************************************/
  881.  
  882. StGWStartBuffering(gwinfo)
  883.     StGWWinInfo *gwinfo;
  884. {
  885.   WindowPtr w;
  886.   GrafPtr savePort;
  887.   Rect r;
  888.  
  889.   if (gwinfo == nil || (w = gwinfo->window) == nil) return;
  890.   
  891.   bufflevel++;
  892.   if (buffering) return;
  893.   buffering = TRUE;
  894.   
  895.   GetPort(&savePort);
  896.   SetPort((StGWUseColor(gwinfo)) ? (GrafPtr) CWorkPort : WorkPort);
  897.  
  898.   set_fore_color(gwinfo);
  899.   set_back_color(gwinfo);
  900.   if (gwinfo->lineType != 0) PenPat(gray);
  901.   else PenPat(black);
  902.   
  903.   PenMode(w->pnMode);
  904.   TextFont(w->txFont);
  905.   TextFace(w->txFace);
  906.   TextMode(w->txMode);
  907.   TextSize(w->txSize);
  908.   SpaceExtra(w->spExtra);
  909.   SetOrigin(gwinfo->view_h, gwinfo->view_v);
  910.   r = w->portRect;
  911.   r.right -= 15;
  912.   if (gwinfo->hasHscroll) r.bottom -= 15;
  913.   ClipRect(&r);
  914.   CopyRgn(w->visRgn, thePort->visRgn);
  915.   CopyRgn(w->clipRgn, thePort->clipRgn);
  916.   SetPort(savePort);
  917. }
  918.  
  919. StGWBufferToScreen(gwinfo, left, top, width, height)
  920.     StGWWinInfo *gwinfo;
  921.     int left, top, width, height;
  922. {
  923.   WindowPtr w;
  924.   GrafPtr savePort, workPort;
  925.   Rect r;
  926.  
  927.   if (gwinfo == nil || (w = gwinfo->window) == nil) return;
  928.   
  929.   if (bufflevel > 0) bufflevel--;
  930.   if (bufflevel > 0) return;
  931.   if (! buffering) return;
  932.   
  933.   buffering = FALSE;  
  934.   workPort = (StGWUseColor(gwinfo)) ? (GrafPtr) CWorkPort : WorkPort;
  935.   
  936.   GetPort(&savePort);
  937.   SetPort(w);
  938.   ForeColor(blackColor);
  939.   BackColor(whiteColor);
  940.   SetRect(&r, left, top, left + width, top + height);
  941.   if (SectRect(&r, &w->portRect, &r))
  942.     CopyBits(&workPort->portBits,&w->portBits, &r, &r, srcCopy, nil);
  943.   set_fore_color(gwinfo);
  944.   set_back_color(gwinfo);
  945.   SetPort(savePort);
  946. }
  947.  
  948. /**************************************************************************/
  949. /**                                                                      **/
  950. /**                         Miscelaneous Functions                       **/
  951. /**                                                                      **/
  952. /**************************************************************************/
  953.  
  954. extern char buf[];
  955.  
  956. StGWCopyToClip(gwinfo)
  957.     StGWWinInfo *gwinfo;
  958. {
  959.   make_picture(gwinfo, nil);
  960. }
  961.  
  962. StGWDumpImage(gwinfo, fname, scale)
  963.     StGWWinInfo *gwinfo;
  964.     char *fname;
  965.     double scale;
  966. {
  967.   make_picture(gwinfo, fname);
  968. }
  969.  
  970. static make_picture(gwinfo, fname)
  971.     StGWWinInfo *gwinfo;
  972.     char *fname;
  973. {
  974.   PicHandle pic;
  975.   Rect r;
  976.   long result, mytype;
  977.   GrafPtr savePort, workPort;
  978.   char *object;
  979.   WindowPtr w;
  980. /*  int vRefNum, i;
  981.   FILE *fptr; */
  982.   
  983.   if (gwinfo == nil || (w = gwinfo->window) == nil) return;
  984.   
  985.   object = (char *) StGWGetObject(gwinfo);
  986.   workPort = (StGWUseColor(gwinfo)) ? (GrafPtr) CWorkPort : WorkPort;
  987.  
  988.   StGWStartBuffering(gwinfo);
  989.   r = w->portRect;
  990.   r.right -= 15;
  991.   if (StGWHasHscroll(gwinfo)) r.bottom -= 15;
  992.   
  993.   copying_to_clip = TRUE;
  994.   GetPort(&savePort);
  995.   SetPort(workPort);
  996.   pic = OpenPicture(&r);
  997.   SetPort(savePort);
  998.   
  999.   StGWObRedraw(object);
  1000.  
  1001.   GetPort(&savePort);
  1002.   SetPort(workPort);
  1003.   ClosePicture();
  1004.   SetPort(savePort);
  1005.   
  1006.   StGWBufferToScreen(gwinfo, 0, 0, 0, 0);
  1007.   
  1008.   if (fname == nil) {
  1009.     ZeroScrap();
  1010.     mytype = 'PICT';
  1011.     HLock((Handle) pic);
  1012.     result = PutScrap(GetHandleSize((Handle) pic), mytype, (Ptr) *pic);
  1013.     HUnlock((Handle) pic);
  1014.   }
  1015.   else {
  1016. /*    if ((fptr = fopen(fname, "w")) == nil)
  1017.       xlfail("can't open file");
  1018.     GetPort(&savePort);
  1019.     SetPort(WorkPort);
  1020.     DrawPicture(pic, &r);
  1021.     SetPort(savePort);
  1022.     writemacp(fptr, WorkRowStarts, r.right - r.left, r.bottom - r.top);
  1023.     xlfail("operation not supported");
  1024.     spoolpict(fname, pic, WorkPort);*/
  1025.   }
  1026.   KillPicture(pic);
  1027.   copying_to_clip = FALSE;
  1028. }
  1029.  
  1030. StGWResetBuffer()
  1031. {
  1032.   copying_to_clip = FALSE;
  1033.   bufflevel = 0;
  1034.   buffering = FALSE;  
  1035. }