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 internal_font_number f
;
44 if (lua_isstring(L
, 1)) {
45 cnom
= lua_tostring(L
, 1);
46 if (lua_isnumber(L
, 2)) {
47 s
= (int) lua_tonumber(L
, 2);
50 if (read_tfm_info(f
, cnom
, s
)) {
51 k
= font_to_lua(L
, f
);
56 luaL_error(L
, "font loading failed");
59 luaL_error(L
, "expected tfm name as first argument");
62 luaL_error(L
, "expected an integer size as second argument");
65 luaL_error(L
, "expected tfm name as first argument");
67 return 2; /* not reached */
71 static int font_read_vf(lua_State
* L
)
75 if (lua_isstring(L
, 1)) {
76 cnom
= lua_tostring(L
, 1);
78 if (lua_isnumber(L
, 2)) {
79 i
= (int) lua_tonumber(L
, 2);
80 return make_vf_table(L
, cnom
, (scaled
) i
);
82 luaL_error(L
, "expected an integer size as second argument");
87 luaL_error(L
, "expected vf name as first argument");
88 return 2; /* not reached */
91 static int tex_current_font(lua_State
* L
)
94 i
= (int) luaL_optinteger(L
, 1, 0);
96 if (is_valid_font(i
)) {
100 luaL_error(L
, "expected a valid font id");
101 return 2; /* not reached */
104 lua_pushnumber(L
, get_cur_font());
109 static int tex_max_font(lua_State
* L
)
111 lua_pushnumber(L
, max_font_id());
116 static int tex_each_font_next(lua_State
* L
)
119 m
= (int) lua_tonumber(L
, 1);
120 i
= (int) lua_tonumber(L
, 2);
122 while (i
<= m
&& !is_valid_font(i
))
128 lua_pushnumber(L
, i
);
129 if (!font_to_lua(L
, i
))
135 static int tex_each_font(lua_State
* L
)
137 lua_pushcclosure(L
, tex_each_font_next
, 0);
138 lua_pushnumber(L
, max_font_id());
139 lua_pushnumber(L
, 0);
143 static int frozenfont(lua_State
* L
)
146 i
= (int) luaL_checkinteger(L
, 1);
148 if (is_valid_font(i
)) {
149 if (font_touched(i
) || font_used(i
)) {
150 lua_pushboolean(L
, 1);
152 lua_pushboolean(L
, 0);
159 luaL_error(L
, "expected an integer argument");
161 return 0; /* not reached */
165 static int setfont(lua_State
* L
)
168 i
= (int) luaL_checkinteger(L
, -2);
170 luaL_checktype(L
, -1, LUA_TTABLE
);
171 if (is_valid_font(i
)) {
172 if (!(font_touched(i
) || font_used(i
))) {
176 "that font has been accessed already, changing it is forbidden");
179 luaL_error(L
, "that integer id is not a valid font");
186 static int deffont(lua_State
* L
)
194 luaL_checktype(L
, -1, LUA_TTABLE
);
197 gettimeofday(&tva
, NULL
);
199 if (font_from_lua(L
, i
)) {
201 gettimeofday(&tvb
, NULL
);
202 tvdiff
= tvb
.tv_sec
* 1000000.0;
203 tvdiff
+= (double) tvb
.tv_usec
;
204 tvdiff
-= (tva
.tv_sec
* 1000000.0);
205 tvdiff
-= (double) tva
.tv_usec
;
207 fprintf(stdout
, "font.define(%s,%i): %f seconds\n",
208 font_fullname(i
), i
, tvdiff
);
210 lua_pushnumber(L
, i
);
213 lua_pop(L
, 1); /* pop the broken table */
215 luaL_error(L
, "font creation failed");
217 return 0; /* not reached */
220 /* this returns the expected (!) next fontid. */
221 static int nextfontid(lua_State
* L
)
223 int i
= get_fontid();
224 lua_pushnumber(L
, i
);
230 static int getfont(lua_State
* L
)
233 i
= (int) luaL_checkinteger(L
, -1);
234 if (i
&& is_valid_font(i
) && font_to_lua(L
, i
))
241 static int getfontid(lua_State
* L
)
247 if (lua_type(L
, 1) == LUA_TSTRING
) {
248 s
= lua_tolstring(L
, 1, &ff
);
249 cs
= string_lookup(s
, ff
);
250 if (cs
== undefined_control_sequence
|| cs
== undefined_cs_cmd
251 || eq_type(cs
) != set_font_cmd
) {
252 lua_pushstring(L
, "not a valid font csname");
257 lua_pushnumber(L
, f
);
259 luaL_error(L
, "expected font csname string as argument");
265 static const struct luaL_Reg fontlib
[] = {
266 {"read_tfm", font_read_tfm
},
267 {"read_vf", font_read_vf
},
268 {"current", tex_current_font
},
269 {"max", tex_max_font
},
270 {"each", tex_each_font
},
271 {"getfont", getfont
},
272 {"setfont", setfont
},
274 {"nextid", nextfontid
},
276 {"frozen", frozenfont
},
277 {NULL
, NULL
} /* sentinel */
280 int luaopen_font(lua_State
* L
)
282 luaL_register(L
, "font", fontlib
);
283 make_table(L
, "fonts", "tex.fonts", "getfont", "setfont");
287 /**********************************************************************/
288 /* "vf" library: Lua functions within virtual fonts */
290 static int l_vf_char(lua_State
* L
)
293 /*int ex = 0;*/ /* Wrong! TODO */
294 vf_struct
*vsp
= static_pdf
->vfstruct
;
295 packet_stack_record
*mat_p
;
296 internal_font_number lf
= vsp
->lf
;
297 int ex_glyph
= vsp
->ex_glyph
/1000;
299 pdf_error("vf", "vf.char() outside virtual font");
300 k
= (int) luaL_checkinteger(L
, 1);
301 if (!char_exists(lf
, (int) k
)) {
302 char_warning(lf
, (int) k
);
304 if (has_packet(lf
, (int) k
))
305 do_vf_packet(static_pdf
, lf
, (int) k
, ex_glyph
);
307 backend_out
[glyph_node
] (static_pdf
, lf
, (int) k
, ex_glyph
);
309 mat_p
= &(vsp
->packet_stack
[vsp
->packet_stack_level
]);
310 w
= char_width(lf
, (int) k
);
311 mat_p
->pos
.h
+= round_xn_over_d(w
, 1000 + ex_glyph
, 1000);
312 synch_pos_with_cur(static_pdf
->posstruct
, vsp
->refpos
, mat_p
->pos
);
316 static int l_vf_down(lua_State
* L
)
319 vf_struct
*vsp
= static_pdf
->vfstruct
;
320 packet_stack_record
*mat_p
;
322 pdf_error("vf", "vf.down() outside virtual font");
323 i
= (scaled
) luaL_checkinteger(L
, 1);
324 i
= store_scaled_f(i
, vsp
->fs_f
);
325 mat_p
= &(vsp
->packet_stack
[vsp
->packet_stack_level
]);
327 synch_pos_with_cur(static_pdf
->posstruct
, vsp
->refpos
, mat_p
->pos
);
331 static int l_vf_fontid(lua_State
* L
)
333 vf_struct
*vsp
= static_pdf
->vfstruct
;
335 pdf_error("vf", "vf.fontid() outside virtual font");
336 vsp
->lf
= (int) luaL_checkinteger(L
, 1);
340 static int l_vf_image(lua_State
* L
)
343 vf_struct
*vsp
= static_pdf
->vfstruct
;
345 pdf_error("vf", "vf.image() outside virtual font");
346 k
= (int) luaL_checkinteger(L
, 1);
347 vf_out_image(static_pdf
, k
);
351 static int l_vf_node(lua_State
* L
)
354 vf_struct
*vsp
= static_pdf
->vfstruct
;
356 pdf_error("vf", "vf.node() outside virtual font");
357 k
= (int) luaL_checkinteger(L
, 1);
358 hlist_out(static_pdf
, (halfword
) k
);
362 static int l_vf_nop(lua_State
* L
)
364 vf_struct
*vsp
= static_pdf
->vfstruct
;
366 pdf_error("vf", "vf.nop() outside virtual font");
370 static int l_vf_pop(lua_State
* L
)
372 vf_struct
*vsp
= static_pdf
->vfstruct
;
373 packet_stack_record
*mat_p
;
375 pdf_error("vf", "vf.pop() outside virtual font");
376 if (vsp
->packet_stack_level
== vsp
->packet_stack_minlevel
)
377 pdf_error("vf", "packet_stack_level underflow");
378 vsp
->packet_stack_level
--;
379 mat_p
= &(vsp
->packet_stack
[vsp
->packet_stack_level
]);
380 synch_pos_with_cur(static_pdf
->posstruct
, vsp
->refpos
, mat_p
->pos
);
384 static int l_vf_push(lua_State
* L
)
386 vf_struct
*vsp
= static_pdf
->vfstruct
;
387 packet_stack_record
*mat_p
;
389 pdf_error("vf", "vf.push() outside virtual font");
390 mat_p
= &(vsp
->packet_stack
[vsp
->packet_stack_level
]);
391 vsp
->packet_stack_level
++;
392 if (vsp
->packet_stack_level
== packet_stack_size
)
393 pdf_error("vf", "packet_stack_level overflow");
394 vsp
->packet_stack
[vsp
->packet_stack_level
] = *mat_p
;
395 mat_p
= &(vsp
->packet_stack
[vsp
->packet_stack_level
]);
399 static int l_vf_right(lua_State
* L
)
402 vf_struct
*vsp
= static_pdf
->vfstruct
;
403 packet_stack_record
*mat_p
;
405 pdf_error("vf", "vf.right() outside virtual font");
406 mat_p
= &(vsp
->packet_stack
[vsp
->packet_stack_level
]);
407 i
= (scaled
) luaL_checkinteger(L
, 1);
408 i
= store_scaled_f(i
, vsp
->fs_f
);
410 synch_pos_with_cur(static_pdf
->posstruct
, vsp
->refpos
, mat_p
->pos
);
414 static int l_vf_rule(lua_State
* L
)
417 vf_struct
*vsp
= static_pdf
->vfstruct
;
418 packet_stack_record
*mat_p
;
420 pdf_error("vf", "vf.rule() outside virtual font");
421 size
.h
= (scaled
) luaL_checkinteger(L
, 1);
422 size
.v
= (scaled
) luaL_checkinteger(L
, 2);
423 size
.h
= store_scaled_f(size
.h
, vsp
->fs_f
);
424 size
.v
= store_scaled_f(size
.v
, vsp
->fs_f
);
425 if (size
.h
> 0 && size
.v
> 0)
426 pdf_place_rule(static_pdf
, 0, size
); /* the 0 is unused */
427 mat_p
= &(vsp
->packet_stack
[vsp
->packet_stack_level
]);
428 mat_p
->pos
.h
+= size
.h
;
429 synch_pos_with_cur(static_pdf
->posstruct
, vsp
->refpos
, mat_p
->pos
);
433 static int l_vf_special(lua_State
* L
)
437 vf_struct
*vsp
= static_pdf
->vfstruct
;
439 pdf_error("vf", "vf.special() outside virtual font");
440 st
.s
= lua_tolstring(L
, 1, &(st
.l
));
441 texstr
= maketexlstring(st
.s
, st
.l
);
442 pdf_literal(static_pdf
, texstr
, scan_special
, false);
447 static const struct luaL_Reg vflib
[] = {
450 /* {"font", l_vf_font}, */
451 {"fontid", l_vf_fontid
},
452 {"image", l_vf_image
},
453 /* {"lua", l_vf_lua}, */
458 {"right", l_vf_right
},
460 /* {"scale", l_vf_scale}, */
461 /* {"slot", l_vf_slot}, */
462 {"special", l_vf_special
},
463 {NULL
, NULL
} /* sentinel */
466 int luaopen_vf(lua_State
* L
)
468 luaL_register(L
, "vf", vflib
);