Back to index

tetex-bin  3.0
Defines | Functions | Variables
spaces.c File Reference
#include "types.h"
#include "objects.h"
#include "spaces.h"
#include "paths.h"
#include "pictures.h"
#include "fonts.h"
#include "arith.h"
#include "trig.h"

Go to the source code of this file.

Defines

#define RESERVED   10 /* 'n' IDs are reserved for invalid & immortal spaces */
#define NEXTID   ((SpaceID < RESERVED) ? (SpaceID = RESERVED) : ++SpaceID)
#define HASINVERSE(flag)   ((flag)&0x80)
#define CoerceInverse(S)
#define MAXCONTEXTS   16
#define FRACTMASK   ((1<<FRACTBITS)-1) /* mask for fractional part */

Functions

static void FindFfcn ()
static void FindIfcn ()
struct XYspaceCopySpace (struct XYspace *S)
static void ConsiderContext (struct xobject *obj, M)
void FXYConvert (struct fractpoint *pt, struct XYspace *S, DOUBLE x, DOUBLE y)
void IXYConvert (struct fractpoint *pt, struct XYspace *S, LONG x, LONG y)
void ForceFloat (struct fractpoint *pt, struct XYspace *S, LONG x, LONG y)
fractpel FXYboth (DOUBLE cx, DOUBLE cy, DOUBLE x, DOUBLE y)
fractpel FXonly (DOUBLE cx, DOUBLE cy, DOUBLE x, DOUBLE y)
fractpel FYonly (DOUBLE cx, DOUBLE cy, DOUBLE x, DOUBLE y)
fractpel IXYboth (fractpel cx, fractpel cy, LONG x, LONG y)
fractpel IXonly (fractpel cx, fractpel cy, LONG x, LONG y)
fractpel IYonly (fractpel cx, fractpel cy, LONG x, LONG y)
fractpel FPXYboth (fractpel cx, fractpel cy, LONG x, LONG y)
fractpel FPXonly (fractpel cx, fractpel cy, LONG x, LONG y)
fractpel FPYonly (fractpel cx, fractpel cy, LONG x, LONG y)
static void FillOutFcns (struct XYspace *S)
static void FindFfcn (DOUBLE cx, DOUBLE cy, fractpel(**fcnP)())
static void FindIfcn (DOUBLE cx, DOUBLE cy, fractpel *icxP, fractpel *icyP, fractpel(**fcnP)())
void UnConvert (struct XYspace *S, struct fractpoint *pt, DOUBLE *xp, DOUBLE *yp)
struct xobjectt1_Xform (struct xobject *obj, M)
struct xobjectt1_Transform (struct xobject *obj, DOUBLE cxx, DOUBLE cyx, DOUBLE cxy, DOUBLE cyy)
struct xobjectt1_Scale (struct xobject *obj, DOUBLE sx, DOUBLE sy)
void PseudoSpace (struct XYspace *S, M)
void MatrixMultiply (A, B, C)
void MatrixInvert (M, Mprime)
void InitSpaces ()
void QuerySpace (struct XYspace *S, DOUBLE *cxxP, DOUBLE *cyxP, DOUBLE *cxyP, DOUBLE *cyyP)
void FormatFP (char *str, fractpel fpel)
void DumpSpace (struct XYspace *S)

Variables

static unsigned int SpaceID = 1
static struct XYspace
struct XYspaceIDENTITY = &identity
static struct doublematrix [MAXCONTEXTS]
struct XYspaceUSER = &identity

Define Documentation

#define CoerceInverse (   S)
Value:
if (!HASINVERSE((S)->flag)) { \
    MatrixInvert((S)->tofract.normal, (S)->tofract.inverse); (S)->flag |= HASINVERSE(ON); }

Definition at line 154 of file spaces.c.

#define FRACTMASK   ((1<<FRACTBITS)-1) /* mask for fractional part */

Definition at line 963 of file spaces.c.

#define HASINVERSE (   flag)    ((flag)&0x80)

Definition at line 148 of file spaces.c.

#define MAXCONTEXTS   16

Definition at line 177 of file spaces.c.

#define NEXTID   ((SpaceID < RESERVED) ? (SpaceID = RESERVED) : ++SpaceID)

Definition at line 121 of file spaces.c.

#define RESERVED   10 /* 'n' IDs are reserved for invalid & immortal spaces */

