1 /* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "include/core/SkCanvas.h" 9 #include "include/core/SkData.h" 10 #include "include/utils/SkLua.h" 11 #include "samplecode/Sample.h" 12 #include "tools/Resources.h" 13 14 extern "C" { 15 #include "lua.h" 16 #include "lualib.h" 17 #include "lauxlib.h" 18 } 19 20 //#define LUA_FILENAME "lua/test.lua" 21 #define LUA_FILENAME "lua/slides.lua" 22 23 static const char gDrawName[] = "onDrawContent"; 24 static const char gClickName[] = "onClickHandler"; 25 static const char gUnicharName[] = "onCharHandler"; 26 27 static const char gMissingCode[] = "" 28 "local paint = Sk.newPaint()" 29 "paint:setAntiAlias(true)" 30 "paint:setTextSize(30)" 31 "" 32 "function onDrawContent(canvas)" 33 " canvas:drawText('missing \"test.lua\"', 20, 50, paint)" 34 "end" 35 ; 36 37 class LuaView : public Sample { 38 public: LuaView()39 LuaView() : fLua(nullptr) {} 40 ~LuaView()41 ~LuaView() override { delete fLua; } 42 setImageFilename(lua_State * L)43 void setImageFilename(lua_State* L) { 44 SkString str = GetResourcePath("images/mandrill_256.png"); 45 46 lua_getglobal(L, "setImageFilename"); 47 if (lua_isfunction(L, -1)) { 48 fLua->pushString(str.c_str()); 49 if (lua_pcall(L, 1, 0, 0) != LUA_OK) { 50 SkDebugf("lua err: %s\n", lua_tostring(L, -1)); 51 } 52 } 53 } 54 ensureLua()55 lua_State* ensureLua() { 56 if (nullptr == fLua) { 57 fLua = new SkLua; 58 59 sk_sp<SkData> data = GetResourceAsData(LUA_FILENAME); 60 if (data) { 61 fLua->runCode(data->data(), data->size()); 62 this->setImageFilename(fLua->get()); 63 } else { 64 fLua->runCode(gMissingCode); 65 } 66 } 67 return fLua->get(); 68 } 69 70 protected: name()71 SkString name() override { return SkString("Lua"); } 72 onChar(SkUnichar uni)73 bool onChar(SkUnichar uni) override { 74 lua_State* L = this->ensureLua(); 75 lua_getglobal(L, gUnicharName); 76 if (lua_isfunction(L, -1)) { 77 SkString str; 78 str.appendUnichar(uni); 79 fLua->pushString(str.c_str()); 80 if (lua_pcall(L, 1, 1, 0) != LUA_OK) { 81 SkDebugf("lua err: %s\n", lua_tostring(L, -1)); 82 } else { 83 if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) { 84 return true; 85 } 86 } 87 } 88 return false; 89 } 90 onDrawContent(SkCanvas * canvas)91 void onDrawContent(SkCanvas* canvas) override { 92 lua_State* L = this->ensureLua(); 93 94 lua_getglobal(L, gDrawName); 95 if (!lua_isfunction(L, -1)) { 96 int t = lua_type(L, -1); 97 SkDebugf("--- expected %s function %d, ignoring.\n", gDrawName, t); 98 lua_pop(L, 1); 99 } else { 100 // does it make sense to try to "cache" the lua version of this 101 // canvas between draws? 102 fLua->pushCanvas(canvas); 103 fLua->pushScalar(this->width()); 104 fLua->pushScalar(this->height()); 105 if (lua_pcall(L, 3, 1, 0) != LUA_OK) { 106 SkDebugf("lua err: %s\n", lua_tostring(L, -1)); 107 } 108 } 109 } 110 onFindClickHandler(SkScalar x,SkScalar y,ModifierKey modi)111 virtual Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, 112 ModifierKey modi) override { 113 lua_State* L = this->ensureLua(); 114 lua_getglobal(L, gClickName); 115 if (lua_isfunction(L, -1)) { 116 fLua->pushScalar(x); 117 fLua->pushScalar(y); 118 fLua->pushString("down"); 119 if (lua_pcall(L, 3, 1, 0) != LUA_OK) { 120 SkDebugf("lua err: %s\n", lua_tostring(L, -1)); 121 } else { 122 if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) { 123 return new Click(); 124 } 125 } 126 } 127 return this->INHERITED::onFindClickHandler(x, y, modi); 128 } 129 onClick(Click * click)130 bool onClick(Click* click) override { 131 const char* state = nullptr; 132 switch (click->fState) { 133 case InputState::kMove: 134 state = "moved"; 135 break; 136 case InputState::kUp: 137 state = "up"; 138 break; 139 default: 140 break; 141 } 142 if (state) { 143 lua_State* L = fLua->get(); 144 lua_getglobal(L, gClickName); 145 fLua->pushScalar(click->fCurr.x()); 146 fLua->pushScalar(click->fCurr.y()); 147 fLua->pushString(state); 148 lua_pcall(L, 3, 1, 0); 149 return lua_isboolean(L, -1) && lua_toboolean(L, -1); 150 } 151 return true; 152 } 153 154 private: 155 SkLua* fLua; 156 157 typedef Sample INHERITED; 158 }; 159 160 ////////////////////////////////////////////////////////////////////////////// 161 162 DEF_SAMPLE( return new LuaView(); ) 163