Looking for routine to expand bitmap
Arthur David Olson
ado at elsie.UUCP
Sat Aug 19 10:08:58 AEST 1989
Here's the X-Window-System code used to do such a job at elsie.
Doug Gwyn's code uses fewer bitblt operations;
this code applies operations to fewer bits.
--
X Window System is a trademark of the Massachusetts Institute of Technology.
--
Arthur David Olson ado at alw.nih.gov ADO is a trademark of Ampex.
static int
is_power_of_two(i)
int i;
{
if (i > 0)
while ((i % 2) == 0)
i /= 2;
return i == 1;
}
typedef enum {
FORWARD,
BACKWARD
} direction_t;
typedef enum {
DONTSWAPXY,
SWAPXY
} swapxy_t;
#define ROTCOPY(disp, src, dest, gc, sx, sy, w, h, dx, dy, swapxy) \
(((swapxy) == DONTSWAPXY) ? \
XCopyArea((disp), (src), (dest), (gc), \
(sx), (sy), \
(unsigned int) (w), (unsigned int) (h), \
(dx), (dy)) : \
XCopyArea((disp), (src), (dest), (gc), \
(sy), (sx), \
(unsigned int) (h), (unsigned int) (w), \
(dy), (dx)))
static void
smear(disp, drawable, gc, x, y, w, h, direction, swapxy)
Display * const disp;
const Drawable drawable;
const GC gc;
const int x, y, w, h;
const direction_t direction;
const swapxy_t swapxy;
{
register int src_x, dest_x;
register int done, copy_w;
if (h <= 0)
return;
for (done = 1; done < w; done += copy_w) {
copy_w = w - done;
if (copy_w > done)
copy_w = done;
if (direction == FORWARD) {
dest_x = x + done;
src_x = dest_x - copy_w;
} else {
src_x = x - done + 1;
dest_x = src_x - copy_w;
}
ROTCOPY(disp, drawable, drawable, gc,
src_x, y, copy_w, h, dest_x, y, swapxy);
}
}
static void
enlsub(disp, drawable, gc, x, y, z, w, h, swapxy)
Display * const disp;
const Drawable drawable;
const int x, y, z, w, h;
const GC gc;
const swapxy_t swapxy;
{
register int src_x, dest_x, copy_w;
register int special, final_z;
if (w <= z) {
smear(disp, drawable, gc, x, y, w, h, FORWARD, swapxy);
return;
}
copy_w = (w - 1) % z + 1;
src_x = x + (w - 1) / z - 1;
dest_x = x + w - copy_w - 1;
special = is_power_of_two(z - 1);
for ( ; ; ) {
ROTCOPY(disp, drawable, drawable, gc,
src_x, y, 2, h, dest_x, y, swapxy);
smear(disp, drawable, gc,
dest_x + 1, y, copy_w, h, FORWARD, swapxy);
if (src_x-- == x) {
final_z = z - 1;
break;
}
if (special && src_x > x) {
copy_w = z - 1;
dest_x -= z;
continue;
}
smear(disp, drawable, gc, dest_x, y, z, h, BACKWARD, swapxy);
if (src_x-- == x) {
final_z = z;
break;
}
copy_w = z;
dest_x -= 2 * z;
}
smear(disp, drawable, gc, x, y, final_z, h, FORWARD, swapxy);
}
int
enlarge(disp, drawable, gc, x, y, z, w, h)
Display * disp;
Drawable drawable;
GC gc;
int x, y, z, w, h;
{
register int myh;
if (z <= 1 || w <= 0 || h <= 0)
return 0;
myh = (h + z - 1) / z;
enlsub(disp, drawable, gc, x, y, z, w, myh, DONTSWAPXY);
enlsub(disp, drawable, gc, y, x, z, h, w, SWAPXY);
return 0;
}
More information about the Comp.lang.c
mailing list