Definition at line 118 of file spaces.c.


Function Documentation

static void ConsiderContext ( struct xobject obj,
 
) [static]

Definition at line 312 of file spaces.c.

{
       register int context; /* index in contexts array                      */
 
       if (obj == NULL) return;
 
       if (ISPATHTYPE(obj->type)) {
               struct segment *path = (struct segment *) obj;
 
               context = path->context;
       }
       else if (obj->type == SPACETYPE) {
               struct XYspace *S = (struct XYspace *) obj;
 
               context = S->context;
       }
       else if (obj->type == PICTURETYPE) {

       }
       else
               context = NULLCONTEXT;
 
       if (context != NULLCONTEXT) {
               MatrixMultiply(contexts[context].inverse, M, M);
               MatrixMultiply(M, contexts[context].normal, M);
       }
}

Here is the caller graph for this function:

struct XYspace* CopySpace ( struct XYspace S) [read]

Definition at line 125 of file spaces.c.

{
       S = (struct XYspace *)Allocate(sizeof(struct XYspace), S, 0);
       S->ID = NEXTID;
       return(S);
}
void DumpSpace ( struct XYspace S)

Definition at line 990 of file spaces.c.

{
       IfTrace4(TRUE,"--Coordinate space at %x,ID=%d,convert=%x,iconvert=%x\n",
                   S, S->ID, S->convert, S->iconvert);
       IfTrace2(TRUE,"             |  %12.3f  %12.3f  |",
                   &S->tofract.normal[0][0], &S->tofract.normal[0][1]);
       IfTrace2(TRUE,"   [  %p  %p ]\n", S->itofract[0][0], S->itofract[0][1]);
       IfTrace2(TRUE,"             |  %12.3f  %12.3f  |",
                   &S->tofract.normal[1][0], &S->tofract.normal[1][1]);
       IfTrace2(TRUE,"   [  %p  %p ]\n", S->itofract[1][0], S->itofract[1][1]);
}
static void FillOutFcns ( struct XYspace S) [static]

Definition at line 522 of file spaces.c.

