static void parse_CharMetric_line(struct temp_font *tf, char *line) { int ch, ch2, wid; float a1, a2, a3, a4; char name[201], *pt; while ( isspace(*line)) ++line; if ( *line=='\0' ) return; wid = tf->ch_width; ch= -1; name[0]='\0'; for ( pt=line; pt && *pt ; ) { if ( isspace(*pt) || *pt==';' ) ++pt; else { if ( pt[0]=='C' && isspace(pt[1])) sscanf( pt, "C %d", &ch ); else if ( pt[0]=='C' && pt[1]=='H' && isspace(pt[2])) sscanf( pt, "CH <%x>", (unsigned *) &ch ); else if ( pt[0]=='W' && pt[1]=='X' && isspace(pt[2])) sscanf( pt, "WX %d", &wid ); else if ( pt[0]=='W' && pt[1]=='0' && pt[2]=='X' && isspace(pt[3])) sscanf( pt, "W0X %d", &wid ); else if ( pt[0]=='N' && isspace(pt[1])) sscanf( pt, "N %200s", name ); else if ( pt[0]=='B' && isspace(pt[1])) sscanf( pt, "B %g %g %g %g", &a1, &a2, &a3, &a4 ); pt = strchr(pt,';'); } } if ( (ch2 = name_char(tf,ch,name))== -1 ) { if ( tf->is_8859_1 ) fprintf( stderr, "Unknown character name <%s>\n", name ); return; } if ( ch2>=tf->max_ch ) tf->max_ch = ch2; if ( ch2<=tf->min_ch ) tf->min_ch = ch2; if ( (ch2&0xff)>=tf->max_ch2 ) tf->max_ch2 = (ch2&0xff); if ( (ch2&0xff)<=tf->min_ch2 ) tf->min_ch2 = (ch2&0xff); a2 = -a2; /* a descent of 1 == a bbox of -1 */ tf->per_char[ch2].width = wid; tf->per_char[ch2].lbearing = a1+.5; tf->per_char[ch2].rbearing = a3+.5; tf->per_char[ch2].ascent = a4+.5; tf->per_char[ch2].descent = a2+.5; tf->per_char[ch2].attributes |= AFM_EXISTS; if ( tf->max_b.lbearing<a1 ) tf->max_b.lbearing = a1; if ( tf->max_b.rbearing<a1 ) tf->max_b.rbearing = a3; if ( tf->max_b.ascent<a1 ) tf->max_b.ascent = a2; if ( tf->max_b.descent<a1 ) tf->max_b.descent = a4; if ( tf->max_b.width<wid ) tf->max_b.width = wid; if ( tf->min_b.lbearing>a1 ) tf->min_b.lbearing = a1; if ( tf->min_b.rbearing>a1 ) tf->min_b.rbearing = a3; if ( tf->min_b.ascent>a1 ) tf->min_b.ascent = a2; if ( tf->min_b.descent>a1 ) tf->min_b.descent = a4; if ( tf->min_b.width>wid ) tf->min_b.width = wid; }
static void advance(struct rnc_source *sp) { sp->cur=!sp->cur; for(;;) { NXT(sp).line=sp->line; NXT(sp).col=sp->col; if(newline(sp->v)||whitespace(sp->v)) {getv(sp); continue;} switch(sp->v) { case -1: NXT(sp).sym=SYM_EOF; return; case '#': getv(sp); if(sp->v=='#') { int i=0; for(;;) { do getv(sp); while(sp->v=='#'); if(whitespace(sp->v)) getv(sp); for(;;) { if(i+U_MAXLEN>NXT(sp).slen) realloc_s(&NXT(sp),2*(i+U_MAXLEN)); if(newline(sp->v)) { do getv(sp); while(whitespace(sp->v)); if(sp->v=='#') {getv(sp); if(sp->v=='#') {NXT(sp).s[i++]='\n'; break;} skip_comment(sp); } NXT(sp).s[i]=0; NXT(sp).sym=SYM_DOCUMENTATION; return; } else i+=u_put(NXT(sp).s+i,sp->v); getv(sp); } } } else {skip_comment(sp); continue;} case '=': getv(sp); NXT(sp).sym=SYM_ASGN; return; case ',': getv(sp); NXT(sp).sym=SYM_GROUP; return; case '|': getv(sp); if(sp->v=='=') { getv(sp); NXT(sp).sym=SYM_ASGN_CHOICE; return; } NXT(sp).sym=SYM_CHOICE; return; case '&': getv(sp); if(sp->v=='=') {getv(sp); NXT(sp).sym=SYM_ASGN_ILEAVE;} else NXT(sp).sym=SYM_ILEAVE; return; case '?': getv(sp); NXT(sp).sym=SYM_OPTIONAL; return; case '*': getv(sp); NXT(sp).sym=SYM_ZERO_OR_MORE; return; /* SYM_ANY_NAME */ case '+': getv(sp); NXT(sp).sym=SYM_ONE_OR_MORE; return; case '-': getv(sp); NXT(sp).sym=SYM_EXCEPT; return; case '~': getv(sp); NXT(sp).sym=SYM_CONCAT; return; case '(': getv(sp); NXT(sp).sym=SYM_LPAR; return; case ')': getv(sp); NXT(sp).sym=SYM_RPAR; return; case '{': getv(sp); NXT(sp).sym=SYM_LCUR; return; case '}': getv(sp); NXT(sp).sym=SYM_RCUR; return; case '[': getv(sp); NXT(sp).sym=SYM_LSQU; return; case ']': getv(sp); NXT(sp).sym=SYM_RSQU; return; case '>': getv(sp); if(sp->v!='>') error(0,sp,RNC_ER_LEXP,sp->fn,sp->line,sp->col,'>'); getv(sp); NXT(sp).sym=SYM_FOLLOW_ANNOTATION; return; case '"': case '\'': { int q=sp->v; int triple=0; int i=0; getv(sp); if(sp->v==q) {getv(sp); if(sp->v==q) { /* triply quoted string */ triple=1; getv(sp); } else { NXT(sp).s[0]='\0'; NXT(sp).sym=SYM_LITERAL; return; } } for(;;) { if(sp->v==q) { if(triple) { if(i>=2 && NXT(sp).s[i-2]==q && NXT(sp).s[i-1]==q) { NXT(sp).s[i-2]='\0'; break; } else i+=u_put(NXT(sp).s+i,sp->v); } else {NXT(sp).s[i]='\0'; break;} } else if(sp->v<=0) { if(sp->v==-1 || !triple) { error(0,sp,RNC_ER_LLIT,sp->fn,sp->line,sp->col); NXT(sp).s[i]='\0'; break; } else NXT(sp).s[i++]='\n'; } else i+=u_put(NXT(sp).s+i,sp->v); getv(sp); if(i+U_MAXLEN>NXT(sp).slen) realloc_s(&NXT(sp),2*(i+U_MAXLEN)); } getv(sp); NXT(sp).sym=SYM_LITERAL; return; } default: { int escaped=0,prefixed=0; if(sp->v=='\\') {escaped=1; getv(sp);} if(name_start(sp->v)) { int i=0; for(;;) { i+=u_put(NXT(sp).s+i,sp->v); if(i+U_MAXLEN>NXT(sp).slen) realloc_s(&NXT(sp),2*(i+U_MAXLEN)); getv(sp); if(!name_char(sp->v)) {NXT(sp).s[i]='\0'; break;} if(sp->v==':') prefixed=1; } if(!(escaped||prefixed)) { int kwd; if((kwd=s_tab(NXT(sp).s,kwdtab,NKWD))!=NKWD) { NXT(sp).sym=kwd; return; } } if(prefixed) { if(NXT(sp).s[i-1]==':'&&sp->v=='*') { getv(sp); NXT(sp).s[i-1]='\0'; NXT(sp).sym=SYM_NSNAME; } else NXT(sp).sym=SYM_QNAME; } else NXT(sp).sym=SYM_IDENT; return; } else { error(0,sp,RNC_ER_LILL,sp->fn,sp->line,sp->col,sp->v); getv(sp); continue; } } } } }