├── .gitignore ├── .gitmodules ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── build_win32.bat ├── doc ├── Makefile ├── bindings.adoc ├── colony.css ├── color.adoc ├── context.adoc ├── enums.adoc ├── image.adoc ├── index.adoc ├── index.html ├── powered-by-lua.gif └── preface.adoc ├── examples ├── canvas.lua ├── images.lua └── test.lua ├── gl_2_0_core.h ├── gles2.h ├── lbind.h ├── lua-nanovg.c ├── nanovg.def ├── pprint.lua ├── rockspecs ├── nanovg-0.1.3-1.rockspec └── nanovg-scm-1.rockspec ├── scripts ├── platform.sh ├── run-tests.sh ├── setenv_lua.sh └── setup_lua.sh └── test ├── .luacov └── test.lua /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | old/* 9 | *.dll 10 | *.so 11 | *.o 12 | *.a 13 | *.vscode 14 | # Build results 15 | .travis/lua-5.*/* 16 | .travis/build/* 17 | 18 | [Dd]ebug/ 19 | [Rr]elease/ 20 | x64/ 21 | build/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 26 | !packages/*/build/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | *_i.c 33 | *_p.c 34 | *.ilk 35 | *.meta 36 | *.obj 37 | *.pch 38 | *.pdb 39 | *.pgc 40 | *.pgd 41 | *.rsp 42 | *.sbr 43 | *.tlb 44 | *.tli 45 | *.tlh 46 | *.tmp 47 | *.tmp_proj 48 | *.log 49 | *.vspscc 50 | *.vssscc 51 | .builds 52 | *.pidb 53 | *.log 54 | *.scc 55 | 56 | luacov.stats.out 57 | 58 | # Visual C++ cache files 59 | ipch/ 60 | *.aps 61 | *.ncb 62 | *.opensdf 63 | *.sdf 64 | *.cachefile 65 | 66 | # Visual Studio profiler 67 | *.psess 68 | *.vsp 69 | *.vspx 70 | 71 | # Guidance Automation Toolkit 72 | *.gpState 73 | 74 | # ReSharper is a .NET coding add-in 75 | _ReSharper*/ 76 | *.[Rr]e[Ss]harper 77 | 78 | # TeamCity is a build add-in 79 | _TeamCity* 80 | 81 | # DotCover is a Code Coverage Tool 82 | *.dotCover 83 | 84 | # NCrunch 85 | *.ncrunch* 86 | .*crunch*.local.xml 87 | 88 | # Installshield output folder 89 | [Ee]xpress/ 90 | 91 | # DocProject is a documentation generator add-in 92 | DocProject/buildhelp/ 93 | DocProject/Help/*.HxT 94 | DocProject/Help/*.HxC 95 | DocProject/Help/*.hhc 96 | DocProject/Help/*.hhk 97 | DocProject/Help/*.hhp 98 | DocProject/Help/Html2 99 | DocProject/Help/html 100 | 101 | # Click-Once directory 102 | publish/ 103 | 104 | # Publish Web Output 105 | *.Publish.xml 106 | 107 | # NuGet Packages Directory 108 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 109 | #packages/ 110 | 111 | # Windows Azure Build Output 112 | csx 113 | *.build.csdef 114 | 115 | # Windows Store app package directory 116 | AppPackages/ 117 | 118 | # Others 119 | sql/ 120 | *.Cache 121 | ClientBin/ 122 | [Ss]tyle[Cc]op.* 123 | ~$* 124 | *~ 125 | *.dbmdl 126 | *.[Pp]ublish.xml 127 | *.pfx 128 | *.publishsettings 129 | 130 | # RIA/Silverlight projects 131 | Generated_Code/ 132 | 133 | # Backup & report files from converting an old project file to a newer 134 | # Visual Studio version. Backup files are not needed, because we have git ;-) 135 | _UpgradeReport_Files/ 136 | Backup*/ 137 | UpgradeLog*.XML 138 | UpgradeLog*.htm 139 | 140 | # SQL Server files 141 | App_Data/*.mdf 142 | App_Data/*.ldf 143 | 144 | 145 | #LightSwitch generated files 146 | GeneratedArtifacts/ 147 | _Pvt_Extensions/ 148 | ModelManifest.xml 149 | 150 | # ========================= 151 | # Windows detritus 152 | # ========================= 153 | 154 | # Windows image file caches 155 | Thumbs.db 156 | ehthumbs.db 157 | 158 | # Folder config file 159 | Desktop.ini 160 | 161 | # Recycle Bin used on file shares 162 | $RECYCLE.BIN/ 163 | 164 | # Mac desktop service store files 165 | .DS_Store 166 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "nanovg"] 2 | path = nanovg 3 | url = https://github.com/memononen/nanovg 4 | [submodule "moonglfw"] 5 | path = moonglfw 6 | url = https://github.com/stetre/moonglfw.git 7 | [submodule "nanosvg"] 8 | path = nanosvg 9 | url = https://github.com/memononen/nanosvg.git 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | 3 | sudo: false 4 | 5 | env: 6 | global: 7 | - LUAROCKS=3.0.0 8 | - LUA=lua5.3 9 | branches: 10 | only: 11 | - master 12 | 13 | script: 14 | - ./scripts/run-tests.sh 15 | 16 | after_success: 17 | - coveralls -b .. -r .. -i ./src --dump c.report.json 18 | - luacov-coveralls -j c.report.json -v 19 | 20 | notifications: 21 | email: 22 | on_success: change 23 | on_failure: always 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [2018] [Xavier Wang] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TARGET_LUAVER=5.3 2 | LUAVER?=$(shell if pkg-config --silence-errors --libs lua$(TARGET_LUAVER); then echo $(TARGET_LUAVER); else echo $(subst .,,$(TARGET_LUAVER)); fi) 3 | L_EXT?=so 4 | UNAME=$(shell uname) 5 | SYS=$(if $(filter Linux%,$(UNAME)),linux,\ 6 | $(if $(filter MINGW%,$(UNAME)),mingw,\ 7 | $(if $(filter Darwin%,$(UNAME)),macosx,\ 8 | undefined\ 9 | ))) 10 | 11 | ifdef MINGW_PREFIX 12 | MINGW=1 13 | L_EXT=dll 14 | else 15 | UNAME_S := $(shell uname -s) 16 | ifeq ($(UNAME_S),Linux) 17 | LINUX=1 18 | endif 19 | ifeq ($(UNAME_S),Darwin) 20 | OSX=1 21 | endif 22 | endif 23 | 24 | # Linux 25 | ifdef LINUX 26 | PREFIX?=/usr/local 27 | INCDIR=`pkg-config --cflags lua$(LUAVER)` 28 | endif 29 | 30 | # OSX - Homebrew 31 | ifdef OSX 32 | PREFIX?=/usr/local 33 | INCDIR=`pkg-config --cflags lua$(LUAVER)` 34 | endif 35 | 36 | # Windows - Mingw/Msys 37 | ifdef MINGW 38 | PREFIX?=$(MINGW_PREFIX) 39 | INCDIR=`pkg-config --cflags lua$(LUAVER)` 40 | endif 41 | 42 | # Directory where to install Lua modules 43 | L_DIR=$(PREFIX)/share/lua/$(LUAVER) 44 | # Directory where to install Lua C modules 45 | C_DIR=$(PREFIX)/lib/lua/$(LUAVER) 46 | # Directory where to install C headers 47 | H_DIR=$(PREFIX)/include 48 | # Directory where to install C libraries 49 | S_DIR=$(PREFIX)/lib 50 | 51 | default : all 52 | 53 | .PHONY: moonglfw test 54 | 55 | all: clean moonglfw $(SYS) doc 56 | 57 | undefined : 58 | @echo "I can't guess your platform, please do 'make PLATFORM' where PLATFORM is one of these:" 59 | @echo " linux mingw macosx" 60 | 61 | clean : 62 | @rm -fr *.$(L_EXT) 63 | @rm -fr *.a 64 | @rm -fr *.o 65 | @echo "Cleaned build files" 66 | @cd moonglfw && $(MAKE) clean 67 | 68 | moonglfw : 69 | @echo "Building moonglfw dependency in $(PREFIX)" 70 | @cd moonglfw && INCDIR=`pkg-config --cflags lua$(LUAVER)` $(MAKE) clean && cd . 71 | @cd moonglfw && INCDIR=`pkg-config --cflags lua$(LUAVER)` $(MAKE) && cd . 72 | @cp moonglfw/src/moonglfw.$(L_EXT) moonglfw.$(L_EXT) 73 | 74 | install : 75 | @echo "Installing moonglfw dependency in $(PREFIX)" 76 | @cd moonglfw && PREFIX=$(PREFIX) $(MAKE) -f Makefile install && cd . 77 | @echo "Installing nvg dependency in $(C_DIR)" 78 | @cp -f nvg.$(L_EXT) $(C_DIR) 79 | 80 | test : 81 | # Test 82 | lua$(LUAVER) examples/test.lua 83 | 84 | mingw : OS := MINGW 85 | mingw : CFLAGS += -DLUAVER=$(LUAVER) -D_GLFW_USE_OPENGL -D_GLFW_WIN32 -D_GLFW_WGL -D_GLFW_BUILD_ALL -Iglfw/include $(shell pkg-config --cflags lua$(LUAVER)) -fPIC 86 | mingw : LDFLAGS += $(shell pkg-config --libs lua$(LUAVER)) -lm -lopengl32 -lgdi32 87 | mingw : 88 | # NanoVG 89 | gcc -c -O3 $(CFLAGS) nanovg/src/nanovg.c 90 | ar rcs libnanovg.a *.o 91 | gcc -shared -O3 $(CFLAGS) -o nvg.$(L_EXT) lua-nanovg.c libnanovg.a $(LDFLAGS) 92 | 93 | linux : OS := LINUX 94 | linux : CFLAGS += -DLUAVER=$(LUAVER) -D_GLFW_USE_OPENGL -D_GLFW_X11 -D_GLFW_BUILD_ALL -Iglfw/include $(shell pkg-config --cflags lua$(LUAVER)) -fPIC 95 | linux : LDFLAGS += $(shell pkg-config --libs lua$(LUAVER) gl) 96 | linux : 97 | # NanoVG 98 | gcc -c -O3 $(CFLAGS) nanovg/src/nanovg.c 99 | ar rcs libnanovg.a *.o 100 | gcc -shared -O3 $(CFLAGS) -o nvg.$(L_EXT) lua-nanovg.c libnanovg.a $(LDFLAGS) 101 | 102 | macosx : OS := MACOSX 103 | macosx : CFLAGS += -DLUAVER=$(LUAVER) -D_GLFW_USE_OPENGL -D_GLFW_COCOA -D_GLFW_BUILD_ALL -D_GLFW_NSGL -Iglfw/include 104 | macosx : 105 | # NanoVG 106 | gcc -c -O3 nanovg/src/nanovg.c 107 | ar rcs libnanovg.a *.o 108 | gcc -O3 -bundle -undefined dynamic_lookup -o nvg.$(L_EXT) lua-nanovg.c libnanovg.a 109 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## lua-nanovg: Lua bindings for NanoVG and NanoSVG 2 | 3 | lua-nanovg is a Lua binding library for [NanoVG](https://github.com/memononen/nanovg/) and [NanoSVG](https://github.com/memononen/nanosvg/). 4 | 5 | It runs on OSX, GNU/Linux and on Windows (MSYS2/MinGW) and requires 6 | [Lua](http://www.lua.org/) (>=5.3) 7 | and [GLFW](http://www.glfw.org/download.html) (>=3.1). 8 | 9 | _Author:_ _[Xavier Wang](https://github.com/starwing)_ 10 | 11 | [![Lua logo](./doc/powered-by-lua.gif)](http://www.lua.org/) 12 | 13 | #### License 14 | 15 | MIT/X11 license (same as Lua). See [LICENSE](./LICENSE). 16 | 17 | #### Documentation 18 | 19 | See the [Reference Manual](https://starwing.github.io/lua-nanovg/doc/index.html). 20 | 21 | #### Getting and installing 22 | 23 | Setup the build environment as described [here](https://github.com/stetre/moonlibs), then: 24 | 25 | ```sh 26 | $ git clone https://github.com/starwing/lua-nanovg 27 | $ git submodule init 28 | $ git submodule update 29 | $ cd lua-nanovg 30 | lua-nanovg$ make 31 | lua-nanovg$ make install # or 'sudo make install' (Ubuntu) 32 | ``` 33 | 34 | #### Example 35 | 36 | ```lua 37 | -- Script: hello.lua 38 | local nvg = require "nvg" 39 | local glfw = require("moonglfw") 40 | -- Allocate a window and deal with OpenGL 41 | w = glfw.create_window(640, 480, "Hello world!") 42 | glfw.make_context_current(w) 43 | -- Only after this we can use nanovg 44 | local canvas = nvg.new "antialias" 45 | -- Repeatedly poll for events: 46 | while not glfw.window_should_close(w) do 47 | if glfw.get_key(w, "escape") == 'press' then break end 48 | t = glfw.get_time() 49 | ww, wh = glfw.get_window_size(w) 50 | mx, my = glfw.get_cursor_pos(w) 51 | local pw, _ = glfw.get_framebuffer_size(w) 52 | local ratio = pw/ww 53 | canvas:beginFrame(ww, wh, ratio) 54 | canvas:clear "#4C4C51" 55 | canvas:roundedRect((ww-320)/2, (wh-240)/2, 320, 240, 3) 56 | canvas.fillStyle = "rgba(128,30,34,100)" 57 | canvas:fill() 58 | canvas:endFrame() 59 | glfw.swap_buffers(w) 60 | glfw.poll_events() 61 | end 62 | ``` 63 | 64 | The script can be executed at the shell prompt with the standard Lua interpreter: 65 | 66 | ```shell 67 | $ lua hello.lua 68 | ``` 69 | 70 | Other examples can be found in the **examples/** directory contained in the release package. 71 | -------------------------------------------------------------------------------- /build_win32.bat: -------------------------------------------------------------------------------- 1 | @del *.o *.a *.dll 2 | 3 | gcc -c -s -O3 nanovg\src\nanovg.c 4 | ar rcs libnanovg.a *.o 5 | @del *.o 6 | gcc -s -O3 -mdll -o nvg.dll nanovg.def lua-nanovg.c libnanovg.a -lopengl32 -llua53 7 | 8 | @pause 9 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | TgtAdoc := index 2 | TgtPdf := MoonGLFW-RefMan 3 | 4 | Stylesdir = ./ 5 | Stylesheet = colony.css 6 | Style = -a stylesheet=$(Stylesheet) -a stylesdir=$(Stylesdir) 7 | Style = 8 | 9 | ifdef TgtAdoc 10 | # one file only 11 | Src = $(TgtAdoc).adoc 12 | else 13 | # all .adoc files 14 | Src := $(wildcard *.adoc) 15 | endif 16 | 17 | Xml := $(Src:.adoc=.xml) 18 | Html := $(Src:.adoc=.html) 19 | Pdf := $(Src:.adoc=.pdf) 20 | 21 | default: html 22 | 23 | check: 24 | 25 | clean: 26 | @-rm -f *~ 27 | @-rm -f *.pdf 28 | @-rm -f *.pdfmarks 29 | @-rm -f *.xml 30 | @-rm -f *.html 31 | @-rm -f *.epub 32 | @-rm -f *.fo 33 | @-rm -f *.log 34 | 35 | install: 36 | 37 | html: clean 38 | @asciidoctor $(Style) $(Src) 39 | 40 | preview: html 41 | @google-chrome $(Html) 42 | 43 | ifdef TgtAdoc 44 | # one file only 45 | pdf: clean 46 | @asciidoctor-pdf $(TgtAdoc).adoc -o $(TgtPdf).pdf 47 | else 48 | # all .adoc files 49 | pdf: clean 50 | @asciidoctor-pdf -a pdf-style=asciidoctor $(TgtAdoc).adoc 51 | endif 52 | 53 | docs: html pdf 54 | -------------------------------------------------------------------------------- /doc/bindings.adoc: -------------------------------------------------------------------------------- 1 | 2 | == Bindings 3 | 4 | The functions list of the nvg module 5 | 6 | include::context.adoc[] 7 | include::color.adoc[] 8 | include::image.adoc[] 9 | 10 | -------------------------------------------------------------------------------- /doc/colony.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v2.1.2 | MIT License | git.io/normalize */ 2 | /* ========================================================================== HTML5 display definitions ========================================================================== */ 3 | /** Correct `block` display not defined in IE 8/9. */ 4 | article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { display: block; } 5 | 6 | /** Correct `inline-block` display not defined in IE 8/9. */ 7 | audio, canvas, video { display: inline-block; } 8 | 9 | /** Prevent modern browsers from displaying `audio` without controls. Remove excess height in iOS 5 devices. */ 10 | audio:not([controls]) { display: none; height: 0; } 11 | 12 | /** Address `[hidden]` styling not present in IE 8/9. Hide the `template` element in IE, Safari, and Firefox < 22. */ 13 | [hidden], template { display: none; } 14 | 15 | script { display: none !important; } 16 | 17 | /* ========================================================================== Base ========================================================================== */ 18 | /** 1. Set default font family to sans-serif. 2. Prevent iOS text size adjust after orientation change, without disabling user zoom. */ 19 | html { font-family: sans-serif; /* 1 */ -ms-text-size-adjust: 100%; /* 2 */ -webkit-text-size-adjust: 100%; /* 2 */ } 20 | 21 | /** Remove default margin. */ 22 | body { margin: 0; } 23 | 24 | /* ========================================================================== Links ========================================================================== */ 25 | /** Remove the gray background color from active links in IE 10. */ 26 | a { background: transparent; } 27 | 28 | /** Address `outline` inconsistency between Chrome and other browsers. */ 29 | a:focus { outline: thin dotted; } 30 | 31 | /** Improve readability when focused and also mouse hovered in all browsers. */ 32 | a:active, a:hover { outline: 0; } 33 | 34 | /* ========================================================================== Typography ========================================================================== */ 35 | /** Address variable `h1` font-size and margin within `section` and `article` contexts in Firefox 4+, Safari 5, and Chrome. */ 36 | h1 { font-size: 2em; margin: 0.67em 0; } 37 | 38 | /** Address styling not present in IE 8/9, Safari 5, and Chrome. */ 39 | abbr[title] { border-bottom: 1px dotted; } 40 | 41 | /** Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. */ 42 | b, strong { font-weight: bold; } 43 | 44 | /** Address styling not present in Safari 5 and Chrome. */ 45 | dfn { font-style: italic; } 46 | 47 | /** Address differences between Firefox and other browsers. */ 48 | hr { -moz-box-sizing: content-box; box-sizing: content-box; height: 0; } 49 | 50 | /** Address styling not present in IE 8/9. */ 51 | mark { background: #ff0; color: #000; } 52 | 53 | /** Correct font family set oddly in Safari 5 and Chrome. */ 54 | code, kbd, pre, samp { font-family: monospace, serif; font-size: 1em; } 55 | 56 | /** Improve readability of pre-formatted text in all browsers. */ 57 | pre { white-space: pre-wrap; } 58 | 59 | /** Set consistent quote types. */ 60 | q { quotes: "\201C" "\201D" "\2018" "\2019"; } 61 | 62 | /** Address inconsistent and variable font size in all browsers. */ 63 | small { font-size: 80%; } 64 | 65 | /** Prevent `sub` and `sup` affecting `line-height` in all browsers. */ 66 | sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } 67 | 68 | sup { top: -0.5em; } 69 | 70 | sub { bottom: -0.25em; } 71 | 72 | /* ========================================================================== Embedded content ========================================================================== */ 73 | /** Remove border when inside `a` element in IE 8/9. */ 74 | img { border: 0; } 75 | 76 | /** Correct overflow displayed oddly in IE 9. */ 77 | svg:not(:root) { overflow: hidden; } 78 | 79 | /* ========================================================================== Figures ========================================================================== */ 80 | /** Address margin not present in IE 8/9 and Safari 5. */ 81 | figure { margin: 0; } 82 | 83 | /* ========================================================================== Forms ========================================================================== */ 84 | /** Define consistent border, margin, and padding. */ 85 | fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; } 86 | 87 | /** 1. Correct `color` not being inherited in IE 8/9. 2. Remove padding so people aren't caught out if they zero out fieldsets. */ 88 | legend { border: 0; /* 1 */ padding: 0; /* 2 */ } 89 | 90 | /** 1. Correct font family not being inherited in all browsers. 2. Correct font size not being inherited in all browsers. 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. */ 91 | button, input, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 2 */ margin: 0; /* 3 */ } 92 | 93 | /** Address Firefox 4+ setting `line-height` on `input` using `!important` in the UA stylesheet. */ 94 | button, input { line-height: normal; } 95 | 96 | /** Address inconsistent `text-transform` inheritance for `button` and `select`. All other form control elements do not inherit `text-transform` values. Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. Correct `select` style inheritance in Firefox 4+ and Opera. */ 97 | button, select { text-transform: none; } 98 | 99 | /** 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls. 2. Correct inability to style clickable `input` types in iOS. 3. Improve usability and consistency of cursor style between image-type `input` and others. */ 100 | button, html input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ } 101 | 102 | /** Re-set default cursor for disabled elements. */ 103 | button[disabled], html input[disabled] { cursor: default; } 104 | 105 | /** 1. Address box sizing set to `content-box` in IE 8/9. 2. Remove excess padding in IE 8/9. */ 106 | input[type="checkbox"], input[type="radio"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ } 107 | 108 | /** 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome (include `-moz` to future-proof). */ 109 | input[type="search"] { -webkit-appearance: textfield; /* 1 */ -moz-box-sizing: content-box; -webkit-box-sizing: content-box; /* 2 */ box-sizing: content-box; } 110 | 111 | /** Remove inner padding and search cancel button in Safari 5 and Chrome on OS X. */ 112 | input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; } 113 | 114 | /** Remove inner padding and border in Firefox 4+. */ 115 | button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; } 116 | 117 | /** 1. Remove default vertical scrollbar in IE 8/9. 2. Improve readability and alignment in all browsers. */ 118 | textarea { overflow: auto; /* 1 */ vertical-align: top; /* 2 */ } 119 | 120 | /* ========================================================================== Tables ========================================================================== */ 121 | /** Remove most spacing between table cells. */ 122 | table { border-collapse: collapse; border-spacing: 0; } 123 | 124 | meta.foundation-mq-small { font-family: "only screen and (min-width: 768px)"; width: 768px; } 125 | 126 | meta.foundation-mq-medium { font-family: "only screen and (min-width:1280px)"; width: 1280px; } 127 | 128 | meta.foundation-mq-large { font-family: "only screen and (min-width:1440px)"; width: 1440px; } 129 | 130 | *, *:before, *:after { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } 131 | 132 | html, body { font-size: 100%; } 133 | 134 | body { background: white; color: #222222; padding: 0; margin: 0; font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; font-weight: normal; font-style: normal; line-height: 1; position: relative; cursor: auto; } 135 | 136 | a:hover { cursor: pointer; } 137 | 138 | img, object, embed { max-width: 100%; height: auto; } 139 | 140 | object, embed { height: 100%; } 141 | 142 | img { -ms-interpolation-mode: bicubic; } 143 | 144 | #map_canvas img, #map_canvas embed, #map_canvas object, .map_canvas img, .map_canvas embed, .map_canvas object { max-width: none !important; } 145 | 146 | .left { float: left !important; } 147 | 148 | .right { float: right !important; } 149 | 150 | .text-left { text-align: left !important; } 151 | 152 | .text-right { text-align: right !important; } 153 | 154 | .text-center { text-align: center !important; } 155 | 156 | .text-justify { text-align: justify !important; } 157 | 158 | .hide { display: none; } 159 | 160 | .antialiased, body { -webkit-font-smoothing: antialiased; } 161 | 162 | img { display: inline-block; vertical-align: middle; } 163 | 164 | textarea { height: auto; min-height: 50px; } 165 | 166 | select { width: 100%; } 167 | 168 | p.lead, .paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { font-size: 1.21875em; line-height: 1.6; } 169 | 170 | .subheader, .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { line-height: 1.4; color: #003b6b; font-weight: 300; margin-top: 0.2em; margin-bottom: 0.5em; } 171 | 172 | /* Typography resets */ 173 | div, dl, dt, dd, ul, ol, li, h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6, pre, form, p, blockquote, th, td { margin: 0; padding: 0; direction: ltr; } 174 | 175 | /* Default Link Styles */ 176 | a { color: #00579e; text-decoration: none; line-height: inherit; } 177 | a:hover, a:focus { color: #333333; } 178 | a img { border: none; } 179 | 180 | /* Default paragraph styles */ 181 | p { font-family: Arial, sans-serif; font-weight: normal; font-size: 1em; line-height: 1.6; margin-bottom: 0.75em; text-rendering: optimizeLegibility; } 182 | p aside { font-size: 0.875em; line-height: 1.35; font-style: italic; } 183 | 184 | /* Default header styles */ 185 | h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { font-family: Arial, sans-serif; font-weight: normal; font-style: normal; color: #7b2d00; text-rendering: optimizeLegibility; margin-top: 0.5em; margin-bottom: 0.5em; line-height: 1.2125em; } 186 | h1 small, h2 small, h3 small, #toctitle small, .sidebarblock > .content > .title small, h4 small, h5 small, h6 small { font-size: 60%; color: #ff6b15; line-height: 0; } 187 | 188 | h1 { font-size: 2.125em; } 189 | 190 | h2 { font-size: 1.6875em; } 191 | 192 | h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.375em; } 193 | 194 | h4 { font-size: 1.125em; } 195 | 196 | h5 { font-size: 1.125em; } 197 | 198 | h6 { font-size: 1em; } 199 | 200 | hr { border: solid #dddddd; border-width: 1px 0 0; clear: both; margin: 1.25em 0 1.1875em; height: 0; } 201 | 202 | /* Helpful Typography Defaults */ 203 | em, i { font-style: italic; line-height: inherit; } 204 | 205 | strong, b { font-weight: bold; line-height: inherit; } 206 | 207 | small { font-size: 60%; line-height: inherit; } 208 | 209 | code { font-family: Consolas, "Liberation Mono", Courier, monospace; font-weight: bold; color: #003426; } 210 | 211 | /* Lists */ 212 | ul, ol, dl { font-size: 1em; line-height: 1.6; margin-bottom: 0.75em; list-style-position: outside; font-family: Arial, sans-serif; } 213 | 214 | ul, ol { margin-left: 1.5em; } 215 | ul.no-bullet, ol.no-bullet { margin-left: 1.5em; } 216 | 217 | /* Unordered Lists */ 218 | ul li ul, ul li ol { margin-left: 1.25em; margin-bottom: 0; font-size: 1em; /* Override nested font-size change */ } 219 | ul.square li ul, ul.circle li ul, ul.disc li ul { list-style: inherit; } 220 | ul.square { list-style-type: square; } 221 | ul.circle { list-style-type: circle; } 222 | ul.disc { list-style-type: disc; } 223 | ul.no-bullet { list-style: none; } 224 | 225 | /* Ordered Lists */ 226 | ol li ul, ol li ol { margin-left: 1.25em; margin-bottom: 0; } 227 | 228 | /* Definition Lists */ 229 | dl dt { margin-bottom: 0.3em; font-weight: bold; } 230 | dl dd { margin-bottom: 0.75em; } 231 | 232 | /* Abbreviations */ 233 | abbr, acronym { text-transform: uppercase; font-size: 90%; color: black; border-bottom: 1px dotted #dddddd; cursor: help; } 234 | 235 | abbr { text-transform: none; } 236 | 237 | /* Blockquotes */ 238 | blockquote { margin: 0 0 0.75em; padding: 0.5625em 1.25em 0 1.1875em; border-left: 1px solid #dddddd; } 239 | blockquote cite { display: block; font-size: 0.8125em; color: #e15200; } 240 | blockquote cite:before { content: "\2014 \0020"; } 241 | blockquote cite a, blockquote cite a:visited { color: #e15200; } 242 | 243 | blockquote, blockquote p { line-height: 1.6; color: #333333; } 244 | 245 | /* Microformats */ 246 | .vcard { display: inline-block; margin: 0 0 1.25em 0; border: 1px solid #dddddd; padding: 0.625em 0.75em; } 247 | .vcard li { margin: 0; display: block; } 248 | .vcard .fn { font-weight: bold; font-size: 0.9375em; } 249 | 250 | .vevent .summary { font-weight: bold; } 251 | .vevent abbr { cursor: auto; text-decoration: none; font-weight: bold; border: none; padding: 0 0.0625em; } 252 | 253 | @media only screen and (min-width: 768px) { h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.4; } 254 | h1 { font-size: 2.75em; } 255 | h2 { font-size: 2.3125em; } 256 | h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.6875em; } 257 | h4 { font-size: 1.4375em; } } 258 | /* Tables */ 259 | table { background: white; margin-bottom: 1.25em; border: solid 1px #d8d8ce; } 260 | table thead, table tfoot { background: -webkit-linear-gradient(top, #add386, #90b66a); font-weight: bold; } 261 | table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { padding: 0.5em 0.625em 0.625em; font-size: inherit; color: white; text-align: left; } 262 | table tr th, table tr td { padding: 0.5625em 0.625em; font-size: inherit; color: #6d6e71; } 263 | table tr.even, table tr.alt, table tr:nth-of-type(even) { background: #edf2f2; } 264 | table thead tr th, table tfoot tr th, table tbody tr td, table tr td, table tfoot tr td { display: table-cell; line-height: 1.4; } 265 | 266 | h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.4; } 267 | 268 | a:hover, a:focus { text-decoration: underline; } 269 | 270 | .clearfix:before, .clearfix:after, .float-group:before, .float-group:after { content: " "; display: table; } 271 | .clearfix:after, .float-group:after { clear: both; } 272 | 273 | *:not(pre) > code { font-size: inherit; font-style: normal !important; letter-spacing: 0; padding: 3px 2px 1px 2px; background-color: #eeeeee; border: 1px solid #dddddd; -webkit-border-radius: 0; border-radius: 0; line-height: inherit; } 274 | 275 | pre, pre > code { line-height: 1.6; color: black; font-family: Consolas, "Liberation Mono", Courier, monospace; font-weight: normal; } 276 | 277 | .keyseq { color: #333333; } 278 | 279 | kbd { display: inline-block; color: black; font-size: 0.75em; line-height: 1.4; background-color: #f7f7f7; border: 1px solid #ccc; -webkit-border-radius: 3px; border-radius: 3px; -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; margin: -0.15em 0.15em 0 0.15em; padding: 0.2em 0.6em 0.2em 0.5em; vertical-align: middle; white-space: nowrap; } 280 | 281 | .keyseq kbd:first-child { margin-left: 0; } 282 | 283 | .keyseq kbd:last-child { margin-right: 0; } 284 | 285 | .menuseq, .menu { color: black; } 286 | 287 | b.button:before, b.button:after { position: relative; top: -1px; font-weight: normal; } 288 | 289 | b.button:before { content: "["; padding: 0 3px 0 2px; } 290 | 291 | b.button:after { content: "]"; padding: 0 2px 0 3px; } 292 | 293 | #header, #content, #footnotes, #footer { width: 100%; margin-left: auto; margin-right: auto; margin-top: 0; margin-bottom: 0; max-width: 62.5em; *zoom: 1; position: relative; padding-left: 1.5em; padding-right: 1.5em; } 294 | #header:before, #header:after, #content:before, #content:after, #footnotes:before, #footnotes:after, #footer:before, #footer:after { content: " "; display: table; } 295 | #header:after, #content:after, #footnotes:after, #footer:after { clear: both; } 296 | 297 | #content { margin-top: 1.25em; } 298 | 299 | #content:before { content: none; } 300 | 301 | #header > h1:first-child { color: #7b2d00; margin-top: 2.25rem; margin-bottom: 0; } 302 | #header > h1:first-child + #toc { margin-top: 8px; border-top: 1px solid #dddddd; } 303 | #header > h1:only-child, body.toc2 #header > h1:nth-last-child(2) { border-bottom: 1px solid #dddddd; padding-bottom: 8px; } 304 | #header .details { border-bottom: 1px solid #dddddd; line-height: 1.45; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 0.25em; color: #e15200; display: -ms-flexbox; display: -webkit-flex; display: flex; -ms-flex-flow: row wrap; -webkit-flex-flow: row wrap; flex-flow: row wrap; } 305 | #header .details span:first-child { margin-left: -0.125em; } 306 | #header .details span.email a { color: #333333; } 307 | #header .details br { display: none; } 308 | #header .details br + span:before { content: "\00a0\2013\00a0"; } 309 | #header .details br + span.author:before { content: "\00a0\22c5\00a0"; color: #333333; } 310 | #header .details br + span#revremark:before { content: "\00a0|\00a0"; } 311 | #header #revnumber { text-transform: capitalize; } 312 | #header #revnumber:after { content: "\00a0"; } 313 | 314 | #content > h1:first-child:not([class]) { color: #7b2d00; border-bottom: 1px solid #dddddd; padding-bottom: 8px; margin-top: 0; padding-top: 1rem; margin-bottom: 1.25rem; } 315 | 316 | #toc { border-bottom: 0 solid #dddddd; padding-bottom: 0.5em; } 317 | #toc > ul { margin-left: 0.125em; } 318 | #toc ul.sectlevel0 > li > a { font-style: italic; } 319 | #toc ul.sectlevel0 ul.sectlevel1 { margin: 0.5em 0; } 320 | #toc ul { font-family: Arial, sans-serif; list-style-type: none; } 321 | #toc a { text-decoration: none; } 322 | #toc a:active { text-decoration: underline; } 323 | 324 | #toctitle { color: #003b6b; font-size: 1.2em; } 325 | 326 | @media only screen and (min-width: 768px) { #toctitle { font-size: 1.375em; } 327 | body.toc2 { padding-left: 15em; padding-right: 0; } 328 | #toc.toc2 { margin-top: 0 !important; background-color: white; position: fixed; width: 15em; left: 0; top: 0; border-right: 1px solid #dddddd; border-top-width: 0 !important; border-bottom-width: 0 !important; z-index: 1000; padding: 1.25em 1em; height: 100%; overflow: auto; } 329 | #toc.toc2 #toctitle { margin-top: 0; font-size: 1.2em; } 330 | #toc.toc2 > ul { font-size: 0.9em; margin-bottom: 0; } 331 | #toc.toc2 ul ul { margin-left: 0; padding-left: 1em; } 332 | #toc.toc2 ul.sectlevel0 ul.sectlevel1 { padding-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; } 333 | body.toc2.toc-right { padding-left: 0; padding-right: 15em; } 334 | body.toc2.toc-right #toc.toc2 { border-right-width: 0; border-left: 1px solid #dddddd; left: auto; right: 0; } } 335 | @media only screen and (min-width: 1280px) { body.toc2 { padding-left: 20em; padding-right: 0; } 336 | #toc.toc2 { width: 20em; } 337 | #toc.toc2 #toctitle { font-size: 1.375em; } 338 | #toc.toc2 > ul { font-size: 0.95em; } 339 | #toc.toc2 ul ul { padding-left: 1.25em; } 340 | body.toc2.toc-right { padding-left: 0; padding-right: 20em; } } 341 | #content #toc { border-style: solid; border-width: 1px; border-color: #e6e6e6; margin-bottom: 1.25em; padding: 1.25em; background: white; -webkit-border-radius: 0; border-radius: 0; } 342 | #content #toc > :first-child { margin-top: 0; } 343 | #content #toc > :last-child { margin-bottom: 0; } 344 | 345 | #footer { max-width: 100%; background-color: none; padding: 1.25em; } 346 | 347 | #footer-text { color: black; line-height: 1.44; } 348 | 349 | .sect1 { padding-bottom: 0.625em; } 350 | 351 | @media only screen and (min-width: 768px) { .sect1 { padding-bottom: 1.25em; } } 352 | .sect1 + .sect1 { border-top: 0 solid #dddddd; } 353 | 354 | #content h1 > a.anchor, h2 > a.anchor, h3 > a.anchor, #toctitle > a.anchor, .sidebarblock > .content > .title > a.anchor, h4 > a.anchor, h5 > a.anchor, h6 > a.anchor { position: absolute; z-index: 1001; width: 1.5ex; margin-left: -1.5ex; display: block; text-decoration: none !important; visibility: hidden; text-align: center; font-weight: normal; } 355 | #content h1 > a.anchor:before, h2 > a.anchor:before, h3 > a.anchor:before, #toctitle > a.anchor:before, .sidebarblock > .content > .title > a.anchor:before, h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before { content: "\00A7"; font-size: 0.85em; display: block; padding-top: 0.1em; } 356 | #content h1:hover > a.anchor, #content h1 > a.anchor:hover, h2:hover > a.anchor, h2 > a.anchor:hover, h3:hover > a.anchor, #toctitle:hover > a.anchor, .sidebarblock > .content > .title:hover > a.anchor, h3 > a.anchor:hover, #toctitle > a.anchor:hover, .sidebarblock > .content > .title > a.anchor:hover, h4:hover > a.anchor, h4 > a.anchor:hover, h5:hover > a.anchor, h5 > a.anchor:hover, h6:hover > a.anchor, h6 > a.anchor:hover { visibility: visible; } 357 | #content h1 > a.link, h2 > a.link, h3 > a.link, #toctitle > a.link, .sidebarblock > .content > .title > a.link, h4 > a.link, h5 > a.link, h6 > a.link { color: #7b2d00; text-decoration: none; } 358 | #content h1 > a.link:hover, h2 > a.link:hover, h3 > a.link:hover, #toctitle > a.link:hover, .sidebarblock > .content > .title > a.link:hover, h4 > a.link:hover, h5 > a.link:hover, h6 > a.link:hover { color: #622400; } 359 | 360 | .audioblock, .imageblock, .literalblock, .listingblock, .stemblock, .videoblock { margin-bottom: 1.25em; } 361 | 362 | .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { text-rendering: optimizeLegibility; text-align: left; } 363 | 364 | table.tableblock > caption.title { white-space: nowrap; overflow: visible; max-width: 0; } 365 | 366 | .paragraph.lead > p, #preamble > .sectionbody > .paragraph:first-of-type p { color: #7b2d00; } 367 | 368 | table.tableblock #preamble > .sectionbody > .paragraph:first-of-type p { font-size: inherit; } 369 | 370 | .admonitionblock > table { border-collapse: separate; border: 0; background: none; width: 100%; } 371 | .admonitionblock > table td.icon { text-align: center; width: 80px; } 372 | .admonitionblock > table td.icon img { max-width: none; } 373 | .admonitionblock > table td.icon .title { font-weight: bold; font-family: Arial, sans-serif; text-transform: uppercase; } 374 | .admonitionblock > table td.content { padding-left: 1.125em; padding-right: 1.25em; border-left: 1px solid #dddddd; color: #e15200; } 375 | .admonitionblock > table td.content > :last-child > :last-child { margin-bottom: 0; } 376 | 377 | .exampleblock > .content { border-style: solid; border-width: 1px; border-color: #e6e6e6; margin-bottom: 1.25em; padding: 1.25em; background: white; -webkit-border-radius: 0; border-radius: 0; } 378 | .exampleblock > .content > :first-child { margin-top: 0; } 379 | .exampleblock > .content > :last-child { margin-bottom: 0; } 380 | 381 | .sidebarblock { border-style: solid; border-width: 1px; border-color: #e6e6e6; margin-bottom: 1.25em; padding: 1.25em; background: white; -webkit-border-radius: 0; border-radius: 0; } 382 | .sidebarblock > :first-child { margin-top: 0; } 383 | .sidebarblock > :last-child { margin-bottom: 0; } 384 | .sidebarblock > .content > .title { color: #003b6b; margin-top: 0; } 385 | 386 | .exampleblock > .content > :last-child > :last-child, .exampleblock > .content .olist > ol > li:last-child > :last-child, .exampleblock > .content .ulist > ul > li:last-child > :last-child, .exampleblock > .content .qlist > ol > li:last-child > :last-child, .sidebarblock > .content > :last-child > :last-child, .sidebarblock > .content .olist > ol > li:last-child > :last-child, .sidebarblock > .content .ulist > ul > li:last-child > :last-child, .sidebarblock > .content .qlist > ol > li:last-child > :last-child { margin-bottom: 0; } 387 | 388 | .literalblock pre, .listingblock pre:not(.highlight), .listingblock pre[class="highlight"], .listingblock pre[class^="highlight "], .listingblock pre.CodeRay, .listingblock pre.prettyprint { background: #eeeeee; } 389 | .sidebarblock .literalblock pre, .sidebarblock .listingblock pre:not(.highlight), .sidebarblock .listingblock pre[class="highlight"], .sidebarblock .listingblock pre[class^="highlight "], .sidebarblock .listingblock pre.CodeRay, .sidebarblock .listingblock pre.prettyprint { background: #f2f1f1; } 390 | 391 | .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { border: 1px dashed #666666; -webkit-border-radius: 0; border-radius: 0; word-wrap: break-word; padding: 1.25em 1.5625em 1.125em 1.5625em; font-size: 0.8125em; } 392 | .literalblock pre.nowrap, .literalblock pre[class].nowrap, .listingblock pre.nowrap, .listingblock pre[class].nowrap { overflow-x: auto; white-space: pre; word-wrap: normal; } 393 | @media only screen and (min-width: 768px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 0.90625em; } } 394 | @media only screen and (min-width: 1280px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 1em; } } 395 | 396 | .literalblock.output pre { color: #eeeeee; background-color: black; } 397 | 398 | .listingblock pre.highlightjs { padding: 0; } 399 | .listingblock pre.highlightjs > code { padding: 1.25em 1.5625em 1.125em 1.5625em; -webkit-border-radius: 0; border-radius: 0; } 400 | 401 | .listingblock > .content { position: relative; } 402 | 403 | .listingblock code[data-lang]:before { display: none; content: attr(data-lang); position: absolute; font-size: 0.75em; top: 0.425rem; right: 0.5rem; line-height: 1; text-transform: uppercase; color: #999; } 404 | 405 | .listingblock:hover code[data-lang]:before { display: block; } 406 | 407 | .listingblock.terminal pre .command:before { content: attr(data-prompt); padding-right: 0.5em; color: #999; } 408 | 409 | .listingblock.terminal pre .command:not([data-prompt]):before { content: "$"; } 410 | 411 | table.pyhltable { border-collapse: separate; border: 0; margin-bottom: 0; background: none; } 412 | 413 | table.pyhltable td { vertical-align: top; padding-top: 0; padding-bottom: 0; } 414 | 415 | table.pyhltable td.code { padding-left: .75em; padding-right: 0; } 416 | 417 | pre.pygments .lineno, table.pyhltable td:not(.code) { color: #999; padding-left: 0; padding-right: .5em; border-right: 1px solid #dddddd; } 418 | 419 | pre.pygments .lineno { display: inline-block; margin-right: .25em; } 420 | 421 | table.pyhltable .linenodiv { background: none !important; padding-right: 0 !important; } 422 | 423 | .quoteblock { margin: 0 1em 0.75em 1.5em; display: table; } 424 | .quoteblock > .title { margin-left: -1.5em; margin-bottom: 0.75em; } 425 | .quoteblock blockquote, .quoteblock blockquote p { color: #333333; font-size: 1.15rem; line-height: 1.75; word-spacing: 0.1em; letter-spacing: 0; font-style: italic; text-align: justify; } 426 | .quoteblock blockquote { margin: 0; padding: 0; border: 0; } 427 | .quoteblock blockquote:before { content: "\201c"; float: left; font-size: 2.75em; font-weight: bold; line-height: 0.6em; margin-left: -0.6em; color: #003b6b; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); } 428 | .quoteblock blockquote > .paragraph:last-child p { margin-bottom: 0; } 429 | .quoteblock .attribution { margin-top: 0.5em; margin-right: 0.5ex; text-align: right; } 430 | .quoteblock .quoteblock { margin-left: 0; margin-right: 0; padding: 0.5em 0; border-left: 3px solid #e15200; } 431 | .quoteblock .quoteblock blockquote { padding: 0 0 0 0.75em; } 432 | .quoteblock .quoteblock blockquote:before { display: none; } 433 | 434 | .verseblock { margin: 0 1em 0.75em 1em; } 435 | .verseblock pre { font-family: "Open Sans", "DejaVu Sans", sans; font-size: 1.15rem; color: #333333; font-weight: 300; text-rendering: optimizeLegibility; } 436 | .verseblock pre strong { font-weight: 400; } 437 | .verseblock .attribution { margin-top: 1.25rem; margin-left: 0.5ex; } 438 | 439 | .quoteblock .attribution, .verseblock .attribution { font-size: 0.8125em; line-height: 1.45; font-style: italic; } 440 | .quoteblock .attribution br, .verseblock .attribution br { display: none; } 441 | .quoteblock .attribution cite, .verseblock .attribution cite { display: block; letter-spacing: -0.05em; color: #e15200; } 442 | 443 | .quoteblock.abstract { margin: 0 0 0.75em 0; display: block; } 444 | .quoteblock.abstract blockquote, .quoteblock.abstract blockquote p { text-align: left; word-spacing: 0; } 445 | .quoteblock.abstract blockquote:before, .quoteblock.abstract blockquote p:first-of-type:before { display: none; } 446 | 447 | table.tableblock { max-width: 100%; border-collapse: separate; } 448 | table.tableblock td > .paragraph:last-child p > p:last-child, table.tableblock th > p:last-child, table.tableblock td > p:last-child { margin-bottom: 0; } 449 | 450 | table.spread { width: 100%; } 451 | 452 | table.tableblock, th.tableblock, td.tableblock { border: 0 solid #d8d8ce; } 453 | 454 | table.grid-all th.tableblock, table.grid-all td.tableblock { border-width: 0 1px 1px 0; } 455 | 456 | table.grid-all tfoot > tr > th.tableblock, table.grid-all tfoot > tr > td.tableblock { border-width: 1px 1px 0 0; } 457 | 458 | table.grid-cols th.tableblock, table.grid-cols td.tableblock { border-width: 0 1px 0 0; } 459 | 460 | table.grid-all * > tr > .tableblock:last-child, table.grid-cols * > tr > .tableblock:last-child { border-right-width: 0; } 461 | 462 | table.grid-rows th.tableblock, table.grid-rows td.tableblock { border-width: 0 0 1px 0; } 463 | 464 | table.grid-all tbody > tr:last-child > th.tableblock, table.grid-all tbody > tr:last-child > td.tableblock, table.grid-all thead:last-child > tr > th.tableblock, table.grid-rows tbody > tr:last-child > th.tableblock, table.grid-rows tbody > tr:last-child > td.tableblock, table.grid-rows thead:last-child > tr > th.tableblock { border-bottom-width: 0; } 465 | 466 | table.grid-rows tfoot > tr > th.tableblock, table.grid-rows tfoot > tr > td.tableblock { border-width: 1px 0 0 0; } 467 | 468 | table.frame-all { border-width: 1px; } 469 | 470 | table.frame-sides { border-width: 0 1px; } 471 | 472 | table.frame-topbot { border-width: 1px 0; } 473 | 474 | th.halign-left, td.halign-left { text-align: left; } 475 | 476 | th.halign-right, td.halign-right { text-align: right; } 477 | 478 | th.halign-center, td.halign-center { text-align: center; } 479 | 480 | th.valign-top, td.valign-top { vertical-align: top; } 481 | 482 | th.valign-bottom, td.valign-bottom { vertical-align: bottom; } 483 | 484 | th.valign-middle, td.valign-middle { vertical-align: middle; } 485 | 486 | table thead th, table tfoot th { font-weight: bold; } 487 | 488 | tbody tr th { display: table-cell; line-height: 1.4; background: -webkit-linear-gradient(top, #add386, #90b66a); } 489 | 490 | tbody tr th, tbody tr th p, tfoot tr th, tfoot tr th p { color: white; font-weight: bold; } 491 | 492 | p.tableblock > code:only-child { background: none; padding: 0; } 493 | 494 | p.tableblock { font-size: 1em; } 495 | 496 | td > div.verse { white-space: pre; } 497 | 498 | ol { margin-left: 1.75em; } 499 | 500 | ul li ol { margin-left: 1.5em; } 501 | 502 | dl dd { margin-left: 1.125em; } 503 | 504 | dl dd:last-child, dl dd:last-child > :last-child { margin-bottom: 0; } 505 | 506 | ol > li p, ul > li p, ul dd, ol dd, .olist .olist, .ulist .ulist, .ulist .olist, .olist .ulist { margin-bottom: 0.375em; } 507 | 508 | ul.unstyled, ol.unnumbered, ul.checklist, ul.none { list-style-type: none; } 509 | 510 | ul.unstyled, ol.unnumbered, ul.checklist { margin-left: 0.625em; } 511 | 512 | ul.checklist li > p:first-child > .fa-square-o:first-child, ul.checklist li > p:first-child > .fa-check-square-o:first-child { width: 1em; font-size: 0.85em; } 513 | 514 | ul.checklist li > p:first-child > input[type="checkbox"]:first-child { width: 1em; position: relative; top: 1px; } 515 | 516 | ul.inline { margin: 0 auto 0.375em auto; margin-left: -1.375em; margin-right: 0; padding: 0; list-style: none; overflow: hidden; } 517 | ul.inline > li { list-style: none; float: left; margin-left: 1.375em; display: block; } 518 | ul.inline > li > * { display: block; } 519 | 520 | .unstyled dl dt { font-weight: normal; font-style: normal; } 521 | 522 | ol.arabic { list-style-type: decimal; } 523 | 524 | ol.decimal { list-style-type: decimal-leading-zero; } 525 | 526 | ol.loweralpha { list-style-type: lower-alpha; } 527 | 528 | ol.upperalpha { list-style-type: upper-alpha; } 529 | 530 | ol.lowerroman { list-style-type: lower-roman; } 531 | 532 | ol.upperroman { list-style-type: upper-roman; } 533 | 534 | ol.lowergreek { list-style-type: lower-greek; } 535 | 536 | .hdlist > table, .colist > table { border: 0; background: none; } 537 | .hdlist > table > tbody > tr, .colist > table > tbody > tr { background: none; } 538 | 539 | td.hdlist1 { padding-right: .75em; font-weight: bold; } 540 | 541 | td.hdlist1, td.hdlist2 { vertical-align: top; } 542 | 543 | .literalblock + .colist, .listingblock + .colist { margin-top: -0.5em; } 544 | 545 | .colist > table tr > td:first-of-type { padding: 0 0.75em; line-height: 1; } 546 | .colist > table tr > td:last-of-type { padding: 0.25em 0; } 547 | 548 | .thumb, .th { line-height: 0; display: inline-block; border: solid 4px white; -webkit-box-shadow: 0 0 0 1px #dddddd; box-shadow: 0 0 0 1px #dddddd; } 549 | 550 | .imageblock.left, .imageblock[style*="float: left"] { margin: 0.25em 0.625em 1.25em 0; } 551 | .imageblock.right, .imageblock[style*="float: right"] { margin: 0.25em 0 1.25em 0.625em; } 552 | .imageblock > .title { margin-bottom: 0; } 553 | .imageblock.thumb, .imageblock.th { border-width: 6px; } 554 | .imageblock.thumb > .title, .imageblock.th > .title { padding: 0 0.125em; } 555 | 556 | .image.left, .image.right { margin-top: 0.25em; margin-bottom: 0.25em; display: inline-block; line-height: 0; } 557 | .image.left { margin-right: 0.625em; } 558 | .image.right { margin-left: 0.625em; } 559 | 560 | a.image { text-decoration: none; } 561 | 562 | span.footnote, span.footnoteref { vertical-align: super; font-size: 0.875em; } 563 | span.footnote a, span.footnoteref a { text-decoration: none; } 564 | span.footnote a:active, span.footnoteref a:active { text-decoration: underline; } 565 | 566 | #footnotes { padding-top: 0.75em; padding-bottom: 0.75em; margin-bottom: 0.625em; } 567 | #footnotes hr { width: 20%; min-width: 6.25em; margin: -.25em 0 .75em 0; border-width: 1px 0 0 0; } 568 | #footnotes .footnote { padding: 0 0.375em; line-height: 1.3; font-size: 0.875em; margin-left: 1.2em; text-indent: -1.2em; margin-bottom: .2em; } 569 | #footnotes .footnote a:first-of-type { font-weight: bold; text-decoration: none; } 570 | #footnotes .footnote:last-of-type { margin-bottom: 0; } 571 | 572 | #content #footnotes { margin-top: -0.625em; margin-bottom: 0; padding: 0.75em 0; } 573 | 574 | .gist .file-data > table { border: 0; background: #fff; width: 100%; margin-bottom: 0; } 575 | .gist .file-data > table td.line-data { width: 99%; } 576 | 577 | div.unbreakable { page-break-inside: avoid; } 578 | 579 | .big { font-size: larger; } 580 | 581 | .small { font-size: smaller; } 582 | 583 | .underline { text-decoration: underline; } 584 | 585 | .overline { text-decoration: overline; } 586 | 587 | .line-through { text-decoration: line-through; } 588 | 589 | .aqua { color: #00bfbf; } 590 | 591 | .aqua-background { background-color: #00fafa; } 592 | 593 | .black { color: black; } 594 | 595 | .black-background { background-color: black; } 596 | 597 | .blue { color: #0000bf; } 598 | 599 | .blue-background { background-color: #0000fa; } 600 | 601 | .fuchsia { color: #bf00bf; } 602 | 603 | .fuchsia-background { background-color: #fa00fa; } 604 | 605 | .gray { color: #606060; } 606 | 607 | .gray-background { background-color: #7d7d7d; } 608 | 609 | .green { color: #006000; } 610 | 611 | .green-background { background-color: #007d00; } 612 | 613 | .lime { color: #00bf00; } 614 | 615 | .lime-background { background-color: #00fa00; } 616 | 617 | .maroon { color: #600000; } 618 | 619 | .maroon-background { background-color: #7d0000; } 620 | 621 | .navy { color: #000060; } 622 | 623 | .navy-background { background-color: #00007d; } 624 | 625 | .olive { color: #606000; } 626 | 627 | .olive-background { background-color: #7d7d00; } 628 | 629 | .purple { color: #600060; } 630 | 631 | .purple-background { background-color: #7d007d; } 632 | 633 | .red { color: #bf0000; } 634 | 635 | .red-background { background-color: #fa0000; } 636 | 637 | .silver { color: #909090; } 638 | 639 | .silver-background { background-color: #bcbcbc; } 640 | 641 | .teal { color: #006060; } 642 | 643 | .teal-background { background-color: #007d7d; } 644 | 645 | .white { color: #bfbfbf; } 646 | 647 | .white-background { background-color: #fafafa; } 648 | 649 | .yellow { color: #bfbf00; } 650 | 651 | .yellow-background { background-color: #fafa00; } 652 | 653 | span.icon > .fa { cursor: default; } 654 | 655 | .admonitionblock td.icon [class^="fa icon-"] { font-size: 2.5em; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); cursor: default; } 656 | .admonitionblock td.icon .icon-note:before { content: "\f05a"; color: #004176; } 657 | .admonitionblock td.icon .icon-tip:before { content: "\f0eb"; text-shadow: 1px 1px 2px rgba(155, 155, 0, 0.8); color: #111; } 658 | .admonitionblock td.icon .icon-warning:before { content: "\f071"; color: #bf6900; } 659 | .admonitionblock td.icon .icon-caution:before { content: "\f06d"; color: #bf3400; } 660 | .admonitionblock td.icon .icon-important:before { content: "\f06a"; color: #bf0000; } 661 | 662 | .conum[data-value] { display: inline-block; color: #fff !important; background-color: black; -webkit-border-radius: 100px; border-radius: 100px; text-align: center; font-size: 0.75em; width: 1.67em; height: 1.67em; line-height: 1.67em; font-family: "Open Sans", "DejaVu Sans", sans-serif; font-style: normal; font-weight: bold; } 663 | .conum[data-value] * { color: #fff !important; } 664 | .conum[data-value] + b { display: none; } 665 | .conum[data-value]:after { content: attr(data-value); } 666 | pre .conum[data-value] { position: relative; top: -0.125em; } 667 | 668 | b.conum * { color: inherit !important; } 669 | 670 | .conum:not([data-value]):empty { display: none; } 671 | 672 | h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { border-bottom: 1px solid #dddddd; } 673 | 674 | .sect1 { padding-bottom: 0; } 675 | 676 | #toctitle { color: #00406F; font-weight: normal; margin-top: 1.5em; } 677 | 678 | .sidebarblock { border-color: #aaa; } 679 | 680 | code { -webkit-border-radius: 4px; border-radius: 4px; } 681 | 682 | p.tableblock.header { color: #6d6e71; } 683 | 684 | .literalblock pre, .listingblock pre { background: #eeeeee; } 685 | -------------------------------------------------------------------------------- /doc/color.adoc: -------------------------------------------------------------------------------- 1 | 2 | === NanoVG.Color 3 | 4 | Color creation and manipulation 5 | 6 | [[Attributes]] 7 | * *NanoVG.Color* attributes: 8 | 9 | ** *r* [small]#Reader for the red component.# 10 | ** *g* [small]#Reader for the green component.# 11 | ** *b* [small]#Reader for the blue component.# 12 | ** *a* [small]#Reader for the alpha(opacity) component.# 13 | 14 | [[parse]] 15 | * *parse*(input:Number|String) 16 | [small]#Tries to parse input to a valid color.# 17 | 18 | [[rgb]] 19 | * color = *rgb*(r,g,b,a) 20 | [small]#Creates a color with specified components.# 21 | 22 | [[rgb8]] 23 | * color = *rgb8*(r,g,b,a) 24 | [small]#Creates a color with specified components.# 25 | 26 | [[hsl]] 27 | * color = *hsl*(h,s,l,a) 28 | [small]#Creates a color with specified components.# 29 | 30 | [[lerp]] 31 | * color = *lerp*(c0,c1,u) 32 | [small]#Creates a color with specified components.# 33 | 34 | [[trans]] 35 | * trans [small]#TODO:.# 36 | 37 | [[torgb]] 38 | * torgb [small]#TODO:.# 39 | 40 | [[torgb8]] 41 | * torgb8 [small]#TODO:.# 42 | -------------------------------------------------------------------------------- /doc/context.adoc: -------------------------------------------------------------------------------- 1 | 2 | To use lua-nanovg, you should first require it, after that, you will 3 | get a function to create context for drawing: 4 | 5 | [source,lua,indent=1] 6 | ---- 7 | local ctx = require("nvg") 8 | ---- 9 | 10 | 11 | You can pass some arguments to this function, to specify the atlas 12 | size and/or edge AA (anti-alias) flags: 13 | 14 | [source,lua,indent=1] 15 | ---- 16 | local ctx = require 'nvg' (256, 256, "AA") -- default 17 | local ctx = require 'nvg' (256, 256) -- no edge anti-alias 18 | local ctx = require 'nvg' "AA" -- use edge anti-alias, and default atlas size. 19 | ---- 20 | 21 | After you get context, you can draw with it. All APIs will exactly 22 | same with HTML5 canvas. 23 | 24 | [source,lua,indent=1] 25 | ---- 26 | ctx:beginFrame() 27 | ctx:endFrame() 28 | ctx:color("name") 29 | ctx:color("#rgb") 30 | ctx:color("#argb") 31 | ctx:color("#rrggbb") 32 | ctx:color("#aarrggbb") 33 | ctx:color(r,g,b) 34 | ctx:color(r,g,b,a) 35 | ctx:color("HSL", h,s,l); 36 | ctx:color("HSL", h,s,l,a); 37 | 38 | ctx:save() 39 | ctx:restore() 40 | ctx:reset() 41 | 42 | ctx.strokeStyle = color|paint; 43 | ctx.fillStyle = color|paint; 44 | 45 | ctx.lineCap = "butt|round|square"; 46 | ctx.lineJoin = "round|bevel|miter"; 47 | ctx.lineWidth = width; 48 | ctx.miterLimit = number; 49 | 50 | ctx:resetTransform() 51 | ctx:scale() 52 | ctx:rotate() 53 | ctx:translate() 54 | ctx:transform() 55 | ctx:setTransform() 56 | 57 | 58 | ctx:image() -> ctx.image.load 59 | ctx:drawImage() 60 | ctx.image.new() 61 | ctx.image.load() 62 | =image.width 63 | =image.height 64 | image:update() 65 | image:delete() 66 | 67 | ctx:gradient() 68 | ctx.gradient.linear() 69 | ctx.gradient.box() 70 | ctx.gradient.radial() 71 | 72 | ctx:scissor() 73 | 74 | ctx.pathWnding = "(solid|hole)|(CCW|CW)"; 75 | ctx:beginPath() 76 | ctx:moveTo() 77 | ctx:lineTo() 78 | ctx:bezierTo() == ctx:bezierCurveTo() 79 | ctx:arcTo() 80 | ctx:closePath() 81 | 82 | ctx:arc() 83 | ctx:rect() 84 | ctx:roundRect() 85 | ctx:ellipse() 86 | ctx:circle() 87 | ctx:fill() 88 | ctx:stroke() 89 | 90 | ctx.font = font; 91 | ctx.textAlign = 92 | ctx.fontBlur = number; 93 | ctx:text() 94 | ctx:measureText() 95 | ---- 96 | 97 | === NanoVG.Context 98 | 99 | Context creation and manipulation 100 | 101 | * The *NanoVG.Context* table contains the following version fields: + 102 | ** *_VERSION*: a string describing the NanoVG version 103 | 104 | 105 | [[new]] 106 | * _inst_ = *new*( ) 107 | [small]#Context constructor.# 108 | 109 | [[font]] 110 | * *font*( ) 111 | [small]#Font setter.# 112 | 113 | [[linearGradient]] 114 | * *linearGradient*(sx, sy, ex, ey, iColor, oColor) 115 | [small]#Defines a linear gradient paint.# 116 | 117 | [[boxGradient]] 118 | * *boxGradient*(x, y, w, h, r, f, iColor, oColor) 119 | [small]#Defines a rectangular gradient paint.# 120 | 121 | [[radialGradient]] 122 | * *radialGradient*(cx, cy, inr, outr, iColor, oColor) 123 | [small]#Defines a radial gradient paint.# 124 | 125 | [[clear]] 126 | * *clear*(color) 127 | [small]#Clears the context using the specified color { r=0, g=0, b=0, a=0 }.# 128 | 129 | [[beginFrame]] 130 | * *beginFrame*() 131 | [small]#Starts a frame scope.# 132 | 133 | [[cancelFrame]] 134 | * *cancelFrame*() 135 | [small]#Cancels a frame scope.# 136 | 137 | [[endFrame]] 138 | * *endFrame*() 139 | [small]#Flushes a frame scope.# 140 | 141 | [[save]] 142 | * *save*() 143 | [small]#Saves the context.# 144 | 145 | [[restore]] 146 | * *restore*() 147 | [small]#Restores the context.# 148 | 149 | [[reset]] 150 | * *reset*() 151 | [small]#Resets the context.# 152 | 153 | [[currentTransform]] 154 | * a, b, c, d, e, f = *currentTransform*() 155 | [small]#Getter for the current transformation.# 156 | 157 | [[transform]] 158 | * *transform*(a, b, c, d, e, f) 159 | [small]#Setter for the current transformation.# 160 | 161 | [[translate]] 162 | * *translate*(x, y) 163 | [small]#Translate by x horizontally and y vertically.# 164 | 165 | [[scale]] 166 | * *scale*(x, y) 167 | [small]#Scale with x horizontally and y vertically.# 168 | 169 | [[rotate]] 170 | * *rotate*(angle) 171 | [small]#Rotate by angle.# 172 | 173 | [[skew]] 174 | * *skew*(x, y) 175 | [small]#Skew with x horizontally and y vertically.# 176 | 177 | [[resetScissor]] 178 | * *resetScissor*() 179 | [small]#Resets the scissor.# 180 | 181 | [[scissor]] 182 | * *scissor*(x, y, w, h) 183 | [small]#Applies the scissor.# 184 | 185 | [[intersectScissor]] 186 | * *intersectScissor*(x, y, w, h) 187 | [small]#Applies the intersection scissor.# 188 | 189 | [[globalCompositeOperation]] 190 | * *globalCompositeOperation*(enum:CompositeOperation) 191 | [small]#Sets the composite operation.# 192 | 193 | [[globalCompositeBlendFunc]] 194 | * *globalCompositeBlendFunc*(enum:BlendFactor) 195 | [small]#Sets the composite blending function operation.# 196 | 197 | [[globalCompositeBlendFuncSeparate]] 198 | * *globalCompositeBlendFuncSeparate*(enum:BlendFactor) 199 | [small]#Sets the composite blending function operation.# 200 | 201 | [[beginPath]] 202 | * *beginPath*() 203 | [small]#Starts a new path.# 204 | 205 | [[moveTo]] 206 | * *moveTo*(x, y) 207 | [small]#Moves the drawing head.# 208 | 209 | [[lineTo]] 210 | * *lineTo*(x, y) 211 | [small]#Draws a line from the head to the specified coordinates.# 212 | 213 | [[quadraticCurveTo]] 214 | * *quadraticCurveTo*(cx, cy, x, y) 215 | [small]#Draws a quadratic curve from the head to the specified coordinates.# 216 | 217 | [[bezierCurveTo]] 218 | * *bezierCurveTo*(c1x, c1y, c2x, c2y, x, y) 219 | [small]#Draws a bezier curve from the head to the specified coordinates.# 220 | 221 | [[arcTo]] 222 | * *arcTo*(x1, y1, x2, y2, radius) 223 | [small]#Draws an arc from the head to the specified coordinates.# 224 | 225 | [[closePath]] 226 | * *closePath*() 227 | [small]#Closes the previously opened path.# 228 | 229 | [[arc]] 230 | * *arc*(cx, cy, r, a0, a1, dir:ArcDirection) 231 | [small]#Draws an arc from the head to the specified coordinates.# 232 | 233 | [[rect]] 234 | * *rect*(x, y, w, h) 235 | [small]#Draws a rect from the head to the specified coordinates.# 236 | 237 | [[roundedRect]] 238 | * *roundedRect*(x, y, w, h, r1|, r2, r3, r4) 239 | [small]#Draws a rounded rectangle defined by the coordinates.# 240 | 241 | [[ellipse]] 242 | * *ellipse*(cx, cy, rx, ry) 243 | [small]#Draws an ellipse defined by the coordinates.# 244 | 245 | [[circle]] 246 | * *circle*(cx, cy, r) 247 | [small]#Draws a circle defined by the coordinates.# 248 | 249 | [[fill]] 250 | * *fill*() 251 | [small]#TODO.# 252 | 253 | [[stroke]] 254 | * *stroke*() 255 | [small]#TODO.# 256 | 257 | [[text]] 258 | * *text*(x, y, text) 259 | [small]#Draws the text.# 260 | 261 | [[textMetrics]] 262 | * *textMetrics*(ascender, descender, lineHeight) 263 | [small]#Sets the text metrics.# 264 | 265 | [[textBounds]] 266 | * *textBounds*(string|(x, y|, width)) 267 | [small]#Sets the text bounds.# 268 | 269 | [[addFallbackFont]] 270 | * *addFallbackFont*(font, fallbackFont) 271 | [small]#Sets an alternate font for the main font.# 272 | 273 | [[shapeAntiAlias]] 274 | * *shapeAntiAlias*(flag) 275 | [small]#Enable of disable the antialiasing of shapes.# 276 | 277 | [[globalAlpha]] 278 | * *globalAlpha*(a) 279 | [small]#Sets the global scene alpha opacity.# 280 | 281 | [[strokeColor]] 282 | * *strokeColor*(color:Color) 283 | [small]#Sets the stroke color.# 284 | 285 | [[fillColor]] 286 | * *fillColor*(color:Color) 287 | [small]#Sets the fill color.# 288 | 289 | [[strokeStyle]] 290 | * *strokeStyle*(color:Color|paint:Paint) 291 | [small]#Sets the stroke style using a color or a paint.# 292 | 293 | [[fillStyle]] 294 | * *fillStyle*(color:Color|paint:Paint) 295 | [small]#Sets the fill style using a color or a paint.# 296 | 297 | [[miterLimit]] 298 | * *miterLimit*(width) 299 | [small]#Sets the miter width limit.# 300 | 301 | [[lineWidth]] 302 | * *lineWidth*(width) 303 | [small]#Sets the width of the line.# 304 | 305 | [[lineCap]] 306 | * *lineCap*(type:{butt|round|square}) 307 | [small]#Sets the line cap type.# 308 | 309 | [[lineJoin]] 310 | * *lineJoin*(type:{round|bevel|miter}) 311 | [small]#Sets the line join type.# 312 | 313 | [[pathWinding]] 314 | * *pathWinding*(winding:PathWinding) 315 | [small]#Sets the path winding.# 316 | 317 | [[fontFace]] 318 | * *fontFace*(face) 319 | [small]#Sets the font face(family).# 320 | 321 | [[fontSize]] 322 | * *fontSize*(size) 323 | [small]#Sets the dimensions of the font.# 324 | 325 | [[fontBlur]] 326 | * *fontBlur*(blur) 327 | [small]#Sets the amount of blur.# 328 | 329 | [[textAlign]] 330 | * *textAlign*(align:Align) 331 | [small]#Sets the text alignment.# 332 | 333 | [[textLetterSpacing]] 334 | * *textLetterSpacing*(space) 335 | [small]#Sets the width of the space between letters.# 336 | 337 | [[textLineHeight]] 338 | * *textLineHeight*(height) 339 | [small]#Sets the text line height.# 340 | -------------------------------------------------------------------------------- /doc/enums.adoc: -------------------------------------------------------------------------------- 1 | 2 | == Enums and structs 3 | 4 | [[CreateFlags]] 5 | * *CreateFlags* 6 | ** antialias 7 | ** stencil_strokes 8 | ** aa 9 | ** ss 10 | * *CompositeOperation* 11 | ** atop 12 | ** copy 13 | ** destination_atop 14 | ** destination_in 15 | ** destination_out 16 | ** destination_over 17 | ** ligther 18 | ** source_in 19 | ** source_out 20 | ** xor 21 | ** source_over 22 | * *BlendFactor* 23 | ** dst_alpha 24 | ** dst_color 25 | ** one 26 | ** one_minus_dst_alpha 27 | ** one_minus_dst_color 28 | ** one_minus_src_alpha 29 | ** one_minus_src_color 30 | ** src_alpha 31 | ** src_alpha_saturate 32 | ** src_color 33 | ** zero 34 | * *ArcDirection* 35 | ** ccw 36 | ** cc# 37 | * *PathWinding* 38 | ** ccw 39 | ** cc 40 | ** hole 41 | ** solid 42 | * *Align* 43 | ** baseline 44 | ** bottom 45 | ** center 46 | ** left 47 | ** middle 48 | ** right 49 | ** top 50 | * *ImageFlags* 51 | ** flipy 52 | ** mipmaps 53 | ** nearest 54 | ** premulti 55 | ** repeatx 56 | ** repeaty 57 | * *ColorName* 58 | ** aliceblue 59 | ** antiquewhite 60 | ** aqua 61 | ** aquamarine 62 | ** azure 63 | ** beige 64 | ** bisque 65 | ** black 66 | ** blanchedalmond 67 | ** blue 68 | ** blueviolet 69 | ** brown 70 | ** burlywood 71 | ** cadetblue 72 | ** chartreuse 73 | ** chocolate 74 | ** coral 75 | ** cornflowerblue 76 | ** cornsilk 77 | ** crimson 78 | ** cyan 79 | ** darkblue 80 | ** darkcyan 81 | ** darkgoldenrod 82 | ** darkgray 83 | ** darkgreen 84 | ** darkkhaki 85 | ** darkmagenta 86 | ** darkolivegreen 87 | ** darkorange 88 | ** darkorchid 89 | ** darkred 90 | ** darksalmon 91 | ** darkseagreen 92 | ** darkslateblue 93 | ** darkslategray 94 | ** darkturquoise 95 | ** darkviolet 96 | ** deeppink 97 | ** deepskyblue 98 | ** dimgray 99 | ** dodgerblue 100 | ** firebrick 101 | ** floralwhite 102 | ** forestgreen 103 | ** fuchsia 104 | ** gainsboro 105 | ** ghostwhite 106 | ** gold 107 | ** goldenrod 108 | ** gray 109 | ** green 110 | ** greenyellow 111 | ** honeydew 112 | ** hotpink 113 | ** indianred 114 | ** indigo 115 | ** ivory 116 | ** khaki 117 | ** lavender 118 | ** lavenderblush 119 | ** lawngreen 120 | ** lemonchiffon 121 | ** lightblue 122 | ** lightcoral 123 | ** lightcyan 124 | ** lightgoldenrodYellow 125 | ** lightgray 126 | ** lightgreen 127 | ** lightpink 128 | ** lightsalmon 129 | ** lightseagreen 130 | ** lightskyblue 131 | ** lightslategray 132 | ** lightsteelblue 133 | ** lightyellow 134 | ** lime 135 | ** limegreen 136 | ** linen 137 | ** magenta 138 | ** maroon 139 | ** mediumaquamarine 140 | ** mediumblue 141 | ** mediumorchid 142 | ** mediumpurple 143 | ** mediumseagreen 144 | ** mediumslateblue 145 | ** mediumspringgreen 146 | ** mediumturquoise 147 | ** mediumvioletred 148 | ** midnightblue 149 | ** mintcream 150 | ** mistyrose 151 | ** moccasin 152 | ** navajowhite 153 | ** navy 154 | ** oldlace 155 | ** olive 156 | ** olivedrab 157 | ** orange 158 | ** orangered 159 | ** orchid 160 | ** palegoldenrod 161 | ** palegreen 162 | ** paleturquoise 163 | ** palevioletred 164 | ** papayawhip 165 | ** peachpuff 166 | ** peru 167 | ** pink 168 | ** plum 169 | ** powderblue 170 | ** purple 171 | ** red 172 | ** rosybrown 173 | ** royalblue 174 | ** saddlebrown 175 | ** salmon 176 | ** sandybrown 177 | ** seagreen 178 | ** seashell 179 | ** sienna 180 | ** silver 181 | ** skyblue 182 | ** slateblue 183 | ** slategray 184 | ** snow 185 | ** springgreen 186 | ** steelblue 187 | ** tan 188 | ** teal 189 | ** thistle 190 | ** tomato 191 | ** transparent 192 | ** turquoise 193 | ** violet 194 | ** wheat 195 | ** white 196 | ** whitesmoke 197 | ** yellow 198 | ** yellowgreen 199 | -------------------------------------------------------------------------------- /doc/image.adoc: -------------------------------------------------------------------------------- 1 | 2 | === NanoVG.Image 3 | 4 | Image creation and manipulation 5 | 6 | [[Attributes]] 7 | * *NanoVG.image* attributes: 8 | 9 | ** *ox* [small]#Reader for ox coordinate.# 10 | ** *oy* [small]#Reader for oy coordinate.# 11 | ** *ex* [small]#Reader for ex coordinate.# 12 | ** *ey* [small]#Reader for ey coordinate.# 13 | ** *angle* [small]#Reader for angle coordinate.# 14 | ** *alpha* [small]#Reader for alpha property.# 15 | ** *image* [small]#Reader for image pointer.# 16 | ** *repeat* [small]#Flag if image is to be repeated.# 17 | 18 | [[load]] 19 | * *load*(path, flags:ImageFlags) 20 | [small]#Creates and loads an image from specified path.# 21 | 22 | [[data]] 23 | * *data*(data, flags:ImageFlags) 24 | [small]#Creates and loads an image from data.# 25 | 26 | [[rgba]] 27 | * *rgba*(w, h, flags:ImageFlags, data:string) 28 | [small]#Creates and loads a rgba image from data.# 29 | 30 | [[update]] 31 | * *update*(data:string) 32 | [small]#Updates image with the bytes specified by data.# 33 | 34 | [[size]] 35 | * w, h = *size*() 36 | [small]#Reads the image size.# 37 | 38 | [[extent]] 39 | * *extent*(ox, oy, ex, ey) 40 | [small]#Sets the image extent.# 41 | 42 | [[width]] 43 | * *width*() 44 | [small]#Reads the image width.# 45 | 46 | [[height]] 47 | * *height*() 48 | [small]#Reads the image height.# 49 | 50 | [[repeat]] 51 | * *repeat*() 52 | [small]#TODO:.# 53 | 54 | [[angle]] 55 | * *angle*() 56 | [small]#TODO:.# 57 | 58 | [[alpha]] 59 | * *alpha*() 60 | [small]#TODO:.# 61 | -------------------------------------------------------------------------------- /doc/index.adoc: -------------------------------------------------------------------------------- 1 | = lua-nanovg Reference Manual 2 | Xavier Wang 3 | v1.0, 2018-08-06 4 | :toc: left 5 | :toclevels: 3 6 | :stylesdir: ./ 7 | :stylesheet: colony.css 8 | :source-highlighter: pygments 9 | :pygments-style: autumn 10 | :source-language: lua 11 | :examplesdir: ../examples 12 | 13 | image::powered-by-lua.gif[Lua logo, link=http://www.lua.org] 14 | 15 | include::preface.adoc[] 16 | 17 | include::bindings.adoc[] 18 | include::enums.adoc[] 19 | -------------------------------------------------------------------------------- /doc/powered-by-lua.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/starwing/lua-nanovg/85b3adbeae51deea0b596d36981540064d91e0b8/doc/powered-by-lua.gif -------------------------------------------------------------------------------- /doc/preface.adoc: -------------------------------------------------------------------------------- 1 | 2 | == Preface 3 | 4 | This is the reference manual of *lua-nanovg*, which is a 5 | http://www.lua.org[*Lua*] binding library for https://github.com/memononen/nanovg[*NanoVG*] and for https://github.com/memononen/nanosvg[*NanoSVG*]. 6 | footnote:[ 7 | This manual is written in 8 | http://www.methods.co.nz/asciidoc/[AsciiDoc], rendered with 9 | http://asciidoctor.org/[AsciiDoctor] and a CSS from the 10 | https://github.com/asciidoctor/asciidoctor-stylesheet-factory[AsciiDoctor Stylesheet Factory]. 11 | The PDF version is produced with 12 | https://github.com/asciidoctor/asciidoctor-pdf[AsciiDoctor-Pdf].] 13 | 14 | It is assumed that the reader is familiar with NanoVG, NanoSVG, GLFW(through https://github.com/stetre/moonglfw[*moonglfw*]) and the Lua programming language. 15 | 16 | For convenience of reference, this document contains external (deep) links to the 17 | http://www.lua.org/manual/5.3/manual.html[Lua Reference Manual] and the 18 | http://www.glfw.org/documentation.html[GLFW documentation]. 19 | 20 | === Getting and installing 21 | 22 | For installation intructions, refer to the README file in the 23 | https://github.com/starwing/lua-nanovg[*lua-nanovg official repository*] 24 | on GitHub. 25 | 26 | //// 27 | The *official repository* of lua-nanovg is on GitHub at the following link: 28 | *https://github.com/starwing/lua-nanovg* . 29 | 30 | lua-nanovg runs on GNU/Linux and requires 31 | *http://www.lua.org[Lua]* version 5.3 or greater, and 32 | *http://www.glfw.org/download.html[GLFW]* version 3.1 or greater. 33 | 34 | To install lua-nanovg, download the 35 | https://github.com/starwing/lua-nanovg/releases[latest release] and do the following: 36 | 37 | [source,shell] 38 | ---- 39 | # ... download lua-nanovg-0.1.tar.gz ... 40 | [ ]$ tar -zxpvf lua-nanovg-0.1.tar.gz 41 | [ ]$ cd lua-nanovg-0.1 42 | [lua-nanovg-0.1]$ make 43 | [lua-nanovg-0.1]$ make check 44 | [lua-nanovg-0.1]$ sudo make install 45 | ---- 46 | 47 | The _$make check_ command shows you what will be installed and where (please read 48 | its output before executing _$make install_). 49 | By default, lua-nanovg installs its components in subdirectories of `/usr/local/` 50 | (and creates such directories, if needed). 51 | This behaviour can be changed by defining PREFIX with the desired alternative 52 | base installation directory. For example, this will install the components 53 | in `/home/joe/local`: 54 | 55 | [source,shell] 56 | ---- 57 | [lua-nanovg-0.1]$ make 58 | [lua-nanovg-0.1]$ make install PREFIX=/home/joe/local 59 | ---- 60 | //// 61 | 62 | === Module organization 63 | 64 | The lua-nanovg module is loaded using Lua's 65 | http://www.lua.org/manual/5.3/manual.html#pdf-require[require]() and 66 | returns a table containing the functions it provides 67 | (as usual with Lua modules). This manual assumes that such 68 | table is named *nvg*, i.e. that it is loaded with: 69 | 70 | [source,lua,indent=1] 71 | ---- 72 | local nvg = require("nvg") 73 | ---- 74 | 75 | but nothing forbids the use of a different name. 76 | 77 | === Examples 78 | 79 | A few examples can be found in the *examples/* directory of the release package. 80 | 81 | === License 82 | 83 | lua-nanovg is released under the *MIT/X11 license* (same as 84 | http://www.lua.org/license.html[Lua], and with the same only requirement to give proper 85 | credits to the original author). 86 | The copyright notice is in the LICENSE file in the base directory 87 | of the https://github.com/starwing/lua-nanovg[official repository] on GitHub. 88 | 89 | [[see-also]] 90 | === See also 91 | 92 | moonglfw is part of https://github.com/stetre/moonlibs[MoonLibs], a collection of 93 | Lua libraries for graphics and audio programming. 94 | -------------------------------------------------------------------------------- /examples/canvas.lua: -------------------------------------------------------------------------------- 1 | local glfw = require "moonglfw" 2 | local nvg = require "nvg" 3 | local canvas = {} 4 | 5 | function canvas.open(w, h, title) 6 | w = glfw.create_window(w, h, title) 7 | glfw.make_context_current(w) 8 | local ctx = nvg.new "antialias" 9 | local win = {} 10 | win.handle = w 11 | win.context = ctx 12 | win.loop = canvas.loop 13 | win.update = canvas.update 14 | return win, ctx 15 | end 16 | 17 | function canvas:update() 18 | self.shouldUpdate = true 19 | return self 20 | end 21 | 22 | function canvas:loop(interval) 23 | local ctx = self.context 24 | local t0 = glfw.get_time() 25 | local prevt = t0 26 | interval = interval or (1000.0/60.0) 27 | w = self.handle 28 | context = self.context 29 | while not glfw.window_should_close(w) do 30 | if glfw.get_key(self.handle, "escape") == 'press' then break end 31 | ww, wh = glfw.get_window_size(w) 32 | local pw, _ = glfw.get_framebuffer_size(w) 33 | local ratio = pw/ww 34 | -- onupdate hook 35 | if self.onupdate then 36 | local nt = glfw.get_time() 37 | self:onupdate(nt - t0, nt - prevt) 38 | prevt = nt 39 | end 40 | -- ondraw hook 41 | if self.ondraw then 42 | context:beginFrame(ww, wh, ratio) 43 | self.ondraw(context) 44 | context:endFrame() 45 | glfw.swap_buffers(w) 46 | self.shouldUpdate = false 47 | end 48 | glfw.wait_events_timeout(interval) 49 | glfw.poll_events() 50 | end 51 | return self 52 | end 53 | 54 | return canvas 55 | -------------------------------------------------------------------------------- /examples/images.lua: -------------------------------------------------------------------------------- 1 | -- Script: hello.lua 2 | local glfw = require "moonglfw" 3 | local nvg = require "nvg" 4 | local color = require "nvg.color" 5 | local pprint = require "pprint" 6 | 7 | -- Allocate a window and deal with OpenGL 8 | w = glfw.create_window(640, 480, "Hello world!") 9 | glfw.make_context_current(w) 10 | -- Only after this we can use nanovg 11 | local ctx = nvg.new "antialias" 12 | -- Load raster assets 13 | raster = ctx:image("nanovg/example/images/image1.jpg") 14 | local dx = (640 - raster.width)/2 15 | local dy = (480 - raster.height)/2 16 | raster:extent(dx, dy , raster.width, raster.height) 17 | -- Load svg assets 18 | vector = ctx:image("nanosvg/example/nano.svg") 19 | local vdx = (640 - vector.width)/2 20 | local vdy = (480 - vector.height)/2 21 | vector:extent(vdx, vdy , vector.width, vector.height) 22 | -- Repeatedly poll for events: 23 | while not glfw.window_should_close(w) do 24 | if glfw.get_key(w, "escape") == 'press' then break end 25 | t = glfw.get_time() 26 | ww, wh = glfw.get_window_size(w) 27 | mx, my = glfw.get_cursor_pos(w) 28 | local pw, _ = glfw.get_framebuffer_size(w) 29 | local ratio = pw/ww 30 | ctx:beginFrame(ww, wh, ratio) 31 | ctx:clear "#4C4C51" 32 | -- Raster 33 | ctx:beginPath() 34 | ctx:rect(dx,dy , raster.width, raster.height) 35 | ctx.fillStyle = raster 36 | ctx:fill() 37 | -- Vector 38 | ctx:beginPath() 39 | ctx:rect(vdx,vdy , vector.width, vector.height) 40 | ctx.fillStyle = vector 41 | ctx:fill() 42 | -- Flush 43 | ctx:endFrame() 44 | glfw.swap_buffers(w) 45 | glfw.poll_events() 46 | end 47 | -------------------------------------------------------------------------------- /examples/test.lua: -------------------------------------------------------------------------------- 1 | local glfw = require "moonglfw" 2 | local nvg = require "nvg" 3 | local color = require "nvg.color" 4 | local pprint = require "pprint" 5 | 6 | 7 | local icons = { 8 | search = "\xF0\x9F\x94\x8D", 9 | circled_cross = "\xE2\x9C\x96", 10 | chevron_right = "\xEE\x9D\x9E", 11 | check = "\xE2\x9C\x93", 12 | login = "\xEE\x9D\x80", 13 | trash = "\xEE\x9C\xA9", 14 | } 15 | 16 | local function loadData(ctx) 17 | ctx:font("sans-bold", "nanovg/example/Roboto-Bold.ttf") 18 | ctx:font("sans", "nanovg/example/Roboto-Regular.ttf") 19 | ctx:font("icons", "nanovg/example/entypo.ttf") 20 | im = ctx:image("nanovg/example/images/image1.jpg") 21 | svg = ctx:image("nanosvg/example/nano.svg") 22 | print("Loaded JPG image width: "..im.width..", height: "..im.height) 23 | print("Loaded SVG image width: "..svg.width..", height: "..svg.height) 24 | return { 25 | context = ctx, 26 | im = im, 27 | svg = svg, 28 | } 29 | end 30 | 31 | local function drawWindow(ctx, title, x, y, w, h) 32 | local cornerRadius = 3.0 33 | ctx:save() 34 | 35 | ctx:beginPath() 36 | ctx:roundedRect(x, y, w, h, cornerRadius) 37 | ctx.fillStyle = "rgba(28,30,34,192)" 38 | ctx:fill() 39 | 40 | 41 | -- drop shadow 42 | ctx:beginPath() 43 | ctx:rect(x-10, y-10, w+20, h+30) 44 | ctx:roundedRect(x, y, w, h, cornerRadius) 45 | ctx.pathWinding = "hole"; 46 | ctx.fillStyle = ctx:boxGradient(x, y+2, w, h, 47 | cornerRadius, 10, "#80000000", "transparent") 48 | ctx:fill() 49 | 50 | -- header 51 | ctx:beginPath() 52 | ctx:roundedRect(x+1, y+1, w-2, 30, cornerRadius-1); 53 | ctx.fillStyle = ctx:linearGradient(x, y, x, y+15, 54 | "#08FFFFFF", "#10000000") 55 | ctx:fill() 56 | 57 | ctx:beginPath() 58 | ctx:moveTo(x+0.5, y+0.5+30) 59 | ctx:lineTo(x+0.5+w-1, y+0.5+30) 60 | ctx.strokeStyle = "#20000000" 61 | ctx:stroke() 62 | 63 | ctx.fontSize = 18 64 | ctx.fontFace = "sans-bold" 65 | ctx.textAlign = "center|middle" 66 | ctx.fontBlur = 2 67 | ctx.fillStyle = "#80000000" 68 | ctx:text(x+w/2, y+16+1, title) 69 | 70 | ctx.fontBlur = 0 71 | ctx.fillStyle = "#A0DCDCDC" 72 | ctx:text(x+w/2, y+16, title) 73 | 74 | ctx:restore() 75 | end 76 | 77 | local function drawSearchBox(ctx, text, x, y, w, h) 78 | local cornerRadius = h/2-1 79 | -- edit 80 | ctx:beginPath() 81 | ctx:roundedRect(x, y, w, h, cornerRadius) 82 | ctx.fillStyle = ctx:boxGradient(x, y+1.5, w, h, h/2, 5, "#20000000", "#5c000000") 83 | ctx:fill() 84 | 85 | ctx.fontSize = h*1.3 86 | ctx.fontFace = "icons" 87 | ctx.fillStyle = "#40FFFFFF" 88 | ctx.textAlign = "center|middle" 89 | ctx:text(x+h*0.55, y+h*0.55, icons.search) 90 | 91 | ctx.fontSize = 20 92 | ctx.fontFace = "sans" 93 | ctx.fillStyle = "#20FFFFFF" 94 | ctx.textAlign = "left|middle" 95 | ctx:text(x+h*1.05, y+h*0.5, text) 96 | 97 | ctx.fontSize = h*1.3 98 | ctx.fontFace = "icons" 99 | ctx.fillStyle = "#20FFFFFF" 100 | ctx.textAlign = "center|middle" 101 | ctx:text(x+w-h*0.55, y+h*0.55, icons.circled_cross) 102 | end 103 | 104 | local function drawDropDown(ctx, text, x, y, w, h) 105 | local cornerRadius = 4.0 106 | 107 | ctx:beginPath() 108 | ctx:roundedRect(x+1, y+1, w-2, h-2, cornerRadius-1) 109 | ctx.fillStyle = ctx:linearGradient(x, y, x, y+h, "#10FFFFFF", "#10000000") 110 | ctx:fill() 111 | 112 | ctx:beginPath() 113 | ctx:roundedRect(x+0.5, y+0.5, w-1, h-1, cornerRadius-0.5) 114 | ctx.strokeStyle = "#30000000" 115 | ctx:stroke() 116 | 117 | ctx.fontSize = 20 118 | ctx.fontFace = "sans" 119 | ctx.fillStyle = "#A0FFFFFF" 120 | ctx.textAlign = "left|middle" 121 | ctx:text(x+h*0.3, y+h*0.5, text) 122 | 123 | ctx.fontSize = h*1.3 124 | ctx.fontFace = "icons" 125 | ctx.fillStyle = "#40FFFFFF" 126 | ctx.textAlign = "center|middle" 127 | ctx:text(x+w-h*0.55, y+h*0.55, icons.chevron_right) 128 | end 129 | 130 | local function drawLabel(ctx, text, x, y, _, h) 131 | ctx.fontSize = 18 132 | ctx.fontFace = "sans" 133 | ctx.fillStyle = "#80FFFFFF" 134 | ctx.textAlign = "left|middle" 135 | ctx:text(x,y+h/2, text) 136 | end 137 | 138 | local function drawEditBoxBase(ctx, x, y, w, h) 139 | ctx:beginPath() 140 | ctx:roundedRect(x+1,y+1, w-2,h-2, 4-1) 141 | ctx.fillStyle = ctx:boxGradient(x+1,y+1+1.5, w-2,h-2, 3,4, "#20FFFFFF", "#20202020") 142 | ctx:fill() 143 | 144 | ctx:beginPath() 145 | ctx:roundedRect(x+0.5, y+0.5, w-1, h-1, 4-0.5) 146 | ctx.strokeStyle = "#30000000" 147 | ctx:stroke() 148 | end 149 | 150 | local function drawEditBox(ctx, text, x, y, w, h) 151 | drawEditBoxBase(ctx, x, y, w, h) 152 | 153 | ctx.fontSize = 20 154 | ctx.fontFace = "sans" 155 | ctx.fillStyle = "#40FFFFFF" 156 | ctx.textAlign = "left|middle" 157 | ctx:text(x+h*0.3, y+h*0.5, text) 158 | end 159 | 160 | local function drawEditBoxNum(ctx, text, units, x, y, w, h) 161 | drawEditBoxBase(ctx, x,y, w,h); 162 | 163 | local uw = ctx:textBounds(units) 164 | 165 | ctx.fontSize = 18 166 | ctx.fontFace = "sans" 167 | ctx.fillStyle = "rgba(255,255,255,64)" 168 | ctx.textAlign = "right|middle" 169 | ctx:text(x+w-h*0.3,y+h*0.5,units) 170 | 171 | ctx.fontSize = 20 172 | ctx.fontFace = "sans" 173 | ctx.fillStyle = "rgba(255,255,255,128)" 174 | ctx.textAlign = "right|middle" 175 | ctx:text(x+w-uw-h*0.5,y+h*0.5,text) 176 | end 177 | 178 | local function drawCheckBox(ctx, text, x, y, _, h) 179 | ctx.fontSize = 18 180 | ctx.fontFace = "sans" 181 | ctx.fillStyle = "rgba(255,255,255,160)" 182 | 183 | ctx.textAlign = "left|middle" 184 | ctx:text(x+28,y+h*0.5,text) 185 | 186 | ctx:beginPath(ctx) 187 | ctx:roundedRect(x+1,y+h*0.5-9, 18,18, 3) 188 | ctx.fillStyle = ctx:boxGradient(x+1,y+h*0.5-9+1, 18,18, 3,3, "rgba(0,0,0,32)", "rgba(0,0,0,92)"); 189 | ctx:fill() 190 | 191 | ctx.fontSize = 40 192 | ctx.fontFace = "icons" 193 | ctx.fillStyle = "rgba(255,255,255,128)" 194 | ctx.textAlign = "center|middle" 195 | ctx:text(x+9+2, y+h*0.5, icons.check) 196 | end 197 | 198 | local function drawButton(ctx, preicon, text, x, y, w, h, col) 199 | local cornerRadius = 4 200 | local iw = 0 201 | col = color.parse(col) 202 | 203 | ctx:beginPath(ctx) 204 | ctx:roundedRect(x+1,y+1, w-2,h-2, cornerRadius-1) 205 | if col ~= 0 then 206 | ctx.fillStyle = col 207 | ctx:fill() 208 | end 209 | ctx.fillStyle = ctx:linearGradient(x,y,x,y+h, 210 | col == 0 and "#10FFFFFF" or "#20FFFFFF", 211 | col == 0 and "#10000000" or "#20000000") 212 | ctx:fill() 213 | 214 | ctx:beginPath() 215 | ctx:roundedRect(x+0.5,y+0.5, w-1,h-1, cornerRadius-0.5) 216 | ctx.strokeStyle = "rgba(0,0,0,48)" 217 | ctx:stroke() 218 | 219 | ctx.fontSize = 20 220 | ctx.fontFace = "sans-bold" 221 | local tw = ctx:textBounds(text) 222 | if preicon then 223 | ctx.fontSize = h*1.3 224 | ctx.fontFace = "icons" 225 | iw = ctx:textBounds(preicon) 226 | iw = iw + h*0.15 227 | end 228 | 229 | if preicon then 230 | ctx.fontSize = h*1.3 231 | ctx.fontFace = "icons" 232 | ctx.fillColor = "rgba(255,255,255,96)" 233 | ctx.textAlign = "left|middle" 234 | ctx:text(x+w*0.5-tw*0.5-iw*0.75, y+h*0.5, preicon) 235 | end 236 | 237 | ctx.fontSize = 20 238 | ctx.fontFace = "sans-bold" 239 | ctx.textAlign = "left|middle" 240 | ctx.fillStyle = "rgba(0,0,0,160)" 241 | ctx:text(x+w*0.5-tw*0.5+iw*0.25,y+h*0.5-1, text) 242 | ctx.fillStyle = "rgba(255,255,255,160)" 243 | ctx:text(x+w*0.5-tw*0.5+iw*0.25,y+h*0.5,text) 244 | end 245 | 246 | local function drawSlider(ctx, pos, x, y, w, h) 247 | local cy = y+h*0.5 248 | local kr = h*0.25 249 | 250 | ctx:save() 251 | 252 | -- Slot 253 | ctx:beginPath() 254 | ctx:roundedRect(x,cy-2, w,4, 2); 255 | ctx.fillStyle = ctx:boxGradient(x,cy-2+1, w,4, 2,2, "rgba(0,0,0,32)", "rgba(0,0,0,128)") 256 | ctx:fill() 257 | 258 | -- Knob Shadow 259 | ctx:beginPath(ctx); 260 | ctx:rect(x+pos*w-kr-5,cy-kr-5,kr*2+5+5,kr*2+5+5+3); 261 | ctx:circle(x+pos*w,cy, kr); 262 | ctx.pathWinding = "hole" 263 | ctx.fillStyle = ctx:radialGradient(x+pos*w,cy+1, kr-3,kr+3, "rgba(0,0,0,64)", "rgba(0,0,0,0)") 264 | ctx:fill() 265 | 266 | -- Knob 267 | ctx:beginPath() 268 | ctx:circle(x+pos*w,cy, kr-1) 269 | ctx.fillStyle = "rgba(40,43,48,255)" 270 | ctx:fill() 271 | ctx.fillStyle = ctx:linearGradient(x,cy-kr,x,cy+kr, "rgba(255,255,255,16)", "rgba(0,0,0,16)") 272 | ctx:fill() 273 | 274 | ctx:beginPath() 275 | ctx:circle(x+pos*w,cy, kr-0.5); 276 | ctx.strokeStyle = "rgba(0,0,0,92)" 277 | ctx:stroke() 278 | 279 | ctx:restore() 280 | end 281 | 282 | local function drawEyes(ctx, x, y, w, h, mx, my, t) 283 | local ex = w *0.23 284 | local ey = h * 0.5 285 | local lx = x + ex 286 | local ly = y + ey 287 | local rx = x + w - ex 288 | local ry = y + ey 289 | local br = math.min(ex, ey) * 0.5 290 | local blink = 1 - (math.sin(t*0.5)^200)*0.8 291 | 292 | ctx:beginPath() 293 | ctx:ellipse(lx+3.0,ly+16.0, ex,ey) 294 | ctx:ellipse(rx+3.0,ry+16.0, ex,ey) 295 | ctx.fillStyle = ctx:linearGradient(x,y+h*0.5,x+w*0.1,y+h, 296 | "rgba(0,0,0,32)", "rgba(0,0,0,16)") 297 | ctx:fill() 298 | 299 | ctx:beginPath() 300 | ctx:ellipse(lx,ly, ex,ey); 301 | ctx:ellipse(rx,ry, ex,ey); 302 | ctx.fillStyle = ctx:linearGradient(x,y+h*0.25,x+w*0.1,y+h, 303 | "rgba(220,220,220,255)", "rgba(128,128,128,255)") 304 | ctx:fill() 305 | 306 | do 307 | local dx = (mx - rx) / (ex * 10) 308 | local dy = (my - ry) / (ey * 10) 309 | local d = math.sqrt(dx*dx+dy*dy) 310 | if d > 1 then 311 | dx, dy = dx / d, dy / d 312 | end 313 | dx = dx * ex*0.4 314 | dy = dy * ey*0.5 315 | ctx:beginPath() 316 | ctx:ellipse(lx+dx,ly+dy+ey*0.25*(1-blink), br,br*blink) 317 | ctx.fillStyle = "rgba(32,32,32,255)" 318 | ctx:fill() 319 | end 320 | 321 | do 322 | local dx = (mx - rx) / (ex * 10) 323 | local dy = (my - ry) / (ey * 10) 324 | local d = math.sqrt(dx*dx+dy*dy) 325 | if d > 1 then 326 | dx, dy = dx / d, dy / d 327 | end 328 | dx = dx * ex*0.4 329 | dy = dy * ey*0.5 330 | ctx:beginPath() 331 | ctx:ellipse(rx+dx,ry+dy+ey*0.25*(1-blink), br,br*blink) 332 | ctx.fillStyle = "rgba(32,32,32,255)" 333 | ctx:fill() 334 | end 335 | 336 | ctx:beginPath() 337 | ctx:ellipse(lx,ly, ex,ey) 338 | ctx.fillStyle = ctx:radialGradient(lx-ex*0.25,ly-ey*0.5, ex*0.1,ex*0.75, 339 | "rgba(255,255,255,128)", "rgba(255,255,255,0)") 340 | ctx:fill() 341 | 342 | ctx:beginPath() 343 | ctx:ellipse(rx,ry, ex,ey) 344 | ctx.fillStyle = ctx:radialGradient(rx-ex*0.25,ry-ey*0.5, ex*0.1,ex*0.75, 345 | "rgba(255,255,255,128)", "rgba(255,255,255,0)") 346 | ctx:fill() 347 | end 348 | 349 | local sx, sy, samples = {}, {}, {} 350 | local function drawGraph(ctx, x, y, w, h, t) 351 | local dx = w/5.0 352 | 353 | samples[1] = (1+math.sin(t*1.2345 +math.cos(t*0.33457)*0.44))*0.5 354 | samples[2] = (1+math.sin(t*0.68363+math.cos(t*1.3)*1.55))*0.5 355 | samples[3] = (1+math.sin(t*1.1642 +math.cos(t*0.33457)*1.24))*0.5 356 | samples[4] = (1+math.sin(t*0.56345+math.cos(t*1.63)*0.14))*0.5 357 | samples[5] = (1+math.sin(t*1.6245 +math.cos(t*0.254)*0.3))*0.5 358 | samples[6] = (1+math.sin(t*0.345 +math.cos(t*0.03)*0.6))*0.5 359 | 360 | for i = 1, 6 do 361 | sx[i] = x+(i-1)*dx 362 | sy[i] = y+h*samples[i]*0.8 363 | end 364 | 365 | -- Graph background 366 | ctx:beginPath() 367 | ctx:moveTo(sx[1], sy[1]) 368 | for i = 2, 6 do 369 | ctx:bezierCurveTo(sx[i-1]+dx*0.5,sy[i-1], sx[i]-dx*0.5,sy[i], sx[i],sy[i]) 370 | end 371 | ctx:lineTo(x+w, y+h) 372 | ctx:lineTo(x, y+h) 373 | ctx.fillStyle = ctx:linearGradient(x,y,x,y+h, 374 | "rgba(0,160,192,0)", "rgba(0,160,192,64)") 375 | ctx:fill() 376 | 377 | -- Graph line 378 | ctx:beginPath() 379 | ctx:moveTo(sx[1], sy[1]+2) 380 | for i = 2, 6 do 381 | ctx:bezierCurveTo(sx[i-1]+dx*0.5,sy[i-1]+2, sx[i]-dx*0.5,sy[i]+2, sx[i],sy[i]+2) 382 | end 383 | ctx.strokeStyle = "rgba(0,0,0,32)" 384 | ctx.strokeWidth = 3 385 | ctx:stroke() 386 | 387 | ctx:beginPath() 388 | ctx:moveTo(sx[1], sy[1]) 389 | for i = 2, 6 do 390 | ctx:bezierCurveTo(sx[i-1]+dx*0.5,sy[i-1], sx[i]-dx*0.5,sy[i], sx[i],sy[i]); 391 | end 392 | ctx.strokeStyle = "rgba(0,160,192,255)" 393 | ctx.strokeWidth = 3 394 | ctx:stroke() 395 | 396 | -- Graph sample pos 397 | for i = 1, 6 do 398 | ctx:beginPath() 399 | ctx:rect(sx[i]-10, sy[i]-10+2, 20,20); 400 | ctx.fillStyle = ctx:radialGradient(sx[i],sy[i]+2, 3.0,8.0, 401 | "rgba(0,0,0,32)", "rgba(0,0,0,0)") 402 | ctx:fill() 403 | end 404 | 405 | ctx:beginPath() 406 | for i = 1, 6 do 407 | ctx:circle(sx[i], sy[i], 4.0) 408 | end 409 | ctx.fillStyle = "rgba(0,160,192,255)" 410 | ctx:fill() 411 | 412 | ctx:beginPath() 413 | for i = 1, 6 do 414 | ctx:circle(sx[i], sy[i], 2.0) 415 | end 416 | ctx.fillStyle = "rgba(220,220,220,255)" 417 | ctx:fill() 418 | 419 | ctx.strokeWidth = 1 420 | end 421 | 422 | local function drawColorWheel(ctx, x, y, w, h, t) 423 | local hue = math.sin(t * 0.12) 424 | local cx = x + w*0.5 425 | local cy = y + h*0.5 426 | local r1 = math.min(w, h) * 0.5 - 5.0 427 | local r0 = r1 - 20.0 428 | local aeps = 0.5 / r1 -- half a pixel arc length in radians (2pi cancels out). 429 | 430 | ctx:save() 431 | for i = 1, 6 do 432 | local a0 = (i-1) / 6.0 * math.pi * 2.0 - aeps 433 | local a1 = i / 6.0 * math.pi * 2.0 + aeps 434 | 435 | ctx:beginPath() 436 | ctx:arc(cx,cy, r0, a0,a1, "cw") 437 | ctx:arc(cx,cy, r1, a1,a0, "ccw") 438 | ctx:closePath() 439 | local ax = cx + math.cos(a0) * (r0+r1)*0.5 440 | local ay = cy + math.sin(a0) * (r0+r1)*0.5 441 | local bx = cx + math.cos(a1) * (r0+r1)*0.5 442 | local by = cy + math.sin(a1) * (r0+r1)*0.5 443 | ctx.fillStyle = ctx:linearGradient(ax,ay, bx,by, 444 | color.hsl(a0/(math.pi*2),1.0,0.55), 445 | color.hsl(a1/(math.pi*2),1.0,0.55)) 446 | ctx:fill() 447 | end 448 | 449 | ctx:beginPath() 450 | ctx:circle(cx,cy, r0-0.5) 451 | ctx:circle(cx,cy, r1+0.5) 452 | ctx.strokeStyle = "rgba(0,0,0,64)" 453 | ctx.strokeWidth = 1 454 | ctx:stroke() 455 | 456 | -- Selector 457 | ctx:save() 458 | ctx:translate(cx,cy) 459 | ctx:rotate(hue*math.pi*2) 460 | 461 | -- Marker on 462 | ctx.strokeWidth = 2 463 | ctx:beginPath() 464 | ctx:rect(r0-1,-3,r1-r0+2,6) 465 | ctx.strokeStyle = "rgba(255,255,255,192)" 466 | ctx:stroke() 467 | 468 | ctx:beginPath() 469 | ctx:rect(r0-2-10,-4-10,r1-r0+4+20,8+20) 470 | ctx:rect(r0-2,-4,r1-r0+4,8) 471 | ctx.pathWinding = "hole" 472 | ctx.fillStyle = ctx:boxGradient(r0-3,-5,r1-r0+6,10, 2,4, 473 | "rgba(0,0,0,128)", "rgba(0,0,0,0)") 474 | ctx:fill() 475 | 476 | -- Center triangle 477 | local r = r0 - 6 478 | local ax = math.cos(120.0/180.0*math.pi) * r 479 | local ay = math.sin(120.0/180.0*math.pi) * r 480 | local bx = math.cos(-120.0/180.0*math.pi) * r 481 | local by = math.sin(-120.0/180.0*math.pi) * r 482 | ctx:beginPath() 483 | ctx:moveTo(r,0) 484 | ctx:lineTo(ax,ay) 485 | ctx:lineTo(bx,by) 486 | ctx:closePath() 487 | ctx.fillStyle = ctx:linearGradient(r,0, ax,ay, 488 | color.hsla(hue,1.0,0.5,255), "rgba(255,255,255,255)") 489 | ctx:fill() 490 | ctx.fillStyle = ctx:linearGradient((r+ax)*0.5,(0+ay)*0.5, bx,by, 491 | "rgba(0,0,0,0)", "rgba(0,0,0,255)") 492 | ctx:fill() 493 | ctx.strokeStyle = "rgba(0,0,0,64)" 494 | ctx:stroke() 495 | 496 | -- Select circle on triangle 497 | ax = math.cos(120.0/180.0*math.pi) * r*0.3 498 | ay = math.sin(120.0/180.0*math.pi) * r*0.4 499 | ctx.strokeWidth = 2 500 | ctx:beginPath() 501 | ctx:circle(ax,ay,5) 502 | ctx.strokeStyle = "rgba(255,255,255,192)" 503 | ctx:stroke() 504 | 505 | ctx:beginPath() 506 | ctx:rect(ax-20,ay-20,40,40) 507 | ctx:circle(ax,ay,7) 508 | ctx.pathWinding = "hole" 509 | ctx.fillStyle = ctx:radialGradient(ax,ay, 7,9, "rgba(0,0,0,64)", "rgba(0,0,0,0)") 510 | ctx:fill() 511 | 512 | ctx:restore() 513 | end 514 | 515 | local function drawImages(ctx, width, height) 516 | local dx = 144 517 | local dy = 44 518 | ctx:beginPath() 519 | ctx:rect(dx,dy , loaded.im.width, loaded.im.height) 520 | loaded.im:extent(dx,dy, loaded.im.width, loaded.im.height) 521 | ctx.fillStyle = loaded.im 522 | ctx:fill() 523 | 524 | ctx:beginPath() 525 | ctx:rect(dx*2 + 10,dy , loaded.svg.width, loaded.svg.height) 526 | loaded.svg:extent(dx,dy, loaded.svg.width, loaded.svg.height) 527 | ctx.fillStyle = loaded.svg 528 | ctx:fill() 529 | ctx:restore() 530 | end 531 | 532 | local function renderDemo(ctx, mx, my, width, height, t, blowup) 533 | local x, y 534 | 535 | drawEyes(ctx, width-250, 50, 150, 100, mx, my, t) 536 | drawGraph(ctx, 0, height/2, width, height/2, t) 537 | drawColorWheel(ctx, width - 300, height - 300, 250, 250, t) 538 | 539 | ctx:save() 540 | if blowup then 541 | ctx:rotate(math.sin(t*0.3)*5/180*math.pi) 542 | ctx:scale(2.0, 2.0) 543 | end 544 | 545 | -- Widgets 546 | drawWindow(ctx, "Widgets `n Stuff", 50, 50, 300, 400) 547 | x, y = 60, 95 548 | drawSearchBox(ctx, "Search", x, y, 280, 25) 549 | y = y + 40 550 | drawDropDown(ctx, "Effects", x,y, 280, 28) 551 | -- popy = y + 14 552 | y = y + 45 553 | 554 | -- Form 555 | drawLabel(ctx, "Login", x, y, 280, 20) 556 | y = y + 25 557 | drawEditBox(ctx, "Email", x, y, 280, 28) 558 | y = y + 35 559 | drawEditBox(ctx, "Password", x, y, 280, 28) 560 | y = y + 38 561 | drawCheckBox(ctx, "Remember me", x, y, 140, 28) 562 | drawButton(ctx, icons.login, "Sign in", x+138, y, 140, 28, "rgba(0,96,128,255)") 563 | y = y + 45 564 | 565 | -- slider 566 | drawLabel(ctx, "Diameter", x, y, 280, 20) 567 | y = y + 25 568 | drawEditBoxNum(ctx, "123.00", "px", x+180, y, 100, 28) 569 | drawSlider(ctx, 0.4, x, y, 170, 28) 570 | y = y + 55 571 | 572 | drawButton(ctx, icons.trash, "Delete", x, y, 160, 28, "rgba(128,16,8,255)") 573 | drawButton(ctx, nil, "Cancel", x+170, y, 110, 28, "rgba(0,0,0,0)"); 574 | 575 | drawImages(ctx, width, height) 576 | 577 | ctx:restore() 578 | end 579 | 580 | local function renderDemoMinimal(ctx, mx, my, width, height, t, blowup) 581 | local x, y 582 | ctx:save() 583 | drawImages(ctx, width, height) 584 | ctx:restore() 585 | end 586 | 587 | w = glfw.create_window(640, 480, "Hello world!") 588 | glfw.make_context_current(w) 589 | -- Only after this we can use nanovg 590 | local canvas = nvg.new "antialias" 591 | loaded = loadData(canvas) 592 | 593 | -- Repeatedly poll for events: 594 | while not glfw.window_should_close(w) do 595 | if glfw.get_key(w, "escape") == 'press' then break end 596 | t = glfw.get_time() 597 | ww, wh = glfw.get_window_size(w) 598 | mx, my = glfw.get_cursor_pos(w) 599 | local pw, _ = glfw.get_framebuffer_size(w) 600 | local ratio = pw/ww 601 | canvas:beginFrame(ww, wh, ratio) 602 | canvas:clear "#4C4C51" 603 | renderDemo(canvas, mx, my, ww, wh, t, blowup) 604 | renderDemoMinimal(canvas, mx, my, ww, wh, t, blowup) 605 | canvas:endFrame() 606 | glfw.swap_buffers(w) 607 | glfw.poll_events() 608 | end 609 | -------------------------------------------------------------------------------- /gles2.h: -------------------------------------------------------------------------------- 1 | #ifndef LOADGL_GL_ES_VERSION_2_0_GENERATED_H 2 | #define LOADGL_GL_ES_VERSION_2_0_GENERATED_H 3 | 4 | #define GL_ES_VERSION_2_0 1 5 | 6 | #ifdef LOADGL_STATIC_API 7 | # ifndef LOADGL_IMPLEMENTATION 8 | # define LOADGL_IMPLEMENTATION 9 | # endif 10 | # if __GNUC__ 11 | # define LOADGL_API static __attribute((unused)) 12 | # else 13 | # define LOADGL_API static 14 | # endif 15 | #endif 16 | 17 | #if !defined(LOADGL_API) && defined(_WIN32) 18 | # ifdef LOADGL_IMPLEMENTATION 19 | # define LOADGL_API __declspec(dllexport) 20 | # else 21 | # define LOADGL_API __declspec(dllimport) 22 | # endif 23 | #endif /* LOADGL_API */ 24 | 25 | #ifndef LOADGL_API 26 | # define LOADGL_API extern 27 | #endif /* LOADGL_API */ 28 | 29 | LOADGL_API int loadgl_Init(void); 30 | LOADGL_API int loadgl_LoadedCount(void); 31 | LOADGL_API int loadgl_GetMajorVersion(void); 32 | LOADGL_API int loadgl_GetMinorVersion(void); 33 | LOADGL_API int loadgl_IsVersionGEQ(int major, int minor); 34 | 35 | 36 | #if defined(__glew_h__) || defined(__GLEW_H__) 37 | # error Attempt to include auto-generated header after including glew.h 38 | #endif 39 | #if defined(__gl_h_) || defined(__GL_H__) 40 | # error Attempt to include auto-generated header after including gl.h 41 | #endif 42 | #if defined(__glext_h_) || defined(__GLEXT_H_) 43 | # error Attempt to include auto-generated header after including glext.h 44 | #endif 45 | #if defined(__gltypes_h_) 46 | # error Attempt to include auto-generated header after gltypes.h 47 | #endif 48 | #if defined(__gl_ATI_h_) 49 | # error Attempt to include auto-generated header after including glATI.h 50 | #endif 51 | 52 | #define __glew_h__ 53 | #define __GLEW_H__ 54 | #define __gl_h_ 55 | #define __GL_H__ 56 | #define __glext_h_ 57 | #define __GLEXT_H_ 58 | #define __gltypes_h_ 59 | #define __gl_ATI_h_ 60 | 61 | #if defined(_WIN32) && !defined(APIENTRY) &&\ 62 | !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) 63 | # ifndef WIN32_LEAN_AND_MEAN 64 | # define WIN32_LEAN_AND_MEAN 1 65 | # endif 66 | # include 67 | #endif 68 | 69 | #ifndef APIENTRY 70 | # define APIENTRY 71 | #endif /* APIENTRY */ 72 | 73 | #ifndef APIENTRYP 74 | # define APIENTRYP APIENTRY * 75 | #endif /* APIENTRYP */ 76 | 77 | #ifndef GLAPI 78 | # define GLAPI extern 79 | #endif /* GLAPI */ 80 | 81 | #ifdef __cplusplus 82 | # define GL_NS_BEGIN extern "C" { 83 | # define GL_NS_END } 84 | #else 85 | # define GL_NS_BEGIN 86 | # define GL_NS_END 87 | #endif /* OpenGL Namespace */ 88 | 89 | 90 | GL_NS_BEGIN 91 | 92 | 93 | #ifndef GLEXT_64_TYPES_DEFINED 94 | /* This code block is duplicated in glxext.h, so must be protected */ 95 | #define GLEXT_64_TYPES_DEFINED 96 | /* Define int32_t, int64_t, and uint64_t types for UST/MSC */ 97 | /* (as used in the GL_EXT_timer_query extension). */ 98 | #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 99 | #include 100 | #elif defined(__sun__) || defined(__digital__) 101 | #include 102 | #if defined(__STDC__) 103 | #if defined(__arch64__) || defined(_LP64) 104 | typedef long int int64_t; 105 | typedef unsigned long int uint64_t; 106 | #else 107 | typedef long long int int64_t; 108 | typedef unsigned long long int uint64_t; 109 | #endif /* __arch64__ */ 110 | #endif /* __STDC__ */ 111 | #elif defined( __VMS ) || defined(__sgi) 112 | #include 113 | #elif defined(__SCO__) || defined(__USLC__) 114 | #include 115 | #elif defined(__UNIXOS2__) || defined(__SOL64__) 116 | typedef long int int32_t; 117 | typedef long long int int64_t; 118 | typedef unsigned long long int uint64_t; 119 | #elif defined(_WIN32) && defined(__GNUC__) 120 | #include 121 | #elif defined(_WIN32) 122 | typedef __int32 int32_t; 123 | typedef __int64 int64_t; 124 | typedef unsigned __int64 uint64_t; 125 | #else 126 | /* Fallback if nothing above works */ 127 | #include 128 | #endif 129 | #endif 130 | typedef unsigned int GLenum; 131 | typedef unsigned int GLuint; 132 | typedef char GLchar; 133 | typedef float GLfloat; 134 | typedef ptrdiff_t GLsizeiptr; 135 | typedef ptrdiff_t GLintptr; 136 | typedef unsigned int GLbitfield; 137 | typedef int GLint; 138 | typedef unsigned char GLboolean; 139 | typedef int GLsizei; 140 | typedef unsigned char GLubyte; 141 | 142 | 143 | /* OpenGL types */ 144 | 145 | /* Not used by the API, for compatibility with old gl2.h */ 146 | 147 | typedef signed char GLbyte; 148 | typedef float GLclampf; 149 | typedef GLint GLfixed; /* Must be 32 bits */ 150 | typedef short GLshort; 151 | typedef unsigned short GLushort; 152 | typedef void GLvoid; /* Not an actual GL type, though used in headers in the past */ 153 | 154 | 155 | typedef struct __GLsync * GLsync; 156 | typedef int64_t GLint64; 157 | typedef uint64_t GLuint64; 158 | 159 | 160 | /* OpenGL enums */ 161 | 162 | #define GL_DEPTH_BUFFER_BIT 0x00000100 163 | #define GL_STENCIL_BUFFER_BIT 0x00000400 164 | #define GL_COLOR_BUFFER_BIT 0x00004000 165 | #define GL_FALSE 0 166 | #define GL_TRUE 1 167 | #define GL_POINTS 0x0000 168 | #define GL_LINES 0x0001 169 | #define GL_LINE_LOOP 0x0002 170 | #define GL_LINE_STRIP 0x0003 171 | #define GL_TRIANGLES 0x0004 172 | #define GL_TRIANGLE_STRIP 0x0005 173 | #define GL_TRIANGLE_FAN 0x0006 174 | #define GL_ZERO 0 175 | #define GL_ONE 1 176 | #define GL_SRC_COLOR 0x0300 177 | #define GL_ONE_MINUS_SRC_COLOR 0x0301 178 | #define GL_SRC_ALPHA 0x0302 179 | #define GL_ONE_MINUS_SRC_ALPHA 0x0303 180 | #define GL_DST_ALPHA 0x0304 181 | #define GL_ONE_MINUS_DST_ALPHA 0x0305 182 | #define GL_DST_COLOR 0x0306 183 | #define GL_ONE_MINUS_DST_COLOR 0x0307 184 | #define GL_SRC_ALPHA_SATURATE 0x0308 185 | #define GL_FUNC_ADD 0x8006 186 | #define GL_BLEND_EQUATION 0x8009 187 | #define GL_BLEND_EQUATION_RGB 0x8009 188 | #define GL_BLEND_EQUATION_ALPHA 0x883D 189 | #define GL_FUNC_SUBTRACT 0x800A 190 | #define GL_FUNC_REVERSE_SUBTRACT 0x800B 191 | #define GL_BLEND_DST_RGB 0x80C8 192 | #define GL_BLEND_SRC_RGB 0x80C9 193 | #define GL_BLEND_DST_ALPHA 0x80CA 194 | #define GL_BLEND_SRC_ALPHA 0x80CB 195 | #define GL_CONSTANT_COLOR 0x8001 196 | #define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 197 | #define GL_CONSTANT_ALPHA 0x8003 198 | #define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 199 | #define GL_BLEND_COLOR 0x8005 200 | #define GL_ARRAY_BUFFER 0x8892 201 | #define GL_ELEMENT_ARRAY_BUFFER 0x8893 202 | #define GL_ARRAY_BUFFER_BINDING 0x8894 203 | #define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 204 | #define GL_STREAM_DRAW 0x88E0 205 | #define GL_STATIC_DRAW 0x88E4 206 | #define GL_DYNAMIC_DRAW 0x88E8 207 | #define GL_BUFFER_SIZE 0x8764 208 | #define GL_BUFFER_USAGE 0x8765 209 | #define GL_CURRENT_VERTEX_ATTRIB 0x8626 210 | #define GL_FRONT 0x0404 211 | #define GL_BACK 0x0405 212 | #define GL_FRONT_AND_BACK 0x0408 213 | #define GL_TEXTURE_2D 0x0DE1 214 | #define GL_CULL_FACE 0x0B44 215 | #define GL_BLEND 0x0BE2 216 | #define GL_DITHER 0x0BD0 217 | #define GL_STENCIL_TEST 0x0B90 218 | #define GL_DEPTH_TEST 0x0B71 219 | #define GL_SCISSOR_TEST 0x0C11 220 | #define GL_POLYGON_OFFSET_FILL 0x8037 221 | #define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E 222 | #define GL_SAMPLE_COVERAGE 0x80A0 223 | #define GL_NO_ERROR 0 224 | #define GL_INVALID_ENUM 0x0500 225 | #define GL_INVALID_VALUE 0x0501 226 | #define GL_INVALID_OPERATION 0x0502 227 | #define GL_OUT_OF_MEMORY 0x0505 228 | #define GL_CW 0x0900 229 | #define GL_CCW 0x0901 230 | #define GL_LINE_WIDTH 0x0B21 231 | #define GL_ALIASED_POINT_SIZE_RANGE 0x846D 232 | #define GL_ALIASED_LINE_WIDTH_RANGE 0x846E 233 | #define GL_CULL_FACE_MODE 0x0B45 234 | #define GL_FRONT_FACE 0x0B46 235 | #define GL_DEPTH_RANGE 0x0B70 236 | #define GL_DEPTH_WRITEMASK 0x0B72 237 | #define GL_DEPTH_CLEAR_VALUE 0x0B73 238 | #define GL_DEPTH_FUNC 0x0B74 239 | #define GL_STENCIL_CLEAR_VALUE 0x0B91 240 | #define GL_STENCIL_FUNC 0x0B92 241 | #define GL_STENCIL_FAIL 0x0B94 242 | #define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 243 | #define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 244 | #define GL_STENCIL_REF 0x0B97 245 | #define GL_STENCIL_VALUE_MASK 0x0B93 246 | #define GL_STENCIL_WRITEMASK 0x0B98 247 | #define GL_STENCIL_BACK_FUNC 0x8800 248 | #define GL_STENCIL_BACK_FAIL 0x8801 249 | #define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 250 | #define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 251 | #define GL_STENCIL_BACK_REF 0x8CA3 252 | #define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 253 | #define GL_STENCIL_BACK_WRITEMASK 0x8CA5 254 | #define GL_VIEWPORT 0x0BA2 255 | #define GL_SCISSOR_BOX 0x0C10 256 | #define GL_COLOR_CLEAR_VALUE 0x0C22 257 | #define GL_COLOR_WRITEMASK 0x0C23 258 | #define GL_UNPACK_ALIGNMENT 0x0CF5 259 | #define GL_PACK_ALIGNMENT 0x0D05 260 | #define GL_MAX_TEXTURE_SIZE 0x0D33 261 | #define GL_MAX_VIEWPORT_DIMS 0x0D3A 262 | #define GL_SUBPIXEL_BITS 0x0D50 263 | #define GL_RED_BITS 0x0D52 264 | #define GL_GREEN_BITS 0x0D53 265 | #define GL_BLUE_BITS 0x0D54 266 | #define GL_ALPHA_BITS 0x0D55 267 | #define GL_DEPTH_BITS 0x0D56 268 | #define GL_STENCIL_BITS 0x0D57 269 | #define GL_POLYGON_OFFSET_UNITS 0x2A00 270 | #define GL_POLYGON_OFFSET_FACTOR 0x8038 271 | #define GL_TEXTURE_BINDING_2D 0x8069 272 | #define GL_SAMPLE_BUFFERS 0x80A8 273 | #define GL_SAMPLES 0x80A9 274 | #define GL_SAMPLE_COVERAGE_VALUE 0x80AA 275 | #define GL_SAMPLE_COVERAGE_INVERT 0x80AB 276 | #define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 277 | #define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 278 | #define GL_DONT_CARE 0x1100 279 | #define GL_FASTEST 0x1101 280 | #define GL_NICEST 0x1102 281 | #define GL_GENERATE_MIPMAP_HINT 0x8192 282 | #define GL_BYTE 0x1400 283 | #define GL_UNSIGNED_BYTE 0x1401 284 | #define GL_SHORT 0x1402 285 | #define GL_UNSIGNED_SHORT 0x1403 286 | #define GL_INT 0x1404 287 | #define GL_UNSIGNED_INT 0x1405 288 | #define GL_FLOAT 0x1406 289 | #define GL_FIXED 0x140C 290 | #define GL_DEPTH_COMPONENT 0x1902 291 | #define GL_ALPHA 0x1906 292 | #define GL_RGB 0x1907 293 | #define GL_RGBA 0x1908 294 | #define GL_LUMINANCE 0x1909 295 | #define GL_LUMINANCE_ALPHA 0x190A 296 | #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 297 | #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 298 | #define GL_UNSIGNED_SHORT_5_6_5 0x8363 299 | #define GL_FRAGMENT_SHADER 0x8B30 300 | #define GL_VERTEX_SHADER 0x8B31 301 | #define GL_MAX_VERTEX_ATTRIBS 0x8869 302 | #define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB 303 | #define GL_MAX_VARYING_VECTORS 0x8DFC 304 | #define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D 305 | #define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C 306 | #define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 307 | #define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD 308 | #define GL_SHADER_TYPE 0x8B4F 309 | #define GL_DELETE_STATUS 0x8B80 310 | #define GL_LINK_STATUS 0x8B82 311 | #define GL_VALIDATE_STATUS 0x8B83 312 | #define GL_ATTACHED_SHADERS 0x8B85 313 | #define GL_ACTIVE_UNIFORMS 0x8B86 314 | #define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 315 | #define GL_ACTIVE_ATTRIBUTES 0x8B89 316 | #define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A 317 | #define GL_SHADING_LANGUAGE_VERSION 0x8B8C 318 | #define GL_CURRENT_PROGRAM 0x8B8D 319 | #define GL_NEVER 0x0200 320 | #define GL_LESS 0x0201 321 | #define GL_EQUAL 0x0202 322 | #define GL_LEQUAL 0x0203 323 | #define GL_GREATER 0x0204 324 | #define GL_NOTEQUAL 0x0205 325 | #define GL_GEQUAL 0x0206 326 | #define GL_ALWAYS 0x0207 327 | #define GL_KEEP 0x1E00 328 | #define GL_REPLACE 0x1E01 329 | #define GL_INCR 0x1E02 330 | #define GL_DECR 0x1E03 331 | #define GL_INVERT 0x150A 332 | #define GL_INCR_WRAP 0x8507 333 | #define GL_DECR_WRAP 0x8508 334 | #define GL_VENDOR 0x1F00 335 | #define GL_RENDERER 0x1F01 336 | #define GL_VERSION 0x1F02 337 | #define GL_EXTENSIONS 0x1F03 338 | #define GL_NEAREST 0x2600 339 | #define GL_LINEAR 0x2601 340 | #define GL_NEAREST_MIPMAP_NEAREST 0x2700 341 | #define GL_LINEAR_MIPMAP_NEAREST 0x2701 342 | #define GL_NEAREST_MIPMAP_LINEAR 0x2702 343 | #define GL_LINEAR_MIPMAP_LINEAR 0x2703 344 | #define GL_TEXTURE_MAG_FILTER 0x2800 345 | #define GL_TEXTURE_MIN_FILTER 0x2801 346 | #define GL_TEXTURE_WRAP_S 0x2802 347 | #define GL_TEXTURE_WRAP_T 0x2803 348 | #define GL_TEXTURE 0x1702 349 | #define GL_TEXTURE_CUBE_MAP 0x8513 350 | #define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 351 | #define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 352 | #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 353 | #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 354 | #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 355 | #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 356 | #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A 357 | #define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C 358 | #define GL_TEXTURE0 0x84C0 359 | #define GL_TEXTURE1 0x84C1 360 | #define GL_TEXTURE2 0x84C2 361 | #define GL_TEXTURE3 0x84C3 362 | #define GL_TEXTURE4 0x84C4 363 | #define GL_TEXTURE5 0x84C5 364 | #define GL_TEXTURE6 0x84C6 365 | #define GL_TEXTURE7 0x84C7 366 | #define GL_TEXTURE8 0x84C8 367 | #define GL_TEXTURE9 0x84C9 368 | #define GL_TEXTURE10 0x84CA 369 | #define GL_TEXTURE11 0x84CB 370 | #define GL_TEXTURE12 0x84CC 371 | #define GL_TEXTURE13 0x84CD 372 | #define GL_TEXTURE14 0x84CE 373 | #define GL_TEXTURE15 0x84CF 374 | #define GL_TEXTURE16 0x84D0 375 | #define GL_TEXTURE17 0x84D1 376 | #define GL_TEXTURE18 0x84D2 377 | #define GL_TEXTURE19 0x84D3 378 | #define GL_TEXTURE20 0x84D4 379 | #define GL_TEXTURE21 0x84D5 380 | #define GL_TEXTURE22 0x84D6 381 | #define GL_TEXTURE23 0x84D7 382 | #define GL_TEXTURE24 0x84D8 383 | #define GL_TEXTURE25 0x84D9 384 | #define GL_TEXTURE26 0x84DA 385 | #define GL_TEXTURE27 0x84DB 386 | #define GL_TEXTURE28 0x84DC 387 | #define GL_TEXTURE29 0x84DD 388 | #define GL_TEXTURE30 0x84DE 389 | #define GL_TEXTURE31 0x84DF 390 | #define GL_ACTIVE_TEXTURE 0x84E0 391 | #define GL_REPEAT 0x2901 392 | #define GL_CLAMP_TO_EDGE 0x812F 393 | #define GL_MIRRORED_REPEAT 0x8370 394 | #define GL_FLOAT_VEC2 0x8B50 395 | #define GL_FLOAT_VEC3 0x8B51 396 | #define GL_FLOAT_VEC4 0x8B52 397 | #define GL_INT_VEC2 0x8B53 398 | #define GL_INT_VEC3 0x8B54 399 | #define GL_INT_VEC4 0x8B55 400 | #define GL_BOOL 0x8B56 401 | #define GL_BOOL_VEC2 0x8B57 402 | #define GL_BOOL_VEC3 0x8B58 403 | #define GL_BOOL_VEC4 0x8B59 404 | #define GL_FLOAT_MAT2 0x8B5A 405 | #define GL_FLOAT_MAT3 0x8B5B 406 | #define GL_FLOAT_MAT4 0x8B5C 407 | #define GL_SAMPLER_2D 0x8B5E 408 | #define GL_SAMPLER_CUBE 0x8B60 409 | #define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 410 | #define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 411 | #define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 412 | #define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 413 | #define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A 414 | #define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 415 | #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F 416 | #define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A 417 | #define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B 418 | #define GL_COMPILE_STATUS 0x8B81 419 | #define GL_INFO_LOG_LENGTH 0x8B84 420 | #define GL_SHADER_SOURCE_LENGTH 0x8B88 421 | #define GL_SHADER_COMPILER 0x8DFA 422 | #define GL_SHADER_BINARY_FORMATS 0x8DF8 423 | #define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 424 | #define GL_LOW_FLOAT 0x8DF0 425 | #define GL_MEDIUM_FLOAT 0x8DF1 426 | #define GL_HIGH_FLOAT 0x8DF2 427 | #define GL_LOW_INT 0x8DF3 428 | #define GL_MEDIUM_INT 0x8DF4 429 | #define GL_HIGH_INT 0x8DF5 430 | #define GL_FRAMEBUFFER 0x8D40 431 | #define GL_RENDERBUFFER 0x8D41 432 | #define GL_RGBA4 0x8056 433 | #define GL_RGB5_A1 0x8057 434 | #define GL_RGB565 0x8D62 435 | #define GL_DEPTH_COMPONENT16 0x81A5 436 | #define GL_STENCIL_INDEX8 0x8D48 437 | #define GL_RENDERBUFFER_WIDTH 0x8D42 438 | #define GL_RENDERBUFFER_HEIGHT 0x8D43 439 | #define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 440 | #define GL_RENDERBUFFER_RED_SIZE 0x8D50 441 | #define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 442 | #define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 443 | #define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 444 | #define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 445 | #define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 446 | #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 447 | #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 448 | #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 449 | #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 450 | #define GL_COLOR_ATTACHMENT0 0x8CE0 451 | #define GL_DEPTH_ATTACHMENT 0x8D00 452 | #define GL_STENCIL_ATTACHMENT 0x8D20 453 | #define GL_NONE 0 454 | #define GL_FRAMEBUFFER_COMPLETE 0x8CD5 455 | #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 456 | #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 457 | #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 458 | #define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD 459 | #define GL_FRAMEBUFFER_BINDING 0x8CA6 460 | #define GL_RENDERBUFFER_BINDING 0x8CA7 461 | #define GL_MAX_RENDERBUFFER_SIZE 0x84E8 462 | #define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 463 | 464 | 465 | /* OpenGL commands */ 466 | 467 | #define LOADGL_COMMAND_COUNT 142 468 | 469 | typedef union LoadGLapis { 470 | void (APIENTRYP arr[LOADGL_COMMAND_COUNT]) (void); 471 | struct { 472 | void (APIENTRYP glActiveTexture_) (GLenum texture); 473 | void (APIENTRYP glAttachShader_) (GLuint program, GLuint shader); 474 | void (APIENTRYP glBindAttribLocation_) (GLuint program, GLuint index, const GLchar * name); 475 | void (APIENTRYP glBindBuffer_) (GLenum target, GLuint buffer); 476 | void (APIENTRYP glBindFramebuffer_) (GLenum target, GLuint framebuffer); 477 | void (APIENTRYP glBindRenderbuffer_) (GLenum target, GLuint renderbuffer); 478 | void (APIENTRYP glBindTexture_) (GLenum target, GLuint texture); 479 | void (APIENTRYP glBlendColor_) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); 480 | void (APIENTRYP glBlendEquation_) (GLenum mode); 481 | void (APIENTRYP glBlendEquationSeparate_) (GLenum modeRGB, GLenum modeAlpha); 482 | void (APIENTRYP glBlendFunc_) (GLenum sfactor, GLenum dfactor); 483 | void (APIENTRYP glBlendFuncSeparate_) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); 484 | void (APIENTRYP glBufferData_) (GLenum target, GLsizeiptr size, const void * data, GLenum usage); 485 | void (APIENTRYP glBufferSubData_) (GLenum target, GLintptr offset, GLsizeiptr size, const void * data); 486 | GLenum (APIENTRYP glCheckFramebufferStatus_) (GLenum target); 487 | void (APIENTRYP glClear_) (GLbitfield mask); 488 | void (APIENTRYP glClearColor_) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); 489 | void (APIENTRYP glClearDepthf_) (GLfloat d); 490 | void (APIENTRYP glClearStencil_) (GLint s); 491 | void (APIENTRYP glColorMask_) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); 492 | void (APIENTRYP glCompileShader_) (GLuint shader); 493 | void (APIENTRYP glCompressedTexImage2D_) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * data); 494 | void (APIENTRYP glCompressedTexSubImage2D_) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data); 495 | void (APIENTRYP glCopyTexImage2D_) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); 496 | void (APIENTRYP glCopyTexSubImage2D_) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); 497 | GLuint (APIENTRYP glCreateProgram_) (void); 498 | GLuint (APIENTRYP glCreateShader_) (GLenum type); 499 | void (APIENTRYP glCullFace_) (GLenum mode); 500 | void (APIENTRYP glDeleteBuffers_) (GLsizei n, const GLuint * buffers); 501 | void (APIENTRYP glDeleteFramebuffers_) (GLsizei n, const GLuint * framebuffers); 502 | void (APIENTRYP glDeleteProgram_) (GLuint program); 503 | void (APIENTRYP glDeleteRenderbuffers_) (GLsizei n, const GLuint * renderbuffers); 504 | void (APIENTRYP glDeleteShader_) (GLuint shader); 505 | void (APIENTRYP glDeleteTextures_) (GLsizei n, const GLuint * textures); 506 | void (APIENTRYP glDepthFunc_) (GLenum func); 507 | void (APIENTRYP glDepthMask_) (GLboolean flag); 508 | void (APIENTRYP glDepthRangef_) (GLfloat n, GLfloat f); 509 | void (APIENTRYP glDetachShader_) (GLuint program, GLuint shader); 510 | void (APIENTRYP glDisable_) (GLenum cap); 511 | void (APIENTRYP glDisableVertexAttribArray_) (GLuint index); 512 | void (APIENTRYP glDrawArrays_) (GLenum mode, GLint first, GLsizei count); 513 | void (APIENTRYP glDrawElements_) (GLenum mode, GLsizei count, GLenum type, const void * indices); 514 | void (APIENTRYP glEnable_) (GLenum cap); 515 | void (APIENTRYP glEnableVertexAttribArray_) (GLuint index); 516 | void (APIENTRYP glFinish_) (void); 517 | void (APIENTRYP glFlush_) (void); 518 | void (APIENTRYP glFramebufferRenderbuffer_) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); 519 | void (APIENTRYP glFramebufferTexture2D_) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); 520 | void (APIENTRYP glFrontFace_) (GLenum mode); 521 | void (APIENTRYP glGenBuffers_) (GLsizei n, GLuint * buffers); 522 | void (APIENTRYP glGenerateMipmap_) (GLenum target); 523 | void (APIENTRYP glGenFramebuffers_) (GLsizei n, GLuint * framebuffers); 524 | void (APIENTRYP glGenRenderbuffers_) (GLsizei n, GLuint * renderbuffers); 525 | void (APIENTRYP glGenTextures_) (GLsizei n, GLuint * textures); 526 | void (APIENTRYP glGetActiveAttrib_) (GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); 527 | void (APIENTRYP glGetActiveUniform_) (GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); 528 | void (APIENTRYP glGetAttachedShaders_) (GLuint program, GLsizei maxCount, GLsizei * count, GLuint * shaders); 529 | GLint (APIENTRYP glGetAttribLocation_) (GLuint program, const GLchar * name); 530 | void (APIENTRYP glGetBooleanv_) (GLenum pname, GLboolean * data); 531 | void (APIENTRYP glGetBufferParameteriv_) (GLenum target, GLenum pname, GLint * params); 532 | GLenum (APIENTRYP glGetError_) (void); 533 | void (APIENTRYP glGetFloatv_) (GLenum pname, GLfloat * data); 534 | void (APIENTRYP glGetFramebufferAttachmentParameteriv_) (GLenum target, GLenum attachment, GLenum pname, GLint * params); 535 | void (APIENTRYP glGetIntegerv_) (GLenum pname, GLint * data); 536 | void (APIENTRYP glGetProgramiv_) (GLuint program, GLenum pname, GLint * params); 537 | void (APIENTRYP glGetProgramInfoLog_) (GLuint program, GLsizei bufSize, GLsizei * length, GLchar * infoLog); 538 | void (APIENTRYP glGetRenderbufferParameteriv_) (GLenum target, GLenum pname, GLint * params); 539 | void (APIENTRYP glGetShaderiv_) (GLuint shader, GLenum pname, GLint * params); 540 | void (APIENTRYP glGetShaderInfoLog_) (GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * infoLog); 541 | void (APIENTRYP glGetShaderPrecisionFormat_) (GLenum shadertype, GLenum precisiontype, GLint * range, GLint * precision); 542 | void (APIENTRYP glGetShaderSource_) (GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * source); 543 | const GLubyte * (APIENTRYP glGetString_) (GLenum name); 544 | void (APIENTRYP glGetTexParameterfv_) (GLenum target, GLenum pname, GLfloat * params); 545 | void (APIENTRYP glGetTexParameteriv_) (GLenum target, GLenum pname, GLint * params); 546 | void (APIENTRYP glGetUniformfv_) (GLuint program, GLint location, GLfloat * params); 547 | void (APIENTRYP glGetUniformiv_) (GLuint program, GLint location, GLint * params); 548 | GLint (APIENTRYP glGetUniformLocation_) (GLuint program, const GLchar * name); 549 | void (APIENTRYP glGetVertexAttribfv_) (GLuint index, GLenum pname, GLfloat * params); 550 | void (APIENTRYP glGetVertexAttribiv_) (GLuint index, GLenum pname, GLint * params); 551 | void (APIENTRYP glGetVertexAttribPointerv_) (GLuint index, GLenum pname, void ** pointer); 552 | void (APIENTRYP glHint_) (GLenum target, GLenum mode); 553 | GLboolean (APIENTRYP glIsBuffer_) (GLuint buffer); 554 | GLboolean (APIENTRYP glIsEnabled_) (GLenum cap); 555 | GLboolean (APIENTRYP glIsFramebuffer_) (GLuint framebuffer); 556 | GLboolean (APIENTRYP glIsProgram_) (GLuint program); 557 | GLboolean (APIENTRYP glIsRenderbuffer_) (GLuint renderbuffer); 558 | GLboolean (APIENTRYP glIsShader_) (GLuint shader); 559 | GLboolean (APIENTRYP glIsTexture_) (GLuint texture); 560 | void (APIENTRYP glLineWidth_) (GLfloat width); 561 | void (APIENTRYP glLinkProgram_) (GLuint program); 562 | void (APIENTRYP glPixelStorei_) (GLenum pname, GLint param); 563 | void (APIENTRYP glPolygonOffset_) (GLfloat factor, GLfloat units); 564 | void (APIENTRYP glReadPixels_) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * pixels); 565 | void (APIENTRYP glReleaseShaderCompiler_) (void); 566 | void (APIENTRYP glRenderbufferStorage_) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); 567 | void (APIENTRYP glSampleCoverage_) (GLfloat value, GLboolean invert); 568 | void (APIENTRYP glScissor_) (GLint x, GLint y, GLsizei width, GLsizei height); 569 | void (APIENTRYP glShaderBinary_) (GLsizei count, const GLuint * shaders, GLenum binaryformat, const void * binary, GLsizei length); 570 | void (APIENTRYP glShaderSource_) (GLuint shader, GLsizei count, const GLchar *const* string, const GLint * length); 571 | void (APIENTRYP glStencilFunc_) (GLenum func, GLint ref, GLuint mask); 572 | void (APIENTRYP glStencilFuncSeparate_) (GLenum face, GLenum func, GLint ref, GLuint mask); 573 | void (APIENTRYP glStencilMask_) (GLuint mask); 574 | void (APIENTRYP glStencilMaskSeparate_) (GLenum face, GLuint mask); 575 | void (APIENTRYP glStencilOp_) (GLenum fail, GLenum zfail, GLenum zpass); 576 | void (APIENTRYP glStencilOpSeparate_) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); 577 | void (APIENTRYP glTexImage2D_) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels); 578 | void (APIENTRYP glTexParameterf_) (GLenum target, GLenum pname, GLfloat param); 579 | void (APIENTRYP glTexParameterfv_) (GLenum target, GLenum pname, const GLfloat * params); 580 | void (APIENTRYP glTexParameteri_) (GLenum target, GLenum pname, GLint param); 581 | void (APIENTRYP glTexParameteriv_) (GLenum target, GLenum pname, const GLint * params); 582 | void (APIENTRYP glTexSubImage2D_) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); 583 | void (APIENTRYP glUniform1f_) (GLint location, GLfloat v0); 584 | void (APIENTRYP glUniform1fv_) (GLint location, GLsizei count, const GLfloat * value); 585 | void (APIENTRYP glUniform1i_) (GLint location, GLint v0); 586 | void (APIENTRYP glUniform1iv_) (GLint location, GLsizei count, const GLint * value); 587 | void (APIENTRYP glUniform2f_) (GLint location, GLfloat v0, GLfloat v1); 588 | void (APIENTRYP glUniform2fv_) (GLint location, GLsizei count, const GLfloat * value); 589 | void (APIENTRYP glUniform2i_) (GLint location, GLint v0, GLint v1); 590 | void (APIENTRYP glUniform2iv_) (GLint location, GLsizei count, const GLint * value); 591 | void (APIENTRYP glUniform3f_) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); 592 | void (APIENTRYP glUniform3fv_) (GLint location, GLsizei count, const GLfloat * value); 593 | void (APIENTRYP glUniform3i_) (GLint location, GLint v0, GLint v1, GLint v2); 594 | void (APIENTRYP glUniform3iv_) (GLint location, GLsizei count, const GLint * value); 595 | void (APIENTRYP glUniform4f_) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); 596 | void (APIENTRYP glUniform4fv_) (GLint location, GLsizei count, const GLfloat * value); 597 | void (APIENTRYP glUniform4i_) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); 598 | void (APIENTRYP glUniform4iv_) (GLint location, GLsizei count, const GLint * value); 599 | void (APIENTRYP glUniformMatrix2fv_) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); 600 | void (APIENTRYP glUniformMatrix3fv_) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); 601 | void (APIENTRYP glUniformMatrix4fv_) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); 602 | void (APIENTRYP glUseProgram_) (GLuint program); 603 | void (APIENTRYP glValidateProgram_) (GLuint program); 604 | void (APIENTRYP glVertexAttrib1f_) (GLuint index, GLfloat x); 605 | void (APIENTRYP glVertexAttrib1fv_) (GLuint index, const GLfloat * v); 606 | void (APIENTRYP glVertexAttrib2f_) (GLuint index, GLfloat x, GLfloat y); 607 | void (APIENTRYP glVertexAttrib2fv_) (GLuint index, const GLfloat * v); 608 | void (APIENTRYP glVertexAttrib3f_) (GLuint index, GLfloat x, GLfloat y, GLfloat z); 609 | void (APIENTRYP glVertexAttrib3fv_) (GLuint index, const GLfloat * v); 610 | void (APIENTRYP glVertexAttrib4f_) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); 611 | void (APIENTRYP glVertexAttrib4fv_) (GLuint index, const GLfloat * v); 612 | void (APIENTRYP glVertexAttribPointer_) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer); 613 | void (APIENTRYP glViewport_) (GLint x, GLint y, GLsizei width, GLsizei height); 614 | } fps; 615 | } LoadGLapis; 616 | 617 | LOADGL_API LoadGLapis oglApis; 618 | 619 | /* macros to call OpenGL functions */ 620 | #define glActiveTexture oglApis.fps.glActiveTexture_ 621 | #define glAttachShader oglApis.fps.glAttachShader_ 622 | #define glBindAttribLocation oglApis.fps.glBindAttribLocation_ 623 | #define glBindBuffer oglApis.fps.glBindBuffer_ 624 | #define glBindFramebuffer oglApis.fps.glBindFramebuffer_ 625 | #define glBindRenderbuffer oglApis.fps.glBindRenderbuffer_ 626 | #define glBindTexture oglApis.fps.glBindTexture_ 627 | #define glBlendColor oglApis.fps.glBlendColor_ 628 | #define glBlendEquation oglApis.fps.glBlendEquation_ 629 | #define glBlendEquationSeparate oglApis.fps.glBlendEquationSeparate_ 630 | #define glBlendFunc oglApis.fps.glBlendFunc_ 631 | #define glBlendFuncSeparate oglApis.fps.glBlendFuncSeparate_ 632 | #define glBufferData oglApis.fps.glBufferData_ 633 | #define glBufferSubData oglApis.fps.glBufferSubData_ 634 | #define glCheckFramebufferStatus oglApis.fps.glCheckFramebufferStatus_ 635 | #define glClear oglApis.fps.glClear_ 636 | #define glClearColor oglApis.fps.glClearColor_ 637 | #define glClearDepthf oglApis.fps.glClearDepthf_ 638 | #define glClearStencil oglApis.fps.glClearStencil_ 639 | #define glColorMask oglApis.fps.glColorMask_ 640 | #define glCompileShader oglApis.fps.glCompileShader_ 641 | #define glCompressedTexImage2D oglApis.fps.glCompressedTexImage2D_ 642 | #define glCompressedTexSubImage2D oglApis.fps.glCompressedTexSubImage2D_ 643 | #define glCopyTexImage2D oglApis.fps.glCopyTexImage2D_ 644 | #define glCopyTexSubImage2D oglApis.fps.glCopyTexSubImage2D_ 645 | #define glCreateProgram oglApis.fps.glCreateProgram_ 646 | #define glCreateShader oglApis.fps.glCreateShader_ 647 | #define glCullFace oglApis.fps.glCullFace_ 648 | #define glDeleteBuffers oglApis.fps.glDeleteBuffers_ 649 | #define glDeleteFramebuffers oglApis.fps.glDeleteFramebuffers_ 650 | #define glDeleteProgram oglApis.fps.glDeleteProgram_ 651 | #define glDeleteRenderbuffers oglApis.fps.glDeleteRenderbuffers_ 652 | #define glDeleteShader oglApis.fps.glDeleteShader_ 653 | #define glDeleteTextures oglApis.fps.glDeleteTextures_ 654 | #define glDepthFunc oglApis.fps.glDepthFunc_ 655 | #define glDepthMask oglApis.fps.glDepthMask_ 656 | #define glDepthRangef oglApis.fps.glDepthRangef_ 657 | #define glDetachShader oglApis.fps.glDetachShader_ 658 | #define glDisable oglApis.fps.glDisable_ 659 | #define glDisableVertexAttribArray oglApis.fps.glDisableVertexAttribArray_ 660 | #define glDrawArrays oglApis.fps.glDrawArrays_ 661 | #define glDrawElements oglApis.fps.glDrawElements_ 662 | #define glEnable oglApis.fps.glEnable_ 663 | #define glEnableVertexAttribArray oglApis.fps.glEnableVertexAttribArray_ 664 | #define glFinish oglApis.fps.glFinish_ 665 | #define glFlush oglApis.fps.glFlush_ 666 | #define glFramebufferRenderbuffer oglApis.fps.glFramebufferRenderbuffer_ 667 | #define glFramebufferTexture2D oglApis.fps.glFramebufferTexture2D_ 668 | #define glFrontFace oglApis.fps.glFrontFace_ 669 | #define glGenBuffers oglApis.fps.glGenBuffers_ 670 | #define glGenerateMipmap oglApis.fps.glGenerateMipmap_ 671 | #define glGenFramebuffers oglApis.fps.glGenFramebuffers_ 672 | #define glGenRenderbuffers oglApis.fps.glGenRenderbuffers_ 673 | #define glGenTextures oglApis.fps.glGenTextures_ 674 | #define glGetActiveAttrib oglApis.fps.glGetActiveAttrib_ 675 | #define glGetActiveUniform oglApis.fps.glGetActiveUniform_ 676 | #define glGetAttachedShaders oglApis.fps.glGetAttachedShaders_ 677 | #define glGetAttribLocation oglApis.fps.glGetAttribLocation_ 678 | #define glGetBooleanv oglApis.fps.glGetBooleanv_ 679 | #define glGetBufferParameteriv oglApis.fps.glGetBufferParameteriv_ 680 | #define glGetError oglApis.fps.glGetError_ 681 | #define glGetFloatv oglApis.fps.glGetFloatv_ 682 | #define glGetFramebufferAttachmentParameteriv oglApis.fps.glGetFramebufferAttachmentParameteriv_ 683 | #define glGetIntegerv oglApis.fps.glGetIntegerv_ 684 | #define glGetProgramiv oglApis.fps.glGetProgramiv_ 685 | #define glGetProgramInfoLog oglApis.fps.glGetProgramInfoLog_ 686 | #define glGetRenderbufferParameteriv oglApis.fps.glGetRenderbufferParameteriv_ 687 | #define glGetShaderiv oglApis.fps.glGetShaderiv_ 688 | #define glGetShaderInfoLog oglApis.fps.glGetShaderInfoLog_ 689 | #define glGetShaderPrecisionFormat oglApis.fps.glGetShaderPrecisionFormat_ 690 | #define glGetShaderSource oglApis.fps.glGetShaderSource_ 691 | #define glGetString oglApis.fps.glGetString_ 692 | #define glGetTexParameterfv oglApis.fps.glGetTexParameterfv_ 693 | #define glGetTexParameteriv oglApis.fps.glGetTexParameteriv_ 694 | #define glGetUniformfv oglApis.fps.glGetUniformfv_ 695 | #define glGetUniformiv oglApis.fps.glGetUniformiv_ 696 | #define glGetUniformLocation oglApis.fps.glGetUniformLocation_ 697 | #define glGetVertexAttribfv oglApis.fps.glGetVertexAttribfv_ 698 | #define glGetVertexAttribiv oglApis.fps.glGetVertexAttribiv_ 699 | #define glGetVertexAttribPointerv oglApis.fps.glGetVertexAttribPointerv_ 700 | #define glHint oglApis.fps.glHint_ 701 | #define glIsBuffer oglApis.fps.glIsBuffer_ 702 | #define glIsEnabled oglApis.fps.glIsEnabled_ 703 | #define glIsFramebuffer oglApis.fps.glIsFramebuffer_ 704 | #define glIsProgram oglApis.fps.glIsProgram_ 705 | #define glIsRenderbuffer oglApis.fps.glIsRenderbuffer_ 706 | #define glIsShader oglApis.fps.glIsShader_ 707 | #define glIsTexture oglApis.fps.glIsTexture_ 708 | #define glLineWidth oglApis.fps.glLineWidth_ 709 | #define glLinkProgram oglApis.fps.glLinkProgram_ 710 | #define glPixelStorei oglApis.fps.glPixelStorei_ 711 | #define glPolygonOffset oglApis.fps.glPolygonOffset_ 712 | #define glReadPixels oglApis.fps.glReadPixels_ 713 | #define glReleaseShaderCompiler oglApis.fps.glReleaseShaderCompiler_ 714 | #define glRenderbufferStorage oglApis.fps.glRenderbufferStorage_ 715 | #define glSampleCoverage oglApis.fps.glSampleCoverage_ 716 | #define glScissor oglApis.fps.glScissor_ 717 | #define glShaderBinary oglApis.fps.glShaderBinary_ 718 | #define glShaderSource oglApis.fps.glShaderSource_ 719 | #define glStencilFunc oglApis.fps.glStencilFunc_ 720 | #define glStencilFuncSeparate oglApis.fps.glStencilFuncSeparate_ 721 | #define glStencilMask oglApis.fps.glStencilMask_ 722 | #define glStencilMaskSeparate oglApis.fps.glStencilMaskSeparate_ 723 | #define glStencilOp oglApis.fps.glStencilOp_ 724 | #define glStencilOpSeparate oglApis.fps.glStencilOpSeparate_ 725 | #define glTexImage2D oglApis.fps.glTexImage2D_ 726 | #define glTexParameterf oglApis.fps.glTexParameterf_ 727 | #define glTexParameterfv oglApis.fps.glTexParameterfv_ 728 | #define glTexParameteri oglApis.fps.glTexParameteri_ 729 | #define glTexParameteriv oglApis.fps.glTexParameteriv_ 730 | #define glTexSubImage2D oglApis.fps.glTexSubImage2D_ 731 | #define glUniform1f oglApis.fps.glUniform1f_ 732 | #define glUniform1fv oglApis.fps.glUniform1fv_ 733 | #define glUniform1i oglApis.fps.glUniform1i_ 734 | #define glUniform1iv oglApis.fps.glUniform1iv_ 735 | #define glUniform2f oglApis.fps.glUniform2f_ 736 | #define glUniform2fv oglApis.fps.glUniform2fv_ 737 | #define glUniform2i oglApis.fps.glUniform2i_ 738 | #define glUniform2iv oglApis.fps.glUniform2iv_ 739 | #define glUniform3f oglApis.fps.glUniform3f_ 740 | #define glUniform3fv oglApis.fps.glUniform3fv_ 741 | #define glUniform3i oglApis.fps.glUniform3i_ 742 | #define glUniform3iv oglApis.fps.glUniform3iv_ 743 | #define glUniform4f oglApis.fps.glUniform4f_ 744 | #define glUniform4fv oglApis.fps.glUniform4fv_ 745 | #define glUniform4i oglApis.fps.glUniform4i_ 746 | #define glUniform4iv oglApis.fps.glUniform4iv_ 747 | #define glUniformMatrix2fv oglApis.fps.glUniformMatrix2fv_ 748 | #define glUniformMatrix3fv oglApis.fps.glUniformMatrix3fv_ 749 | #define glUniformMatrix4fv oglApis.fps.glUniformMatrix4fv_ 750 | #define glUseProgram oglApis.fps.glUseProgram_ 751 | #define glValidateProgram oglApis.fps.glValidateProgram_ 752 | #define glVertexAttrib1f oglApis.fps.glVertexAttrib1f_ 753 | #define glVertexAttrib1fv oglApis.fps.glVertexAttrib1fv_ 754 | #define glVertexAttrib2f oglApis.fps.glVertexAttrib2f_ 755 | #define glVertexAttrib2fv oglApis.fps.glVertexAttrib2fv_ 756 | #define glVertexAttrib3f oglApis.fps.glVertexAttrib3f_ 757 | #define glVertexAttrib3fv oglApis.fps.glVertexAttrib3fv_ 758 | #define glVertexAttrib4f oglApis.fps.glVertexAttrib4f_ 759 | #define glVertexAttrib4fv oglApis.fps.glVertexAttrib4fv_ 760 | #define glVertexAttribPointer oglApis.fps.glVertexAttribPointer_ 761 | #define glViewport oglApis.fps.glViewport_ 762 | 763 | GL_NS_END 764 | 765 | #endif /* LOADGL_GL_ES_VERSION_2_0_GENERATED_H */ 766 | 767 | 768 | #if defined(LOADGL_IMPLEMENTATION) && !defined(loadgl_implemented) 769 | #define loadgl_implemented 770 | 771 | 772 | #include 773 | #include 774 | 775 | 776 | #ifdef __APPLE__ 777 | 778 | #include 779 | 780 | static void *loadgl_GetProcAddress (const char *name) { 781 | static void* image = NULL; 782 | if (image == NULL) 783 | image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", 784 | RTLD_LAZY); 785 | return image ? dlsym(image, name) : NULL; 786 | } 787 | 788 | #elif defined(__sgi) || defined(__sun) 789 | 790 | #include 791 | #include 792 | 793 | static void* loadgl_GetProcAddress (const char* name) { 794 | static void* h = NULL; 795 | static void* gpa; 796 | 797 | if (h == NULL) { 798 | if ((h = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL)) == NULL) 799 | return NULL; 800 | gpa = dlsym(h, "glXGetProcAddress"); 801 | } 802 | 803 | if (gpa != NULL) 804 | return ((void*(*)(const GLubyte*))gpa)((const GLubyte*)name); 805 | else 806 | return dlsym(h, name); 807 | } 808 | 809 | #elif defined(__WIN32) 810 | 811 | #ifdef _MSC_VER 812 | #pragma warning(disable: 4055) 813 | #pragma warning(disable: 4054) 814 | #endif 815 | 816 | static int loadgl_TestPointer(const PROC pTest) { 817 | ptrdiff_t iTest; 818 | if(!pTest) return 0; 819 | iTest = (ptrdiff_t)pTest; 820 | return iTest != 1 && iTest != 2 && iTest != 3 && iTest != -1; 821 | } 822 | 823 | static PROC loadgl_GetProcAddress(const char *name) { 824 | HMODULE glMod = NULL; 825 | PROC pFunc = wglGetProcAddress((LPCSTR)name); 826 | if(loadgl_TestPointer(pFunc)) 827 | return pFunc; 828 | glMod = GetModuleHandleA("OpenGL32.dll"); 829 | return (PROC)GetProcAddress(glMod, (LPCSTR)name); 830 | } 831 | 832 | #else 833 | 834 | #include 835 | 836 | #define loadgl_GetProcAddress(name) \ 837 | ((*glXGetProcAddressARB)((const GLubyte*)name)) 838 | 839 | #endif 840 | 841 | 842 | GL_NS_BEGIN 843 | 844 | /* OpenGL routines load */ 845 | 846 | LOADGL_API LoadGLapis oglApis; 847 | 848 | static int loadgl_loaded_count = 0; 849 | 850 | static int loadgl_LoadFunctions(void) { 851 | const char *commands[] = { 852 | "glActiveTexture", 853 | "glAttachShader", 854 | "glBindAttribLocation", 855 | "glBindBuffer", 856 | "glBindFramebuffer", 857 | "glBindRenderbuffer", 858 | "glBindTexture", 859 | "glBlendColor", 860 | "glBlendEquation", 861 | "glBlendEquationSeparate", 862 | "glBlendFunc", 863 | "glBlendFuncSeparate", 864 | "glBufferData", 865 | "glBufferSubData", 866 | "glCheckFramebufferStatus", 867 | "glClear", 868 | "glClearColor", 869 | "glClearDepthf", 870 | "glClearStencil", 871 | "glColorMask", 872 | "glCompileShader", 873 | "glCompressedTexImage2D", 874 | "glCompressedTexSubImage2D", 875 | "glCopyTexImage2D", 876 | "glCopyTexSubImage2D", 877 | "glCreateProgram", 878 | "glCreateShader", 879 | "glCullFace", 880 | "glDeleteBuffers", 881 | "glDeleteFramebuffers", 882 | "glDeleteProgram", 883 | "glDeleteRenderbuffers", 884 | "glDeleteShader", 885 | "glDeleteTextures", 886 | "glDepthFunc", 887 | "glDepthMask", 888 | "glDepthRangef", 889 | "glDetachShader", 890 | "glDisable", 891 | "glDisableVertexAttribArray", 892 | "glDrawArrays", 893 | "glDrawElements", 894 | "glEnable", 895 | "glEnableVertexAttribArray", 896 | "glFinish", 897 | "glFlush", 898 | "glFramebufferRenderbuffer", 899 | "glFramebufferTexture2D", 900 | "glFrontFace", 901 | "glGenBuffers", 902 | "glGenerateMipmap", 903 | "glGenFramebuffers", 904 | "glGenRenderbuffers", 905 | "glGenTextures", 906 | "glGetActiveAttrib", 907 | "glGetActiveUniform", 908 | "glGetAttachedShaders", 909 | "glGetAttribLocation", 910 | "glGetBooleanv", 911 | "glGetBufferParameteriv", 912 | "glGetError", 913 | "glGetFloatv", 914 | "glGetFramebufferAttachmentParameteriv", 915 | "glGetIntegerv", 916 | "glGetProgramiv", 917 | "glGetProgramInfoLog", 918 | "glGetRenderbufferParameteriv", 919 | "glGetShaderiv", 920 | "glGetShaderInfoLog", 921 | "glGetShaderPrecisionFormat", 922 | "glGetShaderSource", 923 | "glGetString", 924 | "glGetTexParameterfv", 925 | "glGetTexParameteriv", 926 | "glGetUniformfv", 927 | "glGetUniformiv", 928 | "glGetUniformLocation", 929 | "glGetVertexAttribfv", 930 | "glGetVertexAttribiv", 931 | "glGetVertexAttribPointerv", 932 | "glHint", 933 | "glIsBuffer", 934 | "glIsEnabled", 935 | "glIsFramebuffer", 936 | "glIsProgram", 937 | "glIsRenderbuffer", 938 | "glIsShader", 939 | "glIsTexture", 940 | "glLineWidth", 941 | "glLinkProgram", 942 | "glPixelStorei", 943 | "glPolygonOffset", 944 | "glReadPixels", 945 | "glReleaseShaderCompiler", 946 | "glRenderbufferStorage", 947 | "glSampleCoverage", 948 | "glScissor", 949 | "glShaderBinary", 950 | "glShaderSource", 951 | "glStencilFunc", 952 | "glStencilFuncSeparate", 953 | "glStencilMask", 954 | "glStencilMaskSeparate", 955 | "glStencilOp", 956 | "glStencilOpSeparate", 957 | "glTexImage2D", 958 | "glTexParameterf", 959 | "glTexParameterfv", 960 | "glTexParameteri", 961 | "glTexParameteriv", 962 | "glTexSubImage2D", 963 | "glUniform1f", 964 | "glUniform1fv", 965 | "glUniform1i", 966 | "glUniform1iv", 967 | "glUniform2f", 968 | "glUniform2fv", 969 | "glUniform2i", 970 | "glUniform2iv", 971 | "glUniform3f", 972 | "glUniform3fv", 973 | "glUniform3i", 974 | "glUniform3iv", 975 | "glUniform4f", 976 | "glUniform4fv", 977 | "glUniform4i", 978 | "glUniform4iv", 979 | "glUniformMatrix2fv", 980 | "glUniformMatrix3fv", 981 | "glUniformMatrix4fv", 982 | "glUseProgram", 983 | "glValidateProgram", 984 | "glVertexAttrib1f", 985 | "glVertexAttrib1fv", 986 | "glVertexAttrib2f", 987 | "glVertexAttrib2fv", 988 | "glVertexAttrib3f", 989 | "glVertexAttrib3fv", 990 | "glVertexAttrib4f", 991 | "glVertexAttrib4fv", 992 | "glVertexAttribPointer", 993 | "glViewport", 994 | }; 995 | int i, failed = 0; 996 | for (i = 0; i < LOADGL_COMMAND_COUNT; ++i) { 997 | oglApis.arr[i] = (void(APIENTRYP)(void))loadgl_GetProcAddress(commands[i]); 998 | if (oglApis.arr[i] == NULL) 999 | ++failed; 1000 | else 1001 | ++loadgl_loaded_count; 1002 | } 1003 | 1004 | return failed; 1005 | } 1006 | 1007 | LOADGL_API int loadgl_Init(void) { 1008 | /* TODO load extensions */ 1009 | 1010 | if (loadgl_loaded_count != LOADGL_COMMAND_COUNT) 1011 | return loadgl_LoadFunctions() == 0; 1012 | return 1; 1013 | } 1014 | 1015 | LOADGL_API int loadgl_LoadedCount() { 1016 | return loadgl_loaded_count; 1017 | } 1018 | 1019 | 1020 | /* OpenGL version detect */ 1021 | 1022 | static int loadgl_major_version = 0; 1023 | static int loadgl_minor_version = 0; 1024 | 1025 | static void loadgl_ParseVersion(int *major, int *minor, const char *s) { 1026 | char *buff, *dot1_pos, *dot2_pos; 1027 | 1028 | if((dot1_pos = strchr(s, '.')) == NULL) 1029 | return; 1030 | 1031 | buff = (char*)malloc(strlen(s) + 1); 1032 | if (buff == NULL) return; 1033 | strcpy(buff, s); 1034 | dot1_pos = &buff[dot1_pos-s]; 1035 | 1036 | *dot1_pos = '\0'; 1037 | *major = atoi(buff); 1038 | 1039 | /* if no extra data. Take the whole rest of the string. */ 1040 | if((dot2_pos = strchr(dot1_pos + 1, ' ')) != NULL) 1041 | *dot2_pos = '\0'; 1042 | 1043 | *minor = atoi(dot1_pos + 1); 1044 | free(buff); 1045 | } 1046 | 1047 | static void loadgl_GetGLVersion() { 1048 | if(loadgl_major_version != 0) return; 1049 | loadgl_ParseVersion( 1050 | &loadgl_major_version, 1051 | &loadgl_minor_version, 1052 | (const char*)glGetString(GL_VERSION)); 1053 | } 1054 | 1055 | LOADGL_API int loadgl_GetMajorVersion() { 1056 | loadgl_GetGLVersion(); 1057 | return loadgl_major_version; 1058 | } 1059 | 1060 | LOADGL_API int loadgl_GetMinorVersion() { 1061 | loadgl_GetGLVersion(); 1062 | return loadgl_minor_version; 1063 | } 1064 | 1065 | LOADGL_API int loadgl_IsVersionGEQ(int major, int minor) { 1066 | loadgl_GetGLVersion(); 1067 | if(major > loadgl_major_version) return 1; 1068 | if(major < loadgl_major_version) return 0; 1069 | if(minor >= loadgl_minor_version) return 1; 1070 | return 0; 1071 | } 1072 | 1073 | 1074 | GL_NS_END 1075 | 1076 | #endif /* LOADGL_IMPLEMENTATION */ 1077 | -------------------------------------------------------------------------------- /lua-nanovg.c: -------------------------------------------------------------------------------- 1 | #ifdef __GNUC__ 2 | # define LB_API static __attribute__((unused)) 3 | #else 4 | # define LB_API static 5 | #endif 6 | #define LBIND_IMPLEMENTATION 7 | #include "lbind.h" 8 | 9 | #define LOADGL_STATIC_API 10 | #ifdef __APPLE__ 11 | #include "gl_2_0_core.h" 12 | static int opengl_loaded = 0; 13 | 14 | #define NANOVG_GL2_IMPLEMENTATION 15 | #include "nanovg/src/nanovg.h" 16 | #include "nanovg/src/nanovg_gl.h" 17 | #undef NANOVG_GL2_IMPLEMENTATION 18 | 19 | #define CONTEXT_NEW nvgCreateGL2 20 | #define CONTEXT_DELETE nvgDeleteGL2 21 | 22 | #else 23 | #include "gles2.h" 24 | static int opengl_loaded = 0; 25 | 26 | #define NANOVG_GLES2_IMPLEMENTATION 27 | #include "nanovg/src/nanovg.h" 28 | #include "nanovg/src/nanovg_gl.h" 29 | #undef NANOVG_GLES2_IMPLEMENTATION 30 | 31 | #define CONTEXT_NEW nvgCreateGLES2 32 | #define CONTEXT_DELETE nvgDeleteGLES2 33 | #endif 34 | 35 | #define NANOSVG_IMPLEMENTATION 36 | #include "nanosvg/src/nanosvg.h" 37 | #define NANOSVGRAST_IMPLEMENTATION 38 | #include "nanosvg/src/nanosvgrast.h" 39 | 40 | LBIND_TYPE(lbT_Context, "NanoVG.Context"); 41 | LBIND_TYPE(lbT_Image, "NanoVG.Image"); 42 | LBIND_TYPE(lbT_Paint, "NanoVG.Paint"); 43 | 44 | 45 | /* object creation */ 46 | 47 | typedef struct LNVGimage LNVGimage; 48 | 49 | static NVGcolor check_color(lua_State *L, int idx); 50 | static int test_color(lua_State *L, int idx, NVGcolor *color); 51 | static int test_paint(lua_State *L, int idx, NVGpaint *paint); 52 | static int opentype_image(lua_State *L); 53 | 54 | #define check_context(L, idx) ((NVGcontext*)lbind_check((L),(idx),&lbT_Context)) 55 | #define check_image(L, idx) ((LNVGimage*)lbind_check((L),(idx),&lbT_Image)) 56 | 57 | static int Lnew(lua_State *L) { 58 | static lbind_EnumItem opts[] = { 59 | { "aa", NVG_ANTIALIAS }, 60 | { "antialias", NVG_ANTIALIAS }, 61 | { "ss", NVG_STENCIL_STROKES }, 62 | { "stencil_strokes", NVG_STENCIL_STROKES }, 63 | { NULL, 0 } 64 | }; 65 | static lbind_Enum et = LBIND_INITENUM("CreateFlags", opts); 66 | int flags; 67 | NVGcontext *ctx; 68 | if (!opengl_loaded) { 69 | if (!loadgl_Init()) 70 | return luaL_error(L, "OpenGL API load failure"); 71 | opengl_loaded = 1; 72 | } 73 | flags = lbind_optmask(L, 1, 0, &et); 74 | ctx = CONTEXT_NEW(flags); 75 | lbind_wrap(L, ctx, &lbT_Context); 76 | return 1; 77 | } 78 | 79 | static int L__gc(lua_State *L) { 80 | NVGcontext *ctx = (NVGcontext*)lbind_test(L, 1, &lbT_Context); 81 | if (ctx != NULL) { 82 | CONTEXT_DELETE(ctx); 83 | lbind_delete(L, 1); 84 | } 85 | return 0; 86 | } 87 | 88 | static NVGpaint *new_paint(lua_State *L, NVGpaint *paint) { 89 | NVGpaint *p = (NVGpaint*)lbind_new(L, sizeof(NVGpaint), &lbT_Paint); 90 | *p = *paint; 91 | return p; 92 | } 93 | 94 | static int Lfont(lua_State *L) { 95 | NVGcontext *ctx = check_context(L, 1); 96 | const char *name = luaL_checkstring(L, 2); 97 | const char *filename = luaL_checkstring(L, 3); 98 | int font = nvgCreateFont(ctx, name, filename); 99 | if (font < 0) 100 | lbind_argferror(L, 3, "invalid font file: %s", filename); 101 | lua_pushinteger(L, font); 102 | return 1; 103 | } 104 | 105 | static int LlinearGradient(lua_State *L) { 106 | NVGcontext *ctx = check_context(L, 1); 107 | float sx = (float)luaL_checknumber(L, 2); 108 | float sy = (float)luaL_checknumber(L, 3); 109 | float ex = (float)luaL_checknumber(L, 4); 110 | float ey = (float)luaL_checknumber(L, 5); 111 | NVGcolor icol = check_color(L, 6); 112 | NVGcolor ocol = check_color(L, 7); 113 | NVGpaint paint = nvgLinearGradient(ctx, sx, sy, ex, ey, icol, ocol); 114 | new_paint(L, &paint); 115 | return 1; 116 | } 117 | 118 | static int LboxGradient(lua_State *L) { 119 | NVGcontext *ctx = check_context(L, 1); 120 | float x = (float)luaL_checknumber(L, 2); 121 | float y = (float)luaL_checknumber(L, 3); 122 | float w = (float)luaL_checknumber(L, 4); 123 | float h = (float)luaL_checknumber(L, 5); 124 | float r = (float)luaL_checknumber(L, 6); 125 | float f = (float)luaL_checknumber(L, 7); 126 | NVGcolor icol = check_color(L, 8); 127 | NVGcolor ocol = check_color(L, 9); 128 | NVGpaint paint = nvgBoxGradient(ctx, x, y, w, h, r, f, icol, ocol); 129 | new_paint(L, &paint); 130 | return 1; 131 | } 132 | 133 | static int LradialGradient(lua_State *L) { 134 | NVGcontext *ctx = check_context(L, 1); 135 | float cx = (float)luaL_checknumber(L, 2); 136 | float cy = (float)luaL_checknumber(L, 3); 137 | float inr = (float)luaL_checknumber(L, 4); 138 | float outr = (float)luaL_checknumber(L, 5); 139 | NVGcolor icol = check_color(L, 6); 140 | NVGcolor ocol = check_color(L, 7); 141 | NVGpaint paint = nvgRadialGradient(ctx, cx, cy, inr, outr, icol, ocol); 142 | new_paint(L, &paint); 143 | return 1; 144 | } 145 | 146 | /* state routines */ 147 | 148 | static int Lclear(lua_State *L) { 149 | NVGcolor c = check_color(L, -1); 150 | glClearColor(c.r, c.g, c.b, c.r); 151 | glClear(GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 152 | lbind_returnself(L); 153 | } 154 | 155 | static int LbeginFrame(lua_State *L) { 156 | NVGcontext *ctx = check_context(L, 1); 157 | GLsizei w = (GLsizei)luaL_checkinteger(L, 2); 158 | GLsizei h = (GLsizei)luaL_checkinteger(L, 3); 159 | float ratio = (float)luaL_optnumber(L, 4, 1.0); 160 | glViewport(0, 0, w*ratio, h*ratio); 161 | nvgBeginFrame(ctx, w, h, ratio); 162 | lbind_returnself(L); 163 | } 164 | 165 | static int LcancelFrame(lua_State *L) { 166 | nvgCancelFrame(check_context(L, 1)); 167 | lbind_returnself(L); 168 | } 169 | 170 | static int LendFrame(lua_State *L) { 171 | nvgEndFrame(check_context(L, 1)); 172 | lbind_returnself(L); 173 | } 174 | 175 | static int Lsave(lua_State *L) { 176 | nvgSave(check_context(L, 1)); 177 | lbind_returnself(L); 178 | } 179 | 180 | static int Lrestore(lua_State *L) { 181 | nvgRestore(check_context(L, 1)); 182 | lbind_returnself(L); 183 | } 184 | 185 | static int Lreset(lua_State *L) { 186 | nvgReset(check_context(L, 1)); 187 | lbind_returnself(L); 188 | } 189 | 190 | /* transform routines */ 191 | 192 | static int LresetTransform(lua_State *L) { 193 | nvgResetTransform(check_context(L, 1)); 194 | lbind_returnself(L); 195 | } 196 | 197 | static int LcurrentTransform(lua_State *L) { 198 | NVGcontext *ctx = check_context(L, 1); 199 | float d[6]; 200 | nvgCurrentTransform(ctx, d); 201 | lua_pushnumber(L, d[0]); 202 | lua_pushnumber(L, d[3]); 203 | lua_pushnumber(L, d[1]); 204 | lua_pushnumber(L, d[4]); 205 | lua_pushnumber(L, d[2]); 206 | lua_pushnumber(L, d[5]); 207 | return 6; 208 | } 209 | 210 | static int Ltransform(lua_State *L) { 211 | NVGcontext *ctx = check_context(L, 1); 212 | float a = (float)luaL_optnumber(L, 2, 1.0); 213 | float b = (float)luaL_optnumber(L, 3, 0.0); 214 | float c = (float)luaL_optnumber(L, 4, 0.0); 215 | float d = (float)luaL_optnumber(L, 5, 0.0); 216 | float e = (float)luaL_optnumber(L, 6, 1.0); 217 | float f = (float)luaL_optnumber(L, 7, 0.0); 218 | nvgTransform(ctx, a, b, c, d, e, f); 219 | lbind_returnself(L); 220 | } 221 | 222 | static int Ltranslate(lua_State *L) { 223 | NVGcontext *ctx = check_context(L, 1); 224 | float x = (float)luaL_checknumber(L, 2); 225 | float y = (float)luaL_checknumber(L, 3); 226 | nvgTranslate(ctx, x, y); 227 | lbind_returnself(L); 228 | } 229 | 230 | static int Lscale(lua_State *L) { 231 | NVGcontext *ctx = check_context(L, 1); 232 | float x = (float)luaL_checknumber(L, 2); 233 | float y = (float)luaL_checknumber(L, 3); 234 | nvgScale(ctx, x, y); 235 | lbind_returnself(L); 236 | } 237 | 238 | static int Lrotate(lua_State *L) { 239 | NVGcontext *ctx = check_context(L, 1); 240 | float angle = (float)luaL_checknumber(L, 2); 241 | nvgRotate(ctx, angle); 242 | lbind_returnself(L); 243 | } 244 | 245 | static int Lskew(lua_State *L) { 246 | NVGcontext *ctx = check_context(L, 1); 247 | float x = (float)luaL_optnumber(L, 2, 0.0); 248 | float y = (float)luaL_optnumber(L, 3, 0.0); 249 | if (x != 0.0) nvgSkewX(ctx, x); 250 | if (y != 0.0) nvgSkewY(ctx, y); 251 | lbind_returnself(L); 252 | } 253 | 254 | /* scissor support */ 255 | 256 | static int LresetScissor(lua_State *L) { 257 | nvgResetScissor(check_context(L, 1)); 258 | lbind_returnself(L); 259 | } 260 | 261 | static int Lscissor(lua_State *L) { 262 | NVGcontext *ctx = check_context(L, 1); 263 | float x = (float)luaL_checknumber(L, 2); 264 | float y = (float)luaL_checknumber(L, 3); 265 | float w = (float)luaL_checknumber(L, 4); 266 | float h = (float)luaL_checknumber(L, 5); 267 | nvgScissor(ctx, x, y, w, h); 268 | lbind_returnself(L); 269 | } 270 | 271 | static int LintersectScissor(lua_State *L) { 272 | NVGcontext *ctx = check_context(L, 1); 273 | float x = (float)luaL_checknumber(L, 2); 274 | float y = (float)luaL_checknumber(L, 3); 275 | float w = (float)luaL_checknumber(L, 4); 276 | float h = (float)luaL_checknumber(L, 5); 277 | nvgIntersectScissor(ctx, x, y, w, h); 278 | lbind_returnself(L); 279 | } 280 | 281 | /* composite operation */ 282 | 283 | static lbind_EnumItem composite_operations[] = { 284 | { "atop", NVG_ATOP }, 285 | { "copy", NVG_COPY }, 286 | { "destination_atop", NVG_DESTINATION_ATOP }, 287 | { "destination_in", NVG_DESTINATION_IN }, 288 | { "destination_out", NVG_DESTINATION_OUT }, 289 | { "destination_over", NVG_DESTINATION_OVER }, 290 | { "ligther", NVG_LIGHTER }, 291 | { "source_in", NVG_SOURCE_IN }, 292 | { "source_out", NVG_SOURCE_OUT }, 293 | { "xor", NVG_XOR }, 294 | { "source_over", NVG_SOURCE_OVER }, 295 | { NULL, 0 } 296 | }; 297 | 298 | static lbind_EnumItem blend_factors[] = { 299 | { "dst_alpha", NVG_DST_ALPHA }, 300 | { "dst_color", NVG_DST_COLOR }, 301 | { "one", NVG_ONE }, 302 | { "one_minus_dst_alpha", NVG_ONE_MINUS_DST_ALPHA }, 303 | { "one_minus_dst_color", NVG_ONE_MINUS_DST_COLOR }, 304 | { "one_minus_src_alpha", NVG_ONE_MINUS_SRC_ALPHA }, 305 | { "one_minus_src_color", NVG_ONE_MINUS_SRC_COLOR }, 306 | { "src_alpha", NVG_SRC_ALPHA }, 307 | { "src_alpha_saturate", NVG_SRC_ALPHA_SATURATE }, 308 | { "src_color", NVG_SRC_COLOR }, 309 | { "zero", NVG_ZERO }, 310 | { NULL, 0 } 311 | }; 312 | 313 | static int LglobalCompositeOperation(lua_State *L) { 314 | static lbind_Enum et = LBIND_INITENUM("CompositeOperation", 315 | composite_operations); 316 | NVGcontext *ctx = check_context(L, 1); 317 | int op = lbind_checkenum(L, 2, &et); 318 | nvgGlobalCompositeOperation(ctx, op); 319 | lbind_returnself(L); 320 | } 321 | 322 | static int LglobalCompositeBlendFunc(lua_State *L) { 323 | static lbind_Enum et = LBIND_INITENUM("BlendFactor", blend_factors); 324 | NVGcontext *ctx = check_context(L, 1); 325 | int sfactor = lbind_checkenum(L, 2, &et); 326 | int dfactor = lbind_checkenum(L, 3, &et); 327 | nvgGlobalCompositeBlendFunc(ctx, sfactor, dfactor); 328 | lbind_returnself(L); 329 | } 330 | 331 | static int LglobalCompositeBlendFuncSeparate(lua_State *L) { 332 | static lbind_Enum et = LBIND_INITENUM("BlendFactor", blend_factors); 333 | NVGcontext *ctx = check_context(L, 1); 334 | int srcRGB = lbind_checkenum(L, 2, &et); 335 | int dstRGB = lbind_checkenum(L, 3, &et); 336 | int srcAlpha = lbind_checkenum(L, 4, &et); 337 | int dstAlpha = lbind_checkenum(L, 5, &et); 338 | nvgGlobalCompositeBlendFuncSeparate(ctx, srcRGB, dstRGB, srcAlpha, dstAlpha); 339 | lbind_returnself(L); 340 | } 341 | 342 | /* path routines */ 343 | 344 | static int LbeginPath(lua_State *L) { 345 | nvgBeginPath(check_context(L, 1)); 346 | lbind_returnself(L); 347 | } 348 | 349 | static int LmoveTo(lua_State *L) { 350 | NVGcontext *ctx = check_context(L, 1); 351 | float x = (float)luaL_checknumber(L, 2); 352 | float y = (float)luaL_checknumber(L, 3); 353 | nvgMoveTo(ctx, x, y); 354 | lbind_returnself(L); 355 | } 356 | 357 | static int LlineTo(lua_State *L) { 358 | NVGcontext *ctx = check_context(L, 1); 359 | float x = (float)luaL_checknumber(L, 2); 360 | float y = (float)luaL_checknumber(L, 3); 361 | nvgLineTo(ctx, x, y); 362 | lbind_returnself(L); 363 | } 364 | 365 | static int LquadraticCurveTo(lua_State *L) { 366 | NVGcontext *ctx = check_context(L, 1); 367 | float cx = (float)luaL_checknumber(L, 2); 368 | float cy = (float)luaL_checknumber(L, 3); 369 | float x = (float)luaL_checknumber(L, 4); 370 | float y = (float)luaL_checknumber(L, 5); 371 | nvgQuadTo(ctx, cx, cy, x, y); 372 | lbind_returnself(L); 373 | } 374 | 375 | static int LbezierCurveTo(lua_State *L) { 376 | NVGcontext *ctx = check_context(L, 1); 377 | float c1x = (float)luaL_checknumber(L, 2); 378 | float c1y = (float)luaL_checknumber(L, 3); 379 | float c2x = (float)luaL_checknumber(L, 4); 380 | float c2y = (float)luaL_checknumber(L, 5); 381 | float x = (float)luaL_checknumber(L, 6); 382 | float y = (float)luaL_checknumber(L, 7); 383 | nvgBezierTo(ctx, c1x, c1y, c2x, c2y, x, y); 384 | lbind_returnself(L); 385 | } 386 | 387 | static int LarcTo(lua_State *L) { 388 | NVGcontext *ctx = check_context(L, 1); 389 | float x1 = (float)luaL_checknumber(L, 2); 390 | float y1 = (float)luaL_checknumber(L, 3); 391 | float x2 = (float)luaL_checknumber(L, 4); 392 | float y2 = (float)luaL_checknumber(L, 5); 393 | float radius = (float)luaL_checknumber(L, 6); 394 | nvgArcTo(ctx, x1, y1, x2, y2, radius); 395 | lbind_returnself(L); 396 | } 397 | 398 | static int LclosePath(lua_State *L) { 399 | nvgClosePath(check_context(L, 1)); 400 | lbind_returnself(L); 401 | } 402 | 403 | /* primitive routines */ 404 | 405 | static int Larc(lua_State *L) { 406 | static lbind_EnumItem opts[] = { 407 | { "ccw", NVG_CCW }, 408 | { "cw", NVG_CW }, 409 | { NULL, 0 } 410 | }; 411 | static lbind_Enum et = LBIND_INITENUM("ArcDirection", opts); 412 | NVGcontext *ctx = check_context(L, 1); 413 | float cx = (float)luaL_checknumber(L, 2); 414 | float cy = (float)luaL_checknumber(L, 3); 415 | float r = (float)luaL_checknumber(L, 4); 416 | float a0 = (float)luaL_checknumber(L, 5); 417 | float a1 = (float)luaL_checknumber(L, 6); 418 | int dir = lbind_optenum(L, 7, NVG_CCW, &et); 419 | nvgArc(ctx, cx, cy, r, a0, a1, dir); 420 | lbind_returnself(L); 421 | } 422 | 423 | static int Lrect(lua_State *L) { 424 | NVGcontext *ctx = check_context(L, 1); 425 | float x = (float)luaL_checknumber(L, 2); 426 | float y = (float)luaL_checknumber(L, 3); 427 | float w = (float)luaL_checknumber(L, 4); 428 | float h = (float)luaL_checknumber(L, 5); 429 | nvgRect(ctx, x, y, w, h); 430 | lbind_returnself(L); 431 | } 432 | 433 | static int LroundedRect(lua_State *L) { 434 | NVGcontext *ctx = check_context(L, 1); 435 | float x = (float)luaL_checknumber(L, 2); 436 | float y = (float)luaL_checknumber(L, 3); 437 | float w = (float)luaL_checknumber(L, 4); 438 | float h = (float)luaL_checknumber(L, 5); 439 | float r = (float)luaL_checknumber(L, 6); 440 | if (lua_gettop(L) == 6) 441 | nvgRoundedRect(ctx, x, y, w, h, r); 442 | else { 443 | float r2 = (float)luaL_checknumber(L, 7); 444 | float r3 = (float)luaL_checknumber(L, 8); 445 | float r4 = (float)luaL_checknumber(L, 9); 446 | nvgRoundedRectVarying(ctx, x, y, w, h, r, r2, r3, r4); 447 | } 448 | lbind_returnself(L); 449 | } 450 | 451 | static int Lellipse(lua_State *L) { 452 | NVGcontext *ctx = check_context(L, 1); 453 | float cx = (float)luaL_checknumber(L, 2); 454 | float cy = (float)luaL_checknumber(L, 3); 455 | float rx = (float)luaL_checknumber(L, 4); 456 | float ry = (float)luaL_checknumber(L, 5); 457 | nvgEllipse(ctx, cx, cy, rx, ry); 458 | lbind_returnself(L); 459 | } 460 | 461 | static int Lcircle(lua_State *L) { 462 | NVGcontext *ctx = check_context(L, 1); 463 | float cx = (float)luaL_checknumber(L, 2); 464 | float cy = (float)luaL_checknumber(L, 3); 465 | float r = (float)luaL_checknumber(L, 4); 466 | nvgCircle(ctx, cx, cy, r); 467 | lbind_returnself(L); 468 | } 469 | 470 | static int Lfill(lua_State *L) { 471 | nvgFill(check_context(L, 1)); 472 | lbind_returnself(L); 473 | } 474 | 475 | static int Lstroke(lua_State *L) { 476 | nvgStroke(check_context(L, 1)); 477 | lbind_returnself(L); 478 | } 479 | 480 | /* text routines */ 481 | 482 | static size_t posrelat(ptrdiff_t pos, size_t len) { 483 | if (pos >= 0) return (size_t)pos; 484 | else if (0u - (size_t)pos > len) return 0; 485 | else return len - ((size_t)-pos) + 1; 486 | } 487 | 488 | static const char *check_text(lua_State *L, int idx, const char **e) { 489 | size_t len; 490 | const char *s = luaL_checklstring(L, idx, &len); 491 | size_t i = posrelat(luaL_optinteger(L, idx+1, 1), len); 492 | size_t j = posrelat(luaL_optinteger(L, idx+2, -1), len); 493 | if (i < 1) i = 1; 494 | if (j > len) j = len; 495 | if (i <= j) { 496 | *e = s + j; 497 | return s + i -1; 498 | } 499 | return NULL; 500 | } 501 | 502 | static int Ltext(lua_State *L) { 503 | NVGcontext *ctx = check_context(L, 1); 504 | float x = (float)luaL_checknumber(L, 2); 505 | float y = (float)luaL_checknumber(L, 3); 506 | float width = 0; 507 | int text_idx = 4; 508 | const char *s, *e; 509 | if (lua_type(L, text_idx) == LUA_TNUMBER) { 510 | width = (float)luaL_checknumber(L, 4); 511 | ++text_idx; 512 | } 513 | s = check_text(L, text_idx, &e); 514 | if (s != NULL) { 515 | if (width == 0) 516 | nvgText(ctx, x, y, s, e); 517 | else 518 | nvgTextBox(ctx, x, y, width, s, e); 519 | } 520 | lbind_returnself(L); 521 | } 522 | 523 | static int LtextBounds(lua_State *L) { 524 | NVGcontext *ctx = check_context(L, 1); 525 | int text_idx = 2; 526 | float x = 0, y = 0, width = 0, box[4]; 527 | const char *s, *e; 528 | if (lua_type(L, 2) == LUA_TNUMBER) { 529 | x = (float)luaL_checknumber(L, 2); 530 | y = (float)luaL_checknumber(L, 3); 531 | text_idx = 4; 532 | if (lua_type(L, 4) == LUA_TNUMBER) { 533 | width = (float)luaL_checknumber(L, 4); 534 | text_idx = 5; 535 | } 536 | } 537 | s = check_text(L, text_idx, &e); 538 | if (s != NULL) { 539 | int nret = 4; 540 | if (width != 0) 541 | nvgTextBoxBounds(ctx, x, y, width, s, e, box); 542 | else { 543 | lua_pushnumber(L, nvgTextBounds(ctx, x, y, s, e, box)); 544 | nret = 5; 545 | } 546 | lua_pushnumber(L, box[0]); 547 | lua_pushnumber(L, box[1]); 548 | lua_pushnumber(L, box[2]); 549 | lua_pushnumber(L, box[3]); 550 | return nret; 551 | } 552 | return 0; 553 | } 554 | 555 | static int LtextMetrics(lua_State *L) { 556 | NVGcontext *ctx = check_context(L, 1); 557 | float ascender, descender, lineh; 558 | nvgTextMetrics(ctx, &ascender, &descender, &lineh); 559 | lua_pushnumber(L, ascender); 560 | lua_pushnumber(L, descender); 561 | lua_pushnumber(L, lineh); 562 | return 3; 563 | } 564 | 565 | static int LaddFallbackFont(lua_State *L) { 566 | NVGcontext *ctx = check_context(L, 1); 567 | const char *font = luaL_checkstring(L, 2); 568 | const char *fallback = luaL_checkstring(L, 3); 569 | nvgAddFallbackFont(ctx, font, fallback); 570 | return 0; 571 | } 572 | 573 | /* context settings */ 574 | 575 | static int LshapeAntiAlias(lua_State *L) { 576 | NVGcontext *ctx = check_context(L, 1); 577 | int enabled = lua_toboolean(L, 3); 578 | nvgShapeAntiAlias(ctx, enabled); 579 | return 0; 580 | } 581 | 582 | static int LglobalAlpha(lua_State *L) { 583 | NVGcontext *ctx = check_context(L, 1); 584 | float a = (float)luaL_checknumber(L, 3); 585 | nvgGlobalAlpha(ctx, a); 586 | return 0; 587 | } 588 | 589 | static int LmiterLimit(lua_State *L) { 590 | NVGcontext *ctx = check_context(L, 1); 591 | float w = (float)luaL_checknumber(L, 3); 592 | nvgMiterLimit(ctx, w); 593 | return 0; 594 | } 595 | 596 | static int LlineWidth(lua_State *L) { 597 | NVGcontext *ctx = check_context(L, 1); 598 | float w = (float)luaL_checknumber(L, 3); 599 | nvgStrokeWidth(ctx, w); 600 | return 0; 601 | } 602 | 603 | static int LfontFace(lua_State *L) { 604 | NVGcontext *ctx = check_context(L, 1); 605 | const char *font = luaL_checkstring(L, 3); 606 | nvgFontFace(ctx, font); 607 | return 0; 608 | } 609 | 610 | static int LfontSize(lua_State *L) { 611 | NVGcontext *ctx = check_context(L, 1); 612 | float s = (float)luaL_checknumber(L, 3); 613 | nvgFontSize(ctx, s); 614 | return 0; 615 | } 616 | 617 | static int LtextLetterSpacing(lua_State *L) { 618 | NVGcontext *ctx = check_context(L, 1); 619 | float s = (float)luaL_checknumber(L, 3); 620 | nvgTextLetterSpacing(ctx, s); 621 | return 0; 622 | } 623 | 624 | static int LtextLineHeight(lua_State *L) { 625 | NVGcontext *ctx = check_context(L, 1); 626 | float s = (float)luaL_checknumber(L, 3); 627 | nvgTextLineHeight(ctx, s); 628 | return 0; 629 | } 630 | 631 | static int LfontBlur(lua_State *L) { 632 | NVGcontext *ctx = check_context(L, 1); 633 | float b = (float)luaL_checknumber(L, 3); 634 | nvgFontBlur(ctx, b); 635 | return 0; 636 | } 637 | 638 | static int LlineCap(lua_State *L) { 639 | static const char *opts[] = { 640 | "butt", "round", "square", NULL 641 | }; 642 | static int map[] = { NVG_BUTT, NVG_ROUND, NVG_SQUARE }; 643 | NVGcontext *ctx = check_context(L, 1); 644 | int opt = luaL_checkoption(L, 3, NULL, opts); 645 | nvgLineCap(ctx, map[opt]); 646 | return 0; 647 | } 648 | 649 | static int LlineJoin(lua_State *L) { 650 | static const char *opts[] = { 651 | "round", "bevel", "miter", NULL 652 | }; 653 | static int map[] = { NVG_ROUND, NVG_BEVEL, NVG_MITER }; 654 | NVGcontext *ctx = check_context(L, 1); 655 | int opt = luaL_checkoption(L, 3, NULL, opts); 656 | nvgLineJoin(ctx, map[opt]); 657 | return 0; 658 | } 659 | 660 | static int LpathWinding(lua_State *L) { 661 | static lbind_EnumItem opts[] = { 662 | { "ccw", NVG_CCW }, 663 | { "cw", NVG_CW }, 664 | { "hole", NVG_HOLE }, 665 | { "solid", NVG_SOLID }, 666 | { NULL, 0 } 667 | }; 668 | static lbind_Enum et = LBIND_INITENUM("PathWinding", opts); 669 | NVGcontext *ctx = check_context(L, 1); 670 | int opt = lbind_checkenum(L, 3, &et); 671 | nvgPathWinding(ctx, opt); 672 | return 0; 673 | } 674 | 675 | static int LtextAlign(lua_State *L) { 676 | static lbind_EnumItem opts[] = { 677 | { "baseline", NVG_ALIGN_BASELINE }, 678 | { "bottom", NVG_ALIGN_BOTTOM }, 679 | { "center", NVG_ALIGN_CENTER }, 680 | { "left", NVG_ALIGN_LEFT }, 681 | { "middle", NVG_ALIGN_MIDDLE }, 682 | { "right", NVG_ALIGN_RIGHT }, 683 | { "top", NVG_ALIGN_TOP }, 684 | { NULL, 0 } 685 | }; 686 | static lbind_Enum et = LBIND_INITENUM("Align", opts); 687 | NVGcontext *ctx = check_context(L, 1); 688 | int align = lbind_checkmask(L, 3, &et); 689 | nvgTextAlign(ctx, align); 690 | return 0; 691 | } 692 | 693 | static int LstrokeColor(lua_State *L) { 694 | NVGcontext *ctx = check_context(L, 1); 695 | NVGcolor color; 696 | if (test_color(L, 3, &color)) 697 | nvgStrokeColor(ctx, color); 698 | else 699 | lbind_typeerror(L, 3, "color"); 700 | return 0; 701 | } 702 | 703 | static int LfillColor(lua_State *L) { 704 | NVGcontext *ctx = check_context(L, 1); 705 | NVGcolor color; 706 | if (test_color(L, 3, &color)) 707 | nvgFillColor(ctx, color); 708 | else 709 | lbind_typeerror(L, 3, "color"); 710 | return 0; 711 | } 712 | 713 | static int LstrokeStyle(lua_State *L) { 714 | NVGcontext *ctx = check_context(L, 1); 715 | NVGpaint paint; 716 | NVGcolor color; 717 | if (test_paint(L, 3, &paint)) 718 | nvgStrokePaint(ctx, paint); 719 | else if (test_color(L, 3, &color)) 720 | nvgStrokeColor(ctx, color); 721 | else 722 | lbind_typeerror(L, 3, "image/paint/color"); 723 | return 0; 724 | } 725 | 726 | static int LfillStyle(lua_State *L) { 727 | NVGcontext *ctx = check_context(L, 1); 728 | NVGcolor color; 729 | NVGpaint paint; 730 | if (test_paint(L, 3, &paint)) 731 | nvgFillPaint(ctx, paint); 732 | else if (test_color(L, 3, &color)) 733 | nvgFillColor(ctx, color); 734 | else 735 | lbind_typeerror(L, 3, "image/paint/color"); 736 | return 0; 737 | } 738 | 739 | /* register lua routines */ 740 | 741 | LBLIB_API int luaopen_nvg(lua_State *L) { 742 | luaL_Reg libs[] = { 743 | #define ENTRY(name) { #name, L##name } 744 | /* meta-methods */ 745 | ENTRY(__gc), 746 | /* object creation */ 747 | ENTRY(new), 748 | ENTRY(font), 749 | ENTRY(linearGradient), 750 | ENTRY(boxGradient), 751 | ENTRY(radialGradient), 752 | /* state routines */ 753 | ENTRY(clear), 754 | ENTRY(beginFrame), 755 | ENTRY(cancelFrame), 756 | ENTRY(endFrame), 757 | ENTRY(save), 758 | ENTRY(restore), 759 | ENTRY(reset), 760 | /* transform routines */ 761 | ENTRY(resetTransform), 762 | ENTRY(currentTransform), 763 | ENTRY(transform), 764 | ENTRY(translate), 765 | ENTRY(scale), 766 | ENTRY(rotate), 767 | ENTRY(skew), 768 | /* scissor support */ 769 | ENTRY(resetScissor), 770 | ENTRY(scissor), 771 | ENTRY(intersectScissor), 772 | /* composite operation */ 773 | ENTRY(globalCompositeOperation), 774 | ENTRY(globalCompositeBlendFunc), 775 | ENTRY(globalCompositeBlendFuncSeparate), 776 | /* path routines */ 777 | ENTRY(beginPath), 778 | ENTRY(moveTo), 779 | ENTRY(lineTo), 780 | ENTRY(quadraticCurveTo), 781 | ENTRY(bezierCurveTo), 782 | ENTRY(arcTo), 783 | ENTRY(closePath), 784 | /* primitive routines */ 785 | ENTRY(arc), 786 | ENTRY(rect), 787 | ENTRY(roundedRect), 788 | ENTRY(ellipse), 789 | ENTRY(circle), 790 | ENTRY(fill), 791 | ENTRY(stroke), 792 | /* text routines */ 793 | ENTRY(text), 794 | ENTRY(textMetrics), 795 | ENTRY(textBounds), 796 | ENTRY(addFallbackFont), 797 | #undef ENTRY 798 | { NULL, NULL } 799 | }; 800 | luaL_Reg setters[] = { 801 | #define ENTRY(name) { #name, L##name } 802 | ENTRY(shapeAntiAlias), 803 | ENTRY(globalAlpha), 804 | ENTRY(strokeColor), 805 | ENTRY(fillColor), 806 | ENTRY(strokeStyle), 807 | ENTRY(fillStyle), 808 | ENTRY(miterLimit), 809 | ENTRY(lineWidth), 810 | ENTRY(lineCap), 811 | ENTRY(lineJoin), 812 | ENTRY(pathWinding), 813 | ENTRY(fontFace), 814 | ENTRY(fontSize), 815 | ENTRY(fontBlur), 816 | ENTRY(textAlign), 817 | ENTRY(textLetterSpacing), 818 | ENTRY(textLineHeight), 819 | #undef ENTRY 820 | { NULL, NULL } 821 | }; 822 | lbind_newmetatable(L, NULL, &lbT_Paint); 823 | if (lbind_newmetatable(L, libs, &lbT_Context)) { 824 | lbind_setmaptable(L, setters, LBIND_NEWINDEX); 825 | opentype_image(L); 826 | lua_setfield(L, -2, "image"); 827 | } 828 | return 1; 829 | } 830 | 831 | 832 | /* image routines */ 833 | 834 | struct LNVGimage { 835 | NVGcontext *ctx; 836 | float ox, oy, ex, ey, angle, alpha; 837 | int image; 838 | int repeat; 839 | }; 840 | 841 | static NVGpaint image_to_paint(LNVGimage *image) { 842 | // fprintf(stdout, "converting image `%d` to paint: {ox: %f, oy: %f, ex: %f, ey: %f}\n", image->image, image->ox, image->oy, image->ex, image->ey); 843 | return nvgImagePattern(image->ctx, 844 | image->ox, image->oy, image->ex, image->ey, 845 | image->angle, image->image, image->alpha); 846 | } 847 | 848 | static int test_paint(lua_State *L, int idx, NVGpaint *paint) { 849 | NVGpaint *p; 850 | LNVGimage *img; 851 | if ((img = (LNVGimage*)lbind_test(L, idx, &lbT_Image)) != NULL) { 852 | *paint = image_to_paint(img); 853 | return 1; 854 | } 855 | else if ((p = (NVGpaint*)lbind_test(L, idx, &lbT_Paint)) != NULL) { 856 | *paint = *p; 857 | return 1; 858 | } 859 | return 0; 860 | } 861 | 862 | static int Limage___gc(lua_State *L) { 863 | LNVGimage *image = (LNVGimage*)lbind_test(L, 1, &lbT_Image); 864 | if (image != NULL && image->image >= 0) { 865 | nvgDeleteImage(image->ctx, image->image); 866 | image->image = -1; 867 | lbind_delete(L, 1); 868 | } 869 | return 0; 870 | } 871 | 872 | static LNVGimage *new_image(lua_State *L) { 873 | LNVGimage *image = (LNVGimage*)lbind_new(L, sizeof(LNVGimage), &lbT_Image); 874 | image->ctx = NULL; 875 | image->ox = image->oy = 0.0f; 876 | image->ex = image->ey = 0.0f; 877 | image->angle = 0.0f; 878 | image->alpha = 1.0f; 879 | image->image = -1; 880 | image->repeat = 0; 881 | return image; 882 | } 883 | 884 | static lbind_EnumItem image_flags[] = { 885 | { "flipy", NVG_IMAGE_FLIPY }, 886 | { "mipmaps", NVG_IMAGE_GENERATE_MIPMAPS }, 887 | { "nearest", NVG_IMAGE_NEAREST }, 888 | { "premulti", NVG_IMAGE_PREMULTIPLIED }, 889 | { "repeatx", NVG_IMAGE_REPEATX }, 890 | { "repeaty", NVG_IMAGE_REPEATY }, 891 | { NULL, 0 } 892 | }; 893 | 894 | static int Limage_load(lua_State *L) { 895 | static lbind_Enum lbE_imageflags = 896 | LBIND_INITENUM("ImageFlags", image_flags); 897 | LNVGimage *image; 898 | int hasDpiArg = 0; 899 | if (lua_gettop(L) == 4) { 900 | hasDpiArg = 1; 901 | } 902 | NVGcontext *ctx = check_context(L, 1); 903 | const char *filename = luaL_checkstring(L, 2); 904 | int flags = lbind_optmask(L, 3, 0, &lbE_imageflags); 905 | float dpi = 96.0f; 906 | if (hasDpiArg) { 907 | dpi = luaL_checknumber(L, 4); 908 | } 909 | const char *ext = strrchr(filename, '.'); 910 | int imageid = -1; 911 | // defaults 912 | float ex = 0.0f; 913 | float ey = 0.0f; 914 | if (lbE_stricmp(".svg", ext, 4) == 0) { 915 | // is SVG 916 | NSVGrasterizer *rast = nsvgCreateRasterizer(); 917 | if (rast == NULL) { 918 | return luaL_error(L, "Failed allocating rasterizer"); 919 | } 920 | NSVGimage *vector = nsvgParseFromFile(filename, "px", dpi); 921 | if (vector != NULL) { 922 | int w = (int)vector->width; 923 | int h = (int)vector->height; 924 | unsigned char* img = malloc(w * h * 4); 925 | if (img == NULL) { 926 | return luaL_error(L, "Failed allocating raster image buffer"); 927 | } else { 928 | nsvgRasterize(rast, vector, 0,0,1, img, w, h, w*4); 929 | imageid = nvgCreateImageRGBA(ctx, w, h, flags, img); 930 | if (imageid > 0) { 931 | ex = w; 932 | ey = h; 933 | } 934 | } 935 | } 936 | if (rast != NULL) { 937 | nsvgDeleteRasterizer(rast); 938 | } 939 | } else { 940 | imageid = nvgCreateImage(ctx, filename, flags); 941 | } 942 | if (imageid < 0) 943 | lbind_argferror(L, 3, "invalid image file: %s", filename); 944 | image = new_image(L); 945 | image->image = imageid; 946 | image->ctx = ctx; 947 | image->ex = ex; 948 | image->ey = ey; 949 | return 1; 950 | } 951 | 952 | static int Limage_data(lua_State *L) { 953 | static lbind_Enum lbE_imageflags = 954 | LBIND_INITENUM("ImageFlags", image_flags); 955 | LNVGimage *image; 956 | NVGcontext *ctx = check_context(L, 1); 957 | size_t len; 958 | const char *data = luaL_checklstring(L, 2, &len); 959 | int flags = lbind_optmask(L, 3, 0, &lbE_imageflags); 960 | int imageid = nvgCreateImageMem(ctx, flags, (unsigned char*)data, len); 961 | if (imageid < 0) 962 | luaL_argerror(L, 3, "invalid image data"); 963 | image = new_image(L); 964 | image->image = imageid; 965 | image->ctx = ctx; 966 | return 1; 967 | } 968 | 969 | static int Limage_rgba(lua_State *L) { 970 | static lbind_Enum lbE_imageflags = 971 | LBIND_INITENUM("ImageFlags", image_flags); 972 | LNVGimage *image; 973 | NVGcontext *ctx = check_context(L, 1); 974 | int w = luaL_checkinteger(L, 2); 975 | int h = luaL_checkinteger(L, 3); 976 | int flags = lbind_optmask(L, 4, 0, &lbE_imageflags); 977 | const char *data = luaL_checkstring(L, 5); 978 | int imageid = nvgCreateImageRGBA(ctx, w, h, flags, (unsigned char*)data); 979 | if (imageid < 0) 980 | luaL_argerror(L, 3, "invalid image data"); 981 | image = new_image(L); 982 | image->image = imageid; 983 | image->ctx = ctx; 984 | return 1; 985 | } 986 | 987 | static int Limage_update(lua_State *L) { 988 | LNVGimage *image = check_image(L, 1); 989 | const char *data = luaL_checkstring(L, 2); 990 | nvgUpdateImage(image->ctx, image->image, (unsigned char*)data); 991 | lbind_returnself(L); 992 | } 993 | 994 | static int Limage_size(lua_State *L) { 995 | LNVGimage *image = check_image(L, 1); 996 | int w, h; 997 | nvgImageSize(image->ctx, image->image, &w, &h); 998 | lua_pushinteger(L, w); 999 | lua_pushinteger(L, h); 1000 | return 2; 1001 | } 1002 | 1003 | static int Limage_extent(lua_State *L) { 1004 | LNVGimage *image = check_image(L, 1); 1005 | image->ox = (float)luaL_checknumber(L, 2); 1006 | image->oy = (float)luaL_checknumber(L, 3); 1007 | image->ex = (float)luaL_checknumber(L, 4); 1008 | image->ey = (float)luaL_checknumber(L, 5); 1009 | lbind_returnself(L); 1010 | } 1011 | 1012 | static int Limage_width(lua_State *L) { 1013 | if (lua_gettop(L) == 3) return 0; 1014 | Limage_size(L); 1015 | lua_pop(L, 1); 1016 | return 1; 1017 | } 1018 | 1019 | static int Limage_height(lua_State *L) { 1020 | if (lua_gettop(L) == 3) return 0; 1021 | Limage_size(L); 1022 | return 1; 1023 | } 1024 | 1025 | static int Limage_repeat(lua_State *L) { 1026 | LNVGimage *image = check_image(L, 1); 1027 | const char *s; 1028 | if (lua_gettop(L) == 2) return 0; 1029 | s = luaL_checkstring(L, 3); 1030 | if (strcmp(s, "x") == 0) 1031 | image->repeat = NVG_IMAGE_REPEATX; 1032 | else if (strcmp(s, "y") == 0) 1033 | image->repeat = NVG_IMAGE_REPEATY; 1034 | else if (strcmp(s, "xy") == 0 || strcmp(s, "yx") == 0) 1035 | image->repeat = NVG_IMAGE_REPEATX|NVG_IMAGE_REPEATY; 1036 | else 1037 | lbind_argferror(L, 3, "invalid image repeat: %s", s); 1038 | return 0; 1039 | } 1040 | 1041 | static int Limage_angle(lua_State *L) { 1042 | LNVGimage *image = check_image(L, 1); 1043 | float angle; 1044 | if (lua_gettop(L) == 2) return 0; 1045 | angle = (float)luaL_checknumber(L, 3); 1046 | image->angle = angle; 1047 | return 0; 1048 | } 1049 | 1050 | static int Limage_alpha(lua_State *L) { 1051 | LNVGimage *image = check_image(L, 1); 1052 | float alpha; 1053 | if (lua_gettop(L) == 2) return 0; 1054 | alpha = (float)luaL_checknumber(L, 3); 1055 | image->alpha = alpha; 1056 | return 0; 1057 | } 1058 | 1059 | static int opentype_image(lua_State *L) { 1060 | luaL_Reg libs[] = { 1061 | #define ENTRY(name) { #name, Limage_##name } 1062 | ENTRY(__gc), 1063 | ENTRY(load), 1064 | ENTRY(data), 1065 | ENTRY(rgba), 1066 | ENTRY(update), 1067 | ENTRY(extent), 1068 | #undef ENTRY 1069 | { NULL, NULL } 1070 | }; 1071 | luaL_Reg attrs[] = { 1072 | #define ENTRY(name) { #name, Limage_##name } 1073 | ENTRY(width), 1074 | ENTRY(height), 1075 | ENTRY(angle), 1076 | ENTRY(repeat), 1077 | ENTRY(alpha), 1078 | #undef ENTRY 1079 | { NULL, NULL } 1080 | }; 1081 | if (lbind_newmetatable(L, libs, &lbT_Image)) { 1082 | lbind_setmaptable(L, attrs, LBIND_INDEX|LBIND_NEWINDEX); 1083 | lbind_setlibcall(L, "load"); 1084 | } 1085 | return 1; 1086 | } 1087 | 1088 | 1089 | /* color routines */ 1090 | 1091 | static lbind_EnumItem colors[] = { 1092 | { "aliceblue", 0xFFF0F8FF }, 1093 | { "antiquewhite", 0xFFFAEBD7 }, 1094 | { "aqua", 0xFF00FFFF }, 1095 | { "aquamarine", 0xFF7FFFD4 }, 1096 | { "azure", 0xFFF0FFFF }, 1097 | { "beige", 0xFFF5F5DC }, 1098 | { "bisque", 0xFFFFE4C4 }, 1099 | { "black", 0xFF000000 }, 1100 | { "blanchedalmond", 0xFFFFEBCD }, 1101 | { "blue", 0xFF0000FF }, 1102 | { "blueviolet", 0xFF8A2BE2 }, 1103 | { "brown", 0xFFA52A2A }, 1104 | { "burlywood", 0xFFDEB887 }, 1105 | { "cadetblue", 0xFF5F9EA0 }, 1106 | { "chartreuse", 0xFF7FFF00 }, 1107 | { "chocolate", 0xFFD2691E }, 1108 | { "coral", 0xFFFF7F50 }, 1109 | { "cornflowerblue", 0xFF6495ED }, 1110 | { "cornsilk", 0xFFFFF8DC }, 1111 | { "crimson", 0xFFDC143C }, 1112 | { "cyan", 0xFF00FFFF }, 1113 | { "darkblue", 0xFF00008B }, 1114 | { "darkcyan", 0xFF008B8B }, 1115 | { "darkgoldenrod", 0xFFB8860B }, 1116 | { "darkgray", 0xFFA9A9A9 }, 1117 | { "darkgreen", 0xFF006400 }, 1118 | { "darkkhaki", 0xFFBDB76B }, 1119 | { "darkmagenta", 0xFF8B008B }, 1120 | { "darkolivegreen", 0xFF556B2F }, 1121 | { "darkorange", 0xFFFF8C00 }, 1122 | { "darkorchid", 0xFF9932CC }, 1123 | { "darkred", 0xFF8B0000 }, 1124 | { "darksalmon", 0xFFE9967A }, 1125 | { "darkseagreen", 0xFF8FBC8F }, 1126 | { "darkslateblue", 0xFF483D8B }, 1127 | { "darkslategray", 0xFF2F4F4F }, 1128 | { "darkturquoise", 0xFF00CED1 }, 1129 | { "darkviolet", 0xFF9400D3 }, 1130 | { "deeppink", 0xFFFF1493 }, 1131 | { "deepskyblue", 0xFF00BFFF }, 1132 | { "dimgray", 0xFF696969 }, 1133 | { "dodgerblue", 0xFF1E90FF }, 1134 | { "firebrick", 0xFFB22222 }, 1135 | { "floralwhite", 0xFFFFFAF0 }, 1136 | { "forestgreen", 0xFF228B22 }, 1137 | { "fuchsia", 0xFFFF00FF }, 1138 | { "gainsboro", 0xFFDCDCDC }, 1139 | { "ghostwhite", 0xFFF8F8FF }, 1140 | { "gold", 0xFFFFD700 }, 1141 | { "goldenrod", 0xFFDAA520 }, 1142 | { "gray", 0xFF808080 }, 1143 | { "green", 0xFF008000 }, 1144 | { "greenyellow", 0xFFADFF2F }, 1145 | { "honeydew", 0xFFF0FFF0 }, 1146 | { "hotpink", 0xFFFF69B4 }, 1147 | { "indianred", 0xFFCD5C5C }, 1148 | { "indigo", 0xFF4B0082 }, 1149 | { "ivory", 0xFFFFFFF0 }, 1150 | { "khaki", 0xFFF0E68C }, 1151 | { "lavender", 0xFFE6E6FA }, 1152 | { "lavenderblush", 0xFFFFF0F5 }, 1153 | { "lawngreen", 0xFF7CFC00 }, 1154 | { "lemonchiffon", 0xFFFFFACD }, 1155 | { "lightblue", 0xFFADD8E6 }, 1156 | { "lightcoral", 0xFFF08080 }, 1157 | { "lightcyan", 0xFFE0FFFF }, 1158 | { "lightgoldenrodYellow", 0xFFFAFAD2 }, 1159 | { "lightgray", 0xFFD3D3D3 }, 1160 | { "lightgreen", 0xFF90EE90 }, 1161 | { "lightpink", 0xFFFFB6C1 }, 1162 | { "lightsalmon", 0xFFFFA07A }, 1163 | { "lightseagreen", 0xFF20B2AA }, 1164 | { "lightskyblue", 0xFF87CEFA }, 1165 | { "lightslategray", 0xFF778899 }, 1166 | { "lightsteelblue", 0xFFB0C4DE }, 1167 | { "lightyellow", 0xFFFFFFE0 }, 1168 | { "lime", 0xFF00FF00 }, 1169 | { "limegreen", 0xFF32CD32 }, 1170 | { "linen", 0xFFFAF0E6 }, 1171 | { "magenta", 0xFFFF00FF }, 1172 | { "maroon", 0xFF800000 }, 1173 | { "mediumaquamarine", 0xFF66CDAA }, 1174 | { "mediumblue", 0xFF0000CD }, 1175 | { "mediumorchid", 0xFFBA55D3 }, 1176 | { "mediumpurple", 0xFF9370DB }, 1177 | { "mediumseagreen", 0xFF3CB371 }, 1178 | { "mediumslateblue", 0xFF7B68EE }, 1179 | { "mediumspringgreen", 0xFF00FA9A }, 1180 | { "mediumturquoise", 0xFF48D1CC }, 1181 | { "mediumvioletred", 0xFFC71585 }, 1182 | { "midnightblue", 0xFF191970 }, 1183 | { "mintcream", 0xFFF5FFFA }, 1184 | { "mistyrose", 0xFFFFE4E1 }, 1185 | { "moccasin", 0xFFFFE4B5 }, 1186 | { "navajowhite", 0xFFFFDEAD }, 1187 | { "navy", 0xFF000080 }, 1188 | { "oldlace", 0xFFFDF5E6 }, 1189 | { "olive", 0xFF808000 }, 1190 | { "olivedrab", 0xFF6B8E23 }, 1191 | { "orange", 0xFFFFA500 }, 1192 | { "orangered", 0xFFFF4500 }, 1193 | { "orchid", 0xFFDA70D6 }, 1194 | { "palegoldenrod", 0xFFEEE8AA }, 1195 | { "palegreen", 0xFF98FB98 }, 1196 | { "paleturquoise", 0xFFAFEEEE }, 1197 | { "palevioletred", 0xFFDB7093 }, 1198 | { "papayawhip", 0xFFFFEFD5 }, 1199 | { "peachpuff", 0xFFFFDAB9 }, 1200 | { "peru", 0xFFCD853F }, 1201 | { "pink", 0xFFFFC0CB }, 1202 | { "plum", 0xFFDDA0DD }, 1203 | { "powderblue", 0xFFB0E0E6 }, 1204 | { "purple", 0xFF800080 }, 1205 | { "red", 0xFFFF0000 }, 1206 | { "rosybrown", 0xFFBC8F8F }, 1207 | { "royalblue", 0xFF4169E1 }, 1208 | { "saddlebrown", 0xFF8B4513 }, 1209 | { "salmon", 0xFFFA8072 }, 1210 | { "sandybrown", 0xFFF4A460 }, 1211 | { "seagreen", 0xFF2E8B57 }, 1212 | { "seashell", 0xFFFFF5EE }, 1213 | { "sienna", 0xFFA0522D }, 1214 | { "silver", 0xFFC0C0C0 }, 1215 | { "skyblue", 0xFF87CEEB }, 1216 | { "slateblue", 0xFF6A5ACD }, 1217 | { "slategray", 0xFF708090 }, 1218 | { "snow", 0xFFFFFAFA }, 1219 | { "springgreen", 0xFF00FF7F }, 1220 | { "steelblue", 0xFF4682B4 }, 1221 | { "tan", 0xFFD2B48C }, 1222 | { "teal", 0xFF008080 }, 1223 | { "thistle", 0xFFD8BFD8 }, 1224 | { "tomato", 0xFFFF6347 }, 1225 | { "transparent", 0x00000000 }, 1226 | { "turquoise", 0xFF40E0D0 }, 1227 | { "violet", 0xFFEE82EE }, 1228 | { "wheat", 0xFFF5DEB3 }, 1229 | { "white", 0xFFFFFFFF }, 1230 | { "whitesmoke", 0xFFF5F5F5 }, 1231 | { "yellow", 0xFFFFFF00 }, 1232 | { "yellowgreen", 0xFF9ACD32 }, 1233 | { NULL, 0 } 1234 | }; 1235 | 1236 | static NVGcolor unpack_color(unsigned packed) { 1237 | NVGcolor color; 1238 | color.a = ((packed >> 24) & 0xFF)/255.0f; 1239 | color.r = ((packed >> 16) & 0xFF)/255.0f; 1240 | color.g = ((packed >> 8) & 0xFF)/255.0f; 1241 | color.b = ((packed ) & 0xFF)/255.0f; 1242 | return color; 1243 | } 1244 | 1245 | static unsigned pack_color(NVGcolor c) { 1246 | return 1247 | ((int)(c.a * 255) << 24) | 1248 | ((int)(c.r * 255) << 16) | 1249 | ((int)(c.g * 255) << 8) | 1250 | ((int)(c.b * 255) ) ; 1251 | } 1252 | 1253 | static int color_from_name(const char *name, size_t len, NVGcolor *c) { 1254 | static lbind_Enum et = LBIND_INITENUM("ColorName", colors); 1255 | lbind_EnumItem *item; 1256 | item = lbind_findenum(&et, name, len); 1257 | if (item == NULL) 1258 | return 0; 1259 | *c = unpack_color(item->value); 1260 | return 1; 1261 | } 1262 | 1263 | static const char *skip_whitespace(const char *s) { 1264 | while (*s == '\t' || *s == '\n' || *s == '\r' || *s == ' ') 1265 | ++s; 1266 | return s; 1267 | } 1268 | 1269 | static const char *parse_hexadigit(const char *s, unsigned *pv) { 1270 | *pv = 0; 1271 | while ((*s >= '0' && *s <= '9') || 1272 | (*s >= 'A' && *s <= 'F') || 1273 | (*s >= 'a' && *s <= 'f')) { 1274 | int ch = *s; 1275 | if (ch <= '9') 1276 | ch -= '0'; 1277 | else if (ch <= 'F') 1278 | ch -= 'A' - 10; 1279 | else 1280 | ch -= 'a' - 10; 1281 | *pv = (*pv << 4) | ch; 1282 | ++s; 1283 | } 1284 | return s; 1285 | } 1286 | 1287 | static int color_from_hexa(const char *s, size_t len, NVGcolor *c) { 1288 | const char *e; 1289 | unsigned v, packed = 0; 1290 | s = skip_whitespace(s); 1291 | if (*s++ != '#') return 0; 1292 | e = parse_hexadigit(s, &v); 1293 | e = skip_whitespace(e); 1294 | if (*e != '\0') return 0; 1295 | if (len == 4 || len == 5) { 1296 | packed = len == 4 ? 0xFF000000 : 1297 | ((v>>8)&0xF0)|((v>>12)&0xF) << 24; 1298 | packed |= 1299 | ((v>>4)&0xF0)|((v>>8)&0xF) << 16 | 1300 | ((v )&0xF0)|((v>>4)&0xF) << 8 | 1301 | ((v<<4)&0xF0)|((v )&0xF) ; 1302 | } 1303 | else if (len == 7 || len == 9) { 1304 | packed = v; 1305 | if (len == 7) 1306 | packed |= 0xFF000000; 1307 | } 1308 | *c = unpack_color(packed); 1309 | return 1; 1310 | } 1311 | 1312 | static const char *parse_decimal(const char *s, int *pv) { 1313 | *pv = 0; 1314 | s = skip_whitespace(s); 1315 | while (*s >= '0' && *s <= '9') { 1316 | *pv *= 10; 1317 | *pv += *s - '0'; 1318 | ++s; 1319 | } 1320 | return skip_whitespace(s); 1321 | } 1322 | 1323 | static int color_from_deci(const char *s, size_t len, NVGcolor *c) { 1324 | const char *e; 1325 | int packed = 0, v; 1326 | s = skip_whitespace(s); 1327 | if (memcmp(s, "rgb(", 4) == 0) 1328 | s += 4; 1329 | else if (memcmp(s, "rgba(", 5) == 0) 1330 | s += 5; 1331 | else 1332 | return 0; 1333 | if ((e = parse_decimal(s, &v)) == s || *e != ',') return 0; 1334 | packed |= (v&0xFF) << 16; s = e+1; 1335 | if ((e = parse_decimal(s, &v)) == s || *e != ',') return 0; 1336 | packed |= (v&0xFF) << 8; s = e+1; 1337 | if ((e = parse_decimal(s, &v)) == s || *e != ',') return 0; 1338 | packed |= (v&0xFF) ; s = e+1; 1339 | e = parse_decimal(s, &v); 1340 | if (v == 0) 1341 | packed |= 0xFF00000000; 1342 | else 1343 | packed |= (v&0xFF) << 24; 1344 | if (*e != ')') return 0; 1345 | *c = unpack_color(packed); 1346 | return 1; 1347 | } 1348 | 1349 | static int test_color(lua_State *L, int idx, NVGcolor *color) { 1350 | int type = lua_type(L, idx); 1351 | if (type == LUA_TNUMBER) { 1352 | *color = unpack_color(lua_tointeger(L, idx)); 1353 | if (color->a == 0.0f) 1354 | color->a = 1.0f; 1355 | return 1; 1356 | } 1357 | else if (type == LUA_TSTRING) { 1358 | size_t len; 1359 | const char *s = luaL_checklstring(L, idx, &len); 1360 | if (!color_from_hexa(s, len, color) && 1361 | !color_from_deci(s, len, color) && 1362 | !color_from_name(s, len, color)) 1363 | return lbind_argferror(L, idx, "invalid color format: %s", s); 1364 | return 1; 1365 | } 1366 | return 0; 1367 | } 1368 | 1369 | static NVGcolor check_color(lua_State *L, int idx) { 1370 | NVGcolor color; 1371 | if (!test_color(L, idx, &color)) 1372 | lbind_typeerror(L, idx, "color"); 1373 | return color; 1374 | } 1375 | 1376 | static int push_color(lua_State *L, NVGcolor c) { 1377 | lua_pushinteger(L, pack_color(c)); 1378 | return 1; 1379 | } 1380 | 1381 | static int Lcolor_parse(lua_State *L) { 1382 | return push_color(L, check_color(L, 1)); 1383 | } 1384 | 1385 | static int Lcolor_rgb(lua_State *L) { 1386 | float r = (float)luaL_checknumber(L, 1); 1387 | float g = (float)luaL_checknumber(L, 2); 1388 | float b = (float)luaL_checknumber(L, 3); 1389 | float a = (float)luaL_optnumber(L, 4, 1.0f); 1390 | return push_color(L, nvgRGBAf(r, g, b, a)); 1391 | } 1392 | 1393 | static int Lcolor_rgb8(lua_State *L) { 1394 | int r = (int)luaL_checkinteger(L, 1); 1395 | int g = (int)luaL_checkinteger(L, 2); 1396 | int b = (int)luaL_checkinteger(L, 3); 1397 | int a = (int)luaL_optinteger(L, 4, 255); 1398 | return push_color(L, nvgRGBA(r, g, b, a)); 1399 | } 1400 | 1401 | static int Lcolor_hsl(lua_State *L) { 1402 | float h = (float)luaL_checknumber(L, 1); 1403 | float s = (float)luaL_checknumber(L, 2); 1404 | float l = (float)luaL_checknumber(L, 3); 1405 | float a = (float)luaL_optnumber(L, 4, 1.0f); 1406 | return push_color(L, nvgHSLA(h, s, l, (int)(a*255))); 1407 | } 1408 | 1409 | static int Lcolor_lerp(lua_State *L) { 1410 | NVGcolor c0 = check_color(L, 1); 1411 | NVGcolor c1 = check_color(L, 2); 1412 | float u = (float)luaL_checknumber(L, 3); 1413 | return push_color(L, nvgLerpRGBA(c0, c1, u)); 1414 | } 1415 | 1416 | static int Lcolor_trans(lua_State *L) { 1417 | NVGcolor c = check_color(L, 1); 1418 | float alpha = (float)luaL_checknumber(L, 2); 1419 | return push_color(L, nvgTransRGBAf(c, alpha)); 1420 | } 1421 | 1422 | static int Lcolor_torgb(lua_State *L) { 1423 | NVGcolor c = check_color(L, 1); 1424 | lua_pushnumber(L, c.r); 1425 | lua_pushnumber(L, c.g); 1426 | lua_pushnumber(L, c.b); 1427 | lua_pushnumber(L, c.a); 1428 | return 4; 1429 | } 1430 | 1431 | static int Lcolor_torgb8(lua_State *L) { 1432 | NVGcolor c = check_color(L, 1); 1433 | lua_pushinteger(L, (int)(c.r * 255)); 1434 | lua_pushinteger(L, (int)(c.g * 255)); 1435 | lua_pushinteger(L, (int)(c.b * 255)); 1436 | lua_pushinteger(L, (int)(c.a * 255)); 1437 | return 4; 1438 | } 1439 | 1440 | LBLIB_API int luaopen_nvg_color(lua_State *L) { 1441 | luaL_Reg libs[] = { 1442 | #define Lcolor_rgba Lcolor_rgb 1443 | #define Lcolor_hsla Lcolor_hsl 1444 | #define ENTRY(name) { #name, Lcolor_##name } 1445 | ENTRY(parse), 1446 | ENTRY(rgb), 1447 | ENTRY(rgb8), 1448 | ENTRY(rgba), 1449 | ENTRY(hsl), 1450 | ENTRY(hsla), 1451 | ENTRY(lerp), 1452 | ENTRY(trans), 1453 | ENTRY(torgb), 1454 | ENTRY(torgb8), 1455 | #undef ENTRY 1456 | { NULL, NULL } 1457 | }; 1458 | luaL_newlib(L, libs); 1459 | return 1; 1460 | } 1461 | 1462 | /* win32cc: flags+='-s -O3 -shared' libs+='-lopengl32 -llua53' 1463 | * win32cc: output+='nanovg.def' output='nvg.dll' 1464 | * maccc: flags+='-O3 -bundle -undefined dynamic_lookup' 1465 | * maccc: libs+='libnanovg.a' output='nvg.so' */ 1466 | 1467 | -------------------------------------------------------------------------------- /nanovg.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | nvgArc 3 | nvgArcTo 4 | nvgBeginFrame 5 | nvgBeginPath 6 | nvgBezierTo 7 | nvgBoxGradient 8 | nvgCancelFrame 9 | nvgCircle 10 | nvgClosePath 11 | nvgCreateFont 12 | nvgCreateFontMem 13 | nvgCreateImage 14 | nvgCreateImageMem 15 | nvgCreateImageRGBA 16 | nvgCreateInternal 17 | nvgCurrentTransform 18 | nvgDebugDumpPathCache 19 | nvgDegToRad 20 | nvgDeleteImage 21 | nvgDeleteInternal 22 | nvgEllipse 23 | nvgEndFrame 24 | nvgFill 25 | nvgFillColor 26 | nvgFillPaint 27 | nvgFindFont 28 | nvgFontBlur 29 | nvgFontFace 30 | nvgFontFaceId 31 | nvgFontSize 32 | nvgGlobalAlpha 33 | nvgHSL 34 | nvgHSLA 35 | nvgImagePattern 36 | nvgImageSize 37 | nvgInternalParams 38 | nvgIntersectScissor 39 | nvgLerpRGBA 40 | nvgLineCap 41 | nvgLineJoin 42 | nvgLineTo 43 | nvgLinearGradient 44 | nvgMiterLimit 45 | nvgMoveTo 46 | nvgPathWinding 47 | nvgQuadTo 48 | nvgRGB 49 | nvgRGBA 50 | nvgRGBAf 51 | nvgRGBf 52 | nvgRadToDeg 53 | nvgRadialGradient 54 | nvgRect 55 | nvgReset 56 | nvgResetScissor 57 | nvgResetTransform 58 | nvgRestore 59 | nvgRotate 60 | nvgRoundedRect 61 | nvgSave 62 | nvgScale 63 | nvgScissor 64 | nvgSkewX 65 | nvgSkewY 66 | nvgStroke 67 | nvgStrokeColor 68 | nvgStrokePaint 69 | nvgStrokeWidth 70 | nvgText 71 | nvgTextAlign 72 | nvgTextBounds 73 | nvgTextBox 74 | nvgTextBoxBounds 75 | nvgTextBreakLines 76 | nvgTextGlyphPositions 77 | nvgTextLetterSpacing 78 | nvgTextLineHeight 79 | nvgTextMetrics 80 | nvgTransRGBA 81 | nvgTransRGBAf 82 | nvgTransform 83 | nvgTransformIdentity 84 | nvgTransformInverse 85 | nvgTransformMultiply 86 | nvgTransformPoint 87 | nvgTransformPremultiply 88 | nvgTransformRotate 89 | nvgTransformScale 90 | nvgTransformSkewX 91 | nvgTransformSkewY 92 | nvgTransformTranslate 93 | nvgTranslate 94 | nvgUpdateImage 95 | -------------------------------------------------------------------------------- /pprint.lua: -------------------------------------------------------------------------------- 1 | local pprint = { VERSION = '0.1' } 2 | 3 | local depth = 1 4 | 5 | pprint.defaults = { 6 | -- If set to number N, then limit table recursion to N deep. 7 | depth_limit = false, 8 | -- type display trigger, hide not useful datatypes by default 9 | -- custom types are treated as table 10 | show_nil = true, 11 | show_boolean = true, 12 | show_number = true, 13 | show_string = true, 14 | show_table = true, 15 | show_function = false, 16 | show_thread = false, 17 | show_userdata = false, 18 | -- additional display trigger 19 | show_metatable = false, -- show metatable 20 | show_all = false, -- override other show settings and show everything 21 | use_tostring = false, -- use __tostring to print table if available 22 | filter_function = nil, -- called like callback(value[,key, parent]), return truty value to hide 23 | object_cache = 'local', -- cache blob and table to give it a id, 'local' cache per print, 'global' cache 24 | -- per process, falsy value to disable (might cause infinite loop) 25 | -- format settings 26 | indent_size = 2, -- indent for each nested table level 27 | level_width = 80, -- max width per indent level 28 | wrap_string = true, -- wrap string when it's longer than level_width 29 | wrap_array = false, -- wrap every array elements 30 | sort_keys = true, -- sort table keys 31 | } 32 | 33 | local TYPES = { 34 | ['nil'] = 1, ['boolean'] = 2, ['number'] = 3, ['string'] = 4, 35 | ['table'] = 5, ['function'] = 6, ['thread'] = 7, ['userdata'] = 8 36 | } 37 | 38 | -- seems this is the only way to escape these, as lua don't know how to map char '\a' to 'a' 39 | local ESCAPE_MAP = { 40 | ['\a'] = '\\a', ['\b'] = '\\b', ['\f'] = '\\f', ['\n'] = '\\n', ['\r'] = '\\r', 41 | ['\t'] = '\\t', ['\v'] = '\\v', ['\\'] = '\\\\', 42 | } 43 | 44 | -- generic utilities 45 | local function escape(s) 46 | s = s:gsub('([%c\\])', ESCAPE_MAP) 47 | local dq = s:find('"') 48 | local sq = s:find("'") 49 | if dq and sq then 50 | return s:gsub('"', '\\"'), '"' 51 | elseif sq then 52 | return s, '"' 53 | else 54 | return s, "'" 55 | end 56 | end 57 | 58 | local function is_plain_key(key) 59 | return type(key) == 'string' and key:match('^[%a_][%a%d_]*$') 60 | end 61 | 62 | local CACHE_TYPES = { 63 | ['table'] = true, ['function'] = true, ['thread'] = true, ['userdata'] = true 64 | } 65 | 66 | -- cache would be populated to be like: 67 | -- { 68 | -- function = { `fun1` = 1, _cnt = 1 }, -- object id 69 | -- table = { `table1` = 1, `table2` = 2, _cnt = 2 }, 70 | -- visited_tables = { `table1` = 7, `table2` = 8 }, -- visit count 71 | -- } 72 | -- use weakrefs to avoid accidentall adding refcount 73 | local function cache_apperance(obj, cache, option) 74 | if not cache.visited_tables then 75 | cache.visited_tables = setmetatable({}, {__mode = 'k'}) 76 | end 77 | local t = type(obj) 78 | 79 | -- TODO can't test filter_function here as we don't have the ix and key, 80 | -- might cause different results? 81 | -- respect show_xxx and filter_function to be consistent with print results 82 | if (not TYPES[t] and not option.show_table) 83 | or (TYPES[t] and not option['show_'..t]) then 84 | return 85 | end 86 | 87 | if CACHE_TYPES[t] or TYPES[t] == nil then 88 | if not cache[t] then 89 | cache[t] = setmetatable({}, {__mode = 'k'}) 90 | cache[t]._cnt = 0 91 | end 92 | if not cache[t][obj] then 93 | cache[t]._cnt = cache[t]._cnt + 1 94 | cache[t][obj] = cache[t]._cnt 95 | end 96 | end 97 | if t == 'table' or TYPES[t] == nil then 98 | if cache.visited_tables[obj] == false then 99 | -- already printed, no need to mark this and its children anymore 100 | return 101 | elseif cache.visited_tables[obj] == nil then 102 | cache.visited_tables[obj] = 1 103 | else 104 | -- visited already, increment and continue 105 | cache.visited_tables[obj] = cache.visited_tables[obj] + 1 106 | return 107 | end 108 | for k, v in pairs(obj) do 109 | cache_apperance(k, cache, option) 110 | cache_apperance(v, cache, option) 111 | end 112 | local mt = getmetatable(obj) 113 | if mt and option.show_metatable then 114 | cache_apperance(mt, cache, option) 115 | end 116 | end 117 | end 118 | 119 | -- makes 'foo2' < 'foo100000'. string.sub makes substring anyway, no need to use index based method 120 | local function str_natural_cmp(lhs, rhs) 121 | while #lhs > 0 and #rhs > 0 do 122 | local lmid, lend = lhs:find('%d+') 123 | local rmid, rend = rhs:find('%d+') 124 | if not (lmid and rmid) then return lhs < rhs end 125 | 126 | local lsub = lhs:sub(1, lmid-1) 127 | local rsub = rhs:sub(1, rmid-1) 128 | if lsub ~= rsub then 129 | return lsub < rsub 130 | end 131 | 132 | local lnum = tonumber(lhs:sub(lmid, lend)) 133 | local rnum = tonumber(rhs:sub(rmid, rend)) 134 | if lnum ~= rnum then 135 | return lnum < rnum 136 | end 137 | 138 | lhs = lhs:sub(lend+1) 139 | rhs = rhs:sub(rend+1) 140 | end 141 | return lhs < rhs 142 | end 143 | 144 | local function cmp(lhs, rhs) 145 | local tleft = type(lhs) 146 | local tright = type(rhs) 147 | if tleft == 'number' and tright == 'number' then return lhs < rhs end 148 | if tleft == 'string' and tright == 'string' then return str_natural_cmp(lhs, rhs) end 149 | if tleft == tright then return str_natural_cmp(tostring(lhs), tostring(rhs)) end 150 | 151 | -- allow custom types 152 | local oleft = TYPES[tleft] or 9 153 | local oright = TYPES[tright] or 9 154 | return oleft < oright 155 | end 156 | 157 | -- setup option with default 158 | local function make_option(option) 159 | if option == nil then 160 | option = {} 161 | end 162 | for k, v in pairs(pprint.defaults) do 163 | if option[k] == nil then 164 | option[k] = v 165 | end 166 | if option.show_all then 167 | for t, _ in pairs(TYPES) do 168 | option['show_'..t] = true 169 | end 170 | option.show_metatable = true 171 | end 172 | end 173 | return option 174 | end 175 | 176 | -- override defaults and take effects for all following calls 177 | function pprint.setup(option) 178 | pprint.defaults = make_option(option) 179 | end 180 | 181 | -- format lua object into a string 182 | function pprint.pformat(obj, option, printer) 183 | option = make_option(option) 184 | local buf = {} 185 | local function default_printer(s) 186 | table.insert(buf, s) 187 | end 188 | printer = printer or default_printer 189 | 190 | local cache 191 | if option.object_cache == 'global' then 192 | -- steal the cache into a local var so it's not visible from _G or anywhere 193 | -- still can't avoid user explicitly referentce pprint._cache but it shouldn't happen anyway 194 | cache = pprint._cache or {} 195 | pprint._cache = nil 196 | elseif option.object_cache == 'local' then 197 | cache = {} 198 | end 199 | 200 | local last = '' -- used for look back and remove trailing comma 201 | local status = { 202 | indent = '', -- current indent 203 | len = 0, -- current line length 204 | } 205 | 206 | local wrapped_printer = function(s) 207 | printer(last) 208 | last = s 209 | end 210 | 211 | local function _indent(d) 212 | status.indent = string.rep(' ', d + #(status.indent)) 213 | end 214 | 215 | local function _n(d) 216 | wrapped_printer('\n') 217 | wrapped_printer(status.indent) 218 | if d then 219 | _indent(d) 220 | end 221 | status.len = 0 222 | return true -- used to close bracket correctly 223 | end 224 | 225 | local function _p(s, nowrap) 226 | status.len = status.len + #s 227 | if not nowrap and status.len > option.level_width then 228 | _n() 229 | wrapped_printer(s) 230 | status.len = #s 231 | else 232 | wrapped_printer(s) 233 | end 234 | end 235 | 236 | local formatter = {} 237 | local function format(v) 238 | local f = formatter[type(v)] 239 | f = f or formatter.table -- allow patched type() 240 | if option.filter_function and option.filter_function(v, nil, nil) then 241 | return '' 242 | else 243 | return f(v) 244 | end 245 | end 246 | 247 | local function tostring_formatter(v) 248 | return tostring(v) 249 | end 250 | 251 | local function number_formatter(n) 252 | return n == math.huge and '[[math.huge]]' or tostring(n) 253 | end 254 | 255 | local function nop_formatter(v) 256 | return '' 257 | end 258 | 259 | local function make_fixed_formatter(t, has_cache) 260 | if has_cache then 261 | return function (v) 262 | return string.format('[[%s %d]]', t, cache[t][v]) 263 | end 264 | else 265 | return function (v) 266 | return '[['..t..']]' 267 | end 268 | end 269 | end 270 | 271 | local function string_formatter(s, force_long_quote) 272 | local s, quote = escape(s) 273 | local quote_len = force_long_quote and 4 or 2 274 | if quote_len + #s + status.len > option.level_width then 275 | _n() 276 | -- only wrap string when is longer than level_width 277 | if option.wrap_string and #s + quote_len > option.level_width then 278 | -- keep the quotes together 279 | _p('[[') 280 | while #s + status.len >= option.level_width do 281 | local seg = option.level_width - status.len 282 | _p(string.sub(s, 1, seg), true) 283 | _n() 284 | s = string.sub(s, seg+1) 285 | end 286 | _p(s) -- print the remaining parts 287 | return ']]' 288 | end 289 | end 290 | 291 | return force_long_quote and '[['..s..']]' or quote..s..quote 292 | end 293 | 294 | local function table_formatter(t) 295 | if option.use_tostring then 296 | local mt = getmetatable(t) 297 | if mt and mt.__tostring then 298 | return string_formatter(tostring(t), true) 299 | end 300 | end 301 | 302 | local print_header_ix = nil 303 | local ttype = type(t) 304 | if option.object_cache then 305 | local cache_state = cache.visited_tables[t] 306 | local tix = cache[ttype][t] 307 | -- FIXME should really handle `cache_state == nil` 308 | -- as user might add things through filter_function 309 | if cache_state == false then 310 | -- already printed, just print the the number 311 | return string_formatter(string.format('%s %d', ttype, tix), true) 312 | elseif cache_state > 1 then 313 | -- appeared more than once, print table header with number 314 | print_header_ix = tix 315 | cache.visited_tables[t] = false 316 | else 317 | -- appeared exactly once, print like a normal table 318 | end 319 | end 320 | 321 | local limit = tonumber(option.depth_limit) 322 | if limit and depth > limit then 323 | if print_header_ix then 324 | return string.format('[[%s %d]]...', ttype, print_header_ix) 325 | end 326 | return string_formatter(tostring(t), true) 327 | end 328 | 329 | local tlen = #t 330 | local wrapped = false 331 | _p('{') 332 | _indent(option.indent_size) 333 | _p(string.rep(' ', option.indent_size - 1)) 334 | if print_header_ix then 335 | _p(string.format('--[[%s %d]] ', ttype, print_header_ix)) 336 | end 337 | for ix = 1,tlen do 338 | local v = t[ix] 339 | if formatter[type(v)] == nop_formatter or 340 | (option.filter_function and option.filter_function(v, ix, t)) then 341 | -- pass 342 | else 343 | if option.wrap_array then 344 | wrapped = _n() 345 | end 346 | depth = depth+1 347 | _p(format(v)..', ') 348 | depth = depth-1 349 | end 350 | end 351 | 352 | -- hashmap part of the table, in contrast to array part 353 | local function is_hash_key(k) 354 | if type(k) ~= 'number' then 355 | return true 356 | end 357 | 358 | local numkey = math.floor(tonumber(k)) 359 | if numkey ~= k or numkey > tlen or numkey <= 0 then 360 | return true 361 | end 362 | end 363 | 364 | local function print_kv(k, v, t) 365 | -- can't use option.show_x as obj may contain custom type 366 | if formatter[type(v)] == nop_formatter or 367 | formatter[type(k)] == nop_formatter or 368 | (option.filter_function and option.filter_function(v, k, t)) then 369 | return 370 | end 371 | wrapped = _n() 372 | if is_plain_key(k) then 373 | _p(k, true) 374 | else 375 | _p('[') 376 | -- [[]] type string in key is illegal, needs to add spaces inbetween 377 | local k = format(k) 378 | if string.match(k, '%[%[') then 379 | _p(' '..k..' ', true) 380 | else 381 | _p(k, true) 382 | end 383 | _p(']') 384 | end 385 | _p(' = ', true) 386 | depth = depth+1 387 | _p(format(v), true) 388 | depth = depth-1 389 | _p(',', true) 390 | end 391 | 392 | if option.sort_keys then 393 | local keys = {} 394 | for k, _ in pairs(t) do 395 | if is_hash_key(k) then 396 | table.insert(keys, k) 397 | end 398 | end 399 | table.sort(keys, cmp) 400 | for _, k in ipairs(keys) do 401 | print_kv(k, t[k], t) 402 | end 403 | else 404 | for k, v in pairs(t) do 405 | if is_hash_key(k) then 406 | print_kv(k, v, t) 407 | end 408 | end 409 | end 410 | 411 | if option.show_metatable then 412 | local mt = getmetatable(t) 413 | if mt then 414 | print_kv('__metatable', mt, t) 415 | end 416 | end 417 | 418 | _indent(-option.indent_size) 419 | -- make { } into {} 420 | last = string.gsub(last, '^ +$', '') 421 | -- peek last to remove trailing comma 422 | last = string.gsub(last, ',%s*$', ' ') 423 | if wrapped then 424 | _n() 425 | end 426 | _p('}') 427 | 428 | return '' 429 | end 430 | 431 | -- set formatters 432 | formatter['nil'] = option.show_nil and tostring_formatter or nop_formatter 433 | formatter['boolean'] = option.show_boolean and tostring_formatter or nop_formatter 434 | formatter['number'] = option.show_number and number_formatter or nop_formatter -- need to handle math.huge 435 | formatter['function'] = option.show_function and make_fixed_formatter('function', option.object_cache) or nop_formatter 436 | formatter['thread'] = option.show_thread and make_fixed_formatter('thread', option.object_cache) or nop_formatter 437 | formatter['userdata'] = option.show_userdata and make_fixed_formatter('userdata', option.object_cache) or nop_formatter 438 | formatter['string'] = option.show_string and string_formatter or nop_formatter 439 | formatter['table'] = option.show_table and table_formatter or nop_formatter 440 | 441 | if option.object_cache then 442 | -- needs to visit the table before start printing 443 | cache_apperance(obj, cache, option) 444 | end 445 | 446 | _p(format(obj)) 447 | printer(last) -- close the buffered one 448 | 449 | -- put cache back if global 450 | if option.object_cache == 'global' then 451 | pprint._cache = cache 452 | end 453 | 454 | return table.concat(buf) 455 | end 456 | 457 | -- pprint all the arguments 458 | function pprint.pprint( ... ) 459 | local args = {...} 460 | -- select will get an accurate count of array len, counting trailing nils 461 | local len = select('#', ...) 462 | for ix = 1,len do 463 | pprint.pformat(args[ix], nil, io.write) 464 | io.write('\n') 465 | end 466 | end 467 | 468 | setmetatable(pprint, { 469 | __call = function (_, ...) 470 | pprint.pprint(...) 471 | end 472 | }) 473 | 474 | return pprint 475 | 476 | -------------------------------------------------------------------------------- /rockspecs/nanovg-0.1.3-1.rockspec: -------------------------------------------------------------------------------- 1 | package = "nanovg" 2 | version = "0.1.3-1" 3 | source = { 4 | url = "https://github.com/starwing/lua-nanovg/releases/download/0.1.3/lua-nanovg-0.1.3.zip", 5 | dir = "lua-nanovg-0.1.3" 6 | } 7 | description = { 8 | summary = "Lua binding for NanoVG", 9 | homepage = "https://github.com/starwing/lua-nanovg", 10 | license = "MIT" 11 | } 12 | dependencies = { 13 | "lua >= 5.1, <= 5.4" 14 | } 15 | build = { 16 | type = "builtin", 17 | platforms = { 18 | windows = { 19 | modules = { 20 | nvg = { 21 | libraries = { 22 | "opengl32", 23 | "gdi32" 24 | }, 25 | } 26 | } 27 | } 28 | }, 29 | modules = { 30 | nvg = { 31 | sources = { 32 | "lua-nanovg.c", 33 | "nanovg/src/nanovg.c", 34 | }, 35 | }, 36 | }, 37 | } 38 | -------------------------------------------------------------------------------- /rockspecs/nanovg-scm-1.rockspec: -------------------------------------------------------------------------------- 1 | package = "nanovg" 2 | version = "scm-1" 3 | source = { 4 | url = "https://github.com/starwing/lua-nanovg.git", 5 | } 6 | description = { 7 | summary = "Lua binding for NanoVG", 8 | homepage = "https://github.com/starwing/lua-nanovg", 9 | license = "MIT" 10 | } 11 | dependencies = { 12 | "lua >= 5.1, <= 5.4" 13 | } 14 | build = { 15 | type = "builtin", 16 | platforms = { 17 | windows = { 18 | modules = { 19 | nvg = { 20 | libraries = { "opengl32" }, 21 | } 22 | } 23 | }, 24 | linux = { 25 | modules = { 26 | nvg = { 27 | libraries = { "GL" }, 28 | } 29 | } 30 | } 31 | }, 32 | modules = { 33 | nvg = { 34 | sources = { 35 | "lua-nanovg.c", 36 | "nanovg/src/nanovg.c", 37 | }, 38 | }, 39 | }, 40 | } 41 | -------------------------------------------------------------------------------- /scripts/platform.sh: -------------------------------------------------------------------------------- 1 | PLATFORM="" 2 | if [ -z "${PLATFORM:-}" ]; then 3 | T_OS=${TRAVIS_OS_NAME:-} 4 | if [ ! -z $T_OS ]; then 5 | PLATFORM=$T_OS 6 | fi 7 | fi 8 | 9 | if [[ -z $PLATFORM ]];then 10 | PLATFORM=posix 11 | if [[ ! -z ${MINGW_PREFIX:-} ]]; then 12 | PLATFORM=mingw 13 | else 14 | UNAME_S=`uname -s` 15 | if [[ $UNAME_S == "Linux" ]]; then 16 | PLATFORM=linux 17 | fi 18 | if [[ $UNAME_S == "Darwin" ]]; then 19 | PLATFORM=macosx 20 | fi 21 | fi 22 | fi 23 | -------------------------------------------------------------------------------- /scripts/run-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | PROJECT_HOME=$( dirname "$( cd "$( dirname "$0" )" && pwd )" ) 4 | function exit_error { 5 | printf "%s\n" "$*" >&2; 6 | exit -1; 7 | } 8 | 9 | 10 | 11 | L_EXT=so 12 | if [[ ! -z $MINGW_PREFIX ]]; then 13 | L_EXT=dll 14 | fi 15 | 16 | cd $PROJECT_HOME 17 | echo "Ensuring project dependencies are installed" 18 | if [[ ! -d $PROJECT_HOME/moonglfw ]] || [[ ! -d $PROJECT_HOME/nanovg ]] || [[ ! -d $PROJECT_HOME/nanosvg ]]; then 19 | git submodule init 20 | git submodule update 21 | fi 22 | cd . 23 | 24 | # resolving build tools 25 | LUA=lua5.3 26 | LUAROCKS=3.0.0 27 | source $PROJECT_HOME/scripts/setup_lua.sh 28 | 29 | exit 0 30 | 31 | NVG_MAIN=$PROJECT_HOME/nvg.$L_EXT 32 | MOONGLFW_MAIN=$PROJECT_HOME/moonglfw.$L_EXT 33 | 34 | echo "Checking if $NVG_MAIN exists" 35 | if [[ ! -f $NVG_MAIN ]]; then 36 | exit_error "NanoVG build is missing from $NVG_MAIN" 37 | fi 38 | 39 | echo "Checking if $MOONGLFW_MAIN exists" 40 | if [[ ! -f $MOONGLFW_MAIN ]]; then 41 | exit_error "MoonGLFW build is missing from $MOONGLFW_MAIN" 42 | fi 43 | 44 | echo "All tests passed" 45 | -------------------------------------------------------------------------------- /scripts/setenv_lua.sh: -------------------------------------------------------------------------------- 1 | PROJECT_HOME=$( dirname "$( cd "$( dirname "$0" )" && pwd )" ) 2 | T_BD=${TRAVIS_BUILD_DIR:-} 3 | if [[ -z $T_BD ]]; then 4 | T_BD=$PROJECT_HOME/build 5 | fi 6 | 7 | export PATH=${PATH}:$HOME/.lua:$HOME/.local/bin:${T_BD}/install/luarocks/bin 8 | bash $PROJECT_HOME/scripts/setup_lua.sh 9 | eval `$HOME/.lua/luarocks path` 10 | -------------------------------------------------------------------------------- /scripts/setup_lua.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | set -e 3 | PROJECT_HOME=$( dirname "$( cd "$( dirname "$0" )" && pwd )" ) 4 | T_BD=${TRAVIS_BUILD_DIR:-} 5 | if [[ -z $T_BD ]]; then 6 | T_BD=$PROJECT_HOME/build 7 | fi 8 | 9 | source $PROJECT_HOME/scripts/platform.sh 10 | 11 | LUA_HOME_DIR=$T_BD/install/lua 12 | LR_HOME_DIR=$T_BD/install/luarocks 13 | 14 | mkdir -p $T_BD 15 | mkdir -p $HOME/.lua 16 | mkdir -p "$LUA_HOME_DIR" 17 | LUASRC_BASE=5.0.0 18 | if [ "$LUA" == "lua5.1" ]; then 19 | LUASRC_BASE=5.1.5 20 | elif [ "$LUA" == "lua5.2" ]; then 21 | LUASRC_BASE=5.2.4 22 | elif [ "$LUA" == "lua5.3" ]; then 23 | LUASRC_BASE=5.3.5 24 | fi 25 | LUASRC_PKG=https://www.lua.org/ftp/lua-$LUASRC_BASE.tar.gz 26 | echo "Ensuring lua $LUASRC_BASE from $LUASRC_PKG" 27 | 28 | if [[ ! -d $T_BD/$LUASRC_BASE ]]; then 29 | curl --location $LUASRC_PKG -o $T_BD/lua-$LUASRC_BASE.tar.gz 30 | tar xzf lua-$LUASRC_BASE.tar.gz 31 | cd $T_BD/lua-$LUASRC_BASE; 32 | # Build Lua without backwards compatibility for testing 33 | perl -i -pe 's/-DLUA_COMPAT_(ALL|5_2)//' src/Makefile 34 | make $PLATFORM && make INSTALL_TOP="$LUA_HOME_DIR" install; 35 | if [[ ! -f $HOME/.lua/lua ]];then 36 | ln -sf $LUA_HOME_DIR/bin/lua $HOME/.lua/lua 37 | fi 38 | if [[ ! -f $HOME/.lua/luac ]];then 39 | ln -sf $LUA_HOME_DIR/bin/luac $HOME/.lua/luac; 40 | fi 41 | fi 42 | 43 | LUAROCKS_BASE=luarocks-$LUAROCKS 44 | if [[ ! -d $T_BD/$LUAROCKS_BASE ]]; then 45 | mkdir -p $T_BD/$LUAROCKS_BASE 46 | cd $T_BD/$LUAROCKS_BASE 47 | curl --location http://luarocks.org/releases/$LUAROCKS_BASE.tar.gz -o $T_BD/$LUAROCKS_BASE.tar.gz 48 | tar xz $T_BD/$LUAROCKS_BASE.tar.gz 49 | cd $LUAROCKS_BASE 50 | ./configure --with-lua="$LUA_HOME_DIR" --prefix="$LR_HOME_DIR" 51 | make build && make install 52 | if [[ ! -h $HOME/.lua/luarocks ]];then 53 | ln -sf $LR_HOME_DIR/bin/luarocks $HOME/.lua/luarocks 54 | fi 55 | cd $T_BD 56 | fi 57 | 58 | luarocks install --local Lua-cURL --server=https://luarocks.org/dev 59 | luarocks install --local luacov-coveralls --server=https://luarocks.org/dev 60 | luarocks install --local lunitx 61 | 62 | export PATH=$T_BD/lua/bin:$T_BD/luarocks/bin:$PATH 63 | lua -v 64 | luarocks --version 65 | lunit.sh $PROJECT_HOME/test/test.lua 66 | -------------------------------------------------------------------------------- /test/.luacov: -------------------------------------------------------------------------------- 1 | --- Global configuration file. Copy, customize and store in your 2 | -- project folder as '.luacov' for project specific configuration 3 | -- @class module 4 | -- @name luacov.defaults 5 | return { 6 | 7 | -- default filename to load for config options if not provided 8 | -- only has effect in 'luacov.defaults.lua' 9 | configfile = ".luacov", 10 | 11 | -- filename to store stats collected 12 | statsfile = "luacov.stats.out", 13 | 14 | -- filename to store report 15 | reportfile = "luacov.report.json", 16 | 17 | -- Run reporter on completion? (won't work for ticks) 18 | runreport = false, 19 | 20 | -- Delete stats file after reporting? 21 | deletestats = false, 22 | 23 | -- Patterns for files to include when reporting 24 | -- all will be included if nothing is listed 25 | -- (exclude overrules include, do not include 26 | -- the .lua extension) 27 | include = { 28 | "/foo$", 29 | "/foo/.+$", 30 | }, 31 | 32 | -- Patterns for files to exclude when reporting 33 | -- all will be included if nothing is listed 34 | -- (exclude overrules include, do not include 35 | -- the .lua extension) 36 | exclude = { 37 | }, 38 | 39 | -- configuration for luacov-coveralls reporter 40 | coveralls = { 41 | 42 | -- debug = true; 43 | 44 | pathcorrect = { 45 | {"^.-/share/lua/5.%d/", "src/lua/"}; 46 | }, 47 | 48 | }, 49 | 50 | } 51 | -------------------------------------------------------------------------------- /test/test.lua: -------------------------------------------------------------------------------- 1 | pcall(require, "luacov") 2 | 3 | 4 | print("------------------------------------") 5 | print("Lua version: " .. (jit and jit.version or _VERSION)) 6 | print("------------------------------------") 7 | print("") 8 | 9 | local HAS_RUNNER = not not lunit 10 | local lunit = require "lunit" 11 | local TEST_CASE = lunit.TEST_CASE 12 | 13 | local _ENV = TEST_CASE"NVG" 14 | 15 | function test_1() 16 | local moonglfw = require "moonglfw" 17 | local ctx = require "nvg" 18 | assert_function(ctx.beginPath) 19 | end 20 | 21 | if not HAS_RUNNER then lunit.run() end 22 | --------------------------------------------------------------------------------