{
       S->convert = FXYConvert;
       S->iconvert = IXYConvert;
 
       FindFfcn(S->tofract.normal[0][0], S->tofract.normal[1][0], &S->xconvert);
       FindFfcn(S->tofract.normal[0][1], S->tofract.normal[1][1], &S->yconvert);
       FindIfcn(S->tofract.normal[0][0], S->tofract.normal[1][0],
                &S->itofract[0][0], &S->itofract[1][0], &S->ixconvert);
       FindIfcn(S->tofract.normal[0][1], S->tofract.normal[1][1],
                &S->itofract[0][1], &S->itofract[1][1], &S->iyconvert);
 
       if (S->ixconvert == NULL || S->iyconvert == NULL)
                S->iconvert = ForceFloat;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void FindFfcn ( ) [static]
static void FindFfcn ( DOUBLE  cx,
DOUBLE  cy,
fractpel (**)()  fcnP 
) [static]

Definition at line 546 of file spaces.c.

{
       if (cx == 0.0)
               *fcnP = FYonly;
       else if (cy == 0.0)
               *fcnP = FXonly;
       else
               *fcnP = FXYboth;
}

Here is the call graph for this function:

static void FindIfcn ( ) [static]
static void FindIfcn ( DOUBLE  cx,
DOUBLE  cy,
fractpel icxP,
fractpel icyP,
fractpel (**)()  fcnP 
) [static]

Definition at line 569 of file spaces.c.

{
       register fractpel imax;  /* maximum of cx and cy                      */
 
       *icxP = cx;
       *icyP = cy;
 
       if (cx != (float) (*icxP) || cy != (float) (*icyP)) {
/*
At this point we know our integer approximations of the coefficients
are not exact.  However, we will still use them if the maximum
coefficient will not fit in a 'fractpel'.   Of course, we have little
choice at that point, but we haven't lost that much precision by
staying with integer arithmetic.  We have enough significant digits
so that
any error we introduce is less than one part in 2:sup/16/.
*/
 
               imax = MAX(ABS(*icxP), ABS(*icyP));
               if (imax < (fractpel) (1<<(FRACTBITS-1)) ) {
/*
At this point we know our integer approximations just do not have
enough significant digits for accuracy.  We will add FRACTBITS
significant digits to the coefficients (by multiplying them by
1<<FRACTBITS) and go to the "FP" form of the functions.  First, we
check to see if we have ANY significant digits at all (that is, if
imax == 0).  If we don't, we suspect that adding FRACTBITS digits
won't help, so we punt the whole thing.
*/
                       if (imax == 0) {
                               *fcnP = NULL;
                               return;
                       }
                       cx *= FRACTFLOAT;
                       cy *= FRACTFLOAT;
                       *icxP = cx;
                       *icyP = cy;
                       *fcnP = FPXYboth;
               }
               else
                       *fcnP = IXYboth;
       }
       else
               *fcnP = IXYboth;
/*
Now we check for special cases where one coefficient is zero (after
integer conversion):
*/
       if (*icxP == 0)
               *fcnP = (*fcnP == FPXYboth) ? FPYonly : IYonly;
       else if (*icyP == 0)
               *fcnP = (*fcnP == FPXYboth) ? FPXonly : IXonly;
}

Here is the call graph for this function:

void ForceFloat ( struct fractpoint pt,
struct XYspace S,
LONG  x,
LONG  y 
)

Definition at line 389 of file spaces.c.

{
       (*S->convert)(pt, S, (DOUBLE) x, (DOUBLE) y);
}
void FormatFP ( char *  str,
fractpel  fpel 
)

Definition at line 965 of file spaces.c.

{
       char temp[8];
       register char *s;
       register char *sign;
 
       if (fpel < 0) {
               sign = "-";
               fpel = -fpel;
       }
       else
               sign = "";
 
       sprintf(temp, "000%x", fpel & FRACTMASK);
       s = temp + strlen(temp) - (FRACTBITS/4);
 
       sprintf(str, "%s%d.%sx", sign, fpel >> FRACTBITS, s);
}

Here is the call graph for this function:

fractpel FPXonly ( fractpel  cx,
fractpel  cy,
LONG  x,
LONG  y 
)

Definition at line 497 of file spaces.c.

{
       return( FPmult(x, cx) );
}

Here is the call graph for this function:

fractpel FPXYboth ( fractpel  cx,
fractpel  cy,
LONG  x,
LONG  y 
)

Definition at line 489 of file spaces.c.

{
       return( FPmult(x, cx) + FPmult(y, cy) );
}

Here is the call graph for this function:

fractpel FPYonly ( fractpel  cx,
fractpel  cy,
LONG  x,
LONG  y 
)

Definition at line 505 of file spaces.c.

{
       return( FPmult(y, cy) );
}

Here is the call graph for this function:

fractpel FXonly ( DOUBLE  cx,
DOUBLE  cy,
DOUBLE  x,
DOUBLE  y 
)

Definition at line 417 of file spaces.c.

{
       register DOUBLE r;    /* temporary float                              */
 
       r = x * cx;
       return((fractpel) r);
}
fractpel FXYboth ( DOUBLE  cx,
DOUBLE  cy,
DOUBLE  x,
DOUBLE  y 
)

Definition at line 406 of file spaces.c.

{
       register DOUBLE r;    /* temporary float                              */
 
       r = x * cx + y * cy;
       return((fractpel) r);
}
void FXYConvert ( struct fractpoint pt,
struct XYspace S,
DOUBLE  x,
DOUBLE  y 
)

Definition at line 364 of file spaces.c.

{
       pt->x = (*S->xconvert)(S->tofract.normal[0][0], S->tofract.normal[1][0], x, y);
       pt->y = (*S->yconvert)(S->tofract.normal[0][1], S->tofract.normal[1][1], x, y);
}
fractpel FYonly ( DOUBLE  cx,
DOUBLE  cy,
DOUBLE  x,
DOUBLE  y 
)

Definition at line 428 of file spaces.c.

{
       register DOUBLE r;    /* temporary float                              */
 
       r = y * cy;
       return((fractpel) r);
}

Definition at line 908 of file spaces.c.

{
       extern char *DEFAULTDEVICE;
 
       IDENTITY->type = SPACETYPE;
       FillOutFcns(IDENTITY);
 
       contexts[NULLCONTEXT].normal[1][0]
             = contexts[NULLCONTEXT].normal[0][1]
             = contexts[NULLCONTEXT].inverse[1][0]
             = contexts[NULLCONTEXT].inverse[0][1] = 0.0;
       contexts[NULLCONTEXT].normal[0][0]
             = contexts[NULLCONTEXT].normal[1][1]
             = contexts[NULLCONTEXT].inverse[0][0]
             = contexts[NULLCONTEXT].inverse[1][1] = 1.0;
 
       USER->flag |= ISIMMORTAL(ON);
       CoerceInverse(USER);
}

Here is the call graph for this function:

fractpel IXonly ( fractpel  cx,
fractpel  cy,
LONG  x,
LONG  y 
)

Definition at line 456 of file spaces.c.

{
       return(x * cx);
}
fractpel IXYboth ( fractpel  cx,
fractpel  cy,
LONG  x,
LONG  y 
)

Definition at line 448 of file spaces.c.

{
       return(x * cx + y * cy);
}
void IXYConvert ( struct fractpoint pt,
struct XYspace S,
LONG  x,
LONG  y 
)

Definition at line 373 of file spaces.c.

{
       pt->x = (*S->ixconvert)(S->itofract[0][0], S->itofract[1][0], x, y);
       pt->y = (*S->iyconvert)(S->itofract[0][1], S->itofract[1][1], x, y);
}
fractpel IYonly ( fractpel  cx,
fractpel  cy,
LONG  x,
LONG  y 
)

Definition at line 464 of file spaces.c.

{
       return(y * cy);
}
void MatrixInvert ( ,
Mprime   
)

Definition at line 875 of file spaces.c.

{
       register DOUBLE D;    /* determinant of matrix M                      */
       register DOUBLE txx,txy,tyx,tyy;
 
       txx = M[0][0];
       txy = M[1][0];
       tyx = M[0][1];
       tyy = M[1][1];
 
       D = M[1][1] * M[0][0] - M[1][0] * M[0][1];
       if (D == 0.0)
               t1_abort("MatrixInvert:  can't");
 
       Mprime[0][0] = tyy / D;
       Mprime[1][0] = -txy / D;
       Mprime[0][1] = -tyx / D;
       Mprime[1][1] = txx / D;
}

Here is the call graph for this function:

void MatrixMultiply ( ,
B  ,
C   
)

Definition at line 853 of file spaces.c.

{
       register DOUBLE txx,txy,tyx,tyy;
 
       txx = A[0][0] * B[0][0] + A[0][1] * B[1][0];
       txy = A[1][0] * B[0][0] + A[1][1] * B[1][0];
       tyx = A[0][0] * B[0][1] + A[0][1] * B[1][1];
       tyy = A[1][0] * B[0][1] + A[1][1] * B[1][1];
 
       C[0][0] = txx;
       C[1][0] = txy;
       C[0][1] = tyx;
       C[1][1] = tyy;
}
void PseudoSpace ( struct XYspace S,
 
)

Definition at line 808 of file spaces.c.

{
       S->type = SPACETYPE;
       S->flag = ISPERMANENT(ON) + ISIMMORTAL(ON);
       S->references = 2;   /* 3-26-91 added PNM  */
       S->tofract.normal[0][0] = M[0][0];
       S->tofract.normal[1][0] = M[1][0];
       S->tofract.normal[0][1] = M[0][1];
       S->tofract.normal[1][1] = M[1][1];
 
       FillOutFcns(S);
}

Here is the call graph for this function:

void QuerySpace ( struct XYspace S,
DOUBLE cxxP,
DOUBLE cyxP,
DOUBLE cxyP,
DOUBLE cyyP 
)

Definition at line 936 of file spaces.c.

{
       DOUBLE M[2][2];       /* temp matrix to build user's answer           */
 
       if (S->type != SPACETYPE) {
               ArgErr("QuerySpace: not a space", S, NULL);
               return;
       }
       MatrixMultiply(S->tofract.normal, IDENTITY->tofract.inverse, M);
       *cxxP = M[0][0];
       *cxyP = M[1][0];
       *cyxP = M[0][1];
       *cyyP = M[1][1];
}
struct xobject* t1_Scale ( struct xobject obj,
DOUBLE  sx,
DOUBLE  sy 
) [read]

Definition at line 760 of file spaces.c.

{
       DOUBLE M[2][2];
       IfTrace3((MustTraceCalls),"Scale(%z, %f, %f)\n", obj, &sx, &sy);
       M[0][0] = sx;
       M[1][1] = sy;
       M[1][0] = M[0][1] = 0.0;
       ConsiderContext(obj, M);
       return(Xform(obj, M));
}

Here is the call graph for this function:

struct xobject* t1_Transform ( struct xobject obj,
DOUBLE  cxx,
DOUBLE  cyx,
DOUBLE  cxy,
DOUBLE  cyy 
) [read]

Definition at line 738 of file spaces.c.

{
       DOUBLE M[2][2];
 
       IfTrace1((MustTraceCalls),"Transform(%z,", obj);
       IfTrace4((MustTraceCalls)," %f %f %f %f)\n", &cxx, &cyx, &cxy, &cyy);
 
       M[0][0] = cxx;
       M[0][1] = cyx;
       M[1][0] = cxy;
       M[1][1] = cyy;
       ConsiderContext(obj, M);
       return(Xform(obj, M));
}

Here is the call graph for this function:

struct xobject* t1_Xform ( struct xobject obj,
 
) [read]

Definition at line 672 of file spaces.c.

{
       if (obj == NULL)
               return(NULL);
 
       if (obj->type == FONTTYPE) {
               register struct font *F = (struct font *) obj;
 
               F = UniqueFont(F);
               return((struct xobject*)F);
       }
       if (obj->type == PICTURETYPE) {
/*
In the case of a picture, we choose both to update the picture's
transformation matrix and keep the handles up to date.
*/
               register struct picture *P = (struct picture *) obj;
               register struct segment *handles;  /* temporary path to transform handles */
 
               P = UniquePicture(P);
               handles = PathSegment(LINETYPE, P->origin.x, P->origin.y);
               handles = Join(handles,
                              PathSegment(LINETYPE, P->ending.x, P->ending.y) );
               handles = (struct segment *)Xform((struct xobject *) handles, M);
               P->origin = handles->dest;
               P->ending = handles->link->dest;
               KillPath(handles);
               return((struct xobject *)P);
       }
 
       if (ISPATHTYPE(obj->type)) {
               struct XYspace pseudo;  /* local temporary space              */
               PseudoSpace(&pseudo, M);
               return((struct xobject *) PathTransform(obj, &pseudo));
       }
 
 
       if (obj->type == SPACETYPE) {
               register struct XYspace *S = (struct XYspace *) obj;
 
/* replaced ISPERMANENT(S->flag) with S->references > 1 3-26-91 PNM */
               if (S->references > 1)
                       S = CopySpace(S);
               else
                       S->ID = NEXTID;
 
               MatrixMultiply(S->tofract.normal, M, S->tofract.normal);
               /*
               * mark inverted matrix invalid:
               */
               S->flag &= ~HASINVERSE(ON);
 
               FillOutFcns(S);
               return((struct xobject *) S);
       }
 
       return(ArgErr("Untransformable object", obj, obj));
}

Here is the call graph for this function:

void UnConvert ( struct XYspace S,
struct fractpoint pt,
DOUBLE xp,
DOUBLE yp 
)

Definition at line 639 of file spaces.c.

{
       DOUBLE x,y;
 
       CoerceInverse(S);
       x = pt->x;
       y = pt->y;
       *xp = S->tofract.inverse[0][0] * x + S->tofract.inverse[1][0] * y;
       *yp = S->tofract.inverse[0][1] * x + S->tofract.inverse[1][1] * y;
}

Variable Documentation

struct doublematrix[MAXCONTEXTS] [static]

Definition at line 179 of file spaces.c.

struct XYspace* IDENTITY = &identity

Definition at line 173 of file spaces.c.

unsigned int SpaceID = 1 [static]

Definition at line 123 of file spaces.c.

struct XYspace* USER = &identity

Definition at line 906 of file spaces.c.

struct XYspace [static]
Initial value:
 { SPACETYPE, ISPERMANENT(ON) + ISIMMORTAL(ON)
                        + HASINVERSE(ON), 2, 
                        NULL, NULL,
                        NULL, NULL, NULL, NULL,
                        INVALIDID + 1, 0,
                        FRACTFLOAT, 0.0, 0.0, FRACTFLOAT,
                        1.0/FRACTFLOAT, 0.0, 0.0, 1.0/FRACTFLOAT,
                        0, 0, 0, 0 }

Definition at line 165 of file spaces.c.