blob: 578166b2e34fc3c79d784f5572c4d4b56c78dc03 [file] [log] [blame]
reed@google.com74ce6f02013-05-22 15:13:18 +00001/*
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 "SkLua.h"
bsalomon@google.com4ebe3822014-02-26 20:22:32 +00009
10#if SK_SUPPORT_GPU
11#include "GrReducedClip.h"
12#endif
13
reed@google.com74ce6f02013-05-22 15:13:18 +000014#include "SkCanvas.h"
mike@reedtribe.org792bbd12013-06-11 02:20:28 +000015#include "SkData.h"
piotaixr4bcc2022014-09-17 14:33:30 -070016#include "SkDecodingImageGenerator.h"
mike@reedtribe.orgfb858242013-06-08 16:39:44 +000017#include "SkDocument.h"
mike@reedtribe.org792bbd12013-06-11 02:20:28 +000018#include "SkImage.h"
19#include "SkMatrix.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000020#include "SkPaint.h"
21#include "SkPath.h"
reed@google.com5fdc9832013-07-24 15:47:52 +000022#include "SkPixelRef.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000023#include "SkRRect.h"
24#include "SkString.h"
reed485557f2014-10-12 10:36:47 -070025#include "SkSurface.h"
fmalitab7425172014-08-26 07:56:44 -070026#include "SkTextBlob.h"
reed@google.come3823fd2013-05-30 18:55:14 +000027#include "SkTypeface.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000028
29extern "C" {
reed@google.com3597b732013-05-22 20:12:50 +000030 #include "lua.h"
31 #include "lualib.h"
32 #include "lauxlib.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000033}
34
reed@google.comfd345872013-05-22 20:53:42 +000035// return the metatable name for a given class
reed@google.com3597b732013-05-22 20:12:50 +000036template <typename T> const char* get_mtname();
reed@google.comfd345872013-05-22 20:53:42 +000037#define DEF_MTNAME(T) \
38 template <> const char* get_mtname<T>() { \
39 return #T "_LuaMetaTableName"; \
40 }
41
42DEF_MTNAME(SkCanvas)
mike@reedtribe.orgfb858242013-06-08 16:39:44 +000043DEF_MTNAME(SkDocument)
mike@reedtribe.org792bbd12013-06-11 02:20:28 +000044DEF_MTNAME(SkImage)
reed@google.comfd345872013-05-22 20:53:42 +000045DEF_MTNAME(SkMatrix)
46DEF_MTNAME(SkRRect)
47DEF_MTNAME(SkPath)
48DEF_MTNAME(SkPaint)
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +000049DEF_MTNAME(SkPathEffect)
reed@google.com5fdc9832013-07-24 15:47:52 +000050DEF_MTNAME(SkShader)
reed485557f2014-10-12 10:36:47 -070051DEF_MTNAME(SkSurface)
fmalitab7425172014-08-26 07:56:44 -070052DEF_MTNAME(SkTextBlob)
mike@reedtribe.orge6469f12013-06-08 03:15:47 +000053DEF_MTNAME(SkTypeface)
reed@google.com74ce6f02013-05-22 15:13:18 +000054
reed@google.com3597b732013-05-22 20:12:50 +000055template <typename T> T* push_new(lua_State* L) {
56 T* addr = (T*)lua_newuserdata(L, sizeof(T));
57 new (addr) T;
58 luaL_getmetatable(L, get_mtname<T>());
59 lua_setmetatable(L, -2);
60 return addr;
61}
reed@google.com74ce6f02013-05-22 15:13:18 +000062
63template <typename T> void push_obj(lua_State* L, const T& obj) {
64 new (lua_newuserdata(L, sizeof(T))) T(obj);
reed@google.com3597b732013-05-22 20:12:50 +000065 luaL_getmetatable(L, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +000066 lua_setmetatable(L, -2);
67}
68
69template <typename T> void push_ref(lua_State* L, T* ref) {
commit-bot@chromium.org77887af2013-12-17 14:28:19 +000070 *(T**)lua_newuserdata(L, sizeof(T*)) = SkSafeRef(ref);
reed@google.com3597b732013-05-22 20:12:50 +000071 luaL_getmetatable(L, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +000072 lua_setmetatable(L, -2);
73}
74
75template <typename T> T* get_ref(lua_State* L, int index) {
reed@google.com3597b732013-05-22 20:12:50 +000076 return *(T**)luaL_checkudata(L, index, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +000077}
78
79template <typename T> T* get_obj(lua_State* L, int index) {
reed@google.com3597b732013-05-22 20:12:50 +000080 return (T*)luaL_checkudata(L, index, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +000081}
82
reed@google.com88c9ec92013-05-22 15:43:21 +000083static bool lua2bool(lua_State* L, int index) {
84 return !!lua_toboolean(L, index);
85}
86
reed@google.com74ce6f02013-05-22 15:13:18 +000087///////////////////////////////////////////////////////////////////////////////
88
reed@google.com3597b732013-05-22 20:12:50 +000089SkLua::SkLua(const char termCode[]) : fTermCode(termCode), fWeOwnL(true) {
90 fL = luaL_newstate();
91 luaL_openlibs(fL);
92 SkLua::Load(fL);
93}
94
95SkLua::SkLua(lua_State* L) : fL(L), fWeOwnL(false) {}
96
97SkLua::~SkLua() {
98 if (fWeOwnL) {
99 if (fTermCode.size() > 0) {
100 lua_getglobal(fL, fTermCode.c_str());
101 if (lua_pcall(fL, 0, 0, 0) != LUA_OK) {
102 SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
103 }
104 }
105 lua_close(fL);
106 }
107}
108
109bool SkLua::runCode(const char code[]) {
110 int err = luaL_loadstring(fL, code) || lua_pcall(fL, 0, 0, 0);
111 if (err) {
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000112 SkDebugf("--- lua failed: %s\n", lua_tostring(fL, -1));
reed@google.com3597b732013-05-22 20:12:50 +0000113 return false;
114 }
115 return true;
116}
117
118bool SkLua::runCode(const void* code, size_t size) {
119 SkString str((const char*)code, size);
120 return this->runCode(str.c_str());
121}
122
123///////////////////////////////////////////////////////////////////////////////
124
125#define CHECK_SETFIELD(key) do if (key) lua_setfield(fL, -2, key); while (0)
126
reed@google.com29563872013-07-10 21:23:49 +0000127static void setfield_bool_if(lua_State* L, const char key[], bool pred) {
128 if (pred) {
129 lua_pushboolean(L, true);
130 lua_setfield(L, -2, key);
131 }
132}
133
reed@google.com74ce6f02013-05-22 15:13:18 +0000134static void setfield_string(lua_State* L, const char key[], const char value[]) {
135 lua_pushstring(L, value);
136 lua_setfield(L, -2, key);
137}
138
139static void setfield_number(lua_State* L, const char key[], double value) {
140 lua_pushnumber(L, value);
141 lua_setfield(L, -2, key);
142}
143
humper@google.com2815c192013-07-10 22:42:30 +0000144static void setfield_boolean(lua_State* L, const char key[], bool value) {
145 lua_pushboolean(L, value);
146 lua_setfield(L, -2, key);
147}
148
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000149static void setfield_scalar(lua_State* L, const char key[], SkScalar value) {
150 setfield_number(L, key, SkScalarToLua(value));
151}
152
reed@google.com3597b732013-05-22 20:12:50 +0000153static void setfield_function(lua_State* L,
154 const char key[], lua_CFunction value) {
155 lua_pushcfunction(L, value);
156 lua_setfield(L, -2, key);
reed@google.com74ce6f02013-05-22 15:13:18 +0000157}
158
reed@google.come3823fd2013-05-30 18:55:14 +0000159static void setarray_number(lua_State* L, int index, double value) {
160 lua_pushnumber(L, value);
161 lua_rawseti(L, -2, index);
162}
163
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +0000164static void setarray_scalar(lua_State* L, int index, SkScalar value) {
165 setarray_number(L, index, SkScalarToLua(value));
166}
167
reed@google.com74ce6f02013-05-22 15:13:18 +0000168void SkLua::pushBool(bool value, const char key[]) {
169 lua_pushboolean(fL, value);
170 CHECK_SETFIELD(key);
171}
172
173void SkLua::pushString(const char str[], const char key[]) {
174 lua_pushstring(fL, str);
175 CHECK_SETFIELD(key);
176}
177
reed@google.come3823fd2013-05-30 18:55:14 +0000178void SkLua::pushString(const char str[], size_t length, const char key[]) {
179 // TODO: how to do this w/o making a copy?
180 SkString s(str, length);
181 lua_pushstring(fL, s.c_str());
182 CHECK_SETFIELD(key);
183}
184
reed@google.com74ce6f02013-05-22 15:13:18 +0000185void SkLua::pushString(const SkString& str, const char key[]) {
186 lua_pushstring(fL, str.c_str());
187 CHECK_SETFIELD(key);
188}
189
190void SkLua::pushColor(SkColor color, const char key[]) {
191 lua_newtable(fL);
192 setfield_number(fL, "a", SkColorGetA(color) / 255.0);
193 setfield_number(fL, "r", SkColorGetR(color) / 255.0);
194 setfield_number(fL, "g", SkColorGetG(color) / 255.0);
195 setfield_number(fL, "b", SkColorGetB(color) / 255.0);
196 CHECK_SETFIELD(key);
197}
198
reed@google.come3823fd2013-05-30 18:55:14 +0000199void SkLua::pushU32(uint32_t value, const char key[]) {
200 lua_pushnumber(fL, (double)value);
201 CHECK_SETFIELD(key);
202}
203
reed@google.com74ce6f02013-05-22 15:13:18 +0000204void SkLua::pushScalar(SkScalar value, const char key[]) {
205 lua_pushnumber(fL, SkScalarToLua(value));
206 CHECK_SETFIELD(key);
207}
208
reed@google.come3823fd2013-05-30 18:55:14 +0000209void SkLua::pushArrayU16(const uint16_t array[], int count, const char key[]) {
210 lua_newtable(fL);
211 for (int i = 0; i < count; ++i) {
212 // make it base-1 to match lua convention
213 setarray_number(fL, i + 1, (double)array[i]);
214 }
215 CHECK_SETFIELD(key);
216}
217
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +0000218void SkLua::pushArrayPoint(const SkPoint array[], int count, const char key[]) {
219 lua_newtable(fL);
220 for (int i = 0; i < count; ++i) {
221 // make it base-1 to match lua convention
222 lua_newtable(fL);
223 this->pushScalar(array[i].fX, "x");
224 this->pushScalar(array[i].fY, "y");
225 lua_rawseti(fL, -2, i + 1);
226 }
227 CHECK_SETFIELD(key);
228}
229
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +0000230void SkLua::pushArrayScalar(const SkScalar array[], int count, const char key[]) {
231 lua_newtable(fL);
232 for (int i = 0; i < count; ++i) {
233 // make it base-1 to match lua convention
234 setarray_scalar(fL, i + 1, array[i]);
235 }
236 CHECK_SETFIELD(key);
237}
238
reed@google.com74ce6f02013-05-22 15:13:18 +0000239void SkLua::pushRect(const SkRect& r, const char key[]) {
240 lua_newtable(fL);
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000241 setfield_scalar(fL, "left", r.fLeft);
242 setfield_scalar(fL, "top", r.fTop);
243 setfield_scalar(fL, "right", r.fRight);
244 setfield_scalar(fL, "bottom", r.fBottom);
reed@google.com74ce6f02013-05-22 15:13:18 +0000245 CHECK_SETFIELD(key);
246}
247
248void SkLua::pushRRect(const SkRRect& rr, const char key[]) {
249 push_obj(fL, rr);
250 CHECK_SETFIELD(key);
251}
252
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +0000253void SkLua::pushDash(const SkPathEffect::DashInfo& info, const char key[]) {
254 lua_newtable(fL);
255 setfield_scalar(fL, "phase", info.fPhase);
256 this->pushArrayScalar(info.fIntervals, info.fCount, "intervals");
257 CHECK_SETFIELD(key);
258}
259
260
reed@google.com74ce6f02013-05-22 15:13:18 +0000261void SkLua::pushMatrix(const SkMatrix& matrix, const char key[]) {
262 push_obj(fL, matrix);
263 CHECK_SETFIELD(key);
264}
265
266void SkLua::pushPaint(const SkPaint& paint, const char key[]) {
267 push_obj(fL, paint);
268 CHECK_SETFIELD(key);
269}
270
271void SkLua::pushPath(const SkPath& path, const char key[]) {
272 push_obj(fL, path);
273 CHECK_SETFIELD(key);
274}
275
276void SkLua::pushCanvas(SkCanvas* canvas, const char key[]) {
277 push_ref(fL, canvas);
278 CHECK_SETFIELD(key);
279}
280
fmalitab7425172014-08-26 07:56:44 -0700281void SkLua::pushTextBlob(const SkTextBlob* blob, const char key[]) {
282 push_ref(fL, const_cast<SkTextBlob*>(blob));
283 CHECK_SETFIELD(key);
284}
285
commit-bot@chromium.org5cc25352014-02-24 18:59:48 +0000286static const char* element_type(SkClipStack::Element::Type type) {
287 switch (type) {
288 case SkClipStack::Element::kEmpty_Type:
289 return "empty";
290 case SkClipStack::Element::kRect_Type:
291 return "rect";
292 case SkClipStack::Element::kRRect_Type:
293 return "rrect";
294 case SkClipStack::Element::kPath_Type:
295 return "path";
296 }
297 return "unknown";
298}
299
300static const char* region_op(SkRegion::Op op) {
301 switch (op) {
302 case SkRegion::kDifference_Op:
303 return "difference";
304 case SkRegion::kIntersect_Op:
305 return "intersect";
306 case SkRegion::kUnion_Op:
307 return "union";
308 case SkRegion::kXOR_Op:
309 return "xor";
310 case SkRegion::kReverseDifference_Op:
311 return "reverse-difference";
312 case SkRegion::kReplace_Op:
313 return "replace";
314 }
315 return "unknown";
316}
317
318void SkLua::pushClipStack(const SkClipStack& stack, const char* key) {
319 lua_newtable(fL);
320 SkClipStack::B2TIter iter(stack);
321 const SkClipStack::Element* element;
322 int i = 0;
bsalomon49f085d2014-09-05 13:34:00 -0700323 while ((element = iter.next())) {
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000324 this->pushClipStackElement(*element);
commit-bot@chromium.org5cc25352014-02-24 18:59:48 +0000325 lua_rawseti(fL, -2, ++i);
326 }
327 CHECK_SETFIELD(key);
328}
329
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000330void SkLua::pushClipStackElement(const SkClipStack::Element& element, const char* key) {
331 lua_newtable(fL);
332 SkClipStack::Element::Type type = element.getType();
333 this->pushString(element_type(type), "type");
334 switch (type) {
335 case SkClipStack::Element::kEmpty_Type:
336 break;
337 case SkClipStack::Element::kRect_Type:
338 this->pushRect(element.getRect(), "rect");
339 break;
340 case SkClipStack::Element::kRRect_Type:
341 this->pushRRect(element.getRRect(), "rrect");
342 break;
343 case SkClipStack::Element::kPath_Type:
344 this->pushPath(element.getPath(), "path");
345 break;
346 }
347 this->pushString(region_op(element.getOp()), "op");
348 this->pushBool(element.isAA(), "aa");
349 CHECK_SETFIELD(key);
350}
351
352
reed@google.com74ce6f02013-05-22 15:13:18 +0000353///////////////////////////////////////////////////////////////////////////////
354///////////////////////////////////////////////////////////////////////////////
355
reed485557f2014-10-12 10:36:47 -0700356static int lua2int_def(lua_State* L, int index, int defaultValue) {
357 if (lua_isnumber(L, index)) {
358 return (int)lua_tonumber(L, index);
359 } else {
360 return defaultValue;
361 }
362}
363
reed@google.com74ce6f02013-05-22 15:13:18 +0000364static SkScalar lua2scalar(lua_State* L, int index) {
365 SkASSERT(lua_isnumber(L, index));
366 return SkLuaToScalar(lua_tonumber(L, index));
367}
368
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000369static SkScalar lua2scalar_def(lua_State* L, int index, SkScalar defaultValue) {
370 if (lua_isnumber(L, index)) {
371 return SkLuaToScalar(lua_tonumber(L, index));
372 } else {
373 return defaultValue;
374 }
375}
376
reed@google.com74ce6f02013-05-22 15:13:18 +0000377static SkScalar getfield_scalar(lua_State* L, int index, const char key[]) {
378 SkASSERT(lua_istable(L, index));
379 lua_pushstring(L, key);
380 lua_gettable(L, index);
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000381
reed@google.com74ce6f02013-05-22 15:13:18 +0000382 SkScalar value = lua2scalar(L, -1);
383 lua_pop(L, 1);
384 return value;
385}
386
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000387static SkScalar getfield_scalar_default(lua_State* L, int index, const char key[], SkScalar def) {
388 SkASSERT(lua_istable(L, index));
389 lua_pushstring(L, key);
390 lua_gettable(L, index);
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000391
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000392 SkScalar value;
393 if (lua_isnil(L, -1)) {
394 value = def;
395 } else {
396 value = lua2scalar(L, -1);
397 }
398 lua_pop(L, 1);
399 return value;
400}
401
reed@google.com74ce6f02013-05-22 15:13:18 +0000402static U8CPU unit2byte(SkScalar x) {
403 if (x <= 0) {
404 return 0;
405 } else if (x >= 1) {
406 return 255;
407 } else {
408 return SkScalarRoundToInt(x * 255);
409 }
410}
411
412static SkColor lua2color(lua_State* L, int index) {
reed485557f2014-10-12 10:36:47 -0700413 return SkColorSetARGB(unit2byte(getfield_scalar_default(L, index, "a", 1)),
414 unit2byte(getfield_scalar_default(L, index, "r", 0)),
415 unit2byte(getfield_scalar_default(L, index, "g", 0)),
416 unit2byte(getfield_scalar_default(L, index, "b", 0)));
reed@google.com74ce6f02013-05-22 15:13:18 +0000417}
418
419static SkRect* lua2rect(lua_State* L, int index, SkRect* rect) {
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000420 rect->set(getfield_scalar_default(L, index, "left", 0),
421 getfield_scalar_default(L, index, "top", 0),
reed@google.com74ce6f02013-05-22 15:13:18 +0000422 getfield_scalar(L, index, "right"),
423 getfield_scalar(L, index, "bottom"));
424 return rect;
425}
426
427static int lcanvas_drawColor(lua_State* L) {
428 get_ref<SkCanvas>(L, 1)->drawColor(lua2color(L, 2));
429 return 0;
430}
431
432static int lcanvas_drawRect(lua_State* L) {
433 SkRect rect;
434 get_ref<SkCanvas>(L, 1)->drawRect(*lua2rect(L, 2, &rect),
435 *get_obj<SkPaint>(L, 3));
436 return 0;
437}
438
439static int lcanvas_drawOval(lua_State* L) {
440 SkRect rect;
441 get_ref<SkCanvas>(L, 1)->drawOval(*lua2rect(L, 2, &rect),
442 *get_obj<SkPaint>(L, 3));
443 return 0;
444}
445
446static int lcanvas_drawCircle(lua_State* L) {
447 get_ref<SkCanvas>(L, 1)->drawCircle(lua2scalar(L, 2),
448 lua2scalar(L, 3),
449 lua2scalar(L, 4),
450 *get_obj<SkPaint>(L, 5));
451 return 0;
452}
453
reed485557f2014-10-12 10:36:47 -0700454static SkPaint* lua2OptionalPaint(lua_State* L, int index, SkPaint* paint) {
455 if (lua_isnumber(L, index)) {
456 paint->setAlpha(SkScalarRoundToInt(lua2scalar(L, index) * 255));
457 return paint;
458 } else {
459 const SkPaint* ptr = get_obj<SkPaint>(L, index);
460 if (ptr) {
461 *paint = *ptr;
462 return paint;
463 }
464 }
465 return NULL;
466}
467
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000468static int lcanvas_drawImage(lua_State* L) {
469 SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
470 SkImage* image = get_ref<SkImage>(L, 2);
471 if (NULL == image) {
472 return 0;
473 }
474 SkScalar x = lua2scalar(L, 3);
475 SkScalar y = lua2scalar(L, 4);
476
477 SkPaint paint;
reed485557f2014-10-12 10:36:47 -0700478 canvas->drawImage(image, x, y, lua2OptionalPaint(L, 5, &paint));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000479 return 0;
480}
481
reedba5fb932014-10-10 15:28:19 -0700482static int lcanvas_drawImageRect(lua_State* L) {
483 SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
484 SkImage* image = get_ref<SkImage>(L, 2);
485 if (NULL == image) {
486 return 0;
487 }
488
489 SkRect srcR, dstR;
490 SkRect* srcRPtr = NULL;
491 if (!lua_isnil(L, 3)) {
492 srcRPtr = lua2rect(L, 3, &srcR);
493 }
494 lua2rect(L, 4, &dstR);
495
496 SkPaint paint;
reed485557f2014-10-12 10:36:47 -0700497 canvas->drawImageRect(image, srcRPtr, dstR, lua2OptionalPaint(L, 5, &paint));
reedba5fb932014-10-10 15:28:19 -0700498 return 0;
499}
500
reed@google.comfd345872013-05-22 20:53:42 +0000501static int lcanvas_drawPath(lua_State* L) {
502 get_ref<SkCanvas>(L, 1)->drawPath(*get_obj<SkPath>(L, 2),
503 *get_obj<SkPaint>(L, 3));
504 return 0;
505}
506
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000507static int lcanvas_drawText(lua_State* L) {
508 if (lua_gettop(L) < 5) {
509 return 0;
510 }
511
512 if (lua_isstring(L, 2) && lua_isnumber(L, 3) && lua_isnumber(L, 4)) {
513 size_t len;
514 const char* text = lua_tolstring(L, 2, &len);
515 get_ref<SkCanvas>(L, 1)->drawText(text, len,
516 lua2scalar(L, 3), lua2scalar(L, 4),
517 *get_obj<SkPaint>(L, 5));
518 }
519 return 0;
520}
521
reed@google.com74ce6f02013-05-22 15:13:18 +0000522static int lcanvas_getSaveCount(lua_State* L) {
523 lua_pushnumber(L, get_ref<SkCanvas>(L, 1)->getSaveCount());
524 return 1;
525}
526
527static int lcanvas_getTotalMatrix(lua_State* L) {
528 SkLua(L).pushMatrix(get_ref<SkCanvas>(L, 1)->getTotalMatrix());
529 return 1;
530}
531
commit-bot@chromium.org5cc25352014-02-24 18:59:48 +0000532static int lcanvas_getClipStack(lua_State* L) {
533 SkLua(L).pushClipStack(*get_ref<SkCanvas>(L, 1)->getClipStack());
534 return 1;
535}
536
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000537int SkLua::lcanvas_getReducedClipStack(lua_State* L) {
538#if SK_SUPPORT_GPU
539 const SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
540 SkISize layerSize = canvas->getTopLayerSize();
541 SkIPoint layerOrigin = canvas->getTopLayerOrigin();
542 SkIRect queryBounds = SkIRect::MakeXYWH(layerOrigin.fX, layerOrigin.fY,
543 layerSize.fWidth, layerSize.fHeight);
544
545 GrReducedClip::ElementList elements;
546 GrReducedClip::InitialState initialState;
547 int32_t genID;
548 SkIRect resultBounds;
549
550 const SkClipStack& stack = *canvas->getClipStack();
551
552 GrReducedClip::ReduceClipStack(stack,
553 queryBounds,
554 &elements,
555 &genID,
556 &initialState,
557 &resultBounds,
558 NULL);
559
560 GrReducedClip::ElementList::Iter iter(elements);
561 int i = 0;
562 lua_newtable(L);
bsalomon49f085d2014-09-05 13:34:00 -0700563 while(iter.get()) {
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000564 SkLua(L).pushClipStackElement(*iter.get());
565 iter.next();
566 lua_rawseti(L, -2, ++i);
567 }
568 // Currently this only returns the element list to lua, not the initial state or result bounds.
569 // It could return these as additional items on the lua stack.
570 return 1;
571#else
572 return 0;
573#endif
574}
575
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000576static int lcanvas_save(lua_State* L) {
577 lua_pushinteger(L, get_ref<SkCanvas>(L, 1)->save());
578 return 1;
579}
580
581static int lcanvas_restore(lua_State* L) {
582 get_ref<SkCanvas>(L, 1)->restore();
583 return 0;
584}
585
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000586static int lcanvas_scale(lua_State* L) {
587 SkScalar sx = lua2scalar_def(L, 2, 1);
588 SkScalar sy = lua2scalar_def(L, 3, sx);
589 get_ref<SkCanvas>(L, 1)->scale(sx, sy);
590 return 0;
591}
592
reed@google.com3597b732013-05-22 20:12:50 +0000593static int lcanvas_translate(lua_State* L) {
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000594 SkScalar tx = lua2scalar_def(L, 2, 0);
595 SkScalar ty = lua2scalar_def(L, 3, 0);
596 get_ref<SkCanvas>(L, 1)->translate(tx, ty);
597 return 0;
598}
599
600static int lcanvas_rotate(lua_State* L) {
601 SkScalar degrees = lua2scalar_def(L, 2, 0);
602 get_ref<SkCanvas>(L, 1)->rotate(degrees);
reed@google.com3597b732013-05-22 20:12:50 +0000603 return 0;
604}
605
reed485557f2014-10-12 10:36:47 -0700606static int lcanvas_newSurface(lua_State* L) {
607 int width = lua2int_def(L, 2, 0);
608 int height = lua2int_def(L, 2, 0);
609 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
610 SkSurface* surface = get_ref<SkCanvas>(L, 1)->newSurface(info);
611 if (NULL == surface) {
612 lua_pushnil(L);
613 } else {
614 push_ref(L, surface);
615 surface->unref();
616 }
617 return 1;
618}
619
reed@google.com74ce6f02013-05-22 15:13:18 +0000620static int lcanvas_gc(lua_State* L) {
621 get_ref<SkCanvas>(L, 1)->unref();
622 return 0;
623}
624
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000625const struct luaL_Reg gSkCanvas_Methods[] = {
reed@google.com74ce6f02013-05-22 15:13:18 +0000626 { "drawColor", lcanvas_drawColor },
627 { "drawRect", lcanvas_drawRect },
628 { "drawOval", lcanvas_drawOval },
629 { "drawCircle", lcanvas_drawCircle },
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000630 { "drawImage", lcanvas_drawImage },
reedba5fb932014-10-10 15:28:19 -0700631 { "drawImageRect", lcanvas_drawImageRect },
reed@google.comfd345872013-05-22 20:53:42 +0000632 { "drawPath", lcanvas_drawPath },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000633 { "drawText", lcanvas_drawText },
reed@google.com74ce6f02013-05-22 15:13:18 +0000634 { "getSaveCount", lcanvas_getSaveCount },
635 { "getTotalMatrix", lcanvas_getTotalMatrix },
commit-bot@chromium.org5cc25352014-02-24 18:59:48 +0000636 { "getClipStack", lcanvas_getClipStack },
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000637#if SK_SUPPORT_GPU
638 { "getReducedClipStack", SkLua::lcanvas_getReducedClipStack },
639#endif
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000640 { "save", lcanvas_save },
641 { "restore", lcanvas_restore },
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000642 { "scale", lcanvas_scale },
reed@google.com3597b732013-05-22 20:12:50 +0000643 { "translate", lcanvas_translate },
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000644 { "rotate", lcanvas_rotate },
reed485557f2014-10-12 10:36:47 -0700645
646 { "newSurface", lcanvas_newSurface },
647
reed@google.com74ce6f02013-05-22 15:13:18 +0000648 { "__gc", lcanvas_gc },
649 { NULL, NULL }
650};
651
652///////////////////////////////////////////////////////////////////////////////
653
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000654static int ldocument_beginPage(lua_State* L) {
655 const SkRect* contentPtr = NULL;
656 push_ref(L, get_ref<SkDocument>(L, 1)->beginPage(lua2scalar(L, 2),
657 lua2scalar(L, 3),
658 contentPtr));
659 return 1;
660}
661
662static int ldocument_endPage(lua_State* L) {
663 get_ref<SkDocument>(L, 1)->endPage();
664 return 0;
665}
666
667static int ldocument_close(lua_State* L) {
668 get_ref<SkDocument>(L, 1)->close();
669 return 0;
670}
671
672static int ldocument_gc(lua_State* L) {
673 get_ref<SkDocument>(L, 1)->unref();
674 return 0;
675}
676
677static const struct luaL_Reg gSkDocument_Methods[] = {
678 { "beginPage", ldocument_beginPage },
679 { "endPage", ldocument_endPage },
680 { "close", ldocument_close },
681 { "__gc", ldocument_gc },
682 { NULL, NULL }
683};
684
685///////////////////////////////////////////////////////////////////////////////
686
reed@google.com74ce6f02013-05-22 15:13:18 +0000687static int lpaint_isAntiAlias(lua_State* L) {
688 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isAntiAlias());
689 return 1;
690}
691
692static int lpaint_setAntiAlias(lua_State* L) {
reed@google.com88c9ec92013-05-22 15:43:21 +0000693 get_obj<SkPaint>(L, 1)->setAntiAlias(lua2bool(L, 2));
reed@google.com74ce6f02013-05-22 15:13:18 +0000694 return 0;
695}
696
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000697static int lpaint_isDither(lua_State* L) {
698 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isDither());
699 return 1;
700}
701
702static int lpaint_isUnderlineText(lua_State* L) {
703 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isUnderlineText());
704 return 1;
705}
706
707static int lpaint_isStrikeThruText(lua_State* L) {
708 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isStrikeThruText());
709 return 1;
710}
711
712static int lpaint_isFakeBoldText(lua_State* L) {
713 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isFakeBoldText());
714 return 1;
715}
716
717static int lpaint_isLinearText(lua_State* L) {
718 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isLinearText());
719 return 1;
720}
721
722static int lpaint_isSubpixelText(lua_State* L) {
723 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isSubpixelText());
724 return 1;
725}
726
reed09a1d672014-10-11 13:13:11 -0700727static int lpaint_setSubpixelText(lua_State* L) {
728 get_obj<SkPaint>(L, 1)->setSubpixelText(lua2bool(L, 2));
729 return 1;
730}
731
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000732static int lpaint_isDevKernText(lua_State* L) {
733 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isDevKernText());
734 return 1;
735}
736
737static int lpaint_isLCDRenderText(lua_State* L) {
738 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isLCDRenderText());
739 return 1;
740}
741
742static int lpaint_isEmbeddedBitmapText(lua_State* L) {
743 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isEmbeddedBitmapText());
744 return 1;
745}
746
747static int lpaint_isAutohinted(lua_State* L) {
748 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isAutohinted());
749 return 1;
750}
751
752static int lpaint_isVerticalText(lua_State* L) {
753 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isVerticalText());
754 return 1;
755}
756
reed@google.com74ce6f02013-05-22 15:13:18 +0000757static int lpaint_getColor(lua_State* L) {
758 SkLua(L).pushColor(get_obj<SkPaint>(L, 1)->getColor());
759 return 1;
760}
761
762static int lpaint_setColor(lua_State* L) {
763 get_obj<SkPaint>(L, 1)->setColor(lua2color(L, 2));
764 return 0;
765}
766
reed@google.come3823fd2013-05-30 18:55:14 +0000767static int lpaint_getTextSize(lua_State* L) {
768 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getTextSize());
769 return 1;
770}
771
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000772static int lpaint_getTextScaleX(lua_State* L) {
773 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getTextScaleX());
774 return 1;
775}
776
777static int lpaint_getTextSkewX(lua_State* L) {
778 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getTextSkewX());
779 return 1;
780}
781
reed@google.come3823fd2013-05-30 18:55:14 +0000782static int lpaint_setTextSize(lua_State* L) {
783 get_obj<SkPaint>(L, 1)->setTextSize(lua2scalar(L, 2));
784 return 0;
785}
786
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000787static int lpaint_getTypeface(lua_State* L) {
788 push_ref(L, get_obj<SkPaint>(L, 1)->getTypeface());
789 return 1;
790}
791
792static int lpaint_setTypeface(lua_State* L) {
793 get_obj<SkPaint>(L, 1)->setTypeface(get_ref<SkTypeface>(L, 2));
794 return 0;
795}
796
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000797static int lpaint_getHinting(lua_State* L) {
798 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getHinting());
799 return 1;
800}
801
reed@google.come3823fd2013-05-30 18:55:14 +0000802static int lpaint_getFontID(lua_State* L) {
803 SkTypeface* face = get_obj<SkPaint>(L, 1)->getTypeface();
804 SkLua(L).pushU32(SkTypeface::UniqueID(face));
805 return 1;
806}
807
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000808static const struct {
809 const char* fLabel;
810 SkPaint::Align fAlign;
811} gAlignRec[] = {
812 { "left", SkPaint::kLeft_Align },
813 { "center", SkPaint::kCenter_Align },
814 { "right", SkPaint::kRight_Align },
815};
816
817static int lpaint_getTextAlign(lua_State* L) {
818 SkPaint::Align align = get_obj<SkPaint>(L, 1)->getTextAlign();
819 for (size_t i = 0; i < SK_ARRAY_COUNT(gAlignRec); ++i) {
820 if (gAlignRec[i].fAlign == align) {
821 lua_pushstring(L, gAlignRec[i].fLabel);
822 return 1;
823 }
824 }
825 return 0;
826}
827
828static int lpaint_setTextAlign(lua_State* L) {
829 if (lua_isstring(L, 2)) {
830 size_t len;
831 const char* label = lua_tolstring(L, 2, &len);
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000832
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000833 for (size_t i = 0; i < SK_ARRAY_COUNT(gAlignRec); ++i) {
834 if (!strcmp(gAlignRec[i].fLabel, label)) {
835 get_obj<SkPaint>(L, 1)->setTextAlign(gAlignRec[i].fAlign);
836 break;
837 }
838 }
839 }
840 return 0;
841}
842
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000843static int lpaint_getStroke(lua_State* L) {
844 lua_pushboolean(L, SkPaint::kStroke_Style == get_obj<SkPaint>(L, 1)->getStyle());
845 return 1;
846}
847
848static int lpaint_setStroke(lua_State* L) {
849 SkPaint::Style style;
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000850
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000851 if (lua_toboolean(L, 2)) {
852 style = SkPaint::kStroke_Style;
853 } else {
854 style = SkPaint::kFill_Style;
855 }
856 get_obj<SkPaint>(L, 1)->setStyle(style);
857 return 0;
858}
859
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000860static int lpaint_getStrokeCap(lua_State* L) {
861 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeCap());
862 return 1;
863}
864
865static int lpaint_getStrokeJoin(lua_State* L) {
866 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeJoin());
867 return 1;
868}
869
870static int lpaint_getTextEncoding(lua_State* L) {
commit-bot@chromium.org641bcc32013-12-19 10:39:59 +0000871 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getTextEncoding());
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000872 return 1;
873}
874
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000875static int lpaint_getStrokeWidth(lua_State* L) {
876 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeWidth());
877 return 1;
878}
879
880static int lpaint_setStrokeWidth(lua_State* L) {
881 get_obj<SkPaint>(L, 1)->setStrokeWidth(lua2scalar(L, 2));
882 return 0;
883}
884
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000885static int lpaint_getStrokeMiter(lua_State* L) {
886 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeMiter());
887 return 1;
888}
889
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000890static int lpaint_measureText(lua_State* L) {
891 if (lua_isstring(L, 2)) {
892 size_t len;
893 const char* text = lua_tolstring(L, 2, &len);
894 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->measureText(text, len));
895 return 1;
896 }
897 return 0;
898}
899
900struct FontMetrics {
901 SkScalar fTop; //!< The greatest distance above the baseline for any glyph (will be <= 0)
902 SkScalar fAscent; //!< The recommended distance above the baseline (will be <= 0)
903 SkScalar fDescent; //!< The recommended distance below the baseline (will be >= 0)
904 SkScalar fBottom; //!< The greatest distance below the baseline for any glyph (will be >= 0)
905 SkScalar fLeading; //!< The recommended distance to add between lines of text (will be >= 0)
906 SkScalar fAvgCharWidth; //!< the average charactor width (>= 0)
907 SkScalar fXMin; //!< The minimum bounding box x value for all glyphs
908 SkScalar fXMax; //!< The maximum bounding box x value for all glyphs
909 SkScalar fXHeight; //!< the height of an 'x' in px, or 0 if no 'x' in face
910};
911
912static int lpaint_getFontMetrics(lua_State* L) {
913 SkPaint::FontMetrics fm;
914 SkScalar height = get_obj<SkPaint>(L, 1)->getFontMetrics(&fm);
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000915
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000916 lua_newtable(L);
917 setfield_scalar(L, "top", fm.fTop);
918 setfield_scalar(L, "ascent", fm.fAscent);
919 setfield_scalar(L, "descent", fm.fDescent);
920 setfield_scalar(L, "bottom", fm.fBottom);
921 setfield_scalar(L, "leading", fm.fLeading);
922 SkLua(L).pushScalar(height);
923 return 2;
924}
925
reed@google.com29563872013-07-10 21:23:49 +0000926static int lpaint_getEffects(lua_State* L) {
927 const SkPaint* paint = get_obj<SkPaint>(L, 1);
skia.committer@gmail.comde2e4e82013-07-11 07:01:01 +0000928
reed@google.com29563872013-07-10 21:23:49 +0000929 lua_newtable(L);
930 setfield_bool_if(L, "looper", !!paint->getLooper());
931 setfield_bool_if(L, "pathEffect", !!paint->getPathEffect());
932 setfield_bool_if(L, "rasterizer", !!paint->getRasterizer());
933 setfield_bool_if(L, "maskFilter", !!paint->getMaskFilter());
934 setfield_bool_if(L, "shader", !!paint->getShader());
935 setfield_bool_if(L, "colorFilter", !!paint->getColorFilter());
936 setfield_bool_if(L, "imageFilter", !!paint->getImageFilter());
937 setfield_bool_if(L, "xfermode", !!paint->getXfermode());
938 return 1;
939}
940
reed@google.com5fdc9832013-07-24 15:47:52 +0000941static int lpaint_getShader(lua_State* L) {
942 const SkPaint* paint = get_obj<SkPaint>(L, 1);
943 SkShader* shader = paint->getShader();
944 if (shader) {
945 push_ref(L, shader);
946 return 1;
947 }
948 return 0;
949}
950
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +0000951static int lpaint_getPathEffect(lua_State* L) {
952 const SkPaint* paint = get_obj<SkPaint>(L, 1);
953 SkPathEffect* pe = paint->getPathEffect();
954 if (pe) {
955 push_ref(L, pe);
956 return 1;
957 }
958 return 0;
959}
960
reed@google.com74ce6f02013-05-22 15:13:18 +0000961static int lpaint_gc(lua_State* L) {
962 get_obj<SkPaint>(L, 1)->~SkPaint();
963 return 0;
964}
965
966static const struct luaL_Reg gSkPaint_Methods[] = {
967 { "isAntiAlias", lpaint_isAntiAlias },
968 { "setAntiAlias", lpaint_setAntiAlias },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000969 { "isDither", lpaint_isDither },
970 { "isUnderlineText", lpaint_isUnderlineText },
971 { "isStrikeThruText", lpaint_isStrikeThruText },
972 { "isFakeBoldText", lpaint_isFakeBoldText },
973 { "isLinearText", lpaint_isLinearText },
974 { "isSubpixelText", lpaint_isSubpixelText },
reed09a1d672014-10-11 13:13:11 -0700975 { "setSubpixelText", lpaint_setSubpixelText },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000976 { "isDevKernText", lpaint_isDevKernText },
977 { "isLCDRenderText", lpaint_isLCDRenderText },
978 { "isEmbeddedBitmapText", lpaint_isEmbeddedBitmapText },
979 { "isAutohinted", lpaint_isAutohinted },
980 { "isVerticalText", lpaint_isVerticalText },
reed@google.com74ce6f02013-05-22 15:13:18 +0000981 { "getColor", lpaint_getColor },
982 { "setColor", lpaint_setColor },
reed@google.come3823fd2013-05-30 18:55:14 +0000983 { "getTextSize", lpaint_getTextSize },
984 { "setTextSize", lpaint_setTextSize },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000985 { "getTextScaleX", lpaint_getTextScaleX },
986 { "getTextSkewX", lpaint_getTextSkewX },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000987 { "getTypeface", lpaint_getTypeface },
988 { "setTypeface", lpaint_setTypeface },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000989 { "getHinting", lpaint_getHinting },
reed@google.come3823fd2013-05-30 18:55:14 +0000990 { "getFontID", lpaint_getFontID },
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000991 { "getTextAlign", lpaint_getTextAlign },
992 { "setTextAlign", lpaint_setTextAlign },
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000993 { "getStroke", lpaint_getStroke },
994 { "setStroke", lpaint_setStroke },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000995 { "getStrokeCap", lpaint_getStrokeCap },
996 { "getStrokeJoin", lpaint_getStrokeJoin },
997 { "getTextEncoding", lpaint_getTextEncoding },
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000998 { "getStrokeWidth", lpaint_getStrokeWidth },
999 { "setStrokeWidth", lpaint_setStrokeWidth },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001000 { "getStrokeMiter", lpaint_getStrokeMiter },
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +00001001 { "measureText", lpaint_measureText },
1002 { "getFontMetrics", lpaint_getFontMetrics },
reed@google.com29563872013-07-10 21:23:49 +00001003 { "getEffects", lpaint_getEffects },
reed@google.com5fdc9832013-07-24 15:47:52 +00001004 { "getShader", lpaint_getShader },
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001005 { "getPathEffect", lpaint_getPathEffect },
reed@google.com74ce6f02013-05-22 15:13:18 +00001006 { "__gc", lpaint_gc },
1007 { NULL, NULL }
1008};
1009
1010///////////////////////////////////////////////////////////////////////////////
1011
reed@google.com5fdc9832013-07-24 15:47:52 +00001012static const char* mode2string(SkShader::TileMode mode) {
1013 static const char* gNames[] = { "clamp", "repeat", "mirror" };
1014 SkASSERT((unsigned)mode < SK_ARRAY_COUNT(gNames));
1015 return gNames[mode];
1016}
1017
1018static const char* gradtype2string(SkShader::GradientType t) {
1019 static const char* gNames[] = {
1020 "none", "color", "linear", "radial", "radial2", "sweep", "conical"
1021 };
1022 SkASSERT((unsigned)t < SK_ARRAY_COUNT(gNames));
1023 return gNames[t];
1024}
1025
1026static int lshader_isOpaque(lua_State* L) {
1027 SkShader* shader = get_ref<SkShader>(L, 1);
1028 return shader && shader->isOpaque();
1029}
1030
1031static int lshader_asABitmap(lua_State* L) {
1032 SkShader* shader = get_ref<SkShader>(L, 1);
1033 if (shader) {
1034 SkBitmap bm;
1035 SkMatrix matrix;
1036 SkShader::TileMode modes[2];
1037 switch (shader->asABitmap(&bm, &matrix, modes)) {
1038 case SkShader::kDefault_BitmapType:
1039 lua_newtable(L);
1040 setfield_number(L, "genID", bm.pixelRef() ? bm.pixelRef()->getGenerationID() : 0);
1041 setfield_number(L, "width", bm.width());
1042 setfield_number(L, "height", bm.height());
1043 setfield_string(L, "tileX", mode2string(modes[0]));
1044 setfield_string(L, "tileY", mode2string(modes[1]));
1045 return 1;
1046 default:
1047 break;
1048 }
1049 }
1050 return 0;
1051}
1052
1053static int lshader_asAGradient(lua_State* L) {
1054 SkShader* shader = get_ref<SkShader>(L, 1);
1055 if (shader) {
1056 SkShader::GradientInfo info;
1057 sk_bzero(&info, sizeof(info));
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001058
1059 SkColor colors[3]; // hacked in for extracting info on 3 color case.
skia.committer@gmail.combd74add2013-08-02 07:00:59 +00001060 SkScalar pos[3];
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001061
1062 info.fColorCount = 3;
1063 info.fColors = &colors[0];
1064 info.fColorOffsets = &pos[0];
skia.committer@gmail.combd74add2013-08-02 07:00:59 +00001065
reed@google.com5fdc9832013-07-24 15:47:52 +00001066 SkShader::GradientType t = shader->asAGradient(&info);
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001067
reed@google.com5fdc9832013-07-24 15:47:52 +00001068 if (SkShader::kNone_GradientType != t) {
1069 lua_newtable(L);
1070 setfield_string(L, "type", gradtype2string(t));
1071 setfield_number(L, "colorCount", info.fColorCount);
1072 setfield_string(L, "tile", mode2string(info.fTileMode));
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001073
1074 if (info.fColorCount == 3){
1075 setfield_number(L, "midPos", pos[1]);
1076 }
skia.committer@gmail.combd74add2013-08-02 07:00:59 +00001077
reed@google.com5fdc9832013-07-24 15:47:52 +00001078 return 1;
1079 }
1080 }
1081 return 0;
1082}
1083
1084static int lshader_gc(lua_State* L) {
1085 get_ref<SkShader>(L, 1)->unref();
1086 return 0;
1087}
1088
1089static const struct luaL_Reg gSkShader_Methods[] = {
1090 { "isOpaque", lshader_isOpaque },
1091 { "asABitmap", lshader_asABitmap },
1092 { "asAGradient", lshader_asAGradient },
1093 { "__gc", lshader_gc },
1094 { NULL, NULL }
1095};
1096
1097///////////////////////////////////////////////////////////////////////////////
1098
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +00001099static int lpatheffect_asADash(lua_State* L) {
1100 SkPathEffect* pe = get_ref<SkPathEffect>(L, 1);
1101 if (pe) {
1102 SkPathEffect::DashInfo info;
1103 SkPathEffect::DashType dashType = pe->asADash(&info);
1104 if (SkPathEffect::kDash_DashType == dashType) {
1105 SkAutoTArray<SkScalar> intervals(info.fCount);
1106 info.fIntervals = intervals.get();
1107 pe->asADash(&info);
1108 SkLua(L).pushDash(info);
1109 return 1;
1110 }
1111 }
1112 return 0;
1113}
1114
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001115static int lpatheffect_gc(lua_State* L) {
1116 get_ref<SkPathEffect>(L, 1)->unref();
1117 return 0;
1118}
1119
1120static const struct luaL_Reg gSkPathEffect_Methods[] = {
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +00001121 { "asADash", lpatheffect_asADash },
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001122 { "__gc", lpatheffect_gc },
1123 { NULL, NULL }
1124};
1125
1126///////////////////////////////////////////////////////////////////////////////
1127
humper@google.com2815c192013-07-10 22:42:30 +00001128static int lmatrix_getType(lua_State* L) {
1129 SkMatrix::TypeMask mask = get_obj<SkMatrix>(L, 1)->getType();
skia.committer@gmail.comde2e4e82013-07-11 07:01:01 +00001130
humper@google.com2815c192013-07-10 22:42:30 +00001131 lua_newtable(L);
1132 setfield_boolean(L, "translate", SkToBool(mask & SkMatrix::kTranslate_Mask));
1133 setfield_boolean(L, "scale", SkToBool(mask & SkMatrix::kScale_Mask));
1134 setfield_boolean(L, "affine", SkToBool(mask & SkMatrix::kAffine_Mask));
1135 setfield_boolean(L, "perspective", SkToBool(mask & SkMatrix::kPerspective_Mask));
1136 return 1;
1137}
1138
humper@google.com0f48ee02013-07-26 15:23:43 +00001139static int lmatrix_getScaleX(lua_State* L) {
1140 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getScaleX());
1141 return 1;
1142}
1143
1144static int lmatrix_getScaleY(lua_State* L) {
1145 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getScaleY());
1146 return 1;
1147}
1148
1149static int lmatrix_getTranslateX(lua_State* L) {
1150 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getTranslateX());
1151 return 1;
1152}
1153
1154static int lmatrix_getTranslateY(lua_State* L) {
1155 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getTranslateY());
1156 return 1;
1157}
1158
humper@google.com2815c192013-07-10 22:42:30 +00001159static const struct luaL_Reg gSkMatrix_Methods[] = {
1160 { "getType", lmatrix_getType },
humper@google.com0f48ee02013-07-26 15:23:43 +00001161 { "getScaleX", lmatrix_getScaleX },
1162 { "getScaleY", lmatrix_getScaleY },
1163 { "getTranslateX", lmatrix_getTranslateX },
1164 { "getTranslateY", lmatrix_getTranslateY },
humper@google.com2815c192013-07-10 22:42:30 +00001165 { NULL, NULL }
1166};
1167
1168///////////////////////////////////////////////////////////////////////////////
1169
reed@google.com74ce6f02013-05-22 15:13:18 +00001170static int lpath_getBounds(lua_State* L) {
1171 SkLua(L).pushRect(get_obj<SkPath>(L, 1)->getBounds());
1172 return 1;
1173}
1174
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001175static const char* fill_type_to_str(SkPath::FillType fill) {
1176 switch (fill) {
1177 case SkPath::kEvenOdd_FillType:
1178 return "even-odd";
1179 case SkPath::kWinding_FillType:
1180 return "winding";
1181 case SkPath::kInverseEvenOdd_FillType:
1182 return "inverse-even-odd";
1183 case SkPath::kInverseWinding_FillType:
1184 return "inverse-winding";
1185 }
1186 return "unknown";
1187}
1188
1189static int lpath_getFillType(lua_State* L) {
1190 SkPath::FillType fill = get_obj<SkPath>(L, 1)->getFillType();
1191 SkLua(L).pushString(fill_type_to_str(fill));
1192 return 1;
1193}
1194
1195static SkString segment_masks_to_str(uint32_t segmentMasks) {
1196 SkString result;
1197 bool first = true;
1198 if (SkPath::kLine_SegmentMask & segmentMasks) {
1199 result.append("line");
1200 first = false;
1201 SkDEBUGCODE(segmentMasks &= ~SkPath::kLine_SegmentMask;)
1202 }
1203 if (SkPath::kQuad_SegmentMask & segmentMasks) {
1204 if (!first) {
1205 result.append(" ");
1206 }
1207 result.append("quad");
1208 first = false;
1209 SkDEBUGCODE(segmentMasks &= ~SkPath::kQuad_SegmentMask;)
1210 }
1211 if (SkPath::kConic_SegmentMask & segmentMasks) {
1212 if (!first) {
1213 result.append(" ");
1214 }
1215 result.append("conic");
1216 first = false;
1217 SkDEBUGCODE(segmentMasks &= ~SkPath::kConic_SegmentMask;)
1218 }
1219 if (SkPath::kCubic_SegmentMask & segmentMasks) {
1220 if (!first) {
1221 result.append(" ");
1222 }
1223 result.append("cubic");
1224 SkDEBUGCODE(segmentMasks &= ~SkPath::kCubic_SegmentMask;)
1225 }
1226 SkASSERT(0 == segmentMasks);
1227 return result;
1228}
1229
krajcevski95498ed2014-08-18 08:02:33 -07001230static int lpath_getSegmentTypes(lua_State* L) {
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001231 uint32_t segMasks = get_obj<SkPath>(L, 1)->getSegmentMasks();
1232 SkLua(L).pushString(segment_masks_to_str(segMasks));
1233 return 1;
1234}
1235
1236static int lpath_isConvex(lua_State* L) {
1237 bool isConvex = SkPath::kConvex_Convexity == get_obj<SkPath>(L, 1)->getConvexity();
1238 SkLua(L).pushBool(isConvex);
1239 return 1;
1240}
1241
reed@google.com74ce6f02013-05-22 15:13:18 +00001242static int lpath_isEmpty(lua_State* L) {
1243 lua_pushboolean(L, get_obj<SkPath>(L, 1)->isEmpty());
1244 return 1;
1245}
1246
1247static int lpath_isRect(lua_State* L) {
1248 SkRect r;
1249 bool pred = get_obj<SkPath>(L, 1)->isRect(&r);
1250 int ret_count = 1;
1251 lua_pushboolean(L, pred);
1252 if (pred) {
1253 SkLua(L).pushRect(r);
1254 ret_count += 1;
1255 }
1256 return ret_count;
1257}
1258
1259static const char* dir2string(SkPath::Direction dir) {
1260 static const char* gStr[] = {
1261 "unknown", "cw", "ccw"
1262 };
1263 SkASSERT((unsigned)dir < SK_ARRAY_COUNT(gStr));
1264 return gStr[dir];
1265}
1266
1267static int lpath_isNestedRects(lua_State* L) {
1268 SkRect rects[2];
1269 SkPath::Direction dirs[2];
1270 bool pred = get_obj<SkPath>(L, 1)->isNestedRects(rects, dirs);
1271 int ret_count = 1;
1272 lua_pushboolean(L, pred);
1273 if (pred) {
1274 SkLua lua(L);
1275 lua.pushRect(rects[0]);
1276 lua.pushRect(rects[1]);
1277 lua_pushstring(L, dir2string(dirs[0]));
1278 lua_pushstring(L, dir2string(dirs[0]));
1279 ret_count += 4;
1280 }
1281 return ret_count;
1282}
1283
commit-bot@chromium.orgc5302082014-02-26 21:38:47 +00001284static int lpath_countPoints(lua_State* L) {
1285 lua_pushinteger(L, get_obj<SkPath>(L, 1)->countPoints());
1286 return 1;
1287}
1288
reed@google.com74ce6f02013-05-22 15:13:18 +00001289static int lpath_reset(lua_State* L) {
1290 get_obj<SkPath>(L, 1)->reset();
1291 return 0;
1292}
1293
1294static int lpath_moveTo(lua_State* L) {
1295 get_obj<SkPath>(L, 1)->moveTo(lua2scalar(L, 2), lua2scalar(L, 3));
1296 return 0;
1297}
1298
1299static int lpath_lineTo(lua_State* L) {
1300 get_obj<SkPath>(L, 1)->lineTo(lua2scalar(L, 2), lua2scalar(L, 3));
1301 return 0;
1302}
1303
1304static int lpath_quadTo(lua_State* L) {
1305 get_obj<SkPath>(L, 1)->quadTo(lua2scalar(L, 2), lua2scalar(L, 3),
1306 lua2scalar(L, 4), lua2scalar(L, 5));
1307 return 0;
1308}
1309
1310static int lpath_cubicTo(lua_State* L) {
1311 get_obj<SkPath>(L, 1)->cubicTo(lua2scalar(L, 2), lua2scalar(L, 3),
1312 lua2scalar(L, 4), lua2scalar(L, 5),
1313 lua2scalar(L, 6), lua2scalar(L, 7));
1314 return 0;
1315}
1316
1317static int lpath_close(lua_State* L) {
1318 get_obj<SkPath>(L, 1)->close();
1319 return 0;
1320}
1321
1322static int lpath_gc(lua_State* L) {
1323 get_obj<SkPath>(L, 1)->~SkPath();
1324 return 0;
1325}
1326
1327static const struct luaL_Reg gSkPath_Methods[] = {
1328 { "getBounds", lpath_getBounds },
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001329 { "getFillType", lpath_getFillType },
krajcevski95498ed2014-08-18 08:02:33 -07001330 { "getSegmentTypes", lpath_getSegmentTypes },
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001331 { "isConvex", lpath_isConvex },
reed@google.com74ce6f02013-05-22 15:13:18 +00001332 { "isEmpty", lpath_isEmpty },
1333 { "isRect", lpath_isRect },
1334 { "isNestedRects", lpath_isNestedRects },
commit-bot@chromium.orgc5302082014-02-26 21:38:47 +00001335 { "countPoints", lpath_countPoints },
reed@google.com74ce6f02013-05-22 15:13:18 +00001336 { "reset", lpath_reset },
1337 { "moveTo", lpath_moveTo },
1338 { "lineTo", lpath_lineTo },
1339 { "quadTo", lpath_quadTo },
1340 { "cubicTo", lpath_cubicTo },
1341 { "close", lpath_close },
1342 { "__gc", lpath_gc },
1343 { NULL, NULL }
1344};
1345
1346///////////////////////////////////////////////////////////////////////////////
1347
1348static const char* rrect_type(const SkRRect& rr) {
1349 switch (rr.getType()) {
1350 case SkRRect::kUnknown_Type: return "unknown";
1351 case SkRRect::kEmpty_Type: return "empty";
1352 case SkRRect::kRect_Type: return "rect";
1353 case SkRRect::kOval_Type: return "oval";
1354 case SkRRect::kSimple_Type: return "simple";
commit-bot@chromium.orgf338d7c2014-03-17 21:17:30 +00001355 case SkRRect::kNinePatch_Type: return "nine-patch";
reed@google.com74ce6f02013-05-22 15:13:18 +00001356 case SkRRect::kComplex_Type: return "complex";
1357 }
mtklein@google.com330313a2013-08-22 15:37:26 +00001358 SkDEBUGFAIL("never get here");
reed@google.com74ce6f02013-05-22 15:13:18 +00001359 return "";
1360}
1361
1362static int lrrect_rect(lua_State* L) {
1363 SkLua(L).pushRect(get_obj<SkRRect>(L, 1)->rect());
1364 return 1;
1365}
1366
1367static int lrrect_type(lua_State* L) {
1368 lua_pushstring(L, rrect_type(*get_obj<SkRRect>(L, 1)));
1369 return 1;
1370}
1371
1372static int lrrect_radii(lua_State* L) {
reed@google.com7fa2a652014-01-27 13:42:58 +00001373 int corner = SkToInt(lua_tointeger(L, 2));
reed@google.com74ce6f02013-05-22 15:13:18 +00001374 SkVector v;
1375 if (corner < 0 || corner > 3) {
1376 SkDebugf("bad corner index %d", corner);
1377 v.set(0, 0);
1378 } else {
1379 v = get_obj<SkRRect>(L, 1)->radii((SkRRect::Corner)corner);
1380 }
1381 lua_pushnumber(L, v.fX);
1382 lua_pushnumber(L, v.fY);
1383 return 2;
1384}
1385
1386static int lrrect_gc(lua_State* L) {
1387 get_obj<SkRRect>(L, 1)->~SkRRect();
1388 return 0;
1389}
1390
1391static const struct luaL_Reg gSkRRect_Methods[] = {
1392 { "rect", lrrect_rect },
1393 { "type", lrrect_type },
1394 { "radii", lrrect_radii },
1395 { "__gc", lrrect_gc },
1396 { NULL, NULL }
1397};
1398
1399///////////////////////////////////////////////////////////////////////////////
1400
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001401static int limage_width(lua_State* L) {
1402 lua_pushinteger(L, get_ref<SkImage>(L, 1)->width());
1403 return 1;
1404}
1405
1406static int limage_height(lua_State* L) {
1407 lua_pushinteger(L, get_ref<SkImage>(L, 1)->height());
1408 return 1;
1409}
1410
1411static int limage_gc(lua_State* L) {
1412 get_ref<SkImage>(L, 1)->unref();
1413 return 0;
1414}
1415
1416static const struct luaL_Reg gSkImage_Methods[] = {
1417 { "width", limage_width },
1418 { "height", limage_height },
1419 { "__gc", limage_gc },
1420 { NULL, NULL }
1421};
1422
1423///////////////////////////////////////////////////////////////////////////////
1424
reed485557f2014-10-12 10:36:47 -07001425static int lsurface_width(lua_State* L) {
1426 lua_pushinteger(L, get_ref<SkSurface>(L, 1)->width());
1427 return 1;
1428}
1429
1430static int lsurface_height(lua_State* L) {
1431 lua_pushinteger(L, get_ref<SkSurface>(L, 1)->height());
1432 return 1;
1433}
1434
1435static int lsurface_getCanvas(lua_State* L) {
1436 SkCanvas* canvas = get_ref<SkSurface>(L, 1)->getCanvas();
1437 if (NULL == canvas) {
1438 lua_pushnil(L);
1439 } else {
1440 push_ref(L, canvas);
1441 // note: we don't unref canvas, since getCanvas did not ref it.
1442 // warning: this is weird: now Lua owns a ref on this canvas, but what if they let
1443 // the real owner (the surface) go away, but still hold onto the canvas?
1444 // *really* we want to sort of ref the surface again, but have the native object
1445 // know that it is supposed to be treated as a canvas...
1446 }
1447 return 1;
1448}
1449
1450static int lsurface_newImageSnapshot(lua_State* L) {
1451 SkImage* image = get_ref<SkSurface>(L, 1)->newImageSnapshot();
1452 if (NULL == image) {
1453 lua_pushnil(L);
1454 } else {
1455 push_ref(L, image);
1456 image->unref();
1457 }
1458 return 1;
1459}
1460
1461static int lsurface_newSurface(lua_State* L) {
1462 int width = lua2int_def(L, 2, 0);
1463 int height = lua2int_def(L, 2, 0);
1464 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
1465 SkSurface* surface = get_ref<SkSurface>(L, 1)->newSurface(info);
1466 if (NULL == surface) {
1467 lua_pushnil(L);
1468 } else {
1469 push_ref(L, surface);
1470 surface->unref();
1471 }
1472 return 1;
1473}
1474
1475static int lsurface_gc(lua_State* L) {
1476 get_ref<SkSurface>(L, 1)->unref();
1477 return 0;
1478}
1479
1480static const struct luaL_Reg gSkSurface_Methods[] = {
1481 { "width", lsurface_width },
1482 { "height", lsurface_height },
1483 { "getCanvas", lsurface_getCanvas },
1484 { "newImageSnapshot", lsurface_newImageSnapshot },
1485 { "newSurface", lsurface_newSurface },
1486 { "__gc", lsurface_gc },
1487 { NULL, NULL }
1488};
1489
1490///////////////////////////////////////////////////////////////////////////////
1491
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001492static int ltypeface_gc(lua_State* L) {
commit-bot@chromium.org77887af2013-12-17 14:28:19 +00001493 SkSafeUnref(get_ref<SkTypeface>(L, 1));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001494 return 0;
1495}
1496
1497static const struct luaL_Reg gSkTypeface_Methods[] = {
1498 { "__gc", ltypeface_gc },
1499 { NULL, NULL }
1500};
1501
1502///////////////////////////////////////////////////////////////////////////////
1503
reed@google.com74ce6f02013-05-22 15:13:18 +00001504class AutoCallLua {
1505public:
1506 AutoCallLua(lua_State* L, const char func[], const char verb[]) : fL(L) {
1507 lua_getglobal(L, func);
1508 if (!lua_isfunction(L, -1)) {
1509 int t = lua_type(L, -1);
1510 SkDebugf("--- expected function %d\n", t);
1511 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001512
reed@google.com74ce6f02013-05-22 15:13:18 +00001513 lua_newtable(L);
1514 setfield_string(L, "verb", verb);
1515 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001516
reed@google.com74ce6f02013-05-22 15:13:18 +00001517 ~AutoCallLua() {
1518 if (lua_pcall(fL, 1, 0, 0) != LUA_OK) {
1519 SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
1520 }
1521 lua_settop(fL, -1);
1522 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001523
reed@google.com74ce6f02013-05-22 15:13:18 +00001524private:
1525 lua_State* fL;
1526};
1527
1528#define AUTO_LUA(verb) AutoCallLua acl(fL, fFunc.c_str(), verb)
1529
1530///////////////////////////////////////////////////////////////////////////////
1531
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001532static int lsk_newDocumentPDF(lua_State* L) {
1533 const char* file = NULL;
1534 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
1535 file = lua_tolstring(L, 1, NULL);
1536 }
1537
1538 SkDocument* doc = SkDocument::CreatePDF(file);
1539 if (NULL == doc) {
1540 // do I need to push a nil on the stack and return 1?
1541 return 0;
1542 } else {
1543 push_ref(L, doc);
1544 doc->unref();
1545 return 1;
1546 }
1547}
1548
reed@google.com3597b732013-05-22 20:12:50 +00001549static int lsk_newPaint(lua_State* L) {
1550 push_new<SkPaint>(L);
1551 return 1;
1552}
1553
1554static int lsk_newPath(lua_State* L) {
1555 push_new<SkPath>(L);
1556 return 1;
1557}
1558
1559static int lsk_newRRect(lua_State* L) {
1560 SkRRect* rr = push_new<SkRRect>(L);
1561 rr->setEmpty();
1562 return 1;
1563}
1564
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001565static int lsk_newTypeface(lua_State* L) {
1566 const char* name = NULL;
1567 int style = SkTypeface::kNormal;
skia.committer@gmail.com63193672013-06-08 07:01:13 +00001568
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001569 int count = lua_gettop(L);
1570 if (count > 0 && lua_isstring(L, 1)) {
1571 name = lua_tolstring(L, 1, NULL);
1572 if (count > 1 && lua_isnumber(L, 2)) {
1573 style = lua_tointegerx(L, 2, NULL) & SkTypeface::kBoldItalic;
1574 }
1575 }
1576
1577 SkTypeface* face = SkTypeface::CreateFromName(name,
1578 (SkTypeface::Style)style);
1579// SkDebugf("---- name <%s> style=%d, face=%p ref=%d\n", name, style, face, face->getRefCnt());
1580 if (NULL == face) {
1581 face = SkTypeface::RefDefault();
1582 }
1583 push_ref(L, face);
1584 face->unref();
1585 return 1;
1586}
reed@google.com3597b732013-05-22 20:12:50 +00001587
reed485557f2014-10-12 10:36:47 -07001588static int lsk_newRasterSurface(lua_State* L) {
1589 int width = lua2int_def(L, 2, 0);
1590 int height = lua2int_def(L, 2, 0);
1591 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
1592 SkSurface* surface = SkSurface::NewRaster(info);
1593 if (NULL == surface) {
1594 lua_pushnil(L);
1595 } else {
1596 push_ref(L, surface);
1597 surface->unref();
1598 }
1599 return 1;
1600}
1601
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001602static int lsk_loadImage(lua_State* L) {
1603 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
1604 const char* name = lua_tolstring(L, 1, NULL);
1605 SkAutoDataUnref data(SkData::NewFromFileName(name));
1606 if (data.get()) {
piotaixr4bcc2022014-09-17 14:33:30 -07001607 SkImage* image = SkImage::NewFromGenerator(
1608 SkDecodingImageGenerator::Create(data, SkDecodingImageGenerator::Options()));
1609
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001610 if (image) {
1611 push_ref(L, image);
1612 image->unref();
1613 return 1;
1614 }
1615 }
1616 }
1617 return 0;
1618}
1619
reed@google.com3597b732013-05-22 20:12:50 +00001620static void register_Sk(lua_State* L) {
1621 lua_newtable(L);
1622 lua_pushvalue(L, -1);
1623 lua_setglobal(L, "Sk");
1624 // the Sk table is still on top
1625
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001626 setfield_function(L, "newDocumentPDF", lsk_newDocumentPDF);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001627 setfield_function(L, "loadImage", lsk_loadImage);
reed@google.com3597b732013-05-22 20:12:50 +00001628 setfield_function(L, "newPaint", lsk_newPaint);
1629 setfield_function(L, "newPath", lsk_newPath);
1630 setfield_function(L, "newRRect", lsk_newRRect);
reed485557f2014-10-12 10:36:47 -07001631 setfield_function(L, "newRasterSurface", lsk_newRasterSurface);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001632 setfield_function(L, "newTypeface", lsk_newTypeface);
reed@google.com3597b732013-05-22 20:12:50 +00001633 lua_pop(L, 1); // pop off the Sk table
1634}
1635
reed@google.com74ce6f02013-05-22 15:13:18 +00001636#define REG_CLASS(L, C) \
1637 do { \
reed@google.com3597b732013-05-22 20:12:50 +00001638 luaL_newmetatable(L, get_mtname<C>()); \
reed@google.com74ce6f02013-05-22 15:13:18 +00001639 lua_pushvalue(L, -1); \
1640 lua_setfield(L, -2, "__index"); \
1641 luaL_setfuncs(L, g##C##_Methods, 0); \
1642 lua_pop(L, 1); /* pop off the meta-table */ \
1643 } while (0)
1644
1645void SkLua::Load(lua_State* L) {
reed@google.com3597b732013-05-22 20:12:50 +00001646 register_Sk(L);
reed@google.com74ce6f02013-05-22 15:13:18 +00001647 REG_CLASS(L, SkCanvas);
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001648 REG_CLASS(L, SkDocument);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001649 REG_CLASS(L, SkImage);
reed@google.com74ce6f02013-05-22 15:13:18 +00001650 REG_CLASS(L, SkPaint);
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001651 REG_CLASS(L, SkPath);
1652 REG_CLASS(L, SkPathEffect);
reed@google.com74ce6f02013-05-22 15:13:18 +00001653 REG_CLASS(L, SkRRect);
reed@google.com5fdc9832013-07-24 15:47:52 +00001654 REG_CLASS(L, SkShader);
reed485557f2014-10-12 10:36:47 -07001655 REG_CLASS(L, SkSurface);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001656 REG_CLASS(L, SkTypeface);
humper@google.com2815c192013-07-10 22:42:30 +00001657 REG_CLASS(L, SkMatrix);
reed@google.com74ce6f02013-05-22 15:13:18 +00001658}
zachr@google.com28c27c82013-06-20 17:15:05 +00001659
reed@google.com7bce9982013-06-20 17:40:21 +00001660extern "C" int luaopen_skia(lua_State* L);
zachr@google.com28c27c82013-06-20 17:15:05 +00001661extern "C" int luaopen_skia(lua_State* L) {
1662 SkLua::Load(L);
1663 return 0;
1664}