blob: fa474b3b1398b9c7f7b37ac2e82a287479fc9f55 [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
Mike Reed4f364fd2017-01-19 14:34:51 -050011//#include "GrReducedClip.h"
bsalomon@google.com4ebe3822014-02-26 20:22:32 +000012#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
Mike Reed5df49342016-11-12 08:06:55 -060076template <typename T> T* push_ptr(lua_State* L, T* ptr) {
77 *(T**)lua_newuserdata(L, sizeof(T*)) = ptr;
78 luaL_getmetatable(L, get_mtname<T>());
79 lua_setmetatable(L, -2);
80 return ptr;
81}
82
reed9fbc3f32014-10-21 07:12:58 -070083template <typename T> T* push_ref(lua_State* L, T* ref) {
commit-bot@chromium.org77887af2013-12-17 14:28:19 +000084 *(T**)lua_newuserdata(L, sizeof(T*)) = SkSafeRef(ref);
reed@google.com3597b732013-05-22 20:12:50 +000085 luaL_getmetatable(L, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +000086 lua_setmetatable(L, -2);
reed9fbc3f32014-10-21 07:12:58 -070087 return ref;
reed@google.com74ce6f02013-05-22 15:13:18 +000088}
89
reed2ad1aa62016-03-09 09:50:50 -080090template <typename T> void push_ref(lua_State* L, sk_sp<T> sp) {
91 *(T**)lua_newuserdata(L, sizeof(T*)) = sp.release();
92 luaL_getmetatable(L, get_mtname<T>());
93 lua_setmetatable(L, -2);
94}
95
reed@google.com74ce6f02013-05-22 15:13:18 +000096template <typename T> T* get_ref(lua_State* L, int index) {
reed@google.com3597b732013-05-22 20:12:50 +000097 return *(T**)luaL_checkudata(L, index, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +000098}
99
100template <typename T> T* get_obj(lua_State* L, int index) {
reed@google.com3597b732013-05-22 20:12:50 +0000101 return (T*)luaL_checkudata(L, index, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +0000102}
103
reed@google.com88c9ec92013-05-22 15:43:21 +0000104static bool lua2bool(lua_State* L, int index) {
105 return !!lua_toboolean(L, index);
106}
107
reed@google.com74ce6f02013-05-22 15:13:18 +0000108///////////////////////////////////////////////////////////////////////////////
109
reed@google.com3597b732013-05-22 20:12:50 +0000110SkLua::SkLua(const char termCode[]) : fTermCode(termCode), fWeOwnL(true) {
111 fL = luaL_newstate();
112 luaL_openlibs(fL);
113 SkLua::Load(fL);
114}
115
116SkLua::SkLua(lua_State* L) : fL(L), fWeOwnL(false) {}
117
118SkLua::~SkLua() {
119 if (fWeOwnL) {
120 if (fTermCode.size() > 0) {
121 lua_getglobal(fL, fTermCode.c_str());
122 if (lua_pcall(fL, 0, 0, 0) != LUA_OK) {
123 SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
124 }
125 }
126 lua_close(fL);
127 }
128}
129
130bool SkLua::runCode(const char code[]) {
131 int err = luaL_loadstring(fL, code) || lua_pcall(fL, 0, 0, 0);
132 if (err) {
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000133 SkDebugf("--- lua failed: %s\n", lua_tostring(fL, -1));
reed@google.com3597b732013-05-22 20:12:50 +0000134 return false;
135 }
136 return true;
137}
138
139bool SkLua::runCode(const void* code, size_t size) {
140 SkString str((const char*)code, size);
141 return this->runCode(str.c_str());
142}
143
144///////////////////////////////////////////////////////////////////////////////
145
146#define CHECK_SETFIELD(key) do if (key) lua_setfield(fL, -2, key); while (0)
147
reed@google.com29563872013-07-10 21:23:49 +0000148static void setfield_bool_if(lua_State* L, const char key[], bool pred) {
149 if (pred) {
150 lua_pushboolean(L, true);
151 lua_setfield(L, -2, key);
152 }
153}
154
reed@google.com74ce6f02013-05-22 15:13:18 +0000155static void setfield_string(lua_State* L, const char key[], const char value[]) {
156 lua_pushstring(L, value);
157 lua_setfield(L, -2, key);
158}
159
160static void setfield_number(lua_State* L, const char key[], double value) {
161 lua_pushnumber(L, value);
162 lua_setfield(L, -2, key);
163}
164
humper@google.com2815c192013-07-10 22:42:30 +0000165static void setfield_boolean(lua_State* L, const char key[], bool value) {
166 lua_pushboolean(L, value);
167 lua_setfield(L, -2, key);
168}
169
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000170static void setfield_scalar(lua_State* L, const char key[], SkScalar value) {
171 setfield_number(L, key, SkScalarToLua(value));
172}
173
reed@google.com3597b732013-05-22 20:12:50 +0000174static void setfield_function(lua_State* L,
175 const char key[], lua_CFunction value) {
176 lua_pushcfunction(L, value);
177 lua_setfield(L, -2, key);
reed@google.com74ce6f02013-05-22 15:13:18 +0000178}
179
reed7a72c672014-11-07 10:23:55 -0800180static int lua2int_def(lua_State* L, int index, int defaultValue) {
181 if (lua_isnumber(L, index)) {
182 return (int)lua_tonumber(L, index);
183 } else {
184 return defaultValue;
185 }
186}
187
188static SkScalar lua2scalar(lua_State* L, int index) {
189 SkASSERT(lua_isnumber(L, index));
190 return SkLuaToScalar(lua_tonumber(L, index));
191}
192
193static SkScalar lua2scalar_def(lua_State* L, int index, SkScalar defaultValue) {
194 if (lua_isnumber(L, index)) {
195 return SkLuaToScalar(lua_tonumber(L, index));
196 } else {
197 return defaultValue;
198 }
199}
200
201static SkScalar getarray_scalar(lua_State* L, int stackIndex, int arrayIndex) {
202 SkASSERT(lua_istable(L, stackIndex));
203 lua_rawgeti(L, stackIndex, arrayIndex);
mtklein8aacf202014-12-18 13:29:54 -0800204
reed7a72c672014-11-07 10:23:55 -0800205 SkScalar value = lua2scalar(L, -1);
206 lua_pop(L, 1);
207 return value;
208}
209
210static void getarray_scalars(lua_State* L, int stackIndex, SkScalar dst[], int count) {
211 for (int i = 0; i < count; ++i) {
212 dst[i] = getarray_scalar(L, stackIndex, i + 1);
213 }
214}
215
216static void getarray_points(lua_State* L, int stackIndex, SkPoint pts[], int count) {
217 getarray_scalars(L, stackIndex, &pts[0].fX, count * 2);
218}
219
reed@google.come3823fd2013-05-30 18:55:14 +0000220static void setarray_number(lua_State* L, int index, double value) {
221 lua_pushnumber(L, value);
222 lua_rawseti(L, -2, index);
223}
224
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +0000225static void setarray_scalar(lua_State* L, int index, SkScalar value) {
226 setarray_number(L, index, SkScalarToLua(value));
227}
228
hstern0b401ce2016-08-02 09:17:59 -0700229static void setarray_string(lua_State* L, int index, const char str[]) {
230 lua_pushstring(L, str);
231 lua_rawseti(L, -2, index);
232}
233
reed@google.com74ce6f02013-05-22 15:13:18 +0000234void SkLua::pushBool(bool value, const char key[]) {
235 lua_pushboolean(fL, value);
236 CHECK_SETFIELD(key);
237}
238
239void SkLua::pushString(const char str[], const char key[]) {
240 lua_pushstring(fL, str);
241 CHECK_SETFIELD(key);
242}
243
reed@google.come3823fd2013-05-30 18:55:14 +0000244void SkLua::pushString(const char str[], size_t length, const char key[]) {
245 // TODO: how to do this w/o making a copy?
246 SkString s(str, length);
247 lua_pushstring(fL, s.c_str());
248 CHECK_SETFIELD(key);
249}
250
reed@google.com74ce6f02013-05-22 15:13:18 +0000251void SkLua::pushString(const SkString& str, const char key[]) {
252 lua_pushstring(fL, str.c_str());
253 CHECK_SETFIELD(key);
254}
255
256void SkLua::pushColor(SkColor color, const char key[]) {
257 lua_newtable(fL);
258 setfield_number(fL, "a", SkColorGetA(color) / 255.0);
259 setfield_number(fL, "r", SkColorGetR(color) / 255.0);
260 setfield_number(fL, "g", SkColorGetG(color) / 255.0);
261 setfield_number(fL, "b", SkColorGetB(color) / 255.0);
262 CHECK_SETFIELD(key);
263}
264
reed@google.come3823fd2013-05-30 18:55:14 +0000265void SkLua::pushU32(uint32_t value, const char key[]) {
266 lua_pushnumber(fL, (double)value);
267 CHECK_SETFIELD(key);
268}
269
reed@google.com74ce6f02013-05-22 15:13:18 +0000270void SkLua::pushScalar(SkScalar value, const char key[]) {
271 lua_pushnumber(fL, SkScalarToLua(value));
272 CHECK_SETFIELD(key);
273}
274
reed@google.come3823fd2013-05-30 18:55:14 +0000275void SkLua::pushArrayU16(const uint16_t array[], int count, const char key[]) {
276 lua_newtable(fL);
277 for (int i = 0; i < count; ++i) {
278 // make it base-1 to match lua convention
279 setarray_number(fL, i + 1, (double)array[i]);
280 }
281 CHECK_SETFIELD(key);
282}
283
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +0000284void SkLua::pushArrayPoint(const SkPoint array[], int count, const char key[]) {
285 lua_newtable(fL);
286 for (int i = 0; i < count; ++i) {
287 // make it base-1 to match lua convention
288 lua_newtable(fL);
289 this->pushScalar(array[i].fX, "x");
290 this->pushScalar(array[i].fY, "y");
291 lua_rawseti(fL, -2, i + 1);
292 }
293 CHECK_SETFIELD(key);
294}
295
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +0000296void SkLua::pushArrayScalar(const SkScalar array[], int count, const char key[]) {
297 lua_newtable(fL);
298 for (int i = 0; i < count; ++i) {
299 // make it base-1 to match lua convention
300 setarray_scalar(fL, i + 1, array[i]);
301 }
302 CHECK_SETFIELD(key);
303}
304
reed@google.com74ce6f02013-05-22 15:13:18 +0000305void SkLua::pushRect(const SkRect& r, const char key[]) {
306 lua_newtable(fL);
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000307 setfield_scalar(fL, "left", r.fLeft);
308 setfield_scalar(fL, "top", r.fTop);
309 setfield_scalar(fL, "right", r.fRight);
310 setfield_scalar(fL, "bottom", r.fBottom);
reed@google.com74ce6f02013-05-22 15:13:18 +0000311 CHECK_SETFIELD(key);
312}
313
314void SkLua::pushRRect(const SkRRect& rr, const char key[]) {
315 push_obj(fL, rr);
316 CHECK_SETFIELD(key);
317}
318
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +0000319void SkLua::pushDash(const SkPathEffect::DashInfo& info, const char key[]) {
320 lua_newtable(fL);
321 setfield_scalar(fL, "phase", info.fPhase);
322 this->pushArrayScalar(info.fIntervals, info.fCount, "intervals");
323 CHECK_SETFIELD(key);
324}
325
326
reed@google.com74ce6f02013-05-22 15:13:18 +0000327void SkLua::pushMatrix(const SkMatrix& matrix, const char key[]) {
328 push_obj(fL, matrix);
329 CHECK_SETFIELD(key);
330}
331
332void SkLua::pushPaint(const SkPaint& paint, const char key[]) {
333 push_obj(fL, paint);
334 CHECK_SETFIELD(key);
335}
336
337void SkLua::pushPath(const SkPath& path, const char key[]) {
338 push_obj(fL, path);
339 CHECK_SETFIELD(key);
340}
341
342void SkLua::pushCanvas(SkCanvas* canvas, const char key[]) {
Mike Reed5df49342016-11-12 08:06:55 -0600343 push_ptr(fL, canvas);
reed@google.com74ce6f02013-05-22 15:13:18 +0000344 CHECK_SETFIELD(key);
345}
346
fmalitab7425172014-08-26 07:56:44 -0700347void SkLua::pushTextBlob(const SkTextBlob* blob, const char key[]) {
348 push_ref(fL, const_cast<SkTextBlob*>(blob));
349 CHECK_SETFIELD(key);
350}
351
reed@google.com74ce6f02013-05-22 15:13:18 +0000352///////////////////////////////////////////////////////////////////////////////
353///////////////////////////////////////////////////////////////////////////////
354
reed@google.com74ce6f02013-05-22 15:13:18 +0000355static SkScalar getfield_scalar(lua_State* L, int index, const char key[]) {
356 SkASSERT(lua_istable(L, index));
357 lua_pushstring(L, key);
358 lua_gettable(L, index);
mtklein8aacf202014-12-18 13:29:54 -0800359
reed@google.com74ce6f02013-05-22 15:13:18 +0000360 SkScalar value = lua2scalar(L, -1);
361 lua_pop(L, 1);
362 return value;
363}
364
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000365static SkScalar getfield_scalar_default(lua_State* L, int index, const char key[], SkScalar def) {
366 SkASSERT(lua_istable(L, index));
367 lua_pushstring(L, key);
368 lua_gettable(L, index);
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000369
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000370 SkScalar value;
371 if (lua_isnil(L, -1)) {
372 value = def;
373 } else {
374 value = lua2scalar(L, -1);
375 }
376 lua_pop(L, 1);
377 return value;
378}
379
reed468b1812014-10-19 11:42:54 -0700380static SkScalar byte2unit(U8CPU byte) {
381 return byte / 255.0f;
382}
383
reed@google.com74ce6f02013-05-22 15:13:18 +0000384static U8CPU unit2byte(SkScalar x) {
385 if (x <= 0) {
386 return 0;
387 } else if (x >= 1) {
388 return 255;
389 } else {
390 return SkScalarRoundToInt(x * 255);
391 }
392}
393
394static SkColor lua2color(lua_State* L, int index) {
reed485557f2014-10-12 10:36:47 -0700395 return SkColorSetARGB(unit2byte(getfield_scalar_default(L, index, "a", 1)),
396 unit2byte(getfield_scalar_default(L, index, "r", 0)),
397 unit2byte(getfield_scalar_default(L, index, "g", 0)),
398 unit2byte(getfield_scalar_default(L, index, "b", 0)));
reed@google.com74ce6f02013-05-22 15:13:18 +0000399}
400
401static SkRect* lua2rect(lua_State* L, int index, SkRect* rect) {
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000402 rect->set(getfield_scalar_default(L, index, "left", 0),
403 getfield_scalar_default(L, index, "top", 0),
reed@google.com74ce6f02013-05-22 15:13:18 +0000404 getfield_scalar(L, index, "right"),
405 getfield_scalar(L, index, "bottom"));
406 return rect;
407}
408
reedf355df52014-10-12 12:18:40 -0700409static int lcanvas_clear(lua_State* L) {
410 get_ref<SkCanvas>(L, 1)->clear(0);
411 return 0;
412}
413
reed@google.com74ce6f02013-05-22 15:13:18 +0000414static int lcanvas_drawColor(lua_State* L) {
415 get_ref<SkCanvas>(L, 1)->drawColor(lua2color(L, 2));
416 return 0;
417}
418
reed9fbc3f32014-10-21 07:12:58 -0700419static int lcanvas_drawPaint(lua_State* L) {
420 get_ref<SkCanvas>(L, 1)->drawPaint(*get_obj<SkPaint>(L, 2));
421 return 0;
422}
423
reed@google.com74ce6f02013-05-22 15:13:18 +0000424static int lcanvas_drawRect(lua_State* L) {
425 SkRect rect;
reed7a72c672014-11-07 10:23:55 -0800426 lua2rect(L, 2, &rect);
427 const SkPaint* paint = get_obj<SkPaint>(L, 3);
428 get_ref<SkCanvas>(L, 1)->drawRect(rect, *paint);
reed@google.com74ce6f02013-05-22 15:13:18 +0000429 return 0;
430}
431
432static int lcanvas_drawOval(lua_State* L) {
433 SkRect rect;
434 get_ref<SkCanvas>(L, 1)->drawOval(*lua2rect(L, 2, &rect),
435 *get_obj<SkPaint>(L, 3));
436 return 0;
437}
438
439static int lcanvas_drawCircle(lua_State* L) {
440 get_ref<SkCanvas>(L, 1)->drawCircle(lua2scalar(L, 2),
441 lua2scalar(L, 3),
442 lua2scalar(L, 4),
443 *get_obj<SkPaint>(L, 5));
444 return 0;
445}
446
reed485557f2014-10-12 10:36:47 -0700447static SkPaint* lua2OptionalPaint(lua_State* L, int index, SkPaint* paint) {
448 if (lua_isnumber(L, index)) {
449 paint->setAlpha(SkScalarRoundToInt(lua2scalar(L, index) * 255));
450 return paint;
reedf355df52014-10-12 12:18:40 -0700451 } else if (lua_isuserdata(L, index)) {
reed485557f2014-10-12 10:36:47 -0700452 const SkPaint* ptr = get_obj<SkPaint>(L, index);
453 if (ptr) {
454 *paint = *ptr;
455 return paint;
456 }
457 }
halcanary96fcdcc2015-08-27 07:41:13 -0700458 return nullptr;
reed485557f2014-10-12 10:36:47 -0700459}
460
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000461static int lcanvas_drawImage(lua_State* L) {
462 SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
463 SkImage* image = get_ref<SkImage>(L, 2);
halcanary96fcdcc2015-08-27 07:41:13 -0700464 if (nullptr == image) {
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000465 return 0;
466 }
467 SkScalar x = lua2scalar(L, 3);
468 SkScalar y = lua2scalar(L, 4);
469
470 SkPaint paint;
reed485557f2014-10-12 10:36:47 -0700471 canvas->drawImage(image, x, y, lua2OptionalPaint(L, 5, &paint));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000472 return 0;
473}
474
reedba5fb932014-10-10 15:28:19 -0700475static int lcanvas_drawImageRect(lua_State* L) {
476 SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
477 SkImage* image = get_ref<SkImage>(L, 2);
halcanary96fcdcc2015-08-27 07:41:13 -0700478 if (nullptr == image) {
reedba5fb932014-10-10 15:28:19 -0700479 return 0;
480 }
481
482 SkRect srcR, dstR;
halcanary96fcdcc2015-08-27 07:41:13 -0700483 SkRect* srcRPtr = nullptr;
reedba5fb932014-10-10 15:28:19 -0700484 if (!lua_isnil(L, 3)) {
485 srcRPtr = lua2rect(L, 3, &srcR);
486 }
487 lua2rect(L, 4, &dstR);
mtklein8aacf202014-12-18 13:29:54 -0800488
reedba5fb932014-10-10 15:28:19 -0700489 SkPaint paint;
reede47829b2015-08-06 10:02:53 -0700490 canvas->legacy_drawImageRect(image, srcRPtr, dstR, lua2OptionalPaint(L, 5, &paint));
reedba5fb932014-10-10 15:28:19 -0700491 return 0;
492}
493
reed7a72c672014-11-07 10:23:55 -0800494static int lcanvas_drawPatch(lua_State* L) {
495 SkPoint cubics[12];
496 SkColor colorStorage[4];
497 SkPoint texStorage[4];
498
halcanary96fcdcc2015-08-27 07:41:13 -0700499 const SkColor* colors = nullptr;
500 const SkPoint* texs = nullptr;
reed7a72c672014-11-07 10:23:55 -0800501
502 getarray_points(L, 2, cubics, 12);
503
504 colorStorage[0] = SK_ColorRED;
505 colorStorage[1] = SK_ColorGREEN;
506 colorStorage[2] = SK_ColorBLUE;
507 colorStorage[3] = SK_ColorGRAY;
508
509 if (lua_isnil(L, 4)) {
510 colors = colorStorage;
511 } else {
512 getarray_points(L, 4, texStorage, 4);
513 texs = texStorage;
514 }
515
Mike Reed7d954ad2016-10-28 15:42:34 -0400516 get_ref<SkCanvas>(L, 1)->drawPatch(cubics, colors, texs, *get_obj<SkPaint>(L, 5));
reed7a72c672014-11-07 10:23:55 -0800517 return 0;
518}
519
reed@google.comfd345872013-05-22 20:53:42 +0000520static int lcanvas_drawPath(lua_State* L) {
521 get_ref<SkCanvas>(L, 1)->drawPath(*get_obj<SkPath>(L, 2),
522 *get_obj<SkPaint>(L, 3));
523 return 0;
524}
525
reed96affcd2014-10-13 12:38:04 -0700526// drawPicture(pic, x, y, paint)
527static int lcanvas_drawPicture(lua_State* L) {
528 SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
529 SkPicture* picture = get_ref<SkPicture>(L, 2);
530 SkScalar x = lua2scalar_def(L, 3, 0);
531 SkScalar y = lua2scalar_def(L, 4, 0);
halcanary96fcdcc2015-08-27 07:41:13 -0700532 SkMatrix matrix, *matrixPtr = nullptr;
reed96affcd2014-10-13 12:38:04 -0700533 if (x || y) {
534 matrix.setTranslate(x, y);
535 matrixPtr = &matrix;
536 }
537 SkPaint paint;
538 canvas->drawPicture(picture, matrixPtr, lua2OptionalPaint(L, 5, &paint));
539 return 0;
540}
541
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000542static int lcanvas_drawText(lua_State* L) {
543 if (lua_gettop(L) < 5) {
544 return 0;
545 }
546
547 if (lua_isstring(L, 2) && lua_isnumber(L, 3) && lua_isnumber(L, 4)) {
548 size_t len;
549 const char* text = lua_tolstring(L, 2, &len);
550 get_ref<SkCanvas>(L, 1)->drawText(text, len,
551 lua2scalar(L, 3), lua2scalar(L, 4),
552 *get_obj<SkPaint>(L, 5));
553 }
554 return 0;
555}
556
reed1b6ab442014-11-03 19:55:41 -0800557static int lcanvas_drawTextBlob(lua_State* L) {
558 const SkTextBlob* blob = get_ref<SkTextBlob>(L, 2);
559 SkScalar x = lua2scalar(L, 3);
560 SkScalar y = lua2scalar(L, 4);
561 const SkPaint& paint = *get_obj<SkPaint>(L, 5);
562 get_ref<SkCanvas>(L, 1)->drawTextBlob(blob, x, y, paint);
563 return 0;
564}
565
reed@google.com74ce6f02013-05-22 15:13:18 +0000566static int lcanvas_getSaveCount(lua_State* L) {
567 lua_pushnumber(L, get_ref<SkCanvas>(L, 1)->getSaveCount());
568 return 1;
569}
570
571static int lcanvas_getTotalMatrix(lua_State* L) {
572 SkLua(L).pushMatrix(get_ref<SkCanvas>(L, 1)->getTotalMatrix());
573 return 1;
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
reed86217d82014-10-25 20:44:40 -0700581static int lcanvas_saveLayer(lua_State* L) {
582 SkPaint paint;
halcanary96fcdcc2015-08-27 07:41:13 -0700583 lua_pushinteger(L, get_ref<SkCanvas>(L, 1)->saveLayer(nullptr, lua2OptionalPaint(L, 2, &paint)));
reed86217d82014-10-25 20:44:40 -0700584 return 1;
585}
586
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000587static int lcanvas_restore(lua_State* L) {
588 get_ref<SkCanvas>(L, 1)->restore();
589 return 0;
590}
591
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000592static int lcanvas_scale(lua_State* L) {
593 SkScalar sx = lua2scalar_def(L, 2, 1);
594 SkScalar sy = lua2scalar_def(L, 3, sx);
595 get_ref<SkCanvas>(L, 1)->scale(sx, sy);
596 return 0;
597}
598
reed@google.com3597b732013-05-22 20:12:50 +0000599static int lcanvas_translate(lua_State* L) {
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000600 SkScalar tx = lua2scalar_def(L, 2, 0);
601 SkScalar ty = lua2scalar_def(L, 3, 0);
602 get_ref<SkCanvas>(L, 1)->translate(tx, ty);
603 return 0;
604}
605
606static int lcanvas_rotate(lua_State* L) {
607 SkScalar degrees = lua2scalar_def(L, 2, 0);
608 get_ref<SkCanvas>(L, 1)->rotate(degrees);
reed@google.com3597b732013-05-22 20:12:50 +0000609 return 0;
610}
611
reedbdc49ae2014-10-14 09:34:52 -0700612static int lcanvas_concat(lua_State* L) {
613 get_ref<SkCanvas>(L, 1)->concat(*get_obj<SkMatrix>(L, 2));
614 return 0;
615}
616
reed485557f2014-10-12 10:36:47 -0700617static int lcanvas_newSurface(lua_State* L) {
618 int width = lua2int_def(L, 2, 0);
reed7a72c672014-11-07 10:23:55 -0800619 int height = lua2int_def(L, 3, 0);
reed485557f2014-10-12 10:36:47 -0700620 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
reede8f30622016-03-23 18:59:25 -0700621 auto surface = get_ref<SkCanvas>(L, 1)->makeSurface(info);
halcanary96fcdcc2015-08-27 07:41:13 -0700622 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -0700623 lua_pushnil(L);
624 } else {
reede8f30622016-03-23 18:59:25 -0700625 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -0700626 }
627 return 1;
628}
629
reed@google.com74ce6f02013-05-22 15:13:18 +0000630static int lcanvas_gc(lua_State* L) {
Mike Reed5df49342016-11-12 08:06:55 -0600631 // don't know how to track a ptr...
reed@google.com74ce6f02013-05-22 15:13:18 +0000632 return 0;
633}
634
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000635const struct luaL_Reg gSkCanvas_Methods[] = {
reedf355df52014-10-12 12:18:40 -0700636 { "clear", lcanvas_clear },
reed@google.com74ce6f02013-05-22 15:13:18 +0000637 { "drawColor", lcanvas_drawColor },
reed9fbc3f32014-10-21 07:12:58 -0700638 { "drawPaint", lcanvas_drawPaint },
reed@google.com74ce6f02013-05-22 15:13:18 +0000639 { "drawRect", lcanvas_drawRect },
640 { "drawOval", lcanvas_drawOval },
641 { "drawCircle", lcanvas_drawCircle },
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000642 { "drawImage", lcanvas_drawImage },
reedba5fb932014-10-10 15:28:19 -0700643 { "drawImageRect", lcanvas_drawImageRect },
reed7a72c672014-11-07 10:23:55 -0800644 { "drawPatch", lcanvas_drawPatch },
reed@google.comfd345872013-05-22 20:53:42 +0000645 { "drawPath", lcanvas_drawPath },
reed96affcd2014-10-13 12:38:04 -0700646 { "drawPicture", lcanvas_drawPicture },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000647 { "drawText", lcanvas_drawText },
reed1b6ab442014-11-03 19:55:41 -0800648 { "drawTextBlob", lcanvas_drawTextBlob },
reed@google.com74ce6f02013-05-22 15:13:18 +0000649 { "getSaveCount", lcanvas_getSaveCount },
650 { "getTotalMatrix", lcanvas_getTotalMatrix },
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000651 { "save", lcanvas_save },
reed86217d82014-10-25 20:44:40 -0700652 { "saveLayer", lcanvas_saveLayer },
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000653 { "restore", lcanvas_restore },
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000654 { "scale", lcanvas_scale },
reed@google.com3597b732013-05-22 20:12:50 +0000655 { "translate", lcanvas_translate },
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000656 { "rotate", lcanvas_rotate },
reedbdc49ae2014-10-14 09:34:52 -0700657 { "concat", lcanvas_concat },
reed485557f2014-10-12 10:36:47 -0700658
659 { "newSurface", lcanvas_newSurface },
660
reed@google.com74ce6f02013-05-22 15:13:18 +0000661 { "__gc", lcanvas_gc },
halcanary96fcdcc2015-08-27 07:41:13 -0700662 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +0000663};
664
665///////////////////////////////////////////////////////////////////////////////
666
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000667static int ldocument_beginPage(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -0700668 const SkRect* contentPtr = nullptr;
Mike Reed5df49342016-11-12 08:06:55 -0600669 push_ptr(L, get_ref<SkDocument>(L, 1)->beginPage(lua2scalar(L, 2),
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000670 lua2scalar(L, 3),
671 contentPtr));
672 return 1;
673}
674
675static int ldocument_endPage(lua_State* L) {
676 get_ref<SkDocument>(L, 1)->endPage();
677 return 0;
678}
679
680static int ldocument_close(lua_State* L) {
681 get_ref<SkDocument>(L, 1)->close();
682 return 0;
683}
684
685static int ldocument_gc(lua_State* L) {
686 get_ref<SkDocument>(L, 1)->unref();
687 return 0;
688}
689
690static const struct luaL_Reg gSkDocument_Methods[] = {
691 { "beginPage", ldocument_beginPage },
692 { "endPage", ldocument_endPage },
693 { "close", ldocument_close },
694 { "__gc", ldocument_gc },
halcanary96fcdcc2015-08-27 07:41:13 -0700695 { nullptr, nullptr }
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000696};
697
698///////////////////////////////////////////////////////////////////////////////
699
reed@google.com74ce6f02013-05-22 15:13:18 +0000700static int lpaint_isAntiAlias(lua_State* L) {
701 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isAntiAlias());
702 return 1;
703}
704
705static int lpaint_setAntiAlias(lua_State* L) {
reed@google.com88c9ec92013-05-22 15:43:21 +0000706 get_obj<SkPaint>(L, 1)->setAntiAlias(lua2bool(L, 2));
reed@google.com74ce6f02013-05-22 15:13:18 +0000707 return 0;
708}
709
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000710static int lpaint_isDither(lua_State* L) {
711 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isDither());
712 return 1;
713}
714
reedbb8a0ab2014-11-03 22:32:07 -0800715static int lpaint_setDither(lua_State* L) {
716 get_obj<SkPaint>(L, 1)->setDither(lua2bool(L, 2));
717 return 0;
718}
719
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000720static int lpaint_isFakeBoldText(lua_State* L) {
721 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isFakeBoldText());
722 return 1;
723}
724
725static int lpaint_isLinearText(lua_State* L) {
726 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isLinearText());
727 return 1;
728}
729
730static int lpaint_isSubpixelText(lua_State* L) {
731 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isSubpixelText());
732 return 1;
733}
734
reed09a1d672014-10-11 13:13:11 -0700735static int lpaint_setSubpixelText(lua_State* L) {
736 get_obj<SkPaint>(L, 1)->setSubpixelText(lua2bool(L, 2));
737 return 1;
738}
739
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000740static int lpaint_isDevKernText(lua_State* L) {
741 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isDevKernText());
742 return 1;
743}
744
745static int lpaint_isLCDRenderText(lua_State* L) {
746 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isLCDRenderText());
747 return 1;
748}
749
reed36c9c112014-11-04 10:58:42 -0800750static int lpaint_setLCDRenderText(lua_State* L) {
751 get_obj<SkPaint>(L, 1)->setLCDRenderText(lua2bool(L, 2));
752 return 1;
753}
754
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000755static int lpaint_isEmbeddedBitmapText(lua_State* L) {
756 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isEmbeddedBitmapText());
757 return 1;
758}
759
760static int lpaint_isAutohinted(lua_State* L) {
761 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isAutohinted());
762 return 1;
763}
764
765static int lpaint_isVerticalText(lua_State* L) {
766 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isVerticalText());
767 return 1;
768}
769
reed468b1812014-10-19 11:42:54 -0700770static int lpaint_getAlpha(lua_State* L) {
771 SkLua(L).pushScalar(byte2unit(get_obj<SkPaint>(L, 1)->getAlpha()));
772 return 1;
773}
774
775static int lpaint_setAlpha(lua_State* L) {
776 get_obj<SkPaint>(L, 1)->setAlpha(unit2byte(lua2scalar(L, 2)));
777 return 0;
778}
779
reed@google.com74ce6f02013-05-22 15:13:18 +0000780static int lpaint_getColor(lua_State* L) {
781 SkLua(L).pushColor(get_obj<SkPaint>(L, 1)->getColor());
782 return 1;
783}
784
785static int lpaint_setColor(lua_State* L) {
786 get_obj<SkPaint>(L, 1)->setColor(lua2color(L, 2));
787 return 0;
788}
789
reed@google.come3823fd2013-05-30 18:55:14 +0000790static int lpaint_getTextSize(lua_State* L) {
791 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getTextSize());
792 return 1;
793}
794
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000795static int lpaint_getTextScaleX(lua_State* L) {
796 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getTextScaleX());
797 return 1;
798}
799
800static int lpaint_getTextSkewX(lua_State* L) {
801 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getTextSkewX());
802 return 1;
803}
804
reed@google.come3823fd2013-05-30 18:55:14 +0000805static int lpaint_setTextSize(lua_State* L) {
806 get_obj<SkPaint>(L, 1)->setTextSize(lua2scalar(L, 2));
807 return 0;
808}
809
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000810static int lpaint_getTypeface(lua_State* L) {
811 push_ref(L, get_obj<SkPaint>(L, 1)->getTypeface());
812 return 1;
813}
814
815static int lpaint_setTypeface(lua_State* L) {
bungeman13b9c952016-05-12 10:09:30 -0700816 get_obj<SkPaint>(L, 1)->setTypeface(sk_ref_sp(get_ref<SkTypeface>(L, 2)));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000817 return 0;
818}
819
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000820static int lpaint_getHinting(lua_State* L) {
821 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getHinting());
822 return 1;
823}
824
reed93a12152015-03-16 10:08:34 -0700825static int lpaint_getFilterQuality(lua_State* L) {
826 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getFilterQuality());
reed7a72c672014-11-07 10:23:55 -0800827 return 1;
828}
829
reed93a12152015-03-16 10:08:34 -0700830static int lpaint_setFilterQuality(lua_State* L) {
reed7a72c672014-11-07 10:23:55 -0800831 int level = lua2int_def(L, 2, -1);
832 if (level >= 0 && level <= 3) {
reed93a12152015-03-16 10:08:34 -0700833 get_obj<SkPaint>(L, 1)->setFilterQuality((SkFilterQuality)level);
reed7a72c672014-11-07 10:23:55 -0800834 }
835 return 0;
836}
837
reed@google.come3823fd2013-05-30 18:55:14 +0000838static int lpaint_getFontID(lua_State* L) {
839 SkTypeface* face = get_obj<SkPaint>(L, 1)->getTypeface();
840 SkLua(L).pushU32(SkTypeface::UniqueID(face));
841 return 1;
842}
843
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000844static const struct {
845 const char* fLabel;
846 SkPaint::Align fAlign;
847} gAlignRec[] = {
848 { "left", SkPaint::kLeft_Align },
849 { "center", SkPaint::kCenter_Align },
850 { "right", SkPaint::kRight_Align },
851};
852
853static int lpaint_getTextAlign(lua_State* L) {
854 SkPaint::Align align = get_obj<SkPaint>(L, 1)->getTextAlign();
855 for (size_t i = 0; i < SK_ARRAY_COUNT(gAlignRec); ++i) {
856 if (gAlignRec[i].fAlign == align) {
857 lua_pushstring(L, gAlignRec[i].fLabel);
858 return 1;
859 }
860 }
861 return 0;
862}
863
864static int lpaint_setTextAlign(lua_State* L) {
865 if (lua_isstring(L, 2)) {
866 size_t len;
867 const char* label = lua_tolstring(L, 2, &len);
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000868
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000869 for (size_t i = 0; i < SK_ARRAY_COUNT(gAlignRec); ++i) {
870 if (!strcmp(gAlignRec[i].fLabel, label)) {
871 get_obj<SkPaint>(L, 1)->setTextAlign(gAlignRec[i].fAlign);
872 break;
873 }
874 }
875 }
876 return 0;
877}
878
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000879static int lpaint_getStroke(lua_State* L) {
880 lua_pushboolean(L, SkPaint::kStroke_Style == get_obj<SkPaint>(L, 1)->getStyle());
881 return 1;
882}
883
884static int lpaint_setStroke(lua_State* L) {
885 SkPaint::Style style;
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000886
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000887 if (lua_toboolean(L, 2)) {
888 style = SkPaint::kStroke_Style;
889 } else {
890 style = SkPaint::kFill_Style;
891 }
892 get_obj<SkPaint>(L, 1)->setStyle(style);
893 return 0;
894}
895
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000896static int lpaint_getStrokeCap(lua_State* L) {
897 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeCap());
898 return 1;
899}
900
901static int lpaint_getStrokeJoin(lua_State* L) {
902 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeJoin());
903 return 1;
904}
905
906static int lpaint_getTextEncoding(lua_State* L) {
commit-bot@chromium.org641bcc32013-12-19 10:39:59 +0000907 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getTextEncoding());
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000908 return 1;
909}
910
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000911static int lpaint_getStrokeWidth(lua_State* L) {
912 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeWidth());
913 return 1;
914}
915
916static int lpaint_setStrokeWidth(lua_State* L) {
917 get_obj<SkPaint>(L, 1)->setStrokeWidth(lua2scalar(L, 2));
918 return 0;
919}
920
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000921static int lpaint_getStrokeMiter(lua_State* L) {
922 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeMiter());
923 return 1;
924}
925
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000926static int lpaint_measureText(lua_State* L) {
927 if (lua_isstring(L, 2)) {
928 size_t len;
929 const char* text = lua_tolstring(L, 2, &len);
930 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->measureText(text, len));
931 return 1;
932 }
933 return 0;
934}
935
936struct FontMetrics {
937 SkScalar fTop; //!< The greatest distance above the baseline for any glyph (will be <= 0)
938 SkScalar fAscent; //!< The recommended distance above the baseline (will be <= 0)
939 SkScalar fDescent; //!< The recommended distance below the baseline (will be >= 0)
940 SkScalar fBottom; //!< The greatest distance below the baseline for any glyph (will be >= 0)
941 SkScalar fLeading; //!< The recommended distance to add between lines of text (will be >= 0)
942 SkScalar fAvgCharWidth; //!< the average charactor width (>= 0)
943 SkScalar fXMin; //!< The minimum bounding box x value for all glyphs
944 SkScalar fXMax; //!< The maximum bounding box x value for all glyphs
945 SkScalar fXHeight; //!< the height of an 'x' in px, or 0 if no 'x' in face
946};
947
948static int lpaint_getFontMetrics(lua_State* L) {
949 SkPaint::FontMetrics fm;
950 SkScalar height = get_obj<SkPaint>(L, 1)->getFontMetrics(&fm);
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000951
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000952 lua_newtable(L);
953 setfield_scalar(L, "top", fm.fTop);
954 setfield_scalar(L, "ascent", fm.fAscent);
955 setfield_scalar(L, "descent", fm.fDescent);
956 setfield_scalar(L, "bottom", fm.fBottom);
957 setfield_scalar(L, "leading", fm.fLeading);
958 SkLua(L).pushScalar(height);
959 return 2;
960}
961
reed@google.com29563872013-07-10 21:23:49 +0000962static int lpaint_getEffects(lua_State* L) {
963 const SkPaint* paint = get_obj<SkPaint>(L, 1);
skia.committer@gmail.comde2e4e82013-07-11 07:01:01 +0000964
reed@google.com29563872013-07-10 21:23:49 +0000965 lua_newtable(L);
reed468b1812014-10-19 11:42:54 -0700966 setfield_bool_if(L, "looper", !!paint->getLooper());
967 setfield_bool_if(L, "pathEffect", !!paint->getPathEffect());
968 setfield_bool_if(L, "rasterizer", !!paint->getRasterizer());
969 setfield_bool_if(L, "maskFilter", !!paint->getMaskFilter());
970 setfield_bool_if(L, "shader", !!paint->getShader());
reed@google.com29563872013-07-10 21:23:49 +0000971 setfield_bool_if(L, "colorFilter", !!paint->getColorFilter());
972 setfield_bool_if(L, "imageFilter", !!paint->getImageFilter());
reed@google.com29563872013-07-10 21:23:49 +0000973 return 1;
974}
975
reed22a517f2015-12-04 20:45:59 -0800976static int lpaint_getColorFilter(lua_State* L) {
977 const SkPaint* paint = get_obj<SkPaint>(L, 1);
978 SkColorFilter* cf = paint->getColorFilter();
979 if (cf) {
980 push_ref(L, cf);
981 return 1;
982 }
983 return 0;
984}
985
986static int lpaint_setColorFilter(lua_State* L) {
987 SkPaint* paint = get_obj<SkPaint>(L, 1);
reedd053ce92016-03-22 10:17:23 -0700988 paint->setColorFilter(sk_ref_sp(get_ref<SkColorFilter>(L, 2)));
reed22a517f2015-12-04 20:45:59 -0800989 return 0;
990}
991
reed468b1812014-10-19 11:42:54 -0700992static int lpaint_getImageFilter(lua_State* L) {
993 const SkPaint* paint = get_obj<SkPaint>(L, 1);
994 SkImageFilter* imf = paint->getImageFilter();
995 if (imf) {
996 push_ref(L, imf);
997 return 1;
998 }
999 return 0;
1000}
1001
1002static int lpaint_setImageFilter(lua_State* L) {
1003 SkPaint* paint = get_obj<SkPaint>(L, 1);
Mike Reed5e257172016-11-01 11:22:05 -04001004 paint->setImageFilter(sk_ref_sp(get_ref<SkImageFilter>(L, 2)));
reed468b1812014-10-19 11:42:54 -07001005 return 0;
1006}
1007
reed@google.com5fdc9832013-07-24 15:47:52 +00001008static int lpaint_getShader(lua_State* L) {
1009 const SkPaint* paint = get_obj<SkPaint>(L, 1);
1010 SkShader* shader = paint->getShader();
1011 if (shader) {
1012 push_ref(L, shader);
1013 return 1;
1014 }
1015 return 0;
1016}
1017
reed9fbc3f32014-10-21 07:12:58 -07001018static int lpaint_setShader(lua_State* L) {
1019 SkPaint* paint = get_obj<SkPaint>(L, 1);
reedfe630452016-03-25 09:08:00 -07001020 paint->setShader(sk_ref_sp(get_ref<SkShader>(L, 2)));
reed9fbc3f32014-10-21 07:12:58 -07001021 return 0;
1022}
1023
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001024static int lpaint_getPathEffect(lua_State* L) {
1025 const SkPaint* paint = get_obj<SkPaint>(L, 1);
1026 SkPathEffect* pe = paint->getPathEffect();
1027 if (pe) {
1028 push_ref(L, pe);
1029 return 1;
1030 }
1031 return 0;
1032}
1033
hstern0b401ce2016-08-02 09:17:59 -07001034static int lpaint_getFillPath(lua_State* L) {
1035 const SkPaint* paint = get_obj<SkPaint>(L, 1);
1036 const SkPath* path = get_obj<SkPath>(L, 2);
1037
1038 SkPath fillpath;
1039 paint->getFillPath(*path, &fillpath);
1040
1041 SkLua lua(L);
1042 lua.pushPath(fillpath);
1043
1044 return 1;
1045}
1046
reed@google.com74ce6f02013-05-22 15:13:18 +00001047static int lpaint_gc(lua_State* L) {
1048 get_obj<SkPaint>(L, 1)->~SkPaint();
1049 return 0;
1050}
1051
1052static const struct luaL_Reg gSkPaint_Methods[] = {
1053 { "isAntiAlias", lpaint_isAntiAlias },
1054 { "setAntiAlias", lpaint_setAntiAlias },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001055 { "isDither", lpaint_isDither },
reedbb8a0ab2014-11-03 22:32:07 -08001056 { "setDither", lpaint_setDither },
reed93a12152015-03-16 10:08:34 -07001057 { "getFilterQuality", lpaint_getFilterQuality },
1058 { "setFilterQuality", lpaint_setFilterQuality },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001059 { "isFakeBoldText", lpaint_isFakeBoldText },
1060 { "isLinearText", lpaint_isLinearText },
1061 { "isSubpixelText", lpaint_isSubpixelText },
reed09a1d672014-10-11 13:13:11 -07001062 { "setSubpixelText", lpaint_setSubpixelText },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001063 { "isDevKernText", lpaint_isDevKernText },
1064 { "isLCDRenderText", lpaint_isLCDRenderText },
reed36c9c112014-11-04 10:58:42 -08001065 { "setLCDRenderText", lpaint_setLCDRenderText },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001066 { "isEmbeddedBitmapText", lpaint_isEmbeddedBitmapText },
1067 { "isAutohinted", lpaint_isAutohinted },
1068 { "isVerticalText", lpaint_isVerticalText },
reed468b1812014-10-19 11:42:54 -07001069 { "getAlpha", lpaint_getAlpha },
1070 { "setAlpha", lpaint_setAlpha },
reed@google.com74ce6f02013-05-22 15:13:18 +00001071 { "getColor", lpaint_getColor },
1072 { "setColor", lpaint_setColor },
reed@google.come3823fd2013-05-30 18:55:14 +00001073 { "getTextSize", lpaint_getTextSize },
1074 { "setTextSize", lpaint_setTextSize },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001075 { "getTextScaleX", lpaint_getTextScaleX },
1076 { "getTextSkewX", lpaint_getTextSkewX },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001077 { "getTypeface", lpaint_getTypeface },
1078 { "setTypeface", lpaint_setTypeface },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001079 { "getHinting", lpaint_getHinting },
reed@google.come3823fd2013-05-30 18:55:14 +00001080 { "getFontID", lpaint_getFontID },
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001081 { "getTextAlign", lpaint_getTextAlign },
1082 { "setTextAlign", lpaint_setTextAlign },
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +00001083 { "getStroke", lpaint_getStroke },
1084 { "setStroke", lpaint_setStroke },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001085 { "getStrokeCap", lpaint_getStrokeCap },
1086 { "getStrokeJoin", lpaint_getStrokeJoin },
1087 { "getTextEncoding", lpaint_getTextEncoding },
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +00001088 { "getStrokeWidth", lpaint_getStrokeWidth },
1089 { "setStrokeWidth", lpaint_setStrokeWidth },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001090 { "getStrokeMiter", lpaint_getStrokeMiter },
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +00001091 { "measureText", lpaint_measureText },
1092 { "getFontMetrics", lpaint_getFontMetrics },
reed@google.com29563872013-07-10 21:23:49 +00001093 { "getEffects", lpaint_getEffects },
reed22a517f2015-12-04 20:45:59 -08001094 { "getColorFilter", lpaint_getColorFilter },
1095 { "setColorFilter", lpaint_setColorFilter },
reed468b1812014-10-19 11:42:54 -07001096 { "getImageFilter", lpaint_getImageFilter },
1097 { "setImageFilter", lpaint_setImageFilter },
reed@google.com5fdc9832013-07-24 15:47:52 +00001098 { "getShader", lpaint_getShader },
reed9fbc3f32014-10-21 07:12:58 -07001099 { "setShader", lpaint_setShader },
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001100 { "getPathEffect", lpaint_getPathEffect },
hstern0b401ce2016-08-02 09:17:59 -07001101 { "getFillPath", lpaint_getFillPath },
reed@google.com74ce6f02013-05-22 15:13:18 +00001102 { "__gc", lpaint_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001103 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001104};
1105
1106///////////////////////////////////////////////////////////////////////////////
1107
reed@google.com5fdc9832013-07-24 15:47:52 +00001108static const char* mode2string(SkShader::TileMode mode) {
1109 static const char* gNames[] = { "clamp", "repeat", "mirror" };
1110 SkASSERT((unsigned)mode < SK_ARRAY_COUNT(gNames));
1111 return gNames[mode];
1112}
1113
1114static const char* gradtype2string(SkShader::GradientType t) {
1115 static const char* gNames[] = {
1116 "none", "color", "linear", "radial", "radial2", "sweep", "conical"
1117 };
1118 SkASSERT((unsigned)t < SK_ARRAY_COUNT(gNames));
1119 return gNames[t];
1120}
1121
1122static int lshader_isOpaque(lua_State* L) {
1123 SkShader* shader = get_ref<SkShader>(L, 1);
1124 return shader && shader->isOpaque();
1125}
1126
Mike Reed627778d2016-09-28 17:13:38 -04001127static int lshader_isAImage(lua_State* L) {
reed@google.com5fdc9832013-07-24 15:47:52 +00001128 SkShader* shader = get_ref<SkShader>(L, 1);
1129 if (shader) {
reed@google.com5fdc9832013-07-24 15:47:52 +00001130 SkMatrix matrix;
1131 SkShader::TileMode modes[2];
Mike Reed627778d2016-09-28 17:13:38 -04001132 if (SkImage* image = shader->isAImage(&matrix, modes)) {
reedf5822822015-08-19 11:46:38 -07001133 lua_newtable(L);
Mike Reed627778d2016-09-28 17:13:38 -04001134 setfield_number(L, "id", image->uniqueID());
1135 setfield_number(L, "width", image->width());
1136 setfield_number(L, "height", image->height());
reedf5822822015-08-19 11:46:38 -07001137 setfield_string(L, "tileX", mode2string(modes[0]));
1138 setfield_string(L, "tileY", mode2string(modes[1]));
1139 return 1;
reed@google.com5fdc9832013-07-24 15:47:52 +00001140 }
1141 }
1142 return 0;
1143}
1144
1145static int lshader_asAGradient(lua_State* L) {
1146 SkShader* shader = get_ref<SkShader>(L, 1);
1147 if (shader) {
1148 SkShader::GradientInfo info;
1149 sk_bzero(&info, sizeof(info));
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001150
reed@google.com5fdc9832013-07-24 15:47:52 +00001151 SkShader::GradientType t = shader->asAGradient(&info);
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001152
reed@google.com5fdc9832013-07-24 15:47:52 +00001153 if (SkShader::kNone_GradientType != t) {
fmenozzib4f254e2016-06-28 14:03:03 -07001154 SkAutoTArray<SkScalar> pos(info.fColorCount);
1155 info.fColorOffsets = pos.get();
1156 shader->asAGradient(&info);
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001157
fmenozzib4f254e2016-06-28 14:03:03 -07001158 lua_newtable(L);
fmenozzi7f2c85e2016-07-12 09:17:39 -07001159 setfield_string(L, "type", gradtype2string(t));
1160 setfield_string(L, "tile", mode2string(info.fTileMode));
1161 setfield_number(L, "colorCount", info.fColorCount);
fmenozzib4f254e2016-06-28 14:03:03 -07001162
1163 lua_newtable(L);
1164 for (int i = 0; i < info.fColorCount; i++) {
1165 // Lua uses 1-based indexing
1166 setarray_scalar(L, i+1, pos[i]);
1167 }
1168 lua_setfield(L, -2, "positions");
1169
reed@google.com5fdc9832013-07-24 15:47:52 +00001170 return 1;
1171 }
1172 }
1173 return 0;
1174}
1175
1176static int lshader_gc(lua_State* L) {
1177 get_ref<SkShader>(L, 1)->unref();
1178 return 0;
1179}
1180
1181static const struct luaL_Reg gSkShader_Methods[] = {
1182 { "isOpaque", lshader_isOpaque },
Mike Reed627778d2016-09-28 17:13:38 -04001183 { "isAImage", lshader_isAImage },
reed@google.com5fdc9832013-07-24 15:47:52 +00001184 { "asAGradient", lshader_asAGradient },
1185 { "__gc", lshader_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001186 { nullptr, nullptr }
reed@google.com5fdc9832013-07-24 15:47:52 +00001187};
1188
1189///////////////////////////////////////////////////////////////////////////////
1190
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +00001191static int lpatheffect_asADash(lua_State* L) {
1192 SkPathEffect* pe = get_ref<SkPathEffect>(L, 1);
1193 if (pe) {
1194 SkPathEffect::DashInfo info;
1195 SkPathEffect::DashType dashType = pe->asADash(&info);
1196 if (SkPathEffect::kDash_DashType == dashType) {
1197 SkAutoTArray<SkScalar> intervals(info.fCount);
1198 info.fIntervals = intervals.get();
1199 pe->asADash(&info);
1200 SkLua(L).pushDash(info);
1201 return 1;
1202 }
1203 }
1204 return 0;
1205}
1206
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001207static int lpatheffect_gc(lua_State* L) {
1208 get_ref<SkPathEffect>(L, 1)->unref();
1209 return 0;
1210}
1211
1212static const struct luaL_Reg gSkPathEffect_Methods[] = {
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +00001213 { "asADash", lpatheffect_asADash },
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001214 { "__gc", lpatheffect_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001215 { nullptr, nullptr }
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001216};
1217
1218///////////////////////////////////////////////////////////////////////////////
1219
reed22a517f2015-12-04 20:45:59 -08001220static int lpcolorfilter_gc(lua_State* L) {
1221 get_ref<SkColorFilter>(L, 1)->unref();
1222 return 0;
1223}
1224
1225static const struct luaL_Reg gSkColorFilter_Methods[] = {
1226 { "__gc", lpcolorfilter_gc },
1227 { nullptr, nullptr }
1228};
1229
1230///////////////////////////////////////////////////////////////////////////////
1231
reed468b1812014-10-19 11:42:54 -07001232static int lpimagefilter_gc(lua_State* L) {
1233 get_ref<SkImageFilter>(L, 1)->unref();
1234 return 0;
1235}
1236
1237static const struct luaL_Reg gSkImageFilter_Methods[] = {
1238 { "__gc", lpimagefilter_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001239 { nullptr, nullptr }
reed468b1812014-10-19 11:42:54 -07001240};
1241
1242///////////////////////////////////////////////////////////////////////////////
1243
humper@google.com2815c192013-07-10 22:42:30 +00001244static int lmatrix_getType(lua_State* L) {
1245 SkMatrix::TypeMask mask = get_obj<SkMatrix>(L, 1)->getType();
skia.committer@gmail.comde2e4e82013-07-11 07:01:01 +00001246
humper@google.com2815c192013-07-10 22:42:30 +00001247 lua_newtable(L);
1248 setfield_boolean(L, "translate", SkToBool(mask & SkMatrix::kTranslate_Mask));
1249 setfield_boolean(L, "scale", SkToBool(mask & SkMatrix::kScale_Mask));
1250 setfield_boolean(L, "affine", SkToBool(mask & SkMatrix::kAffine_Mask));
1251 setfield_boolean(L, "perspective", SkToBool(mask & SkMatrix::kPerspective_Mask));
1252 return 1;
1253}
1254
humper@google.com0f48ee02013-07-26 15:23:43 +00001255static int lmatrix_getScaleX(lua_State* L) {
1256 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getScaleX());
1257 return 1;
1258}
1259
1260static int lmatrix_getScaleY(lua_State* L) {
1261 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getScaleY());
1262 return 1;
1263}
1264
1265static int lmatrix_getTranslateX(lua_State* L) {
1266 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getTranslateX());
1267 return 1;
1268}
1269
1270static int lmatrix_getTranslateY(lua_State* L) {
1271 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getTranslateY());
1272 return 1;
1273}
1274
reed7a72c672014-11-07 10:23:55 -08001275static int lmatrix_invert(lua_State* L) {
1276 lua_pushboolean(L, get_obj<SkMatrix>(L, 1)->invert(get_obj<SkMatrix>(L, 2)));
1277 return 1;
1278}
1279
1280static int lmatrix_mapXY(lua_State* L) {
1281 SkPoint pt = { lua2scalar(L, 2), lua2scalar(L, 3) };
1282 get_obj<SkMatrix>(L, 1)->mapPoints(&pt, &pt, 1);
1283 lua_pushnumber(L, pt.x());
1284 lua_pushnumber(L, pt.y());
1285 return 2;
1286}
1287
reedbdc49ae2014-10-14 09:34:52 -07001288static int lmatrix_setRectToRect(lua_State* L) {
1289 SkMatrix* matrix = get_obj<SkMatrix>(L, 1);
1290 SkRect srcR, dstR;
1291 lua2rect(L, 2, &srcR);
1292 lua2rect(L, 3, &dstR);
1293 const char* scaleToFitStr = lua_tostring(L, 4);
1294 SkMatrix::ScaleToFit scaleToFit = SkMatrix::kFill_ScaleToFit;
1295
1296 if (scaleToFitStr) {
1297 const struct {
1298 const char* fName;
1299 SkMatrix::ScaleToFit fScaleToFit;
1300 } rec[] = {
1301 { "fill", SkMatrix::kFill_ScaleToFit },
1302 { "start", SkMatrix::kStart_ScaleToFit },
1303 { "center", SkMatrix::kCenter_ScaleToFit },
1304 { "end", SkMatrix::kEnd_ScaleToFit },
1305 };
1306
1307 for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
1308 if (strcmp(rec[i].fName, scaleToFitStr) == 0) {
1309 scaleToFit = rec[i].fScaleToFit;
1310 break;
1311 }
1312 }
1313 }
1314
1315 matrix->setRectToRect(srcR, dstR, scaleToFit);
1316 return 0;
1317}
1318
humper@google.com2815c192013-07-10 22:42:30 +00001319static const struct luaL_Reg gSkMatrix_Methods[] = {
1320 { "getType", lmatrix_getType },
humper@google.com0f48ee02013-07-26 15:23:43 +00001321 { "getScaleX", lmatrix_getScaleX },
1322 { "getScaleY", lmatrix_getScaleY },
1323 { "getTranslateX", lmatrix_getTranslateX },
1324 { "getTranslateY", lmatrix_getTranslateY },
reedbdc49ae2014-10-14 09:34:52 -07001325 { "setRectToRect", lmatrix_setRectToRect },
reed7a72c672014-11-07 10:23:55 -08001326 { "invert", lmatrix_invert },
1327 { "mapXY", lmatrix_mapXY },
halcanary96fcdcc2015-08-27 07:41:13 -07001328 { nullptr, nullptr }
humper@google.com2815c192013-07-10 22:42:30 +00001329};
1330
1331///////////////////////////////////////////////////////////////////////////////
1332
reed@google.com74ce6f02013-05-22 15:13:18 +00001333static int lpath_getBounds(lua_State* L) {
1334 SkLua(L).pushRect(get_obj<SkPath>(L, 1)->getBounds());
1335 return 1;
1336}
1337
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001338static const char* fill_type_to_str(SkPath::FillType fill) {
1339 switch (fill) {
1340 case SkPath::kEvenOdd_FillType:
1341 return "even-odd";
1342 case SkPath::kWinding_FillType:
1343 return "winding";
1344 case SkPath::kInverseEvenOdd_FillType:
1345 return "inverse-even-odd";
1346 case SkPath::kInverseWinding_FillType:
1347 return "inverse-winding";
1348 }
1349 return "unknown";
1350}
1351
1352static int lpath_getFillType(lua_State* L) {
1353 SkPath::FillType fill = get_obj<SkPath>(L, 1)->getFillType();
1354 SkLua(L).pushString(fill_type_to_str(fill));
1355 return 1;
1356}
1357
1358static SkString segment_masks_to_str(uint32_t segmentMasks) {
1359 SkString result;
1360 bool first = true;
1361 if (SkPath::kLine_SegmentMask & segmentMasks) {
1362 result.append("line");
1363 first = false;
1364 SkDEBUGCODE(segmentMasks &= ~SkPath::kLine_SegmentMask;)
1365 }
1366 if (SkPath::kQuad_SegmentMask & segmentMasks) {
1367 if (!first) {
1368 result.append(" ");
1369 }
1370 result.append("quad");
1371 first = false;
1372 SkDEBUGCODE(segmentMasks &= ~SkPath::kQuad_SegmentMask;)
1373 }
1374 if (SkPath::kConic_SegmentMask & segmentMasks) {
1375 if (!first) {
1376 result.append(" ");
1377 }
1378 result.append("conic");
1379 first = false;
1380 SkDEBUGCODE(segmentMasks &= ~SkPath::kConic_SegmentMask;)
1381 }
1382 if (SkPath::kCubic_SegmentMask & segmentMasks) {
1383 if (!first) {
1384 result.append(" ");
1385 }
1386 result.append("cubic");
1387 SkDEBUGCODE(segmentMasks &= ~SkPath::kCubic_SegmentMask;)
1388 }
1389 SkASSERT(0 == segmentMasks);
1390 return result;
1391}
1392
krajcevski95498ed2014-08-18 08:02:33 -07001393static int lpath_getSegmentTypes(lua_State* L) {
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001394 uint32_t segMasks = get_obj<SkPath>(L, 1)->getSegmentMasks();
1395 SkLua(L).pushString(segment_masks_to_str(segMasks));
1396 return 1;
1397}
1398
1399static int lpath_isConvex(lua_State* L) {
1400 bool isConvex = SkPath::kConvex_Convexity == get_obj<SkPath>(L, 1)->getConvexity();
1401 SkLua(L).pushBool(isConvex);
1402 return 1;
1403}
1404
reed@google.com74ce6f02013-05-22 15:13:18 +00001405static int lpath_isEmpty(lua_State* L) {
1406 lua_pushboolean(L, get_obj<SkPath>(L, 1)->isEmpty());
1407 return 1;
1408}
1409
1410static int lpath_isRect(lua_State* L) {
1411 SkRect r;
1412 bool pred = get_obj<SkPath>(L, 1)->isRect(&r);
1413 int ret_count = 1;
1414 lua_pushboolean(L, pred);
1415 if (pred) {
1416 SkLua(L).pushRect(r);
1417 ret_count += 1;
1418 }
1419 return ret_count;
1420}
1421
1422static const char* dir2string(SkPath::Direction dir) {
1423 static const char* gStr[] = {
1424 "unknown", "cw", "ccw"
1425 };
1426 SkASSERT((unsigned)dir < SK_ARRAY_COUNT(gStr));
1427 return gStr[dir];
1428}
1429
caryclark95bc5f32015-04-08 08:34:15 -07001430static int lpath_isNestedFillRects(lua_State* L) {
reed@google.com74ce6f02013-05-22 15:13:18 +00001431 SkRect rects[2];
1432 SkPath::Direction dirs[2];
caryclark95bc5f32015-04-08 08:34:15 -07001433 bool pred = get_obj<SkPath>(L, 1)->isNestedFillRects(rects, dirs);
reed@google.com74ce6f02013-05-22 15:13:18 +00001434 int ret_count = 1;
1435 lua_pushboolean(L, pred);
1436 if (pred) {
1437 SkLua lua(L);
1438 lua.pushRect(rects[0]);
1439 lua.pushRect(rects[1]);
1440 lua_pushstring(L, dir2string(dirs[0]));
1441 lua_pushstring(L, dir2string(dirs[0]));
1442 ret_count += 4;
1443 }
1444 return ret_count;
1445}
1446
commit-bot@chromium.orgc5302082014-02-26 21:38:47 +00001447static int lpath_countPoints(lua_State* L) {
1448 lua_pushinteger(L, get_obj<SkPath>(L, 1)->countPoints());
1449 return 1;
1450}
1451
hstern0b401ce2016-08-02 09:17:59 -07001452static int lpath_getVerbs(lua_State* L) {
1453 const SkPath* path = get_obj<SkPath>(L, 1);
1454 SkPath::Iter iter(*path, false);
1455 SkPoint pts[4];
1456
1457 lua_newtable(L);
1458
1459 bool done = false;
1460 int i = 0;
1461 do {
1462 switch (iter.next(pts, true)) {
1463 case SkPath::kMove_Verb:
1464 setarray_string(L, ++i, "move");
1465 break;
1466 case SkPath::kClose_Verb:
1467 setarray_string(L, ++i, "close");
1468 break;
1469 case SkPath::kLine_Verb:
1470 setarray_string(L, ++i, "line");
1471 break;
1472 case SkPath::kQuad_Verb:
1473 setarray_string(L, ++i, "quad");
1474 break;
1475 case SkPath::kConic_Verb:
1476 setarray_string(L, ++i, "conic");
1477 break;
1478 case SkPath::kCubic_Verb:
1479 setarray_string(L, ++i, "cubic");
1480 break;
1481 case SkPath::kDone_Verb:
1482 setarray_string(L, ++i, "done");
1483 done = true;
1484 break;
1485 }
1486 } while (!done);
1487
1488 return 1;
1489}
1490
reed@google.com74ce6f02013-05-22 15:13:18 +00001491static int lpath_reset(lua_State* L) {
1492 get_obj<SkPath>(L, 1)->reset();
1493 return 0;
1494}
1495
1496static int lpath_moveTo(lua_State* L) {
1497 get_obj<SkPath>(L, 1)->moveTo(lua2scalar(L, 2), lua2scalar(L, 3));
1498 return 0;
1499}
1500
1501static int lpath_lineTo(lua_State* L) {
1502 get_obj<SkPath>(L, 1)->lineTo(lua2scalar(L, 2), lua2scalar(L, 3));
1503 return 0;
1504}
1505
1506static int lpath_quadTo(lua_State* L) {
1507 get_obj<SkPath>(L, 1)->quadTo(lua2scalar(L, 2), lua2scalar(L, 3),
1508 lua2scalar(L, 4), lua2scalar(L, 5));
1509 return 0;
1510}
1511
1512static int lpath_cubicTo(lua_State* L) {
1513 get_obj<SkPath>(L, 1)->cubicTo(lua2scalar(L, 2), lua2scalar(L, 3),
1514 lua2scalar(L, 4), lua2scalar(L, 5),
1515 lua2scalar(L, 6), lua2scalar(L, 7));
1516 return 0;
1517}
1518
1519static int lpath_close(lua_State* L) {
1520 get_obj<SkPath>(L, 1)->close();
1521 return 0;
1522}
1523
1524static int lpath_gc(lua_State* L) {
1525 get_obj<SkPath>(L, 1)->~SkPath();
1526 return 0;
1527}
1528
1529static const struct luaL_Reg gSkPath_Methods[] = {
1530 { "getBounds", lpath_getBounds },
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001531 { "getFillType", lpath_getFillType },
krajcevski95498ed2014-08-18 08:02:33 -07001532 { "getSegmentTypes", lpath_getSegmentTypes },
hstern0b401ce2016-08-02 09:17:59 -07001533 { "getVerbs", lpath_getVerbs },
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001534 { "isConvex", lpath_isConvex },
reed@google.com74ce6f02013-05-22 15:13:18 +00001535 { "isEmpty", lpath_isEmpty },
1536 { "isRect", lpath_isRect },
caryclark95bc5f32015-04-08 08:34:15 -07001537 { "isNestedFillRects", lpath_isNestedFillRects },
commit-bot@chromium.orgc5302082014-02-26 21:38:47 +00001538 { "countPoints", lpath_countPoints },
reed@google.com74ce6f02013-05-22 15:13:18 +00001539 { "reset", lpath_reset },
1540 { "moveTo", lpath_moveTo },
1541 { "lineTo", lpath_lineTo },
1542 { "quadTo", lpath_quadTo },
1543 { "cubicTo", lpath_cubicTo },
1544 { "close", lpath_close },
1545 { "__gc", lpath_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001546 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001547};
1548
1549///////////////////////////////////////////////////////////////////////////////
1550
1551static const char* rrect_type(const SkRRect& rr) {
1552 switch (rr.getType()) {
reed@google.com74ce6f02013-05-22 15:13:18 +00001553 case SkRRect::kEmpty_Type: return "empty";
1554 case SkRRect::kRect_Type: return "rect";
1555 case SkRRect::kOval_Type: return "oval";
1556 case SkRRect::kSimple_Type: return "simple";
commit-bot@chromium.orgf338d7c2014-03-17 21:17:30 +00001557 case SkRRect::kNinePatch_Type: return "nine-patch";
reed@google.com74ce6f02013-05-22 15:13:18 +00001558 case SkRRect::kComplex_Type: return "complex";
1559 }
mtklein@google.com330313a2013-08-22 15:37:26 +00001560 SkDEBUGFAIL("never get here");
reed@google.com74ce6f02013-05-22 15:13:18 +00001561 return "";
1562}
1563
1564static int lrrect_rect(lua_State* L) {
1565 SkLua(L).pushRect(get_obj<SkRRect>(L, 1)->rect());
1566 return 1;
1567}
1568
1569static int lrrect_type(lua_State* L) {
1570 lua_pushstring(L, rrect_type(*get_obj<SkRRect>(L, 1)));
1571 return 1;
1572}
1573
1574static int lrrect_radii(lua_State* L) {
reed@google.com7fa2a652014-01-27 13:42:58 +00001575 int corner = SkToInt(lua_tointeger(L, 2));
reed@google.com74ce6f02013-05-22 15:13:18 +00001576 SkVector v;
1577 if (corner < 0 || corner > 3) {
1578 SkDebugf("bad corner index %d", corner);
1579 v.set(0, 0);
1580 } else {
1581 v = get_obj<SkRRect>(L, 1)->radii((SkRRect::Corner)corner);
1582 }
1583 lua_pushnumber(L, v.fX);
1584 lua_pushnumber(L, v.fY);
1585 return 2;
1586}
1587
1588static int lrrect_gc(lua_State* L) {
1589 get_obj<SkRRect>(L, 1)->~SkRRect();
1590 return 0;
1591}
1592
1593static const struct luaL_Reg gSkRRect_Methods[] = {
1594 { "rect", lrrect_rect },
1595 { "type", lrrect_type },
1596 { "radii", lrrect_radii },
1597 { "__gc", lrrect_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001598 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001599};
1600
1601///////////////////////////////////////////////////////////////////////////////
1602
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001603static int limage_width(lua_State* L) {
1604 lua_pushinteger(L, get_ref<SkImage>(L, 1)->width());
1605 return 1;
1606}
1607
1608static int limage_height(lua_State* L) {
1609 lua_pushinteger(L, get_ref<SkImage>(L, 1)->height());
1610 return 1;
1611}
1612
reed7a72c672014-11-07 10:23:55 -08001613static int limage_newShader(lua_State* L) {
1614 SkShader::TileMode tmode = SkShader::kClamp_TileMode;
halcanary96fcdcc2015-08-27 07:41:13 -07001615 const SkMatrix* localM = nullptr;
reed5671c5b2016-03-09 14:47:34 -08001616 push_ref(L, get_ref<SkImage>(L, 1)->makeShader(tmode, tmode, localM));
reed7a72c672014-11-07 10:23:55 -08001617 return 1;
1618}
1619
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001620static int limage_gc(lua_State* L) {
1621 get_ref<SkImage>(L, 1)->unref();
1622 return 0;
1623}
1624
1625static const struct luaL_Reg gSkImage_Methods[] = {
1626 { "width", limage_width },
1627 { "height", limage_height },
reed7a72c672014-11-07 10:23:55 -08001628 { "newShader", limage_newShader },
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001629 { "__gc", limage_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001630 { nullptr, nullptr }
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001631};
1632
1633///////////////////////////////////////////////////////////////////////////////
1634
reed485557f2014-10-12 10:36:47 -07001635static int lsurface_width(lua_State* L) {
1636 lua_pushinteger(L, get_ref<SkSurface>(L, 1)->width());
1637 return 1;
1638}
1639
1640static int lsurface_height(lua_State* L) {
1641 lua_pushinteger(L, get_ref<SkSurface>(L, 1)->height());
1642 return 1;
1643}
1644
1645static int lsurface_getCanvas(lua_State* L) {
1646 SkCanvas* canvas = get_ref<SkSurface>(L, 1)->getCanvas();
halcanary96fcdcc2015-08-27 07:41:13 -07001647 if (nullptr == canvas) {
reed485557f2014-10-12 10:36:47 -07001648 lua_pushnil(L);
1649 } else {
Mike Reed5df49342016-11-12 08:06:55 -06001650 push_ptr(L, canvas);
reed485557f2014-10-12 10:36:47 -07001651 // note: we don't unref canvas, since getCanvas did not ref it.
1652 // warning: this is weird: now Lua owns a ref on this canvas, but what if they let
1653 // the real owner (the surface) go away, but still hold onto the canvas?
1654 // *really* we want to sort of ref the surface again, but have the native object
1655 // know that it is supposed to be treated as a canvas...
1656 }
1657 return 1;
1658}
1659
1660static int lsurface_newImageSnapshot(lua_State* L) {
reed9ce9d672016-03-17 10:51:11 -07001661 sk_sp<SkImage> image = get_ref<SkSurface>(L, 1)->makeImageSnapshot();
1662 if (!image) {
reed485557f2014-10-12 10:36:47 -07001663 lua_pushnil(L);
1664 } else {
reed9ce9d672016-03-17 10:51:11 -07001665 push_ref(L, image);
reed485557f2014-10-12 10:36:47 -07001666 }
1667 return 1;
1668}
1669
1670static int lsurface_newSurface(lua_State* L) {
1671 int width = lua2int_def(L, 2, 0);
reed96affcd2014-10-13 12:38:04 -07001672 int height = lua2int_def(L, 3, 0);
reed485557f2014-10-12 10:36:47 -07001673 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
reede8f30622016-03-23 18:59:25 -07001674 auto surface = get_ref<SkSurface>(L, 1)->makeSurface(info);
halcanary96fcdcc2015-08-27 07:41:13 -07001675 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -07001676 lua_pushnil(L);
1677 } else {
reede8f30622016-03-23 18:59:25 -07001678 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -07001679 }
1680 return 1;
1681}
1682
1683static int lsurface_gc(lua_State* L) {
1684 get_ref<SkSurface>(L, 1)->unref();
1685 return 0;
1686}
1687
1688static const struct luaL_Reg gSkSurface_Methods[] = {
1689 { "width", lsurface_width },
1690 { "height", lsurface_height },
1691 { "getCanvas", lsurface_getCanvas },
1692 { "newImageSnapshot", lsurface_newImageSnapshot },
1693 { "newSurface", lsurface_newSurface },
1694 { "__gc", lsurface_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001695 { nullptr, nullptr }
reed485557f2014-10-12 10:36:47 -07001696};
1697
1698///////////////////////////////////////////////////////////////////////////////
1699
reed96affcd2014-10-13 12:38:04 -07001700static int lpicturerecorder_beginRecording(lua_State* L) {
1701 const SkScalar w = lua2scalar_def(L, 2, -1);
1702 const SkScalar h = lua2scalar_def(L, 3, -1);
1703 if (w <= 0 || h <= 0) {
1704 lua_pushnil(L);
1705 return 1;
1706 }
1707
1708 SkCanvas* canvas = get_obj<SkPictureRecorder>(L, 1)->beginRecording(w, h);
halcanary96fcdcc2015-08-27 07:41:13 -07001709 if (nullptr == canvas) {
reed96affcd2014-10-13 12:38:04 -07001710 lua_pushnil(L);
1711 return 1;
1712 }
1713
Mike Reed5df49342016-11-12 08:06:55 -06001714 push_ptr(L, canvas);
reed96affcd2014-10-13 12:38:04 -07001715 return 1;
1716}
1717
1718static int lpicturerecorder_getCanvas(lua_State* L) {
1719 SkCanvas* canvas = get_obj<SkPictureRecorder>(L, 1)->getRecordingCanvas();
halcanary96fcdcc2015-08-27 07:41:13 -07001720 if (nullptr == canvas) {
reed96affcd2014-10-13 12:38:04 -07001721 lua_pushnil(L);
1722 return 1;
1723 }
Mike Reed5df49342016-11-12 08:06:55 -06001724 push_ptr(L, canvas);
reed96affcd2014-10-13 12:38:04 -07001725 return 1;
1726}
1727
1728static int lpicturerecorder_endRecording(lua_State* L) {
reedca2622b2016-03-18 07:25:55 -07001729 sk_sp<SkPicture> pic = get_obj<SkPictureRecorder>(L, 1)->finishRecordingAsPicture();
1730 if (!pic) {
reed96affcd2014-10-13 12:38:04 -07001731 lua_pushnil(L);
1732 return 1;
1733 }
reedca2622b2016-03-18 07:25:55 -07001734 push_ref(L, std::move(pic));
reed96affcd2014-10-13 12:38:04 -07001735 return 1;
1736}
1737
1738static int lpicturerecorder_gc(lua_State* L) {
1739 get_obj<SkPictureRecorder>(L, 1)->~SkPictureRecorder();
1740 return 0;
1741}
1742
1743static const struct luaL_Reg gSkPictureRecorder_Methods[] = {
1744 { "beginRecording", lpicturerecorder_beginRecording },
1745 { "getCanvas", lpicturerecorder_getCanvas },
1746 { "endRecording", lpicturerecorder_endRecording },
1747 { "__gc", lpicturerecorder_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001748 { nullptr, nullptr }
reed96affcd2014-10-13 12:38:04 -07001749};
1750
1751///////////////////////////////////////////////////////////////////////////////
1752
1753static int lpicture_width(lua_State* L) {
1754 lua_pushnumber(L, get_ref<SkPicture>(L, 1)->cullRect().width());
1755 return 1;
1756}
1757
1758static int lpicture_height(lua_State* L) {
1759 lua_pushnumber(L, get_ref<SkPicture>(L, 1)->cullRect().height());
1760 return 1;
1761}
1762
1763static int lpicture_gc(lua_State* L) {
1764 get_ref<SkPicture>(L, 1)->unref();
1765 return 0;
1766}
1767
1768static const struct luaL_Reg gSkPicture_Methods[] = {
1769 { "width", lpicture_width },
1770 { "height", lpicture_height },
1771 { "__gc", lpicture_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001772 { nullptr, nullptr }
reed96affcd2014-10-13 12:38:04 -07001773};
1774
1775///////////////////////////////////////////////////////////////////////////////
1776
reed1b6ab442014-11-03 19:55:41 -08001777static int ltextblob_bounds(lua_State* L) {
1778 SkLua(L).pushRect(get_ref<SkTextBlob>(L, 1)->bounds());
1779 return 1;
1780}
1781
1782static int ltextblob_gc(lua_State* L) {
1783 SkSafeUnref(get_ref<SkTextBlob>(L, 1));
1784 return 0;
1785}
1786
1787static const struct luaL_Reg gSkTextBlob_Methods[] = {
1788 { "bounds", ltextblob_bounds },
1789 { "__gc", ltextblob_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001790 { nullptr, nullptr }
reed1b6ab442014-11-03 19:55:41 -08001791};
1792
1793///////////////////////////////////////////////////////////////////////////////
1794
reed36c9c112014-11-04 10:58:42 -08001795static int ltypeface_getFamilyName(lua_State* L) {
1796 SkString str;
1797 get_ref<SkTypeface>(L, 1)->getFamilyName(&str);
1798 lua_pushstring(L, str.c_str());
1799 return 1;
1800}
1801
1802static int ltypeface_getStyle(lua_State* L) {
1803 lua_pushnumber(L, (double)get_ref<SkTypeface>(L, 1)->style());
1804 return 1;
1805}
1806
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001807static int ltypeface_gc(lua_State* L) {
commit-bot@chromium.org77887af2013-12-17 14:28:19 +00001808 SkSafeUnref(get_ref<SkTypeface>(L, 1));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001809 return 0;
1810}
1811
1812static const struct luaL_Reg gSkTypeface_Methods[] = {
reed36c9c112014-11-04 10:58:42 -08001813 { "getFamilyName", ltypeface_getFamilyName },
1814 { "getStyle", ltypeface_getStyle },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001815 { "__gc", ltypeface_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001816 { nullptr, nullptr }
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001817};
1818
1819///////////////////////////////////////////////////////////////////////////////
1820
reed@google.com74ce6f02013-05-22 15:13:18 +00001821class AutoCallLua {
1822public:
1823 AutoCallLua(lua_State* L, const char func[], const char verb[]) : fL(L) {
1824 lua_getglobal(L, func);
1825 if (!lua_isfunction(L, -1)) {
1826 int t = lua_type(L, -1);
1827 SkDebugf("--- expected function %d\n", t);
1828 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001829
reed@google.com74ce6f02013-05-22 15:13:18 +00001830 lua_newtable(L);
1831 setfield_string(L, "verb", verb);
1832 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001833
reed@google.com74ce6f02013-05-22 15:13:18 +00001834 ~AutoCallLua() {
1835 if (lua_pcall(fL, 1, 0, 0) != LUA_OK) {
1836 SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
1837 }
1838 lua_settop(fL, -1);
1839 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001840
reed@google.com74ce6f02013-05-22 15:13:18 +00001841private:
1842 lua_State* fL;
1843};
1844
1845#define AUTO_LUA(verb) AutoCallLua acl(fL, fFunc.c_str(), verb)
1846
1847///////////////////////////////////////////////////////////////////////////////
1848
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001849static int lsk_newDocumentPDF(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07001850 const char* file = nullptr;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001851 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001852 file = lua_tolstring(L, 1, nullptr);
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001853 }
1854
halcanary676ab682016-05-03 12:10:04 -07001855 sk_sp<SkDocument> doc = SkDocument::MakePDF(file);
halcanary96fcdcc2015-08-27 07:41:13 -07001856 if (nullptr == doc) {
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001857 // do I need to push a nil on the stack and return 1?
1858 return 0;
1859 } else {
halcanary676ab682016-05-03 12:10:04 -07001860 push_ref(L, std::move(doc));
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001861 return 1;
1862 }
1863}
1864
reed468b1812014-10-19 11:42:54 -07001865static int lsk_newBlurImageFilter(lua_State* L) {
1866 SkScalar sigmaX = lua2scalar_def(L, 1, 0);
1867 SkScalar sigmaY = lua2scalar_def(L, 2, 0);
robertphillips6e7025a2016-04-04 04:31:25 -07001868 sk_sp<SkImageFilter> imf(SkBlurImageFilter::Make(sigmaX, sigmaY, nullptr));
1869 if (!imf) {
reed468b1812014-10-19 11:42:54 -07001870 lua_pushnil(L);
1871 } else {
robertphillips6e7025a2016-04-04 04:31:25 -07001872 push_ref(L, std::move(imf));
reed9fbc3f32014-10-21 07:12:58 -07001873 }
1874 return 1;
1875}
1876
1877static int lsk_newLinearGradient(lua_State* L) {
1878 SkScalar x0 = lua2scalar_def(L, 1, 0);
1879 SkScalar y0 = lua2scalar_def(L, 2, 0);
1880 SkColor c0 = lua2color(L, 3);
1881 SkScalar x1 = lua2scalar_def(L, 4, 0);
1882 SkScalar y1 = lua2scalar_def(L, 5, 0);
1883 SkColor c1 = lua2color(L, 6);
1884
1885 SkPoint pts[] = { { x0, y0 }, { x1, y1 } };
1886 SkColor colors[] = { c0, c1 };
robertphillips6e7025a2016-04-04 04:31:25 -07001887 sk_sp<SkShader> s(SkGradientShader::MakeLinear(pts, colors, nullptr, 2,
1888 SkShader::kClamp_TileMode));
reed2ad1aa62016-03-09 09:50:50 -08001889 if (!s) {
reed9fbc3f32014-10-21 07:12:58 -07001890 lua_pushnil(L);
1891 } else {
reed2ad1aa62016-03-09 09:50:50 -08001892 push_ref(L, std::move(s));
reed468b1812014-10-19 11:42:54 -07001893 }
1894 return 1;
1895}
1896
reedbdc49ae2014-10-14 09:34:52 -07001897static int lsk_newMatrix(lua_State* L) {
1898 push_new<SkMatrix>(L)->reset();
1899 return 1;
1900}
1901
reed@google.com3597b732013-05-22 20:12:50 +00001902static int lsk_newPaint(lua_State* L) {
1903 push_new<SkPaint>(L);
1904 return 1;
1905}
1906
1907static int lsk_newPath(lua_State* L) {
1908 push_new<SkPath>(L);
1909 return 1;
1910}
1911
reed96affcd2014-10-13 12:38:04 -07001912static int lsk_newPictureRecorder(lua_State* L) {
1913 push_new<SkPictureRecorder>(L);
1914 return 1;
1915}
1916
reed@google.com3597b732013-05-22 20:12:50 +00001917static int lsk_newRRect(lua_State* L) {
reedbdc49ae2014-10-14 09:34:52 -07001918 push_new<SkRRect>(L)->setEmpty();
reed@google.com3597b732013-05-22 20:12:50 +00001919 return 1;
1920}
1921
reed1b6ab442014-11-03 19:55:41 -08001922#include "SkTextBox.h"
1923// Sk.newTextBlob(text, rect, paint)
1924static int lsk_newTextBlob(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07001925 const char* text = lua_tolstring(L, 1, nullptr);
reed1b6ab442014-11-03 19:55:41 -08001926 SkRect bounds;
1927 lua2rect(L, 2, &bounds);
1928 const SkPaint& paint = *get_obj<SkPaint>(L, 3);
1929
1930 SkTextBox box;
1931 box.setMode(SkTextBox::kLineBreak_Mode);
1932 box.setBox(bounds);
1933 box.setText(text, strlen(text), paint);
1934
1935 SkScalar newBottom;
fmalita37283c22016-09-13 10:00:23 -07001936 push_ref<SkTextBlob>(L, box.snapshotTextBlob(&newBottom));
reed1b6ab442014-11-03 19:55:41 -08001937 SkLua(L).pushScalar(newBottom);
1938 return 2;
1939}
1940
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001941static int lsk_newTypeface(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07001942 const char* name = nullptr;
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001943 int style = SkTypeface::kNormal;
skia.committer@gmail.com63193672013-06-08 07:01:13 +00001944
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001945 int count = lua_gettop(L);
1946 if (count > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001947 name = lua_tolstring(L, 1, nullptr);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001948 if (count > 1 && lua_isnumber(L, 2)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001949 style = lua_tointegerx(L, 2, nullptr) & SkTypeface::kBoldItalic;
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001950 }
1951 }
1952
mbocee6a9912016-05-31 11:42:36 -07001953 sk_sp<SkTypeface> face(SkTypeface::MakeFromName(name, SkFontStyle::FromOldStyle(style)));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001954// SkDebugf("---- name <%s> style=%d, face=%p ref=%d\n", name, style, face, face->getRefCnt());
halcanary96fcdcc2015-08-27 07:41:13 -07001955 if (nullptr == face) {
bungeman13b9c952016-05-12 10:09:30 -07001956 face = SkTypeface::MakeDefault();
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001957 }
bungeman13b9c952016-05-12 10:09:30 -07001958 push_ref(L, std::move(face));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001959 return 1;
1960}
reed@google.com3597b732013-05-22 20:12:50 +00001961
reed485557f2014-10-12 10:36:47 -07001962static int lsk_newRasterSurface(lua_State* L) {
reed7b864662014-11-04 13:24:47 -08001963 int width = lua2int_def(L, 1, 0);
reed485557f2014-10-12 10:36:47 -07001964 int height = lua2int_def(L, 2, 0);
1965 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
robertphillips702edbd2015-06-23 06:26:08 -07001966 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
reede8f30622016-03-23 18:59:25 -07001967 auto surface = SkSurface::MakeRaster(info, &props);
halcanary96fcdcc2015-08-27 07:41:13 -07001968 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -07001969 lua_pushnil(L);
1970 } else {
reede8f30622016-03-23 18:59:25 -07001971 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -07001972 }
1973 return 1;
1974}
1975
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001976static int lsk_loadImage(lua_State* L) {
1977 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001978 const char* name = lua_tolstring(L, 1, nullptr);
reed9ce9d672016-03-17 10:51:11 -07001979 sk_sp<SkData> data(SkData::MakeFromFileName(name));
1980 if (data) {
1981 auto image = SkImage::MakeFromEncoded(std::move(data));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001982 if (image) {
reed9ce9d672016-03-17 10:51:11 -07001983 push_ref(L, std::move(image));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001984 return 1;
1985 }
1986 }
1987 }
1988 return 0;
1989}
1990
reed@google.com3597b732013-05-22 20:12:50 +00001991static void register_Sk(lua_State* L) {
1992 lua_newtable(L);
1993 lua_pushvalue(L, -1);
1994 lua_setglobal(L, "Sk");
1995 // the Sk table is still on top
1996
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001997 setfield_function(L, "newDocumentPDF", lsk_newDocumentPDF);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001998 setfield_function(L, "loadImage", lsk_loadImage);
reed468b1812014-10-19 11:42:54 -07001999 setfield_function(L, "newBlurImageFilter", lsk_newBlurImageFilter);
reed9fbc3f32014-10-21 07:12:58 -07002000 setfield_function(L, "newLinearGradient", lsk_newLinearGradient);
reedbdc49ae2014-10-14 09:34:52 -07002001 setfield_function(L, "newMatrix", lsk_newMatrix);
reed@google.com3597b732013-05-22 20:12:50 +00002002 setfield_function(L, "newPaint", lsk_newPaint);
2003 setfield_function(L, "newPath", lsk_newPath);
reed96affcd2014-10-13 12:38:04 -07002004 setfield_function(L, "newPictureRecorder", lsk_newPictureRecorder);
reed@google.com3597b732013-05-22 20:12:50 +00002005 setfield_function(L, "newRRect", lsk_newRRect);
reed485557f2014-10-12 10:36:47 -07002006 setfield_function(L, "newRasterSurface", lsk_newRasterSurface);
reed1b6ab442014-11-03 19:55:41 -08002007 setfield_function(L, "newTextBlob", lsk_newTextBlob);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00002008 setfield_function(L, "newTypeface", lsk_newTypeface);
reed@google.com3597b732013-05-22 20:12:50 +00002009 lua_pop(L, 1); // pop off the Sk table
2010}
2011
reed@google.com74ce6f02013-05-22 15:13:18 +00002012#define REG_CLASS(L, C) \
2013 do { \
reed@google.com3597b732013-05-22 20:12:50 +00002014 luaL_newmetatable(L, get_mtname<C>()); \
reed@google.com74ce6f02013-05-22 15:13:18 +00002015 lua_pushvalue(L, -1); \
2016 lua_setfield(L, -2, "__index"); \
2017 luaL_setfuncs(L, g##C##_Methods, 0); \
2018 lua_pop(L, 1); /* pop off the meta-table */ \
2019 } while (0)
2020
2021void SkLua::Load(lua_State* L) {
reed@google.com3597b732013-05-22 20:12:50 +00002022 register_Sk(L);
reed@google.com74ce6f02013-05-22 15:13:18 +00002023 REG_CLASS(L, SkCanvas);
reed22a517f2015-12-04 20:45:59 -08002024 REG_CLASS(L, SkColorFilter);
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00002025 REG_CLASS(L, SkDocument);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00002026 REG_CLASS(L, SkImage);
reed468b1812014-10-19 11:42:54 -07002027 REG_CLASS(L, SkImageFilter);
reed1b6ab442014-11-03 19:55:41 -08002028 REG_CLASS(L, SkMatrix);
reed@google.com74ce6f02013-05-22 15:13:18 +00002029 REG_CLASS(L, SkPaint);
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00002030 REG_CLASS(L, SkPath);
2031 REG_CLASS(L, SkPathEffect);
reed96affcd2014-10-13 12:38:04 -07002032 REG_CLASS(L, SkPicture);
2033 REG_CLASS(L, SkPictureRecorder);
reed@google.com74ce6f02013-05-22 15:13:18 +00002034 REG_CLASS(L, SkRRect);
reed@google.com5fdc9832013-07-24 15:47:52 +00002035 REG_CLASS(L, SkShader);
reed485557f2014-10-12 10:36:47 -07002036 REG_CLASS(L, SkSurface);
reed1b6ab442014-11-03 19:55:41 -08002037 REG_CLASS(L, SkTextBlob);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00002038 REG_CLASS(L, SkTypeface);
reed@google.com74ce6f02013-05-22 15:13:18 +00002039}
zachr@google.com28c27c82013-06-20 17:15:05 +00002040
reed@google.com7bce9982013-06-20 17:40:21 +00002041extern "C" int luaopen_skia(lua_State* L);
zachr@google.com28c27c82013-06-20 17:15:05 +00002042extern "C" int luaopen_skia(lua_State* L) {
2043 SkLua::Load(L);
2044 return 0;
2045}