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 mplib_init_S(a) do { \
26 lua_pushliteral(L,#a); \
27 mplib_##a##_index = luaL_ref (L,LUA_REGISTRYINDEX); \
30 #define mplib_push_S(a) do { \
31 lua_rawgeti(L,LUA_REGISTRYINDEX,mplib_##a##_index); \
34 #define mplib_make_S(a) static int mplib_##a##_index = 0;
36 mplib_make_S(left_type);
37 mplib_make_S(right_type);
38 mplib_make_S(x_coord);
39 mplib_make_S(y_coord);
42 mplib_make_S(right_x);
43 mplib_make_S(right_y);
44 mplib_make_S(originator);
46 void mplib_init_Ses(lua_State *L) {
47 mplib_init_S(left_type);
48 mplib_init_S(right_type);
49 mplib_init_S(x_coord);
50 mplib_init_S(y_coord);
53 mplib_init_S(right_x);
54 mplib_init_S(right_y);
55 mplib_init_S(originator);
60 #define xfree(A) if ((A)!=NULL) { free((A)); A = NULL; }
62 #define is_mp(L,b) (MP *)luaL_checkudata(L,b,MPLIB_METATABLE)
63 #define is_fig(L,b) (struct mp_edge_object **)luaL_checkudata(L,b,MPLIB_FIG_METATABLE)
64 #define is_gr_object(L,b) (struct mp_graphic_object **)luaL_checkudata(L,b,MPLIB_GR_METATABLE)
66 /* Enumeration string arrays */
68 static const char *interaction_options[] =
69 { "unknown","batch","nonstop","scroll","errorstop", NULL};
71 static const char *mplib_filetype_names[] =
72 {"term", "error", "mp", "log", "ps", "mem", "tfm", "map", "pfb", "enc", NULL};
74 /* only "endpoint" and "explicit" actually happen in paths,
75 as well as "open" in elliptical pens */
77 static const char *knot_type_enum[] =
78 { "endpoint", "explicit", "given", "curl", "open", "end_cycle" };
80 static const char *knot_originator_enum[] =
81 { "program" ,"user" };
84 /* this looks a bit funny because of the holes */
86 static const char *color_model_enum[] =
87 { NULL, "none", NULL, "grey", NULL, "rgb", NULL, "cmyk", NULL, "uninitialized" };
91 #define FIELD(A) (strcmp(field,#A)==0)
93 static const char *fill_fields[] =
94 { "type", "path", "htap", "pen", "color", "linejoin", "miterlimit",
95 "prescript", "postscript", NULL };
97 static const char *stroked_fields[] =
98 { "type", "path", "pen", "color", "linejoin", "miterlimit", "linecap", "dash",
99 "prescript", "postscript", NULL };
101 static const char *text_fields[] =
102 { "type", "text", "dsize", "font", "color", "width", "height", "depth", "transform",
103 "prescript", "postscript", NULL };
105 static const char *special_fields[] =
106 { "type", "prescript", NULL };
108 static const char *start_bounds_fields[] =
109 { "type", "path", NULL };
111 static const char *start_clip_fields[] =
112 { "type", "path", NULL };
114 static const char *stop_bounds_fields[] =
117 static const char *stop_clip_fields[] =
120 static const char *no_fields[] =
124 P_ERROR_LINE, P_HALF_LINE, P_MAX_LINE, P_MAIN_MEMORY,
125 P_HASH_SIZE, P_HASH_PRIME, P_PARAM_SIZE, P_IN_OPEN, P_RANDOM_SEED,
126 P_INTERACTION, P_INI_VERSION, P_TROFF_MODE, P_PRINT_NAMES, P_MEM_NAME,
127 P_JOB_NAME, P_FIND_FILE, P__SENTINEL,
131 const char *name; /* parameter name */
132 mplib_parm_idx idx; /* parameter index */
135 static mplib_parm_struct mplib_parms[] = {
136 {"error_line", P_ERROR_LINE },
137 {"half_error_line", P_HALF_LINE },
138 {"max_print_line", P_MAX_LINE },
139 {"main_memory", P_MAIN_MEMORY },
140 {"hash_size", P_HASH_SIZE },
141 {"hash_prime", P_HASH_PRIME },
142 {"param_size", P_PARAM_SIZE },
143 {"max_in_open", P_IN_OPEN },
144 {"random_seed", P_RANDOM_SEED },
145 {"interaction", P_INTERACTION },
146 {"ini_version", P_INI_VERSION },
147 {"troff_mode", P_TROFF_MODE },
148 {"print_found_names", P_PRINT_NAMES },
149 {"mem_name", P_MEM_NAME },
150 {"job_name", P_JOB_NAME },
151 {"find_file", P_FIND_FILE },
155 typedef struct _FILE_ITEM {
159 typedef struct _FILE_ITEM File;
161 #define make_stream_buf(A) char *A; size_t A##_size; size_t A##_used
163 #define free_stream_buf(A) xfree(mplib_data->A); mplib_data->A##_size = 0; mplib_data->A##_used = 0
165 typedef struct _MPLIB_INSTANCE_DATA {
170 make_stream_buf(term_out);
171 make_stream_buf(error_out);
172 make_stream_buf(log_out);
173 make_stream_buf(ps_out);
175 char *input_data_ptr;
176 size_t input_data_len;
177 struct mp_edge_object *edges ;
179 } _MPLIB_INSTANCE_DATA;
181 typedef struct _MPLIB_INSTANCE_DATA mplib_instance;
183 static mplib_instance *mplib_get_data (MP mp) {
184 return (mplib_instance *)mp->userdata;
187 static mplib_instance *mplib_make_data (void) {
188 mplib_instance *mplib_data = malloc(sizeof(mplib_instance));
189 memset(mplib_data,0,sizeof(mplib_instance));
194 /* Start by defining all the callback routines for the library
195 * except |run_make_mpx| and |run_editor|.
199 char *mplib_find_file (MP mp, char *fname, char *fmode, int ftype) {
200 mplib_instance *mplib_data = mplib_get_data(mp);
201 lua_State *L = mplib_data->LL;
203 lua_getfield(L,LUA_REGISTRYINDEX,"mplib_file_finder");
204 if (lua_isfunction(L,-1)) {
205 char *s = NULL, *x = NULL;
206 lua_pushstring(L, fname);
207 lua_pushstring(L, fmode);
208 if (ftype >= mp_filetype_text) {
209 lua_pushnumber(L, ftype-mp_filetype_text);
211 lua_pushstring(L, mplib_filetype_names[ftype]);
213 if(lua_pcall(L,3,1,0) != 0) {
214 fprintf(stdout,"Error in mp.find_file: %s\n", (char *)lua_tostring(L,-1));
217 x = (char *)lua_tostring(L,-1);
220 lua_pop(L,1); /* pop the string */
225 if (fmode[0] != 'r' || (! access (fname,R_OK)) || ftype) {
226 return strdup(fname);
232 mplib_find_file_function (lua_State *L) {
233 if (! (lua_isfunction(L,-1)|| lua_isnil(L,-1) )) {
234 return 1; /* error */
236 lua_pushstring(L, "mplib_file_finder");
238 lua_rawset(L,LUA_REGISTRYINDEX);
242 void *mplib_open_file(MP mp, char *fname, char *fmode, int ftype) {
243 mplib_instance *mplib_data = mplib_get_data(mp);
244 File *ff = malloc(sizeof (File));
247 if (ftype==mp_filetype_terminal) {
248 if (fmode[0] == 'r') {
251 xfree(mplib_data->term_file_ptr);
253 mplib_data->term_file_ptr = ff->f;
255 } else if (ftype==mp_filetype_error) {
256 xfree(mplib_data->err_file_ptr);
258 mplib_data->err_file_ptr = ff->f;
259 } else if (ftype == mp_filetype_log) {
260 xfree(mplib_data->log_file_ptr);
262 mplib_data->log_file_ptr = ff->f;
263 } else if (ftype == mp_filetype_postscript) {
264 xfree(mplib_data->ps_file_ptr);
266 mplib_data->ps_file_ptr = ff->f;
269 if (fmode[0] == 'r') {
270 f = mplib_find_file(mp, fname,fmode,ftype);
274 ff->f = fopen(f, fmode);
275 if ((fmode[0] == 'r') && (ff->f == NULL)) {
286 mplib_get_char (void *f, mplib_instance *mplib_data) {
288 if (f==stdin && mplib_data->input_data != NULL) {
289 if (mplib_data->input_data_len==0) {
290 if (mplib_data->input_data_ptr!=NULL)
291 mplib_data->input_data_ptr = NULL;
293 mplib_data->input_data = NULL;
296 mplib_data->input_data_len--;
297 c = *(mplib_data->input_data_ptr)++;
306 mplib_unget_char (void *f, mplib_instance *mplib_data, int c) {
307 if (f==stdin && mplib_data->input_data_ptr != NULL) {
308 mplib_data->input_data_len++;
309 mplib_data->input_data_ptr--;
316 char *mplib_read_ascii_file (MP mp, void *ff, size_t *size) {
318 size_t len = 0, lim = 128;
320 mplib_instance *mplib_data = mplib_get_data(mp);
322 FILE *f = ((File *)ff)->f;
326 c = mplib_get_char(f,mplib_data);
330 if (s==NULL) return NULL;
331 while (c!=EOF && c!='\n' && c!='\r') {
333 s =realloc(s, (lim+(lim>>2)));
334 if (s==NULL) return NULL;
338 c = mplib_get_char(f,mplib_data);
341 c = mplib_get_char(f,mplib_data);
342 if (c!=EOF && c!='\n')
343 mplib_unget_char(f,mplib_data,c);
351 #define APPEND_STRING(a,b) do { \
352 if ((mplib_data->a##_used+strlen(b))>=mplib_data->a##_size) { \
353 mplib_data->a##_size += 256+(mplib_data->a##_size)/5+strlen(b); \
354 mplib_data->a = realloc(mplib_data->a,mplib_data->a##_size); \
356 (void)strcpy(mplib_data->a+mplib_data->a##_used,b); \
357 mplib_data->a##_used += strlen(b); \
360 void mplib_write_ascii_file (MP mp, void *ff, char *s) {
361 mplib_instance *mplib_data = mplib_get_data(mp);
363 void *f = ((File *)ff)->f;
365 if (f==mplib_data->term_file_ptr) {
366 APPEND_STRING(term_out,s);
367 } else if (f==mplib_data->err_file_ptr) {
368 APPEND_STRING(error_out,s);
369 } else if (f==mplib_data->log_file_ptr) {
370 APPEND_STRING(log_out,s);
371 } else if (f==mplib_data->ps_file_ptr) {
372 APPEND_STRING(ps_out,s);
374 fprintf((FILE *)f,s);
380 void mplib_read_binary_file (MP mp, void *ff, void **data, size_t *size) {
384 FILE *f = ((File *)ff)->f;
386 len = fread(*data,1,*size,f);
391 void mplib_write_binary_file (MP mp, void *ff, void *s, size_t size) {
394 FILE *f = ((File *)ff)->f;
401 void mplib_close_file (MP mp, void *ff) {
402 mplib_instance *mplib_data = mplib_get_data(mp);
404 void *f = ((File *)ff)->f;
405 if (f != NULL && f != mplib_data->term_file_ptr && f != mplib_data->err_file_ptr
406 && f != mplib_data->log_file_ptr && f != mplib_data->ps_file_ptr) {
413 int mplib_eof_file (MP mp, void *ff) {
414 mplib_instance *mplib_data = mplib_get_data(mp);
416 FILE *f = ((File *)ff)->f;
419 if (f==stdin && mplib_data->input_data != NULL) {
420 return (mplib_data->input_data_len==0);
427 void mplib_flush_file (MP mp, void *ff) {
433 #define APPEND_TO_EDGES(a) do { \
434 if (mplib_data->edges==NULL) { \
435 mplib_data->edges = hh; \
437 struct mp_edge_object *p = mplib_data->edges; \
438 while (p->_next!=NULL) { p = p->_next; } \
443 void mplib_shipout_backend (MP mp, int h) {
444 struct mp_edge_object *hh;
445 mplib_instance *mplib_data = mplib_get_data(mp);
446 hh = mp_gr_export(mp, h);
454 mplib_setup_file_ops(struct MP_options * options) {
455 options->find_file = mplib_find_file;
456 options->open_file = mplib_open_file;
457 options->close_file = mplib_close_file;
458 options->eof_file = mplib_eof_file;
459 options->flush_file = mplib_flush_file;
460 options->write_ascii_file = mplib_write_ascii_file;
461 options->read_ascii_file = mplib_read_ascii_file;
462 options->write_binary_file = mplib_write_binary_file;
463 options->read_binary_file = mplib_read_binary_file;
464 options->shipout_backend = mplib_shipout_backend;
468 mplib_new (lua_State *L) {
471 mplib_instance *mplib_data;
472 struct MP_options * options; /* instance options */
473 mp_ptr = lua_newuserdata(L, sizeof(MP *));
475 options = mp_options();
476 mplib_setup_file_ops(options);
477 mplib_data = mplib_make_data();
479 options->userdata = (void *)mplib_data;
480 options->noninteractive = 1; /* required ! */
481 options->print_found_names = 0;
482 if (lua_type(L,1)==LUA_TTABLE) {
483 for (i=0;mplib_parms[i].name!=NULL;i++) {
484 lua_getfield(L,1,mplib_parms[i].name);
485 if (lua_isnil(L,-1)) {
487 continue; /* skip unset */
489 switch(mplib_parms[i].idx) {
491 options->error_line = lua_tointeger(L,-1);
494 options->half_error_line = lua_tointeger(L,-1);
497 options->max_print_line = lua_tointeger(L,-1);
500 options->main_memory = lua_tointeger(L,-1);
503 options->hash_size = lua_tointeger(L,-1);
506 options->hash_prime = lua_tointeger(L,-1);
509 options->param_size = lua_tointeger(L,-1);
512 options->max_in_open = lua_tointeger(L,-1);
515 options->random_seed = lua_tointeger(L,-1);
518 options->interaction = luaL_checkoption(L,-1,"errorstopmode", interaction_options);
521 options->ini_version = lua_toboolean(L,-1);
524 options->troff_mode = lua_toboolean(L,-1);
527 options->print_found_names = lua_toboolean(L,-1);
531 options->command_line = strdup((char *)lua_tostring(L,-1));
535 options->mem_name = strdup((char *)lua_tostring(L,-1));
538 options->job_name = strdup((char *)lua_tostring(L,-1));
541 if(mplib_find_file_function(L)) { /* error here */
542 fprintf(stdout,"Invalid arguments to mp.new({find_file=...})\n");
551 *mp_ptr = mp_new(options);
552 xfree(options->command_line);
553 xfree(options->mem_name);
554 xfree(options->job_name);
557 luaL_getmetatable(L,MPLIB_METATABLE);
558 lua_setmetatable(L,-2);
567 mplib_collect (lua_State *L) {
568 MP *mp_ptr = is_mp(L,1);
574 mplib_tostring (lua_State *L) {
575 MP *mp_ptr = is_mp(L,1);
577 lua_pushfstring(L,"<MP %p>",*mp_ptr);
584 mplib_wrapresults(lua_State *L, mplib_instance *mplib_data, int h) {
587 if (mplib_data->term_out != NULL) {
588 lua_pushstring(L,mplib_data->term_out);
589 lua_setfield(L,-2,"term");
590 free_stream_buf(term_out);
592 if (mplib_data->error_out != NULL) {
593 lua_pushstring(L,mplib_data->error_out);
594 lua_setfield(L,-2,"error");
595 free_stream_buf(error_out);
597 if (mplib_data->log_out != NULL ) {
598 lua_pushstring(L,mplib_data->log_out);
599 lua_setfield(L,-2,"log");
600 free_stream_buf(log_out);
602 if (mplib_data->edges != NULL ) {
603 struct mp_edge_object **v;
604 struct mp_edge_object *p = mplib_data->edges;
608 v = lua_newuserdata (L, sizeof(struct mp_edge_object *));
610 luaL_getmetatable(L,MPLIB_FIG_METATABLE);
611 lua_setmetatable(L,-2);
612 lua_rawseti(L,-2,i); i++;
615 lua_setfield(L,-2,"fig");
616 mplib_data->edges = NULL;
619 lua_setfield(L,-2,"status");
624 mplib_execute (lua_State *L) {
626 MP *mp_ptr = is_mp(L,1);
627 if (*mp_ptr!=NULL && lua_isstring(L,2)) {
628 mplib_instance *mplib_data = mplib_get_data(*mp_ptr);
629 mplib_data->input_data = (char *)lua_tolstring(L,2, &(mplib_data->input_data_len));
630 mplib_data->input_data_ptr = mplib_data->input_data;
631 if ((*mp_ptr)->run_state==0) {
632 h = mp_initialize(*mp_ptr);
634 h = mp_execute(*mp_ptr);
635 if (mplib_data->input_data_len!=0) {
636 xfree(mplib_data->input_data);
637 xfree(mplib_data->input_data_ptr);
638 mplib_data->input_data_len=0;
640 return mplib_wrapresults(L, mplib_data, h);
648 mplib_finish (lua_State *L) {
649 MP *mp_ptr = is_mp(L,1);
651 mplib_instance *mplib_data = mplib_get_data(*mp_ptr);
652 int h = mp_finish(*mp_ptr);
653 return mplib_wrapresults(L, mplib_data, h);
663 mplib_fig_collect (lua_State *L) {
664 struct mp_edge_object **hh = is_fig(L,1);
666 mp_gr_toss_objects (*hh);
673 mplib_fig_body (lua_State *L) {
675 struct mp_graphic_object **v;
676 struct mp_graphic_object *p;
677 struct mp_edge_object **hh = is_fig(L,1);
681 v = lua_newuserdata (L, sizeof(struct mp_graphic_object *));
683 luaL_getmetatable(L,MPLIB_GR_METATABLE);
684 lua_setmetatable(L,-2);
685 lua_rawseti(L,-2,i); i++;
688 (*hh)->body = NULL; /* prevent double free */
693 mplib_fig_copy_body (lua_State *L) {
695 struct mp_graphic_object **v;
696 struct mp_graphic_object *p;
697 struct mp_edge_object **hh = is_fig(L,1);
701 v = lua_newuserdata (L, sizeof(struct mp_graphic_object *));
702 *v = mp_gr_copy_object((*hh)->_parent,p);
703 luaL_getmetatable(L,MPLIB_GR_METATABLE);
704 lua_setmetatable(L,-2);
705 lua_rawseti(L,-2,i); i++;
713 mplib_fig_tostring (lua_State *L) {
714 struct mp_edge_object **hh = is_fig(L,1);
715 lua_pushfstring(L,"<figure %p>",*hh);
722 mp_wrapped_shipout (struct mp_edge_object *hh, int prologues, int procset) {
724 if (setjmp(mp->jump_buf)) {
727 mp_gr_ship_out(hh,prologues,procset);
732 mplib_fig_postscript (lua_State *L) {
733 struct mp_edge_object **hh = is_fig(L,1);
734 int prologues = luaL_optnumber(L,2,-1);
735 int procset = luaL_optnumber(L,3,-1);
736 mplib_instance *mplib_data = mplib_get_data((*hh)->_parent);
737 if (mplib_data->ps_out == NULL) {
738 if (mp_wrapped_shipout(*hh,prologues, procset)) {
739 if (mplib_data->ps_out!=NULL ) {
740 lua_pushstring(L, mplib_data->ps_out);
741 free_stream_buf(ps_out);
748 lua_pushstring(L,mplib_data->log_out);
749 xfree(mplib_data->ps_out);
758 mplib_fig_filename (lua_State *L) {
759 struct mp_edge_object **hh = is_fig(L,1);
761 char *s = (*hh)->_filename;
771 mplib_fig_bb (lua_State *L) {
772 struct mp_edge_object **hh = is_fig(L,1);
774 lua_pushnumber(L, (double)(*hh)->_minx/65536.0);
776 lua_pushnumber(L, (double)(*hh)->_miny/65536.0);
778 lua_pushnumber(L, (double)(*hh)->_maxx/65536.0);
780 lua_pushnumber(L, (double)(*hh)->_maxy/65536.0);
788 mplib_gr_collect (lua_State *L) {
789 struct mp_graphic_object **hh = is_gr_object(L,1);
791 mp_gr_toss_object(*hh);
798 mplib_gr_tostring (lua_State *L) {
799 struct mp_graphic_object **hh = is_gr_object(L,1);
800 lua_pushfstring(L,"<object %p>",*hh);
805 mplib_push_number (lua_State *L, integer x ) {
808 lua_pushnumber(L, y);
815 mplib_push_path (lua_State *L, struct mp_knot *h, int is_pen) {
816 struct mp_knot *p; /* for scanning the path */
822 lua_createtable(L,0,9);
823 mplib_push_S(originator);
824 lua_pushstring(L,knot_originator_enum[p->originator_field]);
826 mplib_push_S(left_type);
827 lua_pushstring(L,(is_pen ? "explicit" : knot_type_enum[p->left_type_field]));
829 mplib_push_S(right_type);
830 lua_pushstring(L,(is_pen ? "explicit" : knot_type_enum[p->right_type_field]));
832 mplib_push_S(x_coord);
833 mplib_push_number(L,p->x_coord_field);
835 mplib_push_S(y_coord);
836 mplib_push_number(L,p->y_coord_field);
838 mplib_push_S(left_x);
839 mplib_push_number(L,p->left_x_field);
841 mplib_push_S(left_y);
842 mplib_push_number(L,p->left_y_field);
844 mplib_push_S(right_x);
845 mplib_push_number(L,p->right_x_field);
847 mplib_push_S(right_y);
848 mplib_push_number(L,p->right_y_field);
850 lua_rawseti(L,-2,i); i++;
851 if ( p->right_type_field==mp_endpoint ) {
862 mplib_push_color (lua_State *L, struct mp_graphic_object *h ) {
865 lua_pushstring(L,color_model_enum[h->color_model_field]);
866 lua_setfield(L,-2,"model");
868 if (h->color_model_field == mp_rgb_model ||
869 h->color_model_field == mp_uninitialized_model) {
871 mplib_push_number(L,h->color_field.rgb._red_val);
873 mplib_push_number(L,h->color_field.rgb._green_val);
875 mplib_push_number(L,h->color_field.rgb._blue_val);
877 lua_setfield(L,-2,"rgb");
880 if (h->color_model_field == mp_cmyk_model ||
881 h->color_model_field == mp_uninitialized_model) {
883 mplib_push_number(L,h->color_field.cmyk._cyan_val);
885 mplib_push_number(L,h->color_field.cmyk._magenta_val);
887 mplib_push_number(L,h->color_field.cmyk._yellow_val);
889 mplib_push_number(L,h->color_field.cmyk._black_val);
891 lua_setfield(L,-2,"cmyk");
893 if (h->color_model_field == mp_grey_model ||
894 h->color_model_field == mp_uninitialized_model) {
896 mplib_push_number(L,h->color_field.grey._grey_val);
898 lua_setfield(L,-2,"grey");
906 /* the dash scale is not exported, the field has no external value */
908 mplib_push_dash (lua_State *L, struct mp_graphic_object *h ) {
910 if (h!=NULL && h->dash_p_field != NULL) {
913 mplib_push_number(L,d->offset_field);
914 lua_setfield(L,-2,"offset");
915 if (d->array_field!=NULL ) {
918 while (*(d->array_field+i) != -1) {
919 mplib_push_number(L, *(d->array_field+1));
923 lua_setfield(L,-2,"dashes");
931 mplib_push_transform (lua_State *L, struct mp_graphic_object *h ) {
935 mplib_push_number(L,h->tx_field);
936 lua_rawseti(L,-2,i); i++;
937 mplib_push_number(L,h->ty_field);
938 lua_rawseti(L,-2,i); i++;
939 mplib_push_number(L,h->txx_field);
940 lua_rawseti(L,-2,i); i++;
941 mplib_push_number(L,h->tyx_field);
942 lua_rawseti(L,-2,i); i++;
943 mplib_push_number(L,h->txy_field);
944 lua_rawseti(L,-2,i); i++;
945 mplib_push_number(L,h->tyy_field);
946 lua_rawseti(L,-2,i); i++;
954 mplib_fill_field (lua_State *L, struct mp_graphic_object *h, char *field) {
956 lua_pushstring(L,"fill");
957 } else if (FIELD(path)) {
958 mplib_push_path(L, h->path_p_field, MPLIB_PATH);
959 } else if (FIELD(htap)) {
960 mplib_push_path(L, h->htap_p_field, MPLIB_PATH);
961 } else if (FIELD(pen)) {
962 mplib_push_path(L, h->pen_p_field, MPLIB_PEN);
963 } else if (FIELD(color)) {
964 mplib_push_color(L, h);
965 } else if (FIELD(linejoin)) {
966 lua_pushnumber(L,h->ljoin_field);
967 } else if (FIELD(miterlimit)) {
968 mplib_push_number(L,h->miterlim_field);
969 } else if (FIELD(prescript)) {
970 lua_pushstring(L,h->pre_script_field);
971 } else if (FIELD(postscript)) {
972 lua_pushstring(L,h->post_script_field);
979 mplib_stroked_field (lua_State *L, struct mp_graphic_object *h, char *field) {
981 lua_pushstring(L,"outline");
982 } else if (FIELD(path)) {
983 mplib_push_path(L, h->path_p_field, MPLIB_PATH);
984 } else if (FIELD(pen)) {
985 mplib_push_path(L, h->pen_p_field, MPLIB_PEN);
986 } else if (FIELD(color)) {
987 mplib_push_color(L, h);
988 } else if (FIELD(dash)) {
989 mplib_push_dash(L, h);
990 } else if (FIELD(linecap)) {
991 lua_pushnumber(L,h->lcap_field);
992 } else if (FIELD(linejoin)) {
993 lua_pushnumber(L,h->ljoin_field);
994 } else if (FIELD(miterlimit)) {
995 mplib_push_number(L,h->miterlim_field);
996 } else if (FIELD(prescript)) {
997 lua_pushstring(L,h->pre_script_field);
998 } else if (FIELD(postscript)) {
999 lua_pushstring(L,h->post_script_field);
1006 mplib_text_field (lua_State *L, struct mp_graphic_object *h, char *field) {
1009 lua_pushstring(L,"text");
1010 } else if (FIELD(text)) {
1011 lua_pushstring(L,h->text_p_field);
1012 } else if (FIELD(dsize)) {
1013 lua_pushnumber(L,h->font_dsize_field);
1014 } else if (FIELD(font)) {
1015 lua_pushstring(L,h->font_name_field);
1016 } else if (FIELD(color)) {
1017 mplib_push_color(L, h);
1018 } else if (FIELD(width)) {
1019 mplib_push_number(L,h->width_field);
1020 } else if (FIELD(height)) {
1021 mplib_push_number(L,h->height_field);
1022 } else if (FIELD(depth)) {
1023 mplib_push_number(L,h->depth_field);
1024 } else if (FIELD(transform)) {
1025 mplib_push_transform(L,h);
1026 } else if (FIELD(prescript)) {
1027 lua_pushstring(L,h->pre_script_field);
1028 } else if (FIELD(postscript)) {
1029 lua_pushstring(L,h->post_script_field);
1036 mplib_special_field (lua_State *L, struct mp_graphic_object *h, char *field) {
1038 lua_pushstring(L,"special");
1039 } else if (FIELD(prescript)) {
1040 lua_pushstring(L,h->pre_script_field);
1047 mplib_start_bounds_field (lua_State *L, struct mp_graphic_object *h, char *field) {
1049 lua_pushstring(L,"start_bounds");
1050 } else if (FIELD(path)) {
1051 mplib_push_path(L,h->path_p_field, MPLIB_PATH);
1058 mplib_start_clip_field (lua_State *L, struct mp_graphic_object *h, char *field) {
1060 lua_pushstring(L,"start_clip");
1061 } else if (FIELD(path)) {
1062 mplib_push_path(L,h->path_p_field, MPLIB_PATH);
1069 mplib_stop_bounds_field (lua_State *L, struct mp_graphic_object *h, char *field) {
1070 if (h!=NULL && FIELD(type)) {
1071 lua_pushstring(L,"stop_bounds");
1078 mplib_stop_clip_field (lua_State *L, struct mp_graphic_object *h, char *field) {
1079 if (h!=NULL && FIELD(type)) {
1080 lua_pushstring(L,"stop_clip");
1087 mplib_gr_fields (lua_State *L) {
1088 const char **fields;
1091 struct mp_graphic_object **hh = is_gr_object(L,1);
1093 switch ((*hh)->_type_field) {
1094 case mp_fill_code: fields = fill_fields; break;
1095 case mp_stroked_code: fields = stroked_fields; break;
1096 case mp_text_code: fields = text_fields; break;
1097 case mp_special_code: fields = special_fields; break;
1098 case mp_start_clip_code: fields = start_clip_fields; break;
1099 case mp_start_bounds_code: fields = start_bounds_fields; break;
1100 case mp_stop_clip_code: fields = stop_clip_fields; break;
1101 case mp_stop_bounds_code: fields = stop_bounds_fields; break;
1102 default: fields = no_fields;
1105 for (f = *fields; f != NULL; f++) {
1106 lua_pushstring(L,f);
1107 lua_rawseti(L,-2,i); i++;
1116 mplib_gr_index (lua_State *L) {
1117 struct mp_graphic_object **hh = is_gr_object(L,1);
1118 char *field = (char *)luaL_checkstring(L,2);
1120 switch ((*hh)->_type_field) {
1121 case mp_fill_code: mplib_fill_field(L,*hh,field); break;
1122 case mp_stroked_code: mplib_stroked_field(L,*hh,field); break;
1123 case mp_text_code: mplib_text_field(L,*hh,field); break;
1124 case mp_special_code: mplib_special_field(L,*hh,field); break;
1125 case mp_start_clip_code: mplib_start_clip_field(L,*hh,field); break;
1126 case mp_start_bounds_code: mplib_start_bounds_field(L,*hh,field); break;
1127 case mp_stop_clip_code: mplib_stop_clip_field(L,*hh,field); break;
1128 case mp_stop_bounds_code: mplib_stop_bounds_field(L,*hh,field); break;
1129 default: lua_pushnil(L);
1138 static const struct luaL_reg mplib_meta[] = {
1139 {"__gc", mplib_collect},
1140 {"__tostring", mplib_tostring},
1141 {NULL, NULL} /* sentinel */
1144 static const struct luaL_reg mplib_fig_meta[] = {
1145 {"__gc", mplib_fig_collect },
1146 {"__tostring", mplib_fig_tostring },
1147 {"objects", mplib_fig_body },
1148 {"copy_objects", mplib_fig_copy_body },
1149 {"filename", mplib_fig_filename },
1150 {"postscript", mplib_fig_postscript },
1151 {"boundingbox", mplib_fig_bb },
1152 {NULL, NULL} /* sentinel */
1155 static const struct luaL_reg mplib_gr_meta[] = {
1156 {"__gc", mplib_gr_collect },
1157 {"__tostring", mplib_gr_tostring },
1158 {"__index", mplib_gr_index },
1159 {"fields", mplib_gr_fields },
1160 {NULL, NULL} /* sentinel */
1164 static const struct luaL_reg mplib_d [] = {
1165 {"execute", mplib_execute },
1166 {"finish", mplib_finish },
1167 {NULL, NULL} /* sentinel */
1171 static const struct luaL_reg mplib_m[] = {
1173 {NULL, NULL} /* sentinel */
1178 luaopen_mp (lua_State *L) {
1180 luaL_newmetatable(L,MPLIB_GR_METATABLE);
1181 lua_pushvalue(L, -1); /* push metatable */
1182 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
1183 luaL_register(L, NULL, mplib_gr_meta); /* object meta methods */
1186 luaL_newmetatable(L,MPLIB_FIG_METATABLE);
1187 lua_pushvalue(L, -1); /* push metatable */
1188 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
1189 luaL_register(L, NULL, mplib_fig_meta); /* figure meta methods */
1192 luaL_newmetatable(L,MPLIB_METATABLE);
1193 lua_pushvalue(L, -1); /* push metatable */
1194 lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
1195 luaL_register(L, NULL, mplib_meta); /* meta methods */
1196 luaL_register(L, NULL, mplib_d); /* dict methods */
1197 luaL_register(L, "mplib", mplib_m); /* module functions */