⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spaces.c

📁 远程桌面连接工具
💻 C
📖 第 1 页 / 共 3 页
字号:
       if (context != NULLCONTEXT) {               MatrixMultiply(contexts[context].inverse, M, M);               MatrixMultiply(M, contexts[context].normal, M);       }} /*:h2.Conversion from User's X,Y to "fractpel" X,Y When the user is building paths (lines, moves, curves, etc.) he passesthe control points (x,y) for the paths together with an XYspace.  Wemust convert from the user's (x,y) to our internal representationwhich is in pels (fractpels, actually).  This involves transformingthe user's (x,y) under the coordinate space transformation.  It isimportant that we do this quickly.  So, we store pointers to differentconversion functions right in the XYspace structure.  This allows usto have simpler special case functions for the more commonlyencountered types of transformations. :h3.Convert(), IConvert(), and ForceFloat() - Called Through "XYspace" Structure These are functions that fit in the "convert" and "iconvert" functionpointers in the XYspace structure.  They call the "xconvert", "yconvert","ixconvert", and "iyconvert" as appropriate to actually do the work.These secondary routines come in many flavors to handle differentspecial cases as quickly as possible.*/ static void FXYConvert(pt, S, x, y)       register struct fractpoint *pt;  /* point to set                      */       register struct XYspace *S;  /* relevant coordinate space             */       register double x,y;  /* user's coordinates of point                  */{       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);} static void IXYConvert(pt, S, x, y)       register struct fractpoint *pt;  /* point to set                      */       register struct XYspace *S;  /* relevant coordinate space             */       register long x,y;    /* user's coordinates of point                  */{       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);} /*ForceFloat is a substitute for IConvert(), when we just do not haveenough significant digits in the coefficients to get high enoughprecision in the answer with fixed point arithmetic.  So, we force theintegers to floats, and do the arithmetic all with floats:*/ static void ForceFloat(pt, S, x, y)       register struct fractpoint *pt;  /* point to set                      */       register struct XYspace *S;  /* relevant coordinate space             */       register long x,y;    /* user's coordinates of point                  */{       (*S->convert)(pt, S, (double) x, (double) y);} /*:h3.FXYboth(), FXonly(), FYonly() - Floating Point Conversion These are the routines we use when the user has given us floatingpoint numbers for x and y. FXYboth() is the general purpose routine;FXonly() and FYonly() are special cases when one of the coefficientsis 0.0.*/ static fractpel FXYboth(cx, cy, x, y)       register double cx,cy;  /* x and y coefficients                       */       register double x,y;  /* user x,y                                     */{       register double r;    /* temporary float                              */        r = x * cx + y * cy;       return((fractpel) r);} /*ARGSUSED*/static fractpel FXonly(cx, cy, x, y)       register double cx,cy;  /* x and y coefficients                       */       register double x,y;  /* user x,y                                     */{       register double r;    /* temporary float                              */        r = x * cx;       return((fractpel) r);} /*ARGSUSED*/static fractpel FYonly(cx, cy, x, y)       register double cx,cy;  /* x and y coefficients                       */       register double x,y;  /* user x,y                                     */{       register double r;    /* temporary float                              */        r = y * cy;       return((fractpel) r);} /*:h3.IXYboth(), IXonly(), IYonly() - Simple Integer Conversion These are the routines we use when the user has given us integers forx and y, and the coefficients have enough significant digits toprovide precise answers with only "long" (32 bit?) multiplication.IXYboth() is the general purpose routine; IXonly() and IYonly() arespecial cases when one of the coefficients is 0.*/ static fractpel IXYboth(cx, cy, x, y)       register fractpel cx,cy;  /* x and y coefficients                     */       register long x,y;    /* user x,y                                     */{       return(x * cx + y * cy);} /*ARGSUSED*/static fractpel IXonly(cx, cy, x, y)       register fractpel cx,cy;  /* x and y coefficients                     */       register long x,y;    /* user x,y                                     */{       return(x * cx);} /*ARGSUSED*/static fractpel IYonly(cx, cy, x, y)       register fractpel cx,cy;  /* x and y coefficients                     */       register long x,y;    /* user x,y                                     */{       return(y * cy);}  /*:h3.FPXYboth(), FPXonly(), FPYonly() - More Involved Integer Conversion These are the routines we use when the user has given us integers forx and y, but the coefficients do not have enough significant digits toprovide precise answers with only "long" (32 bit?)  multiplication.We have increased the number of significant bits in the coefficientsby FRACTBITS; therefore we must use "double long" (64 bit?)multiplication by calling FPmult().  FPXYboth() is the general purposeroutine; FPXonly() and FPYonly() are special cases when one of thecoefficients is 0. Note that it is perfectly possible for us to calculate X with the"FP" method and Y with the "I" method, or vice versa.  It all dependson how the functions in the XYspace structure are filled out.*/ static fractpel FPXYboth(cx, cy, x, y)       register fractpel cx,cy;  /* x and y coefficients                     */       register long x,y;    /* user x,y                                     */{       return( FPmult(x, cx) + FPmult(y, cy) );} /*ARGSUSED*/static fractpel FPXonly(cx, cy, x, y)       register fractpel cx,cy;  /* x and y coefficients                     */       register long x,y;    /* user x,y                                     */{       return( FPmult(x, cx) );} /*ARGSUSED*/static fractpel FPYonly(cx, cy, x, y)       register fractpel cx,cy;  /* x and y coefficients                     */       register long x,y;    /* user x,y                                     */{       return( FPmult(y, cy) );}   /*:h3.FillOutFcns() - Determine the Appropriate Functions to Use for Conversion This function fills out the "convert" and "iconvert" function pointersin an XYspace structure, and also fills the "helper"functions that actually do the work.*/ static void FillOutFcns(S)       register struct XYspace *S;  /* functions will be set in this structure */{       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;} /*:h4.FindFfcn() - Subroutine of FillOutFcns() to Fill Out Floating Functions This function tests for the special case of one of the coefficientsbeing zero:*/ static void FindFfcn(cx, cy, fcnP)       register double cx,cy;  /* x and y coefficients                       */       register fractpel (**fcnP)();  /* pointer to function to set          */{       if (cx == 0.0)               *fcnP = FYonly;       else if (cy == 0.0)               *fcnP = FXonly;       else               *fcnP = FXYboth;} /*:h4.FindIfcn() - Subroutine of FillOutFcns() to Fill Out Integer Functions There are two types of integer functions, the 'I' type and the 'FP' type.We use the I type functions when we are satisfied with simple integerarithmetic.  We used the FP functions when we feel we need higherprecision (but still fixed point) arithmetic.  If all else fails,we store a NULL indicating that this we should do the conversion infloating point.*/ static void FindIfcn(cx, cy, icxP, icyP, fcnP)       register double cx,cy;  /* x and y coefficients                       */       register fractpel *icxP,*icyP;  /* fixed point coefficients to set    */       register fractpel (**fcnP)();  /* pointer to function to set          */{       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 coefficientsare not exact.  However, we will still use them if the maximumcoefficient will not fit in a 'fractpel'.   Of course, we have littlechoice at that point, but we haven't lost that much precision bystaying with integer arithmetic.  We have enough significant digitsso thatany 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 haveenough significant digits for accuracy.  We will add FRACTBITSsignificant digits to the coefficients (by multiplying them by1<<FRACTBITS) and go to the "FP" form of the functions.  First, wecheck to see if we have ANY significant digits at all (that is, ifimax == 0).  If we don't, we suspect that adding FRACTBITS digitswon'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 (afterinteger conversion):*/       if (*icxP == 0)               *fcnP = (*fcnP == FPXYboth) ? FPYonly : IYonly;       else if (*icyP == 0)               *fcnP = (*fcnP == FPXYboth) ? FPXonly : IXonly;}/*:h3.UnConvert() - Find User Coordinates From FractPoints The interesting thing with this routine is that we avoid calculatingthe matrix inverse of the device transformation until we really needit, which is to say, until this routine is called for the first timewith a given coordinate space. We also only calculate it only once.  If the inverted matrix is valid,we don't calculate it; if not, we do.  We never expect matrices withzero determinants, so by convention, we mark the matrix is invalid bymarking both X terms zero.*/ void UnConvert(S, pt, xp, yp)       register struct XYspace *S;  /* relevant coordinate space             */       register struct fractpoint *pt;  /* device coordinates                */       double *xp,*yp;       /* where to store resulting x,y                 */{       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;} /*:h2.Transformations*//*:h3 id=xform.Xform() - Transform Object in X and Y TYPE1IMAGER wants transformations of objects like paths to be identicalto transformations of spaces.  For example, if you scale a line(1,1)by 10 it should yield the same result as generating the line(1,1) ina coordinate space that has been scaled by 10. We handle fonts by storing the accumulated transform, for example, SR(accumulating on the right).  Then when we map the font through space TD,for example, we multiply the accumulated font transform on the left bythe space transform on the right, yielding SRTD in this case.  We willget the same result if we did S, then R, then T on the space and mappingan unmodified font through that space.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -