home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c100 / 1.ddi / SNAV0111.ZIP / SNAV0.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-16  |  8.6 KB  |  345 lines

  1. //          ┌───────┐
  2. //    ─────────>│ AVNER │
  3. //    ─────────>│  BEN  │──────> Software Engineering Method
  4. //          └───────┘
  5. //    10 Dov-Hoz st. Tel-Aviv 63416 Israel tel. 972-3-221535
  6.  
  7. // The Screen NAVigator, ver 1.10 March 1990
  8. // Copyright (c) 1989 by Avner Ben
  9. // Snav is not, and never was, free software.
  10. // for conditions for use refer to file "copyrigh.txt"
  11.  
  12. // The Screen Navigator is an object-oriented device-independent
  13. // character-graphics driver package, written in the C++ language,
  14. // distributed in the form of C++ source code.
  15. // For further information refer to the documentation files.
  16.  
  17. // The user may not omit this text, from the beginning of the file, to
  18. // the line of asterisks below.
  19.  
  20. /***************************************************************************/
  21.  
  22. // package nucleus part 1 - source code.
  23. // This file defines the basic terms of "character geometry", to be used
  24. // in the more specific other parts.
  25. // for data-structure logic, refer to file "article".
  26.  
  27. // History:
  28. // 25.3.89 avner ben coded.
  29. /////// snav v1.0
  30. // 28.7.89 avner ben - classified.
  31. /////// snav v1.1
  32. // 5.3.90  avner ben - C++ v2.0 upgrade.
  33.  
  34. // Site history (of this copy):
  35. // __.__.__ ____________ : __________________.
  36.  
  37. #include <stdio.h>
  38. #include <string.h>
  39. #include <ctype.h>
  40.  
  41. #define  SNAV0_C
  42. #include "snav0.hpp"
  43.  
  44. boolean env_modify=FALSE;        // governs the behaviour of some methods
  45.  
  46. /****************************** constants ************************************/
  47.  
  48. // predefoned instances ("figurative constants")
  49. weight_d      // intended to be read only!
  50.     twgwgt(0),
  51.     h1v1(1,1),
  52.     h1v2(1,2),
  53.     h2v1(2,1),
  54.     h2v2(2,2),
  55.     fullwgt(3,3);
  56. axis          // intended to be read only!
  57.     nodim(NODIM),
  58.     hdim(HDIM),
  59.     vdim(VDIM);
  60. intersection
  61.     nodirs(NODIR),
  62.     hdirs(hdim.whereto()),
  63.     vdirs(vdim.whereto()),
  64.     alldirs("cross");
  65. direction      // intended to be read only!
  66.     nodir(NODIR),
  67.     rt(RTDIR),
  68.     up(UPDIR),
  69.     lt(LTDIR),
  70.     dn(DNDIR);
  71.  
  72. /******************************** directions *********************************/
  73.  
  74. connective direction :: opposite(void)
  75. { // "opposite" direction. other direction on same axis
  76.  
  77.     intersection result((axis(*this)).directions());
  78.     result.exclude(*this);
  79.     return (where=(connective)result());
  80. }
  81.  
  82. direction :: direction(char c)
  83. { // construct direction from letter code */
  84.  
  85.     where=(connective)0x0001;
  86.     c=toupper(c);
  87.     for (; where; next())
  88.         if (code()==c) break;
  89. }
  90.  
  91. char *direction :: name(void)
  92. {
  93.     static char result[6];
  94.     switch (where) {
  95.         case RTDIR : strcpy(result,"Right"); break;
  96.         case UPDIR : strcpy(result,"Up"); break;
  97.         case LTDIR : strcpy(result,"Left"); break;
  98.         case DNDIR : strcpy(result,"Down"); break;
  99.         default    : *result='\0'; break;
  100.     }
  101.     return result;
  102. }
  103.  
  104. char direction :: code(void)
  105. { /* first letter of direction name */
  106.  
  107.     return(*name());
  108. }
  109.  
  110. direction operator~(const direction &dir)
  111. { // non-destructive opposite()
  112.  
  113.     direction result=dir;
  114.     result.opposite();
  115.     return(result);                          // copied
  116. }
  117.  
  118. int direction :: serial(void)
  119. {
  120.     int i=4, dirval=8;;
  121.     for (; i; i--, dirval>>=1)
  122.         if (dirval==where) return(i);
  123.     return(0);
  124. }
  125.  
  126. connective direction :: clockwise(void)
  127. // circular movement clockwise
  128. { prev(); if (!where) where=(connective)0x0008; return where; }
  129.  
  130. /**************************** direction sets ********************************/
  131.  
  132. intersection :: intersection(char *name)
  133. { // construct by name
  134.  
  135.     if (!strcmp(name+1,"arrow"))
  136.         value=(~(direction(*name))).whereto();
  137.     else if (!strcmp(name,"dash"))
  138.         value=hdirs();
  139.     else if (!strcmp(name,"bar"))
  140.         value=vdirs();
  141.     else if (!strcmp(name+2,"corner"))
  142.         value=(~(direction(*name))).whereto()
  143.         | (~(direction(*(name+1)))).whereto();
  144.     else if (!strcmp(name+1,"fork")) {
  145.         value=hdirs()|vdirs();
  146.         exclude(~(direction(*name)));
  147.     } else if (!strcmp(name,"cross"))
  148.         value=hdirs()|vdirs();
  149.     else value=NODIR;
  150. }
  151.  
  152. boolean intersection :: includes(const direction &member)
  153. { // test if direction is included
  154.  
  155.     if (value & member.where)
  156.         for (direction dir; dir.where; dir++)
  157.             if (dir==member && (value & dir.where))
  158.                 return(TRUE);
  159.     return(FALSE);
  160. }
  161.  
  162. boolean intersection :: includes(const intersection &subset)
  163. { // test if all target directions are included
  164.  
  165.     for (direction dir; dir.where; dir++)
  166.         if (subset.includes(dir) && !(includes(dir)))
  167.             return(FALSE);
  168.     return(TRUE);
  169. }
  170.  
  171. boolean intersection :: intersects(const intersection ¶lel)
  172. // test if at least one of the target directions is included
  173.  
  174.     { return(value & paralel.value); }
  175.  
  176. boolean intersection :: unary(void)
  177. // test if set conains only one member
  178.     { return(type()==J_ARROW); }
  179.  
  180. char *intersection :: names()
  181. { /* decode names of directions in set */
  182.  
  183.     static char nm[20]; *nm='\0';
  184.     int save=value;
  185.     for (direction dir; dir.where; dir++)
  186.         if (includes(dir)) {
  187.             strcat(nm,dir.name());
  188.             exclude(dir);
  189.             if (value) strcat(nm,",");
  190.         }
  191.     value=save;
  192.     return(nm);
  193. }
  194.  
  195. intersection_type intersection :: type(void)
  196. {
  197.     int numdir=0;
  198.     for (direction dir; dir(); dir++)
  199.         if (includes(dir)) numdir++;
  200.     switch (numdir) {
  201.         case 1 : return(J_ARROW);
  202.         case 2 : if (value==hdirs() || value==vdirs()) return J_LINE;
  203.              else return(J_CORNER);
  204.         case 3 : return(J_FORK);
  205.         case 4 : return(J_CROSS);
  206.         default: return(J_NUL);
  207.     }
  208. }
  209.  
  210. char *intersection :: name()
  211. { // decode names of intersection value
  212.  
  213.     static char nm[9]; *nm='\0';
  214.     char    *s=nm;
  215.  
  216.     switch (type()) {
  217.         case J_ARROW :    *nm=(~(direction((connective)value))).code();
  218.                 strcpy(nm+1,"arrow");
  219.                 break;
  220.         case J_LINE  :    if (value==hdirs()) strcpy(nm,"dash");
  221.                 else strcpy(nm,"bar");
  222.                 break;
  223.         case J_CORNER:    for (direction dir; dir(); dir++)
  224.                     if (includes(~dir))
  225.                         *(s++)=(dir).code();
  226.                 strcpy(s,"corner");
  227.                 break;
  228.         case J_FORK  :    if (includes(hdirs))
  229.                     *nm=(direction((connective)value-hdirs())).code();
  230.                 else *nm=(direction((connective)value-vdirs())).code();
  231.                 strcpy(nm+1,"fork");
  232.                 break;
  233.         case J_CROSS :    strcpy(nm,"cross"); break;
  234.         default      :    strcpy(nm,"nowhere");
  235.     }
  236.     return(nm);
  237. }
  238.  
  239. direction intersection :: ask_first()
  240. { // find first member
  241.  
  242.     for (direction dir; dir.where; dir++)
  243.         if (includes(dir)) return(dir);
  244.     return(dir);                             // copied
  245. }
  246.  
  247. direction intersection :: get_first()
  248. { // extract first member
  249.  
  250.     for (direction dir; dir.where; dir++)
  251.         if (includes(dir))
  252.             { exclude(dir); return(dir); }
  253.  
  254.     return(dir);                             // copied
  255. }
  256.  
  257. /****************************** dimensions of the plane **********************/
  258.  
  259. void axis :: set_dirs(biconnective newdim)
  260. { // default empty
  261.  
  262.     if (newdim==HDIM)
  263.         { where=(biconnective)newdim; value=RTDIR|LTDIR; }
  264.     else if (newdim==VDIM)
  265.         { where=(biconnective)newdim; value=DNDIR|UPDIR; }
  266.     else { where=NODIM; value=NODIR; }
  267. }
  268.  
  269. axis :: axis(const direction &dir)
  270. { // generalize direction
  271.  
  272.     if (dir()==RTDIR || dir()==LTDIR)
  273.         { where=HDIM; value=RTDIR|LTDIR; }
  274.     else if (dir()==DNDIR || dir()==UPDIR)
  275.         { where=VDIM; value=DNDIR|UPDIR; }
  276.     else {    where=NODIM; value=NODIR; }
  277. }
  278.  
  279. biconnective axis :: opposite(void)
  280. { // turn the other dimension
  281.  
  282.     if (where==HDIM)
  283.         { where=VDIM; value=DNDIR|UPDIR; }
  284.     else if (where==VDIM)
  285.         { where=HDIM; value=RTDIR|LTDIR; }
  286.     return where;
  287. }
  288.  
  289. /* friend */ axis operator~(const axis &dim)
  290. { // non-destructive opposite()
  291.  
  292.     axis result=dim;
  293.     result.opposite();
  294.     return(result);                          // copied
  295. }
  296.  
  297. intersection axis :: directions(void)
  298. // copy pending direction set
  299.     { intersection result(value); return(result); }
  300.  
  301. char *axis :: name(void)
  302. {
  303.     static char result[11];
  304.     switch (where) {
  305.         case HDIM : strcpy(result,"Horizontal"); break;
  306.         case VDIM : strcpy(result,"Vertical"); break;
  307.         default   : *result='\0'; break;
  308.     }
  309.     return result;
  310. }
  311.  
  312. char axis :: code(void)
  313. // first letter of direction name
  314.     { return(*name()); }
  315.  
  316. int weight_d :: replace(const axis &dim, int width)
  317. // replace width on one axis
  318. {    wgt[dim()].width=width;
  319.     // bitwise operation assumes 2 dimensions
  320.     return (value=wgt[HDIM].width|(wgt[VDIM].width<<2));
  321. }
  322.  
  323. weight_d :: weight_d(int weight_combi)
  324. // default typewriter-graphics
  325. {    value=weight_combi;
  326.     // bitwise operation assumes 2 dimensions
  327.     wgt[HDIM].width=value & 0x0003; wgt[HDIM].set_axis(HDIM);
  328.     wgt[VDIM].width=value>>2; wgt[VDIM].set_axis(VDIM);
  329. }
  330. weight_d :: weight_d(const weight_d &other)
  331. {    value=other.value;
  332.     wgt[HDIM]=other.wgt[HDIM];
  333.     wgt[VDIM]=other.wgt[VDIM];
  334. }
  335.  
  336. weight_d & weight_d :: mask(const weight_d &other)
  337. {
  338.     for (int i=1; i<=NUMDIMS; i++)
  339.         if (wgt[i].width==0)
  340.             wgt[i].width=other.wgt[i].width;
  341.     return *this;
  342. }
  343.  
  344.  
  345.