/* AFM_parse.c */ #include #ifndef AIX #include # endif #include #include "defines.h" #include "myopen.h" #include "mymalloc.h" #include "ps2mf.h" #include "ps2mfutl.h" #include "AFMparse.h" #ifdef MSDOS #include #endif #ifdef __STDC__ int AFM_command (char * s) #else int AFM_command (s) char * s; #endif { char ** p; int n; for (p = AFM_key_words, n = 0; * p; p ++, n ++) { if (strequ (s, * p)) return (n); } return (not_an_AFM_keyword); } #ifdef __STDC__ int find_TeX_num (char * p) #else int find_TeX_num (p) char * p; #endif { AFM_info_tp * ai; for (ai = AFM_chars; ai; ai = ai -> next) { if (strequ (p, ai -> AFM_name)) return (ai -> TeX_num); } fprintf (stderr, "! No TeX coding found for character %s\n", p); error ("! Are you sure the configuration file is OK?\n"); } kern_tp * new_kern () { kern_tp * nk; nk = (kern_tp *) my_malloc (sizeof (kern_tp)); nk -> next = NULL; nk -> succ = NULL; nk -> delta = 0; return (nk); } AFM_info_tp * new_char () { AFM_info_tp * ai; ai = (AFM_info_tp *) my_malloc (sizeof (AFM_info_tp)); ai -> AFM_num = -1; ai -> TeX_num = -1; ai -> width = -1; ai -> AFM_name = NULL; ai -> bbox_llx = -1; ai -> bbox_lly = -1; ai -> bbox_urx = -1; ai -> bbox_ury = -1; ai -> ligs = NULL; ai -> kerns = NULL; ai -> pccs = NULL; ai -> next = AFM_chars; ai -> in_MF_file = FALSE; AFM_chars = ai; return (ai); } lig_tp * new_lig () { lig_tp * nl; nl = (lig_tp *) my_malloc (sizeof (lig_tp)); nl -> next = NULL; nl -> succ = NULL; nl -> sub = NULL; return (nl); } void process_char () { AFM_info_tp * ai; configuration_info_tp * ci; lig_tp * nl, * cilig; ai = new_char (); ai -> AFM_num = param_num (); expect (";"); expect ("WX"); ai -> width = transform (param_num (), 0); expect (";"); expect ("N"); ai -> AFM_name = param_new_string (); expect (";"); expect ("B"); ai -> bbox_llx = param_num (); ai -> bbox_lly = param_num (); ai -> bbox_urx = param_num (); ai -> bbox_ury = param_num (); ai -> bbox_llx = transform (ai -> bbox_llx, ai -> bbox_lly); ai -> bbox_urx = transform (ai -> bbox_urx, ai -> bbox_ury); if (ai -> bbox_lly > 0) ai -> bbox_lly = 0; if (ai -> bbox_ury < 0) ai -> bbox_ury = 0; if (strequ (ai -> AFM_name, "space")) font_space = ai -> width; if (strequ (ai -> AFM_name, "M")) font_quad = ai -> width; if (strequ (ai -> AFM_name, "x") && ! x_height_is_defined) { x_height = ai -> bbox_ury; } expect (";"); while (* param == 'L') { expect ("L"); nl = new_lig (); nl -> succ = param_new_string (); nl -> sub = param_new_string (); nl -> next = ai -> ligs; ai -> ligs = nl; expect (";"); } for (ci = TeX_configuration; ci; ci = ci -> next) { if (strequ (ai -> AFM_name, ci -> AFM_name)) { for (cilig = ci -> ligs; cilig; cilig = cilig -> next) { nl = new_lig (); nl -> succ = cilig -> succ; nl -> sub = cilig -> sub; nl -> next = ai -> ligs; ai -> ligs = nl; } } } } void process_kern () { AFM_info_tp * ai; char * p; kern_tp * nk; p = param_string (); if (strequ (p, "space")) return; ai = find_AFM_info_for (p); if (ai == NULL) error ("! kern char not found"); if (ai -> AFM_num < '0' || ai -> AFM_num > '9') { nk = new_kern (); nk -> succ = param_new_string (); if (strequ (nk -> succ, "space")) return; nk -> delta = transform (param_num (), 0); nk -> next = ai -> kerns; ai -> kerns = nk; } } pcc_tp * new_pcc () { pcc_tp * np; np = (pcc_tp *) my_malloc (sizeof (pcc_tp)); np -> next = NULL; np -> part_name = NULL; np -> x_offset = 0; np -> y_offset = 0; return (np); } void process_composite_char () { AFM_info_tp * ai; char * p; pcc_tp * np; int n; pcc_tp * npp = NULL; p = param_string (); ai = find_AFM_info_for (p); if (ai == NULL) error ("! composite character name not found"); n = param_num (); expect (";"); while (n --) { expect ("PCC"); /* see afm2tfm.c: handleconstruct*/ np = new_pcc (); np -> part_name = param_new_string (); if (find_AFM_info_for (np -> part_name) == NULL) return; np -> x_offset = param_num (); np -> y_offset = param_num (); np -> x_offset = transform (np -> x_offset, np -> y_offset); if (npp) npp -> next = np; else ai -> pccs = np; npp = np; expect (";"); } } #ifdef __STDC__ void append_liginfo (lig_tp * ail, lig_tp * cil) # else void append_liginfo (ail, cil) lig_tp * ail, * cil; # endif { lig_tp * dummy_cil; if (ail == NULL) { ail = cil; return; } if (cil == NULL) return; dummy_cil = cil; while (dummy_cil -> next != NULL) dummy_cil = dummy_cil -> next; dummy_cil -> next = ail; ail = cil; } void assign_chars () { char ** p; int i; bool stop; AFM_info_tp * ai; configuration_info_tp * ci; int nextfree; for (ai = AFM_chars; ai; ai = ai -> next) { stop = FALSE; ci = TeX_configuration; while (! stop && ci) { if (strequ (ai -> AFM_name, ci -> AFM_name)) { ai -> TeX_num = ci -> TeX_num; append_liginfo (ai -> ligs, ci -> ligs); stop = TRUE; } ci = ci -> next; } } } void delete_TeX_configuration () { configuration_info_tp * ci; while (TeX_configuration) { ci = TeX_configuration -> next; free (TeX_configuration); TeX_configuration = ci; } } void parse_AFM () { strcpy (font_name, "Unknown"); italic_angle = 0.0; fixed_pitch = FALSE; x_height = 400; font_space = 250; font_quad = 800; x_height_is_defined = FALSE; while (get_line (afm_file)) { switch (AFM_command (param_string ())) { case FontName: { strcpy (font_name, param_string ()); } break; case EncodingScheme: { /*strcpy (coding_scheme, param_string ());*/ } break; case ItalicAngle: { italic_angle = param_float (); } break; case IsFixedPitch: { if (* param == 't' || * param == 'T') { fixed_pitch = TRUE; } else fixed_pitch = FALSE; } break; case XHeight: { x_height = param_num (); x_height_is_defined = TRUE; } break; case C: { process_char (); } break; case KPX: { process_kern (); } break; case CC: { process_composite_char (); } break; default: break; } } assign_chars (); delete_TeX_configuration (); } #ifdef __STDC__ int config_command (char * s) #else int config_command (s) char * s; #endif { char ** p; int n; for (p = config_key_words, n = 0; * p; p ++, n ++) { if (strequ (s, * p)) return (n); } return (not_a_config_keyword); } configuration_info_tp * new_conf_info () { configuration_info_tp * nsl; nsl = (configuration_info_tp *) my_malloc (sizeof (configuration_info_tp)); nsl -> TeX_num = 0; nsl -> AFM_name = NULL; nsl -> ligs = NULL; nsl -> next = TeX_configuration; TeX_configuration = nsl; return (nsl); } #ifdef __STDC__ void process_configuration (int base) # else void process_configuration (base) int base; # endif { configuration_info_tp * ci; lig_tp * nl; ci = new_conf_info (); if (base == 8) ci -> TeX_num = param_oct (); else if (base == 10) ci -> TeX_num = param_num (); else if (base == 16) ci -> TeX_num = param_hex (); expect (";"); expect ("N"); ci -> AFM_name = param_new_string (); expect (";"); while (* param == 'L') { expect ("L"); nl = new_lig (); nl -> succ = param_new_string (); nl -> sub = param_new_string (); nl -> next = ci -> ligs; ci -> ligs = nl; expect (";"); } } ignore_info_tp * new_ignore_info () { ignore_info_tp * nii; nii = (ignore_info_tp *) my_malloc (sizeof (ignore_info_tp)); nii -> AFM_name = NULL; nii -> next = ignore_list; ignore_list = nii; return (nii); } void process_ignore () { ignore_info_tp * ii; ii = new_ignore_info (); ii -> AFM_name = param_new_string (); expect (";"); } void process_encoding () { strcpy (coding_scheme, param_string ()); while (* param != ';') { strcat (coding_scheme, " "); strcat (coding_scheme, param_string ()); } expect (";"); } void parse_config () { strcpy (coding_scheme, "Unspecified"); while (get_line (conf_file)) { switch (config_command (param_string ())) { case config_C: case config_D: { process_configuration (10); } break; case config_H: { process_configuration (16); } break; case config_O: { process_configuration (8); } break; case config_I: { process_ignore (); } break; case config_Encoding: { process_encoding (); } break; default: break; } } } #ifdef __STDC__ void process_ligatures (AFM_info_tp * ai) # else void process_ligatures (ai) AFM_info_tp * ai; # endif { AFM_info_tp * ai2, * ai3; while (ai -> ligs != NULL) { if (! has_ligs [ai -> TeX_num]) { ai2 = find_AFM_info_for (ai -> ligs -> succ); ai3 = find_AFM_info_for (ai -> ligs -> sub); if (ai2 -> in_MF_file && ai3 -> in_MF_file) { if (first_ligtable_entry) fprintf (mf_file, "\nligtable %d", ai -> TeX_num); fprintf (mf_file, "%s%d=:%d", first_ligtable_entry ? ":\n" : ",\n", ai2 -> TeX_num, ai3 -> TeX_num); has_ligs [ai -> TeX_num] = TRUE; first_ligtable_entry = FALSE; } } ai -> ligs = ai -> ligs -> next; } } #ifdef __STDC__ void process_kerns (AFM_info_tp * ai) # else void process_kerns (ai) AFM_info_tp * ai; # endif { AFM_info_tp * ai2; while (ai -> kerns != NULL) { if (! has_ligs [ai -> TeX_num]) { ai2 = find_AFM_info_for (ai -> kerns -> succ); if (ai2 -> in_MF_file) { if (first_ligtable_entry) fprintf (mf_file, "\nligtable %d", ai -> TeX_num); fprintf (mf_file, "%s%d kern %dFX#", first_ligtable_entry ? ":\n" : ",\n", ai2 -> TeX_num, ai -> kerns -> delta); first_ligtable_entry = FALSE; } } ai -> kerns = ai -> kerns -> next; } } void process_ligatures_and_kerns () { AFM_info_tp * ai, * ai2, * ai3; int i; fprintf (stderr, "Generating a ligaturetable\n"); for (ai = AFM_chars; ai; ai = ai -> next) { for (i = 0; i < 255; i ++) has_ligs [i] = FALSE; first_ligtable_entry = TRUE; if (ai -> in_MF_file && (ai -> ligs != NULL || ai -> kerns != NULL)) { if (ai -> ligs != NULL) process_ligatures (ai); if (ai -> kerns != NULL) process_kerns (ai); if (! first_ligtable_entry) fprintf (mf_file, ";\n"); } } }