home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume19 / xfig / part12 / u_bound.c next >
Encoding:
C/C++ Source or Header  |  1993-05-27  |  16.3 KB  |  639 lines

  1. /*
  2.  * FIG : Facility for Interactive Generation of figures
  3.  * Copyright (c) 1985 by Supoj Sutanthavibul
  4.  *
  5.  * "Permission to use, copy, modify, distribute, and sell this software and its
  6.  * documentation for any purpose is hereby granted without fee, provided that
  7.  * the above copyright notice appear in all copies and that both the copyright
  8.  * notice and this permission notice appear in supporting documentation. 
  9.  * No representations are made about the suitability of this software for 
  10.  * any purpose.  It is provided "as is" without express or implied warranty."
  11.  */
  12.  
  13. #include "fig.h"
  14. #include "resources.h"
  15. #include "object.h"
  16. #include "mode.h"
  17. #include "u_bound.h"
  18.  
  19. #define        Ninety_deg        M_PI_2
  20. #define        One_eighty_deg        M_PI
  21. #define        Two_seventy_deg        (M_PI + M_PI_2)
  22. #define        Three_sixty_deg        (M_PI + M_PI)
  23. #define        half(z1 ,z2)        ((z1+z2)/2.0)
  24.  
  25. /* macro which rounds DOWN the coordinates depending on point positioning mode */
  26. #define        floor_coords(x) \
  27.     if (cur_pointposn != P_ANY) { \
  28.         tmp_t = ((x) + 1) % posn_rnd[cur_pointposn]; \
  29.         (x) = (x) - tmp_t; \
  30.     }
  31.  
  32. /* macro which rounds UP the coordinates depending on point positioning mode */
  33. #define        ceil_coords(x) \
  34.     if (cur_pointposn != P_ANY) { \
  35.         (x) = (x) + posn_rnd[cur_pointposn]; \
  36.         tmp_t = (x)%posn_rnd[cur_pointposn]; \
  37.         (x) = (x) - tmp_t - 1; \
  38.     }
  39.  
  40. static void    points_bound();
  41. static void    int_spline_bound();
  42. static void    normal_spline_bound();
  43. static int    tmp_t;
  44.  
  45. arc_bound(arc, xmin, ymin, xmax, ymax)
  46.     F_arc       *arc;
  47.     int           *xmin, *ymin, *xmax, *ymax;
  48. {
  49.     float        alpha, beta;
  50.     double        dx, dy, radius;
  51.     int            bx, by, sx, sy;
  52.     int            half_wd;
  53.  
  54.     dx = arc->point[0].x - arc->center.x;
  55.     dy = arc->center.y - arc->point[0].y;
  56.     alpha = atan2(dy, dx);
  57.     if (alpha < 0.0)
  58.     alpha += Three_sixty_deg;
  59.     /* compute_angle returns value between 0 to 2PI */
  60.  
  61.     radius = sqrt((double) (dx * dx + dy * dy));
  62.  
  63.     dx = arc->point[2].x - arc->center.x;
  64.     dy = arc->center.y - arc->point[2].y;
  65.     beta = atan2(dy, dx);
  66.     if (beta < 0.0)
  67.     beta += Three_sixty_deg;
  68.  
  69.     bx = max2(arc->point[0].x, arc->point[1].x);
  70.     bx = max2(arc->point[2].x, bx);
  71.     by = max2(arc->point[0].y, arc->point[1].y);
  72.     by = max2(arc->point[2].y, by);
  73.     sx = min2(arc->point[0].x, arc->point[1].x);
  74.     sx = min2(arc->point[2].x, sx);
  75.     sy = min2(arc->point[0].y, arc->point[1].y);
  76.     sy = min2(arc->point[2].y, sy);
  77.  
  78.     if (arc->direction == 1) {    /* counter clockwise */
  79.     if (alpha > beta) {
  80.         if (alpha <= 0 || 0 <= beta)
  81.         bx = (int) (arc->center.x + radius + 1.0);
  82.         if (alpha <= Ninety_deg || Ninety_deg <= beta)
  83.         sy = (int) (arc->center.y - radius - 1.0);
  84.         if (alpha <= One_eighty_deg || One_eighty_deg <= beta)
  85.         sx = (int) (arc->center.x - radius - 1.0);
  86.         if (alpha <= Two_seventy_deg || Two_seventy_deg <= beta)
  87.         by = (int) (arc->center.y + radius + 1.0);
  88.     } else {
  89.         if (0 <= beta && alpha <= 0)
  90.         bx = (int) (arc->center.x + radius + 1.0);
  91.         if (Ninety_deg <= beta && alpha <= Ninety_deg)
  92.         sy = (int) (arc->center.y - radius - 1.0);
  93.         if (One_eighty_deg <= beta && alpha <= One_eighty_deg)
  94.         sx = (int) (arc->center.x - radius - 1.0);
  95.         if (Two_seventy_deg <= beta && alpha <= Two_seventy_deg)
  96.         by = (int) (arc->center.y + radius + 1.0);
  97.     }
  98.     } else {            /* clockwise     */
  99.     if (alpha > beta) {
  100.         if (beta <= 0 && 0 <= alpha)
  101.         bx = (int) (arc->center.x + radius + 1.0);
  102.         if (beta <= Ninety_deg && Ninety_deg <= alpha)
  103.         sy = (int) (arc->center.y - radius - 1.0);
  104.         if (beta <= One_eighty_deg && One_eighty_deg <= alpha)
  105.         sx = (int) (arc->center.x - radius - 1.0);
  106.         if (beta <= Two_seventy_deg && Two_seventy_deg <= alpha)
  107.         by = (int) (arc->center.y + radius + 1.0);
  108.     } else {
  109.         if (0 <= alpha || beta <= 0)
  110.         bx = (int) (arc->center.x + radius + 1.0);
  111.         if (Ninety_deg <= alpha || beta <= Ninety_deg)
  112.         sy = (int) (arc->center.y - radius - 1.0);
  113.         if (One_eighty_deg <= alpha || beta <= One_eighty_deg)
  114.         sx = (int) (arc->center.x - radius - 1.0);
  115.         if (Two_seventy_deg <= alpha || beta <= Two_seventy_deg)
  116.         by = (int) (arc->center.y + radius + 1.0);
  117.     }
  118.     }
  119.     half_wd = arc->thickness / 2;
  120.     *xmax = bx + half_wd;
  121.     *ymax = by + half_wd;
  122.     *xmin = sx - half_wd;
  123.     *ymin = sy - half_wd;
  124. }
  125.  
  126. compound_bound(compound, xmin, ymin, xmax, ymax)
  127.     F_compound       *compound;
  128.     int           *xmin, *ymin, *xmax, *ymax;
  129. {
  130.     F_arc       *a;
  131.     F_ellipse       *e;
  132.     F_compound       *c;
  133.     F_spline       *s;
  134.     F_line       *l;
  135.     F_text       *t;
  136.     int            bx, by, sx, sy, first = 1;
  137.     int            llx, lly, urx, ury;
  138.  
  139.     for (a = compound->arcs; a != NULL; a = a->next) {
  140.     arc_bound(a, &sx, &sy, &bx, &by);
  141.     if (first) {
  142.         first = 0;
  143.         llx = sx;
  144.         lly = sy;
  145.         urx = bx;
  146.         ury = by;
  147.     } else {
  148.         llx = min2(llx, sx);
  149.         lly = min2(lly, sy);
  150.         urx = max2(urx, bx);
  151.         ury = max2(ury, by);
  152.     }
  153.     }
  154.  
  155.     for (c = compound->compounds; c != NULL; c = c->next) {
  156.     sx = c->nwcorner.x;
  157.     sy = c->nwcorner.y;
  158.     bx = c->secorner.x;
  159.     by = c->secorner.y;
  160.     if (first) {
  161.         first = 0;
  162.         llx = sx;
  163.         lly = sy;
  164.         urx = bx;
  165.         ury = by;
  166.     } else {
  167.         llx = min2(llx, sx);
  168.         lly = min2(lly, sy);
  169.         urx = max2(urx, bx);
  170.         ury = max2(ury, by);
  171.     }
  172.     }
  173.  
  174.     for (e = compound->ellipses; e != NULL; e = e->next) {
  175.     ellipse_bound(e, &sx, &sy, &bx, &by);
  176.     if (first) {
  177.         first = 0;
  178.         llx = sx;
  179.         lly = sy;
  180.         urx = bx;
  181.         ury = by;
  182.     } else {
  183.         llx = min2(llx, sx);
  184.         lly = min2(lly, sy);
  185.         urx = max2(urx, bx);
  186.         ury = max2(ury, by);
  187.     }
  188.     }
  189.  
  190.     for (l = compound->lines; l != NULL; l = l->next) {
  191.     line_bound(l, &sx, &sy, &bx, &by);
  192.     if (first) {
  193.         first = 0;
  194.         llx = sx;
  195.         lly = sy;
  196.         urx = bx;
  197.         ury = by;
  198.     } else {
  199.         llx = min2(llx, sx);
  200.         lly = min2(lly, sy);
  201.         urx = max2(urx, bx);
  202.         ury = max2(ury, by);
  203.     }
  204.     }
  205.  
  206.     for (s = compound->splines; s != NULL; s = s->next) {
  207.     spline_bound(s, &sx, &sy, &bx, &by);
  208.     if (first) {
  209.         first = 0;
  210.         llx = sx;
  211.         lly = sy;
  212.         urx = bx;
  213.         ury = by;
  214.     } else {
  215.         llx = min2(llx, sx);
  216.         lly = min2(lly, sy);
  217.         urx = max2(urx, bx);
  218.         ury = max2(ury, by);
  219.     }
  220.     }
  221.  
  222.     for (t = compound->texts; t != NULL; t = t->next) {
  223.     int    dum;
  224.     text_bound_actual(t, t->angle, &sx, &sy, &bx, &by, 
  225.               &dum,&dum,&dum,&dum,&dum,&dum,&dum,&dum);
  226.     if (first) {
  227.         first = 0;
  228.         llx = sx;
  229.         lly = sy;
  230.         urx = bx;
  231.         ury = by;
  232.     } else {
  233.         llx = min2(llx, sx);
  234.         lly = min2(lly, sy);
  235.         urx = max2(urx, bx);
  236.         ury = max2(ury, by);
  237.     }
  238.     }
  239.  
  240.     /* round the corners to the current positioning grid */
  241.     floor_coords(llx);
  242.     floor_coords(lly);
  243.     ceil_coords(urx);
  244.     ceil_coords(ury);
  245.     *xmin = llx;
  246.     *ymin = lly;
  247.     *xmax = urx;
  248.     *ymax = ury;
  249. }
  250.  
  251. /* basically, use the code for drawing the ellipse to find its bounds */
  252. /* From James Tough (see u_draw.c: angle_ellipse() */
  253. /* include the bounds for the markers (even though we don't know if they 
  254.    are on or off now */
  255.  
  256. ellipse_bound(e, xmin, ymin, xmax, ymax)
  257.     F_ellipse       *e;
  258.     int           *xmin, *ymin, *xmax, *ymax;
  259. {
  260.     int        half_wd;
  261.     double        c1, c2, c3, c4, c5, c6, v1, cphi, sphi, cphisqr, sphisqr;
  262.     double        xleft, xright, d, asqr, bsqr;
  263.     int        yymax, yy=0;
  264.     float        xcen, ycen, a, b; 
  265.  
  266.     xcen = e->center.x;
  267.     ycen = e->center.y;
  268.     a = e->radiuses.x;
  269.     b = e->radiuses.y;
  270.     if (a==0 || b==0)
  271.         {
  272.         *xmin = *xmax = xcen;
  273.         *ymin = *ymax = ycen;
  274.         return;
  275.         }
  276.  
  277.     cphi = cos((double)e->angle);
  278.     sphi = sin((double)e->angle);
  279.     cphisqr = cphi*cphi;
  280.     sphisqr = sphi*sphi;
  281.     asqr = a*a;
  282.     bsqr = b*b;
  283.     
  284.     c1 = (cphisqr/asqr)+(sphisqr/bsqr);
  285.     c2 = ((cphi*sphi/asqr)-(cphi*sphi/bsqr))/c1;
  286.     c3 = (bsqr*cphisqr) + (asqr*sphisqr);
  287.     yymax = sqrt(c3);
  288.     c4 = a*b/c3;
  289.     c5 = 0;
  290.     v1 = c4*c4;
  291.     c6 = 2*v1;
  292.     c3 = c3*v1-v1;
  293.     /* odd first points */
  294.     *xmin = *ymin =  100000;
  295.     *xmax = *ymax = -100000;
  296.     if (yymax % 2) {
  297.         d = sqrt(c3);
  298.         *xmin = min2(*xmin,xcen-d);
  299.         *xmax = max2(*xmax,xcen+d);
  300.         *ymin = min2(*ymin,ycen);
  301.         *ymax = max2(*ymax,ycen);
  302.         c5 = c2;
  303.         yy=1;
  304.     }
  305.     while (c3>=0) {
  306.         d = sqrt(c3);
  307.         xleft = c5-d;
  308.         xright = c5+d;                        
  309.         *xmin = min2(*xmin,xcen+xleft);
  310.         *xmax = max2(*xmax,xcen+xleft);
  311.         *ymax = max2(*ymax,ycen+yy);
  312.         *xmin = min2(*xmin,xcen+xright);
  313.         *xmax = max2(*xmax,xcen+xright);
  314.         *ymax = max2(*ymax,ycen+yy);
  315.         *xmin = min2(*xmin,xcen-xright);
  316.         *xmax = max2(*xmax,xcen-xright);
  317.         *ymin = min2(*ymin,ycen-yy);
  318.         *xmin = min2(*xmin,xcen-xleft);
  319.         *xmax = max2(*xmax,xcen-xleft);
  320.         *ymin = min2(*ymin,ycen-yy);
  321.         c5+=c2;
  322.         v1+=c6;
  323.         c3-=v1;
  324.         yy=yy+1;
  325.     }
  326.     /* for simplicity, just add half the line thickness to xmax and ymax
  327.        and subtract half from xmin and ymin */
  328.     half_wd = e->thickness/2;
  329.     *xmax += half_wd;
  330.     *ymax += half_wd;
  331.     *xmin -= half_wd;
  332.     *ymin -= half_wd;
  333.     /* now include the markers because they could be outside the bounds of 
  334.        the ellipse (+/-3 is (roughly) half the size of the markers (5)) */
  335.     *xmax = max2(*xmax, max2(e->start.x, e->end.x)+3);
  336.     *ymax = max2(*ymax, max2(e->start.y, e->end.y)+3);
  337.     *xmin = min2(*xmin, min2(e->start.x, e->end.x)-3);
  338.     *ymin = min2(*ymin, min2(e->start.y, e->end.y)-3);
  339. }
  340.  
  341. line_bound(l, xmin, ymin, xmax, ymax)
  342.     F_line       *l;
  343.     int           *xmin, *ymin, *xmax, *ymax;
  344. {
  345.     points_bound(l->points, (l->thickness / 2), xmin, ymin, xmax, ymax);
  346. }
  347.  
  348. spline_bound(s, xmin, ymin, xmax, ymax)
  349.     F_spline       *s;
  350.     int           *xmin, *ymin, *xmax, *ymax;
  351. {
  352.     if (int_spline(s)) {
  353.     int_spline_bound(s, xmin, ymin, xmax, ymax);
  354.     } else {
  355.     normal_spline_bound(s, xmin, ymin, xmax, ymax);
  356.     }
  357. }
  358.  
  359. static void
  360. int_spline_bound(s, xmin, ymin, xmax, ymax)
  361.     F_spline       *s;
  362.     int           *xmin, *ymin, *xmax, *ymax;
  363. {
  364.     F_point       *p1, *p2;
  365.     F_control       *cp1, *cp2;
  366.     float        x0, y0, x1, y1, x2, y2, x3, y3, sx1, sy1, sx2, sy2;
  367.     float        tx, ty, tx1, ty1, tx2, ty2;
  368.     float        sx, sy, bx, by;
  369.     int            half_wd;
  370.  
  371.     half_wd = s->thickness / 2;
  372.     p1 = s->points;
  373.     sx = bx = p1->x;
  374.     sy = by = p1->y;
  375.     cp1 = s->controls;
  376.     for (p2 = p1->next, cp2 = cp1->next; p2 != NULL;
  377.      p1 = p2, cp1 = cp2, p2 = p2->next, cp2 = cp2->next) {
  378.     x0 = p1->x;
  379.     y0 = p1->y;
  380.     x1 = cp1->rx;
  381.     y1 = cp1->ry;
  382.     x2 = cp2->lx;
  383.     y2 = cp2->ly;
  384.     x3 = p2->x;
  385.     y3 = p2->y;
  386.     tx = half(x1, x2);
  387.     ty = half(y1, y2);
  388.     sx1 = half(x0, x1);
  389.     sy1 = half(y0, y1);
  390.     sx2 = half(sx1, tx);
  391.     sy2 = half(sy1, ty);
  392.     tx2 = half(x2, x3);
  393.     ty2 = half(y2, y3);
  394.     tx1 = half(tx2, tx);
  395.     ty1 = half(ty2, ty);
  396.  
  397.     sx = min2(x0, sx);
  398.     sy = min2(y0, sy);
  399.     sx = min2(sx1, sx);
  400.     sy = min2(sy1, sy);
  401.     sx = min2(sx2, sx);
  402.     sy = min2(sy2, sy);
  403.     sx = min2(tx1, sx);
  404.     sy = min2(ty1, sy);
  405.     sx = min2(tx2, sx);
  406.     sy = min2(ty2, sy);
  407.     sx = min2(x3, sx);
  408.     sy = min2(y3, sy);
  409.  
  410.     bx = max2(x0, bx);
  411.     by = max2(y0, by);
  412.     bx = max2(sx1, bx);
  413.     by = max2(sy1, by);
  414.     bx = max2(sx2, bx);
  415.     by = max2(sy2, by);
  416.     bx = max2(tx1, bx);
  417.     by = max2(ty1, by);
  418.     bx = max2(tx2, bx);
  419.     by = max2(ty2, by);
  420.     bx = max2(x3, bx);
  421.     by = max2(y3, by);
  422.     }
  423.     *xmin = round(sx) - half_wd;
  424.     *ymin = round(sy) - half_wd;
  425.     *xmax = round(bx) + half_wd;
  426.     *ymax = round(by) + half_wd;
  427. }
  428.  
  429. static void
  430. normal_spline_bound(s, xmin, ymin, xmax, ymax)
  431.     F_spline       *s;
  432.     int           *xmin, *ymin, *xmax, *ymax;
  433. {
  434.     F_point       *p;
  435.     float        cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
  436.     float        x1, y1, x2, y2, sx, sy, bx, by;
  437.     float        px, py, qx, qy;
  438.     int            half_wd;
  439.  
  440.     half_wd = s->thickness / 2;
  441.     p = s->points;
  442.     x1 = p->x;
  443.     y1 = p->y;
  444.     p = p->next;
  445.     x2 = p->x;
  446.     y2 = p->y;
  447.     cx1 = (x1 + x2) / 2.0;
  448.     cy1 = (y1 + y2) / 2.0;
  449.     cx2 = (cx1 + x2) / 2.0;
  450.     cy2 = (cy1 + y2) / 2.0;
  451.     if (closed_spline(s)) {
  452.     x1 = (cx1 + x1) / 2.0;
  453.     y1 = (cy1 + y1) / 2.0;
  454.     }
  455.     sx = min2(x1, cx2);
  456.     sy = min2(y1, cy2);
  457.     bx = max2(x1, cx2);
  458.     by = max2(y1, cy2);
  459.  
  460.     for (p = p->next; p != NULL; p = p->next) {
  461.     x1 = x2;
  462.     y1 = y2;
  463.     x2 = p->x;
  464.     y2 = p->y;
  465.     cx4 = (x1 + x2) / 2.0;
  466.     cy4 = (y1 + y2) / 2.0;
  467.     cx3 = (x1 + cx4) / 2.0;
  468.     cy3 = (y1 + cy4) / 2.0;
  469.     cx2 = (cx4 + x2) / 2.0;
  470.     cy2 = (cy4 + y2) / 2.0;
  471.  
  472.     px = min2(cx2, cx3);
  473.     py = min2(cy2, cy3);
  474.     qx = max2(cx2, cx3);
  475.     qy = max2(cy2, cy3);
  476.  
  477.     sx = min2(sx, px);
  478.     sy = min2(sy, py);
  479.     bx = max2(bx, qx);
  480.     by = max2(by, qy);
  481.     }
  482.     if (closed_spline(s)) {
  483.     *xmin = round(sx) - half_wd;
  484.     *ymin = round(sy) - half_wd;
  485.     *xmax = round(bx) + half_wd;
  486.     *ymax = round(by) + half_wd;
  487.     } else {
  488.     *xmin = round(min2(sx, x2)) - half_wd;
  489.     *ymin = round(min2(sy, y2)) - half_wd;
  490.     *xmax = round(max2(bx, x2)) + half_wd;
  491.     *ymax = round(max2(by, y2)) + half_wd;
  492.     }
  493. }
  494.  
  495. /* This procedure calculates the bounding box for text that is displayed
  496.    horizontally or vertically (all text on the canvas in otherwords)
  497.    Use text_bound_actual() to decide whether or not text would be off
  498.    the PRINTED page (if rotated) */
  499.  
  500. text_bound(t, xmin, ymin, xmax, ymax)
  501.     F_text       *t;
  502.     int           *xmin, *ymin, *xmax, *ymax;
  503. {
  504.     int            length, dx, dy, mx, my, dum;
  505.     double        angle;
  506.  
  507.     angle = t->angle;
  508.     /* fix the angle to one of four - 0, 90, 180 or 270 */
  509.     if (angle < M_PI_2 - 0.001)
  510.     angle = 0.0;
  511.     else if (angle < M_PI - 0.001)
  512.     angle = M_PI_2;
  513.     else if (angle < 3*M_PI_2 - 0.001)
  514.     angle = M_PI;
  515.     else
  516.     angle = 3*M_PI_2;
  517.     text_bound_actual(t, angle, xmin, ymin, xmax, ymax,
  518.           &dum, &dum, &dum, &dum, &dum, &dum, &dum, &dum);
  519. }
  520.  
  521. /* this procedure calculates the bouding box for text ASSUMING that it 
  522.    will be DISPLAYED rotated (if it has any rotation angle).
  523.    The actual corners of the rectangle are returned in (rx1,ry1)...(rx4,ry4)
  524.    The min and max x and y are returned in (xmin, ymin) (xmax, ymax)
  525. */
  526.  
  527. text_bound_actual(t, angle, xmin, ymin, xmax, ymax, 
  528.           rx1, ry1, rx2, ry2, rx3, ry3, rx4, ry4)
  529.     F_text       *t;
  530.     double        angle;
  531.     int           *xmin, *ymin, *xmax, *ymax;
  532.     int           *rx1,*ry1, *rx2,*ry2, *rx3,*ry3, *rx4,*ry4;
  533. {
  534.     int            h, l;
  535.     int            x1,y1, x2,y2, x3,y3, x4,y4;
  536.     double        cost, sint;
  537.     double        lcost, lsint, hcost, hsint;
  538.  
  539.     l = text_length(t);
  540.     h = t->height;
  541.     cost = cos((double)angle);
  542.     sint = sin((double)angle);
  543.     lcost = round(l*cost);
  544.     lsint = round(l*sint);
  545.     hcost = round(h*cost);
  546.     hsint = round(h*sint);
  547.     x1 = t->base_x;
  548.     y1 = t->base_y;
  549.     if (t->type == T_CENTER_JUSTIFIED) {
  550.     x1 = t->base_x - round((l/2)*cost);
  551.     y1 = t->base_y + round((l/2)*sint);
  552.     x2 = x1 + lcost;
  553.     y2 = y1 - lsint;
  554.     }
  555.     else if (t->type == T_RIGHT_JUSTIFIED) {
  556.     x1 = t->base_x - lcost;
  557.     y1 = t->base_y + lsint;
  558.     x2 = t->base_x;
  559.     y2 = t->base_y;
  560.     }
  561.     else {
  562.     x2 = x1 + lcost;
  563.     y2 = y1 - lsint;
  564.     }
  565.     x4 = x1 - hsint;
  566.     y4 = y1 - hcost;
  567.     x3 = x2 - hsint;
  568.     y3 = y2 - hcost;
  569.  
  570.     *xmin = min2(x1,min2(x2,min2(x3,x4)));
  571.     *xmax = max2(x1,max2(x2,max2(x3,x4)));
  572.     *ymin = min2(y1,min2(y2,min2(y3,y4)));
  573.     *ymax = max2(y1,max2(y2,max2(y3,y4)));
  574.     *rx1=x1; *ry1=y1;
  575.     *rx2=x2; *ry2=y2;
  576.     *rx3=x3; *ry3=y3;
  577.     *rx4=x4; *ry4=y4;
  578. }
  579.  
  580. /* this procedure calculates the union of the two types of bounding boxes */
  581. /* this is usually called by the redisplay code which needs the bounding
  582.    rectangle if the user is displaying the textoutline */
  583.  
  584. text_bound_both(t, xmin, ymin, xmax, ymax,
  585.           rx1, ry1, rx2, ry2, rx3, ry3, rx4, ry4)
  586.     F_text      *t;
  587.     int          *xmin, *ymin, *xmax, *ymax;
  588.     int           *rx1,*ry1, *rx2,*ry2, *rx3,*ry3, *rx4,*ry4;
  589. {
  590.     int           xmin1, ymin1, xmax1, ymax1;
  591.     int           xmin2, ymin2, xmax2, ymax2;
  592.     int           dum;
  593.     text_bound_actual(t, t->angle, &xmin1, &ymin1, &xmax1, &ymax1, 
  594.           rx1, ry1, rx2, ry2, rx3, ry3, rx4, ry4);
  595.     text_bound(t, &xmin2, &ymin2, &xmax2, &ymax2);
  596.     *xmin = min2(xmin1,xmin2);
  597.     *xmax = max2(xmax1,xmax2);
  598.     *ymin = min2(ymin1,ymin2);
  599.     *ymax = max2(ymax1,ymax2);
  600. }
  601.  
  602. static void
  603. points_bound(points, half_wd, xmin, ymin, xmax, ymax)
  604.     F_point       *points;
  605.     int            half_wd;
  606.     int           *xmin, *ymin, *xmax, *ymax;
  607. {
  608.     int            bx, by, sx, sy;
  609.     F_point       *p;
  610.  
  611.     bx = sx = points->x;
  612.     by = sy = points->y;
  613.     for (p = points->next; p != NULL; p = p->next) {
  614.     sx = min2(sx, p->x);
  615.     sy = min2(sy, p->y);
  616.     bx = max2(bx, p->x);
  617.     by = max2(by, p->y);
  618.     }
  619.     *xmin = sx - half_wd;
  620.     *ymin = sy - half_wd;
  621.     *xmax = bx + half_wd;
  622.     *ymax = by + half_wd;
  623. }
  624.  
  625. int
  626. overlapping(xmin1, ymin1, xmax1, ymax1, xmin2, ymin2, xmax2, ymax2)
  627.     int            xmin1, ymin1, xmax1, ymax1, xmin2, ymin2, xmax2, ymax2;
  628. {
  629.     if (xmin1 < xmin2)
  630.     if (ymin1 < ymin2)
  631.         return (xmax1 >= xmin2 && ymax1 >= ymin2);
  632.     else
  633.         return (xmax1 >= xmin2 && ymin1 <= ymax2);
  634.     else if (ymin1 < ymin2)
  635.     return (xmin1 <= xmax2 && ymax1 >= ymin2);
  636.     else
  637.     return (xmin1 <= xmax2 && ymin1 <= ymax2);
  638. }
  639.