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

📄 ps_afm.c

📁 PSlib是一个用来生成PostScript文件的类库。提供了一个生成PostScript文件的简单方法。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* rmkernmatch() {{{ * * Some routines to remove kerns that match certain patterns. */static KERN *rmkernmatch(PSDoc *psdoc, KERN *k, char *s){	KERN *nk, *ktmp ;	while (k != NULL && strcmp(k->succ, s)==0) {		psdoc->free(psdoc, k->succ);		ktmp = k->next;		psdoc->free(psdoc, k);		k = ktmp;	}	if (k) {		for (nk = k; nk; nk = nk->next)			while (nk->next && strcmp(nk->next->succ, s)==0) {				psdoc->free(psdoc, nk->next->succ);				ktmp = nk->next->next;				psdoc->free(psdoc, nk->next);				nk->next = ktmp;			}	}	return k ;}/* }}} *//* rmkern() {{{ * * Recursive to one level. */static void rmkern(PSDoc *psdoc, ght_hash_table_t *gadobechars, char *s1, char *s2, ADOBEINFO *ai){	ght_iterator_t iterator;	char *p;	if (ai == 0) {		if (strcmp(s1, "*") == 0) {			for(ai = ght_first(gadobechars, &iterator, (void **) &p); ai; ai = ght_next(gadobechars, &iterator, (void **) &p))				rmkern(psdoc, gadobechars, s1, s2, ai) ;			return ;		} else {			ai = gfindadobe(gadobechars, s1) ;			if (ai == 0)				return ;		}	}	if (strcmp(s2, "*")==0) {		KERN *k, *ktmp;		k = ai->kerns;		while(k != NULL) {			if(k->succ)				psdoc->free(psdoc, k->succ);			ktmp = k->next;			psdoc->free(psdoc, k);			k = ktmp;		}		ai->kerns = NULL ; /* drop them on the floor */	} else		ai->kerns = rmkernmatch(psdoc, ai->kerns, s2) ;}/* }}} *//* copykern() {{{ * Make the kerning for character S1 equivalent to that for S2. * If either S1 or S2 do not exist, do nothing. * If S1 already has kerning, do nothing. */static void copykern(PSDoc *psdoc, ght_hash_table_t *gadobechars, char *s1, char *s2){	ADOBEINFO *ai1 = gfindadobe(gadobechars, s1);	ADOBEINFO *ai2 = gfindadobe(gadobechars, s2);	if (ai1 && ai2 && !ai1->kerns) {		/* Put the new one at the head of the list, since order is immaterial.  */		ADOBEPTR *ap = (ADOBEPTR *) psdoc->malloc(psdoc, (unsigned long) sizeof(ADOBEPTR), "copykern: adobeptr");		ap->next = ai2->kern_equivs;		ap->ch = ai1;		ai2->kern_equivs = ap;	}}/* }}} */static int sawligkern ;/* checkligkern() {{{ * * Reads a ligkern line, if this is one.  Assumes the first character * passed is `%'. */static void checkligkern(PSDoc *psdoc, ADOBEFONTMETRIC *metrics, char *s){	char *oparam = param ;	char *mlist[5] ;	int n ;	ght_hash_table_t *gadobechars = metrics->gadobechars;	s++ ;	while (*s && *s <= ' ')		s++ ;	if (strncmp(s, "LIGKERN", 7)==0) {		sawligkern = 1 ;		s += 7 ;		while (*s && *s <= ' ')			s++ ;		param = s ;		while (*param) {			for (n=0; n<5;) {				if (*param == 0)					break ;				mlist[n] = paramstring() ;				if (strcmp(mlist[n], ";") == 0)					break ;				n++ ;			}			if (n > 4) {				ps_error(psdoc, PS_RuntimeError, _("Too many parameters in lig kern data."));				return;			}			if (n < 3) {				ps_error(psdoc, PS_RuntimeError, _("Too few parameters in lig kern data."));				return;			}			if (n == 3 && strcmp(mlist[1], "{}") == 0) { /* rmkern command */				rmkern(psdoc, gadobechars, mlist[0], mlist[2], (ADOBEINFO *)0) ;			} else if (n == 3 && strcmp(mlist[1], "<>") == 0) { /* copykern */				/* FIXME: What is the meaning of kern_equivs?				 * copykern() does not set the kern by kern_equivs which is not				 * used.				 */				copykern(psdoc, gadobechars, mlist[0], mlist[2]) ;			} else if (n == 3 && strcmp(mlist[0], "||") == 0 &&				strcmp(mlist[1], "=") == 0) { /* bc command */				ADOBEINFO *ai = gfindadobe(gadobechars, "||") ;				if (boundarychar != -1) {					ps_error(psdoc, PS_RuntimeError, _("Multiple boundary character commands?"));					return;				}				if (sscanf(mlist[2], "%d", &n) != 1) {					ps_error(psdoc, PS_RuntimeError, _("Expected number assignment for boundary char."));					return;				}				if (n < 0 || n > 255) {					ps_error(psdoc, PS_RuntimeError, _("Boundary character number must be 0..255."));					return;				}				boundarychar = n ;				if (ai == 0) {					ps_error(psdoc, PS_RuntimeError, _("Internal error: boundary char."));					return;				}				ai->texnum = n ; /* prime the pump, so to speak, for lig/kerns */			} else if (n == 4) {				int op = -1 ;				ADOBEINFO *ai ;				for (n=0; encligops[n]; n++)					if (strcmp(mlist[2], encligops[n])==0) {						op = n ;						break ;					}				if (op < 0) {					ps_error(psdoc, PS_RuntimeError, _("Bad ligature operation specified."));					return;				}				if (0 != (ai = gfindadobe(gadobechars, mlist[0]))) {					LIG *lig ;					/* This does not make sense */					if (gfindadobe(gadobechars, mlist[2]))	  /* remove coincident kerns */						rmkern(psdoc, gadobechars, mlist[0], mlist[1], ai) ;					if (strcmp(mlist[3], "||") == 0) {						ps_error(psdoc, PS_RuntimeError, _("You can't lig to the boundary character!"));						return;					}					/* FIXME: The following code is commented because the staticligkern					 * instruction didn't work anymore. For some reason e.g. the endash					 * wasn't found, though it was part of the font. I appears that					 * at this point the list of glyphs on gadobechars isn't complete					 */					/*					if (gfindadobe(gadobechars, mlist[3]))	{						ps_error(psdoc, PS_RuntimeError, _("Ligature '%s' not available in font."), mlist[3]);						return;					}					*/					if (!metrics->fixedpitch) { /* fixed pitch fonts get *0* ligs */						for (lig=ai->ligs; lig; lig = lig->next)							if (strcmp(lig->succ, mlist[1]) == 0)								break ; /* we'll re-use this structure *///						printf("Adding new lig %s %s -> %s\n", mlist[0], mlist[1], mlist[3]);						if (lig == 0) {							lig = newlig(psdoc) ;							lig->succ = newstring(psdoc, mlist[1]) ;							lig->next = ai->ligs ;							ai->ligs = lig ;						}						if(lig->sub)							psdoc->free(psdoc, lig->sub);						lig->sub = newstring(psdoc, mlist[3]) ;						lig->op = op ;						if (strcmp(mlist[1], "||")==0) {							lig->boundleft = 1 ;							if (strcmp(mlist[0], "||")==0) {								ps_error(psdoc, PS_RuntimeError, _("You can't lig boundary character to boundary character."));								return;							}						} else							lig->boundleft = 0 ;					}				}			} else {				ps_error(psdoc, PS_RuntimeError, _("Bad form in LIGKERN command."));				return;			}		}	}	param = oparam ;}/* }}} *//* char *gettoken() {{{ * * Here we get a token from the encoding file. We parse just as much PostScript * as we expect to find in an encoding file.	We allow commented lines and * names like 0, .notdef, _foo_.	We do not allow //abc. * This function calls checkligkern() which reads extra ligatures which * are usually at the beginning of the file marked as PostScript comments. */static char smbuffer[100] ;		/* for tokens */static char *gettoken(PSDoc *psdoc, ADOBEFONTMETRIC *metrics) {	char *p, *q ;	while (1) {		while (param == NULL || *param == '\0') {			if (getline(metrics->afmin) == 0)				ps_error(psdoc, PS_RuntimeError, _("Premature end of encoding file."));			for (p=buffer; *p != '\0'; p++)				if (*p == '%') {					if (ignoreligkern == 0)						checkligkern(psdoc, metrics, p) ;					*p = '\0' ;					break ;				}		}		while (*param != '\0' && *param <= ' ')			param++ ;		if (*param) {			if (*param == '[' || *param == ']' ||				 *param == '{' || *param == '}') {				smbuffer[0] = *param++ ;				smbuffer[1] = '\0' ;				return smbuffer ;			} else if (*param == '/' || *param == '-' || *param == '_' ||						  *param == '.' ||						  ('0' <= *param && *param <= '9') ||						  ('a' <= *param && *param <= 'z') ||						  ('A' <= *param && *param <= 'Z')) {				smbuffer[0] = *param ;				for (p=param+1, q=smbuffer+1;								*p == '-' || *p == '_' || *p == '.' ||								('0' <= *p && *p <= '9') ||								('a' <= *p && *p <= 'z') ||								('A' <= *p && *p <= 'Z'); p++, q++)					*q = *p ;				*q = '\0' ;				param = p ;				return smbuffer ;			}		}	}}/* }}} *//* getligkerndefaults() {{{ *  * Set default ligatures */static void getligkerndefaults(PSDoc *psdoc, ADOBEFONTMETRIC *metrics) {	int i ;	for (i=0; staticligkern[i]; i++) {		strncpy(buffer, staticligkern[i], BUFFERLEN) ;		strncpy(obuffer, staticligkern[i], BUFFERLEN) ;		param = buffer ;		checkligkern(psdoc, metrics, buffer) ;	}}/* }}} *//* readencoding() {{{ * * This routine reads in an encoding file, given the name.  It modifies * the passed font metrics structure. It returns -1 in case of error and * 0 otherwise. It performs a number of consistency checks. * If enc is NULL it will use the default encoding from ps_fontenc.c */int readencoding(PSDoc *psdoc, ADOBEFONTMETRIC *metrics, const char *enc) {	char *p ;	int i ;	ENCODING *e;	sawligkern = 0 ;	if (metrics->afmin) {		ps_error(psdoc, PS_RuntimeError, _("Encoding file for this font seems to be already open."));		return -1;	}	if(enc) {		metrics->afmin = ps_open_file_in_path(psdoc, enc) ;		param = 0 ;		if (metrics->afmin == NULL) {			ps_error(psdoc, PS_RuntimeError, _("Could not open encoding file '%s'."), enc);			return -1;		}		p = gettoken(psdoc, metrics) ;		if (*p != '/' || p[1] == '\0') {			ps_error(psdoc, PS_RuntimeError, _("Encoding file must start with name of encoding."));			return -1;		}		e = (ENCODING *) psdoc->malloc(psdoc, sizeof(ENCODING), _("Allocate memory for new encoding vector.")) ;		if(NULL == e) {			ps_error(psdoc, PS_MemoryError, _("Could not allocate memory for encoding vector."));			return -1;		}		e->name = newstring(psdoc, p+1) ;		p = gettoken(psdoc, metrics) ;		if (0 != strcmp(p, "[")) {			ps_error(psdoc, PS_RuntimeError, _("Name of encoding must be followed by an '['."));			psdoc->free(psdoc, e->name);			psdoc->free(psdoc, e);			return -1;		}		for (i=0; i<256; i++) {			p = gettoken(psdoc, metrics) ;			if (*p != '/' || p[1] == '\0') {				ps_error(psdoc, PS_RuntimeError, _("Encoding vector must contain 256 glyph names."));				for (i--; i>=0; i--) {					psdoc->free(psdoc, e->vec[i]);				}				psdoc->free(psdoc, e->name);				psdoc->free(psdoc, e);				return -1;			}			e->vec[i] = newstring(psdoc, p+1) ;		}		p = gettoken(psdoc, metrics) ;		if (0 != strcmp(p, "]")) {			ps_error(psdoc, PS_RuntimeError, _("Encoding vector must be ended by an ']'."));			for (i=0; i<256; i++) {				psdoc->free(psdoc, e->vec[i]);			}			psdoc->free(psdoc, e->name);			psdoc->free(psdoc, e);			return -1;		}		while (getline(metrics->afmin)) {			for (p=buffer; *p != '\0'; p++)				if (*p == '%') {					if (ignoreligkern == 0)						checkligkern(psdoc, metrics, p) ;					*p = '\0' ;					break ;				}		}		fclose(metrics->afmin) ;		metrics->afmin = NULL ;		if (ignoreligkern == 0 && sawligkern == 0) {			getligkerndefaults(psdoc, metrics) ;		}		metrics->fontenc = ps_build_enc_hash(psdoc, e);		if(metrics->codingscheme)			psdoc->free(psdoc, metrics->codingscheme);		metrics->codingscheme = newstring(psdoc, e->name);		/* FIXME: For now we through away the fontenc from the file and		 * take the predefined font encoding.		 */		for (i=0; i<256; i++) {			psdoc->free(psdoc, e->vec[i]);		}		psdoc->free(psdoc, e->name);		psdoc->free(psdoc, e);	} else { /* not font encoding file name passed */		e = &fontencoding[0] ;		getligkerndefaults(psdoc, metrics) ;		metrics->fontenc = ps_build_enc_hash(psdoc, e);		if(metrics->codingscheme)			psdoc->free(psdoc, metrics->codingscheme);		metrics->codingscheme = newstring(psdoc, e->name);	}	param = 0 ;	return 0 ;}/* }}} *//*   readadobe() ;	if (fontspace == 0) {		ADOBEINFO *ai ;	}	handlereencoding() ;*/

⌨️ 快捷键说明

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