1 /*
2  * luagd -- GD bindings for Lua.
3  * (c) 2004-06 Alexandre Erwin Ittner <aittner@netuno.com.br>
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * If you use this package in a product, an acknowledgment in the product
25  * documentation would be greatly appreciated (but it is not required).
26  *
27  */
28 
29 static char *rev = "$Id: luagd.c,v 1.86 2006/05/01 00:39:09 dermeister Exp $";
30 
31 #include <lua.h>
32 #include <lauxlib.h>
33 #include <stdlib.h>
34 
35 #include <gd.h>
36 
37 /* Standard gd fonts */
38 #include <gdfonts.h>
39 #include <gdfontl.h>
40 #include <gdfontmb.h>
41 #include <gdfontg.h>
42 #include <gdfontt.h>
43 
44 #define LIB_NAME        "gd"
45 #define GD_VERSION      "2.0.33"
46 #define LIB_VERSION     "lua-gd " GD_VERSION "r2"
47 #define LIB_COPYRIGHT   LIB_VERSION " (c) 2004-06 Alexandre Erwin Ittner"
48 
49 #define GD_IMAGE_PTR_TYPENAME   "gdImagePtr_handle"
50 
51 
52 /* Compatibility between Lua 5.1+ and Lua 5.0 */
53 #ifndef LUA_VERSION_NUM
54 #define LUA_VERSION_NUM 0
55 #endif
56 #if LUA_VERSION_NUM < 501
57 #define luaL_register(a, b, c) luaL_openlib((a), (b), (c), 0)
58 #endif
59 
60 /* Emulates lua_(un)boxpointer from Lua 5.0 (don't exists on Lua 5.1) */
61 #define boxptr(L, p)   (*(void**)(lua_newuserdata(L, sizeof(void*))) = (p))
62 #define unboxptr(L, i) (*(void**)(lua_touserdata(L, i)))
63 
64 /* Table assumed on top */
65 #define tblseticons(L, c, v)    \
66     lua_pushliteral(L, c);      \
67     lua_pushnumber(L, v);       \
68     lua_settable(L, -3);
69 
70 /* Standard gd fonts */
71 #define MY_GD_FONT_SMALL            0
72 #define MY_GD_FONT_LARGE            1
73 #define MY_GD_FONT_MEDIUM_BOLD      2
74 #define MY_GD_FONT_GIANT            3
75 #define MY_GD_FONT_TINY             4
76 
77 
getImagePtr(lua_State * L,int i)78 static gdImagePtr getImagePtr(lua_State *L, int i) {
79     if (luaL_checkudata(L, i, GD_IMAGE_PTR_TYPENAME) != NULL) {
80         gdImagePtr im = unboxptr(L, i);
81         if (im == NULL)
82             luaL_error(L, "attempt to use an invalid " GD_IMAGE_PTR_TYPENAME);
83         return im;
84     }
85     luaL_typerror(L, i, GD_IMAGE_PTR_TYPENAME);
86     return NULL;
87 }
88 
89 
pushImagePtr(lua_State * L,gdImagePtr im)90 static void pushImagePtr(lua_State *L, gdImagePtr im) {
91     boxptr(L, im);
92     luaL_getmetatable(L, GD_IMAGE_PTR_TYPENAME);
93     lua_setmetatable(L, -2);    /* Done */
94 }
95 
96 
getStdFont(lua_State * L,int i)97 static gdFontPtr getStdFont(lua_State *L, int i) {
98     int size;
99 
100     if (lua_isnumber(L, i) == 0) {
101         luaL_typerror(L, i, "Standard GD Font");
102         return gdFontGetSmall();
103     }
104 
105     size = luaL_checkinteger(L, i);
106     switch(size) {
107         case MY_GD_FONT_SMALL:
108             return gdFontGetSmall();
109 
110         case MY_GD_FONT_LARGE:
111             return gdFontGetLarge();
112 
113         case MY_GD_FONT_MEDIUM_BOLD:
114             return gdFontGetMediumBold();
115 
116         case MY_GD_FONT_GIANT:
117             return gdFontGetGiant();
118 
119         case MY_GD_FONT_TINY:
120             return gdFontGetTiny();
121 
122         default:
123             luaL_typerror(L, i, "Standard GD Font");
124             return gdFontGetSmall();
125     }
126 
127     return gdFontGetSmall(); /* Not reached */
128 }
129 
130 
131 
132 
133 /*
134  * Reads a Lua table and returns a pointer to a "gdFTStringExtra" struct. The
135  * table should have the following fields:
136  *
137  * {
138  *     linespacing = 1.0,                   -- linespacing for '\n'
139  *     charmap = gd.FTEX_Unicode,           -- default charset
140  *     hdpi = 96,                           -- horizontal resolution
141  *     vdpi = 96,                           -- vertical resolution
142  *     disable_kerning = true,              -- disable kerning?
143  *     xshow = true,                        -- return char positions?
144  *     return_font_path_name = true,        -- return font path names?
145  *     fontconfig = true                    -- use fontconfig?
146  * }
147  *
148  */
149 #ifdef GD_FREETYPE
getFTStringExtraPtr(lua_State * L,int i)150 static gdFTStringExtra *getFTStringExtraPtr(lua_State *L, int i) {
151     gdFTStringExtra *ex = (gdFTStringExtra*) malloc(sizeof(gdFTStringExtra));
152 
153     if (ex == NULL)
154         luaL_error(L, "Memory allocation failure");
155 
156     ex->flags = 0;
157 
158     luaL_checktype(L, i, LUA_TTABLE);
159 
160     lua_pushstring(L, "linespacing");
161     lua_gettable(L, i);
162     if (!lua_isnil(L, -1)) {
163         ex->flags |= gdFTEX_LINESPACE;
164         ex->linespacing = (double) lua_tonumber(L, -1);
165     }
166     lua_pop(L, 1);
167 
168     lua_pushstring(L, "charmap");
169     lua_gettable(L, i);
170     if (!lua_isnil(L, -1)) {
171         ex->flags |= gdFTEX_CHARMAP;;
172         ex->charmap = (int) lua_tonumber(L, -1);
173         switch(ex->charmap) {
174             case gdFTEX_Unicode:
175             case gdFTEX_Shift_JIS:
176             case gdFTEX_Big5:
177             /* Future charsets here */
178                 break;
179             default:
180                 free(ex);
181                 luaL_error(L, "Invalid charset");
182         }
183     }
184     lua_pop(L, 1);
185 
186     ex->hdpi = 96;
187     ex->vdpi = 96;
188 
189     lua_pushstring(L, "hdpi");
190     lua_gettable(L, i);
191     if (!lua_isnil(L, -1)) {
192         ex->flags |= gdFTEX_RESOLUTION;
193         ex->hdpi = (double) lua_tonumber(L, -1);
194     }
195     lua_pop(L, 1);
196 
197     lua_pushstring(L, "vdpi");
198     lua_gettable(L, i);
199     if (!lua_isnil(L, -1)) {
200         ex->flags |= gdFTEX_RESOLUTION;
201         ex->vdpi = (double) lua_tonumber(L, -1);
202     }
203     lua_pop(L, 1);
204 
205     lua_pushstring(L, "disable_kerning");
206     lua_gettable(L, i);
207     if (lua_toboolean(L, -1))
208         ex->flags |= gdFTEX_DISABLE_KERNING;
209     lua_pop(L, 1);
210 
211     lua_pushvalue(L, i);
212     lua_pushstring(L, "xshow");
213     lua_gettable(L, i);
214     if (lua_toboolean(L, -1))
215         ex->flags |= gdFTEX_XSHOW;
216     lua_pop(L, 1);
217 
218     lua_pushstring(L, "return_font_path_name");
219     lua_gettable(L, i);
220     if (lua_toboolean(L, -1))
221         ex->flags |= gdFTEX_RETURNFONTPATHNAME;
222     lua_pop(L, 1);
223 
224     lua_pushstring(L, "fontconfig");
225     lua_gettable(L, i);
226     if (lua_toboolean(L, -1))
227         ex->flags |= gdFTEX_FONTCONFIG;
228     lua_pop(L, 1);
229 
230     return ex;
231 }
232 #endif
233 
234 
235 /* gdImageCreate(int sx, int sy) */
LgdImageCreate(lua_State * L)236 static int LgdImageCreate(lua_State *L) {
237     int sx, sy;
238     gdImagePtr im;
239 
240     sx = luaL_checkinteger(L, 1);
241     sy = luaL_checkinteger(L, 2);
242     im = gdImageCreate(sx, sy);
243     if (im != NULL)
244         pushImagePtr(L, im);
245     else
246         lua_pushnil(L); /* Error */
247     return 1;
248 }
249 
250 /* gdImageCreatePalette(int sx, int sy) */
251 /* Useless? */
LgdImageCreatePalette(lua_State * L)252 static int LgdImageCreatePalette(lua_State *L) {
253     int sx, sy;
254     gdImagePtr im;
255 
256     sx = luaL_checkinteger(L, 1);
257     sy = luaL_checkinteger(L, 2);
258     im = gdImageCreatePalette(sx, sy);
259     if (im != NULL)
260         pushImagePtr(L, im);
261     else
262         lua_pushnil(L); /* Error */
263     return 1;
264 }
265 
266 
267 
268 /* gdImageCreateTrueColor(int sx, int sy) */
LgdImageCreateTrueColor(lua_State * L)269 static int LgdImageCreateTrueColor(lua_State *L) {
270     int sx, sy;
271     gdImagePtr im;
272 
273     sx = luaL_checkinteger(L, 1);
274     sy = luaL_checkinteger(L, 2);
275     im = gdImageCreateTrueColor(sx, sy);
276     if (im != NULL)
277         pushImagePtr(L, im);
278     else
279         lua_pushnil(L); /* Error */
280     return 1;
281 }
282 
283 /* gdImagePtr gdImageCreatePaletteFromTrueColor(gdImagePtr im, int ditherFlag,
284     int colorsWanted) */
LgdImageCreatePaletteFromTrueColor(lua_State * L)285 static int LgdImageCreatePaletteFromTrueColor(lua_State *L) {
286     gdImagePtr im = getImagePtr(L, 1);
287     int dither = lua_toboolean(L, 2);
288     int colors = luaL_checkinteger(L, 3);
289     gdImagePtr nim = gdImageCreatePaletteFromTrueColor(im, dither, colors);
290 
291     if (nim)
292         pushImagePtr(L, nim);
293     else
294         lua_pushnil(L);
295     return 1;
296 }
297 
298 
299 /* void gdImageTrueColorToPalette(gdImagePtr im, int ditherFlag,
300     int colorsWanted) */
LgdImageTrueColorToPalette(lua_State * L)301 static int LgdImageTrueColorToPalette(lua_State *L) {
302     gdImagePtr im = getImagePtr(L, 1);
303     int dither = lua_toboolean(L, 2);
304     int colors = luaL_checkinteger(L, 3);
305 
306     gdImageTrueColorToPalette(im, dither, colors);
307     return 0;
308 }
309 
310 
311 
312 /* gdImageDestroy(gdImagePtr im) */
LgdImageDestroy(lua_State * L)313 static int LgdImageDestroy(lua_State *L) {
314     gdImagePtr im = getImagePtr(L, 1);
315     if (im)
316         gdImageDestroy(im);
317     return 0;
318 }
319 
320 #ifdef GD_JPEG
321 /* gdImageCreateFromJpeg(FILE *in) */
322 /* Changed to: gd.createFromJpeg(char *filename) */
LgdImageCreateFromJpeg(lua_State * L)323 static int LgdImageCreateFromJpeg(lua_State *L) {
324     gdImagePtr im;
325     FILE *fp;
326     const char *fname = luaL_checkstring(L, 1);
327 
328     if (fname == NULL) {
329         lua_pushnil(L);
330         return 1;  /* Error */
331     }
332     if ((fp = fopen(fname, "rb")) == NULL) {
333         lua_pushnil(L);
334         return 1;  /* Error */
335     }
336     im = gdImageCreateFromJpeg(fp);
337     fclose(fp);
338     if (im != NULL)
339         pushImagePtr(L, im);
340     else
341         lua_pushnil(L); /* Error */
342     return 1;
343 }
344 
345 
346 /* gdImageCreateFromJpegPtr(int size, void *data) */
LgdImageCreateFromJpegPtr(lua_State * L)347 static int LgdImageCreateFromJpegPtr(lua_State *L) {
348     gdImagePtr im;
349     int size = lua_strlen(L, 1);
350     void *str = (void*) luaL_checkstring(L, 1);
351 
352     if (str == NULL) {
353         lua_pushnil(L);
354         return 1;  /* Error */
355     }
356     im = gdImageCreateFromJpegPtr(size, str);
357     if (im != NULL)
358         pushImagePtr(L, im);
359     else
360         lua_pushnil(L); /* Error */
361     return 1;
362 }
363 #endif
364 
365 
366 #ifdef GD_GIF
367 /* gdImageCreateFromGif (FILE *in) */
368 /* Changed to: gd.createFromGif (filename) */
LgdImageCreateFromGif(lua_State * L)369 static int LgdImageCreateFromGif (lua_State *L) {
370     gdImagePtr im;
371     FILE *fp;
372     const char *fname = luaL_checkstring(L, 1);
373 
374     if (fname == NULL) {
375         lua_pushnil(L);
376         return 1;  /* Error */
377     }
378     if ((fp = fopen(fname, "rb")) == NULL) {
379         lua_pushnil(L);
380         return 1;  /* Error */
381     }
382     im = gdImageCreateFromGif (fp);
383     fclose(fp);
384     if (im != NULL)
385         pushImagePtr(L, im);
386     else
387         lua_pushnil(L); /* Error */
388     return 1;
389 }
390 
391 /* gdImageCreateFromGifPtr(int size, void *data) */
LgdImageCreateFromGifPtr(lua_State * L)392 static int LgdImageCreateFromGifPtr(lua_State *L) {
393     gdImagePtr im;
394     int size = lua_strlen(L, 1);
395     void *str = (void*) luaL_checkstring(L, 1);
396 
397     if (str == NULL) {
398         lua_pushnil(L);
399         return 1;  /* Error */
400     }
401     im = gdImageCreateFromGifPtr(size, str);
402     if (im != NULL)
403         pushImagePtr(L, im);
404     else
405         lua_pushnil(L); /* Error */
406     return 1;
407 }
408 #endif
409 
410 
411 #ifdef GD_PNG
412 /* gdImageCreateFromPng(FILE *in) */
413 /* Changed to: gd.createFromPng(filename) */
LgdImageCreateFromPng(lua_State * L)414 static int LgdImageCreateFromPng(lua_State *L) {
415     gdImagePtr im;
416     FILE *fp;
417     const char *fname = luaL_checkstring(L, 1);
418 
419     if (fname == NULL) {
420         lua_pushnil(L);
421         return 1;  /* Error */
422     }
423     if ((fp = fopen(fname, "rb")) == NULL) {
424         lua_pushnil(L);
425         return 1;  /* Error */
426     }
427     im = gdImageCreateFromPng(fp);
428     fclose(fp);
429     if (im != NULL)
430         pushImagePtr(L, im);
431     else
432         lua_pushnil(L); /* Error */
433     return 1;
434 }
435 
436 
437 /* gdImageCreateFromPngPtr(int size, void *data) */
LgdImageCreateFromPngPtr(lua_State * L)438 static int LgdImageCreateFromPngPtr(lua_State *L) {
439     gdImagePtr im;
440     int size = lua_strlen(L, 1);
441     void *str = (void*) luaL_checkstring(L, 1);
442 
443     if (str == NULL) {
444         lua_pushnil(L);
445         return 1;  /* Error */
446     }
447     im = gdImageCreateFromPngPtr(size, str);
448     if (im != NULL)
449         pushImagePtr(L, im);
450     else
451         lua_pushnil(L); /* Error */
452     return 1;
453 }
454 #endif
455 
456 
457 /* gdImageCreateFromGd(FILE *in) */
458 /* Changed to: gd.createFromGd(filename) */
LgdImageCreateFromGd(lua_State * L)459 static int LgdImageCreateFromGd(lua_State *L) {
460     gdImagePtr im;
461     FILE *fp;
462     const char *fname = luaL_checkstring(L, 1);
463 
464     if (fname == NULL) {
465         lua_pushnil(L);
466         return 1;  /* Error */
467     }
468     if ((fp = fopen(fname, "rb")) == NULL) {
469         lua_pushnil(L);
470         return 1;  /* Error */
471     }
472     im = gdImageCreateFromGd(fp);
473     fclose(fp);
474     if (im != NULL)
475         pushImagePtr(L, im);
476     else
477         lua_pushnil(L); /* Error */
478     return 1;
479 }
480 
481 
482 /* gdImageCreateFromGdPtr(int size, void *data) */
LgdImageCreateFromGdPtr(lua_State * L)483 static int LgdImageCreateFromGdPtr(lua_State *L) {
484     gdImagePtr im;
485     int size = lua_strlen(L, 1);
486     void *str = (void*) luaL_checkstring(L, 1);
487 
488     if (str == NULL) {
489         lua_pushnil(L);
490         return 1;  /* Error */
491     }
492     im = gdImageCreateFromGdPtr(size, str);
493     if (im != NULL)
494         pushImagePtr(L, im);
495     else
496         lua_pushnil(L); /* Error */
497     return 1;
498 }
499 
500 
501 /* gdImageCreateFromGd2(FILE *in) */
502 /* Changed to: gd.createFromGd2(filename) */
LgdImageCreateFromGd2(lua_State * L)503 static int LgdImageCreateFromGd2(lua_State *L) {
504     gdImagePtr im;
505     FILE *fp;
506     const char *fname = luaL_checkstring(L, 1);
507 
508     if (fname == NULL) {
509         lua_pushnil(L);
510         return 1;  /* Error */
511     }
512     if ((fp = fopen(fname, "rb")) == NULL) {
513         lua_pushnil(L);
514         return 1;  /* Error */
515     }
516     im = gdImageCreateFromGd2(fp);
517     fclose(fp);
518     if (im != NULL)
519         pushImagePtr(L, im);
520     else
521         lua_pushnil(L); /* Error */
522     return 1;
523 }
524 
525 
526 /* gdImageCreateFromGd2Ptr(int size, void *data) */
LgdImageCreateFromGd2Ptr(lua_State * L)527 static int LgdImageCreateFromGd2Ptr(lua_State *L) {
528     gdImagePtr im;
529     int size = lua_strlen(L, 1);
530     void *str = (void*) luaL_checkstring(L, 1);
531 
532     if (str == NULL) {
533         lua_pushnil(L);
534         return 1;  /* Error */
535     }
536     im = gdImageCreateFromGd2Ptr(size, str);
537     if (im != NULL)
538         pushImagePtr(L, im);
539     else
540         lua_pushnil(L); /* Error */
541     return 1;
542 }
543 
544 
545 /* gdImageCreateFromGd2Part(FILE *in, int x, int y, int w, int h) */
546 /* Changed to: gd.createFromGd2Part(filename, x, y, w, h)) */
LgdImageCreateFromGd2Part(lua_State * L)547 static int LgdImageCreateFromGd2Part(lua_State *L) {
548     gdImagePtr im;
549     FILE *fp;
550     const char *fname = luaL_checkstring(L, 1);
551     const int x = luaL_checkinteger(L, 2);
552     const int y = luaL_checkinteger(L, 3);
553     const int w = luaL_checkinteger(L, 4);
554     const int h = luaL_checkinteger(L, 5);
555 
556     if (fname == NULL) {
557         lua_pushnil(L);
558         return 1;  /* Error */
559     }
560     if ((fp = fopen(fname, "rb")) == NULL) {
561         lua_pushnil(L);
562         return 1;  /* Error */
563     }
564     im = gdImageCreateFromGd2Part(fp, x, y, w, h);
565     fclose(fp);
566     if (im != NULL)
567         pushImagePtr(L, im);
568     else
569         lua_pushnil(L); /* Error */
570     return 1;
571 }
572 
573 
574 /* gdImageCreateFromGd2PartPtr(int size, void *data,
575                 int srcX, int srcY, int w, int h)  */
LgdImageCreateFromGd2PartPtr(lua_State * L)576 static int LgdImageCreateFromGd2PartPtr(lua_State *L) {
577     gdImagePtr im;
578     int size = lua_strlen(L, 1);
579     void *str = (void*) luaL_checkstring(L, 1);
580     const int x = luaL_checkinteger(L, 2);
581     const int y = luaL_checkinteger(L, 3);
582     const int w = luaL_checkinteger(L, 4);
583     const int h = luaL_checkinteger(L, 5);
584 
585     if (str == NULL) {
586         lua_pushnil(L);
587         return 1;  /* Error */
588     }
589     im = gdImageCreateFromGd2PartPtr(size, str, x, y, w, h);
590     if (im != NULL)
591         pushImagePtr(L, im);
592     else
593         lua_pushnil(L); /* Error */
594     return 1;
595 }
596 
597 
598 #ifdef GD_XPM
599 /* gdImageCreateFromXbm(FILE *in) */
600 /* Changed to: gd.createFromXbm(filename) */
LgdImageCreateFromXbm(lua_State * L)601 static int LgdImageCreateFromXbm(lua_State *L) {
602     gdImagePtr im;
603     FILE *fp;
604     const char *fname = luaL_checkstring(L, 1);
605 
606     if (fname == NULL) {
607         lua_pushnil(L);
608         return 1;  /* Error */
609     }
610     if ((fp = fopen(fname, "rb")) == NULL) {
611         lua_pushnil(L);
612         return 1;  /* Error */
613     }
614     im = gdImageCreateFromXbm(fp);
615     fclose(fp);
616     if (im != NULL)
617         pushImagePtr(L, im);
618     else
619         lua_pushnil(L); /* Error */
620     return 1;
621 }
622 
623 
624 /* gdImageCreateFromXpm(char *filename) */
LgdImageCreateFromXpm(lua_State * L)625 static int LgdImageCreateFromXpm(lua_State *L) {
626     gdImagePtr im;
627     char *fname = (char*) luaL_checkstring(L, 1);
628 
629     if (fname == NULL) {
630         lua_pushnil(L);
631         return 1;  /* Error */
632     }
633     im = gdImageCreateFromXpm(fname);
634     if (im != NULL)
635         pushImagePtr(L, im);
636     else
637         lua_pushnil(L); /* Error */
638     return 1;
639 }
640 #endif
641 
642 
643 
644 #ifdef GD_JPEG
645 /* gdImageJpeg(gdImagePtr im, FILE *out, int quality) */
646 /* Changed to: gd.jpeg(im, fname, quality) */
LgdImageJpeg(lua_State * L)647 static int LgdImageJpeg(lua_State *L) {
648     gdImagePtr im = getImagePtr(L, 1);
649     const char *fname = luaL_checkstring(L, 2);
650     int quality = luaL_checkinteger(L, 3);
651     FILE *fp;
652 
653     if (fname == NULL) {
654         lua_pushboolean(L, 0);
655         return 1;
656     }
657     if ((fp = fopen(fname, "wb")) == NULL) {
658         lua_pushboolean(L, 0);
659         return 1;
660     }
661     gdImageJpeg(im, fp, quality);
662     fclose(fp);
663     lua_pushboolean(L, 1);
664     return 1;
665 }
666 
667 
668 /* void *gdImageJpegPtr(gdImagePtr im, int quality) */
LgdImageJpegPtr(lua_State * L)669 static int LgdImageJpegPtr(lua_State *L) {
670     gdImagePtr im = getImagePtr(L, 1);
671     int quality = luaL_checkinteger(L, 2);
672     char *str;
673     int size;
674 
675     str = gdImageJpegPtr(im, &size, quality);
676     if (str != NULL) {
677         lua_pushlstring(L, str, size);
678         gdFree(str);
679     } else {
680         lua_pushnil(L);  /* Error */
681     }
682     return 1;
683 }
684 #endif
685 
686 #ifdef GD_PNG
687 /* gdImagePng(gdImagePtr im, FILE *out) */
688 /* Changed to: gd.png(im, fname) */
LgdImagePng(lua_State * L)689 static int LgdImagePng(lua_State *L) {
690     gdImagePtr im = getImagePtr(L, 1);
691     const char *fname = luaL_checkstring(L, 2);
692     FILE *fp;
693 
694     if (fname == NULL) {
695         lua_pushboolean(L, 0);
696         return 1;
697     }
698     if ((fp = fopen(fname, "wb")) == NULL) {
699         lua_pushboolean(L, 0);
700         return 1;
701     }
702     gdImagePng(im, fp);
703     fclose(fp);
704     lua_pushboolean(L, 1);
705     return 1;
706 }
707 
708 
709 /* void *gdImagePngPtr(gdImagePtr im) */
LgdImagePngPtr(lua_State * L)710 static int LgdImagePngPtr(lua_State *L) {
711     gdImagePtr im = getImagePtr(L, 1);
712     char *str;
713     int size;
714 
715     str = gdImagePngPtr(im, &size);
716     if (str != NULL) {
717         lua_pushlstring(L, str, size);
718         gdFree(str);
719     } else {
720         lua_pushnil(L);  /* Error */
721     }
722     return 1;
723 }
724 
725 
726 /* gdImagePngEx(gdImagePtr im, FILE *out, int compression_level) */
727 /* Changed to: gd.pngEx(im, fname, compression_level) */
LgdImagePngEx(lua_State * L)728 static int LgdImagePngEx(lua_State *L) {
729     gdImagePtr im = getImagePtr(L, 1);
730     const char *fname = luaL_checkstring(L, 2);
731     int level = luaL_checkinteger(L, 3);
732     FILE *fp;
733 
734     if (fname == NULL) {
735         lua_pushboolean(L, 0);
736         return 1;
737     }
738     if ((fp = fopen(fname, "wb")) == NULL) {
739         lua_pushboolean(L, 0);
740         return 1;
741     }
742     gdImagePngEx(im, fp, level);
743     fclose(fp);
744     lua_pushboolean(L, 1);
745     return 1;
746 }
747 
748 
749 /* void *gdImagePngPtrEx(gdImagePtr im, int compression_level) */
LgdImagePngPtrEx(lua_State * L)750 static int LgdImagePngPtrEx(lua_State *L) {
751     gdImagePtr im = getImagePtr(L, 1);
752     int level = luaL_checkinteger(L, 2);
753     char *str;
754     int size;
755 
756     str = gdImagePngPtrEx(im, &size, level);
757     if (str != NULL) {
758         lua_pushlstring(L, str, size);
759         gdFree(str);
760     } else {
761         lua_pushnil(L);  /* Error */
762     }
763     return 1;
764 }
765 #endif
766 
767 
768 #ifdef GD_GIF
769 /* gdImageGif (gdImagePtr im, FILE *out) */
770 /* Changed to: gd.gif (im, fname) */
LgdImageGif(lua_State * L)771 static int LgdImageGif (lua_State *L) {
772     gdImagePtr im = getImagePtr(L, 1);
773     const char *fname = luaL_checkstring(L, 2);
774     FILE *fp;
775 
776     if (fname == NULL) {
777         lua_pushboolean(L, 0);
778         return 1;
779     }
780     if ((fp = fopen(fname, "wb")) == NULL) {
781         lua_pushboolean(L, 0);
782         return 1;
783     }
784     gdImageGif (im, fp);
785     fclose(fp);
786     lua_pushboolean(L, 1);
787     return 1;
788 }
789 #endif
790 
791 #ifdef GD_GIF
792 /* void *gdImageGifPtr(gdImagePtr im) */
LgdImageGifPtr(lua_State * L)793 static int LgdImageGifPtr(lua_State *L) {
794     gdImagePtr im = getImagePtr(L, 1);
795     char *str;
796     int size;
797 
798     str = gdImageGifPtr(im, &size);
799     if (str != NULL) {
800         lua_pushlstring(L, str, size);
801         gdFree(str);
802     } else {
803         lua_pushnil(L);  /* Error */
804     }
805     return 1;
806 }
807 #endif
808 
809 
810 /* gdImageGd(gdImagePtr im, FILE *out) */
811 /* Changed to: gd.gd(im, fname) */
LgdImageGd(lua_State * L)812 static int LgdImageGd(lua_State *L) {
813     gdImagePtr im = getImagePtr(L, 1);
814     const char *fname = luaL_checkstring(L, 2);
815     FILE *fp;
816 
817     if (fname == NULL) {
818         lua_pushboolean(L, 0);
819         return 1;
820     }
821     if ((fp = fopen(fname, "wb")) == NULL) {
822         lua_pushboolean(L, 0);
823         return 1;
824     }
825     gdImageGd(im, fp);
826     fclose(fp);
827     lua_pushboolean(L, 1);
828     return 1;
829 }
830 
831 
832 /* void *gdImageGdPtr(gdImagePtr im) */
LgdImageGdPtr(lua_State * L)833 static int LgdImageGdPtr(lua_State *L) {
834     gdImagePtr im = getImagePtr(L, 1);
835     char *str;
836     int size;
837 
838     str = gdImageGdPtr(im, &size);
839     if (str != NULL) {
840         lua_pushlstring(L, str, size);
841         gdFree(str);
842     } else {
843         lua_pushnil(L);  /* Error */
844     }
845     return 1;
846 }
847 
848 
849 
850 /* gdImageGd2(gdImagePtr im, FILE *out, int chunkSize, int fmt) */
851 /* Changed to: gd.gd2(im, fname, chunkSize, fmt) */
LgdImageGd2(lua_State * L)852 static int LgdImageGd2(lua_State *L) {
853     gdImagePtr im = getImagePtr(L, 1);
854     const char *fname = luaL_checkstring(L, 2);
855     int cs = luaL_checkinteger(L, 3);
856     int fmt = luaL_checkinteger(L, 4);
857     FILE *fp;
858 
859     if (fname == NULL) {
860         lua_pushboolean(L, 0);
861         return 1;
862     }
863     if ((fp = fopen(fname, "wb")) == NULL) {
864         lua_pushboolean(L, 0);
865         return 1;
866     }
867     gdImageGd2(im, fp, cs, fmt);
868     fclose(fp);
869     lua_pushboolean(L, 1);
870     return 1;
871 }
872 
873 
874 /* void* gdImageGd2Ptr(gdImagePtr im, int chunkSize, int fmt, int *size) */
LgdImageGd2Ptr(lua_State * L)875 static int LgdImageGd2Ptr(lua_State *L) {
876     gdImagePtr im = getImagePtr(L, 1);
877     int cs = luaL_checkinteger(L, 2);
878     int fmt = luaL_checkinteger(L, 3);
879     char *str;
880     int size;
881 
882     str = gdImageGd2Ptr(im, cs, fmt, &size);
883     if (str != NULL) {
884         lua_pushlstring(L, str, size);
885         gdFree(str);
886     } else
887         lua_pushnil(L);  /* Error */
888     return 1;
889 }
890 
891 
892 /* void gdImageWBMP(gdImagePtr im, int fg, FILE *out) */
893 /* Changed to: gd.wbmp(im, int fg, filename) */
LgdImageWBMP(lua_State * L)894 static int LgdImageWBMP(lua_State *L) {
895     gdImagePtr im = getImagePtr(L, 1);
896     int fg = luaL_checkinteger(L, 2);
897     const char *fname = luaL_checkstring(L, 3);
898     FILE *fp;
899 
900     if (fname == NULL) {
901         lua_pushnil(L);
902         return 1;
903     }
904     if ((fp = fopen(fname, "wb")) == NULL) {
905         lua_pushnil(L);
906         return 1;
907     }
908     gdImageWBMP(im, fg, fp);
909     fclose(fp);
910     lua_pushboolean(L, 1);
911     return 1;
912 }
913 
914 
915 /* void* gdImageWBMPPtr(gdImagePtr im, int *size) */
LgdImageWBMPPtr(lua_State * L)916 static int LgdImageWBMPPtr(lua_State *L) {
917     gdImagePtr im = getImagePtr(L, 1);
918     int fg = luaL_checkinteger(L, 2);
919     char *str;
920     int size;
921 
922     str = gdImageWBMPPtr(im, &size, fg);
923     if (str != NULL) {
924         lua_pushlstring(L, str, size);
925         gdFree(str);
926     } else {
927         lua_pushnil(L);  /* Error */
928     }
929     return 1;
930 }
931 
932 
933 /* int gdImageColorAllocate(gdImagePtr im, int r, int g, int b) */
LgdImageColorAllocate(lua_State * L)934 static int LgdImageColorAllocate(lua_State *L) {
935     gdImagePtr im = getImagePtr(L, 1);
936     int r = luaL_checkinteger(L, 2);
937     int g = luaL_checkinteger(L, 3);
938     int b = luaL_checkinteger(L, 4);
939     int c;
940 
941     c = gdImageColorAllocate(im, r, g, b);
942     if (c >= 0)
943         lua_pushnumber(L, c);  /* ok */
944     else
945         lua_pushnil(L); /* Can not allocate color */
946     return 1;
947 }
948 
949 
950 /* int gdImageColorAllocateAlpha(gdImagePtr im, int r, int g, int b, int a) */
LgdImageColorAllocateAlpha(lua_State * L)951 static int LgdImageColorAllocateAlpha(lua_State *L) {
952     gdImagePtr im = getImagePtr(L, 1);
953     int r = luaL_checkinteger(L, 2);
954     int g = luaL_checkinteger(L, 3);
955     int b = luaL_checkinteger(L, 4);
956     int a = luaL_checkinteger(L, 5);
957     int c;
958 
959     c = gdImageColorAllocateAlpha(im, r, g, b, a);
960     if (c >= 0)
961         lua_pushnumber(L, c);  /* ok */
962     else
963         lua_pushnil(L); /* Can not allocate color */
964     return 1;
965 }
966 
967 
968 /* int gdImageColorClosest(gdImagePtr im, int r, int g, int b) */
LgdImageColorClosest(lua_State * L)969 static int LgdImageColorClosest(lua_State *L) {
970     gdImagePtr im = getImagePtr(L, 1);
971     int r = luaL_checkinteger(L, 2);
972     int g = luaL_checkinteger(L, 3);
973     int b = luaL_checkinteger(L, 4);
974     int c;
975 
976     c = gdImageColorClosest(im, r, g, b);
977     if (c >= 0)
978         lua_pushnumber(L, c);  /* ok */
979     else
980         lua_pushnil(L); /* Can not allocate color */
981     return 1;
982 }
983 
984 
985 /* int gdImageColorClosestAlpha(gdImagePtr im, int r, int g, int b, int a) */
LgdImageColorClosestAlpha(lua_State * L)986 static int LgdImageColorClosestAlpha(lua_State *L) {
987     gdImagePtr im = getImagePtr(L, 1);
988     int r = luaL_checkinteger(L, 2);
989     int g = luaL_checkinteger(L, 3);
990     int b = luaL_checkinteger(L, 4);
991     int a = luaL_checkinteger(L, 5);
992     int c;
993 
994     c = gdImageColorClosestAlpha(im, r, g, b, a);
995     if (c > 0)
996         lua_pushnumber(L, c);  /* ok */
997     else
998         lua_pushnil(L); /* Can not allocate color */
999     return 1;
1000 }
1001 
1002 
1003 /* int gdImageColorClosestHWB(gdImagePtr im, int r, int g, int b) */
LgdImageColorClosestHWB(lua_State * L)1004 static int LgdImageColorClosestHWB(lua_State *L) {
1005     gdImagePtr im = getImagePtr(L, 1);
1006     int r = luaL_checkinteger(L, 2);
1007     int g = luaL_checkinteger(L, 3);
1008     int b = luaL_checkinteger(L, 4);
1009     int c;
1010 
1011     c = gdImageColorClosestHWB(im, r, g, b);
1012     if (c >= 0)
1013         lua_pushnumber(L, c);  /* ok */
1014     else
1015         lua_pushnil(L); /* Can not allocate color */
1016     return 1;
1017 }
1018 
1019 
1020 /* int gdImageColorExact(gdImagePtr im, int r, int g, int b) */
LgdImageColorExact(lua_State * L)1021 static int LgdImageColorExact(lua_State *L) {
1022     gdImagePtr im = getImagePtr(L, 1);
1023     int r = luaL_checkinteger(L, 2);
1024     int g = luaL_checkinteger(L, 3);
1025     int b = luaL_checkinteger(L, 4);
1026     int c;
1027 
1028     c = gdImageColorExact(im, r, g, b);
1029     if (c >= 0)
1030         lua_pushnumber(L, c);  /* ok */
1031     else
1032         lua_pushnil(L); /* Can not allocate color */
1033     return 1;
1034 }
1035 
1036 
1037 /* int gdImageColorExactAlpha(gdImagePtr im, int r, int g, int b, int a) */
LgdImageColorExactAlpha(lua_State * L)1038 static int LgdImageColorExactAlpha(lua_State *L) {
1039     gdImagePtr im = getImagePtr(L, 1);
1040     int r = luaL_checkinteger(L, 2);
1041     int g = luaL_checkinteger(L, 3);
1042     int b = luaL_checkinteger(L, 4);
1043     int a = luaL_checkinteger(L, 5);
1044     int c;
1045 
1046     c = gdImageColorExactAlpha(im, r, g, b, a);
1047     if (c >= 0)
1048         lua_pushnumber(L, c);  /* ok */
1049     else
1050         lua_pushnil(L); /* Can not allocate color */
1051     return 1;
1052 }
1053 
1054 
1055 /* int gdImageColorResolve(gdImagePtr im, int r, int g, int b) */
LgdImageColorResolve(lua_State * L)1056 static int LgdImageColorResolve(lua_State *L) {
1057     gdImagePtr im = getImagePtr(L, 1);
1058     int r = luaL_checkinteger(L, 2);
1059     int g = luaL_checkinteger(L, 3);
1060     int b = luaL_checkinteger(L, 4);
1061     int c;
1062 
1063     c = gdImageColorResolve(im, r, g, b);
1064     if (c >= 0)
1065         lua_pushnumber(L, c);  /* ok */
1066     else
1067         lua_pushnil(L); /* Can not allocate color */
1068     return 1;
1069 }
1070 
1071 
1072 /* int gdImageColorResolveAlpha(gdImagePtr im, int r, int g, int b, int a) */
LgdImageColorResolveAlpha(lua_State * L)1073 static int LgdImageColorResolveAlpha(lua_State *L) {
1074     gdImagePtr im = getImagePtr(L, 1);
1075     int r = luaL_checkinteger(L, 2);
1076     int g = luaL_checkinteger(L, 3);
1077     int b = luaL_checkinteger(L, 4);
1078     int a = luaL_checkinteger(L, 5);
1079     int c;
1080 
1081     c = gdImageColorResolveAlpha(im, r, g, b, a);
1082     if (c >= 0)
1083         lua_pushnumber(L, c);  /* ok */
1084     else
1085         lua_pushnil(L); /* Can not allocate color */
1086     return 1;
1087 }
1088 
1089 
1090 /* int gdImageColorsTotal(gdImagePtr im) */
LgdImageColorsTotal(lua_State * L)1091 static int LgdImageColorsTotal(lua_State *L) {
1092     gdImagePtr im = getImagePtr(L, 1);
1093 
1094     lua_pushnumber(L, gdImageColorsTotal(im));  /* ok */
1095     return 1;
1096 }
1097 
1098 
1099 /* int gdImageRed(gdImagePtr im, int c) */
LgdImageRed(lua_State * L)1100 static int LgdImageRed(lua_State *L) {
1101     gdImagePtr im = getImagePtr(L, 1);
1102     int c = luaL_checkinteger(L, 2);
1103 
1104     lua_pushnumber(L, gdImageRed(im, c));  /* ok */
1105     return 1;
1106 }
1107 
1108 /* int gdImageBlue(gdImagePtr im, int c) */
LgdImageBlue(lua_State * L)1109 static int LgdImageBlue(lua_State *L) {
1110     gdImagePtr im = getImagePtr(L, 1);
1111     int c = luaL_checkinteger(L, 2);
1112 
1113     lua_pushnumber(L, gdImageBlue(im, c));  /* ok */
1114     return 1;
1115 }
1116 
1117 /* int gdImageBlue(gdImagePtr im, int c) */
LgdImageGreen(lua_State * L)1118 static int LgdImageGreen(lua_State *L) {
1119     gdImagePtr im = getImagePtr(L, 1);
1120     int c = luaL_checkinteger(L, 2);
1121 
1122     lua_pushnumber(L, gdImageGreen(im, c));  /* ok */
1123     return 1;
1124 }
1125 
1126 /* int gdImageAlpha(gdImagePtr im, int color) */
LgdImageAlpha(lua_State * L)1127 static int LgdImageAlpha(lua_State *L) {
1128     gdImagePtr im = getImagePtr(L, 1);
1129     int c = luaL_checkinteger(L, 2);
1130     lua_pushnumber(L, gdImageAlpha(im, c));
1131     return 1;
1132 }
1133 
1134 /* int gdImageGetInterlaced(gdImagePtr im) */
LgdImageGetInterlaced(lua_State * L)1135 static int LgdImageGetInterlaced(lua_State *L) {
1136     gdImagePtr im = getImagePtr(L, 1);
1137     int ret = gdImageGetInterlaced(im);
1138 
1139     if (ret != 0)
1140         lua_pushnumber(L, ret);
1141     else
1142         lua_pushnil(L);
1143     return 1;
1144 }
1145 
1146 /* int gdImageGetTransparent(gdImagePtr im) */
LgdImageGetTransparent(lua_State * L)1147 static int LgdImageGetTransparent(lua_State *L) {
1148     gdImagePtr im = getImagePtr(L, 1);
1149     int ret = gdImageGetTransparent(im);
1150 
1151     if (ret != -1)
1152         lua_pushnumber(L, ret);
1153     else
1154         lua_pushnil(L);
1155     return 1;
1156 }
1157 
1158 
1159 /* void gdImageColorTransparent(gdImagePtr im, int c) */
LgdImageColorTransparent(lua_State * L)1160 static int LgdImageColorTransparent(lua_State *L) {
1161     gdImagePtr im = getImagePtr(L, 1);
1162     int c = -1;
1163     if (!lua_isnil(L, 2))
1164       c = luaL_checkinteger(L, 2);
1165     gdImageColorTransparent(im, c);
1166     return 0;
1167 }
1168 
1169 
1170 /* void gdImageColorDeallocate(gdImagePtr im, int c) */
LgdImageColorDeallocate(lua_State * L)1171 static int LgdImageColorDeallocate(lua_State *L) {
1172     gdImagePtr im = getImagePtr(L, 1);
1173     int c = luaL_checkinteger(L, 2);
1174     gdImageColorDeallocate(im, c);
1175     return 0;
1176 }
1177 
1178 
1179 /* int gdImageSX(gdImagePtr im) */
LgdImageSX(lua_State * L)1180 static int LgdImageSX(lua_State *L) {
1181     gdImagePtr im = getImagePtr(L, 1);
1182     lua_pushnumber(L, gdImageSX(im));
1183     return 1;
1184 }
1185 
1186 
1187 /* int gdImageSY(gdImagePtr im) */
LgdImageSY(lua_State * L)1188 static int LgdImageSY(lua_State *L) {
1189     gdImagePtr im = getImagePtr(L, 1);
1190     lua_pushnumber(L, gdImageSY(im));
1191     return 1;
1192 }
1193 
1194 
1195 /* Fear the power of the Moon!!  ---   x, y = im:sizeXY() */
LgdImageSXY(lua_State * L)1196 static int LgdImageSXY(lua_State *L) {
1197     gdImagePtr im = getImagePtr(L, 1);
1198     lua_pushnumber(L, gdImageSX(im));
1199     lua_pushnumber(L, gdImageSY(im));
1200     return 2;
1201 }
1202 
1203 
1204 /* int gdImageBoundsSafe(gdImagePtr im, int x, int y) */
LgdImageBoundsSafe(lua_State * L)1205 static int LgdImageBoundsSafe(lua_State *L) {
1206     gdImagePtr im = getImagePtr(L, 1);
1207     int x = luaL_checkinteger(L, 2);
1208     int y = luaL_checkinteger(L, 3);
1209 
1210     if (gdImageBoundsSafe(im, x, y) != 0)
1211         lua_pushboolean(L, 1);
1212     else
1213         lua_pushboolean(L, 0);
1214     return 1;
1215 }
1216 
1217 
1218 /* int gdImageGetPixel(gdImagePtr im, int x, int y) */
LgdImageGetPixel(lua_State * L)1219 static int LgdImageGetPixel(lua_State *L) {
1220     gdImagePtr im = getImagePtr(L, 1);
1221     int x = luaL_checkinteger(L, 2);
1222     int y = luaL_checkinteger(L, 3);
1223 
1224     lua_pushnumber(L, gdImageGetPixel(im, x, y));
1225     return 1;
1226 }
1227 
1228 
1229 /* void gdImageSetPixel(gdImagePtr im, int x, int y, int color) */
LgdImageSetPixel(lua_State * L)1230 static int LgdImageSetPixel(lua_State *L) {
1231     gdImagePtr im = getImagePtr(L, 1);
1232     int x = luaL_checkinteger(L, 2);
1233     int y = luaL_checkinteger(L, 3);
1234     int c = luaL_checkinteger(L, 4);
1235 
1236     gdImageSetPixel(im, x, y, c);
1237     return 0;
1238 }
1239 
1240 
1241 /* void gdImageLine(gdImagePtr im, int x1, int y1, int x2, int y2, int c) */
LgdImageLine(lua_State * L)1242 static int LgdImageLine(lua_State *L) {
1243     gdImagePtr im = getImagePtr(L, 1);
1244     int x1 = luaL_checkinteger(L, 2);
1245     int y1 = luaL_checkinteger(L, 3);
1246     int x2 = luaL_checkinteger(L, 4);
1247     int y2 = luaL_checkinteger(L, 5);
1248     int c = luaL_checkinteger(L, 6);
1249 
1250     gdImageLine(im, x1, y1, x2, y2, c);
1251     return 0;
1252 }
1253 
1254 /* void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2,
1255         int c) */
LgdImageRectangle(lua_State * L)1256 static int LgdImageRectangle(lua_State *L) {
1257     gdImagePtr im = getImagePtr(L, 1);
1258     int x1 = luaL_checkinteger(L, 2);
1259     int y1 = luaL_checkinteger(L, 3);
1260     int x2 = luaL_checkinteger(L, 4);
1261     int y2 = luaL_checkinteger(L, 5);
1262     int c = luaL_checkinteger(L, 6);
1263 
1264     gdImageRectangle(im, x1, y1, x2, y2, c);
1265     return 0;
1266 }
1267 
1268 
1269 /* void gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2,
1270         int c) */
LgdImageFilledRectangle(lua_State * L)1271 static int LgdImageFilledRectangle(lua_State *L) {
1272     gdImagePtr im = getImagePtr(L, 1);
1273     int x1 = luaL_checkinteger(L, 2);
1274     int y1 = luaL_checkinteger(L, 3);
1275     int x2 = luaL_checkinteger(L, 4);
1276     int y2 = luaL_checkinteger(L, 5);
1277     int c = luaL_checkinteger(L, 6);
1278 
1279     gdImageFilledRectangle(im, x1, y1, x2, y2, c);
1280     return 0;
1281 }
1282 
1283 
1284 /* Stack must have ONLY the table of points */
getPointList(lua_State * L,int * size)1285 static gdPoint *getPointList(lua_State *L, int *size) {
1286     gdPoint *plist;
1287     int i;
1288 
1289     luaL_checktype(L, -1, LUA_TTABLE);
1290     *size = luaL_getn(L, -1);
1291     plist = (gdPoint*) malloc(*size * sizeof(gdPoint));
1292 
1293     for (i = 0; i < *size; i++) {
1294         /* Stack: T */
1295         lua_rawgeti(L, 1, i + 1);
1296 
1297         /* Stack:  T, T'  */
1298         if (lua_type(L, 2) != LUA_TTABLE) {
1299             free(plist);
1300             luaL_typerror(L, 2, "Point");
1301         }
1302 
1303         lua_rawgeti(L, 2, 1);
1304         /* Stack:  T, T', X  */
1305         plist[i].x = luaL_checkinteger(L, -1);
1306         lua_remove(L, -1);
1307 
1308         lua_rawgeti(L, 2, 2);
1309         /* Stack:  T, T', Y  */
1310         plist[i].y = luaL_checkinteger(L, -1);
1311         lua_remove(L, -1);
1312 
1313         /* Stack:  T, T' */
1314         lua_remove(L, -1);
1315 
1316         /* Stack: T */
1317     }
1318 
1319     lua_remove(L, -1);
1320     return plist;
1321 }
1322 
1323 
1324 
1325 /* void gdImagePolygon(gdImagePtr im, gdPointPtr points, int pointsTotal,
1326         int color)
1327   Changed to: gd.polygon(im, { { x1, y1 }, { x2, y2 } ... }, color)  */
LgdImagePolygon(lua_State * L)1328 static int LgdImagePolygon(lua_State *L) {
1329     gdImagePtr im = getImagePtr(L, 1);
1330     gdPoint *plist;
1331     int size;
1332     int c;
1333 
1334     c = luaL_checkinteger(L, 3);
1335     lua_remove(L, 3); /* Get and drop color */
1336     lua_remove(L, 1); /* Drop image from the stack */
1337     plist = getPointList(L, &size);
1338     gdImagePolygon(im, plist, size, c);
1339     free(plist);
1340     return 0;
1341 }
1342 
1343 
1344 
1345 /* void gdImageFilledPolygon(gdImagePtr im, gdPointPtr points,
1346         int pointsTotal, int color)
1347   Changed to: gd.filledPolygon(im, { { x1, y1 }, { x2, y2 } ... }, color) */
LgdImageFilledPolygon(lua_State * L)1348 static int LgdImageFilledPolygon(lua_State *L) {
1349     gdImagePtr im = getImagePtr(L, 1);
1350     gdPoint *plist;
1351     int size;
1352     int c;
1353 
1354     c = luaL_checkinteger(L, 3);
1355     lua_remove(L, 3); /* Get and drop color */
1356     lua_remove(L, 1); /* Drop image from the stack */
1357 
1358     plist = getPointList(L, &size);
1359     gdImageFilledPolygon(im, plist, size, c);
1360     free(plist);
1361     return 0;
1362 }
1363 
1364 
1365 /* void gdImageOpenPolygon(gdImagePtr im, gdPointPtr points,
1366         int pointsTotal, int color)
1367   Changed to: gd.openPolygon(im, { { x1, y1 }, { x2, y2 } ... }, color) */
LgdImageOpenPolygon(lua_State * L)1368 static int LgdImageOpenPolygon(lua_State *L) {
1369     gdImagePtr im = getImagePtr(L, 1);
1370     gdPoint *plist;
1371     int size;
1372     int c;
1373 
1374     c = luaL_checkinteger(L, 3);
1375     lua_remove(L, 3); /* Get and drop color */
1376     lua_remove(L, 1); /* Drop image from the stack */
1377 
1378     plist = getPointList(L, &size);
1379     gdImageOpenPolygon(im, plist, size, c);
1380     free(plist);
1381     return 0;
1382 }
1383 
1384 
1385 
1386 /* void gdImageArc(gdImagePtr im, int cx, int cy, int w, int h, int s, int e,
1387     int color) */
LgdImageArc(lua_State * L)1388 static int LgdImageArc(lua_State *L) {
1389     gdImagePtr im = getImagePtr(L, 1);
1390     int cx = luaL_checkinteger(L, 2);
1391     int cy = luaL_checkinteger(L, 3);
1392     int w = luaL_checkinteger(L, 4);
1393     int h = luaL_checkinteger(L, 5);
1394     int s = luaL_checkinteger(L, 6);
1395     int e = luaL_checkinteger(L, 7);
1396     int c = luaL_checkinteger(L, 8);
1397 
1398     gdImageArc(im, cx, cy, w, h, s, e, c);
1399     return 0;
1400 }
1401 
1402 
1403 /* void gdImageFilledArc(gdImagePtr im, int cx, int cy, int w, int h,
1404     int s, int e, int color, int style) */
LgdImageFilledArc(lua_State * L)1405 static int LgdImageFilledArc(lua_State *L) {
1406     gdImagePtr im = getImagePtr(L, 1);
1407     int cx = luaL_checkinteger(L, 2);
1408     int cy = luaL_checkinteger(L, 3);
1409     int w = luaL_checkinteger(L, 4);
1410     int h = luaL_checkinteger(L, 5);
1411     int s = luaL_checkinteger(L, 6);
1412     int e = luaL_checkinteger(L, 7);
1413     int c = luaL_checkinteger(L, 8);
1414     int sty = luaL_checkinteger(L, 9);
1415 
1416     gdImageFilledArc(im, cx, cy, w, h, s, e, c, sty);
1417     return 0;
1418 }
1419 
1420 
1421 /* void gdImageFilledEllipse(gdImagePtr im, int cx, int cy, int w, int h,
1422         int color) */
LgdImageFilledEllipse(lua_State * L)1423 static int LgdImageFilledEllipse(lua_State *L) {
1424     gdImagePtr im = getImagePtr(L, 1);
1425     int cx = luaL_checkinteger(L, 2);
1426     int cy = luaL_checkinteger(L, 3);
1427     int w = luaL_checkinteger(L, 4);
1428     int h = luaL_checkinteger(L, 5);
1429     int c = luaL_checkinteger(L, 6);
1430 
1431     gdImageFilledEllipse(im, cx, cy, w, h, c);
1432     return 0;
1433 }
1434 
1435 
1436 /* void gdImageFill(gdImagePtr im, int x, int y, int color) */
LgdImageFill(lua_State * L)1437 static int LgdImageFill(lua_State *L) {
1438     gdImagePtr im = getImagePtr(L, 1);
1439     int x = luaL_checkinteger(L, 2);
1440     int y = luaL_checkinteger(L, 3);
1441     int c = luaL_checkinteger(L, 4);
1442 
1443     gdImageFill(im, x, y, c);
1444     return 0;
1445 }
1446 
1447 
1448 /* void gdImageFillToBorder(gdImagePtr im, int x, int y, int border,
1449         int color) */
LgdImageFillToBorder(lua_State * L)1450 static int LgdImageFillToBorder(lua_State *L) {
1451     gdImagePtr im = getImagePtr(L, 1);
1452     int x = luaL_checkinteger(L, 2);
1453     int y = luaL_checkinteger(L, 3);
1454     int b = luaL_checkinteger(L, 4);
1455     int c = luaL_checkinteger(L, 5);
1456 
1457     gdImageFillToBorder(im, x, y, b, c);
1458     return 0;
1459 }
1460 
1461 
1462 /* void gdImageSetAntiAliased(gdImagePtr im, int c) */
LgdImageSetAntiAliased(lua_State * L)1463 static int LgdImageSetAntiAliased(lua_State *L) {
1464     gdImagePtr im = getImagePtr(L, 1);
1465     int c = luaL_checkinteger(L, 2);
1466 
1467     gdImageSetAntiAliased(im, c);
1468     return 0;
1469 }
1470 
1471 
1472 /* void gdImageSetAntiAliasedDontBlend(gdImagePtr im, int c) */
LgdImageSetAntiAliasedDontBlend(lua_State * L)1473 static int LgdImageSetAntiAliasedDontBlend(lua_State *L) {
1474     gdImagePtr im = getImagePtr(L, 1);
1475     int c = luaL_checkinteger(L, 2);
1476 
1477     gdImageSetAntiAliasedDontBlend(im, c, 1);
1478     return 0;
1479 }
1480 
1481 
1482 /* void gdImageSetBrush(gdImagePtr im, gdImagePtr brush) */
LgdImageSetBrush(lua_State * L)1483 static int LgdImageSetBrush(lua_State *L) {
1484     gdImagePtr im = getImagePtr(L, 1);
1485     gdImagePtr b = getImagePtr(L, 2);
1486 
1487     gdImageSetBrush(im, b);
1488     return 0;
1489 }
1490 
1491 
1492 /* void gdImageSetTile(gdImagePtr im, gdImagePtr tile) */
LgdImageSetTile(lua_State * L)1493 static int LgdImageSetTile(lua_State *L) {
1494     gdImagePtr im = getImagePtr(L, 1);
1495     gdImagePtr t = getImagePtr(L, 1);
1496 
1497     gdImageSetTile(im, t);
1498     return 0;
1499 }
1500 
1501 
1502 /* void gdImageSetStyle(gdImagePtr im, int *style, int styleLength)  */
1503 /* Changed To: gd.setStyle(im, { c1, c2, c3,  ...  } ) */
LgdImageSetStyle(lua_State * L)1504 static int LgdImageSetStyle(lua_State *L) {
1505     gdImagePtr im = getImagePtr(L, 1);
1506     int *slist;
1507     int size;
1508     int i;
1509 
1510     /* Stack: Im, T */
1511     luaL_checktype(L, -1, LUA_TTABLE);
1512     size = luaL_getn(L, -1);
1513     slist = (int*) malloc(size * sizeof(int));
1514 
1515     for (i = 0; i < size; i++) {
1516         /* Stack: Im, T */
1517         lua_rawgeti(L, 2, i + 1);
1518 
1519         /* Stack:  Im, T, num */
1520         if (lua_type(L, -1) != LUA_TNUMBER) {
1521             free(slist);
1522             luaL_typerror(L, -1, "Number");
1523         }
1524 
1525         slist[i] = luaL_checkinteger(L, -1);
1526         lua_remove(L, -1);
1527 
1528         /* Stack: Im, T */
1529     }
1530 
1531     gdImageSetStyle(im, slist, size);
1532     free(slist);
1533     return 0;
1534 }
1535 
1536 
1537 /* void gdImageSetThickness(gdImagePtr im, int thickness) */
LgdImageSetThickness(lua_State * L)1538 static int LgdImageSetThickness(lua_State *L) {
1539     gdImagePtr im = getImagePtr(L, 1);
1540     int t = luaL_checkinteger(L, 2);
1541 
1542     gdImageSetThickness(im, t);
1543     return 0;
1544 }
1545 
1546 
1547 /* void gdImageAlphaBlending(gdImagePtr im, int blending) */
1548 /* Changed to: im:alphaBlending(true_or_false) */
LgdImageAlphaBlending(lua_State * L)1549 static int LgdImageAlphaBlending(lua_State *L) {
1550     gdImagePtr im = getImagePtr(L, 1);
1551     int b = lua_toboolean(L, 2);
1552 
1553     gdImageAlphaBlending(im, b);
1554     return 0;
1555 }
1556 
1557 
1558 /* void gdImageSaveAlpha(gdImagePtr im, int saveFlag) */
1559 /* Changed to: im:saveAlpha(true_or_false) */
LgdImageSaveAlpha(lua_State * L)1560 static int LgdImageSaveAlpha(lua_State *L) {
1561     gdImagePtr im = getImagePtr(L, 1);
1562     int b = lua_toboolean(L, 2);
1563 
1564     gdImageSaveAlpha(im, b);
1565     return 0;
1566 }
1567 
1568 
1569 /* gdImageInterlace(gdImagePtr im, int interlace) */
1570 /* Changed to: im:interlace(true_or_false) */
LgdImageInterlace(lua_State * L)1571 static int LgdImageInterlace(lua_State *L) {
1572     gdImagePtr im = getImagePtr(L, 1);
1573     int i = lua_toboolean(L, 2);
1574 
1575     gdImageInterlace(im, i);
1576     return 0;
1577 }
1578 
1579 
1580 /* void gdImageString(gdImagePtr im, gdFontPtr font, int x, int y,
1581         unsigned char *s, int color) */
LgdImageString(lua_State * L)1582 static int LgdImageString(lua_State *L) {
1583     gdImagePtr im = getImagePtr(L, 1);
1584     gdFontPtr fnt = getStdFont(L, 2);
1585     int x = luaL_checkinteger(L, 3);
1586     int y = luaL_checkinteger(L, 4);
1587     unsigned char *str = (unsigned char*) luaL_checkstring(L, 5);
1588     int c = luaL_checkinteger(L, 6);
1589 
1590     gdImageString(im, fnt, x, y, str, c);
1591     return 0;
1592 }
1593 
1594 
1595 /* void gdImageStringUp(gdImagePtr im, gdFontPtr font, int x, int y,
1596         unsigned char *s, int color)  */
LgdImageStringUp(lua_State * L)1597 static int LgdImageStringUp(lua_State *L) {
1598     gdImagePtr im = getImagePtr(L, 1);
1599     gdFontPtr fnt = getStdFont(L, 2);
1600     int x = luaL_checkinteger(L, 3);
1601     int y = luaL_checkinteger(L, 4);
1602     unsigned char *str = (unsigned char*) luaL_checkstring(L, 5);
1603     int c = luaL_checkinteger(L, 6);
1604 
1605     gdImageStringUp(im, fnt, x, y, str, c);
1606     return 0;
1607 }
1608 
1609 
1610 /* void gdImageChar(gdImagePtr im, gdFontPtr font, int x, int y,
1611             int c, int color)  */
1612 /* Useless? */
LgdImageChar(lua_State * L)1613 static int LgdImageChar(lua_State *L) {
1614     gdImagePtr im = getImagePtr(L, 1);
1615     gdFontPtr fnt = getStdFont(L, 2);
1616     int x = luaL_checkinteger(L, 3);
1617     int y = luaL_checkinteger(L, 4);
1618     char *str = (char*) luaL_checkstring(L, 5);
1619     int c = luaL_checkinteger(L, 6);
1620     int chr;
1621 
1622     if (str) {
1623         chr = (int) str[0];
1624     } else {
1625         luaL_typerror(L, 5, "string");
1626         return 0;
1627     }
1628 
1629     gdImageChar(im, fnt, x, y, chr, c);
1630     return 0;
1631 }
1632 
1633 
1634 /* void gdImageCharUp(gdImagePtr im, gdFontPtr font, int x, int y,
1635             int c, int color)  */
LgdImageCharUp(lua_State * L)1636 static int LgdImageCharUp(lua_State *L) {
1637     gdImagePtr im = getImagePtr(L, 1);
1638     gdFontPtr fnt = getStdFont(L, 2);
1639     int x = luaL_checkinteger(L, 3);
1640     int y = luaL_checkinteger(L, 4);
1641     char *str = (char*) luaL_checkstring(L, 5);
1642     int c = luaL_checkinteger(L, 6);
1643     int chr;
1644 
1645     if (str)
1646         chr = (int) str[0];
1647     else {
1648         luaL_typerror(L, 5, "string");
1649         return 0;
1650     }
1651 
1652     gdImageCharUp(im, fnt, x, y, chr, c);
1653     return 0;
1654 }
1655 
1656 
1657 /* void gdImageCopy(gdImagePtr dst, gdImagePtr src, int dstX, int dstY,
1658             int srcX, int srcY, int w, int h) */
LgdImageCopy(lua_State * L)1659 static int LgdImageCopy(lua_State *L) {
1660     gdImagePtr dst = getImagePtr(L, 1);
1661     gdImagePtr src = getImagePtr(L, 2);
1662     int dstX = luaL_checkinteger(L, 3);
1663     int dstY = luaL_checkinteger(L, 4);
1664     int srcX = luaL_checkinteger(L, 5);
1665     int srcY = luaL_checkinteger(L, 6);
1666     int w = luaL_checkinteger(L, 7);
1667     int h = luaL_checkinteger(L, 8);
1668 
1669     gdImageCopy(dst, src, dstX, dstY, srcX, srcY, w, h);
1670     return 0;
1671 }
1672 
1673 
1674 
1675 /* void gdImageCopyResized(gdImagePtr dst, gdImagePtr src, int dstX,
1676             int dstY, int srcX, int srcY, int destW, int destH,
1677             int srcW, int srcH)  */
LgdImageCopyResized(lua_State * L)1678 static int LgdImageCopyResized(lua_State *L) {
1679     gdImagePtr dst = getImagePtr(L, 1);
1680     gdImagePtr src = getImagePtr(L, 2);
1681     int dstX = luaL_checkinteger(L, 3);
1682     int dstY = luaL_checkinteger(L, 4);
1683     int srcX = luaL_checkinteger(L, 5);
1684     int srcY = luaL_checkinteger(L, 6);
1685     int dstW = luaL_checkinteger(L, 7);
1686     int dstH = luaL_checkinteger(L, 8);
1687     int srcW = luaL_checkinteger(L, 9);
1688     int srcH = luaL_checkinteger(L, 10);
1689 
1690     gdImageCopyResized(dst, src, dstX, dstY, srcX, srcY, dstW, dstH,
1691         srcW, srcH);
1692     return 0;
1693 }
1694 
1695 
1696 /* void gdImageCopyResampled(gdImagePtr dst, gdImagePtr src, int dstX,
1697         int dstY, int srcX, int srcY, int destW, int destH, int srcW,
1698         int srcH)  */
LgdImageCopyResampled(lua_State * L)1699 static int LgdImageCopyResampled(lua_State *L) {
1700     gdImagePtr dst = getImagePtr(L, 1);
1701     gdImagePtr src = getImagePtr(L, 2);
1702     int dstX = luaL_checkinteger(L, 3);
1703     int dstY = luaL_checkinteger(L, 4);
1704     int srcX = luaL_checkinteger(L, 5);
1705     int srcY = luaL_checkinteger(L, 6);
1706     int dstW = luaL_checkinteger(L, 7);
1707     int dstH = luaL_checkinteger(L, 8);
1708     int srcW = luaL_checkinteger(L, 9);
1709     int srcH = luaL_checkinteger(L, 10);
1710 
1711     gdImageCopyResampled(dst, src, dstX, dstY, srcX, srcY, dstW, dstH,
1712         srcW, srcH);
1713     return 0;
1714 }
1715 
1716 
1717 /* void gdImageCopyRotated(gdImagePtr dst, gdImagePtr src, double dstX,
1718         double dstY, int srcX, int srcY, int srcW, int srcH, int angle) */
LgdImageCopyRotated(lua_State * L)1719 static int LgdImageCopyRotated(lua_State *L) {
1720     gdImagePtr dst = getImagePtr(L, 1);
1721     gdImagePtr src = getImagePtr(L, 2);
1722     double dstX = (double) lua_tonumber(L, 3);
1723     double dstY = (double) lua_tonumber(L, 4);
1724     int srcX = luaL_checkinteger(L, 5);
1725     int srcY = luaL_checkinteger(L, 6);
1726     int srcW = luaL_checkinteger(L, 7);
1727     int srcH = luaL_checkinteger(L, 8);
1728     int ang = luaL_checkinteger(L, 9);
1729 
1730     gdImageCopyRotated(dst, src, dstX, dstY, srcX, srcY, srcW, srcH, ang);
1731     return 0;
1732 }
1733 
1734 
1735 /* void gdImageCopyMerge(gdImagePtr dst, gdImagePtr src, int dstX,
1736         int dstY, int srcX, int srcY, int w, int h, int pct)  */
LgdImageCopyMerge(lua_State * L)1737 static int LgdImageCopyMerge(lua_State *L) {
1738     gdImagePtr dst = getImagePtr(L, 1);
1739     gdImagePtr src = getImagePtr(L, 2);
1740     int dstX = luaL_checkinteger(L, 3);
1741     int dstY = luaL_checkinteger(L, 4);
1742     int srcX = luaL_checkinteger(L, 5);
1743     int srcY = luaL_checkinteger(L, 6);
1744     int w = luaL_checkinteger(L, 7);
1745     int h = luaL_checkinteger(L, 8);
1746     int pct = luaL_checkinteger(L, 9);
1747 
1748     gdImageCopyMerge(dst, src, dstX, dstY, srcX, srcY, w, h, pct);
1749     return 0;
1750 }
1751 
1752 
1753 /* void gdImageCopyMergeGray(gdImagePtr dst, gdImagePtr src, int dstX,
1754         int dstY, int srcX, int srcY, int w, int h, int pct) */
LgdImageCopyMergeGray(lua_State * L)1755 static int LgdImageCopyMergeGray(lua_State *L) {
1756     gdImagePtr dst = getImagePtr(L, 1);
1757     gdImagePtr src = getImagePtr(L, 2);
1758     int dstX = luaL_checkinteger(L, 3);
1759     int dstY = luaL_checkinteger(L, 4);
1760     int srcX = luaL_checkinteger(L, 5);
1761     int srcY = luaL_checkinteger(L, 6);
1762     int w = luaL_checkinteger(L, 7);
1763     int h = luaL_checkinteger(L, 8);
1764     int pct = luaL_checkinteger(L, 9);
1765 
1766     gdImageCopyMergeGray(dst, src, dstX, dstY, srcX, srcY, w, h, pct);
1767     return 0;
1768 }
1769 
1770 
1771 /* void gdImagePaletteCopy(gdImagePtr dst, gdImagePtr src) */
LgdImagePaletteCopy(lua_State * L)1772 static int LgdImagePaletteCopy(lua_State *L) {
1773     gdImagePtr dst = getImagePtr(L, 1);
1774     gdImagePtr src = getImagePtr(L, 2);
1775 
1776     gdImagePaletteCopy(dst, src);
1777     return 0;
1778 }
1779 
1780 
1781 /* void gdImageSquareToCircle(gdImagePtr im, int radius) */
LgdImageSquareToCircle(lua_State * L)1782 static int LgdImageSquareToCircle(lua_State *L) {
1783     gdImagePtr im = getImagePtr(L, 1);
1784     int r = luaL_checkinteger(L, 2);
1785 
1786     gdImageSquareToCircle(im, r);
1787     return 0;
1788 }
1789 
1790 
1791 /* void gdImageSharpen(gdImagePtr im, int pct) */
LgdImageSharpen(lua_State * L)1792 static int LgdImageSharpen(lua_State *L) {
1793     gdImagePtr im = getImagePtr(L, 1);
1794     int pct = luaL_checkinteger(L, 2);
1795 
1796     gdImageSharpen(im, pct);
1797     return 0;
1798 }
1799 
1800 
1801 /* void gdImageSetClip(gdImagePtr im, int x1, int y1, int x2, int y2) */
LgdImageSetClip(lua_State * L)1802 static int LgdImageSetClip(lua_State *L) {
1803     gdImagePtr im = getImagePtr(L, 1);
1804     int x1 = luaL_checkinteger(L, 2);
1805     int y1 = luaL_checkinteger(L, 3);
1806     int x2 = luaL_checkinteger(L, 4);
1807     int y2 = luaL_checkinteger(L, 5);
1808 
1809     gdImageSetClip(im, x1, y1, x2, y2);
1810     return 0;
1811 }
1812 
1813 
1814 /* void gdImageGetClip(gdImagePtr im, int *x1, int *y1, int *x2, int *y2) */
1815 /* Changed to:  x1p, y1p, x2p, y2p = im:getClip() */
LgdImageGetClip(lua_State * L)1816 static int LgdImageGetClip(lua_State *L) {
1817     gdImagePtr im = getImagePtr(L, 1);
1818     int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
1819 
1820     gdImageGetClip(im, &x1, &y1, &x2, &y2);
1821     lua_pushnumber(L, x1);
1822     lua_pushnumber(L, y1);
1823     lua_pushnumber(L, x2);
1824     lua_pushnumber(L, y2);
1825     return 4;
1826 }
1827 
1828 
1829 #ifdef GD_FONTCONFIG
1830 /* int gdFTUseFontConfig(int flag) */
1831 /* Changed to: gd.useFontConfig(true_or_false) */
LgdFTUseFontConfig(lua_State * L)1832 static int LgdFTUseFontConfig(lua_State *L) {
1833     int b = lua_toboolean(L, 1);
1834     lua_pushboolean(L, gdFTUseFontConfig(b));
1835     return 1;
1836 }
1837 #endif
1838 
1839 
1840 #ifdef GD_FREETYPE
1841 /* int gdFontCacheSetup(void) */
LgdFontCacheSetup(lua_State * L)1842 static int LgdFontCacheSetup(lua_State *L) {
1843     lua_pushboolean(L, !gdFontCacheSetup());
1844     return 1;
1845 }
1846 
1847 
1848 /* void gdFontCacheShutdown(void) */
LgdFontCacheShutdown(lua_State * L)1849 static int LgdFontCacheShutdown(lua_State *L) {
1850     gdFontCacheShutdown();
1851     return 0;
1852 }
1853 #endif
1854 
1855 
1856 /* char *gdImageStringFT(gdImagePtr im, int *brect, int fg, char *fontname,
1857         double ptsize, double angle, int x, int y, char *string)
1858 
1859  Changed To:
1860     llX, llY, lrX, lrY, urX, urY, ulX, ulY = im:stringFT(fg, fontname,
1861             ptsize, angle, x, y, string)
1862 
1863   Or (to get the points only):
1864     llX, llY, lrX, lrY, urX, urY, ulX, ulY = gd.stringFT(nil, fg,
1865             fontname, ptsize, angle, x, y, string)
1866 */
1867 
1868 #ifdef GD_FREETYPE
LgdImageStringFT(lua_State * L)1869 static int LgdImageStringFT(lua_State *L) {
1870     gdImagePtr im;
1871     int fg = luaL_checkinteger(L, 2);
1872     char *font = (char*) luaL_checkstring(L, 3);
1873     double size = (double) lua_tonumber(L, 4);
1874     double ang = (double) lua_tonumber(L, 5);
1875     int x = luaL_checkinteger(L, 6);
1876     int y = luaL_checkinteger(L, 7);
1877     char *str = (char*) luaL_checkstring(L, 8);
1878     int brect[8];
1879 
1880     if (lua_isnil(L, 1))
1881         im = NULL;
1882     else
1883         im = getImagePtr(L, 1);
1884 
1885     if (gdImageStringFT(im, brect, fg, font, size, ang, x, y, str) == NULL) {
1886         lua_pushnumber(L, brect[0]);
1887         lua_pushnumber(L, brect[1]);
1888         lua_pushnumber(L, brect[2]);
1889         lua_pushnumber(L, brect[3]);
1890         lua_pushnumber(L, brect[4]);
1891         lua_pushnumber(L, brect[5]);
1892         lua_pushnumber(L, brect[6]);
1893         lua_pushnumber(L, brect[7]);
1894         return 8;
1895     }
1896 
1897     lua_pushnil(L);
1898     return 1;
1899 }
1900 
1901 
1902 /* char *gdImageStringFT(gdImagePtr im, int *brect, int fg, char *fontname,
1903         double ptsize, double angle, int x, int y, char *string)
1904 
1905  Changed To:
1906     llX, llY, lrX, lrY, urX, urY, ulX, ulY [, xshow] [, fontpath] =
1907         im:stringFTEx(fg, fontname, ptsize, angle, x, y, string, { ... })
1908 
1909   Or:
1910     llX, llY, lrX, lrY, urX, urY, ulX, ulY [, xshow] [, fontpath] =
1911         gd.stringFTEx(nil, fg, fontname, ptsize, angle, x, y, string, { ... })
1912 
1913 */
1914 
LgdImageStringFTEx(lua_State * L)1915 static int LgdImageStringFTEx(lua_State *L) {
1916     gdImagePtr im;
1917     int fg = luaL_checkinteger(L, 2);
1918     char *font = (char*) luaL_checkstring(L, 3);
1919     double size = (double) lua_tonumber(L, 4);
1920     double ang = (double) lua_tonumber(L, 5);
1921     int x = luaL_checkinteger(L, 6);
1922     int y = luaL_checkinteger(L, 7);
1923     char *str = (char*) luaL_checkstring(L, 8);
1924     gdFTStringExtra *ex = getFTStringExtraPtr(L, 9);
1925     int brect[8];
1926     int ret = 8;
1927 
1928     if (lua_isnil(L, 1))
1929         im = NULL;
1930     else
1931         im = getImagePtr(L, 1);
1932 
1933     if (gdImageStringFTEx(im, brect, fg, font, size, ang, x, y, str, ex) == NULL) {
1934         lua_pushnumber(L, brect[0]);
1935         lua_pushnumber(L, brect[1]);
1936         lua_pushnumber(L, brect[2]);
1937         lua_pushnumber(L, brect[3]);
1938         lua_pushnumber(L, brect[4]);
1939         lua_pushnumber(L, brect[5]);
1940         lua_pushnumber(L, brect[6]);
1941         lua_pushnumber(L, brect[7]);
1942         ret = 8;
1943         if (ex->flags & gdFTEX_XSHOW) {
1944             lua_pushstring(L, ex->xshow);
1945             gdFree(ex->xshow);
1946             ret++;
1947         }
1948         if (ex->flags & gdFTEX_RETURNFONTPATHNAME) {
1949             lua_pushstring(L, ex->fontpath);
1950             gdFree(ex->fontpath);
1951             ret++;
1952         }
1953 
1954         free(ex);
1955         return ret;
1956     }
1957 
1958     lua_pushnil(L);
1959     return 1;
1960 }
1961 
1962 
1963 
1964 /* char *gdImageStringFTCircle(gdImagePtr im, int cx, int cy, double radius,
1965                 double textRadius, double fillPortion, char *font,
1966                 double points, char *top, char *bottom, int fgcolor)
1967 
1968    Changed to: im:stringFTCircle(cx, cy, radius, textRadius,
1969                    fillPortion, fontname, points, top, bottom, color)
1970 */
1971 
LgdImageStringFTCircle(lua_State * L)1972 static int LgdImageStringFTCircle(lua_State *L) {
1973     gdImagePtr im = getImagePtr(L, 1);
1974     int cx = luaL_checkinteger(L, 2);
1975     int cy = luaL_checkinteger(L, 3);
1976     double radius = (double) lua_tonumber(L, 4);
1977     double textRadius = (double) lua_tonumber(L, 5);
1978     double fillPortion = (double) lua_tonumber(L, 6);
1979     char *font = (char*) luaL_checkstring(L, 7);
1980     double points = (double) lua_tonumber(L, 8);
1981     char *top = (char*) luaL_checkstring(L, 9);
1982     char *bottom = (char*) luaL_checkstring(L, 10);
1983     int color = luaL_checkinteger(L, 11);
1984 
1985     if (gdImageStringFTCircle(im, cx, cy, radius, textRadius, fillPortion,
1986         font, points, top, bottom, color))
1987         lua_pushboolean(L, 0);  /* Error */
1988     else
1989         lua_pushboolean(L, 1);
1990     return 1;
1991 }
1992 #endif
1993 
1994 
1995 #ifdef GD_GIF
1996 /* void gdImageGifAnimBegin(gdImagePtr im, FILE *out, int GlobalCM, int Loops)
1997     Changed to:  im:gifAnimBegin(filename, globalCM, loops)
1998 */
1999 
LgdImageGifAnimBegin(lua_State * L)2000 static int LgdImageGifAnimBegin(lua_State *L) {
2001     gdImagePtr im = getImagePtr(L, 1);
2002     const char *fname = luaL_checkstring(L, 2);
2003     int globalCM = lua_toboolean(L, 3);
2004     int loops = luaL_checkinteger(L, 4);
2005     FILE *fp;
2006 
2007     if ((fp = fopen(fname, "wb")) == NULL) {
2008         lua_pushboolean(L, 0); /* Error */
2009         return 1;
2010     }
2011 
2012     gdImageGifAnimBegin(im, fp, globalCM, loops);
2013     fclose(fp);
2014     lua_pushboolean(L, 1);  /* ok */
2015     return 1;
2016 }
2017 
2018 
2019 /* void gdImageGifAnimAdd(gdImagePtr im, FILE *out, int LocalCM, int LeftOfs,
2020             int TopOfs, int Delay, int Disposal, gdImagePtr previm)
2021     Changed to:  im:gifAnimAdd(filename, localCM, leftOfs, topOfs, delay,
2022                     disposal [, previm])
2023 */
2024 
LgdImageGifAnimAdd(lua_State * L)2025 static int LgdImageGifAnimAdd(lua_State *L) {
2026     gdImagePtr im = getImagePtr(L, 1);
2027     const char *fname = luaL_checkstring(L, 2);
2028     int localCM = lua_toboolean(L, 3);
2029     int leftOfs = luaL_checkinteger(L, 4);
2030     int topOfs = luaL_checkinteger(L, 5);
2031     int delay = luaL_checkinteger(L, 6);
2032     int disp = luaL_checkinteger(L, 7);
2033     gdImagePtr previm = NULL;
2034     FILE *fp;
2035 
2036     if (lua_gettop(L) >= 8)
2037         previm = getImagePtr(L, 8);
2038 
2039     if ((fp = fopen(fname, "ab")) == NULL) {
2040         lua_pushboolean(L, 0); /* Error */
2041         return 1;
2042     }
2043 
2044     gdImageGifAnimAdd(im, fp, localCM, leftOfs, topOfs, delay, disp, previm);
2045     fclose(fp);
2046     lua_pushboolean(L, 1);  /* ok */
2047     return 1;
2048 }
2049 
2050 
2051 /*  void gdImageGifAnimEnd(FILE *out)
2052     Changed to:  gd.gifAnimEnd(filename)
2053 */
2054 
LgdImageGifAnimEnd(lua_State * L)2055 static int LgdImageGifAnimEnd(lua_State *L) {
2056     const char *fname = luaL_checkstring(L, 1);
2057     FILE *fp;
2058 
2059     if ((fp = fopen(fname, "ab")) == NULL) {
2060         lua_pushboolean(L, 0); /* Error */
2061         return 1;
2062     }
2063 
2064     gdImageGifAnimEnd(fp);
2065     fclose(fp);
2066     lua_pushboolean(L, 1);  /* ok */
2067     return 1;
2068 }
2069 
2070 
2071 /* void* gdImageGifAnimBeginPtr(gdImagePtr im, int *size, int GlobalCM,
2072         int Loops)
2073     Changed to:  im:gifAnimBeginStr(globalCM, loops)
2074 */
2075 
LgdImageGifAnimBeginPtr(lua_State * L)2076 static int LgdImageGifAnimBeginPtr(lua_State *L) {
2077     gdImagePtr im = getImagePtr(L, 1);
2078     int globalCM = lua_toboolean(L, 2);
2079     int loops = luaL_checkinteger(L, 3);
2080     char *str;
2081     int size;
2082 
2083     str = gdImageGifAnimBeginPtr(im, &size, globalCM, loops);
2084     if (str != NULL) {
2085         lua_pushlstring(L, str, size);
2086         gdFree(str);
2087     } else
2088         lua_pushnil(L);
2089     return 1;
2090 }
2091 
2092 
2093 /* void* gdImageGifAnimAddPtr(gdImagePtr im, int *size, int LocalCM,
2094     int LeftOfs, int TopOfs, int Delay, int Disposal, gdImagePtr previm)
2095 
2096     Changed to: im:gifAnimAddStr(localCM, leftOfs, topOfs, delay,
2097                     disposal [, previm])
2098 */
2099 
LgdImageGifAnimAddPtr(lua_State * L)2100 static int LgdImageGifAnimAddPtr(lua_State *L) {
2101     gdImagePtr im = getImagePtr(L, 1);
2102     int localCM = lua_toboolean(L, 2);
2103     int leftOfs = luaL_checkinteger(L, 3);
2104     int topOfs = luaL_checkinteger(L, 4);
2105     int delay = luaL_checkinteger(L, 5);
2106     int disp = luaL_checkinteger(L, 6);
2107     gdImagePtr previm = NULL;
2108     int size;
2109     char *str;
2110 
2111     if (lua_gettop(L) >= 7)
2112         previm = getImagePtr(L, 7);
2113 
2114     str = gdImageGifAnimAddPtr(im, &size, localCM, leftOfs, topOfs, delay,
2115             disp, previm);
2116     if (str != NULL) {
2117         lua_pushlstring(L, str, size);
2118         gdFree(str);
2119     } else
2120         lua_pushnil(L);
2121     return 1;
2122 }
2123 
2124 
2125 /* void* gdImageGifAnimEndPtr(int *size)
2126     Changed to:  gd.gifAnimEndStr()
2127 */
2128 
LgdImageGifAnimEndPtr(lua_State * L)2129 static int LgdImageGifAnimEndPtr(lua_State *L) {
2130     int size;
2131     char *str;
2132 
2133     str = gdImageGifAnimEndPtr(&size);
2134     if (str != NULL) {
2135         lua_pushlstring(L, str, size);
2136         gdFree(str);
2137     } else
2138         lua_pushnil(L);
2139     return 1;
2140 }
2141 
2142 #endif
2143 
2144 
2145 
2146 static const luaL_reg LgdFunctions[] =
2147 {
2148 /*  Leave Lua do it!
2149     { "destroy",                LgdImageDestroy }, */
2150 
2151     { "create",                     LgdImageCreate },
2152     { "createPalette",              LgdImageCreatePalette },
2153     { "createTrueColor",            LgdImageCreateTrueColor },
2154     { "createPaletteFromTrueColor", LgdImageCreatePaletteFromTrueColor },
2155     { "trueColorToPalette",         LgdImageTrueColorToPalette },
2156 
2157 #ifdef GD_JPEG
2158     { "createFromJpeg",         LgdImageCreateFromJpeg },
2159     { "createFromJpegStr",      LgdImageCreateFromJpegPtr },
2160 #endif
2161 #ifdef GD_GIF
2162     { "createFromGif",          LgdImageCreateFromGif },
2163     { "createFromGifStr",       LgdImageCreateFromGifPtr },
2164 #endif
2165     { "createFromPng",          LgdImageCreateFromPng },
2166     { "createFromPngStr",       LgdImageCreateFromPngPtr },
2167     { "createFromGd",           LgdImageCreateFromGd },
2168     { "createFromGdStr",        LgdImageCreateFromGdPtr },
2169     { "createFromGd2",          LgdImageCreateFromGd2 },
2170     { "createFromGd2Str",       LgdImageCreateFromGd2Ptr },
2171     { "createFromGd2Part",      LgdImageCreateFromGd2Part },
2172     { "createFromGd2PartStr",   LgdImageCreateFromGd2PartPtr },
2173 
2174 #ifdef GD_XPM
2175     { "createFromXbm",          LgdImageCreateFromXbm },
2176     { "createFromXpm",          LgdImageCreateFromXpm },
2177 #endif
2178 
2179 #ifdef GD_JPEG
2180     { "jpeg",                   LgdImageJpeg },
2181     { "jpegStr",                LgdImageJpegPtr },
2182 #endif
2183 #ifdef GD_PNG
2184     { "png",                    LgdImagePng },
2185     { "pngStr",                 LgdImagePngPtr },
2186     { "pngEx",                  LgdImagePngEx },
2187     { "pngStrEx",               LgdImagePngPtrEx },
2188 #endif
2189 #ifdef GD_GIF
2190     { "gif",                    LgdImageGif },
2191     { "gifStr",                 LgdImageGifPtr },
2192 #endif
2193     { "gd",                     LgdImageGd },
2194     { "gdStr",                  LgdImageGdPtr },
2195     { "gd2",                    LgdImageGd2 },
2196     { "gd2Str",                 LgdImageGd2Ptr },
2197     { "wbmp",                   LgdImageWBMP },
2198     { "wbmpStr",                LgdImageWBMPPtr },
2199 
2200     { "colorAllocate",          LgdImageColorAllocate },
2201     { "colorAllocateAlpha",     LgdImageColorAllocateAlpha },
2202     { "colorClosest",           LgdImageColorClosest },
2203     { "colorClosestAlpha",      LgdImageColorClosestAlpha },
2204     { "colorClosestHWB",        LgdImageColorClosestHWB },
2205     { "colorExact",             LgdImageColorExact },
2206     { "colorExactAlpha",        LgdImageColorExactAlpha },
2207     { "colorResolve",           LgdImageColorResolve },
2208     { "colorResolveAlpha",      LgdImageColorResolveAlpha },
2209     { "colorsTotal",            LgdImageColorsTotal },
2210     { "red",                    LgdImageRed },
2211     { "blue",                   LgdImageBlue },
2212     { "green",                  LgdImageGreen },
2213     { "alpha",                  LgdImageAlpha },
2214     { "getTransparent",         LgdImageGetTransparent },
2215     { "colorTransparent",       LgdImageColorTransparent },
2216     { "colorDeallocate",        LgdImageColorDeallocate },
2217 
2218     { "boundsSafe",             LgdImageBoundsSafe },
2219     { "getPixel",               LgdImageGetPixel },
2220     { "sizeX",                  LgdImageSX },
2221     { "sizeY",                  LgdImageSY },
2222     { "sizeXY",                 LgdImageSXY },
2223     { "getClip",                LgdImageGetClip },
2224     { "setClip",                LgdImageSetClip },
2225 
2226     { "setPixel",               LgdImageSetPixel },
2227     { "line",                   LgdImageLine },
2228     { "rectangle",              LgdImageRectangle },
2229     { "filledRectangle",        LgdImageFilledRectangle },
2230     { "polygon",                LgdImagePolygon },
2231     { "filledPolygon",          LgdImageFilledPolygon },
2232     { "openPolygon",            LgdImageOpenPolygon },
2233     { "arc",                    LgdImageArc },
2234     { "filledArc",              LgdImageFilledArc },
2235     { "filledEllipse",          LgdImageFilledEllipse },
2236     { "fill",                   LgdImageFill },
2237     { "fillToBorder",           LgdImageFillToBorder },
2238 
2239     { "setAntiAliased",            LgdImageSetAntiAliased },
2240     { "setAntiAliasedDontBlend",   LgdImageSetAntiAliasedDontBlend },
2241     { "setBrush",                  LgdImageSetBrush },
2242     { "setTile",                   LgdImageSetTile },
2243     { "setStyle",                  LgdImageSetStyle },
2244     { "setThickness",              LgdImageSetThickness },
2245     { "alphaBlending",             LgdImageAlphaBlending },
2246     { "saveAlpha",                 LgdImageSaveAlpha },
2247     { "getInterlaced",             LgdImageGetInterlaced },
2248     { "interlace",                 LgdImageInterlace },
2249 
2250     { "string",                 LgdImageString },
2251     { "stringUp",               LgdImageStringUp },
2252     { "char",                   LgdImageChar },
2253     { "charUp",                 LgdImageCharUp },
2254 
2255     { "copy",                   LgdImageCopy },
2256     { "copyResized",            LgdImageCopyResized },
2257     { "copyResampled",          LgdImageCopyResampled },
2258     { "copyRotated",            LgdImageCopyRotated },
2259     { "copyMerge",              LgdImageCopyMerge },
2260     { "copyMergeGray",          LgdImageCopyMergeGray },
2261     { "paletteCopy",            LgdImagePaletteCopy },
2262     { "squareToCircle",         LgdImageSquareToCircle },
2263     { "sharpen",                LgdImageSharpen },
2264 
2265 #ifdef GD_FREETYPE
2266     { "stringFT",               LgdImageStringFT },
2267     { "stringFTEx",             LgdImageStringFTEx },
2268     { "stringFTCircle",         LgdImageStringFTCircle },
2269     { "fontCacheSetup",         LgdFontCacheSetup },
2270     { "fontCacheShutdown",      LgdFontCacheShutdown },
2271 #endif
2272 
2273 #ifdef GD_FONTCONFIG
2274     { "useFontConfig",          LgdFTUseFontConfig },
2275 #endif
2276 
2277 #ifdef GD_GIF  /* Gif animation */
2278     { "gifAnimBegin",           LgdImageGifAnimBegin },
2279     { "gifAnimAdd",             LgdImageGifAnimAdd },
2280     { "gifAnimEnd",             LgdImageGifAnimEnd },
2281     { "gifAnimBeginStr",        LgdImageGifAnimBeginPtr },
2282     { "gifAnimAddStr",          LgdImageGifAnimAddPtr },
2283     { "gifAnimEndStr",          LgdImageGifAnimEndPtr },
2284 #endif
2285 
2286     { NULL, NULL }
2287 };
2288 
2289 
2290 static const luaL_reg LgdMetatable[] =
2291 {
2292     { "__gc", LgdImageDestroy },
2293     { NULL, NULL }
2294 };
2295 
2296 
luaopen_gd(lua_State * L)2297 int luaopen_gd(lua_State *L) {
2298     luaL_register(L, LIB_NAME, LgdFunctions);
2299 
2300     lua_pushliteral(L, "VERSION");
2301     lua_pushstring(L, LIB_VERSION);
2302     lua_settable(L, -3);
2303 
2304     lua_pushliteral(L, "REVISION");
2305     lua_pushstring(L, rev);
2306     lua_settable(L, -3);
2307 
2308     lua_pushliteral(L, "COPYRIGHT");
2309     lua_pushstring(L, LIB_COPYRIGHT);
2310     lua_settable(L, -3);
2311 
2312     tblseticons(L, "MAX_COLORS", gdMaxColors);
2313     tblseticons(L, "GD2_FMT_RAW", GD2_FMT_RAW);
2314     tblseticons(L, "GD2_FMT_COMPRESSED", GD2_FMT_COMPRESSED);
2315     tblseticons(L, "ARC", gdArc);
2316     tblseticons(L, "CHORD", gdChord);
2317     tblseticons(L, "PIE", gdPie);
2318     tblseticons(L, "NO_FILL", gdNoFill);
2319     tblseticons(L, "EDGED", gdEdged);
2320     tblseticons(L, "ANTI_ALIASED", gdAntiAliased);
2321     tblseticons(L, "BRUSHED", gdBrushed);
2322     tblseticons(L, "STYLED", gdStyled);
2323     tblseticons(L, "STYLED_BRUSHED", gdStyledBrushed);
2324     tblseticons(L, "TILED", gdTiled);
2325     tblseticons(L, "TRANSPARENT", gdTransparent);
2326 
2327 #ifdef GD_FREETYPE
2328     /* For gd.StringFTEx */
2329     tblseticons(L, "FTEX_Unicode", gdFTEX_Unicode);
2330     tblseticons(L, "FTEX_Shift_JIS", gdFTEX_Shift_JIS);
2331     tblseticons(L, "FTEX_Big5", gdFTEX_Big5);
2332 #endif
2333 
2334 #ifdef GD_GIF
2335     /* For gif animation */
2336     tblseticons(L, "DISPOSAL_NONE", gdDisposalNone);
2337     tblseticons(L, "DISPOSAL_UNKNOWN", gdDisposalUnknown);
2338     tblseticons(L, "DISPOSAL_RESTORE_BACKGROUND", gdDisposalRestoreBackground);
2339     tblseticons(L, "DISPOSAL_RESTORE_PREVIUOUS", gdDisposalRestorePrevious);
2340 #endif
2341 
2342     /* Standard gd fonts */
2343     tblseticons(L, "FONT_TINY", MY_GD_FONT_TINY);
2344     tblseticons(L, "FONT_SMALL", MY_GD_FONT_SMALL);
2345     tblseticons(L, "FONT_MEDIUM", MY_GD_FONT_MEDIUM_BOLD);
2346     tblseticons(L, "FONT_LARGE", MY_GD_FONT_LARGE);
2347     tblseticons(L, "FONT_GIANT", MY_GD_FONT_GIANT);
2348 
2349     luaL_newmetatable(L, GD_IMAGE_PTR_TYPENAME);
2350     lua_pushliteral(L, "__index");
2351     lua_pushvalue(L, -3);
2352     lua_settable(L, -3);
2353     luaL_openlib(L, NULL, LgdMetatable, 0);
2354     lua_pop(L, 1);
2355 
2356     return 1;
2357 }
2358 
2359