├── .gitignore ├── COPYING ├── Makefile ├── README ├── README.win32 ├── debian ├── changelog ├── control ├── copyright └── rules ├── demos ├── Vera.ttf ├── brush.lua ├── bugs.jpg ├── circle.lua ├── clock.lua ├── colortransparent.lua ├── counter.lua ├── ellipse.lua ├── fontconfig.lua ├── fractal.lua ├── gd-open-any.lua ├── gifanim.lua ├── gifanim2.lua ├── gifanim3.lua ├── lua-gd.png ├── lualogo.lua ├── paper.png ├── poly.lua ├── setstyle.lua ├── stdfont.lua ├── steg.lua ├── test.lua ├── test2.lua ├── ttftext.lua ├── ttftextex.lua └── utf-8.lua ├── doc ├── cat.png ├── catdiff.png ├── catmsg.png ├── clock-example.png ├── fontconfig-example.png ├── gifanim.gif ├── index.html ├── lua-gd.png ├── sierpinski.png └── stdfonts.png ├── lua-gd.ps ├── lua-gd.spec ├── luagd-2.0.33r3-1.rockspec ├── luagd.c └── test_features.lua /.gitignore: -------------------------------------------------------------------------------- 1 | *.so 2 | *.lo 3 | *.tar.gz 4 | 5 | demos/out.png 6 | demos/out.gif 7 | demos/counter.txt 8 | 9 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Lua-GD (c) 2004-2006 Alexandre Erwin Ittner 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | If you use this package in a product, an acknowledgment in the product 23 | documentation would be greatly appreciated (but it is not required). 24 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # luagd -- gd bindings for the Lua Programming Language. 2 | # (c) 2004-11 Alexandre Erwin Ittner 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining 5 | # a copy of this software and associated documentation files (the 6 | # "Software"), to deal in the Software without restriction, including 7 | # without limitation the rights to use, copy, modify, merge, publish, 8 | # distribute, sublicense, and/or sell copies of the Software, and to 9 | # permit persons to whom the Software is furnished to do so, subject to 10 | # the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be 13 | # included in all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | # IN NO EVENT SHALL THE AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY 19 | # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | # 23 | # If you use this package in a product, an acknowledgment in the product 24 | # documentation would be greatly appreciated (but it is not required). 25 | # 26 | 27 | 28 | # Lua-GD version. This one must be set. 29 | VERSION=2.0.33r3 30 | 31 | # Command used to run Lua code 32 | LUABIN=lua5.1 33 | 34 | # Optimization for the brave of heart ;) 35 | OMITFP=-fomit-frame-pointer 36 | 37 | 38 | # --------------------------------------------------------------------------- 39 | # Automatic configuration using pkgconfig. These lines should work on most 40 | # Linux/Unix systems. If your system does not have these programs you must 41 | # comment out these lines and uncomment and change the next ones. 42 | 43 | # Name of .pc file. "lua5.1" on Debian/Ubuntu 44 | LUAPKG=lua5.1 45 | OUTFILE=gd.so 46 | 47 | CFLAGS=-O3 -Wall -fPIC $(OMITFP) 48 | CFLAGS+=`pkg-config $(LUAPKG) --cflags` 49 | CFLAGS+=-DVERSION=\"$(VERSION)\" 50 | 51 | GDFEATURES=-DGD_XPM -DGD_JPEG -DGD_FONTCONFIG -DGD_FREETYPE -DGD_PNG -DGD_GIF 52 | LFLAGS=-shared `pkg-config $(LUAPKG) --libs` -lgd 53 | 54 | INSTALL_PATH := `pkg-config $(LUAPKG) --variable=INSTALL_CMOD` 55 | 56 | 57 | # --------------------------------------------------------------------------- 58 | # Manual configuration for systems without pkgconfig. 59 | # WARNING: These instructions will only work on older versions of GD, since 60 | # gdlib-config has been removed in favor of pkg-config. 61 | 62 | # Path to the utility 'gdlib-config'. This may be changed to compile the 63 | # module with development versions of libgd. 64 | #GDLIBCONFIG=gdlib-config 65 | 66 | #OUTFILE=gd.so 67 | #CFLAGS=-O3 -Wall -fPIC $(OMITFP) 68 | #CFLAGS+=`$(GDLIBCONFIG) --cflags` -I/usr/include/lua5.1 69 | #CFLAGS+=-DVERSION=\"$(VERSION)\" 70 | #GDFEATURES=`$(GDLIBCONFIG) --features |sed -e "s/GD_/-DGD_/g"` 71 | #LFLAGS=-shared `$(GDLIBCONFIG) --ldflags` `$(GDLIBCONFIG) --libs` -lgd 72 | #INSTALL_PATH=/usr/lib/lua/ 73 | 74 | 75 | # --------------------------------------------------------------------------- 76 | # Manual configuration for Windows and systems without sed, pkgconfig, etc. 77 | # Uncomment, change and good luck :) 78 | 79 | #OUTFILE=gd.dll 80 | #CFLAGS=-O3 -Wall -fPIC $(OMITFP) 81 | #CFLAGS+=-IC:/lua5.1/ 82 | #CFLAGS+=-DVERSION=\"$(VERSION)\" 83 | #GDFEATURES=-DGD_XPM -DGD_JPEG -DGD_FONTCONFIG -DGD_FREETYPE -DGD_PNG -DGD_GIF 84 | #LFLAGS=-shared -lgd2 -lm $(OMITFP) 85 | #INSTALL_PATH="C:/Program Files/lua/" 86 | # --------------------------------------------------------------------------- 87 | 88 | 89 | all: test 90 | 91 | $(OUTFILE): gd.lo 92 | $(CC) -o $(OUTFILE) gd.lo $(LFLAGS) 93 | 94 | test: $(OUTFILE) 95 | $(LUABIN) test_features.lua 96 | 97 | gd.lo: luagd.c 98 | $(CC) -o gd.lo -c $(GDFEATURES) $(CFLAGS) luagd.c 99 | 100 | install: $(OUTFILE) 101 | install -D -s $(OUTFILE) $(DESTDIR)/$(INSTALL_PATH)/$(OUTFILE) 102 | 103 | 104 | # Rules for making a distribution tarball 105 | 106 | TDIR=lua-gd-$(VERSION) 107 | DFILES=COPYING README luagd.c lua-gd.spec Makefile test_features.lua 108 | dist: $(DISTFILES) 109 | rm -f $(TDIR).tar.gz 110 | mkdir $(TDIR) 111 | mkdir -p $(TDIR)/doc $(TDIR)/demos $(TDIR)/debian 112 | cp $(DFILES) $(TDIR) 113 | cp demos/* $(TDIR)/demos/ 114 | cp doc/* $(TDIR)/doc/ 115 | cp debian/* $(TDIR)/debian/ 116 | tar czf $(TDIR).tar.gz $(TDIR) 117 | rm -rf $(TDIR) 118 | 119 | clean: 120 | rm -f $(OUTFILE) gd.lo 121 | rm -rf $(TDIR) $(TDIR).tar.gz 122 | rm -f demos/out.png demos/out.gif demos/counter.txt 123 | 124 | .PHONY: all test install clean dist 125 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Lua-GD, the gd bindings for the Lua Programming Language 2 | (c) 2004-13 Alexandre Erwin Ittner 3 | 4 | 5 | + Introduction 6 | 7 | "gd" is a C graphics library created by Thomas Boutell that allows your 8 | code to quickly draw complete images with lines, polygons, arcs, text, 9 | multiple colors, cut and paste from other images, flood fills, read in 10 | or write out images in the PNG, JPEG or GIF format. This is particularly 11 | useful in World Wide Web applications, where PNG and JPEG are two of the 12 | formats accepted for inline images by most browsers. gd does not provide 13 | for every possible desirable graphics operation. It is not necessary or 14 | desirable for gd to become a kitchen-sink graphics package, but it does 15 | include most frequently requested features, including both truecolor 16 | and palette images, resampling (smooth resizing of truecolor images) 17 | and so forth. You can get more information about gd from it's homepage. 18 | 19 | Lua-GD is a "binding": a library that exports gd functions to the Lua 20 | Programming Language, allowing you to use gd from Lua. The API was 21 | NOT literally exported, but changed in a way that make it familiar to 22 | Lua users. 23 | 24 | Lua-GD is a programming library, not a paint program. If you are looking 25 | for that or are not familiar to the Lua Programming Language, you are 26 | in the wrong place. 27 | 28 | 29 | + Documentation 30 | 31 | See doc/index.html for installation instructions and API documentation. 32 | 33 | 34 | + License 35 | 36 | Lua-GD is copyrighted free software, distributed under the MIT license 37 | (the same used by Lua 5.1) and it can be used at no cost for both academic 38 | and commercial purpouses. Or, more precisely: 39 | 40 | Permission is hereby granted, free of charge, to any person obtaining 41 | a copy of this software and associated documentation files (the 42 | "Software"), to deal in the Software without restriction, including 43 | without limitation the rights to use, copy, modify, merge, publish, 44 | distribute, sublicense, and/or sell copies of the Software, and to 45 | permit persons to whom the Software is furnished to do so, subject to 46 | the following conditions: 47 | 48 | The above copyright notice and this permission notice shall be 49 | included in all copies or substantial portions of the Software. 50 | 51 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 52 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 53 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 54 | IN NO EVENT SHALL THE AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY 55 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 56 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 57 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 58 | 59 | If you use this package in a product, an acknowledgment in the product 60 | documentation would be greatly appreciated (but it is not required). 61 | -------------------------------------------------------------------------------- /README.win32: -------------------------------------------------------------------------------- 1 | Lua-GD, the gd bindings for the Lua Programming Language 2 | (c) 2004-11 Alexandre Erwin Ittner 3 | 4 | These are the Windows binaries for Lua-GD for Lua 5.1, compiled with 5 | mingw32 3.4.4. These binaries also work with LuaJit 1.1.0. GD and its 6 | dependencies were included in the distribution package for convenience. 7 | 8 | Please refer to 'README' For non-win32 specific information. 9 | 10 | 11 | + Licensing 12 | 13 | Each library has its own license. Please carefully read the following files: 14 | 15 | gd-license.txt 16 | libfreetype-license.txt 17 | libjpeg-license.txt 18 | libpng-license.txt 19 | zlib-license.txt 20 | 21 | 22 | + Instalation 23 | 24 | There is no automatic installation procedure for Windows. You must copy the 25 | following DLLs to somewhere in your system path: 26 | 27 | freetype6.dll 28 | jpeg62.dll 29 | libgd2.dll 30 | libiconv2.dll 31 | libpng13.dll 32 | xpm4.dll 33 | zlib1.dll 34 | 35 | and, finally, copy the file "gd.dll" to your Lua binary package directory. 36 | 37 | 38 | + URLs 39 | 40 | Lua-GD: http://lua-gd.luaforge.net/ 41 | Lua binaries: http://luabinaries.luaforge.net/ 42 | GD binaries: http://gnuwin32.sourceforge.net/packages/gd.htm 43 | 44 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | lua-gd (2.0.33r3-1) unstable; urgency=low 2 | 3 | * Update version. 4 | 5 | -- Alexandre Erwin Ittner Tue, 03 Oct 2013 01:00:00 -0300 6 | 7 | lua-gd (2.0.33r2-2) unstable; urgency=low 8 | 9 | * Updated to Debian compatibility level 4. 10 | 11 | -- Alexandre Erwin Ittner Sun, 11 Feb 2007 15:20:09 -0200 12 | 13 | 14 | lua-gd (2.0.33r2-1) unstable; urgency=low 15 | 16 | * Initial release Closes: #nnnn (nnnn is the bug number of your ITP) 17 | 18 | -- Alexandre Erwin Ittner Wed, 3 May 2006 00:46:09 -0300 19 | 20 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: lua-gd 2 | Priority: optional 3 | Maintainer: Alexandre Erwin Ittner 4 | Build-Depends: debhelper (>= 4.0.0), liblua5.1-dev 5 | Standards-Version: 3.6.1 6 | Section: interpreters 7 | 8 | Package: lua-gd 9 | Architecture: any 10 | Depends: ${shlibs:Depends} 11 | Recommends: lua5.1 12 | Description: GD bindings for the Lua Programming Language 13 | Lua-GD is a library that allows you to use the gd graphic library from 14 | programs written in the Lua programming language. 15 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Lua-GD (c) 2004-2006 Alexandre Erwin Ittner 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | If you use this package in a product, an acknowledgment in the product 23 | documentation would be greatly appreciated (but it is not required). 24 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | 4 | ## This is my first Debian package. Please, be patient ;) 5 | 6 | 7 | # Uncomment this to turn on verbose mode. 8 | #export DH_VERBOSE=1 9 | 10 | # This is the debhelper compatability version to use. 11 | export DH_COMPAT=4 12 | 13 | LUAPKG=lua5.1 14 | INSTALL_PATH=`pkg-config $(LUAPKG) --variable=INSTALL_CMOD` 15 | 16 | CFLAGS = -Wall -g 17 | 18 | build: build-stamp 19 | build-stamp: 20 | dh_testdir 21 | 22 | # Well, this does it all. 23 | $(MAKE) 24 | 25 | touch build-stamp 26 | 27 | clean: 28 | dh_testdir 29 | dh_testroot 30 | rm -f gd.so 31 | rm -f build-stamp configure-stamp 32 | 33 | # Toplevel clean does it all 34 | -$(MAKE) clean 35 | 36 | dh_clean 37 | 38 | install: build 39 | dh_testdir 40 | dh_testroot 41 | dh_clean -k 42 | dh_installdirs 43 | 44 | mkdir -p debian/lua-gd/usr/share/doc/lua-gd 45 | mkdir -p debian/lua-gd/usr/share/doc/lua-gd/demos/ 46 | mkdir -p debian/lua-gd/$(INSTALL_PATH) 47 | 48 | cp gd.so debian/lua-gd/$(INSTALL_PATH) 49 | cp README COPYING doc/* debian/lua-gd/usr/share/doc/lua-gd/ 50 | cp demos/* debian/lua-gd/usr/share/doc/lua-gd/demos/ 51 | 52 | # Build architecture-dependent files here. 53 | binary-arch: build install 54 | dh_testdir -a 55 | dh_testroot -a 56 | # dh_installdebconf -a 57 | dh_installdocs -a 58 | # dh_installexamples -a 59 | # dh_installmenu -a 60 | # dh_installlogrotate -a 61 | # dh_installemacsen -a 62 | # dh_installpam -a 63 | # dh_installmime -a 64 | # dh_installinit -a 65 | # dh_installcron -a 66 | # dh_installman -a 67 | # dh_installinfo -a 68 | # dh_undocumented -a 69 | dh_installchangelogs -a 70 | dh_strip -a 71 | dh_link -a 72 | dh_compress -a 73 | dh_fixperms -a 74 | dh_makeshlibs -a -V 75 | dh_installdeb -a 76 | # dh_perl -a 77 | dh_shlibdeps -a 78 | dh_gencontrol -a 79 | dh_md5sums -a 80 | dh_builddeb -a 81 | 82 | binary: binary-arch 83 | .PHONY: build clean binary-indep binary-arch binary install configure 84 | -------------------------------------------------------------------------------- /demos/Vera.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ittner/lua-gd/2ce8e478a8591afd71e607506bc8c64b161bbd30/demos/Vera.ttf -------------------------------------------------------------------------------- /demos/brush.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local gd = require("gd") 4 | 5 | local im = gd.createTrueColor(400, 400) 6 | assert(im) 7 | 8 | local black = im:colorAllocate(0, 0, 0) 9 | local white = im:colorAllocate(255, 255, 255) 10 | 11 | local brush = gd.createFromPng("paper.png") 12 | im:setBrush(brush) 13 | im:line(60, 60, 70, 70, gd.BRUSHED) 14 | im:line(120, 120, 130, 130, gd.BRUSHED) 15 | im:line(180, 180, 190, 190, gd.BRUSHED) 16 | im:line(240, 240, 250, 250, gd.BRUSHED) 17 | im:line(300, 300, 310, 310, gd.BRUSHED) 18 | 19 | im:png("out.png") 20 | os.execute("xdg-open out.png") 21 | -------------------------------------------------------------------------------- /demos/bugs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ittner/lua-gd/2ce8e478a8591afd71e607506bc8c64b161bbd30/demos/bugs.jpg -------------------------------------------------------------------------------- /demos/circle.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local gd = require("gd") 4 | 5 | local im = gd.createTrueColor(100, 100) 6 | 7 | local white = im:colorAllocate(255, 255, 255) 8 | local blue = im:colorAllocate(0, 0, 255) 9 | 10 | im:filledRectangle(0, 0, 100, 100, white) 11 | im:stringFTCircle(50, 50, 40, 10, 0.9, "./Vera.ttf", 24, "Powered", "by Lua", blue) 12 | 13 | im:png("out.png") 14 | os.execute("xdg-open out.png") 15 | -------------------------------------------------------------------------------- /demos/clock.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | -- a cgi script that draws an analog clock with lua and lua-gd 4 | -- (c) 2004 Alexandre Erwin Ittner 5 | 6 | local gd = require("gd") 7 | 8 | local function createClock(size, hours, minutes) 9 | local im = gd.createTrueColor(size, size) 10 | local white = im:colorAllocate(255, 255, 255) 11 | local gray = im:colorAllocate(128, 128, 128) 12 | local black = im:colorAllocate(0, 0, 0) 13 | local blue = im:colorAllocate(0, 0, 128) 14 | local cxy = size/2 15 | 16 | im:filledRectangle(0, 0, size, size, white) 17 | im:setThickness(math.max(1, size/100)) 18 | im:arc(cxy, cxy, size, size, 0, 360, black) 19 | 20 | local ang = 0 21 | local rang, gsize 22 | while ang < 360 do 23 | rang = math.rad(ang) 24 | if (ang % 90) == 0 then 25 | gsize = 0.75 26 | else 27 | gsize = 0.85 28 | end 29 | im:line( 30 | cxy + gsize * cxy * math.sin(rang), 31 | size - (cxy + gsize * cxy * math.cos(rang)), 32 | cxy + cxy * 0.9 * math.sin(rang), 33 | size - (cxy + cxy * 0.9 * math.cos(rang)), 34 | gray) 35 | ang = ang + 30 36 | end 37 | 38 | im:setThickness(math.max(1, size/50)) 39 | im:line(cxy, cxy, 40 | cxy + 0.45 * size * math.sin(math.rad(6*minutes)), 41 | size - (cxy + 0.45 * size * math.cos(math.rad(6*minutes))), 42 | blue) 43 | 44 | im:setThickness(math.max(1, size/25)) 45 | rang = math.rad(30*hours + minutes/2) 46 | im:line(cxy, cxy, 47 | cxy + 0.25 * size * math.sin(rang), 48 | size - (cxy + 0.25 * size * math.cos(rang)), 49 | blue) 50 | 51 | im:setThickness(1) 52 | local sp = math.max(1, size/20) 53 | im:filledArc(cxy, cxy, sp, sp, 0, 360, black, gd.ARC) 54 | 55 | return im 56 | end 57 | 58 | local dh = os.date("*t") 59 | local im = createClock(100, dh.hour, dh.min) 60 | 61 | print("Content-type: image/png") 62 | print("Refresh: 60") -- Ask browser to reload the image after 60s 63 | print("Pragma: no-cache") -- Can mozilla understand this? 64 | print("Expires: Thu Jan 01 00:00:00 UTC 1970") -- Marks as expired 65 | print("") 66 | 67 | io.write(im:pngStr()) 68 | 69 | -------------------------------------------------------------------------------- /demos/colortransparent.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local gd = require("gd") 4 | 5 | local im = gd.createPalette(90, 90) 6 | 7 | local white = im:colorAllocate(255, 255, 255) 8 | local blue = im:colorAllocate(0, 0, 255) 9 | local red = im:colorAllocate(255, 0, 0) 10 | 11 | im:colorTransparent(white) 12 | im:filledRectangle(10, 10, 50, 50, blue) 13 | im:filledRectangle(40, 40, 80, 80, red) 14 | 15 | im:gif("out.gif") 16 | os.execute("xdg-open out.gif") 17 | -------------------------------------------------------------------------------- /demos/counter.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | -- counter.lua -- a web counter in Lua! 3 | -- (c) 2004 Alexandre Erwin Ittner 4 | 5 | local gd = require("gd") 6 | 7 | local datafile = "counter.txt" 8 | local fp = io.open(datafile, "r+") 9 | local cnt = 0 10 | if fp then 11 | cnt = tonumber(fp:read("*l")) or 0 12 | fp:seek("set", 0) 13 | else 14 | fp = io.open(datafile, "w") 15 | assert(fp) 16 | end 17 | cnt = cnt + 1 18 | fp:write(cnt .."\n") 19 | fp:close() 20 | 21 | local sx = math.max(string.len(tostring(cnt)), 1) * 8 22 | local im = gd.create(sx, 15) 23 | -- first allocated color defines the background. 24 | local white = im:colorAllocate(255, 255, 255) 25 | im:colorTransparent(white) 26 | local black = im:colorAllocate(0, 0, 0) 27 | im:string(gd.FONT_MEDIUM, 1, 1, cnt, black) 28 | 29 | print("Content-type: image/png\n") 30 | io.write(im:pngStr()) 31 | -------------------------------------------------------------------------------- /demos/ellipse.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local gd = require("gd") 4 | local im = gd.createTrueColor(80, 80) 5 | assert(im) 6 | 7 | local black = im:colorAllocate(0, 0, 0) 8 | local white = im:colorAllocate(255, 255, 255) 9 | im:filledEllipse(40, 40, 70, 50, white) 10 | 11 | im:png("out.png") 12 | os.execute("xdg-open out.png") 13 | -------------------------------------------------------------------------------- /demos/fontconfig.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | -- The fonts used in this example comes with Microsoft operating systems 4 | -- and can be downloaded from http://corefonts.sourceforge.net 5 | 6 | local gd = require("gd") 7 | 8 | local im = gd.createTrueColor(220, 190) 9 | local white = im:colorAllocate(255, 255, 255) 10 | local black = im:colorAllocate(0, 0, 0) 11 | local x, y = im:sizeXY() 12 | im:filledRectangle(0, 0, x, y, white) 13 | 14 | gd.useFontConfig(true) 15 | im:stringFT(black, "Arial", 20, 0, 10, 30, "Standard Arial") 16 | im:stringFT(black, "Arial:bold", 20, 0, 10, 60, "Bold Arial") 17 | im:stringFT(black, "Arial:italic", 20, 0, 10, 90, "Italic Arial") 18 | im:stringFT(black, "Arial:bold:italic", 20, 0, 10, 120, "Italic Bold Arial") 19 | im:stringFT(black, "Times New Roman", 20, 0, 10, 150, "Times New Roman") 20 | im:stringFT(black, "Comic Sans MS", 20, 0, 10, 180, "Comic Sans MS") 21 | 22 | im:png("out.png") 23 | os.execute("xdg-open out.png") 24 | -------------------------------------------------------------------------------- /demos/fractal.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | -- Draws the famous Sierpinski triangle with lua-gd 4 | 5 | local gd = require("gd") 6 | 7 | local size = 500 8 | 9 | local im = gd.createPalette(size, size) 10 | local white = im:colorAllocate(255, 255, 255) 11 | local black = im:colorAllocate(0, 0, 0) 12 | 13 | local m = {} 14 | m[math.floor(size/2)] = true 15 | 16 | local n 17 | for i = 1, size do 18 | n = {} 19 | for j = 1, size do 20 | if m[j] then 21 | im:setPixel(j, i, black) 22 | n[j+1] = not n[j+1] 23 | n[j-1] = not n[j-1] 24 | end 25 | end 26 | m = n 27 | end 28 | 29 | im:png("out.png") 30 | os.execute("xdg-open out.png") 31 | 32 | -------------------------------------------------------------------------------- /demos/gd-open-any.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- Open images automatically according to the file magic number. 3 | -- Part of Lua-GD 4 | -- 5 | 6 | 7 | local gd = require("gd") 8 | local io = require("io") 9 | 10 | local magics = { 11 | { "\137PNG", gd.createFromPng }, 12 | { "GIF87a", gd.createFromGif }, 13 | { "GIF89a", gd.createFromGif }, 14 | { "\255\216\255\224\0\16\74\70\73\70\0", gd.createFromJpeg }, 15 | { "\255\216\255\225\19\133\69\120\105\102\0", gd.createFromJpeg }, -- JPEG Exif 16 | } 17 | 18 | -- 19 | -- Open some common image types according to the file headers 20 | -- 21 | -- Arguments: 22 | -- fname: a string with the file name 23 | -- 24 | -- Return values: 25 | -- on success, returns a GD image handler. 26 | -- on error, returns nil followed by a string with the error description. 27 | -- 28 | 29 | local function openany(fname) 30 | local fp = io.open(fname, "rb") 31 | if not fp then 32 | return nil, "Error opening file" 33 | end 34 | 35 | local header = fp:read(16) 36 | if not header then 37 | return nil, "Error reading file" 38 | end 39 | fp:close() 40 | 41 | for _, v in ipairs(magics) do 42 | if header:sub(1, #v[1]) == v[1] then 43 | return v[2](fname) 44 | end 45 | end 46 | 47 | return nil, "Image type not recognized" 48 | end 49 | 50 | 51 | return { openany = openany } 52 | 53 | -------------------------------------------------------------------------------- /demos/gifanim.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local gd = require("gd") 4 | 5 | local im = gd.createPalette(80, 80) 6 | assert(im) 7 | 8 | local black = im:colorAllocate(0, 0, 0) 9 | local white = im:colorAllocate(255, 255, 255) 10 | im:gifAnimBegin("out.gif", true, 0) 11 | 12 | for i = 1, 10 do 13 | tim = gd.createPalette(80, 80) 14 | tim:paletteCopy(im) 15 | tim:arc(40, 40, 40, 40, 36*(i-1), 36*i, white) 16 | tim:gifAnimAdd("out.gif", false, 0, 0, 5, gd.DISPOSAL_NONE) 17 | end 18 | 19 | gd.gifAnimEnd("out.gif") 20 | os.execute("xdg-open out.gif") 21 | 22 | -------------------------------------------------------------------------------- /demos/gifanim2.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local gd = require("gd") 4 | 5 | local im = gd.createPalette(120, 120) 6 | assert(im) 7 | 8 | local black = im:colorAllocate(0, 0, 0) 9 | local blue = {} 10 | for i = 1, 20 do 11 | blue[i] = im:colorAllocate(0, 0, 120+6*i) 12 | end 13 | 14 | im:gifAnimBegin("out.gif", true, 0) 15 | for i = 1, 20 do 16 | tim = gd.createPalette(120, 120) 17 | tim:paletteCopy(im) 18 | tim:arc(60, 60, 6*i, 6*i, 0, 360, blue[21-i]) 19 | tim:gifAnimAdd("out.gif", false, 0, 0, 5, gd.DISPOSAL_NONE) 20 | end 21 | 22 | gd.gifAnimEnd("out.gif") 23 | os.execute("xdg-open out.gif") 24 | 25 | -------------------------------------------------------------------------------- /demos/gifanim3.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local gd = require("gd") 4 | 5 | local im = gd.createPalette(120, 120) 6 | assert(im) 7 | 8 | local black = im:colorAllocate(0, 0, 0) 9 | local blue = {} 10 | for i = 1, 20 do 11 | blue[i] = im:colorAllocate(0, 0, 120+6*i) 12 | end 13 | 14 | local fp = io.open("out.gif", "w") 15 | assert(fp, "Failed to open file for writting") 16 | 17 | fp:write(im:gifAnimBeginStr(true, 0)) 18 | 19 | for i = 1, 20 do 20 | tim = gd.createPalette(120, 120) 21 | tim:paletteCopy(im) 22 | tim:arc(60, 60, 6*i, 6*i, 0, 360, blue[21-i]) 23 | fp:write(tim:gifAnimAddStr(false, 0, 0, 5, gd.DISPOSAL_NONE)) 24 | end 25 | 26 | fp:write(gd.gifAnimEndStr()) 27 | fp:close() 28 | 29 | os.execute("xdg-open out.gif") 30 | -------------------------------------------------------------------------------- /demos/lua-gd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ittner/lua-gd/2ce8e478a8591afd71e607506bc8c64b161bbd30/demos/lua-gd.png -------------------------------------------------------------------------------- /demos/lualogo.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | -- 4 | -- lualogo.lua (c) 2006-11 Alexandre Erwin Ittner 5 | -- 6 | -- Drawns the Lua Logo. This script requires fontconfig and the "Helvetica" 7 | -- font installed in your system. 8 | -- 9 | -- 10 | 11 | 12 | local gd = require("gd") 13 | 14 | gd.useFontConfig(true) 15 | 16 | function makelogo(size) 17 | local nsize = 3 * size 18 | local im = gd.createTrueColor(nsize, nsize) 19 | local white = im:colorAllocate(255, 255, 255) 20 | local blue = im:colorAllocate(0, 0, 128) 21 | local gray = im:colorAllocate(170, 170, 170) 22 | 23 | local ediam = nsize * 0.68 -- Earth diameter 24 | local mdiam = ediam * (1 - math.sqrt(2) / 2) -- Moon diameter 25 | local odiam = ediam * 1.3 -- Orbit diameter 26 | local emdist = odiam/2 * 1.05 -- Earth - Moon distance 27 | local esdist = odiam/2 * 0.4 -- Earth - Moon shadow distance 28 | local mang = 45 -- Moon angle (degrees) 29 | local mangr = math.rad(mang) 30 | local cxy = nsize/2.0 31 | 32 | im:fill(0, 0, white) 33 | im:filledArc(cxy, cxy, ediam, ediam, 0, 360, blue, gd.ARC) 34 | 35 | im:setThickness(math.max(0.02 * ediam, 1)) 36 | for i = 0, 360, 10 do 37 | im:arc(cxy, cxy, odiam, odiam, i, i+5, gray) 38 | end 39 | im:setThickness(1) 40 | 41 | -- Moon 42 | local mcx = cxy + math.sin(math.rad(mang)) * emdist 43 | local mcy = cxy - math.cos(math.rad(mang)) * emdist 44 | im:filledArc(mcx, mcy, mdiam, mdiam, 0, 360, blue, gd.ARC) 45 | 46 | -- Moon shadow 47 | local mscx = cxy + math.sin(math.rad(mang)) * esdist 48 | local mscy = cxy - math.cos(math.rad(mang)) * esdist 49 | im:filledArc(mscx, mscy, mdiam, mdiam, 0, 360, white, gd.ARC) 50 | 51 | im:stringFT(white, "Helvetica", 0.23*nsize, 0, 0.25*nsize, 0.7*nsize, "Lua") 52 | 53 | -- Implementation of the "Desperate anti-aliasing algorithm" ;) 54 | local im2 = gd.createTrueColor(size, size) 55 | im2:copyResampled(im, 0, 0, 0, 0, size, size, nsize, nsize) 56 | return im2 57 | end 58 | 59 | makelogo(140):png("out.png") 60 | os.execute("xdg-open out.png") 61 | -------------------------------------------------------------------------------- /demos/paper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ittner/lua-gd/2ce8e478a8591afd71e607506bc8c64b161bbd30/demos/paper.png -------------------------------------------------------------------------------- /demos/poly.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local gd = require("gd") 4 | 5 | local im = gd.createTrueColor(80, 80) 6 | assert(im) 7 | 8 | local black = im:colorAllocate(0, 0, 0) 9 | local white = im:colorAllocate(255, 255, 255) 10 | 11 | im:polygon( { { 10, 10 }, { 10, 20 }, { 20, 20 }, { 20, 10 } }, white) 12 | im:filledPolygon( { { 30, 30 }, { 30, 40 }, { 40, 40 }, { 40, 30 } }, white) 13 | im:openPolygon( { { 50, 50 }, { 50, 60 }, { 60, 60 }, { 60, 50 } }, white) 14 | 15 | im:png("out.png") 16 | print(os.execute("xdg-open out.png")) 17 | -------------------------------------------------------------------------------- /demos/setstyle.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local gd = require("gd") 4 | 5 | local im = gd.createPalette(150, 100) 6 | assert(im, "Failed to create new image.") 7 | 8 | local white = im:colorAllocate(255, 255, 255) 9 | local red = im:colorAllocate(200, 0, 0) 10 | local green = im:colorAllocate(0, 128, 0) 11 | local blue = im:colorAllocate(0, 0, 128) 12 | 13 | local style = {} 14 | 15 | for i = 0, 10 do 16 | style[#style+1] = red 17 | end 18 | 19 | for i = 0, 5 do 20 | style[#style+1] = blue 21 | end 22 | 23 | for i = 0, 2 do 24 | style[#style+1] = green 25 | end 26 | 27 | im:setStyle(style) 28 | 29 | for i = 0, 100, 2 do 30 | im:line(i, i, i+50, i, gd.STYLED) 31 | end 32 | 33 | im:png("out.png") 34 | os.execute("xdg-open out.png") 35 | 36 | 37 | -------------------------------------------------------------------------------- /demos/stdfont.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local gd = require("gd") 4 | 5 | local x, y = 140, 110 6 | 7 | local im = gd.createPalette(x, y) 8 | local white = im:colorAllocate(255, 255, 255) 9 | local black = im:colorAllocate(0, 0, 0) 10 | 11 | im:string(gd.FONT_TINY, 10, 10, "gd.FONT_TINY", black) 12 | im:string(gd.FONT_SMALL, 10, 20, "gd.FONT_SMALL", black) 13 | im:string(gd.FONT_MEDIUM, 10, 35, "gd.FONT_MEDIUM", black) 14 | im:string(gd.FONT_LARGE, 10, 48, "gd.FONT_LARGE", black) 15 | im:string(gd.FONT_GIANT, 10, 65, "gd.FONT_GIANT", black) 16 | 17 | im:line(60, 93, 70, 93, black) 18 | im:string(gd.FONT_SMALL, 80, 86, "= 10 px", black) 19 | 20 | im:png("out.png") 21 | os.execute("xdg-open out.png") 22 | 23 | -------------------------------------------------------------------------------- /demos/steg.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | --[[ 3 | 4 | Steganography with Lua-GD 5 | 6 | Steganography is the technique of writing hidden messages in such a way 7 | that no one apart from the intended recipient knows of the existence of 8 | the message; this is in contrast to cryptography, where the existence 9 | of the message is clear, but the meaning is obscured. Generally a 10 | steganographic message will appear to be something else, like a shopping 11 | list, an article, a picture, or some other "cover" message. In the 12 | digital age, steganography works by replacing bits of useless or unused 13 | data in regular computer files (such as graphics, sound, text, HTML, or 14 | even floppy disks) with bits of different, invisible information. This 15 | hidden information can be plain text, cipher text or even images. 16 | 17 | 18 | A Simple Example 19 | 20 | If Alice wants to send a secret message to Bob through an insecure 21 | channel, she can use some encryption software (like GnuPG) to encrypt 22 | the message with Bob's public key. It's a good solution because no 23 | one unless Bob will be able to read the message. She can also sign the 24 | message so Bob will know that the message really comes from her. BUT, 25 | a potential attacker will know that a ciphered message was sent. If the 26 | attacker has control over the communication channel, he might block the 27 | message in some way that Bob will never receive it. If Alice also HIDES 28 | the ciphertext in an unsuspected piece of information (like a photo of her 29 | cat) the attacker will not detect it and the message will arrive to Bob. 30 | 31 | This program will help Alice to hide some arbitrary text in a PNG image by 32 | replacing the least significant bits of each color channel of some pixels 33 | with bits from the encrypted message. PNG or other loseless compression 34 | algorithm are mandatory here, since compressing the image with a lossy 35 | algorithm will destroy the stored information. The maximum length of the 36 | message is limited by the image's size (each byte needs 8 color channels or 37 | 2 pixels and 2 channels from the next pixel). So, the image must have at 38 | least "ceil((length+1)*8/3)" pixels (the extra byte is the NUL marker for 39 | the end of the string). So, if Alice's message is "Meet me in the secret 40 | place at nine o'clock.", she will encrypt and sign it to something like 41 | "PyJYDpz5LCOSHPiXDvLHmVzxLV8qS7EFvZnoo1Mxk+BlT+7lMjpQKs" (imagine Alice's 42 | cat walking in you keyboard :). This is the ciphertext that will be sent 43 | to Bob through the image. 44 | 45 | The following table shows what happens to the first eight pixels from 46 | the image when mixed to the first three bytes from the encrypted message: 47 | 48 | 49 | +-----+---+----------+-----------------+----------+ 50 | | Pix | C | Orig img | Message | New img | 51 | | # | | bits | Chr | Dec | Bin | bits | 52 | +-----+---+----------+-----+-----+-----+----------+ 53 | | | R | 01010010 | | | 0 | 01010010 | 54 | | 1 | G | 00101010 | | | 1 | 00101011 | 55 | |_____| B | 00010101 | | | 0 | 00010100 | 56 | | | R | 11100100 | P | 080 | 1 | 11100101 | 57 | | 2 | G | 00100100 | | | 0 | 00100100 | 58 | |_____| B | 01001111 | | | 0 | 01001110 | 59 | | | R | 01010010 | | | 0 | 01010010 | 60 | | 3 | G | 00101110 |_____|_____|__0__| 00101110 | 61 | |_____| B | 00111001 | | | 0 | 00111000 | 62 | | | R | 10010110 | | | 1 | 10010111 | 63 | | 4 | G | 01011101 | | | 1 | 01011101 | 64 | |_____| B | 00100101 | y | 121 | 1 | 00100101 | 65 | | | R | 01001001 | | | 1 | 01001001 | 66 | | 5 | G | 10110110 | | | 0 | 10110110 | 67 | |_____| B | 00010101 | | | 0 | 00010100 | 68 | | | R | 00110100 |_____|_____|__1__| 00110101 | 69 | | 6 | G | 01000111 | | | 0 | 01000110 | 70 | |_____| B | 01001000 | | | 1 | 01001001 | 71 | | | R | 01010110 | | | 0 | 01010110 | 72 | | 7 | G | 00011001 | | | 0 | 00011000 | 73 | |_____| B | 10010100 | J | 074 | 1 | 10010101 | 74 | | | R | 00010101 | | | 0 | 00010100 | 75 | | 8 | G | 01011010 | | | 1 | 01011011 | 76 | | | B | 01010001 | | | 0 | 01010000 | 77 | +-----+---+----------+-----+-----+-----+----------+ 78 | 79 | 80 | When Bob wants to read the message he will extract the least significant 81 | bit (LSB) from each color channel from some pixels of the image and 82 | join them to get the original ciphertext. A NULL character (ASCII #0) 83 | will mark the end of the message within the image, so he will know when 84 | to stop. Of course, this program will also do this boring job for Bob. 85 | 86 | 87 | ]] 88 | 89 | 90 | local gd = require("gd") 91 | 92 | 93 | local function getLSB(n) 94 | return (n % 2) ~= 0 95 | end 96 | 97 | 98 | -- Bizarre way to do some bit-level operations without bitlib. 99 | local function setLSB(n, b) 100 | if type(b) == "number" then 101 | if b == 0 then 102 | b = false 103 | else 104 | b = true 105 | end 106 | end 107 | if getLSB(n) then 108 | if b then 109 | return n 110 | elseif n > 0 then 111 | return n - 1 112 | else 113 | return n + 1 114 | end 115 | else 116 | if not b then 117 | return n 118 | elseif n > 0 then 119 | return n - 1 120 | else 121 | return n + 1 122 | end 123 | end 124 | end 125 | 126 | 127 | local function intToBitArray(n) 128 | local ret = {} 129 | local i = 0 130 | while n ~= 0 do 131 | ret[i] = getLSB(n) 132 | n = math.floor(n/2) 133 | ret.size = i 134 | i = i + 1 135 | end 136 | return ret 137 | end 138 | 139 | 140 | local function printBitArray(a) 141 | local i 142 | for i = a.size,0,-1 do 143 | if a[i] then 144 | io.write("1") 145 | else 146 | io.write("0") 147 | end 148 | end 149 | end 150 | 151 | 152 | local function mergeMessage(im, msg) 153 | local w, h = im:sizeXY() 154 | msg = msg .. string.char(0) 155 | local len = string.len(msg) 156 | if h * w < len * 8 then 157 | return nil 158 | end 159 | local x, y = 0, 0 160 | local oim = gd.createTrueColor(w, h) 161 | local i = 1 162 | local a2, c, nc, chr 163 | local a = {} 164 | local s, e = 1, 1 165 | local rgb = {} 166 | 167 | while y < h do 168 | c = im:getPixel(x, y) 169 | rgb.r = im:red(c) 170 | rgb.g = im:green(c) 171 | rgb.b = im:blue(c) 172 | if i <= len and e - s < 3 then 173 | a2 = intToBitArray(string.byte(string.sub(msg, i, i))) 174 | for cnt = 7,0,-1 do 175 | a[e+7-cnt] = a2[cnt] 176 | end 177 | i = i + 1 178 | e = e + 8 179 | end 180 | if e - s > 0 then 181 | rgb.r = setLSB(rgb.r, a[s]) 182 | a[s] = nil 183 | s = s + 1 184 | end 185 | if e - s > 0 then 186 | rgb.g = setLSB(rgb.g, a[s]) 187 | a[s] = nil 188 | s = s + 1 189 | end 190 | if e - s > 0 then 191 | rgb.b = setLSB(rgb.b, a[s]) 192 | a[s] = nil 193 | s = s + 1 194 | end 195 | nc = oim:colorResolve(rgb.r, rgb.g, rgb.b) 196 | oim:setPixel(x, y, nc) 197 | x = x + 1 198 | if x == w then 199 | x = 0 200 | y = y + 1 201 | end 202 | end 203 | return oim, len*8, w*h 204 | end 205 | 206 | 207 | local function getMessage(im) 208 | local msg = {} 209 | local w, h = im:sizeXY() 210 | local x, y = 0, 0 211 | local a = {} 212 | local s, e = 1, 1 213 | local b = 0 214 | local c 215 | while y <= h do 216 | c = im:getPixel(x, y) 217 | a[e] = getLSB(im:red(c)) 218 | a[e+1] = getLSB(im:green(c)) 219 | a[e+2] = getLSB(im:blue(c)) 220 | e = e + 2 221 | if e - s >= 7 then 222 | b = 0 223 | for p = s, s+7 do 224 | b = b * 2 225 | if a[p] then 226 | b = b + 1 227 | end 228 | a[p] = nil 229 | end 230 | s = s + 8 231 | if b == 0 then 232 | return table.concat(msg) 233 | else 234 | msg[#msg+1] = string.char(b) 235 | end 236 | end 237 | e = e + 1 238 | x = x + 1 239 | if x == w then 240 | x = 0 241 | y = y + 1 242 | end 243 | end 244 | return table.concat(msg) 245 | end 246 | 247 | 248 | local function compare(fimg1, fimg2) 249 | local im1 = gd.createFromPng(fimg1) 250 | if not im1 then 251 | print("ERROR: " .. fimg1 .. " bad PNG data.") 252 | os.exit(1) 253 | end 254 | local im2 = gd.createFromPng(fimg2) 255 | if not im2 then 256 | print("ERROR: " .. fimg2 .. " bad PNG data.") 257 | os.exit(1) 258 | end 259 | local w1, h1 = im1:sizeXY() 260 | local w2, h2 = im2:sizeXY() 261 | if w1 ~= w2 or h1 ~= h2 then 262 | print("ERROR: Images have different sizes.") 263 | os.exit(1) 264 | end 265 | local oim = gd.createTrueColor(w1, h1) 266 | local x, y = 0, 0 267 | local c1, c2, oc, f, fc 268 | while y < h1 do 269 | c1 = im1:getPixel(x, y) 270 | c2 = im2:getPixel(x, y) 271 | if im1:red(c1) ~= im2:red(c2) 272 | or im1:green(c1) ~= im2:green(c2) 273 | or im1:blue(c1) ~= im2:blue(c2) then 274 | oc = oim:colorResolve(im2:red(c2), im2:green(c2), im2:blue(c2)) 275 | oim:setPixel(x, y, oc) 276 | else 277 | f = math.floor((im1:red(c1) + im1:green(c1) + im1:blue(c1))/6.0) 278 | fc = oim:colorResolve(f, f, f) 279 | oim:setPixel(x, y, fc) 280 | end 281 | x = x + 1 282 | if x == w1 then 283 | x = 0 284 | y = y + 1 285 | end 286 | end 287 | return oim 288 | end 289 | 290 | 291 | local function usage() 292 | print("Usage:") 293 | print(" lua steg.lua hide ") 294 | print(" lua steg.lua show ") 295 | print(" lua steg.lua diff ") 296 | print("") 297 | print(" hide - Reads a message from stdin and saves into .") 298 | print(" show - Reads a message from and prints it to stdout.") 299 | print(" diff - Compares two images and writes the diff to .") 300 | print("") 301 | print(" WARNING: All files used here must be in the PNG format!") 302 | end 303 | 304 | 305 | if not arg[1] or not arg[2] then 306 | usage() 307 | os.exit(1) 308 | end 309 | 310 | if arg[1] == "show" then 311 | local im = gd.createFromPng(arg[2]) 312 | if not im then 313 | print("ERROR: Bad image data.") 314 | os.exit(1) 315 | end 316 | io.write(getMessage(im)) 317 | os.exit(0) 318 | end 319 | 320 | if arg[1] == "hide" then 321 | if not arg[3] then 322 | usage() 323 | os.exit(1) 324 | end 325 | local im = gd.createFromPng(arg[2]) 326 | if not im then 327 | print("ERROR: Bad image data.") 328 | os.exit(1) 329 | end 330 | print("Type your message and press CTRL+D to finish.") 331 | local msg = io.read("*a") 332 | local oim, l, t = mergeMessage(im, msg) 333 | if not oim then 334 | print("ERROR: Image is too small for the message.") 335 | os.exit(1) 336 | end 337 | if not oim:png(arg[3]) then 338 | print("ERROR: Failed to write output file.") 339 | os.exit(1) 340 | end 341 | print(string.format("DONE: %2.1f%% of the image used to store the message.", 342 | 100.0*l/t)) 343 | os.exit(0) 344 | end 345 | 346 | if arg[1] == "diff" then 347 | if not arg[3] and arg[4] then 348 | usage() 349 | os.exit(1) 350 | end 351 | local oim = compare(arg[2], arg[3]) 352 | if not oim:png(arg[4]) then 353 | print("ERROR: Failed to write output file.") 354 | os.exit(1) 355 | end 356 | os.exit(0) 357 | end 358 | 359 | usage() 360 | os.exit(1) 361 | 362 | -------------------------------------------------------------------------------- /demos/test.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local gd = require("gd") 4 | 5 | math.randomseed(os.time()) 6 | 7 | local im = gd.createFromJpeg("./bugs.jpg") 8 | assert(im) 9 | local sx, sy = im:sizeXY() 10 | 11 | local im2 = gd.createTrueColor(2*sx, sy) 12 | local black = im2:colorAllocate(0, 0, 0) 13 | local white = im2:colorAllocate(255, 255, 255) 14 | gd.copy(im2, im, 0, 0, 0, 0, sx, sy, sx, sy) 15 | 16 | local sx2, sy2 = im2:sizeXY() 17 | im2:stringUp(gd.FONT_SMALL, 5, sy2-10, gd.VERSION, white) 18 | 19 | for i = 0, 14 do 20 | for j = 0, 24 do 21 | local rcl = im2:colorAllocate(math.random(255), math.random(255), 22 | math.random(255)) 23 | im2:filledRectangle(sx+20+j*10, i*20+40, sx+30+j*10, i*20+50, rcl) 24 | end 25 | end 26 | 27 | im2:string(gd.FONT_GIANT, sx+80, 10, "Powered by Lua", white) 28 | 29 | local blackTr = im2:colorAllocateAlpha(0, 0, 0, 80) 30 | im2:stringFT(blackTr, "./Vera.ttf", 140, 0, 70, 130, "gd") 31 | im2:stringFT(white, "./Vera.ttf", 45, math.pi/5, 340, 250, "FreeType") 32 | 33 | 34 | im2:png("out.png") 35 | os.execute("xdg-open out.png") 36 | -------------------------------------------------------------------------------- /demos/test2.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local gd = require("gd") 4 | 5 | local im = gd.createFromJpeg("./bugs.jpg") 6 | assert(im) 7 | 8 | local white = im:colorAllocate(255, 255, 255) 9 | im:string(gd.FONT_MEDIUM, 10, 10, "Powered by", white) 10 | 11 | local imlua = gd.createFromPng("./lua-gd.png") 12 | -- imlua:colorTransparent(imlua:getPixel(0, 0)) 13 | 14 | local sx, sy = imlua:sizeXY() 15 | gd.copy(im, imlua, 10, 25, 0, 0, sx, sy, sx, sy) 16 | im:string(gd.FONT_MEDIUM, 10, 330, "http://ittner.github.com/lua-gd/", white) 17 | 18 | im:png("out.png") 19 | os.execute("xdg-open out.png") 20 | -------------------------------------------------------------------------------- /demos/ttftext.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ittner/lua-gd/2ce8e478a8591afd71e607506bc8c64b161bbd30/demos/ttftext.lua -------------------------------------------------------------------------------- /demos/ttftextex.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local gd = require("gd") 4 | 5 | gd.useFontConfig(true) -- Use Fontconfig by default. 6 | 7 | local im = gd.createTrueColor(400, 400) 8 | assert(im) 9 | 10 | local black = im:colorAllocate(0, 0, 0) 11 | local grayt = im:colorAllocateAlpha(255, 255, 255, 80) 12 | local blue = im:colorAllocate(0, 0, 250) 13 | local red = im:colorAllocate(255, 0, 0) 14 | local green = im:colorAllocate(0, 250, 0) 15 | local lblue = im:colorAllocate(180, 180, 255) 16 | local yellow = im:colorAllocate(240, 240, 0) 17 | 18 | im:stringFTEx(lblue, "Vera", 20, 0, 40, 40, "Half\nspace", 19 | { linespacing = 0.5 } ) 20 | 21 | im:stringFTEx(red, "Vera", 20, 0, 140, 40, "Single\nspace", 22 | { linespacing = 1.0 } ) 23 | 24 | im:stringFTEx(green, "Vera", 20, 0, 240, 40, "Double\nspace", 25 | { linespacing = 2.0 } ) 26 | 27 | im:stringFTEx(yellow, "Vera", 40, 0, 80, 140, "Distorted!", 28 | { hdpi = 96, vdpi = 30 } ) 29 | 30 | 31 | local k = "Kerniiiiiiiiiiiiiiiiiing?" 32 | print(im:stringFTEx(red, "Vera", 30, 0, 10, 200, k, {})) 33 | print(im:stringFTEx(red, "Vera", 30, 0, 10, 240, k, 34 | { disable_kerning = true } )) 35 | 36 | for i = 10, 400, 10 do 37 | im:line(i, 170, i, 250, grayt) 38 | end 39 | 40 | 41 | local llX, llY, lrX, lrY, urX, urY, ulX, ulY, fontpath = 42 | im:stringFTEx(lblue, "Vera", 20, 0, 50, 320, "This font comes from", 43 | { return_font_path_name = true } ) 44 | 45 | im:string(gd.FONT_MEDIUM, 10, 340, fontpath, lblue) 46 | 47 | 48 | im:png("out.png") 49 | os.execute("xdg-open out.png") 50 | -------------------------------------------------------------------------------- /demos/utf-8.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | -- -*- coding: utf-8 -*- 3 | 4 | -- UTF-8 encoded unicode text. You must use an UTF-8 compatible text editor 5 | -- to change this and a compatible Unicode font (FreeSerif is a good one). 6 | -- 7 | -- WARNING: Windows Notepad will add some prefixes, making this file an 8 | -- invalid Lua script. 9 | 10 | local gd = require("gd") 11 | 12 | local text = [[ 13 | ⌠ ☾ Lua-GD 14 | ⌡ Unicode/UTF-8 15 | ↺↻⇒✇☢☣☠ 16 | ♜♞♝♛♚♝♞♜ 17 | ♟♟♟♟♟♟♟♟ 18 | ♙♙♙♙♙♙♙♙ 19 | ♖♘♗♕♔♗♘♖ 20 | ]] 21 | 22 | local fontname = "FreeSerif" -- Common on Unix systems 23 | -- local fontname = "Arial Unicode" -- Common on Windows systems 24 | 25 | gd.useFontConfig(true) 26 | 27 | local im = gd.createTrueColor(180, 180) 28 | local white = im:colorAllocate(255, 255, 255) 29 | local black = im:colorAllocate(0, 0, 0) 30 | local x, y = im:sizeXY() 31 | im:filledRectangle(0, 0, x, y, white) 32 | im:stringFT(black, fontname, 16, 0, 10, 30, text) 33 | 34 | im:png("out.png") 35 | os.execute("xdg-open out.png") 36 | -------------------------------------------------------------------------------- /doc/cat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ittner/lua-gd/2ce8e478a8591afd71e607506bc8c64b161bbd30/doc/cat.png -------------------------------------------------------------------------------- /doc/catdiff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ittner/lua-gd/2ce8e478a8591afd71e607506bc8c64b161bbd30/doc/catdiff.png -------------------------------------------------------------------------------- /doc/catmsg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ittner/lua-gd/2ce8e478a8591afd71e607506bc8c64b161bbd30/doc/catmsg.png -------------------------------------------------------------------------------- /doc/clock-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ittner/lua-gd/2ce8e478a8591afd71e607506bc8c64b161bbd30/doc/clock-example.png -------------------------------------------------------------------------------- /doc/fontconfig-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ittner/lua-gd/2ce8e478a8591afd71e607506bc8c64b161bbd30/doc/fontconfig-example.png -------------------------------------------------------------------------------- /doc/gifanim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ittner/lua-gd/2ce8e478a8591afd71e607506bc8c64b161bbd30/doc/gifanim.gif -------------------------------------------------------------------------------- /doc/lua-gd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ittner/lua-gd/2ce8e478a8591afd71e607506bc8c64b161bbd30/doc/lua-gd.png -------------------------------------------------------------------------------- /doc/sierpinski.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ittner/lua-gd/2ce8e478a8591afd71e607506bc8c64b161bbd30/doc/sierpinski.png -------------------------------------------------------------------------------- /doc/stdfonts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ittner/lua-gd/2ce8e478a8591afd71e607506bc8c64b161bbd30/doc/stdfonts.png -------------------------------------------------------------------------------- /lua-gd.ps: -------------------------------------------------------------------------------- 1 | %!PS-Adobe-2.0 EPSF-2.0 2 | %%Title: Lua logo 3 | %%Creator: lua@tecgraf.puc-rio.br 4 | %%CreationDate: Wed Nov 29 19:04:04 EDT 2000 5 | %%BoundingBox: -45 0 1035 1080 6 | %%Pages: 1 7 | %%EndComments 8 | %%EndProlog 9 | 10 | %------------------------------------------------------------------------------ 11 | % 12 | % Graphic design by Alexandre Nakonechnyj. 13 | % PostScript programming by the Lua team. 14 | % This code is hereby placed in the public domain. 15 | % 16 | % Permission is hereby granted, without written agreement and without license 17 | % or royalty fees, to use, copy, and distribute this logo for any purpose, 18 | % including commercial applications, subject to the following conditions: 19 | % 20 | % * The origin of this logo must not be misrepresented; you must not 21 | % claim that you drew the original logo. We recommend that you give credit 22 | % to the graphics designer in all printed matter that includes the logo. 23 | % 24 | % * The only modification you can make is to adapt the orbiting text to 25 | % your product name. 26 | % 27 | % * The logo can be used in any scale as long as the relative proportions 28 | % of its elements are maintained. 29 | % 30 | %------------------------------------------------------------------------------ 31 | 32 | /LABEL (Lua-GD) def 33 | 34 | %-- DO NOT CHANGE ANYTHING BELOW THIS LINE ------------------------------------ 35 | 36 | /PLANETCOLOR {0 0 0.5 setrgbcolor} bind def 37 | /HOLECOLOR {1.0 setgray} bind def 38 | /ORBITCOLOR {0.5 setgray} bind def 39 | /LOGOFONT {/Helvetica 0.90} def 40 | /LABELFONT {/Helvetica 0.36} def 41 | 42 | %------------------------------------------------------------------------------ 43 | 44 | /MOONCOLOR {PLANETCOLOR} bind def 45 | /LOGOCOLOR {HOLECOLOR} bind def 46 | /LABELCOLOR {ORBITCOLOR} bind def 47 | 48 | /LABELANGLE 125 def 49 | /LOGO (Lua) def 50 | 51 | /DASHANGLE 10 def 52 | /HALFDASHANGLE DASHANGLE 2 div def 53 | 54 | % moon radius. planet radius is 1. 55 | /r 1 2 sqrt 2 div sub def 56 | 57 | /D {0 360 arc fill} bind def 58 | /F {exch findfont exch scalefont setfont} bind def 59 | 60 | % place it nicely on the paper 61 | /RESOLUTION 1024 def 62 | RESOLUTION 2 div dup translate 63 | RESOLUTION 2 div 2 sqrt div dup scale 64 | 65 | %-------------------------------------------------------------------- planet -- 66 | PLANETCOLOR 67 | 0 0 1 D 68 | 69 | %---------------------------------------------------------------------- hole -- 70 | HOLECOLOR 71 | 1 2 r mul sub dup r D 72 | 73 | %---------------------------------------------------------------------- moon -- 74 | MOONCOLOR 75 | 1 1 r D 76 | 77 | %---------------------------------------------------------------------- logo -- 78 | LOGOCOLOR 79 | LOGOFONT 80 | F 81 | LOGO stringwidth pop 2 div neg 82 | -0.5 moveto 83 | LOGO show 84 | 85 | %------------------------------------------------------------------------------ 86 | % based on code from Blue Book Program 10, on pages 167--169 87 | % available at ftp://ftp.adobe.com/pub/adobe/displaypostscript/bluebook.shar 88 | 89 | % str ptsize centerangle radius outsidecircletext -- 90 | /outsidecircletext { 91 | circtextdict begin 92 | /radius exch def 93 | /centerangle exch def 94 | /ptsize exch def 95 | /str exch def 96 | 97 | gsave 98 | str radius ptsize findhalfangle 99 | centerangle 100 | add rotate 101 | str 102 | { /charcode exch def 103 | ( ) dup 0 charcode put outsideplacechar 104 | } forall 105 | 106 | grestore 107 | end 108 | } def 109 | 110 | % string radius ptsize findhalfangle halfangle 111 | /findhalfangle { 112 | 4 div add 113 | exch 114 | stringwidth pop 2 div 115 | exch 116 | 2 mul 3.1415926535 mul div 360 mul 117 | } def 118 | 119 | /circtextdict 16 dict def 120 | circtextdict begin 121 | 122 | /outsideplacechar { 123 | /char exch def 124 | /halfangle char radius ptsize findhalfangle def 125 | gsave 126 | halfangle neg rotate 127 | radius 0 translate 128 | -90 rotate 129 | char stringwidth pop 2 div neg 0 moveto 130 | char show 131 | grestore 132 | halfangle 2 mul neg rotate 133 | } def 134 | 135 | end 136 | 137 | %--------------------------------------------------------------------- label -- 138 | LABELFONT 139 | F 140 | 141 | /LABELSIZE LABELFONT exch pop def 142 | /LABELRADIUS LABELSIZE 3 div 1 r add sub neg 1.02 mul def 143 | 144 | 145 | /HALFANGLE 146 | LABEL LABELRADIUS LABELSIZE findhalfangle 147 | HALFDASHANGLE div ceiling HALFDASHANGLE mul 148 | def 149 | 150 | /LABELANGLE 151 | 60 LABELANGLE HALFANGLE sub 152 | lt 153 | { 154 | HALFANGLE 155 | HALFANGLE DASHANGLE div floor DASHANGLE mul 156 | eq 157 | {LABELANGLE DASHANGLE div ceiling DASHANGLE mul} 158 | {LABELANGLE HALFDASHANGLE sub DASHANGLE div round DASHANGLE mul HALFDASHANGLE add} 159 | ifelse 160 | } 161 | {HALFANGLE 60 add} 162 | ifelse 163 | def 164 | 165 | LABELCOLOR 166 | LABEL 167 | LABELSIZE 168 | LABELANGLE 169 | LABELRADIUS 170 | outsidecircletext 171 | 172 | %--------------------------------------------------------------------- orbit -- 173 | ORBITCOLOR 174 | 0.03 setlinewidth 175 | [1 r add 3.1415926535 180 div HALFDASHANGLE mul mul] 0 setdash 176 | newpath 177 | 0 0 178 | 1 r add 179 | 3 copy 180 | 30 181 | LABELANGLE HALFANGLE add 182 | arcn 183 | stroke 184 | 60 185 | LABELANGLE HALFANGLE sub 186 | 2 copy 187 | lt {arc stroke} {4 {pop} repeat} ifelse 188 | 189 | %------------------------------------------------------------------ copyright -- 190 | /COPYRIGHT 191 | (Graphic design by A. Nakonechnyj. Copyright (c) 1998, All rights reserved.) 192 | def 193 | 194 | LABELCOLOR 195 | LOGOFONT 196 | 32 div 197 | F 198 | 2 sqrt 0.99 mul 199 | dup 200 | neg 201 | moveto 202 | COPYRIGHT 203 | 90 rotate 204 | %show 205 | 206 | %---------------------------------------------------------------------- done -- 207 | showpage 208 | 209 | %%Trailer 210 | %%EOF 211 | -------------------------------------------------------------------------------- /lua-gd.spec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ittner/lua-gd/2ce8e478a8591afd71e607506bc8c64b161bbd30/lua-gd.spec -------------------------------------------------------------------------------- /luagd-2.0.33r3-1.rockspec: -------------------------------------------------------------------------------- 1 | package = "LuaGD" 2 | version = "2.0.33r3-1" 3 | 4 | source = { 5 | url = "https://github.com/ittner/lua-gd/archive/lua-gd-2.0.33r3.tar.gz", 6 | } 7 | 8 | description = { 9 | summary = "Lua binding to LibGD", 10 | detailed = [[ 11 | Lua-GD is a set of Lua bindings to the Thomas Boutell's gd library that 12 | allows your code to quickly draw complete images with lines, polygons, arcs, 13 | text, multiple colors, cut and paste from other images, flood fills, read in 14 | or write out images in the PNG, JPEG or GIF format. It is not a kitchen-sink 15 | graphics package, but it does include most frequently requested features, 16 | including both truecolor and palette images, resampling (smooth resizing of 17 | truecolor images) and so forth. It is particularly useful in Web applications. 18 | ]], 19 | homepage = "http://ittner.github.io/lua-gd/", 20 | license = "MIT/X11", 21 | maintainer = "Alexandre Erwin Ittner" 22 | } 23 | 24 | dependencies = { 25 | "lua >= 5.1" 26 | } 27 | 28 | external_dependencies = { 29 | GD = { header = "gd.h" } 30 | } 31 | 32 | build = { 33 | type = "make", 34 | platforms = { 35 | unix = { 36 | build_pass = true, 37 | install_pass = false, 38 | install = { lib = { "gd.so" } }, 39 | copy_directories = { "doc", "demos" } 40 | } 41 | -- Some way to detect GD features on Windows? 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /luagd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * luagd -- GD bindings for Lua. 3 | * (c) 2004-13 Alexandre Erwin Ittner 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 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | /* Standard gd fonts */ 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #ifndef VERSION 43 | #error "Trying to build without -DVERSION=xxx defined. Check the Makefile" 44 | #endif 45 | #define LIB_VERSION "lua-gd " VERSION 46 | #define LIB_COPYRIGHT LIB_VERSION " (c) 2004-13 Alexandre Erwin Ittner" 47 | 48 | #define GD_IMAGE_PTR_TYPENAME "gdImagePtr_handle" 49 | 50 | 51 | /* Compatibility between Lua 5.1 and Lua 5.2 */ 52 | #if LUA_VERSION_NUM < 501 53 | #error "Unsuported Lua version. You must use Lua >= 5.1" 54 | #endif 55 | 56 | #if LUA_VERSION_NUM < 502 57 | #define luaL_setfuncs(L, f, unused) { luaL_register(L, NULL, f); } 58 | #define lua_rawlen lua_objlen 59 | #endif 60 | 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 | 78 | static int typerror(lua_State *L, int narg, const char *tname) { 79 | const char *msg = lua_pushfstring(L, "%s expected, got %s", 80 | tname, luaL_typename(L, narg)); 81 | return luaL_argerror(L, narg, msg); 82 | } 83 | 84 | 85 | static gdImagePtr getImagePtr(lua_State *L, int i) { 86 | if (luaL_checkudata(L, i, GD_IMAGE_PTR_TYPENAME) != NULL) { 87 | gdImagePtr im = unboxptr(L, i); 88 | if (im == NULL) 89 | luaL_error(L, "attempt to use an invalid " GD_IMAGE_PTR_TYPENAME); 90 | return im; 91 | } 92 | typerror(L, i, GD_IMAGE_PTR_TYPENAME); 93 | return NULL; 94 | } 95 | 96 | 97 | static void pushImagePtr(lua_State *L, gdImagePtr im) { 98 | boxptr(L, im); 99 | luaL_getmetatable(L, GD_IMAGE_PTR_TYPENAME); 100 | lua_setmetatable(L, -2); /* Done */ 101 | } 102 | 103 | 104 | static gdFontPtr getStdFont(lua_State *L, int i) { 105 | int size; 106 | 107 | if (lua_isnumber(L, i) == 0) { 108 | typerror(L, i, "Standard GD Font"); 109 | return gdFontGetSmall(); 110 | } 111 | 112 | size = luaL_checkinteger(L, i); 113 | switch(size) { 114 | case MY_GD_FONT_SMALL: 115 | return gdFontGetSmall(); 116 | 117 | case MY_GD_FONT_LARGE: 118 | return gdFontGetLarge(); 119 | 120 | case MY_GD_FONT_MEDIUM_BOLD: 121 | return gdFontGetMediumBold(); 122 | 123 | case MY_GD_FONT_GIANT: 124 | return gdFontGetGiant(); 125 | 126 | case MY_GD_FONT_TINY: 127 | return gdFontGetTiny(); 128 | 129 | default: 130 | typerror(L, i, "Standard GD Font"); 131 | return gdFontGetSmall(); 132 | } 133 | 134 | return gdFontGetSmall(); /* Not reached */ 135 | } 136 | 137 | 138 | 139 | 140 | /* 141 | * Reads a Lua table and returns a pointer to a "gdFTStringExtra" struct. The 142 | * table should have the following fields: 143 | * 144 | * { 145 | * linespacing = 1.0, -- linespacing for '\n' 146 | * charmap = gd.FTEX_Unicode, -- default charset 147 | * hdpi = 96, -- horizontal resolution 148 | * vdpi = 96, -- vertical resolution 149 | * disable_kerning = true, -- disable kerning? 150 | * xshow = true, -- return char positions? 151 | * return_font_path_name = true, -- return font path names? 152 | * fontconfig = true -- use fontconfig? 153 | * } 154 | * 155 | */ 156 | #ifdef GD_FREETYPE 157 | static gdFTStringExtra *getFTStringExtraPtr(lua_State *L, int i) { 158 | luaL_checktype(L, i, LUA_TTABLE); 159 | 160 | gdFTStringExtra *ex = (gdFTStringExtra*) malloc(sizeof(gdFTStringExtra)); 161 | if (ex == NULL) 162 | luaL_error(L, "Memory allocation failure"); 163 | 164 | ex->flags = 0; 165 | 166 | lua_pushstring(L, "linespacing"); 167 | lua_gettable(L, i); 168 | if (!lua_isnil(L, -1)) { 169 | ex->flags |= gdFTEX_LINESPACE; 170 | ex->linespacing = (double) lua_tonumber(L, -1); 171 | } 172 | lua_pop(L, 1); 173 | 174 | lua_pushstring(L, "charmap"); 175 | lua_gettable(L, i); 176 | if (!lua_isnil(L, -1)) { 177 | ex->flags |= gdFTEX_CHARMAP;; 178 | ex->charmap = (int) lua_tonumber(L, -1); 179 | switch(ex->charmap) { 180 | case gdFTEX_Unicode: 181 | case gdFTEX_Shift_JIS: 182 | case gdFTEX_Big5: 183 | /* Future charsets here */ 184 | break; 185 | default: 186 | free(ex); 187 | luaL_error(L, "Invalid charset"); 188 | } 189 | } 190 | lua_pop(L, 1); 191 | 192 | ex->hdpi = 96; 193 | ex->vdpi = 96; 194 | 195 | lua_pushstring(L, "hdpi"); 196 | lua_gettable(L, i); 197 | if (!lua_isnil(L, -1)) { 198 | ex->flags |= gdFTEX_RESOLUTION; 199 | ex->hdpi = (double) lua_tonumber(L, -1); 200 | } 201 | lua_pop(L, 1); 202 | 203 | lua_pushstring(L, "vdpi"); 204 | lua_gettable(L, i); 205 | if (!lua_isnil(L, -1)) { 206 | ex->flags |= gdFTEX_RESOLUTION; 207 | ex->vdpi = (double) lua_tonumber(L, -1); 208 | } 209 | lua_pop(L, 1); 210 | 211 | lua_pushstring(L, "disable_kerning"); 212 | lua_gettable(L, i); 213 | if (lua_toboolean(L, -1)) 214 | ex->flags |= gdFTEX_DISABLE_KERNING; 215 | lua_pop(L, 1); 216 | 217 | lua_pushvalue(L, i); 218 | lua_pushstring(L, "xshow"); 219 | lua_gettable(L, i); 220 | if (lua_toboolean(L, -1)) 221 | ex->flags |= gdFTEX_XSHOW; 222 | lua_pop(L, 1); 223 | 224 | lua_pushstring(L, "return_font_path_name"); 225 | lua_gettable(L, i); 226 | if (lua_toboolean(L, -1)) 227 | ex->flags |= gdFTEX_RETURNFONTPATHNAME; 228 | lua_pop(L, 1); 229 | 230 | lua_pushstring(L, "fontconfig"); 231 | lua_gettable(L, i); 232 | if (lua_toboolean(L, -1)) 233 | ex->flags |= gdFTEX_FONTCONFIG; 234 | lua_pop(L, 1); 235 | 236 | return ex; 237 | } 238 | #endif 239 | 240 | 241 | /* gdImageCreate(int sx, int sy) */ 242 | static int LgdImageCreate(lua_State *L) { 243 | int sx, sy; 244 | gdImagePtr im; 245 | 246 | sx = luaL_checkinteger(L, 1); 247 | sy = luaL_checkinteger(L, 2); 248 | im = gdImageCreate(sx, sy); 249 | if (im != NULL) 250 | pushImagePtr(L, im); 251 | else 252 | lua_pushnil(L); /* Error */ 253 | return 1; 254 | } 255 | 256 | /* gdImageCreatePalette(int sx, int sy) */ 257 | /* Useless? */ 258 | static int LgdImageCreatePalette(lua_State *L) { 259 | int sx, sy; 260 | gdImagePtr im; 261 | 262 | sx = luaL_checkinteger(L, 1); 263 | sy = luaL_checkinteger(L, 2); 264 | im = gdImageCreatePalette(sx, sy); 265 | if (im != NULL) 266 | pushImagePtr(L, im); 267 | else 268 | lua_pushnil(L); /* Error */ 269 | return 1; 270 | } 271 | 272 | 273 | 274 | /* gdImageCreateTrueColor(int sx, int sy) */ 275 | static int LgdImageCreateTrueColor(lua_State *L) { 276 | int sx, sy; 277 | gdImagePtr im; 278 | 279 | sx = luaL_checkinteger(L, 1); 280 | sy = luaL_checkinteger(L, 2); 281 | im = gdImageCreateTrueColor(sx, sy); 282 | if (im != NULL) 283 | pushImagePtr(L, im); 284 | else 285 | lua_pushnil(L); /* Error */ 286 | return 1; 287 | } 288 | 289 | /* gdImagePtr gdImageCreatePaletteFromTrueColor(gdImagePtr im, int ditherFlag, 290 | int colorsWanted) */ 291 | static int LgdImageCreatePaletteFromTrueColor(lua_State *L) { 292 | gdImagePtr im = getImagePtr(L, 1); 293 | int dither = lua_toboolean(L, 2); 294 | int colors = luaL_checkinteger(L, 3); 295 | gdImagePtr nim = gdImageCreatePaletteFromTrueColor(im, dither, colors); 296 | 297 | if (nim) 298 | pushImagePtr(L, nim); 299 | else 300 | lua_pushnil(L); 301 | return 1; 302 | } 303 | 304 | 305 | /* void gdImageTrueColorToPalette(gdImagePtr im, int ditherFlag, 306 | int colorsWanted) */ 307 | static int LgdImageTrueColorToPalette(lua_State *L) { 308 | gdImagePtr im = getImagePtr(L, 1); 309 | int dither = lua_toboolean(L, 2); 310 | int colors = luaL_checkinteger(L, 3); 311 | 312 | gdImageTrueColorToPalette(im, dither, colors); 313 | return 0; 314 | } 315 | 316 | 317 | 318 | /* gdImageDestroy(gdImagePtr im) */ 319 | static int LgdImageDestroy(lua_State *L) { 320 | gdImagePtr im = getImagePtr(L, 1); 321 | if (im) 322 | gdImageDestroy(im); 323 | return 0; 324 | } 325 | 326 | #ifdef GD_JPEG 327 | /* gdImageCreateFromJpeg(FILE *in) */ 328 | /* Changed to: gd.createFromJpeg(char *filename) */ 329 | static int LgdImageCreateFromJpeg(lua_State *L) { 330 | gdImagePtr im; 331 | FILE *fp; 332 | const char *fname = luaL_checkstring(L, 1); 333 | 334 | if (fname == NULL) { 335 | lua_pushnil(L); 336 | return 1; /* Error */ 337 | } 338 | if ((fp = fopen(fname, "rb")) == NULL) { 339 | lua_pushnil(L); 340 | return 1; /* Error */ 341 | } 342 | im = gdImageCreateFromJpeg(fp); 343 | fclose(fp); 344 | if (im != NULL) 345 | pushImagePtr(L, im); 346 | else 347 | lua_pushnil(L); /* Error */ 348 | return 1; 349 | } 350 | 351 | 352 | /* gdImageCreateFromJpegPtr(int size, void *data) */ 353 | static int LgdImageCreateFromJpegPtr(lua_State *L) { 354 | gdImagePtr im; 355 | int size = lua_rawlen(L, 1); 356 | void *str = (void*) luaL_checkstring(L, 1); 357 | 358 | if (str == NULL) { 359 | lua_pushnil(L); 360 | return 1; /* Error */ 361 | } 362 | im = gdImageCreateFromJpegPtr(size, str); 363 | if (im != NULL) 364 | pushImagePtr(L, im); 365 | else 366 | lua_pushnil(L); /* Error */ 367 | return 1; 368 | } 369 | #endif 370 | 371 | 372 | #ifdef GD_GIF 373 | /* gdImageCreateFromGif (FILE *in) */ 374 | /* Changed to: gd.createFromGif (filename) */ 375 | static int LgdImageCreateFromGif (lua_State *L) { 376 | gdImagePtr im; 377 | FILE *fp; 378 | const char *fname = luaL_checkstring(L, 1); 379 | 380 | if (fname == NULL) { 381 | lua_pushnil(L); 382 | return 1; /* Error */ 383 | } 384 | if ((fp = fopen(fname, "rb")) == NULL) { 385 | lua_pushnil(L); 386 | return 1; /* Error */ 387 | } 388 | im = gdImageCreateFromGif (fp); 389 | fclose(fp); 390 | if (im != NULL) 391 | pushImagePtr(L, im); 392 | else 393 | lua_pushnil(L); /* Error */ 394 | return 1; 395 | } 396 | 397 | /* gdImageCreateFromGifPtr(int size, void *data) */ 398 | static int LgdImageCreateFromGifPtr(lua_State *L) { 399 | gdImagePtr im; 400 | int size = lua_rawlen(L, 1); 401 | void *str = (void*) luaL_checkstring(L, 1); 402 | 403 | if (str == NULL) { 404 | lua_pushnil(L); 405 | return 1; /* Error */ 406 | } 407 | im = gdImageCreateFromGifPtr(size, str); 408 | if (im != NULL) 409 | pushImagePtr(L, im); 410 | else 411 | lua_pushnil(L); /* Error */ 412 | return 1; 413 | } 414 | #endif 415 | 416 | 417 | #ifdef GD_PNG 418 | /* gdImageCreateFromPng(FILE *in) */ 419 | /* Changed to: gd.createFromPng(filename) */ 420 | static int LgdImageCreateFromPng(lua_State *L) { 421 | gdImagePtr im; 422 | FILE *fp; 423 | const char *fname = luaL_checkstring(L, 1); 424 | 425 | if (fname == NULL) { 426 | lua_pushnil(L); 427 | return 1; /* Error */ 428 | } 429 | if ((fp = fopen(fname, "rb")) == NULL) { 430 | lua_pushnil(L); 431 | return 1; /* Error */ 432 | } 433 | im = gdImageCreateFromPng(fp); 434 | fclose(fp); 435 | if (im != NULL) 436 | pushImagePtr(L, im); 437 | else 438 | lua_pushnil(L); /* Error */ 439 | return 1; 440 | } 441 | 442 | 443 | /* gdImageCreateFromPngPtr(int size, void *data) */ 444 | static int LgdImageCreateFromPngPtr(lua_State *L) { 445 | gdImagePtr im; 446 | int size = lua_rawlen(L, 1); 447 | void *str = (void*) luaL_checkstring(L, 1); 448 | 449 | if (str == NULL) { 450 | lua_pushnil(L); 451 | return 1; /* Error */ 452 | } 453 | im = gdImageCreateFromPngPtr(size, str); 454 | if (im != NULL) 455 | pushImagePtr(L, im); 456 | else 457 | lua_pushnil(L); /* Error */ 458 | return 1; 459 | } 460 | #endif 461 | 462 | 463 | /* gdImageCreateFromGd(FILE *in) */ 464 | /* Changed to: gd.createFromGd(filename) */ 465 | static int LgdImageCreateFromGd(lua_State *L) { 466 | gdImagePtr im; 467 | FILE *fp; 468 | const char *fname = luaL_checkstring(L, 1); 469 | 470 | if (fname == NULL) { 471 | lua_pushnil(L); 472 | return 1; /* Error */ 473 | } 474 | if ((fp = fopen(fname, "rb")) == NULL) { 475 | lua_pushnil(L); 476 | return 1; /* Error */ 477 | } 478 | im = gdImageCreateFromGd(fp); 479 | fclose(fp); 480 | if (im != NULL) 481 | pushImagePtr(L, im); 482 | else 483 | lua_pushnil(L); /* Error */ 484 | return 1; 485 | } 486 | 487 | 488 | /* gdImageCreateFromGdPtr(int size, void *data) */ 489 | static int LgdImageCreateFromGdPtr(lua_State *L) { 490 | gdImagePtr im; 491 | int size = lua_rawlen(L, 1); 492 | void *str = (void*) luaL_checkstring(L, 1); 493 | 494 | if (str == NULL) { 495 | lua_pushnil(L); 496 | return 1; /* Error */ 497 | } 498 | im = gdImageCreateFromGdPtr(size, str); 499 | if (im != NULL) 500 | pushImagePtr(L, im); 501 | else 502 | lua_pushnil(L); /* Error */ 503 | return 1; 504 | } 505 | 506 | 507 | /* gdImageCreateFromGd2(FILE *in) */ 508 | /* Changed to: gd.createFromGd2(filename) */ 509 | static int LgdImageCreateFromGd2(lua_State *L) { 510 | gdImagePtr im; 511 | FILE *fp; 512 | const char *fname = luaL_checkstring(L, 1); 513 | 514 | if (fname == NULL) { 515 | lua_pushnil(L); 516 | return 1; /* Error */ 517 | } 518 | if ((fp = fopen(fname, "rb")) == NULL) { 519 | lua_pushnil(L); 520 | return 1; /* Error */ 521 | } 522 | im = gdImageCreateFromGd2(fp); 523 | fclose(fp); 524 | if (im != NULL) 525 | pushImagePtr(L, im); 526 | else 527 | lua_pushnil(L); /* Error */ 528 | return 1; 529 | } 530 | 531 | 532 | /* gdImageCreateFromGd2Ptr(int size, void *data) */ 533 | static int LgdImageCreateFromGd2Ptr(lua_State *L) { 534 | gdImagePtr im; 535 | int size = lua_rawlen(L, 1); 536 | void *str = (void*) luaL_checkstring(L, 1); 537 | 538 | if (str == NULL) { 539 | lua_pushnil(L); 540 | return 1; /* Error */ 541 | } 542 | im = gdImageCreateFromGd2Ptr(size, str); 543 | if (im != NULL) 544 | pushImagePtr(L, im); 545 | else 546 | lua_pushnil(L); /* Error */ 547 | return 1; 548 | } 549 | 550 | 551 | /* gdImageCreateFromGd2Part(FILE *in, int x, int y, int w, int h) */ 552 | /* Changed to: gd.createFromGd2Part(filename, x, y, w, h)) */ 553 | static int LgdImageCreateFromGd2Part(lua_State *L) { 554 | gdImagePtr im; 555 | FILE *fp; 556 | const char *fname = luaL_checkstring(L, 1); 557 | const int x = luaL_checkinteger(L, 2); 558 | const int y = luaL_checkinteger(L, 3); 559 | const int w = luaL_checkinteger(L, 4); 560 | const int h = luaL_checkinteger(L, 5); 561 | 562 | if (fname == NULL) { 563 | lua_pushnil(L); 564 | return 1; /* Error */ 565 | } 566 | if ((fp = fopen(fname, "rb")) == NULL) { 567 | lua_pushnil(L); 568 | return 1; /* Error */ 569 | } 570 | im = gdImageCreateFromGd2Part(fp, x, y, w, h); 571 | fclose(fp); 572 | if (im != NULL) 573 | pushImagePtr(L, im); 574 | else 575 | lua_pushnil(L); /* Error */ 576 | return 1; 577 | } 578 | 579 | 580 | /* gdImageCreateFromGd2PartPtr(int size, void *data, 581 | int srcX, int srcY, int w, int h) */ 582 | static int LgdImageCreateFromGd2PartPtr(lua_State *L) { 583 | gdImagePtr im; 584 | int size = lua_rawlen(L, 1); 585 | void *str = (void*) luaL_checkstring(L, 1); 586 | const int x = luaL_checkinteger(L, 2); 587 | const int y = luaL_checkinteger(L, 3); 588 | const int w = luaL_checkinteger(L, 4); 589 | const int h = luaL_checkinteger(L, 5); 590 | 591 | if (str == NULL) { 592 | lua_pushnil(L); 593 | return 1; /* Error */ 594 | } 595 | im = gdImageCreateFromGd2PartPtr(size, str, x, y, w, h); 596 | if (im != NULL) 597 | pushImagePtr(L, im); 598 | else 599 | lua_pushnil(L); /* Error */ 600 | return 1; 601 | } 602 | 603 | 604 | #ifdef GD_XPM 605 | /* gdImageCreateFromXbm(FILE *in) */ 606 | /* Changed to: gd.createFromXbm(filename) */ 607 | static int LgdImageCreateFromXbm(lua_State *L) { 608 | gdImagePtr im; 609 | FILE *fp; 610 | const char *fname = luaL_checkstring(L, 1); 611 | 612 | if (fname == NULL) { 613 | lua_pushnil(L); 614 | return 1; /* Error */ 615 | } 616 | if ((fp = fopen(fname, "rb")) == NULL) { 617 | lua_pushnil(L); 618 | return 1; /* Error */ 619 | } 620 | im = gdImageCreateFromXbm(fp); 621 | fclose(fp); 622 | if (im != NULL) 623 | pushImagePtr(L, im); 624 | else 625 | lua_pushnil(L); /* Error */ 626 | return 1; 627 | } 628 | 629 | 630 | /* gdImageCreateFromXpm(char *filename) */ 631 | static int LgdImageCreateFromXpm(lua_State *L) { 632 | gdImagePtr im; 633 | char *fname = (char*) luaL_checkstring(L, 1); 634 | 635 | if (fname == NULL) { 636 | lua_pushnil(L); 637 | return 1; /* Error */ 638 | } 639 | im = gdImageCreateFromXpm(fname); 640 | if (im != NULL) 641 | pushImagePtr(L, im); 642 | else 643 | lua_pushnil(L); /* Error */ 644 | return 1; 645 | } 646 | #endif 647 | 648 | 649 | 650 | #ifdef GD_JPEG 651 | /* gdImageJpeg(gdImagePtr im, FILE *out, int quality) */ 652 | /* Changed to: gd.jpeg(im, fname, quality) */ 653 | static int LgdImageJpeg(lua_State *L) { 654 | gdImagePtr im = getImagePtr(L, 1); 655 | const char *fname = luaL_checkstring(L, 2); 656 | int quality = luaL_checkinteger(L, 3); 657 | FILE *fp; 658 | 659 | if (fname == NULL) { 660 | lua_pushboolean(L, 0); 661 | return 1; 662 | } 663 | if ((fp = fopen(fname, "wb")) == NULL) { 664 | lua_pushboolean(L, 0); 665 | return 1; 666 | } 667 | gdImageJpeg(im, fp, quality); 668 | fclose(fp); 669 | lua_pushboolean(L, 1); 670 | return 1; 671 | } 672 | 673 | 674 | /* void *gdImageJpegPtr(gdImagePtr im, int quality) */ 675 | static int LgdImageJpegPtr(lua_State *L) { 676 | gdImagePtr im = getImagePtr(L, 1); 677 | int quality = luaL_checkinteger(L, 2); 678 | char *str; 679 | int size; 680 | 681 | str = gdImageJpegPtr(im, &size, quality); 682 | if (str != NULL) { 683 | lua_pushlstring(L, str, size); 684 | gdFree(str); 685 | } else { 686 | lua_pushnil(L); /* Error */ 687 | } 688 | return 1; 689 | } 690 | #endif 691 | 692 | #ifdef GD_PNG 693 | /* gdImagePng(gdImagePtr im, FILE *out) */ 694 | /* Changed to: gd.png(im, fname) */ 695 | static int LgdImagePng(lua_State *L) { 696 | gdImagePtr im = getImagePtr(L, 1); 697 | const char *fname = luaL_checkstring(L, 2); 698 | FILE *fp; 699 | 700 | if (fname == NULL) { 701 | lua_pushboolean(L, 0); 702 | return 1; 703 | } 704 | if ((fp = fopen(fname, "wb")) == NULL) { 705 | lua_pushboolean(L, 0); 706 | return 1; 707 | } 708 | gdImagePng(im, fp); 709 | fclose(fp); 710 | lua_pushboolean(L, 1); 711 | return 1; 712 | } 713 | 714 | 715 | /* void *gdImagePngPtr(gdImagePtr im) */ 716 | static int LgdImagePngPtr(lua_State *L) { 717 | gdImagePtr im = getImagePtr(L, 1); 718 | char *str; 719 | int size; 720 | 721 | str = gdImagePngPtr(im, &size); 722 | if (str != NULL) { 723 | lua_pushlstring(L, str, size); 724 | gdFree(str); 725 | } else { 726 | lua_pushnil(L); /* Error */ 727 | } 728 | return 1; 729 | } 730 | 731 | 732 | /* gdImagePngEx(gdImagePtr im, FILE *out, int compression_level) */ 733 | /* Changed to: gd.pngEx(im, fname, compression_level) */ 734 | static int LgdImagePngEx(lua_State *L) { 735 | gdImagePtr im = getImagePtr(L, 1); 736 | const char *fname = luaL_checkstring(L, 2); 737 | int level = luaL_checkinteger(L, 3); 738 | FILE *fp; 739 | 740 | if (fname == NULL) { 741 | lua_pushboolean(L, 0); 742 | return 1; 743 | } 744 | if ((fp = fopen(fname, "wb")) == NULL) { 745 | lua_pushboolean(L, 0); 746 | return 1; 747 | } 748 | gdImagePngEx(im, fp, level); 749 | fclose(fp); 750 | lua_pushboolean(L, 1); 751 | return 1; 752 | } 753 | 754 | 755 | /* void *gdImagePngPtrEx(gdImagePtr im, int compression_level) */ 756 | static int LgdImagePngPtrEx(lua_State *L) { 757 | gdImagePtr im = getImagePtr(L, 1); 758 | int level = luaL_checkinteger(L, 2); 759 | char *str; 760 | int size; 761 | 762 | str = gdImagePngPtrEx(im, &size, level); 763 | if (str != NULL) { 764 | lua_pushlstring(L, str, size); 765 | gdFree(str); 766 | } else { 767 | lua_pushnil(L); /* Error */ 768 | } 769 | return 1; 770 | } 771 | #endif 772 | 773 | 774 | #ifdef GD_GIF 775 | /* gdImageGif (gdImagePtr im, FILE *out) */ 776 | /* Changed to: gd.gif (im, fname) */ 777 | static int LgdImageGif (lua_State *L) { 778 | gdImagePtr im = getImagePtr(L, 1); 779 | const char *fname = luaL_checkstring(L, 2); 780 | FILE *fp; 781 | 782 | if (fname == NULL) { 783 | lua_pushboolean(L, 0); 784 | return 1; 785 | } 786 | if ((fp = fopen(fname, "wb")) == NULL) { 787 | lua_pushboolean(L, 0); 788 | return 1; 789 | } 790 | gdImageGif (im, fp); 791 | fclose(fp); 792 | lua_pushboolean(L, 1); 793 | return 1; 794 | } 795 | #endif 796 | 797 | #ifdef GD_GIF 798 | /* void *gdImageGifPtr(gdImagePtr im) */ 799 | static int LgdImageGifPtr(lua_State *L) { 800 | gdImagePtr im = getImagePtr(L, 1); 801 | char *str; 802 | int size; 803 | 804 | str = gdImageGifPtr(im, &size); 805 | if (str != NULL) { 806 | lua_pushlstring(L, str, size); 807 | gdFree(str); 808 | } else { 809 | lua_pushnil(L); /* Error */ 810 | } 811 | return 1; 812 | } 813 | #endif 814 | 815 | 816 | /* gdImageGd(gdImagePtr im, FILE *out) */ 817 | /* Changed to: gd.gd(im, fname) */ 818 | static int LgdImageGd(lua_State *L) { 819 | gdImagePtr im = getImagePtr(L, 1); 820 | const char *fname = luaL_checkstring(L, 2); 821 | FILE *fp; 822 | 823 | if (fname == NULL) { 824 | lua_pushboolean(L, 0); 825 | return 1; 826 | } 827 | if ((fp = fopen(fname, "wb")) == NULL) { 828 | lua_pushboolean(L, 0); 829 | return 1; 830 | } 831 | gdImageGd(im, fp); 832 | fclose(fp); 833 | lua_pushboolean(L, 1); 834 | return 1; 835 | } 836 | 837 | 838 | /* void *gdImageGdPtr(gdImagePtr im) */ 839 | static int LgdImageGdPtr(lua_State *L) { 840 | gdImagePtr im = getImagePtr(L, 1); 841 | char *str; 842 | int size; 843 | 844 | str = gdImageGdPtr(im, &size); 845 | if (str != NULL) { 846 | lua_pushlstring(L, str, size); 847 | gdFree(str); 848 | } else { 849 | lua_pushnil(L); /* Error */ 850 | } 851 | return 1; 852 | } 853 | 854 | 855 | 856 | /* gdImageGd2(gdImagePtr im, FILE *out, int chunkSize, int fmt) */ 857 | /* Changed to: gd.gd2(im, fname, chunkSize, fmt) */ 858 | static int LgdImageGd2(lua_State *L) { 859 | gdImagePtr im = getImagePtr(L, 1); 860 | const char *fname = luaL_checkstring(L, 2); 861 | int cs = luaL_checkinteger(L, 3); 862 | int fmt = luaL_checkinteger(L, 4); 863 | FILE *fp; 864 | 865 | if (fname == NULL) { 866 | lua_pushboolean(L, 0); 867 | return 1; 868 | } 869 | if ((fp = fopen(fname, "wb")) == NULL) { 870 | lua_pushboolean(L, 0); 871 | return 1; 872 | } 873 | gdImageGd2(im, fp, cs, fmt); 874 | fclose(fp); 875 | lua_pushboolean(L, 1); 876 | return 1; 877 | } 878 | 879 | 880 | /* void* gdImageGd2Ptr(gdImagePtr im, int chunkSize, int fmt, int *size) */ 881 | static int LgdImageGd2Ptr(lua_State *L) { 882 | gdImagePtr im = getImagePtr(L, 1); 883 | int cs = luaL_checkinteger(L, 2); 884 | int fmt = luaL_checkinteger(L, 3); 885 | char *str; 886 | int size; 887 | 888 | str = gdImageGd2Ptr(im, cs, fmt, &size); 889 | if (str != NULL) { 890 | lua_pushlstring(L, str, size); 891 | gdFree(str); 892 | } else 893 | lua_pushnil(L); /* Error */ 894 | return 1; 895 | } 896 | 897 | 898 | /* void gdImageWBMP(gdImagePtr im, int fg, FILE *out) */ 899 | /* Changed to: gd.wbmp(im, int fg, filename) */ 900 | static int LgdImageWBMP(lua_State *L) { 901 | gdImagePtr im = getImagePtr(L, 1); 902 | int fg = luaL_checkinteger(L, 2); 903 | const char *fname = luaL_checkstring(L, 3); 904 | FILE *fp; 905 | 906 | if (fname == NULL) { 907 | lua_pushnil(L); 908 | return 1; 909 | } 910 | if ((fp = fopen(fname, "wb")) == NULL) { 911 | lua_pushnil(L); 912 | return 1; 913 | } 914 | gdImageWBMP(im, fg, fp); 915 | fclose(fp); 916 | lua_pushboolean(L, 1); 917 | return 1; 918 | } 919 | 920 | 921 | /* void* gdImageWBMPPtr(gdImagePtr im, int *size) */ 922 | static int LgdImageWBMPPtr(lua_State *L) { 923 | gdImagePtr im = getImagePtr(L, 1); 924 | int fg = luaL_checkinteger(L, 2); 925 | char *str; 926 | int size; 927 | 928 | str = gdImageWBMPPtr(im, &size, fg); 929 | if (str != NULL) { 930 | lua_pushlstring(L, str, size); 931 | gdFree(str); 932 | } else { 933 | lua_pushnil(L); /* Error */ 934 | } 935 | return 1; 936 | } 937 | 938 | 939 | /* int gdImageColorAllocate(gdImagePtr im, int r, int g, int b) */ 940 | static int LgdImageColorAllocate(lua_State *L) { 941 | gdImagePtr im = getImagePtr(L, 1); 942 | int r = luaL_checkinteger(L, 2); 943 | int g = luaL_checkinteger(L, 3); 944 | int b = luaL_checkinteger(L, 4); 945 | int c; 946 | 947 | c = gdImageColorAllocate(im, r, g, b); 948 | if (c >= 0) 949 | lua_pushnumber(L, c); /* ok */ 950 | else 951 | lua_pushnil(L); /* Can not allocate color */ 952 | return 1; 953 | } 954 | 955 | 956 | /* int gdImageColorAllocateAlpha(gdImagePtr im, int r, int g, int b, int a) */ 957 | static int LgdImageColorAllocateAlpha(lua_State *L) { 958 | gdImagePtr im = getImagePtr(L, 1); 959 | int r = luaL_checkinteger(L, 2); 960 | int g = luaL_checkinteger(L, 3); 961 | int b = luaL_checkinteger(L, 4); 962 | int a = luaL_checkinteger(L, 5); 963 | int c; 964 | 965 | c = gdImageColorAllocateAlpha(im, r, g, b, a); 966 | if (c >= 0) 967 | lua_pushnumber(L, c); /* ok */ 968 | else 969 | lua_pushnil(L); /* Can not allocate color */ 970 | return 1; 971 | } 972 | 973 | 974 | /* int gdImageColorClosest(gdImagePtr im, int r, int g, int b) */ 975 | static int LgdImageColorClosest(lua_State *L) { 976 | gdImagePtr im = getImagePtr(L, 1); 977 | int r = luaL_checkinteger(L, 2); 978 | int g = luaL_checkinteger(L, 3); 979 | int b = luaL_checkinteger(L, 4); 980 | int c; 981 | 982 | c = gdImageColorClosest(im, r, g, b); 983 | if (c >= 0) 984 | lua_pushnumber(L, c); /* ok */ 985 | else 986 | lua_pushnil(L); /* Can not allocate color */ 987 | return 1; 988 | } 989 | 990 | 991 | /* int gdImageColorClosestAlpha(gdImagePtr im, int r, int g, int b, int a) */ 992 | static int LgdImageColorClosestAlpha(lua_State *L) { 993 | gdImagePtr im = getImagePtr(L, 1); 994 | int r = luaL_checkinteger(L, 2); 995 | int g = luaL_checkinteger(L, 3); 996 | int b = luaL_checkinteger(L, 4); 997 | int a = luaL_checkinteger(L, 5); 998 | int c; 999 | 1000 | c = gdImageColorClosestAlpha(im, r, g, b, a); 1001 | if (c > 0) 1002 | lua_pushnumber(L, c); /* ok */ 1003 | else 1004 | lua_pushnil(L); /* Can not allocate color */ 1005 | return 1; 1006 | } 1007 | 1008 | 1009 | /* int gdImageColorClosestHWB(gdImagePtr im, int r, int g, int b) */ 1010 | static int LgdImageColorClosestHWB(lua_State *L) { 1011 | gdImagePtr im = getImagePtr(L, 1); 1012 | int r = luaL_checkinteger(L, 2); 1013 | int g = luaL_checkinteger(L, 3); 1014 | int b = luaL_checkinteger(L, 4); 1015 | int c; 1016 | 1017 | c = gdImageColorClosestHWB(im, r, g, b); 1018 | if (c >= 0) 1019 | lua_pushnumber(L, c); /* ok */ 1020 | else 1021 | lua_pushnil(L); /* Can not allocate color */ 1022 | return 1; 1023 | } 1024 | 1025 | 1026 | /* int gdImageColorExact(gdImagePtr im, int r, int g, int b) */ 1027 | static int LgdImageColorExact(lua_State *L) { 1028 | gdImagePtr im = getImagePtr(L, 1); 1029 | int r = luaL_checkinteger(L, 2); 1030 | int g = luaL_checkinteger(L, 3); 1031 | int b = luaL_checkinteger(L, 4); 1032 | int c; 1033 | 1034 | c = gdImageColorExact(im, r, g, b); 1035 | if (c >= 0) 1036 | lua_pushnumber(L, c); /* ok */ 1037 | else 1038 | lua_pushnil(L); /* Can not allocate color */ 1039 | return 1; 1040 | } 1041 | 1042 | 1043 | /* int gdImageColorExactAlpha(gdImagePtr im, int r, int g, int b, int a) */ 1044 | static int LgdImageColorExactAlpha(lua_State *L) { 1045 | gdImagePtr im = getImagePtr(L, 1); 1046 | int r = luaL_checkinteger(L, 2); 1047 | int g = luaL_checkinteger(L, 3); 1048 | int b = luaL_checkinteger(L, 4); 1049 | int a = luaL_checkinteger(L, 5); 1050 | int c; 1051 | 1052 | c = gdImageColorExactAlpha(im, r, g, b, a); 1053 | if (c >= 0) 1054 | lua_pushnumber(L, c); /* ok */ 1055 | else 1056 | lua_pushnil(L); /* Can not allocate color */ 1057 | return 1; 1058 | } 1059 | 1060 | 1061 | /* int gdImageColorResolve(gdImagePtr im, int r, int g, int b) */ 1062 | static int LgdImageColorResolve(lua_State *L) { 1063 | gdImagePtr im = getImagePtr(L, 1); 1064 | int r = luaL_checkinteger(L, 2); 1065 | int g = luaL_checkinteger(L, 3); 1066 | int b = luaL_checkinteger(L, 4); 1067 | int c; 1068 | 1069 | c = gdImageColorResolve(im, r, g, b); 1070 | if (c >= 0) 1071 | lua_pushnumber(L, c); /* ok */ 1072 | else 1073 | lua_pushnil(L); /* Can not allocate color */ 1074 | return 1; 1075 | } 1076 | 1077 | 1078 | /* int gdImageColorResolveAlpha(gdImagePtr im, int r, int g, int b, int a) */ 1079 | static int LgdImageColorResolveAlpha(lua_State *L) { 1080 | gdImagePtr im = getImagePtr(L, 1); 1081 | int r = luaL_checkinteger(L, 2); 1082 | int g = luaL_checkinteger(L, 3); 1083 | int b = luaL_checkinteger(L, 4); 1084 | int a = luaL_checkinteger(L, 5); 1085 | int c; 1086 | 1087 | c = gdImageColorResolveAlpha(im, r, g, b, a); 1088 | if (c >= 0) 1089 | lua_pushnumber(L, c); /* ok */ 1090 | else 1091 | lua_pushnil(L); /* Can not allocate color */ 1092 | return 1; 1093 | } 1094 | 1095 | 1096 | /* int gdImageColorsTotal(gdImagePtr im) */ 1097 | static int LgdImageColorsTotal(lua_State *L) { 1098 | gdImagePtr im = getImagePtr(L, 1); 1099 | 1100 | lua_pushnumber(L, gdImageColorsTotal(im)); /* ok */ 1101 | return 1; 1102 | } 1103 | 1104 | 1105 | /* int gdImageRed(gdImagePtr im, int c) */ 1106 | static int LgdImageRed(lua_State *L) { 1107 | gdImagePtr im = getImagePtr(L, 1); 1108 | int c = luaL_checkinteger(L, 2); 1109 | 1110 | lua_pushnumber(L, gdImageRed(im, c)); /* ok */ 1111 | return 1; 1112 | } 1113 | 1114 | /* int gdImageBlue(gdImagePtr im, int c) */ 1115 | static int LgdImageBlue(lua_State *L) { 1116 | gdImagePtr im = getImagePtr(L, 1); 1117 | int c = luaL_checkinteger(L, 2); 1118 | 1119 | lua_pushnumber(L, gdImageBlue(im, c)); /* ok */ 1120 | return 1; 1121 | } 1122 | 1123 | /* int gdImageBlue(gdImagePtr im, int c) */ 1124 | static int LgdImageGreen(lua_State *L) { 1125 | gdImagePtr im = getImagePtr(L, 1); 1126 | int c = luaL_checkinteger(L, 2); 1127 | 1128 | lua_pushnumber(L, gdImageGreen(im, c)); /* ok */ 1129 | return 1; 1130 | } 1131 | 1132 | /* int gdImageAlpha(gdImagePtr im, int color) */ 1133 | static int LgdImageAlpha(lua_State *L) { 1134 | gdImagePtr im = getImagePtr(L, 1); 1135 | int c = luaL_checkinteger(L, 2); 1136 | lua_pushnumber(L, gdImageAlpha(im, c)); 1137 | return 1; 1138 | } 1139 | 1140 | /* int gdImageGetInterlaced(gdImagePtr im) */ 1141 | static int LgdImageGetInterlaced(lua_State *L) { 1142 | gdImagePtr im = getImagePtr(L, 1); 1143 | int ret = gdImageGetInterlaced(im); 1144 | 1145 | if (ret != 0) 1146 | lua_pushnumber(L, ret); 1147 | else 1148 | lua_pushnil(L); 1149 | return 1; 1150 | } 1151 | 1152 | /* int gdImageGetTransparent(gdImagePtr im) */ 1153 | static int LgdImageGetTransparent(lua_State *L) { 1154 | gdImagePtr im = getImagePtr(L, 1); 1155 | int ret = gdImageGetTransparent(im); 1156 | 1157 | if (ret != -1) 1158 | lua_pushnumber(L, ret); 1159 | else 1160 | lua_pushnil(L); 1161 | return 1; 1162 | } 1163 | 1164 | 1165 | /* void gdImageColorTransparent(gdImagePtr im, int c) */ 1166 | static int LgdImageColorTransparent(lua_State *L) { 1167 | gdImagePtr im = getImagePtr(L, 1); 1168 | int c = -1; 1169 | if (!lua_isnil(L, 2)) 1170 | c = luaL_checkinteger(L, 2); 1171 | gdImageColorTransparent(im, c); 1172 | return 0; 1173 | } 1174 | 1175 | 1176 | /* void gdImageColorDeallocate(gdImagePtr im, int c) */ 1177 | static int LgdImageColorDeallocate(lua_State *L) { 1178 | gdImagePtr im = getImagePtr(L, 1); 1179 | int c = luaL_checkinteger(L, 2); 1180 | gdImageColorDeallocate(im, c); 1181 | return 0; 1182 | } 1183 | 1184 | 1185 | /* int gdImageSX(gdImagePtr im) */ 1186 | static int LgdImageSX(lua_State *L) { 1187 | gdImagePtr im = getImagePtr(L, 1); 1188 | lua_pushnumber(L, gdImageSX(im)); 1189 | return 1; 1190 | } 1191 | 1192 | 1193 | /* int gdImageSY(gdImagePtr im) */ 1194 | static int LgdImageSY(lua_State *L) { 1195 | gdImagePtr im = getImagePtr(L, 1); 1196 | lua_pushnumber(L, gdImageSY(im)); 1197 | return 1; 1198 | } 1199 | 1200 | 1201 | /* Fear the power of the Moon!! --- x, y = im:sizeXY() */ 1202 | static int LgdImageSXY(lua_State *L) { 1203 | gdImagePtr im = getImagePtr(L, 1); 1204 | lua_pushnumber(L, gdImageSX(im)); 1205 | lua_pushnumber(L, gdImageSY(im)); 1206 | return 2; 1207 | } 1208 | 1209 | 1210 | /* int gdImageBoundsSafe(gdImagePtr im, int x, int y) */ 1211 | static int LgdImageBoundsSafe(lua_State *L) { 1212 | gdImagePtr im = getImagePtr(L, 1); 1213 | int x = luaL_checkinteger(L, 2); 1214 | int y = luaL_checkinteger(L, 3); 1215 | 1216 | if (gdImageBoundsSafe(im, x, y) != 0) 1217 | lua_pushboolean(L, 1); 1218 | else 1219 | lua_pushboolean(L, 0); 1220 | return 1; 1221 | } 1222 | 1223 | 1224 | /* int gdImageGetPixel(gdImagePtr im, int x, int y) */ 1225 | static int LgdImageGetPixel(lua_State *L) { 1226 | gdImagePtr im = getImagePtr(L, 1); 1227 | int x = luaL_checkinteger(L, 2); 1228 | int y = luaL_checkinteger(L, 3); 1229 | 1230 | lua_pushnumber(L, gdImageGetPixel(im, x, y)); 1231 | return 1; 1232 | } 1233 | 1234 | 1235 | /* void gdImageSetPixel(gdImagePtr im, int x, int y, int color) */ 1236 | static int LgdImageSetPixel(lua_State *L) { 1237 | gdImagePtr im = getImagePtr(L, 1); 1238 | int x = luaL_checkinteger(L, 2); 1239 | int y = luaL_checkinteger(L, 3); 1240 | int c = luaL_checkinteger(L, 4); 1241 | 1242 | gdImageSetPixel(im, x, y, c); 1243 | return 0; 1244 | } 1245 | 1246 | 1247 | /* void gdImageLine(gdImagePtr im, int x1, int y1, int x2, int y2, int c) */ 1248 | static int LgdImageLine(lua_State *L) { 1249 | gdImagePtr im = getImagePtr(L, 1); 1250 | int x1 = luaL_checkinteger(L, 2); 1251 | int y1 = luaL_checkinteger(L, 3); 1252 | int x2 = luaL_checkinteger(L, 4); 1253 | int y2 = luaL_checkinteger(L, 5); 1254 | int c = luaL_checkinteger(L, 6); 1255 | 1256 | gdImageLine(im, x1, y1, x2, y2, c); 1257 | return 0; 1258 | } 1259 | 1260 | /* void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, 1261 | int c) */ 1262 | static int LgdImageRectangle(lua_State *L) { 1263 | gdImagePtr im = getImagePtr(L, 1); 1264 | int x1 = luaL_checkinteger(L, 2); 1265 | int y1 = luaL_checkinteger(L, 3); 1266 | int x2 = luaL_checkinteger(L, 4); 1267 | int y2 = luaL_checkinteger(L, 5); 1268 | int c = luaL_checkinteger(L, 6); 1269 | 1270 | gdImageRectangle(im, x1, y1, x2, y2, c); 1271 | return 0; 1272 | } 1273 | 1274 | 1275 | /* void gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, 1276 | int c) */ 1277 | static int LgdImageFilledRectangle(lua_State *L) { 1278 | gdImagePtr im = getImagePtr(L, 1); 1279 | int x1 = luaL_checkinteger(L, 2); 1280 | int y1 = luaL_checkinteger(L, 3); 1281 | int x2 = luaL_checkinteger(L, 4); 1282 | int y2 = luaL_checkinteger(L, 5); 1283 | int c = luaL_checkinteger(L, 6); 1284 | 1285 | gdImageFilledRectangle(im, x1, y1, x2, y2, c); 1286 | return 0; 1287 | } 1288 | 1289 | 1290 | /* Stack must have ONLY the table of points */ 1291 | static gdPoint *getPointList(lua_State *L, int *size) { 1292 | gdPoint *plist; 1293 | int i; 1294 | 1295 | luaL_checktype(L, -1, LUA_TTABLE); 1296 | *size = lua_rawlen(L, -1); 1297 | plist = (gdPoint*) malloc(*size * sizeof(gdPoint)); 1298 | 1299 | for (i = 0; i < *size; i++) { 1300 | /* Stack: T */ 1301 | lua_rawgeti(L, 1, i + 1); 1302 | 1303 | /* Stack: T, T' */ 1304 | if (lua_type(L, 2) != LUA_TTABLE) { 1305 | free(plist); 1306 | typerror(L, 2, "Point"); 1307 | } 1308 | 1309 | lua_rawgeti(L, 2, 1); 1310 | /* Stack: T, T', X */ 1311 | plist[i].x = luaL_checkinteger(L, -1); 1312 | lua_remove(L, -1); 1313 | 1314 | lua_rawgeti(L, 2, 2); 1315 | /* Stack: T, T', Y */ 1316 | plist[i].y = luaL_checkinteger(L, -1); 1317 | lua_remove(L, -1); 1318 | 1319 | /* Stack: T, T' */ 1320 | lua_remove(L, -1); 1321 | 1322 | /* Stack: T */ 1323 | } 1324 | 1325 | lua_remove(L, -1); 1326 | return plist; 1327 | } 1328 | 1329 | 1330 | 1331 | /* void gdImagePolygon(gdImagePtr im, gdPointPtr points, int pointsTotal, 1332 | int color) 1333 | Changed to: gd.polygon(im, { { x1, y1 }, { x2, y2 } ... }, color) */ 1334 | static int LgdImagePolygon(lua_State *L) { 1335 | gdImagePtr im = getImagePtr(L, 1); 1336 | gdPoint *plist; 1337 | int size; 1338 | int c; 1339 | 1340 | c = luaL_checkinteger(L, 3); 1341 | lua_remove(L, 3); /* Get and drop color */ 1342 | lua_remove(L, 1); /* Drop image from the stack */ 1343 | plist = getPointList(L, &size); 1344 | gdImagePolygon(im, plist, size, c); 1345 | free(plist); 1346 | return 0; 1347 | } 1348 | 1349 | 1350 | 1351 | /* void gdImageFilledPolygon(gdImagePtr im, gdPointPtr points, 1352 | int pointsTotal, int color) 1353 | Changed to: gd.filledPolygon(im, { { x1, y1 }, { x2, y2 } ... }, color) */ 1354 | static int LgdImageFilledPolygon(lua_State *L) { 1355 | gdImagePtr im = getImagePtr(L, 1); 1356 | gdPoint *plist; 1357 | int size; 1358 | int c; 1359 | 1360 | c = luaL_checkinteger(L, 3); 1361 | lua_remove(L, 3); /* Get and drop color */ 1362 | lua_remove(L, 1); /* Drop image from the stack */ 1363 | 1364 | plist = getPointList(L, &size); 1365 | gdImageFilledPolygon(im, plist, size, c); 1366 | free(plist); 1367 | return 0; 1368 | } 1369 | 1370 | 1371 | /* void gdImageOpenPolygon(gdImagePtr im, gdPointPtr points, 1372 | int pointsTotal, int color) 1373 | Changed to: gd.openPolygon(im, { { x1, y1 }, { x2, y2 } ... }, color) */ 1374 | static int LgdImageOpenPolygon(lua_State *L) { 1375 | gdImagePtr im = getImagePtr(L, 1); 1376 | gdPoint *plist; 1377 | int size; 1378 | int c; 1379 | 1380 | c = luaL_checkinteger(L, 3); 1381 | lua_remove(L, 3); /* Get and drop color */ 1382 | lua_remove(L, 1); /* Drop image from the stack */ 1383 | 1384 | plist = getPointList(L, &size); 1385 | gdImageOpenPolygon(im, plist, size, c); 1386 | free(plist); 1387 | return 0; 1388 | } 1389 | 1390 | 1391 | 1392 | /* void gdImageArc(gdImagePtr im, int cx, int cy, int w, int h, int s, int e, 1393 | int color) */ 1394 | static int LgdImageArc(lua_State *L) { 1395 | gdImagePtr im = getImagePtr(L, 1); 1396 | int cx = luaL_checkinteger(L, 2); 1397 | int cy = luaL_checkinteger(L, 3); 1398 | int w = luaL_checkinteger(L, 4); 1399 | int h = luaL_checkinteger(L, 5); 1400 | int s = luaL_checkinteger(L, 6); 1401 | int e = luaL_checkinteger(L, 7); 1402 | int c = luaL_checkinteger(L, 8); 1403 | 1404 | gdImageArc(im, cx, cy, w, h, s, e, c); 1405 | return 0; 1406 | } 1407 | 1408 | 1409 | /* void gdImageFilledArc(gdImagePtr im, int cx, int cy, int w, int h, 1410 | int s, int e, int color, int style) */ 1411 | static int LgdImageFilledArc(lua_State *L) { 1412 | gdImagePtr im = getImagePtr(L, 1); 1413 | int cx = luaL_checkinteger(L, 2); 1414 | int cy = luaL_checkinteger(L, 3); 1415 | int w = luaL_checkinteger(L, 4); 1416 | int h = luaL_checkinteger(L, 5); 1417 | int s = luaL_checkinteger(L, 6); 1418 | int e = luaL_checkinteger(L, 7); 1419 | int c = luaL_checkinteger(L, 8); 1420 | int sty = luaL_checkinteger(L, 9); 1421 | 1422 | gdImageFilledArc(im, cx, cy, w, h, s, e, c, sty); 1423 | return 0; 1424 | } 1425 | 1426 | 1427 | /* void gdImageFilledEllipse(gdImagePtr im, int cx, int cy, int w, int h, 1428 | int color) */ 1429 | static int LgdImageFilledEllipse(lua_State *L) { 1430 | gdImagePtr im = getImagePtr(L, 1); 1431 | int cx = luaL_checkinteger(L, 2); 1432 | int cy = luaL_checkinteger(L, 3); 1433 | int w = luaL_checkinteger(L, 4); 1434 | int h = luaL_checkinteger(L, 5); 1435 | int c = luaL_checkinteger(L, 6); 1436 | 1437 | gdImageFilledEllipse(im, cx, cy, w, h, c); 1438 | return 0; 1439 | } 1440 | 1441 | 1442 | /* void gdImageFill(gdImagePtr im, int x, int y, int color) */ 1443 | static int LgdImageFill(lua_State *L) { 1444 | gdImagePtr im = getImagePtr(L, 1); 1445 | int x = luaL_checkinteger(L, 2); 1446 | int y = luaL_checkinteger(L, 3); 1447 | int c = luaL_checkinteger(L, 4); 1448 | 1449 | gdImageFill(im, x, y, c); 1450 | return 0; 1451 | } 1452 | 1453 | 1454 | /* void gdImageFillToBorder(gdImagePtr im, int x, int y, int border, 1455 | int color) */ 1456 | static int LgdImageFillToBorder(lua_State *L) { 1457 | gdImagePtr im = getImagePtr(L, 1); 1458 | int x = luaL_checkinteger(L, 2); 1459 | int y = luaL_checkinteger(L, 3); 1460 | int b = luaL_checkinteger(L, 4); 1461 | int c = luaL_checkinteger(L, 5); 1462 | 1463 | gdImageFillToBorder(im, x, y, b, c); 1464 | return 0; 1465 | } 1466 | 1467 | 1468 | /* void gdImageSetAntiAliased(gdImagePtr im, int c) */ 1469 | static int LgdImageSetAntiAliased(lua_State *L) { 1470 | gdImagePtr im = getImagePtr(L, 1); 1471 | int c = luaL_checkinteger(L, 2); 1472 | 1473 | gdImageSetAntiAliased(im, c); 1474 | return 0; 1475 | } 1476 | 1477 | 1478 | /* void gdImageSetAntiAliasedDontBlend(gdImagePtr im, int c) */ 1479 | static int LgdImageSetAntiAliasedDontBlend(lua_State *L) { 1480 | gdImagePtr im = getImagePtr(L, 1); 1481 | int c = luaL_checkinteger(L, 2); 1482 | 1483 | gdImageSetAntiAliasedDontBlend(im, c, 1); 1484 | return 0; 1485 | } 1486 | 1487 | 1488 | /* void gdImageSetBrush(gdImagePtr im, gdImagePtr brush) */ 1489 | static int LgdImageSetBrush(lua_State *L) { 1490 | gdImagePtr im = getImagePtr(L, 1); 1491 | gdImagePtr b = getImagePtr(L, 2); 1492 | 1493 | gdImageSetBrush(im, b); 1494 | return 0; 1495 | } 1496 | 1497 | 1498 | /* void gdImageSetTile(gdImagePtr im, gdImagePtr tile) */ 1499 | static int LgdImageSetTile(lua_State *L) { 1500 | gdImagePtr im = getImagePtr(L, 1); 1501 | gdImagePtr t = getImagePtr(L, 1); 1502 | 1503 | gdImageSetTile(im, t); 1504 | return 0; 1505 | } 1506 | 1507 | 1508 | /* void gdImageSetStyle(gdImagePtr im, int *style, int styleLength) */ 1509 | /* Changed To: gd.setStyle(im, { c1, c2, c3, ... } ) */ 1510 | static int LgdImageSetStyle(lua_State *L) { 1511 | gdImagePtr im = getImagePtr(L, 1); 1512 | int *slist; 1513 | int size; 1514 | int i; 1515 | 1516 | /* Stack: Im, T */ 1517 | luaL_checktype(L, -1, LUA_TTABLE); 1518 | size = lua_rawlen(L, -1); 1519 | slist = (int*) malloc(size * sizeof(int)); 1520 | 1521 | for (i = 0; i < size; i++) { 1522 | /* Stack: Im, T */ 1523 | lua_rawgeti(L, 2, i + 1); 1524 | 1525 | /* Stack: Im, T, num */ 1526 | if (lua_type(L, -1) != LUA_TNUMBER) { 1527 | free(slist); 1528 | typerror(L, -1, "Number"); 1529 | } 1530 | 1531 | slist[i] = luaL_checkinteger(L, -1); 1532 | lua_remove(L, -1); 1533 | 1534 | /* Stack: Im, T */ 1535 | } 1536 | 1537 | gdImageSetStyle(im, slist, size); 1538 | free(slist); 1539 | return 0; 1540 | } 1541 | 1542 | 1543 | /* void gdImageSetThickness(gdImagePtr im, int thickness) */ 1544 | static int LgdImageSetThickness(lua_State *L) { 1545 | gdImagePtr im = getImagePtr(L, 1); 1546 | int t = luaL_checkinteger(L, 2); 1547 | 1548 | gdImageSetThickness(im, t); 1549 | return 0; 1550 | } 1551 | 1552 | 1553 | /* void gdImageAlphaBlending(gdImagePtr im, int blending) */ 1554 | /* Changed to: im:alphaBlending(true_or_false) */ 1555 | static int LgdImageAlphaBlending(lua_State *L) { 1556 | gdImagePtr im = getImagePtr(L, 1); 1557 | int b = lua_toboolean(L, 2); 1558 | 1559 | gdImageAlphaBlending(im, b); 1560 | return 0; 1561 | } 1562 | 1563 | 1564 | /* void gdImageSaveAlpha(gdImagePtr im, int saveFlag) */ 1565 | /* Changed to: im:saveAlpha(true_or_false) */ 1566 | static int LgdImageSaveAlpha(lua_State *L) { 1567 | gdImagePtr im = getImagePtr(L, 1); 1568 | int b = lua_toboolean(L, 2); 1569 | 1570 | gdImageSaveAlpha(im, b); 1571 | return 0; 1572 | } 1573 | 1574 | 1575 | /* gdImageInterlace(gdImagePtr im, int interlace) */ 1576 | /* Changed to: im:interlace(true_or_false) */ 1577 | static int LgdImageInterlace(lua_State *L) { 1578 | gdImagePtr im = getImagePtr(L, 1); 1579 | int i = lua_toboolean(L, 2); 1580 | 1581 | gdImageInterlace(im, i); 1582 | return 0; 1583 | } 1584 | 1585 | 1586 | /* void gdImageString(gdImagePtr im, gdFontPtr font, int x, int y, 1587 | unsigned char *s, int color) */ 1588 | static int LgdImageString(lua_State *L) { 1589 | gdImagePtr im = getImagePtr(L, 1); 1590 | gdFontPtr fnt = getStdFont(L, 2); 1591 | int x = luaL_checkinteger(L, 3); 1592 | int y = luaL_checkinteger(L, 4); 1593 | unsigned char *str = (unsigned char*) luaL_checkstring(L, 5); 1594 | int c = luaL_checkinteger(L, 6); 1595 | 1596 | gdImageString(im, fnt, x, y, str, c); 1597 | return 0; 1598 | } 1599 | 1600 | 1601 | /* void gdImageStringUp(gdImagePtr im, gdFontPtr font, int x, int y, 1602 | unsigned char *s, int color) */ 1603 | static int LgdImageStringUp(lua_State *L) { 1604 | gdImagePtr im = getImagePtr(L, 1); 1605 | gdFontPtr fnt = getStdFont(L, 2); 1606 | int x = luaL_checkinteger(L, 3); 1607 | int y = luaL_checkinteger(L, 4); 1608 | unsigned char *str = (unsigned char*) luaL_checkstring(L, 5); 1609 | int c = luaL_checkinteger(L, 6); 1610 | 1611 | gdImageStringUp(im, fnt, x, y, str, c); 1612 | return 0; 1613 | } 1614 | 1615 | 1616 | /* void gdImageChar(gdImagePtr im, gdFontPtr font, int x, int y, 1617 | int c, int color) */ 1618 | /* Useless? */ 1619 | static int LgdImageChar(lua_State *L) { 1620 | gdImagePtr im = getImagePtr(L, 1); 1621 | gdFontPtr fnt = getStdFont(L, 2); 1622 | int x = luaL_checkinteger(L, 3); 1623 | int y = luaL_checkinteger(L, 4); 1624 | char *str = (char*) luaL_checkstring(L, 5); 1625 | int c = luaL_checkinteger(L, 6); 1626 | int chr; 1627 | 1628 | if (str) { 1629 | chr = (int) str[0]; 1630 | } else { 1631 | typerror(L, 5, "string"); 1632 | return 0; 1633 | } 1634 | 1635 | gdImageChar(im, fnt, x, y, chr, c); 1636 | return 0; 1637 | } 1638 | 1639 | 1640 | /* void gdImageCharUp(gdImagePtr im, gdFontPtr font, int x, int y, 1641 | int c, int color) */ 1642 | static int LgdImageCharUp(lua_State *L) { 1643 | gdImagePtr im = getImagePtr(L, 1); 1644 | gdFontPtr fnt = getStdFont(L, 2); 1645 | int x = luaL_checkinteger(L, 3); 1646 | int y = luaL_checkinteger(L, 4); 1647 | char *str = (char*) luaL_checkstring(L, 5); 1648 | int c = luaL_checkinteger(L, 6); 1649 | int chr; 1650 | 1651 | if (str) 1652 | chr = (int) str[0]; 1653 | else { 1654 | typerror(L, 5, "string"); 1655 | return 0; 1656 | } 1657 | 1658 | gdImageCharUp(im, fnt, x, y, chr, c); 1659 | return 0; 1660 | } 1661 | 1662 | 1663 | /* void gdImageCopy(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, 1664 | int srcX, int srcY, int w, int h) */ 1665 | static int LgdImageCopy(lua_State *L) { 1666 | gdImagePtr dst = getImagePtr(L, 1); 1667 | gdImagePtr src = getImagePtr(L, 2); 1668 | int dstX = luaL_checkinteger(L, 3); 1669 | int dstY = luaL_checkinteger(L, 4); 1670 | int srcX = luaL_checkinteger(L, 5); 1671 | int srcY = luaL_checkinteger(L, 6); 1672 | int w = luaL_checkinteger(L, 7); 1673 | int h = luaL_checkinteger(L, 8); 1674 | 1675 | gdImageCopy(dst, src, dstX, dstY, srcX, srcY, w, h); 1676 | return 0; 1677 | } 1678 | 1679 | 1680 | 1681 | /* void gdImageCopyResized(gdImagePtr dst, gdImagePtr src, int dstX, 1682 | int dstY, int srcX, int srcY, int destW, int destH, 1683 | int srcW, int srcH) */ 1684 | static int LgdImageCopyResized(lua_State *L) { 1685 | gdImagePtr dst = getImagePtr(L, 1); 1686 | gdImagePtr src = getImagePtr(L, 2); 1687 | int dstX = luaL_checkinteger(L, 3); 1688 | int dstY = luaL_checkinteger(L, 4); 1689 | int srcX = luaL_checkinteger(L, 5); 1690 | int srcY = luaL_checkinteger(L, 6); 1691 | int dstW = luaL_checkinteger(L, 7); 1692 | int dstH = luaL_checkinteger(L, 8); 1693 | int srcW = luaL_checkinteger(L, 9); 1694 | int srcH = luaL_checkinteger(L, 10); 1695 | 1696 | gdImageCopyResized(dst, src, dstX, dstY, srcX, srcY, dstW, dstH, 1697 | srcW, srcH); 1698 | return 0; 1699 | } 1700 | 1701 | 1702 | /* void gdImageCopyResampled(gdImagePtr dst, gdImagePtr src, int dstX, 1703 | int dstY, int srcX, int srcY, int destW, int destH, int srcW, 1704 | int srcH) */ 1705 | static int LgdImageCopyResampled(lua_State *L) { 1706 | gdImagePtr dst = getImagePtr(L, 1); 1707 | gdImagePtr src = getImagePtr(L, 2); 1708 | int dstX = luaL_checkinteger(L, 3); 1709 | int dstY = luaL_checkinteger(L, 4); 1710 | int srcX = luaL_checkinteger(L, 5); 1711 | int srcY = luaL_checkinteger(L, 6); 1712 | int dstW = luaL_checkinteger(L, 7); 1713 | int dstH = luaL_checkinteger(L, 8); 1714 | int srcW = luaL_checkinteger(L, 9); 1715 | int srcH = luaL_checkinteger(L, 10); 1716 | 1717 | gdImageCopyResampled(dst, src, dstX, dstY, srcX, srcY, dstW, dstH, 1718 | srcW, srcH); 1719 | return 0; 1720 | } 1721 | 1722 | 1723 | /* void gdImageCopyRotated(gdImagePtr dst, gdImagePtr src, double dstX, 1724 | double dstY, int srcX, int srcY, int srcW, int srcH, int angle) */ 1725 | static int LgdImageCopyRotated(lua_State *L) { 1726 | gdImagePtr dst = getImagePtr(L, 1); 1727 | gdImagePtr src = getImagePtr(L, 2); 1728 | double dstX = (double) lua_tonumber(L, 3); 1729 | double dstY = (double) lua_tonumber(L, 4); 1730 | int srcX = luaL_checkinteger(L, 5); 1731 | int srcY = luaL_checkinteger(L, 6); 1732 | int srcW = luaL_checkinteger(L, 7); 1733 | int srcH = luaL_checkinteger(L, 8); 1734 | int ang = luaL_checkinteger(L, 9); 1735 | 1736 | gdImageCopyRotated(dst, src, dstX, dstY, srcX, srcY, srcW, srcH, ang); 1737 | return 0; 1738 | } 1739 | 1740 | 1741 | /* void gdImageCopyMerge(gdImagePtr dst, gdImagePtr src, int dstX, 1742 | int dstY, int srcX, int srcY, int w, int h, int pct) */ 1743 | static int LgdImageCopyMerge(lua_State *L) { 1744 | gdImagePtr dst = getImagePtr(L, 1); 1745 | gdImagePtr src = getImagePtr(L, 2); 1746 | int dstX = luaL_checkinteger(L, 3); 1747 | int dstY = luaL_checkinteger(L, 4); 1748 | int srcX = luaL_checkinteger(L, 5); 1749 | int srcY = luaL_checkinteger(L, 6); 1750 | int w = luaL_checkinteger(L, 7); 1751 | int h = luaL_checkinteger(L, 8); 1752 | int pct = luaL_checkinteger(L, 9); 1753 | 1754 | gdImageCopyMerge(dst, src, dstX, dstY, srcX, srcY, w, h, pct); 1755 | return 0; 1756 | } 1757 | 1758 | 1759 | /* void gdImageCopyMergeGray(gdImagePtr dst, gdImagePtr src, int dstX, 1760 | int dstY, int srcX, int srcY, int w, int h, int pct) */ 1761 | static int LgdImageCopyMergeGray(lua_State *L) { 1762 | gdImagePtr dst = getImagePtr(L, 1); 1763 | gdImagePtr src = getImagePtr(L, 2); 1764 | int dstX = luaL_checkinteger(L, 3); 1765 | int dstY = luaL_checkinteger(L, 4); 1766 | int srcX = luaL_checkinteger(L, 5); 1767 | int srcY = luaL_checkinteger(L, 6); 1768 | int w = luaL_checkinteger(L, 7); 1769 | int h = luaL_checkinteger(L, 8); 1770 | int pct = luaL_checkinteger(L, 9); 1771 | 1772 | gdImageCopyMergeGray(dst, src, dstX, dstY, srcX, srcY, w, h, pct); 1773 | return 0; 1774 | } 1775 | 1776 | 1777 | /* void gdImagePaletteCopy(gdImagePtr dst, gdImagePtr src) */ 1778 | static int LgdImagePaletteCopy(lua_State *L) { 1779 | gdImagePtr dst = getImagePtr(L, 1); 1780 | gdImagePtr src = getImagePtr(L, 2); 1781 | 1782 | gdImagePaletteCopy(dst, src); 1783 | return 0; 1784 | } 1785 | 1786 | 1787 | /* void gdImageSquareToCircle(gdImagePtr im, int radius) */ 1788 | static int LgdImageSquareToCircle(lua_State *L) { 1789 | gdImagePtr im = getImagePtr(L, 1); 1790 | int r = luaL_checkinteger(L, 2); 1791 | 1792 | gdImageSquareToCircle(im, r); 1793 | return 0; 1794 | } 1795 | 1796 | 1797 | /* void gdImageSharpen(gdImagePtr im, int pct) */ 1798 | static int LgdImageSharpen(lua_State *L) { 1799 | gdImagePtr im = getImagePtr(L, 1); 1800 | int pct = luaL_checkinteger(L, 2); 1801 | 1802 | gdImageSharpen(im, pct); 1803 | return 0; 1804 | } 1805 | 1806 | 1807 | /* void gdImageSetClip(gdImagePtr im, int x1, int y1, int x2, int y2) */ 1808 | static int LgdImageSetClip(lua_State *L) { 1809 | gdImagePtr im = getImagePtr(L, 1); 1810 | int x1 = luaL_checkinteger(L, 2); 1811 | int y1 = luaL_checkinteger(L, 3); 1812 | int x2 = luaL_checkinteger(L, 4); 1813 | int y2 = luaL_checkinteger(L, 5); 1814 | 1815 | gdImageSetClip(im, x1, y1, x2, y2); 1816 | return 0; 1817 | } 1818 | 1819 | 1820 | /* void gdImageGetClip(gdImagePtr im, int *x1, int *y1, int *x2, int *y2) */ 1821 | /* Changed to: x1p, y1p, x2p, y2p = im:getClip() */ 1822 | static int LgdImageGetClip(lua_State *L) { 1823 | gdImagePtr im = getImagePtr(L, 1); 1824 | int x1 = 0, y1 = 0, x2 = 0, y2 = 0; 1825 | 1826 | gdImageGetClip(im, &x1, &y1, &x2, &y2); 1827 | lua_pushnumber(L, x1); 1828 | lua_pushnumber(L, y1); 1829 | lua_pushnumber(L, x2); 1830 | lua_pushnumber(L, y2); 1831 | return 4; 1832 | } 1833 | 1834 | 1835 | #ifdef GD_FONTCONFIG 1836 | /* int gdFTUseFontConfig(int flag) */ 1837 | /* Changed to: gd.useFontConfig(true_or_false) */ 1838 | static int LgdFTUseFontConfig(lua_State *L) { 1839 | int b = lua_toboolean(L, 1); 1840 | lua_pushboolean(L, gdFTUseFontConfig(b)); 1841 | return 1; 1842 | } 1843 | #endif 1844 | 1845 | 1846 | #ifdef GD_FREETYPE 1847 | /* int gdFontCacheSetup(void) */ 1848 | static int LgdFontCacheSetup(lua_State *L) { 1849 | lua_pushboolean(L, !gdFontCacheSetup()); 1850 | return 1; 1851 | } 1852 | 1853 | 1854 | /* void gdFontCacheShutdown(void) */ 1855 | static int LgdFontCacheShutdown(lua_State *L) { 1856 | gdFontCacheShutdown(); 1857 | return 0; 1858 | } 1859 | #endif 1860 | 1861 | 1862 | /* char *gdImageStringFT(gdImagePtr im, int *brect, int fg, char *fontname, 1863 | double ptsize, double angle, int x, int y, char *string) 1864 | 1865 | Changed To: 1866 | llX, llY, lrX, lrY, urX, urY, ulX, ulY = im:stringFT(fg, fontname, 1867 | ptsize, angle, x, y, string) 1868 | 1869 | Or (to get the points only): 1870 | llX, llY, lrX, lrY, urX, urY, ulX, ulY = gd.stringFT(nil, fg, 1871 | fontname, ptsize, angle, x, y, string) 1872 | */ 1873 | 1874 | #ifdef GD_FREETYPE 1875 | static int LgdImageStringFT(lua_State *L) { 1876 | gdImagePtr im; 1877 | int fg = luaL_checkinteger(L, 2); 1878 | char *font = (char*) luaL_checkstring(L, 3); 1879 | double size = (double) lua_tonumber(L, 4); 1880 | double ang = (double) lua_tonumber(L, 5); 1881 | int x = luaL_checkinteger(L, 6); 1882 | int y = luaL_checkinteger(L, 7); 1883 | char *str = (char*) luaL_checkstring(L, 8); 1884 | int brect[8]; 1885 | 1886 | if (lua_isnil(L, 1)) 1887 | im = NULL; 1888 | else 1889 | im = getImagePtr(L, 1); 1890 | 1891 | if (gdImageStringFT(im, brect, fg, font, size, ang, x, y, str) == NULL) { 1892 | lua_pushnumber(L, brect[0]); 1893 | lua_pushnumber(L, brect[1]); 1894 | lua_pushnumber(L, brect[2]); 1895 | lua_pushnumber(L, brect[3]); 1896 | lua_pushnumber(L, brect[4]); 1897 | lua_pushnumber(L, brect[5]); 1898 | lua_pushnumber(L, brect[6]); 1899 | lua_pushnumber(L, brect[7]); 1900 | return 8; 1901 | } 1902 | 1903 | lua_pushnil(L); 1904 | return 1; 1905 | } 1906 | 1907 | 1908 | /* char *gdImageStringFT(gdImagePtr im, int *brect, int fg, char *fontname, 1909 | double ptsize, double angle, int x, int y, char *string) 1910 | 1911 | Changed To: 1912 | llX, llY, lrX, lrY, urX, urY, ulX, ulY [, xshow] [, fontpath] = 1913 | im:stringFTEx(fg, fontname, ptsize, angle, x, y, string, { ... }) 1914 | 1915 | Or: 1916 | llX, llY, lrX, lrY, urX, urY, ulX, ulY [, xshow] [, fontpath] = 1917 | gd.stringFTEx(nil, fg, fontname, ptsize, angle, x, y, string, { ... }) 1918 | 1919 | */ 1920 | 1921 | static int LgdImageStringFTEx(lua_State *L) { 1922 | gdImagePtr im; 1923 | int fg = luaL_checkinteger(L, 2); 1924 | char *font = (char*) luaL_checkstring(L, 3); 1925 | double size = (double) lua_tonumber(L, 4); 1926 | double ang = (double) lua_tonumber(L, 5); 1927 | int x = luaL_checkinteger(L, 6); 1928 | int y = luaL_checkinteger(L, 7); 1929 | char *str = (char*) luaL_checkstring(L, 8); 1930 | gdFTStringExtra *ex = getFTStringExtraPtr(L, 9); 1931 | int brect[8]; 1932 | int ret = 8; 1933 | 1934 | if (lua_isnil(L, 1)) 1935 | im = NULL; 1936 | else 1937 | im = getImagePtr(L, 1); 1938 | 1939 | if (gdImageStringFTEx(im, brect, fg, font, size, ang, x, y, str, ex) == NULL) { 1940 | lua_pushnumber(L, brect[0]); 1941 | lua_pushnumber(L, brect[1]); 1942 | lua_pushnumber(L, brect[2]); 1943 | lua_pushnumber(L, brect[3]); 1944 | lua_pushnumber(L, brect[4]); 1945 | lua_pushnumber(L, brect[5]); 1946 | lua_pushnumber(L, brect[6]); 1947 | lua_pushnumber(L, brect[7]); 1948 | ret = 8; 1949 | if (ex->flags & gdFTEX_XSHOW) { 1950 | lua_pushstring(L, ex->xshow); 1951 | gdFree(ex->xshow); 1952 | ret++; 1953 | } 1954 | if (ex->flags & gdFTEX_RETURNFONTPATHNAME) { 1955 | lua_pushstring(L, ex->fontpath); 1956 | gdFree(ex->fontpath); 1957 | ret++; 1958 | } 1959 | 1960 | free(ex); 1961 | return ret; 1962 | } 1963 | 1964 | lua_pushnil(L); 1965 | return 1; 1966 | } 1967 | 1968 | 1969 | 1970 | /* char *gdImageStringFTCircle(gdImagePtr im, int cx, int cy, double radius, 1971 | double textRadius, double fillPortion, char *font, 1972 | double points, char *top, char *bottom, int fgcolor) 1973 | 1974 | Changed to: im:stringFTCircle(cx, cy, radius, textRadius, 1975 | fillPortion, fontname, points, top, bottom, color) 1976 | */ 1977 | 1978 | static int LgdImageStringFTCircle(lua_State *L) { 1979 | gdImagePtr im = getImagePtr(L, 1); 1980 | int cx = luaL_checkinteger(L, 2); 1981 | int cy = luaL_checkinteger(L, 3); 1982 | double radius = (double) lua_tonumber(L, 4); 1983 | double textRadius = (double) lua_tonumber(L, 5); 1984 | double fillPortion = (double) lua_tonumber(L, 6); 1985 | char *font = (char*) luaL_checkstring(L, 7); 1986 | double points = (double) lua_tonumber(L, 8); 1987 | char *top = (char*) luaL_checkstring(L, 9); 1988 | char *bottom = (char*) luaL_checkstring(L, 10); 1989 | int color = luaL_checkinteger(L, 11); 1990 | 1991 | if (gdImageStringFTCircle(im, cx, cy, radius, textRadius, fillPortion, 1992 | font, points, top, bottom, color)) 1993 | lua_pushboolean(L, 0); /* Error */ 1994 | else 1995 | lua_pushboolean(L, 1); 1996 | return 1; 1997 | } 1998 | #endif 1999 | 2000 | 2001 | #ifdef GD_GIF 2002 | /* void gdImageGifAnimBegin(gdImagePtr im, FILE *out, int GlobalCM, int Loops) 2003 | Changed to: im:gifAnimBegin(filename, globalCM, loops) 2004 | */ 2005 | 2006 | static int LgdImageGifAnimBegin(lua_State *L) { 2007 | gdImagePtr im = getImagePtr(L, 1); 2008 | const char *fname = luaL_checkstring(L, 2); 2009 | int globalCM = lua_toboolean(L, 3); 2010 | int loops = luaL_checkinteger(L, 4); 2011 | FILE *fp; 2012 | 2013 | if ((fp = fopen(fname, "wb")) == NULL) { 2014 | lua_pushboolean(L, 0); /* Error */ 2015 | return 1; 2016 | } 2017 | 2018 | gdImageGifAnimBegin(im, fp, globalCM, loops); 2019 | fclose(fp); 2020 | lua_pushboolean(L, 1); /* ok */ 2021 | return 1; 2022 | } 2023 | 2024 | 2025 | /* void gdImageGifAnimAdd(gdImagePtr im, FILE *out, int LocalCM, int LeftOfs, 2026 | int TopOfs, int Delay, int Disposal, gdImagePtr previm) 2027 | Changed to: im:gifAnimAdd(filename, localCM, leftOfs, topOfs, delay, 2028 | disposal [, previm]) 2029 | */ 2030 | 2031 | static int LgdImageGifAnimAdd(lua_State *L) { 2032 | gdImagePtr im = getImagePtr(L, 1); 2033 | const char *fname = luaL_checkstring(L, 2); 2034 | int localCM = lua_toboolean(L, 3); 2035 | int leftOfs = luaL_checkinteger(L, 4); 2036 | int topOfs = luaL_checkinteger(L, 5); 2037 | int delay = luaL_checkinteger(L, 6); 2038 | int disp = luaL_checkinteger(L, 7); 2039 | gdImagePtr previm = NULL; 2040 | FILE *fp; 2041 | 2042 | if (lua_gettop(L) >= 8) 2043 | previm = getImagePtr(L, 8); 2044 | 2045 | if ((fp = fopen(fname, "ab")) == NULL) { 2046 | lua_pushboolean(L, 0); /* Error */ 2047 | return 1; 2048 | } 2049 | 2050 | gdImageGifAnimAdd(im, fp, localCM, leftOfs, topOfs, delay, disp, previm); 2051 | fclose(fp); 2052 | lua_pushboolean(L, 1); /* ok */ 2053 | return 1; 2054 | } 2055 | 2056 | 2057 | /* void gdImageGifAnimEnd(FILE *out) 2058 | Changed to: gd.gifAnimEnd(filename) 2059 | */ 2060 | 2061 | static int LgdImageGifAnimEnd(lua_State *L) { 2062 | const char *fname = luaL_checkstring(L, 1); 2063 | FILE *fp; 2064 | 2065 | if ((fp = fopen(fname, "ab")) == NULL) { 2066 | lua_pushboolean(L, 0); /* Error */ 2067 | return 1; 2068 | } 2069 | 2070 | gdImageGifAnimEnd(fp); 2071 | fclose(fp); 2072 | lua_pushboolean(L, 1); /* ok */ 2073 | return 1; 2074 | } 2075 | 2076 | 2077 | /* void* gdImageGifAnimBeginPtr(gdImagePtr im, int *size, int GlobalCM, 2078 | int Loops) 2079 | Changed to: im:gifAnimBeginStr(globalCM, loops) 2080 | */ 2081 | 2082 | static int LgdImageGifAnimBeginPtr(lua_State *L) { 2083 | gdImagePtr im = getImagePtr(L, 1); 2084 | int globalCM = lua_toboolean(L, 2); 2085 | int loops = luaL_checkinteger(L, 3); 2086 | char *str; 2087 | int size; 2088 | 2089 | str = gdImageGifAnimBeginPtr(im, &size, globalCM, loops); 2090 | if (str != NULL) { 2091 | lua_pushlstring(L, str, size); 2092 | gdFree(str); 2093 | } else 2094 | lua_pushnil(L); 2095 | return 1; 2096 | } 2097 | 2098 | 2099 | /* void* gdImageGifAnimAddPtr(gdImagePtr im, int *size, int LocalCM, 2100 | int LeftOfs, int TopOfs, int Delay, int Disposal, gdImagePtr previm) 2101 | 2102 | Changed to: im:gifAnimAddStr(localCM, leftOfs, topOfs, delay, 2103 | disposal [, previm]) 2104 | */ 2105 | 2106 | static int LgdImageGifAnimAddPtr(lua_State *L) { 2107 | gdImagePtr im = getImagePtr(L, 1); 2108 | int localCM = lua_toboolean(L, 2); 2109 | int leftOfs = luaL_checkinteger(L, 3); 2110 | int topOfs = luaL_checkinteger(L, 4); 2111 | int delay = luaL_checkinteger(L, 5); 2112 | int disp = luaL_checkinteger(L, 6); 2113 | gdImagePtr previm = NULL; 2114 | int size; 2115 | char *str; 2116 | 2117 | if (lua_gettop(L) >= 7) 2118 | previm = getImagePtr(L, 7); 2119 | 2120 | str = gdImageGifAnimAddPtr(im, &size, localCM, leftOfs, topOfs, delay, 2121 | disp, previm); 2122 | if (str != NULL) { 2123 | lua_pushlstring(L, str, size); 2124 | gdFree(str); 2125 | } else 2126 | lua_pushnil(L); 2127 | return 1; 2128 | } 2129 | 2130 | 2131 | /* void* gdImageGifAnimEndPtr(int *size) 2132 | Changed to: gd.gifAnimEndStr() 2133 | */ 2134 | 2135 | static int LgdImageGifAnimEndPtr(lua_State *L) { 2136 | int size; 2137 | char *str; 2138 | 2139 | str = gdImageGifAnimEndPtr(&size); 2140 | if (str != NULL) { 2141 | lua_pushlstring(L, str, size); 2142 | gdFree(str); 2143 | } else 2144 | lua_pushnil(L); 2145 | return 1; 2146 | } 2147 | 2148 | #endif 2149 | 2150 | 2151 | 2152 | static const luaL_Reg LgdFunctions[] = 2153 | { 2154 | /* Leave Lua do it! 2155 | { "destroy", LgdImageDestroy }, */ 2156 | 2157 | { "create", LgdImageCreate }, 2158 | { "createPalette", LgdImageCreatePalette }, 2159 | { "createTrueColor", LgdImageCreateTrueColor }, 2160 | { "createPaletteFromTrueColor", LgdImageCreatePaletteFromTrueColor }, 2161 | { "trueColorToPalette", LgdImageTrueColorToPalette }, 2162 | 2163 | #ifdef GD_JPEG 2164 | { "createFromJpeg", LgdImageCreateFromJpeg }, 2165 | { "createFromJpegStr", LgdImageCreateFromJpegPtr }, 2166 | #endif 2167 | #ifdef GD_GIF 2168 | { "createFromGif", LgdImageCreateFromGif }, 2169 | { "createFromGifStr", LgdImageCreateFromGifPtr }, 2170 | #endif 2171 | { "createFromPng", LgdImageCreateFromPng }, 2172 | { "createFromPngStr", LgdImageCreateFromPngPtr }, 2173 | { "createFromGd", LgdImageCreateFromGd }, 2174 | { "createFromGdStr", LgdImageCreateFromGdPtr }, 2175 | { "createFromGd2", LgdImageCreateFromGd2 }, 2176 | { "createFromGd2Str", LgdImageCreateFromGd2Ptr }, 2177 | { "createFromGd2Part", LgdImageCreateFromGd2Part }, 2178 | { "createFromGd2PartStr", LgdImageCreateFromGd2PartPtr }, 2179 | 2180 | #ifdef GD_XPM 2181 | { "createFromXbm", LgdImageCreateFromXbm }, 2182 | { "createFromXpm", LgdImageCreateFromXpm }, 2183 | #endif 2184 | 2185 | #ifdef GD_JPEG 2186 | { "jpeg", LgdImageJpeg }, 2187 | { "jpegStr", LgdImageJpegPtr }, 2188 | #endif 2189 | #ifdef GD_PNG 2190 | { "png", LgdImagePng }, 2191 | { "pngStr", LgdImagePngPtr }, 2192 | { "pngEx", LgdImagePngEx }, 2193 | { "pngStrEx", LgdImagePngPtrEx }, 2194 | #endif 2195 | #ifdef GD_GIF 2196 | { "gif", LgdImageGif }, 2197 | { "gifStr", LgdImageGifPtr }, 2198 | #endif 2199 | { "gd", LgdImageGd }, 2200 | { "gdStr", LgdImageGdPtr }, 2201 | { "gd2", LgdImageGd2 }, 2202 | { "gd2Str", LgdImageGd2Ptr }, 2203 | { "wbmp", LgdImageWBMP }, 2204 | { "wbmpStr", LgdImageWBMPPtr }, 2205 | 2206 | { "colorAllocate", LgdImageColorAllocate }, 2207 | { "colorAllocateAlpha", LgdImageColorAllocateAlpha }, 2208 | { "colorClosest", LgdImageColorClosest }, 2209 | { "colorClosestAlpha", LgdImageColorClosestAlpha }, 2210 | { "colorClosestHWB", LgdImageColorClosestHWB }, 2211 | { "colorExact", LgdImageColorExact }, 2212 | { "colorExactAlpha", LgdImageColorExactAlpha }, 2213 | { "colorResolve", LgdImageColorResolve }, 2214 | { "colorResolveAlpha", LgdImageColorResolveAlpha }, 2215 | { "colorsTotal", LgdImageColorsTotal }, 2216 | { "red", LgdImageRed }, 2217 | { "blue", LgdImageBlue }, 2218 | { "green", LgdImageGreen }, 2219 | { "alpha", LgdImageAlpha }, 2220 | { "getTransparent", LgdImageGetTransparent }, 2221 | { "colorTransparent", LgdImageColorTransparent }, 2222 | { "colorDeallocate", LgdImageColorDeallocate }, 2223 | 2224 | { "boundsSafe", LgdImageBoundsSafe }, 2225 | { "getPixel", LgdImageGetPixel }, 2226 | { "sizeX", LgdImageSX }, 2227 | { "sizeY", LgdImageSY }, 2228 | { "sizeXY", LgdImageSXY }, 2229 | { "getClip", LgdImageGetClip }, 2230 | { "setClip", LgdImageSetClip }, 2231 | 2232 | { "setPixel", LgdImageSetPixel }, 2233 | { "line", LgdImageLine }, 2234 | { "rectangle", LgdImageRectangle }, 2235 | { "filledRectangle", LgdImageFilledRectangle }, 2236 | { "polygon", LgdImagePolygon }, 2237 | { "filledPolygon", LgdImageFilledPolygon }, 2238 | { "openPolygon", LgdImageOpenPolygon }, 2239 | { "arc", LgdImageArc }, 2240 | { "filledArc", LgdImageFilledArc }, 2241 | { "filledEllipse", LgdImageFilledEllipse }, 2242 | { "fill", LgdImageFill }, 2243 | { "fillToBorder", LgdImageFillToBorder }, 2244 | 2245 | { "setAntiAliased", LgdImageSetAntiAliased }, 2246 | { "setAntiAliasedDontBlend", LgdImageSetAntiAliasedDontBlend }, 2247 | { "setBrush", LgdImageSetBrush }, 2248 | { "setTile", LgdImageSetTile }, 2249 | { "setStyle", LgdImageSetStyle }, 2250 | { "setThickness", LgdImageSetThickness }, 2251 | { "alphaBlending", LgdImageAlphaBlending }, 2252 | { "saveAlpha", LgdImageSaveAlpha }, 2253 | { "getInterlaced", LgdImageGetInterlaced }, 2254 | { "interlace", LgdImageInterlace }, 2255 | 2256 | { "string", LgdImageString }, 2257 | { "stringUp", LgdImageStringUp }, 2258 | { "char", LgdImageChar }, 2259 | { "charUp", LgdImageCharUp }, 2260 | 2261 | { "copy", LgdImageCopy }, 2262 | { "copyResized", LgdImageCopyResized }, 2263 | { "copyResampled", LgdImageCopyResampled }, 2264 | { "copyRotated", LgdImageCopyRotated }, 2265 | { "copyMerge", LgdImageCopyMerge }, 2266 | { "copyMergeGray", LgdImageCopyMergeGray }, 2267 | { "paletteCopy", LgdImagePaletteCopy }, 2268 | { "squareToCircle", LgdImageSquareToCircle }, 2269 | { "sharpen", LgdImageSharpen }, 2270 | 2271 | #ifdef GD_FREETYPE 2272 | { "stringFT", LgdImageStringFT }, 2273 | { "stringFTEx", LgdImageStringFTEx }, 2274 | { "stringFTCircle", LgdImageStringFTCircle }, 2275 | { "fontCacheSetup", LgdFontCacheSetup }, 2276 | { "fontCacheShutdown", LgdFontCacheShutdown }, 2277 | #endif 2278 | 2279 | #ifdef GD_FONTCONFIG 2280 | { "useFontConfig", LgdFTUseFontConfig }, 2281 | #endif 2282 | 2283 | #ifdef GD_GIF /* Gif animation */ 2284 | { "gifAnimBegin", LgdImageGifAnimBegin }, 2285 | { "gifAnimAdd", LgdImageGifAnimAdd }, 2286 | { "gifAnimEnd", LgdImageGifAnimEnd }, 2287 | { "gifAnimBeginStr", LgdImageGifAnimBeginPtr }, 2288 | { "gifAnimAddStr", LgdImageGifAnimAddPtr }, 2289 | { "gifAnimEndStr", LgdImageGifAnimEndPtr }, 2290 | #endif 2291 | 2292 | { NULL, NULL } 2293 | }; 2294 | 2295 | 2296 | static const luaL_Reg LgdMetatable[] = 2297 | { 2298 | { "__gc", LgdImageDestroy }, 2299 | { NULL, NULL } 2300 | }; 2301 | 2302 | 2303 | int luaopen_gd(lua_State *L) { 2304 | lua_newtable(L); 2305 | luaL_setfuncs(L, LgdFunctions, 0); 2306 | 2307 | lua_pushliteral(L, "VERSION"); 2308 | lua_pushstring(L, LIB_VERSION); 2309 | lua_settable(L, -3); 2310 | 2311 | lua_pushliteral(L, "COPYRIGHT"); 2312 | lua_pushstring(L, LIB_COPYRIGHT); 2313 | lua_settable(L, -3); 2314 | 2315 | tblseticons(L, "MAX_COLORS", gdMaxColors); 2316 | tblseticons(L, "GD2_FMT_RAW", GD2_FMT_RAW); 2317 | tblseticons(L, "GD2_FMT_COMPRESSED", GD2_FMT_COMPRESSED); 2318 | tblseticons(L, "ARC", gdArc); 2319 | tblseticons(L, "CHORD", gdChord); 2320 | tblseticons(L, "PIE", gdPie); 2321 | tblseticons(L, "NO_FILL", gdNoFill); 2322 | tblseticons(L, "EDGED", gdEdged); 2323 | tblseticons(L, "ANTI_ALIASED", gdAntiAliased); 2324 | tblseticons(L, "BRUSHED", gdBrushed); 2325 | tblseticons(L, "STYLED", gdStyled); 2326 | tblseticons(L, "STYLED_BRUSHED", gdStyledBrushed); 2327 | tblseticons(L, "TILED", gdTiled); 2328 | tblseticons(L, "TRANSPARENT", gdTransparent); 2329 | 2330 | #ifdef GD_FREETYPE 2331 | /* For gd.StringFTEx */ 2332 | tblseticons(L, "FTEX_Unicode", gdFTEX_Unicode); 2333 | tblseticons(L, "FTEX_Shift_JIS", gdFTEX_Shift_JIS); 2334 | tblseticons(L, "FTEX_Big5", gdFTEX_Big5); 2335 | #endif 2336 | 2337 | #ifdef GD_GIF 2338 | /* For gif animation */ 2339 | tblseticons(L, "DISPOSAL_NONE", gdDisposalNone); 2340 | tblseticons(L, "DISPOSAL_UNKNOWN", gdDisposalUnknown); 2341 | tblseticons(L, "DISPOSAL_RESTORE_BACKGROUND", gdDisposalRestoreBackground); 2342 | tblseticons(L, "DISPOSAL_RESTORE_PREVIOUS", gdDisposalRestorePrevious); 2343 | #endif 2344 | 2345 | /* Standard gd fonts */ 2346 | tblseticons(L, "FONT_TINY", MY_GD_FONT_TINY); 2347 | tblseticons(L, "FONT_SMALL", MY_GD_FONT_SMALL); 2348 | tblseticons(L, "FONT_MEDIUM", MY_GD_FONT_MEDIUM_BOLD); 2349 | tblseticons(L, "FONT_LARGE", MY_GD_FONT_LARGE); 2350 | tblseticons(L, "FONT_GIANT", MY_GD_FONT_GIANT); 2351 | 2352 | luaL_newmetatable(L, GD_IMAGE_PTR_TYPENAME); 2353 | lua_pushliteral(L, "__index"); 2354 | lua_pushvalue(L, -3); 2355 | lua_settable(L, -3); 2356 | luaL_setfuncs(L, LgdMetatable, 0); 2357 | lua_pop(L, 1); 2358 | 2359 | return 1; 2360 | } 2361 | 2362 | -------------------------------------------------------------------------------- /test_features.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local gd = require("gd") 4 | 5 | function enabled(res, desc) 6 | local str = " " .. desc .. " " 7 | str = str .. string.rep(".", 37 - string.len(str)) 8 | if res then 9 | print(str .. " Enabled") 10 | else 11 | print(str .. " Disabled") 12 | end 13 | end 14 | 15 | print("Lua-GD version: " .. gd.VERSION) 16 | print("Lua-GD features:") 17 | 18 | enabled(gd.png, "PNG support") 19 | enabled(gd.gif, "GIF support") 20 | enabled(gd.jpeg, "JPEG support") 21 | enabled(gd.createFromXpm, "XPM/XBM support") 22 | enabled(gd.stringFT, "FreeType support") 23 | enabled(gd.useFontConfig, "Fontconfig support") 24 | 25 | --------------------------------------------------------------------------------