blob: aef08897712a1672e991d717681d2365523b30a5 [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"
Mike Reed5f528e52019-01-28 10:57:28 -050019#include "SkFontMetrics.h"
Ben Wagnerc6c10b42017-08-07 09:56:21 -040020#include "SkFontStyle.h"
reed9fbc3f32014-10-21 07:12:58 -070021#include "SkGradientShader.h"
mike@reedtribe.org792bbd12013-06-11 02:20:28 +000022#include "SkImage.h"
Mike Reed7ff6ca52018-01-08 14:45:31 -050023#include "SkMakeUnique.h"
mike@reedtribe.org792bbd12013-06-11 02:20:28 +000024#include "SkMatrix.h"
Hal Canary23564b92018-09-07 14:33:14 -040025#include "SkPDFDocument.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000026#include "SkPaint.h"
27#include "SkPath.h"
reed96affcd2014-10-13 12:38:04 -070028#include "SkPictureRecorder.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000029#include "SkRRect.h"
Herb Derby1724db12018-05-22 12:01:50 -040030#include "SkShaper.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000031#include "SkString.h"
reed485557f2014-10-12 10:36:47 -070032#include "SkSurface.h"
fmalitab7425172014-08-26 07:56:44 -070033#include "SkTextBlob.h"
Hal Canaryc640d0d2018-06-13 09:59:02 -040034#include "SkTo.h"
reed@google.come3823fd2013-05-30 18:55:14 +000035#include "SkTypeface.h"
Mike Klein79aea6a2018-06-11 10:45:26 -040036#include <new>
reed@google.com74ce6f02013-05-22 15:13:18 +000037
38extern "C" {
reed@google.com3597b732013-05-22 20:12:50 +000039 #include "lua.h"
40 #include "lualib.h"
41 #include "lauxlib.h"
reed@google.com74ce6f02013-05-22 15:13:18 +000042}
43
Mike Reed7ff6ca52018-01-08 14:45:31 -050044struct DocHolder {
45 sk_sp<SkDocument> fDoc;
46 std::unique_ptr<SkWStream> fStream;
47};
48
reed@google.comfd345872013-05-22 20:53:42 +000049// return the metatable name for a given class
reed@google.com3597b732013-05-22 20:12:50 +000050template <typename T> const char* get_mtname();
reed@google.comfd345872013-05-22 20:53:42 +000051#define DEF_MTNAME(T) \
52 template <> const char* get_mtname<T>() { \
53 return #T "_LuaMetaTableName"; \
54 }
55
56DEF_MTNAME(SkCanvas)
reed22a517f2015-12-04 20:45:59 -080057DEF_MTNAME(SkColorFilter)
Mike Reed7ff6ca52018-01-08 14:45:31 -050058DEF_MTNAME(DocHolder)
Mike Reed91919132019-01-02 12:21:01 -050059DEF_MTNAME(SkFont)
mike@reedtribe.org792bbd12013-06-11 02:20:28 +000060DEF_MTNAME(SkImage)
reed468b1812014-10-19 11:42:54 -070061DEF_MTNAME(SkImageFilter)
reed@google.comfd345872013-05-22 20:53:42 +000062DEF_MTNAME(SkMatrix)
63DEF_MTNAME(SkRRect)
64DEF_MTNAME(SkPath)
65DEF_MTNAME(SkPaint)
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +000066DEF_MTNAME(SkPathEffect)
reed96affcd2014-10-13 12:38:04 -070067DEF_MTNAME(SkPicture)
68DEF_MTNAME(SkPictureRecorder)
reed@google.com5fdc9832013-07-24 15:47:52 +000069DEF_MTNAME(SkShader)
reed485557f2014-10-12 10:36:47 -070070DEF_MTNAME(SkSurface)
fmalitab7425172014-08-26 07:56:44 -070071DEF_MTNAME(SkTextBlob)
mike@reedtribe.orge6469f12013-06-08 03:15:47 +000072DEF_MTNAME(SkTypeface)
Ben Wagnerc6c10b42017-08-07 09:56:21 -040073DEF_MTNAME(SkFontStyle)
reed@google.com74ce6f02013-05-22 15:13:18 +000074
Ben Wagnerc6c10b42017-08-07 09:56:21 -040075template <typename T, typename... Args> T* push_new(lua_State* L, Args&&... args) {
reed@google.com3597b732013-05-22 20:12:50 +000076 T* addr = (T*)lua_newuserdata(L, sizeof(T));
Ben Wagnerc6c10b42017-08-07 09:56:21 -040077 new (addr) T(std::forward<Args>(args)...);
reed@google.com3597b732013-05-22 20:12:50 +000078 luaL_getmetatable(L, get_mtname<T>());
79 lua_setmetatable(L, -2);
80 return addr;
81}
reed@google.com74ce6f02013-05-22 15:13:18 +000082
83template <typename T> void push_obj(lua_State* L, const T& obj) {
84 new (lua_newuserdata(L, sizeof(T))) T(obj);
reed@google.com3597b732013-05-22 20:12:50 +000085 luaL_getmetatable(L, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +000086 lua_setmetatable(L, -2);
87}
88
Mike Reed5df49342016-11-12 08:06:55 -060089template <typename T> T* push_ptr(lua_State* L, T* ptr) {
90 *(T**)lua_newuserdata(L, sizeof(T*)) = ptr;
91 luaL_getmetatable(L, get_mtname<T>());
92 lua_setmetatable(L, -2);
93 return ptr;
94}
95
reed9fbc3f32014-10-21 07:12:58 -070096template <typename T> T* push_ref(lua_State* L, T* ref) {
commit-bot@chromium.org77887af2013-12-17 14:28:19 +000097 *(T**)lua_newuserdata(L, sizeof(T*)) = SkSafeRef(ref);
reed@google.com3597b732013-05-22 20:12:50 +000098 luaL_getmetatable(L, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +000099 lua_setmetatable(L, -2);
reed9fbc3f32014-10-21 07:12:58 -0700100 return ref;
reed@google.com74ce6f02013-05-22 15:13:18 +0000101}
102
reed2ad1aa62016-03-09 09:50:50 -0800103template <typename T> void push_ref(lua_State* L, sk_sp<T> sp) {
104 *(T**)lua_newuserdata(L, sizeof(T*)) = sp.release();
105 luaL_getmetatable(L, get_mtname<T>());
106 lua_setmetatable(L, -2);
107}
108
reed@google.com74ce6f02013-05-22 15:13:18 +0000109template <typename T> T* get_ref(lua_State* L, int index) {
reed@google.com3597b732013-05-22 20:12:50 +0000110 return *(T**)luaL_checkudata(L, index, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +0000111}
112
113template <typename T> T* get_obj(lua_State* L, int index) {
reed@google.com3597b732013-05-22 20:12:50 +0000114 return (T*)luaL_checkudata(L, index, get_mtname<T>());
reed@google.com74ce6f02013-05-22 15:13:18 +0000115}
116
reed@google.com88c9ec92013-05-22 15:43:21 +0000117static bool lua2bool(lua_State* L, int index) {
118 return !!lua_toboolean(L, index);
119}
120
reed@google.com74ce6f02013-05-22 15:13:18 +0000121///////////////////////////////////////////////////////////////////////////////
122
reed@google.com3597b732013-05-22 20:12:50 +0000123SkLua::SkLua(const char termCode[]) : fTermCode(termCode), fWeOwnL(true) {
124 fL = luaL_newstate();
125 luaL_openlibs(fL);
126 SkLua::Load(fL);
127}
128
129SkLua::SkLua(lua_State* L) : fL(L), fWeOwnL(false) {}
130
131SkLua::~SkLua() {
132 if (fWeOwnL) {
133 if (fTermCode.size() > 0) {
134 lua_getglobal(fL, fTermCode.c_str());
135 if (lua_pcall(fL, 0, 0, 0) != LUA_OK) {
136 SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
137 }
138 }
139 lua_close(fL);
140 }
141}
142
143bool SkLua::runCode(const char code[]) {
144 int err = luaL_loadstring(fL, code) || lua_pcall(fL, 0, 0, 0);
145 if (err) {
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000146 SkDebugf("--- lua failed: %s\n", lua_tostring(fL, -1));
reed@google.com3597b732013-05-22 20:12:50 +0000147 return false;
148 }
149 return true;
150}
151
152bool SkLua::runCode(const void* code, size_t size) {
153 SkString str((const char*)code, size);
154 return this->runCode(str.c_str());
155}
156
157///////////////////////////////////////////////////////////////////////////////
158
159#define CHECK_SETFIELD(key) do if (key) lua_setfield(fL, -2, key); while (0)
160
reed@google.com29563872013-07-10 21:23:49 +0000161static void setfield_bool_if(lua_State* L, const char key[], bool pred) {
162 if (pred) {
163 lua_pushboolean(L, true);
164 lua_setfield(L, -2, key);
165 }
166}
167
reed@google.com74ce6f02013-05-22 15:13:18 +0000168static void setfield_string(lua_State* L, const char key[], const char value[]) {
169 lua_pushstring(L, value);
170 lua_setfield(L, -2, key);
171}
172
173static void setfield_number(lua_State* L, const char key[], double value) {
174 lua_pushnumber(L, value);
175 lua_setfield(L, -2, key);
176}
177
humper@google.com2815c192013-07-10 22:42:30 +0000178static void setfield_boolean(lua_State* L, const char key[], bool value) {
179 lua_pushboolean(L, value);
180 lua_setfield(L, -2, key);
181}
182
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000183static void setfield_scalar(lua_State* L, const char key[], SkScalar value) {
184 setfield_number(L, key, SkScalarToLua(value));
185}
186
reed@google.com3597b732013-05-22 20:12:50 +0000187static void setfield_function(lua_State* L,
188 const char key[], lua_CFunction value) {
189 lua_pushcfunction(L, value);
190 lua_setfield(L, -2, key);
reed@google.com74ce6f02013-05-22 15:13:18 +0000191}
192
reed7a72c672014-11-07 10:23:55 -0800193static int lua2int_def(lua_State* L, int index, int defaultValue) {
194 if (lua_isnumber(L, index)) {
195 return (int)lua_tonumber(L, index);
196 } else {
197 return defaultValue;
198 }
199}
200
201static SkScalar lua2scalar(lua_State* L, int index) {
202 SkASSERT(lua_isnumber(L, index));
203 return SkLuaToScalar(lua_tonumber(L, index));
204}
205
206static SkScalar lua2scalar_def(lua_State* L, int index, SkScalar defaultValue) {
207 if (lua_isnumber(L, index)) {
208 return SkLuaToScalar(lua_tonumber(L, index));
209 } else {
210 return defaultValue;
211 }
212}
213
214static SkScalar getarray_scalar(lua_State* L, int stackIndex, int arrayIndex) {
215 SkASSERT(lua_istable(L, stackIndex));
216 lua_rawgeti(L, stackIndex, arrayIndex);
mtklein8aacf202014-12-18 13:29:54 -0800217
reed7a72c672014-11-07 10:23:55 -0800218 SkScalar value = lua2scalar(L, -1);
219 lua_pop(L, 1);
220 return value;
221}
222
223static void getarray_scalars(lua_State* L, int stackIndex, SkScalar dst[], int count) {
224 for (int i = 0; i < count; ++i) {
225 dst[i] = getarray_scalar(L, stackIndex, i + 1);
226 }
227}
228
229static void getarray_points(lua_State* L, int stackIndex, SkPoint pts[], int count) {
230 getarray_scalars(L, stackIndex, &pts[0].fX, count * 2);
231}
232
reed@google.come3823fd2013-05-30 18:55:14 +0000233static void setarray_number(lua_State* L, int index, double value) {
234 lua_pushnumber(L, value);
235 lua_rawseti(L, -2, index);
236}
237
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +0000238static void setarray_scalar(lua_State* L, int index, SkScalar value) {
239 setarray_number(L, index, SkScalarToLua(value));
240}
241
hstern0b401ce2016-08-02 09:17:59 -0700242static void setarray_string(lua_State* L, int index, const char str[]) {
243 lua_pushstring(L, str);
244 lua_rawseti(L, -2, index);
245}
246
reed@google.com74ce6f02013-05-22 15:13:18 +0000247void SkLua::pushBool(bool value, const char key[]) {
248 lua_pushboolean(fL, value);
249 CHECK_SETFIELD(key);
250}
251
252void SkLua::pushString(const char str[], const char key[]) {
253 lua_pushstring(fL, str);
254 CHECK_SETFIELD(key);
255}
256
reed@google.come3823fd2013-05-30 18:55:14 +0000257void SkLua::pushString(const char str[], size_t length, const char key[]) {
258 // TODO: how to do this w/o making a copy?
259 SkString s(str, length);
260 lua_pushstring(fL, s.c_str());
261 CHECK_SETFIELD(key);
262}
263
reed@google.com74ce6f02013-05-22 15:13:18 +0000264void SkLua::pushString(const SkString& str, const char key[]) {
265 lua_pushstring(fL, str.c_str());
266 CHECK_SETFIELD(key);
267}
268
269void SkLua::pushColor(SkColor color, const char key[]) {
270 lua_newtable(fL);
271 setfield_number(fL, "a", SkColorGetA(color) / 255.0);
272 setfield_number(fL, "r", SkColorGetR(color) / 255.0);
273 setfield_number(fL, "g", SkColorGetG(color) / 255.0);
274 setfield_number(fL, "b", SkColorGetB(color) / 255.0);
275 CHECK_SETFIELD(key);
276}
277
reed@google.come3823fd2013-05-30 18:55:14 +0000278void SkLua::pushU32(uint32_t value, const char key[]) {
279 lua_pushnumber(fL, (double)value);
280 CHECK_SETFIELD(key);
281}
282
reed@google.com74ce6f02013-05-22 15:13:18 +0000283void SkLua::pushScalar(SkScalar value, const char key[]) {
284 lua_pushnumber(fL, SkScalarToLua(value));
285 CHECK_SETFIELD(key);
286}
287
reed@google.come3823fd2013-05-30 18:55:14 +0000288void SkLua::pushArrayU16(const uint16_t array[], int count, const char key[]) {
289 lua_newtable(fL);
290 for (int i = 0; i < count; ++i) {
291 // make it base-1 to match lua convention
292 setarray_number(fL, i + 1, (double)array[i]);
293 }
294 CHECK_SETFIELD(key);
295}
296
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +0000297void SkLua::pushArrayPoint(const SkPoint array[], int count, const char key[]) {
298 lua_newtable(fL);
299 for (int i = 0; i < count; ++i) {
300 // make it base-1 to match lua convention
301 lua_newtable(fL);
302 this->pushScalar(array[i].fX, "x");
303 this->pushScalar(array[i].fY, "y");
304 lua_rawseti(fL, -2, i + 1);
305 }
306 CHECK_SETFIELD(key);
307}
308
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +0000309void SkLua::pushArrayScalar(const SkScalar array[], int count, const char key[]) {
310 lua_newtable(fL);
311 for (int i = 0; i < count; ++i) {
312 // make it base-1 to match lua convention
313 setarray_scalar(fL, i + 1, array[i]);
314 }
315 CHECK_SETFIELD(key);
316}
317
reed@google.com74ce6f02013-05-22 15:13:18 +0000318void SkLua::pushRect(const SkRect& r, const char key[]) {
319 lua_newtable(fL);
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000320 setfield_scalar(fL, "left", r.fLeft);
321 setfield_scalar(fL, "top", r.fTop);
322 setfield_scalar(fL, "right", r.fRight);
323 setfield_scalar(fL, "bottom", r.fBottom);
reed@google.com74ce6f02013-05-22 15:13:18 +0000324 CHECK_SETFIELD(key);
325}
326
327void SkLua::pushRRect(const SkRRect& rr, const char key[]) {
328 push_obj(fL, rr);
329 CHECK_SETFIELD(key);
330}
331
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +0000332void SkLua::pushDash(const SkPathEffect::DashInfo& info, const char key[]) {
333 lua_newtable(fL);
334 setfield_scalar(fL, "phase", info.fPhase);
335 this->pushArrayScalar(info.fIntervals, info.fCount, "intervals");
336 CHECK_SETFIELD(key);
337}
338
339
reed@google.com74ce6f02013-05-22 15:13:18 +0000340void SkLua::pushMatrix(const SkMatrix& matrix, const char key[]) {
341 push_obj(fL, matrix);
342 CHECK_SETFIELD(key);
343}
344
345void SkLua::pushPaint(const SkPaint& paint, const char key[]) {
346 push_obj(fL, paint);
347 CHECK_SETFIELD(key);
348}
349
350void SkLua::pushPath(const SkPath& path, const char key[]) {
351 push_obj(fL, path);
352 CHECK_SETFIELD(key);
353}
354
355void SkLua::pushCanvas(SkCanvas* canvas, const char key[]) {
Mike Reed5df49342016-11-12 08:06:55 -0600356 push_ptr(fL, canvas);
reed@google.com74ce6f02013-05-22 15:13:18 +0000357 CHECK_SETFIELD(key);
358}
359
fmalitab7425172014-08-26 07:56:44 -0700360void SkLua::pushTextBlob(const SkTextBlob* blob, const char key[]) {
361 push_ref(fL, const_cast<SkTextBlob*>(blob));
362 CHECK_SETFIELD(key);
363}
364
reed@google.com74ce6f02013-05-22 15:13:18 +0000365///////////////////////////////////////////////////////////////////////////////
366///////////////////////////////////////////////////////////////////////////////
367
reed@google.com74ce6f02013-05-22 15:13:18 +0000368static SkScalar getfield_scalar(lua_State* L, int index, const char key[]) {
369 SkASSERT(lua_istable(L, index));
370 lua_pushstring(L, key);
371 lua_gettable(L, index);
mtklein8aacf202014-12-18 13:29:54 -0800372
reed@google.com74ce6f02013-05-22 15:13:18 +0000373 SkScalar value = lua2scalar(L, -1);
374 lua_pop(L, 1);
375 return value;
376}
377
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000378static SkScalar getfield_scalar_default(lua_State* L, int index, const char key[], SkScalar def) {
379 SkASSERT(lua_istable(L, index));
380 lua_pushstring(L, key);
381 lua_gettable(L, index);
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000382
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000383 SkScalar value;
384 if (lua_isnil(L, -1)) {
385 value = def;
386 } else {
387 value = lua2scalar(L, -1);
388 }
389 lua_pop(L, 1);
390 return value;
391}
392
reed468b1812014-10-19 11:42:54 -0700393static SkScalar byte2unit(U8CPU byte) {
394 return byte / 255.0f;
395}
396
reed@google.com74ce6f02013-05-22 15:13:18 +0000397static U8CPU unit2byte(SkScalar x) {
398 if (x <= 0) {
399 return 0;
400 } else if (x >= 1) {
401 return 255;
402 } else {
403 return SkScalarRoundToInt(x * 255);
404 }
405}
406
407static SkColor lua2color(lua_State* L, int index) {
reed485557f2014-10-12 10:36:47 -0700408 return SkColorSetARGB(unit2byte(getfield_scalar_default(L, index, "a", 1)),
409 unit2byte(getfield_scalar_default(L, index, "r", 0)),
410 unit2byte(getfield_scalar_default(L, index, "g", 0)),
411 unit2byte(getfield_scalar_default(L, index, "b", 0)));
reed@google.com74ce6f02013-05-22 15:13:18 +0000412}
413
414static SkRect* lua2rect(lua_State* L, int index, SkRect* rect) {
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000415 rect->set(getfield_scalar_default(L, index, "left", 0),
416 getfield_scalar_default(L, index, "top", 0),
reed@google.com74ce6f02013-05-22 15:13:18 +0000417 getfield_scalar(L, index, "right"),
418 getfield_scalar(L, index, "bottom"));
419 return rect;
420}
421
reedf355df52014-10-12 12:18:40 -0700422static int lcanvas_clear(lua_State* L) {
423 get_ref<SkCanvas>(L, 1)->clear(0);
424 return 0;
425}
426
reed@google.com74ce6f02013-05-22 15:13:18 +0000427static int lcanvas_drawColor(lua_State* L) {
428 get_ref<SkCanvas>(L, 1)->drawColor(lua2color(L, 2));
429 return 0;
430}
431
reed9fbc3f32014-10-21 07:12:58 -0700432static int lcanvas_drawPaint(lua_State* L) {
433 get_ref<SkCanvas>(L, 1)->drawPaint(*get_obj<SkPaint>(L, 2));
434 return 0;
435}
436
reed@google.com74ce6f02013-05-22 15:13:18 +0000437static int lcanvas_drawRect(lua_State* L) {
438 SkRect rect;
reed7a72c672014-11-07 10:23:55 -0800439 lua2rect(L, 2, &rect);
440 const SkPaint* paint = get_obj<SkPaint>(L, 3);
441 get_ref<SkCanvas>(L, 1)->drawRect(rect, *paint);
reed@google.com74ce6f02013-05-22 15:13:18 +0000442 return 0;
443}
444
445static int lcanvas_drawOval(lua_State* L) {
446 SkRect rect;
447 get_ref<SkCanvas>(L, 1)->drawOval(*lua2rect(L, 2, &rect),
448 *get_obj<SkPaint>(L, 3));
449 return 0;
450}
451
452static int lcanvas_drawCircle(lua_State* L) {
453 get_ref<SkCanvas>(L, 1)->drawCircle(lua2scalar(L, 2),
454 lua2scalar(L, 3),
455 lua2scalar(L, 4),
456 *get_obj<SkPaint>(L, 5));
457 return 0;
458}
459
reed485557f2014-10-12 10:36:47 -0700460static SkPaint* lua2OptionalPaint(lua_State* L, int index, SkPaint* paint) {
461 if (lua_isnumber(L, index)) {
462 paint->setAlpha(SkScalarRoundToInt(lua2scalar(L, index) * 255));
463 return paint;
reedf355df52014-10-12 12:18:40 -0700464 } else if (lua_isuserdata(L, index)) {
reed485557f2014-10-12 10:36:47 -0700465 const SkPaint* ptr = get_obj<SkPaint>(L, index);
466 if (ptr) {
467 *paint = *ptr;
468 return paint;
469 }
470 }
halcanary96fcdcc2015-08-27 07:41:13 -0700471 return nullptr;
reed485557f2014-10-12 10:36:47 -0700472}
473
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000474static int lcanvas_drawImage(lua_State* L) {
475 SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
476 SkImage* image = get_ref<SkImage>(L, 2);
halcanary96fcdcc2015-08-27 07:41:13 -0700477 if (nullptr == image) {
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000478 return 0;
479 }
480 SkScalar x = lua2scalar(L, 3);
481 SkScalar y = lua2scalar(L, 4);
482
483 SkPaint paint;
reed485557f2014-10-12 10:36:47 -0700484 canvas->drawImage(image, x, y, lua2OptionalPaint(L, 5, &paint));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000485 return 0;
486}
487
reedba5fb932014-10-10 15:28:19 -0700488static int lcanvas_drawImageRect(lua_State* L) {
489 SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
490 SkImage* image = get_ref<SkImage>(L, 2);
halcanary96fcdcc2015-08-27 07:41:13 -0700491 if (nullptr == image) {
reedba5fb932014-10-10 15:28:19 -0700492 return 0;
493 }
494
495 SkRect srcR, dstR;
halcanary96fcdcc2015-08-27 07:41:13 -0700496 SkRect* srcRPtr = nullptr;
reedba5fb932014-10-10 15:28:19 -0700497 if (!lua_isnil(L, 3)) {
498 srcRPtr = lua2rect(L, 3, &srcR);
499 }
500 lua2rect(L, 4, &dstR);
mtklein8aacf202014-12-18 13:29:54 -0800501
reedba5fb932014-10-10 15:28:19 -0700502 SkPaint paint;
reede47829b2015-08-06 10:02:53 -0700503 canvas->legacy_drawImageRect(image, srcRPtr, dstR, lua2OptionalPaint(L, 5, &paint));
reedba5fb932014-10-10 15:28:19 -0700504 return 0;
505}
506
reed7a72c672014-11-07 10:23:55 -0800507static int lcanvas_drawPatch(lua_State* L) {
508 SkPoint cubics[12];
509 SkColor colorStorage[4];
510 SkPoint texStorage[4];
511
halcanary96fcdcc2015-08-27 07:41:13 -0700512 const SkColor* colors = nullptr;
513 const SkPoint* texs = nullptr;
reed7a72c672014-11-07 10:23:55 -0800514
515 getarray_points(L, 2, cubics, 12);
516
517 colorStorage[0] = SK_ColorRED;
518 colorStorage[1] = SK_ColorGREEN;
519 colorStorage[2] = SK_ColorBLUE;
520 colorStorage[3] = SK_ColorGRAY;
521
522 if (lua_isnil(L, 4)) {
523 colors = colorStorage;
524 } else {
525 getarray_points(L, 4, texStorage, 4);
526 texs = texStorage;
527 }
528
Mike Reed7d954ad2016-10-28 15:42:34 -0400529 get_ref<SkCanvas>(L, 1)->drawPatch(cubics, colors, texs, *get_obj<SkPaint>(L, 5));
reed7a72c672014-11-07 10:23:55 -0800530 return 0;
531}
532
reed@google.comfd345872013-05-22 20:53:42 +0000533static int lcanvas_drawPath(lua_State* L) {
534 get_ref<SkCanvas>(L, 1)->drawPath(*get_obj<SkPath>(L, 2),
535 *get_obj<SkPaint>(L, 3));
536 return 0;
537}
538
reed96affcd2014-10-13 12:38:04 -0700539// drawPicture(pic, x, y, paint)
540static int lcanvas_drawPicture(lua_State* L) {
541 SkCanvas* canvas = get_ref<SkCanvas>(L, 1);
542 SkPicture* picture = get_ref<SkPicture>(L, 2);
543 SkScalar x = lua2scalar_def(L, 3, 0);
544 SkScalar y = lua2scalar_def(L, 4, 0);
halcanary96fcdcc2015-08-27 07:41:13 -0700545 SkMatrix matrix, *matrixPtr = nullptr;
reed96affcd2014-10-13 12:38:04 -0700546 if (x || y) {
547 matrix.setTranslate(x, y);
548 matrixPtr = &matrix;
549 }
550 SkPaint paint;
551 canvas->drawPicture(picture, matrixPtr, lua2OptionalPaint(L, 5, &paint));
552 return 0;
553}
554
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000555static int lcanvas_drawText(lua_State* L) {
556 if (lua_gettop(L) < 5) {
557 return 0;
558 }
559
Mike Reed5f528e52019-01-28 10:57:28 -0500560 // TODO: restore this logic based on SkFont instead of SkPaint
561#if 0
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000562 if (lua_isstring(L, 2) && lua_isnumber(L, 3) && lua_isnumber(L, 4)) {
563 size_t len;
564 const char* text = lua_tolstring(L, 2, &len);
Hal Canary292ece82019-01-09 10:59:08 -0500565 get_ref<SkCanvas>(L, 1)->drawSimpleText(
566 text, len, kUTF8_SkTextEncoding,
567 lua2scalar(L, 3), lua2scalar(L, 4),
568 SkFont::LEGACY_ExtractFromPaint(*get_obj<SkPaint>(L, 5)),
569 *get_obj<SkPaint>(L, 5));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000570 }
Mike Reede5f9cfa2019-01-10 13:55:35 -0500571#endif
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000572 return 0;
573}
574
reed1b6ab442014-11-03 19:55:41 -0800575static int lcanvas_drawTextBlob(lua_State* L) {
576 const SkTextBlob* blob = get_ref<SkTextBlob>(L, 2);
577 SkScalar x = lua2scalar(L, 3);
578 SkScalar y = lua2scalar(L, 4);
579 const SkPaint& paint = *get_obj<SkPaint>(L, 5);
580 get_ref<SkCanvas>(L, 1)->drawTextBlob(blob, x, y, paint);
581 return 0;
582}
583
reed@google.com74ce6f02013-05-22 15:13:18 +0000584static int lcanvas_getSaveCount(lua_State* L) {
585 lua_pushnumber(L, get_ref<SkCanvas>(L, 1)->getSaveCount());
586 return 1;
587}
588
589static int lcanvas_getTotalMatrix(lua_State* L) {
590 SkLua(L).pushMatrix(get_ref<SkCanvas>(L, 1)->getTotalMatrix());
591 return 1;
592}
593
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000594static int lcanvas_save(lua_State* L) {
595 lua_pushinteger(L, get_ref<SkCanvas>(L, 1)->save());
596 return 1;
597}
598
reed86217d82014-10-25 20:44:40 -0700599static int lcanvas_saveLayer(lua_State* L) {
600 SkPaint paint;
halcanary96fcdcc2015-08-27 07:41:13 -0700601 lua_pushinteger(L, get_ref<SkCanvas>(L, 1)->saveLayer(nullptr, lua2OptionalPaint(L, 2, &paint)));
reed86217d82014-10-25 20:44:40 -0700602 return 1;
603}
604
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000605static int lcanvas_restore(lua_State* L) {
606 get_ref<SkCanvas>(L, 1)->restore();
607 return 0;
608}
609
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000610static int lcanvas_scale(lua_State* L) {
611 SkScalar sx = lua2scalar_def(L, 2, 1);
612 SkScalar sy = lua2scalar_def(L, 3, sx);
613 get_ref<SkCanvas>(L, 1)->scale(sx, sy);
614 return 0;
615}
616
reed@google.com3597b732013-05-22 20:12:50 +0000617static int lcanvas_translate(lua_State* L) {
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000618 SkScalar tx = lua2scalar_def(L, 2, 0);
619 SkScalar ty = lua2scalar_def(L, 3, 0);
620 get_ref<SkCanvas>(L, 1)->translate(tx, ty);
621 return 0;
622}
623
624static int lcanvas_rotate(lua_State* L) {
625 SkScalar degrees = lua2scalar_def(L, 2, 0);
626 get_ref<SkCanvas>(L, 1)->rotate(degrees);
reed@google.com3597b732013-05-22 20:12:50 +0000627 return 0;
628}
629
reedbdc49ae2014-10-14 09:34:52 -0700630static int lcanvas_concat(lua_State* L) {
631 get_ref<SkCanvas>(L, 1)->concat(*get_obj<SkMatrix>(L, 2));
632 return 0;
633}
634
reed485557f2014-10-12 10:36:47 -0700635static int lcanvas_newSurface(lua_State* L) {
636 int width = lua2int_def(L, 2, 0);
reed7a72c672014-11-07 10:23:55 -0800637 int height = lua2int_def(L, 3, 0);
reed485557f2014-10-12 10:36:47 -0700638 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
reede8f30622016-03-23 18:59:25 -0700639 auto surface = get_ref<SkCanvas>(L, 1)->makeSurface(info);
halcanary96fcdcc2015-08-27 07:41:13 -0700640 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -0700641 lua_pushnil(L);
642 } else {
reede8f30622016-03-23 18:59:25 -0700643 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -0700644 }
645 return 1;
646}
647
reed@google.com74ce6f02013-05-22 15:13:18 +0000648static int lcanvas_gc(lua_State* L) {
Mike Reed5df49342016-11-12 08:06:55 -0600649 // don't know how to track a ptr...
reed@google.com74ce6f02013-05-22 15:13:18 +0000650 return 0;
651}
652
bsalomon@google.com4ebe3822014-02-26 20:22:32 +0000653const struct luaL_Reg gSkCanvas_Methods[] = {
reedf355df52014-10-12 12:18:40 -0700654 { "clear", lcanvas_clear },
reed@google.com74ce6f02013-05-22 15:13:18 +0000655 { "drawColor", lcanvas_drawColor },
reed9fbc3f32014-10-21 07:12:58 -0700656 { "drawPaint", lcanvas_drawPaint },
reed@google.com74ce6f02013-05-22 15:13:18 +0000657 { "drawRect", lcanvas_drawRect },
658 { "drawOval", lcanvas_drawOval },
659 { "drawCircle", lcanvas_drawCircle },
mike@reedtribe.org792bbd12013-06-11 02:20:28 +0000660 { "drawImage", lcanvas_drawImage },
reedba5fb932014-10-10 15:28:19 -0700661 { "drawImageRect", lcanvas_drawImageRect },
reed7a72c672014-11-07 10:23:55 -0800662 { "drawPatch", lcanvas_drawPatch },
reed@google.comfd345872013-05-22 20:53:42 +0000663 { "drawPath", lcanvas_drawPath },
reed96affcd2014-10-13 12:38:04 -0700664 { "drawPicture", lcanvas_drawPicture },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +0000665 { "drawText", lcanvas_drawText },
reed1b6ab442014-11-03 19:55:41 -0800666 { "drawTextBlob", lcanvas_drawTextBlob },
reed@google.com74ce6f02013-05-22 15:13:18 +0000667 { "getSaveCount", lcanvas_getSaveCount },
668 { "getTotalMatrix", lcanvas_getTotalMatrix },
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000669 { "save", lcanvas_save },
reed86217d82014-10-25 20:44:40 -0700670 { "saveLayer", lcanvas_saveLayer },
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000671 { "restore", lcanvas_restore },
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000672 { "scale", lcanvas_scale },
reed@google.com3597b732013-05-22 20:12:50 +0000673 { "translate", lcanvas_translate },
mike@reedtribe.org1d32cc62013-06-13 01:28:56 +0000674 { "rotate", lcanvas_rotate },
reedbdc49ae2014-10-14 09:34:52 -0700675 { "concat", lcanvas_concat },
reed485557f2014-10-12 10:36:47 -0700676
677 { "newSurface", lcanvas_newSurface },
678
reed@google.com74ce6f02013-05-22 15:13:18 +0000679 { "__gc", lcanvas_gc },
halcanary96fcdcc2015-08-27 07:41:13 -0700680 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +0000681};
682
683///////////////////////////////////////////////////////////////////////////////
684
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000685static int ldocument_beginPage(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -0700686 const SkRect* contentPtr = nullptr;
Mike Reed7ff6ca52018-01-08 14:45:31 -0500687 push_ptr(L, get_obj<DocHolder>(L, 1)->fDoc->beginPage(lua2scalar(L, 2),
688 lua2scalar(L, 3),
689 contentPtr));
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000690 return 1;
691}
692
693static int ldocument_endPage(lua_State* L) {
Mike Reed7ff6ca52018-01-08 14:45:31 -0500694 get_obj<DocHolder>(L, 1)->fDoc->endPage();
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000695 return 0;
696}
697
698static int ldocument_close(lua_State* L) {
Mike Reed7ff6ca52018-01-08 14:45:31 -0500699 get_obj<DocHolder>(L, 1)->fDoc->close();
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000700 return 0;
701}
702
703static int ldocument_gc(lua_State* L) {
Mike Reed7ff6ca52018-01-08 14:45:31 -0500704 get_obj<DocHolder>(L, 1)->~DocHolder();
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000705 return 0;
706}
707
Mike Reed7ff6ca52018-01-08 14:45:31 -0500708static const struct luaL_Reg gDocHolder_Methods[] = {
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000709 { "beginPage", ldocument_beginPage },
710 { "endPage", ldocument_endPage },
711 { "close", ldocument_close },
712 { "__gc", ldocument_gc },
halcanary96fcdcc2015-08-27 07:41:13 -0700713 { nullptr, nullptr }
mike@reedtribe.orgfb858242013-06-08 16:39:44 +0000714};
715
716///////////////////////////////////////////////////////////////////////////////
717
reed@google.com74ce6f02013-05-22 15:13:18 +0000718static int lpaint_isAntiAlias(lua_State* L) {
719 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isAntiAlias());
720 return 1;
721}
722
723static int lpaint_setAntiAlias(lua_State* L) {
reed@google.com88c9ec92013-05-22 15:43:21 +0000724 get_obj<SkPaint>(L, 1)->setAntiAlias(lua2bool(L, 2));
reed@google.com74ce6f02013-05-22 15:13:18 +0000725 return 0;
726}
727
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000728static int lpaint_isDither(lua_State* L) {
729 lua_pushboolean(L, get_obj<SkPaint>(L, 1)->isDither());
730 return 1;
731}
732
reedbb8a0ab2014-11-03 22:32:07 -0800733static int lpaint_setDither(lua_State* L) {
734 get_obj<SkPaint>(L, 1)->setDither(lua2bool(L, 2));
735 return 0;
736}
737
reed468b1812014-10-19 11:42:54 -0700738static int lpaint_getAlpha(lua_State* L) {
739 SkLua(L).pushScalar(byte2unit(get_obj<SkPaint>(L, 1)->getAlpha()));
740 return 1;
741}
742
743static int lpaint_setAlpha(lua_State* L) {
744 get_obj<SkPaint>(L, 1)->setAlpha(unit2byte(lua2scalar(L, 2)));
745 return 0;
746}
747
reed@google.com74ce6f02013-05-22 15:13:18 +0000748static int lpaint_getColor(lua_State* L) {
749 SkLua(L).pushColor(get_obj<SkPaint>(L, 1)->getColor());
750 return 1;
751}
752
753static int lpaint_setColor(lua_State* L) {
754 get_obj<SkPaint>(L, 1)->setColor(lua2color(L, 2));
755 return 0;
756}
757
reed93a12152015-03-16 10:08:34 -0700758static int lpaint_getFilterQuality(lua_State* L) {
759 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getFilterQuality());
reed7a72c672014-11-07 10:23:55 -0800760 return 1;
761}
762
reed93a12152015-03-16 10:08:34 -0700763static int lpaint_setFilterQuality(lua_State* L) {
reed7a72c672014-11-07 10:23:55 -0800764 int level = lua2int_def(L, 2, -1);
765 if (level >= 0 && level <= 3) {
reed93a12152015-03-16 10:08:34 -0700766 get_obj<SkPaint>(L, 1)->setFilterQuality((SkFilterQuality)level);
reed7a72c672014-11-07 10:23:55 -0800767 }
768 return 0;
769}
770
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000771static int lpaint_getStroke(lua_State* L) {
772 lua_pushboolean(L, SkPaint::kStroke_Style == get_obj<SkPaint>(L, 1)->getStyle());
773 return 1;
774}
775
776static int lpaint_setStroke(lua_State* L) {
777 SkPaint::Style style;
skia.committer@gmail.com370c5342013-06-09 07:01:05 +0000778
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000779 if (lua_toboolean(L, 2)) {
780 style = SkPaint::kStroke_Style;
781 } else {
782 style = SkPaint::kFill_Style;
783 }
784 get_obj<SkPaint>(L, 1)->setStyle(style);
785 return 0;
786}
787
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000788static int lpaint_getStrokeCap(lua_State* L) {
789 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeCap());
790 return 1;
791}
792
793static int lpaint_getStrokeJoin(lua_State* L) {
794 SkLua(L).pushU32(get_obj<SkPaint>(L, 1)->getStrokeJoin());
795 return 1;
796}
797
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000798static int lpaint_getStrokeWidth(lua_State* L) {
799 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeWidth());
800 return 1;
801}
802
803static int lpaint_setStrokeWidth(lua_State* L) {
804 get_obj<SkPaint>(L, 1)->setStrokeWidth(lua2scalar(L, 2));
805 return 0;
806}
807
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000808static int lpaint_getStrokeMiter(lua_State* L) {
809 SkLua(L).pushScalar(get_obj<SkPaint>(L, 1)->getStrokeMiter());
810 return 1;
811}
812
reed@google.com29563872013-07-10 21:23:49 +0000813static int lpaint_getEffects(lua_State* L) {
814 const SkPaint* paint = get_obj<SkPaint>(L, 1);
skia.committer@gmail.comde2e4e82013-07-11 07:01:01 +0000815
reed@google.com29563872013-07-10 21:23:49 +0000816 lua_newtable(L);
reed468b1812014-10-19 11:42:54 -0700817 setfield_bool_if(L, "looper", !!paint->getLooper());
818 setfield_bool_if(L, "pathEffect", !!paint->getPathEffect());
reed468b1812014-10-19 11:42:54 -0700819 setfield_bool_if(L, "maskFilter", !!paint->getMaskFilter());
820 setfield_bool_if(L, "shader", !!paint->getShader());
reed@google.com29563872013-07-10 21:23:49 +0000821 setfield_bool_if(L, "colorFilter", !!paint->getColorFilter());
822 setfield_bool_if(L, "imageFilter", !!paint->getImageFilter());
reed@google.com29563872013-07-10 21:23:49 +0000823 return 1;
824}
825
reed22a517f2015-12-04 20:45:59 -0800826static int lpaint_getColorFilter(lua_State* L) {
827 const SkPaint* paint = get_obj<SkPaint>(L, 1);
828 SkColorFilter* cf = paint->getColorFilter();
829 if (cf) {
830 push_ref(L, cf);
831 return 1;
832 }
833 return 0;
834}
835
836static int lpaint_setColorFilter(lua_State* L) {
837 SkPaint* paint = get_obj<SkPaint>(L, 1);
reedd053ce92016-03-22 10:17:23 -0700838 paint->setColorFilter(sk_ref_sp(get_ref<SkColorFilter>(L, 2)));
reed22a517f2015-12-04 20:45:59 -0800839 return 0;
840}
841
reed468b1812014-10-19 11:42:54 -0700842static int lpaint_getImageFilter(lua_State* L) {
843 const SkPaint* paint = get_obj<SkPaint>(L, 1);
844 SkImageFilter* imf = paint->getImageFilter();
845 if (imf) {
846 push_ref(L, imf);
847 return 1;
848 }
849 return 0;
850}
851
852static int lpaint_setImageFilter(lua_State* L) {
853 SkPaint* paint = get_obj<SkPaint>(L, 1);
Mike Reed5e257172016-11-01 11:22:05 -0400854 paint->setImageFilter(sk_ref_sp(get_ref<SkImageFilter>(L, 2)));
reed468b1812014-10-19 11:42:54 -0700855 return 0;
856}
857
reed@google.com5fdc9832013-07-24 15:47:52 +0000858static int lpaint_getShader(lua_State* L) {
859 const SkPaint* paint = get_obj<SkPaint>(L, 1);
860 SkShader* shader = paint->getShader();
861 if (shader) {
862 push_ref(L, shader);
863 return 1;
864 }
865 return 0;
866}
867
reed9fbc3f32014-10-21 07:12:58 -0700868static int lpaint_setShader(lua_State* L) {
869 SkPaint* paint = get_obj<SkPaint>(L, 1);
reedfe630452016-03-25 09:08:00 -0700870 paint->setShader(sk_ref_sp(get_ref<SkShader>(L, 2)));
reed9fbc3f32014-10-21 07:12:58 -0700871 return 0;
872}
873
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +0000874static int lpaint_getPathEffect(lua_State* L) {
875 const SkPaint* paint = get_obj<SkPaint>(L, 1);
876 SkPathEffect* pe = paint->getPathEffect();
877 if (pe) {
878 push_ref(L, pe);
879 return 1;
880 }
881 return 0;
882}
883
hstern0b401ce2016-08-02 09:17:59 -0700884static int lpaint_getFillPath(lua_State* L) {
885 const SkPaint* paint = get_obj<SkPaint>(L, 1);
886 const SkPath* path = get_obj<SkPath>(L, 2);
887
888 SkPath fillpath;
889 paint->getFillPath(*path, &fillpath);
890
891 SkLua lua(L);
892 lua.pushPath(fillpath);
893
894 return 1;
895}
896
reed@google.com74ce6f02013-05-22 15:13:18 +0000897static int lpaint_gc(lua_State* L) {
898 get_obj<SkPaint>(L, 1)->~SkPaint();
899 return 0;
900}
901
902static const struct luaL_Reg gSkPaint_Methods[] = {
903 { "isAntiAlias", lpaint_isAntiAlias },
904 { "setAntiAlias", lpaint_setAntiAlias },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000905 { "isDither", lpaint_isDither },
reedbb8a0ab2014-11-03 22:32:07 -0800906 { "setDither", lpaint_setDither },
reed93a12152015-03-16 10:08:34 -0700907 { "getFilterQuality", lpaint_getFilterQuality },
908 { "setFilterQuality", lpaint_setFilterQuality },
reed468b1812014-10-19 11:42:54 -0700909 { "getAlpha", lpaint_getAlpha },
910 { "setAlpha", lpaint_setAlpha },
reed@google.com74ce6f02013-05-22 15:13:18 +0000911 { "getColor", lpaint_getColor },
912 { "setColor", lpaint_setColor },
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000913 { "getStroke", lpaint_getStroke },
914 { "setStroke", lpaint_setStroke },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000915 { "getStrokeCap", lpaint_getStrokeCap },
916 { "getStrokeJoin", lpaint_getStrokeJoin },
mike@reedtribe.org73d9f1c2013-06-09 01:54:56 +0000917 { "getStrokeWidth", lpaint_getStrokeWidth },
918 { "setStrokeWidth", lpaint_setStrokeWidth },
commit-bot@chromium.org1cd71fb2013-12-18 18:28:07 +0000919 { "getStrokeMiter", lpaint_getStrokeMiter },
reed@google.com29563872013-07-10 21:23:49 +0000920 { "getEffects", lpaint_getEffects },
reed22a517f2015-12-04 20:45:59 -0800921 { "getColorFilter", lpaint_getColorFilter },
922 { "setColorFilter", lpaint_setColorFilter },
reed468b1812014-10-19 11:42:54 -0700923 { "getImageFilter", lpaint_getImageFilter },
924 { "setImageFilter", lpaint_setImageFilter },
reed@google.com5fdc9832013-07-24 15:47:52 +0000925 { "getShader", lpaint_getShader },
reed9fbc3f32014-10-21 07:12:58 -0700926 { "setShader", lpaint_setShader },
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +0000927 { "getPathEffect", lpaint_getPathEffect },
hstern0b401ce2016-08-02 09:17:59 -0700928 { "getFillPath", lpaint_getFillPath },
reed@google.com74ce6f02013-05-22 15:13:18 +0000929 { "__gc", lpaint_gc },
halcanary96fcdcc2015-08-27 07:41:13 -0700930 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +0000931};
932
933///////////////////////////////////////////////////////////////////////////////
934
Mike Reed91919132019-01-02 12:21:01 -0500935static int lfont_getSize(lua_State* L) {
936 SkLua(L).pushScalar(get_obj<SkFont>(L, 1)->getSize());
937 return 1;
938}
939
940static int lfont_getScaleX(lua_State* L) {
941 SkLua(L).pushScalar(get_obj<SkFont>(L, 1)->getScaleX());
942 return 1;
943}
944
945static int lfont_getSkewX(lua_State* L) {
946 SkLua(L).pushScalar(get_obj<SkFont>(L, 1)->getSkewX());
947 return 1;
948}
949
950static int lfont_setSize(lua_State* L) {
951 get_obj<SkFont>(L, 1)->setSize(lua2scalar(L, 2));
952 return 0;
953}
954
955static int lfont_getTypeface(lua_State* L) {
Herb Derby087fad72019-01-22 14:45:16 -0500956 push_ref(L, get_obj<SkFont>(L, 1)->getTypefaceOrDefault());
Mike Reed91919132019-01-02 12:21:01 -0500957 return 1;
958}
959
960static int lfont_setTypeface(lua_State* L) {
961 get_obj<SkFont>(L, 1)->setTypeface(sk_ref_sp(get_ref<SkTypeface>(L, 2)));
962 return 0;
963}
964
965static int lfont_getHinting(lua_State* L) {
966 SkLua(L).pushU32((unsigned)get_obj<SkFont>(L, 1)->getHinting());
967 return 1;
968}
969
970static int lfont_getFontID(lua_State* L) {
Herb Derby087fad72019-01-22 14:45:16 -0500971 SkTypeface* face = get_obj<SkFont>(L, 1)->getTypefaceOrDefault();
Mike Reed91919132019-01-02 12:21:01 -0500972 SkLua(L).pushU32(SkTypeface::UniqueID(face));
973 return 1;
974}
975
976static int lfont_measureText(lua_State* L) {
977 if (lua_isstring(L, 2)) {
978 size_t len;
979 const char* text = lua_tolstring(L, 2, &len);
980 SkLua(L).pushScalar(get_obj<SkFont>(L, 1)->measureText(text, len, kUTF8_SkTextEncoding));
981 return 1;
982 }
983 return 0;
984}
985
986static int lfont_getMetrics(lua_State* L) {
987 SkFontMetrics fm;
988 SkScalar height = get_obj<SkFont>(L, 1)->getMetrics(&fm);
989
990 lua_newtable(L);
991 setfield_scalar(L, "top", fm.fTop);
992 setfield_scalar(L, "ascent", fm.fAscent);
993 setfield_scalar(L, "descent", fm.fDescent);
994 setfield_scalar(L, "bottom", fm.fBottom);
995 setfield_scalar(L, "leading", fm.fLeading);
996 SkLua(L).pushScalar(height);
997 return 2;
998}
999
1000static int lfont_gc(lua_State* L) {
1001 get_obj<SkFont>(L, 1)->~SkFont();
1002 return 0;
1003}
1004
1005static const struct luaL_Reg gSkFont_Methods[] = {
1006 { "getSize", lfont_getSize },
1007 { "setSize", lfont_setSize },
1008 { "getScaleX", lfont_getScaleX },
1009 { "getSkewX", lfont_getSkewX },
1010 { "getTypeface", lfont_getTypeface },
1011 { "setTypeface", lfont_setTypeface },
1012 { "getHinting", lfont_getHinting },
1013 { "getFontID", lfont_getFontID },
1014 { "measureText", lfont_measureText },
1015 { "getMetrics", lfont_getMetrics },
1016 { "__gc", lfont_gc },
1017 { nullptr, nullptr }
1018};
1019
1020///////////////////////////////////////////////////////////////////////////////
1021
Mike Reedfae8fce2019-04-03 10:27:45 -04001022static const char* mode2string(SkTileMode mode) {
1023 static const char* gNames[] = { "clamp", "repeat", "mirror", "decal" };
reed@google.com5fdc9832013-07-24 15:47:52 +00001024 SkASSERT((unsigned)mode < SK_ARRAY_COUNT(gNames));
Mike Reedfae8fce2019-04-03 10:27:45 -04001025 return gNames[static_cast<int>(mode)];
reed@google.com5fdc9832013-07-24 15:47:52 +00001026}
1027
1028static const char* gradtype2string(SkShader::GradientType t) {
1029 static const char* gNames[] = {
1030 "none", "color", "linear", "radial", "radial2", "sweep", "conical"
1031 };
1032 SkASSERT((unsigned)t < SK_ARRAY_COUNT(gNames));
1033 return gNames[t];
1034}
1035
1036static int lshader_isOpaque(lua_State* L) {
1037 SkShader* shader = get_ref<SkShader>(L, 1);
1038 return shader && shader->isOpaque();
1039}
1040
Mike Reed627778d2016-09-28 17:13:38 -04001041static int lshader_isAImage(lua_State* L) {
reed@google.com5fdc9832013-07-24 15:47:52 +00001042 SkShader* shader = get_ref<SkShader>(L, 1);
1043 if (shader) {
reed@google.com5fdc9832013-07-24 15:47:52 +00001044 SkMatrix matrix;
Mike Reedfae8fce2019-04-03 10:27:45 -04001045 SkTileMode modes[2];
Mike Reed627778d2016-09-28 17:13:38 -04001046 if (SkImage* image = shader->isAImage(&matrix, modes)) {
reedf5822822015-08-19 11:46:38 -07001047 lua_newtable(L);
Mike Reed627778d2016-09-28 17:13:38 -04001048 setfield_number(L, "id", image->uniqueID());
1049 setfield_number(L, "width", image->width());
1050 setfield_number(L, "height", image->height());
reedf5822822015-08-19 11:46:38 -07001051 setfield_string(L, "tileX", mode2string(modes[0]));
1052 setfield_string(L, "tileY", mode2string(modes[1]));
1053 return 1;
reed@google.com5fdc9832013-07-24 15:47:52 +00001054 }
1055 }
1056 return 0;
1057}
1058
1059static int lshader_asAGradient(lua_State* L) {
1060 SkShader* shader = get_ref<SkShader>(L, 1);
1061 if (shader) {
1062 SkShader::GradientInfo info;
1063 sk_bzero(&info, sizeof(info));
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001064
reed@google.com5fdc9832013-07-24 15:47:52 +00001065 SkShader::GradientType t = shader->asAGradient(&info);
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001066
reed@google.com5fdc9832013-07-24 15:47:52 +00001067 if (SkShader::kNone_GradientType != t) {
fmenozzib4f254e2016-06-28 14:03:03 -07001068 SkAutoTArray<SkScalar> pos(info.fColorCount);
1069 info.fColorOffsets = pos.get();
1070 shader->asAGradient(&info);
commit-bot@chromium.org74f96b92013-08-01 17:32:56 +00001071
fmenozzib4f254e2016-06-28 14:03:03 -07001072 lua_newtable(L);
fmenozzi7f2c85e2016-07-12 09:17:39 -07001073 setfield_string(L, "type", gradtype2string(t));
Mike Reedfae8fce2019-04-03 10:27:45 -04001074 setfield_string(L, "tile", mode2string((SkTileMode)info.fTileMode));
fmenozzi7f2c85e2016-07-12 09:17:39 -07001075 setfield_number(L, "colorCount", info.fColorCount);
fmenozzib4f254e2016-06-28 14:03:03 -07001076
1077 lua_newtable(L);
1078 for (int i = 0; i < info.fColorCount; i++) {
1079 // Lua uses 1-based indexing
1080 setarray_scalar(L, i+1, pos[i]);
1081 }
1082 lua_setfield(L, -2, "positions");
1083
reed@google.com5fdc9832013-07-24 15:47:52 +00001084 return 1;
1085 }
1086 }
1087 return 0;
1088}
1089
1090static int lshader_gc(lua_State* L) {
1091 get_ref<SkShader>(L, 1)->unref();
1092 return 0;
1093}
1094
1095static const struct luaL_Reg gSkShader_Methods[] = {
1096 { "isOpaque", lshader_isOpaque },
Mike Reed627778d2016-09-28 17:13:38 -04001097 { "isAImage", lshader_isAImage },
reed@google.com5fdc9832013-07-24 15:47:52 +00001098 { "asAGradient", lshader_asAGradient },
1099 { "__gc", lshader_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001100 { nullptr, nullptr }
reed@google.com5fdc9832013-07-24 15:47:52 +00001101};
1102
1103///////////////////////////////////////////////////////////////////////////////
1104
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +00001105static int lpatheffect_asADash(lua_State* L) {
1106 SkPathEffect* pe = get_ref<SkPathEffect>(L, 1);
1107 if (pe) {
1108 SkPathEffect::DashInfo info;
1109 SkPathEffect::DashType dashType = pe->asADash(&info);
1110 if (SkPathEffect::kDash_DashType == dashType) {
1111 SkAutoTArray<SkScalar> intervals(info.fCount);
1112 info.fIntervals = intervals.get();
1113 pe->asADash(&info);
1114 SkLua(L).pushDash(info);
1115 return 1;
1116 }
1117 }
1118 return 0;
1119}
1120
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001121static int lpatheffect_gc(lua_State* L) {
1122 get_ref<SkPathEffect>(L, 1)->unref();
1123 return 0;
1124}
1125
1126static const struct luaL_Reg gSkPathEffect_Methods[] = {
commit-bot@chromium.org4d803a92014-05-14 16:03:14 +00001127 { "asADash", lpatheffect_asADash },
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001128 { "__gc", lpatheffect_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001129 { nullptr, nullptr }
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00001130};
1131
1132///////////////////////////////////////////////////////////////////////////////
1133
reed22a517f2015-12-04 20:45:59 -08001134static int lpcolorfilter_gc(lua_State* L) {
1135 get_ref<SkColorFilter>(L, 1)->unref();
1136 return 0;
1137}
1138
1139static const struct luaL_Reg gSkColorFilter_Methods[] = {
1140 { "__gc", lpcolorfilter_gc },
1141 { nullptr, nullptr }
1142};
1143
1144///////////////////////////////////////////////////////////////////////////////
1145
reed468b1812014-10-19 11:42:54 -07001146static int lpimagefilter_gc(lua_State* L) {
1147 get_ref<SkImageFilter>(L, 1)->unref();
1148 return 0;
1149}
1150
1151static const struct luaL_Reg gSkImageFilter_Methods[] = {
1152 { "__gc", lpimagefilter_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001153 { nullptr, nullptr }
reed468b1812014-10-19 11:42:54 -07001154};
1155
1156///////////////////////////////////////////////////////////////////////////////
1157
humper@google.com2815c192013-07-10 22:42:30 +00001158static int lmatrix_getType(lua_State* L) {
1159 SkMatrix::TypeMask mask = get_obj<SkMatrix>(L, 1)->getType();
skia.committer@gmail.comde2e4e82013-07-11 07:01:01 +00001160
humper@google.com2815c192013-07-10 22:42:30 +00001161 lua_newtable(L);
1162 setfield_boolean(L, "translate", SkToBool(mask & SkMatrix::kTranslate_Mask));
1163 setfield_boolean(L, "scale", SkToBool(mask & SkMatrix::kScale_Mask));
1164 setfield_boolean(L, "affine", SkToBool(mask & SkMatrix::kAffine_Mask));
1165 setfield_boolean(L, "perspective", SkToBool(mask & SkMatrix::kPerspective_Mask));
1166 return 1;
1167}
1168
humper@google.com0f48ee02013-07-26 15:23:43 +00001169static int lmatrix_getScaleX(lua_State* L) {
1170 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getScaleX());
1171 return 1;
1172}
1173
1174static int lmatrix_getScaleY(lua_State* L) {
1175 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getScaleY());
1176 return 1;
1177}
1178
1179static int lmatrix_getTranslateX(lua_State* L) {
1180 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getTranslateX());
1181 return 1;
1182}
1183
1184static int lmatrix_getTranslateY(lua_State* L) {
1185 lua_pushnumber(L, get_obj<SkMatrix>(L,1)->getTranslateY());
1186 return 1;
1187}
1188
reed7a72c672014-11-07 10:23:55 -08001189static int lmatrix_invert(lua_State* L) {
1190 lua_pushboolean(L, get_obj<SkMatrix>(L, 1)->invert(get_obj<SkMatrix>(L, 2)));
1191 return 1;
1192}
1193
1194static int lmatrix_mapXY(lua_State* L) {
1195 SkPoint pt = { lua2scalar(L, 2), lua2scalar(L, 3) };
1196 get_obj<SkMatrix>(L, 1)->mapPoints(&pt, &pt, 1);
1197 lua_pushnumber(L, pt.x());
1198 lua_pushnumber(L, pt.y());
1199 return 2;
1200}
1201
reedbdc49ae2014-10-14 09:34:52 -07001202static int lmatrix_setRectToRect(lua_State* L) {
1203 SkMatrix* matrix = get_obj<SkMatrix>(L, 1);
1204 SkRect srcR, dstR;
1205 lua2rect(L, 2, &srcR);
1206 lua2rect(L, 3, &dstR);
1207 const char* scaleToFitStr = lua_tostring(L, 4);
1208 SkMatrix::ScaleToFit scaleToFit = SkMatrix::kFill_ScaleToFit;
1209
1210 if (scaleToFitStr) {
1211 const struct {
1212 const char* fName;
1213 SkMatrix::ScaleToFit fScaleToFit;
1214 } rec[] = {
1215 { "fill", SkMatrix::kFill_ScaleToFit },
1216 { "start", SkMatrix::kStart_ScaleToFit },
1217 { "center", SkMatrix::kCenter_ScaleToFit },
1218 { "end", SkMatrix::kEnd_ScaleToFit },
1219 };
1220
1221 for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
1222 if (strcmp(rec[i].fName, scaleToFitStr) == 0) {
1223 scaleToFit = rec[i].fScaleToFit;
1224 break;
1225 }
1226 }
1227 }
1228
1229 matrix->setRectToRect(srcR, dstR, scaleToFit);
1230 return 0;
1231}
1232
humper@google.com2815c192013-07-10 22:42:30 +00001233static const struct luaL_Reg gSkMatrix_Methods[] = {
1234 { "getType", lmatrix_getType },
humper@google.com0f48ee02013-07-26 15:23:43 +00001235 { "getScaleX", lmatrix_getScaleX },
1236 { "getScaleY", lmatrix_getScaleY },
1237 { "getTranslateX", lmatrix_getTranslateX },
1238 { "getTranslateY", lmatrix_getTranslateY },
reedbdc49ae2014-10-14 09:34:52 -07001239 { "setRectToRect", lmatrix_setRectToRect },
reed7a72c672014-11-07 10:23:55 -08001240 { "invert", lmatrix_invert },
1241 { "mapXY", lmatrix_mapXY },
halcanary96fcdcc2015-08-27 07:41:13 -07001242 { nullptr, nullptr }
humper@google.com2815c192013-07-10 22:42:30 +00001243};
1244
1245///////////////////////////////////////////////////////////////////////////////
1246
reed@google.com74ce6f02013-05-22 15:13:18 +00001247static int lpath_getBounds(lua_State* L) {
1248 SkLua(L).pushRect(get_obj<SkPath>(L, 1)->getBounds());
1249 return 1;
1250}
1251
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001252static const char* fill_type_to_str(SkPath::FillType fill) {
1253 switch (fill) {
1254 case SkPath::kEvenOdd_FillType:
1255 return "even-odd";
1256 case SkPath::kWinding_FillType:
1257 return "winding";
1258 case SkPath::kInverseEvenOdd_FillType:
1259 return "inverse-even-odd";
1260 case SkPath::kInverseWinding_FillType:
1261 return "inverse-winding";
1262 }
1263 return "unknown";
1264}
1265
1266static int lpath_getFillType(lua_State* L) {
1267 SkPath::FillType fill = get_obj<SkPath>(L, 1)->getFillType();
1268 SkLua(L).pushString(fill_type_to_str(fill));
1269 return 1;
1270}
1271
1272static SkString segment_masks_to_str(uint32_t segmentMasks) {
1273 SkString result;
1274 bool first = true;
1275 if (SkPath::kLine_SegmentMask & segmentMasks) {
1276 result.append("line");
1277 first = false;
1278 SkDEBUGCODE(segmentMasks &= ~SkPath::kLine_SegmentMask;)
1279 }
1280 if (SkPath::kQuad_SegmentMask & segmentMasks) {
1281 if (!first) {
1282 result.append(" ");
1283 }
1284 result.append("quad");
1285 first = false;
1286 SkDEBUGCODE(segmentMasks &= ~SkPath::kQuad_SegmentMask;)
1287 }
1288 if (SkPath::kConic_SegmentMask & segmentMasks) {
1289 if (!first) {
1290 result.append(" ");
1291 }
1292 result.append("conic");
1293 first = false;
1294 SkDEBUGCODE(segmentMasks &= ~SkPath::kConic_SegmentMask;)
1295 }
1296 if (SkPath::kCubic_SegmentMask & segmentMasks) {
1297 if (!first) {
1298 result.append(" ");
1299 }
1300 result.append("cubic");
1301 SkDEBUGCODE(segmentMasks &= ~SkPath::kCubic_SegmentMask;)
1302 }
1303 SkASSERT(0 == segmentMasks);
1304 return result;
1305}
1306
krajcevski95498ed2014-08-18 08:02:33 -07001307static int lpath_getSegmentTypes(lua_State* L) {
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001308 uint32_t segMasks = get_obj<SkPath>(L, 1)->getSegmentMasks();
1309 SkLua(L).pushString(segment_masks_to_str(segMasks));
1310 return 1;
1311}
1312
1313static int lpath_isConvex(lua_State* L) {
1314 bool isConvex = SkPath::kConvex_Convexity == get_obj<SkPath>(L, 1)->getConvexity();
1315 SkLua(L).pushBool(isConvex);
1316 return 1;
1317}
1318
reed@google.com74ce6f02013-05-22 15:13:18 +00001319static int lpath_isEmpty(lua_State* L) {
1320 lua_pushboolean(L, get_obj<SkPath>(L, 1)->isEmpty());
1321 return 1;
1322}
1323
1324static int lpath_isRect(lua_State* L) {
1325 SkRect r;
1326 bool pred = get_obj<SkPath>(L, 1)->isRect(&r);
1327 int ret_count = 1;
1328 lua_pushboolean(L, pred);
1329 if (pred) {
1330 SkLua(L).pushRect(r);
1331 ret_count += 1;
1332 }
1333 return ret_count;
1334}
1335
1336static const char* dir2string(SkPath::Direction dir) {
1337 static const char* gStr[] = {
1338 "unknown", "cw", "ccw"
1339 };
1340 SkASSERT((unsigned)dir < SK_ARRAY_COUNT(gStr));
1341 return gStr[dir];
1342}
1343
caryclark95bc5f32015-04-08 08:34:15 -07001344static int lpath_isNestedFillRects(lua_State* L) {
reed@google.com74ce6f02013-05-22 15:13:18 +00001345 SkRect rects[2];
1346 SkPath::Direction dirs[2];
caryclark95bc5f32015-04-08 08:34:15 -07001347 bool pred = get_obj<SkPath>(L, 1)->isNestedFillRects(rects, dirs);
reed@google.com74ce6f02013-05-22 15:13:18 +00001348 int ret_count = 1;
1349 lua_pushboolean(L, pred);
1350 if (pred) {
1351 SkLua lua(L);
1352 lua.pushRect(rects[0]);
1353 lua.pushRect(rects[1]);
1354 lua_pushstring(L, dir2string(dirs[0]));
1355 lua_pushstring(L, dir2string(dirs[0]));
1356 ret_count += 4;
1357 }
1358 return ret_count;
1359}
1360
commit-bot@chromium.orgc5302082014-02-26 21:38:47 +00001361static int lpath_countPoints(lua_State* L) {
1362 lua_pushinteger(L, get_obj<SkPath>(L, 1)->countPoints());
1363 return 1;
1364}
1365
hstern0b401ce2016-08-02 09:17:59 -07001366static int lpath_getVerbs(lua_State* L) {
1367 const SkPath* path = get_obj<SkPath>(L, 1);
1368 SkPath::Iter iter(*path, false);
1369 SkPoint pts[4];
1370
1371 lua_newtable(L);
1372
1373 bool done = false;
1374 int i = 0;
1375 do {
1376 switch (iter.next(pts, true)) {
1377 case SkPath::kMove_Verb:
1378 setarray_string(L, ++i, "move");
1379 break;
1380 case SkPath::kClose_Verb:
1381 setarray_string(L, ++i, "close");
1382 break;
1383 case SkPath::kLine_Verb:
1384 setarray_string(L, ++i, "line");
1385 break;
1386 case SkPath::kQuad_Verb:
1387 setarray_string(L, ++i, "quad");
1388 break;
1389 case SkPath::kConic_Verb:
1390 setarray_string(L, ++i, "conic");
1391 break;
1392 case SkPath::kCubic_Verb:
1393 setarray_string(L, ++i, "cubic");
1394 break;
1395 case SkPath::kDone_Verb:
1396 setarray_string(L, ++i, "done");
1397 done = true;
1398 break;
1399 }
1400 } while (!done);
1401
1402 return 1;
1403}
1404
reed@google.com74ce6f02013-05-22 15:13:18 +00001405static int lpath_reset(lua_State* L) {
1406 get_obj<SkPath>(L, 1)->reset();
1407 return 0;
1408}
1409
1410static int lpath_moveTo(lua_State* L) {
1411 get_obj<SkPath>(L, 1)->moveTo(lua2scalar(L, 2), lua2scalar(L, 3));
1412 return 0;
1413}
1414
1415static int lpath_lineTo(lua_State* L) {
1416 get_obj<SkPath>(L, 1)->lineTo(lua2scalar(L, 2), lua2scalar(L, 3));
1417 return 0;
1418}
1419
1420static int lpath_quadTo(lua_State* L) {
1421 get_obj<SkPath>(L, 1)->quadTo(lua2scalar(L, 2), lua2scalar(L, 3),
1422 lua2scalar(L, 4), lua2scalar(L, 5));
1423 return 0;
1424}
1425
1426static int lpath_cubicTo(lua_State* L) {
1427 get_obj<SkPath>(L, 1)->cubicTo(lua2scalar(L, 2), lua2scalar(L, 3),
1428 lua2scalar(L, 4), lua2scalar(L, 5),
1429 lua2scalar(L, 6), lua2scalar(L, 7));
1430 return 0;
1431}
1432
1433static int lpath_close(lua_State* L) {
1434 get_obj<SkPath>(L, 1)->close();
1435 return 0;
1436}
1437
1438static int lpath_gc(lua_State* L) {
1439 get_obj<SkPath>(L, 1)->~SkPath();
1440 return 0;
1441}
1442
1443static const struct luaL_Reg gSkPath_Methods[] = {
1444 { "getBounds", lpath_getBounds },
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001445 { "getFillType", lpath_getFillType },
krajcevski95498ed2014-08-18 08:02:33 -07001446 { "getSegmentTypes", lpath_getSegmentTypes },
hstern0b401ce2016-08-02 09:17:59 -07001447 { "getVerbs", lpath_getVerbs },
commit-bot@chromium.orgd85b8222014-02-24 21:59:29 +00001448 { "isConvex", lpath_isConvex },
reed@google.com74ce6f02013-05-22 15:13:18 +00001449 { "isEmpty", lpath_isEmpty },
1450 { "isRect", lpath_isRect },
caryclark95bc5f32015-04-08 08:34:15 -07001451 { "isNestedFillRects", lpath_isNestedFillRects },
commit-bot@chromium.orgc5302082014-02-26 21:38:47 +00001452 { "countPoints", lpath_countPoints },
reed@google.com74ce6f02013-05-22 15:13:18 +00001453 { "reset", lpath_reset },
1454 { "moveTo", lpath_moveTo },
1455 { "lineTo", lpath_lineTo },
1456 { "quadTo", lpath_quadTo },
1457 { "cubicTo", lpath_cubicTo },
1458 { "close", lpath_close },
1459 { "__gc", lpath_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001460 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001461};
1462
1463///////////////////////////////////////////////////////////////////////////////
1464
1465static const char* rrect_type(const SkRRect& rr) {
1466 switch (rr.getType()) {
reed@google.com74ce6f02013-05-22 15:13:18 +00001467 case SkRRect::kEmpty_Type: return "empty";
1468 case SkRRect::kRect_Type: return "rect";
1469 case SkRRect::kOval_Type: return "oval";
1470 case SkRRect::kSimple_Type: return "simple";
commit-bot@chromium.orgf338d7c2014-03-17 21:17:30 +00001471 case SkRRect::kNinePatch_Type: return "nine-patch";
reed@google.com74ce6f02013-05-22 15:13:18 +00001472 case SkRRect::kComplex_Type: return "complex";
1473 }
mtklein@google.com330313a2013-08-22 15:37:26 +00001474 SkDEBUGFAIL("never get here");
reed@google.com74ce6f02013-05-22 15:13:18 +00001475 return "";
1476}
1477
1478static int lrrect_rect(lua_State* L) {
1479 SkLua(L).pushRect(get_obj<SkRRect>(L, 1)->rect());
1480 return 1;
1481}
1482
1483static int lrrect_type(lua_State* L) {
1484 lua_pushstring(L, rrect_type(*get_obj<SkRRect>(L, 1)));
1485 return 1;
1486}
1487
1488static int lrrect_radii(lua_State* L) {
reed@google.com7fa2a652014-01-27 13:42:58 +00001489 int corner = SkToInt(lua_tointeger(L, 2));
reed@google.com74ce6f02013-05-22 15:13:18 +00001490 SkVector v;
1491 if (corner < 0 || corner > 3) {
1492 SkDebugf("bad corner index %d", corner);
1493 v.set(0, 0);
1494 } else {
1495 v = get_obj<SkRRect>(L, 1)->radii((SkRRect::Corner)corner);
1496 }
1497 lua_pushnumber(L, v.fX);
1498 lua_pushnumber(L, v.fY);
1499 return 2;
1500}
1501
1502static int lrrect_gc(lua_State* L) {
1503 get_obj<SkRRect>(L, 1)->~SkRRect();
1504 return 0;
1505}
1506
1507static const struct luaL_Reg gSkRRect_Methods[] = {
1508 { "rect", lrrect_rect },
1509 { "type", lrrect_type },
1510 { "radii", lrrect_radii },
1511 { "__gc", lrrect_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001512 { nullptr, nullptr }
reed@google.com74ce6f02013-05-22 15:13:18 +00001513};
1514
1515///////////////////////////////////////////////////////////////////////////////
1516
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001517static int limage_width(lua_State* L) {
1518 lua_pushinteger(L, get_ref<SkImage>(L, 1)->width());
1519 return 1;
1520}
1521
1522static int limage_height(lua_State* L) {
1523 lua_pushinteger(L, get_ref<SkImage>(L, 1)->height());
1524 return 1;
1525}
1526
reed7a72c672014-11-07 10:23:55 -08001527static int limage_newShader(lua_State* L) {
Mike Reedfae8fce2019-04-03 10:27:45 -04001528 SkTileMode tmode = SkTileMode::kClamp;
halcanary96fcdcc2015-08-27 07:41:13 -07001529 const SkMatrix* localM = nullptr;
reed5671c5b2016-03-09 14:47:34 -08001530 push_ref(L, get_ref<SkImage>(L, 1)->makeShader(tmode, tmode, localM));
reed7a72c672014-11-07 10:23:55 -08001531 return 1;
1532}
1533
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001534static int limage_gc(lua_State* L) {
1535 get_ref<SkImage>(L, 1)->unref();
1536 return 0;
1537}
1538
1539static const struct luaL_Reg gSkImage_Methods[] = {
1540 { "width", limage_width },
1541 { "height", limage_height },
reed7a72c672014-11-07 10:23:55 -08001542 { "newShader", limage_newShader },
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001543 { "__gc", limage_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001544 { nullptr, nullptr }
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001545};
1546
1547///////////////////////////////////////////////////////////////////////////////
1548
reed485557f2014-10-12 10:36:47 -07001549static int lsurface_width(lua_State* L) {
1550 lua_pushinteger(L, get_ref<SkSurface>(L, 1)->width());
1551 return 1;
1552}
1553
1554static int lsurface_height(lua_State* L) {
1555 lua_pushinteger(L, get_ref<SkSurface>(L, 1)->height());
1556 return 1;
1557}
1558
1559static int lsurface_getCanvas(lua_State* L) {
1560 SkCanvas* canvas = get_ref<SkSurface>(L, 1)->getCanvas();
halcanary96fcdcc2015-08-27 07:41:13 -07001561 if (nullptr == canvas) {
reed485557f2014-10-12 10:36:47 -07001562 lua_pushnil(L);
1563 } else {
Mike Reed5df49342016-11-12 08:06:55 -06001564 push_ptr(L, canvas);
reed485557f2014-10-12 10:36:47 -07001565 // note: we don't unref canvas, since getCanvas did not ref it.
1566 // warning: this is weird: now Lua owns a ref on this canvas, but what if they let
1567 // the real owner (the surface) go away, but still hold onto the canvas?
1568 // *really* we want to sort of ref the surface again, but have the native object
1569 // know that it is supposed to be treated as a canvas...
1570 }
1571 return 1;
1572}
1573
1574static int lsurface_newImageSnapshot(lua_State* L) {
reed9ce9d672016-03-17 10:51:11 -07001575 sk_sp<SkImage> image = get_ref<SkSurface>(L, 1)->makeImageSnapshot();
1576 if (!image) {
reed485557f2014-10-12 10:36:47 -07001577 lua_pushnil(L);
1578 } else {
reed9ce9d672016-03-17 10:51:11 -07001579 push_ref(L, image);
reed485557f2014-10-12 10:36:47 -07001580 }
1581 return 1;
1582}
1583
1584static int lsurface_newSurface(lua_State* L) {
1585 int width = lua2int_def(L, 2, 0);
reed96affcd2014-10-13 12:38:04 -07001586 int height = lua2int_def(L, 3, 0);
reed485557f2014-10-12 10:36:47 -07001587 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
reede8f30622016-03-23 18:59:25 -07001588 auto surface = get_ref<SkSurface>(L, 1)->makeSurface(info);
halcanary96fcdcc2015-08-27 07:41:13 -07001589 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -07001590 lua_pushnil(L);
1591 } else {
reede8f30622016-03-23 18:59:25 -07001592 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -07001593 }
1594 return 1;
1595}
1596
1597static int lsurface_gc(lua_State* L) {
1598 get_ref<SkSurface>(L, 1)->unref();
1599 return 0;
1600}
1601
1602static const struct luaL_Reg gSkSurface_Methods[] = {
1603 { "width", lsurface_width },
1604 { "height", lsurface_height },
1605 { "getCanvas", lsurface_getCanvas },
1606 { "newImageSnapshot", lsurface_newImageSnapshot },
1607 { "newSurface", lsurface_newSurface },
1608 { "__gc", lsurface_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001609 { nullptr, nullptr }
reed485557f2014-10-12 10:36:47 -07001610};
1611
1612///////////////////////////////////////////////////////////////////////////////
1613
reed96affcd2014-10-13 12:38:04 -07001614static int lpicturerecorder_beginRecording(lua_State* L) {
1615 const SkScalar w = lua2scalar_def(L, 2, -1);
1616 const SkScalar h = lua2scalar_def(L, 3, -1);
1617 if (w <= 0 || h <= 0) {
1618 lua_pushnil(L);
1619 return 1;
1620 }
1621
1622 SkCanvas* canvas = get_obj<SkPictureRecorder>(L, 1)->beginRecording(w, h);
halcanary96fcdcc2015-08-27 07:41:13 -07001623 if (nullptr == canvas) {
reed96affcd2014-10-13 12:38:04 -07001624 lua_pushnil(L);
1625 return 1;
1626 }
1627
Mike Reed5df49342016-11-12 08:06:55 -06001628 push_ptr(L, canvas);
reed96affcd2014-10-13 12:38:04 -07001629 return 1;
1630}
1631
1632static int lpicturerecorder_getCanvas(lua_State* L) {
1633 SkCanvas* canvas = get_obj<SkPictureRecorder>(L, 1)->getRecordingCanvas();
halcanary96fcdcc2015-08-27 07:41:13 -07001634 if (nullptr == canvas) {
reed96affcd2014-10-13 12:38:04 -07001635 lua_pushnil(L);
1636 return 1;
1637 }
Mike Reed5df49342016-11-12 08:06:55 -06001638 push_ptr(L, canvas);
reed96affcd2014-10-13 12:38:04 -07001639 return 1;
1640}
1641
1642static int lpicturerecorder_endRecording(lua_State* L) {
reedca2622b2016-03-18 07:25:55 -07001643 sk_sp<SkPicture> pic = get_obj<SkPictureRecorder>(L, 1)->finishRecordingAsPicture();
1644 if (!pic) {
reed96affcd2014-10-13 12:38:04 -07001645 lua_pushnil(L);
1646 return 1;
1647 }
reedca2622b2016-03-18 07:25:55 -07001648 push_ref(L, std::move(pic));
reed96affcd2014-10-13 12:38:04 -07001649 return 1;
1650}
1651
1652static int lpicturerecorder_gc(lua_State* L) {
1653 get_obj<SkPictureRecorder>(L, 1)->~SkPictureRecorder();
1654 return 0;
1655}
1656
1657static const struct luaL_Reg gSkPictureRecorder_Methods[] = {
1658 { "beginRecording", lpicturerecorder_beginRecording },
1659 { "getCanvas", lpicturerecorder_getCanvas },
1660 { "endRecording", lpicturerecorder_endRecording },
1661 { "__gc", lpicturerecorder_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001662 { nullptr, nullptr }
reed96affcd2014-10-13 12:38:04 -07001663};
1664
1665///////////////////////////////////////////////////////////////////////////////
1666
1667static int lpicture_width(lua_State* L) {
1668 lua_pushnumber(L, get_ref<SkPicture>(L, 1)->cullRect().width());
1669 return 1;
1670}
1671
1672static int lpicture_height(lua_State* L) {
1673 lua_pushnumber(L, get_ref<SkPicture>(L, 1)->cullRect().height());
1674 return 1;
1675}
1676
1677static int lpicture_gc(lua_State* L) {
1678 get_ref<SkPicture>(L, 1)->unref();
1679 return 0;
1680}
1681
1682static const struct luaL_Reg gSkPicture_Methods[] = {
1683 { "width", lpicture_width },
1684 { "height", lpicture_height },
1685 { "__gc", lpicture_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001686 { nullptr, nullptr }
reed96affcd2014-10-13 12:38:04 -07001687};
1688
1689///////////////////////////////////////////////////////////////////////////////
1690
reed1b6ab442014-11-03 19:55:41 -08001691static int ltextblob_bounds(lua_State* L) {
1692 SkLua(L).pushRect(get_ref<SkTextBlob>(L, 1)->bounds());
1693 return 1;
1694}
1695
1696static int ltextblob_gc(lua_State* L) {
1697 SkSafeUnref(get_ref<SkTextBlob>(L, 1));
1698 return 0;
1699}
1700
1701static const struct luaL_Reg gSkTextBlob_Methods[] = {
1702 { "bounds", ltextblob_bounds },
1703 { "__gc", ltextblob_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001704 { nullptr, nullptr }
reed1b6ab442014-11-03 19:55:41 -08001705};
1706
1707///////////////////////////////////////////////////////////////////////////////
1708
reed36c9c112014-11-04 10:58:42 -08001709static int ltypeface_getFamilyName(lua_State* L) {
1710 SkString str;
1711 get_ref<SkTypeface>(L, 1)->getFamilyName(&str);
1712 lua_pushstring(L, str.c_str());
1713 return 1;
1714}
1715
1716static int ltypeface_getStyle(lua_State* L) {
Ben Wagner26308e12017-08-08 15:23:47 -04001717 push_obj(L, get_ref<SkTypeface>(L, 1)->fontStyle());
reed36c9c112014-11-04 10:58:42 -08001718 return 1;
1719}
1720
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001721static int ltypeface_gc(lua_State* L) {
commit-bot@chromium.org77887af2013-12-17 14:28:19 +00001722 SkSafeUnref(get_ref<SkTypeface>(L, 1));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001723 return 0;
1724}
1725
1726static const struct luaL_Reg gSkTypeface_Methods[] = {
reed36c9c112014-11-04 10:58:42 -08001727 { "getFamilyName", ltypeface_getFamilyName },
1728 { "getStyle", ltypeface_getStyle },
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001729 { "__gc", ltypeface_gc },
halcanary96fcdcc2015-08-27 07:41:13 -07001730 { nullptr, nullptr }
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001731};
1732
1733///////////////////////////////////////////////////////////////////////////////
1734
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001735static int lfontstyle_weight(lua_State* L) {
1736 lua_pushnumber(L, get_ref<SkFontStyle>(L, 1)->weight());
1737 return 1;
1738}
1739
1740static int lfontstyle_width(lua_State* L) {
1741 lua_pushnumber(L, get_ref<SkFontStyle>(L, 1)->width());
1742 return 1;
1743}
1744
1745static int lfontstyle_slant(lua_State* L) {
1746 lua_pushnumber(L, get_ref<SkFontStyle>(L, 1)->slant());
1747 return 1;
1748}
1749
1750static int lfontstyle_gc(lua_State* L) {
1751 get_obj<SkFontStyle>(L, 1)->~SkFontStyle();
1752 return 0;
1753}
1754
1755static const struct luaL_Reg gSkFontStyle_Methods[] = {
1756 { "weight", lfontstyle_weight },
1757 { "width", lfontstyle_width },
1758 { "slant", lfontstyle_slant },
1759 { "__gc", lfontstyle_gc },
1760 { nullptr, nullptr }
1761};
1762
1763///////////////////////////////////////////////////////////////////////////////
1764
reed@google.com74ce6f02013-05-22 15:13:18 +00001765class AutoCallLua {
1766public:
1767 AutoCallLua(lua_State* L, const char func[], const char verb[]) : fL(L) {
1768 lua_getglobal(L, func);
1769 if (!lua_isfunction(L, -1)) {
1770 int t = lua_type(L, -1);
1771 SkDebugf("--- expected function %d\n", t);
1772 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001773
reed@google.com74ce6f02013-05-22 15:13:18 +00001774 lua_newtable(L);
1775 setfield_string(L, "verb", verb);
1776 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001777
reed@google.com74ce6f02013-05-22 15:13:18 +00001778 ~AutoCallLua() {
1779 if (lua_pcall(fL, 1, 0, 0) != LUA_OK) {
1780 SkDebugf("lua err: %s\n", lua_tostring(fL, -1));
1781 }
1782 lua_settop(fL, -1);
1783 }
skia.committer@gmail.com2d816ad2013-05-23 07:01:22 +00001784
reed@google.com74ce6f02013-05-22 15:13:18 +00001785private:
1786 lua_State* fL;
1787};
1788
1789#define AUTO_LUA(verb) AutoCallLua acl(fL, fFunc.c_str(), verb)
1790
1791///////////////////////////////////////////////////////////////////////////////
1792
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001793static int lsk_newDocumentPDF(lua_State* L) {
Mike Reed7ff6ca52018-01-08 14:45:31 -05001794 const char* filename = nullptr;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001795 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
Mike Reed7ff6ca52018-01-08 14:45:31 -05001796 filename = lua_tolstring(L, 1, nullptr);
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001797 }
Mike Reed7ff6ca52018-01-08 14:45:31 -05001798 if (!filename) {
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001799 return 0;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001800 }
Mike Reed7ff6ca52018-01-08 14:45:31 -05001801 auto file = skstd::make_unique<SkFILEWStream>(filename);
1802 if (!file->isValid()) {
1803 return 0;
1804 }
Hal Canary3026d4b2019-01-07 10:00:48 -05001805 auto doc = SkPDF::MakeDocument(file.get());
Mike Reed7ff6ca52018-01-08 14:45:31 -05001806 if (!doc) {
1807 return 0;
1808 }
1809 push_ptr(L, new DocHolder{std::move(doc), std::move(file)});
1810 return 1;
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001811}
1812
reed468b1812014-10-19 11:42:54 -07001813static int lsk_newBlurImageFilter(lua_State* L) {
1814 SkScalar sigmaX = lua2scalar_def(L, 1, 0);
1815 SkScalar sigmaY = lua2scalar_def(L, 2, 0);
robertphillips6e7025a2016-04-04 04:31:25 -07001816 sk_sp<SkImageFilter> imf(SkBlurImageFilter::Make(sigmaX, sigmaY, nullptr));
1817 if (!imf) {
reed468b1812014-10-19 11:42:54 -07001818 lua_pushnil(L);
1819 } else {
robertphillips6e7025a2016-04-04 04:31:25 -07001820 push_ref(L, std::move(imf));
reed9fbc3f32014-10-21 07:12:58 -07001821 }
1822 return 1;
1823}
1824
1825static int lsk_newLinearGradient(lua_State* L) {
1826 SkScalar x0 = lua2scalar_def(L, 1, 0);
1827 SkScalar y0 = lua2scalar_def(L, 2, 0);
1828 SkColor c0 = lua2color(L, 3);
1829 SkScalar x1 = lua2scalar_def(L, 4, 0);
1830 SkScalar y1 = lua2scalar_def(L, 5, 0);
1831 SkColor c1 = lua2color(L, 6);
1832
1833 SkPoint pts[] = { { x0, y0 }, { x1, y1 } };
1834 SkColor colors[] = { c0, c1 };
Mike Reedfae8fce2019-04-03 10:27:45 -04001835 sk_sp<SkShader> s(SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp));
reed2ad1aa62016-03-09 09:50:50 -08001836 if (!s) {
reed9fbc3f32014-10-21 07:12:58 -07001837 lua_pushnil(L);
1838 } else {
reed2ad1aa62016-03-09 09:50:50 -08001839 push_ref(L, std::move(s));
reed468b1812014-10-19 11:42:54 -07001840 }
1841 return 1;
1842}
1843
reedbdc49ae2014-10-14 09:34:52 -07001844static int lsk_newMatrix(lua_State* L) {
1845 push_new<SkMatrix>(L)->reset();
1846 return 1;
1847}
1848
reed@google.com3597b732013-05-22 20:12:50 +00001849static int lsk_newPaint(lua_State* L) {
1850 push_new<SkPaint>(L);
1851 return 1;
1852}
1853
1854static int lsk_newPath(lua_State* L) {
1855 push_new<SkPath>(L);
1856 return 1;
1857}
1858
reed96affcd2014-10-13 12:38:04 -07001859static int lsk_newPictureRecorder(lua_State* L) {
1860 push_new<SkPictureRecorder>(L);
1861 return 1;
1862}
1863
reed@google.com3597b732013-05-22 20:12:50 +00001864static int lsk_newRRect(lua_State* L) {
reedbdc49ae2014-10-14 09:34:52 -07001865 push_new<SkRRect>(L)->setEmpty();
reed@google.com3597b732013-05-22 20:12:50 +00001866 return 1;
1867}
1868
reed1b6ab442014-11-03 19:55:41 -08001869// Sk.newTextBlob(text, rect, paint)
1870static int lsk_newTextBlob(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07001871 const char* text = lua_tolstring(L, 1, nullptr);
reed1b6ab442014-11-03 19:55:41 -08001872 SkRect bounds;
1873 lua2rect(L, 2, &bounds);
reed1b6ab442014-11-03 19:55:41 -08001874
Ben Wagnerb0591942019-02-15 14:46:18 -05001875 std::unique_ptr<SkShaper> shaper = SkShaper::Make();
reed1b6ab442014-11-03 19:55:41 -08001876
Mike Reed5f528e52019-01-28 10:57:28 -05001877 // TODO: restore this logic based on SkFont instead of SkPaint
1878#if 0
Mike Reede5f9cfa2019-01-10 13:55:35 -05001879 const SkPaint& paint = *get_obj<SkPaint>(L, 3);
Hal Canary2a1848d2018-11-26 17:23:24 -05001880 SkFont font = SkFont::LEGACY_ExtractFromPaint(paint);
Mike Reede5f9cfa2019-01-10 13:55:35 -05001881#else
1882 SkFont font;
1883#endif
Ben Wagner3bdb69c2019-04-01 19:01:09 -04001884 SkTextBlobBuilderRunHandler builder(text, { bounds.left(), bounds.top() });
1885 shaper->shape(text, strlen(text), font, true, bounds.width(), &builder);
Herb Derby1724db12018-05-22 12:01:50 -04001886
Florin Malita9867f612018-12-12 10:54:49 -05001887 push_ref<SkTextBlob>(L, builder.makeBlob());
Ben Wagner3bdb69c2019-04-01 19:01:09 -04001888 SkLua(L).pushScalar(builder.endPoint().fY);
reed1b6ab442014-11-03 19:55:41 -08001889 return 2;
1890}
1891
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001892static int lsk_newTypeface(lua_State* L) {
halcanary96fcdcc2015-08-27 07:41:13 -07001893 const char* name = nullptr;
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001894 SkFontStyle style;
skia.committer@gmail.com63193672013-06-08 07:01:13 +00001895
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001896 int count = lua_gettop(L);
1897 if (count > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001898 name = lua_tolstring(L, 1, nullptr);
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001899 if (count > 1) {
1900 SkFontStyle* passedStyle = get_obj<SkFontStyle>(L, 2);
1901 if (passedStyle) {
1902 style = *passedStyle;
1903 }
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001904 }
1905 }
1906
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001907 sk_sp<SkTypeface> face(SkTypeface::MakeFromName(name, style));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001908// SkDebugf("---- name <%s> style=%d, face=%p ref=%d\n", name, style, face, face->getRefCnt());
halcanary96fcdcc2015-08-27 07:41:13 -07001909 if (nullptr == face) {
bungeman13b9c952016-05-12 10:09:30 -07001910 face = SkTypeface::MakeDefault();
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001911 }
bungeman13b9c952016-05-12 10:09:30 -07001912 push_ref(L, std::move(face));
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001913 return 1;
1914}
reed@google.com3597b732013-05-22 20:12:50 +00001915
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001916static int lsk_newFontStyle(lua_State* L) {
1917 int count = lua_gettop(L);
1918 int weight = SkFontStyle::kNormal_Weight;
1919 int width = SkFontStyle::kNormal_Width;
1920 SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant;
1921 if (count >= 1 && lua_isnumber(L, 1)) {
1922 weight = lua_tointegerx(L, 1, nullptr);
1923 }
1924 if (count >= 2 && lua_isnumber(L, 2)) {
1925 width = lua_tointegerx(L, 2, nullptr);
1926 }
1927 if (count >= 3 && lua_isnumber(L, 3)) {
1928 slant = static_cast<SkFontStyle::Slant>(lua_tointegerx(L, 3, nullptr));
1929 }
1930 push_new<SkFontStyle>(L, weight, width, slant);
1931 return 1;
1932}
1933
reed485557f2014-10-12 10:36:47 -07001934static int lsk_newRasterSurface(lua_State* L) {
reed7b864662014-11-04 13:24:47 -08001935 int width = lua2int_def(L, 1, 0);
reed485557f2014-10-12 10:36:47 -07001936 int height = lua2int_def(L, 2, 0);
1937 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
robertphillips702edbd2015-06-23 06:26:08 -07001938 SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
reede8f30622016-03-23 18:59:25 -07001939 auto surface = SkSurface::MakeRaster(info, &props);
halcanary96fcdcc2015-08-27 07:41:13 -07001940 if (nullptr == surface) {
reed485557f2014-10-12 10:36:47 -07001941 lua_pushnil(L);
1942 } else {
reede8f30622016-03-23 18:59:25 -07001943 push_ref(L, surface);
reed485557f2014-10-12 10:36:47 -07001944 }
1945 return 1;
1946}
1947
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001948static int lsk_loadImage(lua_State* L) {
1949 if (lua_gettop(L) > 0 && lua_isstring(L, 1)) {
halcanary96fcdcc2015-08-27 07:41:13 -07001950 const char* name = lua_tolstring(L, 1, nullptr);
reed9ce9d672016-03-17 10:51:11 -07001951 sk_sp<SkData> data(SkData::MakeFromFileName(name));
1952 if (data) {
1953 auto image = SkImage::MakeFromEncoded(std::move(data));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001954 if (image) {
reed9ce9d672016-03-17 10:51:11 -07001955 push_ref(L, std::move(image));
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001956 return 1;
1957 }
1958 }
1959 }
1960 return 0;
1961}
1962
reed@google.com3597b732013-05-22 20:12:50 +00001963static void register_Sk(lua_State* L) {
1964 lua_newtable(L);
1965 lua_pushvalue(L, -1);
1966 lua_setglobal(L, "Sk");
1967 // the Sk table is still on top
1968
mike@reedtribe.orgfb858242013-06-08 16:39:44 +00001969 setfield_function(L, "newDocumentPDF", lsk_newDocumentPDF);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00001970 setfield_function(L, "loadImage", lsk_loadImage);
reed468b1812014-10-19 11:42:54 -07001971 setfield_function(L, "newBlurImageFilter", lsk_newBlurImageFilter);
reed9fbc3f32014-10-21 07:12:58 -07001972 setfield_function(L, "newLinearGradient", lsk_newLinearGradient);
reedbdc49ae2014-10-14 09:34:52 -07001973 setfield_function(L, "newMatrix", lsk_newMatrix);
reed@google.com3597b732013-05-22 20:12:50 +00001974 setfield_function(L, "newPaint", lsk_newPaint);
1975 setfield_function(L, "newPath", lsk_newPath);
reed96affcd2014-10-13 12:38:04 -07001976 setfield_function(L, "newPictureRecorder", lsk_newPictureRecorder);
reed@google.com3597b732013-05-22 20:12:50 +00001977 setfield_function(L, "newRRect", lsk_newRRect);
reed485557f2014-10-12 10:36:47 -07001978 setfield_function(L, "newRasterSurface", lsk_newRasterSurface);
reed1b6ab442014-11-03 19:55:41 -08001979 setfield_function(L, "newTextBlob", lsk_newTextBlob);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00001980 setfield_function(L, "newTypeface", lsk_newTypeface);
Ben Wagnerc6c10b42017-08-07 09:56:21 -04001981 setfield_function(L, "newFontStyle", lsk_newFontStyle);
reed@google.com3597b732013-05-22 20:12:50 +00001982 lua_pop(L, 1); // pop off the Sk table
1983}
1984
reed@google.com74ce6f02013-05-22 15:13:18 +00001985#define REG_CLASS(L, C) \
1986 do { \
reed@google.com3597b732013-05-22 20:12:50 +00001987 luaL_newmetatable(L, get_mtname<C>()); \
reed@google.com74ce6f02013-05-22 15:13:18 +00001988 lua_pushvalue(L, -1); \
1989 lua_setfield(L, -2, "__index"); \
1990 luaL_setfuncs(L, g##C##_Methods, 0); \
1991 lua_pop(L, 1); /* pop off the meta-table */ \
1992 } while (0)
1993
1994void SkLua::Load(lua_State* L) {
reed@google.com3597b732013-05-22 20:12:50 +00001995 register_Sk(L);
reed@google.com74ce6f02013-05-22 15:13:18 +00001996 REG_CLASS(L, SkCanvas);
reed22a517f2015-12-04 20:45:59 -08001997 REG_CLASS(L, SkColorFilter);
Mike Reed7ff6ca52018-01-08 14:45:31 -05001998 REG_CLASS(L, DocHolder);
Mike Reed91919132019-01-02 12:21:01 -05001999 REG_CLASS(L, SkFont);
mike@reedtribe.org792bbd12013-06-11 02:20:28 +00002000 REG_CLASS(L, SkImage);
reed468b1812014-10-19 11:42:54 -07002001 REG_CLASS(L, SkImageFilter);
reed1b6ab442014-11-03 19:55:41 -08002002 REG_CLASS(L, SkMatrix);
reed@google.com74ce6f02013-05-22 15:13:18 +00002003 REG_CLASS(L, SkPaint);
commit-bot@chromium.org1301bf32014-03-17 23:09:47 +00002004 REG_CLASS(L, SkPath);
2005 REG_CLASS(L, SkPathEffect);
reed96affcd2014-10-13 12:38:04 -07002006 REG_CLASS(L, SkPicture);
2007 REG_CLASS(L, SkPictureRecorder);
reed@google.com74ce6f02013-05-22 15:13:18 +00002008 REG_CLASS(L, SkRRect);
reed@google.com5fdc9832013-07-24 15:47:52 +00002009 REG_CLASS(L, SkShader);
reed485557f2014-10-12 10:36:47 -07002010 REG_CLASS(L, SkSurface);
reed1b6ab442014-11-03 19:55:41 -08002011 REG_CLASS(L, SkTextBlob);
mike@reedtribe.orge6469f12013-06-08 03:15:47 +00002012 REG_CLASS(L, SkTypeface);
Ben Wagnerc6c10b42017-08-07 09:56:21 -04002013 REG_CLASS(L, SkFontStyle);
reed@google.com74ce6f02013-05-22 15:13:18 +00002014}
zachr@google.com28c27c82013-06-20 17:15:05 +00002015
reed@google.com7bce9982013-06-20 17:40:21 +00002016extern "C" int luaopen_skia(lua_State* L);
zachr@google.com28c27c82013-06-20 17:15:05 +00002017extern "C" int luaopen_skia(lua_State* L) {
2018 SkLua::Load(L);
2019 return 0;
2020}