blob: bba28f9c9539d3ba4edbc65ed250e606a101e052 [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"
Mike Klein79aea6a2018-06-11 10:45:26 -040035#include <new>
reed@google.com74ce6f02013-05-22 15:13:18 +000036
37extern "C" {
reed@google.com3597b732013-05-22 20:12:50 +000038 #include "lua.h"
39 #include "lualib.h"
40 #include "lauxlib.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000041}
42
Mike Reed7ff6ca52018-01-08 14:45:31 -050043struct DocHolder {
44 sk_sp<SkDocument> fDoc;
45 std::unique_ptr<SkWStream> fStream;
46};
47
reed@google.comfd345872013-05-22 20:53:42 +000048// return the metatable name for a given class
reed@google.com3597b732013-05-22 20:12:50 +000049template <typename T> const char* get_mtname();
reed@google.comfd345872013-05-22 20:53:42 +000050#define DEF_MTNAME(T) \
51 template <> const char* get_mtname<T>() { \
52 return #T "_LuaMetaTableName"; \
53 }
54
55DEF_MTNAME(SkCanvas)
reed22a517f2015-12-04 20:45:59 -080056DEF_MTNAME(SkColorFilter)
Mike Reed7ff6ca52018-01-08 14:45:31 -050057DEF_MTNAME(DocHolder)
Mike Reed91919132019-01-02 12:21:01 -050058DEF_MTNAME(SkFont)
mike@reedtribe.org792bbd12013-06-11 02:20:28 +000059DEF_MTNAME(SkImage)
reed468b1812014-10-19 11:42:54 -070060DEF_MTNAME(SkImageFilter)
reed@google.comfd345872013-05-22 20:53:42 +000061DEF_MTNAME(SkMatrix)
62DEF_MTNAME(SkRRect)
63DEF_MTNAME(SkPath)
64DEF_MTNAME(SkPaint)
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +000065DEF_MTNAME(SkPathEffect)
reed96affcd2014-10-13 12:38:04 -070066DEF_MTNAME(SkPicture)
67DEF_MTNAME(SkPictureRecorder)
reed@google.com5fdc9832013-07-24 15:47:52 +000068DEF_MTNAME(SkShader)
reed485557f2014-10-12 10:36:47 -070069DEF_MTNAME(SkSurface)
fmalitab7425172014-08-26 07:56:44 -070070DEF_MTNAME(SkTextBlob)
mike@reedtribe.orge6469f12013-06-08 03:15:47 +000071DEF_MTNAME(SkTypeface)
Ben Wagnerc6c10b42017-08-07 09:56:21 -040072DEF_MTNAME(SkFontStyle)
reed@google.com74ce6f02013-05-22 15:13:18 +000073
Ben Wagnerc6c10b42017-08-07 09:56:21 -040074template <typename T, typename... Args> T* push_new(lua_State* L, Args&&... args) {
reed@google.com3597b732013-05-22 20:12:50 +000075 T* addr = (T*)lua_newuserdata(L, sizeof(T));
Ben Wagnerc6c10b42017-08-07 09:56:21 -040076 new (addr) T(std::forward<Args>(args)...);
reed@google.com3597b732013-05-22 20:12:50 +000077 luaL_getmetatable(L, get_mtname<T>());
78 lua_setmetatable(L, -2);
79 return addr;
80}
reed@google.com74ce6f02013-05-22 15:13:18 +000081
82template <typename T> void push_obj(lua_State* L, const T& obj) {
83 new (lua_newuserdata(L, sizeof(T))) T(obj);
reed@google.com3597b732013-05-22 20:12:50 +000084 luaL_getmetatable(L, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +000085 lua_setmetatable(L, -2);
86}
87
Mike Reed5df49342016-11-12 08:06:55 -060088template <typename T> T* push_ptr(lua_State* L, T* ptr) {
89 *(T**)lua_newuserdata(L, sizeof(T*)) = ptr;
90 luaL_getmetatable(L, get_mtname<T>());
91 lua_setmetatable(L, -2);
92 return ptr;
93}
94
reed9fbc3f32014-10-21 07:12:58 -070095template <typename T> T* push_ref(lua_State* L, T* ref) {
commit-bot@chromium.org77887af2013-12-17 14:28:19 +000096 *(T**)lua_newuserdata(L, sizeof(T*)) = SkSafeRef(ref);
reed@google.com3597b732013-05-22 20:12:50 +000097 luaL_getmetatable(L, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +000098 lua_setmetatable(L, -2);
reed9fbc3f32014-10-21 07:12:58 -070099 return ref;
reed@google.com74ce6f02013-05-22 15:13:18 +0000100}
101
reed2ad1aa62016-03-09 09:50:50 -0800102template <typename T> void push_ref(lua_State* L, sk_sp<T> sp) {
103 *(T**)lua_newuserdata(L, sizeof(T*)) = sp.release();
104 luaL_getmetatable(L, get_mtname<T>());
105 lua_setmetatable(L, -2);
106}
107
reed@google.com74ce6f02013-05-22 15:13:18 +0000108template <typename T> T* get_ref(lua_State* L, int index) {
reed@google.com3597b732013-05-22 20:12:50 +0000109 return *(T**)luaL_checkudata(L, index, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +0000110}
111
112template <typename T> T* get_obj(lua_State* L, int index) {
reed@google.com3597b732013-05-22 20:12:50 +0000113 return (T*)luaL_checkudata(L, index, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +0000114}
115
reed@google.com88c9ec92013-05-22 15:43:21 +0000116static bool lua2bool(lua_State* L, int index) {
117 return !!lua_toboolean(L, index);
118}
119
reed@google.com74ce6f02013-05-22 15:13:18 +0000120///////////////////////////////////////////////////////////////////////////////
121
reed@google.com3597b732013-05-22 20:12:50 +0000122SkLua::SkLua(const char termCode[]) : fTermCode(termCode), fWeOwnL(true) {
123 fL = luaL_newstate();
124 luaL_openlibs(fL);
125 SkLua::Load(fL);
126}
127
128SkLua::SkLua(lua_State* L) : fL(L), fWeOwnL(false) {}
129
130SkLua::~SkLua() {
131 if (fWeOwnL) {
132 if (fTermCode.size() > 0) {
133 lua_getglobal(fL, fTermCode.c_str());
134 if (lua_pcall(fL, 0, 0, 0) != LUA_OK) {
135 SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
136 }
137 }
138 lua_close(fL);
139 }
140}
141
142bool SkLua::runCode(const char code[]) {
143 int err = luaL_loadstring(fL, code) || lua_pcall(fL, 0, 0, 0);
144 if (err) {
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000145 SkDebugf("--- lua failed: %s\n", lua_tostring(fL, -1));
reed@google.com3597b732013-05-22 20:12:50 +0000146 return false;
147 }
148 return true;
149}
150
151bool SkLua::runCode(const void* code, size_t size) {
152 SkString str((const char*)code, size);
153 return this->runCode(str.c_str());
154}
155
156///////////////////////////////////////////////////////////////////////////////
157
158#define CHECK_SETFIELD(key) do if (key) lua_setfield(fL, -2, key); while (0)
159
reed@google.com29563872013-07-10 21:23:49 +0000160static void setfield_bool_if(lua_State* L, const char key[], bool pred) {
161 if (pred) {
162 lua_pushboolean(L, true);
163 lua_setfield(L, -2, key);
164 }
165}
166
reed@google.com74ce6f02013-05-22 15:13:18 +0000167static void setfield_string(lua_State* L, const char key[], const char value[]) {
168 lua_pushstring(L, value);
169 lua_setfield(L, -2, key);
170}
171
172static void setfield_number(lua_State* L, const char key[], double value) {
173 lua_pushnumber(L, value);
174 lua_setfield(L, -2, key);
175}
176
humper@google.com2815c192013-07-10 22:42:30 +0000177static void setfield_boolean(lua_State* L, const char key[], bool value) {
178 lua_pushboolean(L, value);
179 lua_setfield(L, -2, key);
180}
181
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000182static void setfield_scalar(lua_State* L, const char key[], SkScalar value) {
183 setfield_number(L, key, SkScalarToLua(value));
184}
185
reed@google.com3597b732013-05-22 20:12:50 +0000186static void setfield_function(lua_State* L,
187 const char key[], lua_CFunction value) {
188 lua_pushcfunction(L, value);
189 lua_setfield(L, -2, key);
reed@google.com74ce6f02013-05-22 15:13:18 +0000190}
191
reed7a72c672014-11-07 10:23:55 -0800192static int lua2int_def(lua_State* L, int index, int defaultValue) {
193 if (lua_isnumber(L, index)) {
194 return (int)lua_tonumber(L, index);
195 } else {
196 return defaultValue;
197 }
198}
199
200static SkScalar lua2scalar(lua_State* L, int index) {
201 SkASSERT(lua_isnumber(L, index));
202 return SkLuaToScalar(lua_tonumber(L, index));
203}
204
205static SkScalar lua2scalar_def(lua_State* L, int index, SkScalar defaultValue) {
206 if (lua_isnumber(L, index)) {
207 return SkLuaToScalar(lua_tonumber(L, index));
208 } else {
209 return defaultValue;
210 }
211}
212
213static SkScalar getarray_scalar(lua_State* L, int stackIndex, int arrayIndex) {
214 SkASSERT(lua_istable(L, stackIndex));
215 lua_rawgeti(L, stackIndex, arrayIndex);
mtklein8aacf202014-12-18 13:29:54 -0800216
reed7a72c672014-11-07 10:23:55 -0800217 SkScalar value = lua2scalar(L, -1);
218 lua_pop(L, 1);
219 return value;
220}
221
222static void getarray_scalars(lua_State* L, int stackIndex, SkScalar dst[], int count) {
223 for (int i = 0; i < count; ++i) {
224 dst[i] = getarray_scalar(L, stackIndex, i + 1);
225 }
226}
227
228static void getarray_points(lua_State* L, int stackIndex, SkPoint pts[], int count) {
229 getarray_scalars(L, stackIndex, &pts[0].fX, count * 2);
230}
231
reed@google.come3823fd2013-05-30 18:55:14 +0000232static void setarray_number(lua_State* L, int index, double value) {
233 lua_pushnumber(L, value);
234 lua_rawseti(L, -2, index);
235}
236
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +0000237static void setarray_scalar(lua_State* L, int index, SkScalar value) {
238 setarray_number(L, index, SkScalarToLua(value));
239}
240
hstern0b401ce2016-08-02 09:17:59 -0700241static void setarray_string(lua_State* L, int index, const char str[]) {
242 lua_pushstring(L, str);
243 lua_rawseti(L, -2, index);
244}
245
reed@google.com74ce6f02013-05-22 15:13:18 +0000246void SkLua::pushBool(bool value, const char key[]) {
247 lua_pushboolean(fL, value);
248 CHECK_SETFIELD(key);
249}
250
251void SkLua::pushString(const char str[], const char key[]) {
252 lua_pushstring(fL, str);
253 CHECK_SETFIELD(key);
254}
255
reed@google.come3823fd2013-05-30 18:55:14 +0000256void SkLua::pushString(const char str[], size_t length, const char key[]) {
257 // TODO: how to do this w/o making a copy?
258 SkString s(str, length);
259 lua_pushstring(fL, s.c_str());
260 CHECK_SETFIELD(key);
261}
262
reed@google.com74ce6f02013-05-22 15:13:18 +0000263void SkLua::pushString(const SkString& str, const char key[]) {
264 lua_pushstring(fL, str.c_str());
265 CHECK_SETFIELD(key);
266}
267
268void SkLua::pushColor(SkColor color, const char key[]) {
269 lua_newtable(fL);
270 setfield_number(fL, "a", SkColorGetA(color) / 255.0);
271 setfield_number(fL, "r", SkColorGetR(color) / 255.0);
272 setfield_number(fL, "g", SkColorGetG(color) / 255.0);
273 setfield_number(fL, "b", SkColorGetB(color) / 255.0);
274 CHECK_SETFIELD(key);
275}
276
reed@google.come3823fd2013-05-30 18:55:14 +0000277void SkLua::pushU32(uint32_t value, const char key[]) {
278 lua_pushnumber(fL, (double)value);
279 CHECK_SETFIELD(key);
280}
281
reed@google.com74ce6f02013-05-22 15:13:18 +0000282void SkLua::pushScalar(SkScalar value, const char key[]) {
283 lua_pushnumber(fL, SkScalarToLua(value));
284 CHECK_SETFIELD(key);
285}
286
reed@google.come3823fd2013-05-30 18:55:14 +0000287void SkLua::pushArrayU16(const uint16_t array[], int count, const char key[]) {
288 lua_newtable(fL);
289 for (int i = 0; i < count; ++i) {
290 // make it base-1 to match lua convention
291 setarray_number(fL, i + 1, (double)array[i]);
292 }
293 CHECK_SETFIELD(key);
294}
295
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +0000296void SkLua::pushArrayPoint(const SkPoint array[], int count, const char key[]) {
297 lua_newtable(fL);
298 for (int i = 0; i < count; ++i) {
299 // make it base-1 to match lua convention
300 lua_newtable(fL);
301 this->pushScalar(array[i].fX, "x");
302 this->pushScalar(array[i].fY, "y");
303 lua_rawseti(fL, -2, i + 1);
304 }
305 CHECK_SETFIELD(key);
306}
307
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +0000308void SkLua::pushArrayScalar(const SkScalar array[], int count, const char key[]) {
309 lua_newtable(fL);
310 for (int i = 0; i < count; ++i) {
311 // make it base-1 to match lua convention
312 setarray_scalar(fL, i + 1, array[i]);
313 }
314 CHECK_SETFIELD(key);
315}
316
reed@google.com74ce6f02013-05-22 15:13:18 +0000317void SkLua::pushRect(const SkRect& r, const char key[]) {
318 lua_newtable(fL);
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000319 setfield_scalar(fL, "left", r.fLeft);
320 setfield_scalar(fL, "top", r.fTop);
321 setfield_scalar(fL, "right", r.fRight);
322 setfield_scalar(fL, "bottom", r.fBottom);
reed@google.com74ce6f02013-05-22 15:13:18 +0000323 CHECK_SETFIELD(key);
324}
325
326void SkLua::pushRRect(const SkRRect& rr, const char key[]) {
327 push_obj(fL, rr);
328 CHECK_SETFIELD(key);
329}
330
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +0000331void SkLua::pushDash(const SkPathEffect::DashInfo& info, const char key[]) {
332 lua_newtable(fL);
333 setfield_scalar(fL, "phase", info.fPhase);
334 this->pushArrayScalar(info.fIntervals, info.fCount, "intervals");
335 CHECK_SETFIELD(key);
336}
337
338
reed@google.com74ce6f02013-05-22 15:13:18 +0000339void SkLua::pushMatrix(const SkMatrix& matrix, const char key[]) {
340 push_obj(fL, matrix);
341 CHECK_SETFIELD(key);
342}
343
344void SkLua::pushPaint(const SkPaint& paint, const char key[]) {
345 push_obj(fL, paint);
346 CHECK_SETFIELD(key);
347}
348
349void SkLua::pushPath(const SkPath& path, const char key[]) {
350 push_obj(fL, path);
351 CHECK_SETFIELD(key);
352}
353
354void SkLua::pushCanvas(SkCanvas* canvas, const char key[]) {
Mike Reed5df49342016-11-12 08:06:55 -0600355 push_ptr(fL, canvas);
reed@google.com74ce6f02013-05-22 15:13:18 +0000356 CHECK_SETFIELD(key);
357}
358
fmalitab7425172014-08-26 07:56:44 -0700359void SkLua::pushTextBlob(const SkTextBlob* blob, const char key[]) {
360 push_ref(fL, const_cast<SkTextBlob*>(blob));
361 CHECK_SETFIELD(key);
362}
363
reed@google.com74ce6f02013-05-22 15:13:18 +0000364///////////////////////////////////////////////////////////////////////////////
365///////////////////////////////////////////////////////////////////////////////
366
reed@google.com74ce6f02013-05-22 15:13:18 +0000367static SkScalar getfield_scalar(lua_State* L, int index, const char key[]) {
368 SkASSERT(lua_istable(L, index));
369 lua_pushstring(L, key);
370 lua_gettable(L, index);
mtklein8aacf202014-12-18 13:29:54 -0800371
reed@google.com74ce6f02013-05-22 15:13:18 +0000372 SkScalar value = lua2scalar(L, -1);
373 lua_pop(L, 1);
374 return value;
375}
376
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000377static SkScalar getfield_scalar_default(lua_State* L, int index, const char key[], SkScalar def) {
378 SkASSERT(lua_istable(L, index));
379 lua_pushstring(L, key);
380 lua_gettable(L, index);
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000381
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000382 SkScalar value;
383 if (lua_isnil(L, -1)) {
384 value = def;
385 } else {
386 value = lua2scalar(L, -1);
387 }
388 lua_pop(L, 1);
389 return value;
390}
391
reed468b1812014-10-19 11:42:54 -0700392static SkScalar byte2unit(U8CPU byte) {
393 return byte / 255.0f;
394}
395
reed@google.com74ce6f02013-05-22 15:13:18 +0000396static U8CPU unit2byte(SkScalar x) {
397 if (x <= 0) {
398 return 0;
399 } else if (x >= 1) {
400 return 255;
401 } else {
402 return SkScalarRoundToInt(x * 255);
403 }
404}
405
406static SkColor lua2color(lua_State* L, int index) {
reed485557f2014-10-12 10:36:47 -0700407 return SkColorSetARGB(unit2byte(getfield_scalar_default(L, index, "a", 1)),
408 unit2byte(getfield_scalar_default(L, index, "r", 0)),
409 unit2byte(getfield_scalar_default(L, index, "g", 0)),
410 unit2byte(getfield_scalar_default(L, index, "b", 0)));
reed@google.com74ce6f02013-05-22 15:13:18 +0000411}
412
413static SkRect* lua2rect(lua_State* L, int index, SkRect* rect) {
Mike Reed92b33352019-08-24 19:39:13 -0400414 rect->setLTRB(getfield_scalar_default(L, index, "left", 0),
415 getfield_scalar_default(L, index, "top", 0),
416 getfield_scalar(L, index, "right"),
417 getfield_scalar(L, index, "bottom"));
reed@google.com74ce6f02013-05-22 15:13:18 +0000418 return rect;
419}
420
reedf355df52014-10-12 12:18:40 -0700421static int lcanvas_clear(lua_State* L) {
422 get_ref<SkCanvas>(L, 1)->clear(0);
423 return 0;
424}
425
reed@google.com74ce6f02013-05-22 15:13:18 +0000426static int lcanvas_drawColor(lua_State* L) {
427 get_ref<SkCanvas>(L, 1)->drawColor(lua2color(L, 2));
428 return 0;
429}
430
reed9fbc3f32014-10-21 07:12:58 -0700431static int lcanvas_drawPaint(lua_State* L) {
432 get_ref<SkCanvas>(L, 1)->drawPaint(*get_obj<SkPaint>(L, 2));
433 return 0;
434}
435
reed@google.com74ce6f02013-05-22 15:13:18 +0000436static int lcanvas_drawRect(lua_State* L) {
437 SkRect rect;
reed7a72c672014-11-07 10:23:55 -0800438 lua2rect(L, 2, &rect);
439 const SkPaint* paint = get_obj<SkPaint>(L, 3);
440 get_ref<SkCanvas>(L, 1)->drawRect(rect, *paint);
reed@google.com74ce6f02013-05-22 15:13:18 +0000441 return 0;
442}
443
444static int lcanvas_drawOval(lua_State* L) {
445 SkRect rect;
446 get_ref<SkCanvas>(L, 1)->drawOval(*lua2rect(L, 2, &rect),
447 *get_obj<SkPaint>(L, 3));
448 return 0;
449}
450
451static int lcanvas_drawCircle(lua_State* L) {
452 get_ref<SkCanvas>(L, 1)->drawCircle(lua2scalar(L, 2),
453 lua2scalar(L, 3),
454 lua2scalar(L, 4),
455 *get_obj<SkPaint>(L, 5));
456 return 0;
457}
458
reed485557f2014-10-12 10:36:47 -0700459static SkPaint* lua2OptionalPaint(lua_State* L, int index, SkPaint* paint) {
460 if (lua_isnumber(L, index)) {
461 paint->setAlpha(SkScalarRoundToInt(lua2scalar(L, index) * 255));
462 return paint;
reedf355df52014-10-12 12:18:40 -0700463 } else if (lua_isuserdata(L, index)) {
reed485557f2014-10-12 10:36:47 -0700464 const SkPaint* ptr = get_obj<SkPaint>(L, index);
465 if (ptr) {
466 *paint = *ptr;
467 return paint;
468 }
469 }
halcanary96fcdcc2015-08-27 07:41:13 -0700470 return nullptr;
reed485557f2014-10-12 10:36:47 -0700471}
472
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000473static int lcanvas_drawImage(lua_State* L) {
474 SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
475 SkImage* image = get_ref<SkImage>(L, 2);
halcanary96fcdcc2015-08-27 07:41:13 -0700476 if (nullptr == image) {
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000477 return 0;
478 }
479 SkScalar x = lua2scalar(L, 3);
480 SkScalar y = lua2scalar(L, 4);
481
482 SkPaint paint;
reed485557f2014-10-12 10:36:47 -0700483 canvas->drawImage(image, x, y, lua2OptionalPaint(L, 5, &paint));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000484 return 0;
485}
486
reedba5fb932014-10-10 15:28:19 -0700487static int lcanvas_drawImageRect(lua_State* L) {
488 SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
489 SkImage* image = get_ref<SkImage>(L, 2);
halcanary96fcdcc2015-08-27 07:41:13 -0700490 if (nullptr == image) {
reedba5fb932014-10-10 15:28:19 -0700491 return 0;
492 }
493
494 SkRect srcR, dstR;
halcanary96fcdcc2015-08-27 07:41:13 -0700495 SkRect* srcRPtr = nullptr;
reedba5fb932014-10-10 15:28:19 -0700496 if (!lua_isnil(L, 3)) {
497 srcRPtr = lua2rect(L, 3, &srcR);
498 }
499 lua2rect(L, 4, &dstR);
mtklein8aacf202014-12-18 13:29:54 -0800500
reedba5fb932014-10-10 15:28:19 -0700501 SkPaint paint;
reede47829b2015-08-06 10:02:53 -0700502 canvas->legacy_drawImageRect(image, srcRPtr, dstR, lua2OptionalPaint(L, 5, &paint));
reedba5fb932014-10-10 15:28:19 -0700503 return 0;
504}
505
reed7a72c672014-11-07 10:23:55 -0800506static int lcanvas_drawPatch(lua_State* L) {
507 SkPoint cubics[12];
508 SkColor colorStorage[4];
509 SkPoint texStorage[4];
510
halcanary96fcdcc2015-08-27 07:41:13 -0700511 const SkColor* colors = nullptr;
512 const SkPoint* texs = nullptr;
reed7a72c672014-11-07 10:23:55 -0800513
514 getarray_points(L, 2, cubics, 12);
515
516 colorStorage[0] = SK_ColorRED;
517 colorStorage[1] = SK_ColorGREEN;
518 colorStorage[2] = SK_ColorBLUE;
519 colorStorage[3] = SK_ColorGRAY;
520
521 if (lua_isnil(L, 4)) {
522 colors = colorStorage;
523 } else {
524 getarray_points(L, 4, texStorage, 4);
525 texs = texStorage;
526 }
527
Mike Reed7d954ad2016-10-28 15:42:34 -0400528 get_ref<SkCanvas>(L, 1)->drawPatch(cubics, colors, texs, *get_obj<SkPaint>(L, 5));
reed7a72c672014-11-07 10:23:55 -0800529 return 0;
530}
531
reed@google.comfd345872013-05-22 20:53:42 +0000532static int lcanvas_drawPath(lua_State* L) {
533 get_ref<SkCanvas>(L, 1)->drawPath(*get_obj<SkPath>(L, 2),
534 *get_obj<SkPaint>(L, 3));
535 return 0;
536}
537
reed96affcd2014-10-13 12:38:04 -0700538// drawPicture(pic, x, y, paint)
539static int lcanvas_drawPicture(lua_State* L) {
540 SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
541 SkPicture* picture = get_ref<SkPicture>(L, 2);
542 SkScalar x = lua2scalar_def(L, 3, 0);
543 SkScalar y = lua2scalar_def(L, 4, 0);
halcanary96fcdcc2015-08-27 07:41:13 -0700544 SkMatrix matrix, *matrixPtr = nullptr;
reed96affcd2014-10-13 12:38:04 -0700545 if (x || y) {
546 matrix.setTranslate(x, y);
547 matrixPtr = &matrix;
548 }
549 SkPaint paint;
550 canvas->drawPicture(picture, matrixPtr, lua2OptionalPaint(L, 5, &paint));
551 return 0;
552}
553
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000554static int lcanvas_drawText(lua_State* L) {
555 if (lua_gettop(L) < 5) {
556 return 0;
557 }
558
Mike Reed5f528e52019-01-28 10:57:28 -0500559 // TODO: restore this logic based on SkFont instead of SkPaint
560#if 0
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000561 if (lua_isstring(L, 2) && lua_isnumber(L, 3) && lua_isnumber(L, 4)) {
562 size_t len;
563 const char* text = lua_tolstring(L, 2, &len);
Hal Canary292ece82019-01-09 10:59:08 -0500564 get_ref<SkCanvas>(L, 1)->drawSimpleText(
Ben Wagner51e15a62019-05-07 15:38:46 -0400565 text, len, SkTextEncoding::kUTF8,
Hal Canary292ece82019-01-09 10:59:08 -0500566 lua2scalar(L, 3), lua2scalar(L, 4),
567 SkFont::LEGACY_ExtractFromPaint(*get_obj<SkPaint>(L, 5)),
568 *get_obj<SkPaint>(L, 5));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000569 }
Mike Reede5f9cfa2019-01-10 13:55:35 -0500570#endif
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000571 return 0;
572}
573
reed1b6ab442014-11-03 19:55:41 -0800574static int lcanvas_drawTextBlob(lua_State* L) {
575 const SkTextBlob* blob = get_ref<SkTextBlob>(L, 2);
576 SkScalar x = lua2scalar(L, 3);
577 SkScalar y = lua2scalar(L, 4);
578 const SkPaint& paint = *get_obj<SkPaint>(L, 5);
579 get_ref<SkCanvas>(L, 1)->drawTextBlob(blob, x, y, paint);
580 return 0;
581}
582
reed@google.com74ce6f02013-05-22 15:13:18 +0000583static int lcanvas_getSaveCount(lua_State* L) {
584 lua_pushnumber(L, get_ref<SkCanvas>(L, 1)->getSaveCount());
585 return 1;
586}
587
588static int lcanvas_getTotalMatrix(lua_State* L) {
589 SkLua(L).pushMatrix(get_ref<SkCanvas>(L, 1)->getTotalMatrix());
590 return 1;
591}
592
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000593static int lcanvas_save(lua_State* L) {
594 lua_pushinteger(L, get_ref<SkCanvas>(L, 1)->save());
595 return 1;
596}
597
reed86217d82014-10-25 20:44:40 -0700598static int lcanvas_saveLayer(lua_State* L) {
599 SkPaint paint;
halcanary96fcdcc2015-08-27 07:41:13 -0700600 lua_pushinteger(L, get_ref<SkCanvas>(L, 1)->saveLayer(nullptr, lua2OptionalPaint(L, 2, &paint)));
reed86217d82014-10-25 20:44:40 -0700601 return 1;
602}
603
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000604static int lcanvas_restore(lua_State* L) {
605 get_ref<SkCanvas>(L, 1)->restore();
606 return 0;
607}
608
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000609static int lcanvas_scale(lua_State* L) {
610 SkScalar sx = lua2scalar_def(L, 2, 1);
611 SkScalar sy = lua2scalar_def(L, 3, sx);
612 get_ref<SkCanvas>(L, 1)->scale(sx, sy);
613 return 0;
614}
615
reed@google.com3597b732013-05-22 20:12:50 +0000616static int lcanvas_translate(lua_State* L) {
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000617 SkScalar tx = lua2scalar_def(L, 2, 0);
618 SkScalar ty = lua2scalar_def(L, 3, 0);
619 get_ref<SkCanvas>(L, 1)->translate(tx, ty);
620 return 0;
621}
622
623static int lcanvas_rotate(lua_State* L) {
624 SkScalar degrees = lua2scalar_def(L, 2, 0);
625 get_ref<SkCanvas>(L, 1)->rotate(degrees);
reed@google.com3597b732013-05-22 20:12:50 +0000626 return 0;
627}
628
reedbdc49ae2014-10-14 09:34:52 -0700629static int lcanvas_concat(lua_State* L) {
630 get_ref<SkCanvas>(L, 1)->concat(*get_obj<SkMatrix>(L, 2));
631 return 0;
632}
633
reed485557f2014-10-12 10:36:47 -0700634static int lcanvas_newSurface(lua_State* L) {
635 int width = lua2int_def(L, 2, 0);
reed7a72c672014-11-07 10:23:55 -0800636 int height = lua2int_def(L, 3, 0);
reed485557f2014-10-12 10:36:47 -0700637 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
reede8f30622016-03-23 18:59:25 -0700638 auto surface = get_ref<SkCanvas>(L, 1)->makeSurface(info);
halcanary96fcdcc2015-08-27 07:41:13 -0700639 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -0700640 lua_pushnil(L);
641 } else {
reede8f30622016-03-23 18:59:25 -0700642 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -0700643 }
644 return 1;
645}
646
reed@google.com74ce6f02013-05-22 15:13:18 +0000647static int lcanvas_gc(lua_State* L) {
Mike Reed5df49342016-11-12 08:06:55 -0600648 // don't know how to track a ptr...
reed@google.com74ce6f02013-05-22 15:13:18 +0000649 return 0;
650}
651
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000652const struct luaL_Reg gSkCanvas_Methods[] = {
reedf355df52014-10-12 12:18:40 -0700653 { "clear", lcanvas_clear },
reed@google.com74ce6f02013-05-22 15:13:18 +0000654 { "drawColor", lcanvas_drawColor },
reed9fbc3f32014-10-21 07:12:58 -0700655 { "drawPaint", lcanvas_drawPaint },
reed@google.com74ce6f02013-05-22 15:13:18 +0000656 { "drawRect", lcanvas_drawRect },
657 { "drawOval", lcanvas_drawOval },
658 { "drawCircle", lcanvas_drawCircle },
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000659 { "drawImage", lcanvas_drawImage },
reedba5fb932014-10-10 15:28:19 -0700660 { "drawImageRect", lcanvas_drawImageRect },
reed7a72c672014-11-07 10:23:55 -0800661 { "drawPatch", lcanvas_drawPatch },
reed@google.comfd345872013-05-22 20:53:42 +0000662 { "drawPath", lcanvas_drawPath },
reed96affcd2014-10-13 12:38:04 -0700663 { "drawPicture", lcanvas_drawPicture },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000664 { "drawText", lcanvas_drawText },
reed1b6ab442014-11-03 19:55:41 -0800665 { "drawTextBlob", lcanvas_drawTextBlob },
reed@google.com74ce6f02013-05-22 15:13:18 +0000666 { "getSaveCount", lcanvas_getSaveCount },
667 { "getTotalMatrix", lcanvas_getTotalMatrix },
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000668 { "save", lcanvas_save },
reed86217d82014-10-25 20:44:40 -0700669 { "saveLayer", lcanvas_saveLayer },
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000670 { "restore", lcanvas_restore },
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000671 { "scale", lcanvas_scale },
reed@google.com3597b732013-05-22 20:12:50 +0000672 { "translate", lcanvas_translate },
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000673 { "rotate", lcanvas_rotate },
reedbdc49ae2014-10-14 09:34:52 -0700674 { "concat", lcanvas_concat },
reed485557f2014-10-12 10:36:47 -0700675
676 { "newSurface", lcanvas_newSurface },
677
reed@google.com74ce6f02013-05-22 15:13:18 +0000678 { "__gc", lcanvas_gc },
halcanary96fcdcc2015-08-27 07:41:13 -0700679 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +0000680};
681
682///////////////////////////////////////////////////////////////////////////////
683
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000684static int ldocument_beginPage(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -0700685 const SkRect* contentPtr = nullptr;
Mike Reed7ff6ca52018-01-08 14:45:31 -0500686 push_ptr(L, get_obj<DocHolder>(L, 1)->fDoc->beginPage(lua2scalar(L, 2),
687 lua2scalar(L, 3),
688 contentPtr));
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000689 return 1;
690}
691
692static int ldocument_endPage(lua_State* L) {
Mike Reed7ff6ca52018-01-08 14:45:31 -0500693 get_obj<DocHolder>(L, 1)->fDoc->endPage();
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000694 return 0;
695}
696
697static int ldocument_close(lua_State* L) {
Mike Reed7ff6ca52018-01-08 14:45:31 -0500698 get_obj<DocHolder>(L, 1)->fDoc->close();
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000699 return 0;
700}
701
702static int ldocument_gc(lua_State* L) {
Mike Reed7ff6ca52018-01-08 14:45:31 -0500703 get_obj<DocHolder>(L, 1)->~DocHolder();
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000704 return 0;
705}
706
Mike Reed7ff6ca52018-01-08 14:45:31 -0500707static const struct luaL_Reg gDocHolder_Methods[] = {
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000708 { "beginPage", ldocument_beginPage },
709 { "endPage", ldocument_endPage },
710 { "close", ldocument_close },
711 { "__gc", ldocument_gc },
halcanary96fcdcc2015-08-27 07:41:13 -0700712 { nullptr, nullptr }
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000713};
714
715///////////////////////////////////////////////////////////////////////////////
716
reed@google.com74ce6f02013-05-22 15:13:18 +0000717static int lpaint_isAntiAlias(lua_State* L) {
718 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isAntiAlias());
719 return 1;
720}
721
722static int lpaint_setAntiAlias(lua_State* L) {
reed@google.com88c9ec92013-05-22 15:43:21 +0000723 get_obj<SkPaint>(L, 1)->setAntiAlias(lua2bool(L, 2));
reed@google.com74ce6f02013-05-22 15:13:18 +0000724 return 0;
725}
726
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000727static int lpaint_isDither(lua_State* L) {
728 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isDither());
729 return 1;
730}
731
reedbb8a0ab2014-11-03 22:32:07 -0800732static int lpaint_setDither(lua_State* L) {
733 get_obj<SkPaint>(L, 1)->setDither(lua2bool(L, 2));
734 return 0;
735}
736
reed468b1812014-10-19 11:42:54 -0700737static int lpaint_getAlpha(lua_State* L) {
738 SkLua(L).pushScalar(byte2unit(get_obj<SkPaint>(L, 1)->getAlpha()));
739 return 1;
740}
741
742static int lpaint_setAlpha(lua_State* L) {
743 get_obj<SkPaint>(L, 1)->setAlpha(unit2byte(lua2scalar(L, 2)));
744 return 0;
745}
746
reed@google.com74ce6f02013-05-22 15:13:18 +0000747static int lpaint_getColor(lua_State* L) {
748 SkLua(L).pushColor(get_obj<SkPaint>(L, 1)->getColor());
749 return 1;
750}
751
752static int lpaint_setColor(lua_State* L) {
753 get_obj<SkPaint>(L, 1)->setColor(lua2color(L, 2));
754 return 0;
755}
756
reed93a12152015-03-16 10:08:34 -0700757static int lpaint_getFilterQuality(lua_State* L) {
758 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getFilterQuality());
reed7a72c672014-11-07 10:23:55 -0800759 return 1;
760}
761
reed93a12152015-03-16 10:08:34 -0700762static int lpaint_setFilterQuality(lua_State* L) {
reed7a72c672014-11-07 10:23:55 -0800763 int level = lua2int_def(L, 2, -1);
764 if (level >= 0 && level <= 3) {
reed93a12152015-03-16 10:08:34 -0700765 get_obj<SkPaint>(L, 1)->setFilterQuality((SkFilterQuality)level);
reed7a72c672014-11-07 10:23:55 -0800766 }
767 return 0;
768}
769
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000770static int lpaint_getStroke(lua_State* L) {
771 lua_pushboolean(L, SkPaint::kStroke_Style == get_obj<SkPaint>(L, 1)->getStyle());
772 return 1;
773}
774
775static int lpaint_setStroke(lua_State* L) {
776 SkPaint::Style style;
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000777
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000778 if (lua_toboolean(L, 2)) {
779 style = SkPaint::kStroke_Style;
780 } else {
781 style = SkPaint::kFill_Style;
782 }
783 get_obj<SkPaint>(L, 1)->setStyle(style);
784 return 0;
785}
786
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000787static int lpaint_getStrokeCap(lua_State* L) {
788 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeCap());
789 return 1;
790}
791
792static int lpaint_getStrokeJoin(lua_State* L) {
793 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeJoin());
794 return 1;
795}
796
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000797static int lpaint_getStrokeWidth(lua_State* L) {
798 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeWidth());
799 return 1;
800}
801
802static int lpaint_setStrokeWidth(lua_State* L) {
803 get_obj<SkPaint>(L, 1)->setStrokeWidth(lua2scalar(L, 2));
804 return 0;
805}
806
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000807static int lpaint_getStrokeMiter(lua_State* L) {
808 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeMiter());
809 return 1;
810}
811
reed@google.com29563872013-07-10 21:23:49 +0000812static int lpaint_getEffects(lua_State* L) {
813 const SkPaint* paint = get_obj<SkPaint>(L, 1);
skia.committer@gmail.comde2e4e82013-07-11 07:01:01 +0000814
reed@google.com29563872013-07-10 21:23:49 +0000815 lua_newtable(L);
reed468b1812014-10-19 11:42:54 -0700816 setfield_bool_if(L, "pathEffect", !!paint->getPathEffect());
reed468b1812014-10-19 11:42:54 -0700817 setfield_bool_if(L, "maskFilter", !!paint->getMaskFilter());
818 setfield_bool_if(L, "shader", !!paint->getShader());
reed@google.com29563872013-07-10 21:23:49 +0000819 setfield_bool_if(L, "colorFilter", !!paint->getColorFilter());
820 setfield_bool_if(L, "imageFilter", !!paint->getImageFilter());
reed@google.com29563872013-07-10 21:23:49 +0000821 return 1;
822}
823
reed22a517f2015-12-04 20:45:59 -0800824static int lpaint_getColorFilter(lua_State* L) {
825 const SkPaint* paint = get_obj<SkPaint>(L, 1);
826 SkColorFilter* cf = paint->getColorFilter();
827 if (cf) {
828 push_ref(L, cf);
829 return 1;
830 }
831 return 0;
832}
833
834static int lpaint_setColorFilter(lua_State* L) {
835 SkPaint* paint = get_obj<SkPaint>(L, 1);
reedd053ce92016-03-22 10:17:23 -0700836 paint->setColorFilter(sk_ref_sp(get_ref<SkColorFilter>(L, 2)));
reed22a517f2015-12-04 20:45:59 -0800837 return 0;
838}
839
reed468b1812014-10-19 11:42:54 -0700840static int lpaint_getImageFilter(lua_State* L) {
841 const SkPaint* paint = get_obj<SkPaint>(L, 1);
842 SkImageFilter* imf = paint->getImageFilter();
843 if (imf) {
844 push_ref(L, imf);
845 return 1;
846 }
847 return 0;
848}
849
850static int lpaint_setImageFilter(lua_State* L) {
851 SkPaint* paint = get_obj<SkPaint>(L, 1);
Mike Reed5e257172016-11-01 11:22:05 -0400852 paint->setImageFilter(sk_ref_sp(get_ref<SkImageFilter>(L, 2)));
reed468b1812014-10-19 11:42:54 -0700853 return 0;
854}
855
reed@google.com5fdc9832013-07-24 15:47:52 +0000856static int lpaint_getShader(lua_State* L) {
857 const SkPaint* paint = get_obj<SkPaint>(L, 1);
858 SkShader* shader = paint->getShader();
859 if (shader) {
860 push_ref(L, shader);
861 return 1;
862 }
863 return 0;
864}
865
reed9fbc3f32014-10-21 07:12:58 -0700866static int lpaint_setShader(lua_State* L) {
867 SkPaint* paint = get_obj<SkPaint>(L, 1);
reedfe630452016-03-25 09:08:00 -0700868 paint->setShader(sk_ref_sp(get_ref<SkShader>(L, 2)));
reed9fbc3f32014-10-21 07:12:58 -0700869 return 0;
870}
871
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +0000872static int lpaint_getPathEffect(lua_State* L) {
873 const SkPaint* paint = get_obj<SkPaint>(L, 1);
874 SkPathEffect* pe = paint->getPathEffect();
875 if (pe) {
876 push_ref(L, pe);
877 return 1;
878 }
879 return 0;
880}
881
hstern0b401ce2016-08-02 09:17:59 -0700882static int lpaint_getFillPath(lua_State* L) {
883 const SkPaint* paint = get_obj<SkPaint>(L, 1);
884 const SkPath* path = get_obj<SkPath>(L, 2);
885
886 SkPath fillpath;
887 paint->getFillPath(*path, &fillpath);
888
889 SkLua lua(L);
890 lua.pushPath(fillpath);
891
892 return 1;
893}
894
reed@google.com74ce6f02013-05-22 15:13:18 +0000895static int lpaint_gc(lua_State* L) {
896 get_obj<SkPaint>(L, 1)->~SkPaint();
897 return 0;
898}
899
900static const struct luaL_Reg gSkPaint_Methods[] = {
901 { "isAntiAlias", lpaint_isAntiAlias },
902 { "setAntiAlias", lpaint_setAntiAlias },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000903 { "isDither", lpaint_isDither },
reedbb8a0ab2014-11-03 22:32:07 -0800904 { "setDither", lpaint_setDither },
reed93a12152015-03-16 10:08:34 -0700905 { "getFilterQuality", lpaint_getFilterQuality },
906 { "setFilterQuality", lpaint_setFilterQuality },
reed468b1812014-10-19 11:42:54 -0700907 { "getAlpha", lpaint_getAlpha },
908 { "setAlpha", lpaint_setAlpha },
reed@google.com74ce6f02013-05-22 15:13:18 +0000909 { "getColor", lpaint_getColor },
910 { "setColor", lpaint_setColor },
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000911 { "getStroke", lpaint_getStroke },
912 { "setStroke", lpaint_setStroke },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000913 { "getStrokeCap", lpaint_getStrokeCap },
914 { "getStrokeJoin", lpaint_getStrokeJoin },
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000915 { "getStrokeWidth", lpaint_getStrokeWidth },
916 { "setStrokeWidth", lpaint_setStrokeWidth },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000917 { "getStrokeMiter", lpaint_getStrokeMiter },
reed@google.com29563872013-07-10 21:23:49 +0000918 { "getEffects", lpaint_getEffects },
reed22a517f2015-12-04 20:45:59 -0800919 { "getColorFilter", lpaint_getColorFilter },
920 { "setColorFilter", lpaint_setColorFilter },
reed468b1812014-10-19 11:42:54 -0700921 { "getImageFilter", lpaint_getImageFilter },
922 { "setImageFilter", lpaint_setImageFilter },
reed@google.com5fdc9832013-07-24 15:47:52 +0000923 { "getShader", lpaint_getShader },
reed9fbc3f32014-10-21 07:12:58 -0700924 { "setShader", lpaint_setShader },
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +0000925 { "getPathEffect", lpaint_getPathEffect },
hstern0b401ce2016-08-02 09:17:59 -0700926 { "getFillPath", lpaint_getFillPath },
reed@google.com74ce6f02013-05-22 15:13:18 +0000927 { "__gc", lpaint_gc },
halcanary96fcdcc2015-08-27 07:41:13 -0700928 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +0000929};
930
931///////////////////////////////////////////////////////////////////////////////
932
Mike Reed91919132019-01-02 12:21:01 -0500933static int lfont_getSize(lua_State* L) {
934 SkLua(L).pushScalar(get_obj<SkFont>(L, 1)->getSize());
935 return 1;
936}
937
938static int lfont_getScaleX(lua_State* L) {
939 SkLua(L).pushScalar(get_obj<SkFont>(L, 1)->getScaleX());
940 return 1;
941}
942
943static int lfont_getSkewX(lua_State* L) {
944 SkLua(L).pushScalar(get_obj<SkFont>(L, 1)->getSkewX());
945 return 1;
946}
947
948static int lfont_setSize(lua_State* L) {
949 get_obj<SkFont>(L, 1)->setSize(lua2scalar(L, 2));
950 return 0;
951}
952
953static int lfont_getTypeface(lua_State* L) {
Herb Derby087fad72019-01-22 14:45:16 -0500954 push_ref(L, get_obj<SkFont>(L, 1)->getTypefaceOrDefault());
Mike Reed91919132019-01-02 12:21:01 -0500955 return 1;
956}
957
958static int lfont_setTypeface(lua_State* L) {
959 get_obj<SkFont>(L, 1)->setTypeface(sk_ref_sp(get_ref<SkTypeface>(L, 2)));
960 return 0;
961}
962
963static int lfont_getHinting(lua_State* L) {
964 SkLua(L).pushU32((unsigned)get_obj<SkFont>(L, 1)->getHinting());
965 return 1;
966}
967
968static int lfont_getFontID(lua_State* L) {
Herb Derby087fad72019-01-22 14:45:16 -0500969 SkTypeface* face = get_obj<SkFont>(L, 1)->getTypefaceOrDefault();
Mike Reed91919132019-01-02 12:21:01 -0500970 SkLua(L).pushU32(SkTypeface::UniqueID(face));
971 return 1;
972}
973
974static int lfont_measureText(lua_State* L) {
975 if (lua_isstring(L, 2)) {
976 size_t len;
977 const char* text = lua_tolstring(L, 2, &len);
Ben Wagner51e15a62019-05-07 15:38:46 -0400978 SkLua(L).pushScalar(get_obj<SkFont>(L, 1)->measureText(text, len, SkTextEncoding::kUTF8));
Mike Reed91919132019-01-02 12:21:01 -0500979 return 1;
980 }
981 return 0;
982}
983
984static int lfont_getMetrics(lua_State* L) {
985 SkFontMetrics fm;
986 SkScalar height = get_obj<SkFont>(L, 1)->getMetrics(&fm);
987
988 lua_newtable(L);
989 setfield_scalar(L, "top", fm.fTop);
990 setfield_scalar(L, "ascent", fm.fAscent);
991 setfield_scalar(L, "descent", fm.fDescent);
992 setfield_scalar(L, "bottom", fm.fBottom);
993 setfield_scalar(L, "leading", fm.fLeading);
994 SkLua(L).pushScalar(height);
995 return 2;
996}
997
998static int lfont_gc(lua_State* L) {
999 get_obj<SkFont>(L, 1)->~SkFont();
1000 return 0;
1001}
1002
1003static const struct luaL_Reg gSkFont_Methods[] = {
1004 { "getSize", lfont_getSize },
1005 { "setSize", lfont_setSize },
1006 { "getScaleX", lfont_getScaleX },
1007 { "getSkewX", lfont_getSkewX },
1008 { "getTypeface", lfont_getTypeface },
1009 { "setTypeface", lfont_setTypeface },
1010 { "getHinting", lfont_getHinting },
1011 { "getFontID", lfont_getFontID },
1012 { "measureText", lfont_measureText },
1013 { "getMetrics", lfont_getMetrics },
1014 { "__gc", lfont_gc },
1015 { nullptr, nullptr }
1016};
1017
1018///////////////////////////////////////////////////////////////////////////////
1019
Mike Reedfae8fce2019-04-03 10:27:45 -04001020static const char* mode2string(SkTileMode mode) {
1021 static const char* gNames[] = { "clamp", "repeat", "mirror", "decal" };
reed@google.com5fdc9832013-07-24 15:47:52 +00001022 SkASSERT((unsigned)mode < SK_ARRAY_COUNT(gNames));
Mike Reedfae8fce2019-04-03 10:27:45 -04001023 return gNames[static_cast<int>(mode)];
reed@google.com5fdc9832013-07-24 15:47:52 +00001024}
1025
1026static const char* gradtype2string(SkShader::GradientType t) {
1027 static const char* gNames[] = {
1028 "none", "color", "linear", "radial", "radial2", "sweep", "conical"
1029 };
1030 SkASSERT((unsigned)t < SK_ARRAY_COUNT(gNames));
1031 return gNames[t];
1032}
1033
1034static int lshader_isOpaque(lua_State* L) {
1035 SkShader* shader = get_ref<SkShader>(L, 1);
1036 return shader && shader->isOpaque();
1037}
1038
Mike Reed627778d2016-09-28 17:13:38 -04001039static int lshader_isAImage(lua_State* L) {
reed@google.com5fdc9832013-07-24 15:47:52 +00001040 SkShader* shader = get_ref<SkShader>(L, 1);
1041 if (shader) {
reed@google.com5fdc9832013-07-24 15:47:52 +00001042 SkMatrix matrix;
Mike Reedfae8fce2019-04-03 10:27:45 -04001043 SkTileMode modes[2];
Mike Reed627778d2016-09-28 17:13:38 -04001044 if (SkImage* image = shader->isAImage(&matrix, modes)) {
reedf5822822015-08-19 11:46:38 -07001045 lua_newtable(L);
Mike Reed627778d2016-09-28 17:13:38 -04001046 setfield_number(L, "id", image->uniqueID());
1047 setfield_number(L, "width", image->width());
1048 setfield_number(L, "height", image->height());
reedf5822822015-08-19 11:46:38 -07001049 setfield_string(L, "tileX", mode2string(modes[0]));
1050 setfield_string(L, "tileY", mode2string(modes[1]));
1051 return 1;
reed@google.com5fdc9832013-07-24 15:47:52 +00001052 }
1053 }
1054 return 0;
1055}
1056
1057static int lshader_asAGradient(lua_State* L) {
1058 SkShader* shader = get_ref<SkShader>(L, 1);
1059 if (shader) {
1060 SkShader::GradientInfo info;
1061 sk_bzero(&info, sizeof(info));
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001062
reed@google.com5fdc9832013-07-24 15:47:52 +00001063 SkShader::GradientType t = shader->asAGradient(&info);
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001064
reed@google.com5fdc9832013-07-24 15:47:52 +00001065 if (SkShader::kNone_GradientType != t) {
fmenozzib4f254e2016-06-28 14:03:03 -07001066 SkAutoTArray<SkScalar> pos(info.fColorCount);
1067 info.fColorOffsets = pos.get();
1068 shader->asAGradient(&info);
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001069
fmenozzib4f254e2016-06-28 14:03:03 -07001070 lua_newtable(L);
fmenozzi7f2c85e2016-07-12 09:17:39 -07001071 setfield_string(L, "type", gradtype2string(t));
Mike Reedfae8fce2019-04-03 10:27:45 -04001072 setfield_string(L, "tile", mode2string((SkTileMode)info.fTileMode));
fmenozzi7f2c85e2016-07-12 09:17:39 -07001073 setfield_number(L, "colorCount", info.fColorCount);
fmenozzib4f254e2016-06-28 14:03:03 -07001074
1075 lua_newtable(L);
1076 for (int i = 0; i < info.fColorCount; i++) {
1077 // Lua uses 1-based indexing
1078 setarray_scalar(L, i+1, pos[i]);
1079 }
1080 lua_setfield(L, -2, "positions");
1081
reed@google.com5fdc9832013-07-24 15:47:52 +00001082 return 1;
1083 }
1084 }
1085 return 0;
1086}
1087
1088static int lshader_gc(lua_State* L) {
1089 get_ref<SkShader>(L, 1)->unref();
1090 return 0;
1091}
1092
1093static const struct luaL_Reg gSkShader_Methods[] = {
1094 { "isOpaque", lshader_isOpaque },
Mike Reed627778d2016-09-28 17:13:38 -04001095 { "isAImage", lshader_isAImage },
reed@google.com5fdc9832013-07-24 15:47:52 +00001096 { "asAGradient", lshader_asAGradient },
1097 { "__gc", lshader_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001098 { nullptr, nullptr }
reed@google.com5fdc9832013-07-24 15:47:52 +00001099};
1100
1101///////////////////////////////////////////////////////////////////////////////
1102
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +00001103static int lpatheffect_asADash(lua_State* L) {
1104 SkPathEffect* pe = get_ref<SkPathEffect>(L, 1);
1105 if (pe) {
1106 SkPathEffect::DashInfo info;
1107 SkPathEffect::DashType dashType = pe->asADash(&info);
1108 if (SkPathEffect::kDash_DashType == dashType) {
1109 SkAutoTArray<SkScalar> intervals(info.fCount);
1110 info.fIntervals = intervals.get();
1111 pe->asADash(&info);
1112 SkLua(L).pushDash(info);
1113 return 1;
1114 }
1115 }
1116 return 0;
1117}
1118
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001119static int lpatheffect_gc(lua_State* L) {
1120 get_ref<SkPathEffect>(L, 1)->unref();
1121 return 0;
1122}
1123
1124static const struct luaL_Reg gSkPathEffect_Methods[] = {
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +00001125 { "asADash", lpatheffect_asADash },
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001126 { "__gc", lpatheffect_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001127 { nullptr, nullptr }
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001128};
1129
1130///////////////////////////////////////////////////////////////////////////////
1131
reed22a517f2015-12-04 20:45:59 -08001132static int lpcolorfilter_gc(lua_State* L) {
1133 get_ref<SkColorFilter>(L, 1)->unref();
1134 return 0;
1135}
1136
1137static const struct luaL_Reg gSkColorFilter_Methods[] = {
1138 { "__gc", lpcolorfilter_gc },
1139 { nullptr, nullptr }
1140};
1141
1142///////////////////////////////////////////////////////////////////////////////
1143
reed468b1812014-10-19 11:42:54 -07001144static int lpimagefilter_gc(lua_State* L) {
1145 get_ref<SkImageFilter>(L, 1)->unref();
1146 return 0;
1147}
1148
1149static const struct luaL_Reg gSkImageFilter_Methods[] = {
1150 { "__gc", lpimagefilter_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001151 { nullptr, nullptr }
reed468b1812014-10-19 11:42:54 -07001152};
1153
1154///////////////////////////////////////////////////////////////////////////////
1155
humper@google.com2815c192013-07-10 22:42:30 +00001156static int lmatrix_getType(lua_State* L) {
1157 SkMatrix::TypeMask mask = get_obj<SkMatrix>(L, 1)->getType();
skia.committer@gmail.comde2e4e82013-07-11 07:01:01 +00001158
humper@google.com2815c192013-07-10 22:42:30 +00001159 lua_newtable(L);
1160 setfield_boolean(L, "translate", SkToBool(mask & SkMatrix::kTranslate_Mask));
1161 setfield_boolean(L, "scale", SkToBool(mask & SkMatrix::kScale_Mask));
1162 setfield_boolean(L, "affine", SkToBool(mask & SkMatrix::kAffine_Mask));
1163 setfield_boolean(L, "perspective", SkToBool(mask & SkMatrix::kPerspective_Mask));
1164 return 1;
1165}
1166
humper@google.com0f48ee02013-07-26 15:23:43 +00001167static int lmatrix_getScaleX(lua_State* L) {
1168 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getScaleX());
1169 return 1;
1170}
1171
1172static int lmatrix_getScaleY(lua_State* L) {
1173 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getScaleY());
1174 return 1;
1175}
1176
1177static int lmatrix_getTranslateX(lua_State* L) {
1178 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getTranslateX());
1179 return 1;
1180}
1181
1182static int lmatrix_getTranslateY(lua_State* L) {
1183 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getTranslateY());
1184 return 1;
1185}
1186
reed7a72c672014-11-07 10:23:55 -08001187static int lmatrix_invert(lua_State* L) {
1188 lua_pushboolean(L, get_obj<SkMatrix>(L, 1)->invert(get_obj<SkMatrix>(L, 2)));
1189 return 1;
1190}
1191
1192static int lmatrix_mapXY(lua_State* L) {
1193 SkPoint pt = { lua2scalar(L, 2), lua2scalar(L, 3) };
1194 get_obj<SkMatrix>(L, 1)->mapPoints(&pt, &pt, 1);
1195 lua_pushnumber(L, pt.x());
1196 lua_pushnumber(L, pt.y());
1197 return 2;
1198}
1199
reedbdc49ae2014-10-14 09:34:52 -07001200static int lmatrix_setRectToRect(lua_State* L) {
1201 SkMatrix* matrix = get_obj<SkMatrix>(L, 1);
1202 SkRect srcR, dstR;
1203 lua2rect(L, 2, &srcR);
1204 lua2rect(L, 3, &dstR);
1205 const char* scaleToFitStr = lua_tostring(L, 4);
1206 SkMatrix::ScaleToFit scaleToFit = SkMatrix::kFill_ScaleToFit;
1207
1208 if (scaleToFitStr) {
1209 const struct {
1210 const char* fName;
1211 SkMatrix::ScaleToFit fScaleToFit;
1212 } rec[] = {
1213 { "fill", SkMatrix::kFill_ScaleToFit },
1214 { "start", SkMatrix::kStart_ScaleToFit },
1215 { "center", SkMatrix::kCenter_ScaleToFit },
1216 { "end", SkMatrix::kEnd_ScaleToFit },
1217 };
1218
1219 for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
1220 if (strcmp(rec[i].fName, scaleToFitStr) == 0) {
1221 scaleToFit = rec[i].fScaleToFit;
1222 break;
1223 }
1224 }
1225 }
1226
1227 matrix->setRectToRect(srcR, dstR, scaleToFit);
1228 return 0;
1229}
1230
humper@google.com2815c192013-07-10 22:42:30 +00001231static const struct luaL_Reg gSkMatrix_Methods[] = {
1232 { "getType", lmatrix_getType },
humper@google.com0f48ee02013-07-26 15:23:43 +00001233 { "getScaleX", lmatrix_getScaleX },
1234 { "getScaleY", lmatrix_getScaleY },
1235 { "getTranslateX", lmatrix_getTranslateX },
1236 { "getTranslateY", lmatrix_getTranslateY },
reedbdc49ae2014-10-14 09:34:52 -07001237 { "setRectToRect", lmatrix_setRectToRect },
reed7a72c672014-11-07 10:23:55 -08001238 { "invert", lmatrix_invert },
1239 { "mapXY", lmatrix_mapXY },
halcanary96fcdcc2015-08-27 07:41:13 -07001240 { nullptr, nullptr }
humper@google.com2815c192013-07-10 22:42:30 +00001241};
1242
1243///////////////////////////////////////////////////////////////////////////////
1244
reed@google.com74ce6f02013-05-22 15:13:18 +00001245static int lpath_getBounds(lua_State* L) {
1246 SkLua(L).pushRect(get_obj<SkPath>(L, 1)->getBounds());
1247 return 1;
1248}
1249
Mike Reed7d34dc72019-11-26 12:17:17 -05001250static const char* fill_type_to_str(SkPathFillType fill) {
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001251 switch (fill) {
Mike Reed7d34dc72019-11-26 12:17:17 -05001252 case SkPathFillType::kEvenOdd:
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001253 return "even-odd";
Mike Reed7d34dc72019-11-26 12:17:17 -05001254 case SkPathFillType::kWinding:
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001255 return "winding";
Mike Reed7d34dc72019-11-26 12:17:17 -05001256 case SkPathFillType::kInverseEvenOdd:
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001257 return "inverse-even-odd";
Mike Reed7d34dc72019-11-26 12:17:17 -05001258 case SkPathFillType::kInverseWinding:
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001259 return "inverse-winding";
1260 }
1261 return "unknown";
1262}
1263
1264static int lpath_getFillType(lua_State* L) {
Mike Reedcf0e3c62019-12-03 16:26:15 -05001265 SkPathFillType fill = get_obj<SkPath>(L, 1)->getFillType();
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001266 SkLua(L).pushString(fill_type_to_str(fill));
1267 return 1;
1268}
1269
1270static SkString segment_masks_to_str(uint32_t segmentMasks) {
1271 SkString result;
1272 bool first = true;
1273 if (SkPath::kLine_SegmentMask & segmentMasks) {
1274 result.append("line");
1275 first = false;
1276 SkDEBUGCODE(segmentMasks &= ~SkPath::kLine_SegmentMask;)
1277 }
1278 if (SkPath::kQuad_SegmentMask & segmentMasks) {
1279 if (!first) {
1280 result.append(" ");
1281 }
1282 result.append("quad");
1283 first = false;
1284 SkDEBUGCODE(segmentMasks &= ~SkPath::kQuad_SegmentMask;)
1285 }
1286 if (SkPath::kConic_SegmentMask & segmentMasks) {
1287 if (!first) {
1288 result.append(" ");
1289 }
1290 result.append("conic");
1291 first = false;
1292 SkDEBUGCODE(segmentMasks &= ~SkPath::kConic_SegmentMask;)
1293 }
1294 if (SkPath::kCubic_SegmentMask & segmentMasks) {
1295 if (!first) {
1296 result.append(" ");
1297 }
1298 result.append("cubic");
1299 SkDEBUGCODE(segmentMasks &= ~SkPath::kCubic_SegmentMask;)
1300 }
1301 SkASSERT(0 == segmentMasks);
1302 return result;
1303}
1304
krajcevski95498ed2014-08-18 08:02:33 -07001305static int lpath_getSegmentTypes(lua_State* L) {
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001306 uint32_t segMasks = get_obj<SkPath>(L, 1)->getSegmentMasks();
1307 SkLua(L).pushString(segment_masks_to_str(segMasks));
1308 return 1;
1309}
1310
1311static int lpath_isConvex(lua_State* L) {
Mike Reed30bc5272019-11-22 18:34:02 +00001312 bool isConvex = get_obj<SkPath>(L, 1)->isConvex();
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001313 SkLua(L).pushBool(isConvex);
1314 return 1;
1315}
1316
reed@google.com74ce6f02013-05-22 15:13:18 +00001317static int lpath_isEmpty(lua_State* L) {
1318 lua_pushboolean(L, get_obj<SkPath>(L, 1)->isEmpty());
1319 return 1;
1320}
1321
1322static int lpath_isRect(lua_State* L) {
1323 SkRect r;
1324 bool pred = get_obj<SkPath>(L, 1)->isRect(&r);
1325 int ret_count = 1;
1326 lua_pushboolean(L, pred);
1327 if (pred) {
1328 SkLua(L).pushRect(r);
1329 ret_count += 1;
1330 }
1331 return ret_count;
1332}
1333
commit-bot@chromium.orgc5302082014-02-26 21:38:47 +00001334static int lpath_countPoints(lua_State* L) {
1335 lua_pushinteger(L, get_obj<SkPath>(L, 1)->countPoints());
1336 return 1;
1337}
1338
hstern0b401ce2016-08-02 09:17:59 -07001339static int lpath_getVerbs(lua_State* L) {
1340 const SkPath* path = get_obj<SkPath>(L, 1);
1341 SkPath::Iter iter(*path, false);
1342 SkPoint pts[4];
1343
1344 lua_newtable(L);
1345
1346 bool done = false;
1347 int i = 0;
1348 do {
Mike Reedba7e9a62019-08-16 13:30:34 -04001349 switch (iter.next(pts)) {
hstern0b401ce2016-08-02 09:17:59 -07001350 case SkPath::kMove_Verb:
1351 setarray_string(L, ++i, "move");
1352 break;
1353 case SkPath::kClose_Verb:
1354 setarray_string(L, ++i, "close");
1355 break;
1356 case SkPath::kLine_Verb:
1357 setarray_string(L, ++i, "line");
1358 break;
1359 case SkPath::kQuad_Verb:
1360 setarray_string(L, ++i, "quad");
1361 break;
1362 case SkPath::kConic_Verb:
1363 setarray_string(L, ++i, "conic");
1364 break;
1365 case SkPath::kCubic_Verb:
1366 setarray_string(L, ++i, "cubic");
1367 break;
1368 case SkPath::kDone_Verb:
1369 setarray_string(L, ++i, "done");
1370 done = true;
1371 break;
1372 }
1373 } while (!done);
1374
1375 return 1;
1376}
1377
reed@google.com74ce6f02013-05-22 15:13:18 +00001378static int lpath_reset(lua_State* L) {
1379 get_obj<SkPath>(L, 1)->reset();
1380 return 0;
1381}
1382
1383static int lpath_moveTo(lua_State* L) {
1384 get_obj<SkPath>(L, 1)->moveTo(lua2scalar(L, 2), lua2scalar(L, 3));
1385 return 0;
1386}
1387
1388static int lpath_lineTo(lua_State* L) {
1389 get_obj<SkPath>(L, 1)->lineTo(lua2scalar(L, 2), lua2scalar(L, 3));
1390 return 0;
1391}
1392
1393static int lpath_quadTo(lua_State* L) {
1394 get_obj<SkPath>(L, 1)->quadTo(lua2scalar(L, 2), lua2scalar(L, 3),
1395 lua2scalar(L, 4), lua2scalar(L, 5));
1396 return 0;
1397}
1398
1399static int lpath_cubicTo(lua_State* L) {
1400 get_obj<SkPath>(L, 1)->cubicTo(lua2scalar(L, 2), lua2scalar(L, 3),
1401 lua2scalar(L, 4), lua2scalar(L, 5),
1402 lua2scalar(L, 6), lua2scalar(L, 7));
1403 return 0;
1404}
1405
1406static int lpath_close(lua_State* L) {
1407 get_obj<SkPath>(L, 1)->close();
1408 return 0;
1409}
1410
1411static int lpath_gc(lua_State* L) {
1412 get_obj<SkPath>(L, 1)->~SkPath();
1413 return 0;
1414}
1415
1416static const struct luaL_Reg gSkPath_Methods[] = {
1417 { "getBounds", lpath_getBounds },
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001418 { "getFillType", lpath_getFillType },
krajcevski95498ed2014-08-18 08:02:33 -07001419 { "getSegmentTypes", lpath_getSegmentTypes },
hstern0b401ce2016-08-02 09:17:59 -07001420 { "getVerbs", lpath_getVerbs },
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001421 { "isConvex", lpath_isConvex },
reed@google.com74ce6f02013-05-22 15:13:18 +00001422 { "isEmpty", lpath_isEmpty },
1423 { "isRect", lpath_isRect },
commit-bot@chromium.orgc5302082014-02-26 21:38:47 +00001424 { "countPoints", lpath_countPoints },
reed@google.com74ce6f02013-05-22 15:13:18 +00001425 { "reset", lpath_reset },
1426 { "moveTo", lpath_moveTo },
1427 { "lineTo", lpath_lineTo },
1428 { "quadTo", lpath_quadTo },
1429 { "cubicTo", lpath_cubicTo },
1430 { "close", lpath_close },
1431 { "__gc", lpath_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001432 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001433};
1434
1435///////////////////////////////////////////////////////////////////////////////
1436
1437static const char* rrect_type(const SkRRect& rr) {
1438 switch (rr.getType()) {
reed@google.com74ce6f02013-05-22 15:13:18 +00001439 case SkRRect::kEmpty_Type: return "empty";
1440 case SkRRect::kRect_Type: return "rect";
1441 case SkRRect::kOval_Type: return "oval";
1442 case SkRRect::kSimple_Type: return "simple";
commit-bot@chromium.orgf338d7c2014-03-17 21:17:30 +00001443 case SkRRect::kNinePatch_Type: return "nine-patch";
reed@google.com74ce6f02013-05-22 15:13:18 +00001444 case SkRRect::kComplex_Type: return "complex";
1445 }
mtklein@google.com330313a2013-08-22 15:37:26 +00001446 SkDEBUGFAIL("never get here");
reed@google.com74ce6f02013-05-22 15:13:18 +00001447 return "";
1448}
1449
1450static int lrrect_rect(lua_State* L) {
1451 SkLua(L).pushRect(get_obj<SkRRect>(L, 1)->rect());
1452 return 1;
1453}
1454
1455static int lrrect_type(lua_State* L) {
1456 lua_pushstring(L, rrect_type(*get_obj<SkRRect>(L, 1)));
1457 return 1;
1458}
1459
1460static int lrrect_radii(lua_State* L) {
reed@google.com7fa2a652014-01-27 13:42:58 +00001461 int corner = SkToInt(lua_tointeger(L, 2));
reed@google.com74ce6f02013-05-22 15:13:18 +00001462 SkVector v;
1463 if (corner < 0 || corner > 3) {
1464 SkDebugf("bad corner index %d", corner);
1465 v.set(0, 0);
1466 } else {
1467 v = get_obj<SkRRect>(L, 1)->radii((SkRRect::Corner)corner);
1468 }
1469 lua_pushnumber(L, v.fX);
1470 lua_pushnumber(L, v.fY);
1471 return 2;
1472}
1473
1474static int lrrect_gc(lua_State* L) {
1475 get_obj<SkRRect>(L, 1)->~SkRRect();
1476 return 0;
1477}
1478
1479static const struct luaL_Reg gSkRRect_Methods[] = {
1480 { "rect", lrrect_rect },
1481 { "type", lrrect_type },
1482 { "radii", lrrect_radii },
1483 { "__gc", lrrect_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001484 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001485};
1486
1487///////////////////////////////////////////////////////////////////////////////
1488
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001489static int limage_width(lua_State* L) {
1490 lua_pushinteger(L, get_ref<SkImage>(L, 1)->width());
1491 return 1;
1492}
1493
1494static int limage_height(lua_State* L) {
1495 lua_pushinteger(L, get_ref<SkImage>(L, 1)->height());
1496 return 1;
1497}
1498
reed7a72c672014-11-07 10:23:55 -08001499static int limage_newShader(lua_State* L) {
Mike Reedfae8fce2019-04-03 10:27:45 -04001500 SkTileMode tmode = SkTileMode::kClamp;
halcanary96fcdcc2015-08-27 07:41:13 -07001501 const SkMatrix* localM = nullptr;
reed5671c5b2016-03-09 14:47:34 -08001502 push_ref(L, get_ref<SkImage>(L, 1)->makeShader(tmode, tmode, localM));
reed7a72c672014-11-07 10:23:55 -08001503 return 1;
1504}
1505
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001506static int limage_gc(lua_State* L) {
1507 get_ref<SkImage>(L, 1)->unref();
1508 return 0;
1509}
1510
1511static const struct luaL_Reg gSkImage_Methods[] = {
1512 { "width", limage_width },
1513 { "height", limage_height },
reed7a72c672014-11-07 10:23:55 -08001514 { "newShader", limage_newShader },
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001515 { "__gc", limage_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001516 { nullptr, nullptr }
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001517};
1518
1519///////////////////////////////////////////////////////////////////////////////
1520
reed485557f2014-10-12 10:36:47 -07001521static int lsurface_width(lua_State* L) {
1522 lua_pushinteger(L, get_ref<SkSurface>(L, 1)->width());
1523 return 1;
1524}
1525
1526static int lsurface_height(lua_State* L) {
1527 lua_pushinteger(L, get_ref<SkSurface>(L, 1)->height());
1528 return 1;
1529}
1530
1531static int lsurface_getCanvas(lua_State* L) {
1532 SkCanvas* canvas = get_ref<SkSurface>(L, 1)->getCanvas();
halcanary96fcdcc2015-08-27 07:41:13 -07001533 if (nullptr == canvas) {
reed485557f2014-10-12 10:36:47 -07001534 lua_pushnil(L);
1535 } else {
Mike Reed5df49342016-11-12 08:06:55 -06001536 push_ptr(L, canvas);
reed485557f2014-10-12 10:36:47 -07001537 // note: we don't unref canvas, since getCanvas did not ref it.
1538 // warning: this is weird: now Lua owns a ref on this canvas, but what if they let
1539 // the real owner (the surface) go away, but still hold onto the canvas?
1540 // *really* we want to sort of ref the surface again, but have the native object
1541 // know that it is supposed to be treated as a canvas...
1542 }
1543 return 1;
1544}
1545
1546static int lsurface_newImageSnapshot(lua_State* L) {
reed9ce9d672016-03-17 10:51:11 -07001547 sk_sp<SkImage> image = get_ref<SkSurface>(L, 1)->makeImageSnapshot();
1548 if (!image) {
reed485557f2014-10-12 10:36:47 -07001549 lua_pushnil(L);
1550 } else {
reed9ce9d672016-03-17 10:51:11 -07001551 push_ref(L, image);
reed485557f2014-10-12 10:36:47 -07001552 }
1553 return 1;
1554}
1555
1556static int lsurface_newSurface(lua_State* L) {
1557 int width = lua2int_def(L, 2, 0);
reed96affcd2014-10-13 12:38:04 -07001558 int height = lua2int_def(L, 3, 0);
reed485557f2014-10-12 10:36:47 -07001559 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
reede8f30622016-03-23 18:59:25 -07001560 auto surface = get_ref<SkSurface>(L, 1)->makeSurface(info);
halcanary96fcdcc2015-08-27 07:41:13 -07001561 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -07001562 lua_pushnil(L);
1563 } else {
reede8f30622016-03-23 18:59:25 -07001564 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -07001565 }
1566 return 1;
1567}
1568
1569static int lsurface_gc(lua_State* L) {
1570 get_ref<SkSurface>(L, 1)->unref();
1571 return 0;
1572}
1573
1574static const struct luaL_Reg gSkSurface_Methods[] = {
1575 { "width", lsurface_width },
1576 { "height", lsurface_height },
1577 { "getCanvas", lsurface_getCanvas },
1578 { "newImageSnapshot", lsurface_newImageSnapshot },
1579 { "newSurface", lsurface_newSurface },
1580 { "__gc", lsurface_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001581 { nullptr, nullptr }
reed485557f2014-10-12 10:36:47 -07001582};
1583
1584///////////////////////////////////////////////////////////////////////////////
1585
reed96affcd2014-10-13 12:38:04 -07001586static int lpicturerecorder_beginRecording(lua_State* L) {
1587 const SkScalar w = lua2scalar_def(L, 2, -1);
1588 const SkScalar h = lua2scalar_def(L, 3, -1);
1589 if (w <= 0 || h <= 0) {
1590 lua_pushnil(L);
1591 return 1;
1592 }
1593
1594 SkCanvas* canvas = get_obj<SkPictureRecorder>(L, 1)->beginRecording(w, h);
halcanary96fcdcc2015-08-27 07:41:13 -07001595 if (nullptr == canvas) {
reed96affcd2014-10-13 12:38:04 -07001596 lua_pushnil(L);
1597 return 1;
1598 }
1599
Mike Reed5df49342016-11-12 08:06:55 -06001600 push_ptr(L, canvas);
reed96affcd2014-10-13 12:38:04 -07001601 return 1;
1602}
1603
1604static int lpicturerecorder_getCanvas(lua_State* L) {
1605 SkCanvas* canvas = get_obj<SkPictureRecorder>(L, 1)->getRecordingCanvas();
halcanary96fcdcc2015-08-27 07:41:13 -07001606 if (nullptr == canvas) {
reed96affcd2014-10-13 12:38:04 -07001607 lua_pushnil(L);
1608 return 1;
1609 }
Mike Reed5df49342016-11-12 08:06:55 -06001610 push_ptr(L, canvas);
reed96affcd2014-10-13 12:38:04 -07001611 return 1;
1612}
1613
1614static int lpicturerecorder_endRecording(lua_State* L) {
reedca2622b2016-03-18 07:25:55 -07001615 sk_sp<SkPicture> pic = get_obj<SkPictureRecorder>(L, 1)->finishRecordingAsPicture();
1616 if (!pic) {
reed96affcd2014-10-13 12:38:04 -07001617 lua_pushnil(L);
1618 return 1;
1619 }
reedca2622b2016-03-18 07:25:55 -07001620 push_ref(L, std::move(pic));
reed96affcd2014-10-13 12:38:04 -07001621 return 1;
1622}
1623
1624static int lpicturerecorder_gc(lua_State* L) {
1625 get_obj<SkPictureRecorder>(L, 1)->~SkPictureRecorder();
1626 return 0;
1627}
1628
1629static const struct luaL_Reg gSkPictureRecorder_Methods[] = {
1630 { "beginRecording", lpicturerecorder_beginRecording },
1631 { "getCanvas", lpicturerecorder_getCanvas },
1632 { "endRecording", lpicturerecorder_endRecording },
1633 { "__gc", lpicturerecorder_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001634 { nullptr, nullptr }
reed96affcd2014-10-13 12:38:04 -07001635};
1636
1637///////////////////////////////////////////////////////////////////////////////
1638
1639static int lpicture_width(lua_State* L) {
1640 lua_pushnumber(L, get_ref<SkPicture>(L, 1)->cullRect().width());
1641 return 1;
1642}
1643
1644static int lpicture_height(lua_State* L) {
1645 lua_pushnumber(L, get_ref<SkPicture>(L, 1)->cullRect().height());
1646 return 1;
1647}
1648
1649static int lpicture_gc(lua_State* L) {
1650 get_ref<SkPicture>(L, 1)->unref();
1651 return 0;
1652}
1653
1654static const struct luaL_Reg gSkPicture_Methods[] = {
1655 { "width", lpicture_width },
1656 { "height", lpicture_height },
1657 { "__gc", lpicture_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001658 { nullptr, nullptr }
reed96affcd2014-10-13 12:38:04 -07001659};
1660
1661///////////////////////////////////////////////////////////////////////////////
1662
reed1b6ab442014-11-03 19:55:41 -08001663static int ltextblob_bounds(lua_State* L) {
1664 SkLua(L).pushRect(get_ref<SkTextBlob>(L, 1)->bounds());
1665 return 1;
1666}
1667
1668static int ltextblob_gc(lua_State* L) {
1669 SkSafeUnref(get_ref<SkTextBlob>(L, 1));
1670 return 0;
1671}
1672
1673static const struct luaL_Reg gSkTextBlob_Methods[] = {
1674 { "bounds", ltextblob_bounds },
1675 { "__gc", ltextblob_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001676 { nullptr, nullptr }
reed1b6ab442014-11-03 19:55:41 -08001677};
1678
1679///////////////////////////////////////////////////////////////////////////////
1680
reed36c9c112014-11-04 10:58:42 -08001681static int ltypeface_getFamilyName(lua_State* L) {
1682 SkString str;
1683 get_ref<SkTypeface>(L, 1)->getFamilyName(&str);
1684 lua_pushstring(L, str.c_str());
1685 return 1;
1686}
1687
1688static int ltypeface_getStyle(lua_State* L) {
Ben Wagner26308e12017-08-08 15:23:47 -04001689 push_obj(L, get_ref<SkTypeface>(L, 1)->fontStyle());
reed36c9c112014-11-04 10:58:42 -08001690 return 1;
1691}
1692
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001693static int ltypeface_gc(lua_State* L) {
commit-bot@chromium.org77887af2013-12-17 14:28:19 +00001694 SkSafeUnref(get_ref<SkTypeface>(L, 1));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001695 return 0;
1696}
1697
1698static const struct luaL_Reg gSkTypeface_Methods[] = {
reed36c9c112014-11-04 10:58:42 -08001699 { "getFamilyName", ltypeface_getFamilyName },
1700 { "getStyle", ltypeface_getStyle },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001701 { "__gc", ltypeface_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001702 { nullptr, nullptr }
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001703};
1704
1705///////////////////////////////////////////////////////////////////////////////
1706
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001707static int lfontstyle_weight(lua_State* L) {
1708 lua_pushnumber(L, get_ref<SkFontStyle>(L, 1)->weight());
1709 return 1;
1710}
1711
1712static int lfontstyle_width(lua_State* L) {
1713 lua_pushnumber(L, get_ref<SkFontStyle>(L, 1)->width());
1714 return 1;
1715}
1716
1717static int lfontstyle_slant(lua_State* L) {
1718 lua_pushnumber(L, get_ref<SkFontStyle>(L, 1)->slant());
1719 return 1;
1720}
1721
1722static int lfontstyle_gc(lua_State* L) {
1723 get_obj<SkFontStyle>(L, 1)->~SkFontStyle();
1724 return 0;
1725}
1726
1727static const struct luaL_Reg gSkFontStyle_Methods[] = {
1728 { "weight", lfontstyle_weight },
1729 { "width", lfontstyle_width },
1730 { "slant", lfontstyle_slant },
1731 { "__gc", lfontstyle_gc },
1732 { nullptr, nullptr }
1733};
1734
1735///////////////////////////////////////////////////////////////////////////////
1736
reed@google.com74ce6f02013-05-22 15:13:18 +00001737class AutoCallLua {
1738public:
1739 AutoCallLua(lua_State* L, const char func[], const char verb[]) : fL(L) {
1740 lua_getglobal(L, func);
1741 if (!lua_isfunction(L, -1)) {
1742 int t = lua_type(L, -1);
1743 SkDebugf("--- expected function %d\n", t);
1744 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001745
reed@google.com74ce6f02013-05-22 15:13:18 +00001746 lua_newtable(L);
1747 setfield_string(L, "verb", verb);
1748 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001749
reed@google.com74ce6f02013-05-22 15:13:18 +00001750 ~AutoCallLua() {
1751 if (lua_pcall(fL, 1, 0, 0) != LUA_OK) {
1752 SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
1753 }
1754 lua_settop(fL, -1);
1755 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001756
reed@google.com74ce6f02013-05-22 15:13:18 +00001757private:
1758 lua_State* fL;
1759};
1760
1761#define AUTO_LUA(verb) AutoCallLua acl(fL, fFunc.c_str(), verb)
1762
1763///////////////////////////////////////////////////////////////////////////////
1764
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001765static int lsk_newDocumentPDF(lua_State* L) {
Mike Reed7ff6ca52018-01-08 14:45:31 -05001766 const char* filename = nullptr;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001767 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
Mike Reed7ff6ca52018-01-08 14:45:31 -05001768 filename = lua_tolstring(L, 1, nullptr);
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001769 }
Mike Reed7ff6ca52018-01-08 14:45:31 -05001770 if (!filename) {
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001771 return 0;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001772 }
Mike Kleinf46d5ca2019-12-11 10:45:01 -05001773 auto file = std::make_unique<SkFILEWStream>(filename);
Mike Reed7ff6ca52018-01-08 14:45:31 -05001774 if (!file->isValid()) {
1775 return 0;
1776 }
Hal Canary3026d4b2019-01-07 10:00:48 -05001777 auto doc = SkPDF::MakeDocument(file.get());
Mike Reed7ff6ca52018-01-08 14:45:31 -05001778 if (!doc) {
1779 return 0;
1780 }
1781 push_ptr(L, new DocHolder{std::move(doc), std::move(file)});
1782 return 1;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001783}
1784
reed468b1812014-10-19 11:42:54 -07001785static int lsk_newBlurImageFilter(lua_State* L) {
1786 SkScalar sigmaX = lua2scalar_def(L, 1, 0);
1787 SkScalar sigmaY = lua2scalar_def(L, 2, 0);
Michael Ludwig06eacf42019-08-01 16:02:27 -04001788 sk_sp<SkImageFilter> imf(SkImageFilters::Blur(sigmaX, sigmaY, nullptr));
robertphillips6e7025a2016-04-04 04:31:25 -07001789 if (!imf) {
reed468b1812014-10-19 11:42:54 -07001790 lua_pushnil(L);
1791 } else {
robertphillips6e7025a2016-04-04 04:31:25 -07001792 push_ref(L, std::move(imf));
reed9fbc3f32014-10-21 07:12:58 -07001793 }
1794 return 1;
1795}
1796
1797static int lsk_newLinearGradient(lua_State* L) {
1798 SkScalar x0 = lua2scalar_def(L, 1, 0);
1799 SkScalar y0 = lua2scalar_def(L, 2, 0);
1800 SkColor c0 = lua2color(L, 3);
1801 SkScalar x1 = lua2scalar_def(L, 4, 0);
1802 SkScalar y1 = lua2scalar_def(L, 5, 0);
1803 SkColor c1 = lua2color(L, 6);
1804
1805 SkPoint pts[] = { { x0, y0 }, { x1, y1 } };
1806 SkColor colors[] = { c0, c1 };
Mike Reedfae8fce2019-04-03 10:27:45 -04001807 sk_sp<SkShader> s(SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp));
reed2ad1aa62016-03-09 09:50:50 -08001808 if (!s) {
reed9fbc3f32014-10-21 07:12:58 -07001809 lua_pushnil(L);
1810 } else {
reed2ad1aa62016-03-09 09:50:50 -08001811 push_ref(L, std::move(s));
reed468b1812014-10-19 11:42:54 -07001812 }
1813 return 1;
1814}
1815
reedbdc49ae2014-10-14 09:34:52 -07001816static int lsk_newMatrix(lua_State* L) {
1817 push_new<SkMatrix>(L)->reset();
1818 return 1;
1819}
1820
reed@google.com3597b732013-05-22 20:12:50 +00001821static int lsk_newPaint(lua_State* L) {
1822 push_new<SkPaint>(L);
1823 return 1;
1824}
1825
1826static int lsk_newPath(lua_State* L) {
1827 push_new<SkPath>(L);
1828 return 1;
1829}
1830
reed96affcd2014-10-13 12:38:04 -07001831static int lsk_newPictureRecorder(lua_State* L) {
1832 push_new<SkPictureRecorder>(L);
1833 return 1;
1834}
1835
reed@google.com3597b732013-05-22 20:12:50 +00001836static int lsk_newRRect(lua_State* L) {
reedbdc49ae2014-10-14 09:34:52 -07001837 push_new<SkRRect>(L)->setEmpty();
reed@google.com3597b732013-05-22 20:12:50 +00001838 return 1;
1839}
1840
reed1b6ab442014-11-03 19:55:41 -08001841// Sk.newTextBlob(text, rect, paint)
1842static int lsk_newTextBlob(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07001843 const char* text = lua_tolstring(L, 1, nullptr);
reed1b6ab442014-11-03 19:55:41 -08001844 SkRect bounds;
1845 lua2rect(L, 2, &bounds);
reed1b6ab442014-11-03 19:55:41 -08001846
Ben Wagnerb0591942019-02-15 14:46:18 -05001847 std::unique_ptr<SkShaper> shaper = SkShaper::Make();
reed1b6ab442014-11-03 19:55:41 -08001848
Mike Reed5f528e52019-01-28 10:57:28 -05001849 // TODO: restore this logic based on SkFont instead of SkPaint
1850#if 0
Mike Reede5f9cfa2019-01-10 13:55:35 -05001851 const SkPaint& paint = *get_obj<SkPaint>(L, 3);
Hal Canary2a1848d2018-11-26 17:23:24 -05001852 SkFont font = SkFont::LEGACY_ExtractFromPaint(paint);
Mike Reede5f9cfa2019-01-10 13:55:35 -05001853#else
1854 SkFont font;
1855#endif
Ben Wagner3bdb69c2019-04-01 19:01:09 -04001856 SkTextBlobBuilderRunHandler builder(text, { bounds.left(), bounds.top() });
1857 shaper->shape(text, strlen(text), font, true, bounds.width(), &builder);
Herb Derby1724db12018-05-22 12:01:50 -04001858
Florin Malita9867f612018-12-12 10:54:49 -05001859 push_ref<SkTextBlob>(L, builder.makeBlob());
Ben Wagner3bdb69c2019-04-01 19:01:09 -04001860 SkLua(L).pushScalar(builder.endPoint().fY);
reed1b6ab442014-11-03 19:55:41 -08001861 return 2;
1862}
1863
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001864static int lsk_newTypeface(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07001865 const char* name = nullptr;
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001866 SkFontStyle style;
skia.committer@gmail.com63193672013-06-08 07:01:13 +00001867
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001868 int count = lua_gettop(L);
1869 if (count > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001870 name = lua_tolstring(L, 1, nullptr);
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001871 if (count > 1) {
1872 SkFontStyle* passedStyle = get_obj<SkFontStyle>(L, 2);
1873 if (passedStyle) {
1874 style = *passedStyle;
1875 }
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001876 }
1877 }
1878
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001879 sk_sp<SkTypeface> face(SkTypeface::MakeFromName(name, style));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001880// SkDebugf("---- name <%s> style=%d, face=%p ref=%d\n", name, style, face, face->getRefCnt());
halcanary96fcdcc2015-08-27 07:41:13 -07001881 if (nullptr == face) {
bungeman13b9c952016-05-12 10:09:30 -07001882 face = SkTypeface::MakeDefault();
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001883 }
bungeman13b9c952016-05-12 10:09:30 -07001884 push_ref(L, std::move(face));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001885 return 1;
1886}
reed@google.com3597b732013-05-22 20:12:50 +00001887
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001888static int lsk_newFontStyle(lua_State* L) {
1889 int count = lua_gettop(L);
1890 int weight = SkFontStyle::kNormal_Weight;
1891 int width = SkFontStyle::kNormal_Width;
1892 SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant;
1893 if (count >= 1 && lua_isnumber(L, 1)) {
1894 weight = lua_tointegerx(L, 1, nullptr);
1895 }
1896 if (count >= 2 && lua_isnumber(L, 2)) {
1897 width = lua_tointegerx(L, 2, nullptr);
1898 }
1899 if (count >= 3 && lua_isnumber(L, 3)) {
1900 slant = static_cast<SkFontStyle::Slant>(lua_tointegerx(L, 3, nullptr));
1901 }
1902 push_new<SkFontStyle>(L, weight, width, slant);
1903 return 1;
1904}
1905
reed485557f2014-10-12 10:36:47 -07001906static int lsk_newRasterSurface(lua_State* L) {
reed7b864662014-11-04 13:24:47 -08001907 int width = lua2int_def(L, 1, 0);
reed485557f2014-10-12 10:36:47 -07001908 int height = lua2int_def(L, 2, 0);
1909 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
robertphillips702edbd2015-06-23 06:26:08 -07001910 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
reede8f30622016-03-23 18:59:25 -07001911 auto surface = SkSurface::MakeRaster(info, &props);
halcanary96fcdcc2015-08-27 07:41:13 -07001912 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -07001913 lua_pushnil(L);
1914 } else {
reede8f30622016-03-23 18:59:25 -07001915 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -07001916 }
1917 return 1;
1918}
1919
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001920static int lsk_loadImage(lua_State* L) {
1921 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001922 const char* name = lua_tolstring(L, 1, nullptr);
reed9ce9d672016-03-17 10:51:11 -07001923 sk_sp<SkData> data(SkData::MakeFromFileName(name));
1924 if (data) {
1925 auto image = SkImage::MakeFromEncoded(std::move(data));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001926 if (image) {
reed9ce9d672016-03-17 10:51:11 -07001927 push_ref(L, std::move(image));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001928 return 1;
1929 }
1930 }
1931 }
1932 return 0;
1933}
1934
reed@google.com3597b732013-05-22 20:12:50 +00001935static void register_Sk(lua_State* L) {
1936 lua_newtable(L);
1937 lua_pushvalue(L, -1);
1938 lua_setglobal(L, "Sk");
1939 // the Sk table is still on top
1940
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001941 setfield_function(L, "newDocumentPDF", lsk_newDocumentPDF);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001942 setfield_function(L, "loadImage", lsk_loadImage);
reed468b1812014-10-19 11:42:54 -07001943 setfield_function(L, "newBlurImageFilter", lsk_newBlurImageFilter);
reed9fbc3f32014-10-21 07:12:58 -07001944 setfield_function(L, "newLinearGradient", lsk_newLinearGradient);
reedbdc49ae2014-10-14 09:34:52 -07001945 setfield_function(L, "newMatrix", lsk_newMatrix);
reed@google.com3597b732013-05-22 20:12:50 +00001946 setfield_function(L, "newPaint", lsk_newPaint);
1947 setfield_function(L, "newPath", lsk_newPath);
reed96affcd2014-10-13 12:38:04 -07001948 setfield_function(L, "newPictureRecorder", lsk_newPictureRecorder);
reed@google.com3597b732013-05-22 20:12:50 +00001949 setfield_function(L, "newRRect", lsk_newRRect);
reed485557f2014-10-12 10:36:47 -07001950 setfield_function(L, "newRasterSurface", lsk_newRasterSurface);
reed1b6ab442014-11-03 19:55:41 -08001951 setfield_function(L, "newTextBlob", lsk_newTextBlob);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001952 setfield_function(L, "newTypeface", lsk_newTypeface);
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001953 setfield_function(L, "newFontStyle", lsk_newFontStyle);
reed@google.com3597b732013-05-22 20:12:50 +00001954 lua_pop(L, 1); // pop off the Sk table
1955}
1956
reed@google.com74ce6f02013-05-22 15:13:18 +00001957#define REG_CLASS(L, C) \
1958 do { \
reed@google.com3597b732013-05-22 20:12:50 +00001959 luaL_newmetatable(L, get_mtname<C>()); \
reed@google.com74ce6f02013-05-22 15:13:18 +00001960 lua_pushvalue(L, -1); \
1961 lua_setfield(L, -2, "__index"); \
1962 luaL_setfuncs(L, g##C##_Methods, 0); \
1963 lua_pop(L, 1); /* pop off the meta-table */ \
1964 } while (0)
1965
1966void SkLua::Load(lua_State* L) {
reed@google.com3597b732013-05-22 20:12:50 +00001967 register_Sk(L);
reed@google.com74ce6f02013-05-22 15:13:18 +00001968 REG_CLASS(L, SkCanvas);
reed22a517f2015-12-04 20:45:59 -08001969 REG_CLASS(L, SkColorFilter);
Mike Reed7ff6ca52018-01-08 14:45:31 -05001970 REG_CLASS(L, DocHolder);
Mike Reed91919132019-01-02 12:21:01 -05001971 REG_CLASS(L, SkFont);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001972 REG_CLASS(L, SkImage);
reed468b1812014-10-19 11:42:54 -07001973 REG_CLASS(L, SkImageFilter);
reed1b6ab442014-11-03 19:55:41 -08001974 REG_CLASS(L, SkMatrix);
reed@google.com74ce6f02013-05-22 15:13:18 +00001975 REG_CLASS(L, SkPaint);
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001976 REG_CLASS(L, SkPath);
1977 REG_CLASS(L, SkPathEffect);
reed96affcd2014-10-13 12:38:04 -07001978 REG_CLASS(L, SkPicture);
1979 REG_CLASS(L, SkPictureRecorder);
reed@google.com74ce6f02013-05-22 15:13:18 +00001980 REG_CLASS(L, SkRRect);
reed@google.com5fdc9832013-07-24 15:47:52 +00001981 REG_CLASS(L, SkShader);
reed485557f2014-10-12 10:36:47 -07001982 REG_CLASS(L, SkSurface);
reed1b6ab442014-11-03 19:55:41 -08001983 REG_CLASS(L, SkTextBlob);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001984 REG_CLASS(L, SkTypeface);
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001985 REG_CLASS(L, SkFontStyle);
reed@google.com74ce6f02013-05-22 15:13:18 +00001986}
zachr@google.com28c27c82013-06-20 17:15:05 +00001987
reed@google.com7bce9982013-06-20 17:40:21 +00001988extern "C" int luaopen_skia(lua_State* L);
zachr@google.com28c27c82013-06-20 17:15:05 +00001989extern "C" int luaopen_skia(lua_State* L) {
1990 SkLua::Load(L);
1991 return 0;
1992}