home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c100 / 1.ddi / SNAV0111.ZIP / SNAV3.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-16  |  6.9 KB  |  218 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 April 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 4 - source code.
  23. // This file defines specific "shape" objects, inheriting the generic "shape"
  24. // defined in snav2. The shape object in snav differs from other
  25. // implementations using the same word, in being an abstract, defined by
  26. // directions of pen motion and sizes, independent of screen position.
  27. // defined are a "tracing" shape that initilizes automatically, given a
  28. // screen image to trace, and the archetypal regular shape "oblong".
  29. // For example of more specific regular shapes, refer to demo-3.
  30.  
  31. // History:
  32. /////// snav v1.1
  33. // 13.3.90-7.3.90 avner ben:
  34.  
  35. // * sperated  from snav2  * debugged  append_stroke of  tracing * debugged
  36. // oblong constructor * added clear to oblong * used pendn feature of curve
  37. // instead of offset * fixed weight  recording bug in first stroke *  added
  38. // color recording *
  39.  
  40. // Site history (of this copy):
  41. // __.__.__ ____________ : __________________.
  42.  
  43. #ifndef SNAV3_C
  44. #define SNAV3_C
  45. #endif
  46.  
  47. #include "snav2.hpp"
  48.  
  49. /*********************** pattern recognition **************************/
  50.  
  51. tracing :: ~tracing()
  52. {
  53.     if (stmark) {
  54.         landmark *next=stmark->next;
  55.         for (; stmark; stmark=next) {
  56.             next=stmark->next;
  57.             delete stmark;
  58.         }
  59.     }
  60. }
  61.  
  62. tracing :: tracing(panel *scr, point_pos *cursor) : shape(NULL,"trace"),
  63.  start(*cursor)
  64. { // "probe constructor"
  65.   /////////////// experimental code! //////////////
  66.  
  67.     stmark=NULL;
  68.     point_pos pt(*cursor);
  69.     // beginning and end of scan are complicated, in an attempt to
  70.     // preserve arcs of length 1, to be lost in a "general" algorithm.
  71.     intersection godir; if (!(scr->gowhere(&pt,&godir))()) return;
  72.     intersection avdir=(alph->cdir(scr->get_c(&pt))); // disregrad neighbours
  73.     direction dir=avdir.ask_first();
  74.     if (!(godir>=~dir)) avdir-=~dir;
  75.     (mark(&pt,&avdir))->proceed(&start,&avdir,&dir);
  76.     landmark *mrk;
  77.     point_pos offset(0,0);
  78.     while (dir()) {
  79.         if (offset.y() || offset.x()) {
  80.             shape::append_stroke(offset);
  81.             offset=point_pos(0,0);
  82.         }
  83.         mrk=append_stroke(scr,&pt,&dir);
  84.         if (mrk) mrk->proceed(&start,&avdir,&dir);
  85.         if (!dir()) { // finished first pass. reposition to pending intersection
  86.             for (mrk=stmark; mrk; mrk=mrk->next)
  87.                 if (mrk->dirleft()) { // directions left unexplored here
  88.                     start=mrk->pos;
  89.                     offset=mrk->pos; offset-=pt;
  90.                     pt=mrk->pos;
  91.                     dir=nodir; avdir=mrk->dirleft;
  92.                     dir=avdir.ask_first();
  93.                     break;
  94.                 }
  95.         }
  96.     }
  97.     // resolve missing axis_weight (in single-line shapes)
  98.     for (stroke *sk=stsk; sk; sk=sk->get_next()) {
  99.         weight_d wgt=sk->ask_wgt();
  100.         if (wgt() && !(wgt.y() && wgt.x())) {
  101.             if (!wgt.y()) wgt.replace(hdim,wgt.x());
  102.             if (!wgt.x()) wgt.replace(vdim,wgt.y());
  103.             sk->set_wgt(wgt);
  104.         }
  105.     }
  106. }
  107.  
  108. landmark * tracing :: append_stroke(panel *scr, point_pos *cursor, direction *curdir)
  109. { // phase in "probe constructor" - read next arc
  110.   ///////////// experimental code! ////////////
  111.  
  112.     char c=scr->get_c(cursor); if (c==' ') return NULL;
  113.     intersection avdir=alph->cdir(c);
  114.     if (!(avdir>=*curdir)) return NULL;    // double-tipped not supported
  115.     if (avdir.unary()) return NULL;     // double-tipped not supported
  116.     color_ind clr=scr->get_color(cursor);
  117.     clr.normalize();
  118.     stroke *sk=new stroke(1,*curdir,alph->cweight(c),FALSE,&clr,TRUE);
  119.     landmark *mrk;
  120.     for (mrk=NULL; !mrk;) {    // stop when we get to junction - let caller decide
  121.         for (mrk=stmark; mrk; mrk=mrk->next)
  122.             if (mrk->pos==*cursor) break;
  123.         if (mrk) {                        // dejavue
  124.             if (sk->ask_len()>1)
  125.                 mrk->dirleft-=~(*curdir); // ain't coming back
  126.             avdir=mrk->dirleft;
  127.             if (mrk->dirleft>=*curdir) {
  128.                 mrk->dirleft-=*curdir;
  129.                 mrk=NULL;            // passing through
  130.             }
  131.         } else if (!avdir.unary())            // unmarked branch
  132.             if (avdir>=*curdir) {           // mark and proceed
  133.                 avdir-=*curdir;
  134.                 mark(cursor,&avdir);
  135.                 avdir+=*curdir;
  136.             } else mrk=mark(cursor,&avdir);        // can't decide
  137.         if (!alph->ccont(scr->get_c(cursor),
  138.          scr->next_c(curdir,cursor),*curdir)
  139.          || (scr->get_color(cursor)).ask_for_clr()!=clr.forgnd)
  140.         {         // end of arc
  141.             mrk=mark(cursor,&avdir);
  142.             if ((scr->gowhere(cursor,&(intersection)alldirs)).unary())
  143.                 start=*cursor;          // end of scan phase
  144.         } else {    // get next
  145.             cursor->move(*curdir); sk->expand();
  146.             avdir=alph->cdir(scr->get_c(cursor));
  147.             avdir-=~(*curdir);          // ain't coming back
  148.         }
  149.     }
  150.     if ((alph->cdir(scr->get_c(cursor))).unary())             // tipped
  151.         sk->toggle_tip();
  152.     shape::append_stroke(sk);
  153.     return mrk;
  154. }
  155.  
  156. landmark :: landmark(point_pos *pt, intersection *avdir)
  157.  : pos(*pt), dirstart(*avdir), dirleft(*avdir)
  158. { next=NULL; }
  159.  
  160. void landmark :: proceed(point_pos *start, intersection *avdir, direction *curdir)
  161. { // solve amiguity. more than one path open from point.
  162.  
  163.  
  164.     if (*start!=pos) dirleft-=~(*curdir);
  165.     if (dirleft())
  166.         if (dirleft>=*curdir) ;                // continue
  167.         else *curdir=dirleft.ask_first();               // turn
  168.     else *curdir=nodir;                    // end of the road
  169.     *avdir=dirleft;
  170. }
  171.  
  172. landmark * tracing :: mark(point_pos *cursor, intersection *avdir)
  173. { // add cursor to intesections-left-to-explore list
  174.  
  175.     landmark *mrk;
  176.     if (!stmark)
  177.         mrk=stmark=new landmark(cursor,avdir);
  178.     else {
  179.         for (mrk=stmark; mrk->next; mrk=mrk->next)
  180.             if (mrk->pos==*cursor) break;        // we've been here
  181.         if (mrk->pos!=*cursor)                     // append
  182.             mrk=mrk->next=new landmark(cursor,avdir);
  183.     }
  184.     return(mrk);
  185. }
  186.  
  187. /*********************** sample regular shape **************************/
  188.  
  189. oblong :: oblong(int inwd, int inhgt, const weight_d &inwgt)
  190.  : shape(NULL,"oblong"), wd(inwd), hgt(inhgt), wgt(inwgt)
  191. {
  192.     // allocate two sides - the rest is for the lister
  193.     direction dir;
  194.     append_stroke(new stroke(wd,dir,wgt)); dir.clockwise();
  195.     append_stroke(new stroke(hgt,dir,wgt));
  196. }
  197.  
  198. void oblong :: list(panel *scr, point_pos *pt0)
  199. {
  200.     point_pos pt=*pt0;
  201.     for (int i=1; i<=2; i++) {
  202.         shape::list(scr,&pt,FALSE);
  203.         stsk->invert();
  204.         stroke *t=stsk->get_next(); t->invert();
  205.     }
  206. }
  207.  
  208. void oblong :: clear(panel *scr, point_pos *pt0)
  209. {
  210.     point_pos pt=*pt0;
  211.     for (int i=1; i<=2; i++) {
  212.         shape::clear(scr,&pt,FALSE);
  213.         stsk->invert();
  214.         stroke *t=stsk->get_next(); t->invert();
  215.     }
  216. }
  217.  
  218.