340 lines
11 KiB
C
340 lines
11 KiB
C
/*
|
|
* Copyright (c) 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.
|
|
*/
|
|
#ifndef lint
|
|
static char sccsid[] = "@(#)bw2subs.c 1.1 94/10/31 Copyr 1985 Sun Micro";
|
|
#endif
|
|
|
|
/*
|
|
* Copyright (c) 1985 by Sun Microsystems, Inc.
|
|
*/
|
|
|
|
#include "coretypes.h"
|
|
#include "corevars.h"
|
|
#include <sunwindow/window_hs.h>
|
|
#include <stdio.h>
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: _core_prsimline */
|
|
/* */
|
|
/* PURPOSE: SIMULATE A LINE OF THE CURRENT LINE STYLE AND WIDTH */
|
|
/* */
|
|
/****************************************************************************/
|
|
static int pattern[4][5] = {0,0,0,0,0, /* solid */
|
|
2500,5000,2500,5000,15000, /* dotted */
|
|
10000,10000,10000,10000,40000, /* dashed */
|
|
22500,7500,7500,7500,45000}; /* dash dot */
|
|
static int pdx[4],pdy[4],pdl[4]; /* pattern length vector */
|
|
static int vecl;
|
|
static int rop;
|
|
static struct pixrect *destpr;
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
_core_bw2simline( x0,y0,x1,y1,wind,op,width,style)
|
|
int x0,y0,x1,y1; /* NDC coords */
|
|
struct windowstruct *wind;
|
|
int op, width, style; /* NDC width */
|
|
{
|
|
int dx,dy; /* vector components */
|
|
int factor, tl;
|
|
short i, dxprime, dyprime, p0x, p0y, p1x, p1y;
|
|
short minax, majax, pos_slope, error;
|
|
int diag_square, cur_error, old_error;
|
|
int maj_count, maj_square, min_count, min_square;
|
|
|
|
rop = op;
|
|
destpr = wind->pixwin->pw_pixrect;
|
|
dx = x1 - x0;
|
|
dy = y1 - y0;
|
|
|
|
vecl = _core_jsqrt((unsigned int)(dx*dx + dy*dy));
|
|
if (style) { /* if not solid fat line */
|
|
if (vecl==0) {
|
|
if (wind->needlock)
|
|
pw_lock( wind->pixwin, (Rect *)&wind->rect);
|
|
circle(x0, y0, (width)/2);
|
|
if (wind->needlock)
|
|
pw_unlock( wind->pixwin);
|
|
return(0);
|
|
}
|
|
for (i=0; i<4; i++) { /* make four part pattern cycle */
|
|
tl = pattern[style][i];
|
|
factor = tl / vecl; /* 10 bits to right of binary pt */
|
|
pdx[i] = (dx * factor); /* length vecs for 4 pieces */
|
|
pdy[i] = (dy * factor); /* 2 bits rt of binary pt */
|
|
pdl[i] = _core_jsqrt((unsigned int)(pdx[i]*pdx[i] + pdy[i]*pdy[i]));
|
|
}
|
|
if (width <= 1) {
|
|
if (wind->needlock)
|
|
pw_lock( wind->pixwin, (Rect *)&wind->rect);
|
|
plotline(x0,y0,x1,y1);
|
|
if (wind->needlock)
|
|
pw_unlock( wind->pixwin);
|
|
return(0);
|
|
}
|
|
}
|
|
else pdl[0] = 0xfffff;
|
|
|
|
if(vecl) {
|
|
|
|
pos_slope = ((dx>0)^(dy>0)) ? FALSE : TRUE;
|
|
dyprime = (width*abs(dx)/vecl)>>1;
|
|
dxprime = (width*abs(dy)/vecl)>>1;
|
|
|
|
if (wind->needlock)
|
|
pw_lock( wind->pixwin, (Rect *)&wind->rect);
|
|
|
|
diag_square = width*width;
|
|
maj_count = 0;
|
|
min_count = 0;
|
|
maj_square = 1;
|
|
min_square = 1;
|
|
cur_error = diag_square - (maj_square + min_square);
|
|
|
|
if (dxprime > dyprime) {
|
|
minax=2*dyprime;
|
|
majax=2*dxprime;
|
|
error=2*dyprime - dxprime;
|
|
p0x=x0-dxprime;
|
|
p1x=x1-dxprime;
|
|
if (pos_slope) {
|
|
p0y = y0+dyprime;
|
|
p1y = y1+dyprime;
|
|
} else {
|
|
p0y = y0-dyprime;
|
|
p1y = y1-dyprime;
|
|
}
|
|
do {
|
|
plotline(p0x,p0y,p1x,p1y);
|
|
p0x++; p1x++;
|
|
maj_count++;
|
|
maj_square += (maj_count<<1) + 1;
|
|
error += minax;
|
|
if (error > 0) {
|
|
plotline(p0x,p0y,p1x,p1y);
|
|
if (pos_slope) {
|
|
p0y--;
|
|
p1y--;
|
|
} else {
|
|
p0y++;
|
|
p1y++;
|
|
}
|
|
min_count++;
|
|
min_square += (min_count<<1) + 1;
|
|
error -= majax;
|
|
}
|
|
old_error = cur_error;
|
|
cur_error = diag_square - (maj_square + min_square);;
|
|
} while ((abs(cur_error)) <= (abs(old_error)));
|
|
|
|
} else {
|
|
minax=2*dxprime;
|
|
majax=2*dyprime;
|
|
error=2*dxprime - dyprime;
|
|
p0y=y0-dyprime;
|
|
p1y=y1-dyprime;
|
|
if (pos_slope) {
|
|
p0x = x0+dxprime;
|
|
p1x = x1+dxprime;
|
|
} else {
|
|
p0x = x0-dxprime;
|
|
p1x = x1-dxprime;
|
|
}
|
|
do {
|
|
plotline(p0x,p0y,p1x,p1y);
|
|
p0y++; p1y++;
|
|
maj_count++;
|
|
maj_square += (maj_count<<1) + 1;
|
|
error += minax;
|
|
if (error > 0) {
|
|
plotline(p0x,p0y,p1x,p1y);
|
|
if (pos_slope) {
|
|
p0x--;
|
|
p1x--;
|
|
} else {
|
|
p0x++;
|
|
p1x++;
|
|
}
|
|
min_count++;
|
|
min_square += (min_count<<1) + 1;
|
|
error -= majax;
|
|
}
|
|
old_error = cur_error;
|
|
cur_error = diag_square - (maj_square + min_square);
|
|
} while ((abs(cur_error)) <= (abs(old_error)));
|
|
}
|
|
}
|
|
circle(x0, y0, (width-1)/2);
|
|
circle(x1, y1, (width-1)/2);
|
|
if (wind->needlock)
|
|
pw_unlock( wind->pixwin);
|
|
return(0);
|
|
}
|
|
|
|
/*-----------------------------------*/
|
|
static plotline( x0,y0,x1,y1)
|
|
short x0,y0,x1,y1;
|
|
{
|
|
register int xb,yb,xe,ye,i;
|
|
int totl;
|
|
|
|
xb = xe = x0 << 10; /* begin and end piece */
|
|
yb = ye = y0 << 10;
|
|
i = 0;
|
|
totl = pdl[i]; /* total line length so far */
|
|
while ( (totl>>10) < vecl) { /* draw one textured line */
|
|
xe += pdx[i]; ye += pdy[i];
|
|
if ((i&1)==0)
|
|
(void)pr_vector(destpr, xb>>10, yb>>10, xe>>10, ye>>10,
|
|
rop|PIX_DONTCLIP, 1);
|
|
totl += pdl[i++];
|
|
i &= 3; /* four part pattern cycle */
|
|
xb = xe; yb = ye;
|
|
}
|
|
(void)pr_vector(destpr, xb>>10, yb>>10, x1, y1,rop|PIX_DONTCLIP,1);
|
|
/* do rest of line */
|
|
}
|
|
|
|
/*--------------------------------*/
|
|
static circle( x0,y0,rad) short x0,y0,rad;
|
|
{
|
|
int x,y,d;
|
|
|
|
x = 0; y = rad;
|
|
d = 3 - 2 * rad;
|
|
while ( x<y) {
|
|
circ_pts( x0,y0,x,y);
|
|
if (d<0) d = d + 4*x + 6;
|
|
else {
|
|
d = d + 4 *(x-y) + 10;
|
|
y = y - 1;
|
|
}
|
|
x += 1;
|
|
}
|
|
if (x=y) circ_pts( x0,y0,x,y);
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static circ_pts( x0,y0,x,y) short x0,y0,x,y;
|
|
{ /* draw symmetry points of circle */
|
|
short a1,a2,a3,a4,b1,b2,b3,b4;
|
|
a1 = x0+x; a2 = x0+y; a3 = x0-x; a4 = x0-y;
|
|
b1 = y0+x; b2 = y0+y; b3 = y0-x; b4 = y0-y;
|
|
(void)pr_vector( destpr, a4, b1, a2, b1, rop, 1);
|
|
(void)pr_vector( destpr, a3, b2, a1, b2, rop, 1);
|
|
(void)pr_vector( destpr, a4, b3, a2, b3, rop, 1);
|
|
(void)pr_vector( destpr, a3, b4, a1, b4, rop, 1);
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* */
|
|
/* FUNCTION: _core_prvectext */
|
|
/* */
|
|
/* PURPOSE: USING THE CHARACTER PARAMETERS, SIMULATE TEXT DRAWING BY */
|
|
/* SENDING THE APPROPRIATE LINE COMMANDS TO THE SURFACE. */
|
|
/* This routine provides for plotting characters on the
|
|
view surfaces in two dimensions. The 5 character fonts available
|
|
are vector fonts, so the DD is used to draw the vectors.
|
|
The fonts have fill vectors so that the characters will appear
|
|
solid if plotted at standard size. The characters are transformed
|
|
by the current transformation. However, since characters are
|
|
defined in world coordinates, their position is set by movabs and
|
|
their attributes are set by setfont, setchsize, setchspc,
|
|
setchpath, and setchup.
|
|
*/
|
|
/* */
|
|
/****************************************************************************/
|
|
_core_bw2vectext( s, font, up, path, space, x0, y0, vwprt, op, windptr)
|
|
char *s; short font; ipt_type *up, *path, *space;
|
|
int x0, y0, op;
|
|
porttype *vwprt;
|
|
struct windowstruct *windptr;
|
|
{
|
|
short xmin, xmax;
|
|
short refx, refy, curx, cury, nxtx, nxty;
|
|
short x1, y1;
|
|
register int upx,upy,lfx,lfy;
|
|
int spx,spy;
|
|
short i, penup, npts, endx, endy, dmx;
|
|
short lastvisible, nextvisible;
|
|
short pts[250]; char ch;
|
|
ipt_type vpup, vppath, vpspace;
|
|
struct pixrect *dstpr;
|
|
|
|
dstpr = windptr->pixwin->pw_pixrect;
|
|
refx = x0; /* start point for text string dev coords */
|
|
refy = y0;
|
|
/* direction vecs in device coords << 4 */
|
|
vpup = *up; /* char up vector */
|
|
upx = vpup.x; upy = vpup.y;
|
|
vppath = *path; /* char path vector */
|
|
lfx = vppath.x; lfy = vppath.y;
|
|
vpspace = *space; /* spacing between chars in dev coords << 4*/
|
|
spx = vpspace.x; spy = vpspace.y;
|
|
|
|
/*
|
|
* Process all chars in string drawing in device coords
|
|
*/
|
|
lastvisible = TRUE;
|
|
nextvisible = TRUE;
|
|
if (_core_wndwclip || _core_outpclip) {
|
|
lastvisible = !(refx < (int)(vwprt->xmin) ||
|
|
refy < (int)(vwprt->ymin) ||
|
|
refx > (int)(vwprt->xmax) ||
|
|
refy > (int)(vwprt->ymax));
|
|
}
|
|
if (windptr->needlock)
|
|
(void)pw_lock(windptr->pixwin, (Rect *)&windptr->rect);
|
|
while (ch = *s++) { /* for all chars in string */
|
|
if (font < 4) _core_scribe( font, ch, &xmin, &xmax, &npts, pts);
|
|
else _core_sfont( font-4, ch, &xmin, &xmax, &npts, pts);
|
|
dmx = xmax - xmin;
|
|
endx = refx + ((dmx * lfx + spx) >> 4);
|
|
endy = refy + ((dmx * lfy + spy) >> 4);
|
|
penup = TRUE;
|
|
if (_core_wndwclip || _core_outpclip) {
|
|
nextvisible = !(endx < (int)(vwprt->xmin) ||
|
|
endy < (int)(vwprt->ymin) ||
|
|
endx > (int)(vwprt->xmax) ||
|
|
endy > (int)(vwprt->ymax));
|
|
}
|
|
if (lastvisible && nextvisible)
|
|
for (i=0; i<npts; i += 2) { /* for vectors in char */
|
|
x1 = pts[i];
|
|
if (x1 == 31) penup = TRUE;
|
|
else { /* 31 is penup command */
|
|
y1 = pts[i+1];
|
|
if (penup) {
|
|
x1 -= xmin;
|
|
curx = refx + ((x1 * lfx + y1 * upx) >> 4);
|
|
cury = refy + ((x1 * lfy + y1 * upy) >> 4 );
|
|
}
|
|
else { /* else draw to the point */
|
|
x1 -= xmin;
|
|
nxtx = refx + ((x1 * lfx + y1 * upx) >> 4 );
|
|
nxty = refy + ((x1 * lfy + y1 * upy) >> 4 );
|
|
(void)pr_vector( dstpr,curx,cury,nxtx,nxty,op,1);
|
|
curx = nxtx; cury = nxty;
|
|
}
|
|
penup = FALSE;
|
|
}
|
|
}
|
|
refx = endx;
|
|
refy = endy;
|
|
lastvisible = nextvisible;
|
|
}
|
|
if (windptr->needlock)
|
|
(void)pw_unlock(windptr->pixwin);
|
|
return(0);
|
|
}
|
|
|