633 lines
22 KiB
C
633 lines
22 KiB
C
#ifndef lint
|
|
static char sccsid[] = "@(#)pixels.c 1.1 92/07/30 Copyr 1985-9 Sun Micro";
|
|
#endif
|
|
|
|
/*
|
|
* Copyright (c) 1985, 1986, 1987, 1988, 1989 by Sun Microsystems, Inc.
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* purpose and without fee is hereby granted, provided that the above
|
|
* copyright notice appear in all copies and that both that copyright
|
|
* notice and this permission notice are retained, and that the name
|
|
* of Sun Microsystems, Inc., not be used in advertising or publicity
|
|
* pertaining to this software without specific, written prior permission.
|
|
* Sun Microsystems, Inc., makes no representations about the suitability
|
|
* of this software or the interface defined in this software for any
|
|
* purpose. It is provided "as is" without express or implied warranty.
|
|
*/
|
|
/*
|
|
* CGI Raster Output Primitives & Inquiry Primatives
|
|
*/
|
|
|
|
/*
|
|
cell_array
|
|
cgipw_cell_array
|
|
_cgi_cell_array
|
|
pixel_array
|
|
cgipw_pixel_array
|
|
_cgi_pixel_array
|
|
inquire_cell_array
|
|
inquire_pixel_array
|
|
*/
|
|
|
|
/*
|
|
bugs:
|
|
error numbers
|
|
cgipw
|
|
absolute value of pixel array args.
|
|
true parallelogram cell array
|
|
fake trig
|
|
new drawing home.
|
|
*/
|
|
|
|
#include "cgipriv.h" /* defines types used in this file */
|
|
#include <pixrect/pixrect_hs.h>
|
|
#include <math.h>
|
|
|
|
View_surface *_cgi_vws; /* current view surface */
|
|
Outatt *_cgi_att; /* structure containing current attributes */
|
|
int _cgi_pix_mode; /* pixrect equivalent of drawing mode */
|
|
int _cgi_errno = 0; /* Gets pixel_array error 69s */
|
|
|
|
extern pw_getcmsdata();
|
|
/* Args: Pixwin *pw; struct colormapseg *cms; int *planes; */
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: cell_array */
|
|
/* */
|
|
/* Points p,q,r define a parellogram with pq as the diagonal where */
|
|
/* p is the lower left-hand corner. r is one of the remaining two */
|
|
/* corners. Dx and dy define the virtual size of the array which is */
|
|
/* mapped onto the area defined by p,q, and r. */
|
|
/****************************************************************************/
|
|
|
|
Cerror cell_array(pcell, qcell, rcell, dx, dy, colorind)
|
|
Ccoor *pcell, *qcell, *rcell; /* corners of parallelogram */
|
|
Cint dx, dy; /* size of color array */
|
|
Cint *colorind; /* array of color values */
|
|
{
|
|
int ivw;
|
|
Cerror err; /* error */
|
|
|
|
err = _cgi_err_check_4();
|
|
if (!err)
|
|
if (dx < 0 || dy < 0)
|
|
err = ECELLPOS;
|
|
if (!err)
|
|
{
|
|
ivw = 0;
|
|
while (_cgi_bump_vws(&ivw))
|
|
{
|
|
err = _cgi_cell_array(_cgi_vws, pcell, qcell, rcell, dx, dy, colorind);
|
|
}
|
|
}
|
|
return (_cgi_errhand(err));
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: cgipw_cell_array */
|
|
/* */
|
|
/* Points p,q,r define a parellogram with pq as the diagonal where */
|
|
/* p is the LOWER LEFT-hand corner. r is one of the remaining two */
|
|
/* corners. Dx and dy define the virtual size of the array which is */
|
|
/* mapped onto the area defined by p, q, and r. */
|
|
/* */
|
|
/* All cells are the same size in DEVICE COORDINATES, not necessarily */
|
|
/* VDC coors. This algorithm DEVIATES from the latest CGI and GKS: */
|
|
/* pixel CENTERS are not used to determine rendering; only integral */
|
|
/* multiplication and skewing is performed -- not resampling. */
|
|
/****************************************************************************/
|
|
Cerror cgipw_cell_array(desc, pcell, qcell, rcell, d1, d2, colorind)
|
|
Ccgiwin *desc;
|
|
Ccoor *pcell, *qcell, *rcell; /* VDC corners of parallelogram */
|
|
Cint d1, d2; /* size of color array in first & second axes */
|
|
Cint *colorind; /* array of color values */
|
|
{
|
|
SETUP_CGIWIN(desc);
|
|
return (_cgi_cell_array(desc->vws, pcell, qcell, rcell, d1, d2, colorind));
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: _cgi_cell_array */
|
|
/* */
|
|
/* Points p,q,r define a parellogram with pq as the diagonal where */
|
|
/* p is the LOWER LEFT-hand corner. r is one of the remaining two */
|
|
/* corners. Dx and dy define the virtual size of the array which is */
|
|
/* mapped onto the area defined by p, q, and r. */
|
|
/* */
|
|
/* All cells are the same size in DEVICE COORDINATES, not necessarily */
|
|
/* VDC coors. This algorithm DEVIATES from the latest CGI and GKS: */
|
|
/* pixel CENTERS are not used to determine rendering; only integral */
|
|
/* multiplication and skewing is performed -- not resampling. */
|
|
/****************************************************************************/
|
|
Cerror _cgi_cell_array(vws, pcell, qcell, rcell, d1, d2, colorind)
|
|
View_surface *vws;
|
|
Ccoor *pcell, *qcell, *rcell; /* VDC corners of parallelogram */
|
|
Cint d1, d2; /* size of color array in first & second axes */
|
|
Cint *colorind; /* array of color values */
|
|
{
|
|
Ccoor pc, qc, rc; /* DC corners of parallelogram */
|
|
short xsign, ysign;
|
|
Ccoor inc1, inc2; /* inc1 x&y is for d1 steps from P to R. inc2
|
|
* x&y is for d2 steps from R to Q. */
|
|
register int i, j; /* Loop counters. */
|
|
int err = NO_ERROR; /* initialize error condition */
|
|
|
|
/* scale coordinates */
|
|
_cgi_devscale(pcell->x, pcell->y, pc.x, pc.y);
|
|
_cgi_devscale(qcell->x, qcell->y, qc.x, qc.y);
|
|
_cgi_devscale(rcell->x, rcell->y, rc.x, rc.y);
|
|
|
|
pw_lock(vws->sunview.pw, &vws->sunview.lock_rect);
|
|
if ((qc.x == rc.x) && (pc.y == rc.y))
|
|
{ /* Rect; P and R both top or bottom: draw
|
|
* aligned rectangles horiz'lly */
|
|
/* No attempt is made to "resample", finding elements over pixel-centers */
|
|
/* Merely replicate elements to identical little rectangles */
|
|
register int x, y, xsize, ysize;
|
|
|
|
/* compute size of each rectangular element */
|
|
xsign = (qc.x - pc.x) < 0 ? -1 : 1; /* One pixel further toward Q
|
|
* in X */
|
|
inc1.x = (qc.x - pc.x + xsign) / d1; /* Final - Initial + One more */
|
|
xsize = abs(inc1.x);
|
|
ysign = (qc.y - pc.y) < 0 ? -1 : 1; /* One pixel further toward Q
|
|
* in Y */
|
|
inc2.y = (qc.y - pc.y + ysign) / d2; /* Final - Initial + One more */
|
|
ysize = abs(inc2.y);
|
|
if (xsize == 0 || ysize == 0)
|
|
{
|
|
err = 66; /* error cell dimensions too small */
|
|
goto unlock_and_return;
|
|
}
|
|
|
|
if (ysign > 0)
|
|
y = pc.y;
|
|
else
|
|
y = pc.y + inc2.y + 1;
|
|
|
|
for (j = 0; j < d2; j++, y += inc2.y)
|
|
{
|
|
|
|
if (xsign > 0)
|
|
x = pc.x;
|
|
else
|
|
x = pc.x + inc1.x + 1;
|
|
|
|
for (i = 0; i < d1; i++, x += inc1.x)
|
|
{
|
|
pw_write(vws->sunview.pw, x, y, xsize, ysize,
|
|
PIX_COLOR(*colorind++) | _cgi_pix_mode, 0, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
else if ((pc.x == rc.x) && (qc.y == rc.y))
|
|
{ /* Rect; P and R both left or right: draw
|
|
* aligned rectangles vertically */
|
|
/* No attempt is made to "resample", finding elements over pixel-centers */
|
|
/* Merely replicate elements to identical little rectangles */
|
|
register int x, y, xsize, ysize;
|
|
|
|
/* compute size of each rectangular element */
|
|
xsign = (qc.x - pc.x) < 0 ? -1 : 1; /* One pixel further toward Q
|
|
* in X */
|
|
inc2.x = (qc.x - pc.x + xsign) / d2; /* Final - Initial + One more */
|
|
xsize = abs(inc2.x);
|
|
ysign = (qc.y - pc.y) < 0 ? -1 : 1; /* One pixel further toward Q
|
|
* in Y */
|
|
inc1.y = (qc.y - pc.y + ysign) / d1; /* Final - Initial + One more */
|
|
ysize = abs(inc1.y);
|
|
if (xsize == 0 || ysize == 0)
|
|
{
|
|
err = 66; /* error cell dimensions too small */
|
|
goto unlock_and_return;
|
|
}
|
|
|
|
if (xsign > 0)
|
|
x = pc.x;
|
|
else
|
|
x = pc.x + inc2.x + 1;
|
|
|
|
|
|
for (i = 0; i < d2; i++, x += inc2.x)
|
|
{
|
|
if (ysign > 0)
|
|
y = pc.y;
|
|
else
|
|
y = pc.y + inc1.y + 1;
|
|
|
|
for (j = 0; j < d1; j++, y += inc1.y)
|
|
{
|
|
pw_write(vws->sunview.pw, x, y, xsize, ysize,
|
|
PIX_COLOR(*colorind++) | _cgi_pix_mode, 0, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{ /* draw using parallelogram */
|
|
/* Each cell element rendered as identical little parallelogram. */
|
|
/* No attempt is made to "resample", finding elements over pixel-centers */
|
|
Ccoor fourpts[4];
|
|
int np = 4; /* number of points in polygon boundry */
|
|
|
|
/* element parallelogram sizes -- No correction made for fragmentation */
|
|
/* start incs as displacements between the array's corners */
|
|
inc1.x = (rc.x - pc.x);
|
|
xsign = (inc1.x < 0) ? -1 : (inc1.x > 0) ? 1 : 0;
|
|
inc1.x = (inc1.x + xsign) / d1;
|
|
|
|
inc1.y = (rc.y - pc.y);
|
|
ysign = (inc1.y < 0) ? -1 : (inc1.y > 0) ? 1 : 0;
|
|
inc1.y = (inc1.y + ysign) / d1;
|
|
|
|
inc2.x = (qc.x - rc.x);
|
|
xsign = (inc2.x < 0) ? -1 : (inc2.x > 0) ? 1 : 0;
|
|
inc2.x = (inc2.x + xsign) / d2;
|
|
|
|
inc2.y = (qc.y - rc.y);
|
|
ysign = (inc2.y < 0) ? -1 : (inc2.y > 0) ? 1 : 0;
|
|
inc2.y = (inc2.y + ysign) / d2;
|
|
/* each element has inc1 pixel displacements from P to R; inc2 from R to Q. */
|
|
|
|
/* Correct polygon rendering that ignores rightmost & bottommost edges. */
|
|
if ((qc.x - pc.x) < 0)
|
|
pc.x++;
|
|
if ((qc.y - pc.y) < 0)
|
|
pc.y++;
|
|
/*
|
|
* These lines don't completely fix the problem: moving P down & right
|
|
* does not necessarily cause the original P to be rendered:
|
|
*
|
|
* Moving P to p doesn't necessarily cause P to be rendered. o*****+
|
|
* o****+ o***+ o**+ o*+ P+ p Pixels marked "+" are added to polygon,
|
|
* but not rendered (on right). All those pixels marked "o" (& P & p)
|
|
* are still on the bottom and will therefore still not be rendered.
|
|
*/
|
|
|
|
for (j = 0; j < d2; j++)
|
|
{
|
|
/* fourpts[0] on P corner; [1] is R corner; [2] is Q corner; [3] other corner */
|
|
fourpts[0].x = pc.x;
|
|
fourpts[0].y = pc.y;
|
|
fourpts[1].x = fourpts[0].x + inc1.x; /* R */
|
|
fourpts[1].y = fourpts[0].y + inc1.y;
|
|
fourpts[2].x = fourpts[1].x + inc2.x; /* Q */
|
|
fourpts[2].y = fourpts[1].y + inc2.y;
|
|
fourpts[3].x = fourpts[0].x + inc2.x; /* Other */
|
|
fourpts[3].y = fourpts[0].y + inc2.y;
|
|
|
|
for (i = 0; i < d1; i++)
|
|
{ /* draw inner d1 elements of cell "row" from P
|
|
* to R */
|
|
pw_polygon_2(vws->sunview.pw, 0, 0, 1, &np,
|
|
(struct pr_pos *) fourpts,
|
|
PIX_COLOR(*colorind++) | _cgi_pix_mode,
|
|
(Pixrect *) 0, 0, 0);
|
|
/* Move cell element parallelogram along d1 axis */
|
|
fourpts[0] = fourpts[1]; /* [0](p) to [1](r) */
|
|
fourpts[3] = fourpts[2]; /* [3](other) to [2](q) */
|
|
fourpts[1].x = fourpts[0].x + inc1.x; /* move R forward */
|
|
fourpts[1].y = fourpts[0].y + inc1.y;
|
|
fourpts[2].x = fourpts[3].x + inc1.x; /* move Q forward */
|
|
fourpts[2].y = fourpts[3].y + inc1.y;
|
|
}
|
|
|
|
/* draw outer d2 elements of cell "column", moving P towards Q */
|
|
pc.x += inc2.x;
|
|
pc.y += inc2.y;
|
|
}
|
|
}
|
|
unlock_and_return:
|
|
pw_unlock(vws->sunview.pw);
|
|
return (err);
|
|
}
|
|
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: pixel_array */
|
|
/* */
|
|
/* draws array colorind starting at point pcell. */
|
|
/* M and N define the size of the array. */
|
|
/****************************************************************************/
|
|
|
|
Cerror pixel_array(pcell, m, n, colorind)
|
|
Ccoor *pcell; /* base of array in VDC space */
|
|
Cint m, n; /* dimensions of color array */
|
|
Cint *colorind; /* array of color values */
|
|
{
|
|
int ivw, err; /* error */
|
|
|
|
err = _cgi_err_check_4();
|
|
if (!err)
|
|
{
|
|
ivw = 0;
|
|
while (_cgi_bump_vws(&ivw))
|
|
{
|
|
err = _cgi_pixel_array(_cgi_vws, pcell, m, n, colorind);
|
|
}
|
|
}
|
|
return (_cgi_errhand(err));
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: cgipw_pixel_array */
|
|
/* */
|
|
/****************************************************************************/
|
|
|
|
Cerror cgipw_pixel_array(desc, pcell, m, n, colorind)
|
|
Ccgiwin *desc;
|
|
Ccoor *pcell; /* base of array in VDC space */
|
|
Cint m, n; /* dimensions of color array */
|
|
Cint *colorind; /* array of color values */
|
|
{
|
|
int err;
|
|
|
|
SETUP_CGIWIN(desc);
|
|
err = _cgi_pixel_array(desc->vws, pcell, m, n, colorind);
|
|
return (err);
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: _cgi_pixel_array */
|
|
/* */
|
|
/* draws array colorind starting at point pcell. */
|
|
/* M and N define the size of the array. */
|
|
/* uses _cgi_att, assumes context loaded */
|
|
/* */
|
|
/* Now returns error 69 if any portion of pixel array is */
|
|
/* outside the window, but draws the pixel array ANYWAY. */
|
|
/****************************************************************************/
|
|
|
|
Cerror _cgi_pixel_array(vws, pcell, m, n, colorind)
|
|
View_surface *vws;
|
|
Ccoor *pcell; /* base of array in VDC space */
|
|
Cint m, n; /* dimensions of color array */
|
|
register Cint *colorind; /* array of color values */
|
|
{
|
|
register int i, j;
|
|
int x, y, incx, rop;
|
|
u_char *stx;
|
|
short *stx1;
|
|
Pixrect *mprect;
|
|
short jmod;
|
|
|
|
_cgi_errno = NO_ERROR;
|
|
_cgi_devscale(pcell->x, pcell->y, x, y);
|
|
_cgi_errno = _cgi_err_check_69(x, y);
|
|
if (!_cgi_errno)
|
|
_cgi_errno = _cgi_err_check_69(x + m, y + n);
|
|
/* WDS 860829: Draw (with clipping) the array ANYWAY -- even if hanging off */
|
|
/* if (!err) */
|
|
{
|
|
mprect = mem_create(m, n, vws->sunview.depth);
|
|
if (vws->sunview.depth == 1)
|
|
{
|
|
register short *xp1;
|
|
|
|
stx1 = mprd_addr(mpr_d(mprect), 0, 0);
|
|
incx = (mpr_mdlinebytes(mprect) + 1) >> 1; /* Words */
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
xp1 = stx1;
|
|
for (j = 0; j < m; j++)
|
|
{
|
|
jmod = j % 16;
|
|
if (jmod == 0 && j != 0)
|
|
xp1++;
|
|
if (*colorind++ != 0)
|
|
#ifdef i386
|
|
*xp1 |= 0x8000 >> (15 - jmod);
|
|
#else !i386
|
|
*xp1 |= 1 << (15 - jmod);
|
|
#endif i386
|
|
}
|
|
stx1 += incx;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
register u_char *xp;
|
|
stx = mprd8_addr(mpr_d(mprect), 0, 0, vws->sunview.depth);
|
|
incx = mpr_mdlinebytes(mprect); /* Bytes */
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
xp = stx;
|
|
for (j = 0; j < m; j++)
|
|
{
|
|
*xp++ = *colorind++;
|
|
}
|
|
stx += incx;
|
|
}
|
|
}
|
|
if (_cgi_errno)
|
|
rop = _cgi_pix_mode & ~(PIX_DONTCLIP); /* Turn CLIPPING ON */
|
|
else
|
|
rop = _cgi_pix_mode;/* No error: leave CLIPPING alone */
|
|
pw_write(vws->sunview.pw, x, y, m, n, rop, mprect, 0, 0);
|
|
(void) pr_destroy(mprect);
|
|
}
|
|
return (_cgi_errno != 69 ? _cgi_errno : 0);
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: inquire_cell_array */
|
|
/* */
|
|
/* Points p,q,r define a parellogram with pq as the diagonal where */
|
|
/* p is the lower left-hand corner. r is one of the remaining two */
|
|
/* corners. Dx and dy define the virtual size of the array which is */
|
|
/* mapped onto the area defined by p,q, and r. */
|
|
/* */
|
|
/* Now allows P to be any corner: sampling is at corner of cell */
|
|
/* element closest to point P, which is lower-left if P is lower-left. */
|
|
/* */
|
|
/* See discussion under cgipw_cell_array about the limitations caused */
|
|
/* by not really resampling. Note that this function is not in the */
|
|
/* 1986 CGI standard at all, since sampling is an application function.*/
|
|
/****************************************************************************/
|
|
|
|
inquire_cell_array(name, pcell, qcell, rcell, d1, d2, colorind)
|
|
Cint name;
|
|
Ccoor *pcell, *qcell, *rcell; /* points of parallelogram */
|
|
Cint d1, d2; /* size of color array in first & second axes */
|
|
Cint *colorind; /* array of color values */
|
|
{
|
|
Ccoor pc, qc, rc; /* DC corners of parallelogram */
|
|
short xsign, ysign;
|
|
Ccoor inc1, inc2; /* inc1 x&y is for d1 steps from P to R. *
|
|
* inc2 x&y is for d2 steps from R to Q. */
|
|
register int i, j; /* Loop counters. */
|
|
register int x, y; /* Loop counters. */
|
|
int err = 0; /* initialize error condition */
|
|
|
|
err = _cgi_context(name);
|
|
if (!err)
|
|
if (d1 < 0 || d2 < 0)
|
|
err = 67;
|
|
if (!err)
|
|
{
|
|
_cgi_devscale(pcell->x, pcell->y, pc.x, pc.y);
|
|
_cgi_devscale(qcell->x, qcell->y, qc.x, qc.y);
|
|
_cgi_devscale(rcell->x, rcell->y, rc.x, rc.y);
|
|
/* element parallelogram sizes -- No correction made for fragmentation */
|
|
/* start incs as displacements between the array's corners */
|
|
inc1.x = (rc.x - pc.x);
|
|
xsign = (inc1.x < 0) ? -1 : (inc1.x > 0) ? 1 : 0;
|
|
inc1.x = (inc1.x + xsign) / d1;
|
|
|
|
inc1.y = (rc.y - pc.y);
|
|
ysign = (inc1.y < 0) ? -1 : (inc1.y > 0) ? 1 : 0;
|
|
inc1.y = (inc1.y + ysign) / d1;
|
|
|
|
inc2.x = (qc.x - rc.x);
|
|
xsign = (inc2.x < 0) ? -1 : (inc2.x > 0) ? 1 : 0;
|
|
inc2.x = (inc2.x + xsign) / d2;
|
|
|
|
inc2.y = (qc.y - rc.y);
|
|
ysign = (inc2.y < 0) ? -1 : (inc2.y > 0) ? 1 : 0;
|
|
inc2.y = (inc2.y + ysign) / d2;
|
|
/* each element has inc1 pixel displacements from P to R; inc2 from R to Q. */
|
|
|
|
/* error cell dimensions too small */
|
|
if ((inc1.x == 0 && inc1.y == 0) || (inc2.x == 0 && inc2.y == 0))
|
|
err = 66; /* error cell dimensions too small */
|
|
if (!err)
|
|
{
|
|
pw_lock(_cgi_vws->sunview.pw, &_cgi_vws->sunview.lock_rect);
|
|
for (j = 0; j < d2; j++)
|
|
{
|
|
x = pc.x;
|
|
y = pc.y; /* Start at P */
|
|
for (i = 0; i < d1; i++)
|
|
{
|
|
*colorind++ = pw_get(_cgi_vws->sunview.pw, x, y);
|
|
x += inc1.x;
|
|
y += inc1.y;/* Move towards R */
|
|
}
|
|
pc.x += inc2.x;
|
|
pc.y += inc2.y; /* Move P towards Q */
|
|
}
|
|
pw_unlock(_cgi_vws->sunview.pw);
|
|
}
|
|
}
|
|
return (_cgi_errhand(err));
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: inquire_pixel_array */
|
|
/* */
|
|
/* reads pixel array into array colorind, */
|
|
/* starting at point pcell. */
|
|
/* M and N define the size of the array. */
|
|
/****************************************************************************/
|
|
|
|
inquire_pixel_array(pcell, m, n, colorind, name)
|
|
Ccoor *pcell; /* base of array in VDC space */
|
|
Cint m, n; /* dimensions of color array */
|
|
Cint *colorind; /* array of color values */
|
|
Cint name;
|
|
{
|
|
int x, y;
|
|
Pixrect *mprect;
|
|
|
|
_cgi_errno = _cgi_context(name);
|
|
if (!_cgi_errno)
|
|
{
|
|
_cgi_devscale(pcell->x, pcell->y, x, y); /* start point */
|
|
_cgi_errno = _cgi_err_check_69(x, y);
|
|
if (!_cgi_errno)
|
|
_cgi_errno = _cgi_err_check_69(x + m, y + n);
|
|
/*
|
|
* WDS 860829: Draw (with clipping) the array ANYWAY -- even if hanging
|
|
* off
|
|
*/
|
|
/* if (!err) */
|
|
{
|
|
mprect = mem_create(m, n, _cgi_vws->sunview.depth);
|
|
pw_read(mprect, 0, 0, m, n, PIX_SRC, _cgi_vws->sunview.pw, x, y);
|
|
|
|
if (_cgi_vws->sunview.depth == 1)
|
|
{
|
|
#define WORD_SIZE 16 /* Number of bits in a u_short */
|
|
register u_short *prpw; /* PixRect Pointer walks by Words */
|
|
register short bit; /* Bit within depth=1 pixrect word */
|
|
u_short *stxw; /* 16-bit word pointer: start of line */
|
|
int incxw; /* 16-bit words per line of pixrect */
|
|
register int i, j; /* Count Y up to n, X up to m */
|
|
|
|
stxw = (u_short *) mprd_addr(mpr_d(mprect), 0, 0); /* 1 bit deep */
|
|
incxw = (mpr_mdlinebytes(mprect) + 1) >> 1; /* Words */
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
prpw = stxw;
|
|
bit = WORD_SIZE - 1; /* Count down from 15 to 0 */
|
|
for (j = 0; j < m; j++)
|
|
{ /* Color values returned necessarily either 1
|
|
* or 0. */
|
|
*colorind++ = (*prpw & (1 << bit)) ? 1 : 0;
|
|
if (--bit < 0) /* Bump X bit-shift counter */
|
|
{ /* Bit count rollover */
|
|
bit = WORD_SIZE - 1; /* Leftmost bit of word */
|
|
prpw++; /* Move on to next word */
|
|
}
|
|
}
|
|
stxw += incxw;
|
|
}
|
|
}
|
|
else /* Non depth 1 pixrect: assume 8 */
|
|
{
|
|
register u_char *prp; /* PixRect Pointer walks by Bytes */
|
|
u_char *stx; /* byte pointer: start of line */
|
|
int incx; /* bytes per line of pixrect */
|
|
register int i, j; /* Count Y up to n, X up to m */
|
|
register unsigned colormap_segment_mask;
|
|
/*
|
|
* Frame buffer's high-order bits are set to the address of the
|
|
* colormap segment in use. The low-order bits are application
|
|
* data. We will have to mask off the high-order bits so the
|
|
* application will see the low-order bits it but there.
|
|
*/
|
|
{
|
|
#define NO_PLANE_PTR ((int *)0)
|
|
struct colormapseg cms;
|
|
int test = 1;
|
|
pw_getcmsdata(_cgi_vws->sunview.pw, &cms, NO_PLANE_PTR);
|
|
/* cms.cms_size is the colormap segment size of this window */
|
|
while (test < cms.cms_size)
|
|
test <<= 1;
|
|
/*
|
|
* test is a power of two (a single bit) >= cms.cms_size,
|
|
* e.g., 8
|
|
*/
|
|
colormap_segment_mask = test - 1; /* e.g., 7 = bin 0111 */
|
|
}
|
|
|
|
|
|
stx = mprd8_addr(mpr_d(mprect), 0, 0, _cgi_vws->sunview.depth);
|
|
incx = mpr_mdlinebytes(mprect);
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
prp = stx;
|
|
for (j = 0; j < m; j++) /* Process one row */
|
|
{
|
|
*colorind++ = (*prp++) & colormap_segment_mask;
|
|
/*
|
|
* high-order bits depends on which colormap segment is
|
|
* used.
|
|
*/
|
|
}
|
|
stx += incx;
|
|
}
|
|
}
|
|
(void) pr_destroy(mprect);
|
|
} /* if (!err) from _cgi_err_check_69 */
|
|
} /* if (!err) from _cgi_context */
|
|
return (_cgi_errhand(_cgi_errno != 69 ? _cgi_errno : 0));
|
|
}
|