Files
Arquivotheca.SunOS-4.1.4/usr.lib/libpixrect/mem/mem32_vec.c
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

299 lines
6.4 KiB
C

#ifndef lint
static char sccsid[] = "@(#)mem32_vec.c 1.1 94/10/31 SMI";
#endif
/* Copyright 1990 Sun Microsystems, Inc. */
/* 8 bit emulation in 24/32 bit memory pixrect */
#include <pixrect/pixrect.h>
#include <pixrect/mem32_var.h>
#include <pixrect/pr_planegroups.h> /* PIX_ALL_PLANES */
mem32_vector(pr, x0, y0, x1, y1, op, color)
Pixrect *pr;
int x0,
y0,
x1,
y1,
op,
color;
{
/* If indexed, then resort to our own (mem_vector compatible) version. */
if (mprp32_d(pr)->windowfd >= -1 && pr->pr_depth > 1 &&
strcmp(mprp32_d(pr)->cms.cms_name, "monochrome") &&
strncmp(mprp32_d(pr)->cms.cms_name,"rootcolor",9))
{
/*
* Variable usage:
* t - the variable to keep track of the slope
* n - used to know when to stop drawing
* dx - the distance to be moved in the x direction
* dy - the distance to be moved in the y direction
* x_inc - the increment in the x direction
* y_inc - the increment in the y direction
*/
int t,
n,
dx,
dy,
x_inc,
y_inc;
unsigned int *dst;
int bytes,
planes,
not_planes,
old_color,
xsize,
ysize,
xlow,
ylow,
xy_major,
dst_val;
unsigned char red[MEM32_8BIT_CMAPSIZE],
green[MEM32_8BIT_CMAPSIZE],
blue[MEM32_8BIT_CMAPSIZE];
struct colormapseg cms;
struct cms_map cmap;
unsigned int int_cmap[MEM32_8BIT_CMAPSIZE];
int i,
cms_addr,
cms_size;
/*
* If the operation is Clear, Set, Source, or ~Source, and no special
* plane mask is used, then mem_vector can handle it with a little
* help.
*/
if (PIX_OPCOLOR(op))
color = PIX_OPCOLOR(op);
op = PIX_OP(op);
planes = mprp32_d(pr)->mprp.planes & PIX_ALL_PLANES;
if (planes > MEM32_8BIT_CMAPSIZE)
planes = mprp32_d(pr)->cms.cms_size - 1;
not_planes = ~planes;
if ((op==PIX_CLR || op==PIX_SET || op==PIX_SRC || op==PIX_NOT(PIX_SRC))
&& (planes == mprp32_d(pr)->cms.cms_size - 1))
{
switch (op)
{
case PIX_CLR:
color = mem32_get_true(pr, 0, planes);
break;
case PIX_SET:
color = mem32_get_true(pr, ~0, planes);
break;
case PIX_SRC:
color = mem32_get_true(pr, color, planes);
break;
case PIX_NOT(PIX_SRC):
color = mem32_get_true(pr, ~color, planes);
break;
}
op = PIX_SRC;
mprp32_d(pr)->mprp.planes = PIX_ALL_PLANES;
return mem_vector(pr, x0, y0, x1, y1, op, color);
}
/*
* Always move x from left to right. The position of x0,y0 with
* respect to x1,y1 indicates a positive or negative y increment.
*/
if (x1 < x0)
{
dx = x0;
dy = y0;
x0 = x1;
y0 = y1;
x1 = dx;
y1 = dy;
}
/* Translate to pr_region coordinates */
x0 += mprp32_d(pr)->mprp.mpr.md_offset.x;
x1 += mprp32_d(pr)->mprp.mpr.md_offset.x;
y0 += mprp32_d(pr)->mprp.mpr.md_offset.y;
y1 += mprp32_d(pr)->mprp.mpr.md_offset.y;
/* set up variables that don't vary inside the big loop */
xlow = mprp32_d(pr)->mprp.mpr.md_offset.x;
ylow = mprp32_d(pr)->mprp.mpr.md_offset.y;
xsize = pr->pr_size.x + mprp32_d(pr)->mprp.mpr.md_offset.x;
ysize = pr->pr_size.y + mprp32_d(pr)->mprp.mpr.md_offset.y;
cmap.cm_red = red;
cmap.cm_green = green;
cmap.cm_blue = blue;
mem32_get_index_cmap(pr, &cms, &cmap);
for (i = 0; i < MEM32_8BIT_CMAPSIZE; i++)
int_cmap[i] = (int) (blue[i] << 16 | green[i] << 8 | red[i]);
cms_addr = cms.cms_addr;
cms_size = cms.cms_addr + cms.cms_size;
dst = (unsigned int *) mprp32_d(pr)->mprp.mpr.md_image;
bytes = mprp32_d(pr)->mprp.mpr.md_linebytes / sizeof(int);
x_inc = 1;
y_inc = (y1 > y0) ? 1 : -1;
dx = x1 - x0;
dy = abs(y1 - y0);
/*
* t is initially set to half the longest distance to be traveled. n
* is set to the longest distance. The longest axis is always
* incremented. The other axis is incremented everytime the slope
* variable, t, indicates that a point would have been > 1 from the
* last axis increment in floating point. This is repeated n times.
*/
if (dx > dy)
{
xy_major = 0;
t = dx >> 1;
n = dx;
}
else
{
xy_major = 1;
t = dy >> 1;
n = dy;
}
for (;; n--)
{
/*
* This is dumb, slow, inefficient, and even embarassing BUT a
* quick and dirty clipping by not writing the pixel if outside
* the pr_region bounds. It does insure EXACT pixel accuracy
* with mem_vector. To be followed by something more efficient
* if we get the time. (how hard are you laughing?)
*/
if (!(op & PIX_DONTCLIP) && x0 >= xlow && x0 < xsize &&
y0 >= ylow && y0 < ysize)
{
old_color = dst[x0 + y0 * bytes];
for (i = cms_addr; i < cms_size; i++)
{
if (old_color == int_cmap[i])
{
old_color = i;
break;
}
}
if (i == cms_size)
old_color = (old_color == int_cmap[0])
? 0 : MEM32_8BIT_CMAPSIZE - 1;
dst_val = old_color;
switch (op >> 1)
{
case 0: /* CLR */
dst_val = 0;
break;
case 1: /* ~s&~d or ~(s|d) */
dst_val = ~(color | dst_val);
break;
case 2: /* ~s&d */
dst_val = ~color & dst_val;
break;
case 3: /* ~s */
dst_val = ~color;
break;
case 4: /* s&~d */
dst_val = color & ~dst_val;
break;
case 5: /* ~d */
dst_val = ~dst_val;
break;
case 6: /* s^d */
dst_val = color ^ dst_val;
break;
case 7: /* ~s|~d or ~(s&d) */
dst_val = ~(color & dst_val);
break;
case 8: /* s&d */
dst_val = color & dst_val;
break;
case 9: /* ~(s^d) */
dst_val = ~(color ^ dst_val);
break;
case 10: /* DST */
break;
case 11: /* ~s|d */
dst_val = ~color | dst_val;
break;
case 12: /* SRC */
dst_val = color;
break;
case 13: /* s|~d */
dst_val = color | ~dst_val;
break;
case 14: /* s|d */
dst_val = color | dst_val;
break;
case 15: /* SET */
dst_val = PIX_ALL_PLANES;
break;
}
dst[x0 + y0 * bytes] =
int_cmap[(not_planes & old_color) | (planes & dst_val)];
}
if (n == 0)
return 0;
if (xy_major)
{
y0 += y_inc;
t += dx;
if (t > dy)
{
x0 += x_inc;
t -= dy;
}
}
else
{
x0 += x_inc;
t += dy;
if (t > dx)
{
y0 += y_inc;
t -= dx;
}
}
}
}
/* otherwise, let mem_vector take it. */
return mem_vector(pr, x0, y0, x1, y1, op, color);
}