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)
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)
32 P__ZERO, P_ERROR_LINE, P_HALF_LINE, P_MAX_LINE, P_MAIN_MEMORY,
33 P_HASH_SIZE, P_HASH_PRIME, P_PARAM_SIZE, P_IN_OPEN, P_RANDOM_SEED,
34 P_INTERACTION, P_INI_VERSION, P_TROFF_MODE, P_PRINT_NAMES, P_COMMAND_LINE,
35 P_MEM_NAME, P_JOB_NAME, P_FIND_FILE, P_OPEN_FILE, P_CLOSE_FILE,
36 P_EOF_FILE, P_FLUSH_FILE, P_WRITE_ASCII, P_READ_ASCII, P_WRITE_BINARY,
37 P_READ_BINARY, P_RUN_EDITOR, P_RUN_MAKEMPX, P_SHIPOUT, P__SENTINEL,
41 const char *name; /* parameter name */
42 parm_idx idx; /* parameter index */
43 int class; /* parameter class */
46 const char *interaction_options[] =
47 { "unknownmode","batchmode","nonstopmode","scrollmode","errorstopmode", NULL};
49 /* the third field (type) is currently not used */
51 mplib_parm_struct mplib_parms[] = {
52 {NULL, P__ZERO, 0 }, /* dummy; lua indices run from 1 */
53 {"error_line", P_ERROR_LINE, 'i' },
54 {"half_error_line", P_HALF_LINE, 'i' },
55 {"max_print_line", P_MAX_LINE, 'i' },
56 {"main_memory", P_MAIN_MEMORY, 'i' },
57 {"hash_size", P_HASH_SIZE, 'i' },
58 {"hash_prime", P_HASH_PRIME, 'i' },
59 {"param_size", P_PARAM_SIZE, 'i' },
60 {"max_in_open", P_IN_OPEN, 'i' },
61 {"random_seed", P_RANDOM_SEED, 'i' },
62 {"interaction", P_INTERACTION, 'e' },
63 {"ini_version", P_INI_VERSION, 'b' },
64 {"troff_mode", P_TROFF_MODE, 'b' },
65 {"print_found_names", P_PRINT_NAMES, 'b' },
66 /* {"command_line", P_COMMAND_LINE,'s' }, */
67 {"mem_name", P_MEM_NAME, 's' },
68 {"job_name", P_JOB_NAME, 's' },
69 {"find_file", P_FIND_FILE, 'p' }, /* intercepted */
70 {NULL, P__SENTINEL, 0 }
73 typedef struct _FILE_ITEM {
77 typedef struct _FILE_ITEM File;
79 /* Start by defining all the callback routines for the library
80 * except |run_make_mpx| and |run_editor|.
83 char *mplib_filetype_names[] = {"term", "error", "mp", "log", "ps",
84 "mem", "tfm", "map", "pfb", "enc", NULL};
88 char *mplib_find_file (char *fname, char *fmode, int ftype) {
92 lua_getfield(L,LUA_REGISTRYINDEX,"mplib_file_finder");
93 if (lua_isfunction(L,-1)) {
94 char *s = NULL, *x = NULL;
95 lua_pushstring(L, fname);
96 lua_pushstring(L, fmode);
97 if (ftype >= mp_filetype_text) {
98 lua_pushnumber(L, ftype-mp_filetype_text);
100 lua_pushstring(L, mplib_filetype_names[ftype]);
102 if(lua_pcall(L,3,1,0) != 0) {
103 fprintf(stdout,"Error in mp.find_file: %s\n", (char *)lua_tostring(L,-1));
106 x = (char *)lua_tostring(L,-1);
109 lua_pop(L,1); /* pop the string */
115 if (fmode[0] != 'r' || (! access (fname,R_OK)) || ftype) {
116 return strdup(fname);
122 mplib_find_file_function (lua_State *L) {
123 if (lua_isfunction(L,-1)) {
125 } else if (lua_isnil(L,-1)) {
128 return 1; /* error */
130 lua_pushstring(L, "mplib_file_finder");
132 lua_rawset(L,LUA_REGISTRYINDEX);
136 void *term_file_ptr = NULL;
137 void *err_file_ptr = NULL;
138 void *log_file_ptr = NULL;
139 void *ps_file_ptr = NULL;
141 void *mplib_open_file(char *fname, char *fmode, int ftype) {
142 File *ff = malloc(sizeof (File));
145 if (ftype==mp_filetype_terminal) {
146 if (fmode[0] == 'r') {
149 xfree(term_file_ptr);
151 term_file_ptr = ff->f;
153 } else if (ftype==mp_filetype_error) {
156 err_file_ptr = ff->f;
157 } else if (ftype == mp_filetype_log) {
160 log_file_ptr = ff->f;
161 } else if (ftype == mp_filetype_postscript) {
167 if (fmode[0] == 'r') {
168 f = mplib_find_file(fname,fmode,ftype);
172 ff->f = fopen(f, fmode);
173 if ((fmode[0] == 'r') && (ff->f == NULL)) {
183 static char * input_data = NULL;
184 static char * input_data_ptr = NULL;
185 static size_t input_data_len = 0;
188 mplib_get_char (void *f) {
190 if (f==stdin && input_data != NULL) {
191 if (input_data_len==0) {
192 if (input_data_ptr!=NULL)
193 input_data_ptr = NULL;
199 c = *input_data_ptr++;
208 mplib_unget_char (void *f, int c) {
209 if (f==stdin && input_data_ptr != NULL) {
218 char *mplib_read_ascii_file (void *ff, size_t *size) {
220 size_t len = 0, lim = 128;
223 FILE *f = ((File *)ff)->f;
227 c = mplib_get_char(f);
231 if (s==NULL) return NULL;
232 while (c!=EOF && c!='\n' && c!='\r') {
234 s =realloc(s, (lim+(lim>>2)));
235 if (s==NULL) return NULL;
239 c = mplib_get_char(f);
242 c = mplib_get_char(f);
243 if (c!=EOF && c!='\n')
244 mplib_unget_char(f,c);
252 static char *term_out = NULL;
253 static char *error_out = NULL;
254 static char *log_out = NULL;
255 static char *ps_out = NULL;
257 #define APPEND_STRING(a,b) do { \
261 a = realloc(a, strlen(a)+strlen(b)+1); \
262 strcpy(a+strlen(a),b); \
266 void mplib_write_ascii_file (void *ff, char *s) {
268 void *f = ((File *)ff)->f;
270 if (f==term_file_ptr) {
271 APPEND_STRING(term_out,s);
272 } else if (f==err_file_ptr) {
273 APPEND_STRING(error_out,s);
274 } else if (f==log_file_ptr) {
275 APPEND_STRING(log_out,s);
276 } else if (f==ps_file_ptr) {
277 APPEND_STRING(ps_out,s);
279 fprintf((FILE *)f,s);
285 void mplib_read_binary_file (void *ff, void **data, size_t *size) {
288 FILE *f = ((File *)ff)->f;
290 len = fread(*data,1,*size,f);
295 void mplib_write_binary_file (void *ff, void *s, size_t size) {
297 FILE *f = ((File *)ff)->f;
304 void mplib_close_file (void *ff) {
306 void *f = ((File *)ff)->f;
307 if (f != NULL && f != term_file_ptr && f != err_file_ptr
308 && f != log_file_ptr && f != ps_file_ptr) {
315 int mplib_eof_file (void *ff) {
317 FILE *f = ((File *)ff)->f;
320 if (f==stdin && input_data != NULL) {
321 return (input_data_len==0);
328 void mplib_flush_file (void *ff) {
332 static struct mp_edge_object *edges = NULL;
334 #define APPEND_TO_EDGES(a) do { \
338 struct mp_edge_object *p = edges; \
339 while (p->_next!=NULL) { p = p->_next; } \
344 void mplib_shipout_backend (MP mp, int h) {
345 struct mp_edge_object *hh;
346 hh = mp_gr_export(mp, h);
354 mplib_setup_file_ops(struct MP_options * options) {
355 options->find_file = mplib_find_file;
356 options->open_file = mplib_open_file;
357 options->close_file = mplib_close_file;
358 options->eof_file = mplib_eof_file;
359 options->flush_file = mplib_flush_file;
360 options->write_ascii_file = mplib_write_ascii_file;
361 options->read_ascii_file = mplib_read_ascii_file;
362 options->write_binary_file = mplib_write_binary_file;
363 options->read_binary_file = mplib_read_binary_file;
364 options->shipout_backend = mplib_shipout_backend;
368 mplib_new (lua_State *L) {
371 struct MP_options * options; /* instance options */
372 mp_ptr = lua_newuserdata(L, sizeof(MP *));
374 options = mp_options();
375 mplib_setup_file_ops(options);
376 options->noninteractive = 1; /* required ! */
377 options->print_found_names = 0;
378 if (lua_type(L,1)==LUA_TTABLE) {
379 for (i=1;mplib_parms[i].name!=NULL;i++) {
380 lua_getfield(L,1,mplib_parms[i].name);
381 if (lua_isnil(L,-1)) {
383 continue; /* skip unset */
385 switch(mplib_parms[i].idx) {
387 options->error_line = lua_tointeger(L,-1);
390 options->half_error_line = lua_tointeger(L,-1);
393 options->max_print_line = lua_tointeger(L,-1);
396 options->main_memory = lua_tointeger(L,-1);
399 options->hash_size = lua_tointeger(L,-1);
402 options->hash_prime = lua_tointeger(L,-1);
405 options->param_size = lua_tointeger(L,-1);
408 options->max_in_open = lua_tointeger(L,-1);
411 options->random_seed = lua_tointeger(L,-1);
414 options->interaction = luaL_checkoption(L,-1,"errorstopmode", interaction_options);
417 options->ini_version = lua_toboolean(L,-1);
420 options->troff_mode = lua_toboolean(L,-1);
423 options->print_found_names = lua_toboolean(L,-1);
427 options->command_line = strdup((char *)lua_tostring(L,-1));
431 options->mem_name = strdup((char *)lua_tostring(L,-1));
434 options->job_name = strdup((char *)lua_tostring(L,-1));
437 if(mplib_find_file_function(L)) { /* error here */
438 fprintf(stdout,"Invalid arguments to mp.new({find_file=...})\n");
447 *mp_ptr = mp_new(options);
448 xfree(options->command_line);
449 xfree(options->mem_name);
450 xfree(options->job_name);
453 luaL_getmetatable(L,MPLIB_METATABLE);
454 lua_setmetatable(L,-2);
463 mplib_collect (lua_State *L) {
464 MP *mp_ptr = is_mp(L,1);
473 mplib_tostring (lua_State *L) {
474 MP *mp_ptr = is_mp(L,1);
476 lua_pushfstring(L,"<MP %p>",*mp_ptr);
483 mplib_wrapresults(lua_State *L,int h) {
486 if (term_out != NULL) {
487 lua_pushstring(L,term_out);
488 lua_setfield(L,-2,"term");
489 free(term_out); term_out = NULL;
491 if (error_out != NULL) {
492 lua_pushstring(L,error_out);
493 lua_setfield(L,-2,"error");
494 free(error_out); error_out = NULL;
496 if (log_out != NULL ) {
497 lua_pushstring(L,log_out);
498 lua_setfield(L,-2,"log");
499 free(log_out); log_out = NULL;
501 if (edges != NULL ) {
502 struct mp_edge_object **v;
503 struct mp_edge_object *p = edges;
507 v = lua_newuserdata (L, sizeof(struct mp_edge_object *));
509 luaL_getmetatable(L,MPLIB_FIG_METATABLE);
510 lua_setmetatable(L,-2);
511 lua_rawseti(L,-2,i); i++;
514 lua_setfield(L,-2,"fig");
518 lua_setfield(L,-2,"status");
523 mplib_execute (lua_State *L) {
525 MP *mp_ptr = is_mp(L,1);
526 if (*mp_ptr!=NULL && lua_isstring(L,2)) {
527 if (input_data_len>0) { /* this should NOT happen */
528 fprintf(stderr,"Can't do concurrency yet!\n");
530 input_data = (char *)lua_tolstring(L,2, &input_data_len);
531 input_data_ptr = input_data;
532 if ((*mp_ptr)->run_state==0) {
533 h = mp_initialize(*mp_ptr);
535 h = mp_execute(*mp_ptr);
536 return mplib_wrapresults(L, h);
546 mplib_finish (lua_State *L) {
547 MP *mp_ptr = is_mp(L,1);
549 int h = mp_finish(*mp_ptr);
550 return mplib_wrapresults(L, h);
560 mplib_fig_collect (lua_State *L) {
561 struct mp_edge_object **hh = is_fig(L,1);
563 mp_gr_toss_objects (*hh);
570 mplib_fig_body (lua_State *L) {
572 struct mp_graphic_object **v;
573 struct mp_graphic_object *p;
574 struct mp_edge_object **hh = is_fig(L,1);
578 v = lua_newuserdata (L, sizeof(struct mp_graphic_object *));
580 luaL_getmetatable(L,MPLIB_GR_METATABLE);
581 lua_setmetatable(L,-2);
582 lua_rawseti(L,-2,i); i++;
585 (*hh)->body = NULL; /* prevent double free */
591 mplib_fig_tostring (lua_State *L) {
592 struct mp_edge_object **hh = is_fig(L,1);
593 lua_pushfstring(L,"<figure %p>",*hh);
600 mp_wrapped_shipout (struct mp_edge_object *hh, int prologues, int procset) {
602 if (setjmp(mp->jump_buf)) {
605 mp_gr_ship_out(hh,prologues,procset);
610 mplib_fig_postscript (lua_State *L) {
611 struct mp_edge_object **hh = is_fig(L,1);
612 int prologues = luaL_optnumber(L,2,-1);
613 int procset = luaL_optnumber(L,3,-1);
614 if (ps_out == NULL) {
615 if (mp_wrapped_shipout(*hh,prologues, procset)) {
617 lua_pushstring(L, ps_out);
618 free(ps_out); ps_out = NULL;
625 lua_pushstring(L,log_out);
626 free(ps_out); ps_out = NULL;
635 mplib_fig_filename (lua_State *L) {
636 struct mp_edge_object **hh = is_fig(L,1);
638 char *s = (*hh)->_filename;
648 mplib_fig_bb (lua_State *L) {
649 struct mp_edge_object **hh = is_fig(L,1);
651 lua_pushnumber(L, (double)(*hh)->_minx/65536.0);
653 lua_pushnumber(L, (double)(*hh)->_miny/65536.0);
655 lua_pushnumber(L, (double)(*hh)->_maxx/65536.0);
657 lua_pushnumber(L, (double)(*hh)->_maxy/65536.0);
665 mplib_gr_collect (lua_State *L) {
666 struct mp_graphic_object **hh = is_gr_object(L,1);
668 mp_gr_toss_object(*hh);
675 mplib_gr_tostring (lua_State *L) {
676 struct mp_graphic_object **hh = is_gr_object(L,1);
677 lua_pushfstring(L,"<object %p>",*hh);
681 /* only "endpoint" and "explicit" actually happen */
683 char *knot_type_enum[] = {
684 "endpoint", "explicit", "given", "curl", "open", "end_cycle"
687 char *knot_originator_enum[] = { "program" ,"user" };
690 mplib_push_number (lua_State *L, integer x ) {
693 lua_pushnumber(L, y);
697 mplib_push_path (lua_State *L, struct mp_knot *h ) {
698 struct mp_knot *p; /* for scanning the path */
705 lua_pushstring(L,knot_originator_enum[p->originator_field]);
706 lua_setfield(L,-2,"originator");
707 lua_pushstring(L,knot_type_enum[p->left_type_field]);
708 lua_setfield(L,-2,"left_type");
709 lua_pushstring(L,knot_type_enum[p->right_type_field]);
710 lua_setfield(L,-2,"right_type");
711 mplib_push_number(L,p->x_coord_field);
712 lua_setfield(L,-2,"x_coord");
713 mplib_push_number(L,p->y_coord_field);
714 lua_setfield(L,-2,"y_coord");
715 mplib_push_number(L,p->left_x_field);
716 lua_setfield(L,-2,"left_x");
717 mplib_push_number(L,p->left_y_field);
718 lua_setfield(L,-2,"left_y");
719 mplib_push_number(L,p->right_x_field);
720 lua_setfield(L,-2,"right_x");
721 mplib_push_number(L,p->right_y_field);
722 lua_setfield(L,-2,"right_y");
723 lua_rawseti(L,-2,i); i++;
724 if ( p->right_type_field==mp_endpoint ) {
734 char *color_model_enum[] = { NULL, "none", NULL, "grey",
735 NULL, "rgb", NULL, "cmyk", NULL, "uninitialized" };
738 mplib_push_color (lua_State *L, struct mp_graphic_object *h ) {
741 lua_pushstring(L,color_model_enum[h->color_model_field]);
742 lua_setfield(L,-2,"model");
744 if (h->color_model_field == mp_rgb_model ||
745 h->color_model_field == mp_uninitialized_model) {
747 mplib_push_number(L,h->color_field.rgb._red_val);
749 mplib_push_number(L,h->color_field.rgb._green_val);
751 mplib_push_number(L,h->color_field.rgb._blue_val);
753 lua_setfield(L,-2,"rgb");
756 if (h->color_model_field == mp_cmyk_model ||
757 h->color_model_field == mp_uninitialized_model) {
759 mplib_push_number(L,h->color_field.cmyk._cyan_val);
761 mplib_push_number(L,h->color_field.cmyk._magenta_val);
763 mplib_push_number(L,h->color_field.cmyk._yellow_val);
765 mplib_push_number(L,h->color_field.cmyk._black_val);
767 lua_setfield(L,-2,"cmyk");
769 if (h->color_model_field == mp_grey_model ||
770 h->color_model_field == mp_uninitialized_model) {
772 mplib_push_number(L,h->color_field.grey._grey_val);
774 lua_setfield(L,-2,"grey");
782 /* dashes are complicated, perhaps it would be better if the
783 object had a PS-compatible representation */
785 mplib_push_dash (lua_State *L, struct mp_graphic_object *h ) {
788 mplib_push_number(L,h->dash_scale_field);
789 lua_setfield(L,-2,"scale");
791 lua_pushnumber(L,(int)h->dash_p_field);
792 lua_setfield(L,-2,"dashes");
799 mplib_push_transform (lua_State *L, struct mp_graphic_object *h ) {
803 mplib_push_number(L,h->tx_field);
804 lua_rawseti(L,-2,i); i++;
805 mplib_push_number(L,h->ty_field);
806 lua_rawseti(L,-2,i); i++;
807 mplib_push_number(L,h->txx_field);
808 lua_rawseti(L,-2,i); i++;
809 mplib_push_number(L,h->txy_field);
810 lua_rawseti(L,-2,i); i++;
811 mplib_push_number(L,h->tyx_field);
812 lua_rawseti(L,-2,i); i++;
813 mplib_push_number(L,h->tyy_field);
814 lua_rawseti(L,-2,i); i++;
820 static char *fill_fields[] = { "type", "path", "htap", "pen", "color", "linejoin", "miterlimit",
821 "prescript", "postscript", NULL };
823 #define FIELD(A) (strcmp(field,#A)==0)
826 mplib_fill_field (lua_State *L, struct mp_graphic_object *h, char *field) {
828 lua_pushstring(L,"fill");
829 } else if (FIELD(path)) {
830 mplib_push_path(L, h->path_p_field);
831 } else if (FIELD(htap)) {
832 mplib_push_path(L, h->htap_p_field);
833 } else if (FIELD(pen)) {
834 mplib_push_path(L, h->pen_p_field);
835 } else if (FIELD(color)) {
836 mplib_push_color(L, h);
837 } else if (FIELD(linejoin)) {
838 lua_pushnumber(L,h->ljoin_field);
839 } else if (FIELD(miterlimit)) {
840 mplib_push_number(L,h->miterlim_field);
841 } else if (FIELD(prescript)) {
842 lua_pushstring(L,h->pre_script_field);
843 } else if (FIELD(postscript)) {
844 lua_pushstring(L,h->post_script_field);
850 static char *stroked_fields[] = {"type", "path", "pen", "color", "linejoin", "miterlimit",
851 "linecap", "dash", "prescript", "postscript", NULL };
854 mplib_stroked_field (lua_State *L, struct mp_graphic_object *h, char *field) {
856 lua_pushstring(L,"outline");
857 } else if (FIELD(path)) {
858 mplib_push_path(L, h->path_p_field);
859 } else if (FIELD(pen)) {
860 mplib_push_path(L, h->pen_p_field);
861 } else if (FIELD(color)) {
862 mplib_push_color(L, h);
863 } else if (FIELD(dash)) {
864 mplib_push_dash(L, h);
865 } else if (FIELD(linecap)) {
866 lua_pushnumber(L,h->lcap_field);
867 } else if (FIELD(linejoin)) {
868 lua_pushnumber(L,h->ljoin_field);
869 } else if (FIELD(miterlimit)) {
870 mplib_push_number(L,h->miterlim_field);
871 } else if (FIELD(prescript)) {
872 lua_pushstring(L,h->pre_script_field);
873 } else if (FIELD(postscript)) {
874 lua_pushstring(L,h->post_script_field);
880 static char *text_fields[] = { "type", "text", "dsize", "font", "color",
881 "width", "height", "depth", "transform",
882 "prescript", "postscript", NULL };
885 mplib_text_field (lua_State *L, struct mp_graphic_object *h, char *field) {
888 lua_pushstring(L,"text");
889 } else if (FIELD(text)) {
890 lua_pushstring(L,h->text_p_field);
891 } else if (FIELD(dsize)) {
892 lua_pushnumber(L,h->font_dsize_field);
893 } else if (FIELD(font)) {
894 lua_pushstring(L,h->font_name_field);
895 } else if (FIELD(color)) {
896 mplib_push_color(L, h);
897 } else if (FIELD(width)) {
898 mplib_push_number(L,h->width_field);
899 } else if (FIELD(height)) {
900 mplib_push_number(L,h->height_field);
901 } else if (FIELD(depth)) {
902 mplib_push_number(L,h->depth_field);
903 } else if (FIELD(transform)) {
904 mplib_push_transform(L,h);
905 } else if (FIELD(prescript)) {
906 lua_pushstring(L,h->pre_script_field);
907 } else if (FIELD(postscript)) {
908 lua_pushstring(L,h->post_script_field);
914 static char *special_fields[] = { "type", "prescript", NULL };
917 mplib_special_field (lua_State *L, struct mp_graphic_object *h, char *field) {
919 lua_pushstring(L,"special");
920 } else if (FIELD(prescript)) {
921 lua_pushstring(L,h->pre_script_field);
927 static char *start_bounds_fields[] = { "type", "path", NULL };
930 mplib_start_bounds_field (lua_State *L, struct mp_graphic_object *h, char *field) {
932 lua_pushstring(L,"start_bounds");
933 } else if (FIELD(path)) {
934 mplib_push_path(L,h->path_p_field);
940 static char *start_clip_fields[] = { "type", "path", NULL };
943 mplib_start_clip_field (lua_State *L, struct mp_graphic_object *h, char *field) {
945 lua_pushstring(L,"start_clip");
946 } else if (FIELD(path)) {
947 mplib_push_path(L,h->path_p_field);
953 static char *stop_bounds_fields[] = { "type", NULL };
956 mplib_stop_bounds_field (lua_State *L, struct mp_graphic_object *h, char *field) {
957 if (h!=NULL && FIELD(type)) {
958 lua_pushstring(L,"stop_bounds");
964 static char *stop_clip_fields[] = { "type", NULL };
967 mplib_stop_clip_field (lua_State *L, struct mp_graphic_object *h, char *field) {
968 if (h!=NULL && FIELD(type)) {
969 lua_pushstring(L,"stop_clip");
975 static char *no_fields[] = { NULL };
978 mplib_gr_fields (lua_State *L) {
982 struct mp_graphic_object **hh = is_gr_object(L,1);
984 switch ((*hh)->_type_field) {
985 case mp_fill_code: fields = fill_fields; break;
986 case mp_stroked_code: fields = stroked_fields; break;
987 case mp_text_code: fields = text_fields; break;
988 case mp_special_code: fields = special_fields; break;
989 case mp_start_clip_code: fields = start_clip_fields; break;
990 case mp_start_bounds_code: fields = start_bounds_fields; break;
991 case mp_stop_clip_code: fields = stop_clip_fields; break;
992 case mp_stop_bounds_code: fields = stop_bounds_fields; break;
993 default: fields = no_fields;
996 for (f = *fields; f != NULL; f++) {
998 lua_rawseti(L,-2,i); i++;
1007 mplib_gr_index (lua_State *L) {
1008 struct mp_graphic_object **hh = is_gr_object(L,1);
1009 char *field = (char *)luaL_checkstring(L,2);
1011 switch ((*hh)->_type_field) {
1012 case mp_fill_code: mplib_fill_field(L,*hh,field); break;
1013 case mp_stroked_code: mplib_stroked_field(L,*hh,field); break;
1014 case mp_text_code: mplib_text_field(L,*hh,field); break;
1015 case mp_special_code: mplib_special_field(L,*hh,field); break;
1016 case mp_start_clip_code: mplib_start_clip_field(L,*hh,field); break;
1017 case mp_start_bounds_code: mplib_start_bounds_field(L,*hh,field); break;
1018 case mp_stop_clip_code: mplib_stop_clip_field(L,*hh,field); break;
1019 case mp_stop_bounds_code: mplib_stop_bounds_field(L,*hh,field); break;
1020 default: lua_pushnil(L);
1029 static const struct luaL_reg mplib_meta[] = {
1030 {"__gc", mplib_collect},
1031 {"__tostring", mplib_tostring},
1032 {NULL, NULL} /* sentinel */
1035 static const struct luaL_reg mplib_fig_meta[] = {
1036 {"__gc", mplib_fig_collect },
1037 {"__tostring", mplib_fig_tostring },
1038 {"objects", mplib_fig_body },
1039 {"filename", mplib_fig_filename },
1040 {"postscript", mplib_fig_postscript },
1041 {"boundingbox", mplib_fig_bb },
1042 {NULL, NULL} /* sentinel */
1045 static const struct luaL_reg mplib_gr_meta[] = {
1046 {"__gc", mplib_gr_collect },
1047 {"__tostring", mplib_gr_tostring },
1048 {"__index", mplib_gr_index },
1049 {"fields", mplib_gr_fields },
1050 {NULL, NULL} /* sentinel */
1054 static const struct luaL_reg mplib_d [] = {
1055 {"execute", mplib_execute },
1056 {"finish", mplib_finish },
1057 {NULL, NULL} /* sentinel */
1061 static const struct luaL_reg mplib_m[] = {
1063 {NULL, NULL} /* sentinel */
1068 luaopen_mp (lua_State *L) {
1069 luaL_newmetatable(L,MPLIB_GR_METATABLE);
1070 lua_pushvalue(L, -1); /* push metatable */
1071 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
1072 luaL_register(L, NULL, mplib_gr_meta); /* object meta methods */
1075 luaL_newmetatable(L,MPLIB_FIG_METATABLE);
1076 lua_pushvalue(L, -1); /* push metatable */
1077 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
1078 luaL_register(L, NULL, mplib_fig_meta); /* figure meta methods */
1081 luaL_newmetatable(L,MPLIB_METATABLE);
1082 lua_pushvalue(L, -1); /* push metatable */
1083 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
1084 luaL_register(L, NULL, mplib_meta); /* meta methods */
1085 luaL_register(L, NULL, mplib_d); /* dict methods */
1086 luaL_register(L, "mplib", mplib_m); /* module functions */