home *** CD-ROM | disk | FTP | other *** search
- // ┌───────┐
- // ─────────>│ AVNER │
- // ─────────>│ BEN │──────> Software Engineering Method
- // └───────┘
- // 10 Dov-Hoz st. Tel-Aviv 63416 Israel tel. 972-3-221535
-
- // The Screen NAVigator, ver 1.10 March 1990
- // Copyright (c) 1989 by Avner Ben
- // Snav is not, and never was, free software.
- // for conditions for use refer to file "copyrigh.txt"
-
- // The Screen Navigator is an object-oriented device-independent
- // character-graphics driver package, written in the C++ language,
- // distributed in the form of C++ source code.
- // For further information refer to the documentation files.
-
- // The user may not omit this text, from the beginning of the file, to
- // the line of asterisks below.
-
- /***************************************************************************/
-
- // package nucleus part 1 - source code.
- // This file defines the basic terms of "character geometry", to be used
- // in the more specific other parts.
- // for data-structure logic, refer to file "article".
-
- // History:
- // 25.3.89 avner ben coded.
- /////// snav v1.0
- // 28.7.89 avner ben - classified.
- /////// snav v1.1
- // 5.3.90 avner ben - C++ v2.0 upgrade.
-
- // Site history (of this copy):
- // __.__.__ ____________ : __________________.
-
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
-
- #define SNAV0_C
- #include "snav0.hpp"
-
- boolean env_modify=FALSE; // governs the behaviour of some methods
-
- /****************************** constants ************************************/
-
- // predefoned instances ("figurative constants")
- weight_d // intended to be read only!
- twgwgt(0),
- h1v1(1,1),
- h1v2(1,2),
- h2v1(2,1),
- h2v2(2,2),
- fullwgt(3,3);
- axis // intended to be read only!
- nodim(NODIM),
- hdim(HDIM),
- vdim(VDIM);
- intersection
- nodirs(NODIR),
- hdirs(hdim.whereto()),
- vdirs(vdim.whereto()),
- alldirs("cross");
- direction // intended to be read only!
- nodir(NODIR),
- rt(RTDIR),
- up(UPDIR),
- lt(LTDIR),
- dn(DNDIR);
-
- /******************************** directions *********************************/
-
- connective direction :: opposite(void)
- { // "opposite" direction. other direction on same axis
-
- intersection result((axis(*this)).directions());
- result.exclude(*this);
- return (where=(connective)result());
- }
-
- direction :: direction(char c)
- { // construct direction from letter code */
-
- where=(connective)0x0001;
- c=toupper(c);
- for (; where; next())
- if (code()==c) break;
- }
-
- char *direction :: name(void)
- {
- static char result[6];
- switch (where) {
- case RTDIR : strcpy(result,"Right"); break;
- case UPDIR : strcpy(result,"Up"); break;
- case LTDIR : strcpy(result,"Left"); break;
- case DNDIR : strcpy(result,"Down"); break;
- default : *result='\0'; break;
- }
- return result;
- }
-
- char direction :: code(void)
- { /* first letter of direction name */
-
- return(*name());
- }
-
- direction operator~(const direction &dir)
- { // non-destructive opposite()
-
- direction result=dir;
- result.opposite();
- return(result); // copied
- }
-
- int direction :: serial(void)
- {
- int i=4, dirval=8;;
- for (; i; i--, dirval>>=1)
- if (dirval==where) return(i);
- return(0);
- }
-
- connective direction :: clockwise(void)
- // circular movement clockwise
- { prev(); if (!where) where=(connective)0x0008; return where; }
-
- /**************************** direction sets ********************************/
-
- intersection :: intersection(char *name)
- { // construct by name
-
- if (!strcmp(name+1,"arrow"))
- value=(~(direction(*name))).whereto();
- else if (!strcmp(name,"dash"))
- value=hdirs();
- else if (!strcmp(name,"bar"))
- value=vdirs();
- else if (!strcmp(name+2,"corner"))
- value=(~(direction(*name))).whereto()
- | (~(direction(*(name+1)))).whereto();
- else if (!strcmp(name+1,"fork")) {
- value=hdirs()|vdirs();
- exclude(~(direction(*name)));
- } else if (!strcmp(name,"cross"))
- value=hdirs()|vdirs();
- else value=NODIR;
- }
-
- boolean intersection :: includes(const direction &member)
- { // test if direction is included
-
- if (value & member.where)
- for (direction dir; dir.where; dir++)
- if (dir==member && (value & dir.where))
- return(TRUE);
- return(FALSE);
- }
-
- boolean intersection :: includes(const intersection &subset)
- { // test if all target directions are included
-
- for (direction dir; dir.where; dir++)
- if (subset.includes(dir) && !(includes(dir)))
- return(FALSE);
- return(TRUE);
- }
-
- boolean intersection :: intersects(const intersection ¶lel)
- // test if at least one of the target directions is included
-
- { return(value & paralel.value); }
-
- boolean intersection :: unary(void)
- // test if set conains only one member
- { return(type()==J_ARROW); }
-
- char *intersection :: names()
- { /* decode names of directions in set */
-
- static char nm[20]; *nm='\0';
- int save=value;
- for (direction dir; dir.where; dir++)
- if (includes(dir)) {
- strcat(nm,dir.name());
- exclude(dir);
- if (value) strcat(nm,",");
- }
- value=save;
- return(nm);
- }
-
- intersection_type intersection :: type(void)
- {
- int numdir=0;
- for (direction dir; dir(); dir++)
- if (includes(dir)) numdir++;
- switch (numdir) {
- case 1 : return(J_ARROW);
- case 2 : if (value==hdirs() || value==vdirs()) return J_LINE;
- else return(J_CORNER);
- case 3 : return(J_FORK);
- case 4 : return(J_CROSS);
- default: return(J_NUL);
- }
- }
-
- char *intersection :: name()
- { // decode names of intersection value
-
- static char nm[9]; *nm='\0';
- char *s=nm;
-
- switch (type()) {
- case J_ARROW : *nm=(~(direction((connective)value))).code();
- strcpy(nm+1,"arrow");
- break;
- case J_LINE : if (value==hdirs()) strcpy(nm,"dash");
- else strcpy(nm,"bar");
- break;
- case J_CORNER: for (direction dir; dir(); dir++)
- if (includes(~dir))
- *(s++)=(dir).code();
- strcpy(s,"corner");
- break;
- case J_FORK : if (includes(hdirs))
- *nm=(direction((connective)value-hdirs())).code();
- else *nm=(direction((connective)value-vdirs())).code();
- strcpy(nm+1,"fork");
- break;
- case J_CROSS : strcpy(nm,"cross"); break;
- default : strcpy(nm,"nowhere");
- }
- return(nm);
- }
-
- direction intersection :: ask_first()
- { // find first member
-
- for (direction dir; dir.where; dir++)
- if (includes(dir)) return(dir);
- return(dir); // copied
- }
-
- direction intersection :: get_first()
- { // extract first member
-
- for (direction dir; dir.where; dir++)
- if (includes(dir))
- { exclude(dir); return(dir); }
-
- return(dir); // copied
- }
-
- /****************************** dimensions of the plane **********************/
-
- void axis :: set_dirs(biconnective newdim)
- { // default empty
-
- if (newdim==HDIM)
- { where=(biconnective)newdim; value=RTDIR|LTDIR; }
- else if (newdim==VDIM)
- { where=(biconnective)newdim; value=DNDIR|UPDIR; }
- else { where=NODIM; value=NODIR; }
- }
-
- axis :: axis(const direction &dir)
- { // generalize direction
-
- if (dir()==RTDIR || dir()==LTDIR)
- { where=HDIM; value=RTDIR|LTDIR; }
- else if (dir()==DNDIR || dir()==UPDIR)
- { where=VDIM; value=DNDIR|UPDIR; }
- else { where=NODIM; value=NODIR; }
- }
-
- biconnective axis :: opposite(void)
- { // turn the other dimension
-
- if (where==HDIM)
- { where=VDIM; value=DNDIR|UPDIR; }
- else if (where==VDIM)
- { where=HDIM; value=RTDIR|LTDIR; }
- return where;
- }
-
- /* friend */ axis operator~(const axis &dim)
- { // non-destructive opposite()
-
- axis result=dim;
- result.opposite();
- return(result); // copied
- }
-
- intersection axis :: directions(void)
- // copy pending direction set
- { intersection result(value); return(result); }
-
- char *axis :: name(void)
- {
- static char result[11];
- switch (where) {
- case HDIM : strcpy(result,"Horizontal"); break;
- case VDIM : strcpy(result,"Vertical"); break;
- default : *result='\0'; break;
- }
- return result;
- }
-
- char axis :: code(void)
- // first letter of direction name
- { return(*name()); }
-
- int weight_d :: replace(const axis &dim, int width)
- // replace width on one axis
- { wgt[dim()].width=width;
- // bitwise operation assumes 2 dimensions
- return (value=wgt[HDIM].width|(wgt[VDIM].width<<2));
- }
-
- weight_d :: weight_d(int weight_combi)
- // default typewriter-graphics
- { value=weight_combi;
- // bitwise operation assumes 2 dimensions
- wgt[HDIM].width=value & 0x0003; wgt[HDIM].set_axis(HDIM);
- wgt[VDIM].width=value>>2; wgt[VDIM].set_axis(VDIM);
- }
- weight_d :: weight_d(const weight_d &other)
- { value=other.value;
- wgt[HDIM]=other.wgt[HDIM];
- wgt[VDIM]=other.wgt[VDIM];
- }
-
- weight_d & weight_d :: mask(const weight_d &other)
- {
- for (int i=1; i<=NUMDIMS; i++)
- if (wgt[i].width==0)
- wgt[i].width=other.wgt[i].width;
- return *this;
- }
-
-
-