SkLua.cpp 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022
  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. #include "include/utils/SkLua.h"
  8. #if SK_SUPPORT_GPU
  9. //#include "src/gpu/GrReducedClip.h"
  10. #endif
  11. #include "include/core/SkCanvas.h"
  12. #include "include/core/SkColorFilter.h"
  13. #include "include/core/SkData.h"
  14. #include "include/core/SkFont.h"
  15. #include "include/core/SkFontMetrics.h"
  16. #include "include/core/SkFontStyle.h"
  17. #include "include/core/SkImage.h"
  18. #include "include/core/SkMatrix.h"
  19. #include "include/core/SkPaint.h"
  20. #include "include/core/SkPath.h"
  21. #include "include/core/SkPictureRecorder.h"
  22. #include "include/core/SkRRect.h"
  23. #include "include/core/SkString.h"
  24. #include "include/core/SkSurface.h"
  25. #include "include/core/SkTextBlob.h"
  26. #include "include/core/SkTypeface.h"
  27. #include "include/docs/SkPDFDocument.h"
  28. #include "include/effects/SkBlurImageFilter.h"
  29. #include "include/effects/SkGradientShader.h"
  30. #include "include/private/SkTo.h"
  31. #include "modules/skshaper/include/SkShaper.h"
  32. #include "src/core/SkMakeUnique.h"
  33. #include <new>
  34. extern "C" {
  35. #include "lua.h"
  36. #include "lualib.h"
  37. #include "lauxlib.h"
  38. }
  39. struct DocHolder {
  40. sk_sp<SkDocument> fDoc;
  41. std::unique_ptr<SkWStream> fStream;
  42. };
  43. // return the metatable name for a given class
  44. template <typename T> const char* get_mtname();
  45. #define DEF_MTNAME(T) \
  46. template <> const char* get_mtname<T>() { \
  47. return #T "_LuaMetaTableName"; \
  48. }
  49. DEF_MTNAME(SkCanvas)
  50. DEF_MTNAME(SkColorFilter)
  51. DEF_MTNAME(DocHolder)
  52. DEF_MTNAME(SkFont)
  53. DEF_MTNAME(SkImage)
  54. DEF_MTNAME(SkImageFilter)
  55. DEF_MTNAME(SkMatrix)
  56. DEF_MTNAME(SkRRect)
  57. DEF_MTNAME(SkPath)
  58. DEF_MTNAME(SkPaint)
  59. DEF_MTNAME(SkPathEffect)
  60. DEF_MTNAME(SkPicture)
  61. DEF_MTNAME(SkPictureRecorder)
  62. DEF_MTNAME(SkShader)
  63. DEF_MTNAME(SkSurface)
  64. DEF_MTNAME(SkTextBlob)
  65. DEF_MTNAME(SkTypeface)
  66. DEF_MTNAME(SkFontStyle)
  67. template <typename T, typename... Args> T* push_new(lua_State* L, Args&&... args) {
  68. T* addr = (T*)lua_newuserdata(L, sizeof(T));
  69. new (addr) T(std::forward<Args>(args)...);
  70. luaL_getmetatable(L, get_mtname<T>());
  71. lua_setmetatable(L, -2);
  72. return addr;
  73. }
  74. template <typename T> void push_obj(lua_State* L, const T& obj) {
  75. new (lua_newuserdata(L, sizeof(T))) T(obj);
  76. luaL_getmetatable(L, get_mtname<T>());
  77. lua_setmetatable(L, -2);
  78. }
  79. template <typename T> T* push_ptr(lua_State* L, T* ptr) {
  80. *(T**)lua_newuserdata(L, sizeof(T*)) = ptr;
  81. luaL_getmetatable(L, get_mtname<T>());
  82. lua_setmetatable(L, -2);
  83. return ptr;
  84. }
  85. template <typename T> T* push_ref(lua_State* L, T* ref) {
  86. *(T**)lua_newuserdata(L, sizeof(T*)) = SkSafeRef(ref);
  87. luaL_getmetatable(L, get_mtname<T>());
  88. lua_setmetatable(L, -2);
  89. return ref;
  90. }
  91. template <typename T> void push_ref(lua_State* L, sk_sp<T> sp) {
  92. *(T**)lua_newuserdata(L, sizeof(T*)) = sp.release();
  93. luaL_getmetatable(L, get_mtname<T>());
  94. lua_setmetatable(L, -2);
  95. }
  96. template <typename T> T* get_ref(lua_State* L, int index) {
  97. return *(T**)luaL_checkudata(L, index, get_mtname<T>());
  98. }
  99. template <typename T> T* get_obj(lua_State* L, int index) {
  100. return (T*)luaL_checkudata(L, index, get_mtname<T>());
  101. }
  102. static bool lua2bool(lua_State* L, int index) {
  103. return !!lua_toboolean(L, index);
  104. }
  105. ///////////////////////////////////////////////////////////////////////////////
  106. SkLua::SkLua(const char termCode[]) : fTermCode(termCode), fWeOwnL(true) {
  107. fL = luaL_newstate();
  108. luaL_openlibs(fL);
  109. SkLua::Load(fL);
  110. }
  111. SkLua::SkLua(lua_State* L) : fL(L), fWeOwnL(false) {}
  112. SkLua::~SkLua() {
  113. if (fWeOwnL) {
  114. if (fTermCode.size() > 0) {
  115. lua_getglobal(fL, fTermCode.c_str());
  116. if (lua_pcall(fL, 0, 0, 0) != LUA_OK) {
  117. SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
  118. }
  119. }
  120. lua_close(fL);
  121. }
  122. }
  123. bool SkLua::runCode(const char code[]) {
  124. int err = luaL_loadstring(fL, code) || lua_pcall(fL, 0, 0, 0);
  125. if (err) {
  126. SkDebugf("--- lua failed: %s\n", lua_tostring(fL, -1));
  127. return false;
  128. }
  129. return true;
  130. }
  131. bool SkLua::runCode(const void* code, size_t size) {
  132. SkString str((const char*)code, size);
  133. return this->runCode(str.c_str());
  134. }
  135. ///////////////////////////////////////////////////////////////////////////////
  136. #define CHECK_SETFIELD(key) do if (key) lua_setfield(fL, -2, key); while (0)
  137. static void setfield_bool_if(lua_State* L, const char key[], bool pred) {
  138. if (pred) {
  139. lua_pushboolean(L, true);
  140. lua_setfield(L, -2, key);
  141. }
  142. }
  143. static void setfield_string(lua_State* L, const char key[], const char value[]) {
  144. lua_pushstring(L, value);
  145. lua_setfield(L, -2, key);
  146. }
  147. static void setfield_number(lua_State* L, const char key[], double value) {
  148. lua_pushnumber(L, value);
  149. lua_setfield(L, -2, key);
  150. }
  151. static void setfield_boolean(lua_State* L, const char key[], bool value) {
  152. lua_pushboolean(L, value);
  153. lua_setfield(L, -2, key);
  154. }
  155. static void setfield_scalar(lua_State* L, const char key[], SkScalar value) {
  156. setfield_number(L, key, SkScalarToLua(value));
  157. }
  158. static void setfield_function(lua_State* L,
  159. const char key[], lua_CFunction value) {
  160. lua_pushcfunction(L, value);
  161. lua_setfield(L, -2, key);
  162. }
  163. static int lua2int_def(lua_State* L, int index, int defaultValue) {
  164. if (lua_isnumber(L, index)) {
  165. return (int)lua_tonumber(L, index);
  166. } else {
  167. return defaultValue;
  168. }
  169. }
  170. static SkScalar lua2scalar(lua_State* L, int index) {
  171. SkASSERT(lua_isnumber(L, index));
  172. return SkLuaToScalar(lua_tonumber(L, index));
  173. }
  174. static SkScalar lua2scalar_def(lua_State* L, int index, SkScalar defaultValue) {
  175. if (lua_isnumber(L, index)) {
  176. return SkLuaToScalar(lua_tonumber(L, index));
  177. } else {
  178. return defaultValue;
  179. }
  180. }
  181. static SkScalar getarray_scalar(lua_State* L, int stackIndex, int arrayIndex) {
  182. SkASSERT(lua_istable(L, stackIndex));
  183. lua_rawgeti(L, stackIndex, arrayIndex);
  184. SkScalar value = lua2scalar(L, -1);
  185. lua_pop(L, 1);
  186. return value;
  187. }
  188. static void getarray_scalars(lua_State* L, int stackIndex, SkScalar dst[], int count) {
  189. for (int i = 0; i < count; ++i) {
  190. dst[i] = getarray_scalar(L, stackIndex, i + 1);
  191. }
  192. }
  193. static void getarray_points(lua_State* L, int stackIndex, SkPoint pts[], int count) {
  194. getarray_scalars(L, stackIndex, &pts[0].fX, count * 2);
  195. }
  196. static void setarray_number(lua_State* L, int index, double value) {
  197. lua_pushnumber(L, value);
  198. lua_rawseti(L, -2, index);
  199. }
  200. static void setarray_scalar(lua_State* L, int index, SkScalar value) {
  201. setarray_number(L, index, SkScalarToLua(value));
  202. }
  203. static void setarray_string(lua_State* L, int index, const char str[]) {
  204. lua_pushstring(L, str);
  205. lua_rawseti(L, -2, index);
  206. }
  207. void SkLua::pushBool(bool value, const char key[]) {
  208. lua_pushboolean(fL, value);
  209. CHECK_SETFIELD(key);
  210. }
  211. void SkLua::pushString(const char str[], const char key[]) {
  212. lua_pushstring(fL, str);
  213. CHECK_SETFIELD(key);
  214. }
  215. void SkLua::pushString(const char str[], size_t length, const char key[]) {
  216. // TODO: how to do this w/o making a copy?
  217. SkString s(str, length);
  218. lua_pushstring(fL, s.c_str());
  219. CHECK_SETFIELD(key);
  220. }
  221. void SkLua::pushString(const SkString& str, const char key[]) {
  222. lua_pushstring(fL, str.c_str());
  223. CHECK_SETFIELD(key);
  224. }
  225. void SkLua::pushColor(SkColor color, const char key[]) {
  226. lua_newtable(fL);
  227. setfield_number(fL, "a", SkColorGetA(color) / 255.0);
  228. setfield_number(fL, "r", SkColorGetR(color) / 255.0);
  229. setfield_number(fL, "g", SkColorGetG(color) / 255.0);
  230. setfield_number(fL, "b", SkColorGetB(color) / 255.0);
  231. CHECK_SETFIELD(key);
  232. }
  233. void SkLua::pushU32(uint32_t value, const char key[]) {
  234. lua_pushnumber(fL, (double)value);
  235. CHECK_SETFIELD(key);
  236. }
  237. void SkLua::pushScalar(SkScalar value, const char key[]) {
  238. lua_pushnumber(fL, SkScalarToLua(value));
  239. CHECK_SETFIELD(key);
  240. }
  241. void SkLua::pushArrayU16(const uint16_t array[], int count, const char key[]) {
  242. lua_newtable(fL);
  243. for (int i = 0; i < count; ++i) {
  244. // make it base-1 to match lua convention
  245. setarray_number(fL, i + 1, (double)array[i]);
  246. }
  247. CHECK_SETFIELD(key);
  248. }
  249. void SkLua::pushArrayPoint(const SkPoint array[], int count, const char key[]) {
  250. lua_newtable(fL);
  251. for (int i = 0; i < count; ++i) {
  252. // make it base-1 to match lua convention
  253. lua_newtable(fL);
  254. this->pushScalar(array[i].fX, "x");
  255. this->pushScalar(array[i].fY, "y");
  256. lua_rawseti(fL, -2, i + 1);
  257. }
  258. CHECK_SETFIELD(key);
  259. }
  260. void SkLua::pushArrayScalar(const SkScalar array[], int count, const char key[]) {
  261. lua_newtable(fL);
  262. for (int i = 0; i < count; ++i) {
  263. // make it base-1 to match lua convention
  264. setarray_scalar(fL, i + 1, array[i]);
  265. }
  266. CHECK_SETFIELD(key);
  267. }
  268. void SkLua::pushRect(const SkRect& r, const char key[]) {
  269. lua_newtable(fL);
  270. setfield_scalar(fL, "left", r.fLeft);
  271. setfield_scalar(fL, "top", r.fTop);
  272. setfield_scalar(fL, "right", r.fRight);
  273. setfield_scalar(fL, "bottom", r.fBottom);
  274. CHECK_SETFIELD(key);
  275. }
  276. void SkLua::pushRRect(const SkRRect& rr, const char key[]) {
  277. push_obj(fL, rr);
  278. CHECK_SETFIELD(key);
  279. }
  280. void SkLua::pushDash(const SkPathEffect::DashInfo& info, const char key[]) {
  281. lua_newtable(fL);
  282. setfield_scalar(fL, "phase", info.fPhase);
  283. this->pushArrayScalar(info.fIntervals, info.fCount, "intervals");
  284. CHECK_SETFIELD(key);
  285. }
  286. void SkLua::pushMatrix(const SkMatrix& matrix, const char key[]) {
  287. push_obj(fL, matrix);
  288. CHECK_SETFIELD(key);
  289. }
  290. void SkLua::pushPaint(const SkPaint& paint, const char key[]) {
  291. push_obj(fL, paint);
  292. CHECK_SETFIELD(key);
  293. }
  294. void SkLua::pushPath(const SkPath& path, const char key[]) {
  295. push_obj(fL, path);
  296. CHECK_SETFIELD(key);
  297. }
  298. void SkLua::pushCanvas(SkCanvas* canvas, const char key[]) {
  299. push_ptr(fL, canvas);
  300. CHECK_SETFIELD(key);
  301. }
  302. void SkLua::pushTextBlob(const SkTextBlob* blob, const char key[]) {
  303. push_ref(fL, const_cast<SkTextBlob*>(blob));
  304. CHECK_SETFIELD(key);
  305. }
  306. ///////////////////////////////////////////////////////////////////////////////
  307. ///////////////////////////////////////////////////////////////////////////////
  308. static SkScalar getfield_scalar(lua_State* L, int index, const char key[]) {
  309. SkASSERT(lua_istable(L, index));
  310. lua_pushstring(L, key);
  311. lua_gettable(L, index);
  312. SkScalar value = lua2scalar(L, -1);
  313. lua_pop(L, 1);
  314. return value;
  315. }
  316. static SkScalar getfield_scalar_default(lua_State* L, int index, const char key[], SkScalar def) {
  317. SkASSERT(lua_istable(L, index));
  318. lua_pushstring(L, key);
  319. lua_gettable(L, index);
  320. SkScalar value;
  321. if (lua_isnil(L, -1)) {
  322. value = def;
  323. } else {
  324. value = lua2scalar(L, -1);
  325. }
  326. lua_pop(L, 1);
  327. return value;
  328. }
  329. static SkScalar byte2unit(U8CPU byte) {
  330. return byte / 255.0f;
  331. }
  332. static U8CPU unit2byte(SkScalar x) {
  333. if (x <= 0) {
  334. return 0;
  335. } else if (x >= 1) {
  336. return 255;
  337. } else {
  338. return SkScalarRoundToInt(x * 255);
  339. }
  340. }
  341. static SkColor lua2color(lua_State* L, int index) {
  342. return SkColorSetARGB(unit2byte(getfield_scalar_default(L, index, "a", 1)),
  343. unit2byte(getfield_scalar_default(L, index, "r", 0)),
  344. unit2byte(getfield_scalar_default(L, index, "g", 0)),
  345. unit2byte(getfield_scalar_default(L, index, "b", 0)));
  346. }
  347. static SkRect* lua2rect(lua_State* L, int index, SkRect* rect) {
  348. rect->set(getfield_scalar_default(L, index, "left", 0),
  349. getfield_scalar_default(L, index, "top", 0),
  350. getfield_scalar(L, index, "right"),
  351. getfield_scalar(L, index, "bottom"));
  352. return rect;
  353. }
  354. static int lcanvas_clear(lua_State* L) {
  355. get_ref<SkCanvas>(L, 1)->clear(0);
  356. return 0;
  357. }
  358. static int lcanvas_drawColor(lua_State* L) {
  359. get_ref<SkCanvas>(L, 1)->drawColor(lua2color(L, 2));
  360. return 0;
  361. }
  362. static int lcanvas_drawPaint(lua_State* L) {
  363. get_ref<SkCanvas>(L, 1)->drawPaint(*get_obj<SkPaint>(L, 2));
  364. return 0;
  365. }
  366. static int lcanvas_drawRect(lua_State* L) {
  367. SkRect rect;
  368. lua2rect(L, 2, &rect);
  369. const SkPaint* paint = get_obj<SkPaint>(L, 3);
  370. get_ref<SkCanvas>(L, 1)->drawRect(rect, *paint);
  371. return 0;
  372. }
  373. static int lcanvas_drawOval(lua_State* L) {
  374. SkRect rect;
  375. get_ref<SkCanvas>(L, 1)->drawOval(*lua2rect(L, 2, &rect),
  376. *get_obj<SkPaint>(L, 3));
  377. return 0;
  378. }
  379. static int lcanvas_drawCircle(lua_State* L) {
  380. get_ref<SkCanvas>(L, 1)->drawCircle(lua2scalar(L, 2),
  381. lua2scalar(L, 3),
  382. lua2scalar(L, 4),
  383. *get_obj<SkPaint>(L, 5));
  384. return 0;
  385. }
  386. static SkPaint* lua2OptionalPaint(lua_State* L, int index, SkPaint* paint) {
  387. if (lua_isnumber(L, index)) {
  388. paint->setAlpha(SkScalarRoundToInt(lua2scalar(L, index) * 255));
  389. return paint;
  390. } else if (lua_isuserdata(L, index)) {
  391. const SkPaint* ptr = get_obj<SkPaint>(L, index);
  392. if (ptr) {
  393. *paint = *ptr;
  394. return paint;
  395. }
  396. }
  397. return nullptr;
  398. }
  399. static int lcanvas_drawImage(lua_State* L) {
  400. SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
  401. SkImage* image = get_ref<SkImage>(L, 2);
  402. if (nullptr == image) {
  403. return 0;
  404. }
  405. SkScalar x = lua2scalar(L, 3);
  406. SkScalar y = lua2scalar(L, 4);
  407. SkPaint paint;
  408. canvas->drawImage(image, x, y, lua2OptionalPaint(L, 5, &paint));
  409. return 0;
  410. }
  411. static int lcanvas_drawImageRect(lua_State* L) {
  412. SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
  413. SkImage* image = get_ref<SkImage>(L, 2);
  414. if (nullptr == image) {
  415. return 0;
  416. }
  417. SkRect srcR, dstR;
  418. SkRect* srcRPtr = nullptr;
  419. if (!lua_isnil(L, 3)) {
  420. srcRPtr = lua2rect(L, 3, &srcR);
  421. }
  422. lua2rect(L, 4, &dstR);
  423. SkPaint paint;
  424. canvas->legacy_drawImageRect(image, srcRPtr, dstR, lua2OptionalPaint(L, 5, &paint));
  425. return 0;
  426. }
  427. static int lcanvas_drawPatch(lua_State* L) {
  428. SkPoint cubics[12];
  429. SkColor colorStorage[4];
  430. SkPoint texStorage[4];
  431. const SkColor* colors = nullptr;
  432. const SkPoint* texs = nullptr;
  433. getarray_points(L, 2, cubics, 12);
  434. colorStorage[0] = SK_ColorRED;
  435. colorStorage[1] = SK_ColorGREEN;
  436. colorStorage[2] = SK_ColorBLUE;
  437. colorStorage[3] = SK_ColorGRAY;
  438. if (lua_isnil(L, 4)) {
  439. colors = colorStorage;
  440. } else {
  441. getarray_points(L, 4, texStorage, 4);
  442. texs = texStorage;
  443. }
  444. get_ref<SkCanvas>(L, 1)->drawPatch(cubics, colors, texs, *get_obj<SkPaint>(L, 5));
  445. return 0;
  446. }
  447. static int lcanvas_drawPath(lua_State* L) {
  448. get_ref<SkCanvas>(L, 1)->drawPath(*get_obj<SkPath>(L, 2),
  449. *get_obj<SkPaint>(L, 3));
  450. return 0;
  451. }
  452. // drawPicture(pic, x, y, paint)
  453. static int lcanvas_drawPicture(lua_State* L) {
  454. SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
  455. SkPicture* picture = get_ref<SkPicture>(L, 2);
  456. SkScalar x = lua2scalar_def(L, 3, 0);
  457. SkScalar y = lua2scalar_def(L, 4, 0);
  458. SkMatrix matrix, *matrixPtr = nullptr;
  459. if (x || y) {
  460. matrix.setTranslate(x, y);
  461. matrixPtr = &matrix;
  462. }
  463. SkPaint paint;
  464. canvas->drawPicture(picture, matrixPtr, lua2OptionalPaint(L, 5, &paint));
  465. return 0;
  466. }
  467. static int lcanvas_drawText(lua_State* L) {
  468. if (lua_gettop(L) < 5) {
  469. return 0;
  470. }
  471. // TODO: restore this logic based on SkFont instead of SkPaint
  472. #if 0
  473. if (lua_isstring(L, 2) && lua_isnumber(L, 3) && lua_isnumber(L, 4)) {
  474. size_t len;
  475. const char* text = lua_tolstring(L, 2, &len);
  476. get_ref<SkCanvas>(L, 1)->drawSimpleText(
  477. text, len, SkTextEncoding::kUTF8,
  478. lua2scalar(L, 3), lua2scalar(L, 4),
  479. SkFont::LEGACY_ExtractFromPaint(*get_obj<SkPaint>(L, 5)),
  480. *get_obj<SkPaint>(L, 5));
  481. }
  482. #endif
  483. return 0;
  484. }
  485. static int lcanvas_drawTextBlob(lua_State* L) {
  486. const SkTextBlob* blob = get_ref<SkTextBlob>(L, 2);
  487. SkScalar x = lua2scalar(L, 3);
  488. SkScalar y = lua2scalar(L, 4);
  489. const SkPaint& paint = *get_obj<SkPaint>(L, 5);
  490. get_ref<SkCanvas>(L, 1)->drawTextBlob(blob, x, y, paint);
  491. return 0;
  492. }
  493. static int lcanvas_getSaveCount(lua_State* L) {
  494. lua_pushnumber(L, get_ref<SkCanvas>(L, 1)->getSaveCount());
  495. return 1;
  496. }
  497. static int lcanvas_getTotalMatrix(lua_State* L) {
  498. SkLua(L).pushMatrix(get_ref<SkCanvas>(L, 1)->getTotalMatrix());
  499. return 1;
  500. }
  501. static int lcanvas_save(lua_State* L) {
  502. lua_pushinteger(L, get_ref<SkCanvas>(L, 1)->save());
  503. return 1;
  504. }
  505. static int lcanvas_saveLayer(lua_State* L) {
  506. SkPaint paint;
  507. lua_pushinteger(L, get_ref<SkCanvas>(L, 1)->saveLayer(nullptr, lua2OptionalPaint(L, 2, &paint)));
  508. return 1;
  509. }
  510. static int lcanvas_restore(lua_State* L) {
  511. get_ref<SkCanvas>(L, 1)->restore();
  512. return 0;
  513. }
  514. static int lcanvas_scale(lua_State* L) {
  515. SkScalar sx = lua2scalar_def(L, 2, 1);
  516. SkScalar sy = lua2scalar_def(L, 3, sx);
  517. get_ref<SkCanvas>(L, 1)->scale(sx, sy);
  518. return 0;
  519. }
  520. static int lcanvas_translate(lua_State* L) {
  521. SkScalar tx = lua2scalar_def(L, 2, 0);
  522. SkScalar ty = lua2scalar_def(L, 3, 0);
  523. get_ref<SkCanvas>(L, 1)->translate(tx, ty);
  524. return 0;
  525. }
  526. static int lcanvas_rotate(lua_State* L) {
  527. SkScalar degrees = lua2scalar_def(L, 2, 0);
  528. get_ref<SkCanvas>(L, 1)->rotate(degrees);
  529. return 0;
  530. }
  531. static int lcanvas_concat(lua_State* L) {
  532. get_ref<SkCanvas>(L, 1)->concat(*get_obj<SkMatrix>(L, 2));
  533. return 0;
  534. }
  535. static int lcanvas_newSurface(lua_State* L) {
  536. int width = lua2int_def(L, 2, 0);
  537. int height = lua2int_def(L, 3, 0);
  538. SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
  539. auto surface = get_ref<SkCanvas>(L, 1)->makeSurface(info);
  540. if (nullptr == surface) {
  541. lua_pushnil(L);
  542. } else {
  543. push_ref(L, surface);
  544. }
  545. return 1;
  546. }
  547. static int lcanvas_gc(lua_State* L) {
  548. // don't know how to track a ptr...
  549. return 0;
  550. }
  551. const struct luaL_Reg gSkCanvas_Methods[] = {
  552. { "clear", lcanvas_clear },
  553. { "drawColor", lcanvas_drawColor },
  554. { "drawPaint", lcanvas_drawPaint },
  555. { "drawRect", lcanvas_drawRect },
  556. { "drawOval", lcanvas_drawOval },
  557. { "drawCircle", lcanvas_drawCircle },
  558. { "drawImage", lcanvas_drawImage },
  559. { "drawImageRect", lcanvas_drawImageRect },
  560. { "drawPatch", lcanvas_drawPatch },
  561. { "drawPath", lcanvas_drawPath },
  562. { "drawPicture", lcanvas_drawPicture },
  563. { "drawText", lcanvas_drawText },
  564. { "drawTextBlob", lcanvas_drawTextBlob },
  565. { "getSaveCount", lcanvas_getSaveCount },
  566. { "getTotalMatrix", lcanvas_getTotalMatrix },
  567. { "save", lcanvas_save },
  568. { "saveLayer", lcanvas_saveLayer },
  569. { "restore", lcanvas_restore },
  570. { "scale", lcanvas_scale },
  571. { "translate", lcanvas_translate },
  572. { "rotate", lcanvas_rotate },
  573. { "concat", lcanvas_concat },
  574. { "newSurface", lcanvas_newSurface },
  575. { "__gc", lcanvas_gc },
  576. { nullptr, nullptr }
  577. };
  578. ///////////////////////////////////////////////////////////////////////////////
  579. static int ldocument_beginPage(lua_State* L) {
  580. const SkRect* contentPtr = nullptr;
  581. push_ptr(L, get_obj<DocHolder>(L, 1)->fDoc->beginPage(lua2scalar(L, 2),
  582. lua2scalar(L, 3),
  583. contentPtr));
  584. return 1;
  585. }
  586. static int ldocument_endPage(lua_State* L) {
  587. get_obj<DocHolder>(L, 1)->fDoc->endPage();
  588. return 0;
  589. }
  590. static int ldocument_close(lua_State* L) {
  591. get_obj<DocHolder>(L, 1)->fDoc->close();
  592. return 0;
  593. }
  594. static int ldocument_gc(lua_State* L) {
  595. get_obj<DocHolder>(L, 1)->~DocHolder();
  596. return 0;
  597. }
  598. static const struct luaL_Reg gDocHolder_Methods[] = {
  599. { "beginPage", ldocument_beginPage },
  600. { "endPage", ldocument_endPage },
  601. { "close", ldocument_close },
  602. { "__gc", ldocument_gc },
  603. { nullptr, nullptr }
  604. };
  605. ///////////////////////////////////////////////////////////////////////////////
  606. static int lpaint_isAntiAlias(lua_State* L) {
  607. lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isAntiAlias());
  608. return 1;
  609. }
  610. static int lpaint_setAntiAlias(lua_State* L) {
  611. get_obj<SkPaint>(L, 1)->setAntiAlias(lua2bool(L, 2));
  612. return 0;
  613. }
  614. static int lpaint_isDither(lua_State* L) {
  615. lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isDither());
  616. return 1;
  617. }
  618. static int lpaint_setDither(lua_State* L) {
  619. get_obj<SkPaint>(L, 1)->setDither(lua2bool(L, 2));
  620. return 0;
  621. }
  622. static int lpaint_getAlpha(lua_State* L) {
  623. SkLua(L).pushScalar(byte2unit(get_obj<SkPaint>(L, 1)->getAlpha()));
  624. return 1;
  625. }
  626. static int lpaint_setAlpha(lua_State* L) {
  627. get_obj<SkPaint>(L, 1)->setAlpha(unit2byte(lua2scalar(L, 2)));
  628. return 0;
  629. }
  630. static int lpaint_getColor(lua_State* L) {
  631. SkLua(L).pushColor(get_obj<SkPaint>(L, 1)->getColor());
  632. return 1;
  633. }
  634. static int lpaint_setColor(lua_State* L) {
  635. get_obj<SkPaint>(L, 1)->setColor(lua2color(L, 2));
  636. return 0;
  637. }
  638. static int lpaint_getFilterQuality(lua_State* L) {
  639. SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getFilterQuality());
  640. return 1;
  641. }
  642. static int lpaint_setFilterQuality(lua_State* L) {
  643. int level = lua2int_def(L, 2, -1);
  644. if (level >= 0 && level <= 3) {
  645. get_obj<SkPaint>(L, 1)->setFilterQuality((SkFilterQuality)level);
  646. }
  647. return 0;
  648. }
  649. static int lpaint_getStroke(lua_State* L) {
  650. lua_pushboolean(L, SkPaint::kStroke_Style == get_obj<SkPaint>(L, 1)->getStyle());
  651. return 1;
  652. }
  653. static int lpaint_setStroke(lua_State* L) {
  654. SkPaint::Style style;
  655. if (lua_toboolean(L, 2)) {
  656. style = SkPaint::kStroke_Style;
  657. } else {
  658. style = SkPaint::kFill_Style;
  659. }
  660. get_obj<SkPaint>(L, 1)->setStyle(style);
  661. return 0;
  662. }
  663. static int lpaint_getStrokeCap(lua_State* L) {
  664. SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeCap());
  665. return 1;
  666. }
  667. static int lpaint_getStrokeJoin(lua_State* L) {
  668. SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeJoin());
  669. return 1;
  670. }
  671. static int lpaint_getStrokeWidth(lua_State* L) {
  672. SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeWidth());
  673. return 1;
  674. }
  675. static int lpaint_setStrokeWidth(lua_State* L) {
  676. get_obj<SkPaint>(L, 1)->setStrokeWidth(lua2scalar(L, 2));
  677. return 0;
  678. }
  679. static int lpaint_getStrokeMiter(lua_State* L) {
  680. SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeMiter());
  681. return 1;
  682. }
  683. static int lpaint_getEffects(lua_State* L) {
  684. const SkPaint* paint = get_obj<SkPaint>(L, 1);
  685. lua_newtable(L);
  686. #ifdef SK_SUPPORT_LEGACY_DRAWLOOPER
  687. setfield_bool_if(L, "looper", !!paint->getLooper());
  688. #endif
  689. setfield_bool_if(L, "pathEffect", !!paint->getPathEffect());
  690. setfield_bool_if(L, "maskFilter", !!paint->getMaskFilter());
  691. setfield_bool_if(L, "shader", !!paint->getShader());
  692. setfield_bool_if(L, "colorFilter", !!paint->getColorFilter());
  693. setfield_bool_if(L, "imageFilter", !!paint->getImageFilter());
  694. return 1;
  695. }
  696. static int lpaint_getColorFilter(lua_State* L) {
  697. const SkPaint* paint = get_obj<SkPaint>(L, 1);
  698. SkColorFilter* cf = paint->getColorFilter();
  699. if (cf) {
  700. push_ref(L, cf);
  701. return 1;
  702. }
  703. return 0;
  704. }
  705. static int lpaint_setColorFilter(lua_State* L) {
  706. SkPaint* paint = get_obj<SkPaint>(L, 1);
  707. paint->setColorFilter(sk_ref_sp(get_ref<SkColorFilter>(L, 2)));
  708. return 0;
  709. }
  710. static int lpaint_getImageFilter(lua_State* L) {
  711. const SkPaint* paint = get_obj<SkPaint>(L, 1);
  712. SkImageFilter* imf = paint->getImageFilter();
  713. if (imf) {
  714. push_ref(L, imf);
  715. return 1;
  716. }
  717. return 0;
  718. }
  719. static int lpaint_setImageFilter(lua_State* L) {
  720. SkPaint* paint = get_obj<SkPaint>(L, 1);
  721. paint->setImageFilter(sk_ref_sp(get_ref<SkImageFilter>(L, 2)));
  722. return 0;
  723. }
  724. static int lpaint_getShader(lua_State* L) {
  725. const SkPaint* paint = get_obj<SkPaint>(L, 1);
  726. SkShader* shader = paint->getShader();
  727. if (shader) {
  728. push_ref(L, shader);
  729. return 1;
  730. }
  731. return 0;
  732. }
  733. static int lpaint_setShader(lua_State* L) {
  734. SkPaint* paint = get_obj<SkPaint>(L, 1);
  735. paint->setShader(sk_ref_sp(get_ref<SkShader>(L, 2)));
  736. return 0;
  737. }
  738. static int lpaint_getPathEffect(lua_State* L) {
  739. const SkPaint* paint = get_obj<SkPaint>(L, 1);
  740. SkPathEffect* pe = paint->getPathEffect();
  741. if (pe) {
  742. push_ref(L, pe);
  743. return 1;
  744. }
  745. return 0;
  746. }
  747. static int lpaint_getFillPath(lua_State* L) {
  748. const SkPaint* paint = get_obj<SkPaint>(L, 1);
  749. const SkPath* path = get_obj<SkPath>(L, 2);
  750. SkPath fillpath;
  751. paint->getFillPath(*path, &fillpath);
  752. SkLua lua(L);
  753. lua.pushPath(fillpath);
  754. return 1;
  755. }
  756. static int lpaint_gc(lua_State* L) {
  757. get_obj<SkPaint>(L, 1)->~SkPaint();
  758. return 0;
  759. }
  760. static const struct luaL_Reg gSkPaint_Methods[] = {
  761. { "isAntiAlias", lpaint_isAntiAlias },
  762. { "setAntiAlias", lpaint_setAntiAlias },
  763. { "isDither", lpaint_isDither },
  764. { "setDither", lpaint_setDither },
  765. { "getFilterQuality", lpaint_getFilterQuality },
  766. { "setFilterQuality", lpaint_setFilterQuality },
  767. { "getAlpha", lpaint_getAlpha },
  768. { "setAlpha", lpaint_setAlpha },
  769. { "getColor", lpaint_getColor },
  770. { "setColor", lpaint_setColor },
  771. { "getStroke", lpaint_getStroke },
  772. { "setStroke", lpaint_setStroke },
  773. { "getStrokeCap", lpaint_getStrokeCap },
  774. { "getStrokeJoin", lpaint_getStrokeJoin },
  775. { "getStrokeWidth", lpaint_getStrokeWidth },
  776. { "setStrokeWidth", lpaint_setStrokeWidth },
  777. { "getStrokeMiter", lpaint_getStrokeMiter },
  778. { "getEffects", lpaint_getEffects },
  779. { "getColorFilter", lpaint_getColorFilter },
  780. { "setColorFilter", lpaint_setColorFilter },
  781. { "getImageFilter", lpaint_getImageFilter },
  782. { "setImageFilter", lpaint_setImageFilter },
  783. { "getShader", lpaint_getShader },
  784. { "setShader", lpaint_setShader },
  785. { "getPathEffect", lpaint_getPathEffect },
  786. { "getFillPath", lpaint_getFillPath },
  787. { "__gc", lpaint_gc },
  788. { nullptr, nullptr }
  789. };
  790. ///////////////////////////////////////////////////////////////////////////////
  791. static int lfont_getSize(lua_State* L) {
  792. SkLua(L).pushScalar(get_obj<SkFont>(L, 1)->getSize());
  793. return 1;
  794. }
  795. static int lfont_getScaleX(lua_State* L) {
  796. SkLua(L).pushScalar(get_obj<SkFont>(L, 1)->getScaleX());
  797. return 1;
  798. }
  799. static int lfont_getSkewX(lua_State* L) {
  800. SkLua(L).pushScalar(get_obj<SkFont>(L, 1)->getSkewX());
  801. return 1;
  802. }
  803. static int lfont_setSize(lua_State* L) {
  804. get_obj<SkFont>(L, 1)->setSize(lua2scalar(L, 2));
  805. return 0;
  806. }
  807. static int lfont_getTypeface(lua_State* L) {
  808. push_ref(L, get_obj<SkFont>(L, 1)->getTypefaceOrDefault());
  809. return 1;
  810. }
  811. static int lfont_setTypeface(lua_State* L) {
  812. get_obj<SkFont>(L, 1)->setTypeface(sk_ref_sp(get_ref<SkTypeface>(L, 2)));
  813. return 0;
  814. }
  815. static int lfont_getHinting(lua_State* L) {
  816. SkLua(L).pushU32((unsigned)get_obj<SkFont>(L, 1)->getHinting());
  817. return 1;
  818. }
  819. static int lfont_getFontID(lua_State* L) {
  820. SkTypeface* face = get_obj<SkFont>(L, 1)->getTypefaceOrDefault();
  821. SkLua(L).pushU32(SkTypeface::UniqueID(face));
  822. return 1;
  823. }
  824. static int lfont_measureText(lua_State* L) {
  825. if (lua_isstring(L, 2)) {
  826. size_t len;
  827. const char* text = lua_tolstring(L, 2, &len);
  828. SkLua(L).pushScalar(get_obj<SkFont>(L, 1)->measureText(text, len, SkTextEncoding::kUTF8));
  829. return 1;
  830. }
  831. return 0;
  832. }
  833. static int lfont_getMetrics(lua_State* L) {
  834. SkFontMetrics fm;
  835. SkScalar height = get_obj<SkFont>(L, 1)->getMetrics(&fm);
  836. lua_newtable(L);
  837. setfield_scalar(L, "top", fm.fTop);
  838. setfield_scalar(L, "ascent", fm.fAscent);
  839. setfield_scalar(L, "descent", fm.fDescent);
  840. setfield_scalar(L, "bottom", fm.fBottom);
  841. setfield_scalar(L, "leading", fm.fLeading);
  842. SkLua(L).pushScalar(height);
  843. return 2;
  844. }
  845. static int lfont_gc(lua_State* L) {
  846. get_obj<SkFont>(L, 1)->~SkFont();
  847. return 0;
  848. }
  849. static const struct luaL_Reg gSkFont_Methods[] = {
  850. { "getSize", lfont_getSize },
  851. { "setSize", lfont_setSize },
  852. { "getScaleX", lfont_getScaleX },
  853. { "getSkewX", lfont_getSkewX },
  854. { "getTypeface", lfont_getTypeface },
  855. { "setTypeface", lfont_setTypeface },
  856. { "getHinting", lfont_getHinting },
  857. { "getFontID", lfont_getFontID },
  858. { "measureText", lfont_measureText },
  859. { "getMetrics", lfont_getMetrics },
  860. { "__gc", lfont_gc },
  861. { nullptr, nullptr }
  862. };
  863. ///////////////////////////////////////////////////////////////////////////////
  864. static const char* mode2string(SkTileMode mode) {
  865. static const char* gNames[] = { "clamp", "repeat", "mirror", "decal" };
  866. SkASSERT((unsigned)mode < SK_ARRAY_COUNT(gNames));
  867. return gNames[static_cast<int>(mode)];
  868. }
  869. static const char* gradtype2string(SkShader::GradientType t) {
  870. static const char* gNames[] = {
  871. "none", "color", "linear", "radial", "radial2", "sweep", "conical"
  872. };
  873. SkASSERT((unsigned)t < SK_ARRAY_COUNT(gNames));
  874. return gNames[t];
  875. }
  876. static int lshader_isOpaque(lua_State* L) {
  877. SkShader* shader = get_ref<SkShader>(L, 1);
  878. return shader && shader->isOpaque();
  879. }
  880. static int lshader_isAImage(lua_State* L) {
  881. SkShader* shader = get_ref<SkShader>(L, 1);
  882. if (shader) {
  883. SkMatrix matrix;
  884. SkTileMode modes[2];
  885. if (SkImage* image = shader->isAImage(&matrix, modes)) {
  886. lua_newtable(L);
  887. setfield_number(L, "id", image->uniqueID());
  888. setfield_number(L, "width", image->width());
  889. setfield_number(L, "height", image->height());
  890. setfield_string(L, "tileX", mode2string(modes[0]));
  891. setfield_string(L, "tileY", mode2string(modes[1]));
  892. return 1;
  893. }
  894. }
  895. return 0;
  896. }
  897. static int lshader_asAGradient(lua_State* L) {
  898. SkShader* shader = get_ref<SkShader>(L, 1);
  899. if (shader) {
  900. SkShader::GradientInfo info;
  901. sk_bzero(&info, sizeof(info));
  902. SkShader::GradientType t = shader->asAGradient(&info);
  903. if (SkShader::kNone_GradientType != t) {
  904. SkAutoTArray<SkScalar> pos(info.fColorCount);
  905. info.fColorOffsets = pos.get();
  906. shader->asAGradient(&info);
  907. lua_newtable(L);
  908. setfield_string(L, "type", gradtype2string(t));
  909. setfield_string(L, "tile", mode2string((SkTileMode)info.fTileMode));
  910. setfield_number(L, "colorCount", info.fColorCount);
  911. lua_newtable(L);
  912. for (int i = 0; i < info.fColorCount; i++) {
  913. // Lua uses 1-based indexing
  914. setarray_scalar(L, i+1, pos[i]);
  915. }
  916. lua_setfield(L, -2, "positions");
  917. return 1;
  918. }
  919. }
  920. return 0;
  921. }
  922. static int lshader_gc(lua_State* L) {
  923. get_ref<SkShader>(L, 1)->unref();
  924. return 0;
  925. }
  926. static const struct luaL_Reg gSkShader_Methods[] = {
  927. { "isOpaque", lshader_isOpaque },
  928. { "isAImage", lshader_isAImage },
  929. { "asAGradient", lshader_asAGradient },
  930. { "__gc", lshader_gc },
  931. { nullptr, nullptr }
  932. };
  933. ///////////////////////////////////////////////////////////////////////////////
  934. static int lpatheffect_asADash(lua_State* L) {
  935. SkPathEffect* pe = get_ref<SkPathEffect>(L, 1);
  936. if (pe) {
  937. SkPathEffect::DashInfo info;
  938. SkPathEffect::DashType dashType = pe->asADash(&info);
  939. if (SkPathEffect::kDash_DashType == dashType) {
  940. SkAutoTArray<SkScalar> intervals(info.fCount);
  941. info.fIntervals = intervals.get();
  942. pe->asADash(&info);
  943. SkLua(L).pushDash(info);
  944. return 1;
  945. }
  946. }
  947. return 0;
  948. }
  949. static int lpatheffect_gc(lua_State* L) {
  950. get_ref<SkPathEffect>(L, 1)->unref();
  951. return 0;
  952. }
  953. static const struct luaL_Reg gSkPathEffect_Methods[] = {
  954. { "asADash", lpatheffect_asADash },
  955. { "__gc", lpatheffect_gc },
  956. { nullptr, nullptr }
  957. };
  958. ///////////////////////////////////////////////////////////////////////////////
  959. static int lpcolorfilter_gc(lua_State* L) {
  960. get_ref<SkColorFilter>(L, 1)->unref();
  961. return 0;
  962. }
  963. static const struct luaL_Reg gSkColorFilter_Methods[] = {
  964. { "__gc", lpcolorfilter_gc },
  965. { nullptr, nullptr }
  966. };
  967. ///////////////////////////////////////////////////////////////////////////////
  968. static int lpimagefilter_gc(lua_State* L) {
  969. get_ref<SkImageFilter>(L, 1)->unref();
  970. return 0;
  971. }
  972. static const struct luaL_Reg gSkImageFilter_Methods[] = {
  973. { "__gc", lpimagefilter_gc },
  974. { nullptr, nullptr }
  975. };
  976. ///////////////////////////////////////////////////////////////////////////////
  977. static int lmatrix_getType(lua_State* L) {
  978. SkMatrix::TypeMask mask = get_obj<SkMatrix>(L, 1)->getType();
  979. lua_newtable(L);
  980. setfield_boolean(L, "translate", SkToBool(mask & SkMatrix::kTranslate_Mask));
  981. setfield_boolean(L, "scale", SkToBool(mask & SkMatrix::kScale_Mask));
  982. setfield_boolean(L, "affine", SkToBool(mask & SkMatrix::kAffine_Mask));
  983. setfield_boolean(L, "perspective", SkToBool(mask & SkMatrix::kPerspective_Mask));
  984. return 1;
  985. }
  986. static int lmatrix_getScaleX(lua_State* L) {
  987. lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getScaleX());
  988. return 1;
  989. }
  990. static int lmatrix_getScaleY(lua_State* L) {
  991. lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getScaleY());
  992. return 1;
  993. }
  994. static int lmatrix_getTranslateX(lua_State* L) {
  995. lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getTranslateX());
  996. return 1;
  997. }
  998. static int lmatrix_getTranslateY(lua_State* L) {
  999. lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getTranslateY());
  1000. return 1;
  1001. }
  1002. static int lmatrix_invert(lua_State* L) {
  1003. lua_pushboolean(L, get_obj<SkMatrix>(L, 1)->invert(get_obj<SkMatrix>(L, 2)));
  1004. return 1;
  1005. }
  1006. static int lmatrix_mapXY(lua_State* L) {
  1007. SkPoint pt = { lua2scalar(L, 2), lua2scalar(L, 3) };
  1008. get_obj<SkMatrix>(L, 1)->mapPoints(&pt, &pt, 1);
  1009. lua_pushnumber(L, pt.x());
  1010. lua_pushnumber(L, pt.y());
  1011. return 2;
  1012. }
  1013. static int lmatrix_setRectToRect(lua_State* L) {
  1014. SkMatrix* matrix = get_obj<SkMatrix>(L, 1);
  1015. SkRect srcR, dstR;
  1016. lua2rect(L, 2, &srcR);
  1017. lua2rect(L, 3, &dstR);
  1018. const char* scaleToFitStr = lua_tostring(L, 4);
  1019. SkMatrix::ScaleToFit scaleToFit = SkMatrix::kFill_ScaleToFit;
  1020. if (scaleToFitStr) {
  1021. const struct {
  1022. const char* fName;
  1023. SkMatrix::ScaleToFit fScaleToFit;
  1024. } rec[] = {
  1025. { "fill", SkMatrix::kFill_ScaleToFit },
  1026. { "start", SkMatrix::kStart_ScaleToFit },
  1027. { "center", SkMatrix::kCenter_ScaleToFit },
  1028. { "end", SkMatrix::kEnd_ScaleToFit },
  1029. };
  1030. for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
  1031. if (strcmp(rec[i].fName, scaleToFitStr) == 0) {
  1032. scaleToFit = rec[i].fScaleToFit;
  1033. break;
  1034. }
  1035. }
  1036. }
  1037. matrix->setRectToRect(srcR, dstR, scaleToFit);
  1038. return 0;
  1039. }
  1040. static const struct luaL_Reg gSkMatrix_Methods[] = {
  1041. { "getType", lmatrix_getType },
  1042. { "getScaleX", lmatrix_getScaleX },
  1043. { "getScaleY", lmatrix_getScaleY },
  1044. { "getTranslateX", lmatrix_getTranslateX },
  1045. { "getTranslateY", lmatrix_getTranslateY },
  1046. { "setRectToRect", lmatrix_setRectToRect },
  1047. { "invert", lmatrix_invert },
  1048. { "mapXY", lmatrix_mapXY },
  1049. { nullptr, nullptr }
  1050. };
  1051. ///////////////////////////////////////////////////////////////////////////////
  1052. static int lpath_getBounds(lua_State* L) {
  1053. SkLua(L).pushRect(get_obj<SkPath>(L, 1)->getBounds());
  1054. return 1;
  1055. }
  1056. static const char* fill_type_to_str(SkPath::FillType fill) {
  1057. switch (fill) {
  1058. case SkPath::kEvenOdd_FillType:
  1059. return "even-odd";
  1060. case SkPath::kWinding_FillType:
  1061. return "winding";
  1062. case SkPath::kInverseEvenOdd_FillType:
  1063. return "inverse-even-odd";
  1064. case SkPath::kInverseWinding_FillType:
  1065. return "inverse-winding";
  1066. }
  1067. return "unknown";
  1068. }
  1069. static int lpath_getFillType(lua_State* L) {
  1070. SkPath::FillType fill = get_obj<SkPath>(L, 1)->getFillType();
  1071. SkLua(L).pushString(fill_type_to_str(fill));
  1072. return 1;
  1073. }
  1074. static SkString segment_masks_to_str(uint32_t segmentMasks) {
  1075. SkString result;
  1076. bool first = true;
  1077. if (SkPath::kLine_SegmentMask & segmentMasks) {
  1078. result.append("line");
  1079. first = false;
  1080. SkDEBUGCODE(segmentMasks &= ~SkPath::kLine_SegmentMask;)
  1081. }
  1082. if (SkPath::kQuad_SegmentMask & segmentMasks) {
  1083. if (!first) {
  1084. result.append(" ");
  1085. }
  1086. result.append("quad");
  1087. first = false;
  1088. SkDEBUGCODE(segmentMasks &= ~SkPath::kQuad_SegmentMask;)
  1089. }
  1090. if (SkPath::kConic_SegmentMask & segmentMasks) {
  1091. if (!first) {
  1092. result.append(" ");
  1093. }
  1094. result.append("conic");
  1095. first = false;
  1096. SkDEBUGCODE(segmentMasks &= ~SkPath::kConic_SegmentMask;)
  1097. }
  1098. if (SkPath::kCubic_SegmentMask & segmentMasks) {
  1099. if (!first) {
  1100. result.append(" ");
  1101. }
  1102. result.append("cubic");
  1103. SkDEBUGCODE(segmentMasks &= ~SkPath::kCubic_SegmentMask;)
  1104. }
  1105. SkASSERT(0 == segmentMasks);
  1106. return result;
  1107. }
  1108. static int lpath_getSegmentTypes(lua_State* L) {
  1109. uint32_t segMasks = get_obj<SkPath>(L, 1)->getSegmentMasks();
  1110. SkLua(L).pushString(segment_masks_to_str(segMasks));
  1111. return 1;
  1112. }
  1113. static int lpath_isConvex(lua_State* L) {
  1114. bool isConvex = SkPath::kConvex_Convexity == get_obj<SkPath>(L, 1)->getConvexity();
  1115. SkLua(L).pushBool(isConvex);
  1116. return 1;
  1117. }
  1118. static int lpath_isEmpty(lua_State* L) {
  1119. lua_pushboolean(L, get_obj<SkPath>(L, 1)->isEmpty());
  1120. return 1;
  1121. }
  1122. static int lpath_isRect(lua_State* L) {
  1123. SkRect r;
  1124. bool pred = get_obj<SkPath>(L, 1)->isRect(&r);
  1125. int ret_count = 1;
  1126. lua_pushboolean(L, pred);
  1127. if (pred) {
  1128. SkLua(L).pushRect(r);
  1129. ret_count += 1;
  1130. }
  1131. return ret_count;
  1132. }
  1133. static const char* dir2string(SkPath::Direction dir) {
  1134. static const char* gStr[] = {
  1135. "unknown", "cw", "ccw"
  1136. };
  1137. SkASSERT((unsigned)dir < SK_ARRAY_COUNT(gStr));
  1138. return gStr[dir];
  1139. }
  1140. static int lpath_isNestedFillRects(lua_State* L) {
  1141. SkRect rects[2];
  1142. SkPath::Direction dirs[2];
  1143. bool pred = get_obj<SkPath>(L, 1)->isNestedFillRects(rects, dirs);
  1144. int ret_count = 1;
  1145. lua_pushboolean(L, pred);
  1146. if (pred) {
  1147. SkLua lua(L);
  1148. lua.pushRect(rects[0]);
  1149. lua.pushRect(rects[1]);
  1150. lua_pushstring(L, dir2string(dirs[0]));
  1151. lua_pushstring(L, dir2string(dirs[0]));
  1152. ret_count += 4;
  1153. }
  1154. return ret_count;
  1155. }
  1156. static int lpath_countPoints(lua_State* L) {
  1157. lua_pushinteger(L, get_obj<SkPath>(L, 1)->countPoints());
  1158. return 1;
  1159. }
  1160. static int lpath_getVerbs(lua_State* L) {
  1161. const SkPath* path = get_obj<SkPath>(L, 1);
  1162. SkPath::Iter iter(*path, false);
  1163. SkPoint pts[4];
  1164. lua_newtable(L);
  1165. bool done = false;
  1166. int i = 0;
  1167. do {
  1168. switch (iter.next(pts, true)) {
  1169. case SkPath::kMove_Verb:
  1170. setarray_string(L, ++i, "move");
  1171. break;
  1172. case SkPath::kClose_Verb:
  1173. setarray_string(L, ++i, "close");
  1174. break;
  1175. case SkPath::kLine_Verb:
  1176. setarray_string(L, ++i, "line");
  1177. break;
  1178. case SkPath::kQuad_Verb:
  1179. setarray_string(L, ++i, "quad");
  1180. break;
  1181. case SkPath::kConic_Verb:
  1182. setarray_string(L, ++i, "conic");
  1183. break;
  1184. case SkPath::kCubic_Verb:
  1185. setarray_string(L, ++i, "cubic");
  1186. break;
  1187. case SkPath::kDone_Verb:
  1188. setarray_string(L, ++i, "done");
  1189. done = true;
  1190. break;
  1191. }
  1192. } while (!done);
  1193. return 1;
  1194. }
  1195. static int lpath_reset(lua_State* L) {
  1196. get_obj<SkPath>(L, 1)->reset();
  1197. return 0;
  1198. }
  1199. static int lpath_moveTo(lua_State* L) {
  1200. get_obj<SkPath>(L, 1)->moveTo(lua2scalar(L, 2), lua2scalar(L, 3));
  1201. return 0;
  1202. }
  1203. static int lpath_lineTo(lua_State* L) {
  1204. get_obj<SkPath>(L, 1)->lineTo(lua2scalar(L, 2), lua2scalar(L, 3));
  1205. return 0;
  1206. }
  1207. static int lpath_quadTo(lua_State* L) {
  1208. get_obj<SkPath>(L, 1)->quadTo(lua2scalar(L, 2), lua2scalar(L, 3),
  1209. lua2scalar(L, 4), lua2scalar(L, 5));
  1210. return 0;
  1211. }
  1212. static int lpath_cubicTo(lua_State* L) {
  1213. get_obj<SkPath>(L, 1)->cubicTo(lua2scalar(L, 2), lua2scalar(L, 3),
  1214. lua2scalar(L, 4), lua2scalar(L, 5),
  1215. lua2scalar(L, 6), lua2scalar(L, 7));
  1216. return 0;
  1217. }
  1218. static int lpath_close(lua_State* L) {
  1219. get_obj<SkPath>(L, 1)->close();
  1220. return 0;
  1221. }
  1222. static int lpath_gc(lua_State* L) {
  1223. get_obj<SkPath>(L, 1)->~SkPath();
  1224. return 0;
  1225. }
  1226. static const struct luaL_Reg gSkPath_Methods[] = {
  1227. { "getBounds", lpath_getBounds },
  1228. { "getFillType", lpath_getFillType },
  1229. { "getSegmentTypes", lpath_getSegmentTypes },
  1230. { "getVerbs", lpath_getVerbs },
  1231. { "isConvex", lpath_isConvex },
  1232. { "isEmpty", lpath_isEmpty },
  1233. { "isRect", lpath_isRect },
  1234. { "isNestedFillRects", lpath_isNestedFillRects },
  1235. { "countPoints", lpath_countPoints },
  1236. { "reset", lpath_reset },
  1237. { "moveTo", lpath_moveTo },
  1238. { "lineTo", lpath_lineTo },
  1239. { "quadTo", lpath_quadTo },
  1240. { "cubicTo", lpath_cubicTo },
  1241. { "close", lpath_close },
  1242. { "__gc", lpath_gc },
  1243. { nullptr, nullptr }
  1244. };
  1245. ///////////////////////////////////////////////////////////////////////////////
  1246. static const char* rrect_type(const SkRRect& rr) {
  1247. switch (rr.getType()) {
  1248. case SkRRect::kEmpty_Type: return "empty";
  1249. case SkRRect::kRect_Type: return "rect";
  1250. case SkRRect::kOval_Type: return "oval";
  1251. case SkRRect::kSimple_Type: return "simple";
  1252. case SkRRect::kNinePatch_Type: return "nine-patch";
  1253. case SkRRect::kComplex_Type: return "complex";
  1254. }
  1255. SkDEBUGFAIL("never get here");
  1256. return "";
  1257. }
  1258. static int lrrect_rect(lua_State* L) {
  1259. SkLua(L).pushRect(get_obj<SkRRect>(L, 1)->rect());
  1260. return 1;
  1261. }
  1262. static int lrrect_type(lua_State* L) {
  1263. lua_pushstring(L, rrect_type(*get_obj<SkRRect>(L, 1)));
  1264. return 1;
  1265. }
  1266. static int lrrect_radii(lua_State* L) {
  1267. int corner = SkToInt(lua_tointeger(L, 2));
  1268. SkVector v;
  1269. if (corner < 0 || corner > 3) {
  1270. SkDebugf("bad corner index %d", corner);
  1271. v.set(0, 0);
  1272. } else {
  1273. v = get_obj<SkRRect>(L, 1)->radii((SkRRect::Corner)corner);
  1274. }
  1275. lua_pushnumber(L, v.fX);
  1276. lua_pushnumber(L, v.fY);
  1277. return 2;
  1278. }
  1279. static int lrrect_gc(lua_State* L) {
  1280. get_obj<SkRRect>(L, 1)->~SkRRect();
  1281. return 0;
  1282. }
  1283. static const struct luaL_Reg gSkRRect_Methods[] = {
  1284. { "rect", lrrect_rect },
  1285. { "type", lrrect_type },
  1286. { "radii", lrrect_radii },
  1287. { "__gc", lrrect_gc },
  1288. { nullptr, nullptr }
  1289. };
  1290. ///////////////////////////////////////////////////////////////////////////////
  1291. static int limage_width(lua_State* L) {
  1292. lua_pushinteger(L, get_ref<SkImage>(L, 1)->width());
  1293. return 1;
  1294. }
  1295. static int limage_height(lua_State* L) {
  1296. lua_pushinteger(L, get_ref<SkImage>(L, 1)->height());
  1297. return 1;
  1298. }
  1299. static int limage_newShader(lua_State* L) {
  1300. SkTileMode tmode = SkTileMode::kClamp;
  1301. const SkMatrix* localM = nullptr;
  1302. push_ref(L, get_ref<SkImage>(L, 1)->makeShader(tmode, tmode, localM));
  1303. return 1;
  1304. }
  1305. static int limage_gc(lua_State* L) {
  1306. get_ref<SkImage>(L, 1)->unref();
  1307. return 0;
  1308. }
  1309. static const struct luaL_Reg gSkImage_Methods[] = {
  1310. { "width", limage_width },
  1311. { "height", limage_height },
  1312. { "newShader", limage_newShader },
  1313. { "__gc", limage_gc },
  1314. { nullptr, nullptr }
  1315. };
  1316. ///////////////////////////////////////////////////////////////////////////////
  1317. static int lsurface_width(lua_State* L) {
  1318. lua_pushinteger(L, get_ref<SkSurface>(L, 1)->width());
  1319. return 1;
  1320. }
  1321. static int lsurface_height(lua_State* L) {
  1322. lua_pushinteger(L, get_ref<SkSurface>(L, 1)->height());
  1323. return 1;
  1324. }
  1325. static int lsurface_getCanvas(lua_State* L) {
  1326. SkCanvas* canvas = get_ref<SkSurface>(L, 1)->getCanvas();
  1327. if (nullptr == canvas) {
  1328. lua_pushnil(L);
  1329. } else {
  1330. push_ptr(L, canvas);
  1331. // note: we don't unref canvas, since getCanvas did not ref it.
  1332. // warning: this is weird: now Lua owns a ref on this canvas, but what if they let
  1333. // the real owner (the surface) go away, but still hold onto the canvas?
  1334. // *really* we want to sort of ref the surface again, but have the native object
  1335. // know that it is supposed to be treated as a canvas...
  1336. }
  1337. return 1;
  1338. }
  1339. static int lsurface_newImageSnapshot(lua_State* L) {
  1340. sk_sp<SkImage> image = get_ref<SkSurface>(L, 1)->makeImageSnapshot();
  1341. if (!image) {
  1342. lua_pushnil(L);
  1343. } else {
  1344. push_ref(L, image);
  1345. }
  1346. return 1;
  1347. }
  1348. static int lsurface_newSurface(lua_State* L) {
  1349. int width = lua2int_def(L, 2, 0);
  1350. int height = lua2int_def(L, 3, 0);
  1351. SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
  1352. auto surface = get_ref<SkSurface>(L, 1)->makeSurface(info);
  1353. if (nullptr == surface) {
  1354. lua_pushnil(L);
  1355. } else {
  1356. push_ref(L, surface);
  1357. }
  1358. return 1;
  1359. }
  1360. static int lsurface_gc(lua_State* L) {
  1361. get_ref<SkSurface>(L, 1)->unref();
  1362. return 0;
  1363. }
  1364. static const struct luaL_Reg gSkSurface_Methods[] = {
  1365. { "width", lsurface_width },
  1366. { "height", lsurface_height },
  1367. { "getCanvas", lsurface_getCanvas },
  1368. { "newImageSnapshot", lsurface_newImageSnapshot },
  1369. { "newSurface", lsurface_newSurface },
  1370. { "__gc", lsurface_gc },
  1371. { nullptr, nullptr }
  1372. };
  1373. ///////////////////////////////////////////////////////////////////////////////
  1374. static int lpicturerecorder_beginRecording(lua_State* L) {
  1375. const SkScalar w = lua2scalar_def(L, 2, -1);
  1376. const SkScalar h = lua2scalar_def(L, 3, -1);
  1377. if (w <= 0 || h <= 0) {
  1378. lua_pushnil(L);
  1379. return 1;
  1380. }
  1381. SkCanvas* canvas = get_obj<SkPictureRecorder>(L, 1)->beginRecording(w, h);
  1382. if (nullptr == canvas) {
  1383. lua_pushnil(L);
  1384. return 1;
  1385. }
  1386. push_ptr(L, canvas);
  1387. return 1;
  1388. }
  1389. static int lpicturerecorder_getCanvas(lua_State* L) {
  1390. SkCanvas* canvas = get_obj<SkPictureRecorder>(L, 1)->getRecordingCanvas();
  1391. if (nullptr == canvas) {
  1392. lua_pushnil(L);
  1393. return 1;
  1394. }
  1395. push_ptr(L, canvas);
  1396. return 1;
  1397. }
  1398. static int lpicturerecorder_endRecording(lua_State* L) {
  1399. sk_sp<SkPicture> pic = get_obj<SkPictureRecorder>(L, 1)->finishRecordingAsPicture();
  1400. if (!pic) {
  1401. lua_pushnil(L);
  1402. return 1;
  1403. }
  1404. push_ref(L, std::move(pic));
  1405. return 1;
  1406. }
  1407. static int lpicturerecorder_gc(lua_State* L) {
  1408. get_obj<SkPictureRecorder>(L, 1)->~SkPictureRecorder();
  1409. return 0;
  1410. }
  1411. static const struct luaL_Reg gSkPictureRecorder_Methods[] = {
  1412. { "beginRecording", lpicturerecorder_beginRecording },
  1413. { "getCanvas", lpicturerecorder_getCanvas },
  1414. { "endRecording", lpicturerecorder_endRecording },
  1415. { "__gc", lpicturerecorder_gc },
  1416. { nullptr, nullptr }
  1417. };
  1418. ///////////////////////////////////////////////////////////////////////////////
  1419. static int lpicture_width(lua_State* L) {
  1420. lua_pushnumber(L, get_ref<SkPicture>(L, 1)->cullRect().width());
  1421. return 1;
  1422. }
  1423. static int lpicture_height(lua_State* L) {
  1424. lua_pushnumber(L, get_ref<SkPicture>(L, 1)->cullRect().height());
  1425. return 1;
  1426. }
  1427. static int lpicture_gc(lua_State* L) {
  1428. get_ref<SkPicture>(L, 1)->unref();
  1429. return 0;
  1430. }
  1431. static const struct luaL_Reg gSkPicture_Methods[] = {
  1432. { "width", lpicture_width },
  1433. { "height", lpicture_height },
  1434. { "__gc", lpicture_gc },
  1435. { nullptr, nullptr }
  1436. };
  1437. ///////////////////////////////////////////////////////////////////////////////
  1438. static int ltextblob_bounds(lua_State* L) {
  1439. SkLua(L).pushRect(get_ref<SkTextBlob>(L, 1)->bounds());
  1440. return 1;
  1441. }
  1442. static int ltextblob_gc(lua_State* L) {
  1443. SkSafeUnref(get_ref<SkTextBlob>(L, 1));
  1444. return 0;
  1445. }
  1446. static const struct luaL_Reg gSkTextBlob_Methods[] = {
  1447. { "bounds", ltextblob_bounds },
  1448. { "__gc", ltextblob_gc },
  1449. { nullptr, nullptr }
  1450. };
  1451. ///////////////////////////////////////////////////////////////////////////////
  1452. static int ltypeface_getFamilyName(lua_State* L) {
  1453. SkString str;
  1454. get_ref<SkTypeface>(L, 1)->getFamilyName(&str);
  1455. lua_pushstring(L, str.c_str());
  1456. return 1;
  1457. }
  1458. static int ltypeface_getStyle(lua_State* L) {
  1459. push_obj(L, get_ref<SkTypeface>(L, 1)->fontStyle());
  1460. return 1;
  1461. }
  1462. static int ltypeface_gc(lua_State* L) {
  1463. SkSafeUnref(get_ref<SkTypeface>(L, 1));
  1464. return 0;
  1465. }
  1466. static const struct luaL_Reg gSkTypeface_Methods[] = {
  1467. { "getFamilyName", ltypeface_getFamilyName },
  1468. { "getStyle", ltypeface_getStyle },
  1469. { "__gc", ltypeface_gc },
  1470. { nullptr, nullptr }
  1471. };
  1472. ///////////////////////////////////////////////////////////////////////////////
  1473. static int lfontstyle_weight(lua_State* L) {
  1474. lua_pushnumber(L, get_ref<SkFontStyle>(L, 1)->weight());
  1475. return 1;
  1476. }
  1477. static int lfontstyle_width(lua_State* L) {
  1478. lua_pushnumber(L, get_ref<SkFontStyle>(L, 1)->width());
  1479. return 1;
  1480. }
  1481. static int lfontstyle_slant(lua_State* L) {
  1482. lua_pushnumber(L, get_ref<SkFontStyle>(L, 1)->slant());
  1483. return 1;
  1484. }
  1485. static int lfontstyle_gc(lua_State* L) {
  1486. get_obj<SkFontStyle>(L, 1)->~SkFontStyle();
  1487. return 0;
  1488. }
  1489. static const struct luaL_Reg gSkFontStyle_Methods[] = {
  1490. { "weight", lfontstyle_weight },
  1491. { "width", lfontstyle_width },
  1492. { "slant", lfontstyle_slant },
  1493. { "__gc", lfontstyle_gc },
  1494. { nullptr, nullptr }
  1495. };
  1496. ///////////////////////////////////////////////////////////////////////////////
  1497. class AutoCallLua {
  1498. public:
  1499. AutoCallLua(lua_State* L, const char func[], const char verb[]) : fL(L) {
  1500. lua_getglobal(L, func);
  1501. if (!lua_isfunction(L, -1)) {
  1502. int t = lua_type(L, -1);
  1503. SkDebugf("--- expected function %d\n", t);
  1504. }
  1505. lua_newtable(L);
  1506. setfield_string(L, "verb", verb);
  1507. }
  1508. ~AutoCallLua() {
  1509. if (lua_pcall(fL, 1, 0, 0) != LUA_OK) {
  1510. SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
  1511. }
  1512. lua_settop(fL, -1);
  1513. }
  1514. private:
  1515. lua_State* fL;
  1516. };
  1517. #define AUTO_LUA(verb) AutoCallLua acl(fL, fFunc.c_str(), verb)
  1518. ///////////////////////////////////////////////////////////////////////////////
  1519. static int lsk_newDocumentPDF(lua_State* L) {
  1520. const char* filename = nullptr;
  1521. if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
  1522. filename = lua_tolstring(L, 1, nullptr);
  1523. }
  1524. if (!filename) {
  1525. return 0;
  1526. }
  1527. auto file = skstd::make_unique<SkFILEWStream>(filename);
  1528. if (!file->isValid()) {
  1529. return 0;
  1530. }
  1531. auto doc = SkPDF::MakeDocument(file.get());
  1532. if (!doc) {
  1533. return 0;
  1534. }
  1535. push_ptr(L, new DocHolder{std::move(doc), std::move(file)});
  1536. return 1;
  1537. }
  1538. static int lsk_newBlurImageFilter(lua_State* L) {
  1539. SkScalar sigmaX = lua2scalar_def(L, 1, 0);
  1540. SkScalar sigmaY = lua2scalar_def(L, 2, 0);
  1541. sk_sp<SkImageFilter> imf(SkBlurImageFilter::Make(sigmaX, sigmaY, nullptr));
  1542. if (!imf) {
  1543. lua_pushnil(L);
  1544. } else {
  1545. push_ref(L, std::move(imf));
  1546. }
  1547. return 1;
  1548. }
  1549. static int lsk_newLinearGradient(lua_State* L) {
  1550. SkScalar x0 = lua2scalar_def(L, 1, 0);
  1551. SkScalar y0 = lua2scalar_def(L, 2, 0);
  1552. SkColor c0 = lua2color(L, 3);
  1553. SkScalar x1 = lua2scalar_def(L, 4, 0);
  1554. SkScalar y1 = lua2scalar_def(L, 5, 0);
  1555. SkColor c1 = lua2color(L, 6);
  1556. SkPoint pts[] = { { x0, y0 }, { x1, y1 } };
  1557. SkColor colors[] = { c0, c1 };
  1558. sk_sp<SkShader> s(SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp));
  1559. if (!s) {
  1560. lua_pushnil(L);
  1561. } else {
  1562. push_ref(L, std::move(s));
  1563. }
  1564. return 1;
  1565. }
  1566. static int lsk_newMatrix(lua_State* L) {
  1567. push_new<SkMatrix>(L)->reset();
  1568. return 1;
  1569. }
  1570. static int lsk_newPaint(lua_State* L) {
  1571. push_new<SkPaint>(L);
  1572. return 1;
  1573. }
  1574. static int lsk_newPath(lua_State* L) {
  1575. push_new<SkPath>(L);
  1576. return 1;
  1577. }
  1578. static int lsk_newPictureRecorder(lua_State* L) {
  1579. push_new<SkPictureRecorder>(L);
  1580. return 1;
  1581. }
  1582. static int lsk_newRRect(lua_State* L) {
  1583. push_new<SkRRect>(L)->setEmpty();
  1584. return 1;
  1585. }
  1586. // Sk.newTextBlob(text, rect, paint)
  1587. static int lsk_newTextBlob(lua_State* L) {
  1588. const char* text = lua_tolstring(L, 1, nullptr);
  1589. SkRect bounds;
  1590. lua2rect(L, 2, &bounds);
  1591. std::unique_ptr<SkShaper> shaper = SkShaper::Make();
  1592. // TODO: restore this logic based on SkFont instead of SkPaint
  1593. #if 0
  1594. const SkPaint& paint = *get_obj<SkPaint>(L, 3);
  1595. SkFont font = SkFont::LEGACY_ExtractFromPaint(paint);
  1596. #else
  1597. SkFont font;
  1598. #endif
  1599. SkTextBlobBuilderRunHandler builder(text, { bounds.left(), bounds.top() });
  1600. shaper->shape(text, strlen(text), font, true, bounds.width(), &builder);
  1601. push_ref<SkTextBlob>(L, builder.makeBlob());
  1602. SkLua(L).pushScalar(builder.endPoint().fY);
  1603. return 2;
  1604. }
  1605. static int lsk_newTypeface(lua_State* L) {
  1606. const char* name = nullptr;
  1607. SkFontStyle style;
  1608. int count = lua_gettop(L);
  1609. if (count > 0 && lua_isstring(L, 1)) {
  1610. name = lua_tolstring(L, 1, nullptr);
  1611. if (count > 1) {
  1612. SkFontStyle* passedStyle = get_obj<SkFontStyle>(L, 2);
  1613. if (passedStyle) {
  1614. style = *passedStyle;
  1615. }
  1616. }
  1617. }
  1618. sk_sp<SkTypeface> face(SkTypeface::MakeFromName(name, style));
  1619. // SkDebugf("---- name <%s> style=%d, face=%p ref=%d\n", name, style, face, face->getRefCnt());
  1620. if (nullptr == face) {
  1621. face = SkTypeface::MakeDefault();
  1622. }
  1623. push_ref(L, std::move(face));
  1624. return 1;
  1625. }
  1626. static int lsk_newFontStyle(lua_State* L) {
  1627. int count = lua_gettop(L);
  1628. int weight = SkFontStyle::kNormal_Weight;
  1629. int width = SkFontStyle::kNormal_Width;
  1630. SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant;
  1631. if (count >= 1 && lua_isnumber(L, 1)) {
  1632. weight = lua_tointegerx(L, 1, nullptr);
  1633. }
  1634. if (count >= 2 && lua_isnumber(L, 2)) {
  1635. width = lua_tointegerx(L, 2, nullptr);
  1636. }
  1637. if (count >= 3 && lua_isnumber(L, 3)) {
  1638. slant = static_cast<SkFontStyle::Slant>(lua_tointegerx(L, 3, nullptr));
  1639. }
  1640. push_new<SkFontStyle>(L, weight, width, slant);
  1641. return 1;
  1642. }
  1643. static int lsk_newRasterSurface(lua_State* L) {
  1644. int width = lua2int_def(L, 1, 0);
  1645. int height = lua2int_def(L, 2, 0);
  1646. SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
  1647. SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
  1648. auto surface = SkSurface::MakeRaster(info, &props);
  1649. if (nullptr == surface) {
  1650. lua_pushnil(L);
  1651. } else {
  1652. push_ref(L, surface);
  1653. }
  1654. return 1;
  1655. }
  1656. static int lsk_loadImage(lua_State* L) {
  1657. if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
  1658. const char* name = lua_tolstring(L, 1, nullptr);
  1659. sk_sp<SkData> data(SkData::MakeFromFileName(name));
  1660. if (data) {
  1661. auto image = SkImage::MakeFromEncoded(std::move(data));
  1662. if (image) {
  1663. push_ref(L, std::move(image));
  1664. return 1;
  1665. }
  1666. }
  1667. }
  1668. return 0;
  1669. }
  1670. static void register_Sk(lua_State* L) {
  1671. lua_newtable(L);
  1672. lua_pushvalue(L, -1);
  1673. lua_setglobal(L, "Sk");
  1674. // the Sk table is still on top
  1675. setfield_function(L, "newDocumentPDF", lsk_newDocumentPDF);
  1676. setfield_function(L, "loadImage", lsk_loadImage);
  1677. setfield_function(L, "newBlurImageFilter", lsk_newBlurImageFilter);
  1678. setfield_function(L, "newLinearGradient", lsk_newLinearGradient);
  1679. setfield_function(L, "newMatrix", lsk_newMatrix);
  1680. setfield_function(L, "newPaint", lsk_newPaint);
  1681. setfield_function(L, "newPath", lsk_newPath);
  1682. setfield_function(L, "newPictureRecorder", lsk_newPictureRecorder);
  1683. setfield_function(L, "newRRect", lsk_newRRect);
  1684. setfield_function(L, "newRasterSurface", lsk_newRasterSurface);
  1685. setfield_function(L, "newTextBlob", lsk_newTextBlob);
  1686. setfield_function(L, "newTypeface", lsk_newTypeface);
  1687. setfield_function(L, "newFontStyle", lsk_newFontStyle);
  1688. lua_pop(L, 1); // pop off the Sk table
  1689. }
  1690. #define REG_CLASS(L, C) \
  1691. do { \
  1692. luaL_newmetatable(L, get_mtname<C>()); \
  1693. lua_pushvalue(L, -1); \
  1694. lua_setfield(L, -2, "__index"); \
  1695. luaL_setfuncs(L, g##C##_Methods, 0); \
  1696. lua_pop(L, 1); /* pop off the meta-table */ \
  1697. } while (0)
  1698. void SkLua::Load(lua_State* L) {
  1699. register_Sk(L);
  1700. REG_CLASS(L, SkCanvas);
  1701. REG_CLASS(L, SkColorFilter);
  1702. REG_CLASS(L, DocHolder);
  1703. REG_CLASS(L, SkFont);
  1704. REG_CLASS(L, SkImage);
  1705. REG_CLASS(L, SkImageFilter);
  1706. REG_CLASS(L, SkMatrix);
  1707. REG_CLASS(L, SkPaint);
  1708. REG_CLASS(L, SkPath);
  1709. REG_CLASS(L, SkPathEffect);
  1710. REG_CLASS(L, SkPicture);
  1711. REG_CLASS(L, SkPictureRecorder);
  1712. REG_CLASS(L, SkRRect);
  1713. REG_CLASS(L, SkShader);
  1714. REG_CLASS(L, SkSurface);
  1715. REG_CLASS(L, SkTextBlob);
  1716. REG_CLASS(L, SkTypeface);
  1717. REG_CLASS(L, SkFontStyle);
  1718. }
  1719. extern "C" int luaopen_skia(lua_State* L);
  1720. extern "C" int luaopen_skia(lua_State* L) {
  1721. SkLua::Load(L);
  1722. return 0;
  1723. }