beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / lua / lfontlib.c
blob2e05f5f33277e4305e4ae4fae475238da57373c2
1 /* lfontlib.c
3 Copyright 2006-2014 Taco Hoekwater <taco@luatex.org>
5 This file is part of LuaTeX.
7 LuaTeX is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2 of the License, or (at your
10 option) any later version.
12 LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License along
18 with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
21 #include "ptexlib.h"
22 #include "lua/luatex-api.h"
24 #define TIMERS 0
26 #if TIMERS
27 # include <sys/time.h>
28 #endif
30 static int get_fontid(void)
32 if (font_tables == NULL || font_tables[0] == NULL) {
33 create_null_font();
35 return new_font();
38 static int font_read_tfm(lua_State * L)
40 if (lua_type(L, 1) == LUA_TSTRING) {
41 const char *cnom = lua_tostring(L, 1);
42 if (lua_type(L, 2) == LUA_TNUMBER) {
43 scaled s = (int) lua_tointeger(L, 2);
44 if (strlen(cnom)) {
45 internal_font_number f = get_fontid();
46 if (read_tfm_info(f, cnom, s)) {
47 int k = font_to_lua(L, f);
48 delete_font(f);
49 return k;
50 } else {
51 delete_font(f);
52 luaL_error(L, "font loading failed");
54 } else {
55 luaL_error(L, "expected tfm name as first argument");
57 } else {
58 luaL_error(L, "expected an integer size as second argument");
60 } else {
61 luaL_error(L, "expected tfm name as first argument");
63 return 2; /* not reached */
67 static int font_read_vf(lua_State * L)
69 if (lua_type(L, 1) == LUA_TSTRING) {
70 const char *cnom = lua_tostring(L, 1);
71 if (strlen(cnom)) {
72 if (lua_type(L, 2) == LUA_TNUMBER) {
73 int i = lua_tointeger(L, 2);
74 return make_vf_table(L, cnom, (scaled) i);
75 } else {
76 luaL_error(L, "expected an integer size as second argument");
77 return 2;
81 luaL_error(L, "expected vf name as first argument");
82 return 2; /* not reached */
85 static int tex_current_font(lua_State * L)
87 int i = luaL_optinteger(L, 1, 0);
88 if (i > 0) {
89 if (is_valid_font(i)) {
90 zset_cur_font(i);
91 return 0;
92 } else {
93 luaL_error(L, "expected a valid font id");
94 return 2; /* not reached */
96 } else {
97 lua_pushinteger(L, get_cur_font());
98 return 1;
102 static int tex_max_font(lua_State * L)
104 lua_pushinteger(L, max_font_id());
105 return 1;
109 static int tex_each_font_next(lua_State * L)
111 int m = lua_tointeger(L, 1);
112 int i = lua_tointeger(L, 2);
113 i++;
114 while (i <= m && !is_valid_font(i))
115 i++;
116 if (i > m) {
117 lua_pushnil(L);
118 return 1;
119 } else {
120 lua_pushinteger(L, i);
121 if (!font_to_lua(L, i))
122 lua_pushnil(L);
123 return 2;
127 static int tex_each_font(lua_State * L)
129 lua_pushcclosure(L, tex_each_font_next, 0);
130 lua_pushinteger(L, max_font_id());
131 lua_pushinteger(L, 0);
132 return 3;
135 static int frozenfont(lua_State * L)
137 int i = luaL_checkinteger(L, 1);
138 if (i) {
139 if (is_valid_font(i)) {
140 if (font_touched(i) || font_used(i)) {
141 lua_pushboolean(L, 1);
142 } else {
143 lua_pushboolean(L, 0);
145 } else {
146 lua_pushnil(L);
148 return 1;
149 } else {
150 luaL_error(L, "expected an integer argument");
152 return 0; /* not reached */
156 static int setfont(lua_State * L)
158 int i = luaL_checkinteger(L, -2);
159 if (i) {
160 luaL_checktype(L, -1, LUA_TTABLE);
161 if (is_valid_font(i)) {
162 if (!(font_touched(i) || font_used(i))) {
163 font_from_lua(L, i);
164 } else {
165 luaL_error(L,
166 "that font has been accessed already, changing it is forbidden");
168 } else {
169 luaL_error(L, "that integer id is not a valid font");
172 return 0;
176 static int deffont(lua_State * L)
178 int i = get_fontid();
179 luaL_checktype(L, -1, LUA_TTABLE);
180 if (font_from_lua(L, i)) {
181 lua_pushinteger(L, i);
182 return 1;
183 } else {
184 lua_pop(L, 1); /* pop the broken table */
185 delete_font(i);
186 luaL_error(L, "font creation failed");
188 return 0; /* not reached */
191 /* this returns the expected (!) next fontid. */
192 static int nextfontid(lua_State * L)
194 int i = get_fontid();
195 lua_pushinteger(L, i);
196 delete_font(i);
197 return 1;
201 static int getfont(lua_State * L)
203 int i = luaL_checkinteger(L, -1);
204 if (i && is_valid_font(i) && font_to_lua(L, i))
205 return 1;
206 lua_pushnil(L);
207 return 1;
211 static int getfontid(lua_State * L)
213 if (lua_type(L, 1) == LUA_TSTRING) {
214 size_t ff;
215 const char *s = lua_tolstring(L, 1, &ff);
216 int cs = string_lookup(s, ff);
217 int f;
218 if (cs == undefined_control_sequence || cs == undefined_cs_cmd || eq_type(cs) != set_font_cmd) {
219 lua_pushstring(L, "not a valid font csname");
220 f = -1;
221 } else {
222 f = equiv(cs);
224 lua_pushinteger(L, f);
225 } else {
226 luaL_error(L, "expected font csname string as argument");
228 return 1;
232 static const struct luaL_Reg fontlib[] = {
233 {"read_tfm", font_read_tfm},
234 {"read_vf", font_read_vf},
235 {"current", tex_current_font},
236 {"max", tex_max_font},
237 {"each", tex_each_font},
238 {"getfont", getfont},
239 {"setfont", setfont},
240 {"define", deffont},
241 {"nextid", nextfontid},
242 {"id", getfontid},
243 {"frozen", frozenfont},
244 {NULL, NULL} /* sentinel */
247 int luaopen_font(lua_State * L)
249 luaL_register(L, "font", fontlib);
250 make_table(L, "fonts", "tex.fonts", "getfont", "setfont");
251 return 1;
254 /**********************************************************************/
255 /* "vf" library: Lua functions within virtual fonts */
257 static int l_vf_char(lua_State * L)
259 int k, w;
260 vf_struct *vsp = static_pdf->vfstruct;
261 packet_stack_record *mat_p;
262 internal_font_number lf = vsp->lf;
263 int ex_glyph = vsp->ex_glyph/1000;
264 if (!vsp->vflua)
265 normal_error("vf", "vf.char() outside virtual font");
266 k = luaL_checkinteger(L, 1);
267 if (!char_exists(lf, k)) {
268 char_warning(lf, k);
269 } else {
270 if (has_packet(lf, k))
271 do_vf_packet(static_pdf, lf, k, ex_glyph);
272 else
273 backend_out[glyph_node] (static_pdf, lf, k, ex_glyph);
275 mat_p = &(vsp->packet_stack[vsp->packet_stack_level]);
276 w = char_width(lf, k);
277 mat_p->pos.h += round_xn_over_d(w, 1000 + ex_glyph, 1000);
278 synch_pos_with_cur(static_pdf->posstruct, vsp->refpos, mat_p->pos);
279 return 0;
282 static int l_vf_down(lua_State * L)
284 scaled i;
285 vf_struct *vsp = static_pdf->vfstruct;
286 packet_stack_record *mat_p;
287 if (!vsp->vflua)
288 normal_error("vf", "vf.down() outside virtual font");
289 i = (scaled) luaL_checkinteger(L, 1);
290 i = store_scaled_f(i, vsp->fs_f);
291 mat_p = &(vsp->packet_stack[vsp->packet_stack_level]);
292 mat_p->pos.v += i;
293 synch_pos_with_cur(static_pdf->posstruct, vsp->refpos, mat_p->pos);
294 return 0;
297 static int l_vf_fontid(lua_State * L)
299 vf_struct *vsp = static_pdf->vfstruct;
300 if (!vsp->vflua)
301 normal_error("vf", "vf.fontid() outside virtual font");
302 vsp->lf = (int) luaL_checkinteger(L, 1);
303 return 0;
306 static int l_vf_image(lua_State * L)
308 int k;
309 vf_struct *vsp = static_pdf->vfstruct;
310 if (!vsp->vflua)
311 normal_error("vf", "vf.image() outside virtual font");
312 k = (int) luaL_checkinteger(L, 1);
313 vf_out_image(static_pdf, k);
314 return 0;
317 static int l_vf_node(lua_State * L)
319 int k;
320 vf_struct *vsp = static_pdf->vfstruct;
321 if (!vsp->vflua)
322 normal_error("vf", "vf.node() outside virtual font");
323 k = (int) luaL_checkinteger(L, 1);
324 hlist_out(static_pdf, (halfword) k, 0);
325 return 0;
328 static int l_vf_nop(lua_State * L)
330 vf_struct *vsp = static_pdf->vfstruct;
331 if (!vsp->vflua)
332 normal_error("vf", "vf.nop() outside virtual font");
333 return 0;
336 static int l_vf_pop(lua_State * L)
338 vf_struct *vsp = static_pdf->vfstruct;
339 packet_stack_record *mat_p;
340 if (!vsp->vflua)
341 normal_error("vf", "vf.pop() outside virtual font");
342 if (vsp->packet_stack_level == vsp->packet_stack_minlevel)
343 normal_error("vf", "packet_stack_level underflow");
344 vsp->packet_stack_level--;
345 mat_p = &(vsp->packet_stack[vsp->packet_stack_level]);
346 synch_pos_with_cur(static_pdf->posstruct, vsp->refpos, mat_p->pos);
347 return 0;
350 static int l_vf_push(lua_State * L)
352 vf_struct *vsp = static_pdf->vfstruct;
353 packet_stack_record *mat_p;
354 if (!vsp->vflua)
355 normal_error("vf", "vf.push() outside virtual font");
356 mat_p = &(vsp->packet_stack[vsp->packet_stack_level]);
357 vsp->packet_stack_level++;
358 if (vsp->packet_stack_level == packet_stack_size)
359 normal_error("vf", "packet_stack_level overflow");
360 vsp->packet_stack[vsp->packet_stack_level] = *mat_p;
361 mat_p = &(vsp->packet_stack[vsp->packet_stack_level]);
362 return 0;
365 static int l_vf_right(lua_State * L)
367 scaled i;
368 vf_struct *vsp = static_pdf->vfstruct;
369 packet_stack_record *mat_p;
370 if (!vsp->vflua)
371 normal_error("vf", "vf.right() outside virtual font");
372 mat_p = &(vsp->packet_stack[vsp->packet_stack_level]);
373 i = (scaled) luaL_checkinteger(L, 1);
374 i = store_scaled_f(i, vsp->fs_f);
375 mat_p->pos.h += i;
376 synch_pos_with_cur(static_pdf->posstruct, vsp->refpos, mat_p->pos);
377 return 0;
380 static int l_vf_rule(lua_State * L)
382 scaledpos size;
383 vf_struct *vsp = static_pdf->vfstruct;
384 packet_stack_record *mat_p;
385 if (!vsp->vflua)
386 normal_error("vf", "vf.rule() outside virtual font");
387 size.h = (scaled) luaL_checkinteger(L, 1);
388 size.v = (scaled) luaL_checkinteger(L, 2);
389 size.h = store_scaled_f(size.h, vsp->fs_f);
390 size.v = store_scaled_f(size.v, vsp->fs_f);
391 if (size.h > 0 && size.v > 0)
392 backend_out[rule_node](static_pdf, 0, size); /* the 0 is unused */
393 mat_p = &(vsp->packet_stack[vsp->packet_stack_level]);
394 mat_p->pos.h += size.h;
395 synch_pos_with_cur(static_pdf->posstruct, vsp->refpos, mat_p->pos);
396 return 0;
399 static int l_vf_special(lua_State * L)
401 const_lstring st;
402 int texstr;
403 vf_struct *vsp = static_pdf->vfstruct;
404 if (!vsp->vflua)
405 normal_error("vf", "vf.special() outside virtual font");
406 st.s = lua_tolstring(L, 1, &(st.l));
407 texstr = maketexlstring(st.s, st.l);
408 pdf_literal(static_pdf, texstr, scan_special, false);
409 flush_str(texstr);
410 return 0;
413 static const struct luaL_Reg vflib[] = {
414 {"char", l_vf_char},
415 {"down", l_vf_down},
416 /* {"font", l_vf_font}, */
417 {"fontid", l_vf_fontid},
418 {"image", l_vf_image},
419 /* {"lua", l_vf_lua}, */
420 {"node", l_vf_node},
421 {"nop", l_vf_nop},
422 {"pop", l_vf_pop},
423 {"push", l_vf_push},
424 {"right", l_vf_right},
425 {"rule", l_vf_rule},
426 /* {"scale", l_vf_scale}, */
427 /* {"slot", l_vf_slot}, */
428 {"special", l_vf_special},
429 {NULL, NULL} /* sentinel */
432 int luaopen_vf(lua_State * L)
434 luaL_register(L, "vf", vflib);
435 return 1;