kolibrios/drivers/video/drm/radeon/clip.inc

122 lines
2.9 KiB
PHP
Raw Permalink Normal View History

#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;
};