home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / cbgi111 / src / bgipline.h < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-03  |  11.5 KB  |  510 lines

  1. /************************************************************************/
  2. /*    Line drawing routine valid for all bitmap devices with only    */
  3. /*  some macro changes.  Line is drawn and clipped using standard     */
  4. /*  routines with address optimization used for speed.            */
  5. /*                                    */
  6. /*    REQUIRED MACROS:                        */
  7. /*        CALC_ADDR( x, y)                    */
  8. /*        X_INCREMENT_CALC()                    */
  9. /*        Y_INCREMENT_CALC()                    */
  10. /*        Y_DECREMENT_CALC()                    */
  11. /*        XOR_POINT( colour)                    */
  12. /*        POINT( colour)                        */
  13. /*                                    */
  14. /*    V 1.00 20/05/90 Robert Adsett Release version.  Clean out site    */
  15. /*                specific header files.            */
  16. /************************************************************************/
  17.  
  18. #define TRUE    1            /* TRUE/FALSE            */
  19. #define FALSE    0
  20.  
  21. static int l_clip(            /* Clip line.            */
  22.     int *x1,
  23.     int *y1,
  24.     int *x2,
  25.     int *y2
  26.     );
  27. static void outcodes(
  28.     int     x,            /* Point.            */
  29.     int    y,
  30.     int    out[4]            /* Boundary flags.        */
  31.     );
  32. static int rej_chk(
  33.     int    out1[4],        /* Outcodes.            */
  34.     int    out2[4]
  35.     );
  36. static int acc_chk(
  37.     int    out1[4],        /* Outcodes.            */
  38.     int    out2[4]
  39.     );
  40. static void sw_out(                 /* swap ends.        */
  41.     int    out1[4], 
  42.     int    out2[4],
  43.     int    *x1, 
  44.     int    *y1, 
  45.     int    *x2, 
  46.     int    *y2
  47.     );
  48.  
  49. int line( int X, int Y, int X1, int Y1)
  50. {
  51. int delta_x, delta_y, incr1, incr2, d, i = 0;
  52. int x3, x4, y3, y4, x5, y5;
  53.  
  54. if( !l_clip( &X, &Y, &X1, &Y1))        /*  clip line to limits        */
  55.     {                    /*  if outside limits return    */
  56.     return( OUT_OF_RANGE);        /*  without drawing.        */
  57.     }
  58.      
  59.  
  60. if( X < X1)
  61.     {
  62.     x3 = X;
  63.     x4 = X1;
  64.     y3 = Y;
  65.     y4 = Y1;
  66.     }
  67. else
  68.     {
  69.     x4 = X;
  70.     x3 = X1;
  71.     y3 = Y1;
  72.     y4 = Y;
  73.     }
  74.  
  75. delta_x = x4 - x3;
  76. delta_y = y4 - y3;
  77.  
  78. if( delta_y > 0)
  79.     {                    /*  positive slope        */
  80.     if( delta_y < delta_x )
  81.          {                /*  slope < 1            */
  82.      incr1 = 2 * delta_y;
  83.      d = 2 * delta_y - delta_x;
  84.      incr2 = 2 * (delta_y - delta_x);
  85.      x5 =  x3;
  86.          y5 =  y3;
  87.          CALC_ADDR( x5, y5);
  88.      if( current_line_style & line_style_mask[ (i++ & 15)])
  89.           {
  90.           if( current_write_mode == XOR)
  91.                {
  92.            XOR_POINT( current_colour);
  93.            }
  94.           else
  95.                {
  96.                POINT( current_colour);
  97.            }
  98.           }
  99.  
  100.      while( x3 < x4)
  101.           {
  102.           x3++;
  103.           X_INCREMENT_CALC();
  104.           if( current_line_style & line_style_mask[ (i++ & 15)])
  105.                {
  106.                if( current_write_mode == XOR)
  107.                     {
  108.                 XOR_POINT( current_colour);
  109.                 }
  110.                else
  111.                     {
  112.                     POINT( current_colour);
  113.                 }
  114.                }
  115.  
  116.           if( d < 0)
  117.                {
  118.            d += incr1;
  119.            }
  120.           else
  121.                {
  122.            d += incr2;
  123.            Y_INCREMENT_CALC();
  124.                if( current_line_style & line_style_mask[ (i++ & 15)])
  125.                     {
  126.                     if( current_write_mode == XOR)
  127.                          {
  128.                      XOR_POINT( current_colour);
  129.                      }
  130.                     else
  131.                          {
  132.                          POINT( current_colour);
  133.                      }
  134.                     }
  135.            }
  136.           }     /* end while x3 > x4 */
  137.      }
  138.     else                    /*  slope >= 1        */
  139.          {
  140.      incr1 = 2 * delta_x;
  141.      d = 2 * delta_x - delta_y;
  142.      incr2 = 2 * (delta_x - delta_y);
  143.      x5 =  x3;
  144.          y5 =  y3;
  145.          CALC_ADDR( x5, y5);
  146.      if( current_line_style & line_style_mask[ (i++ & 15)])
  147.           {
  148.           if( current_write_mode == XOR)
  149.                {
  150.            XOR_POINT( current_colour);
  151.            }
  152.           else
  153.                {
  154.                POINT( current_colour);
  155.            }
  156.           }
  157.  
  158.      while( y3 < y4)
  159.           {
  160.           y3++;
  161.           Y_INCREMENT_CALC();
  162.           if( current_line_style & line_style_mask[ (i++ & 15)])
  163.                {
  164.                if( current_write_mode == XOR)
  165.                     {
  166.                 XOR_POINT( current_colour);
  167.                 }
  168.                else
  169.                     {
  170.                     POINT( current_colour);
  171.                 }
  172.                }
  173.           if( d < 0)
  174.                {
  175.            d += incr1;
  176.            }
  177.           else
  178.                {
  179.            d += incr2;
  180.            X_INCREMENT_CALC();
  181.                if( current_line_style & line_style_mask[ (i++ & 15)])
  182.                     {
  183.                     if( current_write_mode == XOR)
  184.                          {
  185.                      XOR_POINT( current_colour);
  186.                      }
  187.                     else
  188.                          {
  189.                          POINT( current_colour);
  190.                      }
  191.                     }
  192.            }
  193.           } /* end while y3 < y4  */
  194.      }  /* Done slope > 1 */
  195.     }  /* Done positive slope. */
  196. else
  197.     {                    /*  negative slope        */
  198.     if( -delta_y < delta_x)        /*  slope > -1            */
  199.          {
  200.      incr1 = -2 * delta_y;
  201.      d = -2 * delta_y - delta_x;
  202.      incr2 = -2 * (delta_x + delta_y);
  203.      x5 =  x3;
  204.          y5 =  y3;
  205.          CALC_ADDR( x5, y5);
  206.      if( current_line_style & line_style_mask[ (i++ & 15)])
  207.           {
  208.           if( current_write_mode == XOR)
  209.                {
  210.            XOR_POINT( current_colour);
  211.            }
  212.           else
  213.                {
  214.                POINT( current_colour);
  215.            }
  216.           }
  217.  
  218.      while( x3 < x4)
  219.           {
  220.           x3++;
  221.           X_INCREMENT_CALC();
  222.           if( current_line_style & line_style_mask[ (i++ & 15)])
  223.                {
  224.                if( current_write_mode == XOR)
  225.                     {
  226.                 XOR_POINT( current_colour);
  227.                 }
  228.                else
  229.                     {
  230.                     POINT( current_colour);
  231.                 }
  232.                }
  233.           if( d < 0)
  234.                {
  235.            d += incr1;
  236.            }
  237.           else
  238.                {
  239.            d += incr2;
  240.            Y_DECREMENT_CALC();
  241.                if( current_line_style & line_style_mask[ (i++ & 15)])
  242.                     {
  243.                     if( current_write_mode == XOR)
  244.                          {
  245.                      XOR_POINT( current_colour);
  246.                      }
  247.                     else
  248.                          {
  249.                          POINT( current_colour);
  250.                      }
  251.                     }
  252.            }
  253.           } /* end while x3 < x4 */
  254.      }  
  255.     else
  256.          {                    /* slope <= -1        */
  257.      d = 2 * delta_x + delta_y;
  258.      incr1 = 2 * delta_x;
  259.      incr2 = 2 * (delta_x + delta_y);
  260.      x5 =  x3;
  261.          y5 =  y3;
  262.          CALC_ADDR( x5, y5);
  263.      if( current_line_style & line_style_mask[ (i++ & 15)])
  264.           {
  265.           if( current_write_mode == XOR)
  266.                {
  267.            XOR_POINT( current_colour);
  268.            }
  269.           else
  270.                {
  271.                POINT( current_colour);
  272.            }
  273.           }
  274.  
  275.      while( y3 > y4)
  276.           {
  277.           y3--;
  278.           Y_DECREMENT_CALC();
  279.           if( current_line_style & line_style_mask[ (i++ & 15)])
  280.                {
  281.                if( current_write_mode == XOR)
  282.                     {
  283.                 XOR_POINT( current_colour);
  284.                 }
  285.                else
  286.                     {
  287.                     POINT( current_colour);
  288.                 }
  289.                }
  290.           if( d < 0)
  291.                {
  292.            d += incr1;
  293.            }
  294.           else
  295.                {
  296.            d += incr2;
  297.            X_INCREMENT_CALC();
  298.                if( current_line_style & line_style_mask[ (i++ & 15)])
  299.                     {
  300.                     if( current_write_mode == XOR)
  301.                          {
  302.                      XOR_POINT( current_colour);
  303.                      }
  304.                     else
  305.                          {
  306.                          POINT( current_colour);
  307.                      }
  308.                     }
  309.            }
  310.           } /* end while y3 > y4 */
  311.      } /* end slope >= -1 */
  312.     } /* end negative slope */
  313. return( 0);
  314. }
  315.  
  316. static int l_clip(
  317.     int *x1,
  318.     int *y1,
  319.     int *x2,
  320.     int *y2
  321.     )
  322. {
  323. int    accept, done, out1[4], out2[4];
  324.  
  325. accept = done = FALSE;            /* Not done.            */
  326. do
  327.     {
  328.     outcodes( *x1, *y1, out1);        /* Check line beginning against    */
  329.                         /* clip boundaries.        */
  330.     outcodes( *x2, *y2, out2);        /* Check line end against    */
  331.                         /* clip boundaries.        */
  332.     if( rej_chk( out1, out2))        /* Trivial  reject?        */
  333.          {
  334.      done = TRUE;            /* reject.            */
  335.      }
  336.     else
  337.      {                /* Trivial acceptance?        */
  338.      if( (accept = acc_chk( out1, out2)) != FALSE)
  339.           {
  340.           done = TRUE;        /* Accept.            */
  341.           }
  342.      else                 /* Must clip.            */
  343.           {
  344.           if( !(out1[0] | out1[1] | out1[2] | out1[3]))
  345.                {            /* This end ok.            */
  346.            sw_out( out1, out2, x1, y1, x2, y2); /* swap ends.    */
  347.            }
  348.           if( out1[0] )
  349.                {
  350.            *x1 = *x1 + ((*x2 - *x1) * ( MAXY - *y1)) /(*y2 - *y1);
  351.            *y1 = MAXY;
  352.            }
  353.           else if( out1[1] )
  354.                {
  355.            *x1 = *x1 + ((*x2 - *x1) * ( -*y1))/(*y2 - *y1);
  356.            *y1 = 0;
  357.            }
  358.           else if( out1[2] )
  359.                {
  360.            *y1 = *y1 + ((*y2 - *y1)*( MAXX - *x1))/(*x2 - *x1);
  361.            *x1 = MAXX;
  362.            }
  363.           else if( out1[3] )
  364.                {
  365.            *y1 = *y1 + ((*y2 - *y1)*( -*x1))/(*x2 - *x1);
  366.            *x1 = 0;
  367.            }
  368.           }
  369.      }
  370.      }while( !done);
  371. if( accept )            /* Accepted.                */
  372.     {
  373.     return( TRUE );
  374.     }
  375. else                /* Rejected.                */
  376.     {
  377.     return( FALSE);
  378.     }
  379. }
  380.  
  381. /************************************************************************/
  382. /*                                    */
  383. /*    Checks to see if the point is outside the clip boundaries    */
  384. /*  and sets the appropriate flags.                    */
  385. /*                                    */
  386. /*        V 1.00 May  24, 1986    R.T.A.                */
  387. /*                                    */
  388. /************************************************************************/
  389.  
  390. static void outcodes(
  391.     int     x,            /* Point.            */
  392.     int    y,
  393.     int    out[4]            /* Boundary flags.        */
  394.     )
  395. {
  396. int    i;                /* index.            */
  397.  
  398. for( i =0; i <=3; i++)
  399.     {
  400.     out[i] = 0;                /* Init flags.            */
  401.     }
  402. if( y > MAXY )                /* Above.            */
  403.     {
  404.     out[0] = 1;
  405.     }
  406. else if( y < MINY )            /* Below.            */
  407.     {
  408.     out[1] = 1;
  409.     }
  410. if( x > MAXX )                /* Right.            */
  411.     {
  412.     out[2] = 1;
  413.     }
  414. else if( x <  MINX )            /* Left.            */
  415.     {
  416.     out[3] =  1;
  417.     }
  418. }                    /* Th-Th-That's all Folk's.    */
  419.  
  420. /************************************************************************/
  421. /*                                    */
  422. /*    Checks the outcodes for the trivial rejection case.        */
  423. /*                                    */
  424. /*        V 1.00 May  24, 1986    R.T.A.                */
  425. /*                                    */
  426. /************************************************************************/
  427.  
  428. static int rej_chk(
  429.     int    out1[4],        /* Outcodes.            */
  430.     int    out2[4]
  431.     )
  432. {
  433. int    i;                /* Index.            */
  434.  
  435. for( i = 0; i <= 3; i++)
  436.     {
  437.     if( out1[i] & out2[i])        /* Both ends outside ?        */
  438.          {
  439.      return( TRUE );        /* Yes.                */
  440.      }
  441.     }
  442. return( FALSE );            /* Can't Reject.        */
  443. }
  444.  
  445. /************************************************************************/
  446. /*                                    */
  447. /*    Checks outcodes for the case of trivial acceptance.        */
  448. /*                                    */
  449. /*        V 1.00 May  24, 1986    R.T.A.                */
  450. /*                                    */
  451. /************************************************************************/
  452.  
  453. static int acc_chk(
  454.     int    out1[4],        /* Outcodes.            */
  455.     int    out2[4]
  456.     )
  457. {
  458. int    i;                /* Index.            */
  459.  
  460. for( i = 0; i <= 3; i ++)
  461.     {
  462.     if( out1[i] )            /* Accept?            */
  463.          {
  464.      return( FALSE );        /* No.                */
  465.      }
  466.     if( out2[i] )            /* Accept?            */
  467.          {
  468.      return( FALSE );        /* No.                */
  469.      }
  470.     }
  471. return ( TRUE );            /* Got this far, accept.    */
  472. }
  473.  
  474. /************************************************************************/
  475. /*                                    */
  476. /*    Switches  outcodes and points for the clipper.            */
  477. /*                                    */
  478. /*        V 1.00 May  24, 1986    R.T.A.                */
  479. /*                                    */
  480. /************************************************************************/
  481.  
  482. static void sw_out(                 /* swap ends.        */
  483.     int    out1[4], 
  484.     int    out2[4],
  485.     int    *x1, 
  486.     int    *y1, 
  487.     int    *x2, 
  488.     int    *y2
  489.     )
  490. {
  491. int    temp;                /* Temporary.            */
  492. int    i, temp2;                   /* Index, temporary.             */
  493.  
  494. for( i = 0; i <= 3; i++)        /* Switch outcodes.        */
  495.     {
  496.     temp2 = out1[i];
  497.     out1[i] = out2[i];
  498.     out2[i] = temp2;
  499.     }
  500. temp = *x1;                /* Switch x's.            */
  501. *x1 = *x2;
  502. *x2 = temp;
  503. temp = *y1;                   /* Switch y's.            */
  504. *y1 = *y2;
  505. *y2 = temp;
  506. }
  507.  
  508.  
  509.  
  510.