blob: c634d5b03f5ddb19aeb358693d87a7bc29dfc162 [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/utils/SkLua.h"
bsalomon@google.com4ebe3822014-02-26 20:22:32 +00009
10#if SK_SUPPORT_GPU
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011//#include "src/gpu/GrReducedClip.h"
bsalomon@google.com4ebe3822014-02-26 20:22:32 +000012#endif
13
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "include/core/SkCanvas.h"
15#include "include/core/SkColorFilter.h"
16#include "include/core/SkData.h"
17#include "include/core/SkFont.h"
18#include "include/core/SkFontMetrics.h"
19#include "include/core/SkFontStyle.h"
20#include "include/core/SkImage.h"
21#include "include/core/SkMatrix.h"
22#include "include/core/SkPaint.h"
23#include "include/core/SkPath.h"
24#include "include/core/SkPictureRecorder.h"
25#include "include/core/SkRRect.h"
26#include "include/core/SkString.h"
27#include "include/core/SkSurface.h"
28#include "include/core/SkTextBlob.h"
29#include "include/core/SkTypeface.h"
30#include "include/docs/SkPDFDocument.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050031#include "include/effects/SkGradientShader.h"
Michael Ludwig06eacf42019-08-01 16:02:27 -040032#include "include/effects/SkImageFilters.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050033#include "include/private/SkTo.h"
34#include "modules/skshaper/include/SkShaper.h"
35#include "src/core/SkMakeUnique.h"
Mike Klein79aea6a2018-06-11 10:45:26 -040036#include <new>
reed@google.com74ce6f02013-05-22 15:13:18 +000037
38extern "C" {
reed@google.com3597b732013-05-22 20:12:50 +000039 #include "lua.h"
40 #include "lualib.h"
41 #include "lauxlib.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000042}
43
Mike Reed7ff6ca52018-01-08 14:45:31 -050044struct DocHolder {
45 sk_sp<SkDocument> fDoc;
46 std::unique_ptr<SkWStream> fStream;
47};
48
reed@google.comfd345872013-05-22 20:53:42 +000049// return the metatable name for a given class
reed@google.com3597b732013-05-22 20:12:50 +000050template <typename T> const char* get_mtname();
reed@google.comfd345872013-05-22 20:53:42 +000051#define DEF_MTNAME(T) \
52 template <> const char* get_mtname<T>() { \
53 return #T "_LuaMetaTableName"; \
54 }
55
56DEF_MTNAME(SkCanvas)
reed22a517f2015-12-04 20:45:59 -080057DEF_MTNAME(SkColorFilter)
Mike Reed7ff6ca52018-01-08 14:45:31 -050058DEF_MTNAME(DocHolder)
Mike Reed91919132019-01-02 12:21:01 -050059DEF_MTNAME(SkFont)
mike@reedtribe.org792bbd12013-06-11 02:20:28 +000060DEF_MTNAME(SkImage)
reed468b1812014-10-19 11:42:54 -070061DEF_MTNAME(SkImageFilter)
reed@google.comfd345872013-05-22 20:53:42 +000062DEF_MTNAME(SkMatrix)
63DEF_MTNAME(SkRRect)
64DEF_MTNAME(SkPath)
65DEF_MTNAME(SkPaint)
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +000066DEF_MTNAME(SkPathEffect)
reed96affcd2014-10-13 12:38:04 -070067DEF_MTNAME(SkPicture)
68DEF_MTNAME(SkPictureRecorder)
reed@google.com5fdc9832013-07-24 15:47:52 +000069DEF_MTNAME(SkShader)
reed485557f2014-10-12 10:36:47 -070070DEF_MTNAME(SkSurface)
fmalitab7425172014-08-26 07:56:44 -070071DEF_MTNAME(SkTextBlob)
mike@reedtribe.orge6469f12013-06-08 03:15:47 +000072DEF_MTNAME(SkTypeface)
Ben Wagnerc6c10b42017-08-07 09:56:21 -040073DEF_MTNAME(SkFontStyle)
reed@google.com74ce6f02013-05-22 15:13:18 +000074
Ben Wagnerc6c10b42017-08-07 09:56:21 -040075template <typename T, typename... Args> T* push_new(lua_State* L, Args&&... args) {
reed@google.com3597b732013-05-22 20:12:50 +000076 T* addr = (T*)lua_newuserdata(L, sizeof(T));
Ben Wagnerc6c10b42017-08-07 09:56:21 -040077 new (addr) T(std::forward<Args>(args)...);
reed@google.com3597b732013-05-22 20:12:50 +000078 luaL_getmetatable(L, get_mtname<T>());
79 lua_setmetatable(L, -2);
80 return addr;
81}
reed@google.com74ce6f02013-05-22 15:13:18 +000082
83template <typename T> void push_obj(lua_State* L, const T& obj) {
84 new (lua_newuserdata(L, sizeof(T))) T(obj);
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);
87}
88
Mike Reed5df49342016-11-12 08:06:55 -060089template <typename T> T* push_ptr(lua_State* L, T* ptr) {
90 *(T**)lua_newuserdata(L, sizeof(T*)) = ptr;
91 luaL_getmetatable(L, get_mtname<T>());
92 lua_setmetatable(L, -2);
93 return ptr;
94}
95
reed9fbc3f32014-10-21 07:12:58 -070096template <typename T> T* push_ref(lua_State* L, T* ref) {
commit-bot@chromium.org77887af2013-12-17 14:28:19 +000097 *(T**)lua_newuserdata(L, sizeof(T*)) = SkSafeRef(ref);
reed@google.com3597b732013-05-22 20:12:50 +000098 luaL_getmetatable(L, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +000099 lua_setmetatable(L, -2);
reed9fbc3f32014-10-21 07:12:58 -0700100 return ref;
reed@google.com74ce6f02013-05-22 15:13:18 +0000101}
102
reed2ad1aa62016-03-09 09:50:50 -0800103template <typename T> void push_ref(lua_State* L, sk_sp<T> sp) {
104 *(T**)lua_newuserdata(L, sizeof(T*)) = sp.release();
105 luaL_getmetatable(L, get_mtname<T>());
106 lua_setmetatable(L, -2);
107}
108
reed@google.com74ce6f02013-05-22 15:13:18 +0000109template <typename T> T* get_ref(lua_State* L, int index) {
reed@google.com3597b732013-05-22 20:12:50 +0000110 return *(T**)luaL_checkudata(L, index, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +0000111}
112
113template <typename T> T* get_obj(lua_State* L, int index) {
reed@google.com3597b732013-05-22 20:12:50 +0000114 return (T*)luaL_checkudata(L, index, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +0000115}
116
reed@google.com88c9ec92013-05-22 15:43:21 +0000117static bool lua2bool(lua_State* L, int index) {
118 return !!lua_toboolean(L, index);
119}
120
reed@google.com74ce6f02013-05-22 15:13:18 +0000121///////////////////////////////////////////////////////////////////////////////
122
reed@google.com3597b732013-05-22 20:12:50 +0000123SkLua::SkLua(const char termCode[]) : fTermCode(termCode), fWeOwnL(true) {
124 fL = luaL_newstate();
125 luaL_openlibs(fL);
126 SkLua::Load(fL);
127}
128
129SkLua::SkLua(lua_State* L) : fL(L), fWeOwnL(false) {}
130
131SkLua::~SkLua() {
132 if (fWeOwnL) {
133 if (fTermCode.size() > 0) {
134 lua_getglobal(fL, fTermCode.c_str());
135 if (lua_pcall(fL, 0, 0, 0) != LUA_OK) {
136 SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
137 }
138 }
139 lua_close(fL);
140 }
141}
142
143bool SkLua::runCode(const char code[]) {
144 int err = luaL_loadstring(fL, code) || lua_pcall(fL, 0, 0, 0);
145 if (err) {
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000146 SkDebugf("--- lua failed: %s\n", lua_tostring(fL, -1));
reed@google.com3597b732013-05-22 20:12:50 +0000147 return false;
148 }
149 return true;
150}
151
152bool SkLua::runCode(const void* code, size_t size) {
153 SkString str((const char*)code, size);
154 return this->runCode(str.c_str());
155}
156
157///////////////////////////////////////////////////////////////////////////////
158
159#define CHECK_SETFIELD(key) do if (key) lua_setfield(fL, -2, key); while (0)
160
reed@google.com29563872013-07-10 21:23:49 +0000161static void setfield_bool_if(lua_State* L, const char key[], bool pred) {
162 if (pred) {
163 lua_pushboolean(L, true);
164 lua_setfield(L, -2, key);
165 }
166}
167
reed@google.com74ce6f02013-05-22 15:13:18 +0000168static void setfield_string(lua_State* L, const char key[], const char value[]) {
169 lua_pushstring(L, value);
170 lua_setfield(L, -2, key);
171}
172
173static void setfield_number(lua_State* L, const char key[], double value) {
174 lua_pushnumber(L, value);
175 lua_setfield(L, -2, key);
176}
177
humper@google.com2815c192013-07-10 22:42:30 +0000178static void setfield_boolean(lua_State* L, const char key[], bool value) {
179 lua_pushboolean(L, value);
180 lua_setfield(L, -2, key);
181}
182
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000183static void setfield_scalar(lua_State* L, const char key[], SkScalar value) {
184 setfield_number(L, key, SkScalarToLua(value));
185}
186
reed@google.com3597b732013-05-22 20:12:50 +0000187static void setfield_function(lua_State* L,
188 const char key[], lua_CFunction value) {
189 lua_pushcfunction(L, value);
190 lua_setfield(L, -2, key);
reed@google.com74ce6f02013-05-22 15:13:18 +0000191}
192
reed7a72c672014-11-07 10:23:55 -0800193static int lua2int_def(lua_State* L, int index, int defaultValue) {
194 if (lua_isnumber(L, index)) {
195 return (int)lua_tonumber(L, index);
196 } else {
197 return defaultValue;
198 }
199}
200
201static SkScalar lua2scalar(lua_State* L, int index) {
202 SkASSERT(lua_isnumber(L, index));
203 return SkLuaToScalar(lua_tonumber(L, index));
204}
205
206static SkScalar lua2scalar_def(lua_State* L, int index, SkScalar defaultValue) {
207 if (lua_isnumber(L, index)) {
208 return SkLuaToScalar(lua_tonumber(L, index));
209 } else {
210 return defaultValue;
211 }
212}
213
214static SkScalar getarray_scalar(lua_State* L, int stackIndex, int arrayIndex) {
215 SkASSERT(lua_istable(L, stackIndex));
216 lua_rawgeti(L, stackIndex, arrayIndex);
mtklein8aacf202014-12-18 13:29:54 -0800217
reed7a72c672014-11-07 10:23:55 -0800218 SkScalar value = lua2scalar(L, -1);
219 lua_pop(L, 1);
220 return value;
221}
222
223static void getarray_scalars(lua_State* L, int stackIndex, SkScalar dst[], int count) {
224 for (int i = 0; i < count; ++i) {
225 dst[i] = getarray_scalar(L, stackIndex, i + 1);
226 }
227}
228
229static void getarray_points(lua_State* L, int stackIndex, SkPoint pts[], int count) {
230 getarray_scalars(L, stackIndex, &pts[0].fX, count * 2);
231}
232
reed@google.come3823fd2013-05-30 18:55:14 +0000233static void setarray_number(lua_State* L, int index, double value) {
234 lua_pushnumber(L, value);
235 lua_rawseti(L, -2, index);
236}
237
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +0000238static void setarray_scalar(lua_State* L, int index, SkScalar value) {
239 setarray_number(L, index, SkScalarToLua(value));
240}
241
hstern0b401ce2016-08-02 09:17:59 -0700242static void setarray_string(lua_State* L, int index, const char str[]) {
243 lua_pushstring(L, str);
244 lua_rawseti(L, -2, index);
245}
246
reed@google.com74ce6f02013-05-22 15:13:18 +0000247void SkLua::pushBool(bool value, const char key[]) {
248 lua_pushboolean(fL, value);
249 CHECK_SETFIELD(key);
250}
251
252void SkLua::pushString(const char str[], const char key[]) {
253 lua_pushstring(fL, str);
254 CHECK_SETFIELD(key);
255}
256
reed@google.come3823fd2013-05-30 18:55:14 +0000257void SkLua::pushString(const char str[], size_t length, const char key[]) {
258 // TODO: how to do this w/o making a copy?
259 SkString s(str, length);
260 lua_pushstring(fL, s.c_str());
261 CHECK_SETFIELD(key);
262}
263
reed@google.com74ce6f02013-05-22 15:13:18 +0000264void SkLua::pushString(const SkString& str, const char key[]) {
265 lua_pushstring(fL, str.c_str());
266 CHECK_SETFIELD(key);
267}
268
269void SkLua::pushColor(SkColor color, const char key[]) {
270 lua_newtable(fL);
271 setfield_number(fL, "a", SkColorGetA(color) / 255.0);
272 setfield_number(fL, "r", SkColorGetR(color) / 255.0);
273 setfield_number(fL, "g", SkColorGetG(color) / 255.0);
274 setfield_number(fL, "b", SkColorGetB(color) / 255.0);
275 CHECK_SETFIELD(key);
276}
277
reed@google.come3823fd2013-05-30 18:55:14 +0000278void SkLua::pushU32(uint32_t value, const char key[]) {
279 lua_pushnumber(fL, (double)value);
280 CHECK_SETFIELD(key);
281}
282
reed@google.com74ce6f02013-05-22 15:13:18 +0000283void SkLua::pushScalar(SkScalar value, const char key[]) {
284 lua_pushnumber(fL, SkScalarToLua(value));
285 CHECK_SETFIELD(key);
286}
287
reed@google.come3823fd2013-05-30 18:55:14 +0000288void SkLua::pushArrayU16(const uint16_t array[], int count, const char key[]) {
289 lua_newtable(fL);
290 for (int i = 0; i < count; ++i) {
291 // make it base-1 to match lua convention
292 setarray_number(fL, i + 1, (double)array[i]);
293 }
294 CHECK_SETFIELD(key);
295}
296
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +0000297void SkLua::pushArrayPoint(const SkPoint array[], int count, const char key[]) {
298 lua_newtable(fL);
299 for (int i = 0; i < count; ++i) {
300 // make it base-1 to match lua convention
301 lua_newtable(fL);
302 this->pushScalar(array[i].fX, "x");
303 this->pushScalar(array[i].fY, "y");
304 lua_rawseti(fL, -2, i + 1);
305 }
306 CHECK_SETFIELD(key);
307}
308
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +0000309void SkLua::pushArrayScalar(const SkScalar array[], int count, const char key[]) {
310 lua_newtable(fL);
311 for (int i = 0; i < count; ++i) {
312 // make it base-1 to match lua convention
313 setarray_scalar(fL, i + 1, array[i]);
314 }
315 CHECK_SETFIELD(key);
316}
317
reed@google.com74ce6f02013-05-22 15:13:18 +0000318void SkLua::pushRect(const SkRect& r, const char key[]) {
319 lua_newtable(fL);
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000320 setfield_scalar(fL, "left", r.fLeft);
321 setfield_scalar(fL, "top", r.fTop);
322 setfield_scalar(fL, "right", r.fRight);
323 setfield_scalar(fL, "bottom", r.fBottom);
reed@google.com74ce6f02013-05-22 15:13:18 +0000324 CHECK_SETFIELD(key);
325}
326
327void SkLua::pushRRect(const SkRRect& rr, const char key[]) {
328 push_obj(fL, rr);
329 CHECK_SETFIELD(key);
330}
331
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +0000332void SkLua::pushDash(const SkPathEffect::DashInfo& info, const char key[]) {
333 lua_newtable(fL);
334 setfield_scalar(fL, "phase", info.fPhase);
335 this->pushArrayScalar(info.fIntervals, info.fCount, "intervals");
336 CHECK_SETFIELD(key);
337}
338
339
reed@google.com74ce6f02013-05-22 15:13:18 +0000340void SkLua::pushMatrix(const SkMatrix& matrix, const char key[]) {
341 push_obj(fL, matrix);
342 CHECK_SETFIELD(key);
343}
344
345void SkLua::pushPaint(const SkPaint& paint, const char key[]) {
346 push_obj(fL, paint);
347 CHECK_SETFIELD(key);
348}
349
350void SkLua::pushPath(const SkPath& path, const char key[]) {
351 push_obj(fL, path);
352 CHECK_SETFIELD(key);
353}
354
355void SkLua::pushCanvas(SkCanvas* canvas, const char key[]) {
Mike Reed5df49342016-11-12 08:06:55 -0600356 push_ptr(fL, canvas);
reed@google.com74ce6f02013-05-22 15:13:18 +0000357 CHECK_SETFIELD(key);
358}
359
fmalitab7425172014-08-26 07:56:44 -0700360void SkLua::pushTextBlob(const SkTextBlob* blob, const char key[]) {
361 push_ref(fL, const_cast<SkTextBlob*>(blob));
362 CHECK_SETFIELD(key);
363}
364
reed@google.com74ce6f02013-05-22 15:13:18 +0000365///////////////////////////////////////////////////////////////////////////////
366///////////////////////////////////////////////////////////////////////////////
367
reed@google.com74ce6f02013-05-22 15:13:18 +0000368static SkScalar getfield_scalar(lua_State* L, int index, const char key[]) {
369 SkASSERT(lua_istable(L, index));
370 lua_pushstring(L, key);
371 lua_gettable(L, index);
mtklein8aacf202014-12-18 13:29:54 -0800372
reed@google.com74ce6f02013-05-22 15:13:18 +0000373 SkScalar value = lua2scalar(L, -1);
374 lua_pop(L, 1);
375 return value;
376}
377
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000378static SkScalar getfield_scalar_default(lua_State* L, int index, const char key[], SkScalar def) {
379 SkASSERT(lua_istable(L, index));
380 lua_pushstring(L, key);
381 lua_gettable(L, index);
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000382
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000383 SkScalar value;
384 if (lua_isnil(L, -1)) {
385 value = def;
386 } else {
387 value = lua2scalar(L, -1);
388 }
389 lua_pop(L, 1);
390 return value;
391}
392
reed468b1812014-10-19 11:42:54 -0700393static SkScalar byte2unit(U8CPU byte) {
394 return byte / 255.0f;
395}
396
reed@google.com74ce6f02013-05-22 15:13:18 +0000397static U8CPU unit2byte(SkScalar x) {
398 if (x <= 0) {
399 return 0;
400 } else if (x >= 1) {
401 return 255;
402 } else {
403 return SkScalarRoundToInt(x * 255);
404 }
405}
406
407static SkColor lua2color(lua_State* L, int index) {
reed485557f2014-10-12 10:36:47 -0700408 return SkColorSetARGB(unit2byte(getfield_scalar_default(L, index, "a", 1)),
409 unit2byte(getfield_scalar_default(L, index, "r", 0)),
410 unit2byte(getfield_scalar_default(L, index, "g", 0)),
411 unit2byte(getfield_scalar_default(L, index, "b", 0)));
reed@google.com74ce6f02013-05-22 15:13:18 +0000412}
413
414static SkRect* lua2rect(lua_State* L, int index, SkRect* rect) {
Mike Reed92b33352019-08-24 19:39:13 -0400415 rect->setLTRB(getfield_scalar_default(L, index, "left", 0),
416 getfield_scalar_default(L, index, "top", 0),
417 getfield_scalar(L, index, "right"),
418 getfield_scalar(L, index, "bottom"));
reed@google.com74ce6f02013-05-22 15:13:18 +0000419 return rect;
420}
421
reedf355df52014-10-12 12:18:40 -0700422static int lcanvas_clear(lua_State* L) {
423 get_ref<SkCanvas>(L, 1)->clear(0);
424 return 0;
425}
426
reed@google.com74ce6f02013-05-22 15:13:18 +0000427static int lcanvas_drawColor(lua_State* L) {
428 get_ref<SkCanvas>(L, 1)->drawColor(lua2color(L, 2));
429 return 0;
430}
431
reed9fbc3f32014-10-21 07:12:58 -0700432static int lcanvas_drawPaint(lua_State* L) {
433 get_ref<SkCanvas>(L, 1)->drawPaint(*get_obj<SkPaint>(L, 2));
434 return 0;
435}
436
reed@google.com74ce6f02013-05-22 15:13:18 +0000437static int lcanvas_drawRect(lua_State* L) {
438 SkRect rect;
reed7a72c672014-11-07 10:23:55 -0800439 lua2rect(L, 2, &rect);
440 const SkPaint* paint = get_obj<SkPaint>(L, 3);
441 get_ref<SkCanvas>(L, 1)->drawRect(rect, *paint);
reed@google.com74ce6f02013-05-22 15:13:18 +0000442 return 0;
443}
444
445static int lcanvas_drawOval(lua_State* L) {
446 SkRect rect;
447 get_ref<SkCanvas>(L, 1)->drawOval(*lua2rect(L, 2, &rect),
448 *get_obj<SkPaint>(L, 3));
449 return 0;
450}
451
452static int lcanvas_drawCircle(lua_State* L) {
453 get_ref<SkCanvas>(L, 1)->drawCircle(lua2scalar(L, 2),
454 lua2scalar(L, 3),
455 lua2scalar(L, 4),
456 *get_obj<SkPaint>(L, 5));
457 return 0;
458}
459
reed485557f2014-10-12 10:36:47 -0700460static SkPaint* lua2OptionalPaint(lua_State* L, int index, SkPaint* paint) {
461 if (lua_isnumber(L, index)) {
462 paint->setAlpha(SkScalarRoundToInt(lua2scalar(L, index) * 255));
463 return paint;
reedf355df52014-10-12 12:18:40 -0700464 } else if (lua_isuserdata(L, index)) {
reed485557f2014-10-12 10:36:47 -0700465 const SkPaint* ptr = get_obj<SkPaint>(L, index);
466 if (ptr) {
467 *paint = *ptr;
468 return paint;
469 }
470 }
halcanary96fcdcc2015-08-27 07:41:13 -0700471 return nullptr;
reed485557f2014-10-12 10:36:47 -0700472}
473
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000474static int lcanvas_drawImage(lua_State* L) {
475 SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
476 SkImage* image = get_ref<SkImage>(L, 2);
halcanary96fcdcc2015-08-27 07:41:13 -0700477 if (nullptr == image) {
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000478 return 0;
479 }
480 SkScalar x = lua2scalar(L, 3);
481 SkScalar y = lua2scalar(L, 4);
482
483 SkPaint paint;
reed485557f2014-10-12 10:36:47 -0700484 canvas->drawImage(image, x, y, lua2OptionalPaint(L, 5, &paint));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000485 return 0;
486}
487
reedba5fb932014-10-10 15:28:19 -0700488static int lcanvas_drawImageRect(lua_State* L) {
489 SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
490 SkImage* image = get_ref<SkImage>(L, 2);
halcanary96fcdcc2015-08-27 07:41:13 -0700491 if (nullptr == image) {
reedba5fb932014-10-10 15:28:19 -0700492 return 0;
493 }
494
495 SkRect srcR, dstR;
halcanary96fcdcc2015-08-27 07:41:13 -0700496 SkRect* srcRPtr = nullptr;
reedba5fb932014-10-10 15:28:19 -0700497 if (!lua_isnil(L, 3)) {
498 srcRPtr = lua2rect(L, 3, &srcR);
499 }
500 lua2rect(L, 4, &dstR);
mtklein8aacf202014-12-18 13:29:54 -0800501
reedba5fb932014-10-10 15:28:19 -0700502 SkPaint paint;
reede47829b2015-08-06 10:02:53 -0700503 canvas->legacy_drawImageRect(image, srcRPtr, dstR, lua2OptionalPaint(L, 5, &paint));
reedba5fb932014-10-10 15:28:19 -0700504 return 0;
505}
506
reed7a72c672014-11-07 10:23:55 -0800507static int lcanvas_drawPatch(lua_State* L) {
508 SkPoint cubics[12];
509 SkColor colorStorage[4];
510 SkPoint texStorage[4];
511
halcanary96fcdcc2015-08-27 07:41:13 -0700512 const SkColor* colors = nullptr;
513 const SkPoint* texs = nullptr;
reed7a72c672014-11-07 10:23:55 -0800514
515 getarray_points(L, 2, cubics, 12);
516
517 colorStorage[0] = SK_ColorRED;
518 colorStorage[1] = SK_ColorGREEN;
519 colorStorage[2] = SK_ColorBLUE;
520 colorStorage[3] = SK_ColorGRAY;
521
522 if (lua_isnil(L, 4)) {
523 colors = colorStorage;
524 } else {
525 getarray_points(L, 4, texStorage, 4);
526 texs = texStorage;
527 }
528
Mike Reed7d954ad2016-10-28 15:42:34 -0400529 get_ref<SkCanvas>(L, 1)->drawPatch(cubics, colors, texs, *get_obj<SkPaint>(L, 5));
reed7a72c672014-11-07 10:23:55 -0800530 return 0;
531}
532
reed@google.comfd345872013-05-22 20:53:42 +0000533static int lcanvas_drawPath(lua_State* L) {
534 get_ref<SkCanvas>(L, 1)->drawPath(*get_obj<SkPath>(L, 2),
535 *get_obj<SkPaint>(L, 3));
536 return 0;
537}
538
reed96affcd2014-10-13 12:38:04 -0700539// drawPicture(pic, x, y, paint)
540static int lcanvas_drawPicture(lua_State* L) {
541 SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
542 SkPicture* picture = get_ref<SkPicture>(L, 2);
543 SkScalar x = lua2scalar_def(L, 3, 0);
544 SkScalar y = lua2scalar_def(L, 4, 0);
halcanary96fcdcc2015-08-27 07:41:13 -0700545 SkMatrix matrix, *matrixPtr = nullptr;
reed96affcd2014-10-13 12:38:04 -0700546 if (x || y) {
547 matrix.setTranslate(x, y);
548 matrixPtr = &matrix;
549 }
550 SkPaint paint;
551 canvas->drawPicture(picture, matrixPtr, lua2OptionalPaint(L, 5, &paint));
552 return 0;
553}
554
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000555static int lcanvas_drawText(lua_State* L) {
556 if (lua_gettop(L) < 5) {
557 return 0;
558 }
559
Mike Reed5f528e52019-01-28 10:57:28 -0500560 // TODO: restore this logic based on SkFont instead of SkPaint
561#if 0
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000562 if (lua_isstring(L, 2) && lua_isnumber(L, 3) && lua_isnumber(L, 4)) {
563 size_t len;
564 const char* text = lua_tolstring(L, 2, &len);
Hal Canary292ece82019-01-09 10:59:08 -0500565 get_ref<SkCanvas>(L, 1)->drawSimpleText(
Ben Wagner51e15a62019-05-07 15:38:46 -0400566 text, len, SkTextEncoding::kUTF8,
Hal Canary292ece82019-01-09 10:59:08 -0500567 lua2scalar(L, 3), lua2scalar(L, 4),
568 SkFont::LEGACY_ExtractFromPaint(*get_obj<SkPaint>(L, 5)),
569 *get_obj<SkPaint>(L, 5));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000570 }
Mike Reede5f9cfa2019-01-10 13:55:35 -0500571#endif
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000572 return 0;
573}
574
reed1b6ab442014-11-03 19:55:41 -0800575static int lcanvas_drawTextBlob(lua_State* L) {
576 const SkTextBlob* blob = get_ref<SkTextBlob>(L, 2);
577 SkScalar x = lua2scalar(L, 3);
578 SkScalar y = lua2scalar(L, 4);
579 const SkPaint& paint = *get_obj<SkPaint>(L, 5);
580 get_ref<SkCanvas>(L, 1)->drawTextBlob(blob, x, y, paint);
581 return 0;
582}
583
reed@google.com74ce6f02013-05-22 15:13:18 +0000584static int lcanvas_getSaveCount(lua_State* L) {
585 lua_pushnumber(L, get_ref<SkCanvas>(L, 1)->getSaveCount());
586 return 1;
587}
588
589static int lcanvas_getTotalMatrix(lua_State* L) {
590 SkLua(L).pushMatrix(get_ref<SkCanvas>(L, 1)->getTotalMatrix());
591 return 1;
592}
593
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000594static int lcanvas_save(lua_State* L) {
595 lua_pushinteger(L, get_ref<SkCanvas>(L, 1)->save());
596 return 1;
597}
598
reed86217d82014-10-25 20:44:40 -0700599static int lcanvas_saveLayer(lua_State* L) {
600 SkPaint paint;
halcanary96fcdcc2015-08-27 07:41:13 -0700601 lua_pushinteger(L, get_ref<SkCanvas>(L, 1)->saveLayer(nullptr, lua2OptionalPaint(L, 2, &paint)));
reed86217d82014-10-25 20:44:40 -0700602 return 1;
603}
604
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000605static int lcanvas_restore(lua_State* L) {
606 get_ref<SkCanvas>(L, 1)->restore();
607 return 0;
608}
609
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000610static int lcanvas_scale(lua_State* L) {
611 SkScalar sx = lua2scalar_def(L, 2, 1);
612 SkScalar sy = lua2scalar_def(L, 3, sx);
613 get_ref<SkCanvas>(L, 1)->scale(sx, sy);
614 return 0;
615}
616
reed@google.com3597b732013-05-22 20:12:50 +0000617static int lcanvas_translate(lua_State* L) {
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000618 SkScalar tx = lua2scalar_def(L, 2, 0);
619 SkScalar ty = lua2scalar_def(L, 3, 0);
620 get_ref<SkCanvas>(L, 1)->translate(tx, ty);
621 return 0;
622}
623
624static int lcanvas_rotate(lua_State* L) {
625 SkScalar degrees = lua2scalar_def(L, 2, 0);
626 get_ref<SkCanvas>(L, 1)->rotate(degrees);
reed@google.com3597b732013-05-22 20:12:50 +0000627 return 0;
628}
629
reedbdc49ae2014-10-14 09:34:52 -0700630static int lcanvas_concat(lua_State* L) {
631 get_ref<SkCanvas>(L, 1)->concat(*get_obj<SkMatrix>(L, 2));
632 return 0;
633}
634
reed485557f2014-10-12 10:36:47 -0700635static int lcanvas_newSurface(lua_State* L) {
636 int width = lua2int_def(L, 2, 0);
reed7a72c672014-11-07 10:23:55 -0800637 int height = lua2int_def(L, 3, 0);
reed485557f2014-10-12 10:36:47 -0700638 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
reede8f30622016-03-23 18:59:25 -0700639 auto surface = get_ref<SkCanvas>(L, 1)->makeSurface(info);
halcanary96fcdcc2015-08-27 07:41:13 -0700640 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -0700641 lua_pushnil(L);
642 } else {
reede8f30622016-03-23 18:59:25 -0700643 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -0700644 }
645 return 1;
646}
647
reed@google.com74ce6f02013-05-22 15:13:18 +0000648static int lcanvas_gc(lua_State* L) {
Mike Reed5df49342016-11-12 08:06:55 -0600649 // don't know how to track a ptr...
reed@google.com74ce6f02013-05-22 15:13:18 +0000650 return 0;
651}
652
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000653const struct luaL_Reg gSkCanvas_Methods[] = {
reedf355df52014-10-12 12:18:40 -0700654 { "clear", lcanvas_clear },
reed@google.com74ce6f02013-05-22 15:13:18 +0000655 { "drawColor", lcanvas_drawColor },
reed9fbc3f32014-10-21 07:12:58 -0700656 { "drawPaint", lcanvas_drawPaint },
reed@google.com74ce6f02013-05-22 15:13:18 +0000657 { "drawRect", lcanvas_drawRect },
658 { "drawOval", lcanvas_drawOval },
659 { "drawCircle", lcanvas_drawCircle },
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000660 { "drawImage", lcanvas_drawImage },
reedba5fb932014-10-10 15:28:19 -0700661 { "drawImageRect", lcanvas_drawImageRect },
reed7a72c672014-11-07 10:23:55 -0800662 { "drawPatch", lcanvas_drawPatch },
reed@google.comfd345872013-05-22 20:53:42 +0000663 { "drawPath", lcanvas_drawPath },
reed96affcd2014-10-13 12:38:04 -0700664 { "drawPicture", lcanvas_drawPicture },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000665 { "drawText", lcanvas_drawText },
reed1b6ab442014-11-03 19:55:41 -0800666 { "drawTextBlob", lcanvas_drawTextBlob },
reed@google.com74ce6f02013-05-22 15:13:18 +0000667 { "getSaveCount", lcanvas_getSaveCount },
668 { "getTotalMatrix", lcanvas_getTotalMatrix },
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000669 { "save", lcanvas_save },
reed86217d82014-10-25 20:44:40 -0700670 { "saveLayer", lcanvas_saveLayer },
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000671 { "restore", lcanvas_restore },
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000672 { "scale", lcanvas_scale },
reed@google.com3597b732013-05-22 20:12:50 +0000673 { "translate", lcanvas_translate },
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000674 { "rotate", lcanvas_rotate },
reedbdc49ae2014-10-14 09:34:52 -0700675 { "concat", lcanvas_concat },
reed485557f2014-10-12 10:36:47 -0700676
677 { "newSurface", lcanvas_newSurface },
678
reed@google.com74ce6f02013-05-22 15:13:18 +0000679 { "__gc", lcanvas_gc },
halcanary96fcdcc2015-08-27 07:41:13 -0700680 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +0000681};
682
683///////////////////////////////////////////////////////////////////////////////
684
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000685static int ldocument_beginPage(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -0700686 const SkRect* contentPtr = nullptr;
Mike Reed7ff6ca52018-01-08 14:45:31 -0500687 push_ptr(L, get_obj<DocHolder>(L, 1)->fDoc->beginPage(lua2scalar(L, 2),
688 lua2scalar(L, 3),
689 contentPtr));
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000690 return 1;
691}
692
693static int ldocument_endPage(lua_State* L) {
Mike Reed7ff6ca52018-01-08 14:45:31 -0500694 get_obj<DocHolder>(L, 1)->fDoc->endPage();
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000695 return 0;
696}
697
698static int ldocument_close(lua_State* L) {
Mike Reed7ff6ca52018-01-08 14:45:31 -0500699 get_obj<DocHolder>(L, 1)->fDoc->close();
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000700 return 0;
701}
702
703static int ldocument_gc(lua_State* L) {
Mike Reed7ff6ca52018-01-08 14:45:31 -0500704 get_obj<DocHolder>(L, 1)->~DocHolder();
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000705 return 0;
706}
707
Mike Reed7ff6ca52018-01-08 14:45:31 -0500708static const struct luaL_Reg gDocHolder_Methods[] = {
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000709 { "beginPage", ldocument_beginPage },
710 { "endPage", ldocument_endPage },
711 { "close", ldocument_close },
712 { "__gc", ldocument_gc },
halcanary96fcdcc2015-08-27 07:41:13 -0700713 { nullptr, nullptr }
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000714};
715
716///////////////////////////////////////////////////////////////////////////////
717
reed@google.com74ce6f02013-05-22 15:13:18 +0000718static int lpaint_isAntiAlias(lua_State* L) {
719 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isAntiAlias());
720 return 1;
721}
722
723static int lpaint_setAntiAlias(lua_State* L) {
reed@google.com88c9ec92013-05-22 15:43:21 +0000724 get_obj<SkPaint>(L, 1)->setAntiAlias(lua2bool(L, 2));
reed@google.com74ce6f02013-05-22 15:13:18 +0000725 return 0;
726}
727
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000728static int lpaint_isDither(lua_State* L) {
729 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isDither());
730 return 1;
731}
732
reedbb8a0ab2014-11-03 22:32:07 -0800733static int lpaint_setDither(lua_State* L) {
734 get_obj<SkPaint>(L, 1)->setDither(lua2bool(L, 2));
735 return 0;
736}
737
reed468b1812014-10-19 11:42:54 -0700738static int lpaint_getAlpha(lua_State* L) {
739 SkLua(L).pushScalar(byte2unit(get_obj<SkPaint>(L, 1)->getAlpha()));
740 return 1;
741}
742
743static int lpaint_setAlpha(lua_State* L) {
744 get_obj<SkPaint>(L, 1)->setAlpha(unit2byte(lua2scalar(L, 2)));
745 return 0;
746}
747
reed@google.com74ce6f02013-05-22 15:13:18 +0000748static int lpaint_getColor(lua_State* L) {
749 SkLua(L).pushColor(get_obj<SkPaint>(L, 1)->getColor());
750 return 1;
751}
752
753static int lpaint_setColor(lua_State* L) {
754 get_obj<SkPaint>(L, 1)->setColor(lua2color(L, 2));
755 return 0;
756}
757
reed93a12152015-03-16 10:08:34 -0700758static int lpaint_getFilterQuality(lua_State* L) {
759 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getFilterQuality());
reed7a72c672014-11-07 10:23:55 -0800760 return 1;
761}
762
reed93a12152015-03-16 10:08:34 -0700763static int lpaint_setFilterQuality(lua_State* L) {
reed7a72c672014-11-07 10:23:55 -0800764 int level = lua2int_def(L, 2, -1);
765 if (level >= 0 && level <= 3) {
reed93a12152015-03-16 10:08:34 -0700766 get_obj<SkPaint>(L, 1)->setFilterQuality((SkFilterQuality)level);
reed7a72c672014-11-07 10:23:55 -0800767 }
768 return 0;
769}
770
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000771static int lpaint_getStroke(lua_State* L) {
772 lua_pushboolean(L, SkPaint::kStroke_Style == get_obj<SkPaint>(L, 1)->getStyle());
773 return 1;
774}
775
776static int lpaint_setStroke(lua_State* L) {
777 SkPaint::Style style;
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000778
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000779 if (lua_toboolean(L, 2)) {
780 style = SkPaint::kStroke_Style;
781 } else {
782 style = SkPaint::kFill_Style;
783 }
784 get_obj<SkPaint>(L, 1)->setStyle(style);
785 return 0;
786}
787
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000788static int lpaint_getStrokeCap(lua_State* L) {
789 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeCap());
790 return 1;
791}
792
793static int lpaint_getStrokeJoin(lua_State* L) {
794 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeJoin());
795 return 1;
796}
797
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000798static int lpaint_getStrokeWidth(lua_State* L) {
799 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeWidth());
800 return 1;
801}
802
803static int lpaint_setStrokeWidth(lua_State* L) {
804 get_obj<SkPaint>(L, 1)->setStrokeWidth(lua2scalar(L, 2));
805 return 0;
806}
807
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000808static int lpaint_getStrokeMiter(lua_State* L) {
809 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeMiter());
810 return 1;
811}
812
reed@google.com29563872013-07-10 21:23:49 +0000813static int lpaint_getEffects(lua_State* L) {
814 const SkPaint* paint = get_obj<SkPaint>(L, 1);
skia.committer@gmail.comde2e4e82013-07-11 07:01:01 +0000815
reed@google.com29563872013-07-10 21:23:49 +0000816 lua_newtable(L);
reed468b1812014-10-19 11:42:54 -0700817 setfield_bool_if(L, "pathEffect", !!paint->getPathEffect());
reed468b1812014-10-19 11:42:54 -0700818 setfield_bool_if(L, "maskFilter", !!paint->getMaskFilter());
819 setfield_bool_if(L, "shader", !!paint->getShader());
reed@google.com29563872013-07-10 21:23:49 +0000820 setfield_bool_if(L, "colorFilter", !!paint->getColorFilter());
821 setfield_bool_if(L, "imageFilter", !!paint->getImageFilter());
reed@google.com29563872013-07-10 21:23:49 +0000822 return 1;
823}
824
reed22a517f2015-12-04 20:45:59 -0800825static int lpaint_getColorFilter(lua_State* L) {
826 const SkPaint* paint = get_obj<SkPaint>(L, 1);
827 SkColorFilter* cf = paint->getColorFilter();
828 if (cf) {
829 push_ref(L, cf);
830 return 1;
831 }
832 return 0;
833}
834
835static int lpaint_setColorFilter(lua_State* L) {
836 SkPaint* paint = get_obj<SkPaint>(L, 1);
reedd053ce92016-03-22 10:17:23 -0700837 paint->setColorFilter(sk_ref_sp(get_ref<SkColorFilter>(L, 2)));
reed22a517f2015-12-04 20:45:59 -0800838 return 0;
839}
840
reed468b1812014-10-19 11:42:54 -0700841static int lpaint_getImageFilter(lua_State* L) {
842 const SkPaint* paint = get_obj<SkPaint>(L, 1);
843 SkImageFilter* imf = paint->getImageFilter();
844 if (imf) {
845 push_ref(L, imf);
846 return 1;
847 }
848 return 0;
849}
850
851static int lpaint_setImageFilter(lua_State* L) {
852 SkPaint* paint = get_obj<SkPaint>(L, 1);
Mike Reed5e257172016-11-01 11:22:05 -0400853 paint->setImageFilter(sk_ref_sp(get_ref<SkImageFilter>(L, 2)));
reed468b1812014-10-19 11:42:54 -0700854 return 0;
855}
856
reed@google.com5fdc9832013-07-24 15:47:52 +0000857static int lpaint_getShader(lua_State* L) {
858 const SkPaint* paint = get_obj<SkPaint>(L, 1);
859 SkShader* shader = paint->getShader();
860 if (shader) {
861 push_ref(L, shader);
862 return 1;
863 }
864 return 0;
865}
866
reed9fbc3f32014-10-21 07:12:58 -0700867static int lpaint_setShader(lua_State* L) {
868 SkPaint* paint = get_obj<SkPaint>(L, 1);
reedfe630452016-03-25 09:08:00 -0700869 paint->setShader(sk_ref_sp(get_ref<SkShader>(L, 2)));
reed9fbc3f32014-10-21 07:12:58 -0700870 return 0;
871}
872
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +0000873static int lpaint_getPathEffect(lua_State* L) {
874 const SkPaint* paint = get_obj<SkPaint>(L, 1);
875 SkPathEffect* pe = paint->getPathEffect();
876 if (pe) {
877 push_ref(L, pe);
878 return 1;
879 }
880 return 0;
881}
882
hstern0b401ce2016-08-02 09:17:59 -0700883static int lpaint_getFillPath(lua_State* L) {
884 const SkPaint* paint = get_obj<SkPaint>(L, 1);
885 const SkPath* path = get_obj<SkPath>(L, 2);
886
887 SkPath fillpath;
888 paint->getFillPath(*path, &fillpath);
889
890 SkLua lua(L);
891 lua.pushPath(fillpath);
892
893 return 1;
894}
895
reed@google.com74ce6f02013-05-22 15:13:18 +0000896static int lpaint_gc(lua_State* L) {
897 get_obj<SkPaint>(L, 1)->~SkPaint();
898 return 0;
899}
900
901static const struct luaL_Reg gSkPaint_Methods[] = {
902 { "isAntiAlias", lpaint_isAntiAlias },
903 { "setAntiAlias", lpaint_setAntiAlias },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000904 { "isDither", lpaint_isDither },
reedbb8a0ab2014-11-03 22:32:07 -0800905 { "setDither", lpaint_setDither },
reed93a12152015-03-16 10:08:34 -0700906 { "getFilterQuality", lpaint_getFilterQuality },
907 { "setFilterQuality", lpaint_setFilterQuality },
reed468b1812014-10-19 11:42:54 -0700908 { "getAlpha", lpaint_getAlpha },
909 { "setAlpha", lpaint_setAlpha },
reed@google.com74ce6f02013-05-22 15:13:18 +0000910 { "getColor", lpaint_getColor },
911 { "setColor", lpaint_setColor },
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000912 { "getStroke", lpaint_getStroke },
913 { "setStroke", lpaint_setStroke },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000914 { "getStrokeCap", lpaint_getStrokeCap },
915 { "getStrokeJoin", lpaint_getStrokeJoin },
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000916 { "getStrokeWidth", lpaint_getStrokeWidth },
917 { "setStrokeWidth", lpaint_setStrokeWidth },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000918 { "getStrokeMiter", lpaint_getStrokeMiter },
reed@google.com29563872013-07-10 21:23:49 +0000919 { "getEffects", lpaint_getEffects },
reed22a517f2015-12-04 20:45:59 -0800920 { "getColorFilter", lpaint_getColorFilter },
921 { "setColorFilter", lpaint_setColorFilter },
reed468b1812014-10-19 11:42:54 -0700922 { "getImageFilter", lpaint_getImageFilter },
923 { "setImageFilter", lpaint_setImageFilter },
reed@google.com5fdc9832013-07-24 15:47:52 +0000924 { "getShader", lpaint_getShader },
reed9fbc3f32014-10-21 07:12:58 -0700925 { "setShader", lpaint_setShader },
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +0000926 { "getPathEffect", lpaint_getPathEffect },
hstern0b401ce2016-08-02 09:17:59 -0700927 { "getFillPath", lpaint_getFillPath },
reed@google.com74ce6f02013-05-22 15:13:18 +0000928 { "__gc", lpaint_gc },
halcanary96fcdcc2015-08-27 07:41:13 -0700929 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +0000930};
931
932///////////////////////////////////////////////////////////////////////////////
933
Mike Reed91919132019-01-02 12:21:01 -0500934static int lfont_getSize(lua_State* L) {
935 SkLua(L).pushScalar(get_obj<SkFont>(L, 1)->getSize());
936 return 1;
937}
938
939static int lfont_getScaleX(lua_State* L) {
940 SkLua(L).pushScalar(get_obj<SkFont>(L, 1)->getScaleX());
941 return 1;
942}
943
944static int lfont_getSkewX(lua_State* L) {
945 SkLua(L).pushScalar(get_obj<SkFont>(L, 1)->getSkewX());
946 return 1;
947}
948
949static int lfont_setSize(lua_State* L) {
950 get_obj<SkFont>(L, 1)->setSize(lua2scalar(L, 2));
951 return 0;
952}
953
954static int lfont_getTypeface(lua_State* L) {
Herb Derby087fad72019-01-22 14:45:16 -0500955 push_ref(L, get_obj<SkFont>(L, 1)->getTypefaceOrDefault());
Mike Reed91919132019-01-02 12:21:01 -0500956 return 1;
957}
958
959static int lfont_setTypeface(lua_State* L) {
960 get_obj<SkFont>(L, 1)->setTypeface(sk_ref_sp(get_ref<SkTypeface>(L, 2)));
961 return 0;
962}
963
964static int lfont_getHinting(lua_State* L) {
965 SkLua(L).pushU32((unsigned)get_obj<SkFont>(L, 1)->getHinting());
966 return 1;
967}
968
969static int lfont_getFontID(lua_State* L) {
Herb Derby087fad72019-01-22 14:45:16 -0500970 SkTypeface* face = get_obj<SkFont>(L, 1)->getTypefaceOrDefault();
Mike Reed91919132019-01-02 12:21:01 -0500971 SkLua(L).pushU32(SkTypeface::UniqueID(face));
972 return 1;
973}
974
975static int lfont_measureText(lua_State* L) {
976 if (lua_isstring(L, 2)) {
977 size_t len;
978 const char* text = lua_tolstring(L, 2, &len);
Ben Wagner51e15a62019-05-07 15:38:46 -0400979 SkLua(L).pushScalar(get_obj<SkFont>(L, 1)->measureText(text, len, SkTextEncoding::kUTF8));
Mike Reed91919132019-01-02 12:21:01 -0500980 return 1;
981 }
982 return 0;
983}
984
985static int lfont_getMetrics(lua_State* L) {
986 SkFontMetrics fm;
987 SkScalar height = get_obj<SkFont>(L, 1)->getMetrics(&fm);
988
989 lua_newtable(L);
990 setfield_scalar(L, "top", fm.fTop);
991 setfield_scalar(L, "ascent", fm.fAscent);
992 setfield_scalar(L, "descent", fm.fDescent);
993 setfield_scalar(L, "bottom", fm.fBottom);
994 setfield_scalar(L, "leading", fm.fLeading);
995 SkLua(L).pushScalar(height);
996 return 2;
997}
998
999static int lfont_gc(lua_State* L) {
1000 get_obj<SkFont>(L, 1)->~SkFont();
1001 return 0;
1002}
1003
1004static const struct luaL_Reg gSkFont_Methods[] = {
1005 { "getSize", lfont_getSize },
1006 { "setSize", lfont_setSize },
1007 { "getScaleX", lfont_getScaleX },
1008 { "getSkewX", lfont_getSkewX },
1009 { "getTypeface", lfont_getTypeface },
1010 { "setTypeface", lfont_setTypeface },
1011 { "getHinting", lfont_getHinting },
1012 { "getFontID", lfont_getFontID },
1013 { "measureText", lfont_measureText },
1014 { "getMetrics", lfont_getMetrics },
1015 { "__gc", lfont_gc },
1016 { nullptr, nullptr }
1017};
1018
1019///////////////////////////////////////////////////////////////////////////////
1020
Mike Reedfae8fce2019-04-03 10:27:45 -04001021static const char* mode2string(SkTileMode mode) {
1022 static const char* gNames[] = { "clamp", "repeat", "mirror", "decal" };
reed@google.com5fdc9832013-07-24 15:47:52 +00001023 SkASSERT((unsigned)mode < SK_ARRAY_COUNT(gNames));
Mike Reedfae8fce2019-04-03 10:27:45 -04001024 return gNames[static_cast<int>(mode)];
reed@google.com5fdc9832013-07-24 15:47:52 +00001025}
1026
1027static const char* gradtype2string(SkShader::GradientType t) {
1028 static const char* gNames[] = {
1029 "none", "color", "linear", "radial", "radial2", "sweep", "conical"
1030 };
1031 SkASSERT((unsigned)t < SK_ARRAY_COUNT(gNames));
1032 return gNames[t];
1033}
1034
1035static int lshader_isOpaque(lua_State* L) {
1036 SkShader* shader = get_ref<SkShader>(L, 1);
1037 return shader && shader->isOpaque();
1038}
1039
Mike Reed627778d2016-09-28 17:13:38 -04001040static int lshader_isAImage(lua_State* L) {
reed@google.com5fdc9832013-07-24 15:47:52 +00001041 SkShader* shader = get_ref<SkShader>(L, 1);
1042 if (shader) {
reed@google.com5fdc9832013-07-24 15:47:52 +00001043 SkMatrix matrix;
Mike Reedfae8fce2019-04-03 10:27:45 -04001044 SkTileMode modes[2];
Mike Reed627778d2016-09-28 17:13:38 -04001045 if (SkImage* image = shader->isAImage(&matrix, modes)) {
reedf5822822015-08-19 11:46:38 -07001046 lua_newtable(L);
Mike Reed627778d2016-09-28 17:13:38 -04001047 setfield_number(L, "id", image->uniqueID());
1048 setfield_number(L, "width", image->width());
1049 setfield_number(L, "height", image->height());
reedf5822822015-08-19 11:46:38 -07001050 setfield_string(L, "tileX", mode2string(modes[0]));
1051 setfield_string(L, "tileY", mode2string(modes[1]));
1052 return 1;
reed@google.com5fdc9832013-07-24 15:47:52 +00001053 }
1054 }
1055 return 0;
1056}
1057
1058static int lshader_asAGradient(lua_State* L) {
1059 SkShader* shader = get_ref<SkShader>(L, 1);
1060 if (shader) {
1061 SkShader::GradientInfo info;
1062 sk_bzero(&info, sizeof(info));
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001063
reed@google.com5fdc9832013-07-24 15:47:52 +00001064 SkShader::GradientType t = shader->asAGradient(&info);
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001065
reed@google.com5fdc9832013-07-24 15:47:52 +00001066 if (SkShader::kNone_GradientType != t) {
fmenozzib4f254e2016-06-28 14:03:03 -07001067 SkAutoTArray<SkScalar> pos(info.fColorCount);
1068 info.fColorOffsets = pos.get();
1069 shader->asAGradient(&info);
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001070
fmenozzib4f254e2016-06-28 14:03:03 -07001071 lua_newtable(L);
fmenozzi7f2c85e2016-07-12 09:17:39 -07001072 setfield_string(L, "type", gradtype2string(t));
Mike Reedfae8fce2019-04-03 10:27:45 -04001073 setfield_string(L, "tile", mode2string((SkTileMode)info.fTileMode));
fmenozzi7f2c85e2016-07-12 09:17:39 -07001074 setfield_number(L, "colorCount", info.fColorCount);
fmenozzib4f254e2016-06-28 14:03:03 -07001075
1076 lua_newtable(L);
1077 for (int i = 0; i < info.fColorCount; i++) {
1078 // Lua uses 1-based indexing
1079 setarray_scalar(L, i+1, pos[i]);
1080 }
1081 lua_setfield(L, -2, "positions");
1082
reed@google.com5fdc9832013-07-24 15:47:52 +00001083 return 1;
1084 }
1085 }
1086 return 0;
1087}
1088
1089static int lshader_gc(lua_State* L) {
1090 get_ref<SkShader>(L, 1)->unref();
1091 return 0;
1092}
1093
1094static const struct luaL_Reg gSkShader_Methods[] = {
1095 { "isOpaque", lshader_isOpaque },
Mike Reed627778d2016-09-28 17:13:38 -04001096 { "isAImage", lshader_isAImage },
reed@google.com5fdc9832013-07-24 15:47:52 +00001097 { "asAGradient", lshader_asAGradient },
1098 { "__gc", lshader_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001099 { nullptr, nullptr }
reed@google.com5fdc9832013-07-24 15:47:52 +00001100};
1101
1102///////////////////////////////////////////////////////////////////////////////
1103
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +00001104static int lpatheffect_asADash(lua_State* L) {
1105 SkPathEffect* pe = get_ref<SkPathEffect>(L, 1);
1106 if (pe) {
1107 SkPathEffect::DashInfo info;
1108 SkPathEffect::DashType dashType = pe->asADash(&info);
1109 if (SkPathEffect::kDash_DashType == dashType) {
1110 SkAutoTArray<SkScalar> intervals(info.fCount);
1111 info.fIntervals = intervals.get();
1112 pe->asADash(&info);
1113 SkLua(L).pushDash(info);
1114 return 1;
1115 }
1116 }
1117 return 0;
1118}
1119
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001120static int lpatheffect_gc(lua_State* L) {
1121 get_ref<SkPathEffect>(L, 1)->unref();
1122 return 0;
1123}
1124
1125static const struct luaL_Reg gSkPathEffect_Methods[] = {
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +00001126 { "asADash", lpatheffect_asADash },
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001127 { "__gc", lpatheffect_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001128 { nullptr, nullptr }
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001129};
1130
1131///////////////////////////////////////////////////////////////////////////////
1132
reed22a517f2015-12-04 20:45:59 -08001133static int lpcolorfilter_gc(lua_State* L) {
1134 get_ref<SkColorFilter>(L, 1)->unref();
1135 return 0;
1136}
1137
1138static const struct luaL_Reg gSkColorFilter_Methods[] = {
1139 { "__gc", lpcolorfilter_gc },
1140 { nullptr, nullptr }
1141};
1142
1143///////////////////////////////////////////////////////////////////////////////
1144
reed468b1812014-10-19 11:42:54 -07001145static int lpimagefilter_gc(lua_State* L) {
1146 get_ref<SkImageFilter>(L, 1)->unref();
1147 return 0;
1148}
1149
1150static const struct luaL_Reg gSkImageFilter_Methods[] = {
1151 { "__gc", lpimagefilter_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001152 { nullptr, nullptr }
reed468b1812014-10-19 11:42:54 -07001153};
1154
1155///////////////////////////////////////////////////////////////////////////////
1156
humper@google.com2815c192013-07-10 22:42:30 +00001157static int lmatrix_getType(lua_State* L) {
1158 SkMatrix::TypeMask mask = get_obj<SkMatrix>(L, 1)->getType();
skia.committer@gmail.comde2e4e82013-07-11 07:01:01 +00001159
humper@google.com2815c192013-07-10 22:42:30 +00001160 lua_newtable(L);
1161 setfield_boolean(L, "translate", SkToBool(mask & SkMatrix::kTranslate_Mask));
1162 setfield_boolean(L, "scale", SkToBool(mask & SkMatrix::kScale_Mask));
1163 setfield_boolean(L, "affine", SkToBool(mask & SkMatrix::kAffine_Mask));
1164 setfield_boolean(L, "perspective", SkToBool(mask & SkMatrix::kPerspective_Mask));
1165 return 1;
1166}
1167
humper@google.com0f48ee02013-07-26 15:23:43 +00001168static int lmatrix_getScaleX(lua_State* L) {
1169 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getScaleX());
1170 return 1;
1171}
1172
1173static int lmatrix_getScaleY(lua_State* L) {
1174 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getScaleY());
1175 return 1;
1176}
1177
1178static int lmatrix_getTranslateX(lua_State* L) {
1179 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getTranslateX());
1180 return 1;
1181}
1182
1183static int lmatrix_getTranslateY(lua_State* L) {
1184 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getTranslateY());
1185 return 1;
1186}
1187
reed7a72c672014-11-07 10:23:55 -08001188static int lmatrix_invert(lua_State* L) {
1189 lua_pushboolean(L, get_obj<SkMatrix>(L, 1)->invert(get_obj<SkMatrix>(L, 2)));
1190 return 1;
1191}
1192
1193static int lmatrix_mapXY(lua_State* L) {
1194 SkPoint pt = { lua2scalar(L, 2), lua2scalar(L, 3) };
1195 get_obj<SkMatrix>(L, 1)->mapPoints(&pt, &pt, 1);
1196 lua_pushnumber(L, pt.x());
1197 lua_pushnumber(L, pt.y());
1198 return 2;
1199}
1200
reedbdc49ae2014-10-14 09:34:52 -07001201static int lmatrix_setRectToRect(lua_State* L) {
1202 SkMatrix* matrix = get_obj<SkMatrix>(L, 1);
1203 SkRect srcR, dstR;
1204 lua2rect(L, 2, &srcR);
1205 lua2rect(L, 3, &dstR);
1206 const char* scaleToFitStr = lua_tostring(L, 4);
1207 SkMatrix::ScaleToFit scaleToFit = SkMatrix::kFill_ScaleToFit;
1208
1209 if (scaleToFitStr) {
1210 const struct {
1211 const char* fName;
1212 SkMatrix::ScaleToFit fScaleToFit;
1213 } rec[] = {
1214 { "fill", SkMatrix::kFill_ScaleToFit },
1215 { "start", SkMatrix::kStart_ScaleToFit },
1216 { "center", SkMatrix::kCenter_ScaleToFit },
1217 { "end", SkMatrix::kEnd_ScaleToFit },
1218 };
1219
1220 for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
1221 if (strcmp(rec[i].fName, scaleToFitStr) == 0) {
1222 scaleToFit = rec[i].fScaleToFit;
1223 break;
1224 }
1225 }
1226 }
1227
1228 matrix->setRectToRect(srcR, dstR, scaleToFit);
1229 return 0;
1230}
1231
humper@google.com2815c192013-07-10 22:42:30 +00001232static const struct luaL_Reg gSkMatrix_Methods[] = {
1233 { "getType", lmatrix_getType },
humper@google.com0f48ee02013-07-26 15:23:43 +00001234 { "getScaleX", lmatrix_getScaleX },
1235 { "getScaleY", lmatrix_getScaleY },
1236 { "getTranslateX", lmatrix_getTranslateX },
1237 { "getTranslateY", lmatrix_getTranslateY },
reedbdc49ae2014-10-14 09:34:52 -07001238 { "setRectToRect", lmatrix_setRectToRect },
reed7a72c672014-11-07 10:23:55 -08001239 { "invert", lmatrix_invert },
1240 { "mapXY", lmatrix_mapXY },
halcanary96fcdcc2015-08-27 07:41:13 -07001241 { nullptr, nullptr }
humper@google.com2815c192013-07-10 22:42:30 +00001242};
1243
1244///////////////////////////////////////////////////////////////////////////////
1245
reed@google.com74ce6f02013-05-22 15:13:18 +00001246static int lpath_getBounds(lua_State* L) {
1247 SkLua(L).pushRect(get_obj<SkPath>(L, 1)->getBounds());
1248 return 1;
1249}
1250
Mike Reed3a509812019-11-25 12:34:17 -05001251static const char* fill_type_to_str(SkPathFillType fill) {
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001252 switch (fill) {
Mike Reed3a509812019-11-25 12:34:17 -05001253 case SkPathFillType::kEvenOdd:
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001254 return "even-odd";
Mike Reed3a509812019-11-25 12:34:17 -05001255 case SkPathFillType::kWinding:
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001256 return "winding";
Mike Reed3a509812019-11-25 12:34:17 -05001257 case SkPathFillType::kInverseEvenOdd:
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001258 return "inverse-even-odd";
Mike Reed3a509812019-11-25 12:34:17 -05001259 case SkPathFillType::kInverseWinding:
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001260 return "inverse-winding";
1261 }
1262 return "unknown";
1263}
1264
1265static int lpath_getFillType(lua_State* L) {
Mike Reed3a509812019-11-25 12:34:17 -05001266 SkPathFillType fill = get_obj<SkPath>(L, 1)->getNewFillType();
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001267 SkLua(L).pushString(fill_type_to_str(fill));
1268 return 1;
1269}
1270
1271static SkString segment_masks_to_str(uint32_t segmentMasks) {
1272 SkString result;
1273 bool first = true;
1274 if (SkPath::kLine_SegmentMask & segmentMasks) {
1275 result.append("line");
1276 first = false;
1277 SkDEBUGCODE(segmentMasks &= ~SkPath::kLine_SegmentMask;)
1278 }
1279 if (SkPath::kQuad_SegmentMask & segmentMasks) {
1280 if (!first) {
1281 result.append(" ");
1282 }
1283 result.append("quad");
1284 first = false;
1285 SkDEBUGCODE(segmentMasks &= ~SkPath::kQuad_SegmentMask;)
1286 }
1287 if (SkPath::kConic_SegmentMask & segmentMasks) {
1288 if (!first) {
1289 result.append(" ");
1290 }
1291 result.append("conic");
1292 first = false;
1293 SkDEBUGCODE(segmentMasks &= ~SkPath::kConic_SegmentMask;)
1294 }
1295 if (SkPath::kCubic_SegmentMask & segmentMasks) {
1296 if (!first) {
1297 result.append(" ");
1298 }
1299 result.append("cubic");
1300 SkDEBUGCODE(segmentMasks &= ~SkPath::kCubic_SegmentMask;)
1301 }
1302 SkASSERT(0 == segmentMasks);
1303 return result;
1304}
1305
krajcevski95498ed2014-08-18 08:02:33 -07001306static int lpath_getSegmentTypes(lua_State* L) {
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001307 uint32_t segMasks = get_obj<SkPath>(L, 1)->getSegmentMasks();
1308 SkLua(L).pushString(segment_masks_to_str(segMasks));
1309 return 1;
1310}
1311
1312static int lpath_isConvex(lua_State* L) {
Mike Reed30bc5272019-11-22 18:34:02 +00001313 bool isConvex = get_obj<SkPath>(L, 1)->isConvex();
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001314 SkLua(L).pushBool(isConvex);
1315 return 1;
1316}
1317
reed@google.com74ce6f02013-05-22 15:13:18 +00001318static int lpath_isEmpty(lua_State* L) {
1319 lua_pushboolean(L, get_obj<SkPath>(L, 1)->isEmpty());
1320 return 1;
1321}
1322
1323static int lpath_isRect(lua_State* L) {
1324 SkRect r;
1325 bool pred = get_obj<SkPath>(L, 1)->isRect(&r);
1326 int ret_count = 1;
1327 lua_pushboolean(L, pred);
1328 if (pred) {
1329 SkLua(L).pushRect(r);
1330 ret_count += 1;
1331 }
1332 return ret_count;
1333}
1334
commit-bot@chromium.orgc5302082014-02-26 21:38:47 +00001335static int lpath_countPoints(lua_State* L) {
1336 lua_pushinteger(L, get_obj<SkPath>(L, 1)->countPoints());
1337 return 1;
1338}
1339
hstern0b401ce2016-08-02 09:17:59 -07001340static int lpath_getVerbs(lua_State* L) {
1341 const SkPath* path = get_obj<SkPath>(L, 1);
1342 SkPath::Iter iter(*path, false);
1343 SkPoint pts[4];
1344
1345 lua_newtable(L);
1346
1347 bool done = false;
1348 int i = 0;
1349 do {
Mike Reedba7e9a62019-08-16 13:30:34 -04001350 switch (iter.next(pts)) {
hstern0b401ce2016-08-02 09:17:59 -07001351 case SkPath::kMove_Verb:
1352 setarray_string(L, ++i, "move");
1353 break;
1354 case SkPath::kClose_Verb:
1355 setarray_string(L, ++i, "close");
1356 break;
1357 case SkPath::kLine_Verb:
1358 setarray_string(L, ++i, "line");
1359 break;
1360 case SkPath::kQuad_Verb:
1361 setarray_string(L, ++i, "quad");
1362 break;
1363 case SkPath::kConic_Verb:
1364 setarray_string(L, ++i, "conic");
1365 break;
1366 case SkPath::kCubic_Verb:
1367 setarray_string(L, ++i, "cubic");
1368 break;
1369 case SkPath::kDone_Verb:
1370 setarray_string(L, ++i, "done");
1371 done = true;
1372 break;
1373 }
1374 } while (!done);
1375
1376 return 1;
1377}
1378
reed@google.com74ce6f02013-05-22 15:13:18 +00001379static int lpath_reset(lua_State* L) {
1380 get_obj<SkPath>(L, 1)->reset();
1381 return 0;
1382}
1383
1384static int lpath_moveTo(lua_State* L) {
1385 get_obj<SkPath>(L, 1)->moveTo(lua2scalar(L, 2), lua2scalar(L, 3));
1386 return 0;
1387}
1388
1389static int lpath_lineTo(lua_State* L) {
1390 get_obj<SkPath>(L, 1)->lineTo(lua2scalar(L, 2), lua2scalar(L, 3));
1391 return 0;
1392}
1393
1394static int lpath_quadTo(lua_State* L) {
1395 get_obj<SkPath>(L, 1)->quadTo(lua2scalar(L, 2), lua2scalar(L, 3),
1396 lua2scalar(L, 4), lua2scalar(L, 5));
1397 return 0;
1398}
1399
1400static int lpath_cubicTo(lua_State* L) {
1401 get_obj<SkPath>(L, 1)->cubicTo(lua2scalar(L, 2), lua2scalar(L, 3),
1402 lua2scalar(L, 4), lua2scalar(L, 5),
1403 lua2scalar(L, 6), lua2scalar(L, 7));
1404 return 0;
1405}
1406
1407static int lpath_close(lua_State* L) {
1408 get_obj<SkPath>(L, 1)->close();
1409 return 0;
1410}
1411
1412static int lpath_gc(lua_State* L) {
1413 get_obj<SkPath>(L, 1)->~SkPath();
1414 return 0;
1415}
1416
1417static const struct luaL_Reg gSkPath_Methods[] = {
1418 { "getBounds", lpath_getBounds },
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001419 { "getFillType", lpath_getFillType },
krajcevski95498ed2014-08-18 08:02:33 -07001420 { "getSegmentTypes", lpath_getSegmentTypes },
hstern0b401ce2016-08-02 09:17:59 -07001421 { "getVerbs", lpath_getVerbs },
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001422 { "isConvex", lpath_isConvex },
reed@google.com74ce6f02013-05-22 15:13:18 +00001423 { "isEmpty", lpath_isEmpty },
1424 { "isRect", lpath_isRect },
commit-bot@chromium.orgc5302082014-02-26 21:38:47 +00001425 { "countPoints", lpath_countPoints },
reed@google.com74ce6f02013-05-22 15:13:18 +00001426 { "reset", lpath_reset },
1427 { "moveTo", lpath_moveTo },
1428 { "lineTo", lpath_lineTo },
1429 { "quadTo", lpath_quadTo },
1430 { "cubicTo", lpath_cubicTo },
1431 { "close", lpath_close },
1432 { "__gc", lpath_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001433 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001434};
1435
1436///////////////////////////////////////////////////////////////////////////////
1437
1438static const char* rrect_type(const SkRRect& rr) {
1439 switch (rr.getType()) {
reed@google.com74ce6f02013-05-22 15:13:18 +00001440 case SkRRect::kEmpty_Type: return "empty";
1441 case SkRRect::kRect_Type: return "rect";
1442 case SkRRect::kOval_Type: return "oval";
1443 case SkRRect::kSimple_Type: return "simple";
commit-bot@chromium.orgf338d7c2014-03-17 21:17:30 +00001444 case SkRRect::kNinePatch_Type: return "nine-patch";
reed@google.com74ce6f02013-05-22 15:13:18 +00001445 case SkRRect::kComplex_Type: return "complex";
1446 }
mtklein@google.com330313a2013-08-22 15:37:26 +00001447 SkDEBUGFAIL("never get here");
reed@google.com74ce6f02013-05-22 15:13:18 +00001448 return "";
1449}
1450
1451static int lrrect_rect(lua_State* L) {
1452 SkLua(L).pushRect(get_obj<SkRRect>(L, 1)->rect());
1453 return 1;
1454}
1455
1456static int lrrect_type(lua_State* L) {
1457 lua_pushstring(L, rrect_type(*get_obj<SkRRect>(L, 1)));
1458 return 1;
1459}
1460
1461static int lrrect_radii(lua_State* L) {
reed@google.com7fa2a652014-01-27 13:42:58 +00001462 int corner = SkToInt(lua_tointeger(L, 2));
reed@google.com74ce6f02013-05-22 15:13:18 +00001463 SkVector v;
1464 if (corner < 0 || corner > 3) {
1465 SkDebugf("bad corner index %d", corner);
1466 v.set(0, 0);
1467 } else {
1468 v = get_obj<SkRRect>(L, 1)->radii((SkRRect::Corner)corner);
1469 }
1470 lua_pushnumber(L, v.fX);
1471 lua_pushnumber(L, v.fY);
1472 return 2;
1473}
1474
1475static int lrrect_gc(lua_State* L) {
1476 get_obj<SkRRect>(L, 1)->~SkRRect();
1477 return 0;
1478}
1479
1480static const struct luaL_Reg gSkRRect_Methods[] = {
1481 { "rect", lrrect_rect },
1482 { "type", lrrect_type },
1483 { "radii", lrrect_radii },
1484 { "__gc", lrrect_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001485 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001486};
1487
1488///////////////////////////////////////////////////////////////////////////////
1489
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001490static int limage_width(lua_State* L) {
1491 lua_pushinteger(L, get_ref<SkImage>(L, 1)->width());
1492 return 1;
1493}
1494
1495static int limage_height(lua_State* L) {
1496 lua_pushinteger(L, get_ref<SkImage>(L, 1)->height());
1497 return 1;
1498}
1499
reed7a72c672014-11-07 10:23:55 -08001500static int limage_newShader(lua_State* L) {
Mike Reedfae8fce2019-04-03 10:27:45 -04001501 SkTileMode tmode = SkTileMode::kClamp;
halcanary96fcdcc2015-08-27 07:41:13 -07001502 const SkMatrix* localM = nullptr;
reed5671c5b2016-03-09 14:47:34 -08001503 push_ref(L, get_ref<SkImage>(L, 1)->makeShader(tmode, tmode, localM));
reed7a72c672014-11-07 10:23:55 -08001504 return 1;
1505}
1506
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001507static int limage_gc(lua_State* L) {
1508 get_ref<SkImage>(L, 1)->unref();
1509 return 0;
1510}
1511
1512static const struct luaL_Reg gSkImage_Methods[] = {
1513 { "width", limage_width },
1514 { "height", limage_height },
reed7a72c672014-11-07 10:23:55 -08001515 { "newShader", limage_newShader },
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001516 { "__gc", limage_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001517 { nullptr, nullptr }
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001518};
1519
1520///////////////////////////////////////////////////////////////////////////////
1521
reed485557f2014-10-12 10:36:47 -07001522static int lsurface_width(lua_State* L) {
1523 lua_pushinteger(L, get_ref<SkSurface>(L, 1)->width());
1524 return 1;
1525}
1526
1527static int lsurface_height(lua_State* L) {
1528 lua_pushinteger(L, get_ref<SkSurface>(L, 1)->height());
1529 return 1;
1530}
1531
1532static int lsurface_getCanvas(lua_State* L) {
1533 SkCanvas* canvas = get_ref<SkSurface>(L, 1)->getCanvas();
halcanary96fcdcc2015-08-27 07:41:13 -07001534 if (nullptr == canvas) {
reed485557f2014-10-12 10:36:47 -07001535 lua_pushnil(L);
1536 } else {
Mike Reed5df49342016-11-12 08:06:55 -06001537 push_ptr(L, canvas);
reed485557f2014-10-12 10:36:47 -07001538 // note: we don't unref canvas, since getCanvas did not ref it.
1539 // warning: this is weird: now Lua owns a ref on this canvas, but what if they let
1540 // the real owner (the surface) go away, but still hold onto the canvas?
1541 // *really* we want to sort of ref the surface again, but have the native object
1542 // know that it is supposed to be treated as a canvas...
1543 }
1544 return 1;
1545}
1546
1547static int lsurface_newImageSnapshot(lua_State* L) {
reed9ce9d672016-03-17 10:51:11 -07001548 sk_sp<SkImage> image = get_ref<SkSurface>(L, 1)->makeImageSnapshot();
1549 if (!image) {
reed485557f2014-10-12 10:36:47 -07001550 lua_pushnil(L);
1551 } else {
reed9ce9d672016-03-17 10:51:11 -07001552 push_ref(L, image);
reed485557f2014-10-12 10:36:47 -07001553 }
1554 return 1;
1555}
1556
1557static int lsurface_newSurface(lua_State* L) {
1558 int width = lua2int_def(L, 2, 0);
reed96affcd2014-10-13 12:38:04 -07001559 int height = lua2int_def(L, 3, 0);
reed485557f2014-10-12 10:36:47 -07001560 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
reede8f30622016-03-23 18:59:25 -07001561 auto surface = get_ref<SkSurface>(L, 1)->makeSurface(info);
halcanary96fcdcc2015-08-27 07:41:13 -07001562 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -07001563 lua_pushnil(L);
1564 } else {
reede8f30622016-03-23 18:59:25 -07001565 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -07001566 }
1567 return 1;
1568}
1569
1570static int lsurface_gc(lua_State* L) {
1571 get_ref<SkSurface>(L, 1)->unref();
1572 return 0;
1573}
1574
1575static const struct luaL_Reg gSkSurface_Methods[] = {
1576 { "width", lsurface_width },
1577 { "height", lsurface_height },
1578 { "getCanvas", lsurface_getCanvas },
1579 { "newImageSnapshot", lsurface_newImageSnapshot },
1580 { "newSurface", lsurface_newSurface },
1581 { "__gc", lsurface_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001582 { nullptr, nullptr }
reed485557f2014-10-12 10:36:47 -07001583};
1584
1585///////////////////////////////////////////////////////////////////////////////
1586
reed96affcd2014-10-13 12:38:04 -07001587static int lpicturerecorder_beginRecording(lua_State* L) {
1588 const SkScalar w = lua2scalar_def(L, 2, -1);
1589 const SkScalar h = lua2scalar_def(L, 3, -1);
1590 if (w <= 0 || h <= 0) {
1591 lua_pushnil(L);
1592 return 1;
1593 }
1594
1595 SkCanvas* canvas = get_obj<SkPictureRecorder>(L, 1)->beginRecording(w, h);
halcanary96fcdcc2015-08-27 07:41:13 -07001596 if (nullptr == canvas) {
reed96affcd2014-10-13 12:38:04 -07001597 lua_pushnil(L);
1598 return 1;
1599 }
1600
Mike Reed5df49342016-11-12 08:06:55 -06001601 push_ptr(L, canvas);
reed96affcd2014-10-13 12:38:04 -07001602 return 1;
1603}
1604
1605static int lpicturerecorder_getCanvas(lua_State* L) {
1606 SkCanvas* canvas = get_obj<SkPictureRecorder>(L, 1)->getRecordingCanvas();
halcanary96fcdcc2015-08-27 07:41:13 -07001607 if (nullptr == canvas) {
reed96affcd2014-10-13 12:38:04 -07001608 lua_pushnil(L);
1609 return 1;
1610 }
Mike Reed5df49342016-11-12 08:06:55 -06001611 push_ptr(L, canvas);
reed96affcd2014-10-13 12:38:04 -07001612 return 1;
1613}
1614
1615static int lpicturerecorder_endRecording(lua_State* L) {
reedca2622b2016-03-18 07:25:55 -07001616 sk_sp<SkPicture> pic = get_obj<SkPictureRecorder>(L, 1)->finishRecordingAsPicture();
1617 if (!pic) {
reed96affcd2014-10-13 12:38:04 -07001618 lua_pushnil(L);
1619 return 1;
1620 }
reedca2622b2016-03-18 07:25:55 -07001621 push_ref(L, std::move(pic));
reed96affcd2014-10-13 12:38:04 -07001622 return 1;
1623}
1624
1625static int lpicturerecorder_gc(lua_State* L) {
1626 get_obj<SkPictureRecorder>(L, 1)->~SkPictureRecorder();
1627 return 0;
1628}
1629
1630static const struct luaL_Reg gSkPictureRecorder_Methods[] = {
1631 { "beginRecording", lpicturerecorder_beginRecording },
1632 { "getCanvas", lpicturerecorder_getCanvas },
1633 { "endRecording", lpicturerecorder_endRecording },
1634 { "__gc", lpicturerecorder_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001635 { nullptr, nullptr }
reed96affcd2014-10-13 12:38:04 -07001636};
1637
1638///////////////////////////////////////////////////////////////////////////////
1639
1640static int lpicture_width(lua_State* L) {
1641 lua_pushnumber(L, get_ref<SkPicture>(L, 1)->cullRect().width());
1642 return 1;
1643}
1644
1645static int lpicture_height(lua_State* L) {
1646 lua_pushnumber(L, get_ref<SkPicture>(L, 1)->cullRect().height());
1647 return 1;
1648}
1649
1650static int lpicture_gc(lua_State* L) {
1651 get_ref<SkPicture>(L, 1)->unref();
1652 return 0;
1653}
1654
1655static const struct luaL_Reg gSkPicture_Methods[] = {
1656 { "width", lpicture_width },
1657 { "height", lpicture_height },
1658 { "__gc", lpicture_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001659 { nullptr, nullptr }
reed96affcd2014-10-13 12:38:04 -07001660};
1661
1662///////////////////////////////////////////////////////////////////////////////
1663
reed1b6ab442014-11-03 19:55:41 -08001664static int ltextblob_bounds(lua_State* L) {
1665 SkLua(L).pushRect(get_ref<SkTextBlob>(L, 1)->bounds());
1666 return 1;
1667}
1668
1669static int ltextblob_gc(lua_State* L) {
1670 SkSafeUnref(get_ref<SkTextBlob>(L, 1));
1671 return 0;
1672}
1673
1674static const struct luaL_Reg gSkTextBlob_Methods[] = {
1675 { "bounds", ltextblob_bounds },
1676 { "__gc", ltextblob_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001677 { nullptr, nullptr }
reed1b6ab442014-11-03 19:55:41 -08001678};
1679
1680///////////////////////////////////////////////////////////////////////////////
1681
reed36c9c112014-11-04 10:58:42 -08001682static int ltypeface_getFamilyName(lua_State* L) {
1683 SkString str;
1684 get_ref<SkTypeface>(L, 1)->getFamilyName(&str);
1685 lua_pushstring(L, str.c_str());
1686 return 1;
1687}
1688
1689static int ltypeface_getStyle(lua_State* L) {
Ben Wagner26308e12017-08-08 15:23:47 -04001690 push_obj(L, get_ref<SkTypeface>(L, 1)->fontStyle());
reed36c9c112014-11-04 10:58:42 -08001691 return 1;
1692}
1693
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001694static int ltypeface_gc(lua_State* L) {
commit-bot@chromium.org77887af2013-12-17 14:28:19 +00001695 SkSafeUnref(get_ref<SkTypeface>(L, 1));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001696 return 0;
1697}
1698
1699static const struct luaL_Reg gSkTypeface_Methods[] = {
reed36c9c112014-11-04 10:58:42 -08001700 { "getFamilyName", ltypeface_getFamilyName },
1701 { "getStyle", ltypeface_getStyle },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001702 { "__gc", ltypeface_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001703 { nullptr, nullptr }
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001704};
1705
1706///////////////////////////////////////////////////////////////////////////////
1707
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001708static int lfontstyle_weight(lua_State* L) {
1709 lua_pushnumber(L, get_ref<SkFontStyle>(L, 1)->weight());
1710 return 1;
1711}
1712
1713static int lfontstyle_width(lua_State* L) {
1714 lua_pushnumber(L, get_ref<SkFontStyle>(L, 1)->width());
1715 return 1;
1716}
1717
1718static int lfontstyle_slant(lua_State* L) {
1719 lua_pushnumber(L, get_ref<SkFontStyle>(L, 1)->slant());
1720 return 1;
1721}
1722
1723static int lfontstyle_gc(lua_State* L) {
1724 get_obj<SkFontStyle>(L, 1)->~SkFontStyle();
1725 return 0;
1726}
1727
1728static const struct luaL_Reg gSkFontStyle_Methods[] = {
1729 { "weight", lfontstyle_weight },
1730 { "width", lfontstyle_width },
1731 { "slant", lfontstyle_slant },
1732 { "__gc", lfontstyle_gc },
1733 { nullptr, nullptr }
1734};
1735
1736///////////////////////////////////////////////////////////////////////////////
1737
reed@google.com74ce6f02013-05-22 15:13:18 +00001738class AutoCallLua {
1739public:
1740 AutoCallLua(lua_State* L, const char func[], const char verb[]) : fL(L) {
1741 lua_getglobal(L, func);
1742 if (!lua_isfunction(L, -1)) {
1743 int t = lua_type(L, -1);
1744 SkDebugf("--- expected function %d\n", t);
1745 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001746
reed@google.com74ce6f02013-05-22 15:13:18 +00001747 lua_newtable(L);
1748 setfield_string(L, "verb", verb);
1749 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001750
reed@google.com74ce6f02013-05-22 15:13:18 +00001751 ~AutoCallLua() {
1752 if (lua_pcall(fL, 1, 0, 0) != LUA_OK) {
1753 SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
1754 }
1755 lua_settop(fL, -1);
1756 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001757
reed@google.com74ce6f02013-05-22 15:13:18 +00001758private:
1759 lua_State* fL;
1760};
1761
1762#define AUTO_LUA(verb) AutoCallLua acl(fL, fFunc.c_str(), verb)
1763
1764///////////////////////////////////////////////////////////////////////////////
1765
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001766static int lsk_newDocumentPDF(lua_State* L) {
Mike Reed7ff6ca52018-01-08 14:45:31 -05001767 const char* filename = nullptr;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001768 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
Mike Reed7ff6ca52018-01-08 14:45:31 -05001769 filename = lua_tolstring(L, 1, nullptr);
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001770 }
Mike Reed7ff6ca52018-01-08 14:45:31 -05001771 if (!filename) {
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001772 return 0;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001773 }
Mike Reed7ff6ca52018-01-08 14:45:31 -05001774 auto file = skstd::make_unique<SkFILEWStream>(filename);
1775 if (!file->isValid()) {
1776 return 0;
1777 }
Hal Canary3026d4b2019-01-07 10:00:48 -05001778 auto doc = SkPDF::MakeDocument(file.get());
Mike Reed7ff6ca52018-01-08 14:45:31 -05001779 if (!doc) {
1780 return 0;
1781 }
1782 push_ptr(L, new DocHolder{std::move(doc), std::move(file)});
1783 return 1;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001784}
1785
reed468b1812014-10-19 11:42:54 -07001786static int lsk_newBlurImageFilter(lua_State* L) {
1787 SkScalar sigmaX = lua2scalar_def(L, 1, 0);
1788 SkScalar sigmaY = lua2scalar_def(L, 2, 0);
Michael Ludwig06eacf42019-08-01 16:02:27 -04001789 sk_sp<SkImageFilter> imf(SkImageFilters::Blur(sigmaX, sigmaY, nullptr));
robertphillips6e7025a2016-04-04 04:31:25 -07001790 if (!imf) {
reed468b1812014-10-19 11:42:54 -07001791 lua_pushnil(L);
1792 } else {
robertphillips6e7025a2016-04-04 04:31:25 -07001793 push_ref(L, std::move(imf));
reed9fbc3f32014-10-21 07:12:58 -07001794 }
1795 return 1;
1796}
1797
1798static int lsk_newLinearGradient(lua_State* L) {
1799 SkScalar x0 = lua2scalar_def(L, 1, 0);
1800 SkScalar y0 = lua2scalar_def(L, 2, 0);
1801 SkColor c0 = lua2color(L, 3);
1802 SkScalar x1 = lua2scalar_def(L, 4, 0);
1803 SkScalar y1 = lua2scalar_def(L, 5, 0);
1804 SkColor c1 = lua2color(L, 6);
1805
1806 SkPoint pts[] = { { x0, y0 }, { x1, y1 } };
1807 SkColor colors[] = { c0, c1 };
Mike Reedfae8fce2019-04-03 10:27:45 -04001808 sk_sp<SkShader> s(SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp));
reed2ad1aa62016-03-09 09:50:50 -08001809 if (!s) {
reed9fbc3f32014-10-21 07:12:58 -07001810 lua_pushnil(L);
1811 } else {
reed2ad1aa62016-03-09 09:50:50 -08001812 push_ref(L, std::move(s));
reed468b1812014-10-19 11:42:54 -07001813 }
1814 return 1;
1815}
1816
reedbdc49ae2014-10-14 09:34:52 -07001817static int lsk_newMatrix(lua_State* L) {
1818 push_new<SkMatrix>(L)->reset();
1819 return 1;
1820}
1821
reed@google.com3597b732013-05-22 20:12:50 +00001822static int lsk_newPaint(lua_State* L) {
1823 push_new<SkPaint>(L);
1824 return 1;
1825}
1826
1827static int lsk_newPath(lua_State* L) {
1828 push_new<SkPath>(L);
1829 return 1;
1830}
1831
reed96affcd2014-10-13 12:38:04 -07001832static int lsk_newPictureRecorder(lua_State* L) {
1833 push_new<SkPictureRecorder>(L);
1834 return 1;
1835}
1836
reed@google.com3597b732013-05-22 20:12:50 +00001837static int lsk_newRRect(lua_State* L) {
reedbdc49ae2014-10-14 09:34:52 -07001838 push_new<SkRRect>(L)->setEmpty();
reed@google.com3597b732013-05-22 20:12:50 +00001839 return 1;
1840}
1841
reed1b6ab442014-11-03 19:55:41 -08001842// Sk.newTextBlob(text, rect, paint)
1843static int lsk_newTextBlob(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07001844 const char* text = lua_tolstring(L, 1, nullptr);
reed1b6ab442014-11-03 19:55:41 -08001845 SkRect bounds;
1846 lua2rect(L, 2, &bounds);
reed1b6ab442014-11-03 19:55:41 -08001847
Ben Wagnerb0591942019-02-15 14:46:18 -05001848 std::unique_ptr<SkShaper> shaper = SkShaper::Make();
reed1b6ab442014-11-03 19:55:41 -08001849
Mike Reed5f528e52019-01-28 10:57:28 -05001850 // TODO: restore this logic based on SkFont instead of SkPaint
1851#if 0
Mike Reede5f9cfa2019-01-10 13:55:35 -05001852 const SkPaint& paint = *get_obj<SkPaint>(L, 3);
Hal Canary2a1848d2018-11-26 17:23:24 -05001853 SkFont font = SkFont::LEGACY_ExtractFromPaint(paint);
Mike Reede5f9cfa2019-01-10 13:55:35 -05001854#else
1855 SkFont font;
1856#endif
Ben Wagner3bdb69c2019-04-01 19:01:09 -04001857 SkTextBlobBuilderRunHandler builder(text, { bounds.left(), bounds.top() });
1858 shaper->shape(text, strlen(text), font, true, bounds.width(), &builder);
Herb Derby1724db12018-05-22 12:01:50 -04001859
Florin Malita9867f612018-12-12 10:54:49 -05001860 push_ref<SkTextBlob>(L, builder.makeBlob());
Ben Wagner3bdb69c2019-04-01 19:01:09 -04001861 SkLua(L).pushScalar(builder.endPoint().fY);
reed1b6ab442014-11-03 19:55:41 -08001862 return 2;
1863}
1864
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001865static int lsk_newTypeface(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07001866 const char* name = nullptr;
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001867 SkFontStyle style;
skia.committer@gmail.com63193672013-06-08 07:01:13 +00001868
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001869 int count = lua_gettop(L);
1870 if (count > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001871 name = lua_tolstring(L, 1, nullptr);
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001872 if (count > 1) {
1873 SkFontStyle* passedStyle = get_obj<SkFontStyle>(L, 2);
1874 if (passedStyle) {
1875 style = *passedStyle;
1876 }
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001877 }
1878 }
1879
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001880 sk_sp<SkTypeface> face(SkTypeface::MakeFromName(name, style));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001881// SkDebugf("---- name <%s> style=%d, face=%p ref=%d\n", name, style, face, face->getRefCnt());
halcanary96fcdcc2015-08-27 07:41:13 -07001882 if (nullptr == face) {
bungeman13b9c952016-05-12 10:09:30 -07001883 face = SkTypeface::MakeDefault();
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001884 }
bungeman13b9c952016-05-12 10:09:30 -07001885 push_ref(L, std::move(face));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001886 return 1;
1887}
reed@google.com3597b732013-05-22 20:12:50 +00001888
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001889static int lsk_newFontStyle(lua_State* L) {
1890 int count = lua_gettop(L);
1891 int weight = SkFontStyle::kNormal_Weight;
1892 int width = SkFontStyle::kNormal_Width;
1893 SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant;
1894 if (count >= 1 && lua_isnumber(L, 1)) {
1895 weight = lua_tointegerx(L, 1, nullptr);
1896 }
1897 if (count >= 2 && lua_isnumber(L, 2)) {
1898 width = lua_tointegerx(L, 2, nullptr);
1899 }
1900 if (count >= 3 && lua_isnumber(L, 3)) {
1901 slant = static_cast<SkFontStyle::Slant>(lua_tointegerx(L, 3, nullptr));
1902 }
1903 push_new<SkFontStyle>(L, weight, width, slant);
1904 return 1;
1905}
1906
reed485557f2014-10-12 10:36:47 -07001907static int lsk_newRasterSurface(lua_State* L) {
reed7b864662014-11-04 13:24:47 -08001908 int width = lua2int_def(L, 1, 0);
reed485557f2014-10-12 10:36:47 -07001909 int height = lua2int_def(L, 2, 0);
1910 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
robertphillips702edbd2015-06-23 06:26:08 -07001911 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
reede8f30622016-03-23 18:59:25 -07001912 auto surface = SkSurface::MakeRaster(info, &props);
halcanary96fcdcc2015-08-27 07:41:13 -07001913 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -07001914 lua_pushnil(L);
1915 } else {
reede8f30622016-03-23 18:59:25 -07001916 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -07001917 }
1918 return 1;
1919}
1920
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001921static int lsk_loadImage(lua_State* L) {
1922 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001923 const char* name = lua_tolstring(L, 1, nullptr);
reed9ce9d672016-03-17 10:51:11 -07001924 sk_sp<SkData> data(SkData::MakeFromFileName(name));
1925 if (data) {
1926 auto image = SkImage::MakeFromEncoded(std::move(data));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001927 if (image) {
reed9ce9d672016-03-17 10:51:11 -07001928 push_ref(L, std::move(image));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001929 return 1;
1930 }
1931 }
1932 }
1933 return 0;
1934}
1935
reed@google.com3597b732013-05-22 20:12:50 +00001936static void register_Sk(lua_State* L) {
1937 lua_newtable(L);
1938 lua_pushvalue(L, -1);
1939 lua_setglobal(L, "Sk");
1940 // the Sk table is still on top
1941
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001942 setfield_function(L, "newDocumentPDF", lsk_newDocumentPDF);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001943 setfield_function(L, "loadImage", lsk_loadImage);
reed468b1812014-10-19 11:42:54 -07001944 setfield_function(L, "newBlurImageFilter", lsk_newBlurImageFilter);
reed9fbc3f32014-10-21 07:12:58 -07001945 setfield_function(L, "newLinearGradient", lsk_newLinearGradient);
reedbdc49ae2014-10-14 09:34:52 -07001946 setfield_function(L, "newMatrix", lsk_newMatrix);
reed@google.com3597b732013-05-22 20:12:50 +00001947 setfield_function(L, "newPaint", lsk_newPaint);
1948 setfield_function(L, "newPath", lsk_newPath);
reed96affcd2014-10-13 12:38:04 -07001949 setfield_function(L, "newPictureRecorder", lsk_newPictureRecorder);
reed@google.com3597b732013-05-22 20:12:50 +00001950 setfield_function(L, "newRRect", lsk_newRRect);
reed485557f2014-10-12 10:36:47 -07001951 setfield_function(L, "newRasterSurface", lsk_newRasterSurface);
reed1b6ab442014-11-03 19:55:41 -08001952 setfield_function(L, "newTextBlob", lsk_newTextBlob);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001953 setfield_function(L, "newTypeface", lsk_newTypeface);
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001954 setfield_function(L, "newFontStyle", lsk_newFontStyle);
reed@google.com3597b732013-05-22 20:12:50 +00001955 lua_pop(L, 1); // pop off the Sk table
1956}
1957
reed@google.com74ce6f02013-05-22 15:13:18 +00001958#define REG_CLASS(L, C) \
1959 do { \
reed@google.com3597b732013-05-22 20:12:50 +00001960 luaL_newmetatable(L, get_mtname<C>()); \
reed@google.com74ce6f02013-05-22 15:13:18 +00001961 lua_pushvalue(L, -1); \
1962 lua_setfield(L, -2, "__index"); \
1963 luaL_setfuncs(L, g##C##_Methods, 0); \
1964 lua_pop(L, 1); /* pop off the meta-table */ \
1965 } while (0)
1966
1967void SkLua::Load(lua_State* L) {
reed@google.com3597b732013-05-22 20:12:50 +00001968 register_Sk(L);
reed@google.com74ce6f02013-05-22 15:13:18 +00001969 REG_CLASS(L, SkCanvas);
reed22a517f2015-12-04 20:45:59 -08001970 REG_CLASS(L, SkColorFilter);
Mike Reed7ff6ca52018-01-08 14:45:31 -05001971 REG_CLASS(L, DocHolder);
Mike Reed91919132019-01-02 12:21:01 -05001972 REG_CLASS(L, SkFont);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001973 REG_CLASS(L, SkImage);
reed468b1812014-10-19 11:42:54 -07001974 REG_CLASS(L, SkImageFilter);
reed1b6ab442014-11-03 19:55:41 -08001975 REG_CLASS(L, SkMatrix);
reed@google.com74ce6f02013-05-22 15:13:18 +00001976 REG_CLASS(L, SkPaint);
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001977 REG_CLASS(L, SkPath);
1978 REG_CLASS(L, SkPathEffect);
reed96affcd2014-10-13 12:38:04 -07001979 REG_CLASS(L, SkPicture);
1980 REG_CLASS(L, SkPictureRecorder);
reed@google.com74ce6f02013-05-22 15:13:18 +00001981 REG_CLASS(L, SkRRect);
reed@google.com5fdc9832013-07-24 15:47:52 +00001982 REG_CLASS(L, SkShader);
reed485557f2014-10-12 10:36:47 -07001983 REG_CLASS(L, SkSurface);
reed1b6ab442014-11-03 19:55:41 -08001984 REG_CLASS(L, SkTextBlob);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001985 REG_CLASS(L, SkTypeface);
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001986 REG_CLASS(L, SkFontStyle);
reed@google.com74ce6f02013-05-22 15:13:18 +00001987}
zachr@google.com28c27c82013-06-20 17:15:05 +00001988
reed@google.com7bce9982013-06-20 17:40:21 +00001989extern "C" int luaopen_skia(lua_State* L);
zachr@google.com28c27c82013-06-20 17:15:05 +00001990extern "C" int luaopen_skia(lua_State* L) {
1991 SkLua::Load(L);
1992 return 0;
1993}