blob: a437fb2301ef1821e3a6f41313d3570ba2acea13 [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 Reede1af4442019-09-13 15:58:25 -04001251static const char* fill_type_to_str(SkPathFillType fill) {
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001252 switch (fill) {
Mike Reede1af4442019-09-13 15:58:25 -04001253 case SkPathFillType::kEvenOdd:
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001254 return "even-odd";
Mike Reede1af4442019-09-13 15:58:25 -04001255 case SkPathFillType::kWinding:
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001256 return "winding";
Mike Reede1af4442019-09-13 15:58:25 -04001257 case SkPathFillType::kInverseEvenOdd:
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001258 return "inverse-even-odd";
Mike Reede1af4442019-09-13 15:58:25 -04001259 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 Reede1af4442019-09-13 15:58:25 -04001266 SkPathFillType fill = (SkPathFillType)get_obj<SkPath>(L, 1)->getFillType();
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 Reede1af4442019-09-13 15:58:25 -04001313 bool isConvex = SkPathConvexityType::kConvex ==
1314 (SkPathConvexityType)get_obj<SkPath>(L, 1)->getConvexity();
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001315 SkLua(L).pushBool(isConvex);
1316 return 1;
1317}
1318
reed@google.com74ce6f02013-05-22 15:13:18 +00001319static int lpath_isEmpty(lua_State* L) {
1320 lua_pushboolean(L, get_obj<SkPath>(L, 1)->isEmpty());
1321 return 1;
1322}
1323
1324static int lpath_isRect(lua_State* L) {
1325 SkRect r;
1326 bool pred = get_obj<SkPath>(L, 1)->isRect(&r);
1327 int ret_count = 1;
1328 lua_pushboolean(L, pred);
1329 if (pred) {
1330 SkLua(L).pushRect(r);
1331 ret_count += 1;
1332 }
1333 return ret_count;
1334}
1335
commit-bot@chromium.orgc5302082014-02-26 21:38:47 +00001336static int lpath_countPoints(lua_State* L) {
1337 lua_pushinteger(L, get_obj<SkPath>(L, 1)->countPoints());
1338 return 1;
1339}
1340
hstern0b401ce2016-08-02 09:17:59 -07001341static int lpath_getVerbs(lua_State* L) {
1342 const SkPath* path = get_obj<SkPath>(L, 1);
1343 SkPath::Iter iter(*path, false);
1344 SkPoint pts[4];
1345
1346 lua_newtable(L);
1347
1348 bool done = false;
1349 int i = 0;
1350 do {
Mike Reedba7e9a62019-08-16 13:30:34 -04001351 switch (iter.next(pts)) {
hstern0b401ce2016-08-02 09:17:59 -07001352 case SkPath::kMove_Verb:
1353 setarray_string(L, ++i, "move");
1354 break;
1355 case SkPath::kClose_Verb:
1356 setarray_string(L, ++i, "close");
1357 break;
1358 case SkPath::kLine_Verb:
1359 setarray_string(L, ++i, "line");
1360 break;
1361 case SkPath::kQuad_Verb:
1362 setarray_string(L, ++i, "quad");
1363 break;
1364 case SkPath::kConic_Verb:
1365 setarray_string(L, ++i, "conic");
1366 break;
1367 case SkPath::kCubic_Verb:
1368 setarray_string(L, ++i, "cubic");
1369 break;
1370 case SkPath::kDone_Verb:
1371 setarray_string(L, ++i, "done");
1372 done = true;
1373 break;
1374 }
1375 } while (!done);
1376
1377 return 1;
1378}
1379
reed@google.com74ce6f02013-05-22 15:13:18 +00001380static int lpath_reset(lua_State* L) {
1381 get_obj<SkPath>(L, 1)->reset();
1382 return 0;
1383}
1384
1385static int lpath_moveTo(lua_State* L) {
1386 get_obj<SkPath>(L, 1)->moveTo(lua2scalar(L, 2), lua2scalar(L, 3));
1387 return 0;
1388}
1389
1390static int lpath_lineTo(lua_State* L) {
1391 get_obj<SkPath>(L, 1)->lineTo(lua2scalar(L, 2), lua2scalar(L, 3));
1392 return 0;
1393}
1394
1395static int lpath_quadTo(lua_State* L) {
1396 get_obj<SkPath>(L, 1)->quadTo(lua2scalar(L, 2), lua2scalar(L, 3),
1397 lua2scalar(L, 4), lua2scalar(L, 5));
1398 return 0;
1399}
1400
1401static int lpath_cubicTo(lua_State* L) {
1402 get_obj<SkPath>(L, 1)->cubicTo(lua2scalar(L, 2), lua2scalar(L, 3),
1403 lua2scalar(L, 4), lua2scalar(L, 5),
1404 lua2scalar(L, 6), lua2scalar(L, 7));
1405 return 0;
1406}
1407
1408static int lpath_close(lua_State* L) {
1409 get_obj<SkPath>(L, 1)->close();
1410 return 0;
1411}
1412
1413static int lpath_gc(lua_State* L) {
1414 get_obj<SkPath>(L, 1)->~SkPath();
1415 return 0;
1416}
1417
1418static const struct luaL_Reg gSkPath_Methods[] = {
1419 { "getBounds", lpath_getBounds },
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001420 { "getFillType", lpath_getFillType },
krajcevski95498ed2014-08-18 08:02:33 -07001421 { "getSegmentTypes", lpath_getSegmentTypes },
hstern0b401ce2016-08-02 09:17:59 -07001422 { "getVerbs", lpath_getVerbs },
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001423 { "isConvex", lpath_isConvex },
reed@google.com74ce6f02013-05-22 15:13:18 +00001424 { "isEmpty", lpath_isEmpty },
1425 { "isRect", lpath_isRect },
commit-bot@chromium.orgc5302082014-02-26 21:38:47 +00001426 { "countPoints", lpath_countPoints },
reed@google.com74ce6f02013-05-22 15:13:18 +00001427 { "reset", lpath_reset },
1428 { "moveTo", lpath_moveTo },
1429 { "lineTo", lpath_lineTo },
1430 { "quadTo", lpath_quadTo },
1431 { "cubicTo", lpath_cubicTo },
1432 { "close", lpath_close },
1433 { "__gc", lpath_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001434 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001435};
1436
1437///////////////////////////////////////////////////////////////////////////////
1438
1439static const char* rrect_type(const SkRRect& rr) {
1440 switch (rr.getType()) {
reed@google.com74ce6f02013-05-22 15:13:18 +00001441 case SkRRect::kEmpty_Type: return "empty";
1442 case SkRRect::kRect_Type: return "rect";
1443 case SkRRect::kOval_Type: return "oval";
1444 case SkRRect::kSimple_Type: return "simple";
commit-bot@chromium.orgf338d7c2014-03-17 21:17:30 +00001445 case SkRRect::kNinePatch_Type: return "nine-patch";
reed@google.com74ce6f02013-05-22 15:13:18 +00001446 case SkRRect::kComplex_Type: return "complex";
1447 }
mtklein@google.com330313a2013-08-22 15:37:26 +00001448 SkDEBUGFAIL("never get here");
reed@google.com74ce6f02013-05-22 15:13:18 +00001449 return "";
1450}
1451
1452static int lrrect_rect(lua_State* L) {
1453 SkLua(L).pushRect(get_obj<SkRRect>(L, 1)->rect());
1454 return 1;
1455}
1456
1457static int lrrect_type(lua_State* L) {
1458 lua_pushstring(L, rrect_type(*get_obj<SkRRect>(L, 1)));
1459 return 1;
1460}
1461
1462static int lrrect_radii(lua_State* L) {
reed@google.com7fa2a652014-01-27 13:42:58 +00001463 int corner = SkToInt(lua_tointeger(L, 2));
reed@google.com74ce6f02013-05-22 15:13:18 +00001464 SkVector v;
1465 if (corner < 0 || corner > 3) {
1466 SkDebugf("bad corner index %d", corner);
1467 v.set(0, 0);
1468 } else {
1469 v = get_obj<SkRRect>(L, 1)->radii((SkRRect::Corner)corner);
1470 }
1471 lua_pushnumber(L, v.fX);
1472 lua_pushnumber(L, v.fY);
1473 return 2;
1474}
1475
1476static int lrrect_gc(lua_State* L) {
1477 get_obj<SkRRect>(L, 1)->~SkRRect();
1478 return 0;
1479}
1480
1481static const struct luaL_Reg gSkRRect_Methods[] = {
1482 { "rect", lrrect_rect },
1483 { "type", lrrect_type },
1484 { "radii", lrrect_radii },
1485 { "__gc", lrrect_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001486 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001487};
1488
1489///////////////////////////////////////////////////////////////////////////////
1490
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001491static int limage_width(lua_State* L) {
1492 lua_pushinteger(L, get_ref<SkImage>(L, 1)->width());
1493 return 1;
1494}
1495
1496static int limage_height(lua_State* L) {
1497 lua_pushinteger(L, get_ref<SkImage>(L, 1)->height());
1498 return 1;
1499}
1500
reed7a72c672014-11-07 10:23:55 -08001501static int limage_newShader(lua_State* L) {
Mike Reedfae8fce2019-04-03 10:27:45 -04001502 SkTileMode tmode = SkTileMode::kClamp;
halcanary96fcdcc2015-08-27 07:41:13 -07001503 const SkMatrix* localM = nullptr;
reed5671c5b2016-03-09 14:47:34 -08001504 push_ref(L, get_ref<SkImage>(L, 1)->makeShader(tmode, tmode, localM));
reed7a72c672014-11-07 10:23:55 -08001505 return 1;
1506}
1507
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001508static int limage_gc(lua_State* L) {
1509 get_ref<SkImage>(L, 1)->unref();
1510 return 0;
1511}
1512
1513static const struct luaL_Reg gSkImage_Methods[] = {
1514 { "width", limage_width },
1515 { "height", limage_height },
reed7a72c672014-11-07 10:23:55 -08001516 { "newShader", limage_newShader },
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001517 { "__gc", limage_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001518 { nullptr, nullptr }
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001519};
1520
1521///////////////////////////////////////////////////////////////////////////////
1522
reed485557f2014-10-12 10:36:47 -07001523static int lsurface_width(lua_State* L) {
1524 lua_pushinteger(L, get_ref<SkSurface>(L, 1)->width());
1525 return 1;
1526}
1527
1528static int lsurface_height(lua_State* L) {
1529 lua_pushinteger(L, get_ref<SkSurface>(L, 1)->height());
1530 return 1;
1531}
1532
1533static int lsurface_getCanvas(lua_State* L) {
1534 SkCanvas* canvas = get_ref<SkSurface>(L, 1)->getCanvas();
halcanary96fcdcc2015-08-27 07:41:13 -07001535 if (nullptr == canvas) {
reed485557f2014-10-12 10:36:47 -07001536 lua_pushnil(L);
1537 } else {
Mike Reed5df49342016-11-12 08:06:55 -06001538 push_ptr(L, canvas);
reed485557f2014-10-12 10:36:47 -07001539 // note: we don't unref canvas, since getCanvas did not ref it.
1540 // warning: this is weird: now Lua owns a ref on this canvas, but what if they let
1541 // the real owner (the surface) go away, but still hold onto the canvas?
1542 // *really* we want to sort of ref the surface again, but have the native object
1543 // know that it is supposed to be treated as a canvas...
1544 }
1545 return 1;
1546}
1547
1548static int lsurface_newImageSnapshot(lua_State* L) {
reed9ce9d672016-03-17 10:51:11 -07001549 sk_sp<SkImage> image = get_ref<SkSurface>(L, 1)->makeImageSnapshot();
1550 if (!image) {
reed485557f2014-10-12 10:36:47 -07001551 lua_pushnil(L);
1552 } else {
reed9ce9d672016-03-17 10:51:11 -07001553 push_ref(L, image);
reed485557f2014-10-12 10:36:47 -07001554 }
1555 return 1;
1556}
1557
1558static int lsurface_newSurface(lua_State* L) {
1559 int width = lua2int_def(L, 2, 0);
reed96affcd2014-10-13 12:38:04 -07001560 int height = lua2int_def(L, 3, 0);
reed485557f2014-10-12 10:36:47 -07001561 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
reede8f30622016-03-23 18:59:25 -07001562 auto surface = get_ref<SkSurface>(L, 1)->makeSurface(info);
halcanary96fcdcc2015-08-27 07:41:13 -07001563 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -07001564 lua_pushnil(L);
1565 } else {
reede8f30622016-03-23 18:59:25 -07001566 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -07001567 }
1568 return 1;
1569}
1570
1571static int lsurface_gc(lua_State* L) {
1572 get_ref<SkSurface>(L, 1)->unref();
1573 return 0;
1574}
1575
1576static const struct luaL_Reg gSkSurface_Methods[] = {
1577 { "width", lsurface_width },
1578 { "height", lsurface_height },
1579 { "getCanvas", lsurface_getCanvas },
1580 { "newImageSnapshot", lsurface_newImageSnapshot },
1581 { "newSurface", lsurface_newSurface },
1582 { "__gc", lsurface_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001583 { nullptr, nullptr }
reed485557f2014-10-12 10:36:47 -07001584};
1585
1586///////////////////////////////////////////////////////////////////////////////
1587
reed96affcd2014-10-13 12:38:04 -07001588static int lpicturerecorder_beginRecording(lua_State* L) {
1589 const SkScalar w = lua2scalar_def(L, 2, -1);
1590 const SkScalar h = lua2scalar_def(L, 3, -1);
1591 if (w <= 0 || h <= 0) {
1592 lua_pushnil(L);
1593 return 1;
1594 }
1595
1596 SkCanvas* canvas = get_obj<SkPictureRecorder>(L, 1)->beginRecording(w, h);
halcanary96fcdcc2015-08-27 07:41:13 -07001597 if (nullptr == canvas) {
reed96affcd2014-10-13 12:38:04 -07001598 lua_pushnil(L);
1599 return 1;
1600 }
1601
Mike Reed5df49342016-11-12 08:06:55 -06001602 push_ptr(L, canvas);
reed96affcd2014-10-13 12:38:04 -07001603 return 1;
1604}
1605
1606static int lpicturerecorder_getCanvas(lua_State* L) {
1607 SkCanvas* canvas = get_obj<SkPictureRecorder>(L, 1)->getRecordingCanvas();
halcanary96fcdcc2015-08-27 07:41:13 -07001608 if (nullptr == canvas) {
reed96affcd2014-10-13 12:38:04 -07001609 lua_pushnil(L);
1610 return 1;
1611 }
Mike Reed5df49342016-11-12 08:06:55 -06001612 push_ptr(L, canvas);
reed96affcd2014-10-13 12:38:04 -07001613 return 1;
1614}
1615
1616static int lpicturerecorder_endRecording(lua_State* L) {
reedca2622b2016-03-18 07:25:55 -07001617 sk_sp<SkPicture> pic = get_obj<SkPictureRecorder>(L, 1)->finishRecordingAsPicture();
1618 if (!pic) {
reed96affcd2014-10-13 12:38:04 -07001619 lua_pushnil(L);
1620 return 1;
1621 }
reedca2622b2016-03-18 07:25:55 -07001622 push_ref(L, std::move(pic));
reed96affcd2014-10-13 12:38:04 -07001623 return 1;
1624}
1625
1626static int lpicturerecorder_gc(lua_State* L) {
1627 get_obj<SkPictureRecorder>(L, 1)->~SkPictureRecorder();
1628 return 0;
1629}
1630
1631static const struct luaL_Reg gSkPictureRecorder_Methods[] = {
1632 { "beginRecording", lpicturerecorder_beginRecording },
1633 { "getCanvas", lpicturerecorder_getCanvas },
1634 { "endRecording", lpicturerecorder_endRecording },
1635 { "__gc", lpicturerecorder_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001636 { nullptr, nullptr }
reed96affcd2014-10-13 12:38:04 -07001637};
1638
1639///////////////////////////////////////////////////////////////////////////////
1640
1641static int lpicture_width(lua_State* L) {
1642 lua_pushnumber(L, get_ref<SkPicture>(L, 1)->cullRect().width());
1643 return 1;
1644}
1645
1646static int lpicture_height(lua_State* L) {
1647 lua_pushnumber(L, get_ref<SkPicture>(L, 1)->cullRect().height());
1648 return 1;
1649}
1650
1651static int lpicture_gc(lua_State* L) {
1652 get_ref<SkPicture>(L, 1)->unref();
1653 return 0;
1654}
1655
1656static const struct luaL_Reg gSkPicture_Methods[] = {
1657 { "width", lpicture_width },
1658 { "height", lpicture_height },
1659 { "__gc", lpicture_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001660 { nullptr, nullptr }
reed96affcd2014-10-13 12:38:04 -07001661};
1662
1663///////////////////////////////////////////////////////////////////////////////
1664
reed1b6ab442014-11-03 19:55:41 -08001665static int ltextblob_bounds(lua_State* L) {
1666 SkLua(L).pushRect(get_ref<SkTextBlob>(L, 1)->bounds());
1667 return 1;
1668}
1669
1670static int ltextblob_gc(lua_State* L) {
1671 SkSafeUnref(get_ref<SkTextBlob>(L, 1));
1672 return 0;
1673}
1674
1675static const struct luaL_Reg gSkTextBlob_Methods[] = {
1676 { "bounds", ltextblob_bounds },
1677 { "__gc", ltextblob_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001678 { nullptr, nullptr }
reed1b6ab442014-11-03 19:55:41 -08001679};
1680
1681///////////////////////////////////////////////////////////////////////////////
1682
reed36c9c112014-11-04 10:58:42 -08001683static int ltypeface_getFamilyName(lua_State* L) {
1684 SkString str;
1685 get_ref<SkTypeface>(L, 1)->getFamilyName(&str);
1686 lua_pushstring(L, str.c_str());
1687 return 1;
1688}
1689
1690static int ltypeface_getStyle(lua_State* L) {
Ben Wagner26308e12017-08-08 15:23:47 -04001691 push_obj(L, get_ref<SkTypeface>(L, 1)->fontStyle());
reed36c9c112014-11-04 10:58:42 -08001692 return 1;
1693}
1694
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001695static int ltypeface_gc(lua_State* L) {
commit-bot@chromium.org77887af2013-12-17 14:28:19 +00001696 SkSafeUnref(get_ref<SkTypeface>(L, 1));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001697 return 0;
1698}
1699
1700static const struct luaL_Reg gSkTypeface_Methods[] = {
reed36c9c112014-11-04 10:58:42 -08001701 { "getFamilyName", ltypeface_getFamilyName },
1702 { "getStyle", ltypeface_getStyle },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001703 { "__gc", ltypeface_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001704 { nullptr, nullptr }
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001705};
1706
1707///////////////////////////////////////////////////////////////////////////////
1708
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001709static int lfontstyle_weight(lua_State* L) {
1710 lua_pushnumber(L, get_ref<SkFontStyle>(L, 1)->weight());
1711 return 1;
1712}
1713
1714static int lfontstyle_width(lua_State* L) {
1715 lua_pushnumber(L, get_ref<SkFontStyle>(L, 1)->width());
1716 return 1;
1717}
1718
1719static int lfontstyle_slant(lua_State* L) {
1720 lua_pushnumber(L, get_ref<SkFontStyle>(L, 1)->slant());
1721 return 1;
1722}
1723
1724static int lfontstyle_gc(lua_State* L) {
1725 get_obj<SkFontStyle>(L, 1)->~SkFontStyle();
1726 return 0;
1727}
1728
1729static const struct luaL_Reg gSkFontStyle_Methods[] = {
1730 { "weight", lfontstyle_weight },
1731 { "width", lfontstyle_width },
1732 { "slant", lfontstyle_slant },
1733 { "__gc", lfontstyle_gc },
1734 { nullptr, nullptr }
1735};
1736
1737///////////////////////////////////////////////////////////////////////////////
1738
reed@google.com74ce6f02013-05-22 15:13:18 +00001739class AutoCallLua {
1740public:
1741 AutoCallLua(lua_State* L, const char func[], const char verb[]) : fL(L) {
1742 lua_getglobal(L, func);
1743 if (!lua_isfunction(L, -1)) {
1744 int t = lua_type(L, -1);
1745 SkDebugf("--- expected function %d\n", t);
1746 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001747
reed@google.com74ce6f02013-05-22 15:13:18 +00001748 lua_newtable(L);
1749 setfield_string(L, "verb", verb);
1750 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001751
reed@google.com74ce6f02013-05-22 15:13:18 +00001752 ~AutoCallLua() {
1753 if (lua_pcall(fL, 1, 0, 0) != LUA_OK) {
1754 SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
1755 }
1756 lua_settop(fL, -1);
1757 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001758
reed@google.com74ce6f02013-05-22 15:13:18 +00001759private:
1760 lua_State* fL;
1761};
1762
1763#define AUTO_LUA(verb) AutoCallLua acl(fL, fFunc.c_str(), verb)
1764
1765///////////////////////////////////////////////////////////////////////////////
1766
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001767static int lsk_newDocumentPDF(lua_State* L) {
Mike Reed7ff6ca52018-01-08 14:45:31 -05001768 const char* filename = nullptr;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001769 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
Mike Reed7ff6ca52018-01-08 14:45:31 -05001770 filename = lua_tolstring(L, 1, nullptr);
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001771 }
Mike Reed7ff6ca52018-01-08 14:45:31 -05001772 if (!filename) {
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001773 return 0;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001774 }
Mike Reed7ff6ca52018-01-08 14:45:31 -05001775 auto file = skstd::make_unique<SkFILEWStream>(filename);
1776 if (!file->isValid()) {
1777 return 0;
1778 }
Hal Canary3026d4b2019-01-07 10:00:48 -05001779 auto doc = SkPDF::MakeDocument(file.get());
Mike Reed7ff6ca52018-01-08 14:45:31 -05001780 if (!doc) {
1781 return 0;
1782 }
1783 push_ptr(L, new DocHolder{std::move(doc), std::move(file)});
1784 return 1;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001785}
1786
reed468b1812014-10-19 11:42:54 -07001787static int lsk_newBlurImageFilter(lua_State* L) {
1788 SkScalar sigmaX = lua2scalar_def(L, 1, 0);
1789 SkScalar sigmaY = lua2scalar_def(L, 2, 0);
Michael Ludwig06eacf42019-08-01 16:02:27 -04001790 sk_sp<SkImageFilter> imf(SkImageFilters::Blur(sigmaX, sigmaY, nullptr));
robertphillips6e7025a2016-04-04 04:31:25 -07001791 if (!imf) {
reed468b1812014-10-19 11:42:54 -07001792 lua_pushnil(L);
1793 } else {
robertphillips6e7025a2016-04-04 04:31:25 -07001794 push_ref(L, std::move(imf));
reed9fbc3f32014-10-21 07:12:58 -07001795 }
1796 return 1;
1797}
1798
1799static int lsk_newLinearGradient(lua_State* L) {
1800 SkScalar x0 = lua2scalar_def(L, 1, 0);
1801 SkScalar y0 = lua2scalar_def(L, 2, 0);
1802 SkColor c0 = lua2color(L, 3);
1803 SkScalar x1 = lua2scalar_def(L, 4, 0);
1804 SkScalar y1 = lua2scalar_def(L, 5, 0);
1805 SkColor c1 = lua2color(L, 6);
1806
1807 SkPoint pts[] = { { x0, y0 }, { x1, y1 } };
1808 SkColor colors[] = { c0, c1 };
Mike Reedfae8fce2019-04-03 10:27:45 -04001809 sk_sp<SkShader> s(SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp));
reed2ad1aa62016-03-09 09:50:50 -08001810 if (!s) {
reed9fbc3f32014-10-21 07:12:58 -07001811 lua_pushnil(L);
1812 } else {
reed2ad1aa62016-03-09 09:50:50 -08001813 push_ref(L, std::move(s));
reed468b1812014-10-19 11:42:54 -07001814 }
1815 return 1;
1816}
1817
reedbdc49ae2014-10-14 09:34:52 -07001818static int lsk_newMatrix(lua_State* L) {
1819 push_new<SkMatrix>(L)->reset();
1820 return 1;
1821}
1822
reed@google.com3597b732013-05-22 20:12:50 +00001823static int lsk_newPaint(lua_State* L) {
1824 push_new<SkPaint>(L);
1825 return 1;
1826}
1827
1828static int lsk_newPath(lua_State* L) {
1829 push_new<SkPath>(L);
1830 return 1;
1831}
1832
reed96affcd2014-10-13 12:38:04 -07001833static int lsk_newPictureRecorder(lua_State* L) {
1834 push_new<SkPictureRecorder>(L);
1835 return 1;
1836}
1837
reed@google.com3597b732013-05-22 20:12:50 +00001838static int lsk_newRRect(lua_State* L) {
reedbdc49ae2014-10-14 09:34:52 -07001839 push_new<SkRRect>(L)->setEmpty();
reed@google.com3597b732013-05-22 20:12:50 +00001840 return 1;
1841}
1842
reed1b6ab442014-11-03 19:55:41 -08001843// Sk.newTextBlob(text, rect, paint)
1844static int lsk_newTextBlob(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07001845 const char* text = lua_tolstring(L, 1, nullptr);
reed1b6ab442014-11-03 19:55:41 -08001846 SkRect bounds;
1847 lua2rect(L, 2, &bounds);
reed1b6ab442014-11-03 19:55:41 -08001848
Ben Wagnerb0591942019-02-15 14:46:18 -05001849 std::unique_ptr<SkShaper> shaper = SkShaper::Make();
reed1b6ab442014-11-03 19:55:41 -08001850
Mike Reed5f528e52019-01-28 10:57:28 -05001851 // TODO: restore this logic based on SkFont instead of SkPaint
1852#if 0
Mike Reede5f9cfa2019-01-10 13:55:35 -05001853 const SkPaint& paint = *get_obj<SkPaint>(L, 3);
Hal Canary2a1848d2018-11-26 17:23:24 -05001854 SkFont font = SkFont::LEGACY_ExtractFromPaint(paint);
Mike Reede5f9cfa2019-01-10 13:55:35 -05001855#else
1856 SkFont font;
1857#endif
Ben Wagner3bdb69c2019-04-01 19:01:09 -04001858 SkTextBlobBuilderRunHandler builder(text, { bounds.left(), bounds.top() });
1859 shaper->shape(text, strlen(text), font, true, bounds.width(), &builder);
Herb Derby1724db12018-05-22 12:01:50 -04001860
Florin Malita9867f612018-12-12 10:54:49 -05001861 push_ref<SkTextBlob>(L, builder.makeBlob());
Ben Wagner3bdb69c2019-04-01 19:01:09 -04001862 SkLua(L).pushScalar(builder.endPoint().fY);
reed1b6ab442014-11-03 19:55:41 -08001863 return 2;
1864}
1865
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001866static int lsk_newTypeface(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07001867 const char* name = nullptr;
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001868 SkFontStyle style;
skia.committer@gmail.com63193672013-06-08 07:01:13 +00001869
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001870 int count = lua_gettop(L);
1871 if (count > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001872 name = lua_tolstring(L, 1, nullptr);
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001873 if (count > 1) {
1874 SkFontStyle* passedStyle = get_obj<SkFontStyle>(L, 2);
1875 if (passedStyle) {
1876 style = *passedStyle;
1877 }
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001878 }
1879 }
1880
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001881 sk_sp<SkTypeface> face(SkTypeface::MakeFromName(name, style));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001882// SkDebugf("---- name <%s> style=%d, face=%p ref=%d\n", name, style, face, face->getRefCnt());
halcanary96fcdcc2015-08-27 07:41:13 -07001883 if (nullptr == face) {
bungeman13b9c952016-05-12 10:09:30 -07001884 face = SkTypeface::MakeDefault();
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001885 }
bungeman13b9c952016-05-12 10:09:30 -07001886 push_ref(L, std::move(face));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001887 return 1;
1888}
reed@google.com3597b732013-05-22 20:12:50 +00001889
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001890static int lsk_newFontStyle(lua_State* L) {
1891 int count = lua_gettop(L);
1892 int weight = SkFontStyle::kNormal_Weight;
1893 int width = SkFontStyle::kNormal_Width;
1894 SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant;
1895 if (count >= 1 && lua_isnumber(L, 1)) {
1896 weight = lua_tointegerx(L, 1, nullptr);
1897 }
1898 if (count >= 2 && lua_isnumber(L, 2)) {
1899 width = lua_tointegerx(L, 2, nullptr);
1900 }
1901 if (count >= 3 && lua_isnumber(L, 3)) {
1902 slant = static_cast<SkFontStyle::Slant>(lua_tointegerx(L, 3, nullptr));
1903 }
1904 push_new<SkFontStyle>(L, weight, width, slant);
1905 return 1;
1906}
1907
reed485557f2014-10-12 10:36:47 -07001908static int lsk_newRasterSurface(lua_State* L) {
reed7b864662014-11-04 13:24:47 -08001909 int width = lua2int_def(L, 1, 0);
reed485557f2014-10-12 10:36:47 -07001910 int height = lua2int_def(L, 2, 0);
1911 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
robertphillips702edbd2015-06-23 06:26:08 -07001912 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
reede8f30622016-03-23 18:59:25 -07001913 auto surface = SkSurface::MakeRaster(info, &props);
halcanary96fcdcc2015-08-27 07:41:13 -07001914 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -07001915 lua_pushnil(L);
1916 } else {
reede8f30622016-03-23 18:59:25 -07001917 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -07001918 }
1919 return 1;
1920}
1921
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001922static int lsk_loadImage(lua_State* L) {
1923 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001924 const char* name = lua_tolstring(L, 1, nullptr);
reed9ce9d672016-03-17 10:51:11 -07001925 sk_sp<SkData> data(SkData::MakeFromFileName(name));
1926 if (data) {
1927 auto image = SkImage::MakeFromEncoded(std::move(data));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001928 if (image) {
reed9ce9d672016-03-17 10:51:11 -07001929 push_ref(L, std::move(image));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001930 return 1;
1931 }
1932 }
1933 }
1934 return 0;
1935}
1936
reed@google.com3597b732013-05-22 20:12:50 +00001937static void register_Sk(lua_State* L) {
1938 lua_newtable(L);
1939 lua_pushvalue(L, -1);
1940 lua_setglobal(L, "Sk");
1941 // the Sk table is still on top
1942
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001943 setfield_function(L, "newDocumentPDF", lsk_newDocumentPDF);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001944 setfield_function(L, "loadImage", lsk_loadImage);
reed468b1812014-10-19 11:42:54 -07001945 setfield_function(L, "newBlurImageFilter", lsk_newBlurImageFilter);
reed9fbc3f32014-10-21 07:12:58 -07001946 setfield_function(L, "newLinearGradient", lsk_newLinearGradient);
reedbdc49ae2014-10-14 09:34:52 -07001947 setfield_function(L, "newMatrix", lsk_newMatrix);
reed@google.com3597b732013-05-22 20:12:50 +00001948 setfield_function(L, "newPaint", lsk_newPaint);
1949 setfield_function(L, "newPath", lsk_newPath);
reed96affcd2014-10-13 12:38:04 -07001950 setfield_function(L, "newPictureRecorder", lsk_newPictureRecorder);
reed@google.com3597b732013-05-22 20:12:50 +00001951 setfield_function(L, "newRRect", lsk_newRRect);
reed485557f2014-10-12 10:36:47 -07001952 setfield_function(L, "newRasterSurface", lsk_newRasterSurface);
reed1b6ab442014-11-03 19:55:41 -08001953 setfield_function(L, "newTextBlob", lsk_newTextBlob);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001954 setfield_function(L, "newTypeface", lsk_newTypeface);
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001955 setfield_function(L, "newFontStyle", lsk_newFontStyle);
reed@google.com3597b732013-05-22 20:12:50 +00001956 lua_pop(L, 1); // pop off the Sk table
1957}
1958
reed@google.com74ce6f02013-05-22 15:13:18 +00001959#define REG_CLASS(L, C) \
1960 do { \
reed@google.com3597b732013-05-22 20:12:50 +00001961 luaL_newmetatable(L, get_mtname<C>()); \
reed@google.com74ce6f02013-05-22 15:13:18 +00001962 lua_pushvalue(L, -1); \
1963 lua_setfield(L, -2, "__index"); \
1964 luaL_setfuncs(L, g##C##_Methods, 0); \
1965 lua_pop(L, 1); /* pop off the meta-table */ \
1966 } while (0)
1967
1968void SkLua::Load(lua_State* L) {
reed@google.com3597b732013-05-22 20:12:50 +00001969 register_Sk(L);
reed@google.com74ce6f02013-05-22 15:13:18 +00001970 REG_CLASS(L, SkCanvas);
reed22a517f2015-12-04 20:45:59 -08001971 REG_CLASS(L, SkColorFilter);
Mike Reed7ff6ca52018-01-08 14:45:31 -05001972 REG_CLASS(L, DocHolder);
Mike Reed91919132019-01-02 12:21:01 -05001973 REG_CLASS(L, SkFont);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001974 REG_CLASS(L, SkImage);
reed468b1812014-10-19 11:42:54 -07001975 REG_CLASS(L, SkImageFilter);
reed1b6ab442014-11-03 19:55:41 -08001976 REG_CLASS(L, SkMatrix);
reed@google.com74ce6f02013-05-22 15:13:18 +00001977 REG_CLASS(L, SkPaint);
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001978 REG_CLASS(L, SkPath);
1979 REG_CLASS(L, SkPathEffect);
reed96affcd2014-10-13 12:38:04 -07001980 REG_CLASS(L, SkPicture);
1981 REG_CLASS(L, SkPictureRecorder);
reed@google.com74ce6f02013-05-22 15:13:18 +00001982 REG_CLASS(L, SkRRect);
reed@google.com5fdc9832013-07-24 15:47:52 +00001983 REG_CLASS(L, SkShader);
reed485557f2014-10-12 10:36:47 -07001984 REG_CLASS(L, SkSurface);
reed1b6ab442014-11-03 19:55:41 -08001985 REG_CLASS(L, SkTextBlob);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001986 REG_CLASS(L, SkTypeface);
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001987 REG_CLASS(L, SkFontStyle);
reed@google.com74ce6f02013-05-22 15:13:18 +00001988}
zachr@google.com28c27c82013-06-20 17:15:05 +00001989
reed@google.com7bce9982013-06-20 17:40:21 +00001990extern "C" int luaopen_skia(lua_State* L);
zachr@google.com28c27c82013-06-20 17:15:05 +00001991extern "C" int luaopen_skia(lua_State* L) {
1992 SkLua::Load(L);
1993 return 0;
1994}