home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / clib / progs / haswinlib / c / graphics < prev    next >
Encoding:
Text File  |  1991-02-04  |  12.8 KB  |  338 lines

  1. /* > $.CLIB.C.graphics
  2.  *
  3.  *      HASWIN Graphics Library
  4.  *     =========================
  5.  *
  6.  *      Copyright (C) H.A.Shaw 1990.
  7.  *              Howard A. Shaw.
  8.  *              The Unit for Space Sciences,
  9.  *              Room 165,
  10.  *              Physics Building,
  11.  *              University of Kent at Canterbury.
  12.  *              Canterbury.
  13.  *              Kent.  CT2 7NJ
  14.  *      You may use and distribute this code freely, however please leave
  15.  *      it alone.  If you find bugs (and there will be many) please contact
  16.  *      me and the master source can be modified.  If you keep me informed
  17.  *      of who you give copies of this to then I can get release upgrades
  18.  *      to them.
  19.  *
  20.  *     low level graphics routines that actually draw on the screen.
  21.  */
  22. #include "includes.h"
  23. #include <stdarg.h>
  24.  
  25. void graphics_plotxy(int code, int x, int y) {
  26.  
  27.         _kernel_swi_regs  regs;
  28.  
  29.         regs.r[0] = code;
  30.         regs.r[1] = x;
  31.         regs.r[2] = y;
  32.         haswin_swi(OS_Plot, ®s);
  33. }
  34.  
  35. /*
  36.  *      routines to perform basic graphics actions in a HASWIN window.
  37.  *      Draw if any part of the object's enclosing rectangle is in the
  38.  *      window.
  39.  *      We assume that graphics windows are set and drawing can be done
  40.  *      immediatly.
  41.  *      in these routines...
  42.  *              x,y  is a coord
  43.  *              r    is a radius
  44.  *              w    is a width
  45.  *              h    is a hieght
  46.  *              c    is a colour
  47.  */
  48. void haswin_circle(window *win, int x, int y, int r) {
  49.  
  50.         if ((!win) || (r < 0) || ((x-r) > haswin_getwindowxmax(win)) ||
  51.                                  ((x+r) < haswin_getwindowxmin(win)) ||
  52.                                  ((y-r) > haswin_getwindowymax(win)) ||
  53.                                  ((y+r) < haswin_getwindowymin(win)))
  54.                 return;
  55.         haswin_convertwinxytoscr(win, &x, &y);
  56.         graphics_circle(x, y, r);
  57. }
  58.  
  59. void haswin_circlefill(window *win, int x, int y, int r) {
  60.         if ((!win) || (r < 0) || ((x-r) > haswin_getwindowxmax(win)) ||
  61.                                  ((x+r) < haswin_getwindowxmin(win)) ||
  62.                                  ((y-r) > haswin_getwindowymax(win)) ||
  63.                                  ((y+r) < haswin_getwindowymin(win)))
  64.                 return;
  65.         haswin_convertwinxytoscr(win, &x, &y);
  66.         graphics_circlefill(x, y, r);
  67. }
  68.  
  69. void haswin_draw(window *win, int x, int y) {
  70.         if ((!win) || (x > haswin_getwindowxmax(win)) ||
  71.                       (x < haswin_getwindowxmin(win)) ||
  72.                       (y > haswin_getwindowymax(win)) ||
  73.                       (y < haswin_getwindowymin(win)))
  74.                 return;
  75.         haswin_convertwinxytoscr(win, &x, &y);
  76.         graphics_draw(x, y);
  77. }
  78.  
  79. void haswin_drawby(window *win, int x, int y) {
  80.         if (!win)
  81.                 return;
  82.         graphics_drawby(x, y);
  83. }
  84.  
  85. void haswin_fill(window *win, int x, int y) {
  86.         if (!win)
  87.                 return;
  88.         haswin_convertwinxytoscr(win, &x, &y);
  89.         graphics_fill(x, y);
  90. }
  91.  
  92. void haswin_rectangle(window *win, int x, int y, int w, int h) {
  93.         if ((!win) || (x > haswin_getwindowxmax(win)) ||
  94.                      ((x+w) < haswin_getwindowxmin(win)) ||
  95.                       (y > haswin_getwindowymax(win)) ||
  96.                      ((y+h) < haswin_getwindowymin(win)))
  97.                 return;
  98.         haswin_convertwinxytoscr(win, &x, &y);
  99.         graphics_rectangle(x, y, w, h);
  100. }
  101.  
  102. void haswin_rectanglefill(window *win, int x, int y, int w, int h) {
  103.         if ((!win) || (x > haswin_getwindowxmax(win)) ||
  104.                      ((x+w) < haswin_getwindowxmin(win)) ||
  105.                       (y > haswin_getwindowymax(win)) ||
  106.                      ((y+h) < haswin_getwindowymin(win)))
  107.                 return;
  108.         haswin_convertwinxytoscr(win, &x, &y);
  109.         graphics_rectanglefill(x, y, w, h);
  110. }
  111.  
  112.  
  113. /*
  114.  *      take the string pointed to by "string" and display on the
  115.  *      graphics screen adjusting for a start at adjx,adjy.
  116.  *
  117.  *      We try to be a little intellegent about what we don't have to draw.
  118.  *      The calculations for filled rectangles are easy, but others are
  119.  *      approximate only and still draw too often.  Circles especially.
  120.  *
  121.  *      The following control codes are understood.
  122.  *      $ is escape sequence start/end.
  123.  *
  124.  *              cx,y,r     circle at x,y radius r
  125.  *              Cx,y,r     filled circle at x,y radius r
  126.  *              dx,y       draw line to x,y
  127.  *              Dx,y       draw line relative to x,y
  128.  *              fn         select foreground colour n
  129.  *                               (background can't be changed)
  130.  *              mx,y       move to x,y
  131.  *              Mx,y       move relative to x,y
  132.  *              rx,y,w,h   rectangle x,y width w, height h
  133.  *              Rx,y,w,h   filled rectangle x,y width w, height h
  134.  *
  135.  *      a single $$ pair can enclose many control sequences.  any non
  136.  *      control symbol (0-9cCdDfmMrR) seperates within $$
  137.  */
  138.  
  139. static char   *c;
  140. int ato_int(void);
  141.  
  142. void graphics_plot(char *string, int adjx, int adjy, int gx0, int gx1,
  143.                    int gy0, int gy1) {
  144.  
  145.         register int    x, y, r, h;
  146.                  int    line, col, movepend, incontrol, charx, chary;
  147.  
  148.         if (!string)
  149.                 return;
  150.         line = adjy;
  151.         col = adjx;
  152.         movepend=0;
  153.         charx = haswin_readvduvariable(VDUVAR_CharXsize);
  154.         chary = haswin_readvduvariable(VDUVAR_CharYsize);
  155.         incontrol=HASWIN_FALSE;
  156.         for (c=string; *c; c++) {
  157.                 switch (*c) {
  158.                 case '\n':
  159.                         line -= chary;
  160.                         /* FALL THRU */
  161.                 case '\r':
  162.                         movepend++;
  163.                         col = adjx;
  164.                         break;
  165.                 case '$':
  166.                         if (incontrol)
  167.                                 incontrol = HASWIN_FALSE;
  168.                         else
  169.                                 incontrol = HASWIN_TRUE;
  170.                         break;
  171.                 default:
  172.                         if (incontrol) {
  173.                                 switch (*c) {
  174.                                 case 'm':
  175.                                         c++; col = adjx+ato_int();
  176.                                         c++; line= adjy+ato_int();
  177.                                         movepend++;
  178.                                         break;
  179.                                 case 'M':
  180.                                         c++; col  += ato_int();
  181.                                         c++; line += ato_int();
  182.                                         movepend++;
  183.                                         break;
  184.                                 case 'c':
  185.                                         c++; x = adjx+ato_int();
  186.                                         c++; y = adjy+ato_int();
  187.                                         c++; r = ato_int();
  188.                                         if ((x-r>gx1) || (x+r<gx0))
  189.                                                 break;
  190.                                         if ((y-r>gy1) || (y+r<gy0))
  191.                                                 break;
  192.                                         graphics_circle(x, y, r);
  193.                                         break;
  194.                                 case 'C':
  195.                                         c++; x = adjx+ato_int();
  196.                                         c++; y = adjy+ato_int();
  197.                                         c++; r = ato_int();
  198.                                         if ((x-r>gx1) || (x+r<gx0))
  199.                                                 break;
  200.                                         if ((y-r>gy1) || (y+r<gy0))
  201.                                                 break;
  202.                                         graphics_circlefill(x, y, r);
  203.                                         break;
  204.                                 case 'd':
  205.                                         if (movepend) {
  206.                                                 movepend = 0;
  207.                                                 graphics_move(col, line);
  208.                                         }
  209.                                         c++; x = adjx+ato_int();
  210.                                         c++; y = adjy+ato_int();
  211.                                         graphics_draw(x, y);
  212.                                         break;
  213.                                 case 'D':
  214.                                         if (movepend) {
  215.                                                 movepend = 0;
  216.                                                 graphics_move(col, line);
  217.                                         }
  218.                                         c++; x = adjx+ato_int();
  219.                                         c++; y = adjy+ato_int();
  220.                                         graphics_drawby(x, y);
  221.                                         break;
  222.                                 case 'f':
  223.                                         c++; x = ato_int();
  224.                                         graphics_gcol(0, x);
  225.                                         break;
  226.                                 case 'r':
  227.                                         c++; x = adjx+ato_int();
  228.                                         c++; y = adjy+ato_int();
  229.                                         c++; r = ato_int();
  230.                                         c++; h = ato_int();
  231.                                         if ((x > gx1) || (x+r < gx0))
  232.                                                 break;
  233.                                         if ((y > gy1) || (y+h < gy0))
  234.                                                 break;
  235.                                         graphics_rectangle(x, y, r, h);
  236.                                         break;
  237.                                 case 'R':
  238.                                         c++; x = adjx+ato_int();
  239.                                         c++; y = adjy+ato_int();
  240.                                         c++; r = ato_int();
  241.                                         c++; h = ato_int();
  242.                                         if ((x > gx1) || (x+r < gx0))
  243.                                                 break;
  244.                                         if ((y > gy1) || (y+h < gy0))
  245.                                                 break;
  246.                                         graphics_rectanglefill(x, y, r, h);
  247.                                         break;
  248.                                 default:
  249.                                         break;
  250.                                 }
  251.                         } else {
  252.                                 if (( col+charx >gx0) && ( col-charx <gx1) &&
  253.                                     (line+chary >gy0) && (line-chary <gy1)) {
  254.                                         if (movepend) {
  255.                                                 movepend = 0;
  256.                                                 graphics_move(col, line);
  257.                                         }
  258.                                         haswin_swi(OS_WriteI+(*c), 0);
  259.                                 }
  260.                                 col += charx;
  261.                         }
  262.                 }
  263.         }
  264. }
  265.  
  266. /*
  267.  *      remove leading spaces and commas, find a number, and return it
  268.  *      c is left pointing to the last digit in the number.
  269.  */
  270. int ato_int() {
  271.  
  272.         register int    b = 0;
  273.  
  274.         while ((*c == ' ') || (*c == ','))
  275.                 c++;
  276.         if (*c == '-') {
  277.                 c++;
  278.                 while ((*c >= '0') && ( *c <= '9'))
  279.                         b = b*10 + (*(c++)-'0');
  280.                 c--;
  281.                 return(-b);
  282.         }
  283.         while ((*c >= '0') && ( *c <= '9'))
  284.                 b = b*10 + (*(c++)-'0');
  285.         c--;
  286.         return(b);
  287. }
  288.  
  289. int haswin_addgraphics(window *win, char *str) {
  290.  
  291.         int     max;
  292.  
  293.         if (!win)
  294.                 return(HASWIN_FALSE);
  295.         max = strlen(str);
  296.         if (win->picture)
  297.                 win->picture = haswin_mallocblock(win->picture, max+((int *)win->picture)[-1]+1, "haswin_addgraphics", "window picture");
  298.         else {
  299.                 win->picture = haswin_mallocblock(0, max+1, "haswin_addgraphics", "window picture");
  300.                 win->picture[0] = '\0';
  301.         }
  302.         strcat(win->picture, str);
  303.         return(HASWIN_TRUE);
  304. }
  305.  
  306. int haswin_cleargraphics(window *win) {
  307.  
  308.         if (!win)
  309.                 return(HASWIN_FALSE);
  310.         if (win->picture) {
  311.                 haswin_freeblock(win->picture);
  312.                 win->picture = 0;
  313.         }
  314.         return(HASWIN_TRUE);
  315. }
  316.  
  317. /*
  318.  *      perform printf() on the graphics in a given window.
  319.  *
  320.  *      The final string is passed to haswin_addgraphics() for display.
  321.  */
  322. int haswin_graphicsprintf(window *win, char *fmt, ...) {
  323.  
  324.         va_list ap;
  325. /* we have to use fixed length strings, guess at 10K in total */
  326.         char    str[10240];
  327.         int     len;
  328.  
  329.         if ((!win) || (!fmt))
  330.                 return(HASWIN_FALSE);
  331.         va_start(ap, fmt);
  332.         len = vsprintf(str, fmt, ap);
  333.         haswin_addgraphics(win, str);
  334.         va_end(ap);
  335.         return(len);
  336. }
  337.  
  338.