summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Ciccani <klan@users.sourceforge.net>2006-04-05 12:44:32 +0000
committerClaudio Ciccani <klan@users.sourceforge.net>2006-04-05 12:44:32 +0000
commit22924ef0924502e0d9b1652651d40270602ee7a0 (patch)
tree8eccf7727cda7370e357e7d738b2995ee5ce27b9
parent386bcef8381fe0813d8407c613d0e950887ee2f1 (diff)
downloadxine-lib-22924ef0924502e0d9b1652651d40270602ee7a0.tar.gz
xine-lib-22924ef0924502e0d9b1652651d40270602ee7a0.tar.bz2
Fixed primitive clipping.
Also negative coordinates are legal now. CVS patchset: 7958 CVS date: 2006/04/05 12:44:32
-rw-r--r--src/xine-engine/osd.c127
1 files changed, 77 insertions, 50 deletions
diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c
index 98f66d268..4a88b18ad 100644
--- a/src/xine-engine/osd.c
+++ b/src/xine-engine/osd.c
@@ -400,6 +400,11 @@ static void osd_point (osd_object_t *osd, int x, int y, int color) {
lprintf("osd=%p (%d x %d)\n", osd, x, y);
+ if (x < 0 || x >= osd->width)
+ return;
+ if (y < 0 || y >= osd->height)
+ return;
+
/* update clipping area */
osd->x1 = MIN(osd->x1, x);
osd->x2 = MAX(osd->x2, (x + 1));
@@ -407,8 +412,7 @@ static void osd_point (osd_object_t *osd, int x, int y, int color) {
osd->y2 = MAX(osd->y2, (y + 1));
c = osd->area + y * osd->width + x;
- if(c <= (osd->area + (osd->width * osd->height)))
- *c = color;
+ *c = color;
}
/*
@@ -420,47 +424,67 @@ static void osd_line (osd_object_t *osd,
uint8_t *c;
int dx, dy, t, inc, d, inc1, inc2;
+ int swap_x = 0;
+ int swap_y = 0;
lprintf("osd=%p (%d,%d)-(%d,%d)\n",osd, x1,y1, x2,y2 );
- /* clip line coordinates and update clipping area */
- if (x2 > x1) {
- if (x1 >= osd->width)
- return;
- x2 = MAX( x2, osd->width );
-
- osd->x1 = MIN( osd->x1, x1 );
- osd->x2 = MAX( osd->x2, x2 );
+ /* sort line */
+ if (x2 < x1) {
+ t = x1;
+ x1 = x2;
+ x2 = t;
+ swap_x = 1;
}
- else {
- if (x2 >= osd->width);
- return;
- x1 = MAX( x1, osd->width );
-
- osd->x1 = MIN( osd->x1, x2 );
- osd->x2 = MAX( osd->x2, x1 );
+ if (y2 < y1) {
+ t = y1;
+ y1 = y2;
+ y2 = t;
+ swap_y = 1;
+ }
+
+ /* clip line */
+ if (x1 < 0) {
+ y1 = y1 + (y2-y1) * -x1 / (x2-x1);
+ x1 = 0;
+ }
+ if (y1 < 0) {
+ x1 = x1 + (x2-x1) * -y1 / (y2-y1);
+ y1 = 0;
+ }
+ if (x2 > osd->width) {
+ y2 = y1 + (y2-y1) * (osd->width-x1) / (x2-x1);
+ x2 = osd->width;
+ }
+ if (y2 > osd->height) {
+ x2 = x1 + (x2-x1) * (osd->height-y1) / (y2-y1);
+ y2 = osd->height;
}
- if (y2 > y1) {
- if (y1 >= osd->height)
- return;
- y2 = MAX( y2, osd->height );
-
- osd->y1 = MIN( osd->y1, y1 );
- osd->y2 = MAX( osd->y2, y2 );
+ if (x1 >= osd->width || y1 >= osd->height)
+ return;
+
+ /* update clipping area */
+ osd->x1 = MIN( osd->x1, x1 );
+ osd->x2 = MAX( osd->x2, x2 );
+ osd->y1 = MIN( osd->y1, y1 );
+ osd->y2 = MAX( osd->y2, y2 );
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+
+ /* unsort line */
+ if (swap_x) {
+ t = x1;
+ x1 = x2;
+ x2 = t;
}
- else {
- if (y2 >= osd->height)
- return;
- y1 = MAX( y1, osd->height );
-
- osd->y1 = MIN( osd->y1, y2 );
- osd->y2 = MAX( osd->y2, y1 );
+ if (swap_y) {
+ t = y1;
+ y1 = y2;
+ y2 = t;
}
- dx = abs(x1-x2);
- dy = abs(y1-y2);
-
if( dx>=dy ) {
if( x1>x2 )
{
@@ -478,11 +502,7 @@ static void osd_line (osd_object_t *osd,
while(x1<x2)
{
-
- if(c <= (osd->area + (osd->width * osd->height)))
- *c = color;
-
- c++;
+ *c++ = color;
x1++;
if( d<0 ) {
@@ -508,9 +528,7 @@ static void osd_line (osd_object_t *osd,
c = osd->area + y1 * osd->width + x1;
while(y1<y2) {
-
- if(c <= (osd->area + (osd->width * osd->height)))
- *c = color;
+ *c = color;
c += osd->width;
y1++;
@@ -537,17 +555,26 @@ static void osd_filled_rect (osd_object_t *osd,
lprintf("osd=%p (%d,%d)-(%d,%d)\n",osd, x1,y1, x2,y2 );
- /* clip rectangle coordinates */
- x = MIN( x1, x2 );
- if (x >= osd->width)
- return;
+ /* sort rectangle */
+ x = MIN( x1, x2 );
dx = MAX( x1, x2 );
- dx = MAX( dx, osd->width );
+ y = MIN( y1, y2 );
+ dy = MAX( y1, y2 );
- y = MIN( y1, y2 );
- if (y >= osd->height)
+ /* clip rectangle */
+ if (x >= osd->width || y >= osd->height)
return;
- dy = MAX( y1, y2 );
+
+ if (x < 0) {
+ dx += x;
+ x = 0;
+ }
+ if (y < 0) {
+ dy += y;
+ y = 0;
+ }
+
+ dx = MAX( dx, osd->width );
dy = MAX( dy, osd->height );
/* update clipping area */