0,0 → 1,121 |
|
#define CLIP_TOP 1 |
#define CLIP_BOTTOM 2 |
#define CLIP_RIGHT 4 |
#define CLIP_LEFT 8 |
|
typedef struct |
{ |
int xmin; |
int ymin; |
int xmax; |
int ymax; |
}clip_t; |
|
|
static int _L1OutCode( clip_t *clip, int x, int y ) |
/*================================= |
|
Verify that a point is inside or outside the active viewport. */ |
{ |
int flag; |
|
flag = 0; |
if( x < clip->xmin ) { |
flag |= CLIP_LEFT; |
} else if( x > clip->xmax ) { |
flag |= CLIP_RIGHT; |
} |
if( y < clip->ymin ) { |
flag |= CLIP_TOP; |
} else if( y > clip->ymax ) { |
flag |= CLIP_BOTTOM; |
} |
return( flag ); |
}; |
|
static void block_inter( clip_t *clip, int *x, int *y, int flag ) |
/*====================================================== |
|
Find the intersection of a block with a boundary of the viewport. */ |
{ |
if( flag & CLIP_TOP ) { |
*y = clip->ymin; |
} else if( flag & CLIP_BOTTOM ) { |
*y = clip->ymax; |
} else if( flag & CLIP_RIGHT ) { |
*x = clip->xmax; |
} else if( flag & CLIP_LEFT ) { |
*x = clip->xmin; |
} |
} |
|
|
int BlockClip(clip_t *clip, int *x1, int *y1, int *x2, int* y2 ) |
/*============================================================== |
|
Clip a block with opposite corners (x1,y1) and (x2,y2) to the |
active viewport based on the Cohen-Sutherland algorithm for line |
clipping. Return the clipped coordinates and a decision drawing |
flag ( 0 draw : 1 don't draw ). */ |
{ |
int flag1; |
int flag2; |
|
flag1 = _L1OutCode( clip, *x1, *y1 ); |
flag2 = _L1OutCode( clip, *x2, *y2 ); |
for( ;; ) { |
if( flag1 & flag2 ) break; /* trivially outside */ |
if( flag1 == flag2 ) break; /* completely inside */ |
if( flag1 == 0 ) { |
block_inter( clip, x2, y2, flag2 ); |
flag2 = _L1OutCode( clip, *x2, *y2 ); |
} else { |
block_inter( clip, x1, y1, flag1 ); |
flag1 = _L1OutCode( clip, *x1, *y1 ); |
} |
} |
return( flag1 & flag2 ); |
} |
|
|
int blit_clip(clip_t *dst_clip,int *dst_x,int *dst_y, |
clip_t *src_clip,int *src_x, int *src_y, |
u32_t *w, u32_t *h) |
{ |
int sx0, sy0, sx1, sy1; |
|
sx0 = *src_x; |
sy0 = *src_y; |
|
sx1 = sx0 + *w - 1; |
sy1 = sy0 + *h - 1; |
|
|
if( ! BlockClip( src_clip, &sx0, &sy0, &sx1, &sy1)) |
{ |
int dx0, dy0, dx1, dy1; |
|
dx0 = *dst_x + sx0 - *src_x; |
dy0 = *dst_y + sy0 - *src_y; |
|
dx1 = dx0 + sx1 - sx0; |
dy1 = dy0 + sy1 - sy0; |
|
if( ! BlockClip( dst_clip, &dx0, &dy0, &dx1, &dy1)) |
{ |
*w = dx1 - dx0 + 1; |
*h = dy1 - dy0 + 1; |
|
*src_x += dx0 - *dst_x; |
*src_y += dy0 - *dst_y; |
|
*dst_x = dx0; |
*dst_y = dy0; |
|
return 0; |
}; |
} |
return 1; |
}; |
|