Back to index

tetex-bin  3.0
header_routines.c
Go to the documentation of this file.
00001 /* header_routines.c: Headers of font metric files.
00002 
00003 This file is part of Omega,
00004 which is based on the web2c distribution of TeX,
00005 
00006 Copyright (c) 1994--2001 John Plaice and Yannis Haralambous
00007 
00008 Omega is free software; you can redistribute it and/or modify
00009 it under the terms of the GNU General Public License as published by
00010 the Free Software Foundation; either version 2 of the License, or
00011 (at your option) any later version.
00012 
00013 Omega is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 GNU General Public License for more details.
00017 
00018 You should have received a copy of the GNU General Public License
00019 along with Omega; if not, write to the Free Software Foundation, Inc.,
00020 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00021 
00022 */
00023 
00024 #include "cpascal.h"
00025 #include "list_routines.h"
00026 #include "manifests.h"
00027 #include "header_routines.h"
00028 #include "print_routines.h"
00029 #include "error_routines.h"
00030 #include "out_ofm.h"
00031 #include "omfonts.h"
00032 
00033 #define LOC_CHECK_SUM       0
00034 #define LOC_DESIGN_SIZE     4
00035 #define LOC_CODING_SCHEME   8
00036 #define LOC_FAMILY          (LOC_CODING_SCHEME+LEN_CODING_SCHEME+1)
00037 #define LOC_SEVEN_FLAG      (LOC_FAMILY+LEN_FAMILY+1)
00038 #define LOC_FACE            (LOC_SEVEN_FLAG+3)
00039 
00040 #define HEADER_MIN                  18
00041 #define HEADER_MAX                 255
00042 
00043 
00044 string header;
00045 av_list header_list = NULL;
00046 unsigned header_max = HEADER_MIN-1;
00047 
00048 unsigned check_sum;
00049 boolean check_sum_specified;
00050 
00051 fix design_size;
00052 boolean design_size_specified;
00053 
00054 fix design_units;
00055 boolean design_units_specified;
00056 
00057 string coding_scheme;
00058 boolean coding_scheme_specified;
00059 
00060 string family;
00061 boolean family_specified;
00062 
00063 unsigned face;
00064 boolean face_specified;
00065 
00066 unsigned ofm_level;
00067 boolean ofm_level_specified;
00068 
00069 unsigned font_dir;
00070 boolean font_dir_specified;
00071 
00072 boolean seven_bit;
00073 boolean seven_bit_specified;
00074 boolean seven_bit_calculated;
00075 
00076 unsigned font_type = FT_VANILLA;
00077 
00078 unsigned lh;
00079 
00080 void
00081 store_header_int(unsigned loc, unsigned val)
00082 {
00083     header[loc]   = 0xff & (val >> 24) ;
00084     header[loc+1] = 0xff & (val >> 16) ;
00085     header[loc+2] = 0xff & (val >>  8) ;
00086     header[loc+3] = 0xff & val ;
00087 }
00088 
00089 void
00090 store_header_byte(unsigned loc, unsigned val)
00091 {
00092     header[loc] = 0xff & val ;
00093 }
00094 
00095 void
00096 retrieve_header_int(unsigned loc, unsigned *where)
00097 {
00098     string ptr = header+loc;
00099 
00100     *where = ((* ptr    & 0xff) << 24) |
00101              ((*(ptr+1) & 0xff) << 16) |
00102              ((*(ptr+2) & 0xff) <<  8) |
00103               (*(ptr+3) & 0xff) ;
00104 
00105 }
00106 
00107 void
00108 retrieve_header_byte(unsigned loc, unsigned char *where)
00109 {
00110     *where = header[loc];
00111 }
00112 
00113 /* HEADER */
00114 
00115 void
00116 init_header_word()
00117 {
00118 header_list = NULL;
00119 header_max = HEADER_MIN-1;
00120 font_type = FT_VANILLA;
00121 }
00122 
00123 void
00124 set_header_word(unsigned index, unsigned val)
00125 {
00126     av_list L1, L2;
00127 
00128     if (index > HEADER_MAX) {
00129        warning_0("HEADER index must be at most 255; ignored");
00130         return;
00131     }
00132     if (index < HEADER_MIN) {
00133        warning_0("HEADER index must be at least 18; ignored");
00134         return;
00135     }
00136     L1 = header_list;
00137     if (L1 == NULL) {
00138        header_list = av_list1(index, val);
00139        header_max = index;
00140     } else {
00141        L2 = L1->ptr;
00142        while ((L2 != NULL) && (lattr(L2) <= index)) {
00143            L1 = L2;
00144            L2 = L2->ptr;
00145        }
00146        if (index < lattr(L1)) {
00147            header_list = av_list1(index, val);
00148            header_list->ptr = L1;
00149         } else if (index == lattr(L1)) {
00150            warning_1("HEADER index (%d) previously defined; "
00151                       "old value ignored", index);
00152            lval(L1)  = val;
00153        } else {
00154            L2 = av_list1(index, val);
00155            L2->ptr = L1->ptr;
00156            if (L1->ptr==NULL) header_max = index;
00157            L1->ptr = L2;
00158        }
00159     }
00160 }
00161 
00162 void
00163 store_header_word()
00164 {
00165     av_list L = header_list;
00166     unsigned ctr = HEADER_MIN;
00167 
00168     header = (string) xmalloc(4*(header_max+1));
00169     while (L != NULL) {
00170        while (ctr<lattr(L)) {
00171            store_header_int(ctr*4,0);
00172            ctr++;
00173        }
00174        store_header_int(ctr*4,lval(L));
00175        ctr++; L = L->ptr;
00176     }
00177 }
00178 
00179 void
00180 retrieve_header_word()
00181 {
00182     unsigned j = HEADER_MIN, value, header_no=lh;
00183 
00184     header_list = NULL; 
00185     while (j <= header_no) {
00186        retrieve_header_int(j*4, &value);
00187        if (value != 0) {
00188            set_header_word(j, value);
00189        }
00190         j++;
00191     }
00192 }
00193 
00194 void
00195 print_header(void)
00196 {
00197     av_list L = header_list;
00198 
00199     print_check_sum();
00200     print_design_size();
00201     print_coding_scheme();
00202     print_family();
00203     print_face();
00204     print_seven_bit_safe_flag();
00205     while (L!=NULL) {
00206        print_header_word(lattr(L),lval(L));
00207        L = L->ptr;
00208     }
00209 }
00210 
00211 /* CHECKSUM */
00212 
00213 void
00214 init_check_sum(void)
00215 {
00216     check_sum = 0;
00217     check_sum_specified = FALSE;
00218 }
00219 
00220 void
00221 set_check_sum(unsigned cs)
00222 {
00223     check_sum = cs;
00224     check_sum_specified = TRUE;
00225 }
00226 
00227 void
00228 store_check_sum(void)
00229 {
00230 
00231     calculate_check_sum();
00232     store_header_int(LOC_CHECK_SUM, check_sum);
00233 }
00234 
00235 void
00236 retrieve_check_sum(void)
00237 {
00238     retrieve_header_int(LOC_CHECK_SUM, &check_sum);
00239 }
00240 
00241 void
00242 calculate_check_sum(void)
00243 {
00244 /* 
00245     if (check_sum_specified == FALSE) {
00246        not_yet_done("checksum calculation");
00247     }
00248 */
00249 }
00250 
00251 
00252 /* DESIGNSIZE */
00253 
00254 void
00255 init_design_size()
00256 {
00257     design_size = 10*UNITY;
00258     design_size_specified = FALSE;
00259 }
00260 
00261 void
00262 set_design_size(fix ds)
00263 {
00264     if (design_size_specified==TRUE)
00265        warning_0("DESIGNSIZE previously defined; old value ignored");
00266     if (ds<1) {
00267         warning_0("DESIGNSIZE value must be at least 1; set to 10");
00268         design_size = 10*UNITY;
00269     } else {
00270         design_size = ds;
00271     }
00272     design_size_specified = TRUE;
00273 }
00274 
00275 void
00276 store_design_size(void)
00277 {
00278     store_header_int(LOC_DESIGN_SIZE, design_size);
00279 }
00280 
00281 void
00282 retrieve_design_size(void)
00283 {
00284     retrieve_header_int(LOC_DESIGN_SIZE, (unsigned *) &design_size);
00285 }
00286 
00287 
00288 /* DESIGNUNITS */
00289 
00290 void
00291 init_design_units(void)
00292 {
00293     design_units = UNITY;
00294     design_units_specified = FALSE;
00295 }
00296 
00297 void
00298 set_design_units(fix du)
00299 {
00300     if (design_units_specified==TRUE)
00301        warning_0("DESIGNUNITS previously defined; old value ignored");
00302     if (du<=0) {
00303         warning_0("DESIGNUNITS value must be positive; set to 1");
00304         design_units = UNITY;
00305     } else {
00306         design_units = du;
00307     }
00308     design_units_specified = TRUE;
00309 }
00310 
00311 
00312 /* CODINGSCHEME */
00313 
00314 void
00315 init_coding_scheme(void)
00316 {
00317     coding_scheme = "UNSPECIFIED";
00318     coding_scheme_specified = FALSE;
00319 }
00320 
00321 void
00322 set_coding_scheme(string sval)
00323 {
00324     if (coding_scheme_specified==TRUE) {
00325        warning_0("CODINGSCHEME previously defined; old value ignored");
00326         free(coding_scheme); coding_scheme=NULL;
00327     }
00328     coding_scheme = sval;
00329     
00330     if (!strncmp(coding_scheme, "TEX MATH SY", 11) ||
00331         !strncmp(coding_scheme, "TeX math sy", 11))
00332         font_type = FT_MATHSY;
00333     else if (!strncmp(coding_scheme, "TEX MATH EX", 11) ||
00334         !strncmp(coding_scheme, "TeX math ex", 11))
00335         font_type = FT_MATHEX;
00336     else font_type = FT_VANILLA;
00337 
00338     coding_scheme_specified = TRUE;
00339 }
00340 
00341 void
00342 store_coding_scheme(void)
00343 {
00344     register unsigned i=0, j=LOC_CODING_SCHEME, len=strlen(coding_scheme);
00345 
00346     header[j] = len;
00347     for (j++; i<len; i++,j++) header[j] = coding_scheme[i];
00348     for (; j<(LOC_CODING_SCHEME+LEN_CODING_SCHEME); j++)
00349         header[j] = '\0';;
00350 }
00351 
00352 
00353 void
00354 retrieve_coding_scheme(void)
00355 {
00356     register unsigned i=0, j=LOC_CODING_SCHEME, len=header[LOC_CODING_SCHEME];
00357 
00358     coding_scheme = (string) xmalloc(len+1);
00359     for (j++; i<len; i++,j++) {
00360        coding_scheme[i] = header[j];
00361        if ((text_format == TEXT_CODE_UPPER) &&
00362            (coding_scheme[i] >= 'a') &&
00363            (coding_scheme[i] <= 'z')) {
00364           coding_scheme[i] += 'A' - 'a';
00365        }
00366     }
00367     coding_scheme[i] = '\0';
00368     if (!strncmp(coding_scheme, "TEX MATH SY", 11) ||
00369         !strncmp(coding_scheme, "TeX math sy", 11))
00370         font_type = FT_MATHSY;
00371     else if (!strncmp(coding_scheme, "TEX MATH EX", 11) ||
00372         !strncmp(coding_scheme, "TeX math ex", 11))
00373         font_type = FT_MATHEX;
00374     else font_type = FT_VANILLA;
00375 }
00376 
00377 /* FAMILY */
00378 
00379 void
00380 init_family(void)
00381 {
00382     family = "UNSPECIFIED";
00383     family_specified = FALSE;
00384 }
00385 
00386 void
00387 set_family(string sval)
00388 {
00389     if (family_specified==TRUE) {
00390        warning_0("FAMILY previously defined; old value ignored");
00391         free(family); family=NULL;
00392     }
00393     family = sval;
00394     family_specified = TRUE;
00395 }
00396 
00397 void
00398 store_family(void)
00399 {
00400     register unsigned i=0, j=LOC_FAMILY, len=strlen(family);
00401 
00402     if (len>LEN_FAMILY) internal_error_1("store_family (len=%d)", len);
00403     header[j] = len;
00404     for (j++; i<len; i++,j++) header[j] = family[i];
00405     for (; j<=(LOC_FAMILY+LEN_FAMILY); j++)
00406         header[j] = '\0';;
00407 }
00408 
00409 
00410 void
00411 retrieve_family(void)
00412 {
00413     register unsigned i=0, j=LOC_FAMILY, len=header[LOC_FAMILY];
00414 
00415     family = (string) xmalloc(len+1);
00416     for (j++; i<len; i++,j++) {
00417        family[i] = header[j];
00418        if ((text_format == TEXT_CODE_UPPER) &&
00419            (family[i] >= 'a') &&
00420            (family[i] <= 'z')) {
00421           family[i] += 'A' - 'a';
00422        }
00423     }
00424     family[i] = '\0';
00425 }
00426 
00427 /* FACE */
00428 
00429 void
00430 init_face()
00431 {
00432     face = 0;
00433     face_specified = FALSE;
00434 }
00435 
00436 void
00437 set_face(unsigned f)
00438 {
00439     if (face_specified==TRUE)
00440        warning_0("FACE previously defined; old value ignored");
00441     if (face>255) {
00442         warning_0("FACE value must be less than 256");
00443     } else {
00444         face = f;
00445     }
00446     face_specified = TRUE;
00447 }
00448 
00449 void
00450 store_face(void)
00451 {
00452     store_header_byte(LOC_FACE, face);
00453 }
00454 
00455 void
00456 retrieve_face(void)
00457 {
00458     unsigned char face_byte;
00459     retrieve_header_byte(LOC_FACE, &face_byte);
00460     face = face_byte;
00461 }
00462 
00463 /* OFMLEVEL */
00464 
00465 void
00466 init_ofm_level()
00467 {
00468     ofm_level = OFM_TFM;
00469     ofm_level_specified = FALSE;
00470 }
00471 
00472 void
00473 set_ofm_level(unsigned level)
00474 {
00475     if (ofm_level_specified==TRUE)
00476         warning_0("OFMLEVEL previously defined; old value ignored");
00477     /* Fix from Joel Riou <joel.riou@normalesup.org> */
00478     if ((level != 0) && (level != 1)) {
00479         warning_0("OFMLEVEL value must be D 0 or D 1");
00480     } else {
00481         ofm_level = level ? OFM_LEVEL1 : OFM_LEVEL0;
00482     }
00483     ofm_level_specified = TRUE;
00484 }
00485 
00486 /* FONTDIR */
00487 
00488 void
00489 init_font_dir()
00490 {
00491     font_dir = DIR_ORD+DIR_TL;
00492     font_dir_specified = FALSE;
00493 }
00494 
00495 void
00496 set_font_dir(unsigned direction)
00497 {
00498     if (font_dir_specified==TRUE)
00499         warning_0("FONTDIR previously defined; old value ignored");
00500     if ((direction < DIR_MIN) || (direction > DIR_MAX)) {
00501         warning_0("bad FONTDIR value; ignored");
00502     } else {
00503         font_dir = direction;
00504     }
00505     font_dir_specified = TRUE;
00506 }
00507 
00508 /* SEVENBITSAFEFLAG */
00509 
00510 void
00511 init_seven_bit_safe_flag()
00512 {
00513     seven_bit = 0;
00514     seven_bit_calculated = 1;
00515     seven_bit_specified = FALSE;
00516 }
00517 
00518 void
00519 set_seven_bit_safe_flag(unsigned f)
00520 {
00521     if (seven_bit_specified==TRUE)
00522         warning_0("SEVENBITSAFEFLAG previously defined; "
00523                   "old value ignored");
00524     if ((f!=FALSE) && (f!=TRUE)) {
00525         internal_error_1("set_seven_bit_safe_flag (f=%d)", f);
00526     }
00527     seven_bit = f;
00528     seven_bit_specified = TRUE;
00529 }
00530 
00531 void
00532 store_seven_bit_safe_flag(void)
00533 {
00534     store_header_byte(LOC_SEVEN_FLAG, seven_bit);
00535 }
00536 
00537 void
00538 retrieve_seven_bit_safe_flag(void)
00539 {
00540     unsigned char seven_bit_byte;
00541     retrieve_header_byte(LOC_SEVEN_FLAG, &seven_bit_byte);
00542     seven_bit = (seven_bit_byte != 0);
00543 }
00544 
00545 void
00546 calculate_seven_bit_safe_flag(void)
00547 {
00548     if ((seven_bit_specified == TRUE) && (seven_bit == 1) &&
00549         (seven_bit_calculated == 0)) {
00550         warning_0("SEVENBITSAFEFLAG value specified TRUE; "
00551                   "really FALSE");
00552     }
00553     seven_bit = seven_bit_calculated;
00554 }
00555 
00556 void
00557 init_header(void)
00558 {
00559     init_header_word();
00560     init_check_sum();
00561     init_design_size();
00562     init_design_units();
00563     init_coding_scheme();
00564     init_family();
00565     init_face();
00566     init_seven_bit_safe_flag();
00567 }
00568 
00569 void
00570 store_header(void)
00571 {
00572 
00573     store_header_word();
00574     store_check_sum();
00575     store_design_size();
00576     store_coding_scheme();
00577     store_family();
00578     store_face();
00579     store_seven_bit_safe_flag();
00580 
00581 /*
00582     { int i;
00583     for (i=0; i<(4*(header_max+1)); i++) {
00584         if (!(i%4)) fprintf(stdout, "\n");
00585        fprintf(stdout, "%d: %c (%d, %2x) ",
00586                 i, header[i], header[i], header[i]);
00587     }
00588     fprintf(stdout, "\n");
00589 */
00590     if (header_list!=NULL) {
00591         av_list L1 = header_list, L2;
00592         while (L1 != NULL) {
00593             L2 = L1->ptr;
00594             free(L1);
00595             L1 = L2;
00596         }
00597     }
00598     lh = header_max;
00599     header_list = NULL;
00600     header_max = HEADER_MIN-1;
00601 
00602     retrieve_header();
00603 }
00604 
00605 void
00606 retrieve_header(void)
00607 {
00608     retrieve_header_word();
00609     retrieve_check_sum();
00610     retrieve_design_size();
00611     retrieve_coding_scheme();
00612     retrieve_family();
00613     retrieve_face();
00614     retrieve_seven_bit_safe_flag();
00615 }
00616 
00617 void
00618 output_ofm_header(void)
00619 {
00620     unsigned i=0, j, k1, k2;
00621 
00622     av_list L = header_list;
00623 
00624     out_ofm_4(check_sum); i++;
00625     out_ofm_4(design_size); i++;
00626     k1 = strlen(coding_scheme);
00627     out_ofm(k1);
00628     for (j=0; j<k1; j++) out_ofm(coding_scheme[j]);
00629     for (j=k1; j<LEN_CODING_SCHEME; j++) out_ofm(0); 
00630     k2 = strlen(family);
00631     out_ofm(k2);
00632     for (j=0; j<k2; j++) out_ofm(family[j]);
00633     for (j=k2; j<LEN_FAMILY; j++) out_ofm(0); 
00634     if ((ofm_level==OFM_TFM) && (seven_bit_specified==TRUE))
00635       out_ofm(seven_bit);
00636     else
00637       out_ofm(0);
00638     out_ofm(0); out_ofm(0); out_ofm(face);
00639     i = 1 + LOC_SEVEN_FLAG / 4;
00640     lh = header_max + 1;
00641     while(L != NULL) {
00642        j=lattr(L);
00643        while (i<j) {
00644            out_ofm_4(0);
00645            i++;
00646        }
00647        out_ofm_4(lval(L));
00648        L = L->ptr; i++;
00649     }
00650     while (i<lh) {out_ofm_4(0); i++;}
00651 }