Back to index

tetex-bin  3.0
fontfcn.c
Go to the documentation of this file.
00001 /* $XConsortium: fontfcn.c,v 1.8 92/03/27 18:15:45 eswu Exp $ */
00002 /* Copyright International Business Machines,Corp. 1991
00003  * All Rights Reserved
00004  *
00005  * License to use, copy, modify, and distribute this software
00006  * and its documentation for any purpose and without fee is
00007  * hereby granted, provided that the above copyright notice
00008  * appear in all copies and that both that copyright notice and
00009  * this permission notice appear in supporting documentation,
00010  * and that the name of IBM not be used in advertising or
00011  * publicity pertaining to distribution of the software without
00012  * specific, written prior permission.
00013  *
00014  * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES
00015  * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT
00016  * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY,
00017  * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
00018  * THIRD PARTY RIGHTS.  THE ENTIRE RISK AS TO THE QUALITY AND
00019  * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
00020  * OR MAINTAIN, BELONGS TO THE LICENSEE.  SHOULD ANY PORTION OF
00021  * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES
00022  * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION.  IN
00023  * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
00024  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
00025  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
00026  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
00027  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00028  * SOFTWARE.
00029  */
00030 /* Author: Katherine A. Hitchcock    IBM Almaden Research Laboratory */
00031  
00032 #include <stdio.h>
00033 #include <string.h>
00034 #include "t1imager.h"
00035 #include "util.h"
00036 #include "fontfcn.h"
00037 #include "fontmisc.h"
00038 
00039 #ifdef HAVE_PROTOTYPES
00040 extern void objFormatName(psobj *, int, char *);
00041 #endif
00042  
00043 extern xobject Type1Char();
00044 extern boolean Init_BuiltInEncoding();
00045 
00046 /***================================================================***/
00047 /*   GLOBALS                                                          */
00048 /***================================================================***/
00049 char CurFontName[120];
00050 char *CurFontEnv;
00051 char *vm_base = NULL;
00052 psfont *FontP = NULL;
00053 psfont TheCurrentFont;
00054  
00055  
00056 /***================================================================***/
00057 /*   SearchDict - look for  name                                      */
00058 /*              - compare for match on len and string                 */
00059 /*                return 0 - not found.                               */
00060 /*                return n - nth element in dictionary.               */
00061 /***================================================================***/
00062 int SearchDictName(dictP,keyP)
00063  psdict *dictP;
00064  psobj  *keyP;
00065 {
00066   int i,n;
00067  
00068  
00069   n =  dictP[0].key.len;
00070   for (i=1;i<=n;i++) {          /* scan the intire dictionary */
00071     if (
00072         (dictP[i].key.len  == keyP->len )
00073         &&
00074         (strncmp(dictP[i].key.data.valueP,
00075                  keyP->data.valueP,
00076                  keyP->len) == 0
00077         )
00078        ) return(i);
00079   }
00080   return(0);
00081 }
00082 /***================================================================***/
00083 boolean initFont()
00084 {
00085 
00086   if (!(vm_init())) return(FALSE);
00087   vm_base = vm_next_byte();
00088   if (!(Init_BuiltInEncoding())) return(FALSE);
00089   strcpy(CurFontName, "");    /* iniitialize to none */
00090   FontP = &TheCurrentFont;
00091   FontP->vm_start = vm_next_byte();
00092   FontP->FontFileName.len = 0;
00093   FontP->FontFileName.data.valueP = CurFontName;
00094   return(TRUE);
00095 }
00096 /***================================================================***/
00097 void resetFont(env)
00098 char *env;
00099 {
00100  
00101   vm_next =  FontP->vm_start;
00102   vm_free = vm_size - ( vm_next - vm_base);
00103   FontP->Subrs.len = 0;
00104   FontP->Subrs.data.stringP = NULL;
00105   FontP->CharStringsP = NULL;
00106   FontP->Private = NULL;
00107   FontP->fontInfoP = NULL;
00108   FontP->BluesP = NULL;
00109   /* This will load the font into the FontP */
00110   strcpy(CurFontName,env);
00111   FontP->FontFileName.len = strlen(CurFontName);
00112   FontP->FontFileName.data.valueP = CurFontName;
00113  
00114 }
00115 /***================================================================***/
00116 /* Read font used to attempt to load the font and, upon failure, 
00117    try a second time with twice as much memory.  Unfortunately, if
00118    it's a really complex font, simply using 2*vm_size may be insufficient.
00119    I've modified it so that the program will try progressively larger
00120    amounts of memory until it really runs out or the font loads
00121    successfully. (ndw)
00122 */
00123 int readFont(env)
00124 char *env;
00125 {
00126   int rcode;
00127  
00128   /* restore the virtual memory and eliminate old font */
00129   resetFont(env);
00130   /* This will load the font into the FontP */
00131   rcode = scan_font(FontP);
00132   return(rcode);
00133 }
00134 /***================================================================***/
00135 xobject fontfcnB(S,code,lenP,mode)
00136 XYspace S;
00137 unsigned char *code;
00138 int  *lenP;
00139 int  *mode;
00140 {
00141 #if 0
00142   path updateWidth();
00143 #endif 
00144   psobj *charnameP; /* points to psobj that is name of character*/
00145   int   N;
00146   psdict *CharStringsDictP; /* dictionary with char strings     */
00147   psobj   CodeName;   /* used to store the translation of the name*/
00148   psobj  *SubrsArrayP;
00149   psobj  *theStringP;
00150  
00151   path  charpath;   /* the path for this character              */
00152  
00153   charnameP = &CodeName;
00154   charnameP->len = *lenP;
00155   charnameP->data.stringP = code;
00156 
00157   CharStringsDictP =  FontP->CharStringsP;
00158  
00159   /* search the chars string for this charname as key */
00160   N = SearchDictName(CharStringsDictP,charnameP);
00161   if (N<=0) {
00162     *mode = FF_PARSE_ERROR;
00163     return(NULL);
00164   }
00165   /* ok, the nth item is the psobj that is the string for this char */
00166   theStringP = &(CharStringsDictP[N].value);
00167  
00168   /* get the dictionary pointers to the Subrs  */
00169  
00170   SubrsArrayP = &(FontP->Subrs);
00171   /* scale the Adobe fonts to 1 unit high */
00172   S = Permanent(Scale(S, 1.0 , 1.0));
00173   /* call the type 1 routine to rasterize the character     */
00174   charpath = Type1Char(FontP,S,theStringP,SubrsArrayP,NULL,
00175                FontP->BluesP , mode);
00176   Destroy(S);
00177   /* if Type1Char reported an error, then return */
00178   if ( *mode == FF_PARSE_ERROR)  return(NULL);
00179   /* fill with winding rule unless path was requested */
00180   if (*mode != FF_PATH) {
00181     charpath =  Interior(charpath,WINDINGRULE+CONTINUITY);
00182   }
00183   return(charpath);
00184 }
00185 /***================================================================***/
00186 /*   fontfcnA(env, mode)                                              */
00187 /*                                                                    */
00188 /*          env is a pointer to a string that contains the fontname.  */
00189 /*                                                                    */
00190 /*     1) initialize the font     - global indicates it has been done */
00191 /*     2) load the font                                               */
00192 /***================================================================***/
00193 Bool fontfcnA(env,mode)
00194 char *env;
00195 int  *mode;
00196 {
00197   int rc;
00198  
00199   /* Has the FontP initialized?  If not, then   */
00200   /* Initialize  */
00201   if (FontP == NULL) {
00202     InitImager();
00203     if (!(initFont())) {
00204       /* we are really out of memory */
00205       *mode = SCAN_OUT_OF_MEMORY;
00206       return(FALSE);
00207     }
00208   }
00209  
00210   /* if the env is null, then use font already loaded */
00211  
00212   /* if the not same font name */
00213   if ( (env) && (strcmp(env,CurFontName) != 0 ) ) {
00214     /* restore the virtual memory and eliminate old font, read new one */
00215     rc = readFont(env);
00216     if (rc != 0 ) {
00217       strcpy(CurFontName, "");    /* no font loaded */
00218       *mode = rc;
00219       return(FALSE);
00220     }
00221   }
00222   return(TRUE);
00223  
00224 }
00225 /***================================================================***/
00226 /*   QueryFontLib(env, infoName,infoValue,rcodeP)                     */
00227 /*                                                                    */
00228 /*          env is a pointer to a string that contains the fontname.  */
00229 /*                                                                    */
00230 /*     1) initialize the font     - global indicates it has been done */
00231 /*     2) load the font                                               */
00232 /*     3) use the font to call getInfo for that value.                */
00233 /***================================================================***/
00234 
00235 void QueryFontLib(env,infoName,infoValue,rcodeP)
00236 char *env;
00237 char *infoName;
00238 pointer infoValue;    /* parameter returned here    */
00239 int  *rcodeP;
00240 {
00241   int rc,N,i;
00242   psdict *dictP;
00243   psobj  nameObj;
00244   psobj  *valueP;
00245  
00246   /* Has the FontP initialized?  If not, then   */
00247   /* Initialize  */
00248   if (FontP == NULL) {
00249     InitImager();
00250     if (!(initFont())) {
00251       *rcodeP = 1;
00252       return;
00253     }
00254   }
00255   /* if the env is null, then use font already loaded */
00256   /* if the not same font name, reset and load next font */
00257   if ( (env) && (strcmp(env,CurFontName) != 0 ) ) {
00258     /* restore the virtual memory and eliminate old font */
00259     rc = readFont(env);
00260     if (rc != 0 ) {
00261       strcpy(CurFontName, "");    /* no font loaded */
00262       *rcodeP = 1;
00263       return;
00264     }
00265   }
00266   dictP = FontP->fontInfoP;
00267   objFormatName(&nameObj,strlen(infoName),infoName);
00268   N = SearchDictName(dictP,&nameObj);
00269   /* if found */
00270   if ( N > 0 ) {
00271     *rcodeP = 0;
00272     switch (dictP[N].value.type) {
00273        case OBJ_ARRAY:
00274          valueP = dictP[N].value.data.arrayP;
00275          if (strcmp(infoName,"FontMatrix") == 0) {
00276            /* 6 elments, return them as floats      */
00277            for (i=0;i<6;i++) {
00278              if (valueP->type == OBJ_INTEGER )
00279                ((float *)infoValue)[i] = valueP->data.integer;
00280              else
00281                ((float *)infoValue)[i] = valueP->data.real;
00282             valueP++;
00283            }
00284          }
00285          if (strcmp(infoName,"FontBBox") == 0) {
00286            /* 4 elments for Bounding Box.  all integers   */
00287            for (i=0;i<4;i++) {
00288              ((int *)infoValue)[i] = valueP->data.integer;
00289              valueP++;
00290            }
00291          break;
00292        case OBJ_INTEGER:
00293        case OBJ_BOOLEAN:
00294          *((int *)infoValue) = dictP[N].value.data.integer;
00295          break;
00296        case OBJ_REAL:
00297          *((float *)infoValue) = dictP[N].value.data.real;
00298          break;
00299        case OBJ_NAME:
00300        case OBJ_STRING:
00301          *((char **)infoValue) =  dictP[N].value.data.valueP;
00302          break;
00303        default:
00304          *rcodeP = 1;
00305          break;
00306      }
00307    }
00308   }
00309   else *rcodeP = 1;
00310 }