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)  

writettf.c
Go to the documentation of this file.
1 /*
2 
3 Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
4 Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
5 
6 This file is part of LuaTeX.
7 
8 LuaTeX is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2 of the License, or (at your
11 option) any later version.
12 
13 LuaTeX is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 License for more details.
17 
18 You should have received a copy of the GNU General Public License along
19 with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #include "ptexlib.h"
24 #include "font/writettf.h"
25 #include <string.h>
26 
27 #define DEFAULT_NTABS 14
28 #define NEW_CMAP_SIZE 2
29 
30 #define ttf_putchar(A) strbuf_putchar(pdf->fb, (A))
31 #define ttf_offset() strbuf_offset(pdf->fb)
32 #define ttf_seek_outbuf(A) strbuf_seek(pdf->fb, (A))
33 
34 unsigned char *ttf_buffer = NULL;
35 int ttf_size = 0;
36 int ttf_curbyte = 0;
37 
38 typedef struct {
39  /*tex the name of glyph */
40  char *name;
41  /*tex the new index of glyph in output file */
42  long newindex;
43 
44 } ttfenc_entry;
45 
46 typedef struct {
47  TTF_USHORT platform_id;
48  TTF_USHORT encoding_id;
49  TTF_USHORT language_id;
50  TTF_USHORT name_id;
53  TTF_USHORT new_offset;
54  TTF_USHORT new_length;
55 } name_record;
56 
57 typedef struct {
58  char *ttf_name;
61  long *table;
63 
73 
76 
77 static long *glyph_index;
80 static int name_record_num;
81 static char *name_buf;
82 static int name_buf_size;
83 static char *glyph_name_buf;
90 
91 /*tex A pointer to the current font descriptor: */
92 
94 
95 static struct avl_table *ttf_cmap_tree = NULL;
96 
98 
99 char notdef[] = ".notdef";
100 
101 const char *mac_glyph_names[] = {
102  /* 0x00 */
103  notdef, ".null", "CR", "space", "exclam", "quotedbl", "numbersign", "dollar",
104  "percent", "ampersand", "quotesingle", "parenleft", "parenright", "asterisk",
105  "plus", "comma",
106  /* 0x10 */
107  "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five",
108  "six", "seven", "eight", "nine", "colon", "semicolon", "less",
109  /* 0x20 */
110  "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H",
111  "I", "J", "K", "L",
112  /* 0x30 */
113  "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
114  "bracketleft", "backslash",
115  /* 0x40 */
116  "bracketright", "asciicircum", "underscore", "grave", "a", "b", "c", "d",
117  "e", "f", "g", "h", "i", "j", "k", "l",
118  /* 0x50 */
119  "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
120  "braceleft", "bar",
121  /* 0x60 */
122  "braceright", "asciitilde", "Adieresis", "Aring", "Ccedilla", "Eacute",
123  "Ntilde", "Odieresis", "Udieresis", "aacute", "agrave", "acircumflex",
124  "adieresis", "atilde", "aring", "ccedilla",
125  /* 0x70 */
126  "eacute", "egrave", "ecircumflex", "edieresis", "iacute", "igrave",
127  "icircumflex", "idieresis", "ntilde", "oacute", "ograve", "ocircumflex",
128  "odieresis", "otilde", "uacute", "ugrave",
129  /* 0x80 */
130  "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling",
131  "section", "bullet", "paragraph", "germandbls", "registered", "copyright",
132  "trademark", "acute", "dieresis", "notequal",
133  /* 0x90 */
134  "AE", "Oslash", "infinity", "plusminus", "lessequal", "greaterequal", "yen",
135  "mu", "partialdiff", "Sigma", "Pi", "pi", "integral", "ordfeminine",
136  "ordmasculine", "Omega",
137  /* 0xa0 */
138  "ae", "oslash", "questiondown", "exclamdown", "logicalnot", "radical",
139  "florin", "approxequal", "Delta", "guillemotleft", "guillemotright",
140  "ellipsis", "nbspace", "Agrave", "Atilde", "Otilde",
141  /* 0xb0 */
142  "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright", "quoteleft",
143  "quoteright", "divide", "lozenge", "ydieresis", "Ydieresis", "fraction",
144  "currency", "guilsinglleft", "guilsinglright",
145  /* 0xc0 */
146  "fi", "fl", "daggerdbl", "periodcentered", "quotesinglbase", "quotedblbase",
147  "perthousand", "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", "Egrave",
148  "Iacute", "Icircumflex", "Idieresis", "Igrave",
149  /* 0xd0 */
150  "Oacute", "Ocircumflex", "applelogo", "Ograve", "Uacute", "Ucircumflex",
151  "Ugrave", "dotlessi", "circumflex", "tilde", "macron", "breve", "dotaccent",
152  "ring", "cedilla", "hungarumlaut",
153  /* 0xe0 */
154  "ogonek", "caron", "Lslash", "lslash", "Scaron", "scaron", "Zcaron",
155  "zcaron", "brokenbar", "Eth", "eth", "Yacute", "yacute", "Thorn", "thorn",
156  "minus",
157  /* 0xf0 */
158  "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf",
159  "onequarter", "threequarters", "franc", "Gbreve", "gbreve", "Idot",
160  "Scedilla", "scedilla", "Cacute", "cacute", "Ccaron",
161  /* 0x100 */
162  "ccaron", "dmacron"
163 };
164 
165 const char *ambiguous_names[] = {
166  "Delta", /* increment */
167  "Omega", /* Ohm */
168  "Pi", /* product */
169  "Sigma", /* summation */
170  "dmacron", /* dslash */
171  "macron", /* overscore */
172  "periodcentered", /* middot */
173  NULL
174 };
175 
176 static const char *newtabnames[] = {
177  "OS/2",
178  "PCLT",
179  "cmap",
180  "cvt ",
181  "fpgm",
182  "glyf",
183  "head",
184  "hhea",
185  "hmtx",
186  "loca",
187  "maxp",
188  "name",
189  "post",
190  "prep"
191 };
192 
193 /* Back to code. Low-level helpers first. */
194 
196 {
197  ttf_cmap_entry *e;
198  e = xtalloc(1, ttf_cmap_entry);
199  e->ttf_name = NULL;
200  e->table = NULL;
201  return e;
202 }
203 
204 static void destroy_ttf_cmap_entry(void *pa, void *pb)
205 {
206  ttf_cmap_entry *p;
207  (void) pb;
208  p = (ttf_cmap_entry *) pa;
209  xfree(p->ttf_name);
210  xfree(p->table);
211  xfree(p);
212 }
213 
214 void ttf_free(void)
215 {
216  if (ttf_cmap_tree != NULL)
218 }
219 
220 static int comp_ttf_cmap_entry(const void *pa, const void *pb, void *p)
221 {
222  const ttf_cmap_entry *p1 = (const ttf_cmap_entry *) pa,
223  *p2 = (const ttf_cmap_entry *) pb;
224  int i;
225  (void) p;
226  if ((i = strcmp(p1->ttf_name, p2->ttf_name)) != 0)
227  return i;
228  cmp_return(p1->pid, p2->pid);
229  cmp_return(p1->eid, p2->eid);
230  return 0;
231 }
232 
233 static unsigned char ttf_addchksm(unsigned char b)
234 {
235  tmp_ulong = (tmp_ulong << 8) + b;
236  tab_length++;
237  if (tab_length % 4 == 0) {
238  checksum += tmp_ulong;
239  tmp_ulong = 0;
240  }
241  return b;
242 }
243 
245 {
246  while (tab_length % 4 != 0) {
247  /*tex |ttf_addchksm| updates |tab_length| */
249  }
250  return checksum;
251 }
252 
253 long ttf_putnum(PDF pdf, int s, long n)
254 {
255  long i = n;
256  char buf[TTF_LONG_SIZE + 1], *p = buf;
257  while (s-- > 0) {
258  *p++ = (char) (i & 0xFF);
259  i >>= 8;
260  }
261  p--;
262  while (p >= buf)
263  ttf_putchar(ttf_addchksm((unsigned char) (*p--)));
264  return n;
265 }
266 
267 long ttf_getnum(int s)
268 {
269  long i = 0;
270  int c;
271  while (s > 0) {
272  if (ttf_eof())
273  normal_error("ttf font","unexpected EOF");
274  c = ttf_getchar();
275  i = (i << 8) + c;
276  s--;
277  }
278  return i;
279 }
280 
281 static long ttf_funit(long n)
282 {
283  if (n < 0)
284  return -((-n / upem) * 1000 + ((-n % upem) * 1000) / upem);
285  else
286  return (n / upem) * 1000 + ((n % upem) * 1000) / upem;
287 }
288 
289 static void ttf_ncopy(PDF pdf, int n)
290 {
291  while (n-- > 0)
292  copy_byte();
293 }
294 
295 dirtab_entry *ttf_name_lookup(const char *s, boolean required)
296 {
297  dirtab_entry *tab;
298  for (tab = dir_tab; tab - dir_tab < ntabs; tab++) {
299  if (strncmp(tab->tag, s, 4) == 0)
300  break;
301  }
302  if (tab - dir_tab == ntabs) {
303  if (required)
304  formatted_error("ttf font","can't find table '%s'", s);
305  else
306  tab = NULL;
307  }
308  return tab;
309 }
310 
312 {
314  ttf_curbyte = (int) (tab->offset + (unsigned long) offset);
315  return tab;
316 }
317 
319 {
320  ttf_curbyte = (int) offset;
321 }
322 
323 static void ttf_copy_encoding(void)
324 {
325  int i, *q;
326  void **aa;
327  char **glyph_names;
328  struct avl_traverser t;
329  if (fd_cur->fe != NULL) {
330  glyph_names = fd_cur->fe->glyph_names;
331  for (i = 0; i < 256; i++)
332  ttfenc_tab[i].name = (char *) notdef;
333  /*tex This is a workaround for a bug of AcroReader 4.0: */
334  if (strcmp(glyph_names[97], "a") == 0) {
335  q = xtalloc(1, int);
336  *q = 'a';
337  aa = avl_probe(fd_cur->tx_tree, q);
338  if (aa == NULL) {
339  /*tex Is this a problem? */
340  }
341  }
342  /*tex Take over collected characters from \TeX, reencode them. */
344  for (q = (int *) avl_t_first(&t, fd_cur->tx_tree); q != NULL; q = (int *) avl_t_next(&t)) {
345  ttfenc_tab[*q].name = glyph_names[*q];
346  }
348  }
349 }
350 
351 #define ttf_append_byte(B) do { \
352  if (name_tab[i].platform_id == 3) { \
353  *q++ = 0; \
354  } \
355  *q++ = B; \
356 } while (0)
357 
358 static char *strip_spaces_and_delims(char *s, int l)
359 {
360  static char buf[SMALL_BUF_SIZE];
361  char *p = buf;
362  int i;
363  for (i = 0; i < l; s++, i++) {
364  if (*s == '(' || *s == ')' || *s == '<' || *s == '>' ||
365  *s == '[' || *s == ']' || *s == '{' || *s == '}' ||
366  *s == '/' || *s == '%' || isspace((unsigned char)*s))
367  continue;
368  *p++ = *s;
369  }
370  *p = 0;
371  return buf;
372 }
373 
374 static void ttf_read_name(void)
375 {
376  int i, j;
378  char *p, buf[SMALL_BUF_SIZE];
381  name_buf_size = (int) ((unsigned) tab->length - (3 * TTF_USHORT_SIZE + (TTF_ULONG) name_record_num * 6 * TTF_USHORT_SIZE));
382  name_buf = xtalloc((unsigned) name_buf_size, char);
384  for (i = 0; i < name_record_num; i++) {
391  }
392  for (p = name_buf; p - name_buf < name_buf_size; p++)
393  *p = get_char();
394  /*tex Look for the \POSTSCRIPT\ font name. */
395  for (i = 0; i < name_record_num; i++) {
396  if (name_tab[i].platform_id == 1 &&
397  name_tab[i].encoding_id == 0 && name_tab[i].name_id == 6) {
400  fd_cur->font_dim[FONTNAME_CODE].set = true;
401  break;
402  }
403  }
404  if (!fd_cur->font_dim[FONTNAME_CODE].set) {
405  for (i = 0; i < name_record_num; i++) {
406  if (name_tab[i].platform_id == 3 &&
407  (name_tab[i].encoding_id == 0 || name_tab[i].encoding_id == 1)
408  && name_tab[i].name_id == 6) {
410  assert(name_tab[i].length < sizeof(buf));
411  for (j = 0, p = buf; j < name_tab[i].length; j += 2)
412  *p++ = name_buf[name_tab[i].offset + j + 1];
413  *p = 0;
415  fd_cur->font_dim[FONTNAME_CODE].set = true;
416  break;
417  }
418  }
419  }
420 }
421 
422 static void ttf_read_mapx(void)
423 {
425  ttf_seek_tab("maxp", TTF_FIXED_SIZE);
426  glyph_tab = xtalloc((unsigned) (1 + (glyphs_count = get_ushort())), glyph_entry);
427  for (glyph = glyph_tab; glyph - glyph_tab < glyphs_count; glyph++) {
428  glyph->newindex = -1;
429  glyph->newoffset = 0;
430  glyph->name_index = 0;
431  glyph->name = (char *) notdef;
432  }
433  glyph_index = xtalloc((unsigned) (glyphs_count + 1), long);
434  /*tex index of the |.notdef| glyph */
435  glyph_index[0] = 0;
436  /*tex index of the |.null| glyph */
437  glyph_index[1] = 1;
438 }
439 
440 void ttf_read_head(void)
441 {
443  upem = get_ushort();
444  ttf_skip(16);
455 }
456 
457 void ttf_read_hhea(void)
458 {
459  ttf_seek_tab("hhea", TTF_FIXED_SIZE);
462  fd_cur->font_dim[ASCENT_CODE].set = true;
463  fd_cur->font_dim[DESCENT_CODE].set = true;
465  nhmtxs = get_ushort();
466 }
467 
468 void ttf_read_pclt(void)
469 {
470  if (ttf_name_lookup("PCLT", false) == NULL)
471  return;
476  fd_cur->font_dim[XHEIGHT_CODE].set = true;
478 }
479 
480 static void ttf_read_hmtx(void)
481 {
483  TTF_UFWORD last_advWidth;
484  ttf_seek_tab("hmtx", 0);
485  for (glyph = glyph_tab; glyph - glyph_tab < nhmtxs; glyph++) {
486  glyph->advWidth = get_ufword();
487  glyph->lsb = (TTF_FWORD) get_ufword();
488  }
489  if (nhmtxs < glyphs_count) {
490  last_advWidth = glyph[-1].advWidth;
491  for (; glyph - glyph_tab < glyphs_count; glyph++) {
492  glyph->advWidth = last_advWidth;
493  glyph->lsb = (TTF_FWORD) get_ufword();
494  }
495  }
496 }
497 
498 void ttf_read_post(void)
499 {
500  int k, nnames;
501  long length;
502  long int_part, frac_part;
503  int sign = 1;
505  char *p;
507  const dirtab_entry *tab = ttf_seek_tab("post", 0);
510  int_part = (long) (italic_angle >> 16);
511  if (int_part > 0x7FFF) {
512  /*tex a negative number */
513  int_part = 0x10000 - int_part;
514  sign = -1;
515  }
516  frac_part = (long) (italic_angle % 0x10000);
517  fd_cur->font_dim[ITALIC_ANGLE_CODE].val = (int) (sign * ((double) int_part + (double) frac_part * 1.0 / 0x10000));
519  if (glyph_tab == NULL) {
520  /*tex We were being called from |writeotf|. */
521  return;
522  }
524  switch (post_format) {
525  case 0x10000:
526  for (glyph = glyph_tab; glyph - glyph_tab < NMACGLYPHS; glyph++) {
527  glyph->name = (const char *) mac_glyph_names[glyph - glyph_tab];
528  glyph->name_index = (TTF_USHORT) (glyph - glyph_tab);
529  }
530  break;
531  case 0x20000:
532  /*tex Some fonts have this value different from |nglyphs|: */
533  nnames = get_ushort();
534  for (glyph = glyph_tab; glyph - glyph_tab < nnames; glyph++) {
535  glyph->name_index = get_ushort();
536  }
537  length = (long) ((long) tab->length - (long) ((long) ttf_curbyte - (long) tab->offset));
538  glyph_name_buf = xtalloc((unsigned) length, char);
539  for (p = glyph_name_buf; p - glyph_name_buf < length;) {
540  for (k = get_byte(); k > 0; k--)
541  *p++ = get_char();
542  *p++ = 0;
543  }
544  for (glyph = glyph_tab; glyph - glyph_tab < nnames; glyph++) {
545  if (glyph->name_index < NMACGLYPHS)
546  glyph->name = mac_glyph_names[glyph->name_index];
547  else {
548  p = glyph_name_buf;
549  k = glyph->name_index - NMACGLYPHS;
550  for (; k > 0; k--)
551  p = strend(p) + 1;
552  glyph->name = p;
553  }
554  }
555  break;
556  default:
557  formatted_warning("ttf font", "unsupported format '%.8X' of 'post' table, assuming 3.0", (unsigned int) post_format);
558  case 0x00030000:
559  for (glyph = glyph_tab; glyph - glyph_tab < NMACGLYPHS; glyph++) {
560  glyph->name_index = (TTF_USHORT) (glyph - glyph_tab);
561  }
562  }
563 }
564 
565 static void ttf_read_loca(void)
566 {
568  ttf_seek_tab("loca", 0);
569  if (loca_format != 0)
570  for (glyph = glyph_tab; glyph - glyph_tab < glyphs_count + 1; glyph++)
571  glyph->offset = (TTF_LONG) get_ulong();
572  else
573  for (glyph = glyph_tab; glyph - glyph_tab < glyphs_count + 1; glyph++)
574  glyph->offset = get_ushort() << 1;
575 }
576 
578 {
579  unsigned long i, num, rem=0;
580  dirtab_entry *tab;
581  /*tex Ignore the tag |ttcf|. */
583  /*tex Ignore the version number. */
585  num = get_ulong();
586  for (i = 0; i < num; i++) {
587  if (i==index) rem = get_ulong(); else ttf_skip(TTF_ULONG_SIZE);
588  }
590  /*tex Ignore the |sfnt| number. */
594  for (tab = dir_tab; tab - dir_tab < ntabs; tab++) {
595  for (i = 0; i < 4; i++)
596  tab->tag[i] = get_char();
597  tab->checksum = get_ulong();
598  tab->offset = get_ulong();
599  tab->length = get_ulong();
600  }
601 }
602 
603 void ttf_read_tabdir(void)
604 {
605  int i;
606  dirtab_entry *tab;
607  /*tex Ignore the |sfnt| number. */
611  for (tab = dir_tab; tab - dir_tab < ntabs; tab++) {
612  for (i = 0; i < 4; i++)
613  tab->tag[i] = get_char();
614  tab->checksum = get_ulong();
615  tab->offset = get_ulong();
616  tab->length = get_ulong();
617  }
618 }
619 
620 static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid, boolean warn)
621 {
622  seg_entry *seg_tab, *s;
623  TTF_USHORT *glyphId, format, segCount;
624  TTF_USHORT ncmapsubtabs, tmp_pid, tmp_eid;
625  TTF_ULONG cmap_offset, tmp_offset;
626  long n, i, k, length, index;
627  ttf_cmap_entry tmp_e, *p;
628  void **aa;
629  /*tex Look up in |ttf_cmap_tree| first, return if found. */
630  tmp_e.ttf_name = ttf_name;
631  tmp_e.pid = (TTF_USHORT) pid;
632  tmp_e.eid = (TTF_USHORT) eid;
633  if (ttf_cmap_tree == NULL) {
636  }
637  p = (ttf_cmap_entry *) avl_find(ttf_cmap_tree, &tmp_e);
638  if (p != NULL)
639  return p;
640  /*tex It's not found so we have to read it. We skip the table version number (0). */
641  ttf_seek_tab("cmap", TTF_USHORT_SIZE);
645  for (i = 0; i < ncmapsubtabs; ++i) {
646  tmp_pid = get_ushort();
647  tmp_eid = get_ushort();
648  tmp_offset = get_ulong();
649  if (tmp_pid == pid && tmp_eid == eid) {
650  ttf_seek_off((TTF_LONG) (cmap_offset + tmp_offset));
651  format = get_ushort();
652  if (format == 4)
653  goto read_cmap_format_4;
654  else {
655  if (warn) {
656  formatted_warning("ttf font", "cmap format %i unsupported", format);
657  }
658  return NULL;
659  }
660  }
661  }
662  if (warn) {
663  formatted_warning("ttf font", "cannot find cmap subtable for (pid,eid) = (%i,%i)", pid, eid);
664  }
665  return NULL;
666  /*tex We jump here: */
667  read_cmap_format_4:
668  /*tex Initialize the new entry. */
669  p = new_ttf_cmap_entry();
670  p->ttf_name = xstrdup(ttf_name);
671  p->pid = (TTF_USHORT) pid;
672  p->eid = (TTF_USHORT) eid;
673  p->table = xtalloc(0x10000, long);
674  for (i = 0; i < 0x10000; ++i) {
675  /*tex Yet unassigned: */
676  p->table[i] = -1;
677  }
678  /*tex Read the subtable. */
679  /*tex length of subtable */
680  length = get_ushort();
681  /*tex skip the version number */
682  (void) get_ushort();
683  segCount = get_ushort() / 2;
684  /*tex skip searchRange */
685  (void) get_ushort();
686  /*tex skip entrySelector */
687  (void) get_ushort();
688  /*tex skip rangeShift */
689  (void) get_ushort();
690  seg_tab = xtalloc(segCount, seg_entry);
691  for (s = seg_tab; s - seg_tab < segCount; s++)
692  s->endCode = get_ushort();
693  /*tex skip reversedPad */
694  (void) get_ushort();
695  for (s = seg_tab; s - seg_tab < segCount; s++)
696  s->startCode = get_ushort();
697  for (s = seg_tab; s - seg_tab < segCount; s++)
698  s->idDelta = get_ushort();
699  for (s = seg_tab; s - seg_tab < segCount; s++)
700  s->idRangeOffset = get_ushort();
701  length -= 8 * TTF_USHORT_SIZE + 4 * segCount * TTF_USHORT_SIZE;
702  /*tex number of glyphID's */
704  glyphId = xtalloc((unsigned) n, TTF_USHORT);
705  for (i = 0; i < n; i++)
706  glyphId[i] = get_ushort();
707  for (s = seg_tab; s - seg_tab < segCount; s++) {
708  for (i = s->startCode; i <= s->endCode; i++) {
709  if (i == 0xFFFF)
710  break;
711  if (s->idRangeOffset != 0xFFFF) {
712  if (s->idRangeOffset == 0)
713  index = (s->idDelta + i) & 0xFFFF;
714  else {
715  k = (i - s->startCode) + s->idRangeOffset / 2 + (s - seg_tab) - segCount;
716  index = glyphId[k];
717  if (index != 0)
718  index = (index + s->idDelta) & 0xFFFF;
719  }
720  if (index >= glyphs_count)
721  formatted_error("ttf font",
722  "cmap issue, glyph index %li out of range [0..%i)",
724  if (p->table[i] != -1)
725  formatted_warning("ttf font",
726  "cmap issue, multiple glyphs are mapped to unicode %.4lX, %li will be used, %li is ignored)",
727  i, p->table[i], index);
728  else
729  p->table[i] = index;
730  }
731  }
732  }
733  xfree(seg_tab);
734  xfree(glyphId);
735  aa = avl_probe(ttf_cmap_tree, p);
736  if (aa == NULL) {
737  /*tex Is this a problem? */
738  }
739  return p;
740 }
741 
742 static void ttf_read_font(void)
743 {
744  ttf_read_tabdir();
745  if (ttf_name_lookup("PCLT", false) == NULL)
746  new_ntabs--;
747  if (ttf_name_lookup("fpgm", false) == NULL)
748  new_ntabs--;
749  if (ttf_name_lookup("cvt ", false) == NULL)
750  new_ntabs--;
751  if (ttf_name_lookup("prep", false) == NULL)
752  new_ntabs--;
753  ttf_read_mapx();
754  ttf_read_head();
755  ttf_read_hhea();
756  ttf_read_pclt();
757  ttf_read_hmtx();
758  ttf_read_post();
759  ttf_read_loca();
760  ttf_read_name();
761 }
762 
764 {
765  checksum = 0;
766  tab_length = 0;
767  tmp_ulong = 0;
768  tab->offset = (TTF_ULONG) ttf_offset();
769  if (tab->offset % 4 != 0)
770  formatted_warning("ttf font","offset of `%4.4s' is not a multiple of 4", tab->tag);
771 }
772 
774 {
775  tab->length = (TTF_ULONG) ttf_offset() - tab->offset;
776  tab->checksum = ttf_getchksm(pdf);
777 }
778 
779 static void ttf_copytab(PDF pdf, const char *name)
780 {
781  long i;
784  for (i = (long) tab->length; i > 0; i--)
785  copy_char();
787 }
788 
789 #define BYTE_ENCODING_LENGTH ((256)*TTF_BYTE_SIZE + 3*TTF_USHORT_SIZE)
790 
792 {
793  ttfenc_entry *e;
794  /*tex Format number (0: byte encoding table) */
795  (void) put_ushort(0);
796  /*tex The length of the table */
798  /*tex The version number */
799  (void) put_ushort(0);
800  for (e = ttfenc_tab; e - ttfenc_tab < 256; e++)
801  if (e->newindex < 256) {
802  put_byte(e->newindex);
803  } else {
804  if (e->name != notdef)
805  formatted_warning("ttf font",
806  "glyph '%s' has been mapped to '%s' in 'ttf_byte_encoding' cmap table",
807  e->name, notdef);
808  /*tex |.notdef|: */
809  put_byte(0);
810  }
811 }
812 
813 #define TRIMMED_TABLE_MAP_LENGTH (TTF_USHORT_SIZE*(5 + (256)))
814 
816 {
817  ttfenc_entry *e;
818  /*tex format number 6: trimmed table mapping */
819  (void) put_ushort(6);
821  /*tex version number 0 */
822  (void) put_ushort(0);
823  /*tex first character code */
824  (void) put_ushort(0);
825  /*tex number of character code in table: */
826  (void) put_ushort(256);
827  for (e = ttfenc_tab; e - ttfenc_tab < 256; e++) {
828  (void) put_ushort(e->newindex);
829  }
830 }
831 
832 #define SEG_MAP_DELTA_LENGTH ((16 + (256))*TTF_USHORT_SIZE)
833 
835 {
836  ttfenc_entry *e;
837  /*tex format number (4: segment mapping to delta values) */
838  (void) put_ushort(4);
840  /*tex version number */
841  (void) put_ushort(0);
842  /*tex 2*segCount */
843  (void) put_ushort(4);
844  /*tex searchRange */
845  (void) put_ushort(4);
846  /*tex entrySelector */
847  (void) put_ushort(1);
848  /*tex rangeShift */
849  (void) put_ushort(0);
850  /*tex endCount[0] */
851  (void) put_ushort(0xF0FF);
852  /*tex endCount[1] */
853  (void) put_ushort(0xFFFF);
854  /*tex reversedPad */
855  (void) put_ushort(0);
856  /*tex startCount[0] */
857  (void) put_ushort(0xF000);
858  /*tex startCount[1] */
859  (void) put_ushort(0xFFFF);
860  /*tex idDelta[0] */
861  (void) put_ushort(0);
862  /*tex idDelta[1] */
863  (void) put_ushort(1);
864  /*tex idRangeOffset[0] */
866  /*tex idRangeOffset[1] */
867  (void) put_ushort(0);
868  for (e = ttfenc_tab; e - ttfenc_tab < 256; e++) {
869  (void) put_ushort(e->newindex);
870  }
871 }
872 
873 #define CMAP_ENTRY_LENGTH (2*TTF_USHORT_SIZE + TTF_ULONG_SIZE)
874 
875 static void ttf_select_cmap(void)
876 {
877  /*tex Macintosh */
878  new_cmap_tab[0].platform_id = 1;
879  /*tex Symbol; ignore code page */
880  new_cmap_tab[0].encoding_id = 0;
881  /*tex byte encoding (0) or trimmed table mapping (6) */
882  new_cmap_tab[0].format = (TTF_USHORT) (new_glyphs_count < 256 ? 0 : 6);
883  /*tex Microsoft */
884  new_cmap_tab[1].platform_id = 3;
885  /*tex Symbol; ignore code page */
886  new_cmap_tab[1].encoding_id = 0;
887  /*tex segment mapping to delta */
888  new_cmap_tab[1].format = 4;
889 }
890 
891 static void ttf_write_cmap(PDF pdf)
892 {
893  cmap_entry *ce;
894  long offset;
895  dirtab_entry *tab = ttf_name_lookup("cmap", true);
896  ttf_select_cmap();
898  /*tex Table version number 0. */
899  (void) put_ushort(0);
900  /*tex Number of encoding tables. */
903  for (ce = new_cmap_tab; ce - new_cmap_tab < NEW_CMAP_SIZE; ce++) {
904  ce->offset = (TTF_ULONG) offset;
905  switch (ce->format) {
906  case 0:
908  break;
909  case 4:
911  break;
912  case 6:
914  break;
915  default:
916  normal_error("ttf font","invalid format (it should not have happened)");
917  }
918  (void) put_ushort(ce->platform_id);
919  (void) put_ushort(ce->encoding_id);
920  put_ulong((long) ce->offset);
921  }
922  for (ce = new_cmap_tab; ce - new_cmap_tab < NEW_CMAP_SIZE; ce++) {
923  switch (ce->format) {
924  case 0:
926  break;
927  case 4:
929  break;
930  case 6:
932  break;
933  }
934  }
936 }
937 
938 static int prepend_subset_tags(int index, char *p)
939 {
940  boolean is_unicode;
941  int i;
943  if (is_unicode) {
944  for (i = 0; i < 6; ++i) {
945  *p++ = 0;
946  *p++ = fd_cur->subset_tag[i];
947  }
948  *p++ = 0;
949  *p++ = '+';
950  return 14;
951  } else {
952  strncpy(p, fd_cur->subset_tag, 6);
953  p += 6;
954  *p++ = '+';
955  return 7;
956  }
957 }
958 
959 
960 static void ttf_write_name(PDF pdf)
961 {
962  int i, l;
963  char *p;
964  int new_name_buf_size;
965  char *new_name_buf;
966  name_record *n;
967  dirtab_entry *tab = ttf_name_lookup("name", true);
968  if (is_subsetted(fd_cur->fm)) {
969  l = 0;
970  for (i = 0; i < name_record_num; i++) {
971  /*tex Maximum lengh of new stogare area. */
972  l += name_tab[i].length + 14;
973  }
974  new_name_buf = xtalloc((unsigned) l, char);
975  /*tex Additional space for subset tags. */
976  p = new_name_buf;
977  for (i = 0; i < name_record_num; i++) {
978  n = name_tab + i;
979  n->new_offset = (TTF_USHORT) (p - new_name_buf);
980  if ((n->name_id == 1 || n->name_id == 3 ||
981  n->name_id == 4 || n->name_id == 6) &&
982  ((n->platform_id == 1 && n->encoding_id == 0) ||
983  (n->platform_id == 3 && n->encoding_id == 0) ||
984  (n->platform_id == 3 && n->encoding_id == 1))) {
985  l = prepend_subset_tags(i, p);
986  p += l;
987  } else
988  l = 0;
989  memcpy(p, name_buf + n->offset, n->length);
990  p += n->length;
991  n->new_length = (TTF_USHORT) (n->length + l);
992  }
993  new_name_buf_size = (int) (p - new_name_buf);
994  } else {
995  new_name_buf = name_buf;
996  new_name_buf_size = name_buf_size;
997  }
999  (void) put_ushort(0);
1000  /*tex Format selector. */
1003  for (i = 0; i < name_record_num; i++) {
1004  (void) put_ushort(name_tab[i].platform_id);
1005  (void) put_ushort(name_tab[i].encoding_id);
1006  (void) put_ushort(name_tab[i].language_id);
1007  (void) put_ushort(name_tab[i].name_id);
1008  (void) put_ushort(name_tab[i].new_length);
1009  (void) put_ushort(name_tab[i].new_offset);
1010  }
1011  for (p = new_name_buf; p - new_name_buf < new_name_buf_size; p++)
1012  put_char(*p);
1013  ttf_set_chksm(pdf, tab);
1014  if (new_name_buf != name_buf)
1015  xfree(new_name_buf);
1016 }
1017 
1019 {
1020  dirtab_entry *tab;
1021  TTF_ULONG i, k;
1022  char *p;
1023  const int save_offset = ttf_offset();
1025  if (is_subsetted(fd_cur->fm)) {
1026  for (i = 0; i < DEFAULT_NTABS; i++) {
1027  tab = ttf_name_lookup(newtabnames[i], false);
1028  if (tab == NULL)
1029  continue;
1030  for (k = 0; k < 4; k++)
1031  put_char(tab->tag[k]);
1032  put_ulong((long) tab->checksum);
1033  put_ulong((long) tab->offset);
1034  put_ulong((long) tab->length);
1035  }
1036  } else {
1037  for (tab = dir_tab; tab - dir_tab < ntabs; tab++) {
1038  for (k = 0; k < 4; k++)
1039  put_char(tab->tag[k]);
1040  put_ulong((long) tab->checksum);
1041  put_ulong((long) tab->offset);
1042  put_ulong((long) tab->length);
1043  }
1044  }
1045  /*tex adjust |checkSumAdjustment| */
1046  tmp_ulong = 0;
1047  checksum = 0;
1048  for (p = (char *) pdf->fb->data, i = 0; i < (unsigned) save_offset;) {
1049  tmp_ulong = (tmp_ulong << 8) + (TTF_ULONG) * p++;
1050  i++;
1051  if (i % 4 == 0) {
1052  checksum += tmp_ulong;
1053  tmp_ulong = 0;
1054  }
1055  }
1056  if (i % 4 != 0) {
1057  formatted_warning("ttf font","font length '%li' is not a multiple of 4", i);
1058  checksum <<= 8 * (4 - i % 4);
1059  }
1060  k = 0xB1B0AFBA - checksum;
1062  put_ulong((long) k);
1064 }
1065 
1066 static void ttf_write_glyf(PDF pdf)
1067 {
1068  long *id, k;
1069  TTF_USHORT idx;
1070  TTF_USHORT flags;
1071  dirtab_entry *tab = ttf_name_lookup("glyf", true);
1072  const long glyf_offset = (long) tab->offset;
1073  const long new_glyf_offset = ttf_offset();
1075  for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) {
1076  glyph_tab[*id].newoffset = ttf_offset() - new_glyf_offset;
1077  if (glyph_tab[*id].offset != glyph_tab[*id + 1].offset) {
1078  ttf_seek_off(glyf_offset + glyph_tab[*id].offset);
1079  k = copy_short();
1081  if (k < 0) {
1082  do {
1083  flags = copy_ushort();
1084  idx = get_ushort();
1085  if (glyph_tab[idx].newindex < 0) {
1088  /*tex
1089  Here we change |new_glyphs_count|, which appears in
1090  the condition of the |for| loop.
1091  */
1092  }
1093  (void) put_ushort(glyph_tab[idx].newindex);
1096  else
1098  if (flags & WE_HAVE_A_SCALE)
1100  else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
1102  else if (flags & WE_HAVE_A_TWO_BY_TWO)
1104  } while (flags & MORE_COMPONENTS);
1107  } else
1108  ttf_ncopy(pdf, (int) (glyph_tab[*id + 1].offset - glyph_tab[*id].offset - TTF_USHORT_SIZE - 4 * TTF_FWORD_SIZE));
1109  }
1110  }
1111  last_glyf_offset = (TTF_ULONG) ttf_offset() - (TTF_ULONG) new_glyf_offset;
1112  ttf_set_chksm(pdf, tab);
1113 }
1114 
1115 /*tex
1116 
1117  Reindexing glyphs: we append index of used glyphs to |glyph_index| while
1118  going through |ttfenc_tab|. After appending a new entry to |glyph_index| we
1119  set field |newindex| of corresponding entries in both |glyph_tab| and
1120  |ttfenc_tab| to the newly created index.
1121 
1122 */
1123 
1124 static void ttf_reindex_glyphs(void)
1125 {
1126  ttfenc_entry *e;
1127  glyph_entry *glyph;
1128  int index;
1129  long *t;
1131  boolean cmap_not_found = false;
1132  for (e = ttfenc_tab; e - ttfenc_tab < 256; e++) {
1133  /*tex The index of the |.notdef| glyph */
1134  e->newindex = 0;
1135  /*tex Handle the case of reencoded fonts. */
1136  if (e->name == notdef)
1137  continue;
1138  /*tex Scan form |index123|. */
1139  if (sscanf(e->name, GLYPH_PREFIX_INDEX "%i", &index) == 1) {
1140  if (index >= glyphs_count) {
1141  formatted_warning("ttf font","'%s' out of valid range [0..%i)", e->name, glyphs_count);
1142  continue;
1143  }
1144  glyph = glyph_tab + index;
1145  goto append_new_glyph;
1146  }
1147  /*tex Scan form |uniABCD|. */
1148  if (sscanf(e->name, GLYPH_PREFIX_UNICODE "%X", &index) == 1) {
1149  if (cmap == NULL && !cmap_not_found) {
1150  /*tex Need to read the \UNICODE\ mapping, i.e. |(pid,eid) = (3,1) or (0,3)|. */
1151  cmap = ttf_read_cmap(fd_cur->fm->ff_name, 3, 1, false);
1152  if (cmap == NULL)
1153  cmap = ttf_read_cmap(fd_cur->fm->ff_name, 0, 3, false);
1154  if (cmap == NULL) {
1155  /*tex Once only. */
1156  normal_warning("ttf font", "no unicode mapping found, all 'uniXXXX' names will be ignored");
1157  cmap_not_found = true;
1158  }
1159  }
1160  if (cmap == NULL)
1161  continue;
1162  t = cmap->table;
1163  if (t[index] != -1) {
1164  if (t[index] >= glyphs_count) {
1165  formatted_warning("ttf font", "'%s' is mapped to index %li which is out of valid range [0..%i)",
1166  e->name, t[index], glyphs_count);
1167  continue;
1168  }
1169  glyph = glyph_tab + t[index];
1170  goto append_new_glyph;
1171  } else {
1172  formatted_warning("ttf font","unicode %s%.4X is not mapped to any glyph", GLYPH_PREFIX_UNICODE, index);
1173  continue;
1174  }
1175  }
1176  /*tex Look up by name: */
1178  if (glyph->name != notdef && strcmp(glyph->name, e->name) == 0)
1179  break;
1180  if (!(glyph - glyph_tab < glyphs_count)) {
1181  formatted_warning("ttf font","glyph '%s' not found", e->name);
1182  continue;
1183  }
1184  append_new_glyph:
1185  if (glyph->newindex < 0) {
1187  glyph->newindex = (TTF_SHORT) new_glyphs_count;
1188  new_glyphs_count++;
1189  }
1190  e->newindex = glyph->newindex;
1191  }
1192 }
1193 
1194 /*tex
1195 
1196  To calculate the checkSum for the 'head' table which itself includes the
1197  checkSumAdjustment entry for the entire font, do the following:
1198 
1199  \startitemize
1200  \startitem
1201  Set the checkSumAdjustment to 0.
1202  \stopitem
1203  \startitem
1204  Calculate the checksum for all the tables including the |head| table
1205  and enter that value into the table directory.
1206  \stopitem
1207  \startitem
1208  Calculate the checksum for the entire font.
1209  \stopitem
1210  \startitem
1211  Subtract that value from the hex value B1B0AFBA.
1212  \stopitem
1213  \startitem
1214  Store the result in checkSumAdjustment.
1215  \stopitem
1216  \startitemize
1217 
1218  The checkSum for the 'head table which includes the checkSumAdjustment entry
1219  for the entire font is now incorrect. That is not a problem. Do not change
1220  it. An application attempting to verify that the 'head' table has not changed
1221  should calculate the checkSum for that table by not including the
1222  checkSumAdjustment value, and compare the result with the entry in the table
1223  directory.
1224 
1225  The table directory also includes the offset of the associated tagged table
1226  from the beginning of the font file and the length of that table.
1227 
1228 */
1229 
1230 static void ttf_write_head(PDF pdf)
1231 {
1232  dirtab_entry *tab;
1233  tab = ttf_seek_tab("head", 0);
1237  put_ulong(0);
1238  /*tex skip |checkSumAdjustment| */
1241  if (is_subsetted(fd_cur->fm)) {
1243  (void) put_short(0);
1244  } else
1246  ttf_set_chksm(pdf, tab);
1247 }
1248 
1249 static void ttf_write_hhea(PDF pdf)
1250 {
1251  dirtab_entry *tab;
1252  tab = ttf_seek_tab("hhea", 0);
1256  ttf_set_chksm(pdf, tab);
1257 }
1258 
1259 static void ttf_write_htmx(PDF pdf)
1260 {
1261  long *id;
1262  dirtab_entry *tab = ttf_seek_tab("hmtx", 0);
1264  for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) {
1265  put_ufword(glyph_tab[*id].advWidth);
1266  put_ufword(glyph_tab[*id].lsb);
1267  }
1268  ttf_set_chksm(pdf, tab);
1269 }
1270 
1271 static void ttf_write_loca(PDF pdf)
1272 {
1273  long *id;
1274  dirtab_entry *tab = ttf_seek_tab("loca", 0);
1276  loca_format = 0;
1277  if (last_glyf_offset >= 0x00020000 || (last_glyf_offset & 1))
1278  loca_format = 1;
1279  else
1280  for (id = glyph_index; id - glyph_index < new_glyphs_count; id++)
1281  if (glyph_tab[*id].newoffset & 1) {
1282  loca_format = 1;
1283  break;
1284  }
1285  if (loca_format != 0) {
1286  for (id = glyph_index; id - glyph_index < new_glyphs_count; id++)
1287  put_ulong(glyph_tab[*id].newoffset);
1288  put_ulong((long) last_glyf_offset);
1289  } else {
1290  for (id = glyph_index; id - glyph_index < new_glyphs_count; id++)
1291  (void) put_ushort(glyph_tab[*id].newoffset / 2);
1292  (void) put_ushort((long) (last_glyf_offset / 2));
1293  }
1294  ttf_set_chksm(pdf, tab);
1295 }
1296 
1297 static void ttf_write_mapx(PDF pdf)
1298 {
1301  put_fixed(0x00010000);
1303  ttf_ncopy(pdf, 13 * TTF_USHORT_SIZE);
1304  ttf_set_chksm(pdf, tab);
1305 }
1306 
1307 static void ttf_write_OS2(PDF pdf)
1308 {
1309  dirtab_entry *tab = ttf_seek_tab("OS/2", 0);
1312  version = get_ushort();
1313  if (version > 3) {
1314  formatted_error("ttf font","unknown version '%.4X' of OS/2 table", version);
1315  }
1316  /*tex fix version to 1 */
1317  (void) put_ushort(0x0001);
1319  /*tex |ulUnicodeRange| 1--4 */
1320  ttf_skip(4 * TTF_ULONG_SIZE);
1321  /*tex Basic Latin + Latin-1 Supplement (0x0000--0x00FF) */
1322  put_ulong(0x00000003);
1323  /*tex Private Use (0xE000--0xF8FF) */
1324  put_ulong(0x10000000);
1325  put_ulong(0x00000000);
1326  put_ulong(0x00000000);
1327  /*tex |achVendID| + |fsSelection| */
1330  /*tex |usFirstCharIndex| */
1331  (void) put_ushort(0x0000);
1332  /*tex |usLastCharIndex| */
1333  (void) put_ushort(0xF0FF);
1335  /*tex For version 0 the OS/2 table ends here, the rest is for version 1. */
1336  /*tex Symbol Character Set: don't use any code page */
1337  put_ulong(0x80000000);
1338  put_ulong(0x00000000);
1339  ttf_set_chksm(pdf, tab);
1340 }
1341 
1342 static boolean unsafe_name(const char *s)
1343 {
1344  const char **p;
1345  for (p = ambiguous_names; *p != NULL; p++)
1346  if (strcmp(s, *p) == 0)
1347  return true;
1348  return false;
1349 }
1350 
1351 static void ttf_write_post(PDF pdf)
1352 {
1354  glyph_entry *glyph;
1355  const char *s;
1356  long *id;
1357  int k, l;
1359  if (!fd_cur->write_ttf_glyph_names || post_format == 0x00030000) {
1360  put_fixed(0x00030000);
1362  } else {
1363  put_fixed(0x00020000);
1366  k = 0;
1367  for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) {
1368  glyph = glyph_tab + *id;
1369  if (glyph->name_index >= NMACGLYPHS || unsafe_name(glyph->name))
1370  glyph->name_index = (TTF_USHORT) (NMACGLYPHS + k++);
1371  (void) put_ushort(glyph->name_index);
1372  }
1373  for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) {
1374  glyph = glyph_tab + *id;
1375  if (glyph->name_index >= NMACGLYPHS) {
1376  s = glyph->name;
1377  l = (int) strlen(s);
1378  put_byte(l);
1379  while (l-- > 0)
1380  put_char(*s++);
1381  }
1382  }
1383  }
1384  ttf_set_chksm(pdf, tab);
1385 }
1386 
1387 static void ttf_init_font(PDF pdf, int n)
1388 {
1389  int i, k;
1390  for (i = 1, k = 0; i <= n; i <<= 1, k++);
1391  /*tex font version */
1392  put_fixed(0x00010000);
1393  /*tex number of tables */
1394  (void) put_ushort(n);
1395  /*tex search range */
1396  (void) put_ushort(i << 3);
1397  /*tex entry selector */
1398  (void) put_ushort(k - 1);
1399  /*tex range shift */
1400  (void) put_ushort((n << 4) - (i << 3));
1402 }
1403 
1405 {
1407  if (ttf_name_lookup("PCLT", false) != NULL)
1408  ttf_copytab(pdf, "PCLT");
1409  if (ttf_name_lookup("fpgm", false) != NULL)
1410  ttf_copytab(pdf, "fpgm");
1411  if (ttf_name_lookup("cvt ", false) != NULL)
1412  ttf_copytab(pdf, "cvt ");
1413  if (ttf_name_lookup("prep", false) != NULL)
1414  ttf_copytab(pdf, "prep");
1418  ttf_write_OS2(pdf);
1427 }
1428 
1429 static void ttf_copy_font(PDF pdf)
1430 {
1431  dirtab_entry *tab;
1433  for (tab = dir_tab; tab - dir_tab < ntabs; tab++) {
1434  if (strncmp(tab->tag, "head", 4) == 0)
1436  else
1437  ttf_copytab(pdf, tab->tag);
1438  }
1440 }
1441 
1443 {
1444  int callback_id;
1445  int file_opened = 0;
1446  /* The next one is global inside |writettf.c| */
1447  fd_cur = fd;
1448  if (is_subsetted(fd_cur->fm) && (fd_cur->fe == NULL)) {
1449  normal_error("ttf font","subset must be a reencoded font");
1450  }
1451  ttf_curbyte = 0;
1452  ttf_size = 0;
1454  if (cur_file_name == NULL) {
1455  formatted_error("ttf font","cannot find font file for reading '%s'", fd_cur->fm->ff_name);
1456  }
1458  if (callback_id > 0) {
1459  if (run_callback(callback_id, "S->bSd", cur_file_name, &file_opened, &ttf_buffer, &ttf_size) && file_opened && ttf_size > 0) {
1460  /* We're okay. */
1461  } else {
1462  formatted_error("ttf font","cannot open font file for reading '%s'", cur_file_name);
1463  }
1464  } else {
1465  if (!ttf_open(cur_file_name)) {
1466  formatted_error("ttf font","cannot open font file for reading '%s'", cur_file_name);
1467  }
1468  ttf_read_file();
1469  ttf_close();
1470  }
1471  if (tracefilenames) {
1472  if (is_subsetted(fd_cur->fm))
1473  tex_printf("<%s", cur_file_name);
1474  else
1475  tex_printf("<<%s", cur_file_name);
1476  }
1477  fd_cur->ff_found = true;
1478  new_glyphs_count = 2;
1480  dir_tab = NULL;
1481  glyph_tab = NULL;
1482  glyph_index = NULL;
1483  glyph_name_buf = NULL;
1484  name_tab = NULL;
1485  name_buf = NULL;
1486  ttf_read_font();
1488  pdf_flush(pdf);
1489  if (is_subsetted(fd_cur->fm)) {
1492  } else
1493  ttf_copy_font(pdf);
1494  ttf_length = ttf_offset();
1495  xfree(dir_tab);
1496  xfree(glyph_tab);
1497  xfree(glyph_index);
1499  xfree(name_tab);
1500  xfree(name_buf);
1501  if (tracefilenames) {
1502  if (is_subsetted(fd_cur->fm))
1503  tex_printf(">");
1504  else
1505  tex_printf(">>");
1506  }
1507  xfree(ttf_buffer);
1508  cur_file_name = NULL;
1509 }
1510 
1511 static void do_writeotf(PDF pdf, fd_entry * fd)
1512 {
1513  long i;
1514  dirtab_entry *tab;
1515  (void) fd;
1516  dir_tab = NULL;
1517  glyph_tab = NULL;
1518  if (tracefilenames)
1519  tex_printf("<<%s", cur_file_name);
1520  ttf_read_tabdir();
1521  /*tex Read teh font parameters. */
1522  if (ttf_name_lookup("head", false) != NULL)
1523  ttf_read_head();
1524  if (ttf_name_lookup("hhea", false) != NULL)
1525  ttf_read_hhea();
1526  if (ttf_name_lookup("PCLT", false) != NULL)
1527  ttf_read_pclt();
1528  if (ttf_name_lookup("post", false) != NULL)
1529  ttf_read_post();
1530  /*tex Copy the font file: */
1531  if (ttf_name_lookup("CFF2", false) != NULL)
1532  tab = ttf_seek_tab("CFF2", 0);
1533  else
1534  tab = ttf_seek_tab("CFF ", 0);
1535  for (i = (long) tab->length; i > 0; i--) {
1536  copy_char();
1537  }
1538  xfree(dir_tab);
1539  if (tracefilenames)
1540  tex_printf(">>");
1541 }
1542 
1544 {
1545  int callback_id;
1546  int file_opened = 0;
1547  fd_cur = fd;
1548  ttf_curbyte = 0;
1549  ttf_size = 0;
1551  if (cur_file_name == NULL) {
1552  formatted_error("otf font","cannot find font file for reading '%s'", fd_cur->fm->ff_name);
1553  }
1555  if (callback_id > 0) {
1556  if (run_callback(callback_id, "S->bSd", cur_file_name, &file_opened, &ttf_buffer, &ttf_size) && file_opened && ttf_size > 0) {
1557  /*tex We're okay. */
1558  } else {
1559  formatted_error("otf font","cannot open font file for reading '%s'", cur_file_name);
1560  }
1561  } else {
1562  if (!otf_open(cur_file_name)) {
1563  formatted_error("otf font","cannot open font file for reading '%s'", cur_file_name);
1564  }
1565  ttf_read_file();
1566  ttf_close();
1567  }
1568  fd_cur->ff_found = true;
1569  do_writeotf(pdf, fd);
1570  xfree(ttf_buffer);
1571  cur_file_name = NULL;
1572 }
1573 
q
Definition: afm2pl.c:2287
struct @88 table[500]
#define name
char * p2
Definition: bmpfont.h:62
char * p1
Definition: bmpfont.h:62
#define n
Definition: t4ht.c:1290
#define b
Definition: jpegint.h:372
static int id
Definition: bifont.c:66
#define FONTBBOX1_CODE
Definition: ptexmac.h:97
#define XHEIGHT_CODE
Definition: ptexmac.h:96
#define ITALIC_ANGLE_CODE
Definition: ptexmac.h:94
#define strend(s)
Definition: ptexmac.h:86
#define xfree(p)
Definition: ptexmac.h:85
#define FONTBBOX2_CODE
Definition: ptexmac.h:98
#define CAPHEIGHT_CODE
Definition: ptexmac.h:91
#define is_subsetted(fm)
Definition: ptexmac.h:126
#define FONTNAME_CODE
Definition: ptexmac.h:93
#define xtalloc
Definition: ptexmac.h:87
#define ASCENT_CODE
Definition: ptexmac.h:90
#define FONTBBOX3_CODE
Definition: ptexmac.h:99
#define FONTBBOX4_CODE
Definition: ptexmac.h:100
#define DESCENT_CODE
Definition: ptexmac.h:92
char * strncpy()
int strcmp()
Definition: coll.cpp:143
int sscanf()
#define SMALL_BUF_SIZE
Definition: ptexmac.h:62
static void
Definition: fpif.c:118
#define s
Definition: afcover.h:80
#define t
Definition: afcover.h:96
#define c(n)
Definition: gpos-common.c:150
#define memcpy(d, s, n)
Definition: gsftopk.c:64
assert(pcxLoadImage24((char *)((void *) 0), fp, pinfo, hdr))
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
FT_UInt idx
Definition: cffcmap.c:135
#define WE_HAVE_A_SCALE
Definition: ttgload.c:73
#define MORE_COMPONENTS
Definition: ttgload.c:75
T1_FIELD_DICT_FONTDICT T1_FIELD_DICT_FONTDICT italic_angle
Definition: t1tokens.h:36
#define put_short(s, w)
Definition: trees.c:174
int num
Definition: disdvi.c:621
#define xstrdup(s)
Definition: writet1.c:34
#define save_offset()
Definition: writet1.c:62
#define buf
#define WE_HAVE_INSTRUCTIONS
Definition: tt_glyf.c:196
#define WE_HAVE_AN_X_AND_Y_SCALE
Definition: tt_glyf.c:194
#define WE_HAVE_A_TWO_BY_TWO
Definition: tt_glyf.c:195
#define ARG_1_AND_2_ARE_WORDS
Definition: tt_glyf.c:188
#define make_subset_tag(a, b)
Definition: writet1.c:54
static const char * tab[]
Definition: xdirtest.c:23
int warn
Definition: var.h:7
static int is_unicode
Definition: bdf.c:76
#define cur_file_name
Definition: ctangleboot.c:60
#define length(c)
Definition: ctangleboot.c:65
void * avl_t_next(struct avl_traverser *trav)
Definition: avl.c:524
void * avl_t_first(struct avl_traverser *trav, struct avl_table *tree)
Definition: avl.c:393
void ** avl_probe(struct avl_table *tree, void *item)
Definition: avl.c:85
void avl_t_init(struct avl_traverser *trav, struct avl_table *tree)
Definition: avl.c:382
struct libavl_allocator avl_xallocator
Definition: avlstuff.c:41
#define ttf_close()
Definition: writettf.c:35
#define ttf_open()
Definition: writettf.c:33
#define ttf_eof()
Definition: writettf.c:37
void writettf(fd_entry *fd)
Definition: writettf.c:1334
integer ttf_length
Definition: writettf.c:103
#define ttf_getchar()
Definition: writettf.c:36
void writeotf(fd_entry *fd)
Definition: writettf.c:1402
void ttf_free(void)
Definition: writettf.c:142
#define get_fword()
Definition: writettf.h:65
#define get_short()
Definition: writettf.h:60
#define TTF_F2DOT14_SIZE
Definition: writettf.h:41
signed short TTF_SHORT
Definition: writettf.h:22
#define get_ulong()
Definition: writettf.h:61
#define ttf_skip(n)
Definition: writettf.h:55
#define get_ushort()
Definition: writettf.h:59
#define TTF_CHAR_SIZE
Definition: writettf.h:32
#define TTF_BYTE_SIZE
Definition: writettf.h:33
#define NMACGLYPHS
Definition: writettf.h:99
#define put_ufword(n)
Definition: writettf.h:80
#define copy_byte()
Definition: writettf.h:83
unsigned short TTF_USHORT
Definition: writettf.h:23
#define TTF_LONG_SIZE
Definition: writettf.h:36
#define TTF_ULONG_SIZE
Definition: writettf.h:37
#define TTF_FWORD_SIZE
Definition: writettf.h:39
#define GLYPH_PREFIX_UNICODE
Definition: writettf.h:104
#define get_byte()
Definition: writettf.h:57
#define get_ufword()
Definition: writettf.h:66
#define TTF_SHORT_SIZE
Definition: writettf.h:34
uint32_t TTF_FIXED
Definition: writettf.h:26
#define get_fixed()
Definition: writettf.h:63
#define TTF_UFWORD_SIZE
Definition: writettf.h:40
#define copy_ushort()
Definition: writettf.h:85
#define GLYPH_PREFIX_INDEX
Definition: writettf.h:103
#define put_fixed(n)
Definition: writettf.h:77
#define TABDIR_OFF
Definition: writettf.h:100
int32_t TTF_LONG
Definition: writettf.h:24
#define copy_short()
Definition: writettf.h:86
signed short TTF_FWORD
Definition: writettf.h:28
uint32_t TTF_ULONG
Definition: writettf.h:25
#define put_ushort(n)
Definition: writettf.h:74
#define get_char()
Definition: writettf.h:58
#define TTF_USHORT_SIZE
Definition: writettf.h:35
unsigned short TTF_UFWORD
Definition: writettf.h:29
#define TTF_FIXED_SIZE
Definition: writettf.h:38
#define copy_char()
Definition: writettf.h:84
#define put_ulong(n)
Definition: writettf.h:76
int strncmp()
int run_callback(int i, const char *values,...)
Definition: lcallbacklib.c:259
void normal_error(const char *t, const char *p)
Definition: errors.c:951
void formatted_error(const char *t, const char *fmt,...)
Definition: errors.c:1038
void formatted_warning(const char *t, const char *fmt,...)
Definition: errors.c:1048
@ read_truetype_file_callback
@ find_truetype_file_callback
@ read_opentype_file_callback
@ find_opentype_file_callback
#define callback_defined(a)
char * luatex_find_file(const char *s, int callback_index)
Definition: texfileio.c:150
boolean tracefilenames
Definition: mainbody.c:181
void normal_warning(const char *t, const char *p)
Definition: errors.c:981
dictionary ce
Definition: pdf.py:1
#define version
Definition: nup.c:10
int k
Definition: otp-parser.c:70
static int format
Definition: pbmclean.c:15
void pdf_flush(PDF pdf)
Definition: pdfgen.c:376
#define pdf_save_offset(pdf)
Definition: pdfgen.h:59
void tex_printf(const char *,...)
#define sign(x)
#define index(s, c)
Definition: plain2.h:351
#define put_byte(b)
Definition: pnmtosgi.c:31
static int offset
Definition: ppmtogif.c:642
#define flags
#define isspace(ch)
Definition: utype.h:87
#define avl_find
Definition: avl.h:18
#define avl_create
Definition: avl.h:19
#define avl_destroy
Definition: avl.h:20
static int prepend_subset_tags(int index, char *p)
Definition: writettf.c:938
static TTF_SHORT loca_format
Definition: writettf.c:67
static TTF_ULONG tab_length
Definition: writettf.c:85
dirtab_entry * dir_tab
Definition: writettf.c:75
static TTF_USHORT new_ntabs
Definition: writettf.c:72
void ttf_read_pclt(void)
Definition: writettf.c:468
static TTF_USHORT ntabs
Definition: writettf.c:64
unsigned char * ttf_buffer
Definition: writettf.c:34
static unsigned char ttf_addchksm(unsigned char b)
Definition: writettf.c:233
static void do_writeotf(PDF pdf, fd_entry *fd)
Definition: writettf.c:1511
static void ttf_reset_chksm(PDF pdf, dirtab_entry *tab)
Definition: writettf.c:763
static void ttf_write_head(PDF pdf)
Definition: writettf.c:1230
static void ttf_read_loca(void)
Definition: writettf.c:565
static void ttf_select_cmap(void)
Definition: writettf.c:875
static void ttf_ncopy(PDF pdf, int n)
Definition: writettf.c:289
static cmap_entry * cmap_tab
Definition: writettf.c:78
static void ttf_seg_map_delta(PDF pdf)
Definition: writettf.c:834
void ttf_read_head(void)
Definition: writettf.c:440
void ttf_read_post(void)
Definition: writettf.c:498
#define SEG_MAP_DELTA_LENGTH
Definition: writettf.c:832
char notdef[]
Definition: writettf.c:99
static void ttf_read_mapx(void)
Definition: writettf.c:422
FILE * ttf_file
Definition: writettf.c:88
static void ttf_read_name(void)
Definition: writettf.c:374
static int comp_ttf_cmap_entry(const void *pa, const void *pb, void *p)
Definition: writettf.c:220
#define CMAP_ENTRY_LENGTH
Definition: writettf.c:873
static int name_record_num
Definition: writettf.c:80
static TTF_USHORT nhmtxs
Definition: writettf.c:71
dirtab_entry * ttf_seek_tab(const char *name, TTF_LONG offset)
Definition: writettf.c:311
#define ttf_offset()
Definition: writettf.c:31
static TTF_ULONG ttf_getchksm(PDF pdf)
Definition: writettf.c:244
static TTF_ULONG last_glyf_offset
Definition: writettf.c:68
static long ttf_funit(long n)
Definition: writettf.c:281
static ttfenc_entry ttfenc_tab[256]
Definition: writettf.c:89
static void ttf_subset_font(PDF pdf)
Definition: writettf.c:1404
const char * mac_glyph_names[]
Definition: writettf.c:101
void ttf_read_tabdir(void)
Definition: writettf.c:603
static void ttf_write_dirtab(PDF pdf)
Definition: writettf.c:1018
#define DEFAULT_NTABS
Definition: writettf.c:27
static void ttf_set_chksm(PDF pdf, dirtab_entry *tab)
Definition: writettf.c:773
static int name_buf_size
Definition: writettf.c:82
static TTF_USHORT new_glyphs_count
Definition: writettf.c:70
static void ttf_read_hmtx(void)
Definition: writettf.c:480
#define ttf_putchar(A)
Definition: writettf.c:30
static void ttf_copy_font(PDF pdf)
Definition: writettf.c:1429
#define ttf_seek_outbuf(A)
Definition: writettf.c:32
long ttf_putnum(PDF pdf, int s, long n)
Definition: writettf.c:253
static void ttf_write_loca(PDF pdf)
Definition: writettf.c:1271
static TTF_ULONG checksum
Definition: writettf.c:84
const char * ambiguous_names[]
Definition: writettf.c:165
static void ttf_write_hhea(PDF pdf)
Definition: writettf.c:1249
static void ttf_write_glyf(PDF pdf)
Definition: writettf.c:1066
static char * name_buf
Definition: writettf.c:81
static void ttf_write_post(PDF pdf)
Definition: writettf.c:1351
#define NEW_CMAP_SIZE
Definition: writettf.c:28
static void ttf_reindex_glyphs(void)
Definition: writettf.c:1124
static char * glyph_name_buf
Definition: writettf.c:83
static TTF_USHORT glyphs_count
Definition: writettf.c:69
static TTF_ULONG checkSumAdjustment_offset
Definition: writettf.c:87
static boolean unsafe_name(const char *s)
Definition: writettf.c:1342
static long * glyph_index
Definition: writettf.c:77
static void destroy_ttf_cmap_entry(void *pa, void *pb)
Definition: writettf.c:204
dirtab_entry * ttf_name_lookup(const char *s, boolean required)
Definition: writettf.c:295
static const char * newtabnames[]
Definition: writettf.c:176
static void ttf_byte_encoding(PDF pdf)
Definition: writettf.c:791
static void ttf_write_htmx(PDF pdf)
Definition: writettf.c:1259
static ttf_cmap_entry * new_ttf_cmap_entry(void)
Definition: writettf.c:195
int ttf_size
Definition: writettf.c:35
static void ttf_write_mapx(PDF pdf)
Definition: writettf.c:1297
static void ttf_copytab(PDF pdf, const char *name)
Definition: writettf.c:779
int ttf_curbyte
Definition: writettf.c:36
void otc_read_tabdir(int index)
Definition: writettf.c:577
long ttf_getnum(int s)
Definition: writettf.c:267
static TTF_USHORT upem
Definition: writettf.c:65
#define BYTE_ENCODING_LENGTH
Definition: writettf.c:789
glyph_entry * glyph_tab
Definition: writettf.c:74
static void ttf_read_font(void)
Definition: writettf.c:742
static TTF_FIXED post_format
Definition: writettf.c:66
static void ttf_copy_encoding(void)
Definition: writettf.c:323
static void ttf_trimmed_table_map(PDF pdf)
Definition: writettf.c:815
static void ttf_write_cmap(PDF pdf)
Definition: writettf.c:891
static TTF_ULONG tmp_ulong
Definition: writettf.c:86
fd_entry * fd_cur
Definition: writettf.c:93
static char * strip_spaces_and_delims(char *s, int l)
Definition: writettf.c:358
static ttf_cmap_entry * ttf_read_cmap(char *ttf_name, int pid, int eid, boolean warn)
Definition: writettf.c:620
static struct avl_table * ttf_cmap_tree
Definition: writettf.c:95
static name_record * name_tab
Definition: writettf.c:79
static cmap_entry new_cmap_tab[2]
Definition: writettf.c:78
static void ttf_seek_off(TTF_LONG offset)
Definition: writettf.c:318
#define TRIMMED_TABLE_MAP_LENGTH
Definition: writettf.c:813
static void ttf_write_name(PDF pdf)
Definition: writettf.c:960
static void ttf_init_font(PDF pdf, int n)
Definition: writettf.c:1387
static void ttf_write_OS2(PDF pdf)
Definition: writettf.c:1307
void ttf_read_hhea(void)
Definition: writettf.c:457
#define ttf_read_file()
Definition: writettf.h:168
#define otf_open(a)
Definition: writettf.h:166
ShellFileEnvironment e
Definition: sh6.c:388
Definition: avl.h:61
Definition: writettf.h:113
TTF_USHORT encoding_id
Definition: writettf.h:115
TTF_USHORT platform_id
Definition: writettf.h:114
TTF_USHORT format
Definition: writettf.h:117
Definition: writettf.h:106
Definition: ptexlib.h:116
char * fontname
Definition: ptexlib.h:118
struct avl_table * tx_tree
Definition: ptexlib.h:129
fm_entry * fm
Definition: ptexlib.h:128
intparm font_dim[(10+1)]
Definition: ptexlib.h:125
boolean write_ttf_glyph_names
Definition: ptexlib.h:124
char * subset_tag
Definition: ptexlib.h:119
boolean ff_found
Definition: ptexlib.h:120
fe_entry * fe
Definition: ptexlib.h:126
char ** glyph_names
Definition: ptexlib.h:74
char * ff_name
Definition: ptexlib.h:99
Definition: writettf.c:39
TTF_LONG newoffset
Definition: writettf.c:41
TTF_SHORT newindex
Definition: writettf.c:45
Definition: pbmfont.h:4
char * name
Definition: pt1.h:151
int lsb
Definition: pt1.h:153
Definition: mendex.h:20
boolean set
Definition: ptexlib.h:113
int val
Definition: ptexlib.h:112
TTF_USHORT language_id
Definition: writettf.c:58
TTF_USHORT encoding_id
Definition: writettf.c:57
TTF_USHORT offset
Definition: writettf.c:61
TTF_USHORT platform_id
Definition: writettf.c:56
TTF_USHORT length
Definition: writettf.c:60
TTF_USHORT name_id
Definition: writettf.c:59
Definition: writettf.h:120
Definition: dvips.h:235
Definition: ttf.h:133
char * ttf_name
Definition: writettf.c:67
TTF_USHORT pid
Definition: writettf.c:68
TTF_USHORT eid
Definition: writettf.c:69
Definition: ttf.h:81
Definition: writettf.c:49
const char * name
Definition: writettf.c:50
char * name
Definition: writettf.c:40
#define FILE
Definition: t1stdio.h:34
int j
Definition: t4ht.c:1589
*job_name strlen((char *) job_name) - 4)
put_char('\n')
return() int(((double) *(font_tbl[cur_fnt].wtbl+(int)(*(font_tbl[cur_fnt].char_wi+(int)(ch - font_tbl[cur_fnt].char_f)% 256)))/(double)(1L<< 20)) *(double) font_tbl[cur_fnt].scale)
long cmap_offset
Definition: ttf2afm.c:125
TTF_USHORT ncmapsubtabs
Definition: ttf2afm.c:124
TT_CharMap cmap
Definition: ttf2pfb.c:163
TT_Glyph glyph
Definition: ttf2pfb.c:162
int eid
Definition: ttf2pfb.c:130
int pid
Definition: ttf2pfb.c:129
static TTF_NAME_REC * name_record
Definition: ttf.c:72
#define cmp_return(a, b)
Definition: ptexmac.h:210