blob: 7ba98e5669fd0263f5774bca627006a64aa5bb3f [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_isUnderlineText(lua_State* L) {
721 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isUnderlineText());
722 return 1;
723}
724
725static int lpaint_isStrikeThruText(lua_State* L) {
726 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isStrikeThruText());
727 return 1;
728}
729
730static int lpaint_isFakeBoldText(lua_State* L) {
731 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isFakeBoldText());
732 return 1;
733}
734
735static int lpaint_isLinearText(lua_State* L) {
736 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isLinearText());
737 return 1;
738}
739
740static int lpaint_isSubpixelText(lua_State* L) {
741 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isSubpixelText());
742 return 1;
743}
744
reed09a1d672014-10-11 13:13:11 -0700745static int lpaint_setSubpixelText(lua_State* L) {
746 get_obj<SkPaint>(L, 1)->setSubpixelText(lua2bool(L, 2));
747 return 1;
748}
749
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000750static int lpaint_isDevKernText(lua_State* L) {
751 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isDevKernText());
752 return 1;
753}
754
755static int lpaint_isLCDRenderText(lua_State* L) {
756 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isLCDRenderText());
757 return 1;
758}
759
reed36c9c112014-11-04 10:58:42 -0800760static int lpaint_setLCDRenderText(lua_State* L) {
761 get_obj<SkPaint>(L, 1)->setLCDRenderText(lua2bool(L, 2));
762 return 1;
763}
764
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000765static int lpaint_isEmbeddedBitmapText(lua_State* L) {
766 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isEmbeddedBitmapText());
767 return 1;
768}
769
770static int lpaint_isAutohinted(lua_State* L) {
771 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isAutohinted());
772 return 1;
773}
774
775static int lpaint_isVerticalText(lua_State* L) {
776 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isVerticalText());
777 return 1;
778}
779
reed468b1812014-10-19 11:42:54 -0700780static int lpaint_getAlpha(lua_State* L) {
781 SkLua(L).pushScalar(byte2unit(get_obj<SkPaint>(L, 1)->getAlpha()));
782 return 1;
783}
784
785static int lpaint_setAlpha(lua_State* L) {
786 get_obj<SkPaint>(L, 1)->setAlpha(unit2byte(lua2scalar(L, 2)));
787 return 0;
788}
789
reed@google.com74ce6f02013-05-22 15:13:18 +0000790static int lpaint_getColor(lua_State* L) {
791 SkLua(L).pushColor(get_obj<SkPaint>(L, 1)->getColor());
792 return 1;
793}
794
795static int lpaint_setColor(lua_State* L) {
796 get_obj<SkPaint>(L, 1)->setColor(lua2color(L, 2));
797 return 0;
798}
799
reed@google.come3823fd2013-05-30 18:55:14 +0000800static int lpaint_getTextSize(lua_State* L) {
801 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getTextSize());
802 return 1;
803}
804
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000805static int lpaint_getTextScaleX(lua_State* L) {
806 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getTextScaleX());
807 return 1;
808}
809
810static int lpaint_getTextSkewX(lua_State* L) {
811 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getTextSkewX());
812 return 1;
813}
814
reed@google.come3823fd2013-05-30 18:55:14 +0000815static int lpaint_setTextSize(lua_State* L) {
816 get_obj<SkPaint>(L, 1)->setTextSize(lua2scalar(L, 2));
817 return 0;
818}
819
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000820static int lpaint_getTypeface(lua_State* L) {
821 push_ref(L, get_obj<SkPaint>(L, 1)->getTypeface());
822 return 1;
823}
824
825static int lpaint_setTypeface(lua_State* L) {
bungeman13b9c952016-05-12 10:09:30 -0700826 get_obj<SkPaint>(L, 1)->setTypeface(sk_ref_sp(get_ref<SkTypeface>(L, 2)));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000827 return 0;
828}
829
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000830static int lpaint_getHinting(lua_State* L) {
831 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getHinting());
832 return 1;
833}
834
reed93a12152015-03-16 10:08:34 -0700835static int lpaint_getFilterQuality(lua_State* L) {
836 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getFilterQuality());
reed7a72c672014-11-07 10:23:55 -0800837 return 1;
838}
839
reed93a12152015-03-16 10:08:34 -0700840static int lpaint_setFilterQuality(lua_State* L) {
reed7a72c672014-11-07 10:23:55 -0800841 int level = lua2int_def(L, 2, -1);
842 if (level >= 0 && level <= 3) {
reed93a12152015-03-16 10:08:34 -0700843 get_obj<SkPaint>(L, 1)->setFilterQuality((SkFilterQuality)level);
reed7a72c672014-11-07 10:23:55 -0800844 }
845 return 0;
846}
847
reed@google.come3823fd2013-05-30 18:55:14 +0000848static int lpaint_getFontID(lua_State* L) {
849 SkTypeface* face = get_obj<SkPaint>(L, 1)->getTypeface();
850 SkLua(L).pushU32(SkTypeface::UniqueID(face));
851 return 1;
852}
853
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000854static const struct {
855 const char* fLabel;
856 SkPaint::Align fAlign;
857} gAlignRec[] = {
858 { "left", SkPaint::kLeft_Align },
859 { "center", SkPaint::kCenter_Align },
860 { "right", SkPaint::kRight_Align },
861};
862
863static int lpaint_getTextAlign(lua_State* L) {
864 SkPaint::Align align = get_obj<SkPaint>(L, 1)->getTextAlign();
865 for (size_t i = 0; i < SK_ARRAY_COUNT(gAlignRec); ++i) {
866 if (gAlignRec[i].fAlign == align) {
867 lua_pushstring(L, gAlignRec[i].fLabel);
868 return 1;
869 }
870 }
871 return 0;
872}
873
874static int lpaint_setTextAlign(lua_State* L) {
875 if (lua_isstring(L, 2)) {
876 size_t len;
877 const char* label = lua_tolstring(L, 2, &len);
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000878
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000879 for (size_t i = 0; i < SK_ARRAY_COUNT(gAlignRec); ++i) {
880 if (!strcmp(gAlignRec[i].fLabel, label)) {
881 get_obj<SkPaint>(L, 1)->setTextAlign(gAlignRec[i].fAlign);
882 break;
883 }
884 }
885 }
886 return 0;
887}
888
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000889static int lpaint_getStroke(lua_State* L) {
890 lua_pushboolean(L, SkPaint::kStroke_Style == get_obj<SkPaint>(L, 1)->getStyle());
891 return 1;
892}
893
894static int lpaint_setStroke(lua_State* L) {
895 SkPaint::Style style;
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000896
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000897 if (lua_toboolean(L, 2)) {
898 style = SkPaint::kStroke_Style;
899 } else {
900 style = SkPaint::kFill_Style;
901 }
902 get_obj<SkPaint>(L, 1)->setStyle(style);
903 return 0;
904}
905
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000906static int lpaint_getStrokeCap(lua_State* L) {
907 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeCap());
908 return 1;
909}
910
911static int lpaint_getStrokeJoin(lua_State* L) {
912 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeJoin());
913 return 1;
914}
915
916static int lpaint_getTextEncoding(lua_State* L) {
commit-bot@chromium.org641bcc32013-12-19 10:39:59 +0000917 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getTextEncoding());
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000918 return 1;
919}
920
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000921static int lpaint_getStrokeWidth(lua_State* L) {
922 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeWidth());
923 return 1;
924}
925
926static int lpaint_setStrokeWidth(lua_State* L) {
927 get_obj<SkPaint>(L, 1)->setStrokeWidth(lua2scalar(L, 2));
928 return 0;
929}
930
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000931static int lpaint_getStrokeMiter(lua_State* L) {
932 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeMiter());
933 return 1;
934}
935
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000936static int lpaint_measureText(lua_State* L) {
937 if (lua_isstring(L, 2)) {
938 size_t len;
939 const char* text = lua_tolstring(L, 2, &len);
940 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->measureText(text, len));
941 return 1;
942 }
943 return 0;
944}
945
946struct FontMetrics {
947 SkScalar fTop; //!< The greatest distance above the baseline for any glyph (will be <= 0)
948 SkScalar fAscent; //!< The recommended distance above the baseline (will be <= 0)
949 SkScalar fDescent; //!< The recommended distance below the baseline (will be >= 0)
950 SkScalar fBottom; //!< The greatest distance below the baseline for any glyph (will be >= 0)
951 SkScalar fLeading; //!< The recommended distance to add between lines of text (will be >= 0)
952 SkScalar fAvgCharWidth; //!< the average charactor width (>= 0)
953 SkScalar fXMin; //!< The minimum bounding box x value for all glyphs
954 SkScalar fXMax; //!< The maximum bounding box x value for all glyphs
955 SkScalar fXHeight; //!< the height of an 'x' in px, or 0 if no 'x' in face
956};
957
958static int lpaint_getFontMetrics(lua_State* L) {
959 SkPaint::FontMetrics fm;
960 SkScalar height = get_obj<SkPaint>(L, 1)->getFontMetrics(&fm);
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000961
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000962 lua_newtable(L);
963 setfield_scalar(L, "top", fm.fTop);
964 setfield_scalar(L, "ascent", fm.fAscent);
965 setfield_scalar(L, "descent", fm.fDescent);
966 setfield_scalar(L, "bottom", fm.fBottom);
967 setfield_scalar(L, "leading", fm.fLeading);
968 SkLua(L).pushScalar(height);
969 return 2;
970}
971
reed@google.com29563872013-07-10 21:23:49 +0000972static int lpaint_getEffects(lua_State* L) {
973 const SkPaint* paint = get_obj<SkPaint>(L, 1);
skia.committer@gmail.comde2e4e82013-07-11 07:01:01 +0000974
reed@google.com29563872013-07-10 21:23:49 +0000975 lua_newtable(L);
reed468b1812014-10-19 11:42:54 -0700976 setfield_bool_if(L, "looper", !!paint->getLooper());
977 setfield_bool_if(L, "pathEffect", !!paint->getPathEffect());
978 setfield_bool_if(L, "rasterizer", !!paint->getRasterizer());
979 setfield_bool_if(L, "maskFilter", !!paint->getMaskFilter());
980 setfield_bool_if(L, "shader", !!paint->getShader());
reed@google.com29563872013-07-10 21:23:49 +0000981 setfield_bool_if(L, "colorFilter", !!paint->getColorFilter());
982 setfield_bool_if(L, "imageFilter", !!paint->getImageFilter());
reed@google.com29563872013-07-10 21:23:49 +0000983 return 1;
984}
985
reed22a517f2015-12-04 20:45:59 -0800986static int lpaint_getColorFilter(lua_State* L) {
987 const SkPaint* paint = get_obj<SkPaint>(L, 1);
988 SkColorFilter* cf = paint->getColorFilter();
989 if (cf) {
990 push_ref(L, cf);
991 return 1;
992 }
993 return 0;
994}
995
996static int lpaint_setColorFilter(lua_State* L) {
997 SkPaint* paint = get_obj<SkPaint>(L, 1);
reedd053ce92016-03-22 10:17:23 -0700998 paint->setColorFilter(sk_ref_sp(get_ref<SkColorFilter>(L, 2)));
reed22a517f2015-12-04 20:45:59 -0800999 return 0;
1000}
1001
reed468b1812014-10-19 11:42:54 -07001002static int lpaint_getImageFilter(lua_State* L) {
1003 const SkPaint* paint = get_obj<SkPaint>(L, 1);
1004 SkImageFilter* imf = paint->getImageFilter();
1005 if (imf) {
1006 push_ref(L, imf);
1007 return 1;
1008 }
1009 return 0;
1010}
1011
1012static int lpaint_setImageFilter(lua_State* L) {
1013 SkPaint* paint = get_obj<SkPaint>(L, 1);
Mike Reed5e257172016-11-01 11:22:05 -04001014 paint->setImageFilter(sk_ref_sp(get_ref<SkImageFilter>(L, 2)));
reed468b1812014-10-19 11:42:54 -07001015 return 0;
1016}
1017
reed@google.com5fdc9832013-07-24 15:47:52 +00001018static int lpaint_getShader(lua_State* L) {
1019 const SkPaint* paint = get_obj<SkPaint>(L, 1);
1020 SkShader* shader = paint->getShader();
1021 if (shader) {
1022 push_ref(L, shader);
1023 return 1;
1024 }
1025 return 0;
1026}
1027
reed9fbc3f32014-10-21 07:12:58 -07001028static int lpaint_setShader(lua_State* L) {
1029 SkPaint* paint = get_obj<SkPaint>(L, 1);
reedfe630452016-03-25 09:08:00 -07001030 paint->setShader(sk_ref_sp(get_ref<SkShader>(L, 2)));
reed9fbc3f32014-10-21 07:12:58 -07001031 return 0;
1032}
1033
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001034static int lpaint_getPathEffect(lua_State* L) {
1035 const SkPaint* paint = get_obj<SkPaint>(L, 1);
1036 SkPathEffect* pe = paint->getPathEffect();
1037 if (pe) {
1038 push_ref(L, pe);
1039 return 1;
1040 }
1041 return 0;
1042}
1043
hstern0b401ce2016-08-02 09:17:59 -07001044static int lpaint_getFillPath(lua_State* L) {
1045 const SkPaint* paint = get_obj<SkPaint>(L, 1);
1046 const SkPath* path = get_obj<SkPath>(L, 2);
1047
1048 SkPath fillpath;
1049 paint->getFillPath(*path, &fillpath);
1050
1051 SkLua lua(L);
1052 lua.pushPath(fillpath);
1053
1054 return 1;
1055}
1056
reed@google.com74ce6f02013-05-22 15:13:18 +00001057static int lpaint_gc(lua_State* L) {
1058 get_obj<SkPaint>(L, 1)->~SkPaint();
1059 return 0;
1060}
1061
1062static const struct luaL_Reg gSkPaint_Methods[] = {
1063 { "isAntiAlias", lpaint_isAntiAlias },
1064 { "setAntiAlias", lpaint_setAntiAlias },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001065 { "isDither", lpaint_isDither },
reedbb8a0ab2014-11-03 22:32:07 -08001066 { "setDither", lpaint_setDither },
reed93a12152015-03-16 10:08:34 -07001067 { "getFilterQuality", lpaint_getFilterQuality },
1068 { "setFilterQuality", lpaint_setFilterQuality },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001069 { "isUnderlineText", lpaint_isUnderlineText },
1070 { "isStrikeThruText", lpaint_isStrikeThruText },
1071 { "isFakeBoldText", lpaint_isFakeBoldText },
1072 { "isLinearText", lpaint_isLinearText },
1073 { "isSubpixelText", lpaint_isSubpixelText },
reed09a1d672014-10-11 13:13:11 -07001074 { "setSubpixelText", lpaint_setSubpixelText },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001075 { "isDevKernText", lpaint_isDevKernText },
1076 { "isLCDRenderText", lpaint_isLCDRenderText },
reed36c9c112014-11-04 10:58:42 -08001077 { "setLCDRenderText", lpaint_setLCDRenderText },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001078 { "isEmbeddedBitmapText", lpaint_isEmbeddedBitmapText },
1079 { "isAutohinted", lpaint_isAutohinted },
1080 { "isVerticalText", lpaint_isVerticalText },
reed468b1812014-10-19 11:42:54 -07001081 { "getAlpha", lpaint_getAlpha },
1082 { "setAlpha", lpaint_setAlpha },
reed@google.com74ce6f02013-05-22 15:13:18 +00001083 { "getColor", lpaint_getColor },
1084 { "setColor", lpaint_setColor },
reed@google.come3823fd2013-05-30 18:55:14 +00001085 { "getTextSize", lpaint_getTextSize },
1086 { "setTextSize", lpaint_setTextSize },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001087 { "getTextScaleX", lpaint_getTextScaleX },
1088 { "getTextSkewX", lpaint_getTextSkewX },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001089 { "getTypeface", lpaint_getTypeface },
1090 { "setTypeface", lpaint_setTypeface },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001091 { "getHinting", lpaint_getHinting },
reed@google.come3823fd2013-05-30 18:55:14 +00001092 { "getFontID", lpaint_getFontID },
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001093 { "getTextAlign", lpaint_getTextAlign },
1094 { "setTextAlign", lpaint_setTextAlign },
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +00001095 { "getStroke", lpaint_getStroke },
1096 { "setStroke", lpaint_setStroke },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001097 { "getStrokeCap", lpaint_getStrokeCap },
1098 { "getStrokeJoin", lpaint_getStrokeJoin },
1099 { "getTextEncoding", lpaint_getTextEncoding },
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +00001100 { "getStrokeWidth", lpaint_getStrokeWidth },
1101 { "setStrokeWidth", lpaint_setStrokeWidth },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +00001102 { "getStrokeMiter", lpaint_getStrokeMiter },
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +00001103 { "measureText", lpaint_measureText },
1104 { "getFontMetrics", lpaint_getFontMetrics },
reed@google.com29563872013-07-10 21:23:49 +00001105 { "getEffects", lpaint_getEffects },
reed22a517f2015-12-04 20:45:59 -08001106 { "getColorFilter", lpaint_getColorFilter },
1107 { "setColorFilter", lpaint_setColorFilter },
reed468b1812014-10-19 11:42:54 -07001108 { "getImageFilter", lpaint_getImageFilter },
1109 { "setImageFilter", lpaint_setImageFilter },
reed@google.com5fdc9832013-07-24 15:47:52 +00001110 { "getShader", lpaint_getShader },
reed9fbc3f32014-10-21 07:12:58 -07001111 { "setShader", lpaint_setShader },
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001112 { "getPathEffect", lpaint_getPathEffect },
hstern0b401ce2016-08-02 09:17:59 -07001113 { "getFillPath", lpaint_getFillPath },
reed@google.com74ce6f02013-05-22 15:13:18 +00001114 { "__gc", lpaint_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001115 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001116};
1117
1118///////////////////////////////////////////////////////////////////////////////
1119
reed@google.com5fdc9832013-07-24 15:47:52 +00001120static const char* mode2string(SkShader::TileMode mode) {
1121 static const char* gNames[] = { "clamp", "repeat", "mirror" };
1122 SkASSERT((unsigned)mode < SK_ARRAY_COUNT(gNames));
1123 return gNames[mode];
1124}
1125
1126static const char* gradtype2string(SkShader::GradientType t) {
1127 static const char* gNames[] = {
1128 "none", "color", "linear", "radial", "radial2", "sweep", "conical"
1129 };
1130 SkASSERT((unsigned)t < SK_ARRAY_COUNT(gNames));
1131 return gNames[t];
1132}
1133
1134static int lshader_isOpaque(lua_State* L) {
1135 SkShader* shader = get_ref<SkShader>(L, 1);
1136 return shader && shader->isOpaque();
1137}
1138
Mike Reed627778d2016-09-28 17:13:38 -04001139static int lshader_isAImage(lua_State* L) {
reed@google.com5fdc9832013-07-24 15:47:52 +00001140 SkShader* shader = get_ref<SkShader>(L, 1);
1141 if (shader) {
reed@google.com5fdc9832013-07-24 15:47:52 +00001142 SkMatrix matrix;
1143 SkShader::TileMode modes[2];
Mike Reed627778d2016-09-28 17:13:38 -04001144 if (SkImage* image = shader->isAImage(&matrix, modes)) {
reedf5822822015-08-19 11:46:38 -07001145 lua_newtable(L);
Mike Reed627778d2016-09-28 17:13:38 -04001146 setfield_number(L, "id", image->uniqueID());
1147 setfield_number(L, "width", image->width());
1148 setfield_number(L, "height", image->height());
reedf5822822015-08-19 11:46:38 -07001149 setfield_string(L, "tileX", mode2string(modes[0]));
1150 setfield_string(L, "tileY", mode2string(modes[1]));
1151 return 1;
reed@google.com5fdc9832013-07-24 15:47:52 +00001152 }
1153 }
1154 return 0;
1155}
1156
1157static int lshader_asAGradient(lua_State* L) {
1158 SkShader* shader = get_ref<SkShader>(L, 1);
1159 if (shader) {
1160 SkShader::GradientInfo info;
1161 sk_bzero(&info, sizeof(info));
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001162
reed@google.com5fdc9832013-07-24 15:47:52 +00001163 SkShader::GradientType t = shader->asAGradient(&info);
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001164
reed@google.com5fdc9832013-07-24 15:47:52 +00001165 if (SkShader::kNone_GradientType != t) {
fmenozzib4f254e2016-06-28 14:03:03 -07001166 SkAutoTArray<SkScalar> pos(info.fColorCount);
1167 info.fColorOffsets = pos.get();
1168 shader->asAGradient(&info);
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001169
fmenozzib4f254e2016-06-28 14:03:03 -07001170 lua_newtable(L);
fmenozzi7f2c85e2016-07-12 09:17:39 -07001171 setfield_string(L, "type", gradtype2string(t));
1172 setfield_string(L, "tile", mode2string(info.fTileMode));
1173 setfield_number(L, "colorCount", info.fColorCount);
fmenozzib4f254e2016-06-28 14:03:03 -07001174
1175 lua_newtable(L);
1176 for (int i = 0; i < info.fColorCount; i++) {
1177 // Lua uses 1-based indexing
1178 setarray_scalar(L, i+1, pos[i]);
1179 }
1180 lua_setfield(L, -2, "positions");
1181
reed@google.com5fdc9832013-07-24 15:47:52 +00001182 return 1;
1183 }
1184 }
1185 return 0;
1186}
1187
1188static int lshader_gc(lua_State* L) {
1189 get_ref<SkShader>(L, 1)->unref();
1190 return 0;
1191}
1192
1193static const struct luaL_Reg gSkShader_Methods[] = {
1194 { "isOpaque", lshader_isOpaque },
Mike Reed627778d2016-09-28 17:13:38 -04001195 { "isAImage", lshader_isAImage },
reed@google.com5fdc9832013-07-24 15:47:52 +00001196 { "asAGradient", lshader_asAGradient },
1197 { "__gc", lshader_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001198 { nullptr, nullptr }
reed@google.com5fdc9832013-07-24 15:47:52 +00001199};
1200
1201///////////////////////////////////////////////////////////////////////////////
1202
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +00001203static int lpatheffect_asADash(lua_State* L) {
1204 SkPathEffect* pe = get_ref<SkPathEffect>(L, 1);
1205 if (pe) {
1206 SkPathEffect::DashInfo info;
1207 SkPathEffect::DashType dashType = pe->asADash(&info);
1208 if (SkPathEffect::kDash_DashType == dashType) {
1209 SkAutoTArray<SkScalar> intervals(info.fCount);
1210 info.fIntervals = intervals.get();
1211 pe->asADash(&info);
1212 SkLua(L).pushDash(info);
1213 return 1;
1214 }
1215 }
1216 return 0;
1217}
1218
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001219static int lpatheffect_gc(lua_State* L) {
1220 get_ref<SkPathEffect>(L, 1)->unref();
1221 return 0;
1222}
1223
1224static const struct luaL_Reg gSkPathEffect_Methods[] = {
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +00001225 { "asADash", lpatheffect_asADash },
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001226 { "__gc", lpatheffect_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001227 { nullptr, nullptr }
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001228};
1229
1230///////////////////////////////////////////////////////////////////////////////
1231
reed22a517f2015-12-04 20:45:59 -08001232static int lpcolorfilter_gc(lua_State* L) {
1233 get_ref<SkColorFilter>(L, 1)->unref();
1234 return 0;
1235}
1236
1237static const struct luaL_Reg gSkColorFilter_Methods[] = {
1238 { "__gc", lpcolorfilter_gc },
1239 { nullptr, nullptr }
1240};
1241
1242///////////////////////////////////////////////////////////////////////////////
1243
reed468b1812014-10-19 11:42:54 -07001244static int lpimagefilter_gc(lua_State* L) {
1245 get_ref<SkImageFilter>(L, 1)->unref();
1246 return 0;
1247}
1248
1249static const struct luaL_Reg gSkImageFilter_Methods[] = {
1250 { "__gc", lpimagefilter_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001251 { nullptr, nullptr }
reed468b1812014-10-19 11:42:54 -07001252};
1253
1254///////////////////////////////////////////////////////////////////////////////
1255
humper@google.com2815c192013-07-10 22:42:30 +00001256static int lmatrix_getType(lua_State* L) {
1257 SkMatrix::TypeMask mask = get_obj<SkMatrix>(L, 1)->getType();
skia.committer@gmail.comde2e4e82013-07-11 07:01:01 +00001258
humper@google.com2815c192013-07-10 22:42:30 +00001259 lua_newtable(L);
1260 setfield_boolean(L, "translate", SkToBool(mask & SkMatrix::kTranslate_Mask));
1261 setfield_boolean(L, "scale", SkToBool(mask & SkMatrix::kScale_Mask));
1262 setfield_boolean(L, "affine", SkToBool(mask & SkMatrix::kAffine_Mask));
1263 setfield_boolean(L, "perspective", SkToBool(mask & SkMatrix::kPerspective_Mask));
1264 return 1;
1265}
1266
humper@google.com0f48ee02013-07-26 15:23:43 +00001267static int lmatrix_getScaleX(lua_State* L) {
1268 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getScaleX());
1269 return 1;
1270}
1271
1272static int lmatrix_getScaleY(lua_State* L) {
1273 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getScaleY());
1274 return 1;
1275}
1276
1277static int lmatrix_getTranslateX(lua_State* L) {
1278 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getTranslateX());
1279 return 1;
1280}
1281
1282static int lmatrix_getTranslateY(lua_State* L) {
1283 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getTranslateY());
1284 return 1;
1285}
1286
reed7a72c672014-11-07 10:23:55 -08001287static int lmatrix_invert(lua_State* L) {
1288 lua_pushboolean(L, get_obj<SkMatrix>(L, 1)->invert(get_obj<SkMatrix>(L, 2)));
1289 return 1;
1290}
1291
1292static int lmatrix_mapXY(lua_State* L) {
1293 SkPoint pt = { lua2scalar(L, 2), lua2scalar(L, 3) };
1294 get_obj<SkMatrix>(L, 1)->mapPoints(&pt, &pt, 1);
1295 lua_pushnumber(L, pt.x());
1296 lua_pushnumber(L, pt.y());
1297 return 2;
1298}
1299
reedbdc49ae2014-10-14 09:34:52 -07001300static int lmatrix_setRectToRect(lua_State* L) {
1301 SkMatrix* matrix = get_obj<SkMatrix>(L, 1);
1302 SkRect srcR, dstR;
1303 lua2rect(L, 2, &srcR);
1304 lua2rect(L, 3, &dstR);
1305 const char* scaleToFitStr = lua_tostring(L, 4);
1306 SkMatrix::ScaleToFit scaleToFit = SkMatrix::kFill_ScaleToFit;
1307
1308 if (scaleToFitStr) {
1309 const struct {
1310 const char* fName;
1311 SkMatrix::ScaleToFit fScaleToFit;
1312 } rec[] = {
1313 { "fill", SkMatrix::kFill_ScaleToFit },
1314 { "start", SkMatrix::kStart_ScaleToFit },
1315 { "center", SkMatrix::kCenter_ScaleToFit },
1316 { "end", SkMatrix::kEnd_ScaleToFit },
1317 };
1318
1319 for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
1320 if (strcmp(rec[i].fName, scaleToFitStr) == 0) {
1321 scaleToFit = rec[i].fScaleToFit;
1322 break;
1323 }
1324 }
1325 }
1326
1327 matrix->setRectToRect(srcR, dstR, scaleToFit);
1328 return 0;
1329}
1330
humper@google.com2815c192013-07-10 22:42:30 +00001331static const struct luaL_Reg gSkMatrix_Methods[] = {
1332 { "getType", lmatrix_getType },
humper@google.com0f48ee02013-07-26 15:23:43 +00001333 { "getScaleX", lmatrix_getScaleX },
1334 { "getScaleY", lmatrix_getScaleY },
1335 { "getTranslateX", lmatrix_getTranslateX },
1336 { "getTranslateY", lmatrix_getTranslateY },
reedbdc49ae2014-10-14 09:34:52 -07001337 { "setRectToRect", lmatrix_setRectToRect },
reed7a72c672014-11-07 10:23:55 -08001338 { "invert", lmatrix_invert },
1339 { "mapXY", lmatrix_mapXY },
halcanary96fcdcc2015-08-27 07:41:13 -07001340 { nullptr, nullptr }
humper@google.com2815c192013-07-10 22:42:30 +00001341};
1342
1343///////////////////////////////////////////////////////////////////////////////
1344
reed@google.com74ce6f02013-05-22 15:13:18 +00001345static int lpath_getBounds(lua_State* L) {
1346 SkLua(L).pushRect(get_obj<SkPath>(L, 1)->getBounds());
1347 return 1;
1348}
1349
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001350static const char* fill_type_to_str(SkPath::FillType fill) {
1351 switch (fill) {
1352 case SkPath::kEvenOdd_FillType:
1353 return "even-odd";
1354 case SkPath::kWinding_FillType:
1355 return "winding";
1356 case SkPath::kInverseEvenOdd_FillType:
1357 return "inverse-even-odd";
1358 case SkPath::kInverseWinding_FillType:
1359 return "inverse-winding";
1360 }
1361 return "unknown";
1362}
1363
1364static int lpath_getFillType(lua_State* L) {
1365 SkPath::FillType fill = get_obj<SkPath>(L, 1)->getFillType();
1366 SkLua(L).pushString(fill_type_to_str(fill));
1367 return 1;
1368}
1369
1370static SkString segment_masks_to_str(uint32_t segmentMasks) {
1371 SkString result;
1372 bool first = true;
1373 if (SkPath::kLine_SegmentMask & segmentMasks) {
1374 result.append("line");
1375 first = false;
1376 SkDEBUGCODE(segmentMasks &= ~SkPath::kLine_SegmentMask;)
1377 }
1378 if (SkPath::kQuad_SegmentMask & segmentMasks) {
1379 if (!first) {
1380 result.append(" ");
1381 }
1382 result.append("quad");
1383 first = false;
1384 SkDEBUGCODE(segmentMasks &= ~SkPath::kQuad_SegmentMask;)
1385 }
1386 if (SkPath::kConic_SegmentMask & segmentMasks) {
1387 if (!first) {
1388 result.append(" ");
1389 }
1390 result.append("conic");
1391 first = false;
1392 SkDEBUGCODE(segmentMasks &= ~SkPath::kConic_SegmentMask;)
1393 }
1394 if (SkPath::kCubic_SegmentMask & segmentMasks) {
1395 if (!first) {
1396 result.append(" ");
1397 }
1398 result.append("cubic");
1399 SkDEBUGCODE(segmentMasks &= ~SkPath::kCubic_SegmentMask;)
1400 }
1401 SkASSERT(0 == segmentMasks);
1402 return result;
1403}
1404
krajcevski95498ed2014-08-18 08:02:33 -07001405static int lpath_getSegmentTypes(lua_State* L) {
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001406 uint32_t segMasks = get_obj<SkPath>(L, 1)->getSegmentMasks();
1407 SkLua(L).pushString(segment_masks_to_str(segMasks));
1408 return 1;
1409}
1410
1411static int lpath_isConvex(lua_State* L) {
1412 bool isConvex = SkPath::kConvex_Convexity == get_obj<SkPath>(L, 1)->getConvexity();
1413 SkLua(L).pushBool(isConvex);
1414 return 1;
1415}
1416
reed@google.com74ce6f02013-05-22 15:13:18 +00001417static int lpath_isEmpty(lua_State* L) {
1418 lua_pushboolean(L, get_obj<SkPath>(L, 1)->isEmpty());
1419 return 1;
1420}
1421
1422static int lpath_isRect(lua_State* L) {
1423 SkRect r;
1424 bool pred = get_obj<SkPath>(L, 1)->isRect(&r);
1425 int ret_count = 1;
1426 lua_pushboolean(L, pred);
1427 if (pred) {
1428 SkLua(L).pushRect(r);
1429 ret_count += 1;
1430 }
1431 return ret_count;
1432}
1433
1434static const char* dir2string(SkPath::Direction dir) {
1435 static const char* gStr[] = {
1436 "unknown", "cw", "ccw"
1437 };
1438 SkASSERT((unsigned)dir < SK_ARRAY_COUNT(gStr));
1439 return gStr[dir];
1440}
1441
caryclark95bc5f32015-04-08 08:34:15 -07001442static int lpath_isNestedFillRects(lua_State* L) {
reed@google.com74ce6f02013-05-22 15:13:18 +00001443 SkRect rects[2];
1444 SkPath::Direction dirs[2];
caryclark95bc5f32015-04-08 08:34:15 -07001445 bool pred = get_obj<SkPath>(L, 1)->isNestedFillRects(rects, dirs);
reed@google.com74ce6f02013-05-22 15:13:18 +00001446 int ret_count = 1;
1447 lua_pushboolean(L, pred);
1448 if (pred) {
1449 SkLua lua(L);
1450 lua.pushRect(rects[0]);
1451 lua.pushRect(rects[1]);
1452 lua_pushstring(L, dir2string(dirs[0]));
1453 lua_pushstring(L, dir2string(dirs[0]));
1454 ret_count += 4;
1455 }
1456 return ret_count;
1457}
1458
commit-bot@chromium.orgc5302082014-02-26 21:38:47 +00001459static int lpath_countPoints(lua_State* L) {
1460 lua_pushinteger(L, get_obj<SkPath>(L, 1)->countPoints());
1461 return 1;
1462}
1463
hstern0b401ce2016-08-02 09:17:59 -07001464static int lpath_getVerbs(lua_State* L) {
1465 const SkPath* path = get_obj<SkPath>(L, 1);
1466 SkPath::Iter iter(*path, false);
1467 SkPoint pts[4];
1468
1469 lua_newtable(L);
1470
1471 bool done = false;
1472 int i = 0;
1473 do {
1474 switch (iter.next(pts, true)) {
1475 case SkPath::kMove_Verb:
1476 setarray_string(L, ++i, "move");
1477 break;
1478 case SkPath::kClose_Verb:
1479 setarray_string(L, ++i, "close");
1480 break;
1481 case SkPath::kLine_Verb:
1482 setarray_string(L, ++i, "line");
1483 break;
1484 case SkPath::kQuad_Verb:
1485 setarray_string(L, ++i, "quad");
1486 break;
1487 case SkPath::kConic_Verb:
1488 setarray_string(L, ++i, "conic");
1489 break;
1490 case SkPath::kCubic_Verb:
1491 setarray_string(L, ++i, "cubic");
1492 break;
1493 case SkPath::kDone_Verb:
1494 setarray_string(L, ++i, "done");
1495 done = true;
1496 break;
1497 }
1498 } while (!done);
1499
1500 return 1;
1501}
1502
reed@google.com74ce6f02013-05-22 15:13:18 +00001503static int lpath_reset(lua_State* L) {
1504 get_obj<SkPath>(L, 1)->reset();
1505 return 0;
1506}
1507
1508static int lpath_moveTo(lua_State* L) {
1509 get_obj<SkPath>(L, 1)->moveTo(lua2scalar(L, 2), lua2scalar(L, 3));
1510 return 0;
1511}
1512
1513static int lpath_lineTo(lua_State* L) {
1514 get_obj<SkPath>(L, 1)->lineTo(lua2scalar(L, 2), lua2scalar(L, 3));
1515 return 0;
1516}
1517
1518static int lpath_quadTo(lua_State* L) {
1519 get_obj<SkPath>(L, 1)->quadTo(lua2scalar(L, 2), lua2scalar(L, 3),
1520 lua2scalar(L, 4), lua2scalar(L, 5));
1521 return 0;
1522}
1523
1524static int lpath_cubicTo(lua_State* L) {
1525 get_obj<SkPath>(L, 1)->cubicTo(lua2scalar(L, 2), lua2scalar(L, 3),
1526 lua2scalar(L, 4), lua2scalar(L, 5),
1527 lua2scalar(L, 6), lua2scalar(L, 7));
1528 return 0;
1529}
1530
1531static int lpath_close(lua_State* L) {
1532 get_obj<SkPath>(L, 1)->close();
1533 return 0;
1534}
1535
1536static int lpath_gc(lua_State* L) {
1537 get_obj<SkPath>(L, 1)->~SkPath();
1538 return 0;
1539}
1540
1541static const struct luaL_Reg gSkPath_Methods[] = {
1542 { "getBounds", lpath_getBounds },
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001543 { "getFillType", lpath_getFillType },
krajcevski95498ed2014-08-18 08:02:33 -07001544 { "getSegmentTypes", lpath_getSegmentTypes },
hstern0b401ce2016-08-02 09:17:59 -07001545 { "getVerbs", lpath_getVerbs },
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001546 { "isConvex", lpath_isConvex },
reed@google.com74ce6f02013-05-22 15:13:18 +00001547 { "isEmpty", lpath_isEmpty },
1548 { "isRect", lpath_isRect },
caryclark95bc5f32015-04-08 08:34:15 -07001549 { "isNestedFillRects", lpath_isNestedFillRects },
commit-bot@chromium.orgc5302082014-02-26 21:38:47 +00001550 { "countPoints", lpath_countPoints },
reed@google.com74ce6f02013-05-22 15:13:18 +00001551 { "reset", lpath_reset },
1552 { "moveTo", lpath_moveTo },
1553 { "lineTo", lpath_lineTo },
1554 { "quadTo", lpath_quadTo },
1555 { "cubicTo", lpath_cubicTo },
1556 { "close", lpath_close },
1557 { "__gc", lpath_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001558 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001559};
1560
1561///////////////////////////////////////////////////////////////////////////////
1562
1563static const char* rrect_type(const SkRRect& rr) {
1564 switch (rr.getType()) {
reed@google.com74ce6f02013-05-22 15:13:18 +00001565 case SkRRect::kEmpty_Type: return "empty";
1566 case SkRRect::kRect_Type: return "rect";
1567 case SkRRect::kOval_Type: return "oval";
1568 case SkRRect::kSimple_Type: return "simple";
commit-bot@chromium.orgf338d7c2014-03-17 21:17:30 +00001569 case SkRRect::kNinePatch_Type: return "nine-patch";
reed@google.com74ce6f02013-05-22 15:13:18 +00001570 case SkRRect::kComplex_Type: return "complex";
1571 }
mtklein@google.com330313a2013-08-22 15:37:26 +00001572 SkDEBUGFAIL("never get here");
reed@google.com74ce6f02013-05-22 15:13:18 +00001573 return "";
1574}
1575
1576static int lrrect_rect(lua_State* L) {
1577 SkLua(L).pushRect(get_obj<SkRRect>(L, 1)->rect());
1578 return 1;
1579}
1580
1581static int lrrect_type(lua_State* L) {
1582 lua_pushstring(L, rrect_type(*get_obj<SkRRect>(L, 1)));
1583 return 1;
1584}
1585
1586static int lrrect_radii(lua_State* L) {
reed@google.com7fa2a652014-01-27 13:42:58 +00001587 int corner = SkToInt(lua_tointeger(L, 2));
reed@google.com74ce6f02013-05-22 15:13:18 +00001588 SkVector v;
1589 if (corner < 0 || corner > 3) {
1590 SkDebugf("bad corner index %d", corner);
1591 v.set(0, 0);
1592 } else {
1593 v = get_obj<SkRRect>(L, 1)->radii((SkRRect::Corner)corner);
1594 }
1595 lua_pushnumber(L, v.fX);
1596 lua_pushnumber(L, v.fY);
1597 return 2;
1598}
1599
1600static int lrrect_gc(lua_State* L) {
1601 get_obj<SkRRect>(L, 1)->~SkRRect();
1602 return 0;
1603}
1604
1605static const struct luaL_Reg gSkRRect_Methods[] = {
1606 { "rect", lrrect_rect },
1607 { "type", lrrect_type },
1608 { "radii", lrrect_radii },
1609 { "__gc", lrrect_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001610 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001611};
1612
1613///////////////////////////////////////////////////////////////////////////////
1614
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001615static int limage_width(lua_State* L) {
1616 lua_pushinteger(L, get_ref<SkImage>(L, 1)->width());
1617 return 1;
1618}
1619
1620static int limage_height(lua_State* L) {
1621 lua_pushinteger(L, get_ref<SkImage>(L, 1)->height());
1622 return 1;
1623}
1624
reed7a72c672014-11-07 10:23:55 -08001625static int limage_newShader(lua_State* L) {
1626 SkShader::TileMode tmode = SkShader::kClamp_TileMode;
halcanary96fcdcc2015-08-27 07:41:13 -07001627 const SkMatrix* localM = nullptr;
reed5671c5b2016-03-09 14:47:34 -08001628 push_ref(L, get_ref<SkImage>(L, 1)->makeShader(tmode, tmode, localM));
reed7a72c672014-11-07 10:23:55 -08001629 return 1;
1630}
1631
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001632static int limage_gc(lua_State* L) {
1633 get_ref<SkImage>(L, 1)->unref();
1634 return 0;
1635}
1636
1637static const struct luaL_Reg gSkImage_Methods[] = {
1638 { "width", limage_width },
1639 { "height", limage_height },
reed7a72c672014-11-07 10:23:55 -08001640 { "newShader", limage_newShader },
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001641 { "__gc", limage_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001642 { nullptr, nullptr }
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001643};
1644
1645///////////////////////////////////////////////////////////////////////////////
1646
reed485557f2014-10-12 10:36:47 -07001647static int lsurface_width(lua_State* L) {
1648 lua_pushinteger(L, get_ref<SkSurface>(L, 1)->width());
1649 return 1;
1650}
1651
1652static int lsurface_height(lua_State* L) {
1653 lua_pushinteger(L, get_ref<SkSurface>(L, 1)->height());
1654 return 1;
1655}
1656
1657static int lsurface_getCanvas(lua_State* L) {
1658 SkCanvas* canvas = get_ref<SkSurface>(L, 1)->getCanvas();
halcanary96fcdcc2015-08-27 07:41:13 -07001659 if (nullptr == canvas) {
reed485557f2014-10-12 10:36:47 -07001660 lua_pushnil(L);
1661 } else {
Mike Reed5df49342016-11-12 08:06:55 -06001662 push_ptr(L, canvas);
reed485557f2014-10-12 10:36:47 -07001663 // note: we don't unref canvas, since getCanvas did not ref it.
1664 // warning: this is weird: now Lua owns a ref on this canvas, but what if they let
1665 // the real owner (the surface) go away, but still hold onto the canvas?
1666 // *really* we want to sort of ref the surface again, but have the native object
1667 // know that it is supposed to be treated as a canvas...
1668 }
1669 return 1;
1670}
1671
1672static int lsurface_newImageSnapshot(lua_State* L) {
reed9ce9d672016-03-17 10:51:11 -07001673 sk_sp<SkImage> image = get_ref<SkSurface>(L, 1)->makeImageSnapshot();
1674 if (!image) {
reed485557f2014-10-12 10:36:47 -07001675 lua_pushnil(L);
1676 } else {
reed9ce9d672016-03-17 10:51:11 -07001677 push_ref(L, image);
reed485557f2014-10-12 10:36:47 -07001678 }
1679 return 1;
1680}
1681
1682static int lsurface_newSurface(lua_State* L) {
1683 int width = lua2int_def(L, 2, 0);
reed96affcd2014-10-13 12:38:04 -07001684 int height = lua2int_def(L, 3, 0);
reed485557f2014-10-12 10:36:47 -07001685 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
reede8f30622016-03-23 18:59:25 -07001686 auto surface = get_ref<SkSurface>(L, 1)->makeSurface(info);
halcanary96fcdcc2015-08-27 07:41:13 -07001687 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -07001688 lua_pushnil(L);
1689 } else {
reede8f30622016-03-23 18:59:25 -07001690 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -07001691 }
1692 return 1;
1693}
1694
1695static int lsurface_gc(lua_State* L) {
1696 get_ref<SkSurface>(L, 1)->unref();
1697 return 0;
1698}
1699
1700static const struct luaL_Reg gSkSurface_Methods[] = {
1701 { "width", lsurface_width },
1702 { "height", lsurface_height },
1703 { "getCanvas", lsurface_getCanvas },
1704 { "newImageSnapshot", lsurface_newImageSnapshot },
1705 { "newSurface", lsurface_newSurface },
1706 { "__gc", lsurface_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001707 { nullptr, nullptr }
reed485557f2014-10-12 10:36:47 -07001708};
1709
1710///////////////////////////////////////////////////////////////////////////////
1711
reed96affcd2014-10-13 12:38:04 -07001712static int lpicturerecorder_beginRecording(lua_State* L) {
1713 const SkScalar w = lua2scalar_def(L, 2, -1);
1714 const SkScalar h = lua2scalar_def(L, 3, -1);
1715 if (w <= 0 || h <= 0) {
1716 lua_pushnil(L);
1717 return 1;
1718 }
1719
1720 SkCanvas* canvas = get_obj<SkPictureRecorder>(L, 1)->beginRecording(w, h);
halcanary96fcdcc2015-08-27 07:41:13 -07001721 if (nullptr == canvas) {
reed96affcd2014-10-13 12:38:04 -07001722 lua_pushnil(L);
1723 return 1;
1724 }
1725
Mike Reed5df49342016-11-12 08:06:55 -06001726 push_ptr(L, canvas);
reed96affcd2014-10-13 12:38:04 -07001727 return 1;
1728}
1729
1730static int lpicturerecorder_getCanvas(lua_State* L) {
1731 SkCanvas* canvas = get_obj<SkPictureRecorder>(L, 1)->getRecordingCanvas();
halcanary96fcdcc2015-08-27 07:41:13 -07001732 if (nullptr == canvas) {
reed96affcd2014-10-13 12:38:04 -07001733 lua_pushnil(L);
1734 return 1;
1735 }
Mike Reed5df49342016-11-12 08:06:55 -06001736 push_ptr(L, canvas);
reed96affcd2014-10-13 12:38:04 -07001737 return 1;
1738}
1739
1740static int lpicturerecorder_endRecording(lua_State* L) {
reedca2622b2016-03-18 07:25:55 -07001741 sk_sp<SkPicture> pic = get_obj<SkPictureRecorder>(L, 1)->finishRecordingAsPicture();
1742 if (!pic) {
reed96affcd2014-10-13 12:38:04 -07001743 lua_pushnil(L);
1744 return 1;
1745 }
reedca2622b2016-03-18 07:25:55 -07001746 push_ref(L, std::move(pic));
reed96affcd2014-10-13 12:38:04 -07001747 return 1;
1748}
1749
1750static int lpicturerecorder_gc(lua_State* L) {
1751 get_obj<SkPictureRecorder>(L, 1)->~SkPictureRecorder();
1752 return 0;
1753}
1754
1755static const struct luaL_Reg gSkPictureRecorder_Methods[] = {
1756 { "beginRecording", lpicturerecorder_beginRecording },
1757 { "getCanvas", lpicturerecorder_getCanvas },
1758 { "endRecording", lpicturerecorder_endRecording },
1759 { "__gc", lpicturerecorder_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001760 { nullptr, nullptr }
reed96affcd2014-10-13 12:38:04 -07001761};
1762
1763///////////////////////////////////////////////////////////////////////////////
1764
1765static int lpicture_width(lua_State* L) {
1766 lua_pushnumber(L, get_ref<SkPicture>(L, 1)->cullRect().width());
1767 return 1;
1768}
1769
1770static int lpicture_height(lua_State* L) {
1771 lua_pushnumber(L, get_ref<SkPicture>(L, 1)->cullRect().height());
1772 return 1;
1773}
1774
1775static int lpicture_gc(lua_State* L) {
1776 get_ref<SkPicture>(L, 1)->unref();
1777 return 0;
1778}
1779
1780static const struct luaL_Reg gSkPicture_Methods[] = {
1781 { "width", lpicture_width },
1782 { "height", lpicture_height },
1783 { "__gc", lpicture_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001784 { nullptr, nullptr }
reed96affcd2014-10-13 12:38:04 -07001785};
1786
1787///////////////////////////////////////////////////////////////////////////////
1788
reed1b6ab442014-11-03 19:55:41 -08001789static int ltextblob_bounds(lua_State* L) {
1790 SkLua(L).pushRect(get_ref<SkTextBlob>(L, 1)->bounds());
1791 return 1;
1792}
1793
1794static int ltextblob_gc(lua_State* L) {
1795 SkSafeUnref(get_ref<SkTextBlob>(L, 1));
1796 return 0;
1797}
1798
1799static const struct luaL_Reg gSkTextBlob_Methods[] = {
1800 { "bounds", ltextblob_bounds },
1801 { "__gc", ltextblob_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001802 { nullptr, nullptr }
reed1b6ab442014-11-03 19:55:41 -08001803};
1804
1805///////////////////////////////////////////////////////////////////////////////
1806
reed36c9c112014-11-04 10:58:42 -08001807static int ltypeface_getFamilyName(lua_State* L) {
1808 SkString str;
1809 get_ref<SkTypeface>(L, 1)->getFamilyName(&str);
1810 lua_pushstring(L, str.c_str());
1811 return 1;
1812}
1813
1814static int ltypeface_getStyle(lua_State* L) {
1815 lua_pushnumber(L, (double)get_ref<SkTypeface>(L, 1)->style());
1816 return 1;
1817}
1818
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001819static int ltypeface_gc(lua_State* L) {
commit-bot@chromium.org77887af2013-12-17 14:28:19 +00001820 SkSafeUnref(get_ref<SkTypeface>(L, 1));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001821 return 0;
1822}
1823
1824static const struct luaL_Reg gSkTypeface_Methods[] = {
reed36c9c112014-11-04 10:58:42 -08001825 { "getFamilyName", ltypeface_getFamilyName },
1826 { "getStyle", ltypeface_getStyle },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001827 { "__gc", ltypeface_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001828 { nullptr, nullptr }
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001829};
1830
1831///////////////////////////////////////////////////////////////////////////////
1832
reed@google.com74ce6f02013-05-22 15:13:18 +00001833class AutoCallLua {
1834public:
1835 AutoCallLua(lua_State* L, const char func[], const char verb[]) : fL(L) {
1836 lua_getglobal(L, func);
1837 if (!lua_isfunction(L, -1)) {
1838 int t = lua_type(L, -1);
1839 SkDebugf("--- expected function %d\n", t);
1840 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001841
reed@google.com74ce6f02013-05-22 15:13:18 +00001842 lua_newtable(L);
1843 setfield_string(L, "verb", verb);
1844 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001845
reed@google.com74ce6f02013-05-22 15:13:18 +00001846 ~AutoCallLua() {
1847 if (lua_pcall(fL, 1, 0, 0) != LUA_OK) {
1848 SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
1849 }
1850 lua_settop(fL, -1);
1851 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001852
reed@google.com74ce6f02013-05-22 15:13:18 +00001853private:
1854 lua_State* fL;
1855};
1856
1857#define AUTO_LUA(verb) AutoCallLua acl(fL, fFunc.c_str(), verb)
1858
1859///////////////////////////////////////////////////////////////////////////////
1860
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001861static int lsk_newDocumentPDF(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07001862 const char* file = nullptr;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001863 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001864 file = lua_tolstring(L, 1, nullptr);
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001865 }
1866
halcanary676ab682016-05-03 12:10:04 -07001867 sk_sp<SkDocument> doc = SkDocument::MakePDF(file);
halcanary96fcdcc2015-08-27 07:41:13 -07001868 if (nullptr == doc) {
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001869 // do I need to push a nil on the stack and return 1?
1870 return 0;
1871 } else {
halcanary676ab682016-05-03 12:10:04 -07001872 push_ref(L, std::move(doc));
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001873 return 1;
1874 }
1875}
1876
reed468b1812014-10-19 11:42:54 -07001877static int lsk_newBlurImageFilter(lua_State* L) {
1878 SkScalar sigmaX = lua2scalar_def(L, 1, 0);
1879 SkScalar sigmaY = lua2scalar_def(L, 2, 0);
robertphillips6e7025a2016-04-04 04:31:25 -07001880 sk_sp<SkImageFilter> imf(SkBlurImageFilter::Make(sigmaX, sigmaY, nullptr));
1881 if (!imf) {
reed468b1812014-10-19 11:42:54 -07001882 lua_pushnil(L);
1883 } else {
robertphillips6e7025a2016-04-04 04:31:25 -07001884 push_ref(L, std::move(imf));
reed9fbc3f32014-10-21 07:12:58 -07001885 }
1886 return 1;
1887}
1888
1889static int lsk_newLinearGradient(lua_State* L) {
1890 SkScalar x0 = lua2scalar_def(L, 1, 0);
1891 SkScalar y0 = lua2scalar_def(L, 2, 0);
1892 SkColor c0 = lua2color(L, 3);
1893 SkScalar x1 = lua2scalar_def(L, 4, 0);
1894 SkScalar y1 = lua2scalar_def(L, 5, 0);
1895 SkColor c1 = lua2color(L, 6);
1896
1897 SkPoint pts[] = { { x0, y0 }, { x1, y1 } };
1898 SkColor colors[] = { c0, c1 };
robertphillips6e7025a2016-04-04 04:31:25 -07001899 sk_sp<SkShader> s(SkGradientShader::MakeLinear(pts, colors, nullptr, 2,
1900 SkShader::kClamp_TileMode));
reed2ad1aa62016-03-09 09:50:50 -08001901 if (!s) {
reed9fbc3f32014-10-21 07:12:58 -07001902 lua_pushnil(L);
1903 } else {
reed2ad1aa62016-03-09 09:50:50 -08001904 push_ref(L, std::move(s));
reed468b1812014-10-19 11:42:54 -07001905 }
1906 return 1;
1907}
1908
reedbdc49ae2014-10-14 09:34:52 -07001909static int lsk_newMatrix(lua_State* L) {
1910 push_new<SkMatrix>(L)->reset();
1911 return 1;
1912}
1913
reed@google.com3597b732013-05-22 20:12:50 +00001914static int lsk_newPaint(lua_State* L) {
1915 push_new<SkPaint>(L);
1916 return 1;
1917}
1918
1919static int lsk_newPath(lua_State* L) {
1920 push_new<SkPath>(L);
1921 return 1;
1922}
1923
reed96affcd2014-10-13 12:38:04 -07001924static int lsk_newPictureRecorder(lua_State* L) {
1925 push_new<SkPictureRecorder>(L);
1926 return 1;
1927}
1928
reed@google.com3597b732013-05-22 20:12:50 +00001929static int lsk_newRRect(lua_State* L) {
reedbdc49ae2014-10-14 09:34:52 -07001930 push_new<SkRRect>(L)->setEmpty();
reed@google.com3597b732013-05-22 20:12:50 +00001931 return 1;
1932}
1933
reed1b6ab442014-11-03 19:55:41 -08001934#include "SkTextBox.h"
1935// Sk.newTextBlob(text, rect, paint)
1936static int lsk_newTextBlob(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07001937 const char* text = lua_tolstring(L, 1, nullptr);
reed1b6ab442014-11-03 19:55:41 -08001938 SkRect bounds;
1939 lua2rect(L, 2, &bounds);
1940 const SkPaint& paint = *get_obj<SkPaint>(L, 3);
1941
1942 SkTextBox box;
1943 box.setMode(SkTextBox::kLineBreak_Mode);
1944 box.setBox(bounds);
1945 box.setText(text, strlen(text), paint);
1946
1947 SkScalar newBottom;
fmalita37283c22016-09-13 10:00:23 -07001948 push_ref<SkTextBlob>(L, box.snapshotTextBlob(&newBottom));
reed1b6ab442014-11-03 19:55:41 -08001949 SkLua(L).pushScalar(newBottom);
1950 return 2;
1951}
1952
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001953static int lsk_newTypeface(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07001954 const char* name = nullptr;
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001955 int style = SkTypeface::kNormal;
skia.committer@gmail.com63193672013-06-08 07:01:13 +00001956
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001957 int count = lua_gettop(L);
1958 if (count > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001959 name = lua_tolstring(L, 1, nullptr);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001960 if (count > 1 && lua_isnumber(L, 2)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001961 style = lua_tointegerx(L, 2, nullptr) & SkTypeface::kBoldItalic;
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001962 }
1963 }
1964
mbocee6a9912016-05-31 11:42:36 -07001965 sk_sp<SkTypeface> face(SkTypeface::MakeFromName(name, SkFontStyle::FromOldStyle(style)));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001966// SkDebugf("---- name <%s> style=%d, face=%p ref=%d\n", name, style, face, face->getRefCnt());
halcanary96fcdcc2015-08-27 07:41:13 -07001967 if (nullptr == face) {
bungeman13b9c952016-05-12 10:09:30 -07001968 face = SkTypeface::MakeDefault();
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001969 }
bungeman13b9c952016-05-12 10:09:30 -07001970 push_ref(L, std::move(face));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001971 return 1;
1972}
reed@google.com3597b732013-05-22 20:12:50 +00001973
reed485557f2014-10-12 10:36:47 -07001974static int lsk_newRasterSurface(lua_State* L) {
reed7b864662014-11-04 13:24:47 -08001975 int width = lua2int_def(L, 1, 0);
reed485557f2014-10-12 10:36:47 -07001976 int height = lua2int_def(L, 2, 0);
1977 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
robertphillips702edbd2015-06-23 06:26:08 -07001978 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
reede8f30622016-03-23 18:59:25 -07001979 auto surface = SkSurface::MakeRaster(info, &props);
halcanary96fcdcc2015-08-27 07:41:13 -07001980 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -07001981 lua_pushnil(L);
1982 } else {
reede8f30622016-03-23 18:59:25 -07001983 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -07001984 }
1985 return 1;
1986}
1987
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001988static int lsk_loadImage(lua_State* L) {
1989 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001990 const char* name = lua_tolstring(L, 1, nullptr);
reed9ce9d672016-03-17 10:51:11 -07001991 sk_sp<SkData> data(SkData::MakeFromFileName(name));
1992 if (data) {
1993 auto image = SkImage::MakeFromEncoded(std::move(data));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001994 if (image) {
reed9ce9d672016-03-17 10:51:11 -07001995 push_ref(L, std::move(image));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001996 return 1;
1997 }
1998 }
1999 }
2000 return 0;
2001}
2002
reed@google.com3597b732013-05-22 20:12:50 +00002003static void register_Sk(lua_State* L) {
2004 lua_newtable(L);
2005 lua_pushvalue(L, -1);
2006 lua_setglobal(L, "Sk");
2007 // the Sk table is still on top
2008
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00002009 setfield_function(L, "newDocumentPDF", lsk_newDocumentPDF);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00002010 setfield_function(L, "loadImage", lsk_loadImage);
reed468b1812014-10-19 11:42:54 -07002011 setfield_function(L, "newBlurImageFilter", lsk_newBlurImageFilter);
reed9fbc3f32014-10-21 07:12:58 -07002012 setfield_function(L, "newLinearGradient", lsk_newLinearGradient);
reedbdc49ae2014-10-14 09:34:52 -07002013 setfield_function(L, "newMatrix", lsk_newMatrix);
reed@google.com3597b732013-05-22 20:12:50 +00002014 setfield_function(L, "newPaint", lsk_newPaint);
2015 setfield_function(L, "newPath", lsk_newPath);
reed96affcd2014-10-13 12:38:04 -07002016 setfield_function(L, "newPictureRecorder", lsk_newPictureRecorder);
reed@google.com3597b732013-05-22 20:12:50 +00002017 setfield_function(L, "newRRect", lsk_newRRect);
reed485557f2014-10-12 10:36:47 -07002018 setfield_function(L, "newRasterSurface", lsk_newRasterSurface);
reed1b6ab442014-11-03 19:55:41 -08002019 setfield_function(L, "newTextBlob", lsk_newTextBlob);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00002020 setfield_function(L, "newTypeface", lsk_newTypeface);
reed@google.com3597b732013-05-22 20:12:50 +00002021 lua_pop(L, 1); // pop off the Sk table
2022}
2023
reed@google.com74ce6f02013-05-22 15:13:18 +00002024#define REG_CLASS(L, C) \
2025 do { \
reed@google.com3597b732013-05-22 20:12:50 +00002026 luaL_newmetatable(L, get_mtname<C>()); \
reed@google.com74ce6f02013-05-22 15:13:18 +00002027 lua_pushvalue(L, -1); \
2028 lua_setfield(L, -2, "__index"); \
2029 luaL_setfuncs(L, g##C##_Methods, 0); \
2030 lua_pop(L, 1); /* pop off the meta-table */ \
2031 } while (0)
2032
2033void SkLua::Load(lua_State* L) {
reed@google.com3597b732013-05-22 20:12:50 +00002034 register_Sk(L);
reed@google.com74ce6f02013-05-22 15:13:18 +00002035 REG_CLASS(L, SkCanvas);
reed22a517f2015-12-04 20:45:59 -08002036 REG_CLASS(L, SkColorFilter);
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00002037 REG_CLASS(L, SkDocument);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00002038 REG_CLASS(L, SkImage);
reed468b1812014-10-19 11:42:54 -07002039 REG_CLASS(L, SkImageFilter);
reed1b6ab442014-11-03 19:55:41 -08002040 REG_CLASS(L, SkMatrix);
reed@google.com74ce6f02013-05-22 15:13:18 +00002041 REG_CLASS(L, SkPaint);
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00002042 REG_CLASS(L, SkPath);
2043 REG_CLASS(L, SkPathEffect);
reed96affcd2014-10-13 12:38:04 -07002044 REG_CLASS(L, SkPicture);
2045 REG_CLASS(L, SkPictureRecorder);
reed@google.com74ce6f02013-05-22 15:13:18 +00002046 REG_CLASS(L, SkRRect);
reed@google.com5fdc9832013-07-24 15:47:52 +00002047 REG_CLASS(L, SkShader);
reed485557f2014-10-12 10:36:47 -07002048 REG_CLASS(L, SkSurface);
reed1b6ab442014-11-03 19:55:41 -08002049 REG_CLASS(L, SkTextBlob);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00002050 REG_CLASS(L, SkTypeface);
reed@google.com74ce6f02013-05-22 15:13:18 +00002051}
zachr@google.com28c27c82013-06-20 17:15:05 +00002052
reed@google.com7bce9982013-06-20 17:40:21 +00002053extern "C" int luaopen_skia(lua_State* L);
zachr@google.com28c27c82013-06-20 17:15:05 +00002054extern "C" int luaopen_skia(lua_State* L) {
2055 SkLua::Load(L);
2056 return 0;
2057}