📄 fontfcn.c
字号:
/* $XConsortium: fontfcn.c,v 1.8 92/03/27 18:15:45 eswu Exp $ *//* Copyright International Business Machines,Corp. 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 not be used in advertising or * publicity pertaining to distribution of the software without * specific, written prior permission. * * IBM PROVIDES 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) ASSUMES * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN * NO EVENT SHALL IBM 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. *//* Author: Katherine A. Hitchcock IBM Almaden Research Laboratory */ #include <stdio.h>#include <string.h>#include <stdlib.h>#include "t1imager.h" #include "util.h"#include "fontfcn.h"#include "fontmisc.h"#include "paths_rmz.h" #include "../t1lib/parseAFM.h" #include "../t1lib/t1types.h"#include "../t1lib/t1extern.h"#include "../t1lib/t1misc.h"#include "../t1lib/t1base.h"#include "../t1lib/t1finfo.h"extern xobject Type1Char(psfont *env, struct XYspace *S, psobj *charstrP, psobj *subrsP, psobj *osubrsP, struct blues_struct *bluesP, int *modeP, char *name);extern xobject Type1Line(psfont *env, struct XYspace *S, float line_position, float line_thickness, float line_length);extern boolean Init_BuiltInEncoding( void);void objFormatName(psobj *objP, int length, char *valueP); extern void T1io_reset( void);#define BEZIERTYPE 0x10+0x02#define LINETYPE 0x10+0x00#define MOVETYPE 0x10+0x05/***================================================================***//* GLOBALS *//***================================================================***/static char CurCharName[257]="";static char BaseCharName[257]="";char CurFontName[120];char *CurFontEnv;char *vm_base = NULL;static char notdef[]=".notdef";/* the following is inserted by RMz for VM checking and reallocating: */char *vm_used = NULL;extern int vm_init_count;extern int vm_init_amount;static psfont *FontP = NULL;psfont TheCurrentFont; /***================================================================***//* SearchDict - look for name *//* - compare for match on len and string *//* return 0 - not found. *//* return n - nth element in dictionary. *//***================================================================***/int SearchDictName(dictP,keyP) psdict *dictP; psobj *keyP;{ int i,n; n = dictP[0].key.len; for (i=1;i<=n;i++) { /* scan the intire dictionary */ if ( (dictP[i].key.len == keyP->len ) && (strncmp(dictP[i].key.data.valueP, keyP->data.valueP, keyP->len) == 0 ) ) return(i); } return(0);}/***================================================================***//* assignment of &TheCurrentFont removed by RMz: */boolean initFont(){ if (!(vm_init())) return(FALSE); vm_base = vm_next_byte(); if (!(Init_BuiltInEncoding())) return(FALSE); strcpy(CurFontName, ""); /* iniitialize to none */ FontP->vm_start = vm_next_byte(); FontP->FontFileName.len = 0; FontP->FontFileName.data.valueP = CurFontName; return(TRUE);}/***================================================================***/int resetFont(env)char *env;{ vm_next = FontP->vm_start; vm_free = vm_size - ( vm_next - vm_base); FontP->Subrs.len = 0; FontP->Subrs.data.stringP = NULL; FontP->CharStringsP = NULL; FontP->Private = NULL; FontP->fontInfoP = NULL; FontP->BluesP = NULL; /* This will load the font into the FontP */ strcpy(CurFontName,env); FontP->FontFileName.len = strlen(CurFontName); FontP->FontFileName.data.nameP = CurFontName; T1io_reset(); return(0); }/***================================================================***//* Read font used to attempt to load the font and, upon failure, try a second time with twice as much memory. Unfortunately, if it's a really complex font, simply using 2*vm_size may be insufficient. I've modified it so that the program will try progressively larger amounts of memory until it really runs out or the font loads successfully. (ndw)*/int readFont(env)char *env;{ int rcode; /* int memscale = 2; */ /* initially, try twice just like we used to ... */ /* restore the virtual memory and eliminate old font */ resetFont(env); /* This will load the font into the FontP */ rcode = scan_font(FontP); return(rcode);}static int isCompositeChar( int FontID, char *charname) { int i; FontInfo *pAFMData; if (pFontBase->pFontArray[FontID].pAFMData==NULL) { /* No AFM data present */ return( -1); } pAFMData=pFontBase->pFontArray[FontID].pAFMData; for ( i=0; i<pAFMData->numOfComps; i++) { if (strcmp( pAFMData->ccd[i].ccName, charname)==0) return( i); } return( -1); }/* dump a description of path elements to stdout */static T1_PATHPOINT getDisplacement( struct segment *path){ register struct segment *ipath; register struct beziersegment *ibpath; T1_PATHPOINT point={0,0}; /* Step through the path list */ ipath=(struct segment *)path; do { if (ipath->type==LINETYPE) { point.x+=ipath->dest.x; point.y+=ipath->dest.y; } else if (ipath->type==MOVETYPE) { point.x+=ipath->dest.x; point.y+=ipath->dest.y; } else if (ipath->type==BEZIERTYPE) { ibpath=(struct beziersegment *)ipath; point.x+=ibpath->dest.x; point.y+=ibpath->dest.y; } ipath=ipath->link; } while (ipath!=NULL); return( point); }/***================================================================***//* RMz: instead of code, which is a character pointer to the name of the character, we use "ev" which is a pointer to a desired encoding vector (or NULL if font-internal encoding should be used) and "index" as an index into the desired encoding vector! The user thus has the opportunity of supplying whatever encoding he wants. Font_Ptr is the pointer to the local psfont-structure. */xobject fontfcnB(int FontID, int modflag, struct XYspace *S, char **ev, unsigned char index, int *mode, psfont *Font_Ptr, int do_raster){ psobj *charnameP; /* points to psobj that is name of character*/ FontInfo *pAFMData=NULL; int i=-1; int j=0; int numPieces=1; int N; T1_PATHPOINT currdisp; int basechar; psdict *CharStringsDictP; /* dictionary with char strings */ psobj CodeName; /* used to store the translation of the name*/ psobj *SubrsArrayP; psobj *theStringP; int localmode=0; struct segment *charpath=NULL; /* the path for this character */ struct segment *tmppath1=NULL; struct segment *tmppath2=NULL; struct segment *tmppath3=NULL; struct segment *tmppath4=NULL; /* set the global font pointer to the address of already allocated structure and setup pointers*/ FontP=Font_Ptr; CharStringsDictP = FontP->CharStringsP; SubrsArrayP = &(FontP->Subrs); charnameP = &CodeName; if (ev==NULL){ /* font-internal encoding should be used */ charnameP->len = FontP->fontInfoP[ENCODING].value.data.arrayP[index].len; charnameP->data.stringP = (unsigned char *) FontP->fontInfoP[ENCODING].value.data.arrayP[index].data.arrayP; } else{ /* some user-supplied encoding is to be used */ charnameP->len = strlen(ev[index]); charnameP->data.stringP = (unsigned char *) ev[index]; } strncpy( (char *)CurCharName, (char *)charnameP->data.stringP, charnameP->len); CurCharName[charnameP->len]='\0'; /* search the chars string for this charname as key */ basechar = SearchDictName(CharStringsDictP,charnameP); if (basechar<=0) { /* Check first, whether a char in question is a composite char */ if ((i=isCompositeChar( FontID, CurCharName))>-1) { /* i is now the index of the composite char definitions (starting at 0). At this point it is clear that AFM-info must be present -> fetch first component of composite char. */ pAFMData=pFontBase->pFontArray[FontID].pAFMData; charnameP->len=strlen( pAFMData->ccd[i].pieces[0].pccName); charnameP->data.stringP=(unsigned char*)pAFMData->ccd[i].pieces[0].pccName; numPieces=pAFMData->ccd[i].numOfPieces; if ((basechar=SearchDictName(CharStringsDictP,charnameP))<=0) { /* this is bad, AFM-file and font file do not match. This will most probably lead to errors or inconsistencies later. However, we substitute .notdef and inform the user via logfile and T1_errno. */ sprintf( err_warn_msg_buf, "Charstring \"%s\" needed to construct composite char \"%s\" not defined (FontID=%d)", pAFMData->ccd[i].pieces[0].pccName, pAFMData->ccd[i].ccName, FontID); T1_PrintLog( "fontfcnB():", err_warn_msg_buf, T1LOG_WARNING); T1_errno=T1ERR_COMPOSITE_CHAR; } } } if (basechar<=0) { /* This means the requested char is unknown or the base char of a composite is not found -> we substitute .notdef */ charnameP = &CodeName; charnameP->len = 7; charnameP->data.stringP = (unsigned char *) notdef; basechar = SearchDictName(CharStringsDictP,charnameP); localmode=FF_NOTDEF_SUBST; /* Font must be completely damaged if it doesn't define a .notdef */ if (basechar<=0) { *mode=FF_PARSE_ERROR; return(NULL); } } /* if (basechar<=0) */ /* basechar is now the index of the base character in the CharStrings dictionary */ /* we provide the Type1Char() procedure with the name of the character to rasterize for debugging purposes */ strncpy( (char *)CurCharName, (char *)charnameP->data.stringP, charnameP->len); CurCharName[charnameP->len]='\0'; /* get CharString and character path */ theStringP = &(CharStringsDictP[basechar].value); tmppath2 = (struct segment *) Type1Char(FontP,S,theStringP,SubrsArrayP,NULL, FontP->BluesP,mode,CurCharName); /* if Type1Char reported an error, then return */ if ( *mode == FF_PARSE_ERROR || *mode==FF_PATH_ERROR) return(NULL); /* Defer rastering to later, we first have to handle the composite symbols */ for (j=1; j<numPieces; j++) { /* get composite symbol name */ charnameP->len=strlen( pAFMData->ccd[i].pieces[j].pccName); charnameP->data.stringP=(unsigned char*)pAFMData->ccd[i].pieces[j].pccName; /* get CharString definition */ if ((N=SearchDictName(CharStringsDictP,charnameP))<=0) { /* handling of errors, see comments above ... */ sprintf( err_warn_msg_buf, "Charstring \"%s\" needed to construct composite char \"%s\" not defined (FontID=%d)", pAFMData->ccd[i].pieces[j].pccName, pAFMData->ccd[i].ccName, FontID); T1_PrintLog( "fontfcnB():", err_warn_msg_buf, T1LOG_WARNING); charnameP = &CodeName; charnameP->len = 7; charnameP->data.stringP = (unsigned char *) notdef; N = SearchDictName(CharStringsDictP,charnameP); localmode=FF_NOTDEF_SUBST; /* damaged Font */ if (N<=0) { *mode=FF_PARSE_ERROR; if (charpath!=NULL) { KillPath( charpath); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -