void std_interpret_ansi(struct virtscreen *cur, unsigned char ch) { switch (ch) { case '(': cur->next_char_send = special_ansi_charset_0; return; case ')': cur->next_char_send = special_ansi_charset_1; return; case '[': cur->cur_ansi_number = 0; cur->ansi_elements = 0; cur->ansi_reading_number = 0; cur->next_char_send = special_reading_ansi; return; case '7': cur->old_attrib = cur->attrib; cur->old_xpos = cur->xpos; cur->old_ypos = cur->ypos; break; case '8': change_attribute(cur,cur->old_attrib); position_console(cur,cur->ypos,cur->xpos,0); break; case 'E': cur->xpos = 0; case 'D': cur->ypos++; if (cur->ypos >= cur->bottom_scroll) { scroll_virtscreen(cur); cur->ypos--; } move_cursor(cur); break; case 'M': cur->ypos--; if (cur->ypos < cur->top_scroll) { cur->ypos++; scroll_virt_up_at_cursor(cur,0); } move_cursor(cur); break; /* recalculate screen pos */ } if (ch != 27) cur->next_char_send = std_interpret_char; }
void special_reading_ansi(struct virtscreen *cur, unsigned char ch) { if ((ch>='0') && (ch<='9')) { cur->cur_ansi_number = (cur->cur_ansi_number * 10) + (ch - '0'); cur->ansi_reading_number = 1; return; } if ((cur->ansi_reading_number) || (ch == ';')) { if (cur->ansi_elements<MAX_ANSI_ELEMENTS) cur->ansi_element[cur->ansi_elements++] = cur->cur_ansi_number; cur->ansi_reading_number = 0; } cur->cur_ansi_number = 0; switch (ch) { case '?': case ';': return; case 'D': position_console(cur,0,(cur->ansi_elements) ? -cur->ansi_element[0] : -1,1); break; case 'a': case 'C': position_console(cur,0,(cur->ansi_elements) ? cur->ansi_element[0] : 1,1); break; case 'A': position_console(cur,(cur->ansi_elements) ? -cur->ansi_element[0] : -1,0,1); break; case 'e': case 'B': position_console(cur,(cur->ansi_elements) ? cur->ansi_element[0] : 1,0,1); break; case '`': case 'G': { int temp = cur->ansi_elements ? cur->ansi_element[0] : 1; if (temp) temp--; position_console(cur,cur->ypos,temp,0); } break; case 'E': position_console(cur,cur->ypos + ((cur->ansi_elements) ? cur->ansi_element[0] : 1), 0,0); break; case 'F': position_console(cur,cur->ypos - ((cur->ansi_elements) ? cur->ansi_element[0] : 1), 0,0); break; case 'd': { int temp = cur->ansi_elements ? cur->ansi_element[0] : 1; if (temp) temp--; position_console(cur,temp,cur->xpos,0); } break; case 'f': case 'H': { int row = (cur->ansi_elements > 0) ? cur->ansi_element[0] : 1; int col = (cur->ansi_elements > 1) ? cur->ansi_element[1] : 1; if (row) row--; if (col) col--; position_console(cur,row,col,0); } break; case 'J': clear_virtscreen(cur,(cur->ansi_elements) ? cur->ansi_element[0]: 0); break; case 'L': { int lines = (cur->ansi_elements) ? cur->ansi_element[0] : 1; while (lines>0) { scroll_virt_up_at_cursor(cur,0); lines--; } } break; case 'M': { int lines = (cur->ansi_elements) ? cur->ansi_element[0] : 1; while (lines>0) { scroll_virt_up_at_cursor(cur,1); lines--; } } break; case 'P': delete_chars_in_line(cur,(cur->ansi_elements) ? cur->ansi_element[0] : 1); break; case 'K': clear_to_eol(cur,cur->ansi_elements ? cur->ansi_element[0] : 0); break; case 's': cur->old_xpos = cur->xpos; cur->old_ypos = cur->ypos; break; case 'u': position_console(cur,cur->old_ypos,cur->old_xpos,0); break; case 'r': { int low = (cur->ansi_elements > 0) ? cur->ansi_element[0] : 1; int high = (cur->ansi_elements > 1) ? cur->ansi_element[1] : cur->rows; if (low<=high) set_scroll_region(cur,low,high); } break; case 'm': { int count = 0; int cthing; if (!cur->ansi_elements) change_attribute(cur,0x07); while (count < cur->ansi_elements) { cthing = cur->ansi_element[count]; switch (cthing) { case 0: case 27: change_attribute(cur,0x07); break; case 1: change_attribute(cur,cur->attrib | 0x08); break; case 5: change_attribute(cur,cur->attrib | 0x80); break; case 7: change_attribute(cur,0x70); break; case 21: case 22: change_attribute(cur,cur->attrib & 0xF7); break; case 25: change_attribute(cur,cur->attrib & 0x7F); break; default: if ((cthing>=30) && (cthing<=37)) { change_attribute(cur,(cur->attrib & 0xF8) | (cthing-30)); } if ((cthing>=40) && (cthing<=47)) { change_attribute(cur,(cur->attrib & 0x8F) | ((cthing-40) << 4)); } break; } count++; } } break; } cur->next_char_send = std_interpret_char; }
int load_font_config(PathInfo pmap, char *confname) { FILE *f; FONTREC **flist=&fontlist; ATTRIBREC **alist=&attriblist; ENCODINGREC **elist=&encodinglist; RANGEREC **rlist=&rangelist; FONTREC *frec; char buffer[512]; char *bpos; int linecount=0; f=open_file(pmap, confname, "r"); if (!f) { fprintf(stderr, "Unable to load font configuration\n"); return 0; } while (*flist) flist=&(*flist)->next; while (*alist) { if ((*alist)->value==-1) lastattrib++; alist=&(*alist)->next; } while (*elist) elist=&(*elist)->next; while (*rlist) rlist=&(*rlist)->next; frec=NULL; while (fgets(buffer, 511, f)) { linecount++; bpos=buffer; skip_spaces(bpos); if (!*bpos || *bpos=='#') continue; if (!strncmp(bpos,"ATTRIBUTE", 9)) { /* define a new attribute: ** ATTRIBUTE name value0 value1 value2 value3 ** value? is a string used as a reference ** defval is the default value ** name is the name used to define the attribute ** (so, a line of the form 'name value1' defines the attribute ** name to be equal to value1 for the current font) ** ** The font attribute detection algorithm uses these values ** to find default attributes for fonts from their name. */ char *c,*h; char tc; int i=-1; c=bpos+9; tc=*c; h=get_string(&c,&tc); while (h) { *alist=malloc(sizeof(ATTRIBREC)); (*alist)->name= add_alias(h, ((i<0)?ATTRIBGROUPALIAS:ATTRIBVALUEALIAS(lastattrib)), *alist); (*alist)->value=i; (*alist)->num=lastattrib; h=get_string(&c,&tc); i++; (*alist)->next=NULL; alist=&(*alist)->next; } /* at least one (perhaps two?) value should be specified */ if (i>=0) { if (!i) { /* no values given */ /* h still points to name of the attribute */ fprintf(stderr, "%s:%i: No values given for attribute %s\n" "%s:%i: Assuming attribute is not used\n", confname, linecount, h,confname,linecount); i=1; } attribinfo[lastattrib].max=i; if (lastattrib) i=i*attribinfo[lastattrib-1].multby; attribinfo[lastattrib].multby=i; attribinfo[lastattrib].divby=i/attribinfo[lastattrib].max; attribinfo[lastattrib].def=0; lastattrib++; } else if (i<0) { fprintf(stderr, "%s:%i: No attribute name given\n", confname, linecount); } } else if (!strncmp(bpos, "ATTRALIAS", 9)) { /* Redefine the attributes for a certain group */ /* For example: ** ATTRIBUTE Weight Medium Bold ** ... ** ATTRALIAS Weight Gewicht Normaal Vet */ char *c,*h; char tc; int aliastype; void *aliasdata; ATTRIBREC *ar; c=bpos+9; tc=*c; h=get_string(&c,&tc); aliasdata=find_alias(h,ATTRIBGROUPALIAS); if (!find_alias) { fprintf(stderr, "%s:%i: Unknow attribute name %s\n", confname, linecount, h); continue; } ar=aliasdata; aliastype=ar->num; h=get_string(&c,&tc); while (ar && (ar->num==aliastype) && h) { ar->name=add_alias(h,(ar->value>=0? ATTRIBVALUEALIAS(aliastype): ATTRIBGROUPALIAS), ar); ar=ar->next; h=get_string(&c,&tc); } if (h) { fprintf(stderr, "%s:%i: Too many attributes given\n.", confname, linecount); } if (ar && (ar->num==aliastype)) { fprintf(stderr, "%s:%i: Not enough values given\n", confname, linecount); } } else if (!strncmp(bpos, "ALIAS",5)) { /* Define an alias for some identifier. */ char *c,*h; char tc; int aliastype; void *aliasdata; c=bpos+5; tc=*c; h=get_string(&c,&tc); aliasdata=find_aliasname(h,&aliastype); if (!aliasdata) { fprintf(stderr, "%s:%i: identifier %s unknown\n", confname, linecount, h); continue; } h=get_string(&c,&tc); while (h) { /* check if h is already defined for that type */ if (!find_alias(h,aliastype)) { add_alias(h,aliastype, aliasdata); } h=get_string(&c,&tc); } } else if (!strncmp(bpos, "RANGE", 5)) { /* define a range. ** syntax: RANGE name n k-l s-t ** n,k,l,s and t are integers in one of the following formats: ** decimal 65, octal 0101, hexadecimal 0x41, character 'A', ** Unicode U+0041. Sorry, no internationalisation for numbers. */ char *c, *h; char tc; RANGEREC *rr; int len, actnum; c=bpos+5; tc=*c; h=get_string(&c,&tc); if (!h) { fprintf(stderr, "%s:%i: No name spacified\n", confname, linecount); continue; } (*rlist)=rr=malloc(sizeof(RANGEREC)); rr->name=add_alias(h,RANGEALIAS, rr); rr->next=NULL; rlist=&rr->next; *c=tc; /* upper limit to the length of the needed array is the length ** of the string, since each number takes at least two positions ** Add 2 for a termination pair. */ skip_spaces(c); len=strlen(c); actnum=0; rr->ranges=malloc(sizeof(int)*(len+2)); while (*c && actnum+1<len) { h=c; c=get_integer(c, rr->ranges+actnum); actnum++; if (*c=='-') { c++; c=get_integer(c,rr->ranges+actnum); } else { rr->ranges[actnum]=rr->ranges[actnum-1]; } actnum++; if (!isspace(*c)) { find_spaces(c); tc=*c; *c=0; fprintf(stderr, "%s:%i: strange range item %s\n", confname, linecount, h); *c=tc; } skip_spaces(c); } rr->ranges[actnum++]= -1; } else if (!strncmp(bpos, "ENCODING", 8)) { /* define an encoding for a font. */ char *c,*h; char tc; c=bpos+8; tc=*c; h=get_string(&c,&tc); while (h) { *elist=malloc(sizeof(ENCODINGREC)); (*elist)->encmap=0; (*elist)->mapfilename=add_alias(h, ENCODINGALIAS, *elist); (*elist)->next=0; elist=&(*elist)->next; h=get_string(&c,&tc); } } else if (!strncmp(bpos, "FONTENC",7)) { char *c, *h; char tc; ENCODINGREC *er; if (!frec) { fprintf(stderr, "%s:%i: Not defining a font yet\n", confname,linecount); continue; } c=bpos+7; tc=*c; h=get_string(&c,&tc); if (!h) { fprintf(stderr, "%s:%i: No encoding specified\n", confname, linecount); continue; } er=find_alias(h, ENCODINGALIAS); if (!er) { fprintf(stderr, "%s:%i: Unknown encoding %s\n", confname, linecount, h); } else { frec->encoding=er; } } else if (!strncmp(bpos, "FONTRANGE",9)) { char *c, *h; char tc; RANGEREC *rr; if (!frec) { fprintf(stderr, "%s:%i: Not defining a font yet\n", confname,linecount); continue; } c=bpos+9; tc=*c; h=get_string(&c,&tc); if (!h) { fprintf(stderr, "%s:%i: No range specified\n", confname, linecount); continue; } rr=find_alias(h, RANGEALIAS); if (!rr) { fprintf(stderr, "%s:%i: Unknown range %s\n", confname, linecount, h); } else { frec->range=rr; } } else if (!strncmp(bpos, "FONT",4)) { /* Start defining a new font with auto-detection of attributes ** and encoding. */ char *c,*h; char tc; c=bpos+4; tc=*c; h=get_string(&c,&tc); frec = (*flist) = malloc(sizeof(FONTREC)); frec->fontname=malloc(sizeof(char)*(c-h+1)); /* c-h==strlen(h) */ strcpy(frec->fontname, h); frec->attribpos=0; frec->encoding=NULL; frec->range=NULL; frec->fonttype=frec->bt=frec->bm=frec->bmax=0; frec->font=0; frec->fstruct=NULL; frec->next=NULL; flist=&frec->next; /* detect attributes: !!! X11 specific code ** * divide the font name in parts between '-' signs ** * for each part, check if it is an alias ** If the encoding is not set at the end, combine the ** last two parts and check if that is an alias. ** Keep track which attributes are already set to make ** sure no redefinitions are made. */ { int attrset[MAXATTRIB]; char *t; void *aliasdata; int aliastype; int tosetleft; int i; /* add an '-' at the end to process the last item */ c[0]='-';c[1]='\0'; c=h; for (i=0; i<lastattrib; i++) attrset[i]=0; tosetleft=lastattrib+2; /* range and encoding */ t=strchr(h,'-'); while (t && tosetleft) { /* skip field of the form "*" and "" */ if (*c!='*' && *c!='-') { *t='\0'; aliasdata=find_aliasname(c,&aliastype); while (aliasdata) { switch (aliastype) { case RANGEALIAS: if (!frec->range) { frec->range=aliasdata; tosetleft--; } break; case ENCODINGALIAS: if (!frec->encoding) { frec->encoding=aliasdata; tosetleft--; } break; case ATTRIBGROUPALIAS: break; default: /* ATTRIBVALUEALIAS(n) */ for (i=0; i<lastattrib; i++) { if (!attrset[i] && aliastype==ATTRIBVALUEALIAS(i)) { ATTRIBREC *ar=aliasdata; attrset[i]=1; tosetleft--; frec->attribpos = change_attribute(frec->attribpos, ar->num, ar->value); continue; } } break; } aliasdata=find_nextname(&aliastype); } *t='-'; } t++; c=t; t=strchr(t,'-'); } } if (!frec->encoding) { /* try to find encoding in last two items ** c is at a last position, after the added '-' ** Remove it and search backward. */ c--; *c='\0'; while (c>h && *c!='-') c--; c--; while (c>h && *c!='-') c--; if (c!=h) { c++; frec->encoding=find_alias(c,ENCODINGALIAS); } } } else { /* The line starts the name of an attribute followed by ** its value. Find the attribute and the value and change ** the attribute of the current font. */ char *c,*h; char tc; ATTRIBREC *ar; ATTRIBREC *aval; int agr; c=bpos; tc=*c; /* get attribute name and look it up */ h=get_string(&c,&tc); ar=find_alias(h,ATTRIBGROUPALIAS); if (!ar) { fprintf(stderr,"%s:%i: unknow attribute group %s\n", confname, linecount, h); continue; } agr=ar->num; /* get attribute value and look it up */ h=get_string(&c,&tc); if (!h) { fprintf(stderr,"%s:%i: no attribute value specified.\n", confname, linecount); aval=NULL; } else { aval=find_alias(h,ATTRIBVALUEALIAS(agr)); } if (!aval) { char *vname; fprintf(stderr,"%s:%i: invalid attribute %s\n", confname, linecount, h); fprintf(stderr,"%s:%i: use one of:", confname, linecount); vname=find_type(ATTRIBVALUEALIAS(agr)); while (vname) { fprintf(stderr, " %s", vname); vname=find_type_next(); } fprintf(stderr, "\n"); continue; } else if (frec) { /* change font attribute of current font */ frec->attribpos=change_attribute(frec->attribpos, aval->num, aval->value); } else { fprintf(stderr, "%s:%i: Not defining a font yet\n", confname, linecount); } } } close_file(f); return 0; }
/* change one attribute in the given font */ int font_change_attribute(int attribcombo, int attrnr, int value) { if (attrnr<0 || value<0 || attrnr>=maxattrib || value >=attribinfo[attrnr].max) return attribcombo; return change_attribute(attribcombo, attrnr, value); }
/* set attribute ATTRNR to VALUE */ void font_set_attribute(int attrnr, int value) { if (attrnr<0 || value<0 || attrnr>=maxattrib || value >= attribinfo[attrnr].max) return; current_attr=change_attribute(current_attr,attrnr,value); }
int font_load_config(char *confname) { FILE *f; FONTREC **flist=&fontlist; ATTRIBREC **alist=&attriblist; ENCODINGREC **elist=&encodinglist; RANGEREC **rlist=&rangelist; REMAPREC **rmlist=&remaplist; FONTREC *frec; char buffer[512]; char *bpos; int linecount=0; if (!pmap) { pmap=make_pathinfo("MAPPATH",DEFAULTMAPPATH,".map,.ufont"); } f=open_file(pmap, confname, "r"); if (!f) { fprintf(stderr, "Unable to find font configuration '%s'\n", confname); return 0; } /* find the end of these lists */ while (*flist) flist=&(*flist)->next; while (*alist) { if ((*alist)->value==-1) maxattrib++; alist=&(*alist)->next; } while (*elist) elist=&(*elist)->next; while (*rlist) rlist=&(*rlist)->next; while (*rmlist) rmlist=&(*rmlist)->next; frec=NULL; /* read in the file, line by line */ /* a buffer of 511 character should suffice */ while (fgets(buffer, 511, f)) { linecount++; bpos=buffer; skip_spaces(bpos); /* skip empty line or comments (starting with #) */ if (!*bpos || *bpos=='#') continue; if (!strncmp(bpos,"ATTRIBUTE", 9)) { /* define a new attribute: ** ATTRIBUTE name value0 value1 value2 value3 ** value? is a string used as a reference ** name is the name used to define the attribute ** (so, a line of the form 'name value1' defines the attribute ** name to be equal to value1 for the current font) ** ** The font attribute detection algorithm uses these values ** to find default attributes for fonts from their name. */ char *c,*h; char tc; int i= -1; c=bpos+9; tc=*c; h=get_string(&c,&tc); while (h) { *alist=malloc(sizeof(ATTRIBREC)); (*alist)->name= add_alias(h, ((i<0)?ATTRIBGROUPALIAS:ATTRIBVALUEALIAS(maxattrib)), *alist); (*alist)->value=i; (*alist)->num=maxattrib; h=get_string(&c,&tc); i++; (*alist)->next=NULL; alist=&(*alist)->next; } /* at least one (perhaps two?) value should be specified */ if (i>=0) { if (!i) { /* no values given */ /* h still points to name of the attribute */ fprintf(stderr, "%s:%i: No values given for attribute %s\n" "%s:%i: Assuming attribute is not used\n", confname, linecount, h,confname,linecount); i=1; } attribinfo[maxattrib].max=i; if (maxattrib) i=i*attribinfo[maxattrib-1].multby; attribinfo[maxattrib].multby=i; attribinfo[maxattrib].divby=i/attribinfo[maxattrib].max; attribinfo[maxattrib].def=0; maxattrib++; } else if (i<0) { fprintf(stderr, "%s:%i: No attribute name given\n", confname, linecount); } } else if (!strncmp(bpos, "ATTRALIAS", 9)) { /* Redefine the attributes for a certain group. These ** attributes might be used in menus and you can adjust ** the menus by changing the attribute names. Useful ** for localization, for example: ** ATTRIBUTE Weight Medium Bold ** ... ** ATTRALIAS Weight Gewicht Normaal Vet */ char *c,*h; char tc; int aliastype; void *aliasdata; ATTRIBREC *ar; c=bpos+9; tc=*c; h=get_string(&c,&tc); aliasdata=find_alias(h,ATTRIBGROUPALIAS); if (!aliasdata) { fprintf(stderr, "%s:%i: Unknow attribute name %s\n", confname, linecount, h); continue; } ar=aliasdata; aliastype=ar->num; h=get_string(&c,&tc); while (ar && (ar->num==aliastype) && h) { ar->name=add_alias(h,(ar->value>=0? ATTRIBVALUEALIAS(aliastype): ATTRIBGROUPALIAS), ar); ar=ar->next; h=get_string(&c,&tc); } if (h) { fprintf(stderr, "%s:%i: Too many attributes given\n.", confname, linecount); } if (ar && (ar->num==aliastype)) { fprintf(stderr, "%s:%i: Not enough values given\n", confname, linecount); } } else if (!strncmp(bpos, "ATTRREMAP", 9)) { /* Add an entry for remapping an attribute within a group */ char *c, *h; char tc; int aliastype; void *aliasdata; ATTRIBREC *ar; ATTRIBREC *oav, *nav; c = bpos+9; tc = *c; h=get_string(&c,&tc); aliasdata=find_alias(h, ATTRIBGROUPALIAS); if (!aliasdata) { fprintf(stderr, "%s:%i: Unknown attribute name %s\n", confname, linecount, h); continue; } ar = aliasdata; aliastype = ar->num; h=get_string(&c, &tc); oav=NULL; nav=NULL; if (h) { oav = find_alias(h, ATTRIBVALUEALIAS(aliastype)); } if (oav) { h=get_string(&c, &tc); if (h) { nav = find_alias(h, ATTRIBVALUEALIAS(aliastype)); if (!nav) { fprintf(stderr, "%s:%i: Unknown attribute value %s for group %s\n", confname, linecount, h, ar->name); } } } else { fprintf(stderr, "%s:%i: Unknown attribute value %s for group %s\n", confname, linecount, h, ar->name); } if (ar && oav && nav) { *rmlist = malloc(sizeof(REMAPREC)); (*rmlist)->attrgroup = aliastype; (*rmlist)->oldval = oav->value; (*rmlist)->newval = nav->value; (*rmlist)->next =0; rmlist = &((*rmlist)->next); } } else if (!strncmp(bpos, "ALIAS",5)) { /* Define an alias for some identifier. */ char *c,*h; char tc; int aliastype; void *aliasdata; c=bpos+5; tc=*c; h=get_string(&c,&tc); aliasdata=find_aliasname(h,&aliastype); if (!aliasdata) { fprintf(stderr, "%s:%i: identifier %s unknown\n", confname, linecount, h); continue; } h=get_string(&c,&tc); while (h) { /* check if h is already defined for that type */ if (!find_alias(h,aliastype)) { add_alias(h,aliastype, aliasdata); } h=get_string(&c,&tc); } } else if (!strncmp(bpos, "RANGE", 5)) { /* define a range. ** syntax: RANGE name n k-l s-t ** n,k,l,s and t are integers in one of the following formats: ** decimal 65, octal 0101, hexadecimal 0x41, character 'A', ** Unicode U+0041. Sorry, no i18n for numbers yet. ** The integers indicate the positions in the encoding of ** the font, not in the Unicode encoding. */ char *c, *h; char tc; RANGEREC *rr; int len, actnum; c=bpos+5; tc=*c; h=get_string(&c,&tc); if (!h) { fprintf(stderr, "%s:%i: No name specified\n", confname, linecount); continue; } (*rlist)=rr=malloc(sizeof(RANGEREC)); rr->name=add_alias(h,RANGEALIAS, rr); rr->next=NULL; rlist=&rr->next; *c=tc; /* upper limit to the length of the needed array is the length ** of the string, since each number takes at least two positions ** Add 2 for a termination pair. */ skip_spaces(c); len=strlen(c); actnum=0; rr->ranges=malloc(sizeof(int)*(len+2)); while (*c && actnum+1<len) { h=c; c=get_integer(c, rr->ranges+actnum); actnum++; if (*c=='-') { c++; c=get_integer(c,rr->ranges+actnum); } else { rr->ranges[actnum]=rr->ranges[actnum-1]; } actnum++; if (!isspace(*c)) { find_spaces(c); tc=*c; *c=0; fprintf(stderr, "%s:%i: strange range item %s\n", confname, linecount, h); *c=tc; } skip_spaces(c); } rr->ranges[actnum++]= -1; } else if (!strncmp(bpos, "ENCODING", 8)) { /* Define an encoding for a font. ** Multiple encoding can occur on the same line. ** The encoding is only loaded when it is actually used. */ char *c,*h; char tc; c=bpos+8; tc=*c; h=get_string(&c,&tc); while (h) { *elist=malloc(sizeof(ENCODINGREC)); (*elist)->encmap=0; (*elist)->mapfilename=add_alias(h, ENCODINGALIAS, *elist); (*elist)->next=0; elist=&(*elist)->next; h=get_string(&c,&tc); } } else if (!strncmp(bpos, "FONTENC",7)) { /* Define the encoding of the current font. ** The name of the encoding has to be defined in an ** "ENCODING" line, or as an alias for an encoding. */ char *c, *h; char tc; ENCODINGREC *er; if (!frec) { fprintf(stderr, "%s:%i: Not defining a font yet\n", confname,linecount); continue; } c=bpos+7; tc=*c; h=get_string(&c,&tc); if (!h) { fprintf(stderr, "%s:%i: No encoding specified\n", confname, linecount); continue; } er=find_alias(h, ENCODINGALIAS); if (!er) { fprintf(stderr, "%s:%i: Unknown encoding %s\n", confname, linecount, h); } else { frec->encoding=er; } } else if (!strncmp(bpos, "FONTRANGE",9)) { /* Define the range of a font. Certain fonts might be too ** large or contain too many bad characters. The range ** is used to select certain characters from a font. ** It will be used when the virtual font is defined and ** when the font is loaded. */ char *c, *h; char tc; RANGEREC *rr; if (!frec) { fprintf(stderr, "%s:%i: Not defining a font yet\n", confname,linecount); continue; } c=bpos+9; tc=*c; h=get_string(&c,&tc); if (!h) { fprintf(stderr, "%s:%i: No range specified\n", confname, linecount); continue; } rr=find_alias(h, RANGEALIAS); if (!rr) { fprintf(stderr, "%s:%i: Unknown range %s\n", confname, linecount, h); } else { frec->range=rr; } } else if (!strncmp(bpos, "FONT",4)) { /* Start defining a new font with auto-detection of attributes ** and encoding. The auto-detection should not load the font ** itself, but rather use the name of the font to detect ** attributes: matching alias names, using a database. */ char *c,*h; char tc; FONTREC *reslist; c=bpos+4; tc=*c; h=get_string(&c,&tc); frec = malloc(sizeof(FONTREC)); frec->fontname=malloc(sizeof(char)*(c-h+1)); /* c-h==strlen(h) */ strcpy(frec->fontname, h); frec->attribpos=0; frec->encoding=NULL; frec->range=NULL; frec->fonttype=frec->loaded=frec->bt=frec->bm=frec->bmax=0; frec->font=0; frec->systemdata=NULL; frec->next=NULL; /* system specific attribute detection */ reslist = multi_detect_attributes(frec); /* Could check if reslist empty. However, it would indicate ** that the font is not available. Just ignore it or complain. ** If the font would be added anyhow, it could result in messages ** when the font has to be loaded. */ if (reslist) { free(frec->fontname); free(frec); *flist = reslist; frec = reslist; while (*flist) flist = &((*flist)->next); } else { free(frec->fontname); free(frec); } } else { /* The line starts the name of an attribute followed by ** its value. Find the attribute and the value and change ** the attribute of the current font. */ char *c,*h; char tc; ATTRIBREC *ar; ATTRIBREC *aval; int agr; c=bpos; tc=*c; /* get attribute name and look it up */ h=get_string(&c,&tc); ar=find_alias(h,ATTRIBGROUPALIAS); if (!ar) { fprintf(stderr,"%s:%i: Unknow attribute group %s\n", confname, linecount, h); continue; } agr=ar->num; /* get attribute value and look it up */ h=get_string(&c,&tc); if (!h) { fprintf(stderr,"%s:%i: No attribute value specified.\n", confname, linecount); aval=NULL; } else { aval=find_alias(h,ATTRIBVALUEALIAS(agr)); } if (!aval) { /* Invalid attribute value. ** Print valid attribute values as feedback. */ char *vname; fprintf(stderr,"%s:%i: Invalid attribute %s\n", confname, linecount, h); fprintf(stderr,"%s:%i: use one of:", confname, linecount); vname=find_type(ATTRIBVALUEALIAS(agr)); while (vname) { fprintf(stderr, " %s", vname); vname=find_type_next(); } fprintf(stderr, "\n"); continue; } else if (frec) { /* change font attribute of current collection of fonts */ FONTREC *flist; flist = frec; while (flist) { flist->attribpos=change_attribute(flist->attribpos, aval->num, aval->value); flist=flist->next; } } else { fprintf(stderr, "%s:%i: Not defining a font yet or previous font not found.\n", confname, linecount); } } } close_file(f); return build_font_structure(); }