Back to index

tetex-bin  3.0
Defines | Functions | Variables
spaces.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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 int FindFfcn ()
static int FindIfcn ()
struct XYspaceCopySpace (struct XYspace *S)
static void ConsiderContext (struct xobject *obj, M)
int FXYConvert (struct fractpoint *pt, struct XYspace *S, DOUBLE x, DOUBLE y)
int IXYConvert (struct fractpoint *pt, struct XYspace *S, LONG x, LONG y)
int 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 int FindFfcn (DOUBLE cx, DOUBLE cy, fractpel(**fcnP)())
static int 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 *string, 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 159 of file spaces.c.

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

Definition at line 978 of file spaces.c.

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

Definition at line 153 of file spaces.c.

#define MAXCONTEXTS   16

Definition at line 182 of file spaces.c.

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

Definition at line 126 of file spaces.c.

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

Definition at line 123 of file spaces.c.


Function Documentation

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

Definition at line 317 of file spaces.c.

{
       register int context=0; /* 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 130 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 1005 of file spaces.c.

{
       IfTrace4(TRUE,"--Coordinate space at %p,ID=%d,convert=%p,iconvert=%p\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,"   [  %d  %d ]\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,"   [  %d  %d ]\n", S->itofract[1][0], S->itofract[1][1]);
}
static void FillOutFcns ( struct XYspace S) [static]

Definition at line 533 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 int FindFfcn ( ) [static]

Here is the caller graph for this function:

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

Definition at line 557 of file spaces.c.

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

Here is the call graph for this function:

static int FindIfcn ( ) [static]

Here is the caller graph for this function:

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

Definition at line 582 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 = TYPE1_MAX(TYPE1_ABS(*icxP), TYPE1_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(0);
                       }
                       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;
       return(0);
       
}

Here is the call graph for this function:

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

Definition at line 398 of file spaces.c.

{
       (*S->convert)(pt, S, (DOUBLE) x, (DOUBLE) y);
       return(0);
       
}

Here is the caller graph for this function:

void FormatFP ( char *  string,
fractpel  fpel 
)

Definition at line 980 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(string, "%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 508 of file spaces.c.

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

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 500 of file spaces.c.

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

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 516 of file spaces.c.

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

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 428 of file spaces.c.

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

Here is the caller graph for this function:

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

Definition at line 417 of file spaces.c.

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

Here is the caller graph for this function:

int FXYConvert ( struct fractpoint pt,
struct XYspace S,
DOUBLE  x,
DOUBLE  y 
)

Definition at line 369 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);
       return(0);
       
}

Here is the caller graph for this function:

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

Definition at line 439 of file spaces.c.

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

Here is the caller graph for this function:

Definition at line 923 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 467 of file spaces.c.

{
       return(x * cx);
}

Here is the caller graph for this function:

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

Definition at line 459 of file spaces.c.

{
       return(x * cx + y * cy);
}

Here is the caller graph for this function:

int IXYConvert ( struct fractpoint pt,
struct XYspace S,
LONG  x,
LONG  y 
)

Definition at line 380 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);
       return(0);
       
}

Here is the caller graph for this function:

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

Definition at line 475 of file spaces.c.

{
       return(y * cy);
}

Here is the caller graph for this function:

void MatrixInvert ( ,
Mprime   
)

Definition at line 890 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)
               abort("MatrixInvert:  can't", 47);
 
       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 868 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 823 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 951 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 775 of file spaces.c.

{
       DOUBLE M[2][2];
       IfTrace3((MustTraceCalls),"Scale(%p, %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));
}
struct xobject* t1_Transform ( struct xobject obj,
DOUBLE  cxx,
DOUBLE  cyx,
DOUBLE  cxy,
DOUBLE  cyy 
) [read]

Definition at line 753 of file spaces.c.

{
       DOUBLE M[2][2];
 
       IfTrace1((MustTraceCalls),"Transform(%p,", 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));
}
struct xobject* t1_Xform ( struct xobject obj,
 
) [read]

Definition at line 687 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 654 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 184 of file spaces.c.

struct XYspace* IDENTITY = &identity

Definition at line 178 of file spaces.c.

unsigned int SpaceID = 1 [static]

Definition at line 128 of file spaces.c.

struct XYspace* USER = &identity

Definition at line 921 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 170 of file spaces.c.