blob: 7ef3b2acb8174b6e9ff84ac1daf81e941b728c47 [file] [log] [blame]
reed@google.com74ce6f02013-05-22 15:13:18 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkLua.h"
bsalomon@google.com4ebe3822014-02-26 20:22:32 +00009
10#if SK_SUPPORT_GPU
Mike Reed4f364fd2017-01-19 14:34:51 -050011//#include "GrReducedClip.h"
bsalomon@google.com4ebe3822014-02-26 20:22:32 +000012#endif
13
reed468b1812014-10-19 11:42:54 -070014#include "SkBlurImageFilter.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000015#include "SkCanvas.h"
reed22a517f2015-12-04 20:45:59 -080016#include "SkColorFilter.h"
mike@reedtribe.org792bbd12013-06-11 02:20:28 +000017#include "SkData.h"
Mike Reed91919132019-01-02 12:21:01 -050018#include "SkFont.h"
Ben Wagnerc6c10b42017-08-07 09:56:21 -040019#include "SkFontStyle.h"
reed9fbc3f32014-10-21 07:12:58 -070020#include "SkGradientShader.h"
mike@reedtribe.org792bbd12013-06-11 02:20:28 +000021#include "SkImage.h"
Mike Reed7ff6ca52018-01-08 14:45:31 -050022#include "SkMakeUnique.h"
mike@reedtribe.org792bbd12013-06-11 02:20:28 +000023#include "SkMatrix.h"
Hal Canary23564b92018-09-07 14:33:14 -040024#include "SkPDFDocument.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000025#include "SkPaint.h"
26#include "SkPath.h"
reed96affcd2014-10-13 12:38:04 -070027#include "SkPictureRecorder.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000028#include "SkRRect.h"
Herb Derby1724db12018-05-22 12:01:50 -040029#include "SkShaper.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000030#include "SkString.h"
reed485557f2014-10-12 10:36:47 -070031#include "SkSurface.h"
fmalitab7425172014-08-26 07:56:44 -070032#include "SkTextBlob.h"
Hal Canaryc640d0d2018-06-13 09:59:02 -040033#include "SkTo.h"
reed@google.come3823fd2013-05-30 18:55:14 +000034#include "SkTypeface.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@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000414 rect->set(getfield_scalar_default(L, index, "left", 0),
415 getfield_scalar_default(L, index, "top", 0),
reed@google.com74ce6f02013-05-22 15:13:18 +0000416 getfield_scalar(L, index, "right"),
417 getfield_scalar(L, index, "bottom"));
418 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 Reede5f9cfa2019-01-10 13:55:35 -0500559#ifdef SK_SUPPORT_LEGACY_PAINT_FONT_FIELDS
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000560 if (lua_isstring(L, 2) && lua_isnumber(L, 3) && lua_isnumber(L, 4)) {
561 size_t len;
562 const char* text = lua_tolstring(L, 2, &len);
Hal Canary292ece82019-01-09 10:59:08 -0500563 get_ref<SkCanvas>(L, 1)->drawSimpleText(
564 text, len, kUTF8_SkTextEncoding,
565 lua2scalar(L, 3), lua2scalar(L, 4),
566 SkFont::LEGACY_ExtractFromPaint(*get_obj<SkPaint>(L, 5)),
567 *get_obj<SkPaint>(L, 5));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000568 }
Mike Reede5f9cfa2019-01-10 13:55:35 -0500569#endif
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000570 return 0;
571}
572
reed1b6ab442014-11-03 19:55:41 -0800573static int lcanvas_drawTextBlob(lua_State* L) {
574 const SkTextBlob* blob = get_ref<SkTextBlob>(L, 2);
575 SkScalar x = lua2scalar(L, 3);
576 SkScalar y = lua2scalar(L, 4);
577 const SkPaint& paint = *get_obj<SkPaint>(L, 5);
578 get_ref<SkCanvas>(L, 1)->drawTextBlob(blob, x, y, paint);
579 return 0;
580}
581
reed@google.com74ce6f02013-05-22 15:13:18 +0000582static int lcanvas_getSaveCount(lua_State* L) {
583 lua_pushnumber(L, get_ref<SkCanvas>(L, 1)->getSaveCount());
584 return 1;
585}
586
587static int lcanvas_getTotalMatrix(lua_State* L) {
588 SkLua(L).pushMatrix(get_ref<SkCanvas>(L, 1)->getTotalMatrix());
589 return 1;
590}
591
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000592static int lcanvas_save(lua_State* L) {
593 lua_pushinteger(L, get_ref<SkCanvas>(L, 1)->save());
594 return 1;
595}
596
reed86217d82014-10-25 20:44:40 -0700597static int lcanvas_saveLayer(lua_State* L) {
598 SkPaint paint;
halcanary96fcdcc2015-08-27 07:41:13 -0700599 lua_pushinteger(L, get_ref<SkCanvas>(L, 1)->saveLayer(nullptr, lua2OptionalPaint(L, 2, &paint)));
reed86217d82014-10-25 20:44:40 -0700600 return 1;
601}
602
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000603static int lcanvas_restore(lua_State* L) {
604 get_ref<SkCanvas>(L, 1)->restore();
605 return 0;
606}
607
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000608static int lcanvas_scale(lua_State* L) {
609 SkScalar sx = lua2scalar_def(L, 2, 1);
610 SkScalar sy = lua2scalar_def(L, 3, sx);
611 get_ref<SkCanvas>(L, 1)->scale(sx, sy);
612 return 0;
613}
614
reed@google.com3597b732013-05-22 20:12:50 +0000615static int lcanvas_translate(lua_State* L) {
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000616 SkScalar tx = lua2scalar_def(L, 2, 0);
617 SkScalar ty = lua2scalar_def(L, 3, 0);
618 get_ref<SkCanvas>(L, 1)->translate(tx, ty);
619 return 0;
620}
621
622static int lcanvas_rotate(lua_State* L) {
623 SkScalar degrees = lua2scalar_def(L, 2, 0);
624 get_ref<SkCanvas>(L, 1)->rotate(degrees);
reed@google.com3597b732013-05-22 20:12:50 +0000625 return 0;
626}
627
reedbdc49ae2014-10-14 09:34:52 -0700628static int lcanvas_concat(lua_State* L) {
629 get_ref<SkCanvas>(L, 1)->concat(*get_obj<SkMatrix>(L, 2));
630 return 0;
631}
632
reed485557f2014-10-12 10:36:47 -0700633static int lcanvas_newSurface(lua_State* L) {
634 int width = lua2int_def(L, 2, 0);
reed7a72c672014-11-07 10:23:55 -0800635 int height = lua2int_def(L, 3, 0);
reed485557f2014-10-12 10:36:47 -0700636 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
reede8f30622016-03-23 18:59:25 -0700637 auto surface = get_ref<SkCanvas>(L, 1)->makeSurface(info);
halcanary96fcdcc2015-08-27 07:41:13 -0700638 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -0700639 lua_pushnil(L);
640 } else {
reede8f30622016-03-23 18:59:25 -0700641 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -0700642 }
643 return 1;
644}
645
reed@google.com74ce6f02013-05-22 15:13:18 +0000646static int lcanvas_gc(lua_State* L) {
Mike Reed5df49342016-11-12 08:06:55 -0600647 // don't know how to track a ptr...
reed@google.com74ce6f02013-05-22 15:13:18 +0000648 return 0;
649}
650
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000651const struct luaL_Reg gSkCanvas_Methods[] = {
reedf355df52014-10-12 12:18:40 -0700652 { "clear", lcanvas_clear },
reed@google.com74ce6f02013-05-22 15:13:18 +0000653 { "drawColor", lcanvas_drawColor },
reed9fbc3f32014-10-21 07:12:58 -0700654 { "drawPaint", lcanvas_drawPaint },
reed@google.com74ce6f02013-05-22 15:13:18 +0000655 { "drawRect", lcanvas_drawRect },
656 { "drawOval", lcanvas_drawOval },
657 { "drawCircle", lcanvas_drawCircle },
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000658 { "drawImage", lcanvas_drawImage },
reedba5fb932014-10-10 15:28:19 -0700659 { "drawImageRect", lcanvas_drawImageRect },
reed7a72c672014-11-07 10:23:55 -0800660 { "drawPatch", lcanvas_drawPatch },
reed@google.comfd345872013-05-22 20:53:42 +0000661 { "drawPath", lcanvas_drawPath },
reed96affcd2014-10-13 12:38:04 -0700662 { "drawPicture", lcanvas_drawPicture },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000663 { "drawText", lcanvas_drawText },
reed1b6ab442014-11-03 19:55:41 -0800664 { "drawTextBlob", lcanvas_drawTextBlob },
reed@google.com74ce6f02013-05-22 15:13:18 +0000665 { "getSaveCount", lcanvas_getSaveCount },
666 { "getTotalMatrix", lcanvas_getTotalMatrix },
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000667 { "save", lcanvas_save },
reed86217d82014-10-25 20:44:40 -0700668 { "saveLayer", lcanvas_saveLayer },
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000669 { "restore", lcanvas_restore },
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000670 { "scale", lcanvas_scale },
reed@google.com3597b732013-05-22 20:12:50 +0000671 { "translate", lcanvas_translate },
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000672 { "rotate", lcanvas_rotate },
reedbdc49ae2014-10-14 09:34:52 -0700673 { "concat", lcanvas_concat },
reed485557f2014-10-12 10:36:47 -0700674
675 { "newSurface", lcanvas_newSurface },
676
reed@google.com74ce6f02013-05-22 15:13:18 +0000677 { "__gc", lcanvas_gc },
halcanary96fcdcc2015-08-27 07:41:13 -0700678 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +0000679};
680
681///////////////////////////////////////////////////////////////////////////////
682
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000683static int ldocument_beginPage(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -0700684 const SkRect* contentPtr = nullptr;
Mike Reed7ff6ca52018-01-08 14:45:31 -0500685 push_ptr(L, get_obj<DocHolder>(L, 1)->fDoc->beginPage(lua2scalar(L, 2),
686 lua2scalar(L, 3),
687 contentPtr));
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000688 return 1;
689}
690
691static int ldocument_endPage(lua_State* L) {
Mike Reed7ff6ca52018-01-08 14:45:31 -0500692 get_obj<DocHolder>(L, 1)->fDoc->endPage();
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000693 return 0;
694}
695
696static int ldocument_close(lua_State* L) {
Mike Reed7ff6ca52018-01-08 14:45:31 -0500697 get_obj<DocHolder>(L, 1)->fDoc->close();
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000698 return 0;
699}
700
701static int ldocument_gc(lua_State* L) {
Mike Reed7ff6ca52018-01-08 14:45:31 -0500702 get_obj<DocHolder>(L, 1)->~DocHolder();
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000703 return 0;
704}
705
Mike Reed7ff6ca52018-01-08 14:45:31 -0500706static const struct luaL_Reg gDocHolder_Methods[] = {
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000707 { "beginPage", ldocument_beginPage },
708 { "endPage", ldocument_endPage },
709 { "close", ldocument_close },
710 { "__gc", ldocument_gc },
halcanary96fcdcc2015-08-27 07:41:13 -0700711 { nullptr, nullptr }
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000712};
713
714///////////////////////////////////////////////////////////////////////////////
715
reed@google.com74ce6f02013-05-22 15:13:18 +0000716static int lpaint_isAntiAlias(lua_State* L) {
717 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isAntiAlias());
718 return 1;
719}
720
721static int lpaint_setAntiAlias(lua_State* L) {
reed@google.com88c9ec92013-05-22 15:43:21 +0000722 get_obj<SkPaint>(L, 1)->setAntiAlias(lua2bool(L, 2));
reed@google.com74ce6f02013-05-22 15:13:18 +0000723 return 0;
724}
725
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000726static int lpaint_isDither(lua_State* L) {
727 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isDither());
728 return 1;
729}
730
reedbb8a0ab2014-11-03 22:32:07 -0800731static int lpaint_setDither(lua_State* L) {
732 get_obj<SkPaint>(L, 1)->setDither(lua2bool(L, 2));
733 return 0;
734}
735
reed468b1812014-10-19 11:42:54 -0700736static int lpaint_getAlpha(lua_State* L) {
737 SkLua(L).pushScalar(byte2unit(get_obj<SkPaint>(L, 1)->getAlpha()));
738 return 1;
739}
740
741static int lpaint_setAlpha(lua_State* L) {
742 get_obj<SkPaint>(L, 1)->setAlpha(unit2byte(lua2scalar(L, 2)));
743 return 0;
744}
745
reed@google.com74ce6f02013-05-22 15:13:18 +0000746static int lpaint_getColor(lua_State* L) {
747 SkLua(L).pushColor(get_obj<SkPaint>(L, 1)->getColor());
748 return 1;
749}
750
751static int lpaint_setColor(lua_State* L) {
752 get_obj<SkPaint>(L, 1)->setColor(lua2color(L, 2));
753 return 0;
754}
755
reed93a12152015-03-16 10:08:34 -0700756static int lpaint_getFilterQuality(lua_State* L) {
757 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getFilterQuality());
reed7a72c672014-11-07 10:23:55 -0800758 return 1;
759}
760
reed93a12152015-03-16 10:08:34 -0700761static int lpaint_setFilterQuality(lua_State* L) {
reed7a72c672014-11-07 10:23:55 -0800762 int level = lua2int_def(L, 2, -1);
763 if (level >= 0 && level <= 3) {
reed93a12152015-03-16 10:08:34 -0700764 get_obj<SkPaint>(L, 1)->setFilterQuality((SkFilterQuality)level);
reed7a72c672014-11-07 10:23:55 -0800765 }
766 return 0;
767}
768
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000769static int lpaint_getStroke(lua_State* L) {
770 lua_pushboolean(L, SkPaint::kStroke_Style == get_obj<SkPaint>(L, 1)->getStyle());
771 return 1;
772}
773
774static int lpaint_setStroke(lua_State* L) {
775 SkPaint::Style style;
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000776
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000777 if (lua_toboolean(L, 2)) {
778 style = SkPaint::kStroke_Style;
779 } else {
780 style = SkPaint::kFill_Style;
781 }
782 get_obj<SkPaint>(L, 1)->setStyle(style);
783 return 0;
784}
785
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000786static int lpaint_getStrokeCap(lua_State* L) {
787 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeCap());
788 return 1;
789}
790
791static int lpaint_getStrokeJoin(lua_State* L) {
792 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeJoin());
793 return 1;
794}
795
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000796static int lpaint_getStrokeWidth(lua_State* L) {
797 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeWidth());
798 return 1;
799}
800
801static int lpaint_setStrokeWidth(lua_State* L) {
802 get_obj<SkPaint>(L, 1)->setStrokeWidth(lua2scalar(L, 2));
803 return 0;
804}
805
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000806static int lpaint_getStrokeMiter(lua_State* L) {
807 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeMiter());
808 return 1;
809}
810
reed@google.com29563872013-07-10 21:23:49 +0000811static int lpaint_getEffects(lua_State* L) {
812 const SkPaint* paint = get_obj<SkPaint>(L, 1);
skia.committer@gmail.comde2e4e82013-07-11 07:01:01 +0000813
reed@google.com29563872013-07-10 21:23:49 +0000814 lua_newtable(L);
reed468b1812014-10-19 11:42:54 -0700815 setfield_bool_if(L, "looper", !!paint->getLooper());
816 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) {
954 push_ref(L, get_obj<SkFont>(L, 1)->getTypeface());
955 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) {
969 SkTypeface* face = get_obj<SkFont>(L, 1)->getTypeface();
970 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);
978 SkLua(L).pushScalar(get_obj<SkFont>(L, 1)->measureText(text, len, kUTF8_SkTextEncoding));
979 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
reed@google.com5fdc9832013-07-24 15:47:52 +00001020static const char* mode2string(SkShader::TileMode mode) {
1021 static const char* gNames[] = { "clamp", "repeat", "mirror" };
1022 SkASSERT((unsigned)mode < SK_ARRAY_COUNT(gNames));
1023 return gNames[mode];
1024}
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;
1043 SkShader::TileMode 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));
1072 setfield_string(L, "tile", mode2string(info.fTileMode));
1073 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
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001250static const char* fill_type_to_str(SkPath::FillType fill) {
1251 switch (fill) {
1252 case SkPath::kEvenOdd_FillType:
1253 return "even-odd";
1254 case SkPath::kWinding_FillType:
1255 return "winding";
1256 case SkPath::kInverseEvenOdd_FillType:
1257 return "inverse-even-odd";
1258 case SkPath::kInverseWinding_FillType:
1259 return "inverse-winding";
1260 }
1261 return "unknown";
1262}
1263
1264static int lpath_getFillType(lua_State* L) {
1265 SkPath::FillType fill = get_obj<SkPath>(L, 1)->getFillType();
1266 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) {
1312 bool isConvex = SkPath::kConvex_Convexity == get_obj<SkPath>(L, 1)->getConvexity();
1313 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
1334static const char* dir2string(SkPath::Direction dir) {
1335 static const char* gStr[] = {
1336 "unknown", "cw", "ccw"
1337 };
1338 SkASSERT((unsigned)dir < SK_ARRAY_COUNT(gStr));
1339 return gStr[dir];
1340}
1341
caryclark95bc5f32015-04-08 08:34:15 -07001342static int lpath_isNestedFillRects(lua_State* L) {
reed@google.com74ce6f02013-05-22 15:13:18 +00001343 SkRect rects[2];
1344 SkPath::Direction dirs[2];
caryclark95bc5f32015-04-08 08:34:15 -07001345 bool pred = get_obj<SkPath>(L, 1)->isNestedFillRects(rects, dirs);
reed@google.com74ce6f02013-05-22 15:13:18 +00001346 int ret_count = 1;
1347 lua_pushboolean(L, pred);
1348 if (pred) {
1349 SkLua lua(L);
1350 lua.pushRect(rects[0]);
1351 lua.pushRect(rects[1]);
1352 lua_pushstring(L, dir2string(dirs[0]));
1353 lua_pushstring(L, dir2string(dirs[0]));
1354 ret_count += 4;
1355 }
1356 return ret_count;
1357}
1358
commit-bot@chromium.orgc5302082014-02-26 21:38:47 +00001359static int lpath_countPoints(lua_State* L) {
1360 lua_pushinteger(L, get_obj<SkPath>(L, 1)->countPoints());
1361 return 1;
1362}
1363
hstern0b401ce2016-08-02 09:17:59 -07001364static int lpath_getVerbs(lua_State* L) {
1365 const SkPath* path = get_obj<SkPath>(L, 1);
1366 SkPath::Iter iter(*path, false);
1367 SkPoint pts[4];
1368
1369 lua_newtable(L);
1370
1371 bool done = false;
1372 int i = 0;
1373 do {
1374 switch (iter.next(pts, true)) {
1375 case SkPath::kMove_Verb:
1376 setarray_string(L, ++i, "move");
1377 break;
1378 case SkPath::kClose_Verb:
1379 setarray_string(L, ++i, "close");
1380 break;
1381 case SkPath::kLine_Verb:
1382 setarray_string(L, ++i, "line");
1383 break;
1384 case SkPath::kQuad_Verb:
1385 setarray_string(L, ++i, "quad");
1386 break;
1387 case SkPath::kConic_Verb:
1388 setarray_string(L, ++i, "conic");
1389 break;
1390 case SkPath::kCubic_Verb:
1391 setarray_string(L, ++i, "cubic");
1392 break;
1393 case SkPath::kDone_Verb:
1394 setarray_string(L, ++i, "done");
1395 done = true;
1396 break;
1397 }
1398 } while (!done);
1399
1400 return 1;
1401}
1402
reed@google.com74ce6f02013-05-22 15:13:18 +00001403static int lpath_reset(lua_State* L) {
1404 get_obj<SkPath>(L, 1)->reset();
1405 return 0;
1406}
1407
1408static int lpath_moveTo(lua_State* L) {
1409 get_obj<SkPath>(L, 1)->moveTo(lua2scalar(L, 2), lua2scalar(L, 3));
1410 return 0;
1411}
1412
1413static int lpath_lineTo(lua_State* L) {
1414 get_obj<SkPath>(L, 1)->lineTo(lua2scalar(L, 2), lua2scalar(L, 3));
1415 return 0;
1416}
1417
1418static int lpath_quadTo(lua_State* L) {
1419 get_obj<SkPath>(L, 1)->quadTo(lua2scalar(L, 2), lua2scalar(L, 3),
1420 lua2scalar(L, 4), lua2scalar(L, 5));
1421 return 0;
1422}
1423
1424static int lpath_cubicTo(lua_State* L) {
1425 get_obj<SkPath>(L, 1)->cubicTo(lua2scalar(L, 2), lua2scalar(L, 3),
1426 lua2scalar(L, 4), lua2scalar(L, 5),
1427 lua2scalar(L, 6), lua2scalar(L, 7));
1428 return 0;
1429}
1430
1431static int lpath_close(lua_State* L) {
1432 get_obj<SkPath>(L, 1)->close();
1433 return 0;
1434}
1435
1436static int lpath_gc(lua_State* L) {
1437 get_obj<SkPath>(L, 1)->~SkPath();
1438 return 0;
1439}
1440
1441static const struct luaL_Reg gSkPath_Methods[] = {
1442 { "getBounds", lpath_getBounds },
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001443 { "getFillType", lpath_getFillType },
krajcevski95498ed2014-08-18 08:02:33 -07001444 { "getSegmentTypes", lpath_getSegmentTypes },
hstern0b401ce2016-08-02 09:17:59 -07001445 { "getVerbs", lpath_getVerbs },
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001446 { "isConvex", lpath_isConvex },
reed@google.com74ce6f02013-05-22 15:13:18 +00001447 { "isEmpty", lpath_isEmpty },
1448 { "isRect", lpath_isRect },
caryclark95bc5f32015-04-08 08:34:15 -07001449 { "isNestedFillRects", lpath_isNestedFillRects },
commit-bot@chromium.orgc5302082014-02-26 21:38:47 +00001450 { "countPoints", lpath_countPoints },
reed@google.com74ce6f02013-05-22 15:13:18 +00001451 { "reset", lpath_reset },
1452 { "moveTo", lpath_moveTo },
1453 { "lineTo", lpath_lineTo },
1454 { "quadTo", lpath_quadTo },
1455 { "cubicTo", lpath_cubicTo },
1456 { "close", lpath_close },
1457 { "__gc", lpath_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001458 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001459};
1460
1461///////////////////////////////////////////////////////////////////////////////
1462
1463static const char* rrect_type(const SkRRect& rr) {
1464 switch (rr.getType()) {
reed@google.com74ce6f02013-05-22 15:13:18 +00001465 case SkRRect::kEmpty_Type: return "empty";
1466 case SkRRect::kRect_Type: return "rect";
1467 case SkRRect::kOval_Type: return "oval";
1468 case SkRRect::kSimple_Type: return "simple";
commit-bot@chromium.orgf338d7c2014-03-17 21:17:30 +00001469 case SkRRect::kNinePatch_Type: return "nine-patch";
reed@google.com74ce6f02013-05-22 15:13:18 +00001470 case SkRRect::kComplex_Type: return "complex";
1471 }
mtklein@google.com330313a2013-08-22 15:37:26 +00001472 SkDEBUGFAIL("never get here");
reed@google.com74ce6f02013-05-22 15:13:18 +00001473 return "";
1474}
1475
1476static int lrrect_rect(lua_State* L) {
1477 SkLua(L).pushRect(get_obj<SkRRect>(L, 1)->rect());
1478 return 1;
1479}
1480
1481static int lrrect_type(lua_State* L) {
1482 lua_pushstring(L, rrect_type(*get_obj<SkRRect>(L, 1)));
1483 return 1;
1484}
1485
1486static int lrrect_radii(lua_State* L) {
reed@google.com7fa2a652014-01-27 13:42:58 +00001487 int corner = SkToInt(lua_tointeger(L, 2));
reed@google.com74ce6f02013-05-22 15:13:18 +00001488 SkVector v;
1489 if (corner < 0 || corner > 3) {
1490 SkDebugf("bad corner index %d", corner);
1491 v.set(0, 0);
1492 } else {
1493 v = get_obj<SkRRect>(L, 1)->radii((SkRRect::Corner)corner);
1494 }
1495 lua_pushnumber(L, v.fX);
1496 lua_pushnumber(L, v.fY);
1497 return 2;
1498}
1499
1500static int lrrect_gc(lua_State* L) {
1501 get_obj<SkRRect>(L, 1)->~SkRRect();
1502 return 0;
1503}
1504
1505static const struct luaL_Reg gSkRRect_Methods[] = {
1506 { "rect", lrrect_rect },
1507 { "type", lrrect_type },
1508 { "radii", lrrect_radii },
1509 { "__gc", lrrect_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001510 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001511};
1512
1513///////////////////////////////////////////////////////////////////////////////
1514
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001515static int limage_width(lua_State* L) {
1516 lua_pushinteger(L, get_ref<SkImage>(L, 1)->width());
1517 return 1;
1518}
1519
1520static int limage_height(lua_State* L) {
1521 lua_pushinteger(L, get_ref<SkImage>(L, 1)->height());
1522 return 1;
1523}
1524
reed7a72c672014-11-07 10:23:55 -08001525static int limage_newShader(lua_State* L) {
1526 SkShader::TileMode tmode = SkShader::kClamp_TileMode;
halcanary96fcdcc2015-08-27 07:41:13 -07001527 const SkMatrix* localM = nullptr;
reed5671c5b2016-03-09 14:47:34 -08001528 push_ref(L, get_ref<SkImage>(L, 1)->makeShader(tmode, tmode, localM));
reed7a72c672014-11-07 10:23:55 -08001529 return 1;
1530}
1531
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001532static int limage_gc(lua_State* L) {
1533 get_ref<SkImage>(L, 1)->unref();
1534 return 0;
1535}
1536
1537static const struct luaL_Reg gSkImage_Methods[] = {
1538 { "width", limage_width },
1539 { "height", limage_height },
reed7a72c672014-11-07 10:23:55 -08001540 { "newShader", limage_newShader },
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001541 { "__gc", limage_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001542 { nullptr, nullptr }
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001543};
1544
1545///////////////////////////////////////////////////////////////////////////////
1546
reed485557f2014-10-12 10:36:47 -07001547static int lsurface_width(lua_State* L) {
1548 lua_pushinteger(L, get_ref<SkSurface>(L, 1)->width());
1549 return 1;
1550}
1551
1552static int lsurface_height(lua_State* L) {
1553 lua_pushinteger(L, get_ref<SkSurface>(L, 1)->height());
1554 return 1;
1555}
1556
1557static int lsurface_getCanvas(lua_State* L) {
1558 SkCanvas* canvas = get_ref<SkSurface>(L, 1)->getCanvas();
halcanary96fcdcc2015-08-27 07:41:13 -07001559 if (nullptr == canvas) {
reed485557f2014-10-12 10:36:47 -07001560 lua_pushnil(L);
1561 } else {
Mike Reed5df49342016-11-12 08:06:55 -06001562 push_ptr(L, canvas);
reed485557f2014-10-12 10:36:47 -07001563 // note: we don't unref canvas, since getCanvas did not ref it.
1564 // warning: this is weird: now Lua owns a ref on this canvas, but what if they let
1565 // the real owner (the surface) go away, but still hold onto the canvas?
1566 // *really* we want to sort of ref the surface again, but have the native object
1567 // know that it is supposed to be treated as a canvas...
1568 }
1569 return 1;
1570}
1571
1572static int lsurface_newImageSnapshot(lua_State* L) {
reed9ce9d672016-03-17 10:51:11 -07001573 sk_sp<SkImage> image = get_ref<SkSurface>(L, 1)->makeImageSnapshot();
1574 if (!image) {
reed485557f2014-10-12 10:36:47 -07001575 lua_pushnil(L);
1576 } else {
reed9ce9d672016-03-17 10:51:11 -07001577 push_ref(L, image);
reed485557f2014-10-12 10:36:47 -07001578 }
1579 return 1;
1580}
1581
1582static int lsurface_newSurface(lua_State* L) {
1583 int width = lua2int_def(L, 2, 0);
reed96affcd2014-10-13 12:38:04 -07001584 int height = lua2int_def(L, 3, 0);
reed485557f2014-10-12 10:36:47 -07001585 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
reede8f30622016-03-23 18:59:25 -07001586 auto surface = get_ref<SkSurface>(L, 1)->makeSurface(info);
halcanary96fcdcc2015-08-27 07:41:13 -07001587 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -07001588 lua_pushnil(L);
1589 } else {
reede8f30622016-03-23 18:59:25 -07001590 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -07001591 }
1592 return 1;
1593}
1594
1595static int lsurface_gc(lua_State* L) {
1596 get_ref<SkSurface>(L, 1)->unref();
1597 return 0;
1598}
1599
1600static const struct luaL_Reg gSkSurface_Methods[] = {
1601 { "width", lsurface_width },
1602 { "height", lsurface_height },
1603 { "getCanvas", lsurface_getCanvas },
1604 { "newImageSnapshot", lsurface_newImageSnapshot },
1605 { "newSurface", lsurface_newSurface },
1606 { "__gc", lsurface_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001607 { nullptr, nullptr }
reed485557f2014-10-12 10:36:47 -07001608};
1609
1610///////////////////////////////////////////////////////////////////////////////
1611
reed96affcd2014-10-13 12:38:04 -07001612static int lpicturerecorder_beginRecording(lua_State* L) {
1613 const SkScalar w = lua2scalar_def(L, 2, -1);
1614 const SkScalar h = lua2scalar_def(L, 3, -1);
1615 if (w <= 0 || h <= 0) {
1616 lua_pushnil(L);
1617 return 1;
1618 }
1619
1620 SkCanvas* canvas = get_obj<SkPictureRecorder>(L, 1)->beginRecording(w, h);
halcanary96fcdcc2015-08-27 07:41:13 -07001621 if (nullptr == canvas) {
reed96affcd2014-10-13 12:38:04 -07001622 lua_pushnil(L);
1623 return 1;
1624 }
1625
Mike Reed5df49342016-11-12 08:06:55 -06001626 push_ptr(L, canvas);
reed96affcd2014-10-13 12:38:04 -07001627 return 1;
1628}
1629
1630static int lpicturerecorder_getCanvas(lua_State* L) {
1631 SkCanvas* canvas = get_obj<SkPictureRecorder>(L, 1)->getRecordingCanvas();
halcanary96fcdcc2015-08-27 07:41:13 -07001632 if (nullptr == canvas) {
reed96affcd2014-10-13 12:38:04 -07001633 lua_pushnil(L);
1634 return 1;
1635 }
Mike Reed5df49342016-11-12 08:06:55 -06001636 push_ptr(L, canvas);
reed96affcd2014-10-13 12:38:04 -07001637 return 1;
1638}
1639
1640static int lpicturerecorder_endRecording(lua_State* L) {
reedca2622b2016-03-18 07:25:55 -07001641 sk_sp<SkPicture> pic = get_obj<SkPictureRecorder>(L, 1)->finishRecordingAsPicture();
1642 if (!pic) {
reed96affcd2014-10-13 12:38:04 -07001643 lua_pushnil(L);
1644 return 1;
1645 }
reedca2622b2016-03-18 07:25:55 -07001646 push_ref(L, std::move(pic));
reed96affcd2014-10-13 12:38:04 -07001647 return 1;
1648}
1649
1650static int lpicturerecorder_gc(lua_State* L) {
1651 get_obj<SkPictureRecorder>(L, 1)->~SkPictureRecorder();
1652 return 0;
1653}
1654
1655static const struct luaL_Reg gSkPictureRecorder_Methods[] = {
1656 { "beginRecording", lpicturerecorder_beginRecording },
1657 { "getCanvas", lpicturerecorder_getCanvas },
1658 { "endRecording", lpicturerecorder_endRecording },
1659 { "__gc", lpicturerecorder_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001660 { nullptr, nullptr }
reed96affcd2014-10-13 12:38:04 -07001661};
1662
1663///////////////////////////////////////////////////////////////////////////////
1664
1665static int lpicture_width(lua_State* L) {
1666 lua_pushnumber(L, get_ref<SkPicture>(L, 1)->cullRect().width());
1667 return 1;
1668}
1669
1670static int lpicture_height(lua_State* L) {
1671 lua_pushnumber(L, get_ref<SkPicture>(L, 1)->cullRect().height());
1672 return 1;
1673}
1674
1675static int lpicture_gc(lua_State* L) {
1676 get_ref<SkPicture>(L, 1)->unref();
1677 return 0;
1678}
1679
1680static const struct luaL_Reg gSkPicture_Methods[] = {
1681 { "width", lpicture_width },
1682 { "height", lpicture_height },
1683 { "__gc", lpicture_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001684 { nullptr, nullptr }
reed96affcd2014-10-13 12:38:04 -07001685};
1686
1687///////////////////////////////////////////////////////////////////////////////
1688
reed1b6ab442014-11-03 19:55:41 -08001689static int ltextblob_bounds(lua_State* L) {
1690 SkLua(L).pushRect(get_ref<SkTextBlob>(L, 1)->bounds());
1691 return 1;
1692}
1693
1694static int ltextblob_gc(lua_State* L) {
1695 SkSafeUnref(get_ref<SkTextBlob>(L, 1));
1696 return 0;
1697}
1698
1699static const struct luaL_Reg gSkTextBlob_Methods[] = {
1700 { "bounds", ltextblob_bounds },
1701 { "__gc", ltextblob_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001702 { nullptr, nullptr }
reed1b6ab442014-11-03 19:55:41 -08001703};
1704
1705///////////////////////////////////////////////////////////////////////////////
1706
reed36c9c112014-11-04 10:58:42 -08001707static int ltypeface_getFamilyName(lua_State* L) {
1708 SkString str;
1709 get_ref<SkTypeface>(L, 1)->getFamilyName(&str);
1710 lua_pushstring(L, str.c_str());
1711 return 1;
1712}
1713
1714static int ltypeface_getStyle(lua_State* L) {
Ben Wagner26308e12017-08-08 15:23:47 -04001715 push_obj(L, get_ref<SkTypeface>(L, 1)->fontStyle());
reed36c9c112014-11-04 10:58:42 -08001716 return 1;
1717}
1718
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001719static int ltypeface_gc(lua_State* L) {
commit-bot@chromium.org77887af2013-12-17 14:28:19 +00001720 SkSafeUnref(get_ref<SkTypeface>(L, 1));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001721 return 0;
1722}
1723
1724static const struct luaL_Reg gSkTypeface_Methods[] = {
reed36c9c112014-11-04 10:58:42 -08001725 { "getFamilyName", ltypeface_getFamilyName },
1726 { "getStyle", ltypeface_getStyle },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001727 { "__gc", ltypeface_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001728 { nullptr, nullptr }
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001729};
1730
1731///////////////////////////////////////////////////////////////////////////////
1732
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001733static int lfontstyle_weight(lua_State* L) {
1734 lua_pushnumber(L, get_ref<SkFontStyle>(L, 1)->weight());
1735 return 1;
1736}
1737
1738static int lfontstyle_width(lua_State* L) {
1739 lua_pushnumber(L, get_ref<SkFontStyle>(L, 1)->width());
1740 return 1;
1741}
1742
1743static int lfontstyle_slant(lua_State* L) {
1744 lua_pushnumber(L, get_ref<SkFontStyle>(L, 1)->slant());
1745 return 1;
1746}
1747
1748static int lfontstyle_gc(lua_State* L) {
1749 get_obj<SkFontStyle>(L, 1)->~SkFontStyle();
1750 return 0;
1751}
1752
1753static const struct luaL_Reg gSkFontStyle_Methods[] = {
1754 { "weight", lfontstyle_weight },
1755 { "width", lfontstyle_width },
1756 { "slant", lfontstyle_slant },
1757 { "__gc", lfontstyle_gc },
1758 { nullptr, nullptr }
1759};
1760
1761///////////////////////////////////////////////////////////////////////////////
1762
reed@google.com74ce6f02013-05-22 15:13:18 +00001763class AutoCallLua {
1764public:
1765 AutoCallLua(lua_State* L, const char func[], const char verb[]) : fL(L) {
1766 lua_getglobal(L, func);
1767 if (!lua_isfunction(L, -1)) {
1768 int t = lua_type(L, -1);
1769 SkDebugf("--- expected function %d\n", t);
1770 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001771
reed@google.com74ce6f02013-05-22 15:13:18 +00001772 lua_newtable(L);
1773 setfield_string(L, "verb", verb);
1774 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001775
reed@google.com74ce6f02013-05-22 15:13:18 +00001776 ~AutoCallLua() {
1777 if (lua_pcall(fL, 1, 0, 0) != LUA_OK) {
1778 SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
1779 }
1780 lua_settop(fL, -1);
1781 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001782
reed@google.com74ce6f02013-05-22 15:13:18 +00001783private:
1784 lua_State* fL;
1785};
1786
1787#define AUTO_LUA(verb) AutoCallLua acl(fL, fFunc.c_str(), verb)
1788
1789///////////////////////////////////////////////////////////////////////////////
1790
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001791static int lsk_newDocumentPDF(lua_State* L) {
Mike Reed7ff6ca52018-01-08 14:45:31 -05001792 const char* filename = nullptr;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001793 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
Mike Reed7ff6ca52018-01-08 14:45:31 -05001794 filename = lua_tolstring(L, 1, nullptr);
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001795 }
Mike Reed7ff6ca52018-01-08 14:45:31 -05001796 if (!filename) {
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001797 return 0;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001798 }
Mike Reed7ff6ca52018-01-08 14:45:31 -05001799 auto file = skstd::make_unique<SkFILEWStream>(filename);
1800 if (!file->isValid()) {
1801 return 0;
1802 }
Hal Canary23564b92018-09-07 14:33:14 -04001803 sk_sp<SkDocument> doc = SkPDF::MakeDocument(file.get());
Mike Reed7ff6ca52018-01-08 14:45:31 -05001804 if (!doc) {
1805 return 0;
1806 }
1807 push_ptr(L, new DocHolder{std::move(doc), std::move(file)});
1808 return 1;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001809}
1810
reed468b1812014-10-19 11:42:54 -07001811static int lsk_newBlurImageFilter(lua_State* L) {
1812 SkScalar sigmaX = lua2scalar_def(L, 1, 0);
1813 SkScalar sigmaY = lua2scalar_def(L, 2, 0);
robertphillips6e7025a2016-04-04 04:31:25 -07001814 sk_sp<SkImageFilter> imf(SkBlurImageFilter::Make(sigmaX, sigmaY, nullptr));
1815 if (!imf) {
reed468b1812014-10-19 11:42:54 -07001816 lua_pushnil(L);
1817 } else {
robertphillips6e7025a2016-04-04 04:31:25 -07001818 push_ref(L, std::move(imf));
reed9fbc3f32014-10-21 07:12:58 -07001819 }
1820 return 1;
1821}
1822
1823static int lsk_newLinearGradient(lua_State* L) {
1824 SkScalar x0 = lua2scalar_def(L, 1, 0);
1825 SkScalar y0 = lua2scalar_def(L, 2, 0);
1826 SkColor c0 = lua2color(L, 3);
1827 SkScalar x1 = lua2scalar_def(L, 4, 0);
1828 SkScalar y1 = lua2scalar_def(L, 5, 0);
1829 SkColor c1 = lua2color(L, 6);
1830
1831 SkPoint pts[] = { { x0, y0 }, { x1, y1 } };
1832 SkColor colors[] = { c0, c1 };
robertphillips6e7025a2016-04-04 04:31:25 -07001833 sk_sp<SkShader> s(SkGradientShader::MakeLinear(pts, colors, nullptr, 2,
1834 SkShader::kClamp_TileMode));
reed2ad1aa62016-03-09 09:50:50 -08001835 if (!s) {
reed9fbc3f32014-10-21 07:12:58 -07001836 lua_pushnil(L);
1837 } else {
reed2ad1aa62016-03-09 09:50:50 -08001838 push_ref(L, std::move(s));
reed468b1812014-10-19 11:42:54 -07001839 }
1840 return 1;
1841}
1842
reedbdc49ae2014-10-14 09:34:52 -07001843static int lsk_newMatrix(lua_State* L) {
1844 push_new<SkMatrix>(L)->reset();
1845 return 1;
1846}
1847
reed@google.com3597b732013-05-22 20:12:50 +00001848static int lsk_newPaint(lua_State* L) {
1849 push_new<SkPaint>(L);
1850 return 1;
1851}
1852
1853static int lsk_newPath(lua_State* L) {
1854 push_new<SkPath>(L);
1855 return 1;
1856}
1857
reed96affcd2014-10-13 12:38:04 -07001858static int lsk_newPictureRecorder(lua_State* L) {
1859 push_new<SkPictureRecorder>(L);
1860 return 1;
1861}
1862
reed@google.com3597b732013-05-22 20:12:50 +00001863static int lsk_newRRect(lua_State* L) {
reedbdc49ae2014-10-14 09:34:52 -07001864 push_new<SkRRect>(L)->setEmpty();
reed@google.com3597b732013-05-22 20:12:50 +00001865 return 1;
1866}
1867
reed1b6ab442014-11-03 19:55:41 -08001868// Sk.newTextBlob(text, rect, paint)
1869static int lsk_newTextBlob(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07001870 const char* text = lua_tolstring(L, 1, nullptr);
reed1b6ab442014-11-03 19:55:41 -08001871 SkRect bounds;
1872 lua2rect(L, 2, &bounds);
reed1b6ab442014-11-03 19:55:41 -08001873
Herb Derby1724db12018-05-22 12:01:50 -04001874 SkShaper shaper(nullptr);
reed1b6ab442014-11-03 19:55:41 -08001875
Mike Reede5f9cfa2019-01-10 13:55:35 -05001876#ifdef SK_SUPPORT_LEGACY_PAINT_FONT_FIELDS
1877 const SkPaint& paint = *get_obj<SkPaint>(L, 3);
Hal Canary2a1848d2018-11-26 17:23:24 -05001878 SkFont font = SkFont::LEGACY_ExtractFromPaint(paint);
Mike Reede5f9cfa2019-01-10 13:55:35 -05001879#else
1880 SkFont font;
1881#endif
Florin Malita950243d2019-01-11 11:08:35 -05001882 SkTextBlobBuilderRunHandler builder;
Hal Canary2a1848d2018-11-26 17:23:24 -05001883 SkPoint end = shaper.shape(&builder, font, text, strlen(text), true,
Herb Derby1724db12018-05-22 12:01:50 -04001884 { bounds.left(), bounds.top() }, bounds.width());
1885
Florin Malita9867f612018-12-12 10:54:49 -05001886 push_ref<SkTextBlob>(L, builder.makeBlob());
Herb Derby1724db12018-05-22 12:01:50 -04001887 SkLua(L).pushScalar(end.fY);
reed1b6ab442014-11-03 19:55:41 -08001888 return 2;
1889}
1890
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001891static int lsk_newTypeface(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07001892 const char* name = nullptr;
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001893 SkFontStyle style;
skia.committer@gmail.com63193672013-06-08 07:01:13 +00001894
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001895 int count = lua_gettop(L);
1896 if (count > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001897 name = lua_tolstring(L, 1, nullptr);
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001898 if (count > 1) {
1899 SkFontStyle* passedStyle = get_obj<SkFontStyle>(L, 2);
1900 if (passedStyle) {
1901 style = *passedStyle;
1902 }
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001903 }
1904 }
1905
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001906 sk_sp<SkTypeface> face(SkTypeface::MakeFromName(name, style));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001907// SkDebugf("---- name <%s> style=%d, face=%p ref=%d\n", name, style, face, face->getRefCnt());
halcanary96fcdcc2015-08-27 07:41:13 -07001908 if (nullptr == face) {
bungeman13b9c952016-05-12 10:09:30 -07001909 face = SkTypeface::MakeDefault();
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001910 }
bungeman13b9c952016-05-12 10:09:30 -07001911 push_ref(L, std::move(face));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001912 return 1;
1913}
reed@google.com3597b732013-05-22 20:12:50 +00001914
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001915static int lsk_newFontStyle(lua_State* L) {
1916 int count = lua_gettop(L);
1917 int weight = SkFontStyle::kNormal_Weight;
1918 int width = SkFontStyle::kNormal_Width;
1919 SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant;
1920 if (count >= 1 && lua_isnumber(L, 1)) {
1921 weight = lua_tointegerx(L, 1, nullptr);
1922 }
1923 if (count >= 2 && lua_isnumber(L, 2)) {
1924 width = lua_tointegerx(L, 2, nullptr);
1925 }
1926 if (count >= 3 && lua_isnumber(L, 3)) {
1927 slant = static_cast<SkFontStyle::Slant>(lua_tointegerx(L, 3, nullptr));
1928 }
1929 push_new<SkFontStyle>(L, weight, width, slant);
1930 return 1;
1931}
1932
reed485557f2014-10-12 10:36:47 -07001933static int lsk_newRasterSurface(lua_State* L) {
reed7b864662014-11-04 13:24:47 -08001934 int width = lua2int_def(L, 1, 0);
reed485557f2014-10-12 10:36:47 -07001935 int height = lua2int_def(L, 2, 0);
1936 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
robertphillips702edbd2015-06-23 06:26:08 -07001937 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
reede8f30622016-03-23 18:59:25 -07001938 auto surface = SkSurface::MakeRaster(info, &props);
halcanary96fcdcc2015-08-27 07:41:13 -07001939 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -07001940 lua_pushnil(L);
1941 } else {
reede8f30622016-03-23 18:59:25 -07001942 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -07001943 }
1944 return 1;
1945}
1946
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001947static int lsk_loadImage(lua_State* L) {
1948 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001949 const char* name = lua_tolstring(L, 1, nullptr);
reed9ce9d672016-03-17 10:51:11 -07001950 sk_sp<SkData> data(SkData::MakeFromFileName(name));
1951 if (data) {
1952 auto image = SkImage::MakeFromEncoded(std::move(data));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001953 if (image) {
reed9ce9d672016-03-17 10:51:11 -07001954 push_ref(L, std::move(image));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001955 return 1;
1956 }
1957 }
1958 }
1959 return 0;
1960}
1961
reed@google.com3597b732013-05-22 20:12:50 +00001962static void register_Sk(lua_State* L) {
1963 lua_newtable(L);
1964 lua_pushvalue(L, -1);
1965 lua_setglobal(L, "Sk");
1966 // the Sk table is still on top
1967
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001968 setfield_function(L, "newDocumentPDF", lsk_newDocumentPDF);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001969 setfield_function(L, "loadImage", lsk_loadImage);
reed468b1812014-10-19 11:42:54 -07001970 setfield_function(L, "newBlurImageFilter", lsk_newBlurImageFilter);
reed9fbc3f32014-10-21 07:12:58 -07001971 setfield_function(L, "newLinearGradient", lsk_newLinearGradient);
reedbdc49ae2014-10-14 09:34:52 -07001972 setfield_function(L, "newMatrix", lsk_newMatrix);
reed@google.com3597b732013-05-22 20:12:50 +00001973 setfield_function(L, "newPaint", lsk_newPaint);
1974 setfield_function(L, "newPath", lsk_newPath);
reed96affcd2014-10-13 12:38:04 -07001975 setfield_function(L, "newPictureRecorder", lsk_newPictureRecorder);
reed@google.com3597b732013-05-22 20:12:50 +00001976 setfield_function(L, "newRRect", lsk_newRRect);
reed485557f2014-10-12 10:36:47 -07001977 setfield_function(L, "newRasterSurface", lsk_newRasterSurface);
reed1b6ab442014-11-03 19:55:41 -08001978 setfield_function(L, "newTextBlob", lsk_newTextBlob);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001979 setfield_function(L, "newTypeface", lsk_newTypeface);
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001980 setfield_function(L, "newFontStyle", lsk_newFontStyle);
reed@google.com3597b732013-05-22 20:12:50 +00001981 lua_pop(L, 1); // pop off the Sk table
1982}
1983
reed@google.com74ce6f02013-05-22 15:13:18 +00001984#define REG_CLASS(L, C) \
1985 do { \
reed@google.com3597b732013-05-22 20:12:50 +00001986 luaL_newmetatable(L, get_mtname<C>()); \
reed@google.com74ce6f02013-05-22 15:13:18 +00001987 lua_pushvalue(L, -1); \
1988 lua_setfield(L, -2, "__index"); \
1989 luaL_setfuncs(L, g##C##_Methods, 0); \
1990 lua_pop(L, 1); /* pop off the meta-table */ \
1991 } while (0)
1992
1993void SkLua::Load(lua_State* L) {
reed@google.com3597b732013-05-22 20:12:50 +00001994 register_Sk(L);
reed@google.com74ce6f02013-05-22 15:13:18 +00001995 REG_CLASS(L, SkCanvas);
reed22a517f2015-12-04 20:45:59 -08001996 REG_CLASS(L, SkColorFilter);
Mike Reed7ff6ca52018-01-08 14:45:31 -05001997 REG_CLASS(L, DocHolder);
Mike Reed91919132019-01-02 12:21:01 -05001998 REG_CLASS(L, SkFont);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001999 REG_CLASS(L, SkImage);
reed468b1812014-10-19 11:42:54 -07002000 REG_CLASS(L, SkImageFilter);
reed1b6ab442014-11-03 19:55:41 -08002001 REG_CLASS(L, SkMatrix);
reed@google.com74ce6f02013-05-22 15:13:18 +00002002 REG_CLASS(L, SkPaint);
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00002003 REG_CLASS(L, SkPath);
2004 REG_CLASS(L, SkPathEffect);
reed96affcd2014-10-13 12:38:04 -07002005 REG_CLASS(L, SkPicture);
2006 REG_CLASS(L, SkPictureRecorder);
reed@google.com74ce6f02013-05-22 15:13:18 +00002007 REG_CLASS(L, SkRRect);
reed@google.com5fdc9832013-07-24 15:47:52 +00002008 REG_CLASS(L, SkShader);
reed485557f2014-10-12 10:36:47 -07002009 REG_CLASS(L, SkSurface);
reed1b6ab442014-11-03 19:55:41 -08002010 REG_CLASS(L, SkTextBlob);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00002011 REG_CLASS(L, SkTypeface);
Ben Wagnerc6c10b42017-08-07 09:56:21 -04002012 REG_CLASS(L, SkFontStyle);
reed@google.com74ce6f02013-05-22 15:13:18 +00002013}
zachr@google.com28c27c82013-06-20 17:15:05 +00002014
reed@google.com7bce9982013-06-20 17:40:21 +00002015extern "C" int luaopen_skia(lua_State* L);
zachr@google.com28c27c82013-06-20 17:15:05 +00002016extern "C" int luaopen_skia(lua_State* L) {
2017 SkLua::Load(L);
2018 return 0;
2019}