Init
This commit is contained in:
321
usr.lib/libcgi/patsubs.c
Normal file
321
usr.lib/libcgi/patsubs.c
Normal file
@@ -0,0 +1,321 @@
|
||||
#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);
|
||||
}
|
||||
Reference in New Issue
Block a user