Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1.  
  2. #define CLIP_TOP        1
  3. #define CLIP_BOTTOM     2
  4. #define CLIP_RIGHT      4
  5. #define CLIP_LEFT       8
  6.  
  7. typedef struct
  8. {
  9.   int xmin;
  10.   int ymin;
  11.   int xmax;
  12.   int ymax;
  13. }clip_t;
  14.  
  15.  
  16. static int _L1OutCode( clip_t *clip, int x, int y )
  17. /*=================================
  18.  
  19.     Verify that a point is inside or outside the active viewport.   */
  20. {
  21.     int   flag;
  22.  
  23.     flag = 0;
  24.     if( x < clip->xmin ) {
  25.         flag |= CLIP_LEFT;
  26.     } else if( x > clip->xmax ) {
  27.         flag |= CLIP_RIGHT;
  28.     }
  29.     if( y < clip->ymin ) {
  30.         flag |= CLIP_TOP;
  31.     } else if( y > clip->ymax ) {
  32.         flag |= CLIP_BOTTOM;
  33.     }
  34.     return( flag );
  35. };
  36.  
  37. static void block_inter( clip_t *clip, int *x, int *y, int flag )
  38. /*======================================================
  39.  
  40.     Find the intersection of a block with a boundary of the viewport.   */
  41. {
  42.     if( flag & CLIP_TOP ) {
  43.         *y = clip->ymin;
  44.     } else if( flag & CLIP_BOTTOM ) {
  45.         *y = clip->ymax;
  46.     } else if( flag & CLIP_RIGHT ) {
  47.         *x = clip->xmax;
  48.     } else if( flag & CLIP_LEFT ) {
  49.         *x = clip->xmin;
  50.     }
  51. }
  52.  
  53.  
  54. int BlockClip(clip_t *clip, int *x1, int *y1, int *x2, int* y2 )
  55. /*==============================================================
  56.  
  57.     Clip a block with opposite corners (x1,y1) and (x2,y2) to the
  58.     active viewport based on the Cohen-Sutherland algorithm for line
  59.     clipping. Return the clipped coordinates and a decision drawing
  60.     flag ( 0 draw : 1 don't draw ). */
  61. {
  62.    int  flag1;
  63.    int  flag2;
  64.  
  65.    flag1 = _L1OutCode( clip, *x1, *y1 );
  66.    flag2 = _L1OutCode( clip, *x2, *y2 );
  67.    for( ;; ) {
  68.        if( flag1 & flag2 ) break;                  /* trivially outside    */
  69.        if( flag1 == flag2 ) break;                 /* completely inside    */
  70.        if( flag1 == 0 ) {
  71.            block_inter( clip, x2, y2, flag2 );
  72.            flag2 = _L1OutCode( clip,  *x2, *y2 );
  73.        } else {
  74.            block_inter( clip, x1, y1, flag1 );
  75.            flag1 = _L1OutCode( clip, *x1, *y1 );
  76.        }
  77.    }
  78.    return( flag1 & flag2 );
  79. }
  80.  
  81.  
  82. int blit_clip(clip_t *dst_clip,int *dst_x,int *dst_y,
  83.              clip_t *src_clip,int *src_x, int *src_y,
  84.              u32_t *w, u32_t *h)
  85. {
  86.    int sx0, sy0, sx1, sy1;
  87.  
  88.    sx0 = *src_x;
  89.    sy0 = *src_y;
  90.  
  91.    sx1 = sx0 + *w - 1;
  92.    sy1 = sy0 + *h - 1;
  93.  
  94.  
  95.    if( ! BlockClip( src_clip, &sx0, &sy0, &sx1, &sy1))
  96.    {
  97.        int dx0, dy0, dx1, dy1;
  98.  
  99.        dx0 = *dst_x + sx0 - *src_x;
  100.        dy0 = *dst_y + sy0 - *src_y;
  101.  
  102.        dx1 = dx0 + sx1 - sx0;
  103.        dy1 = dy0 + sy1 - sy0;
  104.  
  105.        if( ! BlockClip( dst_clip, &dx0, &dy0, &dx1, &dy1))
  106.        {
  107.            *w = dx1 - dx0 + 1;
  108.            *h = dy1 - dy0 + 1;
  109.  
  110.            *src_x += dx0 - *dst_x;
  111.            *src_y += dy0 - *dst_y;
  112.  
  113.            *dst_x = dx0;
  114.            *dst_y = dy0;
  115.  
  116.            return 0;
  117.        };
  118.    }
  119.    return 1;
  120. };
  121.  
  122.