w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

char_routines.c
Go to the documentation of this file.
1 /* char_routines.c: Data structures for character information
2 
3 This file is part of Omega,
4 which is based on the web2c distribution of TeX,
5 
6 Copyright (c) 1994--2001 John Plaice and Yannis Haralambous
7 
8 Omega is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12 
13 Omega is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Omega; if not, write to the Free Software Foundation, Inc.,
20 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
21 
22 */
23 
24 #include "cpascal.h"
25 #include "manifests.h"
26 #include "list_routines.h"
27 #include "char_routines.h"
28 #include "print_routines.h"
29 #include "out_routines.h"
30 #include "error_routines.h"
31 #include "ligkern_routines.h"
32 #include "dimen_routines.h"
33 #include "header_routines.h"
34 #include "font_routines.h"
35 #include "out_ofm.h"
36 #include "omfonts.h"
37 #include "parse_ofm.h"
38 #include "dvi.h"
39 
40 #define PLANE 0x10000
41 #define INDEX_MAX (PLANE-1)
42 #define HALFPLANE 0x08000
43 
44 #define MAX_START_OFM 65535
45 #define MAX_START_TFM 255
46 
47 /*
48  * Characters can range from 0x0 to 0x7fffffff (31 bits unsigned),
49  * which is a lot of characters. We would expect characters to either
50  * be bunched up in a given region, or else sparsely defined throughout
51  * the range. The data structure to hold them is an array of HALFPLANE
52  * arrays, each of which holds a full PLANE (0x10000) of characters.
53  *
54  * At all times, init_character ensures that planes[0] to planes[plane_max]
55  * are either NULL or allocated arrays of PLANE characters.
56  *
57  * For allocated array p, init_character also ensures that planes[p][0]
58  * to planes[p][char_max[p]] are either NULL or pointers to allocated
59  * char_entry values.
60  *
61  * init_character can be called when actually reading a CHARACTER definition
62  * or when the character is referenced in a charlist cycle, an extensible
63  * piece or in a ligature/kerning table. In the latter case, ensure_existence
64  * is called, and it sets the defined field of the character to be FALSE;
65  *
66  * init_character also sets current_character to the character entry;
67  *
68  */
69 
70 unsigned bc=0x7fffffff;
71 unsigned ec=0x0;
72 unsigned ne=0;
73 
75 unsigned char_max[HALFPLANE];
76 unsigned plane_max = 0;
77 
80 
83 
84 unsigned no_labels = 0;
89 
90 void
92 {
93  plane_max = 0;
95 }
96 
97 void
98 init_character(unsigned c, char_entry *ready_made)
99 {
100  register unsigned i, index, plane;
101 
102  if ((c<CHAR_MINIMUM) || (c>CHAR_MAXIMUM)) {
103  warning_1("CHARACTER index (H %X) not 31-bit unsigned integer; "
104  "ignored", c);
106  return;
107  }
108  plane = c / PLANE;
109  index = c % PLANE;
110  for (i=plane_max+1; i<=plane; i++) {
111  planes[i] = NULL;
112  }
113  if (planes[plane]==NULL) {
114  planes[plane] = (char_entry **)xmalloc(PLANE * sizeof(char_entry *));
115  char_max[plane] = 0;
116  planes[plane][0] = NULL;
117  }
118  for (i=char_max[plane]+1; i<=index; i++) {
119  planes[plane][i] = NULL;
120  }
121  if (plane>plane_max) plane_max = plane;
122  if (index>char_max[plane]) char_max[plane] = index;
123 
124  if (planes[plane][index] != NULL) {
125  if (planes[plane][index]->defined == FALSE) {
126  current_character = planes[plane][index];
127  current_character->defined = TRUE;
128  return;
129  }
130  warning_1("CHARACTER index (H %X) previously defined; "
131  "old definition ignored", c);
134  }
135  if (ready_made != NULL) {
136  current_character = ready_made;
137  planes[plane][index] = current_character;
138  } else {
140  planes[plane][index] = current_character;
141  for (i=C_MIN; i<=C_MAX; i++) {
142  current_character->indices[i] = NULL;
143  current_character->index_indices[i] = 0;
144  }
145  current_character->c = c;
146  current_character->copies = 0;
147  current_character->remainder = 0;
149  current_character->defined = TRUE;
150  current_character->accent = ACC_NONE;
151  current_character->ovf_packet_length = 0;
152  current_character->ovf_packet = NULL;
153  cur_packet = NULL;
154  }
155 }
156 
157 void
158 copy_characters(unsigned c, unsigned copies)
159 {
160  unsigned i=0;
161  unsigned plane, index;
162  char_entry *the_entry;
163 
164  if ((c<CHAR_MINIMUM) || (c>CHAR_MAXIMUM)) {
165  warning_1("CHARACTER index (H %X) not 31-bit unsigned integer; "
166  "ignored", c);
168  return;
169  }
170  plane = c / PLANE;
171  index = c % PLANE;
172  if ((plane>plane_max) || (planes[plane]==NULL))
173  internal_error_1("copy_characters (plane %d)", plane);
174  the_entry = planes[plane][index];
175  if (the_entry==NULL)
176  internal_error_1("copy_characters (index %d)", index);
177  the_entry->copies = copies;
178  for (i=(c+1); i<=(c+copies); i++)
179  init_character(i, the_entry);
180 }
181 
182 void
184 {
185  register unsigned index, plane;
186  plane = c / PLANE;
187  index = c % PLANE;
188 
189  if ((plane>plane_max) || (planes[plane]==NULL) ||
190  (index>char_max[plane]) || (planes[plane][index]==NULL)) {
192  planes[plane][index]->defined = FALSE;
193  }
195 }
196 
197 #define FOR_ALL_CHARACTERS(FOR_ALL_CHARACTERS_ACTION) \
198  for (plane = 0; plane <=plane_max; plane++) { \
199  if (planes[plane] != NULL) { \
200  for (index = 0; index <=char_max[plane]; index++) { \
201  entry = planes[plane][index]; \
202  if (entry != NULL) { \
203  FOR_ALL_CHARACTERS_ACTION \
204  } \
205  } \
206  } \
207  }
208 
209 #define FOR_ALL_EXISTING_CHARACTERS(FOR_ALL_EXISTING_CHARACTERS_ACTION) \
210  FOR_ALL_CHARACTERS( \
211  if (entry->defined == TRUE) { \
212  FOR_ALL_EXISTING_CHARACTERS_ACTION \
213  } \
214  )
215 
216 void
218 {
219  register unsigned index, plane, k;
220  char_entry *entry;
221  fix wd;
222 
224  unsigned c = plane*PLANE + index;
225 
226  if ((entry->indices[C_WD] == NULL) || (entry->indices[C_WD]->index == 0))
227  continue;
228  wd = lval(entry->indices[C_WD]);
229  if (design_units != UNITY)
230  wd = zround(((double)wd) / ((double)design_units) * 1048576.0);
231  if ((entry->ovf_packet_length>241) ||
232  (wd < 0) || (wd >= 0x1000000) ||
233  (c < 0) || (c >255)) {
234  out_ovf(242); out_ovf_4(entry->ovf_packet_length);
235  out_ovf_4(c); out_ovf_4(wd);
236  } else {
237  out_ovf(entry->ovf_packet_length); out_ovf(c);
238  out_ovf((wd >>16) & 0xff); out_ovf((wd >>8) & 0xff);
239  out_ovf(wd & 0xff);
240  }
241  for (k=0; k<entry->ovf_packet_length; k++)
242  out_ovf(entry->ovf_packet[k]);
243  )
244 }
245 
246 
247 static void
249 {
250  register unsigned index, plane;
251  char_entry *entry;
252  unsigned *exten;
253  unsigned j;
254 
256  unsigned c = plane*PLANE + index;
257  if (entry->indices[C_WD] == NULL) {
258  current_character = entry;
259  set_character_measure(C_WD, 0);
260  }
261  switch(entry->tag) {
262  case TAG_NONE: { break; }
263  case TAG_LIG: {
264  check_ligature_program(c, entry->remainder);
265  break;
266  }
267  case TAG_LIST:{
268  check_existence_and_safety(c, entry->remainder, "",
269  "%sCharacter (H %X) NEXTLARGER than (H %X) "
270  "has no CHARACTER spec");
271  if (entry->remainder > 0xffff) {
272  fprintf(stderr, "Character (H %X) NEXTLARGER than (H %X) "
273  "exceeds ffff\n", entry->remainder, c);
274  exit(2);
275  }
276  break;
277  }
278  case TAG_EXT:{
279  exten = entry->extens;
280  for (j=E_MIN; j<=E_MAX; j++) {
281  if (exten[j]!=0) {
284  "%s piece (H %X) of character (H %X) "
285  "has no CHARACTER spec");
286  if (exten[j] > 0xfff) {
287  fprintf(stderr, "%s piece (H %X) of character (H %X) "
288  "exceeds ffff\n", extensible_pieces[j], exten[j], c);
289  exit(2);
290  }
291  }
292  }
293  break;
294  }
295  }
296  )
297 }
298 
299 void
301 {
302  register unsigned index, plane;
303  char_entry *entry;
304 
306  if (entry->tag == TAG_LIG) {
307  entry->tag = TAG_NONE;
308  entry->remainder = 0;
309  }
310  )
311 }
312 
313 void
315 {
317 
318  if ((g<CHAR_MINIMUM) || (g>CHAR_MAXIMUM))
319  internal_error_1("check_existence_and_safety (g=%d)", g);
322  if ((g>=128) && (c<128))
324  if (gentry->defined == FALSE) {
325  warning_s_2(fmt, extra, g, c);
328  gentry->defined = TRUE;
329  }
330 }
331 
332 void
334 {
336 
337  if ((g<CHAR_MINIMUM) || (g>CHAR_MAXIMUM))
338  internal_error_1("doublecheck_existence (g=%d)", g);
341  if (gentry->defined == FALSE) {
342  warning_s_1(fmt, extra, g);
344 /*
345  set_character_measure(C_WD, 0);
346 */
347  }
348 }
349 
350 static void print_packet(unsigned char *, unsigned);
351 
352 #define check_range(ndx, mx, name) \
353  if (entry->index_indices[ndx] >= mx) { \
354  fprintf(stderr, "\n%s index for character \"%x is too large;\n" \
355  "so I reset it to zero.\n", name, c); \
356  entry->index_indices[ndx] = 0; \
357  changed = TRUE; \
358  }
359 
360 void
361 print_characters(boolean read_ovf)
362 {
363  register unsigned index, plane;
364  char_entry *entry;
365  four_pieces *exten;
366  four_entries *lentry;
367  unsigned j,k;
368  unsigned copies = 0;
369 
371  unsigned c = plane*PLANE + index;
372  if (copies > 0)
373  copies--;
374  else {
375  if (entry->index_indices[C_WD] != 0) {
376  copies = entry->copies;
377  if (copies > 0)
378  print_character_repeat(c, copies);
379  else
380  print_character(c);
381  check_range(C_WD, nw, "Width")
382  check_range(C_HT, nh, "Height")
383  check_range(C_DP, nd, "Depth")
384  check_range(C_IC, ni, "Italic correction")
385  for (k=C_MIN; k<C_MAX; k++) {
386  if (entry->index_indices[k] != 0) {
387  print_character_measure(k,
388  dimen_tables[k][entry->index_indices[k]]);
389  }
390  }
392  switch (entry->tag) {
393  case TAG_NONE: { break; }
394  case TAG_LIG: {
395  if (entry->remainder >= nl) {
396  fprintf(stderr, "\nLigature/kern starting index for character \"%x is too large;\n"
397  "so I removed it.\n", c);
398  entry->tag = 0;
399  entry->remainder = 0;
400  changed = TRUE;
401  break;
402  }
403  left();
404  out("COMMENT"); out_ln();
405  lentry = lig_kern_table + entry->remainder;
406  if (lentry->entries[0] > STOP_FLAG) {
407  lentry = lig_kern_table +
408  (256*lentry->entries[2]+lentry->entries[3]);
409  }
410  do {
412  if (lentry->entries[0] >= STOP_FLAG) {
413  lentry = lig_kern_table + nl;
414  } else {
415  lentry = lentry + 1 + lentry->entries[0];
416  }
417  } while (lentry < (lig_kern_table + nl));
418  right();
419  break;
420  }
421  case TAG_LIST: {
422  print_next_larger(entry->remainder);
423  break;
424  }
425  case TAG_EXT: {
426  if (entry->remainder >= ne) {
427  fprintf(stderr, "\nExtensible index for character \"%x is too large;\n"
428  "so I reset it to zero.\n", c);
429  entry->tag = 0;
430  entry->remainder = 0;
431  changed = TRUE;
432  break;
433  }
435  exten = exten_table[entry->remainder];
436  for (j=E_MIN; j<=E_MAX; j++) {
437  if (exten->pieces[j]!=0)
438  print_extensible_piece(j,exten->pieces[j]);
439  }
440  right();
441  break;
442  }
443  }
444  if ((read_ovf==TRUE) && (entry->ovf_packet_length>0)) {
445  print_map();
446  print_packet(entry->ovf_packet, entry->ovf_packet_length);
447  right();
448  }
449  right();
451  }
452  }
453  )
454 }
455 
456 unsigned stack_top = 0;
457 int wstack[1000];
458 int xstack[1000];
459 int ystack[1000];
460 int zstack[1000];
461 
462 static int
463 string_balance(unsigned char *special, int k)
464 {
465  unsigned paren_level = 0;
466 
467  if (k == 0)
468  return 1;
469  if (*special == ' ')
470  return 0;
471  for (; k > 0; k--, special++) {
472  if ((*special < ' ') || (*special > '~'))
473  return 0;
474  if (*special == '(')
475  paren_level++;
476  if (*special == ')') {
477  if (paren_level-- == 0)
478  return 0;
479  }
480  }
481  return (paren_level == 0);
482 }
483 
484 static void
485 print_packet(unsigned char *packet_start, unsigned packet_length)
486 {
487  unsigned cmd, arg;
488  fix fix_arg, fix_arg1;
489  unsigned char *packet = packet_start;
490  unsigned char *max_packet = packet+packet_length;
491 
492  stack_top = 0;
495  while (packet <max_packet) {
496  if (*packet <= DVI_SET_CHAR_127) {
497  arg = *packet; packet++;
498  print_set_char(arg);
499  } else if ((*packet >= DVI_FNT_NUM_0) && (*packet <= DVI_FNT_NUM_63)) {
500  arg = *packet - DVI_FNT_NUM_0; packet++;
501  print_select_font(arg);
502  } else switch(*packet) {
503  case DVI_SET_1: case DVI_SET_2: case DVI_SET_3: case DVI_SET_4:
504  cmd = *packet; packet++;
505  arg = ovf_get_arg(&packet, cmd - DVI_SET_1 + 1, FALSE);
506  print_set_char(arg);
507  break;
508  case DVI_NOP:
509  packet++;
510  break;
511  case DVI_PUSH:
512  cmd = DVI_PUSH; packet++; stack_top++;
517  print_push();
518  break;
519  case DVI_POP:
520  cmd = DVI_PUSH; packet++; stack_top--;
521  print_pop();
522  break;
523  case DVI_SET_RULE:
524  cmd = DVI_SET_RULE; packet++; fix_arg = ovf_get_arg(&packet, 4, TRUE);
525  fix_arg1 = ovf_get_arg(&packet, 4, TRUE);
526  print_set_rule(fix_arg, fix_arg1);
527  break;
528  case DVI_PUT_RULE:
529  cmd = DVI_PUT_RULE; packet++; fix_arg = ovf_get_arg(&packet, 4, TRUE);
530  fix_arg1 = ovf_get_arg(&packet, 4, TRUE);
531  print_put_rule(fix_arg, fix_arg1);
532  break;
533  case DVI_RIGHT_1: case DVI_RIGHT_2: case DVI_RIGHT_3: case DVI_RIGHT_4:
534  cmd = *packet; packet++;
535  fix_arg = ovf_get_arg(&packet, cmd - DVI_RIGHT_1 + 1, TRUE);
536  print_move(M_RIGHT, fix_arg);
537  break;
538  case DVI_DOWN_1: case DVI_DOWN_2: case DVI_DOWN_3: case DVI_DOWN_4:
539  cmd = *packet; packet++;
540  fix_arg = ovf_get_arg(&packet, cmd - DVI_DOWN_1 + 1, TRUE);
541  print_move(M_DOWN, fix_arg);
542  break;
543  case DVI_W_0:
544  cmd = DVI_W_0; packet++;
546  break;
547  case DVI_W_1: case DVI_W_2: case DVI_W_3: case DVI_W_4:
548  cmd = *packet; packet++;
549  wstack[stack_top] = ovf_get_arg(&packet, cmd - DVI_W_1 + 1, TRUE);
551  break;
552  case DVI_X_0:
553  cmd = DVI_X_0; packet++;
555  break;
556  case DVI_X_1: case DVI_X_2: case DVI_X_3: case DVI_X_4:
557  cmd = *packet; packet++;
558  xstack[stack_top] = ovf_get_arg(&packet, cmd - DVI_X_1 + 1, TRUE);
560  break;
561  case DVI_Y_0:
562  cmd = DVI_Y_0; packet++;
564  break;
565  case DVI_Y_1: case DVI_Y_2: case DVI_Y_3: case DVI_Y_4:
566  cmd = *packet; packet++;
567  ystack[stack_top] = ovf_get_arg(&packet, cmd - DVI_Y_1 + 1, TRUE);
569  break;
570  case DVI_Z_0:
571  cmd = DVI_Z_0; packet++;
573  break;
574  case DVI_Z_1: case DVI_Z_2: case DVI_Z_3: case DVI_Z_4:
575  cmd = *packet; packet++;
576  zstack[stack_top] = ovf_get_arg(&packet, cmd - DVI_Z_1 + 1, TRUE);
578  break;
579  case DVI_PUT_1: case DVI_PUT_2: case DVI_PUT_3: case DVI_PUT_4:
580  cmd = *packet; packet++;
581  fix_arg = ovf_get_arg(&packet, cmd - DVI_PUT_1 + 1, FALSE);
582  print_put_char(fix_arg);
583  break;
584  case DVI_XXX_1: case DVI_XXX_2: case DVI_XXX_3: case DVI_XXX_4:
585  cmd = *packet; packet++;
586  fix_arg = ovf_get_arg(&packet, cmd - DVI_XXX_1 + 1, FALSE);
587  if (fix_arg < 0) {
588  internal_error_1("Special string with negative length (%d)\n", fix_arg);
589  }
590  if ((fix_arg <= 64) && string_balance(packet, fix_arg)) {
591  char *special = (char *) xmalloc(fix_arg+1);
592  strncpy(special, (const char *)packet, fix_arg);
593  special[fix_arg] = '\0';
595  free(special);
596  } else {
597  print_special_hex(packet, fix_arg);
598  }
599  packet += fix_arg;
600  break;
601  case DVI_FNT_1: case DVI_FNT_2: case DVI_FNT_3: case DVI_FNT_4:
602  cmd = *packet; packet++;
603  fix_arg = ovf_get_arg(&packet, cmd - DVI_FNT_1 + 1, FALSE);
604  print_select_font(fix_arg);
605  break;
606  default:
607  internal_error_1("Unrecognized DVI packet (%d)\n", *packet);
608  }
609  }
611  fflush(stderr);
612 }
613 
614 void
615 check_char_tag(unsigned c)
616 {
618 }
619 
620 void
621 set_char_tag(unsigned c, unsigned tag)
622 {
624  planes[c/PLANE][c%PLANE]->tag = tag;
625 }
626 
627 void
628 set_char_remainder(unsigned c, unsigned remainder)
629 {
631  planes[c/PLANE][c%PLANE]->remainder = remainder;
632 }
633 
634 static int
636 {
638  return planes[c/PLANE][c%PLANE]->remainder;
639 }
640 
641 void
642 set_next_larger(unsigned larger)
643 {
647 }
648 
649 void
651 {
653  unsigned j;
654 
658  for (j=E_MIN; j<=E_MAX; j++) {
659  entry->pieces[j] = 0;
660  }
662  current_character->extens = (unsigned int *)entry->pieces;
663  ne++;
664 }
665 
666 void
667 set_extensible_piece(unsigned piece, unsigned val)
668 {
669  unsigned *exten = current_character->extens;
670 
671  if ((piece < E_MIN) || (piece > E_MAX))
672  internal_error_1("set_extensible_piece (piece=%d)", piece);
673  if (exten[piece]!=0)
674  warning_0("value already defined");
675  exten[piece] = val;
676 }
677 
678 void
679 adjust_labels(boolean play_with_starts)
680 {
681  unsigned plane, index;
682  char_entry *entry;
683  int max_start = (ofm_level==OFM_TFM) ? MAX_START_TFM : MAX_START_OFM;
684 
686  label_ptr = 0;
687  label_table[0].rr = -1; /* sentinel */
688 
689  if (!play_with_starts && (bchar_label < nl)) {
690  label_ptr = 1;
691  label_table[1].cc = -1;
693  }
694 
696  unsigned c = plane*PLANE + index;
697  if ((c>=bc) && (c<=ec) && (entry->tag == TAG_LIG)) {
698  int r = entry->remainder;
699  if (r < nl) {
700  unsigned s = lig_kern_table[r].entries[0];
701  if ((s < 256) && (s > STOP_FLAG)) {
702  r = 256 * lig_kern_table[r].entries[2] + lig_kern_table[r].entries[3];
703  if (!play_with_starts && (r < nl) && (activity[entry->remainder] == A_UNREACHABLE))
704  activity[entry->remainder] = A_PASS_THROUGH;
705  }
706  }
707  sort_ptr = label_ptr; /* hole at position sort_ptr+1 */
708  while (label_table[sort_ptr].rr > r) {
710  sort_ptr--; /* move the hole */
711  }
712  label_table[sort_ptr+1].cc = c;
713  label_table[sort_ptr+1].rr = r;
714  label_ptr++;
715  if (!play_with_starts)
717  }
718  )
719  if (play_with_starts) {
720  if (bchar != CHAR_BOUNDARY) {
722  } else {
724  }
725  sort_ptr = label_ptr; /* the largest unallocated label */
726  if ((label_table[sort_ptr].rr + lk_offset) > max_start) {
728  /* location 0 can do double duty */
729  do {
731  while (label_table[sort_ptr-1].rr == label_table[sort_ptr].rr) {
732  sort_ptr--;
734  }
735  lk_offset++; sort_ptr--;
736  } while ((lk_offset+label_table[sort_ptr].rr) > max_start);
737  /* N.B. lk_offset=MAX_START+1 satisfies this when sort_ptr=0 */
738  }
739  if (lk_offset>0) {
740  while (sort_ptr>0) {
743  +lk_offset);
744  sort_ptr--;
745  }
746  }
747  }
748  if (bchar_label < nl) {
749  lig_kern_table[nl-1].entries[2] = (bchar_label + lk_offset) / (max_start + 1);
750  lig_kern_table[nl-1].entries[3] = (bchar_label + lk_offset) % (max_start + 1);
751  }
752 }
753 
754 void
756 {
757  unsigned i;
758 
759  if (label_ptr>0) {
760  left(); out("COMMENT"); out_ln();
761  for (i=1; i<=label_ptr; i++) {
762  left(); out("LABEL_ENTRY"); out(" ");
763  out_int(i,10); out(" ");
764  out_char(label_table[i].cc); out(" ");
765  out_int(label_table[i].rr, 10); right();
766  }
767  right();
768  }
769 }
770 
771 static void check_charlist_infinite_loops(void);
772 static void doublecheck_extens(void);
773 static void build_exten_table(void);
774 
775 void
777 {
790 }
791 
792 static void
794 {
795  unsigned plane, index;
796  char_entry *entry;
797  unsigned g;
798 
800  unsigned c = plane*PLANE + index;
801  if (entry->tag == TAG_LIST) {
802  g = entry->remainder;
803  while ((g < c) && (planes[g/PLANE][g%PLANE]->tag == TAG_LIST)) {
804  g = planes[g/PLANE][g%PLANE]->remainder;
805  }
806  if (g == c) {
807  entry->tag = TAG_NONE;
808  entry->remainder = 0;
809  warning_1("Cycle of NEXTLARGER characters "
810  "has been broken at ",c);
811  }
812  }
813  )
814 }
815 
816 static void
818 {
820  unsigned i = 0;
821 
822  exten_table = (four_pieces **) xmalloc(ne*sizeof(four_pieces *));
823  while (L1 != NULL) {
824  exten_table[i] = (four_pieces *)L1->contents;
825  L2 = L1->ptr;
826  free(L1); L1 = L2;
827  i++;
828  }
829 }
830 
831 void
833 {
834  unsigned i = 0, j;
836 
837  exten_table = (four_pieces **) xmalloc(ne*sizeof(four_pieces *));
838  for (i=0; i<ne; i++) {
839  exten_table[i] = entry = (four_pieces *) xmalloc(sizeof(four_pieces));
840  for (j=E_MIN; j<=E_MAX; j++) {
841  if (ofm_level==OFM_TFM) {
842  entry->pieces[j] = table[4*i+j] & 0xff;
843  } else {
844  entry->pieces[j] =
845  ((table[8*i+j*2] & 0xff) << 8) |
846  (table[8*i+j*2+1] & 0xff);
847  }
848  }
849  }
850 }
851 
852 void
854 {
855  unsigned i,j;
856 
857  if (ne>0) {
858  left(); out("COMMENT"); out_ln();
859  for (i=0; i<ne; i++) {
860  left(); out("EXTEN_ENTRY");
861  out(" "); out_int(i,10); out_ln();
862  for (j=E_MIN; j<=E_MAX; j++) {
863  if (exten_table[i]->pieces[j] != 0)
865  }
866  right();
867  }
868  right();
869  }
870 }
871 
872 static void
874 {
875  unsigned i,j;
876 
877  if (ne>0) {
878  for (i=0; i<ne; i++) {
879  for (j=E_MIN; j<=E_MAX; j++) {
880  if (exten_table[i]->pieces[j] != 0)
882  exten_table[i]->pieces[j], extensible_pieces[j],
883  "Unused %s piece (H %X) refers to "
884  "nonexistent character");
885  }
886  }
887  }
888 }
889 
890 void
892 {
893 }
894 
895 void
897 {
898  unsigned i,j;
899 
900  for (i=0; i<ne; i++) {
901  for (j=E_MIN; j<=E_MAX; j++) {
902  if (exten_table[i]->pieces[j] != 0)
903  out_ofm_char(exten_table[i]->pieces[j]);
904  else out_ofm_char(0);
905  }
906  }
907 }
908 
910 
911 #define XX_ENTRY(key) (entry->indices[key] != NULL ? entry->indices[key]->index : 0)
912 #define WD_ENTRY XX_ENTRY(C_WD)
913 #define HT_ENTRY XX_ENTRY(C_HT)
914 #define DP_ENTRY XX_ENTRY(C_DP)
915 #define IC_ENTRY XX_ENTRY(C_IC)
916 
917 #define XX_NEXT(key) ((next != NULL) && (next->indices[key] != NULL) ? next->indices[key]->index : 0)
918 #define WD_NEXT XX_NEXT(C_WD)
919 #define HT_NEXT XX_NEXT(C_HT)
920 #define DP_NEXT XX_NEXT(C_DP)
921 #define IC_NEXT XX_NEXT(C_IC)
922 #define YY_NEXT(field) (next != NULL ? next->field : 0)
923 #define RM_NEXT YY_NEXT(remainder)
924 #define TG_NEXT YY_NEXT(tag)
925 
926 static void
928 {
929  unsigned c;
930  unsigned plane, index;
931  char_entry *entry;
932  unsigned c0 = bc, c1 = ec, c2 = bc, c3 = ec;
933  fix wd;
934 
935  for (c = bc; c <= ec; c++) {
936  plane = c / PLANE;
937  index = c % PLANE;
938  entry = planes[plane][index];
939  if ((entry == NULL) || (WD_ENTRY == 0))
940  continue;
941  wd = lval(entry->indices[C_WD]);
942  if (design_units != UNITY)
943  wd = zround((wd / (double)design_units) * 1048576.0);
944  wd += (c + 4) * 0x400000; /* this should be positive */
945  c0 = (c0 + c0 + wd) % 255;
946  c1 = (c1 + c1 + wd) % 253;
947  c2 = (c2 + c2 + wd) % 251;
948  c3 = (c3 + c3 + wd) % 247;
949  }
950  check_sum = (c0 << 24) | (c1 << 16) | (c2 << 8) | c3;
951 }
952 
953 void
955 {
956  unsigned c;
957  unsigned plane, index;
958  char_entry *entry;
959 
960  bc = 0x7fffffff; ec=0;
962  c = plane*PLANE + index;
963  if (c < bc) bc = c;
964  if (c > ec) ec = c;
965  )
966  if (bc > ec) bc = 1;
967 
968  /* fill gaps */
969  for (plane = 0; plane < plane_max; plane++) {
970  if (planes[plane] == NULL) {
971  planes[plane] = (char_entry **)xmalloc(PLANE * sizeof(char_entry *));
972  char_max[plane] = 0;
973  planes[plane][0] = NULL;
974  }
975  for (index = char_max[plane]+1; index <= INDEX_MAX; index++) {
976  planes[plane][index] = NULL;
977  }
978  char_max[plane] = INDEX_MAX;
979  }
980 
981  switch (ofm_level) {
982  case OFM_TFM: {
983  if (ec>0xff)
985  "Char (%x) too big for TFM (max ff); use OFM file",ec);
986  break;
987  }
988  case OFM_LEVEL0: {
989  if (ec>0x10ffff)
991  "Char (%x) too big for OFM level-0 (max 10ffff); use level-2",
992  ec);
993  break;
994  }
995  case OFM_LEVEL1: {
996  if (ec>0x10ffff)
998  "Char (%x) too big for OFM level-1 (max 10ffff); use level-2",
999  ec);
1000  num_char_info = 0;
1001  for (c = bc; c <= ec; c++) {
1002  unsigned saved_c = c;
1003  char_entry *next;
1004 
1005  plane = c / PLANE;
1006  index = c % PLANE;
1007  entry = planes[plane][index];
1008  if ((entry != NULL) && (WD_ENTRY != 0)) {
1009  unsigned wd = WD_ENTRY, ht = HT_ENTRY, dp = DP_ENTRY, ic = IC_ENTRY;
1010 
1011  c += entry->copies;
1012  for (; (c < ec) && (c-saved_c < 0xffff); c++) {
1013  plane = (c+1) / PLANE;
1014  index = (c+1) % PLANE;
1015  next = planes[plane][index];
1016  if ((WD_NEXT != wd) || (HT_NEXT != ht) ||
1017  (DP_NEXT != dp) || (IC_NEXT != ic) ||
1018  (RM_NEXT != entry->remainder) || (TG_NEXT != entry->tag))
1019  break;
1020  planes[plane][index] = entry;
1021  }
1022  } else {
1023  plane = c / PLANE;
1024  index = c % PLANE;
1025  planes[plane][index] = NULL;
1026  init_character(c, NULL);
1028  for (; (c < ec) && (c-saved_c < 0xffff); c++) {
1029  plane = (c+1) / PLANE;
1030  index = (c+1) % PLANE;
1031  next = planes[plane][index];
1032  if (WD_NEXT != 0)
1033  break;
1034  planes[plane][index] = entry;
1035  }
1036  }
1037  entry->copies = c - saved_c;
1038  num_char_info++;
1039  }
1040  break;
1041  }
1042  default: { internal_error_0("compute_ofm_character_info"); }
1043  }
1044 
1047 }
1048 
1049 void
1051 {
1052  unsigned plane, index;
1053  char_entry *entry;
1054 
1055  switch (ofm_level) {
1056  case OFM_TFM: {
1057  plane=0;
1058  for (index = bc; index <= ec; index++) {
1059  entry = planes[plane][index];
1060  if (entry == NULL) {
1061  out_ofm_4(0);
1062  } else {
1063  out_ofm(WD_ENTRY);
1064  out_ofm(HT_ENTRY*16 + DP_ENTRY);
1065  out_ofm(IC_ENTRY*4 + entry->tag);
1066  out_ofm(entry->remainder);
1067  }
1068  }
1069  break;
1070  }
1071  case OFM_LEVEL0: {
1072  unsigned c;
1073 
1074  for (c = bc; c <= ec; c++) {
1075  plane = c / PLANE;
1076  index = c % PLANE;
1077  entry = planes[plane][index];
1078  if (entry == NULL) {
1079  out_ofm_4(0); out_ofm_4(0);
1080  } else {
1082  out_ofm(HT_ENTRY);
1083  out_ofm(DP_ENTRY);
1084  out_ofm(IC_ENTRY);
1085  out_ofm(entry->tag);
1086  out_ofm_2(entry->remainder);
1087  }
1088  }
1089  break;
1090  }
1091  case OFM_LEVEL1: {
1092  unsigned i;
1093  unsigned c;
1094 
1095  for (c = bc; c <= ec; c++) {
1096  plane = c / PLANE;
1097  index = c % PLANE;
1098  entry = planes[plane][index];
1099  if (entry == NULL) {
1100  for (i=0; i<words_per_entry; i++)
1101  out_ofm_4(0);
1102  } else {
1103  unsigned copies = entry->copies;
1104 
1106  out_ofm(HT_ENTRY);
1107  out_ofm(DP_ENTRY);
1108  out_ofm(IC_ENTRY);
1109  /* assume no ctag */
1110  out_ofm(entry->tag);
1111  out_ofm_2(entry->remainder);
1112  out_ofm_2(copies);
1113  /* assume no character params */
1114  for (i=0; i<npc; i++)
1115  out_ofm_2(0);
1116  /* padding */
1117  if (0 == npc % 2)
1118  out_ofm_2(0);
1119  c += copies;
1120  }
1121  }
1122  break;
1123  }
1124  default: { internal_error_0("compute_ofm_character_info"); }
1125  }
1126 }
double __cdecl remainder(double _X, double _Y)
int nl
Definition: afm2tfm.c:885
#define next(a)
Definition: aptex-macros.h:924
void output_ovf_chars(void)
#define IC_NEXT
#define HT_NEXT
void copy_characters(unsigned c, unsigned copies)
void ensure_existence(unsigned c)
char_entry * current_secondary_character
Definition: char_routines.c:79
unsigned num_char_info
void check_existence_and_safety(unsigned c, unsigned g, const_string extra, const_string fmt)
#define FOR_ALL_CHARACTERS(FOR_ALL_CHARACTERS_ACTION)
void print_extens(void)
void init_character(unsigned c, char_entry *ready_made)
Definition: char_routines.c:98
int ystack[1000]
#define HT_ENTRY
#define INDEX_MAX
Definition: char_routines.c:41
static int string_balance(unsigned char *special, int k)
unsigned stack_top
#define DP_ENTRY
void doublecheck_existence(unsigned g, const_string extra, const_string fmt)
static void check_existence_all_character_fields(void)
static void compute_check_sum(void)
int zstack[1000]
#define TG_NEXT
#define FOR_ALL_EXISTING_CHARACTERS(FOR_ALL_EXISTING_CHARACTERS_ACTION)
void check_and_correct(void)
boolean extra_loc_needed
Definition: char_routines.c:88
int wstack[1000]
unsigned plane_max
Definition: char_routines.c:76
void set_next_larger(unsigned larger)
void set_char_remainder(unsigned c, unsigned remainder)
void output_ofm_extensible(void)
void clear_ligature_entries(void)
unsigned ne
Definition: char_routines.c:72
label_entry * label_table
Definition: char_routines.c:85
int xstack[1000]
#define MAX_START_TFM
Definition: char_routines.c:45
int lk_offset
Definition: char_routines.c:87
#define PLANE
Definition: char_routines.c:40
#define HALFPLANE
Definition: char_routines.c:42
#define DP_NEXT
#define MAX_START_OFM
Definition: char_routines.c:44
static void build_exten_table(void)
unsigned ec
Definition: char_routines.c:71
static int get_char_remainder(unsigned c)
#define WD_ENTRY
void compute_ofm_character_info(void)
#define RM_NEXT
unsigned bc
Definition: char_routines.c:70
unsigned words_per_entry
int sort_ptr
Definition: char_routines.c:86
int label_ptr
Definition: char_routines.c:86
queue exten_queue
Definition: char_routines.c:81
char_entry * current_character
Definition: char_routines.c:78
void init_var_character(void)
void adjust_labels(boolean play_with_starts)
void check_char_tag(unsigned c)
static void doublecheck_extens(void)
void compute_ligkern_offset(void)
unsigned no_labels
Definition: char_routines.c:84
void set_char_tag(unsigned c, unsigned tag)
#define WD_NEXT
char_entry ** planes[0x08000]
Definition: char_routines.c:74
void output_ofm_character_info(void)
void init_planes(void)
Definition: char_routines.c:91
unsigned char_max[0x08000]
Definition: char_routines.c:75
void print_characters(boolean read_ovf)
void print_labels(void)
static void check_charlist_infinite_loops(void)
static void print_packet(unsigned char *, unsigned)
four_pieces ** exten_table
Definition: char_routines.c:82
#define IC_ENTRY
void retrieve_exten_table(unsigned char *table)
void set_extensible_piece(unsigned piece, unsigned val)
struct label_entry_struct label_entry
@ FALSE
Definition: dd.h:101
@ TRUE
Definition: dd.h:102
#define free(a)
Definition: decNumber.cpp:310
#define special
Definition: devnag.c:330
void build_dimen_tables(void)
void set_character_measure(int index, int val)
#define fflush
Definition: xxstdio.h:24
char * strncpy()
void internal_error_0(const_string fmt)
void warning_0(const_string fmt)
void internal_error_1(const_string fmt, int item)
void fatal_error_1(const_string fmt, int item)
void warning_s_1(const_string fmt, const_string item, int item1)
void warning_1(const_string fmt, int item)
void warning_s_2(const_string fmt, const_string item, int item1, int item2)
void out_ovf(unsigned i)
unsigned char * cur_packet
int ovf_get_arg(unsigned char **ptr, unsigned k, boolean is_signed)
#define c(n)
Definition: gpos-common.c:150
FILE * out
Definition: hbf2gf.c:286
unsigned char out_char[1023 *1023+1]
Definition: hbf2gf.c:373
unsigned check_sum
void calculate_seven_bit_safe_flag(void)
fix design_units
boolean check_sum_specified
boolean seven_bit_calculated
unsigned ofm_level
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific i
Definition: afcover.h:80
for(n=0;n< outline->n_points;n++)
Definition: ftbbox.c:494
void exit()
@ right
Definition: annotate.c:15
#define xmalloc(size)
Definition: writet1.c:33
pdf_obj * entry
Definition: pdfdoc.c:64
const char * const_string
Definition: simpletypes.h:59
#define fprintf
Definition: mendex.h:64
#define DVI_PUSH
Definition: dvicodes.h:50
#define DVI_POP
Definition: dvicodes.h:51
#define DVI_NOP
Definition: dvicodes.h:43
integer zround(double)
Definition: zround.c:8
#define DVI_DOWN_2
Definition: dvi.h:63
#define DVI_RIGHT_1
Definition: dvi.h:48
#define DVI_SET_1
Definition: dvi.h:33
#define DVI_SET_2
Definition: dvi.h:34
#define DVI_W_3
Definition: dvi.h:55
#define DVI_XXX_3
Definition: dvi.h:84
#define DVI_X_4
Definition: dvi.h:61
#define DVI_Y_0
Definition: dvi.h:66
#define DVI_RIGHT_2
Definition: dvi.h:49
#define DVI_SET_3
Definition: dvi.h:35
#define DVI_DOWN_1
Definition: dvi.h:62
#define DVI_DOWN_4
Definition: dvi.h:65
#define DVI_X_2
Definition: dvi.h:59
#define DVI_Z_4
Definition: dvi.h:75
#define DVI_X_3
Definition: dvi.h:60
#define DVI_SET_4
Definition: dvi.h:36
#define DVI_XXX_2
Definition: dvi.h:83
#define DVI_Y_2
Definition: dvi.h:68
#define DVI_DOWN_3
Definition: dvi.h:64
#define DVI_Y_1
Definition: dvi.h:67
#define DVI_W_4
Definition: dvi.h:56
#define DVI_Z_2
Definition: dvi.h:73
#define DVI_X_1
Definition: dvi.h:58
#define DVI_FNT_4
Definition: dvi.h:81
#define DVI_Y_4
Definition: dvi.h:70
#define DVI_W_0
Definition: dvi.h:52
#define DVI_FNT_NUM_63
Definition: dvi.h:77
#define DVI_PUT_1
Definition: dvi.h:38
#define DVI_W_1
Definition: dvi.h:53
#define DVI_PUT_3
Definition: dvi.h:40
#define DVI_FNT_1
Definition: dvi.h:78
#define DVI_W_2
Definition: dvi.h:54
#define DVI_RIGHT_4
Definition: dvi.h:51
#define DVI_Z_0
Definition: dvi.h:71
#define DVI_X_0
Definition: dvi.h:57
#define DVI_SET_CHAR_127
Definition: dvi.h:32
#define DVI_Z_1
Definition: dvi.h:72
#define DVI_RIGHT_3
Definition: dvi.h:50
#define DVI_SET_RULE
Definition: dvi.h:37
#define DVI_PUT_2
Definition: dvi.h:39
#define DVI_PUT_RULE
Definition: dvi.h:42
#define DVI_XXX_1
Definition: dvi.h:82
#define DVI_Z_3
Definition: dvi.h:74
#define DVI_XXX_4
Definition: dvi.h:85
#define DVI_PUT_4
Definition: dvi.h:41
#define DVI_FNT_NUM_0
Definition: dvi.h:76
#define DVI_FNT_3
Definition: dvi.h:80
#define DVI_Y_3
Definition: dvi.h:69
#define DVI_FNT_2
Definition: dvi.h:79
void build_kern_table(void)
void check_ligature_infinite_loops(void)
four_entries * lig_kern_table
void doublecheck_ligatures(void)
unsigned bchar_label
void check_ligature_ends_properly(void)
unsigned char * activity
unsigned bchar
void print_one_lig_kern_entry(four_entries *lentry, boolean show_stop)
#define STOP_FLAG
void append_to_queue(queue *q, void *content)
Definition: list_routines.c:81
#define lval(L)
Definition: list_routines.h:69
int fix
Definition: list_routines.h:24
#define OFM_LEVEL0
Definition: manifests.h:283
#define OFM_TFM
Definition: manifests.h:282
#define TAG_NONE
Definition: manifests.h:261
#define CHAR_MINIMUM
Definition: manifests.h:266
#define M_RIGHT
Definition: manifests.h:190
#define TAG_LIG
Definition: manifests.h:262
#define CHAR_BOUNDARY
Definition: manifests.h:268
#define M_DOWN
Definition: manifests.h:193
#define OFM_LEVEL1
Definition: manifests.h:284
#define E_MAX
Definition: manifests.h:65
#define C_MAX
Definition: manifests.h:54
#define TAG_EXT
Definition: manifests.h:264
#define CHAR_MAXIMUM
Definition: manifests.h:267
#define A_ACCESSIBLE
Definition: manifests.h:85
#define ACC_NONE
Definition: manifests.h:181
#define C_WD
Definition: manifests.h:28
#define C_MIN
Definition: manifests.h:26
#define E_MIN
Definition: manifests.h:58
#define TAG_LIST
Definition: manifests.h:263
#define UNITY
Definition: manifests.h:252
#define cmd(arg)
Definition: mitsu.h:44
FILE * file_output
Definition: omfonts.c:69
double ** L1
Definition: opts.c:80
double ** L2
Definition: opts.h:106
int k
Definition: otp-parser.c:70
void out_ofm(unsigned i)
Definition: out_ofm.c:132
void out_ofm_char(unsigned i)
Definition: out_ofm.c:158
void out_ofm_2(unsigned i)
Definition: out_ofm.c:139
void out_ofm_4(unsigned i)
Definition: out_ofm.c:148
void out_ln(void)
Definition: out_routines.c:260
const_string extensible_pieces[]
Definition: out_routines.c:55
void out_int(unsigned val, unsigned base)
Definition: out_routines.c:302
boolean changed
Definition: parse_ofm.c:90
unsigned npc
Definition: parse_ofm.c:67
static void print_map()
Definition: pbmto4425.c:144
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
#define index(s, c)
Definition: plain2.h:351
int g
Definition: ppmqvga.c:68
int r
Definition: ppmqvga.c:68
void print_special_hex(unsigned char *special, int k)
void print_var_character(void)
void print_set_char(unsigned val)
void print_push(void)
void print_special(string sval)
void print_pop(void)
void print_put_rule(fix fval1, fix fval2)
void print_put_char(unsigned val)
void print_set_rule(fix fval1, fix fval2)
void print_move(unsigned direction, fix fval)
void print_select_font(unsigned val)
void print_next_larger(unsigned val)
void print_extensible_piece(unsigned piece, unsigned val)
lft_cell * left
Definition: routines.h:73
RETTYPE mp_ptr mp_size_t mp_srcptr dp
Definition: sec_div.c:70
Definition: dvi2xx.h:373
unsigned int pieces[4]
Definition: list_routines.h:72
Definition: pt1.h:7
Definition: mendex.h:20
Definition: char_routines.h:55
int cc
Definition: char_routines.h:57
int rr
Definition: char_routines.h:56
struct cell_struct * front
Definition: list_routines.h:58
Definition: table.h:30
Definition: xmlparse.c:179
Definition: strexpr.c:21
#define c2
Definition: t1io.c:53
#define c1
Definition: t1io.c:52
int j
Definition: t4ht.c:1589
while(temp)
Definition: t4ht.c:858
char fmt[256]
Definition: tex4ht.c:3925
val
Definition: tex4ht.c:3227
tag int tag
Definition: tex4ht.c:2554