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

322 lines
11 KiB
C

#ifndef lint
static char sccsid[] = "@(#)patsubs.c 1.1 94/10/31 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 Pattern fill functions
* Nonstandard functionality added 850815 wds
*/
#include "cgipriv.h"
#include <stdio.h>
Cint *_cgi_pattern_table[MAXNUMPATS]; /* pattern table */
View_surface *_cgi_vws; /* current view surface */
Outatt *_cgi_att; /* structure containing current attributes */
short _cgi_pattern_with_fill_color = 0;
/****************************************************************************/
/* */
/* FUNCTION: pattern_with_fill_color */
/* */
/* Non-standard CGI routine to change the interpretation of PATTERNs */
/* This routine sets ON or OFF a flag which controls PATTERN fills. */
/* */
/* If the flag is OFF (the default), PATTERN fills perform as the CGI */
/* standard says they should: pattern values from the entry in the */
/* pattern table are used verbatim (though scaled and translated). */
/* */
/* If the flag is ON, PATTERN fills are performed with only two colors:*/
/* Color zero (where pattern value is zero), */
/* and the current fill color (where pattern value is nonzero). */
/* */
/* Note that HATCH fill is not affected by this attribute flag. */
/****************************************************************************/
Cerror pattern_with_fill_color(flag)
Cflag flag;
{
int err;
err = _cgi_check_state_5();
if (!err)
_cgi_pattern_with_fill_color = (short) flag;
return (_cgi_errhand(err));
}
/****************************************************************************/
/* */
/* FUNCTION: _cgi_pattern */
/* */
/* _cgi_pattern creates one copy of the pattern which is used for */
/* pattern and hatch fill. Hatch fill is not scalable whereas */
/* pattern fill is scalable */
/****************************************************************************/
struct pixrect *_cgi_pattern(index, flag)
short index, flag; /* pattern number */
{
register int *pdp; /* pattern pointer walks thru pattern defn */
register short j; /* count X up to mscale pixels in patrect */
register short xctr; /* counter for X within m x n block */
register short mxctr; /* counter for X in mscale x nscale pixrect */
register short i; /* count Y up to nscale pixels in patrect */
register short yctr; /* counter for Y within m x n block */
register short myctr; /* counter for Y in mscale x nscale pixrect */
struct pixrect *patrect;
int incx; /* number of bytes per line of pixrect */
u_char *stx; /* Start of pixrect line */
u_short *stxw; /* 16-bit word pointer: start of line */
int incxw; /* 16-bit words per line of pixrect */
#define WORD_SIZE 16 /* Number of bits in a u_short */
int m, n;
int mscale, nscale;
int xscale, yscale;
int xoff, yoff;
int *pattern_defn = _cgi_pattern_table[index]; /* wds added 850823 */
_cgi_vws->sunview.depth = _cgi_vws->sunview.pw->pw_pixrect->pr_depth;
m = pattern_defn[1]; /* pattern or hatch size */
n = pattern_defn[2];
if (!flag)
{ /* HATCH -- no scaling required */
patrect = mem_create(m, n, _cgi_vws->sunview.depth); /* create memory pixrect */
#ifdef i386
mpr_d(patrect)->md_flags &= ~MP_I386;
#endif i386
incx = mpr_mdlinebytes(patrect); /* Num bytes in pixrect row */
pdp = &pattern_defn[3]; /* starting point (not selectable) */
if (_cgi_vws->sunview.depth == 1)
{ /* black and white HATCH -- no scaling */
/* pixrect pointer walks thru patrect pixrect */
register u_short *prpw; /* PixRect Pointer walks by Words */
register short bit;/* Bit within depth=1 pixrect word */
stxw = (u_short *) mprd_addr(mpr_d(patrect), 0, 0); /* 1-bit deep */
incxw = incx / 2 + incx % 2;
for (i = 0; i < n; i++)
{
prpw = stxw;
bit = WORD_SIZE - 1; /* count down from 15 to 0 */
for (j = 0; j < m; j++)
{ /* put "colors" in bits " */
/* if color is nonzero, it's black */
if (*pdp++ != 0)
*prpw |= 1 << bit; /* 1 << 15, ..., 1 << 0 */
if (--bit < 0) /* Bump X bit-shift counter */
{ /* Bit count rollover */
bit = WORD_SIZE - 1; /* Leftmost bit of word */
prpw++; /* Next word in pixrect */
}
}
stxw += incxw;
}
}
else
{ /* color HATCH -- no scaling */
/* pixrect pointer walks thru patrect pixrect */
register u_char *prp; /* PixRect Pointer walks (by bytes) */
stx = mprd8_addr(mpr_d(patrect), 0, 0, _cgi_vws->sunview.depth);
for (i = 0; i < n; i++)
{
prp = stx;
for (j = 0; j < m; j++) /* fill row */
{
*prp++ = *pdp++;
}
stx += incx;
}
}
}
else
{ /* PATTERN may be scaled */
/* calculate size of individual element */
_cgi_devscalen(_cgi_att->pattern.dx, xscale);
_cgi_devscalen(_cgi_att->pattern.dy, yscale);
if (xscale < 1)
xscale = 1;
if (yscale < 1)
yscale = 1;
mscale = xscale * m; /* pattern size in pixels */
nscale = yscale * n;
/* wds 850812: arbitrarily "clipping" [mn]scale won't work. */
patrect = mem_create(mscale, nscale, _cgi_vws->sunview.depth);
if (patrect == (struct pixrect *) NULL)
{
(void) _cgi_errhand(EMEMSPAC);
(void) fprintf(stderr, "Pattern scaling failed. CGI cannot continue.\n");
return (0);
}
incx = mpr_mdlinebytes(patrect); /* Num bytes in pixrect row */
_cgi_devscale(_cgi_att->pattern.point->x,
_cgi_att->pattern.point->y,
xoff, yoff);
xoff %= mscale;
yoff %= nscale;
pdp = &pattern_defn[3 + (xoff / xscale) + (yoff / yscale) * m];
if (_cgi_vws->sunview.depth == 1)
{ /* black and white PATTERN */
/* pixrect pointer walks thru patrect pixrect */
register u_short *prpw; /* PixRect Pointer walks by Words */
register short bit;/* Bit within depth=1 pixrect word */
xctr = (xoff % xscale);
yctr = (yoff % yscale);
mxctr = xoff;
myctr = yoff;
incxw = incx / 2 + incx % 2; /* Round up: num of u_shorts */
stxw = (u_short *) mprd_addr(mpr_d(patrect), 0, 0); /* 1-bit deep */
for (i = 1; i <= nscale;)
{
prpw = (u_short *) stxw;
bit = WORD_SIZE - 1; /* count down from 15 to 0 */
for (j = 1; j <= mscale; j++)
{
if (*pdp != 0)
*prpw |= 1 << bit; /* 1 << 15, ..., 1 << 0 */
if (++xctr >= xscale) /* Bump x block counter */
{
pdp++; /* Go to next block */
xctr = 0; /* Left edge of that block */
}
if (--bit < 0) /* Bump X bit-shift counter */
{ /* Bit count rollover */
bit = WORD_SIZE - 1; /* Leftmost bit of word */
prpw++; /* Next word in pixrect */
}
if (++mxctr >= mscale) /* Bump x counter */
{ /* Registration-caused wrap. */
pdp -= m; /* Wrap to start of row. */
mxctr = 0; /* Left edge of pixrect */
}
/* pdp == &pattern_defn[idx] */
/* (pdp - &pattern_defn[0]) == idx */
}
pdp += m; /* Next, use next defn row */
++i, ++yctr, ++myctr; /* One more line done */
stxw += incxw; /* Start of next line to do */
/* Bump i, y block counter and y counter for each line done */
while ((i <= nscale) && (yctr < yscale) && (myctr < nscale))
{
/* make next patrect line identical to the previous line */
/* bcopy FROM_BYTE TO_BYTE LENGTH_IN_BYTES, not words */
bcopy((char *) (stxw - incxw), (char *) stxw, incx);
stxw += incxw; /* Start of next line to do */
++i, ++yctr, ++myctr; /* One more line done */
}
if (yctr >= yscale)
yctr = 0; /* Top of next block */
if (myctr >= nscale) /* Already bumped y counter */
{
myctr = 0; /* Top edge of pixrect */
/* Top row, proper X */
pdp = &pattern_defn[3 + (xoff / xscale)];
}
}
}
else
{ /* color PATTERN */
/* pixrect pointer walks thru patrect pixrect */
register u_char *prp; /* PixRect Pointer walks (by bytes) */
xctr = (xoff % xscale);
yctr = (yoff % yscale);
mxctr = xoff;
myctr = yoff;
stx = mprd8_addr(mpr_d(patrect), 0, 0, _cgi_vws->sunview.depth);
for (i = 1; i <= nscale;)
{
prp = stx;
/* Nonstandard functionality added 850815 wds */
if (_cgi_pattern_with_fill_color)
{
/* Nonzero pattern values rendered with fill color */
for (j = 1; j <= mscale; j++)
{
*prp++ = (*pdp) ? _cgi_att->fill.color : 0;
if (++xctr >= xscale) /* Bump x block counter */
{
pdp++; /* Go to next block */
xctr = 0; /* Left edge of that block */
}
if (++mxctr >= mscale) /* Bump x counter */
{ /* Registration-caused wrap. */
pdp -= m; /* Wrap to start of row. */
mxctr = 0; /* Left edge of pixrect */
}
/* pdp == &pattern_defn[idx] */
/* (pdp - &pattern_defn[0]) == idx */
}
}
else /* ! _cgi_pattern_with_fill_color */
{
/* pattern values are used verbatim */
for (j = 1; j <= mscale; j++)
{
*prp++ = (*pdp);
if (++xctr >= xscale) /* Bump x block counter */
{
pdp++; /* Go to next block */
xctr = 0; /* Left edge of that block */
}
if (++mxctr >= mscale) /* Bump x counter */
{ /* Registration-caused wrap. */
pdp -= m; /* Wrap to start of row. */
mxctr = 0; /* Left edge of pixrect */
}
}
}
/* Note if it is helpful: when here, (mxctr == xoff) */
pdp += m; /* Next, use next defn row */
++i, ++yctr, ++myctr; /* One more line done */
stx += incx; /* Start of next line to do */
/* Bump i, y block counter and y counter for each line done */
while ((i <= nscale) && (yctr < yscale) && (myctr < nscale))
{
/* make next patrect line identical to the previous line */
/* bcopy FROM_BYTE TO_BYTE LENGTH_IN_BYTES */
bcopy((char *) (stx - incx), (char *) stx, incx);
stx += incx;/* Start of next line to do */
++i, ++yctr, ++myctr; /* One more line done */
}
if (yctr >= yscale)
yctr = 0; /* Top of next block */
if (myctr >= nscale) /* Already bumped y counter */
{
myctr = 0; /* Top edge of pixrect */
/* Top row, proper X */
pdp = &pattern_defn[3 + (xoff / xscale)];
}
}
}
}
/* pw_write (_cgi_vws->sunview.pw, 0, 0, m, n, _cgi_pix_mode, patrect, 0, 0); */
return (patrect);
}