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/>. */
22 #include "lua/luatex-api.h"
27 # include <sys/time.h>
30 static int get_fontid(void)
32 if (font_tables
== NULL
|| font_tables
[0] == NULL
) {
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);
45 internal_font_number f
= get_fontid();
46 if (read_tfm_info(f
, cnom
, s
)) {
47 int k
= font_to_lua(L
, f
);
52 luaL_error(L
, "font loading failed");
55 luaL_error(L
, "expected tfm name as first argument");
58 luaL_error(L
, "expected an integer size as second argument");
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);
72 if (lua_type(L
, 2) == LUA_TNUMBER
) {
73 int i
= lua_tointeger(L
, 2);
74 return make_vf_table(L
, cnom
, (scaled
) i
);
76 luaL_error(L
, "expected an integer size as second argument");
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);
89 if (is_valid_font(i
)) {
93 luaL_error(L
, "expected a valid font id");
94 return 2; /* not reached */
97 lua_pushinteger(L
, get_cur_font());
102 static int tex_max_font(lua_State
* L
)
104 lua_pushinteger(L
, max_font_id());
109 static int tex_each_font_next(lua_State
* L
)
111 int m
= lua_tointeger(L
, 1);
112 int i
= lua_tointeger(L
, 2);
114 while (i
<= m
&& !is_valid_font(i
))
120 lua_pushinteger(L
, i
);
121 if (!font_to_lua(L
, i
))
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);
135 static int frozenfont(lua_State
* L
)
137 int i
= luaL_checkinteger(L
, 1);
139 if (is_valid_font(i
)) {
140 if (font_touched(i
) || font_used(i
)) {
141 lua_pushboolean(L
, 1);
143 lua_pushboolean(L
, 0);
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);
160 luaL_checktype(L
, -1, LUA_TTABLE
);
161 if (is_valid_font(i
)) {
162 if (!(font_touched(i
) || font_used(i
))) {
166 "that font has been accessed already, changing it is forbidden");
169 luaL_error(L
, "that integer id is not a valid font");
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
);
184 lua_pop(L
, 1); /* pop the broken table */
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
);
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
))
211 static int getfontid(lua_State
* L
)
213 if (lua_type(L
, 1) == LUA_TSTRING
) {
215 const char *s
= lua_tolstring(L
, 1, &ff
);
216 int cs
= string_lookup(s
, ff
);
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");
224 lua_pushinteger(L
, f
);
226 luaL_error(L
, "expected font csname string as argument");
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
},
241 {"nextid", nextfontid
},
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");
254 /**********************************************************************/
255 /* "vf" library: Lua functions within virtual fonts */
257 static int l_vf_char(lua_State
* L
)
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;
265 normal_error("vf", "vf.char() outside virtual font");
266 k
= luaL_checkinteger(L
, 1);
267 if (!char_exists(lf
, k
)) {
270 if (has_packet(lf
, k
))
271 do_vf_packet(static_pdf
, lf
, k
, ex_glyph
);
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
);
282 static int l_vf_down(lua_State
* L
)
285 vf_struct
*vsp
= static_pdf
->vfstruct
;
286 packet_stack_record
*mat_p
;
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
]);
293 synch_pos_with_cur(static_pdf
->posstruct
, vsp
->refpos
, mat_p
->pos
);
297 static int l_vf_fontid(lua_State
* L
)
299 vf_struct
*vsp
= static_pdf
->vfstruct
;
301 normal_error("vf", "vf.fontid() outside virtual font");
302 vsp
->lf
= (int) luaL_checkinteger(L
, 1);
306 static int l_vf_image(lua_State
* L
)
309 vf_struct
*vsp
= static_pdf
->vfstruct
;
311 normal_error("vf", "vf.image() outside virtual font");
312 k
= (int) luaL_checkinteger(L
, 1);
313 vf_out_image(static_pdf
, k
);
317 static int l_vf_node(lua_State
* L
)
320 vf_struct
*vsp
= static_pdf
->vfstruct
;
322 normal_error("vf", "vf.node() outside virtual font");
323 k
= (int) luaL_checkinteger(L
, 1);
324 hlist_out(static_pdf
, (halfword
) k
, 0);
328 static int l_vf_nop(lua_State
* L
)
330 vf_struct
*vsp
= static_pdf
->vfstruct
;
332 normal_error("vf", "vf.nop() outside virtual font");
336 static int l_vf_pop(lua_State
* L
)
338 vf_struct
*vsp
= static_pdf
->vfstruct
;
339 packet_stack_record
*mat_p
;
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
);
350 static int l_vf_push(lua_State
* L
)
352 vf_struct
*vsp
= static_pdf
->vfstruct
;
353 packet_stack_record
*mat_p
;
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
]);
365 static int l_vf_right(lua_State
* L
)
368 vf_struct
*vsp
= static_pdf
->vfstruct
;
369 packet_stack_record
*mat_p
;
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
);
376 synch_pos_with_cur(static_pdf
->posstruct
, vsp
->refpos
, mat_p
->pos
);
380 static int l_vf_rule(lua_State
* L
)
383 vf_struct
*vsp
= static_pdf
->vfstruct
;
384 packet_stack_record
*mat_p
;
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
);
399 static int l_vf_special(lua_State
* L
)
403 vf_struct
*vsp
= static_pdf
->vfstruct
;
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);
413 static const struct luaL_Reg vflib
[] = {
416 /* {"font", l_vf_font}, */
417 {"fontid", l_vf_fontid
},
418 {"image", l_vf_image
},
419 /* {"lua", l_vf_lua}, */
424 {"right", l_vf_right
},
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
);