/************************************************************************/ /* Transfer source block of dimension DX x DY from XS,YS */ /* to XD, YD */ /************************************************************************/ slow_bitblt(xs, ys, xd, yd, dx, dy, fn) int xs, ys; /* Source upper left corner */ int xd, yd; /* Destination upper left */ int dx, dy; /* Dimensions of the block */ int fn; /* Logical operation */ { #define COPY 0 #define CLEAR 1 #define OR 2 #define XOR 3 #define AND 4 int x_incr, y_incr, x_max, y_max, x, y, i, j, value; /****************************************************************/ /* Compute starting points and directions of transfer */ /****************************************************************/ x = 0; /* Assume no overlap or ++ */ y = 0; /* i.e. xs > xd && ys > yd */ x_incr = 1; y_incr = 1; if (xs <= xd && xs + dx >= xd) /* Reverse x direction if source*/ { /* overlaps left half of dest. */ x = dx - 1; x_incr = -1; } if (ys > yd && ys <= yd + dy) /* Revers y direction if source */ { /* overlaps bottom half of dest */ y = dy - 1; y_incr = -1; } /****************************************************************/ /* Transfer the block */ /****************************************************************/ for (j = 0; j < dy; j++) /* Loop over rasters */ { for (i = 0; i < dx; i++) /* Loop over pixels */ { switch (fn) /* Select logical op */ { case COPY: value = pixel_read(xs+x,ys+y); pixel_write(xd+x,yd+y,value); break; case CLEAR: value = 0; pixel_write(xd+x,yd+y,value); break; case OR: value = pixel_read(xs+x,ys+y) | pixel_read(xd+x,yd+x); pixel_write(xd+x,yd+y,value); break; case XOR: value = pixel_read(xs+x,ys+y) ^ pixel_read(xd+x,yd+x); pixel_write(xd+x,yd+y,value); break; case AND: value = pixel_read(xs+x,ys+y) & pixel_read(xd+x,yd+x); pixel_write(xd+x,yd+y,value); break; default: break; } x += x_incr; /* Update pixel pointer */ } y += y_incr; /* Update raster pointer*/ x -= dx * x_incr; /* Reset pixel pointer */ } }