beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / font / writeenc.w
bloba6e4ebaaeac3dc82e3ec1772ba00c8e71ce33ff9
1 % writeenc.w
3 % Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
4 % Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org>
6 % This file is part of LuaTeX.
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.
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.
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/>.
21 @ @c
24 #include "ptexlib.h"
26 @ All encoding entries go into AVL tree for fast search by name.
28 struct avl_table *fe_tree = NULL;
30 @ AVL sort |fe_entry| into |fe_tree| by name
32 static int comp_fe_entry(const void *pa, const void *pb, void *p)
34 (void) p;
35 return strcmp(((const fe_entry *) pa)->name, ((const fe_entry *) pb)->name);
38 static fe_entry *new_fe_entry(void)
40 fe_entry *fe;
41 fe = xtalloc(1, fe_entry);
42 fe->name = NULL;
43 fe->fe_objnum = 0;
44 fe->glyph_names = NULL; /* encoding file not yet read in */
45 fe->tx_tree = NULL;
46 return fe;
49 static fe_entry *lookup_fe_entry(char *s)
51 fe_entry fe;
52 assert(s != NULL);
53 fe.name = s;
54 if (fe_tree == NULL) {
55 fe_tree = avl_create(comp_fe_entry, NULL, &avl_xallocator);
56 assert(fe_tree != NULL);
58 return (fe_entry *) avl_find(fe_tree, &fe);
61 static void register_fe_entry(fe_entry * fe)
63 void **aa;
64 if (fe_tree == NULL) {
65 fe_tree = avl_create(comp_fe_entry, NULL, &avl_xallocator);
66 assert(fe_tree != NULL);
68 assert(fe != NULL);
69 assert(fe->name != NULL);
70 assert(lookup_fe_entry(fe->name) == NULL); /* encoding not yet registered */
71 aa = avl_probe(fe_tree, fe);
72 assert(aa != NULL);
75 fe_entry *get_fe_entry(char *s)
77 fe_entry *fe;
78 char **gl;
79 if ((fe = lookup_fe_entry(s)) == NULL && (gl = load_enc_file(s)) != NULL) {
80 fe = new_fe_entry();
81 fe->name = s;
82 fe->glyph_names = gl;
83 register_fe_entry(fe);
85 return fe;
88 @ @c
89 static void write_enc(PDF pdf, char **glyph_names, struct avl_table *tx_tree,
90 int fe_objnum)
92 int i_old, *p;
93 struct avl_traverser t;
94 assert(glyph_names != NULL);
95 assert(tx_tree != NULL);
96 assert(fe_objnum != 0);
97 pdf_begin_obj(pdf, fe_objnum, OBJSTM_ALWAYS);
98 pdf_begin_dict(pdf);
99 pdf_dict_add_name(pdf, "Type", "Encoding");
100 pdf_add_name(pdf, "Differences");
101 pdf_begin_array(pdf);
102 avl_t_init(&t, tx_tree);
103 for (i_old = -2, p = (int *) avl_t_first(&t, tx_tree); p != NULL;
104 p = (int *) avl_t_next(&t)) {
105 if (*p == i_old + 1) /* consecutive */
106 pdf_add_name(pdf, glyph_names[*p]);
107 else {
108 pdf_add_int(pdf, *p);
109 pdf_add_name(pdf, glyph_names[*p]);
111 i_old = *p;
113 pdf_end_array(pdf);
114 pdf_end_dict(pdf);
115 pdf_end_obj(pdf);
118 static void write_fontencoding(PDF pdf, fe_entry * fe)
120 assert(fe != NULL);
121 write_enc(pdf, fe->glyph_names, fe->tx_tree, fe->fe_objnum);
124 void write_fontencodings(PDF pdf)
126 fe_entry *fe;
127 struct avl_traverser t;
128 if (fe_tree == NULL)
129 return;
130 avl_t_init(&t, fe_tree);
131 for (fe = (fe_entry *) avl_t_first(&t, fe_tree); fe != NULL;
132 fe = (fe_entry *) avl_t_next(&t))
133 if (fe->fe_objnum != 0)
134 write_fontencoding(pdf, fe);
137 @ cleaning up...
140 static void destroy_fe_entry(void *pa, void *pb)
142 fe_entry *p;
143 int i;
144 (void) pb;
145 p = (fe_entry *) pa;
146 xfree(p->name);
147 if (p->glyph_names != NULL)
148 for (i = 0; i < 256; i++)
149 if (p->glyph_names[i] != notdef)
150 xfree(p->glyph_names[i]);
151 xfree(p->glyph_names);
152 avl_destroy(p->tx_tree,NULL);
153 xfree(p);
156 void enc_free(void)
158 if (fe_tree != NULL)
159 avl_destroy(fe_tree, destroy_fe_entry);
160 fe_tree = NULL;