blob: d85fb91a033a4164046f934e7b6e1f2dbb8232eb [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
reed468b1812014-10-19 11:42:54 -070014#include "SkBlurImageFilter.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000015#include "SkCanvas.h"
reed22a517f2015-12-04 20:45:59 -080016#include "SkColorFilter.h"
mike@reedtribe.org792bbd12013-06-11 02:20:28 +000017#include "SkData.h"
mike@reedtribe.orgfb858242013-06-08 16:39:44 +000018#include "SkDocument.h"
reed9fbc3f32014-10-21 07:12:58 -070019#include "SkGradientShader.h"
mike@reedtribe.org792bbd12013-06-11 02:20:28 +000020#include "SkImage.h"
21#include "SkMatrix.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000022#include "SkPaint.h"
23#include "SkPath.h"
reed96affcd2014-10-13 12:38:04 -070024#include "SkPictureRecorder.h"
reed@google.com5fdc9832013-07-24 15:47:52 +000025#include "SkPixelRef.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000026#include "SkRRect.h"
27#include "SkString.h"
reed485557f2014-10-12 10:36:47 -070028#include "SkSurface.h"
fmalitab7425172014-08-26 07:56:44 -070029#include "SkTextBlob.h"
reed@google.come3823fd2013-05-30 18:55:14 +000030#include "SkTypeface.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000031
32extern "C" {
reed@google.com3597b732013-05-22 20:12:50 +000033 #include "lua.h"
34 #include "lualib.h"
35 #include "lauxlib.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000036}
37
reed@google.comfd345872013-05-22 20:53:42 +000038// return the metatable name for a given class
reed@google.com3597b732013-05-22 20:12:50 +000039template <typename T> const char* get_mtname();
reed@google.comfd345872013-05-22 20:53:42 +000040#define DEF_MTNAME(T) \
41 template <> const char* get_mtname<T>() { \
42 return #T "_LuaMetaTableName"; \
43 }
44
45DEF_MTNAME(SkCanvas)
reed22a517f2015-12-04 20:45:59 -080046DEF_MTNAME(SkColorFilter)
mike@reedtribe.orgfb858242013-06-08 16:39:44 +000047DEF_MTNAME(SkDocument)
mike@reedtribe.org792bbd12013-06-11 02:20:28 +000048DEF_MTNAME(SkImage)
reed468b1812014-10-19 11:42:54 -070049DEF_MTNAME(SkImageFilter)
reed@google.comfd345872013-05-22 20:53:42 +000050DEF_MTNAME(SkMatrix)
51DEF_MTNAME(SkRRect)
52DEF_MTNAME(SkPath)
53DEF_MTNAME(SkPaint)
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +000054DEF_MTNAME(SkPathEffect)
reed96affcd2014-10-13 12:38:04 -070055DEF_MTNAME(SkPicture)
56DEF_MTNAME(SkPictureRecorder)
reed@google.com5fdc9832013-07-24 15:47:52 +000057DEF_MTNAME(SkShader)
reed485557f2014-10-12 10:36:47 -070058DEF_MTNAME(SkSurface)
fmalitab7425172014-08-26 07:56:44 -070059DEF_MTNAME(SkTextBlob)
mike@reedtribe.orge6469f12013-06-08 03:15:47 +000060DEF_MTNAME(SkTypeface)
reed@google.com74ce6f02013-05-22 15:13:18 +000061
reed@google.com3597b732013-05-22 20:12:50 +000062template <typename T> T* push_new(lua_State* L) {
63 T* addr = (T*)lua_newuserdata(L, sizeof(T));
64 new (addr) T;
65 luaL_getmetatable(L, get_mtname<T>());
66 lua_setmetatable(L, -2);
67 return addr;
68}
reed@google.com74ce6f02013-05-22 15:13:18 +000069
70template <typename T> void push_obj(lua_State* L, const T& obj) {
71 new (lua_newuserdata(L, sizeof(T))) T(obj);
reed@google.com3597b732013-05-22 20:12:50 +000072 luaL_getmetatable(L, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +000073 lua_setmetatable(L, -2);
74}
75
reed9fbc3f32014-10-21 07:12:58 -070076template <typename T> T* push_ref(lua_State* L, T* ref) {
commit-bot@chromium.org77887af2013-12-17 14:28:19 +000077 *(T**)lua_newuserdata(L, sizeof(T*)) = SkSafeRef(ref);
reed@google.com3597b732013-05-22 20:12:50 +000078 luaL_getmetatable(L, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +000079 lua_setmetatable(L, -2);
reed9fbc3f32014-10-21 07:12:58 -070080 return ref;
reed@google.com74ce6f02013-05-22 15:13:18 +000081}
82
83template <typename T> T* get_ref(lua_State* L, int index) {
reed@google.com3597b732013-05-22 20:12:50 +000084 return *(T**)luaL_checkudata(L, index, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +000085}
86
87template <typename T> T* get_obj(lua_State* L, int index) {
reed@google.com3597b732013-05-22 20:12:50 +000088 return (T*)luaL_checkudata(L, index, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +000089}
90
reed@google.com88c9ec92013-05-22 15:43:21 +000091static bool lua2bool(lua_State* L, int index) {
92 return !!lua_toboolean(L, index);
93}
94
reed@google.com74ce6f02013-05-22 15:13:18 +000095///////////////////////////////////////////////////////////////////////////////
96
reed@google.com3597b732013-05-22 20:12:50 +000097SkLua::SkLua(const char termCode[]) : fTermCode(termCode), fWeOwnL(true) {
98 fL = luaL_newstate();
99 luaL_openlibs(fL);
100 SkLua::Load(fL);
101}
102
103SkLua::SkLua(lua_State* L) : fL(L), fWeOwnL(false) {}
104
105SkLua::~SkLua() {
106 if (fWeOwnL) {
107 if (fTermCode.size() > 0) {
108 lua_getglobal(fL, fTermCode.c_str());
109 if (lua_pcall(fL, 0, 0, 0) != LUA_OK) {
110 SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
111 }
112 }
113 lua_close(fL);
114 }
115}
116
117bool SkLua::runCode(const char code[]) {
118 int err = luaL_loadstring(fL, code) || lua_pcall(fL, 0, 0, 0);
119 if (err) {
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000120 SkDebugf("--- lua failed: %s\n", lua_tostring(fL, -1));
reed@google.com3597b732013-05-22 20:12:50 +0000121 return false;
122 }
123 return true;
124}
125
126bool SkLua::runCode(const void* code, size_t size) {
127 SkString str((const char*)code, size);
128 return this->runCode(str.c_str());
129}
130
131///////////////////////////////////////////////////////////////////////////////
132
133#define CHECK_SETFIELD(key) do if (key) lua_setfield(fL, -2, key); while (0)
134
reed@google.com29563872013-07-10 21:23:49 +0000135static void setfield_bool_if(lua_State* L, const char key[], bool pred) {
136 if (pred) {
137 lua_pushboolean(L, true);
138 lua_setfield(L, -2, key);
139 }
140}
141
reed@google.com74ce6f02013-05-22 15:13:18 +0000142static void setfield_string(lua_State* L, const char key[], const char value[]) {
143 lua_pushstring(L, value);
144 lua_setfield(L, -2, key);
145}
146
147static void setfield_number(lua_State* L, const char key[], double value) {
148 lua_pushnumber(L, value);
149 lua_setfield(L, -2, key);
150}
151
humper@google.com2815c192013-07-10 22:42:30 +0000152static void setfield_boolean(lua_State* L, const char key[], bool value) {
153 lua_pushboolean(L, value);
154 lua_setfield(L, -2, key);
155}
156
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000157static void setfield_scalar(lua_State* L, const char key[], SkScalar value) {
158 setfield_number(L, key, SkScalarToLua(value));
159}
160
reed@google.com3597b732013-05-22 20:12:50 +0000161static void setfield_function(lua_State* L,
162 const char key[], lua_CFunction value) {
163 lua_pushcfunction(L, value);
164 lua_setfield(L, -2, key);
reed@google.com74ce6f02013-05-22 15:13:18 +0000165}
166
reed7a72c672014-11-07 10:23:55 -0800167static int lua2int_def(lua_State* L, int index, int defaultValue) {
168 if (lua_isnumber(L, index)) {
169 return (int)lua_tonumber(L, index);
170 } else {
171 return defaultValue;
172 }
173}
174
175static SkScalar lua2scalar(lua_State* L, int index) {
176 SkASSERT(lua_isnumber(L, index));
177 return SkLuaToScalar(lua_tonumber(L, index));
178}
179
180static SkScalar lua2scalar_def(lua_State* L, int index, SkScalar defaultValue) {
181 if (lua_isnumber(L, index)) {
182 return SkLuaToScalar(lua_tonumber(L, index));
183 } else {
184 return defaultValue;
185 }
186}
187
188static SkScalar getarray_scalar(lua_State* L, int stackIndex, int arrayIndex) {
189 SkASSERT(lua_istable(L, stackIndex));
190 lua_rawgeti(L, stackIndex, arrayIndex);
mtklein8aacf202014-12-18 13:29:54 -0800191
reed7a72c672014-11-07 10:23:55 -0800192 SkScalar value = lua2scalar(L, -1);
193 lua_pop(L, 1);
194 return value;
195}
196
197static void getarray_scalars(lua_State* L, int stackIndex, SkScalar dst[], int count) {
198 for (int i = 0; i < count; ++i) {
199 dst[i] = getarray_scalar(L, stackIndex, i + 1);
200 }
201}
202
203static void getarray_points(lua_State* L, int stackIndex, SkPoint pts[], int count) {
204 getarray_scalars(L, stackIndex, &pts[0].fX, count * 2);
205}
206
reed@google.come3823fd2013-05-30 18:55:14 +0000207static void setarray_number(lua_State* L, int index, double value) {
208 lua_pushnumber(L, value);
209 lua_rawseti(L, -2, index);
210}
211
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +0000212static void setarray_scalar(lua_State* L, int index, SkScalar value) {
213 setarray_number(L, index, SkScalarToLua(value));
214}
215
reed@google.com74ce6f02013-05-22 15:13:18 +0000216void SkLua::pushBool(bool value, const char key[]) {
217 lua_pushboolean(fL, value);
218 CHECK_SETFIELD(key);
219}
220
221void SkLua::pushString(const char str[], const char key[]) {
222 lua_pushstring(fL, str);
223 CHECK_SETFIELD(key);
224}
225
reed@google.come3823fd2013-05-30 18:55:14 +0000226void SkLua::pushString(const char str[], size_t length, const char key[]) {
227 // TODO: how to do this w/o making a copy?
228 SkString s(str, length);
229 lua_pushstring(fL, s.c_str());
230 CHECK_SETFIELD(key);
231}
232
reed@google.com74ce6f02013-05-22 15:13:18 +0000233void SkLua::pushString(const SkString& str, const char key[]) {
234 lua_pushstring(fL, str.c_str());
235 CHECK_SETFIELD(key);
236}
237
238void SkLua::pushColor(SkColor color, const char key[]) {
239 lua_newtable(fL);
240 setfield_number(fL, "a", SkColorGetA(color) / 255.0);
241 setfield_number(fL, "r", SkColorGetR(color) / 255.0);
242 setfield_number(fL, "g", SkColorGetG(color) / 255.0);
243 setfield_number(fL, "b", SkColorGetB(color) / 255.0);
244 CHECK_SETFIELD(key);
245}
246
reed@google.come3823fd2013-05-30 18:55:14 +0000247void SkLua::pushU32(uint32_t value, const char key[]) {
248 lua_pushnumber(fL, (double)value);
249 CHECK_SETFIELD(key);
250}
251
reed@google.com74ce6f02013-05-22 15:13:18 +0000252void SkLua::pushScalar(SkScalar value, const char key[]) {
253 lua_pushnumber(fL, SkScalarToLua(value));
254 CHECK_SETFIELD(key);
255}
256
reed@google.come3823fd2013-05-30 18:55:14 +0000257void SkLua::pushArrayU16(const uint16_t array[], int count, const char key[]) {
258 lua_newtable(fL);
259 for (int i = 0; i < count; ++i) {
260 // make it base-1 to match lua convention
261 setarray_number(fL, i + 1, (double)array[i]);
262 }
263 CHECK_SETFIELD(key);
264}
265
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +0000266void SkLua::pushArrayPoint(const SkPoint array[], int count, const char key[]) {
267 lua_newtable(fL);
268 for (int i = 0; i < count; ++i) {
269 // make it base-1 to match lua convention
270 lua_newtable(fL);
271 this->pushScalar(array[i].fX, "x");
272 this->pushScalar(array[i].fY, "y");
273 lua_rawseti(fL, -2, i + 1);
274 }
275 CHECK_SETFIELD(key);
276}
277
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +0000278void SkLua::pushArrayScalar(const SkScalar array[], int count, const char key[]) {
279 lua_newtable(fL);
280 for (int i = 0; i < count; ++i) {
281 // make it base-1 to match lua convention
282 setarray_scalar(fL, i + 1, array[i]);
283 }
284 CHECK_SETFIELD(key);
285}
286
reed@google.com74ce6f02013-05-22 15:13:18 +0000287void SkLua::pushRect(const SkRect& r, const char key[]) {
288 lua_newtable(fL);
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000289 setfield_scalar(fL, "left", r.fLeft);
290 setfield_scalar(fL, "top", r.fTop);
291 setfield_scalar(fL, "right", r.fRight);
292 setfield_scalar(fL, "bottom", r.fBottom);
reed@google.com74ce6f02013-05-22 15:13:18 +0000293 CHECK_SETFIELD(key);
294}
295
296void SkLua::pushRRect(const SkRRect& rr, const char key[]) {
297 push_obj(fL, rr);
298 CHECK_SETFIELD(key);
299}
300
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +0000301void SkLua::pushDash(const SkPathEffect::DashInfo& info, const char key[]) {
302 lua_newtable(fL);
303 setfield_scalar(fL, "phase", info.fPhase);
304 this->pushArrayScalar(info.fIntervals, info.fCount, "intervals");
305 CHECK_SETFIELD(key);
306}
307
308
reed@google.com74ce6f02013-05-22 15:13:18 +0000309void SkLua::pushMatrix(const SkMatrix& matrix, const char key[]) {
310 push_obj(fL, matrix);
311 CHECK_SETFIELD(key);
312}
313
314void SkLua::pushPaint(const SkPaint& paint, const char key[]) {
315 push_obj(fL, paint);
316 CHECK_SETFIELD(key);
317}
318
319void SkLua::pushPath(const SkPath& path, const char key[]) {
320 push_obj(fL, path);
321 CHECK_SETFIELD(key);
322}
323
324void SkLua::pushCanvas(SkCanvas* canvas, const char key[]) {
325 push_ref(fL, canvas);
326 CHECK_SETFIELD(key);
327}
328
fmalitab7425172014-08-26 07:56:44 -0700329void SkLua::pushTextBlob(const SkTextBlob* blob, const char key[]) {
330 push_ref(fL, const_cast<SkTextBlob*>(blob));
331 CHECK_SETFIELD(key);
332}
333
commit-bot@chromium.org5cc25352014-02-24 18:59:48 +0000334static const char* element_type(SkClipStack::Element::Type type) {
335 switch (type) {
336 case SkClipStack::Element::kEmpty_Type:
337 return "empty";
338 case SkClipStack::Element::kRect_Type:
339 return "rect";
340 case SkClipStack::Element::kRRect_Type:
341 return "rrect";
342 case SkClipStack::Element::kPath_Type:
343 return "path";
344 }
345 return "unknown";
346}
347
348static const char* region_op(SkRegion::Op op) {
349 switch (op) {
350 case SkRegion::kDifference_Op:
351 return "difference";
352 case SkRegion::kIntersect_Op:
353 return "intersect";
354 case SkRegion::kUnion_Op:
355 return "union";
356 case SkRegion::kXOR_Op:
357 return "xor";
358 case SkRegion::kReverseDifference_Op:
359 return "reverse-difference";
360 case SkRegion::kReplace_Op:
361 return "replace";
362 }
363 return "unknown";
364}
365
366void SkLua::pushClipStack(const SkClipStack& stack, const char* key) {
367 lua_newtable(fL);
368 SkClipStack::B2TIter iter(stack);
369 const SkClipStack::Element* element;
370 int i = 0;
bsalomon49f085d2014-09-05 13:34:00 -0700371 while ((element = iter.next())) {
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000372 this->pushClipStackElement(*element);
commit-bot@chromium.org5cc25352014-02-24 18:59:48 +0000373 lua_rawseti(fL, -2, ++i);
374 }
375 CHECK_SETFIELD(key);
376}
377
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000378void SkLua::pushClipStackElement(const SkClipStack::Element& element, const char* key) {
379 lua_newtable(fL);
380 SkClipStack::Element::Type type = element.getType();
381 this->pushString(element_type(type), "type");
382 switch (type) {
383 case SkClipStack::Element::kEmpty_Type:
384 break;
385 case SkClipStack::Element::kRect_Type:
386 this->pushRect(element.getRect(), "rect");
387 break;
388 case SkClipStack::Element::kRRect_Type:
389 this->pushRRect(element.getRRect(), "rrect");
390 break;
391 case SkClipStack::Element::kPath_Type:
392 this->pushPath(element.getPath(), "path");
393 break;
394 }
395 this->pushString(region_op(element.getOp()), "op");
396 this->pushBool(element.isAA(), "aa");
397 CHECK_SETFIELD(key);
398}
399
400
reed@google.com74ce6f02013-05-22 15:13:18 +0000401///////////////////////////////////////////////////////////////////////////////
402///////////////////////////////////////////////////////////////////////////////
403
reed@google.com74ce6f02013-05-22 15:13:18 +0000404static SkScalar getfield_scalar(lua_State* L, int index, const char key[]) {
405 SkASSERT(lua_istable(L, index));
406 lua_pushstring(L, key);
407 lua_gettable(L, index);
mtklein8aacf202014-12-18 13:29:54 -0800408
reed@google.com74ce6f02013-05-22 15:13:18 +0000409 SkScalar value = lua2scalar(L, -1);
410 lua_pop(L, 1);
411 return value;
412}
413
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000414static SkScalar getfield_scalar_default(lua_State* L, int index, const char key[], SkScalar def) {
415 SkASSERT(lua_istable(L, index));
416 lua_pushstring(L, key);
417 lua_gettable(L, index);
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000418
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000419 SkScalar value;
420 if (lua_isnil(L, -1)) {
421 value = def;
422 } else {
423 value = lua2scalar(L, -1);
424 }
425 lua_pop(L, 1);
426 return value;
427}
428
reed468b1812014-10-19 11:42:54 -0700429static SkScalar byte2unit(U8CPU byte) {
430 return byte / 255.0f;
431}
432
reed@google.com74ce6f02013-05-22 15:13:18 +0000433static U8CPU unit2byte(SkScalar x) {
434 if (x <= 0) {
435 return 0;
436 } else if (x >= 1) {
437 return 255;
438 } else {
439 return SkScalarRoundToInt(x * 255);
440 }
441}
442
443static SkColor lua2color(lua_State* L, int index) {
reed485557f2014-10-12 10:36:47 -0700444 return SkColorSetARGB(unit2byte(getfield_scalar_default(L, index, "a", 1)),
445 unit2byte(getfield_scalar_default(L, index, "r", 0)),
446 unit2byte(getfield_scalar_default(L, index, "g", 0)),
447 unit2byte(getfield_scalar_default(L, index, "b", 0)));
reed@google.com74ce6f02013-05-22 15:13:18 +0000448}
449
450static SkRect* lua2rect(lua_State* L, int index, SkRect* rect) {
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000451 rect->set(getfield_scalar_default(L, index, "left", 0),
452 getfield_scalar_default(L, index, "top", 0),
reed@google.com74ce6f02013-05-22 15:13:18 +0000453 getfield_scalar(L, index, "right"),
454 getfield_scalar(L, index, "bottom"));
455 return rect;
456}
457
reedf355df52014-10-12 12:18:40 -0700458static int lcanvas_clear(lua_State* L) {
459 get_ref<SkCanvas>(L, 1)->clear(0);
460 return 0;
461}
462
reed@google.com74ce6f02013-05-22 15:13:18 +0000463static int lcanvas_drawColor(lua_State* L) {
464 get_ref<SkCanvas>(L, 1)->drawColor(lua2color(L, 2));
465 return 0;
466}
467
reed9fbc3f32014-10-21 07:12:58 -0700468static int lcanvas_drawPaint(lua_State* L) {
469 get_ref<SkCanvas>(L, 1)->drawPaint(*get_obj<SkPaint>(L, 2));
470 return 0;
471}
472
reed@google.com74ce6f02013-05-22 15:13:18 +0000473static int lcanvas_drawRect(lua_State* L) {
474 SkRect rect;
reed7a72c672014-11-07 10:23:55 -0800475 lua2rect(L, 2, &rect);
476 const SkPaint* paint = get_obj<SkPaint>(L, 3);
477 get_ref<SkCanvas>(L, 1)->drawRect(rect, *paint);
reed@google.com74ce6f02013-05-22 15:13:18 +0000478 return 0;
479}
480
481static int lcanvas_drawOval(lua_State* L) {
482 SkRect rect;
483 get_ref<SkCanvas>(L, 1)->drawOval(*lua2rect(L, 2, &rect),
484 *get_obj<SkPaint>(L, 3));
485 return 0;
486}
487
488static int lcanvas_drawCircle(lua_State* L) {
489 get_ref<SkCanvas>(L, 1)->drawCircle(lua2scalar(L, 2),
490 lua2scalar(L, 3),
491 lua2scalar(L, 4),
492 *get_obj<SkPaint>(L, 5));
493 return 0;
494}
495
reed485557f2014-10-12 10:36:47 -0700496static SkPaint* lua2OptionalPaint(lua_State* L, int index, SkPaint* paint) {
497 if (lua_isnumber(L, index)) {
498 paint->setAlpha(SkScalarRoundToInt(lua2scalar(L, index) * 255));
499 return paint;
reedf355df52014-10-12 12:18:40 -0700500 } else if (lua_isuserdata(L, index)) {
reed485557f2014-10-12 10:36:47 -0700501 const SkPaint* ptr = get_obj<SkPaint>(L, index);
502 if (ptr) {
503 *paint = *ptr;
504 return paint;
505 }
506 }
halcanary96fcdcc2015-08-27 07:41:13 -0700507 return nullptr;
reed485557f2014-10-12 10:36:47 -0700508}
509
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000510static int lcanvas_drawImage(lua_State* L) {
511 SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
512 SkImage* image = get_ref<SkImage>(L, 2);
halcanary96fcdcc2015-08-27 07:41:13 -0700513 if (nullptr == image) {
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000514 return 0;
515 }
516 SkScalar x = lua2scalar(L, 3);
517 SkScalar y = lua2scalar(L, 4);
518
519 SkPaint paint;
reed485557f2014-10-12 10:36:47 -0700520 canvas->drawImage(image, x, y, lua2OptionalPaint(L, 5, &paint));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000521 return 0;
522}
523
reedba5fb932014-10-10 15:28:19 -0700524static int lcanvas_drawImageRect(lua_State* L) {
525 SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
526 SkImage* image = get_ref<SkImage>(L, 2);
halcanary96fcdcc2015-08-27 07:41:13 -0700527 if (nullptr == image) {
reedba5fb932014-10-10 15:28:19 -0700528 return 0;
529 }
530
531 SkRect srcR, dstR;
halcanary96fcdcc2015-08-27 07:41:13 -0700532 SkRect* srcRPtr = nullptr;
reedba5fb932014-10-10 15:28:19 -0700533 if (!lua_isnil(L, 3)) {
534 srcRPtr = lua2rect(L, 3, &srcR);
535 }
536 lua2rect(L, 4, &dstR);
mtklein8aacf202014-12-18 13:29:54 -0800537
reedba5fb932014-10-10 15:28:19 -0700538 SkPaint paint;
reede47829b2015-08-06 10:02:53 -0700539 canvas->legacy_drawImageRect(image, srcRPtr, dstR, lua2OptionalPaint(L, 5, &paint));
reedba5fb932014-10-10 15:28:19 -0700540 return 0;
541}
542
reed7a72c672014-11-07 10:23:55 -0800543static int lcanvas_drawPatch(lua_State* L) {
544 SkPoint cubics[12];
545 SkColor colorStorage[4];
546 SkPoint texStorage[4];
547
halcanary96fcdcc2015-08-27 07:41:13 -0700548 const SkColor* colors = nullptr;
549 const SkPoint* texs = nullptr;
reed7a72c672014-11-07 10:23:55 -0800550
551 getarray_points(L, 2, cubics, 12);
552
553 colorStorage[0] = SK_ColorRED;
554 colorStorage[1] = SK_ColorGREEN;
555 colorStorage[2] = SK_ColorBLUE;
556 colorStorage[3] = SK_ColorGRAY;
557
558 if (lua_isnil(L, 4)) {
559 colors = colorStorage;
560 } else {
561 getarray_points(L, 4, texStorage, 4);
562 texs = texStorage;
563 }
564
halcanary96fcdcc2015-08-27 07:41:13 -0700565 get_ref<SkCanvas>(L, 1)->drawPatch(cubics, colors, texs, nullptr, *get_obj<SkPaint>(L, 5));
reed7a72c672014-11-07 10:23:55 -0800566 return 0;
567}
568
reed@google.comfd345872013-05-22 20:53:42 +0000569static int lcanvas_drawPath(lua_State* L) {
570 get_ref<SkCanvas>(L, 1)->drawPath(*get_obj<SkPath>(L, 2),
571 *get_obj<SkPaint>(L, 3));
572 return 0;
573}
574
reed96affcd2014-10-13 12:38:04 -0700575// drawPicture(pic, x, y, paint)
576static int lcanvas_drawPicture(lua_State* L) {
577 SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
578 SkPicture* picture = get_ref<SkPicture>(L, 2);
579 SkScalar x = lua2scalar_def(L, 3, 0);
580 SkScalar y = lua2scalar_def(L, 4, 0);
halcanary96fcdcc2015-08-27 07:41:13 -0700581 SkMatrix matrix, *matrixPtr = nullptr;
reed96affcd2014-10-13 12:38:04 -0700582 if (x || y) {
583 matrix.setTranslate(x, y);
584 matrixPtr = &matrix;
585 }
586 SkPaint paint;
587 canvas->drawPicture(picture, matrixPtr, lua2OptionalPaint(L, 5, &paint));
588 return 0;
589}
590
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000591static int lcanvas_drawText(lua_State* L) {
592 if (lua_gettop(L) < 5) {
593 return 0;
594 }
595
596 if (lua_isstring(L, 2) && lua_isnumber(L, 3) && lua_isnumber(L, 4)) {
597 size_t len;
598 const char* text = lua_tolstring(L, 2, &len);
599 get_ref<SkCanvas>(L, 1)->drawText(text, len,
600 lua2scalar(L, 3), lua2scalar(L, 4),
601 *get_obj<SkPaint>(L, 5));
602 }
603 return 0;
604}
605
reed1b6ab442014-11-03 19:55:41 -0800606static int lcanvas_drawTextBlob(lua_State* L) {
607 const SkTextBlob* blob = get_ref<SkTextBlob>(L, 2);
608 SkScalar x = lua2scalar(L, 3);
609 SkScalar y = lua2scalar(L, 4);
610 const SkPaint& paint = *get_obj<SkPaint>(L, 5);
611 get_ref<SkCanvas>(L, 1)->drawTextBlob(blob, x, y, paint);
612 return 0;
613}
614
reed@google.com74ce6f02013-05-22 15:13:18 +0000615static int lcanvas_getSaveCount(lua_State* L) {
616 lua_pushnumber(L, get_ref<SkCanvas>(L, 1)->getSaveCount());
617 return 1;
618}
619
620static int lcanvas_getTotalMatrix(lua_State* L) {
621 SkLua(L).pushMatrix(get_ref<SkCanvas>(L, 1)->getTotalMatrix());
622 return 1;
623}
624
commit-bot@chromium.org5cc25352014-02-24 18:59:48 +0000625static int lcanvas_getClipStack(lua_State* L) {
626 SkLua(L).pushClipStack(*get_ref<SkCanvas>(L, 1)->getClipStack());
627 return 1;
628}
629
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000630int SkLua::lcanvas_getReducedClipStack(lua_State* L) {
631#if SK_SUPPORT_GPU
632 const SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
633 SkISize layerSize = canvas->getTopLayerSize();
634 SkIPoint layerOrigin = canvas->getTopLayerOrigin();
635 SkIRect queryBounds = SkIRect::MakeXYWH(layerOrigin.fX, layerOrigin.fY,
636 layerSize.fWidth, layerSize.fHeight);
637
638 GrReducedClip::ElementList elements;
639 GrReducedClip::InitialState initialState;
640 int32_t genID;
641 SkIRect resultBounds;
642
643 const SkClipStack& stack = *canvas->getClipStack();
644
645 GrReducedClip::ReduceClipStack(stack,
646 queryBounds,
647 &elements,
648 &genID,
649 &initialState,
650 &resultBounds,
halcanary96fcdcc2015-08-27 07:41:13 -0700651 nullptr);
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000652
653 GrReducedClip::ElementList::Iter iter(elements);
654 int i = 0;
655 lua_newtable(L);
bsalomon49f085d2014-09-05 13:34:00 -0700656 while(iter.get()) {
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000657 SkLua(L).pushClipStackElement(*iter.get());
658 iter.next();
659 lua_rawseti(L, -2, ++i);
660 }
661 // Currently this only returns the element list to lua, not the initial state or result bounds.
662 // It could return these as additional items on the lua stack.
663 return 1;
664#else
665 return 0;
666#endif
667}
668
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000669static int lcanvas_save(lua_State* L) {
670 lua_pushinteger(L, get_ref<SkCanvas>(L, 1)->save());
671 return 1;
672}
673
reed86217d82014-10-25 20:44:40 -0700674static int lcanvas_saveLayer(lua_State* L) {
675 SkPaint paint;
halcanary96fcdcc2015-08-27 07:41:13 -0700676 lua_pushinteger(L, get_ref<SkCanvas>(L, 1)->saveLayer(nullptr, lua2OptionalPaint(L, 2, &paint)));
reed86217d82014-10-25 20:44:40 -0700677 return 1;
678}
679
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000680static int lcanvas_restore(lua_State* L) {
681 get_ref<SkCanvas>(L, 1)->restore();
682 return 0;
683}
684
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000685static int lcanvas_scale(lua_State* L) {
686 SkScalar sx = lua2scalar_def(L, 2, 1);
687 SkScalar sy = lua2scalar_def(L, 3, sx);
688 get_ref<SkCanvas>(L, 1)->scale(sx, sy);
689 return 0;
690}
691
reed@google.com3597b732013-05-22 20:12:50 +0000692static int lcanvas_translate(lua_State* L) {
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000693 SkScalar tx = lua2scalar_def(L, 2, 0);
694 SkScalar ty = lua2scalar_def(L, 3, 0);
695 get_ref<SkCanvas>(L, 1)->translate(tx, ty);
696 return 0;
697}
698
699static int lcanvas_rotate(lua_State* L) {
700 SkScalar degrees = lua2scalar_def(L, 2, 0);
701 get_ref<SkCanvas>(L, 1)->rotate(degrees);
reed@google.com3597b732013-05-22 20:12:50 +0000702 return 0;
703}
704
reedbdc49ae2014-10-14 09:34:52 -0700705static int lcanvas_concat(lua_State* L) {
706 get_ref<SkCanvas>(L, 1)->concat(*get_obj<SkMatrix>(L, 2));
707 return 0;
708}
709
reed485557f2014-10-12 10:36:47 -0700710static int lcanvas_newSurface(lua_State* L) {
711 int width = lua2int_def(L, 2, 0);
reed7a72c672014-11-07 10:23:55 -0800712 int height = lua2int_def(L, 3, 0);
reed485557f2014-10-12 10:36:47 -0700713 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
714 SkSurface* surface = get_ref<SkCanvas>(L, 1)->newSurface(info);
halcanary96fcdcc2015-08-27 07:41:13 -0700715 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -0700716 lua_pushnil(L);
717 } else {
reed9fbc3f32014-10-21 07:12:58 -0700718 push_ref(L, surface)->unref();
reed485557f2014-10-12 10:36:47 -0700719 }
720 return 1;
721}
722
reed@google.com74ce6f02013-05-22 15:13:18 +0000723static int lcanvas_gc(lua_State* L) {
724 get_ref<SkCanvas>(L, 1)->unref();
725 return 0;
726}
727
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000728const struct luaL_Reg gSkCanvas_Methods[] = {
reedf355df52014-10-12 12:18:40 -0700729 { "clear", lcanvas_clear },
reed@google.com74ce6f02013-05-22 15:13:18 +0000730 { "drawColor", lcanvas_drawColor },
reed9fbc3f32014-10-21 07:12:58 -0700731 { "drawPaint", lcanvas_drawPaint },
reed@google.com74ce6f02013-05-22 15:13:18 +0000732 { "drawRect", lcanvas_drawRect },
733 { "drawOval", lcanvas_drawOval },
734 { "drawCircle", lcanvas_drawCircle },
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000735 { "drawImage", lcanvas_drawImage },
reedba5fb932014-10-10 15:28:19 -0700736 { "drawImageRect", lcanvas_drawImageRect },
reed7a72c672014-11-07 10:23:55 -0800737 { "drawPatch", lcanvas_drawPatch },
reed@google.comfd345872013-05-22 20:53:42 +0000738 { "drawPath", lcanvas_drawPath },
reed96affcd2014-10-13 12:38:04 -0700739 { "drawPicture", lcanvas_drawPicture },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000740 { "drawText", lcanvas_drawText },
reed1b6ab442014-11-03 19:55:41 -0800741 { "drawTextBlob", lcanvas_drawTextBlob },
reed@google.com74ce6f02013-05-22 15:13:18 +0000742 { "getSaveCount", lcanvas_getSaveCount },
743 { "getTotalMatrix", lcanvas_getTotalMatrix },
commit-bot@chromium.org5cc25352014-02-24 18:59:48 +0000744 { "getClipStack", lcanvas_getClipStack },
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000745#if SK_SUPPORT_GPU
746 { "getReducedClipStack", SkLua::lcanvas_getReducedClipStack },
747#endif
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000748 { "save", lcanvas_save },
reed86217d82014-10-25 20:44:40 -0700749 { "saveLayer", lcanvas_saveLayer },
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000750 { "restore", lcanvas_restore },
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000751 { "scale", lcanvas_scale },
reed@google.com3597b732013-05-22 20:12:50 +0000752 { "translate", lcanvas_translate },
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000753 { "rotate", lcanvas_rotate },
reedbdc49ae2014-10-14 09:34:52 -0700754 { "concat", lcanvas_concat },
reed485557f2014-10-12 10:36:47 -0700755
756 { "newSurface", lcanvas_newSurface },
757
reed@google.com74ce6f02013-05-22 15:13:18 +0000758 { "__gc", lcanvas_gc },
halcanary96fcdcc2015-08-27 07:41:13 -0700759 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +0000760};
761
762///////////////////////////////////////////////////////////////////////////////
763
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000764static int ldocument_beginPage(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -0700765 const SkRect* contentPtr = nullptr;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000766 push_ref(L, get_ref<SkDocument>(L, 1)->beginPage(lua2scalar(L, 2),
767 lua2scalar(L, 3),
768 contentPtr));
769 return 1;
770}
771
772static int ldocument_endPage(lua_State* L) {
773 get_ref<SkDocument>(L, 1)->endPage();
774 return 0;
775}
776
777static int ldocument_close(lua_State* L) {
778 get_ref<SkDocument>(L, 1)->close();
779 return 0;
780}
781
782static int ldocument_gc(lua_State* L) {
783 get_ref<SkDocument>(L, 1)->unref();
784 return 0;
785}
786
787static const struct luaL_Reg gSkDocument_Methods[] = {
788 { "beginPage", ldocument_beginPage },
789 { "endPage", ldocument_endPage },
790 { "close", ldocument_close },
791 { "__gc", ldocument_gc },
halcanary96fcdcc2015-08-27 07:41:13 -0700792 { nullptr, nullptr }
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000793};
794
795///////////////////////////////////////////////////////////////////////////////
796
reed@google.com74ce6f02013-05-22 15:13:18 +0000797static int lpaint_isAntiAlias(lua_State* L) {
798 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isAntiAlias());
799 return 1;
800}
801
802static int lpaint_setAntiAlias(lua_State* L) {
reed@google.com88c9ec92013-05-22 15:43:21 +0000803 get_obj<SkPaint>(L, 1)->setAntiAlias(lua2bool(L, 2));
reed@google.com74ce6f02013-05-22 15:13:18 +0000804 return 0;
805}
806
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000807static int lpaint_isDither(lua_State* L) {
808 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isDither());
809 return 1;
810}
811
reedbb8a0ab2014-11-03 22:32:07 -0800812static int lpaint_setDither(lua_State* L) {
813 get_obj<SkPaint>(L, 1)->setDither(lua2bool(L, 2));
814 return 0;
815}
816
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000817static int lpaint_isUnderlineText(lua_State* L) {
818 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isUnderlineText());
819 return 1;
820}
821
822static int lpaint_isStrikeThruText(lua_State* L) {
823 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isStrikeThruText());
824 return 1;
825}
826
827static int lpaint_isFakeBoldText(lua_State* L) {
828 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isFakeBoldText());
829 return 1;
830}
831
832static int lpaint_isLinearText(lua_State* L) {
833 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isLinearText());
834 return 1;
835}
836
837static int lpaint_isSubpixelText(lua_State* L) {
838 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isSubpixelText());
839 return 1;
840}
841
reed09a1d672014-10-11 13:13:11 -0700842static int lpaint_setSubpixelText(lua_State* L) {
843 get_obj<SkPaint>(L, 1)->setSubpixelText(lua2bool(L, 2));
844 return 1;
845}
846
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000847static int lpaint_isDevKernText(lua_State* L) {
848 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isDevKernText());
849 return 1;
850}
851
852static int lpaint_isLCDRenderText(lua_State* L) {
853 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isLCDRenderText());
854 return 1;
855}
856
reed36c9c112014-11-04 10:58:42 -0800857static int lpaint_setLCDRenderText(lua_State* L) {
858 get_obj<SkPaint>(L, 1)->setLCDRenderText(lua2bool(L, 2));
859 return 1;
860}
861
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000862static int lpaint_isEmbeddedBitmapText(lua_State* L) {
863 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isEmbeddedBitmapText());
864 return 1;
865}
866
867static int lpaint_isAutohinted(lua_State* L) {
868 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isAutohinted());
869 return 1;
870}
871
872static int lpaint_isVerticalText(lua_State* L) {
873 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isVerticalText());
874 return 1;
875}
876
reed468b1812014-10-19 11:42:54 -0700877static int lpaint_getAlpha(lua_State* L) {
878 SkLua(L).pushScalar(byte2unit(get_obj<SkPaint>(L, 1)->getAlpha()));
879 return 1;
880}
881
882static int lpaint_setAlpha(lua_State* L) {
883 get_obj<SkPaint>(L, 1)->setAlpha(unit2byte(lua2scalar(L, 2)));
884 return 0;
885}
886
reed@google.com74ce6f02013-05-22 15:13:18 +0000887static int lpaint_getColor(lua_State* L) {
888 SkLua(L).pushColor(get_obj<SkPaint>(L, 1)->getColor());
889 return 1;
890}
891
892static int lpaint_setColor(lua_State* L) {
893 get_obj<SkPaint>(L, 1)->setColor(lua2color(L, 2));
894 return 0;
895}
896
reed@google.come3823fd2013-05-30 18:55:14 +0000897static int lpaint_getTextSize(lua_State* L) {
898 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getTextSize());
899 return 1;
900}
901
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000902static int lpaint_getTextScaleX(lua_State* L) {
903 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getTextScaleX());
904 return 1;
905}
906
907static int lpaint_getTextSkewX(lua_State* L) {
908 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getTextSkewX());
909 return 1;
910}
911
reed@google.come3823fd2013-05-30 18:55:14 +0000912static int lpaint_setTextSize(lua_State* L) {
913 get_obj<SkPaint>(L, 1)->setTextSize(lua2scalar(L, 2));
914 return 0;
915}
916
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000917static int lpaint_getTypeface(lua_State* L) {
918 push_ref(L, get_obj<SkPaint>(L, 1)->getTypeface());
919 return 1;
920}
921
922static int lpaint_setTypeface(lua_State* L) {
923 get_obj<SkPaint>(L, 1)->setTypeface(get_ref<SkTypeface>(L, 2));
924 return 0;
925}
926
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000927static int lpaint_getHinting(lua_State* L) {
928 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getHinting());
929 return 1;
930}
931
reed93a12152015-03-16 10:08:34 -0700932static int lpaint_getFilterQuality(lua_State* L) {
933 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getFilterQuality());
reed7a72c672014-11-07 10:23:55 -0800934 return 1;
935}
936
reed93a12152015-03-16 10:08:34 -0700937static int lpaint_setFilterQuality(lua_State* L) {
reed7a72c672014-11-07 10:23:55 -0800938 int level = lua2int_def(L, 2, -1);
939 if (level >= 0 && level <= 3) {
reed93a12152015-03-16 10:08:34 -0700940 get_obj<SkPaint>(L, 1)->setFilterQuality((SkFilterQuality)level);
reed7a72c672014-11-07 10:23:55 -0800941 }
942 return 0;
943}
944
reed@google.come3823fd2013-05-30 18:55:14 +0000945static int lpaint_getFontID(lua_State* L) {
946 SkTypeface* face = get_obj<SkPaint>(L, 1)->getTypeface();
947 SkLua(L).pushU32(SkTypeface::UniqueID(face));
948 return 1;
949}
950
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000951static const struct {
952 const char* fLabel;
953 SkPaint::Align fAlign;
954} gAlignRec[] = {
955 { "left", SkPaint::kLeft_Align },
956 { "center", SkPaint::kCenter_Align },
957 { "right", SkPaint::kRight_Align },
958};
959
960static int lpaint_getTextAlign(lua_State* L) {
961 SkPaint::Align align = get_obj<SkPaint>(L, 1)->getTextAlign();
962 for (size_t i = 0; i < SK_ARRAY_COUNT(gAlignRec); ++i) {
963 if (gAlignRec[i].fAlign == align) {
964 lua_pushstring(L, gAlignRec[i].fLabel);
965 return 1;
966 }
967 }
968 return 0;
969}
970
971static int lpaint_setTextAlign(lua_State* L) {
972 if (lua_isstring(L, 2)) {
973 size_t len;
974 const char* label = lua_tolstring(L, 2, &len);
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000975
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000976 for (size_t i = 0; i < SK_ARRAY_COUNT(gAlignRec); ++i) {
977 if (!strcmp(gAlignRec[i].fLabel, label)) {
978 get_obj<SkPaint>(L, 1)->setTextAlign(gAlignRec[i].fAlign);
979 break;
980 }
981 }
982 }
983 return 0;
984}
985
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000986static int lpaint_getStroke(lua_State* L) {
987 lua_pushboolean(L, SkPaint::kStroke_Style == get_obj<SkPaint>(L, 1)->getStyle());
988 return 1;
989}
990
991static int lpaint_setStroke(lua_State* L) {
992 SkPaint::Style style;
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000993
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000994 if (lua_toboolean(L, 2)) {
995 style = SkPaint::kStroke_Style;
996 } else {
997 style = SkPaint::kFill_Style;
998 }
999 get_obj<SkPaint>(L, 1)->setStyle(style);
1000 return 0;
1001}
1002
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001003static int lpaint_getStrokeCap(lua_State* L) {
1004 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeCap());
1005 return 1;
1006}
1007
1008static int lpaint_getStrokeJoin(lua_State* L) {
1009 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeJoin());
1010 return 1;
1011}
1012
1013static int lpaint_getTextEncoding(lua_State* L) {
commit-bot@chromium.org641bcc32013-12-19 10:39:59 +00001014 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getTextEncoding());
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001015 return 1;
1016}
1017
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +00001018static int lpaint_getStrokeWidth(lua_State* L) {
1019 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeWidth());
1020 return 1;
1021}
1022
1023static int lpaint_setStrokeWidth(lua_State* L) {
1024 get_obj<SkPaint>(L, 1)->setStrokeWidth(lua2scalar(L, 2));
1025 return 0;
1026}
1027
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001028static int lpaint_getStrokeMiter(lua_State* L) {
1029 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeMiter());
1030 return 1;
1031}
1032
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +00001033static int lpaint_measureText(lua_State* L) {
1034 if (lua_isstring(L, 2)) {
1035 size_t len;
1036 const char* text = lua_tolstring(L, 2, &len);
1037 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->measureText(text, len));
1038 return 1;
1039 }
1040 return 0;
1041}
1042
1043struct FontMetrics {
1044 SkScalar fTop; //!< The greatest distance above the baseline for any glyph (will be <= 0)
1045 SkScalar fAscent; //!< The recommended distance above the baseline (will be <= 0)
1046 SkScalar fDescent; //!< The recommended distance below the baseline (will be >= 0)
1047 SkScalar fBottom; //!< The greatest distance below the baseline for any glyph (will be >= 0)
1048 SkScalar fLeading; //!< The recommended distance to add between lines of text (will be >= 0)
1049 SkScalar fAvgCharWidth; //!< the average charactor width (>= 0)
1050 SkScalar fXMin; //!< The minimum bounding box x value for all glyphs
1051 SkScalar fXMax; //!< The maximum bounding box x value for all glyphs
1052 SkScalar fXHeight; //!< the height of an 'x' in px, or 0 if no 'x' in face
1053};
1054
1055static int lpaint_getFontMetrics(lua_State* L) {
1056 SkPaint::FontMetrics fm;
1057 SkScalar height = get_obj<SkPaint>(L, 1)->getFontMetrics(&fm);
skia.committer@gmail.com370c5342013-06-09 07:01:05 +00001058
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +00001059 lua_newtable(L);
1060 setfield_scalar(L, "top", fm.fTop);
1061 setfield_scalar(L, "ascent", fm.fAscent);
1062 setfield_scalar(L, "descent", fm.fDescent);
1063 setfield_scalar(L, "bottom", fm.fBottom);
1064 setfield_scalar(L, "leading", fm.fLeading);
1065 SkLua(L).pushScalar(height);
1066 return 2;
1067}
1068
reed@google.com29563872013-07-10 21:23:49 +00001069static int lpaint_getEffects(lua_State* L) {
1070 const SkPaint* paint = get_obj<SkPaint>(L, 1);
skia.committer@gmail.comde2e4e82013-07-11 07:01:01 +00001071
reed@google.com29563872013-07-10 21:23:49 +00001072 lua_newtable(L);
reed468b1812014-10-19 11:42:54 -07001073 setfield_bool_if(L, "looper", !!paint->getLooper());
1074 setfield_bool_if(L, "pathEffect", !!paint->getPathEffect());
1075 setfield_bool_if(L, "rasterizer", !!paint->getRasterizer());
1076 setfield_bool_if(L, "maskFilter", !!paint->getMaskFilter());
1077 setfield_bool_if(L, "shader", !!paint->getShader());
reed@google.com29563872013-07-10 21:23:49 +00001078 setfield_bool_if(L, "colorFilter", !!paint->getColorFilter());
1079 setfield_bool_if(L, "imageFilter", !!paint->getImageFilter());
reed468b1812014-10-19 11:42:54 -07001080 setfield_bool_if(L, "xfermode", !!paint->getXfermode());
reed@google.com29563872013-07-10 21:23:49 +00001081 return 1;
1082}
1083
reed22a517f2015-12-04 20:45:59 -08001084static int lpaint_getColorFilter(lua_State* L) {
1085 const SkPaint* paint = get_obj<SkPaint>(L, 1);
1086 SkColorFilter* cf = paint->getColorFilter();
1087 if (cf) {
1088 push_ref(L, cf);
1089 return 1;
1090 }
1091 return 0;
1092}
1093
1094static int lpaint_setColorFilter(lua_State* L) {
1095 SkPaint* paint = get_obj<SkPaint>(L, 1);
1096 paint->setColorFilter(get_ref<SkColorFilter>(L, 2));
1097 return 0;
1098}
1099
reed468b1812014-10-19 11:42:54 -07001100static int lpaint_getImageFilter(lua_State* L) {
1101 const SkPaint* paint = get_obj<SkPaint>(L, 1);
1102 SkImageFilter* imf = paint->getImageFilter();
1103 if (imf) {
1104 push_ref(L, imf);
1105 return 1;
1106 }
1107 return 0;
1108}
1109
1110static int lpaint_setImageFilter(lua_State* L) {
1111 SkPaint* paint = get_obj<SkPaint>(L, 1);
1112 paint->setImageFilter(get_ref<SkImageFilter>(L, 2));
1113 return 0;
1114}
1115
reed@google.com5fdc9832013-07-24 15:47:52 +00001116static int lpaint_getShader(lua_State* L) {
1117 const SkPaint* paint = get_obj<SkPaint>(L, 1);
1118 SkShader* shader = paint->getShader();
1119 if (shader) {
1120 push_ref(L, shader);
1121 return 1;
1122 }
1123 return 0;
1124}
1125
reed9fbc3f32014-10-21 07:12:58 -07001126static int lpaint_setShader(lua_State* L) {
1127 SkPaint* paint = get_obj<SkPaint>(L, 1);
1128 paint->setShader(get_ref<SkShader>(L, 2));
1129 return 0;
1130}
1131
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001132static int lpaint_getPathEffect(lua_State* L) {
1133 const SkPaint* paint = get_obj<SkPaint>(L, 1);
1134 SkPathEffect* pe = paint->getPathEffect();
1135 if (pe) {
1136 push_ref(L, pe);
1137 return 1;
1138 }
1139 return 0;
1140}
1141
reed@google.com74ce6f02013-05-22 15:13:18 +00001142static int lpaint_gc(lua_State* L) {
1143 get_obj<SkPaint>(L, 1)->~SkPaint();
1144 return 0;
1145}
1146
1147static const struct luaL_Reg gSkPaint_Methods[] = {
1148 { "isAntiAlias", lpaint_isAntiAlias },
1149 { "setAntiAlias", lpaint_setAntiAlias },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001150 { "isDither", lpaint_isDither },
reedbb8a0ab2014-11-03 22:32:07 -08001151 { "setDither", lpaint_setDither },
reed93a12152015-03-16 10:08:34 -07001152 { "getFilterQuality", lpaint_getFilterQuality },
1153 { "setFilterQuality", lpaint_setFilterQuality },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001154 { "isUnderlineText", lpaint_isUnderlineText },
1155 { "isStrikeThruText", lpaint_isStrikeThruText },
1156 { "isFakeBoldText", lpaint_isFakeBoldText },
1157 { "isLinearText", lpaint_isLinearText },
1158 { "isSubpixelText", lpaint_isSubpixelText },
reed09a1d672014-10-11 13:13:11 -07001159 { "setSubpixelText", lpaint_setSubpixelText },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001160 { "isDevKernText", lpaint_isDevKernText },
1161 { "isLCDRenderText", lpaint_isLCDRenderText },
reed36c9c112014-11-04 10:58:42 -08001162 { "setLCDRenderText", lpaint_setLCDRenderText },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001163 { "isEmbeddedBitmapText", lpaint_isEmbeddedBitmapText },
1164 { "isAutohinted", lpaint_isAutohinted },
1165 { "isVerticalText", lpaint_isVerticalText },
reed468b1812014-10-19 11:42:54 -07001166 { "getAlpha", lpaint_getAlpha },
1167 { "setAlpha", lpaint_setAlpha },
reed@google.com74ce6f02013-05-22 15:13:18 +00001168 { "getColor", lpaint_getColor },
1169 { "setColor", lpaint_setColor },
reed@google.come3823fd2013-05-30 18:55:14 +00001170 { "getTextSize", lpaint_getTextSize },
1171 { "setTextSize", lpaint_setTextSize },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001172 { "getTextScaleX", lpaint_getTextScaleX },
1173 { "getTextSkewX", lpaint_getTextSkewX },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001174 { "getTypeface", lpaint_getTypeface },
1175 { "setTypeface", lpaint_setTypeface },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001176 { "getHinting", lpaint_getHinting },
reed@google.come3823fd2013-05-30 18:55:14 +00001177 { "getFontID", lpaint_getFontID },
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001178 { "getTextAlign", lpaint_getTextAlign },
1179 { "setTextAlign", lpaint_setTextAlign },
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +00001180 { "getStroke", lpaint_getStroke },
1181 { "setStroke", lpaint_setStroke },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001182 { "getStrokeCap", lpaint_getStrokeCap },
1183 { "getStrokeJoin", lpaint_getStrokeJoin },
1184 { "getTextEncoding", lpaint_getTextEncoding },
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +00001185 { "getStrokeWidth", lpaint_getStrokeWidth },
1186 { "setStrokeWidth", lpaint_setStrokeWidth },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001187 { "getStrokeMiter", lpaint_getStrokeMiter },
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +00001188 { "measureText", lpaint_measureText },
1189 { "getFontMetrics", lpaint_getFontMetrics },
reed@google.com29563872013-07-10 21:23:49 +00001190 { "getEffects", lpaint_getEffects },
reed22a517f2015-12-04 20:45:59 -08001191 { "getColorFilter", lpaint_getColorFilter },
1192 { "setColorFilter", lpaint_setColorFilter },
reed468b1812014-10-19 11:42:54 -07001193 { "getImageFilter", lpaint_getImageFilter },
1194 { "setImageFilter", lpaint_setImageFilter },
reed@google.com5fdc9832013-07-24 15:47:52 +00001195 { "getShader", lpaint_getShader },
reed9fbc3f32014-10-21 07:12:58 -07001196 { "setShader", lpaint_setShader },
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001197 { "getPathEffect", lpaint_getPathEffect },
reed@google.com74ce6f02013-05-22 15:13:18 +00001198 { "__gc", lpaint_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001199 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001200};
1201
1202///////////////////////////////////////////////////////////////////////////////
1203
reed@google.com5fdc9832013-07-24 15:47:52 +00001204static const char* mode2string(SkShader::TileMode mode) {
1205 static const char* gNames[] = { "clamp", "repeat", "mirror" };
1206 SkASSERT((unsigned)mode < SK_ARRAY_COUNT(gNames));
1207 return gNames[mode];
1208}
1209
1210static const char* gradtype2string(SkShader::GradientType t) {
1211 static const char* gNames[] = {
1212 "none", "color", "linear", "radial", "radial2", "sweep", "conical"
1213 };
1214 SkASSERT((unsigned)t < SK_ARRAY_COUNT(gNames));
1215 return gNames[t];
1216}
1217
1218static int lshader_isOpaque(lua_State* L) {
1219 SkShader* shader = get_ref<SkShader>(L, 1);
1220 return shader && shader->isOpaque();
1221}
1222
reedf5822822015-08-19 11:46:38 -07001223static int lshader_isABitmap(lua_State* L) {
reed@google.com5fdc9832013-07-24 15:47:52 +00001224 SkShader* shader = get_ref<SkShader>(L, 1);
1225 if (shader) {
1226 SkBitmap bm;
1227 SkMatrix matrix;
1228 SkShader::TileMode modes[2];
reedf5822822015-08-19 11:46:38 -07001229 if (shader->isABitmap(&bm, &matrix, modes)) {
1230 lua_newtable(L);
1231 setfield_number(L, "genID", bm.pixelRef() ? bm.pixelRef()->getGenerationID() : 0);
1232 setfield_number(L, "width", bm.width());
1233 setfield_number(L, "height", bm.height());
1234 setfield_string(L, "tileX", mode2string(modes[0]));
1235 setfield_string(L, "tileY", mode2string(modes[1]));
1236 return 1;
reed@google.com5fdc9832013-07-24 15:47:52 +00001237 }
1238 }
1239 return 0;
1240}
1241
1242static int lshader_asAGradient(lua_State* L) {
1243 SkShader* shader = get_ref<SkShader>(L, 1);
1244 if (shader) {
1245 SkShader::GradientInfo info;
1246 sk_bzero(&info, sizeof(info));
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001247
1248 SkColor colors[3]; // hacked in for extracting info on 3 color case.
skia.committer@gmail.combd74add2013-08-02 07:00:59 +00001249 SkScalar pos[3];
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001250
1251 info.fColorCount = 3;
1252 info.fColors = &colors[0];
1253 info.fColorOffsets = &pos[0];
skia.committer@gmail.combd74add2013-08-02 07:00:59 +00001254
reed@google.com5fdc9832013-07-24 15:47:52 +00001255 SkShader::GradientType t = shader->asAGradient(&info);
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001256
reed@google.com5fdc9832013-07-24 15:47:52 +00001257 if (SkShader::kNone_GradientType != t) {
1258 lua_newtable(L);
1259 setfield_string(L, "type", gradtype2string(t));
1260 setfield_number(L, "colorCount", info.fColorCount);
1261 setfield_string(L, "tile", mode2string(info.fTileMode));
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001262
1263 if (info.fColorCount == 3){
1264 setfield_number(L, "midPos", pos[1]);
1265 }
skia.committer@gmail.combd74add2013-08-02 07:00:59 +00001266
reed@google.com5fdc9832013-07-24 15:47:52 +00001267 return 1;
1268 }
1269 }
1270 return 0;
1271}
1272
1273static int lshader_gc(lua_State* L) {
1274 get_ref<SkShader>(L, 1)->unref();
1275 return 0;
1276}
1277
1278static const struct luaL_Reg gSkShader_Methods[] = {
1279 { "isOpaque", lshader_isOpaque },
reedf5822822015-08-19 11:46:38 -07001280 { "isABitmap", lshader_isABitmap },
reed@google.com5fdc9832013-07-24 15:47:52 +00001281 { "asAGradient", lshader_asAGradient },
1282 { "__gc", lshader_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001283 { nullptr, nullptr }
reed@google.com5fdc9832013-07-24 15:47:52 +00001284};
1285
1286///////////////////////////////////////////////////////////////////////////////
1287
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +00001288static int lpatheffect_asADash(lua_State* L) {
1289 SkPathEffect* pe = get_ref<SkPathEffect>(L, 1);
1290 if (pe) {
1291 SkPathEffect::DashInfo info;
1292 SkPathEffect::DashType dashType = pe->asADash(&info);
1293 if (SkPathEffect::kDash_DashType == dashType) {
1294 SkAutoTArray<SkScalar> intervals(info.fCount);
1295 info.fIntervals = intervals.get();
1296 pe->asADash(&info);
1297 SkLua(L).pushDash(info);
1298 return 1;
1299 }
1300 }
1301 return 0;
1302}
1303
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001304static int lpatheffect_gc(lua_State* L) {
1305 get_ref<SkPathEffect>(L, 1)->unref();
1306 return 0;
1307}
1308
1309static const struct luaL_Reg gSkPathEffect_Methods[] = {
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +00001310 { "asADash", lpatheffect_asADash },
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001311 { "__gc", lpatheffect_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001312 { nullptr, nullptr }
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001313};
1314
1315///////////////////////////////////////////////////////////////////////////////
1316
reed22a517f2015-12-04 20:45:59 -08001317static int lpcolorfilter_gc(lua_State* L) {
1318 get_ref<SkColorFilter>(L, 1)->unref();
1319 return 0;
1320}
1321
1322static const struct luaL_Reg gSkColorFilter_Methods[] = {
1323 { "__gc", lpcolorfilter_gc },
1324 { nullptr, nullptr }
1325};
1326
1327///////////////////////////////////////////////////////////////////////////////
1328
reed468b1812014-10-19 11:42:54 -07001329static int lpimagefilter_gc(lua_State* L) {
1330 get_ref<SkImageFilter>(L, 1)->unref();
1331 return 0;
1332}
1333
1334static const struct luaL_Reg gSkImageFilter_Methods[] = {
1335 { "__gc", lpimagefilter_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001336 { nullptr, nullptr }
reed468b1812014-10-19 11:42:54 -07001337};
1338
1339///////////////////////////////////////////////////////////////////////////////
1340
humper@google.com2815c192013-07-10 22:42:30 +00001341static int lmatrix_getType(lua_State* L) {
1342 SkMatrix::TypeMask mask = get_obj<SkMatrix>(L, 1)->getType();
skia.committer@gmail.comde2e4e82013-07-11 07:01:01 +00001343
humper@google.com2815c192013-07-10 22:42:30 +00001344 lua_newtable(L);
1345 setfield_boolean(L, "translate", SkToBool(mask & SkMatrix::kTranslate_Mask));
1346 setfield_boolean(L, "scale", SkToBool(mask & SkMatrix::kScale_Mask));
1347 setfield_boolean(L, "affine", SkToBool(mask & SkMatrix::kAffine_Mask));
1348 setfield_boolean(L, "perspective", SkToBool(mask & SkMatrix::kPerspective_Mask));
1349 return 1;
1350}
1351
humper@google.com0f48ee02013-07-26 15:23:43 +00001352static int lmatrix_getScaleX(lua_State* L) {
1353 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getScaleX());
1354 return 1;
1355}
1356
1357static int lmatrix_getScaleY(lua_State* L) {
1358 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getScaleY());
1359 return 1;
1360}
1361
1362static int lmatrix_getTranslateX(lua_State* L) {
1363 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getTranslateX());
1364 return 1;
1365}
1366
1367static int lmatrix_getTranslateY(lua_State* L) {
1368 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getTranslateY());
1369 return 1;
1370}
1371
reed7a72c672014-11-07 10:23:55 -08001372static int lmatrix_invert(lua_State* L) {
1373 lua_pushboolean(L, get_obj<SkMatrix>(L, 1)->invert(get_obj<SkMatrix>(L, 2)));
1374 return 1;
1375}
1376
1377static int lmatrix_mapXY(lua_State* L) {
1378 SkPoint pt = { lua2scalar(L, 2), lua2scalar(L, 3) };
1379 get_obj<SkMatrix>(L, 1)->mapPoints(&pt, &pt, 1);
1380 lua_pushnumber(L, pt.x());
1381 lua_pushnumber(L, pt.y());
1382 return 2;
1383}
1384
reedbdc49ae2014-10-14 09:34:52 -07001385static int lmatrix_setRectToRect(lua_State* L) {
1386 SkMatrix* matrix = get_obj<SkMatrix>(L, 1);
1387 SkRect srcR, dstR;
1388 lua2rect(L, 2, &srcR);
1389 lua2rect(L, 3, &dstR);
1390 const char* scaleToFitStr = lua_tostring(L, 4);
1391 SkMatrix::ScaleToFit scaleToFit = SkMatrix::kFill_ScaleToFit;
1392
1393 if (scaleToFitStr) {
1394 const struct {
1395 const char* fName;
1396 SkMatrix::ScaleToFit fScaleToFit;
1397 } rec[] = {
1398 { "fill", SkMatrix::kFill_ScaleToFit },
1399 { "start", SkMatrix::kStart_ScaleToFit },
1400 { "center", SkMatrix::kCenter_ScaleToFit },
1401 { "end", SkMatrix::kEnd_ScaleToFit },
1402 };
1403
1404 for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
1405 if (strcmp(rec[i].fName, scaleToFitStr) == 0) {
1406 scaleToFit = rec[i].fScaleToFit;
1407 break;
1408 }
1409 }
1410 }
1411
1412 matrix->setRectToRect(srcR, dstR, scaleToFit);
1413 return 0;
1414}
1415
humper@google.com2815c192013-07-10 22:42:30 +00001416static const struct luaL_Reg gSkMatrix_Methods[] = {
1417 { "getType", lmatrix_getType },
humper@google.com0f48ee02013-07-26 15:23:43 +00001418 { "getScaleX", lmatrix_getScaleX },
1419 { "getScaleY", lmatrix_getScaleY },
1420 { "getTranslateX", lmatrix_getTranslateX },
1421 { "getTranslateY", lmatrix_getTranslateY },
reedbdc49ae2014-10-14 09:34:52 -07001422 { "setRectToRect", lmatrix_setRectToRect },
reed7a72c672014-11-07 10:23:55 -08001423 { "invert", lmatrix_invert },
1424 { "mapXY", lmatrix_mapXY },
halcanary96fcdcc2015-08-27 07:41:13 -07001425 { nullptr, nullptr }
humper@google.com2815c192013-07-10 22:42:30 +00001426};
1427
1428///////////////////////////////////////////////////////////////////////////////
1429
reed@google.com74ce6f02013-05-22 15:13:18 +00001430static int lpath_getBounds(lua_State* L) {
1431 SkLua(L).pushRect(get_obj<SkPath>(L, 1)->getBounds());
1432 return 1;
1433}
1434
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001435static const char* fill_type_to_str(SkPath::FillType fill) {
1436 switch (fill) {
1437 case SkPath::kEvenOdd_FillType:
1438 return "even-odd";
1439 case SkPath::kWinding_FillType:
1440 return "winding";
1441 case SkPath::kInverseEvenOdd_FillType:
1442 return "inverse-even-odd";
1443 case SkPath::kInverseWinding_FillType:
1444 return "inverse-winding";
1445 }
1446 return "unknown";
1447}
1448
1449static int lpath_getFillType(lua_State* L) {
1450 SkPath::FillType fill = get_obj<SkPath>(L, 1)->getFillType();
1451 SkLua(L).pushString(fill_type_to_str(fill));
1452 return 1;
1453}
1454
1455static SkString segment_masks_to_str(uint32_t segmentMasks) {
1456 SkString result;
1457 bool first = true;
1458 if (SkPath::kLine_SegmentMask & segmentMasks) {
1459 result.append("line");
1460 first = false;
1461 SkDEBUGCODE(segmentMasks &= ~SkPath::kLine_SegmentMask;)
1462 }
1463 if (SkPath::kQuad_SegmentMask & segmentMasks) {
1464 if (!first) {
1465 result.append(" ");
1466 }
1467 result.append("quad");
1468 first = false;
1469 SkDEBUGCODE(segmentMasks &= ~SkPath::kQuad_SegmentMask;)
1470 }
1471 if (SkPath::kConic_SegmentMask & segmentMasks) {
1472 if (!first) {
1473 result.append(" ");
1474 }
1475 result.append("conic");
1476 first = false;
1477 SkDEBUGCODE(segmentMasks &= ~SkPath::kConic_SegmentMask;)
1478 }
1479 if (SkPath::kCubic_SegmentMask & segmentMasks) {
1480 if (!first) {
1481 result.append(" ");
1482 }
1483 result.append("cubic");
1484 SkDEBUGCODE(segmentMasks &= ~SkPath::kCubic_SegmentMask;)
1485 }
1486 SkASSERT(0 == segmentMasks);
1487 return result;
1488}
1489
krajcevski95498ed2014-08-18 08:02:33 -07001490static int lpath_getSegmentTypes(lua_State* L) {
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001491 uint32_t segMasks = get_obj<SkPath>(L, 1)->getSegmentMasks();
1492 SkLua(L).pushString(segment_masks_to_str(segMasks));
1493 return 1;
1494}
1495
1496static int lpath_isConvex(lua_State* L) {
1497 bool isConvex = SkPath::kConvex_Convexity == get_obj<SkPath>(L, 1)->getConvexity();
1498 SkLua(L).pushBool(isConvex);
1499 return 1;
1500}
1501
reed@google.com74ce6f02013-05-22 15:13:18 +00001502static int lpath_isEmpty(lua_State* L) {
1503 lua_pushboolean(L, get_obj<SkPath>(L, 1)->isEmpty());
1504 return 1;
1505}
1506
1507static int lpath_isRect(lua_State* L) {
1508 SkRect r;
1509 bool pred = get_obj<SkPath>(L, 1)->isRect(&r);
1510 int ret_count = 1;
1511 lua_pushboolean(L, pred);
1512 if (pred) {
1513 SkLua(L).pushRect(r);
1514 ret_count += 1;
1515 }
1516 return ret_count;
1517}
1518
1519static const char* dir2string(SkPath::Direction dir) {
1520 static const char* gStr[] = {
1521 "unknown", "cw", "ccw"
1522 };
1523 SkASSERT((unsigned)dir < SK_ARRAY_COUNT(gStr));
1524 return gStr[dir];
1525}
1526
caryclark95bc5f32015-04-08 08:34:15 -07001527static int lpath_isNestedFillRects(lua_State* L) {
reed@google.com74ce6f02013-05-22 15:13:18 +00001528 SkRect rects[2];
1529 SkPath::Direction dirs[2];
caryclark95bc5f32015-04-08 08:34:15 -07001530 bool pred = get_obj<SkPath>(L, 1)->isNestedFillRects(rects, dirs);
reed@google.com74ce6f02013-05-22 15:13:18 +00001531 int ret_count = 1;
1532 lua_pushboolean(L, pred);
1533 if (pred) {
1534 SkLua lua(L);
1535 lua.pushRect(rects[0]);
1536 lua.pushRect(rects[1]);
1537 lua_pushstring(L, dir2string(dirs[0]));
1538 lua_pushstring(L, dir2string(dirs[0]));
1539 ret_count += 4;
1540 }
1541 return ret_count;
1542}
1543
commit-bot@chromium.orgc5302082014-02-26 21:38:47 +00001544static int lpath_countPoints(lua_State* L) {
1545 lua_pushinteger(L, get_obj<SkPath>(L, 1)->countPoints());
1546 return 1;
1547}
1548
reed@google.com74ce6f02013-05-22 15:13:18 +00001549static int lpath_reset(lua_State* L) {
1550 get_obj<SkPath>(L, 1)->reset();
1551 return 0;
1552}
1553
1554static int lpath_moveTo(lua_State* L) {
1555 get_obj<SkPath>(L, 1)->moveTo(lua2scalar(L, 2), lua2scalar(L, 3));
1556 return 0;
1557}
1558
1559static int lpath_lineTo(lua_State* L) {
1560 get_obj<SkPath>(L, 1)->lineTo(lua2scalar(L, 2), lua2scalar(L, 3));
1561 return 0;
1562}
1563
1564static int lpath_quadTo(lua_State* L) {
1565 get_obj<SkPath>(L, 1)->quadTo(lua2scalar(L, 2), lua2scalar(L, 3),
1566 lua2scalar(L, 4), lua2scalar(L, 5));
1567 return 0;
1568}
1569
1570static int lpath_cubicTo(lua_State* L) {
1571 get_obj<SkPath>(L, 1)->cubicTo(lua2scalar(L, 2), lua2scalar(L, 3),
1572 lua2scalar(L, 4), lua2scalar(L, 5),
1573 lua2scalar(L, 6), lua2scalar(L, 7));
1574 return 0;
1575}
1576
1577static int lpath_close(lua_State* L) {
1578 get_obj<SkPath>(L, 1)->close();
1579 return 0;
1580}
1581
1582static int lpath_gc(lua_State* L) {
1583 get_obj<SkPath>(L, 1)->~SkPath();
1584 return 0;
1585}
1586
1587static const struct luaL_Reg gSkPath_Methods[] = {
1588 { "getBounds", lpath_getBounds },
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001589 { "getFillType", lpath_getFillType },
krajcevski95498ed2014-08-18 08:02:33 -07001590 { "getSegmentTypes", lpath_getSegmentTypes },
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001591 { "isConvex", lpath_isConvex },
reed@google.com74ce6f02013-05-22 15:13:18 +00001592 { "isEmpty", lpath_isEmpty },
1593 { "isRect", lpath_isRect },
caryclark95bc5f32015-04-08 08:34:15 -07001594 { "isNestedFillRects", lpath_isNestedFillRects },
commit-bot@chromium.orgc5302082014-02-26 21:38:47 +00001595 { "countPoints", lpath_countPoints },
reed@google.com74ce6f02013-05-22 15:13:18 +00001596 { "reset", lpath_reset },
1597 { "moveTo", lpath_moveTo },
1598 { "lineTo", lpath_lineTo },
1599 { "quadTo", lpath_quadTo },
1600 { "cubicTo", lpath_cubicTo },
1601 { "close", lpath_close },
1602 { "__gc", lpath_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001603 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001604};
1605
1606///////////////////////////////////////////////////////////////////////////////
1607
1608static const char* rrect_type(const SkRRect& rr) {
1609 switch (rr.getType()) {
reed@google.com74ce6f02013-05-22 15:13:18 +00001610 case SkRRect::kEmpty_Type: return "empty";
1611 case SkRRect::kRect_Type: return "rect";
1612 case SkRRect::kOval_Type: return "oval";
1613 case SkRRect::kSimple_Type: return "simple";
commit-bot@chromium.orgf338d7c2014-03-17 21:17:30 +00001614 case SkRRect::kNinePatch_Type: return "nine-patch";
reed@google.com74ce6f02013-05-22 15:13:18 +00001615 case SkRRect::kComplex_Type: return "complex";
1616 }
mtklein@google.com330313a2013-08-22 15:37:26 +00001617 SkDEBUGFAIL("never get here");
reed@google.com74ce6f02013-05-22 15:13:18 +00001618 return "";
1619}
1620
1621static int lrrect_rect(lua_State* L) {
1622 SkLua(L).pushRect(get_obj<SkRRect>(L, 1)->rect());
1623 return 1;
1624}
1625
1626static int lrrect_type(lua_State* L) {
1627 lua_pushstring(L, rrect_type(*get_obj<SkRRect>(L, 1)));
1628 return 1;
1629}
1630
1631static int lrrect_radii(lua_State* L) {
reed@google.com7fa2a652014-01-27 13:42:58 +00001632 int corner = SkToInt(lua_tointeger(L, 2));
reed@google.com74ce6f02013-05-22 15:13:18 +00001633 SkVector v;
1634 if (corner < 0 || corner > 3) {
1635 SkDebugf("bad corner index %d", corner);
1636 v.set(0, 0);
1637 } else {
1638 v = get_obj<SkRRect>(L, 1)->radii((SkRRect::Corner)corner);
1639 }
1640 lua_pushnumber(L, v.fX);
1641 lua_pushnumber(L, v.fY);
1642 return 2;
1643}
1644
1645static int lrrect_gc(lua_State* L) {
1646 get_obj<SkRRect>(L, 1)->~SkRRect();
1647 return 0;
1648}
1649
1650static const struct luaL_Reg gSkRRect_Methods[] = {
1651 { "rect", lrrect_rect },
1652 { "type", lrrect_type },
1653 { "radii", lrrect_radii },
1654 { "__gc", lrrect_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001655 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001656};
1657
1658///////////////////////////////////////////////////////////////////////////////
1659
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001660static int limage_width(lua_State* L) {
1661 lua_pushinteger(L, get_ref<SkImage>(L, 1)->width());
1662 return 1;
1663}
1664
1665static int limage_height(lua_State* L) {
1666 lua_pushinteger(L, get_ref<SkImage>(L, 1)->height());
1667 return 1;
1668}
1669
reed7a72c672014-11-07 10:23:55 -08001670static int limage_newShader(lua_State* L) {
1671 SkShader::TileMode tmode = SkShader::kClamp_TileMode;
halcanary96fcdcc2015-08-27 07:41:13 -07001672 const SkMatrix* localM = nullptr;
reed7a72c672014-11-07 10:23:55 -08001673 SkAutoTUnref<SkShader> shader(get_ref<SkImage>(L, 1)->newShader(tmode, tmode, localM));
1674 push_ref(L, shader.get());
1675 return 1;
1676}
1677
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001678static int limage_gc(lua_State* L) {
1679 get_ref<SkImage>(L, 1)->unref();
1680 return 0;
1681}
1682
1683static const struct luaL_Reg gSkImage_Methods[] = {
1684 { "width", limage_width },
1685 { "height", limage_height },
reed7a72c672014-11-07 10:23:55 -08001686 { "newShader", limage_newShader },
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001687 { "__gc", limage_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001688 { nullptr, nullptr }
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001689};
1690
1691///////////////////////////////////////////////////////////////////////////////
1692
reed485557f2014-10-12 10:36:47 -07001693static int lsurface_width(lua_State* L) {
1694 lua_pushinteger(L, get_ref<SkSurface>(L, 1)->width());
1695 return 1;
1696}
1697
1698static int lsurface_height(lua_State* L) {
1699 lua_pushinteger(L, get_ref<SkSurface>(L, 1)->height());
1700 return 1;
1701}
1702
1703static int lsurface_getCanvas(lua_State* L) {
1704 SkCanvas* canvas = get_ref<SkSurface>(L, 1)->getCanvas();
halcanary96fcdcc2015-08-27 07:41:13 -07001705 if (nullptr == canvas) {
reed485557f2014-10-12 10:36:47 -07001706 lua_pushnil(L);
1707 } else {
1708 push_ref(L, canvas);
1709 // note: we don't unref canvas, since getCanvas did not ref it.
1710 // warning: this is weird: now Lua owns a ref on this canvas, but what if they let
1711 // the real owner (the surface) go away, but still hold onto the canvas?
1712 // *really* we want to sort of ref the surface again, but have the native object
1713 // know that it is supposed to be treated as a canvas...
1714 }
1715 return 1;
1716}
1717
1718static int lsurface_newImageSnapshot(lua_State* L) {
1719 SkImage* image = get_ref<SkSurface>(L, 1)->newImageSnapshot();
halcanary96fcdcc2015-08-27 07:41:13 -07001720 if (nullptr == image) {
reed485557f2014-10-12 10:36:47 -07001721 lua_pushnil(L);
1722 } else {
reed9fbc3f32014-10-21 07:12:58 -07001723 push_ref(L, image)->unref();
reed485557f2014-10-12 10:36:47 -07001724 }
1725 return 1;
1726}
1727
1728static int lsurface_newSurface(lua_State* L) {
1729 int width = lua2int_def(L, 2, 0);
reed96affcd2014-10-13 12:38:04 -07001730 int height = lua2int_def(L, 3, 0);
reed485557f2014-10-12 10:36:47 -07001731 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
1732 SkSurface* surface = get_ref<SkSurface>(L, 1)->newSurface(info);
halcanary96fcdcc2015-08-27 07:41:13 -07001733 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -07001734 lua_pushnil(L);
1735 } else {
reed9fbc3f32014-10-21 07:12:58 -07001736 push_ref(L, surface)->unref();
reed485557f2014-10-12 10:36:47 -07001737 }
1738 return 1;
1739}
1740
1741static int lsurface_gc(lua_State* L) {
1742 get_ref<SkSurface>(L, 1)->unref();
1743 return 0;
1744}
1745
1746static const struct luaL_Reg gSkSurface_Methods[] = {
1747 { "width", lsurface_width },
1748 { "height", lsurface_height },
1749 { "getCanvas", lsurface_getCanvas },
1750 { "newImageSnapshot", lsurface_newImageSnapshot },
1751 { "newSurface", lsurface_newSurface },
1752 { "__gc", lsurface_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001753 { nullptr, nullptr }
reed485557f2014-10-12 10:36:47 -07001754};
1755
1756///////////////////////////////////////////////////////////////////////////////
1757
reed96affcd2014-10-13 12:38:04 -07001758static int lpicturerecorder_beginRecording(lua_State* L) {
1759 const SkScalar w = lua2scalar_def(L, 2, -1);
1760 const SkScalar h = lua2scalar_def(L, 3, -1);
1761 if (w <= 0 || h <= 0) {
1762 lua_pushnil(L);
1763 return 1;
1764 }
1765
1766 SkCanvas* canvas = get_obj<SkPictureRecorder>(L, 1)->beginRecording(w, h);
halcanary96fcdcc2015-08-27 07:41:13 -07001767 if (nullptr == canvas) {
reed96affcd2014-10-13 12:38:04 -07001768 lua_pushnil(L);
1769 return 1;
1770 }
1771
1772 push_ref(L, canvas);
1773 return 1;
1774}
1775
1776static int lpicturerecorder_getCanvas(lua_State* L) {
1777 SkCanvas* canvas = get_obj<SkPictureRecorder>(L, 1)->getRecordingCanvas();
halcanary96fcdcc2015-08-27 07:41:13 -07001778 if (nullptr == canvas) {
reed96affcd2014-10-13 12:38:04 -07001779 lua_pushnil(L);
1780 return 1;
1781 }
1782 push_ref(L, canvas);
1783 return 1;
1784}
1785
1786static int lpicturerecorder_endRecording(lua_State* L) {
1787 SkPicture* pic = get_obj<SkPictureRecorder>(L, 1)->endRecording();
halcanary96fcdcc2015-08-27 07:41:13 -07001788 if (nullptr == pic) {
reed96affcd2014-10-13 12:38:04 -07001789 lua_pushnil(L);
1790 return 1;
1791 }
reed9fbc3f32014-10-21 07:12:58 -07001792 push_ref(L, pic)->unref();
reed96affcd2014-10-13 12:38:04 -07001793 return 1;
1794}
1795
1796static int lpicturerecorder_gc(lua_State* L) {
1797 get_obj<SkPictureRecorder>(L, 1)->~SkPictureRecorder();
1798 return 0;
1799}
1800
1801static const struct luaL_Reg gSkPictureRecorder_Methods[] = {
1802 { "beginRecording", lpicturerecorder_beginRecording },
1803 { "getCanvas", lpicturerecorder_getCanvas },
1804 { "endRecording", lpicturerecorder_endRecording },
1805 { "__gc", lpicturerecorder_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001806 { nullptr, nullptr }
reed96affcd2014-10-13 12:38:04 -07001807};
1808
1809///////////////////////////////////////////////////////////////////////////////
1810
1811static int lpicture_width(lua_State* L) {
1812 lua_pushnumber(L, get_ref<SkPicture>(L, 1)->cullRect().width());
1813 return 1;
1814}
1815
1816static int lpicture_height(lua_State* L) {
1817 lua_pushnumber(L, get_ref<SkPicture>(L, 1)->cullRect().height());
1818 return 1;
1819}
1820
1821static int lpicture_gc(lua_State* L) {
1822 get_ref<SkPicture>(L, 1)->unref();
1823 return 0;
1824}
1825
1826static const struct luaL_Reg gSkPicture_Methods[] = {
1827 { "width", lpicture_width },
1828 { "height", lpicture_height },
1829 { "__gc", lpicture_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001830 { nullptr, nullptr }
reed96affcd2014-10-13 12:38:04 -07001831};
1832
1833///////////////////////////////////////////////////////////////////////////////
1834
reed1b6ab442014-11-03 19:55:41 -08001835static int ltextblob_bounds(lua_State* L) {
1836 SkLua(L).pushRect(get_ref<SkTextBlob>(L, 1)->bounds());
1837 return 1;
1838}
1839
1840static int ltextblob_gc(lua_State* L) {
1841 SkSafeUnref(get_ref<SkTextBlob>(L, 1));
1842 return 0;
1843}
1844
1845static const struct luaL_Reg gSkTextBlob_Methods[] = {
1846 { "bounds", ltextblob_bounds },
1847 { "__gc", ltextblob_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001848 { nullptr, nullptr }
reed1b6ab442014-11-03 19:55:41 -08001849};
1850
1851///////////////////////////////////////////////////////////////////////////////
1852
reed36c9c112014-11-04 10:58:42 -08001853static int ltypeface_getFamilyName(lua_State* L) {
1854 SkString str;
1855 get_ref<SkTypeface>(L, 1)->getFamilyName(&str);
1856 lua_pushstring(L, str.c_str());
1857 return 1;
1858}
1859
1860static int ltypeface_getStyle(lua_State* L) {
1861 lua_pushnumber(L, (double)get_ref<SkTypeface>(L, 1)->style());
1862 return 1;
1863}
1864
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001865static int ltypeface_gc(lua_State* L) {
commit-bot@chromium.org77887af2013-12-17 14:28:19 +00001866 SkSafeUnref(get_ref<SkTypeface>(L, 1));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001867 return 0;
1868}
1869
1870static const struct luaL_Reg gSkTypeface_Methods[] = {
reed36c9c112014-11-04 10:58:42 -08001871 { "getFamilyName", ltypeface_getFamilyName },
1872 { "getStyle", ltypeface_getStyle },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001873 { "__gc", ltypeface_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001874 { nullptr, nullptr }
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001875};
1876
1877///////////////////////////////////////////////////////////////////////////////
1878
reed@google.com74ce6f02013-05-22 15:13:18 +00001879class AutoCallLua {
1880public:
1881 AutoCallLua(lua_State* L, const char func[], const char verb[]) : fL(L) {
1882 lua_getglobal(L, func);
1883 if (!lua_isfunction(L, -1)) {
1884 int t = lua_type(L, -1);
1885 SkDebugf("--- expected function %d\n", t);
1886 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001887
reed@google.com74ce6f02013-05-22 15:13:18 +00001888 lua_newtable(L);
1889 setfield_string(L, "verb", verb);
1890 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001891
reed@google.com74ce6f02013-05-22 15:13:18 +00001892 ~AutoCallLua() {
1893 if (lua_pcall(fL, 1, 0, 0) != LUA_OK) {
1894 SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
1895 }
1896 lua_settop(fL, -1);
1897 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001898
reed@google.com74ce6f02013-05-22 15:13:18 +00001899private:
1900 lua_State* fL;
1901};
1902
1903#define AUTO_LUA(verb) AutoCallLua acl(fL, fFunc.c_str(), verb)
1904
1905///////////////////////////////////////////////////////////////////////////////
1906
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001907static int lsk_newDocumentPDF(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07001908 const char* file = nullptr;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001909 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001910 file = lua_tolstring(L, 1, nullptr);
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001911 }
1912
1913 SkDocument* doc = SkDocument::CreatePDF(file);
halcanary96fcdcc2015-08-27 07:41:13 -07001914 if (nullptr == doc) {
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001915 // do I need to push a nil on the stack and return 1?
1916 return 0;
1917 } else {
reed9fbc3f32014-10-21 07:12:58 -07001918 push_ref(L, doc)->unref();
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001919 return 1;
1920 }
1921}
1922
reed468b1812014-10-19 11:42:54 -07001923static int lsk_newBlurImageFilter(lua_State* L) {
1924 SkScalar sigmaX = lua2scalar_def(L, 1, 0);
1925 SkScalar sigmaY = lua2scalar_def(L, 2, 0);
1926 SkImageFilter* imf = SkBlurImageFilter::Create(sigmaX, sigmaY);
halcanary96fcdcc2015-08-27 07:41:13 -07001927 if (nullptr == imf) {
reed468b1812014-10-19 11:42:54 -07001928 lua_pushnil(L);
1929 } else {
reed9fbc3f32014-10-21 07:12:58 -07001930 push_ref(L, imf)->unref();
1931 }
1932 return 1;
1933}
1934
1935static int lsk_newLinearGradient(lua_State* L) {
1936 SkScalar x0 = lua2scalar_def(L, 1, 0);
1937 SkScalar y0 = lua2scalar_def(L, 2, 0);
1938 SkColor c0 = lua2color(L, 3);
1939 SkScalar x1 = lua2scalar_def(L, 4, 0);
1940 SkScalar y1 = lua2scalar_def(L, 5, 0);
1941 SkColor c1 = lua2color(L, 6);
1942
1943 SkPoint pts[] = { { x0, y0 }, { x1, y1 } };
1944 SkColor colors[] = { c0, c1 };
halcanary96fcdcc2015-08-27 07:41:13 -07001945 SkShader* s = SkGradientShader::CreateLinear(pts, colors, nullptr, 2, SkShader::kClamp_TileMode);
1946 if (nullptr == s) {
reed9fbc3f32014-10-21 07:12:58 -07001947 lua_pushnil(L);
1948 } else {
1949 push_ref(L, s)->unref();
reed468b1812014-10-19 11:42:54 -07001950 }
1951 return 1;
1952}
1953
reedbdc49ae2014-10-14 09:34:52 -07001954static int lsk_newMatrix(lua_State* L) {
1955 push_new<SkMatrix>(L)->reset();
1956 return 1;
1957}
1958
reed@google.com3597b732013-05-22 20:12:50 +00001959static int lsk_newPaint(lua_State* L) {
1960 push_new<SkPaint>(L);
1961 return 1;
1962}
1963
1964static int lsk_newPath(lua_State* L) {
1965 push_new<SkPath>(L);
1966 return 1;
1967}
1968
reed96affcd2014-10-13 12:38:04 -07001969static int lsk_newPictureRecorder(lua_State* L) {
1970 push_new<SkPictureRecorder>(L);
1971 return 1;
1972}
1973
reed@google.com3597b732013-05-22 20:12:50 +00001974static int lsk_newRRect(lua_State* L) {
reedbdc49ae2014-10-14 09:34:52 -07001975 push_new<SkRRect>(L)->setEmpty();
reed@google.com3597b732013-05-22 20:12:50 +00001976 return 1;
1977}
1978
reed1b6ab442014-11-03 19:55:41 -08001979#include "SkTextBox.h"
1980// Sk.newTextBlob(text, rect, paint)
1981static int lsk_newTextBlob(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07001982 const char* text = lua_tolstring(L, 1, nullptr);
reed1b6ab442014-11-03 19:55:41 -08001983 SkRect bounds;
1984 lua2rect(L, 2, &bounds);
1985 const SkPaint& paint = *get_obj<SkPaint>(L, 3);
1986
1987 SkTextBox box;
1988 box.setMode(SkTextBox::kLineBreak_Mode);
1989 box.setBox(bounds);
1990 box.setText(text, strlen(text), paint);
1991
1992 SkScalar newBottom;
1993 SkAutoTUnref<SkTextBlob> blob(box.snapshotTextBlob(&newBottom));
1994 push_ref<SkTextBlob>(L, blob);
1995 SkLua(L).pushScalar(newBottom);
1996 return 2;
1997}
1998
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001999static int lsk_newTypeface(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07002000 const char* name = nullptr;
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00002001 int style = SkTypeface::kNormal;
skia.committer@gmail.com63193672013-06-08 07:01:13 +00002002
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00002003 int count = lua_gettop(L);
2004 if (count > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07002005 name = lua_tolstring(L, 1, nullptr);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00002006 if (count > 1 && lua_isnumber(L, 2)) {
halcanary96fcdcc2015-08-27 07:41:13 -07002007 style = lua_tointegerx(L, 2, nullptr) & SkTypeface::kBoldItalic;
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00002008 }
2009 }
2010
2011 SkTypeface* face = SkTypeface::CreateFromName(name,
2012 (SkTypeface::Style)style);
2013// SkDebugf("---- name <%s> style=%d, face=%p ref=%d\n", name, style, face, face->getRefCnt());
halcanary96fcdcc2015-08-27 07:41:13 -07002014 if (nullptr == face) {
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00002015 face = SkTypeface::RefDefault();
2016 }
reed9fbc3f32014-10-21 07:12:58 -07002017 push_ref(L, face)->unref();
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00002018 return 1;
2019}
reed@google.com3597b732013-05-22 20:12:50 +00002020
reed485557f2014-10-12 10:36:47 -07002021static int lsk_newRasterSurface(lua_State* L) {
reed7b864662014-11-04 13:24:47 -08002022 int width = lua2int_def(L, 1, 0);
reed485557f2014-10-12 10:36:47 -07002023 int height = lua2int_def(L, 2, 0);
2024 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
robertphillips702edbd2015-06-23 06:26:08 -07002025 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
2026 SkSurface* surface = SkSurface::NewRaster(info, &props);
halcanary96fcdcc2015-08-27 07:41:13 -07002027 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -07002028 lua_pushnil(L);
2029 } else {
reed9fbc3f32014-10-21 07:12:58 -07002030 push_ref(L, surface)->unref();
reed485557f2014-10-12 10:36:47 -07002031 }
2032 return 1;
2033}
2034
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00002035static int lsk_loadImage(lua_State* L) {
2036 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07002037 const char* name = lua_tolstring(L, 1, nullptr);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00002038 SkAutoDataUnref data(SkData::NewFromFileName(name));
2039 if (data.get()) {
reed871872f2015-06-22 12:48:26 -07002040 SkImage* image = SkImage::NewFromEncoded(data);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00002041 if (image) {
reed9fbc3f32014-10-21 07:12:58 -07002042 push_ref(L, image)->unref();
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00002043 return 1;
2044 }
2045 }
2046 }
2047 return 0;
2048}
2049
reed@google.com3597b732013-05-22 20:12:50 +00002050static void register_Sk(lua_State* L) {
2051 lua_newtable(L);
2052 lua_pushvalue(L, -1);
2053 lua_setglobal(L, "Sk");
2054 // the Sk table is still on top
2055
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00002056 setfield_function(L, "newDocumentPDF", lsk_newDocumentPDF);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00002057 setfield_function(L, "loadImage", lsk_loadImage);
reed468b1812014-10-19 11:42:54 -07002058 setfield_function(L, "newBlurImageFilter", lsk_newBlurImageFilter);
reed9fbc3f32014-10-21 07:12:58 -07002059 setfield_function(L, "newLinearGradient", lsk_newLinearGradient);
reedbdc49ae2014-10-14 09:34:52 -07002060 setfield_function(L, "newMatrix", lsk_newMatrix);
reed@google.com3597b732013-05-22 20:12:50 +00002061 setfield_function(L, "newPaint", lsk_newPaint);
2062 setfield_function(L, "newPath", lsk_newPath);
reed96affcd2014-10-13 12:38:04 -07002063 setfield_function(L, "newPictureRecorder", lsk_newPictureRecorder);
reed@google.com3597b732013-05-22 20:12:50 +00002064 setfield_function(L, "newRRect", lsk_newRRect);
reed485557f2014-10-12 10:36:47 -07002065 setfield_function(L, "newRasterSurface", lsk_newRasterSurface);
reed1b6ab442014-11-03 19:55:41 -08002066 setfield_function(L, "newTextBlob", lsk_newTextBlob);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00002067 setfield_function(L, "newTypeface", lsk_newTypeface);
reed@google.com3597b732013-05-22 20:12:50 +00002068 lua_pop(L, 1); // pop off the Sk table
2069}
2070
reed@google.com74ce6f02013-05-22 15:13:18 +00002071#define REG_CLASS(L, C) \
2072 do { \
reed@google.com3597b732013-05-22 20:12:50 +00002073 luaL_newmetatable(L, get_mtname<C>()); \
reed@google.com74ce6f02013-05-22 15:13:18 +00002074 lua_pushvalue(L, -1); \
2075 lua_setfield(L, -2, "__index"); \
2076 luaL_setfuncs(L, g##C##_Methods, 0); \
2077 lua_pop(L, 1); /* pop off the meta-table */ \
2078 } while (0)
2079
2080void SkLua::Load(lua_State* L) {
reed@google.com3597b732013-05-22 20:12:50 +00002081 register_Sk(L);
reed@google.com74ce6f02013-05-22 15:13:18 +00002082 REG_CLASS(L, SkCanvas);
reed22a517f2015-12-04 20:45:59 -08002083 REG_CLASS(L, SkColorFilter);
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00002084 REG_CLASS(L, SkDocument);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00002085 REG_CLASS(L, SkImage);
reed468b1812014-10-19 11:42:54 -07002086 REG_CLASS(L, SkImageFilter);
reed1b6ab442014-11-03 19:55:41 -08002087 REG_CLASS(L, SkMatrix);
reed@google.com74ce6f02013-05-22 15:13:18 +00002088 REG_CLASS(L, SkPaint);
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00002089 REG_CLASS(L, SkPath);
2090 REG_CLASS(L, SkPathEffect);
reed96affcd2014-10-13 12:38:04 -07002091 REG_CLASS(L, SkPicture);
2092 REG_CLASS(L, SkPictureRecorder);
reed@google.com74ce6f02013-05-22 15:13:18 +00002093 REG_CLASS(L, SkRRect);
reed@google.com5fdc9832013-07-24 15:47:52 +00002094 REG_CLASS(L, SkShader);
reed485557f2014-10-12 10:36:47 -07002095 REG_CLASS(L, SkSurface);
reed1b6ab442014-11-03 19:55:41 -08002096 REG_CLASS(L, SkTextBlob);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00002097 REG_CLASS(L, SkTypeface);
reed@google.com74ce6f02013-05-22 15:13:18 +00002098}
zachr@google.com28c27c82013-06-20 17:15:05 +00002099
reed@google.com7bce9982013-06-20 17:40:21 +00002100extern "C" int luaopen_skia(lua_State* L);
zachr@google.com28c27c82013-06-20 17:15:05 +00002101extern "C" int luaopen_skia(lua_State* L) {
2102 SkLua::Load(L);
2103 return 0;
2104}