Back to index

tetex-bin  3.0
dimen_routines.c
Go to the documentation of this file.
00001 /* dimen_routines.c: Data structures for holding widths, heights, etc.
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 "dimen_routines.h"
00029 #include "char_routines.h"
00030 #include "out_routines.h"
00031 #include "error_routines.h"
00032 #include "out_ofm.h"
00033 #include "parse_ofm.h"
00034 #include "omfonts.h"
00035 
00036 int *measure_max_entries;
00037 int  TFM_measure_max_entries[] =
00038     {256,16,16,64, 0,0,0,0,
00039      0,0,0,0,      0,0,0,0,
00040      0,0,0,0,      0,0,0,0};
00041 int  OFM0_measure_max_entries[] =
00042     {65536,256,256,256, 0,0,0,0,
00043      0,0,0,0,           0,0,0,0,
00044      0,0,0,0,           0,0,0,0};
00045 int  OFM2_measure_max_entries[] =
00046     {256,256,256,256, 256,256,256,256,
00047      256,256,256,256, 256,256,256,0,
00048      256,256,256,256, 256,256,256,0};
00049 
00050 in_list measure_list[C_MAX+1];
00051 int measure_max[C_MAX+1];
00052 int *dimen_tables[C_MAX+1];
00053 unsigned char *measure_base[C_MAX+1];
00054 
00055 unsigned nw=0;
00056 unsigned nh=0;
00057 unsigned nd=0;
00058 unsigned ni=0;
00059 
00060 void
00061 init_measures(void)
00062 {
00063     register int i;
00064     for (i=C_MIN; i<=C_MAX; i++) {
00065         measure_list[i] = in_list1(INFINITY, NULL);
00066         measure_max[i] = 0;
00067     }
00068 }
00069 
00070 void
00071 set_character_measure(int index, int val)
00072 {
00073     in_list L1, L2, *the_list;
00074 
00075     if ((index < C_MIN) || (index > C_MAX)) {
00076         internal_error_1("set_character_measure (index=%d)", index);
00077         return;
00078     }
00079     the_list = measure_list+index;
00080     L1 = *the_list;
00081     if (L1 == NULL) {
00082        internal_error_0("set_character_measure (L1)");
00083     } else {
00084         L2 = L1->ptr;
00085         while ((L2 != NULL) && (lval(L2) <= val)) {
00086             L1 = L2;
00087             L2 = L2->ptr;
00088         }
00089         if (val < lval(L1)) {
00090             *the_list = in_list1(val, NULL);
00091             (*the_list)->ptr = L1;
00092             (*the_list)->actual = *the_list;
00093             measure_max[index]++;
00094             current_character->indices[index] = *the_list;
00095         } else if (val == lval(L1)) {
00096             current_character->indices[index] = L1;
00097         } else {
00098             L2 = in_list1(val, NULL);
00099             L2->ptr = L1->ptr;
00100             L2->actual = L2;
00101             L1->ptr = L2;
00102             measure_max[index]++;
00103             current_character->indices[index] = L2;
00104         }
00105     }
00106     /* print_measures(); */
00107 }
00108 
00109 void
00110 print_measures(void)
00111 {
00112     in_list L;
00113     register int i,j;
00114 
00115     for (i=C_MIN; i<=C_MAX; i++) {
00116        L = measure_list[i];
00117         if (L!=NULL) {
00118            j=0;
00119            out_character_measure(i);
00120            fprintf(stdout, ":\n");
00121             while (L != NULL) {
00122               fprintf(stdout, "   %d: ", j++);
00123               out_fix(lval(L));
00124               fprintf(stdout, "\n");
00125                L = L->ptr;
00126             }
00127            fprintf(stdout, "\n");
00128         }
00129     }
00130     fprintf(stdout, "--------------------------------\n");
00131 }
00132 
00133 
00134 int next_d;
00135 int excess;
00136 int delta;
00137 
00138 int
00139 min_cover(int h, int d)
00140 {
00141     in_list L = measure_list[h];
00142     int m=0; /* the current size of the cover being generated */
00143     int l;   /* the least element covered by the current interval */
00144 
00145     m = 0; next_d = INFINITY;
00146     while (lval(L) != INFINITY) {
00147         m++; l = lval(L);
00148         while (lval(L->ptr) <= (l+d)) L = L->ptr;
00149        L = L->ptr;
00150         if ((lval(L) - l) < next_d) next_d = lval(L) - l;
00151     }
00152     return m;
00153 }
00154 
00155 /* finds best way to round */
00156 
00157 int
00158 shorten(int h, int m)
00159 {
00160     int d=0; /* the current trial interval length */
00161     int k; /* the size of a minimum cover */
00162     int M = measure_max[h];
00163 
00164     if (M>m) {
00165         excess = M-m;
00166         k = min_cover(h,0); d = next_d;
00167         /* now the answer is at least d*/
00168         /* first we ascend rapidly until finding the range */
00169         do {
00170             d = d+d; k = min_cover(h,d);
00171         } while (k>m);
00172         /* now we run through the feasible steps */
00173         d = d/2; k=min_cover(h,d);
00174         while (k>m) {
00175             d = next_d; k = min_cover(h,d);
00176         }
00177     }
00178     return d;
00179 }
00180 
00181 /* reduces and indexes a list */
00182 
00183 void
00184 set_indices(int h, int d)
00185 {
00186     in_list L1;     /* the current node of interest */
00187     in_list L2;     /* trails one step behind L1 */
00188     int l;          /* least value in the current interval */
00189     int lprime;     /* middle value for current interval */
00190     int m;          /* index number of nodes in the current interval */
00191 
00192 /* How to store the information for each character ? */
00193     L1 = measure_list[h]; m = 0;
00194     while (lval(L1) != INFINITY) {
00195         L2 = L1;
00196         m++; l = lval(L1); 
00197        L1->index = m;
00198         while (lval(L1->ptr) <= (l+d)) {
00199             L1 = L1->ptr; excess--;
00200             if (excess==0) d = 0;
00201         }
00202         lprime = l + (lval(L1)-l) / 2;
00203        lval(L1) = lprime;
00204        while (L2 != L1) {
00205           lval(L2) = lprime;
00206           L2->actual = L1;
00207           L2->index = m;
00208           L2 = L2->ptr;
00209        }
00210         L1 = L1->ptr; L2 = L1; 
00211     }
00212     measure_max[h] = m;
00213 }
00214 
00215 void
00216 build_dimen_tables(void)
00217 {
00218     int delta;
00219     in_list L1;
00220     int i,j;
00221 
00222     switch(ofm_level) {
00223       case OFM_TFM:
00224         measure_max_entries = TFM_measure_max_entries;
00225         break;
00226       case OFM_LEVEL0: case OFM_LEVEL1:
00227         measure_max_entries = OFM0_measure_max_entries;
00228         break;
00229       default:
00230         measure_max_entries = OFM2_measure_max_entries;
00231     }
00232     for (i=C_MIN; i<=C_MAX; i++) {
00233         if (measure_max_entries[i] != 0) {
00234             delta=shorten(i,measure_max_entries[i]);
00235             set_indices(i,delta);
00236             dimen_tables[i] = (int *) malloc((measure_max[i]+1)*sizeof(int));
00237             L1 = measure_list[i];
00238             j=0;
00239             while (lval(L1) != INFINITY) {
00240                 L1 = L1->actual;
00241                 dimen_tables[i][j] = lval(L1);
00242                 L1 = L1->ptr;
00243                 j++;
00244             }
00245         }
00246     }
00247     nw = measure_max[C_WD];
00248     nh = measure_max[C_HT];
00249     nd = measure_max[C_DP];
00250     ni = measure_max[C_IC];
00251 }
00252 
00253 void
00254 retrieve_dimen_tables(void)
00255 {
00256     unsigned i, j;
00257     unsigned char *k;
00258 
00259     measure_max[C_WD] = nw;
00260     measure_max[C_HT] = nh;
00261     measure_max[C_DP] = nd;
00262     measure_max[C_IC] = ni;
00263     measure_base[C_WD] = ofm+width_base*4;
00264     measure_base[C_HT] = ofm+height_base*4;
00265     measure_base[C_DP] = ofm+depth_base*4;
00266     measure_base[C_IC] = ofm+italic_base*4;
00267     for (i=C_IC+1; i<=C_MAX; i++) {
00268         measure_max[i] = 0;
00269         dimen_tables[i] = NULL;
00270     }
00271     for (i=C_MIN; i<=C_MAX; i++) {
00272         dimen_tables[i] = (int *) malloc((measure_max[i]+1)*sizeof(int));
00273         for (j=0; j<measure_max[i]; j++) {
00274             k = measure_base[i]+4*j;
00275             dimen_tables[i][j] = (((*k)&0xff) << 24) |
00276                                  (((*(k+1))&0xff) << 16) |
00277                                  (((*(k+2))&0xff) << 8) |
00278                                  ((*(k+3))&0xff);
00279         }
00280     }
00281 }
00282 
00283 void
00284 print_dimen_tables(void)
00285 {
00286     int i, j;
00287 
00288     for (i=C_MIN; i<=C_MAX; i++) {
00289         if (measure_max[i] != 0) {
00290             left(); out("COMMENT"); out_ln();
00291             for (j=0; j<measure_max[i]; j++) {
00292                 left(); 
00293                 out_character_measure(i); out("_ENTRY");
00294                 out(" "); out_int(j,10);
00295                 out(" "); out_fix(dimen_tables[i][j]);
00296                 right();
00297             }
00298             right();
00299         }
00300     }
00301 }
00302 
00303 void
00304 set_accent(unsigned kind)
00305 {
00306     if ((kind<ACC_TOP) || (kind>ACC_BOT)) {
00307         warning_0("bad ACCENT value; ignored");
00308         kind = ACC_NONE;
00309     }
00310     current_character->accent = kind;
00311 }
00312 
00313 void
00314 output_ofm_dimension(void)
00315 {
00316     int i, j;
00317 
00318     for (i=C_WD; i<=C_IC; i++) {
00319         out_ofm_4(0);
00320         for (j=0; j<measure_max[i]; j++) {
00321             out_ofm_4(dimen_tables[i][j]);
00322         }
00323     }
00324 }