diff options
Diffstat (limited to 'Build/source/texk/web2c/omegafonts/parse_ofm.c')
-rw-r--r-- | Build/source/texk/web2c/omegafonts/parse_ofm.c | 373 |
1 files changed, 373 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/omegafonts/parse_ofm.c b/Build/source/texk/web2c/omegafonts/parse_ofm.c new file mode 100644 index 00000000000..7aa0dadccbc --- /dev/null +++ b/Build/source/texk/web2c/omegafonts/parse_ofm.c @@ -0,0 +1,373 @@ +/* parse_ofm.h: Checking an existent OFM file + +This file is part of Omega, +which is based on the web2c distribution of TeX, + +Copyright (c) 1994--2001 John Plaice and Yannis Haralambous +Copyright (C) 2005, 2006 Roozbeh Pournader + +Omega is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +Omega is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Omega; if not, write to the Free Software Foundation, Inc., +59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "cpascal.h" +#include "list_routines.h" +#include "header_routines.h" +#include "manifests.h" +#include "char_routines.h" +#include "ligkern_routines.h" +#include "out_ofm.h" +#include "extra_routines.h" +#include "param_routines.h" +#include "dimen_routines.h" +#include "error_routines.h" +#include "print_routines.h" +#include "out_routines.h" +#include "font_routines.h" +#include "parse_ofm.h" +#include "omfonts.h" +#include "manifests.h" + +unsigned top_char, top_width, top_height, top_depth, top_italic; +unsigned start_ptr, check_sum_pos, design_size_pos, scheme_pos; +unsigned seven_bit_flag_pos; +unsigned random_word_pos, header_length; + +unsigned ivalues_start,fvalues_start,mvalues_start, + rules_start,glues_start,penalties_start; +unsigned ivalues_base,fvalues_base,mvalues_base, + rules_base,glues_base,penalties_base; +unsigned char_base,width_base,height_base,depth_base,italic_base; +unsigned lig_kern_base,kern_base,exten_base,param_base; + /* base addresses for the subfiles */ +unsigned char_start; +unsigned bytes_per_entry; + +unsigned lf; +boolean ofm_on; +unsigned start_pos; +unsigned family_pos; +unsigned ofm_ptr; +unsigned ncw; +unsigned ncl; +unsigned nce; +unsigned nco; +unsigned npc; + +static void +eval_two_bytes(unsigned *pos) { + if (ofm[ofm_ptr]>127) + fatal_error_0("One of the subfile sizes (2) is negative"); + *pos = ofm[ofm_ptr]*0x100 + ofm[ofm_ptr+1]; + ofm_ptr += 2; +} + +static void +eval_four_bytes(unsigned *pos) { + if (ofm[ofm_ptr]>127) + fatal_error_0("One of the subfile sizes (4) is negative"); + *pos = ofm[ofm_ptr]*0x1000000 + ofm[ofm_ptr+1]*0x10000 + + ofm[ofm_ptr+2]*0x100 + ofm[ofm_ptr+3]; + ofm_ptr += 4; +} + +static void ofm_organize(void); +static void ofm_read_simple(void); +static void ofm_read_rest(void); + +boolean changed = FALSE; + +void +parse_ofm(boolean read_ovf) +{ + ofm_organize(); + if (read_ovf == TRUE) input_ovf_file(); + ofm_read_simple(); + if (read_ovf == TRUE) input_ovf_fonts(); + ofm_read_rest(); + if (read_ovf == TRUE) input_ovf_chars(); + print_characters(read_ovf); + if (changed) { + left(); + out("COMMENT THE OFM FILE WAS BAD, SO THE DATA HAS BEEN CHANGED!"); + right(); + } +} + +/* parse_ofm ensures that all of the header entries are consistent. + The file is assumed to have been read in already, with the + contents in the ofm array (length_ofm bytes). +*/ + +void +ofm_organize(void) +{ + unsigned copies,i; + + ofm_on = false; ofm_level = OFM_NOLEVEL; lf = 0; lh = 0; + nco = 0; ncw = 0; npc = 0; + bc = 0; ec = 0; nw = 0; nh = 0; nd = 0; ni = 0; + nl = 0; nk = 0; ne = 0; np = 0; + nki = 0; nwi = 0; nkf = 0; nwf = 0; + nkm = 0; nwm = 0; + nkr = 0; nwr = 0; nkg = 0; nwg = 0; + nkp = 0; nwp = 0; font_dir = 0; + + if (length_ofm < 8) + fatal_error_0("File too short"); + lf = ofm[0]*256 + ofm[1]; + if (lf==0) { /* This is not a TFM file, it is an OFM-file */ + ofm_on = TRUE; + + /* next line edited by Thomas Esser, based on a patch sent + * by Hossein Movahhedian. The old code had " + 1" + * instead of "+ OFM_LEVEL0" and caused lots of segfaults */ + ofm_level = ofm[2]*0x100 + ofm[3] + OFM_LEVEL0; + if (ofm[4]>127) + fatal_error_0("File length is negative"); + lf = ofm[4]*0x1000000 + ofm[5]*0x10000 + ofm[6]*0x100 + ofm[7]; + } else { + ofm_on = FALSE; + ofm_level = OFM_TFM; + } + if ((lf*4)!=length_ofm) + fatal_error_2("Stated (%d) and actual (%d) file length do not match", + lf*4, length_ofm); + + switch(ofm_level) { + case OFM_TFM: { start_pos = 2; check_sum_pos = 24; break; } + case OFM_LEVEL0: { start_pos = 8; check_sum_pos = 56; break; } + case OFM_LEVEL1: { start_pos = 8; check_sum_pos = 116; break; } + default: { fatal_error_1("OFMLEVEL %d not supported", ofm_level-OFM_LEVEL0); + break; } + } + design_size_pos = check_sum_pos+4; + scheme_pos = design_size_pos+4; + family_pos = scheme_pos+40; + random_word_pos = family_pos+20; + + ofm_ptr = start_pos; + + if (ofm_on==FALSE) { + eval_two_bytes(&lh); + eval_two_bytes(&bc); + eval_two_bytes(&ec); + eval_two_bytes(&nw); + eval_two_bytes(&nh); + eval_two_bytes(&nd); + eval_two_bytes(&ni); + eval_two_bytes(&nl); + eval_two_bytes(&nk); + eval_two_bytes(&ne); + eval_two_bytes(&np); + ncw = (ec-bc+1); + ncl = nl; + nce = ne; + header_length = 6; + top_char = 255; + top_width = 255; + top_height = 15; + top_depth = 15; + top_italic = 63; + } else { + eval_four_bytes(&lh); + eval_four_bytes(&bc); + eval_four_bytes(&ec); + eval_four_bytes(&nw); + eval_four_bytes(&nh); + eval_four_bytes(&nd); + eval_four_bytes(&ni); + eval_four_bytes(&nl); + eval_four_bytes(&nk); + eval_four_bytes(&ne); + eval_four_bytes(&np); + eval_four_bytes(&font_dir); + top_char = 0x10ffff; + top_width = 65535; + top_height = 255; + top_depth = 255; + top_italic = 255; + ncl = nl*2; + nce = ne*2; + if (ofm_level==OFM_LEVEL0) { + header_length = 14; + ncw = 2*(ec-bc+1); + } else { + header_length = 29; + eval_four_bytes(&nco); + eval_four_bytes(&ncw); + eval_four_bytes(&npc); + eval_four_bytes(&nki); /* Kinds of font ivalues */ + eval_four_bytes(&nwi); /* Words of font ivalues */ + eval_four_bytes(&nkf); /* Kinds of font fvalues */ + eval_four_bytes(&nwf); /* Words of font fvalues */ + eval_four_bytes(&nkm); /* Kinds of font mvalues */ + eval_four_bytes(&nwm); /* Words of font mvalues */ + eval_four_bytes(&nkr); /* Kinds of font rules */ + eval_four_bytes(&nwr); /* Words of font rules */ + eval_four_bytes(&nkg); /* Kinds of font glues */ + eval_four_bytes(&nwg); /* Words of font glues */ + eval_four_bytes(&nkp); /* Kinds of font penalties */ + eval_four_bytes(&nwp); /* Words of font penalties */ + } + } + if (lf != (header_length+lh+ncw+nw+nh+nd+ni+ncl+nk+nce+np+ + nki+nwi+nkf+nwf+nkm+nwm+nkr+nwr+nkg+nwg+nkp+nwp)) + fatal_error_0("Subfile sizes do not add up to the stated total"); + if (lh < 2) + fatal_error_1("The header length is only %d", lh); + if ((bc > (ec+1)) || (ec > top_char)) + fatal_error_2("The character code range %d .. %d is illegal", bc, ec); + if ((nw==0) || (nh==0) || (nd==0) || (ni==0)) + fatal_error_0("Incomplete subfiles for character dimensions"); + ivalues_start = header_length+lh; + fvalues_start = ivalues_start+nki; + mvalues_start = fvalues_start+nkf; + rules_start = mvalues_start+nkm; + glues_start = rules_start+nkr; + penalties_start = glues_start+nkg; + ivalues_base = penalties_start+nkp; + fvalues_base = ivalues_base+nwi; + mvalues_base = fvalues_base+nwf; + rules_base = mvalues_base+nwm; + glues_base = rules_base+nwr; + penalties_base = glues_base+nwg; + char_base = penalties_base+nwp; + bytes_per_entry = (12 + 2*npc) / 4 * 4; + init_planes(); + no_labels = 0; + switch (ofm_level) { + case OFM_TFM: { + for(i=bc; i<=ec; i++) { + init_character(i,NULL); + char_start = 4*char_base+4*(i-bc); + current_character->index_indices[C_WD] = + ofm[char_start] & 0xff; + current_character->index_indices[C_HT] = + (ofm[char_start+1] & 0xf0) >> 4; + current_character->index_indices[C_DP] = + ofm[char_start+1] & 0xf; + current_character->index_indices[C_IC] = + (ofm[char_start+2] & 0xfc) >> 2; + current_character->tag = + ofm[char_start+2] & 0x3; + if (current_character->tag == TAG_LIG) no_labels++; + current_character->remainder = + ofm[char_start+3] & 0xff; + } + break; + } + case OFM_LEVEL0: { + for(i=bc; i<=ec; i++) { + init_character(i,NULL); + char_start = 4*char_base+8*(i-bc); + current_character->index_indices[C_WD] = + ((ofm[char_start] & 0xff) << 8) | + (ofm[char_start+1] & 0xff); + current_character->index_indices[C_HT] = + ofm[char_start+2] & 0xff; + current_character->index_indices[C_DP] = + ofm[char_start+3] & 0xff; + current_character->index_indices[C_IC] = + ofm[char_start+4] & 0xff; + current_character->tag = + ofm[char_start+5] & 0x3; + if (current_character->tag == TAG_LIG) no_labels++; + current_character->remainder = + ((ofm[char_start+6] & 0xff) << 8) | + (ofm[char_start+7] & 0xff); + } + break; + } + case OFM_LEVEL1: { + char_start = 4*char_base; + i = bc; + while (i<=ec) { + init_character(i,NULL); + current_character->index_indices[C_WD] = + ((ofm[char_start] & 0xff) << 8) | + (ofm[char_start+1] & 0xff); + current_character->index_indices[C_HT] = + ofm[char_start+2] & 0xff; + current_character->index_indices[C_DP] = + ofm[char_start+3] & 0xff; + current_character->index_indices[C_IC] = + ofm[char_start+4] & 0xff; + current_character->tag = + ofm[char_start+5] & 0x3; + if (current_character->tag == TAG_LIG) no_labels++; + current_character->remainder = + ((ofm[char_start+6] & 0xff) << 8) | + (ofm[char_start+7] & 0xff); + copies = 256*ofm[char_start+8]+ofm[char_start+9]; + /* Handle character params */ + copy_characters(i, copies); + i += copies + 1; + char_start += bytes_per_entry; + } + if (char_start != (4*(char_base+ncw))) + fatal_error_0("Length of char info table does not " + "correspond to specification"); + break; + } + default: { + fatal_error_1("Inappropriate font level (%d)", ofm_level-OFM_LEVEL0); + } + } + width_base = char_base+ncw; + height_base = width_base+nw; + depth_base = height_base+nh; + italic_base = depth_base+nd; + lig_kern_base = italic_base+ni; + kern_base = lig_kern_base+ncl; + exten_base = kern_base+nk; + param_base = exten_base+nce-1; +} + +void +ofm_read_simple(void) +{ + + if (ofm_on==TRUE) { + print_ofm_level(ofm_level-OFM_LEVEL0); + print_font_dir(font_dir); + } + header = (char *) ofm+check_sum_pos; + retrieve_header(); + print_family(); + print_face(); + print_coding_scheme(); + print_design_size(); + out("(COMMENT DESIGNSIZE IS IN POINTS)"); out_ln(); + out("(COMMENT OTHER SIZES ARE MULTIPLES OF DESIGNSIZE)"); out_ln(); + print_check_sum(); + if ((seven_bit == TRUE) || (ofm_level != OFM_TFM)) + print_seven_bit_safe_flag(); + retrieve_parameters(ofm+(4*param_base)); + print_parameters(); +} + +void +ofm_read_rest(void) +{ + retrieve_dimen_tables(); + if (verbose_option==TRUE) print_dimen_tables(); + retrieve_ligkern_table(ofm+(4*lig_kern_base), ofm+(4*kern_base)); + adjust_labels(FALSE); + if (verbose_option==TRUE) print_labels(); + print_ligkern_table(); + retrieve_exten_table(ofm+(4*exten_base)); + if (verbose_option==TRUE) print_extens(); +} |