?? spaces.c
字號(hào):
/* $XConsortium: spaces.c,v 1.8 95/06/08 23:20:39 gildea Exp $ *//* Copyright International Business Machines, Corp. 1991 * All Rights Reserved * Copyright Lexmark International, Inc. 1991 * All Rights Reserved * * License to use, copy, modify, and distribute this software and its * documentation 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 appear in * supporting documentation, and that the name of IBM or Lexmark not be * used in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF * THIS SOFTWARE. */ /* SPACES CWEB V0021 ******** *//*:h1 id=spaces.SPACES Module - Handles Coordinate Spaces This module is responsible for handling the TYPE1IMAGER "XYspace" object. &author. Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com) :h3.Include Files*/#include "objects.h"#include "spaces.h"#include "paths.h"#include "pictures.h"#include "fonts.h"#include "arith.h"#include "trig.h"static void FindFfcn();static void FindIfcn();/*:h3.Entry Points Provided to the TYPE1IMAGER User*/ /*SHARED LINE(S) ORIGINATED HERE*/ /*:h3.Entry Points Provided to Other Modules*/ /*In addition, other modules call the SPACES module through functionvectors in the "XYspace" structure. The entry points accessed thatway are "FConvert()", "IConvert()", and "ForceFloat()".*/ /*SHARED LINE(S) ORIGINATED HERE*//*:h3.Macros and Typedefs Provided to Other Modules :h4.Duplicating and Killing Spaces Destroying XYspaces is so simple we can do it with amacro:*/ /*SHARED LINE(S) ORIGINATED HERE*//*On the other hand, duplicating XYspaces is slightly more difficultbecause of the need to keep a unique ID in the space, see:hdref refid=dupspace.. :h4.Fixed Point Pel Representation We represent pel positions with fixed point numbers. This does NOTmean integer, but truly means fixed point, with a certain numberof binary digits (FRACTBITS) representing the fractional part of thepel.*/ /*SHARED LINE(S) ORIGINATED HERE*//*:h2.Data Structures for Coordinate Spaces and Points*//*:h3 id=matrix.Matrices TYPE1IMAGER uses 2x2 transformation matrices. We'll use C notation forsuch a matrix (M[2][2]), the first index being rows, the second columns.*/ /*:h3.The "doublematrix" Structure We frequently find it desirable to store both a matrix and itsinverse. We store these in a "doublematrix" structure.*/ /*SHARED LINE(S) ORIGINATED HERE*/ /*:h3.The "XYspace" Structure The XYspace structure represents the XYspace object.*/ /*SHARED LINE(S) ORIGINATED HERE*/#define RESERVED 10 /* 'n' IDs are reserved for invalid & immortal spaces *//**/#define NEXTID ((SpaceID < RESERVED) ? (SpaceID = RESERVED) : ++SpaceID) static unsigned int SpaceID = 1; struct XYspace *CopySpace(S) register struct XYspace *S;{ S = (struct XYspace *)Allocate(sizeof(struct XYspace), S, 0); S->ID = NEXTID; return(S);}/*:h3.The "fractpoint" Structure A fractional point is just a "fractpel" x and y:*/ /*SHARED LINE(S) ORIGINATED HERE*/ /*:h3.Lazy Evaluation of Matrix Inverses Calculating the inverse of a matrix is somewhat involved, and we usuallydo not need them. So, we flag whether or not the space has the inversealready calculated:*/ #define HASINVERSE(flag) ((flag)&0x80) /*The following macro forces a space to have an inverse:*/ #define CoerceInverse(S) if (!HASINVERSE((S)->flag)) { \ MatrixInvert((S)->tofract.normal, (S)->tofract.inverse); (S)->flag |= HASINVERSE(ON); }/*:h3.IDENTITY Space IDENTITY space is (logically) the space corresponding to the identitytransformation matrix. However, since all our transformation matriceshave a common FRACTFLOAT scale factor to convert to 'fractpel's, thatis actually what we store in 'tofract' matrix of IDENTITY:*/ static struct XYspace identity = { SPACETYPE, ISPERMANENT(ON) + ISIMMORTAL(ON) + HASINVERSE(ON), 2, /* added 3-26-91 PNM */ 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 };struct XYspace *IDENTITY = &identity; /**/#define MAXCONTEXTS 16 static struct doublematrix contexts[MAXCONTEXTS]; #ifdef notdefstatic int nextcontext = 1; /*SHARED LINE(S) ORIGINATED HERE*/#ifdef __STDC__#define pointer void *#else#define pointer char *#endif /*:h3.FindDeviceContext() - Find the Context Given a Device This routine, given a device, returns the index of the device'stransformation matrix in the context array. If it cannot find it,it will allocate a new array entry and fill it out.*/ static int FindDeviceContext(device) pointer device; /* device token */{ double M[2][2]; /* temporary matrix */ float Xres,Yres; /* device resolution */ int orient = -1; /* device orientation */ int rc = -1; /* return code for QueryDeviceState */ if (rc != 0) /* we only bother with this check once */ abort("Context: QueryDeviceState didn't work"); M[0][0] = M[1][0] = M[0][1] = M[1][1] = 0.0; switch (orient) { case 0: M[0][0] = Xres; M[1][1] = -Yres; break; case 1: M[1][0] = Yres; M[0][1] = Xres; break; case 2: M[0][0] = -Xres; M[1][1] = Yres; break; case 3: M[1][0] = -Yres; M[0][1] = -Xres; break; default: abort("QueryDeviceState returned invalid orientation"); } return(FindContext(M));} /*:h3.FindContext() - Find the Context Given a Matrix This routine, given a matrix, returns the index of that matrix matrix inthe context array. If it cannot find it, it will allocate a new arrayentry and fill it out.*/ int FindContext(M) double M[2][2]; /* array to search for */{ register int i; /* loop variable for search */ for (i=0; i < nextcontext; i++) if (M[0][0] == contexts[i].normal[0][0] && M[1][0] == contexts[i].normal[1][0] && M[0][1] == contexts[i].normal[0][1] && M[1][1] == contexts[i].normal[1][1]) break; if (i >= nextcontext) { if (i >= MAXCONTEXTS) abort("Context: out of them"); LONGCOPY(contexts[i].normal, M, sizeof(contexts[i].normal)); MatrixInvert(M, contexts[i].inverse); nextcontext++; } return(i);} /*:h3.Context() - Create a Coordinate Space for a Device This user operator is implemented by first finding the device contextarray index, then transforming IDENTITY space to create an appropriatecooridnate space.*/ struct XYspace *Context(device, units) pointer device; /* device token */ double units; /* multiples of one inch */{ double M[2][2]; /* device transformation matrix */ register int n; /* will hold device context number */ register struct XYspace *S; /* XYspace constructed */ IfTrace2((MustTraceCalls),"Context(%x, %f)\n", device, &units); ARGCHECK((device == NULL), "Context of NULLDEVICE not allowed", NULL, IDENTITY, (0), struct XYspace *); ARGCHECK((units == 0.0), "Context: bad units", NULL, IDENTITY, (0), struct XYspace *); n = FindDeviceContext(device); LONGCOPY(M, contexts[n].normal, sizeof(M)); M[0][0] *= units; M[0][1] *= units; M[1][0] *= units; M[1][1] *= units; S = (struct XYspace *)Xform(IDENTITY, M); S->context = n; return(S);}#endif /*:h3.ConsiderContext() - Adjust a Matrix to Take Out Device Transform Remember, we have :f/x times U times D/ and :f/M/ and and we want :f/xtimes U times M times D/. An easy way to do this is to calculate:f/D sup <-1> times M times D/, because::formula.x times U times D times D sup <-1> times M times D = x times U times M times D:formula.So this subroutine, given an :f/M/and an object, finds the :f/D/ for thatobject and modifies :f/M/ so it is :f/D sup <-1> times M times D/.*/ static void ConsiderContext(obj, M) register struct xobject *obj; /* object to be transformed */ register double M[2][2]; /* matrix (may be changed) */{ 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;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -