home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume8 / xfig2.8 / part10 / glue.c < prev    next >
C/C++ Source or Header  |  1990-07-03  |  11KB  |  476 lines

  1. /* 
  2.  *    FIG : Facility for Interactive Generation of figures
  3.  *
  4.  *    Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
  5.  *    January 1985.
  6.  *    1st revision : Aug 1985.
  7.  *
  8.  *    %W%    %G%
  9. */
  10. #include "fig.h"
  11. #include "resources.h"
  12. #include "alloc.h"
  13. #include "func.h"
  14. #include "object.h"
  15. #include "paintop.h"
  16.  
  17. #define            TOLERANCE    7
  18. #define            min(a, b)    (((a) < (b)) ? (a) : (b))
  19. #define            max(a, b)    (((a) > (b)) ? (a) : (b))
  20.  
  21. extern F_pos        last_position, new_position;  /* undo.c   */
  22. extern int        fix_x, fix_y, cur_x, cur_y;
  23.  
  24. extern            (*canvas_kbd_proc)();
  25. extern            (*canvas_locmove_proc)();
  26. extern            (*canvas_leftbut_proc)();
  27. extern            (*canvas_middlebut_proc)();
  28. extern            (*canvas_rightbut_proc)();
  29. extern            null_proc();
  30. extern            set_popupmenu();
  31.  
  32. extern F_compound    objects;
  33. extern int        compoundbox_shown;
  34. extern int        pointmarker_shown;
  35. extern int        foreground_color, background_color;
  36.  
  37. extern int        create_compound();
  38. extern F_compound    *compound_point_search();
  39.  
  40. extern int        init_create_compound();
  41.  
  42. compound_selected()
  43. {
  44.     canvas_kbd_proc = null_proc;
  45.     canvas_locmove_proc = null_proc;
  46.     canvas_leftbut_proc = init_create_compound;
  47.     canvas_middlebut_proc = null_proc;
  48.     canvas_rightbut_proc = set_popupmenu;
  49.     set_cursor(&arrow_cursor);
  50.     reset_action_on();
  51.     }
  52.  
  53. init_create_compound(x, y)
  54. int    x, y;
  55. {
  56.     init_box_drawing(x, y);
  57.     canvas_middlebut_proc = create_compound;
  58.     canvas_leftbut_proc = canvas_rightbut_proc = null_proc;
  59.     }
  60.  
  61. create_compound(x, y)
  62. int    x, y;
  63. {
  64.     F_compound    *c;
  65.  
  66.     if (NULL == (Compound_malloc(c))) {
  67.         put_msg(Err_mem);
  68.         return;
  69.         }
  70.     draw_rectbox(fix_x, fix_y, cur_x, cur_y, INV_PAINT);
  71.     c->nwcorner.x = min(fix_x, x);
  72.     c->nwcorner.y = min(fix_y, y);
  73.     c->secorner.x = max(fix_x, x);
  74.     c->secorner.y = max(fix_y, y);
  75.     if (compose_compound(c) == 0) {
  76.         free((char*)c);
  77.         compound_selected();
  78.         put_msg("Empty compound, ignore");
  79.         return;
  80.         }
  81.     draw_compoundbox(c, INV_PAINT);
  82.     c->next = NULL;
  83.     clean_up();
  84.     set_action(F_GLUE);
  85.     insert_compound(&objects.compounds, c);
  86.     set_latestcompound(c);
  87.     compound_selected();
  88.     }
  89.  
  90. compose_compound(c)
  91. F_compound    *c;
  92. {
  93.     c->ellipses = NULL;
  94.     c->lines = NULL;
  95.     c->texts = NULL;
  96.     c->splines = NULL;
  97.     c->arcs = NULL;
  98.     c->compounds = NULL;
  99.     get_ellipse(&c->ellipses, c->nwcorner.x, c->nwcorner.y,
  100.         c->secorner.x, c->secorner.y);
  101.     get_lineobj(&c->lines, c->nwcorner.x, c->nwcorner.y,
  102.         c->secorner.x, c->secorner.y);
  103.     get_spline(&c->splines, c->nwcorner.x, c->nwcorner.y,
  104.         c->secorner.x, c->secorner.y);
  105.     get_text(&c->texts, c->nwcorner.x, c->nwcorner.y,
  106.         c->secorner.x, c->secorner.y);
  107.     get_arc(&c->arcs, c->nwcorner.x, c->nwcorner.y,
  108.         c->secorner.x, c->secorner.y);
  109.     get_compound(&c->compounds, c->nwcorner.x, c->nwcorner.y,
  110.              c->secorner.x, c->secorner.y);
  111.     /*  get rid of point-marker  */
  112.     if (pointmarker_shown) toggle_compoundpointmarker(c);
  113.     if (c->ellipses != NULL) return(1);
  114.     if (c->splines != NULL) return(1);
  115.     if (c->lines != NULL) return(1);
  116.     if (c->texts != NULL) return(1);
  117.     if (c->arcs != NULL) return(1);
  118.     if (c->compounds != NULL) return(1);
  119.     return(0);
  120.     }
  121.  
  122. draw_compoundbox(c, op)
  123. F_compound    *c;
  124. int        op;
  125. {
  126.     draw_rectbox( c->nwcorner.x-1, c->nwcorner.y-1,
  127.         c->secorner.x+1, c->secorner.y+1, op);
  128.     draw_rectbox( c->nwcorner.x, c->nwcorner.y,
  129.         c->secorner.x, c->secorner.y, op);
  130.     draw_rectbox( c->nwcorner.x+1, c->nwcorner.y+1,
  131.         c->secorner.x-1, c->secorner.y-1, op);
  132.     }
  133.  
  134. get_ellipse(list, xmin, ymin, xmax, ymax)
  135. F_ellipse    **list;
  136. int        xmin, ymin, xmax, ymax;
  137. {
  138.     F_ellipse    *e, *ee, *ellipse;
  139.  
  140.     for (e = objects.ellipses; e != NULL;) {
  141.         if (xmin > e->center.x - e->radiuses.x) { 
  142.         ee = e; e = e->next; continue;
  143.         }
  144.         if (xmax < e->center.x + e->radiuses.x) {
  145.         ee = e; e = e->next; continue;
  146.         }
  147.         if (ymin > e->center.y - e->radiuses.y) {
  148.         ee = e; e = e->next; continue;
  149.         }
  150.         if (ymax < e->center.y + e->radiuses.y) {
  151.         ee = e; e = e->next; continue;
  152.         }
  153.         ellipse = e;
  154.         if (e == objects.ellipses) 
  155.         e = objects.ellipses = objects.ellipses->next;
  156.         else {
  157.         e = ee->next = e->next;
  158.         }
  159.         ellipse->next = *list;
  160.         *list = ellipse;
  161.         }
  162.     }
  163.  
  164. get_arc(list, xmin, ymin, xmax, ymax)
  165. F_arc    **list;
  166. int        xmin, ymin, xmax, ymax;
  167. {
  168.     F_arc    *a, *arc, *aa;
  169.     int    urx, ury, llx, lly;
  170.  
  171.     for (a = objects.arcs; a != NULL;) {
  172.         arc_bound(a, &llx, &lly, &urx, &ury);
  173.         if (xmin > llx) goto out;
  174.         if (xmax < urx) goto out;
  175.         if (ymin > lly) goto out;
  176.         if (ymax < ury) goto out;
  177.         arc = a;
  178.         if (a == objects.arcs) 
  179.         a = objects.arcs = objects.arcs->next;
  180.         else
  181.         a = aa->next = a->next;
  182.         arc->next = *list;
  183.         *list = arc;
  184.         continue;
  185.     out:
  186.         aa = a; a = a->next;
  187.         }
  188.     }
  189.  
  190. get_lineobj(list, xmin, ymin, xmax, ymax)
  191. F_line    **list;
  192. int    xmin, ymin, xmax, ymax;
  193. {
  194.     F_line    *line, *l, *ll;
  195.     F_point    *p;
  196.     int    inbound;
  197.  
  198.     for (l = objects.lines; l != NULL;) {
  199.         for (inbound = 1, p = l->points; p!= NULL && inbound; 
  200.             p = p->next) {
  201.         inbound = 0;
  202.         if (xmin > p->x) continue;
  203.         if (xmax < p->x) continue;
  204.         if (ymin > p->y) continue;
  205.         if (ymax < p->y) continue;
  206.         inbound = 1;
  207.         }
  208.         if (! inbound) {
  209.         ll = l; l = l->next; continue;
  210.         }
  211.         line = l;
  212.         if (l == objects.lines) 
  213.         l = objects.lines = objects.lines->next;
  214.         else
  215.         l = ll->next = l->next;
  216.         line->next = *list;
  217.         *list = line;
  218.         }
  219.     }
  220.  
  221. get_spline(list, xmin, ymin, xmax, ymax)
  222. F_spline    **list;
  223. int        xmin, ymin, xmax, ymax;
  224. {
  225.     F_spline    *spline, *s, *ss;
  226.     int        urx, ury, llx, lly;
  227.  
  228.     for (s = objects.splines; s != NULL;) {
  229.         spline_bound(s, &llx, &lly, &urx, &ury);
  230.         if (xmin > llx) goto out;
  231.         if (xmax < urx) goto out;
  232.         if (ymin > lly) goto out;
  233.         if (ymax < ury) goto out;
  234.         spline = s;
  235.         if (s == objects.splines) 
  236.         s = objects.splines = objects.splines->next;
  237.         else
  238.         s = ss->next = s->next;
  239.         spline->next = *list;
  240.         *list = spline;
  241.         continue;
  242.     out:
  243.         ss = s; s = s->next;
  244.         }
  245.     }
  246.  
  247. get_text(list, xmin, ymin, xmax, ymax)
  248. F_text    **list;
  249. int    xmin, ymin, xmax, ymax;
  250. {
  251.     int halflen;
  252.     F_text    *text, *t, *tt;
  253.  
  254.     for (t = objects.texts; t != NULL;) {
  255.         halflen = t->length/2;
  256.         if ( ((t->type == T_LEFT_JUSTIFIED) && xmin > t->base_x) ||
  257.             ((t->type == T_CENTER_JUSTIFIED) && xmin > t->base_x - halflen) ||
  258.             ((t->type == T_RIGHT_JUSTIFIED) && xmin > t->base_x - t->length) )
  259.             {
  260.             tt = t; t = t->next ; continue;
  261.             }
  262.         if ( ((t->type == T_LEFT_JUSTIFIED) && xmax < t->base_x + t->length) ||
  263.             ((t->type == T_CENTER_JUSTIFIED) && xmax < t->base_x + halflen) ||
  264.             ((t->type == T_RIGHT_JUSTIFIED) && xmax < t->base_x) )
  265.             {
  266.             tt = t; t = t->next ; continue;
  267.             }
  268.         if (ymin > t->base_y - t->height) {
  269.         tt = t; t = t->next; continue;
  270.         }
  271.         if (ymax < t->base_y) {
  272.         tt = t; t = t->next; continue;
  273.         }
  274.         text = t;
  275.         if (t == objects.texts) 
  276.         t = objects.texts = objects.texts->next;
  277.         else
  278.         t = tt->next = t->next;
  279.         text->next = *list;
  280.         *list = text;
  281.         }
  282.     }
  283.  
  284. get_compound(list, xmin, ymin, xmax, ymax)
  285. F_compound    **list;
  286. int    xmin, ymin, xmax, ymax;
  287. {
  288.     F_compound    *compd, *c, *cc;
  289.     for (c = objects.compounds; c != NULL;)
  290.     {
  291.         if (xmin > c->nwcorner.x)
  292.         {
  293.             cc = c;
  294.             c = c->next;
  295.             continue;
  296.         }
  297.         if (xmax < c->secorner.x)
  298.         {
  299.             cc = c;
  300.             c = c->next;
  301.             continue;
  302.         }
  303.         if (ymin > c->nwcorner.y)
  304.         {
  305.             cc = c;
  306.             c = c->next;
  307.             continue;
  308.         }
  309.         if (ymax < c->secorner.y)
  310.         {
  311.             cc = c;
  312.             c = c->next;
  313.             continue;
  314.         }
  315.         compd = c;
  316.         if (c == objects.compounds) 
  317.             c = objects.compounds = objects.compounds->next;
  318.         else
  319.             c = cc->next = c->next;
  320.         compd->next = *list;
  321.         *list = compd;
  322.     }
  323. }
  324.  
  325. F_compound *
  326. compound_point_search(x, y, tol, px, py)
  327. int    x, y, tol, *px, *py;
  328. {
  329.     F_compound    *c;
  330.  
  331.     for (c = objects.compounds; c != NULL; c = c->next) {
  332.         if (abs(c->nwcorner.x - x) <= tol && 
  333.         abs(c->nwcorner.y - y) <= tol) {
  334.         *px = c->nwcorner.x;
  335.         *py = c->nwcorner.y;
  336.         return(c);
  337.         }
  338.         if (abs(c->nwcorner.x - x) <= tol && 
  339.         abs(c->secorner.y - y) <= tol) {
  340.         *px = c->nwcorner.x;
  341.         *py = c->secorner.y;
  342.         return(c);
  343.         }
  344.         if (abs(c->secorner.x - x) <= tol && 
  345.         abs(c->nwcorner.y - y) <= tol) {
  346.         *px = c->secorner.x;
  347.         *py = c->nwcorner.y;
  348.         return(c);
  349.         }
  350.         if (abs(c->secorner.x - x) <= tol && 
  351.         abs(c->secorner.y - y) <= tol) {
  352.         *px = c->secorner.x;
  353.         *py = c->secorner.y;
  354.         return(c);
  355.         }
  356.         }
  357.     return(NULL);
  358.     }
  359.  
  360. draw_compound(c)
  361. F_compound    *c;
  362. {
  363.     draw_compoundelements(c, foreground_color, foreground_color,
  364.                 PAINT, PAINT, PAINT, PAINT);
  365.     }
  366.  
  367. erase_compound(c)
  368. F_compound    *c;
  369. {
  370.     draw_compoundelements(c, background_color, background_color,
  371.                 ERASE, ERASE, INV_PAINT, ERASE);
  372.     }
  373.  
  374. draw_compoundelements(c, arcop, ellipseop, lineop, splineop, textop, compop)
  375. F_compound    *c;
  376. int        arcop, ellipseop, lineop, splineop, textop, compop;
  377. {
  378.     F_line        *l;
  379.     F_spline    *s;
  380.     F_ellipse    *e;
  381.     F_text        *t;
  382.     F_arc        *a;
  383.     F_compound    *c1;
  384.     
  385.     for (l = c->lines; l != NULL; l = l->next) {
  386.         draw_line(l, lineop);
  387.         }
  388.     for (s = c->splines; s != NULL; s = s->next) {
  389.         draw_spline(s, splineop);
  390.        } 
  391.     for (a = c->arcs; a != NULL; a = a->next) {
  392.         draw_arc(a, arcop);
  393.        } 
  394.     for (e = c->ellipses; e != NULL; e = e->next) {
  395.         draw_ellipse(e, ellipseop);
  396.         }
  397.     for (t = c->texts; t != NULL; t = t->next) {
  398.         draw_text(t, textop);
  399.         }
  400.     for (c1 = c->compounds; c1 != NULL; c1 = c1->next) {
  401.         draw_compoundbox(c1, INV_PAINT);
  402.         compop == ERASE ? erase_compound(c1) : draw_compound(c1);
  403.         }
  404.     }
  405.  
  406. F_compound *
  407. compound_search(x, y, tolerance, px, py)
  408. int    x, y, tolerance, *px, *py;
  409. {
  410.     F_compound    *c;
  411.     float        tol2;
  412.  
  413.     tol2 = tolerance * tolerance;
  414.     
  415.     for (c = objects.compounds; c != NULL; c = c->next) {
  416.         if (close_to_vector(c->nwcorner.x, c->nwcorner.y, c->nwcorner.x,
  417.             c->secorner.y, x, y, tolerance, tol2, px, py)) 
  418.         return(c);
  419.         if (close_to_vector(c->secorner.x, c->secorner.y, c->nwcorner.x,
  420.             c->secorner.y, x, y, tolerance, tol2, px, py)) 
  421.         return(c);
  422.         if (close_to_vector(c->secorner.x, c->secorner.y, c->secorner.x,
  423.             c->nwcorner.y, x, y, tolerance, tol2, px, py)) 
  424.         return(c);
  425.         if (close_to_vector(c->nwcorner.x, c->nwcorner.y, c->secorner.x,
  426.             c->nwcorner.y, x, y, tolerance, tol2, px, py)) 
  427.         return(c);
  428.         }
  429.     return(NULL);
  430.     }
  431.  
  432. toggle_compoundpointmarker(c)
  433. F_compound    *c;
  434. {
  435.     F_line        *l;
  436.     F_spline    *s;
  437.     F_ellipse    *e;
  438.     F_arc        *a;
  439.  
  440.     for (l = c->lines; l != NULL; l = l->next) {
  441.         toggle_linepointmarker(l);
  442.         }
  443.     for (s = c->splines; s != NULL; s = s->next) {
  444.         toggle_splinepointmarker(s);
  445.        } 
  446.     for (a = c->arcs; a != NULL; a = a->next) {
  447.         toggle_arcpointmarker(a);
  448.        } 
  449.     for (e = c->ellipses; e != NULL; e = e->next) {
  450.         toggle_ellipsepointmarker(e);
  451.         }
  452.     }
  453.  
  454. show_compoundbox()
  455. {
  456.     F_compound    *c;
  457.  
  458.     if (compoundbox_shown) return;
  459.     compoundbox_shown = 1;
  460.     for (c = objects.compounds; c != NULL; c = c->next) 
  461.         draw_compoundbox(c, INV_PAINT);
  462.     }
  463.  
  464. erase_compoundbox()
  465. {
  466.     F_compound    *c;
  467.  
  468.     if (! compoundbox_shown) return;
  469.     compoundbox_shown = 0;
  470.     for (c = objects.compounds; c != NULL; c = c->next) 
  471.         draw_compoundbox(c, INV_PAINT);
  472.     }
  473.  
  474.  
  475.  
  476.