]> git.sesse.net Git - rdpsrv/blobdiff - Xserver/lib/font/Type1/objects.c
Removed Xserver/ directory, it does nothing useful ATM.
[rdpsrv] / Xserver / lib / font / Type1 / objects.c
diff --git a/Xserver/lib/font/Type1/objects.c b/Xserver/lib/font/Type1/objects.c
deleted file mode 100644 (file)
index 9fffa62..0000000
+++ /dev/null
@@ -1,1119 +0,0 @@
-/* $XConsortium: objects.c,v 1.11 94/03/23 14:28:05 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.
- */
- /* OBJECTS  CWEB         V0025 ********                             */
-/*
-:h1.OBJECTS Module - TYPE1IMAGER Objects Common Routines
-This module defines and implements the C structures that represent
-objects in the TYPE1IMAGER.  All common routines for manipulating these
-objects are defined in this module.  Specific routines for
-specific objects are defined in the modules that deal with that
-object type.
-&author. Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com)
-:h3.Include Files
-The included files are:
-*/
-#define   GLOBALS  1         /* see :hdref refid=debugvar.                   */
-/*
-The following two includes are C standards; we include them because we
-use 'toupper' and the 'str'-type functions in this module.  Potentially
-these may be defined as macros; if these ".h" files do not exist on your
-system it is a pretty safe bet that these are external entry points and
-you do do not need to include these header files.
-*/
-#include  <string.h>
-#include  <ctype.h>
-/*
-override incorrect system functions; for example you might define
-a macro for "strcpy" that diverts it to "my_strcpy".
-*/
-                               /* moved these includes from above the    */
-                               /*   was included first (it contains com- */
-                               /*   piler defines).  dsr 081291          */
-#include  "objects.h"
-#include  "spaces.h"
-#include  "paths.h"
-#include  "regions.h"
-#include  "fonts.h"
-#include  "pictures.h"
-#include  "strokes.h"
-#include  "cluts.h"
-static char *TypeFmt();
-static ObjectPostMortem();
-
-/*
-:h3.The "pointer" Macro - Define a Generic Pointer
-Sadly, many compilers will give a warning message when a pointer to
-one structure is assigned to a pointer to another.  We've even seen
-some that give severe errors (when the wrong pointer type is used as
-an initializer or returned from a function).  TYPE1IMAGER has routines
-like Dup and Allocate that are perfectly willing to duplicate or
-allocate any of a number of different types of structures.  How to
-declare them in a truely portable way?
-Well, there is no single good answer that I've found.  You can always
-beg the question and "cast" everything.  I find this distracting and the
-resulting code ugly.  On the other hand, we have found at least one
-compiler that will accept "void *" as a generic pointer that can
-assigned to any other pointer type without error or warning (apparently
-this is also the ANSI standard).  So, we define "void *" to be a generic
-pointer.  (You might have to change this for your compiler; the "ifndef"
-allows the change to be made on the command line if you want.)
-:i1/portability assumptions/
-*/
-/*SHARED LINE(S) ORIGINATED HERE*/
-/*
-:h3.Functions Provided to the TYPE1IMAGER User
-This module provides the following TYPE1IMAGER entry points:
-*/
-/*SHARED LINE(S) ORIGINATED HERE*/
-/*
-Note that entry points that are intended for use external to TYPE1IMAGER
-begin with the characters :q/xi/.  Macros are used to make the names
-more mnemonic.
-*/
-/*
-:h3.Functions Provided to Other Modules
-This module provides the following functions for other modules:
-*/
-/*SHARED LINE(S) ORIGINATED HERE*/
-/*
-Note that entry points that intended for use within TYPE1IMAGER, but
-which must be global because they are used across module boundaries,
-begin with the characters :q/I_/.  Macros are used to make the names
-more mnemonic.
-Entry points totally within a module use mnemonic names and are
-declared :hp2/static/.  One of the compilers I used had a bug when
-static functions were passed as addresses.  Thus, some functions
-which are logically "static" are not so declared.
-Note also the trick of declaring routines, like Consume(), with a
-variable number of arguments.  To avoid the restrictions on variable
-numbers of arguments in the macro processor, we just replace the
-text 'Consume' with 'I_Consume'.
-*/
-/*
-:h3.Macros Provided to Other Modules
-This is the module where we define all the useful constants like
-TRUE, FALSE, and NULL, and simple expressions like MIN(), MAX(), and ABS().
-We might as well get to it right here:
-*/
-/*SHARED LINE(S) ORIGINATED HERE*/
-/*
-Notice that upper case is used for constant values and macro
-definitions.  I generally follow that convention.
-Many more global macros are defined later in this module.
-*/
-/*
-:h2.Basic TYPE1IMAGER Object Structure
-All TYPE1IMAGER objects which are available to the user have a common
-header.  This header is defined below:
-*/
-/*SHARED LINE(S) ORIGINATED HERE*/
-/*
-The following define is an attempt to centralize the definition of the
-common xobject data shared by structures that are derived from the
-generic xobject structure. For example, the structure font, defined in
-fonts.shr :
-&code.
-    struct font {
-           char type;
-           char flag;
-           int references;
-           ... other data types & structs ...
-           }
-&ecode.
-would now be defined as:
-&code.
-    struct font {
-           XOBJ_COMMON
-           ... other data types & structs ...
-           }
-&ecode.
-Thus we have a better-structured inheritance mechanism. 3-26-91 PNM
-*/
-/*SHARED LINE(S) ORIGINATED HERE*/
-/*
-:h3.Object Type Definitions
-These constants define the values which go in the 'type' field of
-an TYPE1IMAGER object structure:
-*/
-/*SHARED LINE(S) ORIGINATED HERE*/
-/*
-:h3.Flag Byte Definitions
-Many programmers define flag bits as a mask (for example, 0x04), and
-test, set, and reset them as follows:
-&code.
-        if ((flag & PERMANENT) != 0)
-        flag |= PERMANENT;
-        flag &= &inv.PERMANENT;
-:exmp.
-I favor a style where the 'if' statement can ask a question:
-&code.
-        if (ISPERMANENT(flag))
-        flag |= ISPERMANENT(ON);
-        flag &= &inv.ISPERMANENT(ON);
-:exmp.
-This said, we now define two bit settings of the flag byte of the
-object.  "ISPERMANENT" will be set by the user, when he calls
-Permanent().  "ISIMMORTAL" will be used for compiled-in objects
-that we don't want the user to ever destroy.
-*/
-/*SHARED LINE(S) ORIGINATED HERE*/
-/*
-Flag bit definitions that apply to all objects are assigned
-starting with the least significant (0x01) bit.  Flag bit definitions
-specific to a certain object type are assigned starting with the
-most significant (0x80) bit.  We hope they never meet.
-*/
-/*
-:h3 id=preserve.PRESERVE() Macro
-Occasionally an TYPE1IMAGER operator is implemented by calling other
-TYPE1IMAGER operators.  For example, Arc2() calls Conic().  When we
-call more than one operator as a subroutine, we have to be careful
-of temporary objects.  A temporary object will be consumed by the
-subroutine operator and then is no longer available for the caller.
-This can be prevented simply by bumping a temporary object's reference
-count.
-*/
-/*SHARED LINE(S) ORIGINATED HERE*/
-/*
-:h3.RefRoll() Macro to Detect References Count Rollover
-The following macro is designed to check for reference count rollover.
-A return value of TRUE means rollover has not occurred; a return value
-of FALSE means we cannot increment the reference count.  Note also that
-those functions that use this macro must decrement the reference count
-afterwards.  3-26-91 PNM
-*/
-#define RefRoll(obj)  (++(obj)->references > 0)
-/*
-:h2.TYPE1IMAGER Object Functions
-:h3.LONGCOPY() - Macro to Copy "long" Aligned Data
-Copying arbitrary bytes in C is a bit of a problem.  "strcpy" can't be
-used, because 0 bytes are special-cased.  Most environments have a
-routine "memcopy" or "bcopy" or "bytecopy" that copies memory containing
-zero bytes.  Sadly, there is no standard on the name of such a routine,
-which makes it impossible to write truely portable code to use it.
-It turns out that TYPE1IMAGER, when it wants to copy data, frequently
-knows that both the source and destination are aligned on "long"
-boundaries.  This allows us to copy by using "long *" pointers.  This
-is usually very efficient on almost all processors.  Frequently, it
-is more efficient than using general-purpose assembly language routines.
-So, we define a macro to do this in a portable way.  "dest" and "source"
-must be long-aligned, and "bytes" must be a multiple of "sizeof(long)":
-*/
-/*SHARED LINE(S) ORIGINATED HERE*/
-/*
-:h3.Allocate() - Allocating a Memory Block
-Allocate returns a pointer to memory object that is a copy of
-the template passed (if any).  In addition, extra bytes may be
-allocated contiguously with the object.  (This may be useful for
-variable size objects such as edge lists.  See :hdref refid=regions..)
-Allocate() always returns a non-immortal object, even if the template is
-immortal.  Therefore a non-NULL template must have a "flag" byte.
-If the template is NULL, then 'size' bytes are cleared to all NULLs.
-If the template is non-NULL, a new object is allocated in memory.
-It therefore seems logical that its reference count field should be
-set to 1. So, a nun-NULL template must also have a "references" field.
-PNM 3-26-91
-*/
-struct xobject *t1_Allocate(size, template, extra)  /* non-ANSI; type checking was too strict */
-       register int size;    /* number of bytes to allocate & initialize     */
-       register struct xobject *template;  /* example structure to allocate  */
-       register int extra;   /* any extra uninitialized bytes needed contiguously */
-{
-       extern char *xiMalloc();  /* standard C routine                         */
-       register struct xobject *r;
-       /*
-       * round up 'size' and 'extra' to be an integer number of 'long's:
-       */
-       size = (size + sizeof(long) - 1) & -(int)sizeof(long);
-       extra = (extra + sizeof(long) - 1) & -(int)sizeof(long);
-       if (size + extra <= 0)
-               abort("Non-positive allocate?");
-       r = (struct xobject *) xiMalloc(size + extra);
-       while (r == NULL) {
-               if (!GimeSpace()) {
-                       IfTrace1(TRUE, "malloc attempted %d bytes.\n",
-                                           size + extra);
-                       abort("We have REALLY run out of memory");
-               }
-               r = (struct xobject *) xiMalloc(size + extra);
-       }
-       /*
-       * copy the template into the new memory:
-       */
-       if (template != NULL) {
-       /* Added references count decrement if template is not permanent.
-          This is for the case where Allocate is called by a Dupxxxx
-          function, which was in turn called by Unique(). (PNM)        */
-               if (!ISPERMANENT(template->flag))
-                   --template->references;
-               LONGCOPY(r, template, size);
-               r->flag &= ~(ISPERMANENT(ON) | ISIMMORTAL(ON));
-       /* added reference field 3-2-6-91 PNM */
-               r->references = 1;
-       }
-       else {
-               register char **p1;
-               for (p1=(char **)r; size > 0; size -= sizeof(char *))
-                       *p1++ = NULL;
-       }
-       if (MemoryDebug > 1) {
-               register long *L;
-               L = (long *) r;
-               IfTrace4(TRUE, "Allocating at %x: %x %x %x\n",
-                                           L, L[-1], L[0], L[1]);
-       }
-       return(r);
-}
-/*
-:h3.Free() - Frees an Allocated Object
-This routine makes a sanity check to make sure the "type" field of the
-standard object structure has not been cleared.  If the object is
-not a standard structure, then the macro "NonObjectFree" is available
-that does not perform this check.
-In either case, the object must not be the NULL pointer.  This preserves
-portability, as the C system xiFree() will not always accept NULL.
-*/
-void Free(obj)              /* non-ANSI to avoid overly strict type checking */
-       register struct xobject *obj;  /* structure to free                   */
-{
-       if (obj->type == INVALIDTYPE)
-               abort("Free of already freed object?");
-       obj->type = INVALIDTYPE;
-       if (MemoryDebug > 1) {
-               register long *L;
-               L = (long *) obj;
-               IfTrace4(TRUE,"Freeing at %x: %x %x %x\n", L, L[-1], L[0], L[1]);
-       }
-       xiFree(obj);
-}
-/*
-:h3.Permanent() - Makes an Object Permanent
-Real simple--just set a flag.  Every routine that consumes its objects
-(which is almost every user entry) must check this flag, and not consume
-the object if it is set.
-If a temporary object is made permanent, and there is more than one
-reference to it, we must first Copy() it, then set the ISPERMANENT
-flag. Note also that the reference count must be incremented when an
-object is changed from temporary to permanent (see the ISUNIQUE macro).
-Note that the purpose of this function is to convert an object into a
-permanent object:
-  If it was permanent to begin with, we do nothing;
-  If it was temporary and unique, we set the PERMANENT flag and increment
-the reference count;
-  If it was temporary and nonunique, we must make a unique Copy(), set
-the PERMANENT flag, and set the reference count to 2. We must also
-decrement the original object's reference count, because what we have
-done is to change one of the old temporary handles to a permanent one.
-3-26-91 PNM
-*/
-struct xobject *t1_Permanent(obj) /* non-ANSI to avoid overly strict type checking */
-       register struct xobject *obj;  /* object to be made permanent         */
-{
-       IfTrace1((MustTraceCalls),"Permanent(%z)\n", obj);
-       if ( (obj != NULL) && ( !(ISPERMANENT(obj->flag)) ) )
-       {
-       /* there is a non-NULL, temporary object to be made permanent.
-          If there are multiple references to this object, first get
-          a new COPY().
-          Note also that we have to decrement the reference count if
-          we do a Copy() here, because we are consuming the temporary
-          argument passed, and returning a unique, permanent one.
-       */
-           if ( obj->references > 1)
-           {
-               obj = Copy(obj);
-           }
-           /* now set the permanent flag, and increment the reference
-              count, since a temporary object has now become permanent. */
-           obj->references++;
-           obj->flag |= ISPERMANENT(ON);
-       }
-       return(obj);
-}
-/*
-:h3.Temporary() - Undoes the Effect of "Permanent()"
-This simply resets the "ISPERMANENT" flag.
-If a permanent object is made temporary, and there is more than one reference
-to it, we must first Copy() it, then reset the ISPERMANENT flag. However,
-if the permanent object has obly one reference, we need only decrement the
-reference count ( and reset the flag).
-Note that this function, in the case of a PERMANENT argument, basically
-converts the PERMANENT handle to a TEMPORARY one. Thus, in the case of
-a nonunique, permanent argument passed, we not only make a Copy(),
-we also decrement the reference count, to reflect the fact that we have
-lost a permanent handle and gained a temporary one.
-PNM 3-2-6-91
-*/
-struct xobject *xiTemporary(obj) /* non-ANSI to avoid overly strict type checking */
-       register struct xobject *obj;  /* object to be made permanent         */
-{
-       IfTrace1((MustTraceCalls),"Temporary(%z)\n", obj);
-       if (obj != NULL) {
-               /* if it's already temporary, there's nothing to do. */
-               if ISPERMANENT(obj->flag)
-               {
-               /* if there are multiple references to this object, get a
-                  Copy we can safely alter. Recall that the reference count
-                  is incremented for permanent objects.
-                  Recall further that Copy returns an object with the
-                  same flag state and a reference count of 2 (for PERMANENT
-                  objects).
-                  Thus, regardless of whether or not we need to copy a
-                  permanent object, we still decrement its reference
-                  count and reset the flag.
-               */
-                   if (obj->references != 2 || ISIMMORTAL(obj->flag))
-                   {
-               /* not unique; consume handle, get a temporary Copy! */
-                       obj = Copy(obj);
-                   }
-               /* else decrement the reference count (since it's going from
-                  permanent to temporary) and clear the flag. */
-                   else {
-                       obj->references--;
-                       obj->flag &= ~ISPERMANENT(ON);
-                   }
-               }
-       }
-       return(obj);
-}
-/*
-:h3.Dup() - Duplicate an Object
-Dup will increment the reference count of an object, only making a
-Copy() if needed.
-Note that Dup() retains the state of the permanent flag.
-3-26-91 PNM
-*/
-struct xobject *t1_Dup(obj)   /* non-ANSI avoids overly strict type checking  */
-       register struct xobject *obj;  /* object to be duplicated             */
-{
-       register char oldflag;   /* copy of original object's flag byte */
-       IfTrace1((MustTraceCalls),"Dup(%z)\n", obj);
-       if (obj == NULL)
-               return(NULL);
-       /* An immortal object must be Copy'ed, so that we get a mortal
-          copy of it, since we try not to destroy immortal objects. */
-       if (ISIMMORTAL(obj->flag))
-           return(Copy(obj));
-       /* if incrementing the reference count doesn't cause the count
-          to wrap, simply return the object with the count bumped. Note
-          that the RefRoll macro increments the count to perform the
-          rollover check, so we must decrement the count. */
-       if (RefRoll(obj))
-           return(obj);
-       /* that didn't work out, so put the count back and call Copy(). */
-       --obj->references;
-       oldflag = obj->flag;
-       obj = Copy(obj);
-       if (ISPERMANENT(oldflag))
-               obj = Permanent(obj);
-       return(obj);
-}
-/*
-:h3.Copy() - Make a New Copy of an Object
-This is the generic Copy() where the object type is unknown.  There
-are specific Copyxxx functions for known object types.
-Copy will create a NEW temporary object, and WILL NOT simply bump the
-reference count.
-Sometimes duplicating an object is just as simple as Allocating with it
-as a template.  But other objects are complicated linked lists.  So, we
-let each module provide us a routine (or macro) that duplicates the
-objects it knows about.
-*/
-struct xobject *t1_Copy(obj)
-       register struct xobject *obj;  /* object to be  Copy'ed              */
-{
-       if (obj == NULL)
-               return(NULL);
-       if (ISPATHTYPE(obj->type))
-               obj = (struct xobject *) CopyPath(obj);
-       else
-               switch (obj->type) {
-                   case SPACETYPE:
-                       obj = (struct xobject *) CopySpace(obj); break;
-                   case FONTTYPE:
-                       obj = (struct xobject *) CopyFont(obj); break;
-                   case REGIONTYPE:
-                       obj = (struct xobject *) CopyRegion(obj); break;
-                   case PICTURETYPE:
-                       obj = (struct xobject *) CopyPicture(obj); break;
-                   case LINESTYLETYPE:
-                       obj = (struct xobject *) CopyLineStyle(obj); break;
-                   case STROKEPATHTYPE:
-                       obj = (struct xobject *) CopyStrokePath(obj); break;
-                   case CLUTTYPE:
-                       obj = (struct xobject *) CopyCLUT(obj); break;
-                   default:
-                       return(ArgErr("Copy: invalid object", obj, NULL));
-               }
-        return(obj);
-}
-/*
-:h3.Destroy() - Destroys an Object
-This can get complicated.  Just like with Copy(), we let the experts
-handle it.
-*/
-struct xobject *Destroy(obj) /* non-ANSI avoids overly strict type checking  */
-       register struct xobject *obj;  /* object to be destroyed              */
-{
-       IfTrace1((MustTraceCalls),"Destroy(%z)\n", obj);
-       if (obj == NULL)
-               return(NULL);
-       if (ISIMMORTAL(obj->flag)) {
-               IfTrace1(TRUE,"Destroy of immortal object %z ignored\n", obj);
-               return(NULL);
-       }
-       if (ISPATHTYPE(obj->type))
-               KillPath(obj);
-       else {
-               switch (obj->type) {
-                   case REGIONTYPE:
-                       KillRegion(obj);
-                       break;
-                   case SPACETYPE:
-                       KillSpace(obj);
-                       break;
-                   case LINESTYLETYPE:
-                       KillLineStyle(obj);
-                       break;
-                   case FONTTYPE:
-                       KillFont(obj);
-                       break;
-                   case PICTURETYPE:
-                       KillPicture(obj);
-                       break;
-                   case STROKEPATHTYPE:
-                       KillStrokePath(obj);
-                       break;
-                   case CLUTTYPE:
-                       KillCLUT(obj);
-                       break;
-                   default:
-                       return(ArgErr("Destroy: invalid object", obj, NULL));
-               }
-       }
-       return(NULL);
-}
-/*
-:h2.Generally Useful Macros
-:h3.FOLLOWING() - Macro to Point to the Data Following a Structure
-There are several places in TYPE1IMAGER where we will allocate variable
-data that belongs to a structure immediately after that structure.
-This is a performance technique, because it reduces the number of
-trips we have to take through xiMalloc() and xiFree().  It turns out C has
-a very convenient way to point past a structure--if 'p' is a pointer
-to a structure, 'p+1' is a pointer to the data after it.  This
-behavior of C is somewhat startling and somewhat hard to follow, if
-you are not used to it, so we define a macro to point to the data
-following a structure:
-*/
-/*SHARED LINE(S) ORIGINATED HERE*/
-/*
-:h3.TYPECHECK() - Verify the Type of an Argument
-This macro tests the type of an argument.  If the test fails, it consumes
-any other arguments as necessary and causes the imbedding routine to
-return the value 'whenBAD'.
-Note that the consumeables list should be an argument list itself, for
-example (0) or (2,A,B).  See :hdref refid=consume. below.
-*/
-/*SHARED LINE(S) ORIGINATED HERE*/
-/*
-:h3.ARGCHECK() - Perform an Arbitrary Check on an Argument
-This macro is a generalization of TYPECHECK to take an arbitrary
-predicate.  If the error occurs (i.e., the predicate is true), the
-arbitrary message 'msg' is returned.
-*/
-/*SHARED LINE(S) ORIGINATED HERE*/
-/*
-:h3.TYPENULLCHECK() - Extension of TYPECHECK() for NULL arguments
-Many routines allow NULLs to be passed as arguments.  'whenBAD' will
-be returned in this case, too.
-*/
-/*SHARED LINE(S) ORIGINATED HERE*/
-/*
-:h3.MAKECONSUME() - Create a "Consume"-type Macro
-Consuming an object means destroying it if it is not permanent.  This
-logic is so common to all the routines, that it is immortalized in this
-macro.  For example, ConsumePath(p) can be simply defined as
-MAKECONSUME(p,KillPath(p)).  In effect, this macro operates on a
-meta-level.
-:i1/consuming objects/
-*/
-/*SHARED LINE(S) ORIGINATED HERE*/
-/*
-:h3.MAKEUNIQUE() - Create a "Unique"-type Macro
-Many routines are written to modify their arguments in place.  Thus,
-they want to insure that they duplicate an object if it is permanent.
-This is called making an object "unique".  For example, UniquePath(p)
-can be simply defined as MAKEUNIQUE(p,DupPath(p)).
-:i1/unique objects/
-*/
-/*SHARED LINE(S) ORIGINATED HERE*/
-/*
-An object is unique (and directly alterable) if there is only one
-reference to it, and it is not permanent (in which case we increment
-the reference count, so we don't have to check the permanent bit).
-3-26-91 PNM
-Note the rules for making a unique object:
-&drawing.
-   IF  (obj->references = 1)    return(obj);
-   ELSE (references > 1)
-       IF (ISPERMANENT(obj->flag))    return(Dupxxx(obj));
-       ELSE (nonunique, temporary object!)
-           obj->references--; return(Dupxxx(obj));
-&edrawing.
-If we must make a Copy of a nonunique, temporary object, we decrement
-reference count of the original object!
-*/
-/*
-:h3.Unique() - Make a Unique Object
-Here is a generic 'Unique' function if the object type is not known.
-Why didn't we build it with the MAKEUNIQUE macro, you ask?  Well, we
-used to, but there is at least one damn compiler in the world that
-raises errors if the types of an "(a) ? b : c" expression do not match.
-Also, when we changed Dup() to retain the permanent/temporary flag, we
-wanted to make sure "Unique" always returned a temporary object.
-Note that we cannot use Dup() to create a copy of the object in question,
-because Dup() may simply bump the reference count, and not return a
-unique copy to us. That is why we use t1_Copy().
-The purpose of this function is to make sure we have a copy of an object
-that we can safely alter:
-:ol.
-:li.If we have a unique, temporary object, we simply return the argument.
-:li.If we have a nonunique, temporary object, we have to make a new copy
-of it, and decrement the reference count of the original object, to reflect
-the fact that we traded temporary handles.
-:li.If we have a permanent object, we make a temporary copy of it, but
-we do not decrement the reference count of the original permanent object,
-because permanent objects, by definition, are persistent. 3-2-6-91 PNM
-:eol.
-*/
-struct xobject *t1_Unique(obj)
-       struct xobject *obj;
-{
-    /* if the original object is not already unique, make a unique
-       copy...Note also that if the object was not permanent, we must
-       consume the old handle! 3-26-91 PNM
-       NOTE : consumption of the old handle moved to Allocate. 4-18-91 */
-    if (!obj || obj->references == 1)
-        return(obj);
-    obj = Copy(obj);
-    /* and make sure we return a temporary object ! */
-    if (ISPERMANENT(obj->flag))
-    {
-        obj->flag &= ~ISPERMANENT(ON);
-        obj->references--;
-    }
-    return(obj);
-}
-/*
-:h2.Initialization, Error, and Debug Routines
-:h3 id=debugvar.Declarations for Debug Purposes
-We declare all the debug flags here.  Some link editors make the not
-unreasonable restriction that only one module may declare and
-initialize global variables; all the rest must declare the variable
-'extern'.  This is logical, but is somewhat awkward to implement with
-C include files.  We solve the problem by temporarily making the name
-'extern' a null name if GLOBALS is defined.  (GLOBALS is only defined
-in this OBJECTS module.)  Since 'externs' can't be initialized, we
-have to handle that with #defines too.
-:i1/GLOBALS (&#define.)/
-*/
-/*SHARED LINE(S) ORIGINATED HERE*/
-static char *ErrorMessage = NULL;
-/*
-:h3.Pragmatics() - Set/Reset Debug Flags
-We provide a controlled way for the TYPE1IMAGER user to set and reset
-our debugging and tracing:
-*/
-void Pragmatics(username, value)
-       char *username;       /* name of the flag                             */
-       int value;            /* value to set it to                           */
-{
-       register char *p;     /* temporary loop variable                      */
-#define    NAMESIZE   40
-       char name[NAMESIZE];  /* buffer to store my copy of 'username'        */
-       if (strlen(username) >= (unsigned)NAMESIZE)
-               abort("Pragmatics name too large");
-       strcpy(name, username);
-       for (p = name; *p != '\0'; p++)
-               *p = toupper(*p);
-       if (!strcmp(name, "ALL"))
-               MustTraceCalls = InternalTrace = /* MustCrash = */
-                    LineIOTrace = value;
-       else if (!strcmp(name, "LINEIOTRACE"))
-               LineIOTrace = value;
-       else if (!strcmp(name, "TRACECALLS"))
-               MustTraceCalls = value;
-       else if (!strcmp(name, "CHECKARGS"))
-               MustCheckArgs = value;
-       else if (!strcmp(name, "PROCESSHINTS"))
-               ProcessHints = value;
-       else if (!strcmp(name, "SAVEFONTPATHS"))
-               SaveFontPaths = value;
-       else if (!strcmp(name, "CRASTERCOMPRESSIONTYPE"))
-               CRASTERCompressionType = value;
-       else if (!strcmp(name, "CRASHONUSERERROR"))
-               MustCrash = value;
-       else if (!strcmp(name, "DEBUG"))
-               StrokeDebug = SpaceDebug = PathDebug = ConicDebug = LineDebug =
-                          RegionDebug = MemoryDebug = FontDebug =
-                          HintDebug = ImageDebug = OffPageDebug = value;
-       else if (!strcmp(name, "CONICDEBUG"))
-               ConicDebug = value;
-       else if (!strcmp(name, "LINEDEBUG"))
-               LineDebug = value;
-       else if (!strcmp(name, "REGIONDEBUG"))
-               RegionDebug = value;
-       else if (!strcmp(name, "PATHDEBUG"))
-               PathDebug = value;
-       else if (!strcmp(name, "SPACEDEBUG"))
-               SpaceDebug = value;
-       else if (!strcmp(name, "STROKEDEBUG"))
-               StrokeDebug = value;
-       else if (!strcmp(name, "MEMORYDEBUG"))
-               MemoryDebug = value;
-       else if (!strcmp(name, "FONTDEBUG"))
-               FontDebug = value;
-       else if (!strcmp(name, "HINTDEBUG"))
-               HintDebug = value;
-       else if (!strcmp(name, "IMAGEDEBUG"))
-               ImageDebug = value;
-       else if (!strcmp(name, "OFFPAGEDEBUG"))
-               OffPageDebug = value;
-#ifdef  MC68000
-/*
-The following pragmatics flag turns on or off instruction histograming
-for performance analysis.  It is only defined in the Delta card
-environment.
-*/
-       else if (!strcmp(name, "PROFILE")) {
-               if (value)
-                       StartProfile();
-               else
-                       StopProfile();
-       }
-#endif
-       else if (!strcmp(name, "FLUSHCACHE")) {
-#ifdef notdef
-               while (GimeSpace()) { ; }
-#endif
-       }
-       else if (!strcmp(name, "CACHEDCHARS"))
-               CachedChars = (value <= 0) ? 1 : value;
-       else if (!strcmp(name, "CACHEDFONTS"))
-               CachedFonts = (value <= 0) ? 1 : value;
-       else if (!strcmp(name, "CACHEBLIMIT"))
-               CacheBLimit = value;
-       else if (!strcmp(name, "CONTINUITY"))
-               Continuity = value;
-       else {
-               printf("Pragmatics flag = '%s'\n", name);
-               ArgErr("Pragmatics:  flag not known", NULL, NULL);
-       }
-       return;
-}
-/*
-:h3.Consume() - Consume a List of Arguments
-This general purpose routine is provided in the case where the object
-type(s) to be consumed are unknown or not yet verified, and/or it is
-not known whether the object is permanent.
-If the type of the argument is known, it is faster to directly consume
-that type, for example, ConsumeRegion() or ConsumePath().  Furthermore,
-if it is already known that the object is temporary, it is faster to
-just kill it rather than consume it, for example, KillSpace().
-*/
-void Consume(n, obj1, obj2, obj3) /* non-ANSI avoids overly strict type checking */
-       int n;
-       struct xobject *obj1,*obj2,*obj3;
-{
-       switch(n) {
-           case 0:
-               return;
-           case 1:
-               if (obj1 != NULL && !ISPERMANENT(obj1->flag))
-                       Destroy(obj1);
-               return;
-           case 2:
-               if (obj1 != NULL && !ISPERMANENT(obj1->flag))
-                       Destroy(obj1);
-               if (obj2 != NULL && !ISPERMANENT(obj2->flag))
-                       Destroy(obj2);
-               return;
-           case 3:
-               if (obj1 != NULL && !ISPERMANENT(obj1->flag))
-                       Destroy(obj1);
-               if (obj2 != NULL && !ISPERMANENT(obj2->flag))
-                       Destroy(obj2);
-               if (obj3 != NULL && !ISPERMANENT(obj3->flag))
-                       Destroy(obj3);
-               return;
-           default:
-               abort("Consume:  too many objects");
-       }
-}
-/*
-:h3.TypeErr() - Handles "Invalid Object Type" Errors
-*/
-struct xobject *TypeErr(name, obj, expect, ret) /* non-ANSI avoids overly strict type checking */
-       char *name;           /* Name of routine (for error message)          */
-       struct xobject *obj;  /* Object in error                              */
-       int expect;           /* type expected                                */
-       struct xobject *ret;  /* object to return to caller                   */
-{
-       static char typemsg[80];
-       if (MustCrash)
-               LineIOTrace = TRUE;
-       sprintf(typemsg, "Wrong object type in %s; expected %s.\n",
-                  name, TypeFmt(expect), TypeFmt(obj->type));
-       IfTrace0(TRUE,typemsg);
-       ObjectPostMortem(obj);
-       if (MustCrash)
-               abort("Terminating because of CrashOnUserError...");
-       else
-               ErrorMessage = typemsg;
-/* changed ISPERMANENT to ret->references > 1 3-26-91 PNM */
-       if (ret != NULL && (ret->references > 1))
-               ret = Dup(ret);
-       return(ret);
-}
-/*
-:h4.TypeFmt() - Returns Pointer to English Name of Object Type
-This is a subroutine of TypeErr().
-*/
-static char *TypeFmt(type)
-       int type;             /* type field                                   */
-{
-       char *r;
-       if (ISPATHTYPE(type))
-               if (type == TEXTTYPE)
-                       r = "path or region (from TextPath)";
-               else
-                       r = "path";
-       else {
-               switch (type) {
-                   case INVALIDTYPE:
-                       r = "INVALID (previously consumed?)";
-                       break;
-                   case REGIONTYPE:
-                       r = "region";
-                       break;
-                   case SPACETYPE:
-                       r = "XYspace";
-                       break;
-                   case LINESTYLETYPE:
-                       r = "linestyle";
-                       break;
-                   case FONTTYPE:
-                       r = "font";
-                       break;
-                   case PICTURETYPE:
-                       r = "picture";
-                       break;
-                   case STROKEPATHTYPE:
-                       r = "path (from StrokePath)";
-                       break;
-                   default:
-                       r = "UNKNOWN";
-                       break;
-               }
-       }
-       return(r);
-}
-/*
-:h4.ObjectPostMortem() - Prints as Much as We Can About a Bad Object
-This is a subroutine of TypeErr() and ArgErr().
-*/
-/*ARGSUSED*/
-static ObjectPostMortem(obj) /* non-ANSI avoids overly strict type checking  */
-       register struct xobject *obj;
-{
-       extern struct XYspace *USER;
-       Pragmatics("Debug", 10);
-       IfTrace2(TRUE,"Bad object is of %s type %z\n", TypeFmt(obj->type), obj);
-       IfTrace0((obj == (struct xobject *) USER),
-                  "Suspect that InitImager() was omitted.\n");
-       Pragmatics("Debug", 0);
-}
-/*
-:h3.ArgErr() - Invalid Argument Passed to a Routine
-A common routine to report argument errors.  It is usually called
-is returned to the caller in case MustCrash is FALSE and ArgErr
-returns to its caller.
-*/
-struct xobject *ArgErr(string, obj, ret) /* non-ANSI avoids overly strict type checking */
-       char *string;         /* description of error                         */
-       struct xobject *obj;  /* object, if any, that was in error            */
-       struct xobject *ret;  /* object returned to caller or NULL            */
-{
-       if (MustCrash)
-               LineIOTrace = TRUE;
-       IfTrace1(TRUE,"ARGUMENT ERROR-- %s.\n", string);
-       if (obj != NULL)
-               ObjectPostMortem(obj);
-       if (MustCrash)
-               abort("Terminating because of CrashOnUserError...");
-       else
-               ErrorMessage = string;
-       return(ret);
-}
-/*
-:h3.abort() - Crash Due to Error
-Defined in objects.h to be FatalError(), the server's abort routine.
-*/
-/*
-:h3.REAL Miscellaneous Stuff
-:h4.ErrorMsg() - Return the User an Error Message
-*/
-char *ErrorMsg()
-{
-       register char *r;
-       r = ErrorMessage;
-       ErrorMessage = NULL;
-       return(r);
-}
-/*
-:h4.InitImager() - Initialize TYPE1IMAGER
-We check that a short is 16 bits and a long 32 bits; we have made
-those assumptions elsewhere in the code.  (This is almost a C standard,
-anyway.)  Note that TYPE1IMAGER makes no assumptions about the size of an
-'int'!
-:i1/portability assumptions/
-*/
-void InitImager()
-{
-/* Check to see if we have been using our own malloc.  If so,*/
-/* Undef malloc so that we can get to the system call. */
-/* All other calls to malloc are defined to xiMalloc.  */
-/*       if (sizeof(short) != 2 || sizeof(INT32) != 4)
-               abort("Fundamental TYPE1IMAGER assumptions invalid in this port");
-*/
-       InitSpaces();
-       InitFonts();
-       InitFiles();
-/*
-In some environments, constants and/or exception handling need to be
-*/
-       LibInit();
-}
-/*
-:h4.TermImager() - Terminate TYPE1IMAGER
-This only makes sense in a server environment; true TYPE1IMAGER needs do
-nothing.
-*/
-void TermImager()
-{
-       return;
-}
-/*
-:h4.reportusage() - A Stub to Get a Clean Link with Portable PMP
-*/
-void reportusage()
-{
-       return;
-}