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 "Sample.h" 9 #include "SkLua.h" 10 #include "SkCanvas.h" 11 #include "Resources.h" 12 #include "SkData.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: onQuery(Sample::Event * evt)71 bool onQuery(Sample::Event* evt) override { 72 if (Sample::TitleQ(*evt)) { 73 Sample::TitleR(evt, "Lua"); 74 return true; 75 } 76 SkUnichar uni; 77 if (Sample::CharQ(*evt, &uni)) { 78 lua_State* L = this->ensureLua(); 79 lua_getglobal(L, gUnicharName); 80 if (lua_isfunction(L, -1)) { 81 SkString str; 82 str.appendUnichar(uni); 83 fLua->pushString(str.c_str()); 84 if (lua_pcall(L, 1, 1, 0) != LUA_OK) { 85 SkDebugf("lua err: %s\n", lua_tostring(L, -1)); 86 } else { 87 if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) { 88 return true; 89 } 90 } 91 } 92 } 93 return this->INHERITED::onQuery(evt); 94 } 95 onDrawContent(SkCanvas * canvas)96 void onDrawContent(SkCanvas* canvas) override { 97 lua_State* L = this->ensureLua(); 98 99 lua_getglobal(L, gDrawName); 100 if (!lua_isfunction(L, -1)) { 101 int t = lua_type(L, -1); 102 SkDebugf("--- expected %s function %d, ignoring.\n", gDrawName, t); 103 lua_pop(L, 1); 104 } else { 105 // does it make sense to try to "cache" the lua version of this 106 // canvas between draws? 107 fLua->pushCanvas(canvas); 108 fLua->pushScalar(this->width()); 109 fLua->pushScalar(this->height()); 110 if (lua_pcall(L, 3, 1, 0) != LUA_OK) { 111 SkDebugf("lua err: %s\n", lua_tostring(L, -1)); 112 } 113 } 114 } 115 onFindClickHandler(SkScalar x,SkScalar y,unsigned modi)116 virtual Sample::Click* onFindClickHandler(SkScalar x, SkScalar y, 117 unsigned modi) override { 118 lua_State* L = this->ensureLua(); 119 lua_getglobal(L, gClickName); 120 if (lua_isfunction(L, -1)) { 121 fLua->pushScalar(x); 122 fLua->pushScalar(y); 123 fLua->pushString("down"); 124 if (lua_pcall(L, 3, 1, 0) != LUA_OK) { 125 SkDebugf("lua err: %s\n", lua_tostring(L, -1)); 126 } else { 127 if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) { 128 return new Click(this); 129 } 130 } 131 } 132 return this->INHERITED::onFindClickHandler(x, y, modi); 133 } 134 onClick(Click * click)135 bool onClick(Click* click) override { 136 const char* state = nullptr; 137 switch (click->fState) { 138 case Click::kMoved_State: 139 state = "moved"; 140 break; 141 case Click::kUp_State: 142 state = "up"; 143 break; 144 default: 145 break; 146 } 147 if (state) { 148 lua_State* L = fLua->get(); 149 lua_getglobal(L, gClickName); 150 fLua->pushScalar(click->fCurr.x()); 151 fLua->pushScalar(click->fCurr.y()); 152 fLua->pushString(state); 153 lua_pcall(L, 3, 1, 0); 154 return lua_isboolean(L, -1) && lua_toboolean(L, -1); 155 } 156 return true; 157 } 158 159 private: 160 SkLua* fLua; 161 162 typedef Sample INHERITED; 163 }; 164 165 ////////////////////////////////////////////////////////////////////////////// 166 167 DEF_SAMPLE( return new LuaView(); ) 168