12 #include <../lua51/lua.h>
13 #include <../lua51/lauxlib.h>
14 #include <../lua51/lualib.h>
19 #include "mppsout.h" /* for mp_edge_object */
21 #define MPLIB_METATABLE "MPlib"
22 #define MPLIB_FIG_METATABLE "MPlib.fig"
23 #define MPLIB_GR_METATABLE "MPlib.gr"
25 #define xfree(A) if ((A)!=NULL) { free((A)); A = NULL; }
27 #define is_mp(L,b) (MP *)luaL_checkudata(L,b,MPLIB_METATABLE)
28 #define is_fig(L,b) (struct mp_edge_object **)luaL_checkudata(L,b,MPLIB_FIG_METATABLE)
29 #define is_gr_object(L,b) (struct mp_graphic_object **)luaL_checkudata(L,b,MPLIB_GR_METATABLE)
31 /* Enumeration string arrays */
33 static const char *interaction_options[] =
34 { "unknown","batch","nonstop","scroll","errorstop", NULL};
36 static const char *mplib_filetype_names[] =
37 {"term", "error", "mp", "log", "ps", "mem", "tfm", "map", "pfb", "enc", NULL};
39 /* only "endpoint" and "explicit" actually happen in paths,
40 as well as "open" in elliptical pens */
42 static const char *knot_type_enum[] =
43 { "endpoint", "explicit", "given", "curl", "open", "end_cycle" };
45 static const char *knot_originator_enum[] =
46 { "program" ,"user" };
49 /* this looks a bit funny because of the holes */
51 static const char *color_model_enum[] =
52 { NULL, "none", NULL, "grey", NULL, "rgb", NULL, "cmyk", NULL, "uninitialized" };
56 #define FIELD(A) (strcmp(field,#A)==0)
58 static const char *fill_fields[] =
59 { "type", "path", "htap", "pen", "color", "linejoin", "miterlimit",
60 "prescript", "postscript", NULL };
62 static const char *stroked_fields[] =
63 { "type", "path", "pen", "color", "linejoin", "miterlimit", "linecap", "dash",
64 "prescript", "postscript", NULL };
66 static const char *text_fields[] =
67 { "type", "text", "dsize", "font", "color", "width", "height", "depth", "transform",
68 "prescript", "postscript", NULL };
70 static const char *special_fields[] =
71 { "type", "prescript", NULL };
73 static const char *start_bounds_fields[] =
74 { "type", "path", NULL };
76 static const char *start_clip_fields[] =
77 { "type", "path", NULL };
79 static const char *stop_bounds_fields[] =
82 static const char *stop_clip_fields[] =
85 static const char *no_fields[] =
89 P_ERROR_LINE, P_HALF_LINE, P_MAX_LINE, P_MAIN_MEMORY,
90 P_HASH_SIZE, P_HASH_PRIME, P_PARAM_SIZE, P_IN_OPEN, P_RANDOM_SEED,
91 P_INTERACTION, P_INI_VERSION, P_TROFF_MODE, P_PRINT_NAMES, P_MEM_NAME,
92 P_JOB_NAME, P_FIND_FILE, P__SENTINEL,
96 const char *name; /* parameter name */
97 mplib_parm_idx idx; /* parameter index */
100 static mplib_parm_struct mplib_parms[] = {
101 {"error_line", P_ERROR_LINE },
102 {"half_error_line", P_HALF_LINE },
103 {"max_print_line", P_MAX_LINE },
104 {"main_memory", P_MAIN_MEMORY },
105 {"hash_size", P_HASH_SIZE },
106 {"hash_prime", P_HASH_PRIME },
107 {"param_size", P_PARAM_SIZE },
108 {"max_in_open", P_IN_OPEN },
109 {"random_seed", P_RANDOM_SEED },
110 {"interaction", P_INTERACTION },
111 {"ini_version", P_INI_VERSION },
112 {"troff_mode", P_TROFF_MODE },
113 {"print_found_names", P_PRINT_NAMES },
114 {"mem_name", P_MEM_NAME },
115 {"job_name", P_JOB_NAME },
116 {"find_file", P_FIND_FILE },
120 typedef struct _FILE_ITEM {
124 typedef struct _FILE_ITEM File;
126 typedef struct _MPLIB_INSTANCE_DATA {
136 char *input_data_ptr;
137 size_t input_data_len;
138 struct mp_edge_object *edges ;
140 } _MPLIB_INSTANCE_DATA;
142 typedef struct _MPLIB_INSTANCE_DATA mplib_instance;
144 static mplib_instance *mplib_get_data (MP mp) {
145 return (mplib_instance *)mp->userdata;
148 static mplib_instance *mplib_make_data (void) {
149 mplib_instance *mplib_data = malloc(sizeof(mplib_instance));
150 memset(mplib_data,0,sizeof(mplib_instance));
155 /* Start by defining all the callback routines for the library
156 * except |run_make_mpx| and |run_editor|.
160 char *mplib_find_file (MP mp, char *fname, char *fmode, int ftype) {
161 mplib_instance *mplib_data = mplib_get_data(mp);
162 lua_State *L = mplib_data->LL;
164 lua_getfield(L,LUA_REGISTRYINDEX,"mplib_file_finder");
165 if (lua_isfunction(L,-1)) {
166 char *s = NULL, *x = NULL;
167 lua_pushstring(L, fname);
168 lua_pushstring(L, fmode);
169 if (ftype >= mp_filetype_text) {
170 lua_pushnumber(L, ftype-mp_filetype_text);
172 lua_pushstring(L, mplib_filetype_names[ftype]);
174 if(lua_pcall(L,3,1,0) != 0) {
175 fprintf(stdout,"Error in mp.find_file: %s\n", (char *)lua_tostring(L,-1));
178 x = (char *)lua_tostring(L,-1);
181 lua_pop(L,1); /* pop the string */
186 if (fmode[0] != 'r' || (! access (fname,R_OK)) || ftype) {
187 return strdup(fname);
193 mplib_find_file_function (lua_State *L) {
194 if (! (lua_isfunction(L,-1)|| lua_isnil(L,-1) )) {
195 return 1; /* error */
197 lua_pushstring(L, "mplib_file_finder");
199 lua_rawset(L,LUA_REGISTRYINDEX);
203 void *mplib_open_file(MP mp, char *fname, char *fmode, int ftype) {
204 mplib_instance *mplib_data = mplib_get_data(mp);
205 File *ff = malloc(sizeof (File));
208 if (ftype==mp_filetype_terminal) {
209 if (fmode[0] == 'r') {
212 xfree(mplib_data->term_file_ptr);
214 mplib_data->term_file_ptr = ff->f;
216 } else if (ftype==mp_filetype_error) {
217 xfree(mplib_data->err_file_ptr);
219 mplib_data->err_file_ptr = ff->f;
220 } else if (ftype == mp_filetype_log) {
221 xfree(mplib_data->log_file_ptr);
223 mplib_data->log_file_ptr = ff->f;
224 } else if (ftype == mp_filetype_postscript) {
225 xfree(mplib_data->ps_file_ptr);
227 mplib_data->ps_file_ptr = ff->f;
230 if (fmode[0] == 'r') {
231 f = mplib_find_file(mp, fname,fmode,ftype);
235 ff->f = fopen(f, fmode);
236 if ((fmode[0] == 'r') && (ff->f == NULL)) {
247 mplib_get_char (void *f, mplib_instance *mplib_data) {
249 if (f==stdin && mplib_data->input_data != NULL) {
250 if (mplib_data->input_data_len==0) {
251 if (mplib_data->input_data_ptr!=NULL)
252 mplib_data->input_data_ptr = NULL;
254 mplib_data->input_data = NULL;
257 mplib_data->input_data_len--;
258 c = *(mplib_data->input_data_ptr)++;
267 mplib_unget_char (void *f, mplib_instance *mplib_data, int c) {
268 if (f==stdin && mplib_data->input_data_ptr != NULL) {
269 mplib_data->input_data_len++;
270 mplib_data->input_data_ptr--;
277 char *mplib_read_ascii_file (MP mp, void *ff, size_t *size) {
279 size_t len = 0, lim = 128;
281 mplib_instance *mplib_data = mplib_get_data(mp);
283 FILE *f = ((File *)ff)->f;
287 c = mplib_get_char(f,mplib_data);
291 if (s==NULL) return NULL;
292 while (c!=EOF && c!='\n' && c!='\r') {
294 s =realloc(s, (lim+(lim>>2)));
295 if (s==NULL) return NULL;
299 c = mplib_get_char(f,mplib_data);
302 c = mplib_get_char(f,mplib_data);
303 if (c!=EOF && c!='\n')
304 mplib_unget_char(f,mplib_data,c);
312 #define APPEND_STRING(a,b) do { \
316 a = realloc(a, strlen(a)+strlen(b)+1); \
317 strcpy(a+strlen(a),b); \
321 void mplib_write_ascii_file (MP mp, void *ff, char *s) {
322 mplib_instance *mplib_data = mplib_get_data(mp);
324 void *f = ((File *)ff)->f;
326 if (f==mplib_data->term_file_ptr) {
327 APPEND_STRING(mplib_data->term_out,s);
328 } else if (f==mplib_data->err_file_ptr) {
329 APPEND_STRING(mplib_data->error_out,s);
330 } else if (f==mplib_data->log_file_ptr) {
331 APPEND_STRING(mplib_data->log_out,s);
332 } else if (f==mplib_data->ps_file_ptr) {
333 APPEND_STRING(mplib_data->ps_out,s);
335 fprintf((FILE *)f,s);
341 void mplib_read_binary_file (MP mp, void *ff, void **data, size_t *size) {
345 FILE *f = ((File *)ff)->f;
347 len = fread(*data,1,*size,f);
352 void mplib_write_binary_file (MP mp, void *ff, void *s, size_t size) {
355 FILE *f = ((File *)ff)->f;
362 void mplib_close_file (MP mp, void *ff) {
363 mplib_instance *mplib_data = mplib_get_data(mp);
365 void *f = ((File *)ff)->f;
366 if (f != NULL && f != mplib_data->term_file_ptr && f != mplib_data->err_file_ptr
367 && f != mplib_data->log_file_ptr && f != mplib_data->ps_file_ptr) {
374 int mplib_eof_file (MP mp, void *ff) {
375 mplib_instance *mplib_data = mplib_get_data(mp);
377 FILE *f = ((File *)ff)->f;
380 if (f==stdin && mplib_data->input_data != NULL) {
381 return (mplib_data->input_data_len==0);
388 void mplib_flush_file (MP mp, void *ff) {
394 #define APPEND_TO_EDGES(a) do { \
395 if (mplib_data->edges==NULL) { \
396 mplib_data->edges = hh; \
398 struct mp_edge_object *p = mplib_data->edges; \
399 while (p->_next!=NULL) { p = p->_next; } \
404 void mplib_shipout_backend (MP mp, int h) {
405 struct mp_edge_object *hh;
406 mplib_instance *mplib_data = mplib_get_data(mp);
407 hh = mp_gr_export(mp, h);
415 mplib_setup_file_ops(struct MP_options * options) {
416 options->find_file = mplib_find_file;
417 options->open_file = mplib_open_file;
418 options->close_file = mplib_close_file;
419 options->eof_file = mplib_eof_file;
420 options->flush_file = mplib_flush_file;
421 options->write_ascii_file = mplib_write_ascii_file;
422 options->read_ascii_file = mplib_read_ascii_file;
423 options->write_binary_file = mplib_write_binary_file;
424 options->read_binary_file = mplib_read_binary_file;
425 options->shipout_backend = mplib_shipout_backend;
429 mplib_new (lua_State *L) {
432 mplib_instance *mplib_data;
433 struct MP_options * options; /* instance options */
434 mp_ptr = lua_newuserdata(L, sizeof(MP *));
436 options = mp_options();
437 mplib_setup_file_ops(options);
438 mplib_data = mplib_make_data();
440 options->userdata = (void *)mplib_data;
441 options->noninteractive = 1; /* required ! */
442 options->print_found_names = 0;
443 if (lua_type(L,1)==LUA_TTABLE) {
444 for (i=0;mplib_parms[i].name!=NULL;i++) {
445 lua_getfield(L,1,mplib_parms[i].name);
446 if (lua_isnil(L,-1)) {
448 continue; /* skip unset */
450 switch(mplib_parms[i].idx) {
452 options->error_line = lua_tointeger(L,-1);
455 options->half_error_line = lua_tointeger(L,-1);
458 options->max_print_line = lua_tointeger(L,-1);
461 options->main_memory = lua_tointeger(L,-1);
464 options->hash_size = lua_tointeger(L,-1);
467 options->hash_prime = lua_tointeger(L,-1);
470 options->param_size = lua_tointeger(L,-1);
473 options->max_in_open = lua_tointeger(L,-1);
476 options->random_seed = lua_tointeger(L,-1);
479 options->interaction = luaL_checkoption(L,-1,"errorstopmode", interaction_options);
482 options->ini_version = lua_toboolean(L,-1);
485 options->troff_mode = lua_toboolean(L,-1);
488 options->print_found_names = lua_toboolean(L,-1);
492 options->command_line = strdup((char *)lua_tostring(L,-1));
496 options->mem_name = strdup((char *)lua_tostring(L,-1));
499 options->job_name = strdup((char *)lua_tostring(L,-1));
502 if(mplib_find_file_function(L)) { /* error here */
503 fprintf(stdout,"Invalid arguments to mp.new({find_file=...})\n");
512 *mp_ptr = mp_new(options);
513 xfree(options->command_line);
514 xfree(options->mem_name);
515 xfree(options->job_name);
518 luaL_getmetatable(L,MPLIB_METATABLE);
519 lua_setmetatable(L,-2);
528 mplib_collect (lua_State *L) {
529 MP *mp_ptr = is_mp(L,1);
535 mplib_tostring (lua_State *L) {
536 MP *mp_ptr = is_mp(L,1);
538 lua_pushfstring(L,"<MP %p>",*mp_ptr);
545 mplib_wrapresults(lua_State *L, mplib_instance *mplib_data, int h) {
548 if (mplib_data->term_out != NULL) {
549 lua_pushstring(L,mplib_data->term_out);
550 lua_setfield(L,-2,"term");
551 xfree(mplib_data->term_out);
553 if (mplib_data->error_out != NULL) {
554 lua_pushstring(L,mplib_data->error_out);
555 lua_setfield(L,-2,"error");
556 xfree(mplib_data->error_out);
558 if (mplib_data->log_out != NULL ) {
559 lua_pushstring(L,mplib_data->log_out);
560 lua_setfield(L,-2,"log");
561 xfree(mplib_data->log_out);
563 if (mplib_data->edges != NULL ) {
564 struct mp_edge_object **v;
565 struct mp_edge_object *p = mplib_data->edges;
569 v = lua_newuserdata (L, sizeof(struct mp_edge_object *));
571 luaL_getmetatable(L,MPLIB_FIG_METATABLE);
572 lua_setmetatable(L,-2);
573 lua_rawseti(L,-2,i); i++;
576 lua_setfield(L,-2,"fig");
577 mplib_data->edges = NULL;
580 lua_setfield(L,-2,"status");
585 mplib_execute (lua_State *L) {
587 MP *mp_ptr = is_mp(L,1);
588 if (*mp_ptr!=NULL && lua_isstring(L,2)) {
589 mplib_instance *mplib_data = mplib_get_data(*mp_ptr);
590 mplib_data->input_data = (char *)lua_tolstring(L,2, &(mplib_data->input_data_len));
591 mplib_data->input_data_ptr = mplib_data->input_data;
592 if ((*mp_ptr)->run_state==0) {
593 h = mp_initialize(*mp_ptr);
595 h = mp_execute(*mp_ptr);
596 if (mplib_data->input_data_len!=0) {
597 xfree(mplib_data->input_data);
598 xfree(mplib_data->input_data_ptr);
599 mplib_data->input_data_len=0;
601 return mplib_wrapresults(L, mplib_data, h);
609 mplib_finish (lua_State *L) {
610 MP *mp_ptr = is_mp(L,1);
612 mplib_instance *mplib_data = mplib_get_data(*mp_ptr);
613 int h = mp_finish(*mp_ptr);
614 return mplib_wrapresults(L, mplib_data, h);
624 mplib_fig_collect (lua_State *L) {
625 struct mp_edge_object **hh = is_fig(L,1);
627 mp_gr_toss_objects (*hh);
634 mplib_fig_body (lua_State *L) {
636 struct mp_graphic_object **v;
637 struct mp_graphic_object *p;
638 struct mp_edge_object **hh = is_fig(L,1);
642 v = lua_newuserdata (L, sizeof(struct mp_graphic_object *));
644 luaL_getmetatable(L,MPLIB_GR_METATABLE);
645 lua_setmetatable(L,-2);
646 lua_rawseti(L,-2,i); i++;
649 (*hh)->body = NULL; /* prevent double free */
654 mplib_fig_body_copy (lua_State *L) {
656 struct mp_graphic_object **v;
657 struct mp_graphic_object *p;
658 struct mp_edge_object **hh = is_fig(L,1);
662 v = lua_newuserdata (L, sizeof(struct mp_graphic_object *));
663 *v = mp_gr_copy_object(p);
664 luaL_getmetatable(L,MPLIB_GR_METATABLE);
665 lua_setmetatable(L,-2);
666 lua_rawseti(L,-2,i); i++;
674 mplib_fig_tostring (lua_State *L) {
675 struct mp_edge_object **hh = is_fig(L,1);
676 lua_pushfstring(L,"<figure %p>",*hh);
683 mp_wrapped_shipout (struct mp_edge_object *hh, int prologues, int procset) {
685 if (setjmp(mp->jump_buf)) {
688 mp_gr_ship_out(hh,prologues,procset);
693 mplib_fig_postscript (lua_State *L) {
694 struct mp_edge_object **hh = is_fig(L,1);
695 int prologues = luaL_optnumber(L,2,-1);
696 int procset = luaL_optnumber(L,3,-1);
697 mplib_instance *mplib_data = mplib_get_data((*hh)->_parent);
698 if (mplib_data->ps_out == NULL) {
699 if (mp_wrapped_shipout(*hh,prologues, procset)) {
700 if (mplib_data->ps_out!=NULL ) {
701 lua_pushstring(L, mplib_data->ps_out);
702 xfree(mplib_data->ps_out);
709 lua_pushstring(L,mplib_data->log_out);
710 xfree(mplib_data->ps_out);
719 mplib_fig_filename (lua_State *L) {
720 struct mp_edge_object **hh = is_fig(L,1);
722 char *s = (*hh)->_filename;
732 mplib_fig_bb (lua_State *L) {
733 struct mp_edge_object **hh = is_fig(L,1);
735 lua_pushnumber(L, (double)(*hh)->_minx/65536.0);
737 lua_pushnumber(L, (double)(*hh)->_miny/65536.0);
739 lua_pushnumber(L, (double)(*hh)->_maxx/65536.0);
741 lua_pushnumber(L, (double)(*hh)->_maxy/65536.0);
749 mplib_gr_collect (lua_State *L) {
750 struct mp_graphic_object **hh = is_gr_object(L,1);
752 mp_gr_toss_object(*hh);
759 mplib_gr_tostring (lua_State *L) {
760 struct mp_graphic_object **hh = is_gr_object(L,1);
761 lua_pushfstring(L,"<object %p>",*hh);
766 mplib_push_number (lua_State *L, integer x ) {
769 lua_pushnumber(L, y);
773 mplib_push_path (lua_State *L, struct mp_knot *h ) {
774 struct mp_knot *p; /* for scanning the path */
781 lua_pushstring(L,knot_originator_enum[p->originator_field]);
782 lua_setfield(L,-2,"originator");
783 lua_pushstring(L,knot_type_enum[p->left_type_field]);
784 lua_setfield(L,-2,"left_type");
785 lua_pushstring(L,knot_type_enum[p->right_type_field]);
786 lua_setfield(L,-2,"right_type");
787 mplib_push_number(L,p->x_coord_field);
788 lua_setfield(L,-2,"x_coord");
789 mplib_push_number(L,p->y_coord_field);
790 lua_setfield(L,-2,"y_coord");
791 mplib_push_number(L,p->left_x_field);
792 lua_setfield(L,-2,"left_x");
793 mplib_push_number(L,p->left_y_field);
794 lua_setfield(L,-2,"left_y");
795 mplib_push_number(L,p->right_x_field);
796 lua_setfield(L,-2,"right_x");
797 mplib_push_number(L,p->right_y_field);
798 lua_setfield(L,-2,"right_y");
799 lua_rawseti(L,-2,i); i++;
800 if ( p->right_type_field==mp_endpoint ) {
811 mplib_push_color (lua_State *L, struct mp_graphic_object *h ) {
814 lua_pushstring(L,color_model_enum[h->color_model_field]);
815 lua_setfield(L,-2,"model");
817 if (h->color_model_field == mp_rgb_model ||
818 h->color_model_field == mp_uninitialized_model) {
820 mplib_push_number(L,h->color_field.rgb._red_val);
822 mplib_push_number(L,h->color_field.rgb._green_val);
824 mplib_push_number(L,h->color_field.rgb._blue_val);
826 lua_setfield(L,-2,"rgb");
829 if (h->color_model_field == mp_cmyk_model ||
830 h->color_model_field == mp_uninitialized_model) {
832 mplib_push_number(L,h->color_field.cmyk._cyan_val);
834 mplib_push_number(L,h->color_field.cmyk._magenta_val);
836 mplib_push_number(L,h->color_field.cmyk._yellow_val);
838 mplib_push_number(L,h->color_field.cmyk._black_val);
840 lua_setfield(L,-2,"cmyk");
842 if (h->color_model_field == mp_grey_model ||
843 h->color_model_field == mp_uninitialized_model) {
845 mplib_push_number(L,h->color_field.grey._grey_val);
847 lua_setfield(L,-2,"grey");
855 /* dashes are complicated, perhaps it would be better if the
856 object had a PS-compatible representation */
858 mplib_push_dash (lua_State *L, struct mp_graphic_object *h ) {
861 mplib_push_number(L,h->dash_scale_field);
862 lua_setfield(L,-2,"scale");
864 lua_pushnumber(L,(int)h->dash_p_field);
865 lua_setfield(L,-2,"dashes");
872 mplib_push_transform (lua_State *L, struct mp_graphic_object *h ) {
876 mplib_push_number(L,h->tx_field);
877 lua_rawseti(L,-2,i); i++;
878 mplib_push_number(L,h->ty_field);
879 lua_rawseti(L,-2,i); i++;
880 mplib_push_number(L,h->txx_field);
881 lua_rawseti(L,-2,i); i++;
882 mplib_push_number(L,h->txy_field);
883 lua_rawseti(L,-2,i); i++;
884 mplib_push_number(L,h->tyx_field);
885 lua_rawseti(L,-2,i); i++;
886 mplib_push_number(L,h->tyy_field);
887 lua_rawseti(L,-2,i); i++;
895 mplib_fill_field (lua_State *L, struct mp_graphic_object *h, char *field) {
897 lua_pushstring(L,"fill");
898 } else if (FIELD(path)) {
899 mplib_push_path(L, h->path_p_field);
900 } else if (FIELD(htap)) {
901 mplib_push_path(L, h->htap_p_field);
902 } else if (FIELD(pen)) {
903 mplib_push_path(L, h->pen_p_field);
904 } else if (FIELD(color)) {
905 mplib_push_color(L, h);
906 } else if (FIELD(linejoin)) {
907 lua_pushnumber(L,h->ljoin_field);
908 } else if (FIELD(miterlimit)) {
909 mplib_push_number(L,h->miterlim_field);
910 } else if (FIELD(prescript)) {
911 lua_pushstring(L,h->pre_script_field);
912 } else if (FIELD(postscript)) {
913 lua_pushstring(L,h->post_script_field);
920 mplib_stroked_field (lua_State *L, struct mp_graphic_object *h, char *field) {
922 lua_pushstring(L,"outline");
923 } else if (FIELD(path)) {
924 mplib_push_path(L, h->path_p_field);
925 } else if (FIELD(pen)) {
926 mplib_push_path(L, h->pen_p_field);
927 } else if (FIELD(color)) {
928 mplib_push_color(L, h);
929 } else if (FIELD(dash)) {
930 mplib_push_dash(L, h);
931 } else if (FIELD(linecap)) {
932 lua_pushnumber(L,h->lcap_field);
933 } else if (FIELD(linejoin)) {
934 lua_pushnumber(L,h->ljoin_field);
935 } else if (FIELD(miterlimit)) {
936 mplib_push_number(L,h->miterlim_field);
937 } else if (FIELD(prescript)) {
938 lua_pushstring(L,h->pre_script_field);
939 } else if (FIELD(postscript)) {
940 lua_pushstring(L,h->post_script_field);
947 mplib_text_field (lua_State *L, struct mp_graphic_object *h, char *field) {
950 lua_pushstring(L,"text");
951 } else if (FIELD(text)) {
952 lua_pushstring(L,h->text_p_field);
953 } else if (FIELD(dsize)) {
954 lua_pushnumber(L,h->font_dsize_field);
955 } else if (FIELD(font)) {
956 lua_pushstring(L,h->font_name_field);
957 } else if (FIELD(color)) {
958 mplib_push_color(L, h);
959 } else if (FIELD(width)) {
960 mplib_push_number(L,h->width_field);
961 } else if (FIELD(height)) {
962 mplib_push_number(L,h->height_field);
963 } else if (FIELD(depth)) {
964 mplib_push_number(L,h->depth_field);
965 } else if (FIELD(transform)) {
966 mplib_push_transform(L,h);
967 } else if (FIELD(prescript)) {
968 lua_pushstring(L,h->pre_script_field);
969 } else if (FIELD(postscript)) {
970 lua_pushstring(L,h->post_script_field);
977 mplib_special_field (lua_State *L, struct mp_graphic_object *h, char *field) {
979 lua_pushstring(L,"special");
980 } else if (FIELD(prescript)) {
981 lua_pushstring(L,h->pre_script_field);
988 mplib_start_bounds_field (lua_State *L, struct mp_graphic_object *h, char *field) {
990 lua_pushstring(L,"start_bounds");
991 } else if (FIELD(path)) {
992 mplib_push_path(L,h->path_p_field);
999 mplib_start_clip_field (lua_State *L, struct mp_graphic_object *h, char *field) {
1001 lua_pushstring(L,"start_clip");
1002 } else if (FIELD(path)) {
1003 mplib_push_path(L,h->path_p_field);
1010 mplib_stop_bounds_field (lua_State *L, struct mp_graphic_object *h, char *field) {
1011 if (h!=NULL && FIELD(type)) {
1012 lua_pushstring(L,"stop_bounds");
1019 mplib_stop_clip_field (lua_State *L, struct mp_graphic_object *h, char *field) {
1020 if (h!=NULL && FIELD(type)) {
1021 lua_pushstring(L,"stop_clip");
1028 mplib_gr_fields (lua_State *L) {
1029 const char **fields;
1032 struct mp_graphic_object **hh = is_gr_object(L,1);
1034 switch ((*hh)->_type_field) {
1035 case mp_fill_code: fields = fill_fields; break;
1036 case mp_stroked_code: fields = stroked_fields; break;
1037 case mp_text_code: fields = text_fields; break;
1038 case mp_special_code: fields = special_fields; break;
1039 case mp_start_clip_code: fields = start_clip_fields; break;
1040 case mp_start_bounds_code: fields = start_bounds_fields; break;
1041 case mp_stop_clip_code: fields = stop_clip_fields; break;
1042 case mp_stop_bounds_code: fields = stop_bounds_fields; break;
1043 default: fields = no_fields;
1046 for (f = *fields; f != NULL; f++) {
1047 lua_pushstring(L,f);
1048 lua_rawseti(L,-2,i); i++;
1057 mplib_gr_index (lua_State *L) {
1058 struct mp_graphic_object **hh = is_gr_object(L,1);
1059 char *field = (char *)luaL_checkstring(L,2);
1061 switch ((*hh)->_type_field) {
1062 case mp_fill_code: mplib_fill_field(L,*hh,field); break;
1063 case mp_stroked_code: mplib_stroked_field(L,*hh,field); break;
1064 case mp_text_code: mplib_text_field(L,*hh,field); break;
1065 case mp_special_code: mplib_special_field(L,*hh,field); break;
1066 case mp_start_clip_code: mplib_start_clip_field(L,*hh,field); break;
1067 case mp_start_bounds_code: mplib_start_bounds_field(L,*hh,field); break;
1068 case mp_stop_clip_code: mplib_stop_clip_field(L,*hh,field); break;
1069 case mp_stop_bounds_code: mplib_stop_bounds_field(L,*hh,field); break;
1070 default: lua_pushnil(L);
1079 static const struct luaL_reg mplib_meta[] = {
1080 {"__gc", mplib_collect},
1081 {"__tostring", mplib_tostring},
1082 {NULL, NULL} /* sentinel */
1085 static const struct luaL_reg mplib_fig_meta[] = {
1086 {"__gc", mplib_fig_collect },
1087 {"__tostring", mplib_fig_tostring },
1088 {"objects", mplib_fig_body },
1089 {"copy_objects", mplib_fig_copy_body },
1090 {"filename", mplib_fig_filename },
1091 {"postscript", mplib_fig_postscript },
1092 {"boundingbox", mplib_fig_bb },
1093 {NULL, NULL} /* sentinel */
1096 static const struct luaL_reg mplib_gr_meta[] = {
1097 {"__gc", mplib_gr_collect },
1098 {"__tostring", mplib_gr_tostring },
1099 {"__index", mplib_gr_index },
1100 {"fields", mplib_gr_fields },
1101 {NULL, NULL} /* sentinel */
1105 static const struct luaL_reg mplib_d [] = {
1106 {"execute", mplib_execute },
1107 {"finish", mplib_finish },
1108 {NULL, NULL} /* sentinel */
1112 static const struct luaL_reg mplib_m[] = {
1114 {NULL, NULL} /* sentinel */
1119 luaopen_mp (lua_State *L) {
1120 luaL_newmetatable(L,MPLIB_GR_METATABLE);
1121 lua_pushvalue(L, -1); /* push metatable */
1122 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
1123 luaL_register(L, NULL, mplib_gr_meta); /* object meta methods */
1126 luaL_newmetatable(L,MPLIB_FIG_METATABLE);
1127 lua_pushvalue(L, -1); /* push metatable */
1128 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
1129 luaL_register(L, NULL, mplib_fig_meta); /* figure meta methods */
1132 luaL_newmetatable(L,MPLIB_METATABLE);
1133 lua_pushvalue(L, -1); /* push metatable */
1134 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
1135 luaL_register(L, NULL, mplib_meta); /* meta methods */
1136 luaL_register(L, NULL, mplib_d); /* dict methods */
1137 luaL_register(L, "mplib", mplib_m); /* module functions */